diff --git a/.ci-operator.yaml b/.ci-operator.yaml
index f01a223d7..57a09da6c 100644
--- a/.ci-operator.yaml
+++ b/.ci-operator.yaml
@@ -1,4 +1,4 @@
build_root_image:
name: builder
namespace: ocp
- tag: rhel-9-golang-1.26-openshift-4.23
\ No newline at end of file
+ tag: rhel-9-golang-1.26-openshift-5.0
\ No newline at end of file
diff --git a/Dockerfile b/Dockerfile
index 0af429666..68d1cb9a3 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -15,7 +15,7 @@ RUN CGO_ENABLED=0 GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH} go build -a -o ex
# Use distroless as minimal base image to package the external-secrets-operator binary
# Refer to https://github.com/GoogleContainerTools/distroless for more details
-FROM registry.access.redhat.com/ubi9-minimal:9.4
+FROM registry.access.redhat.com/ubi9/ubi-minimal:latest
WORKDIR /
COPY --from=builder /workspace/external-secrets-operator /bin/external-secrets-operator
USER 65534:65534
diff --git a/Makefile b/Makefile
index 62426199f..02d2e2032 100644
--- a/Makefile
+++ b/Makefile
@@ -16,9 +16,9 @@ export XDG_CONFIG_HOME ?= $(PROJECT_ROOT)/_output/.config
# IMG_VERSION defines the images version for the operator, bundle and catalog (must be valid semver: Major.Minor.Patch).
# To re-generate any image for another specific version without changing the standard setup, you can:
-# - use the IMG_VERSION as arg of the specific image build and push targets (e.g make IMG_VERSION=1.2.0 bundle-build bundle-push)
-# - use environment variables to overwrite this value (e.g export IMG_VERSION=1.2.0)
-IMG_VERSION ?= 1.2.0
+# - use the IMG_VERSION as arg of the specific image build and push targets (e.g make IMG_VERSION=1.3.0 bundle-build bundle-push)
+# - use environment variables to overwrite this value (e.g export IMG_VERSION=1.3.0)
+IMG_VERSION ?= 1.3.0
# Validate IMG_VERSION is valid semver (Major.Minor.Patch), fallback to default if not.
ifneq ($(shell echo '$(IMG_VERSION)' | grep -Eq '^[0-9]+\.[0-9]+\.[0-9]+$$' && echo valid),valid)
@@ -33,9 +33,9 @@ EXTERNAL_SECRETS_VERSION ?= v2.5.0
# To re-generate a bundle for other specific channels without changing the standard setup, you can:
# - use the CHANNELS as arg of the bundle target (e.g make bundle CHANNELS=candidate,fast,stable)
# - use environment variables to overwrite this value (e.g export CHANNELS="candidate,fast,stable")
-BUNDLE_CHANNELS ?=
+CHANNELS ?= stable-v1,stable-v1.3
ifneq ($(origin CHANNELS), undefined)
-BUNDLE_CHANNELS := --channels=$(CHANNELS)
+BUNDLE_CHANNELS := $(CHANNELS)
endif
# DEFAULT_CHANNEL defines the default channel used in the bundle.
@@ -43,11 +43,11 @@ endif
# To re-generate a bundle for any other default channel without changing the default setup, you can:
# - use the DEFAULT_CHANNEL as arg of the bundle target (e.g make bundle DEFAULT_CHANNEL=stable)
# - use environment variables to overwrite this value (e.g export DEFAULT_CHANNEL="stable")
-BUNDLE_DEFAULT_CHANNEL ?=
+DEFAULT_CHANNEL ?= stable-v1
ifneq ($(origin DEFAULT_CHANNEL), undefined)
-BUNDLE_DEFAULT_CHANNEL := --default-channel=$(DEFAULT_CHANNEL)
+BUNDLE_DEFAULT_CHANNEL := $(DEFAULT_CHANNEL)
endif
-BUNDLE_METADATA_OPTS ?= $(BUNDLE_CHANNELS) $(BUNDLE_DEFAULT_CHANNEL)
+BUNDLE_METADATA_OPTS ?= --channels=$(BUNDLE_CHANNELS) --default-channel=$(BUNDLE_DEFAULT_CHANNEL)
# IMAGE_TAG_BASE defines the docker.io namespace and part of the image name for remote images.
# This variable is used to construct full image tags for bundle and catalog images.
@@ -61,7 +61,7 @@ IMAGE_TAG_BASE ?= operator.openshift.io/external-secrets-operator
BUNDLE_IMG ?= $(IMAGE_TAG_BASE)-bundle:v$(IMG_VERSION)
# BUNDLE_GEN_FLAGS are the flags passed to the operator-sdk generate bundle command
-BUNDLE_GEN_FLAGS ?= -q --overwrite --version $(IMG_VERSION) $(BUNDLE_METADATA_OPTS)
+BUNDLE_GEN_FLAGS ?= -q --overwrite=false --version $(IMG_VERSION) $(BUNDLE_METADATA_OPTS)
# USE_IMAGE_DIGESTS defines if images are resolved via tags or digests
# You can enable this value if you would like to use SHA Based Digests
@@ -73,11 +73,11 @@ endif
# IMG is the image URL used for building/pushing image targets.
# Default tag is 'latest' to avoid unnecessary changes in checked-in manifests.
-# Override with a specific version when building release images (e.g., IMG=openshift.io/external-secrets-operator:v1.2.0).
+# Override with a specific version when building release images (e.g., IMG=openshift.io/external-secrets-operator:v1.3.0).
IMG ?= openshift.io/external-secrets-operator:latest
# ENVTEST_K8S_VERSION refers to the version of kubebuilder assets to be downloaded by envtest binary.
-ENVTEST_K8S_VERSION = 1.32.0
+ENVTEST_K8S_VERSION = 1.36.0
# Get the currently used golang install path (in GOPATH/bin, unless GOBIN is set)
ifeq (,$(shell go env GOBIN))
@@ -107,7 +107,7 @@ GO_PACKAGE ?= github.com/openshift/external-secrets-operator
SOURCE_GIT_COMMIT ?= $(shell git rev-parse HEAD 2>/dev/null)
BUILD_DATE ?= $(shell date -u +'%Y-%m-%dT%H:%M:%SZ')
-# Extract major/minor from IMG_VERSION (e.g., 1.2.0 -> major=1, minor=1)
+# Extract major/minor from IMG_VERSION (e.g., 1.3.0 -> major=1, minor=3)
IMG_VERSION_MAJOR = $(word 1,$(subst ., ,$(IMG_VERSION)))
IMG_VERSION_MINOR = $(word 2,$(subst ., ,$(IMG_VERSION)))
@@ -143,9 +143,9 @@ KUBE_API_LINT = $(LOCALBIN)/kube-api-linter.so
# Tool Versions
# Set the Operator SDK version to use. By default, what is installed on the system is used.
# This is useful for CI or a project to utilize a specific version of the operator-sdk toolkit.
-OPERATOR_SDK_VERSION ?= v1.39.0
-YQ_VERSION = v4.50.1
-HELM_VERSION ?= v3.17.3
+OPERATOR_SDK_VERSION ?= v1.42.3
+YQ_VERSION = v4.53.3
+HELM_VERSION ?= v4.2.4
# Image tag produced by markdownlint-image; base image for that Dockerfile.
MARKDOWNLINT_IMAGE ?= external-secrets-operator-markdownlint:latest
diff --git a/bindata/external-secrets/networkpolicy_allow-api-server-and-webhook-traffic.yaml b/bindata/external-secrets/networkpolicy_allow-api-server-and-webhook-traffic.yaml
index 76abf0e48..e4bf93318 100644
--- a/bindata/external-secrets/networkpolicy_allow-api-server-and-webhook-traffic.yaml
+++ b/bindata/external-secrets/networkpolicy_allow-api-server-and-webhook-traffic.yaml
@@ -6,7 +6,7 @@ metadata:
labels:
app.kubernetes.io/name: external-secrets-webhook
app.kubernetes.io/instance: external-secrets
- app.kubernetes.io/version: "v1.2.0"
+ app.kubernetes.io/version: "v1.3.0"
app.kubernetes.io/managed-by: external-secrets-operator
external-secrets.io/component: webhook
spec:
diff --git a/bindata/external-secrets/networkpolicy_allow-api-server-egress-for-bitwarden-sever.yaml b/bindata/external-secrets/networkpolicy_allow-api-server-egress-for-bitwarden-sever.yaml
index 0ff3102d9..1e6c119e0 100644
--- a/bindata/external-secrets/networkpolicy_allow-api-server-egress-for-bitwarden-sever.yaml
+++ b/bindata/external-secrets/networkpolicy_allow-api-server-egress-for-bitwarden-sever.yaml
@@ -6,7 +6,7 @@ metadata:
labels:
app.kubernetes.io/name: bitwarden-sdk-server
app.kubernetes.io/instance: external-secrets
- app.kubernetes.io/version: "v1.2.0"
+ app.kubernetes.io/version: "v1.3.0"
app.kubernetes.io/managed-by: external-secrets-operator
spec:
podSelector:
diff --git a/bindata/external-secrets/networkpolicy_allow-api-server-egress-for-cert-controller-traffic.yaml b/bindata/external-secrets/networkpolicy_allow-api-server-egress-for-cert-controller-traffic.yaml
index 4c2f13e29..5fceb9e85 100644
--- a/bindata/external-secrets/networkpolicy_allow-api-server-egress-for-cert-controller-traffic.yaml
+++ b/bindata/external-secrets/networkpolicy_allow-api-server-egress-for-cert-controller-traffic.yaml
@@ -6,7 +6,7 @@ metadata:
labels:
app.kubernetes.io/name: external-secrets-cert-controller
app.kubernetes.io/instance: external-secrets
- app.kubernetes.io/version: "v1.2.0"
+ app.kubernetes.io/version: "v1.3.0"
app.kubernetes.io/managed-by: external-secrets-operator
spec:
podSelector:
diff --git a/bindata/external-secrets/networkpolicy_allow-api-server-egress-for-main-controller-traffic.yaml b/bindata/external-secrets/networkpolicy_allow-api-server-egress-for-main-controller-traffic.yaml
index af1730ba2..6cd43f928 100644
--- a/bindata/external-secrets/networkpolicy_allow-api-server-egress-for-main-controller-traffic.yaml
+++ b/bindata/external-secrets/networkpolicy_allow-api-server-egress-for-main-controller-traffic.yaml
@@ -6,7 +6,7 @@ metadata:
labels:
app.kubernetes.io/name: external-secrets
app.kubernetes.io/instance: external-secrets
- app.kubernetes.io/version: "v1.2.0"
+ app.kubernetes.io/version: "v1.3.0"
app.kubernetes.io/managed-by: external-secrets-operator
spec:
podSelector:
diff --git a/bindata/external-secrets/networkpolicy_allow-dns.yaml b/bindata/external-secrets/networkpolicy_allow-dns.yaml
index f1058b18a..c5d24e355 100644
--- a/bindata/external-secrets/networkpolicy_allow-dns.yaml
+++ b/bindata/external-secrets/networkpolicy_allow-dns.yaml
@@ -4,7 +4,7 @@ metadata:
labels:
app.kubernetes.io/name: external-secrets
app.kubernetes.io/instance: external-secrets
- app.kubernetes.io/version: "v1.2.0"
+ app.kubernetes.io/version: "v1.3.0"
app.kubernetes.io/managed-by: external-secrets-operator
name: eso-sys-allow-to-dns
spec:
diff --git a/bindata/external-secrets/networkpolicy_deny-all.yaml b/bindata/external-secrets/networkpolicy_deny-all.yaml
index 1a796971d..bf4417616 100644
--- a/bindata/external-secrets/networkpolicy_deny-all.yaml
+++ b/bindata/external-secrets/networkpolicy_deny-all.yaml
@@ -6,7 +6,7 @@ metadata:
labels:
app.kubernetes.io/name: external-secrets
app.kubernetes.io/instance: external-secrets
- app.kubernetes.io/version: "v1.2.0"
+ app.kubernetes.io/version: "v1.3.0"
app.kubernetes.io/managed-by: external-secrets-operator
spec:
podSelector: {}
diff --git a/bundle.Dockerfile b/bundle.Dockerfile
index 7620a7f45..d72d1ae97 100644
--- a/bundle.Dockerfile
+++ b/bundle.Dockerfile
@@ -1,12 +1,13 @@
-FROM scratch
+FROM registry.access.redhat.com/ubi9/ubi-minimal:latest
# Core bundle labels.
LABEL operators.operatorframework.io.bundle.mediatype.v1=registry+v1
LABEL operators.operatorframework.io.bundle.manifests.v1=manifests/
LABEL operators.operatorframework.io.bundle.metadata.v1=metadata/
LABEL operators.operatorframework.io.bundle.package.v1=openshift-external-secrets-operator
-LABEL operators.operatorframework.io.bundle.channels.v1=alpha
-LABEL operators.operatorframework.io.metrics.builder=operator-sdk-v1.39.0
+LABEL operators.operatorframework.io.bundle.channels.v1=stable-v1,stable-v1.3
+LABEL operators.operatorframework.io.bundle.channel.default.v1=stable-v1
+LABEL operators.operatorframework.io.metrics.builder=operator-sdk-v1.42.0
LABEL operators.operatorframework.io.metrics.mediatype.v1=metrics+v1
LABEL operators.operatorframework.io.metrics.project_layout=go.kubebuilder.io/v4
diff --git a/bundle/manifests/openshift-external-secrets-operator.clusterserviceversion.yaml b/bundle/manifests/openshift-external-secrets-operator.clusterserviceversion.yaml
index fd449d41c..9aa4f75af 100644
--- a/bundle/manifests/openshift-external-secrets-operator.clusterserviceversion.yaml
+++ b/bundle/manifests/openshift-external-secrets-operator.clusterserviceversion.yaml
@@ -220,7 +220,7 @@ metadata:
categories: Security
console.openshift.io/disable-operand-delete: "true"
containerImage: openshift.io/external-secrets-operator:latest
- createdAt: "2026-06-19T12:17:03Z"
+ createdAt: "2026-08-19T15:21:11Z"
features.operators.openshift.io/cnf: "false"
features.operators.openshift.io/cni: "false"
features.operators.openshift.io/csi: "false"
@@ -231,7 +231,7 @@ metadata:
features.operators.openshift.io/token-auth-aws: "false"
features.operators.openshift.io/token-auth-azure: "false"
features.operators.openshift.io/token-auth-gcp: "false"
- olm.skipRange: '>=1.1.0 <1.2.0'
+ olm.skipRange: '>=1.2.0 <1.3.0'
operator.openshift.io/uninstall-message: The External Secrets Operator for Red
Hat OpenShift will be removed from external-secrets-operator namespace. If your
Operator configured any off-cluster resources, these will continue to run and
@@ -242,7 +242,7 @@ metadata:
operatorframework.io/suggested-namespace: external-secrets-operator
operators.openshift.io/valid-subscription: '["OpenShift Kubernetes Engine", "OpenShift
Container Platform", "OpenShift Platform Plus"]'
- operators.operatorframework.io/builder: operator-sdk-v1.39.0
+ operators.operatorframework.io/builder: operator-sdk-v1.42.3
operators.operatorframework.io/project_layout: go.kubebuilder.io/v4
repository: https://github.com/openshift/external-secrets-operator
support: Red Hat, Inc.
@@ -252,7 +252,7 @@ metadata:
operatorframework.io/arch.ppc64le: supported
operatorframework.io/arch.s390x: supported
operatorframework.io/os.linux: supported
- name: openshift-external-secrets-operator.v1.2.0
+ name: openshift-external-secrets-operator.v1.3.0
namespace: placeholder
spec:
apiservicedefinitions: {}
@@ -743,7 +743,7 @@ spec:
- name: OPERATOR_NAME
value: external-secrets-operator
- name: OPERATOR_IMAGE_VERSION
- value: 1.2.0
+ value: 1.3.0
- name: RELATED_IMAGE_EXTERNAL_SECRETS
value: ghcr.io/external-secrets/external-secrets:v2.5.0
- name: OPERAND_EXTERNAL_SECRETS_IMAGE_VERSION
@@ -844,5 +844,5 @@ spec:
name: external-secrets
- image: ghcr.io/external-secrets/bitwarden-sdk-server:v0.6.0
name: bitwarden-sdk-server
- replaces: external-secrets-operator.v1.1.0
- version: 1.2.0
+ replaces: external-secrets-operator.v1.2.0
+ version: 1.3.0
diff --git a/bundle/manifests/operator.openshift.io_externalsecretsconfigs.yaml b/bundle/manifests/operator.openshift.io_externalsecretsconfigs.yaml
index 699f85bfc..2e70cb1f5 100644
--- a/bundle/manifests/operator.openshift.io_externalsecretsconfigs.yaml
+++ b/bundle/manifests/operator.openshift.io_externalsecretsconfigs.yaml
@@ -2,7 +2,7 @@ apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
- controller-gen.kubebuilder.io/version: v0.19.0
+ controller-gen.kubebuilder.io/version: v0.21.0
creationTimestamp: null
labels:
app.kubernetes.io/name: externalsecretsconfig
diff --git a/bundle/manifests/operator.openshift.io_externalsecretsmanagers.yaml b/bundle/manifests/operator.openshift.io_externalsecretsmanagers.yaml
index 84161e138..75135e1ee 100644
--- a/bundle/manifests/operator.openshift.io_externalsecretsmanagers.yaml
+++ b/bundle/manifests/operator.openshift.io_externalsecretsmanagers.yaml
@@ -2,7 +2,7 @@ apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
- controller-gen.kubebuilder.io/version: v0.19.0
+ controller-gen.kubebuilder.io/version: v0.21.0
creationTimestamp: null
labels:
app.kubernetes.io/name: externalsecretsmanager
diff --git a/bundle/metadata/annotations.yaml b/bundle/metadata/annotations.yaml
index a9d223a9d..8f120c00e 100644
--- a/bundle/metadata/annotations.yaml
+++ b/bundle/metadata/annotations.yaml
@@ -4,8 +4,9 @@ annotations:
operators.operatorframework.io.bundle.manifests.v1: manifests/
operators.operatorframework.io.bundle.metadata.v1: metadata/
operators.operatorframework.io.bundle.package.v1: openshift-external-secrets-operator
- operators.operatorframework.io.bundle.channels.v1: alpha
- operators.operatorframework.io.metrics.builder: operator-sdk-v1.39.0
+ operators.operatorframework.io.bundle.channels.v1: stable-v1,stable-v1.3
+ operators.operatorframework.io.bundle.channel.default.v1: stable-v1
+ operators.operatorframework.io.metrics.builder: operator-sdk-v1.42.0
operators.operatorframework.io.metrics.mediatype.v1: metrics+v1
operators.operatorframework.io.metrics.project_layout: go.kubebuilder.io/v4
diff --git a/cmd/external-secrets-operator/go.mod b/cmd/external-secrets-operator/go.mod
index 7a140460a..072638f81 100644
--- a/cmd/external-secrets-operator/go.mod
+++ b/cmd/external-secrets-operator/go.mod
@@ -2,15 +2,17 @@ module github.com/openshift/external-secrets-operator/cmd/external-secrets-opera
go 1.26.0
+replace github.com/openshift/external-secrets-operator => ../..
+
require (
- github.com/cert-manager/cert-manager v1.18.5
+ github.com/cert-manager/cert-manager v1.21.1
github.com/openshift/external-secrets-operator v0.0.0-00010101000000-000000000000
- k8s.io/api v0.35.6
- k8s.io/apiextensions-apiserver v0.35.3
- k8s.io/apimachinery v0.35.6
- k8s.io/client-go v0.35.6
+ k8s.io/api v0.36.3
+ k8s.io/apiextensions-apiserver v0.36.3
+ k8s.io/apimachinery v0.36.3
+ k8s.io/client-go v0.36.3
k8s.io/klog/v2 v2.140.0
- sigs.k8s.io/controller-runtime v0.23.3
+ sigs.k8s.io/controller-runtime v0.24.1
)
require (
@@ -25,28 +27,26 @@ require (
github.com/emicklei/go-restful/v3 v3.13.0 // indirect
github.com/evanphx/json-patch/v5 v5.9.11 // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect
- github.com/fsnotify/fsnotify v1.9.0 // indirect
- github.com/fxamacker/cbor/v2 v2.9.0 // indirect
- github.com/go-logr/logr v1.4.3 // indirect
+ github.com/fsnotify/fsnotify v1.10.0 // indirect
+ github.com/fxamacker/cbor/v2 v2.9.3 // indirect
+ github.com/go-logr/logr v1.4.4 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
- github.com/go-openapi/jsonpointer v0.22.4 // indirect
- github.com/go-openapi/jsonreference v0.21.4 // indirect
- github.com/go-openapi/swag v0.25.4 // indirect
- github.com/go-openapi/swag/cmdutils v0.25.4 // indirect
- github.com/go-openapi/swag/conv v0.25.4 // indirect
- github.com/go-openapi/swag/fileutils v0.25.4 // indirect
- github.com/go-openapi/swag/jsonname v0.25.4 // indirect
- github.com/go-openapi/swag/jsonutils v0.25.4 // indirect
- github.com/go-openapi/swag/loading v0.25.4 // indirect
- github.com/go-openapi/swag/mangling v0.25.4 // indirect
- github.com/go-openapi/swag/netutils v0.25.4 // indirect
- github.com/go-openapi/swag/stringutils v0.25.4 // indirect
- github.com/go-openapi/swag/typeutils v0.25.4 // indirect
- github.com/go-openapi/swag/yamlutils v0.25.4 // indirect
- github.com/google/btree v1.1.3 // indirect
+ github.com/go-openapi/jsonpointer v1.0.0 // indirect
+ github.com/go-openapi/jsonreference v1.0.0 // indirect
+ github.com/go-openapi/swag v0.28.0 // indirect
+ github.com/go-openapi/swag/cmdutils v0.28.0 // indirect
+ github.com/go-openapi/swag/conv v0.28.0 // indirect
+ github.com/go-openapi/swag/fileutils v0.28.0 // indirect
+ github.com/go-openapi/swag/jsonutils v0.28.0 // indirect
+ github.com/go-openapi/swag/loading v0.28.0 // indirect
+ github.com/go-openapi/swag/mangling v0.28.0 // indirect
+ github.com/go-openapi/swag/netutils v0.28.0 // indirect
+ github.com/go-openapi/swag/pools v0.28.0 // indirect
+ github.com/go-openapi/swag/stringutils v0.28.0 // indirect
+ github.com/go-openapi/swag/typeutils v0.28.0 // indirect
+ github.com/go-openapi/swag/yamlutils v0.28.0 // indirect
github.com/google/cel-go v0.31.0 // indirect
github.com/google/gnostic-models v0.7.1 // indirect
- github.com/google/go-cmp v0.7.0 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.7 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
@@ -59,55 +59,52 @@ require (
github.com/prometheus/client_golang v1.23.2 // indirect
github.com/prometheus/client_model v0.6.2 // indirect
github.com/prometheus/common v0.67.5 // indirect
- github.com/prometheus/procfs v0.19.2 // indirect
+ github.com/prometheus/procfs v0.20.1 // indirect
github.com/robfig/cron/v3 v3.0.1 // indirect
github.com/spf13/cobra v1.10.2 // indirect
github.com/spf13/pflag v1.0.10 // indirect
github.com/x448/float16 v0.8.4 // indirect
go.opentelemetry.io/auto/sdk v1.2.1 // indirect
- go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.65.0 // indirect
- go.opentelemetry.io/otel v1.41.0 // indirect
+ go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.67.0 // indirect
+ go.opentelemetry.io/otel v1.44.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.40.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.40.0 // indirect
- go.opentelemetry.io/otel/metric v1.41.0 // indirect
- go.opentelemetry.io/otel/sdk v1.40.0 // indirect
- go.opentelemetry.io/otel/trace v1.41.0 // indirect
+ go.opentelemetry.io/otel/metric v1.44.0 // indirect
+ go.opentelemetry.io/otel/sdk v1.43.0 // indirect
+ go.opentelemetry.io/otel/trace v1.44.0 // indirect
go.opentelemetry.io/proto/otlp v1.9.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
- go.uber.org/zap v1.27.1 // indirect
- go.yaml.in/yaml/v2 v2.4.3 // indirect
- go.yaml.in/yaml/v3 v3.0.4 // indirect
+ go.uber.org/zap v1.28.0 // indirect
+ go.yaml.in/yaml/v2 v2.4.4 // indirect
+ go.yaml.in/yaml/v3 v3.0.5 // indirect
golang.org/x/exp v0.0.0-20260112195511-716be5621a96 // indirect
golang.org/x/net v0.58.0 // indirect
- golang.org/x/oauth2 v0.34.0 // indirect
+ golang.org/x/oauth2 v0.36.0 // indirect
golang.org/x/sync v0.22.0 // indirect
golang.org/x/sys v0.47.0 // indirect
golang.org/x/term v0.45.0 // indirect
golang.org/x/text v0.41.0 // indirect
- golang.org/x/time v0.14.0 // indirect
+ golang.org/x/time v0.15.0 // indirect
gomodules.xyz/jsonpatch/v2 v2.5.0 // indirect
- google.golang.org/genproto/googleapis/api v0.0.0-20260202165425-ce8ad4cf556b // indirect
- google.golang.org/genproto/googleapis/rpc v0.0.0-20260202165425-ce8ad4cf556b // indirect
- google.golang.org/grpc v1.79.3 // indirect
- google.golang.org/protobuf v1.36.12-0.20260120151049-f2248ac996af // indirect
+ google.golang.org/genproto/googleapis/api v0.0.0-20260414002931-afd174a4e478 // indirect
+ google.golang.org/genproto/googleapis/rpc v0.0.0-20260610212136-7ab31c22f7ad // indirect
+ google.golang.org/grpc v1.82.1 // indirect
+ google.golang.org/protobuf v1.36.12 // indirect
gopkg.in/evanphx/json-patch.v4 v4.13.0 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
- k8s.io/apiserver v0.35.6 // indirect
- k8s.io/component-base v0.35.6 // indirect
+ k8s.io/apiserver v0.36.3 // indirect
+ k8s.io/component-base v0.36.3 // indirect
k8s.io/component-helpers v0.35.6 // indirect
k8s.io/controller-manager v0.35.6 // indirect
- k8s.io/kube-openapi v0.0.0-20260317180543-43fb72c5454a // indirect
+ k8s.io/kube-openapi v0.0.0-20260721132016-d427ff9ee9ad // indirect
k8s.io/kubelet v0.32.2 // indirect
- k8s.io/kubernetes v1.35.6 // indirect
- k8s.io/utils v0.0.0-20260210185600-b8788abfbbc2 // indirect
+ k8s.io/kubernetes v1.36.3 // indirect
+ k8s.io/streaming v0.36.3 // indirect
+ k8s.io/utils v0.0.0-20260707023825-cf1189d6abe3 // indirect
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.34.0 // indirect
- sigs.k8s.io/gateway-api v1.1.0 // indirect
+ sigs.k8s.io/gateway-api v1.6.0 // indirect
sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect
sigs.k8s.io/randfill v1.0.0 // indirect
- sigs.k8s.io/structured-merge-diff/v6 v6.3.2 // indirect
+ sigs.k8s.io/structured-merge-diff/v6 v6.4.2 // indirect
sigs.k8s.io/yaml v1.6.0 // indirect
)
-
-replace github.com/openshift/external-secrets-operator => ../..
-
-replace github.com/external-secrets/external-secrets => github.com/openshift/external-secrets v0.20.4
diff --git a/cmd/external-secrets-operator/go.sum b/cmd/external-secrets-operator/go.sum
index 0f7539a4d..a282ebeba 100644
--- a/cmd/external-secrets-operator/go.sum
+++ b/cmd/external-secrets-operator/go.sum
@@ -1,7 +1,7 @@
cel.dev/expr v0.25.1 h1:1KrZg61W6TWSxuNZ37Xy49ps13NUovb66QLprthtwi4=
cel.dev/expr v0.25.1/go.mod h1:hrXvqGP6G6gyx8UAHSHJ5RGk//1Oj5nXQ2NI02Nrsg4=
-github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0=
-github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=
+github.com/Masterminds/semver/v3 v3.5.0 h1:kQceYJfbupGfZOKZQg0kou0DgAKhzDg2NZPAwZ/2OOE=
+github.com/Masterminds/semver/v3 v3.5.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=
github.com/antlr4-go/antlr/v4 v4.13.1 h1:SqQKkuVZ+zWkMMNkjy5FZe5mr5WURWnlpmOuzYWrPrQ=
github.com/antlr4-go/antlr/v4 v4.13.1/go.mod h1:GKmUxMtwp6ZgGwZSva4eWPC5mS6vUAmOABFgjdkM7Nw=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
@@ -10,8 +10,8 @@ github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM
github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ=
github.com/cenkalti/backoff/v5 v5.0.3 h1:ZN+IMa753KfX5hd8vVaMixjnqRZ3y8CuJKRKj1xcsSM=
github.com/cenkalti/backoff/v5 v5.0.3/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw=
-github.com/cert-manager/cert-manager v1.18.5 h1:Gx4FSpSPYcSC4MQf43QjbxDfyTEbwZgfZQs5Lq9QlBs=
-github.com/cert-manager/cert-manager v1.18.5/go.mod h1:HbPSO5MW/44wu19t84eY/K4c4/WwyPB4bA3uffOH92s=
+github.com/cert-manager/cert-manager v1.21.1 h1:0LttV37Q5c2CBNoHkjuI8sLKTXWZDC2SwQkxrBMKV9w=
+github.com/cert-manager/cert-manager v1.21.1/go.mod h1:sVwmLBWoiB1BRd0rJElBGQuiu94z4k7p3Kd0FRQyfgw=
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
@@ -29,57 +29,55 @@ github.com/evanphx/json-patch/v5 v5.9.11 h1:/8HVnzMq13/3x9TPvjG08wUGqBTmZBsCWzjT
github.com/evanphx/json-patch/v5 v5.9.11/go.mod h1:3j+LviiESTElxA4p3EMKAB9HXj3/XEtnUf6OZxqIQTM=
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
-github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k=
-github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
-github.com/fxamacker/cbor/v2 v2.9.0 h1:NpKPmjDBgUfBms6tr6JZkTHtfFGcMKsw3eGcmD/sapM=
-github.com/fxamacker/cbor/v2 v2.9.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ=
+github.com/fsnotify/fsnotify v1.10.0 h1:Xx/5Ydg9CeBDX/wi4VJqStNtohYjitZhhlHt4h3St1M=
+github.com/fsnotify/fsnotify v1.10.0/go.mod h1:TLheqan6HD6GBK6PrDWyDPBaEV8LspOxvPSjC+bVfgo=
+github.com/fxamacker/cbor/v2 v2.9.3 h1:oQBnFATpNdY8gJHTndDDv5Xl4QqNaz51G5LLEPhng3Q=
+github.com/fxamacker/cbor/v2 v2.9.3/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ=
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
-github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
-github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
+github.com/go-logr/logr v1.4.4 h1:tG4xh9yMsRCAiodLVTxyrkzSZ9+o0L1Kg/+cPVcbP/8=
+github.com/go-logr/logr v1.4.4/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ=
github.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR8/Gg=
-github.com/go-openapi/jsonpointer v0.22.4 h1:dZtK82WlNpVLDW2jlA1YCiVJFVqkED1MegOUy9kR5T4=
-github.com/go-openapi/jsonpointer v0.22.4/go.mod h1:elX9+UgznpFhgBuaMQ7iu4lvvX1nvNsesQ3oxmYTw80=
-github.com/go-openapi/jsonreference v0.21.4 h1:24qaE2y9bx/q3uRK/qN+TDwbok1NhbSmGjjySRCHtC8=
-github.com/go-openapi/jsonreference v0.21.4/go.mod h1:rIENPTjDbLpzQmQWCj5kKj3ZlmEh+EFVbz3RTUh30/4=
-github.com/go-openapi/swag v0.25.4 h1:OyUPUFYDPDBMkqyxOTkqDYFnrhuhi9NR6QVUvIochMU=
-github.com/go-openapi/swag v0.25.4/go.mod h1:zNfJ9WZABGHCFg2RnY0S4IOkAcVTzJ6z2Bi+Q4i6qFQ=
-github.com/go-openapi/swag/cmdutils v0.25.4 h1:8rYhB5n6WawR192/BfUu2iVlxqVR9aRgGJP6WaBoW+4=
-github.com/go-openapi/swag/cmdutils v0.25.4/go.mod h1:pdae/AFo6WxLl5L0rq87eRzVPm/XRHM3MoYgRMvG4A0=
-github.com/go-openapi/swag/conv v0.25.4 h1:/Dd7p0LZXczgUcC/Ikm1+YqVzkEeCc9LnOWjfkpkfe4=
-github.com/go-openapi/swag/conv v0.25.4/go.mod h1:3LXfie/lwoAv0NHoEuY1hjoFAYkvlqI/Bn5EQDD3PPU=
-github.com/go-openapi/swag/fileutils v0.25.4 h1:2oI0XNW5y6UWZTC7vAxC8hmsK/tOkWXHJQH4lKjqw+Y=
-github.com/go-openapi/swag/fileutils v0.25.4/go.mod h1:cdOT/PKbwcysVQ9Tpr0q20lQKH7MGhOEb6EwmHOirUk=
-github.com/go-openapi/swag/jsonname v0.25.4 h1:bZH0+MsS03MbnwBXYhuTttMOqk+5KcQ9869Vye1bNHI=
-github.com/go-openapi/swag/jsonname v0.25.4/go.mod h1:GPVEk9CWVhNvWhZgrnvRA6utbAltopbKwDu8mXNUMag=
-github.com/go-openapi/swag/jsonutils v0.25.4 h1:VSchfbGhD4UTf4vCdR2F4TLBdLwHyUDTd1/q4i+jGZA=
-github.com/go-openapi/swag/jsonutils v0.25.4/go.mod h1:7OYGXpvVFPn4PpaSdPHJBtF0iGnbEaTk8AvBkoWnaAY=
-github.com/go-openapi/swag/jsonutils/fixtures_test v0.25.4 h1:IACsSvBhiNJwlDix7wq39SS2Fh7lUOCJRmx/4SN4sVo=
-github.com/go-openapi/swag/jsonutils/fixtures_test v0.25.4/go.mod h1:Mt0Ost9l3cUzVv4OEZG+WSeoHwjWLnarzMePNDAOBiM=
-github.com/go-openapi/swag/loading v0.25.4 h1:jN4MvLj0X6yhCDduRsxDDw1aHe+ZWoLjW+9ZQWIKn2s=
-github.com/go-openapi/swag/loading v0.25.4/go.mod h1:rpUM1ZiyEP9+mNLIQUdMiD7dCETXvkkC30z53i+ftTE=
-github.com/go-openapi/swag/mangling v0.25.4 h1:2b9kBJk9JvPgxr36V23FxJLdwBrpijI26Bx5JH4Hp48=
-github.com/go-openapi/swag/mangling v0.25.4/go.mod h1:6dxwu6QyORHpIIApsdZgb6wBk/DPU15MdyYj/ikn0Hg=
-github.com/go-openapi/swag/netutils v0.25.4 h1:Gqe6K71bGRb3ZQLusdI8p/y1KLgV4M/k+/HzVSqT8H0=
-github.com/go-openapi/swag/netutils v0.25.4/go.mod h1:m2W8dtdaoX7oj9rEttLyTeEFFEBvnAx9qHd5nJEBzYg=
-github.com/go-openapi/swag/stringutils v0.25.4 h1:O6dU1Rd8bej4HPA3/CLPciNBBDwZj9HiEpdVsb8B5A8=
-github.com/go-openapi/swag/stringutils v0.25.4/go.mod h1:GTsRvhJW5xM5gkgiFe0fV3PUlFm0dr8vki6/VSRaZK0=
-github.com/go-openapi/swag/typeutils v0.25.4 h1:1/fbZOUN472NTc39zpa+YGHn3jzHWhv42wAJSN91wRw=
-github.com/go-openapi/swag/typeutils v0.25.4/go.mod h1:Ou7g//Wx8tTLS9vG0UmzfCsjZjKhpjxayRKTHXf2pTE=
-github.com/go-openapi/swag/yamlutils v0.25.4 h1:6jdaeSItEUb7ioS9lFoCZ65Cne1/RZtPBZ9A56h92Sw=
-github.com/go-openapi/swag/yamlutils v0.25.4/go.mod h1:MNzq1ulQu+yd8Kl7wPOut/YHAAU/H6hL91fF+E2RFwc=
-github.com/go-openapi/testify/enable/yaml/v2 v2.0.2 h1:0+Y41Pz1NkbTHz8NngxTuAXxEodtNSI1WG1c/m5Akw4=
-github.com/go-openapi/testify/enable/yaml/v2 v2.0.2/go.mod h1:kme83333GCtJQHXQ8UKX3IBZu6z8T5Dvy5+CW3NLUUg=
-github.com/go-openapi/testify/v2 v2.0.2 h1:X999g3jeLcoY8qctY/c/Z8iBHTbwLz7R2WXd6Ub6wls=
-github.com/go-openapi/testify/v2 v2.0.2/go.mod h1:HCPmvFFnheKK2BuwSA0TbbdxJ3I16pjwMkYkP4Ywn54=
+github.com/go-openapi/jsonpointer v1.0.0 h1:kR9tHqY0CtZaOPVFm622dPVNhrvYpwr4uCxgL3h1H8s=
+github.com/go-openapi/jsonpointer v1.0.0/go.mod h1:Z3rw7dWu1p9IgitXCFamSlA5lmDiklEB6vkaxcNZW5Y=
+github.com/go-openapi/jsonreference v1.0.0 h1:jlmTr6torcd1YgDQvSfNmRtKzYDO4FGBkrAdlAVWnpY=
+github.com/go-openapi/jsonreference v1.0.0/go.mod h1:jtwdyGbJk0Xhe5Y+rwtglQP6Sb1WZST4rT32LWB+sv0=
+github.com/go-openapi/swag v0.28.0 h1:xkgbOSKj6DZziNpyqRRAOt3GJGtgjgsd2RoyT30VWuw=
+github.com/go-openapi/swag v0.28.0/go.mod h1:4qYnT3Cqr1p1VknOdPo70evN4rgQnAg6jwApHyxSGIg=
+github.com/go-openapi/swag/cmdutils v0.28.0 h1:7TOeNtkYru1SG8Y34tDh9WBbLsMqGnptuxWiHREPZ4Q=
+github.com/go-openapi/swag/cmdutils v0.28.0/go.mod h1:Sm1MVFMkF6guJJ+pQqHnQA3N0j9qALV3NxzDSv6bETM=
+github.com/go-openapi/swag/conv v0.28.0 h1:GtqqbyFe7vR5Y7ehxG9W6/OvrSFdf1OLeTGp40TqxH8=
+github.com/go-openapi/swag/conv v0.28.0/go.mod h1:mbUE+mzctnhxi864m0Q07SpN8OowD9JhxmxuYvZZD/k=
+github.com/go-openapi/swag/fileutils v0.28.0 h1:Z04XWQD7R8Eq+7GnOrjovBxPPmZzsS4gt2H2GPGIViU=
+github.com/go-openapi/swag/fileutils v0.28.0/go.mod h1:VvJFZLTZS0AI854gEQz5tk7dBESdLjiNUMSZ/th2ry8=
+github.com/go-openapi/swag/jsonutils v0.28.0 h1:YIch6FwO7RXzeAnbO8Tu7dWBZeUEH+4nA0HXltVTnv4=
+github.com/go-openapi/swag/jsonutils v0.28.0/go.mod h1:CYM3WlTUcagR2ZoHdz54di/cbBqt82tuxuXgAjxw+mg=
+github.com/go-openapi/swag/jsonutils/fixtures_test v0.28.0 h1:qV+VVUAx5Oro8WjVWpZeql7YReTKhT4smR4zhcOQZr0=
+github.com/go-openapi/swag/jsonutils/fixtures_test v0.28.0/go.mod h1:mofwUWx70wvskwESqRJ//k/9kURmCgyJl5m5Ppoh5kY=
+github.com/go-openapi/swag/loading v0.28.0 h1:td8QZdZC9MIYGGSnSPKShKiK22I2tU5UQvuUhIBPRLU=
+github.com/go-openapi/swag/loading v0.28.0/go.mod h1:rXB0QiQX5mMveXEA7ouM4KiiM9jVJe4K6BVbwhD1M4k=
+github.com/go-openapi/swag/mangling v0.28.0 h1:pH8eyeNO9SLYsTMWJrurnNfKmDa28XrlA+HePVD53VM=
+github.com/go-openapi/swag/mangling v0.28.0/go.mod h1:jtBE2+V+3pILxOR7Vgce+Cwp6A2PgZbvVqfNntbVs0w=
+github.com/go-openapi/swag/netutils v0.28.0 h1:YXN6TALEi2pzts8/8GNm6T61HTAZsieukGZidap989k=
+github.com/go-openapi/swag/netutils v0.28.0/go.mod h1:J+WYyFMLtvtCGqa6jLv+YNUmIKI3ZRQRrvfNDMoQoEQ=
+github.com/go-openapi/swag/pools v0.28.0 h1:HPMZWSAfce3rdVTFcjFiCIBtDg9h4x2QlRrHipwhxeU=
+github.com/go-openapi/swag/pools v0.28.0/go.mod h1:kVQefhSK5RWuRe7BXsL8htgBPAMpN7HDGpGEknqugeE=
+github.com/go-openapi/swag/stringutils v0.28.0 h1:ixsc9iYgDPubHL/8nSkbnryEHpD2VRlBMLKpQyPXcDU=
+github.com/go-openapi/swag/stringutils v0.28.0/go.mod h1:lzRN95CxXmA03XcDWHLOb6nOMcxCqR5rGY0lOgsfRoM=
+github.com/go-openapi/swag/typeutils v0.28.0 h1:nRBKSBXjDgf01VDPB3fWeD9nQuhCOVeIYAkUx2tbkyY=
+github.com/go-openapi/swag/typeutils v0.28.0/go.mod h1:Srm0xFNRZ1Y+vCxJclo5qzx8aj+1pAKda/YfFPrG0dQ=
+github.com/go-openapi/swag/yamlutils v0.28.0 h1:TV3JXH6DS46KUroDtMLAYHGkdWf5VDq3wVWFirmzROY=
+github.com/go-openapi/swag/yamlutils v0.28.0/go.mod h1:x0q/yndZHEgk9Rx3DyDqzFUmHy55KTvIZldvF2dTJXs=
+github.com/go-openapi/testify/enable/yaml/v2 v2.6.0 h1:gGHwAJ0R/5jU8BEGDbfRNR3hL68dAVi84WuOApp29B0=
+github.com/go-openapi/testify/enable/yaml/v2 v2.6.0/go.mod h1:tY+St1SGq4NFl0QIqdTY4aEdbChAHxhyB77XQi9iJCo=
+github.com/go-openapi/testify/v2 v2.6.0 h1:5PKH2HE7YJ/LuRPQGvSxBRlFXNQhSetBLlGAgUEu3ug=
+github.com/go-openapi/testify/v2 v2.6.0/go.mod h1:SgsVHtfooshd0tublTtJ50FPKhujf47YRqauXXOUxfw=
github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
-github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg=
-github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4=
github.com/google/cel-go v0.31.0 h1:H0bhpFTqOvmHrBGrWKp7ZlhBm5Hh8PYUEXnwxT1LL7A=
github.com/google/cel-go v0.31.0/go.mod h1:X0bD6iVNR8pkROSOoHVdgTkzmRcosof7WQqCD6wcMc8=
github.com/google/gnostic-models v0.7.1 h1:SisTfuFKJSKM5CPZkffwi6coztzzeYUhc3v4yxLWH8c=
@@ -89,8 +87,8 @@ github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
-github.com/google/pprof v0.0.0-20260115054156-294ebfa9ad83 h1:z2ogiKUYzX5Is6zr/vP9vJGqPwcdqsWjOt+V8J7+bTc=
-github.com/google/pprof v0.0.0-20260115054156-294ebfa9ad83/go.mod h1:MxpfABSjhmINe3F1It9d+8exIHFvUqtLIRCdOGNXqiI=
+github.com/google/pprof v0.0.0-20260802141513-ef3492d7dac3 h1:LMLX+LgTNWpfvCBdFebv6EsYotImrt/Ppc5cXIriCSo=
+github.com/google/pprof v0.0.0-20260802141513-ef3492d7dac3/go.mod h1:jl5iWTm0/hd5PjEYEOuwAJ57L/CibdZfrqZ5XA5GrCk=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.7 h1:X+2YciYSxvMQK0UZ7sg45ZVabVZBeBuvMkmuI2V3Fak=
@@ -101,10 +99,6 @@ github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnr
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
-github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
-github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
-github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
-github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
@@ -115,10 +109,10 @@ github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee h1:W5t00kpgFd
github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
-github.com/onsi/ginkgo/v2 v2.27.4 h1:fcEcQW/A++6aZAZQNUmNjvA9PSOzefMJBerHJ4t8v8Y=
-github.com/onsi/ginkgo/v2 v2.27.4/go.mod h1:ArE1D/XhNXBXCBkKOLkbsb2c81dQHCRcF5zwn/ykDRo=
-github.com/onsi/gomega v1.39.0 h1:y2ROC3hKFmQZJNFeGAMeHZKkjBL65mIZcvrLQBF9k6Q=
-github.com/onsi/gomega v1.39.0/go.mod h1:ZCU1pkQcXDO5Sl9/VVEGlDyp+zm0m1cmeG5TOzLgdh4=
+github.com/onsi/ginkgo/v2 v2.32.1 h1:6tlvcDm/3sE8lGJbZ4+d4mO3RLy24/tQWOFzVSQNIfw=
+github.com/onsi/ginkgo/v2 v2.32.1/go.mod h1:+aXOY+vzZ5mu2iI2HpTZUPmM//oQfsNFX6gU9kNcA44=
+github.com/onsi/gomega v1.40.0 h1:Vtol0e1MghCD2ZVIilPDIg44XSL9l2QAn8ZNaljWcJc=
+github.com/onsi/gomega v1.40.0/go.mod h1:M/Uqpu/8qTjtzCLUA2zJHX9Iilrau25x1PdoSRbWh5A=
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
@@ -132,12 +126,10 @@ github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNw
github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE=
github.com/prometheus/common v0.67.5 h1:pIgK94WWlQt1WLwAC5j2ynLaBRDiinoAb86HZHTUGI4=
github.com/prometheus/common v0.67.5/go.mod h1:SjE/0MzDEEAyrdr5Gqc6G+sXI67maCxzaT3A2+HqjUw=
-github.com/prometheus/procfs v0.19.2 h1:zUMhqEW66Ex7OXIiDkll3tl9a1ZdilUOd/F6ZXw4Vws=
-github.com/prometheus/procfs v0.19.2/go.mod h1:M0aotyiemPhBCM0z5w87kL22CxfcH05ZpYlu+b4J7mw=
+github.com/prometheus/procfs v0.20.1 h1:XwbrGOIplXW/AU3YhIhLODXMJYyC1isLFfYCsTEycfc=
+github.com/prometheus/procfs v0.20.1/go.mod h1:o9EMBZGRyvDrSPH1RqdxhojkuXstoe4UlK79eF5TGGo=
github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
-github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
-github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU=
github.com/spf13/cobra v1.10.2/go.mod h1:7C1pvHqHw5A4vrJfjNwvOdzYu0Gml16OCs2GRiTUUS4=
@@ -154,42 +146,43 @@ github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64=
go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y=
-go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.65.0 h1:7iP2uCb7sGddAr30RRS6xjKy7AZ2JtTOPA3oolgVSw8=
-go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.65.0/go.mod h1:c7hN3ddxs/z6q9xwvfLPk+UHlWRQyaeR1LdgfL/66l0=
-go.opentelemetry.io/otel v1.41.0 h1:YlEwVsGAlCvczDILpUXpIpPSL/VPugt7zHThEMLce1c=
-go.opentelemetry.io/otel v1.41.0/go.mod h1:Yt4UwgEKeT05QbLwbyHXEwhnjxNO6D8L5PQP51/46dE=
+go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.67.0 h1:OyrsyzuttWTSur2qN/Lm0m2a8yqyIjUVBZcxFPuXq2o=
+go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.67.0/go.mod h1:C2NGBr+kAB4bk3xtMXfZ94gqFDtg/GkI7e9zqGh5Beg=
+go.opentelemetry.io/otel v1.44.0 h1:JjwHmHpA4iZ3wBxluu2fbbE7j4kqlE8jXyAyPXH7HqU=
+go.opentelemetry.io/otel v1.44.0/go.mod h1:BMgjTHL9WPRlRjL2oZCBTL4whCGtXch2H4BhOPIAyYc=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.40.0 h1:QKdN8ly8zEMrByybbQgv8cWBcdAarwmIPZ6FThrWXJs=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.40.0/go.mod h1:bTdK1nhqF76qiPoCCdyFIV+N/sRHYXYCTQc+3VCi3MI=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.40.0 h1:DvJDOPmSWQHWywQS6lKL+pb8s3gBLOZUtw4N+mavW1I=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.40.0/go.mod h1:EtekO9DEJb4/jRyN4v4Qjc2yA7AtfCBuz2FynRUWTXs=
-go.opentelemetry.io/otel/metric v1.41.0 h1:rFnDcs4gRzBcsO9tS8LCpgR0dxg4aaxWlJxCno7JlTQ=
-go.opentelemetry.io/otel/metric v1.41.0/go.mod h1:xPvCwd9pU0VN8tPZYzDZV/BMj9CM9vs00GuBjeKhJps=
-go.opentelemetry.io/otel/sdk v1.40.0 h1:KHW/jUzgo6wsPh9At46+h4upjtccTmuZCFAc9OJ71f8=
-go.opentelemetry.io/otel/sdk v1.40.0/go.mod h1:Ph7EFdYvxq72Y8Li9q8KebuYUr2KoeyHx0DRMKrYBUE=
-go.opentelemetry.io/otel/sdk/metric v1.40.0 h1:mtmdVqgQkeRxHgRv4qhyJduP3fYJRMX4AtAlbuWdCYw=
-go.opentelemetry.io/otel/sdk/metric v1.40.0/go.mod h1:4Z2bGMf0KSK3uRjlczMOeMhKU2rhUqdWNoKcYrtcBPg=
-go.opentelemetry.io/otel/trace v1.41.0 h1:Vbk2co6bhj8L59ZJ6/xFTskY+tGAbOnCtQGVVa9TIN0=
-go.opentelemetry.io/otel/trace v1.41.0/go.mod h1:U1NU4ULCoxeDKc09yCWdWe+3QoyweJcISEVa1RBzOis=
+go.opentelemetry.io/otel/metric v1.44.0 h1:1w0gILTcHdr3YI+ixLyjemwrVnsMURbTZFrSYCdDdmc=
+go.opentelemetry.io/otel/metric v1.44.0/go.mod h1:8O7hanEPBNgEMmybD3s2VBKcgWOCsA6tzHBPODAiquo=
+go.opentelemetry.io/otel/sdk v1.43.0 h1:pi5mE86i5rTeLXqoF/hhiBtUNcrAGHLKQdhg4h4V9Dg=
+go.opentelemetry.io/otel/sdk v1.43.0/go.mod h1:P+IkVU3iWukmiit/Yf9AWvpyRDlUeBaRg6Y+C58QHzg=
+go.opentelemetry.io/otel/sdk/metric v1.43.0 h1:S88dyqXjJkuBNLeMcVPRFXpRw2fuwdvfCGLEo89fDkw=
+go.opentelemetry.io/otel/sdk/metric v1.43.0/go.mod h1:C/RJtwSEJ5hzTiUz5pXF1kILHStzb9zFlIEe85bhj6A=
+go.opentelemetry.io/otel/trace v1.44.0 h1:jxF5CsGYCe74MCRx2X4g7WsY/VBKRqqpNvXlX/6gtIk=
+go.opentelemetry.io/otel/trace v1.44.0/go.mod h1:oLl1jrMQAVo6v3GAggN+1VH9VIz9iUSvW53sW1Q8PIE=
go.opentelemetry.io/proto/otlp v1.9.0 h1:l706jCMITVouPOqEnii2fIAuO3IVGBRPV5ICjceRb/A=
go.opentelemetry.io/proto/otlp v1.9.0/go.mod h1:xE+Cx5E/eEHw+ISFkwPLwCZefwVjY+pqKg1qcK03+/4=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
-go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc=
-go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
-go.yaml.in/yaml/v2 v2.4.3 h1:6gvOSjQoTB3vt1l+CU+tSyi/HOjfOjRLJ4YwYZGwRO0=
-go.yaml.in/yaml/v2 v2.4.3/go.mod h1:zSxWcmIDjOzPXpjlTTbAsKokqkDNAVtZO0WOMiT90s8=
-go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
+go.uber.org/zap v1.28.0 h1:IZzaP1Fv73/T/pBMLk4VutPl36uNC+OSUh3JLG3FIjo=
+go.uber.org/zap v1.28.0/go.mod h1:rDLpOi171uODNm/mxFcuYWxDsqWSAVkFdX4XojSKg/Q=
+go.yaml.in/yaml/v2 v2.4.4 h1:tuyd0P+2Ont/d6e2rl3be67goVK4R6deVxCUX5vyPaQ=
+go.yaml.in/yaml/v2 v2.4.4/go.mod h1:gMZqIpDtDqOfM0uNfy0SkpRhvUryYH0Z6wdMYcacYXQ=
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
+go.yaml.in/yaml/v3 v3.0.5 h1:N6y/pJk8buWs9NY5ERU2HSMfm+IuD/OtfdAnq6kESPw=
+go.yaml.in/yaml/v3 v3.0.5/go.mod h1:HVTZu1O7/Vkt2N+BFy8Zza+lnLsABggaTM2ZpNIGuKg=
golang.org/x/exp v0.0.0-20260112195511-716be5621a96 h1:Z/6YuSHTLOHfNFdb8zVZomZr7cqNgTJvA8+Qz75D8gU=
golang.org/x/exp v0.0.0-20260112195511-716be5621a96/go.mod h1:nzimsREAkjBCIEFtHiYkrJyT+2uy9YZJB7H1k68CXZU=
-golang.org/x/mod v0.38.0 h1:MECBjubtXD7yj4HrhIUcywNaGeNVUdfVnxmPajOk4yk=
-golang.org/x/mod v0.38.0/go.mod h1:V6Xz0pq8TQ3dGqVQ1FVHuelZpAL0uNhSkk9ogYP3c40=
+golang.org/x/mod v0.40.0 h1:hUv+3cXcdRHz08UmSiOob7sadHig73uo5bkXxQ/tvUs=
+golang.org/x/mod v0.40.0/go.mod h1:0/weTWkPWGBikyTWAX3dkjVztMmBA5hM0DH6BElSupE=
golang.org/x/net v0.58.0 h1:ynWG7rqYi4ccpTEuPZ2QGWHktVEM9DMCj9yzDE0Q7To=
golang.org/x/net v0.58.0/go.mod h1:YwCddHnFlT7eLQqVprV19OnhLGtc5xOKgE0RyqgfWAU=
-golang.org/x/oauth2 v0.34.0 h1:hqK/t4AKgbqWkdkcAeI8XLmbK+4m4G5YeQRrmiotGlw=
-golang.org/x/oauth2 v0.34.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA=
+golang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs=
+golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q=
golang.org/x/sync v0.22.0 h1:SZjpbeLmrCk4xhRSZFNZW5gFUeCeFgjekvI/+gfScek=
golang.org/x/sync v0.22.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
golang.org/x/sys v0.47.0 h1:o7XGOvZQCADBQQ4Y7VNq2dRWQR7JmOUW8Kxx4ZsNgWs=
@@ -198,68 +191,68 @@ golang.org/x/term v0.45.0 h1:NwWyBmoJCbfTHpxrWoZ9C6/VxOf7ic219I8xZZFdrf0=
golang.org/x/term v0.45.0/go.mod h1:9aqxs0blBcrm/n0L9QW0aRVD+ktan8ssZromtqJC43w=
golang.org/x/text v0.41.0 h1:vz/seA0lnX87Othu2f/0L24RcgrXD9/YFTSuGjj3rH8=
golang.org/x/text v0.41.0/go.mod h1:jvf1O8ajNzZqhSrQBPbutR/EB83Cc0CFrezNQIwbb5M=
-golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI=
-golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4=
-golang.org/x/tools v0.48.0 h1:3+hClM1aLL5mjMKm5ovokw9epgRXPuu2tILgismM6RE=
-golang.org/x/tools v0.48.0/go.mod h1:08xX0orndb/F7jJxGDicx061tyd5pcMto75YMAXr6lk=
+golang.org/x/time v0.15.0 h1:bbrp8t3bGUeFOx08pvsMYRTCVSMk89u4tKbNOZbp88U=
+golang.org/x/time v0.15.0/go.mod h1:Y4YMaQmXwGQZoFaVFk4YpCt4FLQMYKZe9oeV/f4MSno=
+golang.org/x/tools v0.49.0 h1:3NI7VXzL9+1WZD52Dx2ttoPwD5DWrFGpl9mFZDlmisI=
+golang.org/x/tools v0.49.0/go.mod h1:SJNXV9DBKT0UbdttsQjbfJlAE/q+y36++zo3uL3N0Oo=
gomodules.xyz/jsonpatch/v2 v2.5.0 h1:JELs8RLM12qJGXU4u/TO3V25KW8GreMKl9pdkk14RM0=
gomodules.xyz/jsonpatch/v2 v2.5.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY=
-gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk=
-gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E=
-google.golang.org/genproto/googleapis/api v0.0.0-20260202165425-ce8ad4cf556b h1:SGYyueaEovpqmWmtTvwtVgo638V/QFE2zlTCnRrR3jg=
-google.golang.org/genproto/googleapis/api v0.0.0-20260202165425-ce8ad4cf556b/go.mod h1:ZdbssH/1SOVnjnDlXzxDHK2MCidiqXtbYccJNzNYPEE=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20260202165425-ce8ad4cf556b h1:GZxXGdFaHX27ZSMHudWc4FokdD+xl8BC2UJm1OVIEzs=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20260202165425-ce8ad4cf556b/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ=
-google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE=
-google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ=
-google.golang.org/protobuf v1.36.12-0.20260120151049-f2248ac996af h1:+5/Sw3GsDNlEmu7TfklWKPdQ0Ykja5VEmq2i817+jbI=
-google.golang.org/protobuf v1.36.12-0.20260120151049-f2248ac996af/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
+gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4=
+gonum.org/v1/gonum v0.17.0/go.mod h1:El3tOrEuMpv2UdMrbNlKEh9vd86bmQ6vqIcDwxEOc1E=
+google.golang.org/genproto/googleapis/api v0.0.0-20260414002931-afd174a4e478 h1:yQugLulqltosq0B/f8l4w9VryjV+N/5gcW0jQ3N8Qec=
+google.golang.org/genproto/googleapis/api v0.0.0-20260414002931-afd174a4e478/go.mod h1:C6ADNqOxbgdUUeRTU+LCHDPB9ttAMCTff6auwCVa4uc=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20260610212136-7ab31c22f7ad h1:45WmJvIV6C2+O/jjLkPUH+F3aOj/1miDoU2DD0+NWbg=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20260610212136-7ab31c22f7ad/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8=
+google.golang.org/grpc v1.82.1 h1:NnAxzGRA0677vCa4BUkOAnO5+FfQqVl9iUXeD0IqcGE=
+google.golang.org/grpc v1.82.1/go.mod h1:yzTZ1TB1Z3SG+LIYaI+WiE8D5+PZ3ArnrSp8zF3+/ZA=
+google.golang.org/protobuf v1.36.12 h1:pJOKDDOyeXErUroCihFAd5LQuwXBSpVnKGrj5o/fwxc=
+google.golang.org/protobuf v1.36.12/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
-gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
-gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/evanphx/json-patch.v4 v4.13.0 h1:czT3CmqEaQ1aanPc5SdlgQrrEIb8w/wwCvWWnfEbYzo=
gopkg.in/evanphx/json-patch.v4 v4.13.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M=
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
-k8s.io/api v0.35.6 h1:phPzP79F3kcONsD2TzmDiITNCV6/1Z5U3CCEcjtsXzI=
-k8s.io/api v0.35.6/go.mod h1:GWKUaIp24fuDFigAgnhr9EJOKDqspnwPjYlpDca5B4U=
-k8s.io/apiextensions-apiserver v0.35.3 h1:2fQUhEO7P17sijylbdwt0nBdXP0TvHrHj0KeqHD8FiU=
-k8s.io/apiextensions-apiserver v0.35.3/go.mod h1:tK4Kz58ykRpwAEkXUb634HD1ZAegEElktz/B3jgETd8=
-k8s.io/apimachinery v0.35.6 h1:ASSpfmmsOArKb2Hsu8gGlIcbIcEMVTboI3FfsfYuQ8k=
-k8s.io/apimachinery v0.35.6/go.mod h1:NNi1taPOpep0jOj+oRha3mBJPqvi0hGdaV8TCqGQ+cc=
-k8s.io/apiserver v0.35.6 h1:VWYg2S0wlAmN3URFpVeuLa4PP2RCpTFg1nvlUHOy2C8=
-k8s.io/apiserver v0.35.6/go.mod h1:wajGSrXO9w+lx69jYq4SaE4Xxw5KxxwvVD1zbttYA2E=
-k8s.io/client-go v0.35.6 h1:qZQv9a5B4YlIpXhFBwsI9qPOOJC6Z8lk9lkEWmrmus8=
-k8s.io/client-go v0.35.6/go.mod h1:LOO6N1EhxdQAzYIZ/73cJVyb3gixrMY6ZDJcJ/ANfsY=
-k8s.io/component-base v0.35.6 h1:dTkck9uefkIrKn7wRCEYiDWNUvHd8UdwZCcVafmHgL4=
-k8s.io/component-base v0.35.6/go.mod h1:qcNKrspACsqR+vgUJXkWzwtgUGkURcnrus41o92jjpk=
+k8s.io/api v0.36.3 h1:NxB+05W2UGqXWFXcLO0RB5cnqnUPP5v5sVlaOH0Iz4w=
+k8s.io/api v0.36.3/go.mod h1:JzLQKqRHC5+I8RVj/lS3lCg0mg6nWI9Fo/Sk3ElxHzg=
+k8s.io/apiextensions-apiserver v0.36.3 h1:dPmOAPhwTtqb1bTxbFPsy18KHPhktQeO3WUPXunZIB0=
+k8s.io/apiextensions-apiserver v0.36.3/go.mod h1:KTXFqgXiuw2pRoL+Wpmttqc+up9Xt/GohadPWeLLOa4=
+k8s.io/apimachinery v0.36.3 h1:PkzMRBRG8joFD8EhCuQAtNPvJlxb82FwplP26HIzvAM=
+k8s.io/apimachinery v0.36.3/go.mod h1:cTSjBWgPe/6CQyBKzY/hDIRWCQQQeK0mfLbml0UYFHE=
+k8s.io/apiserver v0.36.3 h1:MGSg2SkdfuytiDEcRylT5mQFmmSsbx90XFUO67Y4bsQ=
+k8s.io/apiserver v0.36.3/go.mod h1:fVH7zv9EUNUA7Fl7LtDKh8aB9W7u1VQPSGtWV5SjUxg=
+k8s.io/client-go v0.36.3 h1:M4JdVzXxYcZk4fGpfDdYnxSwhLKWCFoQsHW6t+z8Hfg=
+k8s.io/client-go v0.36.3/go.mod h1:gcPwr0c87vjjG6HB6pWEqOeuYVoXSsREjzux2j6GF30=
+k8s.io/component-base v0.36.3 h1:vc/UFvPCkW0irPz84LAodAL1j3f4xktPM6dDJIEheAY=
+k8s.io/component-base v0.36.3/go.mod h1:hZbNFG+gCMl9EbykDGEu73feKP9/Cq6JsV4pTo9GTO8=
k8s.io/component-helpers v0.35.6 h1:AEGfqbEWjSM6Tkjtwslv2vQIGIiehvnAVoTDg74QQ0s=
k8s.io/component-helpers v0.35.6/go.mod h1:zog+ILMcmModWjoT1Vsom8sg8IW81mkzom2C/U1lgcs=
k8s.io/controller-manager v0.35.6 h1:NjgU2q6hrrHdT5/mn0tMOHYK5IB5QIVq9QnxUb4iDvU=
k8s.io/controller-manager v0.35.6/go.mod h1:Jq+7QZNSzGoiFaKnobvc0VszFHea6nJyI4U/wgiYOyo=
k8s.io/klog/v2 v2.140.0 h1:Tf+J3AH7xnUzZyVVXhTgGhEKnFqye14aadWv7bzXdzc=
k8s.io/klog/v2 v2.140.0/go.mod h1:o+/RWfJ6PwpnFn7OyAG3QnO47BFsymfEfrz6XyYSSp0=
-k8s.io/kube-openapi v0.0.0-20260317180543-43fb72c5454a h1:xCeOEAOoGYl2jnJoHkC3hkbPJgdATINPMAxaynU2Ovg=
-k8s.io/kube-openapi v0.0.0-20260317180543-43fb72c5454a/go.mod h1:uGBT7iTA6c6MvqUvSXIaYZo9ukscABYi2btjhvgKGZ0=
+k8s.io/kube-openapi v0.0.0-20260721132016-d427ff9ee9ad h1:oXImqH8mQNk7PmvzKhmN3ddJoY6OnyM225MXwGHPm0A=
+k8s.io/kube-openapi v0.0.0-20260721132016-d427ff9ee9ad/go.mod h1:0/mqHCVhlumdJ3BhCfnjSZQE037nAhNodh1/hK0T8/I=
k8s.io/kubelet v0.32.2 h1:WFTSYdt3BB1aTApDuKNI16x/4MYqqX8WBBBBh3KupDg=
k8s.io/kubelet v0.32.2/go.mod h1:cC1ms5RS+lu0ckVr6AviCQXHLSPKEBC3D5oaCBdTGkI=
-k8s.io/kubernetes v1.35.6 h1:Kh9V2tfdF+yNVZ1UX5lVfd1zNpa94vdIkfhyAmWXzQI=
-k8s.io/kubernetes v1.35.6/go.mod h1:fPfnQs8GtfrLQ+KuOcpvwQ+mV17jVcgdvPL6ZHxKp10=
-k8s.io/utils v0.0.0-20260210185600-b8788abfbbc2 h1:AZYQSJemyQB5eRxqcPky+/7EdBj0xi3g0ZcxxJ7vbWU=
-k8s.io/utils v0.0.0-20260210185600-b8788abfbbc2/go.mod h1:xDxuJ0whA3d0I4mf/C4ppKHxXynQ+fxnkmQH0vTHnuk=
+k8s.io/kubernetes v1.36.3 h1:qDQdoMiluAE2Eab6Fa52YV+WjiGz9mZFFoagEA6cI+o=
+k8s.io/kubernetes v1.36.3/go.mod h1:6oChkQeI7Yf6lV9lFpSdRzODdbY/ECp/4zUeBk8ONaw=
+k8s.io/streaming v0.36.3 h1:9rAaqBk0C0Pc7+/fqGekj07NV+/Xrew58p647A0JT8w=
+k8s.io/streaming v0.36.3/go.mod h1:z6fV3D+NVkoeqRMtWwlUZK6U17SY/LqNzOxWL6GyR/s=
+k8s.io/utils v0.0.0-20260707023825-cf1189d6abe3 h1:jVkFFVfXdXP74B/zbO3hM3hpSFD0xvhQ5U686DPurkE=
+k8s.io/utils v0.0.0-20260707023825-cf1189d6abe3/go.mod h1:M2s5JB1lIYP3jzZdorPLHXIPJzt9vv2muW5a6L9DtNM=
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.34.0 h1:hSfpvjjTQXQY2Fol2CS0QHMNs/WI1MOSGzCm1KhM5ec=
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.34.0/go.mod h1:Ve9uj1L+deCXFrPOk1LpFXqTg7LCFzFso6PA48q/XZw=
-sigs.k8s.io/controller-runtime v0.23.3 h1:VjB/vhoPoA9l1kEKZHBMnQF33tdCLQKJtydy4iqwZ80=
-sigs.k8s.io/controller-runtime v0.23.3/go.mod h1:B6COOxKptp+YaUT5q4l6LqUJTRpizbgf9KSRNdQGns0=
-sigs.k8s.io/gateway-api v1.1.0 h1:DsLDXCi6jR+Xz8/xd0Z1PYl2Pn0TyaFMOPPZIj4inDM=
-sigs.k8s.io/gateway-api v1.1.0/go.mod h1:ZH4lHrL2sDi0FHZ9jjneb8kKnGzFWyrTya35sWUTrRs=
+sigs.k8s.io/controller-runtime v0.24.1 h1:miPEwrmirImAvgME1L9qebGHrOnGJoVmVdtOU9fRfo4=
+sigs.k8s.io/controller-runtime v0.24.1/go.mod h1:vFkfY5fGt5xAC/sKb8IBFKgWPNKG9OUG29dR8Y2wImw=
+sigs.k8s.io/gateway-api v1.6.0 h1:735YBRj5NXFrOGX0GoSjwzUIzbz8kiEOfADsqHFmHgE=
+sigs.k8s.io/gateway-api v1.6.0/go.mod h1:FVfx3t389ybeXOqvDghLbdvJdSCfI/PReqCUI3lu3mY=
sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 h1:IpInykpT6ceI+QxKBbEflcR5EXP7sU1kvOlxwZh5txg=
sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg=
sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU=
sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY=
-sigs.k8s.io/structured-merge-diff/v6 v6.3.2 h1:kwVWMx5yS1CrnFWA/2QHyRVJ8jM6dBA80uLmm0wJkk8=
-sigs.k8s.io/structured-merge-diff/v6 v6.3.2/go.mod h1:M3W8sfWvn2HhQDIbGWj3S099YozAsymCo/wrT5ohRUE=
+sigs.k8s.io/structured-merge-diff/v6 v6.4.2 h1:qdOxHwrl2Kaag1aQEarlYcOA9vSyGCp3CIki3aW8c4Q=
+sigs.k8s.io/structured-merge-diff/v6 v6.4.2/go.mod h1:M3W8sfWvn2HhQDIbGWj3S099YozAsymCo/wrT5ohRUE=
sigs.k8s.io/yaml v1.6.0 h1:G8fkbMSAFqgEFgh4b1wmtzDnioxFCUgTZhlbj5P9QYs=
sigs.k8s.io/yaml v1.6.0/go.mod h1:796bPqUfzR/0jLAl6XjHl3Ck7MiyVv8dbTdyT3/pMf4=
diff --git a/config/crd/bases/operator.openshift.io_externalsecretsconfigs.yaml b/config/crd/bases/operator.openshift.io_externalsecretsconfigs.yaml
index 4dcfb2135..00a94347b 100644
--- a/config/crd/bases/operator.openshift.io_externalsecretsconfigs.yaml
+++ b/config/crd/bases/operator.openshift.io_externalsecretsconfigs.yaml
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
- controller-gen.kubebuilder.io/version: v0.19.0
+ controller-gen.kubebuilder.io/version: v0.21.0
labels:
app.kubernetes.io/name: externalsecretsconfig
app.kubernetes.io/part-of: external-secrets-operator
diff --git a/config/crd/bases/operator.openshift.io_externalsecretsmanagers.yaml b/config/crd/bases/operator.openshift.io_externalsecretsmanagers.yaml
index bd0a2fde3..4309f2e69 100644
--- a/config/crd/bases/operator.openshift.io_externalsecretsmanagers.yaml
+++ b/config/crd/bases/operator.openshift.io_externalsecretsmanagers.yaml
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
- controller-gen.kubebuilder.io/version: v0.19.0
+ controller-gen.kubebuilder.io/version: v0.21.0
labels:
app.kubernetes.io/name: externalsecretsmanager
app.kubernetes.io/part-of: external-secrets-operator
diff --git a/config/manager/manager.yaml b/config/manager/manager.yaml
index 384e24d35..633c6ff6a 100644
--- a/config/manager/manager.yaml
+++ b/config/manager/manager.yaml
@@ -80,7 +80,7 @@ spec:
- name: OPERATOR_NAME
value: external-secrets-operator
- name: OPERATOR_IMAGE_VERSION
- value: 1.2.0
+ value: 1.3.0
- name: RELATED_IMAGE_EXTERNAL_SECRETS
value: ghcr.io/external-secrets/external-secrets:v2.5.0
- name: OPERAND_EXTERNAL_SECRETS_IMAGE_VERSION
diff --git a/config/manifests/bases/openshift-external-secrets-operator.clusterserviceversion.yaml b/config/manifests/bases/openshift-external-secrets-operator.clusterserviceversion.yaml
index 0f6d82b3b..c061c39da 100644
--- a/config/manifests/bases/openshift-external-secrets-operator.clusterserviceversion.yaml
+++ b/config/manifests/bases/openshift-external-secrets-operator.clusterserviceversion.yaml
@@ -18,7 +18,7 @@ metadata:
features.operators.openshift.io/token-auth-aws: "false"
features.operators.openshift.io/token-auth-azure: "false"
features.operators.openshift.io/token-auth-gcp: "false"
- olm.skipRange: '>=1.1.0 <1.2.0'
+ olm.skipRange: '>=1.2.0 <1.3.0'
operator.openshift.io/uninstall-message: The External Secrets Operator for Red
Hat OpenShift will be removed from external-secrets-operator namespace. If your
Operator configured any off-cluster resources, these will continue to run and
@@ -38,7 +38,7 @@ metadata:
operatorframework.io/arch.ppc64le: supported
operatorframework.io/arch.s390x: supported
operatorframework.io/os.linux: supported
- name: openshift-external-secrets-operator.v1.1.0
+ name: openshift-external-secrets-operator.v1.3.0
namespace: placeholder
spec:
apiservicedefinitions: {}
@@ -240,5 +240,5 @@ spec:
minKubeVersion: 1.31.0
provider:
name: Red Hat, Inc.
- replaces: external-secrets-operator.v1.1.0
- version: 1.2.0
+ replaces: external-secrets-operator.v1.2.0
+ version: 1.3.0
diff --git a/docs/api_reference.md b/docs/api_reference.md
index a9851a1b6..8c2333add 100644
--- a/docs/api_reference.md
+++ b/docs/api_reference.md
@@ -29,14 +29,14 @@ _Appears in:_
| Field | Description | Default | Validation |
| --- | --- | --- | --- |
-| `logLevel` _integer_ | logLevel supports value range as per [Kubernetes logging guidelines](https://github.com/kubernetes/community/blob/master/contributors/devel/sig-instrumentation/logging.md#what-method-to-use). | 1 | Maximum: 5 Minimum: 1 |
-| `resources` _[ResourceRequirements](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.32/#resourcerequirements-v1-core)_ | resources is for defining the resource requirements. Cannot be updated. ref: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ | | |
-| `affinity` _[Affinity](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.32/#affinity-v1-core)_ | affinity is for setting scheduling affinity rules. ref: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/ | | |
-| `tolerations` _[Toleration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.32/#toleration-v1-core) array_ | tolerations is for setting the pod tolerations. ref: https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/ This field can have a maximum of 50 entries. | | MaxItems: 50 MinItems: 0 |
-| `nodeSelector` _object (keys:string, values:string)_ | nodeSelector is for defining the scheduling criteria using node labels. ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ This field can have a maximum of 50 entries. | | MaxProperties: 50 MinProperties: 0 |
-| `proxy` _[ProxyConfig](#proxyconfig)_ | proxy is for setting the proxy configurations which will be made available in operand containers managed by the operator as environment variables. | | |
-| `operatingNamespace` _string_ | operatingNamespace is for restricting the external-secrets operations to the provided namespace. When configured `ClusterSecretStore` and `ClusterExternalSecret` are implicitly disabled. | | MaxLength: 63 MinLength: 1 |
-| `webhookConfig` _[WebhookConfig](#webhookconfig)_ | webhookConfig is for configuring external-secrets webhook specifics. | | |
+| `logLevel` _integer_ | logLevel supports value range as per [Kubernetes logging guidelines](https://github.com/kubernetes/community/blob/master/contributors/devel/sig-instrumentation/logging.md#what-method-to-use). | 1 | Maximum: 5 Minimum: 1 Optional: \{\} |
+| `resources` _[ResourceRequirements](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.32/#resourcerequirements-v1-core)_ | resources is for defining the resource requirements. Cannot be updated. ref: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ | | Optional: \{\} |
+| `affinity` _[Affinity](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.32/#affinity-v1-core)_ | affinity is for setting scheduling affinity rules. ref: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/ | | Optional: \{\} |
+| `tolerations` _[Toleration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.32/#toleration-v1-core) array_ | tolerations is for setting the pod tolerations. ref: https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/ This field can have a maximum of 50 entries. | | MaxItems: 50 MinItems: 0 Optional: \{\} |
+| `nodeSelector` _object (keys:string, values:string)_ | nodeSelector is for defining the scheduling criteria using node labels. ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ This field can have a maximum of 50 entries. | | MaxProperties: 50 MinProperties: 0 Optional: \{\} |
+| `proxy` _[ProxyConfig](#proxyconfig)_ | proxy is for setting the proxy configurations which will be made available in operand containers managed by the operator as environment variables. | | Optional: \{\} |
+| `operatingNamespace` _string_ | operatingNamespace is for restricting the external-secrets operations to the provided namespace. When configured `ClusterSecretStore` and `ClusterExternalSecret` are implicitly disabled. | | MaxLength: 63 MinLength: 1 Optional: \{\} |
+| `webhookConfig` _[WebhookConfig](#webhookconfig)_ | webhookConfig is for configuring external-secrets webhook specifics. | | Optional: \{\} |
#### BitwardenSecretManagerProvider
@@ -52,8 +52,8 @@ _Appears in:_
| Field | Description | Default | Validation |
| --- | --- | --- | --- |
-| `mode` _[Mode](#mode)_ | mode indicates bitwarden secrets manager provider state, which can be indicated by setting Enabled or Disabled. Enabled: Enables the Bitwarden provider plugin. The operator will ensure the plugin is deployed and its state is synchronized. Disabled: Disables reconciliation of the Bitwarden provider plugin. The plugin and its resources will remain in their current state and will not be managed by the operator. | Disabled | Enum: [Enabled Disabled] |
-| `secretRef` _SecretReference_ | secretRef is the Kubernetes secret containing the TLS key pair to be used for the bitwarden server. The issuer in CertManagerConfig will be utilized to generate the required certificate if the secret reference is not provided and CertManagerConfig is configured. The key names in secret for certificate must be `tls.crt`, for private key must be `tls.key` and for CA certificate key name must be `ca.crt`. | | |
+| `mode` _[Mode](#mode)_ | mode indicates bitwarden secrets manager provider state, which can be indicated by setting Enabled or Disabled. Enabled: Enables the Bitwarden provider plugin. The operator will ensure the plugin is deployed and its state is synchronized. Disabled: Disables reconciliation of the Bitwarden provider plugin. The plugin and its resources will remain in their current state and will not be managed by the operator. | Disabled | Enum: [Enabled Disabled] Optional: \{\} |
+| `secretRef` _SecretReference_ | secretRef is the Kubernetes secret containing the TLS key pair to be used for the bitwarden server. The issuer in CertManagerConfig will be utilized to generate the required certificate if the secret reference is not provided and CertManagerConfig is configured. The key names in secret for certificate must be `tls.crt`, for private key must be `tls.key` and for CA certificate key name must be `ca.crt`. | | Optional: \{\} |
#### CertManagerConfig
@@ -69,11 +69,11 @@ _Appears in:_
| Field | Description | Default | Validation |
| --- | --- | --- | --- |
-| `mode` _[Mode](#mode)_ | mode indicates whether to use cert-manager for certificate management, instead of built-in cert-controller. Enabled: Makes use of cert-manager for obtaining the certificates for webhook server and other components. Disabled: Makes use of in-built cert-controller for obtaining the certificates for webhook server, which is the default behavior. This field is immutable once set. | | Enum: [Enabled Disabled] |
-| `injectAnnotations` _string_ | injectAnnotations is for adding the `cert-manager.io/inject-ca-from` annotation to the webhooks and CRDs to automatically setup webhook to use the cert-manager CA. This requires CA Injector to be enabled in cert-manager. Use `true` or `false` to indicate the preference. This field is immutable once set. | false | Enum: [true false] |
-| `issuerRef` _ObjectReference_ | issuerRef contains details of the referenced object used for obtaining certificates. When `issuerRef.Kind` is `Issuer`, it must exist in the `external-secrets` namespace. This field is immutable once set. | | |
-| `certificateDuration` _[Duration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.32/#duration-v1-meta)_ | certificateDuration is the validity period of the webhook certificate. | 8760h | |
-| `certificateRenewBefore` _[Duration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.32/#duration-v1-meta)_ | certificateRenewBefore is the ahead time to renew the webhook certificate before expiry. | 30m | |
+| `mode` _[Mode](#mode)_ | mode indicates whether to use cert-manager for certificate management, instead of built-in cert-controller. Enabled: Makes use of cert-manager for obtaining the certificates for webhook server and other components. Disabled: Makes use of in-built cert-controller for obtaining the certificates for webhook server, which is the default behavior. This field is immutable once set. | | Enum: [Enabled Disabled] Required: \{\} |
+| `injectAnnotations` _string_ | injectAnnotations is for adding the `cert-manager.io/inject-ca-from` annotation to the webhooks and CRDs to automatically setup webhook to use the cert-manager CA. This requires CA Injector to be enabled in cert-manager. Use `true` or `false` to indicate the preference. This field is immutable once set. | false | Enum: [true false] Optional: \{\} |
+| `issuerRef` _ObjectReference_ | issuerRef contains details of the referenced object used for obtaining certificates. When `issuerRef.Kind` is `Issuer`, it must exist in the `external-secrets` namespace. This field is immutable once set. | | Optional: \{\} |
+| `certificateDuration` _[Duration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.32/#duration-v1-meta)_ | certificateDuration is the validity period of the webhook certificate. | 8760h | Optional: \{\} |
+| `certificateRenewBefore` _[Duration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.32/#duration-v1-meta)_ | certificateRenewBefore is the ahead time to renew the webhook certificate before expiry. | 30m | Optional: \{\} |
#### CertProvidersConfig
@@ -89,7 +89,7 @@ _Appears in:_
| Field | Description | Default | Validation |
| --- | --- | --- | --- |
-| `certManager` _[CertManagerConfig](#certmanagerconfig)_ | certManager is for configuring cert-manager provider specifics. | | |
+| `certManager` _[CertManagerConfig](#certmanagerconfig)_ | certManager is for configuring cert-manager provider specifics. | | Optional: \{\} |
#### CommonConfigs
@@ -106,12 +106,12 @@ _Appears in:_
| Field | Description | Default | Validation |
| --- | --- | --- | --- |
-| `logLevel` _integer_ | logLevel supports value range as per [Kubernetes logging guidelines](https://github.com/kubernetes/community/blob/master/contributors/devel/sig-instrumentation/logging.md#what-method-to-use). | 1 | Maximum: 5 Minimum: 1 |
-| `resources` _[ResourceRequirements](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.32/#resourcerequirements-v1-core)_ | resources is for defining the resource requirements. Cannot be updated. ref: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ | | |
-| `affinity` _[Affinity](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.32/#affinity-v1-core)_ | affinity is for setting scheduling affinity rules. ref: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/ | | |
-| `tolerations` _[Toleration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.32/#toleration-v1-core) array_ | tolerations is for setting the pod tolerations. ref: https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/ This field can have a maximum of 50 entries. | | MaxItems: 50 MinItems: 0 |
-| `nodeSelector` _object (keys:string, values:string)_ | nodeSelector is for defining the scheduling criteria using node labels. ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ This field can have a maximum of 50 entries. | | MaxProperties: 50 MinProperties: 0 |
-| `proxy` _[ProxyConfig](#proxyconfig)_ | proxy is for setting the proxy configurations which will be made available in operand containers managed by the operator as environment variables. | | |
+| `logLevel` _integer_ | logLevel supports value range as per [Kubernetes logging guidelines](https://github.com/kubernetes/community/blob/master/contributors/devel/sig-instrumentation/logging.md#what-method-to-use). | 1 | Maximum: 5 Minimum: 1 Optional: \{\} |
+| `resources` _[ResourceRequirements](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.32/#resourcerequirements-v1-core)_ | resources is for defining the resource requirements. Cannot be updated. ref: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ | | Optional: \{\} |
+| `affinity` _[Affinity](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.32/#affinity-v1-core)_ | affinity is for setting scheduling affinity rules. ref: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/ | | Optional: \{\} |
+| `tolerations` _[Toleration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.32/#toleration-v1-core) array_ | tolerations is for setting the pod tolerations. ref: https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/ This field can have a maximum of 50 entries. | | MaxItems: 50 MinItems: 0 Optional: \{\} |
+| `nodeSelector` _object (keys:string, values:string)_ | nodeSelector is for defining the scheduling criteria using node labels. ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ This field can have a maximum of 50 entries. | | MaxProperties: 50 MinProperties: 0 Optional: \{\} |
+| `proxy` _[ProxyConfig](#proxyconfig)_ | proxy is for setting the proxy configurations which will be made available in operand containers managed by the operator as environment variables. | | Optional: \{\} |
#### ComponentConfig
@@ -127,9 +127,9 @@ _Appears in:_
| Field | Description | Default | Validation |
| --- | --- | --- | --- |
-| `componentName` _[ComponentName](#componentname)_ | componentName identifies which external-secrets component this configuration applies to. Valid component names: ExternalSecretsCoreController, Webhook, CertController, BitwardenSDKServer. | | Enum: [ExternalSecretsCoreController Webhook CertController BitwardenSDKServer] |
-| `deploymentConfigs` _[DeploymentConfig](#deploymentconfig)_ | deploymentConfigs specifies overrides for the Kubernetes Deployment resource of this component. | | |
-| `overrideEnv` _[EnvVar](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.32/#envvar-v1-core) array_ | overrideEnv specifies custom environment variables for this component's container. These are merged with operator-managed environment variables, with user-defined values taking precedence. Names starting with 'KUBERNETES_' or 'EXTERNAL_SECRETS_' are reserved prefixes and will be rejected. The exact names 'HOSTNAME', 'SSL_CERT_DIR', and 'SSL_CERT_FILE' are also reserved. | | MaxItems: 50 |
+| `componentName` _[ComponentName](#componentname)_ | componentName identifies which external-secrets component this configuration applies to. Valid component names: ExternalSecretsCoreController, Webhook, CertController, BitwardenSDKServer. | | Enum: [ExternalSecretsCoreController Webhook CertController BitwardenSDKServer] Required: \{\} |
+| `deploymentConfigs` _[DeploymentConfig](#deploymentconfig)_ | deploymentConfigs specifies overrides for the Kubernetes Deployment resource of this component. | | Optional: \{\} |
+| `overrideEnv` _[EnvVar](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.32/#envvar-v1-core) array_ | overrideEnv specifies custom environment variables for this component's container. These are merged with operator-managed environment variables, with user-defined values taking precedence. Names starting with 'KUBERNETES_' or 'EXTERNAL_SECRETS_' are reserved prefixes and will be rejected. The exact names 'HOSTNAME', 'SSL_CERT_DIR', and 'SSL_CERT_FILE' are also reserved. | | MaxItems: 50 Optional: \{\} |
#### ComponentName
@@ -165,9 +165,9 @@ _Appears in:_
| Field | Description | Default | Validation |
| --- | --- | --- | --- |
-| `type` _string_ | type of the condition | | |
-| `status` _[ConditionStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.32/#conditionstatus-v1-meta)_ | status of the condition | | |
-| `message` _string_ | message provides details about the state. | | |
+| `type` _string_ | type of the condition | | Required: \{\} |
+| `status` _[ConditionStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.32/#conditionstatus-v1-meta)_ | status of the condition | | Optional: \{\} |
+| `message` _string_ | message provides details about the state. | | Optional: \{\} |
#### ConditionalStatus
@@ -183,7 +183,7 @@ _Appears in:_
| Field | Description | Default | Validation |
| --- | --- | --- | --- |
-| `conditions` _[Condition](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.32/#condition-v1-meta) array_ | conditions holds information of the current state of deployment. | | |
+| `conditions` _[Condition](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.32/#condition-v1-meta) array_ | conditions holds information of the current state of deployment. | | Optional: \{\} |
#### ConfigMapKeyReference
@@ -199,8 +199,8 @@ _Appears in:_
| Field | Description | Default | Validation |
| --- | --- | --- | --- |
-| `name` _string_ | name of the ConfigMap resource being referred to. | | MaxLength: 253 MinLength: 1 |
-| `key` _string_ | key is the specific key in the ConfigMap to be utilized. When omitted, defaults to "ca-bundle.crt". | ca-bundle.crt | MaxLength: 253 MinLength: 1 Pattern: `^[-._a-zA-Z0-9]+$` |
+| `name` _string_ | name of the ConfigMap resource being referred to. | | MaxLength: 253 MinLength: 1 Required: \{\} |
+| `key` _string_ | key is the specific key in the ConfigMap to be utilized. When omitted, defaults to "ca-bundle.crt". | ca-bundle.crt | MaxLength: 253 MinLength: 1 Pattern: `^[-._a-zA-Z0-9]+$` Optional: \{\} |
#### ControllerConfig
@@ -216,12 +216,12 @@ _Appears in:_
| Field | Description | Default | Validation |
| --- | --- | --- | --- |
-| `certProvider` _[CertProvidersConfig](#certprovidersconfig)_ | certProvider is for defining the configuration for certificate providers used to manage TLS certificates for webhook and plugins. | | |
-| `labels` _object (keys:string, values:string)_ | labels to apply to all resources created for the external-secrets operand deployment. This field can have a maximum of 20 entries. | | MaxProperties: 20 MinProperties: 0 |
-| `annotations` _object (keys:string, values:string)_ | annotations are for adding custom annotations to all the resources created for external-secrets deployment. The annotations are merged with any default annotations set by the operator. User-specified annotations take precedence over defaults in case of conflicts. Annotation keys containing domains `kubernetes.io/`, `openshift.io/`, `cert-manager.io/` or `k8s.io/` (including subdomains like `*.kubernetes.io/`) are not allowed. | | MaxProperties: 20 MinProperties: 0 |
-| `networkPolicies` _[NetworkPolicy](#networkpolicy) array_ | networkPolicies specifies the list of network policy configurations to be applied to external-secrets pods. Each entry allows specifying a name for the generated NetworkPolicy object, along with its full Kubernetes NetworkPolicy definition. The operator prepends "eso-user-" to the provided name when creating the Kubernetes object. If this field is not provided, external-secrets components will be isolated with deny-all network policies, which will prevent proper operation. | | MaxItems: 50 MinItems: 0 |
-| `componentConfigs` _[ComponentConfig](#componentconfig) array_ | componentConfigs allows specifying deployment-level configuration overrides for individual external-secrets components. This field enables fine-grained control over deployment settings for each component independently. Each component can only have one configuration entry. | | MaxItems: 4 MinItems: 0 |
-| `trustedCABundle` _[ConfigMapKeyReference](#configmapkeyreference)_ | trustedCABundle references a ConfigMap containing PEM-encoded CA certificates for the external-secrets core controller to trust when making outbound TLS connections. If specified, this bundle is used for all outbound TLS traffic, including connections to external secret management systems and configured proxies. The ConfigMap must exist in the external-secrets operand namespace and must not carry the CNO inject-trusted-cabundle label when proxy is configured. When omitted, external providers use standard system certificates. When proxy is configured, proxy TLS connections use the operator-managed OpenShift trusted CA bundle injected by the Cluster Network Operator. | | |
+| `certProvider` _[CertProvidersConfig](#certprovidersconfig)_ | certProvider is for defining the configuration for certificate providers used to manage TLS certificates for webhook and plugins. | | Optional: \{\} |
+| `labels` _object (keys:string, values:string)_ | labels to apply to all resources created for the external-secrets operand deployment. This field can have a maximum of 20 entries. | | MaxProperties: 20 MinProperties: 0 Optional: \{\} |
+| `annotations` _object (keys:string, values:string)_ | annotations are for adding custom annotations to all the resources created for external-secrets deployment. The annotations are merged with any default annotations set by the operator. User-specified annotations take precedence over defaults in case of conflicts. Annotation keys containing domains `kubernetes.io/`, `openshift.io/`, `cert-manager.io/` or `k8s.io/` (including subdomains like `*.kubernetes.io/`) are not allowed. | | MaxProperties: 20 MinProperties: 0 Optional: \{\} |
+| `networkPolicies` _[NetworkPolicy](#networkpolicy) array_ | networkPolicies specifies the list of network policy configurations to be applied to external-secrets pods. Each entry allows specifying a name for the generated NetworkPolicy object, along with its full Kubernetes NetworkPolicy definition. The operator prepends "eso-user-" to the provided name when creating the Kubernetes object. If this field is not provided, external-secrets components will be isolated with deny-all network policies, which will prevent proper operation. | | MaxItems: 50 MinItems: 0 Optional: \{\} |
+| `componentConfigs` _[ComponentConfig](#componentconfig) array_ | componentConfigs allows specifying deployment-level configuration overrides for individual external-secrets components. This field enables fine-grained control over deployment settings for each component independently. Each component can only have one configuration entry. | | MaxItems: 4 MinItems: 0 Optional: \{\} |
+| `trustedCABundle` _[ConfigMapKeyReference](#configmapkeyreference)_ | trustedCABundle references a ConfigMap containing PEM-encoded CA certificates for the external-secrets core controller to trust when making outbound TLS connections. If specified, this bundle is used for all outbound TLS traffic, including connections to external secret management systems and configured proxies. The ConfigMap must exist in the external-secrets operand namespace and must not carry the CNO inject-trusted-cabundle label when proxy is configured. When omitted, external providers use standard system certificates. When proxy is configured, proxy TLS connections use the operator-managed OpenShift trusted CA bundle injected by the Cluster Network Operator. | | Optional: \{\} |
#### ControllerStatus
@@ -237,9 +237,9 @@ _Appears in:_
| Field | Description | Default | Validation |
| --- | --- | --- | --- |
-| `name` _string_ | name of the controller for which the observed condition is recorded. | | |
+| `name` _string_ | name of the controller for which the observed condition is recorded. | | Required: \{\} |
| `conditions` _[Condition](#condition) array_ | conditions holds information of the current state of the external-secrets-operator controllers. | | |
-| `observedGeneration` _integer_ | observedGeneration represents the .metadata.generation on the observed resource. | | Minimum: 0 |
+| `observedGeneration` _integer_ | observedGeneration represents the .metadata.generation on the observed resource. | | Minimum: 0 Optional: \{\} |
#### DeploymentConfig
@@ -255,7 +255,7 @@ _Appears in:_
| Field | Description | Default | Validation |
| --- | --- | --- | --- |
-| `revisionHistoryLimit` _integer_ | revisionHistoryLimit specifies the number of old ReplicaSets to retain for rollback purposes. This allows rolling back to previous deployment versions using 'kubectl rollout undo'. Must be at least 1 to ensure rollback capability. Maximum value is 50 to limit resource usage. If not specified, defaults to 10. | 10 | Maximum: 50 Minimum: 1 |
+| `revisionHistoryLimit` _integer_ | revisionHistoryLimit specifies the number of old ReplicaSets to retain for rollback purposes. This allows rolling back to previous deployment versions using 'kubectl rollout undo'. Must be at least 1 to ensure rollback capability. Maximum value is 50 to limit resource usage. If not specified, defaults to 10. | 10 | Maximum: 50 Minimum: 1 Optional: \{\} |
#### ExternalSecretsConfig
@@ -276,9 +276,9 @@ _Appears in:_
| --- | --- | --- | --- |
| `apiVersion` _string_ | `operator.openshift.io/v1alpha1` | | |
| `kind` _string_ | `ExternalSecretsConfig` | | |
-| `metadata` _[ObjectMeta](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.32/#objectmeta-v1-meta)_ | Refer to Kubernetes API documentation for fields of `metadata`. | | |
-| `spec` _[ExternalSecretsConfigSpec](#externalsecretsconfigspec)_ | spec is the specification of the desired behavior of the ExternalSecretsConfig. | | |
-| `status` _[ExternalSecretsConfigStatus](#externalsecretsconfigstatus)_ | status is the most recently observed status of the ExternalSecretsConfig. | | |
+| `metadata` _[ObjectMeta](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.32/#objectmeta-v1-meta)_ | Refer to Kubernetes API documentation for fields of `metadata`. | | Required: \{\} |
+| `spec` _[ExternalSecretsConfigSpec](#externalsecretsconfigspec)_ | spec is the specification of the desired behavior of the ExternalSecretsConfig. | | Optional: \{\} |
+| `status` _[ExternalSecretsConfigStatus](#externalsecretsconfigstatus)_ | status is the most recently observed status of the ExternalSecretsConfig. | | Optional: \{\} |
#### ExternalSecretsConfigList
@@ -312,9 +312,9 @@ _Appears in:_
| Field | Description | Default | Validation |
| --- | --- | --- | --- |
-| `appConfig` _[ApplicationConfig](#applicationconfig)_ | appConfig is for specifying the configurations for the `external-secrets` operand. | | |
-| `plugins` _[PluginsConfig](#pluginsconfig)_ | plugins is for configuring the optional provider plugins. | | |
-| `controllerConfig` _[ControllerConfig](#controllerconfig)_ | controllerConfig is for specifying the configurations for the controller to use while installing the `external-secrets` operand and the plugins. | | |
+| `appConfig` _[ApplicationConfig](#applicationconfig)_ | appConfig is for specifying the configurations for the `external-secrets` operand. | | Optional: \{\} |
+| `plugins` _[PluginsConfig](#pluginsconfig)_ | plugins is for configuring the optional provider plugins. | | Optional: \{\} |
+| `controllerConfig` _[ControllerConfig](#controllerconfig)_ | controllerConfig is for specifying the configurations for the controller to use while installing the `external-secrets` operand and the plugins. | | Optional: \{\} |
#### ExternalSecretsConfigStatus
@@ -330,9 +330,9 @@ _Appears in:_
| Field | Description | Default | Validation |
| --- | --- | --- | --- |
-| `conditions` _[Condition](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.32/#condition-v1-meta) array_ | conditions holds information of the current state of deployment. | | |
-| `externalSecretsImage` _string_ | externalSecretsImage is the name of the image and the tag used for deploying external-secrets. | | |
-| `bitwardenSDKServerImage` _string_ | bitwardenSDKServerImage is the name of the image and the tag used for deploying bitwarden-sdk-server. | | |
+| `conditions` _[Condition](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.32/#condition-v1-meta) array_ | conditions holds information of the current state of deployment. | | Optional: \{\} |
+| `externalSecretsImage` _string_ | externalSecretsImage is the name of the image and the tag used for deploying external-secrets. | | Optional: \{\} |
+| `bitwardenSDKServerImage` _string_ | bitwardenSDKServerImage is the name of the image and the tag used for deploying bitwarden-sdk-server. | | Optional: \{\} |
#### ExternalSecretsManager
@@ -354,9 +354,9 @@ _Appears in:_
| --- | --- | --- | --- |
| `apiVersion` _string_ | `operator.openshift.io/v1alpha1` | | |
| `kind` _string_ | `ExternalSecretsManager` | | |
-| `metadata` _[ObjectMeta](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.32/#objectmeta-v1-meta)_ | Refer to Kubernetes API documentation for fields of `metadata`. | | |
-| `spec` _[ExternalSecretsManagerSpec](#externalsecretsmanagerspec)_ | spec is the specification of the desired behavior | | |
-| `status` _[ExternalSecretsManagerStatus](#externalsecretsmanagerstatus)_ | status is the most recently observed status of controllers used by External Secrets Operator. | | |
+| `metadata` _[ObjectMeta](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.32/#objectmeta-v1-meta)_ | Refer to Kubernetes API documentation for fields of `metadata`. | | Required: \{\} |
+| `spec` _[ExternalSecretsManagerSpec](#externalsecretsmanagerspec)_ | spec is the specification of the desired behavior | | Optional: \{\} |
+| `status` _[ExternalSecretsManagerStatus](#externalsecretsmanagerstatus)_ | status is the most recently observed status of controllers used by External Secrets Operator. | | Optional: \{\} |
#### ExternalSecretsManagerList
@@ -390,8 +390,8 @@ _Appears in:_
| Field | Description | Default | Validation |
| --- | --- | --- | --- |
-| `globalConfig` _[GlobalConfig](#globalconfig)_ | globalConfig is for configuring the behavior of deployments that are managed by external secrets-operator. | | |
-| `features` _[Feature](#feature) array_ | features configures optional capabilities across deployments managed by the external-secrets-operator, including the operator itself and any current or future operands. Each entry is uniquely identified by name and can be individually enabled or disabled. This field can have a maximum of 1 entry. | | MaxItems: 1 MinItems: 0 |
+| `globalConfig` _[GlobalConfig](#globalconfig)_ | globalConfig is for configuring the behavior of deployments that are managed by external secrets-operator. | | Optional: \{\} |
+| `features` _[Feature](#feature) array_ | features configures optional capabilities across deployments managed by the external-secrets-operator, including the operator itself and any current or future operands. Each entry is uniquely identified by name and can be individually enabled or disabled. This field can have a maximum of 1 entry. | | MaxItems: 1 MinItems: 0 Optional: \{\} |
#### ExternalSecretsManagerStatus
@@ -407,8 +407,8 @@ _Appears in:_
| Field | Description | Default | Validation |
| --- | --- | --- | --- |
-| `controllerStatuses` _[ControllerStatus](#controllerstatus) array_ | controllerStatuses holds the observed conditions of the controllers part of the operator. | | |
-| `lastTransitionTime` _[Time](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.32/#time-v1-meta)_ | lastTransitionTime is the last time the condition transitioned from one status to another. | | Format: date-time Type: string |
+| `controllerStatuses` _[ControllerStatus](#controllerstatus) array_ | controllerStatuses holds the observed conditions of the controllers part of the operator. | | Optional: \{\} |
+| `lastTransitionTime` _[Time](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.32/#time-v1-meta)_ | lastTransitionTime is the last time the condition transitioned from one status to another. | | Format: date-time Type: string Optional: \{\} |
#### Feature
@@ -424,8 +424,8 @@ _Appears in:_
| Field | Description | Default | Validation |
| --- | --- | --- | --- |
-| `name` _[FeatureName](#featurename)_ | name identifies the optional feature to configure. Currently, the only supported value is UnsafeAllowGenericTargets. | | Enum: [UnsafeAllowGenericTargets] |
-| `mode` _[Mode](#mode)_ | mode controls whether the feature is active. When set to Enabled, the operator applies the configuration associated with the named feature to the relevant managed deployments. For UnsafeAllowGenericTargets, this passes the `--unsafe-allow-generic-targets` flag to the external-secrets core controller, allowing ExternalSecret resources to target Kubernetes resources other than Secrets (for example, ConfigMaps or custom resources). Warning: Generic targets require additional RBAC permissions on the affected operand; enabling this feature without the appropriate permissions will cause reconciliation failures. | Disabled | Enum: [Enabled Disabled] |
+| `name` _[FeatureName](#featurename)_ | name identifies the optional feature to configure. Currently, the only supported value is UnsafeAllowGenericTargets. | | Enum: [UnsafeAllowGenericTargets] Required: \{\} |
+| `mode` _[Mode](#mode)_ | mode controls whether the feature is active. When set to Enabled, the operator applies the configuration associated with the named feature to the relevant managed deployments. For UnsafeAllowGenericTargets, this passes the `--unsafe-allow-generic-targets` flag to the external-secrets core controller, allowing ExternalSecret resources to target Kubernetes resources other than Secrets (for example, ConfigMaps or custom resources). Warning: Generic targets require additional RBAC permissions on the affected operand; enabling this feature without the appropriate permissions will cause reconciliation failures. | Disabled | Enum: [Enabled Disabled] Optional: \{\} |
#### FeatureName
@@ -457,13 +457,13 @@ _Appears in:_
| Field | Description | Default | Validation |
| --- | --- | --- | --- |
-| `logLevel` _integer_ | logLevel supports value range as per [Kubernetes logging guidelines](https://github.com/kubernetes/community/blob/master/contributors/devel/sig-instrumentation/logging.md#what-method-to-use). | 1 | Maximum: 5 Minimum: 1 |
-| `resources` _[ResourceRequirements](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.32/#resourcerequirements-v1-core)_ | resources is for defining the resource requirements. Cannot be updated. ref: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ | | |
-| `affinity` _[Affinity](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.32/#affinity-v1-core)_ | affinity is for setting scheduling affinity rules. ref: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/ | | |
-| `tolerations` _[Toleration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.32/#toleration-v1-core) array_ | tolerations is for setting the pod tolerations. ref: https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/ This field can have a maximum of 50 entries. | | MaxItems: 50 MinItems: 0 |
-| `nodeSelector` _object (keys:string, values:string)_ | nodeSelector is for defining the scheduling criteria using node labels. ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ This field can have a maximum of 50 entries. | | MaxProperties: 50 MinProperties: 0 |
-| `proxy` _[ProxyConfig](#proxyconfig)_ | proxy is for setting the proxy configurations which will be made available in operand containers managed by the operator as environment variables. | | |
-| `labels` _object (keys:string, values:string)_ | labels to apply to all resources created by the operator. This field can have a maximum of 20 entries. | | MaxProperties: 20 MinProperties: 0 |
+| `logLevel` _integer_ | logLevel supports value range as per [Kubernetes logging guidelines](https://github.com/kubernetes/community/blob/master/contributors/devel/sig-instrumentation/logging.md#what-method-to-use). | 1 | Maximum: 5 Minimum: 1 Optional: \{\} |
+| `resources` _[ResourceRequirements](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.32/#resourcerequirements-v1-core)_ | resources is for defining the resource requirements. Cannot be updated. ref: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ | | Optional: \{\} |
+| `affinity` _[Affinity](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.32/#affinity-v1-core)_ | affinity is for setting scheduling affinity rules. ref: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/ | | Optional: \{\} |
+| `tolerations` _[Toleration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.32/#toleration-v1-core) array_ | tolerations is for setting the pod tolerations. ref: https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/ This field can have a maximum of 50 entries. | | MaxItems: 50 MinItems: 0 Optional: \{\} |
+| `nodeSelector` _object (keys:string, values:string)_ | nodeSelector is for defining the scheduling criteria using node labels. ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ This field can have a maximum of 50 entries. | | MaxProperties: 50 MinProperties: 0 Optional: \{\} |
+| `proxy` _[ProxyConfig](#proxyconfig)_ | proxy is for setting the proxy configurations which will be made available in operand containers managed by the operator as environment variables. | | Optional: \{\} |
+| `labels` _object (keys:string, values:string)_ | labels to apply to all resources created by the operator. This field can have a maximum of 20 entries. | | MaxProperties: 20 MinProperties: 0 Optional: \{\} |
#### ManagementState
@@ -516,9 +516,9 @@ _Appears in:_
| Field | Description | Default | Validation |
| --- | --- | --- | --- |
-| `name` _string_ | Name is the logical identifier for this network policy entry. The operator prepends "eso-user-" to this value when creating the Kubernetes NetworkPolicy object (e.g. "allow-egress" becomes "eso-user-allow-egress"). Maximum length is 243 to accommodate the prefix within the 253-character Kubernetes name limit. | | MaxLength: 243 MinLength: 1 |
-| `componentName` _[ComponentName](#componentname)_ | componentName specifies which external-secrets component this network policy applies to. | | Enum: [ExternalSecretsCoreController BitwardenSDKServer] |
-| `egress` _[NetworkPolicyEgressRule](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.32/#networkpolicyegressrule-v1-networking) array_ | egress is a list of egress rules to be applied to the selected pods. Outgoing traffic is allowed if there are no NetworkPolicies selecting the pod (and cluster policy otherwise allows the traffic), OR if the traffic matches at least one egress rule across all the NetworkPolicy objects whose podSelector matches the pod. If this field is empty then this NetworkPolicy limits all outgoing traffic (and serves solely to ensure that the pods it selects are isolated by default). The operator will automatically handle ingress rules based on the current running ports. | | |
+| `name` _string_ | Name is the logical identifier for this network policy entry. The operator prepends "eso-user-" to this value when creating the Kubernetes NetworkPolicy object (e.g. "allow-egress" becomes "eso-user-allow-egress"). Maximum length is 243 to accommodate the prefix within the 253-character Kubernetes name limit. | | MaxLength: 243 MinLength: 1 Required: \{\} |
+| `componentName` _[ComponentName](#componentname)_ | componentName specifies which external-secrets component this network policy applies to. | | Enum: [ExternalSecretsCoreController BitwardenSDKServer] Required: \{\} |
+| `egress` _[NetworkPolicyEgressRule](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.32/#networkpolicyegressrule-v1-networking) array_ | egress is a list of egress rules to be applied to the selected pods. Outgoing traffic is allowed if there are no NetworkPolicies selecting the pod (and cluster policy otherwise allows the traffic), OR if the traffic matches at least one egress rule across all the NetworkPolicy objects whose podSelector matches the pod. If this field is empty then this NetworkPolicy limits all outgoing traffic (and serves solely to ensure that the pods it selects are isolated by default). The operator will automatically handle ingress rules based on the current running ports. | | Required: \{\} |
#### ObjectReference
@@ -547,7 +547,7 @@ _Appears in:_
| Field | Description | Default | Validation |
| --- | --- | --- | --- |
-| `bitwardenSecretManagerProvider` _[BitwardenSecretManagerProvider](#bitwardensecretmanagerprovider)_ | bitwardenSecretManagerProvider is for enabling the bitwarden secrets manager provider plugin for connecting with the bitwarden secrets manager. | | |
+| `bitwardenSecretManagerProvider` _[BitwardenSecretManagerProvider](#bitwardensecretmanagerprovider)_ | bitwardenSecretManagerProvider is for enabling the bitwarden secrets manager provider plugin for connecting with the bitwarden secrets manager. | | Optional: \{\} |
#### ProxyConfig
@@ -565,10 +565,10 @@ _Appears in:_
| Field | Description | Default | Validation |
| --- | --- | --- | --- |
-| `httpProxy` _string_ | httpProxy is the URL of the proxy for HTTP requests. This field can have a maximum of 2048 characters. | | MaxLength: 2048 MinLength: 0 |
-| `httpsProxy` _string_ | httpsProxy is the URL of the proxy for HTTPS requests. This field can have a maximum of 2048 characters. | | MaxLength: 2048 MinLength: 0 |
-| `noProxy` _string_ | noProxy is a comma-separated list of hostnames and/or CIDRs and/or IPs for which the proxy should not be used. This field can have a maximum of 4096 characters. | | MaxLength: 4096 MinLength: 0 |
-| `networkPolicyProvisioning` _[ManagementState](#managementstate)_ | networkPolicyProvisioning defines the management strategy for the proxy egress rule. When set to Managed, the operator automatically provisions and maintains a NetworkPolicy allowing traffic to the configured proxy. If no proxy is configured, no NetworkPolicy will be created regardless of this setting. | Managed | Enum: [Managed Unmanaged] |
+| `httpProxy` _string_ | httpProxy is the URL of the proxy for HTTP requests. This field can have a maximum of 2048 characters. | | MaxLength: 2048 MinLength: 0 Optional: \{\} |
+| `httpsProxy` _string_ | httpsProxy is the URL of the proxy for HTTPS requests. This field can have a maximum of 2048 characters. | | MaxLength: 2048 MinLength: 0 Optional: \{\} |
+| `noProxy` _string_ | noProxy is a comma-separated list of hostnames and/or CIDRs and/or IPs for which the proxy should not be used. This field can have a maximum of 4096 characters. | | MaxLength: 4096 MinLength: 0 Optional: \{\} |
+| `networkPolicyProvisioning` _[ManagementState](#managementstate)_ | networkPolicyProvisioning defines the management strategy for the proxy egress rule. When set to Managed, the operator automatically provisions and maintains a NetworkPolicy allowing traffic to the configured proxy. If no proxy is configured, no NetworkPolicy will be created regardless of this setting. | Managed | Enum: [Managed Unmanaged] Optional: \{\} |
#### SecretReference
@@ -584,7 +584,7 @@ _Appears in:_
| Field | Description | Default | Validation |
| --- | --- | --- | --- |
-| `name` _string_ | name of the secret resource being referred to. | | MaxLength: 253 MinLength: 1 |
+| `name` _string_ | name of the secret resource being referred to. | | MaxLength: 253 MinLength: 1 Required: \{\} |
#### WebhookConfig
@@ -600,6 +600,6 @@ _Appears in:_
| Field | Description | Default | Validation |
| --- | --- | --- | --- |
-| `certificateCheckInterval` _[Duration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.32/#duration-v1-meta)_ | certificateCheckInterval is for configuring the polling interval to check the certificate validity. | 5m | |
+| `certificateCheckInterval` _[Duration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.32/#duration-v1-meta)_ | certificateCheckInterval is for configuring the polling interval to check the certificate validity. | 5m | Optional: \{\} |
diff --git a/go.mod b/go.mod
index b617cb135..b6607ec24 100644
--- a/go.mod
+++ b/go.mod
@@ -2,20 +2,24 @@ module github.com/openshift/external-secrets-operator
go 1.26.0
+// Exclude old monolithic genproto to avoid ambiguous imports with modular versions
+exclude google.golang.org/genproto v0.0.0-20220519153652-3a47de7e79bd
+
require (
- github.com/cert-manager/cert-manager v1.18.5
- github.com/go-logr/logr v1.4.3
- go.uber.org/zap v1.27.1
- k8s.io/api v0.35.6
- k8s.io/apiextensions-apiserver v0.35.3
- k8s.io/apimachinery v0.35.6
- k8s.io/client-go v0.35.6
- k8s.io/kubernetes v1.35.6
- k8s.io/utils v0.0.0-20260210185600-b8788abfbbc2
- sigs.k8s.io/controller-runtime v0.23.3
+ github.com/cert-manager/cert-manager v1.21.1
+ github.com/go-logr/logr v1.4.4
+ go.uber.org/zap v1.28.0
+ k8s.io/api v0.36.3
+ k8s.io/apiextensions-apiserver v0.36.3
+ k8s.io/apimachinery v0.36.3
+ k8s.io/client-go v0.36.3
+ k8s.io/kubernetes v1.36.3
+ k8s.io/utils v0.0.0-20260707023825-cf1189d6abe3
+ sigs.k8s.io/controller-runtime v0.24.1
)
require (
+ github.com/Masterminds/semver/v3 v3.5.0 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/blang/semver/v4 v4.0.0 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
@@ -23,71 +27,68 @@ require (
github.com/distribution/reference v0.6.0 // indirect
github.com/emicklei/go-restful/v3 v3.13.0 // indirect
github.com/evanphx/json-patch/v5 v5.9.11 // indirect
- github.com/fsnotify/fsnotify v1.9.0 // indirect
- github.com/fxamacker/cbor/v2 v2.9.0 // indirect
- github.com/go-openapi/jsonpointer v0.22.4 // indirect
- github.com/go-openapi/jsonreference v0.21.4 // indirect
- github.com/go-openapi/swag v0.25.4 // indirect
- github.com/go-openapi/swag/cmdutils v0.25.4 // indirect
- github.com/go-openapi/swag/conv v0.25.4 // indirect
- github.com/go-openapi/swag/fileutils v0.25.4 // indirect
- github.com/go-openapi/swag/jsonname v0.25.4 // indirect
- github.com/go-openapi/swag/jsonutils v0.25.4 // indirect
- github.com/go-openapi/swag/loading v0.25.4 // indirect
- github.com/go-openapi/swag/mangling v0.25.4 // indirect
- github.com/go-openapi/swag/netutils v0.25.4 // indirect
- github.com/go-openapi/swag/stringutils v0.25.4 // indirect
- github.com/go-openapi/swag/typeutils v0.25.4 // indirect
- github.com/go-openapi/swag/yamlutils v0.25.4 // indirect
- github.com/google/btree v1.1.3 // indirect
+ github.com/fsnotify/fsnotify v1.10.0 // indirect
+ github.com/fxamacker/cbor/v2 v2.9.3 // indirect
+ github.com/go-openapi/jsonpointer v1.0.0 // indirect
+ github.com/go-openapi/jsonreference v1.0.0 // indirect
+ github.com/go-openapi/swag v0.28.0 // indirect
+ github.com/go-openapi/swag/cmdutils v0.28.0 // indirect
+ github.com/go-openapi/swag/conv v0.28.0 // indirect
+ github.com/go-openapi/swag/fileutils v0.28.0 // indirect
+ github.com/go-openapi/swag/jsonutils v0.28.0 // indirect
+ github.com/go-openapi/swag/loading v0.28.0 // indirect
+ github.com/go-openapi/swag/mangling v0.28.0 // indirect
+ github.com/go-openapi/swag/netutils v0.28.0 // indirect
+ github.com/go-openapi/swag/pools v0.28.0 // indirect
+ github.com/go-openapi/swag/stringutils v0.28.0 // indirect
+ github.com/go-openapi/swag/typeutils v0.28.0 // indirect
+ github.com/go-openapi/swag/yamlutils v0.28.0 // indirect
github.com/google/gnostic-models v0.7.1 // indirect
- github.com/google/go-cmp v0.7.0 // indirect
- github.com/google/pprof v0.0.0-20260115054156-294ebfa9ad83 // indirect
+ github.com/google/pprof v0.0.0-20260802141513-ef3492d7dac3 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
- github.com/onsi/ginkgo/v2 v2.27.4 // indirect
- github.com/onsi/gomega v1.39.0 // indirect
+ github.com/onsi/ginkgo/v2 v2.32.1 // indirect
+ github.com/onsi/gomega v1.40.0 // indirect
github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/prometheus/client_golang v1.23.2 // indirect
github.com/prometheus/client_model v0.6.2 // indirect
github.com/prometheus/common v0.67.5 // indirect
- github.com/prometheus/procfs v0.19.2 // indirect
+ github.com/prometheus/procfs v0.20.1 // indirect
github.com/robfig/cron/v3 v3.0.1 // indirect
github.com/spf13/pflag v1.0.10 // indirect
github.com/x448/float16 v0.8.4 // indirect
- go.opentelemetry.io/otel v1.41.0 // indirect
- go.opentelemetry.io/otel/trace v1.41.0 // indirect
+ go.opentelemetry.io/otel v1.44.0 // indirect
+ go.opentelemetry.io/otel/trace v1.44.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
- go.yaml.in/yaml/v2 v2.4.3 // indirect
- go.yaml.in/yaml/v3 v3.0.4 // indirect
+ go.yaml.in/yaml/v2 v2.4.4 // indirect
+ go.yaml.in/yaml/v3 v3.0.5 // indirect
+ golang.org/x/mod v0.40.0 // indirect
golang.org/x/net v0.58.0 // indirect
- golang.org/x/oauth2 v0.34.0 // indirect
+ golang.org/x/oauth2 v0.36.0 // indirect
golang.org/x/sync v0.22.0 // indirect
golang.org/x/sys v0.47.0 // indirect
golang.org/x/term v0.45.0 // indirect
golang.org/x/text v0.41.0 // indirect
- golang.org/x/time v0.14.0 // indirect
+ golang.org/x/time v0.15.0 // indirect
+ golang.org/x/tools v0.49.0 // indirect
gomodules.xyz/jsonpatch/v2 v2.5.0 // indirect
- google.golang.org/protobuf v1.36.12-0.20260120151049-f2248ac996af // indirect
+ google.golang.org/protobuf v1.36.12 // indirect
gopkg.in/evanphx/json-patch.v4 v4.13.0 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
- k8s.io/apiserver v0.35.6 // indirect
- k8s.io/component-base v0.35.6 // indirect
+ k8s.io/apiserver v0.36.3 // indirect
+ k8s.io/component-base v0.36.3 // indirect
k8s.io/component-helpers v0.35.6 // indirect
k8s.io/controller-manager v0.35.6 // indirect
k8s.io/klog/v2 v2.140.0 // indirect
- k8s.io/kube-openapi v0.0.0-20260317180543-43fb72c5454a // indirect
+ k8s.io/kube-openapi v0.0.0-20260721132016-d427ff9ee9ad // indirect
k8s.io/kubelet v0.32.2 //indirect
- sigs.k8s.io/gateway-api v1.1.0 // indirect
+ sigs.k8s.io/gateway-api v1.6.0 // indirect
sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect
sigs.k8s.io/randfill v1.0.0 // indirect
- sigs.k8s.io/structured-merge-diff/v6 v6.3.2 // indirect
+ sigs.k8s.io/structured-merge-diff/v6 v6.4.2 // indirect
sigs.k8s.io/yaml v1.6.0 // indirect
)
-
-// Exclude old monolithic genproto to avoid ambiguous imports with modular versions
-exclude google.golang.org/genproto v0.0.0-20220519153652-3a47de7e79bd
diff --git a/go.sum b/go.sum
index aa04d2bec..219c300a2 100644
--- a/go.sum
+++ b/go.sum
@@ -1,11 +1,11 @@
-github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0=
-github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=
+github.com/Masterminds/semver/v3 v3.5.0 h1:kQceYJfbupGfZOKZQg0kou0DgAKhzDg2NZPAwZ/2OOE=
+github.com/Masterminds/semver/v3 v3.5.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM=
github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ=
-github.com/cert-manager/cert-manager v1.18.5 h1:Gx4FSpSPYcSC4MQf43QjbxDfyTEbwZgfZQs5Lq9QlBs=
-github.com/cert-manager/cert-manager v1.18.5/go.mod h1:HbPSO5MW/44wu19t84eY/K4c4/WwyPB4bA3uffOH92s=
+github.com/cert-manager/cert-manager v1.21.1 h1:0LttV37Q5c2CBNoHkjuI8sLKTXWZDC2SwQkxrBMKV9w=
+github.com/cert-manager/cert-manager v1.21.1/go.mod h1:sVwmLBWoiB1BRd0rJElBGQuiu94z4k7p3Kd0FRQyfgw=
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@@ -20,52 +20,50 @@ github.com/evanphx/json-patch v5.9.0+incompatible h1:fBXyNpNMuTTDdquAq/uisOr2lSh
github.com/evanphx/json-patch v5.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/evanphx/json-patch/v5 v5.9.11 h1:/8HVnzMq13/3x9TPvjG08wUGqBTmZBsCWzjTM0wiaDU=
github.com/evanphx/json-patch/v5 v5.9.11/go.mod h1:3j+LviiESTElxA4p3EMKAB9HXj3/XEtnUf6OZxqIQTM=
-github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k=
-github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
-github.com/fxamacker/cbor/v2 v2.9.0 h1:NpKPmjDBgUfBms6tr6JZkTHtfFGcMKsw3eGcmD/sapM=
-github.com/fxamacker/cbor/v2 v2.9.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ=
-github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
-github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
+github.com/fsnotify/fsnotify v1.10.0 h1:Xx/5Ydg9CeBDX/wi4VJqStNtohYjitZhhlHt4h3St1M=
+github.com/fsnotify/fsnotify v1.10.0/go.mod h1:TLheqan6HD6GBK6PrDWyDPBaEV8LspOxvPSjC+bVfgo=
+github.com/fxamacker/cbor/v2 v2.9.3 h1:oQBnFATpNdY8gJHTndDDv5Xl4QqNaz51G5LLEPhng3Q=
+github.com/fxamacker/cbor/v2 v2.9.3/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ=
+github.com/go-logr/logr v1.4.4 h1:tG4xh9yMsRCAiodLVTxyrkzSZ9+o0L1Kg/+cPVcbP/8=
+github.com/go-logr/logr v1.4.4/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ=
github.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR8/Gg=
-github.com/go-openapi/jsonpointer v0.22.4 h1:dZtK82WlNpVLDW2jlA1YCiVJFVqkED1MegOUy9kR5T4=
-github.com/go-openapi/jsonpointer v0.22.4/go.mod h1:elX9+UgznpFhgBuaMQ7iu4lvvX1nvNsesQ3oxmYTw80=
-github.com/go-openapi/jsonreference v0.21.4 h1:24qaE2y9bx/q3uRK/qN+TDwbok1NhbSmGjjySRCHtC8=
-github.com/go-openapi/jsonreference v0.21.4/go.mod h1:rIENPTjDbLpzQmQWCj5kKj3ZlmEh+EFVbz3RTUh30/4=
-github.com/go-openapi/swag v0.25.4 h1:OyUPUFYDPDBMkqyxOTkqDYFnrhuhi9NR6QVUvIochMU=
-github.com/go-openapi/swag v0.25.4/go.mod h1:zNfJ9WZABGHCFg2RnY0S4IOkAcVTzJ6z2Bi+Q4i6qFQ=
-github.com/go-openapi/swag/cmdutils v0.25.4 h1:8rYhB5n6WawR192/BfUu2iVlxqVR9aRgGJP6WaBoW+4=
-github.com/go-openapi/swag/cmdutils v0.25.4/go.mod h1:pdae/AFo6WxLl5L0rq87eRzVPm/XRHM3MoYgRMvG4A0=
-github.com/go-openapi/swag/conv v0.25.4 h1:/Dd7p0LZXczgUcC/Ikm1+YqVzkEeCc9LnOWjfkpkfe4=
-github.com/go-openapi/swag/conv v0.25.4/go.mod h1:3LXfie/lwoAv0NHoEuY1hjoFAYkvlqI/Bn5EQDD3PPU=
-github.com/go-openapi/swag/fileutils v0.25.4 h1:2oI0XNW5y6UWZTC7vAxC8hmsK/tOkWXHJQH4lKjqw+Y=
-github.com/go-openapi/swag/fileutils v0.25.4/go.mod h1:cdOT/PKbwcysVQ9Tpr0q20lQKH7MGhOEb6EwmHOirUk=
-github.com/go-openapi/swag/jsonname v0.25.4 h1:bZH0+MsS03MbnwBXYhuTttMOqk+5KcQ9869Vye1bNHI=
-github.com/go-openapi/swag/jsonname v0.25.4/go.mod h1:GPVEk9CWVhNvWhZgrnvRA6utbAltopbKwDu8mXNUMag=
-github.com/go-openapi/swag/jsonutils v0.25.4 h1:VSchfbGhD4UTf4vCdR2F4TLBdLwHyUDTd1/q4i+jGZA=
-github.com/go-openapi/swag/jsonutils v0.25.4/go.mod h1:7OYGXpvVFPn4PpaSdPHJBtF0iGnbEaTk8AvBkoWnaAY=
-github.com/go-openapi/swag/jsonutils/fixtures_test v0.25.4 h1:IACsSvBhiNJwlDix7wq39SS2Fh7lUOCJRmx/4SN4sVo=
-github.com/go-openapi/swag/jsonutils/fixtures_test v0.25.4/go.mod h1:Mt0Ost9l3cUzVv4OEZG+WSeoHwjWLnarzMePNDAOBiM=
-github.com/go-openapi/swag/loading v0.25.4 h1:jN4MvLj0X6yhCDduRsxDDw1aHe+ZWoLjW+9ZQWIKn2s=
-github.com/go-openapi/swag/loading v0.25.4/go.mod h1:rpUM1ZiyEP9+mNLIQUdMiD7dCETXvkkC30z53i+ftTE=
-github.com/go-openapi/swag/mangling v0.25.4 h1:2b9kBJk9JvPgxr36V23FxJLdwBrpijI26Bx5JH4Hp48=
-github.com/go-openapi/swag/mangling v0.25.4/go.mod h1:6dxwu6QyORHpIIApsdZgb6wBk/DPU15MdyYj/ikn0Hg=
-github.com/go-openapi/swag/netutils v0.25.4 h1:Gqe6K71bGRb3ZQLusdI8p/y1KLgV4M/k+/HzVSqT8H0=
-github.com/go-openapi/swag/netutils v0.25.4/go.mod h1:m2W8dtdaoX7oj9rEttLyTeEFFEBvnAx9qHd5nJEBzYg=
-github.com/go-openapi/swag/stringutils v0.25.4 h1:O6dU1Rd8bej4HPA3/CLPciNBBDwZj9HiEpdVsb8B5A8=
-github.com/go-openapi/swag/stringutils v0.25.4/go.mod h1:GTsRvhJW5xM5gkgiFe0fV3PUlFm0dr8vki6/VSRaZK0=
-github.com/go-openapi/swag/typeutils v0.25.4 h1:1/fbZOUN472NTc39zpa+YGHn3jzHWhv42wAJSN91wRw=
-github.com/go-openapi/swag/typeutils v0.25.4/go.mod h1:Ou7g//Wx8tTLS9vG0UmzfCsjZjKhpjxayRKTHXf2pTE=
-github.com/go-openapi/swag/yamlutils v0.25.4 h1:6jdaeSItEUb7ioS9lFoCZ65Cne1/RZtPBZ9A56h92Sw=
-github.com/go-openapi/swag/yamlutils v0.25.4/go.mod h1:MNzq1ulQu+yd8Kl7wPOut/YHAAU/H6hL91fF+E2RFwc=
-github.com/go-openapi/testify/enable/yaml/v2 v2.0.2 h1:0+Y41Pz1NkbTHz8NngxTuAXxEodtNSI1WG1c/m5Akw4=
-github.com/go-openapi/testify/enable/yaml/v2 v2.0.2/go.mod h1:kme83333GCtJQHXQ8UKX3IBZu6z8T5Dvy5+CW3NLUUg=
-github.com/go-openapi/testify/v2 v2.0.2 h1:X999g3jeLcoY8qctY/c/Z8iBHTbwLz7R2WXd6Ub6wls=
-github.com/go-openapi/testify/v2 v2.0.2/go.mod h1:HCPmvFFnheKK2BuwSA0TbbdxJ3I16pjwMkYkP4Ywn54=
+github.com/go-openapi/jsonpointer v1.0.0 h1:kR9tHqY0CtZaOPVFm622dPVNhrvYpwr4uCxgL3h1H8s=
+github.com/go-openapi/jsonpointer v1.0.0/go.mod h1:Z3rw7dWu1p9IgitXCFamSlA5lmDiklEB6vkaxcNZW5Y=
+github.com/go-openapi/jsonreference v1.0.0 h1:jlmTr6torcd1YgDQvSfNmRtKzYDO4FGBkrAdlAVWnpY=
+github.com/go-openapi/jsonreference v1.0.0/go.mod h1:jtwdyGbJk0Xhe5Y+rwtglQP6Sb1WZST4rT32LWB+sv0=
+github.com/go-openapi/swag v0.28.0 h1:xkgbOSKj6DZziNpyqRRAOt3GJGtgjgsd2RoyT30VWuw=
+github.com/go-openapi/swag v0.28.0/go.mod h1:4qYnT3Cqr1p1VknOdPo70evN4rgQnAg6jwApHyxSGIg=
+github.com/go-openapi/swag/cmdutils v0.28.0 h1:7TOeNtkYru1SG8Y34tDh9WBbLsMqGnptuxWiHREPZ4Q=
+github.com/go-openapi/swag/cmdutils v0.28.0/go.mod h1:Sm1MVFMkF6guJJ+pQqHnQA3N0j9qALV3NxzDSv6bETM=
+github.com/go-openapi/swag/conv v0.28.0 h1:GtqqbyFe7vR5Y7ehxG9W6/OvrSFdf1OLeTGp40TqxH8=
+github.com/go-openapi/swag/conv v0.28.0/go.mod h1:mbUE+mzctnhxi864m0Q07SpN8OowD9JhxmxuYvZZD/k=
+github.com/go-openapi/swag/fileutils v0.28.0 h1:Z04XWQD7R8Eq+7GnOrjovBxPPmZzsS4gt2H2GPGIViU=
+github.com/go-openapi/swag/fileutils v0.28.0/go.mod h1:VvJFZLTZS0AI854gEQz5tk7dBESdLjiNUMSZ/th2ry8=
+github.com/go-openapi/swag/jsonutils v0.28.0 h1:YIch6FwO7RXzeAnbO8Tu7dWBZeUEH+4nA0HXltVTnv4=
+github.com/go-openapi/swag/jsonutils v0.28.0/go.mod h1:CYM3WlTUcagR2ZoHdz54di/cbBqt82tuxuXgAjxw+mg=
+github.com/go-openapi/swag/jsonutils/fixtures_test v0.28.0 h1:qV+VVUAx5Oro8WjVWpZeql7YReTKhT4smR4zhcOQZr0=
+github.com/go-openapi/swag/jsonutils/fixtures_test v0.28.0/go.mod h1:mofwUWx70wvskwESqRJ//k/9kURmCgyJl5m5Ppoh5kY=
+github.com/go-openapi/swag/loading v0.28.0 h1:td8QZdZC9MIYGGSnSPKShKiK22I2tU5UQvuUhIBPRLU=
+github.com/go-openapi/swag/loading v0.28.0/go.mod h1:rXB0QiQX5mMveXEA7ouM4KiiM9jVJe4K6BVbwhD1M4k=
+github.com/go-openapi/swag/mangling v0.28.0 h1:pH8eyeNO9SLYsTMWJrurnNfKmDa28XrlA+HePVD53VM=
+github.com/go-openapi/swag/mangling v0.28.0/go.mod h1:jtBE2+V+3pILxOR7Vgce+Cwp6A2PgZbvVqfNntbVs0w=
+github.com/go-openapi/swag/netutils v0.28.0 h1:YXN6TALEi2pzts8/8GNm6T61HTAZsieukGZidap989k=
+github.com/go-openapi/swag/netutils v0.28.0/go.mod h1:J+WYyFMLtvtCGqa6jLv+YNUmIKI3ZRQRrvfNDMoQoEQ=
+github.com/go-openapi/swag/pools v0.28.0 h1:HPMZWSAfce3rdVTFcjFiCIBtDg9h4x2QlRrHipwhxeU=
+github.com/go-openapi/swag/pools v0.28.0/go.mod h1:kVQefhSK5RWuRe7BXsL8htgBPAMpN7HDGpGEknqugeE=
+github.com/go-openapi/swag/stringutils v0.28.0 h1:ixsc9iYgDPubHL/8nSkbnryEHpD2VRlBMLKpQyPXcDU=
+github.com/go-openapi/swag/stringutils v0.28.0/go.mod h1:lzRN95CxXmA03XcDWHLOb6nOMcxCqR5rGY0lOgsfRoM=
+github.com/go-openapi/swag/typeutils v0.28.0 h1:nRBKSBXjDgf01VDPB3fWeD9nQuhCOVeIYAkUx2tbkyY=
+github.com/go-openapi/swag/typeutils v0.28.0/go.mod h1:Srm0xFNRZ1Y+vCxJclo5qzx8aj+1pAKda/YfFPrG0dQ=
+github.com/go-openapi/swag/yamlutils v0.28.0 h1:TV3JXH6DS46KUroDtMLAYHGkdWf5VDq3wVWFirmzROY=
+github.com/go-openapi/swag/yamlutils v0.28.0/go.mod h1:x0q/yndZHEgk9Rx3DyDqzFUmHy55KTvIZldvF2dTJXs=
+github.com/go-openapi/testify/enable/yaml/v2 v2.6.0 h1:gGHwAJ0R/5jU8BEGDbfRNR3hL68dAVi84WuOApp29B0=
+github.com/go-openapi/testify/enable/yaml/v2 v2.6.0/go.mod h1:tY+St1SGq4NFl0QIqdTY4aEdbChAHxhyB77XQi9iJCo=
+github.com/go-openapi/testify/v2 v2.6.0 h1:5PKH2HE7YJ/LuRPQGvSxBRlFXNQhSetBLlGAgUEu3ug=
+github.com/go-openapi/testify/v2 v2.6.0/go.mod h1:SgsVHtfooshd0tublTtJ50FPKhujf47YRqauXXOUxfw=
github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
-github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg=
-github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4=
github.com/google/gnostic-models v0.7.1 h1:SisTfuFKJSKM5CPZkffwi6coztzzeYUhc3v4yxLWH8c=
github.com/google/gnostic-models v0.7.1/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ=
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
@@ -73,18 +71,14 @@ github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
-github.com/google/pprof v0.0.0-20260115054156-294ebfa9ad83 h1:z2ogiKUYzX5Is6zr/vP9vJGqPwcdqsWjOt+V8J7+bTc=
-github.com/google/pprof v0.0.0-20260115054156-294ebfa9ad83/go.mod h1:MxpfABSjhmINe3F1It9d+8exIHFvUqtLIRCdOGNXqiI=
+github.com/google/pprof v0.0.0-20260802141513-ef3492d7dac3 h1:LMLX+LgTNWpfvCBdFebv6EsYotImrt/Ppc5cXIriCSo=
+github.com/google/pprof v0.0.0-20260802141513-ef3492d7dac3/go.mod h1:jl5iWTm0/hd5PjEYEOuwAJ57L/CibdZfrqZ5XA5GrCk=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
-github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
-github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
-github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
-github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
@@ -95,10 +89,10 @@ github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee h1:W5t00kpgFd
github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
-github.com/onsi/ginkgo/v2 v2.27.4 h1:fcEcQW/A++6aZAZQNUmNjvA9PSOzefMJBerHJ4t8v8Y=
-github.com/onsi/ginkgo/v2 v2.27.4/go.mod h1:ArE1D/XhNXBXCBkKOLkbsb2c81dQHCRcF5zwn/ykDRo=
-github.com/onsi/gomega v1.39.0 h1:y2ROC3hKFmQZJNFeGAMeHZKkjBL65mIZcvrLQBF9k6Q=
-github.com/onsi/gomega v1.39.0/go.mod h1:ZCU1pkQcXDO5Sl9/VVEGlDyp+zm0m1cmeG5TOzLgdh4=
+github.com/onsi/ginkgo/v2 v2.32.1 h1:6tlvcDm/3sE8lGJbZ4+d4mO3RLy24/tQWOFzVSQNIfw=
+github.com/onsi/ginkgo/v2 v2.32.1/go.mod h1:+aXOY+vzZ5mu2iI2HpTZUPmM//oQfsNFX6gU9kNcA44=
+github.com/onsi/gomega v1.40.0 h1:Vtol0e1MghCD2ZVIilPDIg44XSL9l2QAn8ZNaljWcJc=
+github.com/onsi/gomega v1.40.0/go.mod h1:M/Uqpu/8qTjtzCLUA2zJHX9Iilrau25x1PdoSRbWh5A=
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
@@ -112,12 +106,10 @@ github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNw
github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE=
github.com/prometheus/common v0.67.5 h1:pIgK94WWlQt1WLwAC5j2ynLaBRDiinoAb86HZHTUGI4=
github.com/prometheus/common v0.67.5/go.mod h1:SjE/0MzDEEAyrdr5Gqc6G+sXI67maCxzaT3A2+HqjUw=
-github.com/prometheus/procfs v0.19.2 h1:zUMhqEW66Ex7OXIiDkll3tl9a1ZdilUOd/F6ZXw4Vws=
-github.com/prometheus/procfs v0.19.2/go.mod h1:M0aotyiemPhBCM0z5w87kL22CxfcH05ZpYlu+b4J7mw=
+github.com/prometheus/procfs v0.20.1 h1:XwbrGOIplXW/AU3YhIhLODXMJYyC1isLFfYCsTEycfc=
+github.com/prometheus/procfs v0.20.1/go.mod h1:o9EMBZGRyvDrSPH1RqdxhojkuXstoe4UlK79eF5TGGo=
github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
-github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
-github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk=
github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
@@ -128,26 +120,26 @@ github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
-go.opentelemetry.io/otel v1.41.0 h1:YlEwVsGAlCvczDILpUXpIpPSL/VPugt7zHThEMLce1c=
-go.opentelemetry.io/otel v1.41.0/go.mod h1:Yt4UwgEKeT05QbLwbyHXEwhnjxNO6D8L5PQP51/46dE=
-go.opentelemetry.io/otel/trace v1.41.0 h1:Vbk2co6bhj8L59ZJ6/xFTskY+tGAbOnCtQGVVa9TIN0=
-go.opentelemetry.io/otel/trace v1.41.0/go.mod h1:U1NU4ULCoxeDKc09yCWdWe+3QoyweJcISEVa1RBzOis=
+go.opentelemetry.io/otel v1.44.0 h1:JjwHmHpA4iZ3wBxluu2fbbE7j4kqlE8jXyAyPXH7HqU=
+go.opentelemetry.io/otel v1.44.0/go.mod h1:BMgjTHL9WPRlRjL2oZCBTL4whCGtXch2H4BhOPIAyYc=
+go.opentelemetry.io/otel/trace v1.44.0 h1:jxF5CsGYCe74MCRx2X4g7WsY/VBKRqqpNvXlX/6gtIk=
+go.opentelemetry.io/otel/trace v1.44.0/go.mod h1:oLl1jrMQAVo6v3GAggN+1VH9VIz9iUSvW53sW1Q8PIE=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
-go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc=
-go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
-go.yaml.in/yaml/v2 v2.4.3 h1:6gvOSjQoTB3vt1l+CU+tSyi/HOjfOjRLJ4YwYZGwRO0=
-go.yaml.in/yaml/v2 v2.4.3/go.mod h1:zSxWcmIDjOzPXpjlTTbAsKokqkDNAVtZO0WOMiT90s8=
-go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
-go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
-golang.org/x/mod v0.38.0 h1:MECBjubtXD7yj4HrhIUcywNaGeNVUdfVnxmPajOk4yk=
-golang.org/x/mod v0.38.0/go.mod h1:V6Xz0pq8TQ3dGqVQ1FVHuelZpAL0uNhSkk9ogYP3c40=
+go.uber.org/zap v1.28.0 h1:IZzaP1Fv73/T/pBMLk4VutPl36uNC+OSUh3JLG3FIjo=
+go.uber.org/zap v1.28.0/go.mod h1:rDLpOi171uODNm/mxFcuYWxDsqWSAVkFdX4XojSKg/Q=
+go.yaml.in/yaml/v2 v2.4.4 h1:tuyd0P+2Ont/d6e2rl3be67goVK4R6deVxCUX5vyPaQ=
+go.yaml.in/yaml/v2 v2.4.4/go.mod h1:gMZqIpDtDqOfM0uNfy0SkpRhvUryYH0Z6wdMYcacYXQ=
+go.yaml.in/yaml/v3 v3.0.5 h1:N6y/pJk8buWs9NY5ERU2HSMfm+IuD/OtfdAnq6kESPw=
+go.yaml.in/yaml/v3 v3.0.5/go.mod h1:HVTZu1O7/Vkt2N+BFy8Zza+lnLsABggaTM2ZpNIGuKg=
+golang.org/x/mod v0.40.0 h1:hUv+3cXcdRHz08UmSiOob7sadHig73uo5bkXxQ/tvUs=
+golang.org/x/mod v0.40.0/go.mod h1:0/weTWkPWGBikyTWAX3dkjVztMmBA5hM0DH6BElSupE=
golang.org/x/net v0.58.0 h1:ynWG7rqYi4ccpTEuPZ2QGWHktVEM9DMCj9yzDE0Q7To=
golang.org/x/net v0.58.0/go.mod h1:YwCddHnFlT7eLQqVprV19OnhLGtc5xOKgE0RyqgfWAU=
-golang.org/x/oauth2 v0.34.0 h1:hqK/t4AKgbqWkdkcAeI8XLmbK+4m4G5YeQRrmiotGlw=
-golang.org/x/oauth2 v0.34.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA=
+golang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs=
+golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q=
golang.org/x/sync v0.22.0 h1:SZjpbeLmrCk4xhRSZFNZW5gFUeCeFgjekvI/+gfScek=
golang.org/x/sync v0.22.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
golang.org/x/sys v0.47.0 h1:o7XGOvZQCADBQQ4Y7VNq2dRWQR7JmOUW8Kxx4ZsNgWs=
@@ -156,58 +148,55 @@ golang.org/x/term v0.45.0 h1:NwWyBmoJCbfTHpxrWoZ9C6/VxOf7ic219I8xZZFdrf0=
golang.org/x/term v0.45.0/go.mod h1:9aqxs0blBcrm/n0L9QW0aRVD+ktan8ssZromtqJC43w=
golang.org/x/text v0.41.0 h1:vz/seA0lnX87Othu2f/0L24RcgrXD9/YFTSuGjj3rH8=
golang.org/x/text v0.41.0/go.mod h1:jvf1O8ajNzZqhSrQBPbutR/EB83Cc0CFrezNQIwbb5M=
-golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI=
-golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4=
-golang.org/x/tools v0.48.0 h1:3+hClM1aLL5mjMKm5ovokw9epgRXPuu2tILgismM6RE=
-golang.org/x/tools v0.48.0/go.mod h1:08xX0orndb/F7jJxGDicx061tyd5pcMto75YMAXr6lk=
+golang.org/x/time v0.15.0 h1:bbrp8t3bGUeFOx08pvsMYRTCVSMk89u4tKbNOZbp88U=
+golang.org/x/time v0.15.0/go.mod h1:Y4YMaQmXwGQZoFaVFk4YpCt4FLQMYKZe9oeV/f4MSno=
+golang.org/x/tools v0.49.0 h1:3NI7VXzL9+1WZD52Dx2ttoPwD5DWrFGpl9mFZDlmisI=
+golang.org/x/tools v0.49.0/go.mod h1:SJNXV9DBKT0UbdttsQjbfJlAE/q+y36++zo3uL3N0Oo=
gomodules.xyz/jsonpatch/v2 v2.5.0 h1:JELs8RLM12qJGXU4u/TO3V25KW8GreMKl9pdkk14RM0=
gomodules.xyz/jsonpatch/v2 v2.5.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY=
-google.golang.org/protobuf v1.36.12-0.20260120151049-f2248ac996af h1:+5/Sw3GsDNlEmu7TfklWKPdQ0Ykja5VEmq2i817+jbI=
-google.golang.org/protobuf v1.36.12-0.20260120151049-f2248ac996af/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
-gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
-gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
-gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
+google.golang.org/protobuf v1.36.12 h1:pJOKDDOyeXErUroCihFAd5LQuwXBSpVnKGrj5o/fwxc=
+google.golang.org/protobuf v1.36.12/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
gopkg.in/evanphx/json-patch.v4 v4.13.0 h1:czT3CmqEaQ1aanPc5SdlgQrrEIb8w/wwCvWWnfEbYzo=
gopkg.in/evanphx/json-patch.v4 v4.13.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M=
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
-k8s.io/api v0.35.6 h1:phPzP79F3kcONsD2TzmDiITNCV6/1Z5U3CCEcjtsXzI=
-k8s.io/api v0.35.6/go.mod h1:GWKUaIp24fuDFigAgnhr9EJOKDqspnwPjYlpDca5B4U=
-k8s.io/apiextensions-apiserver v0.35.3 h1:2fQUhEO7P17sijylbdwt0nBdXP0TvHrHj0KeqHD8FiU=
-k8s.io/apiextensions-apiserver v0.35.3/go.mod h1:tK4Kz58ykRpwAEkXUb634HD1ZAegEElktz/B3jgETd8=
-k8s.io/apimachinery v0.35.6 h1:ASSpfmmsOArKb2Hsu8gGlIcbIcEMVTboI3FfsfYuQ8k=
-k8s.io/apimachinery v0.35.6/go.mod h1:NNi1taPOpep0jOj+oRha3mBJPqvi0hGdaV8TCqGQ+cc=
-k8s.io/apiserver v0.35.6 h1:VWYg2S0wlAmN3URFpVeuLa4PP2RCpTFg1nvlUHOy2C8=
-k8s.io/apiserver v0.35.6/go.mod h1:wajGSrXO9w+lx69jYq4SaE4Xxw5KxxwvVD1zbttYA2E=
-k8s.io/client-go v0.35.6 h1:qZQv9a5B4YlIpXhFBwsI9qPOOJC6Z8lk9lkEWmrmus8=
-k8s.io/client-go v0.35.6/go.mod h1:LOO6N1EhxdQAzYIZ/73cJVyb3gixrMY6ZDJcJ/ANfsY=
-k8s.io/component-base v0.35.6 h1:dTkck9uefkIrKn7wRCEYiDWNUvHd8UdwZCcVafmHgL4=
-k8s.io/component-base v0.35.6/go.mod h1:qcNKrspACsqR+vgUJXkWzwtgUGkURcnrus41o92jjpk=
+k8s.io/api v0.36.3 h1:NxB+05W2UGqXWFXcLO0RB5cnqnUPP5v5sVlaOH0Iz4w=
+k8s.io/api v0.36.3/go.mod h1:JzLQKqRHC5+I8RVj/lS3lCg0mg6nWI9Fo/Sk3ElxHzg=
+k8s.io/apiextensions-apiserver v0.36.3 h1:dPmOAPhwTtqb1bTxbFPsy18KHPhktQeO3WUPXunZIB0=
+k8s.io/apiextensions-apiserver v0.36.3/go.mod h1:KTXFqgXiuw2pRoL+Wpmttqc+up9Xt/GohadPWeLLOa4=
+k8s.io/apimachinery v0.36.3 h1:PkzMRBRG8joFD8EhCuQAtNPvJlxb82FwplP26HIzvAM=
+k8s.io/apimachinery v0.36.3/go.mod h1:cTSjBWgPe/6CQyBKzY/hDIRWCQQQeK0mfLbml0UYFHE=
+k8s.io/apiserver v0.36.3 h1:MGSg2SkdfuytiDEcRylT5mQFmmSsbx90XFUO67Y4bsQ=
+k8s.io/apiserver v0.36.3/go.mod h1:fVH7zv9EUNUA7Fl7LtDKh8aB9W7u1VQPSGtWV5SjUxg=
+k8s.io/client-go v0.36.3 h1:M4JdVzXxYcZk4fGpfDdYnxSwhLKWCFoQsHW6t+z8Hfg=
+k8s.io/client-go v0.36.3/go.mod h1:gcPwr0c87vjjG6HB6pWEqOeuYVoXSsREjzux2j6GF30=
+k8s.io/component-base v0.36.3 h1:vc/UFvPCkW0irPz84LAodAL1j3f4xktPM6dDJIEheAY=
+k8s.io/component-base v0.36.3/go.mod h1:hZbNFG+gCMl9EbykDGEu73feKP9/Cq6JsV4pTo9GTO8=
k8s.io/component-helpers v0.35.6 h1:AEGfqbEWjSM6Tkjtwslv2vQIGIiehvnAVoTDg74QQ0s=
k8s.io/component-helpers v0.35.6/go.mod h1:zog+ILMcmModWjoT1Vsom8sg8IW81mkzom2C/U1lgcs=
k8s.io/controller-manager v0.35.6 h1:NjgU2q6hrrHdT5/mn0tMOHYK5IB5QIVq9QnxUb4iDvU=
k8s.io/controller-manager v0.35.6/go.mod h1:Jq+7QZNSzGoiFaKnobvc0VszFHea6nJyI4U/wgiYOyo=
k8s.io/klog/v2 v2.140.0 h1:Tf+J3AH7xnUzZyVVXhTgGhEKnFqye14aadWv7bzXdzc=
k8s.io/klog/v2 v2.140.0/go.mod h1:o+/RWfJ6PwpnFn7OyAG3QnO47BFsymfEfrz6XyYSSp0=
-k8s.io/kube-openapi v0.0.0-20260317180543-43fb72c5454a h1:xCeOEAOoGYl2jnJoHkC3hkbPJgdATINPMAxaynU2Ovg=
-k8s.io/kube-openapi v0.0.0-20260317180543-43fb72c5454a/go.mod h1:uGBT7iTA6c6MvqUvSXIaYZo9ukscABYi2btjhvgKGZ0=
+k8s.io/kube-openapi v0.0.0-20260721132016-d427ff9ee9ad h1:oXImqH8mQNk7PmvzKhmN3ddJoY6OnyM225MXwGHPm0A=
+k8s.io/kube-openapi v0.0.0-20260721132016-d427ff9ee9ad/go.mod h1:0/mqHCVhlumdJ3BhCfnjSZQE037nAhNodh1/hK0T8/I=
k8s.io/kubelet v0.32.2 h1:WFTSYdt3BB1aTApDuKNI16x/4MYqqX8WBBBBh3KupDg=
k8s.io/kubelet v0.32.2/go.mod h1:cC1ms5RS+lu0ckVr6AviCQXHLSPKEBC3D5oaCBdTGkI=
-k8s.io/kubernetes v1.35.6 h1:Kh9V2tfdF+yNVZ1UX5lVfd1zNpa94vdIkfhyAmWXzQI=
-k8s.io/kubernetes v1.35.6/go.mod h1:fPfnQs8GtfrLQ+KuOcpvwQ+mV17jVcgdvPL6ZHxKp10=
-k8s.io/utils v0.0.0-20260210185600-b8788abfbbc2 h1:AZYQSJemyQB5eRxqcPky+/7EdBj0xi3g0ZcxxJ7vbWU=
-k8s.io/utils v0.0.0-20260210185600-b8788abfbbc2/go.mod h1:xDxuJ0whA3d0I4mf/C4ppKHxXynQ+fxnkmQH0vTHnuk=
-sigs.k8s.io/controller-runtime v0.23.3 h1:VjB/vhoPoA9l1kEKZHBMnQF33tdCLQKJtydy4iqwZ80=
-sigs.k8s.io/controller-runtime v0.23.3/go.mod h1:B6COOxKptp+YaUT5q4l6LqUJTRpizbgf9KSRNdQGns0=
-sigs.k8s.io/gateway-api v1.1.0 h1:DsLDXCi6jR+Xz8/xd0Z1PYl2Pn0TyaFMOPPZIj4inDM=
-sigs.k8s.io/gateway-api v1.1.0/go.mod h1:ZH4lHrL2sDi0FHZ9jjneb8kKnGzFWyrTya35sWUTrRs=
+k8s.io/kubernetes v1.36.3 h1:qDQdoMiluAE2Eab6Fa52YV+WjiGz9mZFFoagEA6cI+o=
+k8s.io/kubernetes v1.36.3/go.mod h1:6oChkQeI7Yf6lV9lFpSdRzODdbY/ECp/4zUeBk8ONaw=
+k8s.io/utils v0.0.0-20260707023825-cf1189d6abe3 h1:jVkFFVfXdXP74B/zbO3hM3hpSFD0xvhQ5U686DPurkE=
+k8s.io/utils v0.0.0-20260707023825-cf1189d6abe3/go.mod h1:M2s5JB1lIYP3jzZdorPLHXIPJzt9vv2muW5a6L9DtNM=
+sigs.k8s.io/controller-runtime v0.24.1 h1:miPEwrmirImAvgME1L9qebGHrOnGJoVmVdtOU9fRfo4=
+sigs.k8s.io/controller-runtime v0.24.1/go.mod h1:vFkfY5fGt5xAC/sKb8IBFKgWPNKG9OUG29dR8Y2wImw=
+sigs.k8s.io/gateway-api v1.6.0 h1:735YBRj5NXFrOGX0GoSjwzUIzbz8kiEOfADsqHFmHgE=
+sigs.k8s.io/gateway-api v1.6.0/go.mod h1:FVfx3t389ybeXOqvDghLbdvJdSCfI/PReqCUI3lu3mY=
sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 h1:IpInykpT6ceI+QxKBbEflcR5EXP7sU1kvOlxwZh5txg=
sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg=
sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU=
sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY=
-sigs.k8s.io/structured-merge-diff/v6 v6.3.2 h1:kwVWMx5yS1CrnFWA/2QHyRVJ8jM6dBA80uLmm0wJkk8=
-sigs.k8s.io/structured-merge-diff/v6 v6.3.2/go.mod h1:M3W8sfWvn2HhQDIbGWj3S099YozAsymCo/wrT5ohRUE=
+sigs.k8s.io/structured-merge-diff/v6 v6.4.2 h1:qdOxHwrl2Kaag1aQEarlYcOA9vSyGCp3CIki3aW8c4Q=
+sigs.k8s.io/structured-merge-diff/v6 v6.4.2/go.mod h1:M3W8sfWvn2HhQDIbGWj3S099YozAsymCo/wrT5ohRUE=
sigs.k8s.io/yaml v1.6.0 h1:G8fkbMSAFqgEFgh4b1wmtzDnioxFCUgTZhlbj5P9QYs=
sigs.k8s.io/yaml v1.6.0/go.mod h1:796bPqUfzR/0jLAl6XjHl3Ck7MiyVv8dbTdyT3/pMf4=
diff --git a/go.work.sum b/go.work.sum
index a9cafe254..0c51a3adb 100644
--- a/go.work.sum
+++ b/go.work.sum
@@ -1,5 +1,3 @@
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I=
github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc=
github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc=
-k8s.io/gengo v0.0.0-20230829151522-9cce18d56c01 h1:pWEwq4Asjm4vjW7vcsmijwBhOr1/shsbSYiWXmNGlks=
-k8s.io/klog v0.2.0 h1:0ElL0OHzF3N+OhoJTL0uca20SxtYt4X4+bzHeqrB83c=
diff --git a/images/ci/Dockerfile b/images/ci/Dockerfile
index 1a52c34fa..c3a348161 100644
--- a/images/ci/Dockerfile
+++ b/images/ci/Dockerfile
@@ -1,5 +1,5 @@
# Build the external-secrets-operator binary
-FROM registry.ci.openshift.org/ocp/builder:rhel-9-golang-1.26-openshift-4.23 AS builder
+FROM registry.ci.openshift.org/ocp/builder:rhel-9-golang-1.26-openshift-5.0 AS builder
ARG SRC_DIR=/go/src/github.com/openshift/external-secrets-operator
ENV GO_BUILD_TAGS=strictfipsruntime,openssl
@@ -14,7 +14,7 @@ COPY . .
RUN go build -tags $GO_BUILD_TAGS -o external-secrets-operator cmd/external-secrets-operator/main.go
-FROM registry.access.redhat.com/ubi9-minimal:9.4
+FROM registry.access.redhat.com/ubi9/ubi-minimal:latest
ARG SRC_DIR=/go/src/github.com/openshift/external-secrets-operator
COPY --from=builder $SRC_DIR/external-secrets-operator /bin/external-secrets-operator
USER 65534:65534
diff --git a/images/ci/Dockerfile.coverage b/images/ci/Dockerfile.coverage
index ceecbebd6..b4d1ac508 100644
--- a/images/ci/Dockerfile.coverage
+++ b/images/ci/Dockerfile.coverage
@@ -1,7 +1,7 @@
# Build the external-secrets-operator binary with coverage instrumentation.
# This mirrors images/ci/Dockerfile but adds Go coverage flags so the binary
# records which lines are executed during E2E tests.
-FROM registry.ci.openshift.org/ocp/builder:rhel-9-golang-1.26-openshift-4.23 AS builder
+FROM registry.ci.openshift.org/ocp/builder:rhel-9-golang-1.26-openshift-5.0 AS builder
ARG SRC_DIR=/go/src/github.com/openshift/external-secrets-operator
ENV GO_BUILD_TAGS=strictfipsruntime,openssl
diff --git a/images/ci/operand.Dockerfile b/images/ci/operand.Dockerfile
index d0ba50dad..3b8087a23 100644
--- a/images/ci/operand.Dockerfile
+++ b/images/ci/operand.Dockerfile
@@ -1,4 +1,4 @@
-FROM registry.ci.openshift.org/ocp/builder:rhel-9-golang-1.26-openshift-4.23 AS builder
+FROM registry.ci.openshift.org/ocp/builder:rhel-9-golang-1.26-openshift-5.0 AS builder
ARG RELEASE_BRANCH=v2.5.0
ARG GO_BUILD_TAGS=strictfipsruntime,openssl
@@ -12,7 +12,7 @@ RUN git clone --depth 1 --branch $RELEASE_BRANCH https://github.com/openshift/ex
RUN go mod vendor
RUN go build -mod=vendor -tags $GO_BUILD_TAGS -o _output/external-secrets main.go
-FROM registry.access.redhat.com/ubi9-minimal:9.4
+FROM registry.access.redhat.com/ubi9/ubi-minimal:latest
ARG SRC_DIR=/go/src/github.com/openshift/external-secrets
COPY --from=builder $SRC_DIR/_output/external-secrets /bin/external-secrets
diff --git a/pkg/controller/external_secrets/certificate.go b/pkg/controller/external_secrets/certificate.go
index bf91f500b..1e7c9600f 100644
--- a/pkg/controller/external_secrets/certificate.go
+++ b/pkg/controller/external_secrets/certificate.go
@@ -126,7 +126,7 @@ func (r *Reconciler) updateCertificateParams(esc *operatorv1alpha1.ExternalSecre
}
externalSecretsNamespace := getNamespace(esc)
- certificate.Spec.IssuerRef = v1.ObjectReference{
+ certificate.Spec.IssuerRef = v1.IssuerReference{
Name: certManageConfig.IssuerRef.Name,
Kind: certManageConfig.IssuerRef.Kind,
Group: certManageConfig.IssuerRef.Group,
@@ -159,7 +159,7 @@ func (r *Reconciler) updateCertificateParams(esc *operatorv1alpha1.ExternalSecre
return nil
}
-func (r *Reconciler) assertIssuerRefExists(issueRef v1.ObjectReference, namespace string) error {
+func (r *Reconciler) assertIssuerRefExists(issueRef v1.IssuerReference, namespace string) error {
issuerExists, err := r.getIssuer(issueRef, namespace)
if err != nil {
if errors.Is(err, errUnsupportedIssuerKind) {
@@ -208,7 +208,7 @@ func (r *Reconciler) assertSecretRefExists(esc *operatorv1alpha1.ExternalSecrets
return nil
}
-func (r *Reconciler) getIssuer(issuerRef v1.ObjectReference, namespace string) (issuerExists bool, err error) {
+func (r *Reconciler) getIssuer(issuerRef v1.IssuerReference, namespace string) (issuerExists bool, err error) {
namespacedName := types.NamespacedName{
Name: issuerRef.Name,
Namespace: namespace,
@@ -231,7 +231,7 @@ func (r *Reconciler) getIssuer(issuerRef v1.ObjectReference, namespace string) (
return issuerExists, nil
}
-func issuerNotFoundError(issueRef v1.ObjectReference) error {
+func issuerNotFoundError(issueRef v1.IssuerReference) error {
return apierrors.NewNotFound(issuerGroupResource(issueRef.Kind), issueRef.Name)
}
diff --git a/pkg/operator/assets/bindata.go b/pkg/operator/assets/bindata.go
index c992bbba3..3be0e73e9 100644
--- a/pkg/operator/assets/bindata.go
+++ b/pkg/operator/assets/bindata.go
@@ -159,7 +159,7 @@ metadata:
labels:
app.kubernetes.io/name: external-secrets-webhook
app.kubernetes.io/instance: external-secrets
- app.kubernetes.io/version: "v1.2.0"
+ app.kubernetes.io/version: "v1.3.0"
app.kubernetes.io/managed-by: external-secrets-operator
external-secrets.io/component: webhook
spec:
@@ -209,7 +209,7 @@ metadata:
labels:
app.kubernetes.io/name: bitwarden-sdk-server
app.kubernetes.io/instance: external-secrets
- app.kubernetes.io/version: "v1.2.0"
+ app.kubernetes.io/version: "v1.3.0"
app.kubernetes.io/managed-by: external-secrets-operator
spec:
podSelector:
@@ -254,7 +254,7 @@ metadata:
labels:
app.kubernetes.io/name: external-secrets-cert-controller
app.kubernetes.io/instance: external-secrets
- app.kubernetes.io/version: "v1.2.0"
+ app.kubernetes.io/version: "v1.3.0"
app.kubernetes.io/managed-by: external-secrets-operator
spec:
podSelector:
@@ -300,7 +300,7 @@ metadata:
labels:
app.kubernetes.io/name: external-secrets
app.kubernetes.io/instance: external-secrets
- app.kubernetes.io/version: "v1.2.0"
+ app.kubernetes.io/version: "v1.3.0"
app.kubernetes.io/managed-by: external-secrets-operator
spec:
podSelector:
@@ -344,7 +344,7 @@ metadata:
labels:
app.kubernetes.io/name: external-secrets
app.kubernetes.io/instance: external-secrets
- app.kubernetes.io/version: "v1.2.0"
+ app.kubernetes.io/version: "v1.3.0"
app.kubernetes.io/managed-by: external-secrets-operator
name: eso-sys-allow-to-dns
spec:
@@ -398,7 +398,7 @@ metadata:
labels:
app.kubernetes.io/name: external-secrets
app.kubernetes.io/instance: external-secrets
- app.kubernetes.io/version: "v1.2.0"
+ app.kubernetes.io/version: "v1.3.0"
app.kubernetes.io/managed-by: external-secrets-operator
spec:
podSelector: {}
diff --git a/test/apis/generator.go b/test/apis/generator.go
index 70c2f84b3..f81751ccb 100644
--- a/test/apis/generator.go
+++ b/test/apis/generator.go
@@ -5,6 +5,7 @@ import (
"fmt"
"os"
"path/filepath"
+ "regexp"
"strings"
. "github.com/onsi/ginkgo/v2" //nolint:staticcheck // ST1001 dot imports are idiomatic for Ginkgo
@@ -163,7 +164,7 @@ func generateOnCreateTable(onCreateTests []OnCreateTestSpec) {
err = k8sClient.Create(ctx, initialObj)
if in.expectedError != "" {
- Expect(err).To(MatchError(ContainSubstring(in.expectedError)))
+ matchExpectedAPIError(err, in.expectedError)
return
}
Expect(err).ToNot(HaveOccurred())
@@ -311,7 +312,7 @@ func generateOnUpdateTable(onUpdateTests []OnUpdateTestSpec, crdFileName string)
err = k8sClient.Update(ctx, updatedObj)
if in.expectedError != "" {
- Expect(err).To(MatchError(ContainSubstring(in.expectedError)))
+ matchExpectedAPIError(err, in.expectedError)
return
}
Expect(err).ToNot(HaveOccurred(), "unexpected error updating spec")
@@ -321,7 +322,7 @@ func generateOnUpdateTable(onUpdateTests []OnUpdateTestSpec, crdFileName string)
err := k8sClient.Status().Update(ctx, updatedObj)
if in.expectedStatusError != "" {
- Expect(err).To(MatchError(ContainSubstring(in.expectedStatusError)))
+ matchExpectedAPIError(err, in.expectedStatusError)
return
}
Expect(err).ToNot(HaveOccurred(), "unexpected error updating status")
@@ -583,3 +584,26 @@ func perTestRuntimeInfo(suitePath, crdName string) (*PerTestRuntimeInfo, error)
}
return ret, nil
}
+
+// normalizeValidationError strips volatile formatting from Kubernetes API validation error
+// messages so assertions remain stable across envtest/Kubernetes versions.
+func normalizeValidationError(msg string) string {
+ // Handle "null" before the generic quoted-value matcher below.
+ msg = strings.ReplaceAll(msg, `Invalid value: "null":`, `Invalid value: null:`)
+ msg = invalidValuePrefixRE.ReplaceAllString(msg, `Invalid value: `)
+ msg = strings.ReplaceAll(msg, `map[string]interface {}`, ``)
+ msg = duplicateValueRE.ReplaceAllStringFunc(msg, func(s string) string {
+ return strings.ReplaceAll(s, `, `, `,`)
+ })
+ return msg
+}
+
+var (
+ invalidValuePrefixRE = regexp.MustCompile(`Invalid value: "[^"]*": `)
+ duplicateValueRE = regexp.MustCompile(`Duplicate value: \{[^}]+\}`)
+)
+
+func matchExpectedAPIError(err error, expected string) {
+ Expect(err).To(HaveOccurred())
+ Expect(normalizeValidationError(err.Error())).To(ContainSubstring(normalizeValidationError(expected)))
+}
diff --git a/test/go.mod b/test/go.mod
index f7f19eb0f..f450962fd 100644
--- a/test/go.mod
+++ b/test/go.mod
@@ -2,26 +2,28 @@ module github.com/openshift/external-secrets-operator/test
go 1.26.0
+replace github.com/openshift/external-secrets-operator => ..
+
require (
github.com/aws/aws-sdk-go v1.55.8
- github.com/cert-manager/cert-manager v1.18.5
+ github.com/cert-manager/cert-manager v1.21.1
github.com/ghodss/yaml v1.0.0
- github.com/onsi/ginkgo/v2 v2.27.4
- github.com/onsi/gomega v1.39.0
+ github.com/onsi/ginkgo/v2 v2.32.1
+ github.com/onsi/gomega v1.40.0
github.com/openshift/external-secrets-operator v0.0.0-00010101000000-000000000000
github.com/operator-framework/api v0.42.0
github.com/stretchr/testify v1.11.1
github.com/vmware-archive/yaml-patch v0.0.11
- k8s.io/api v0.35.6
- k8s.io/apiextensions-apiserver v0.35.3
- k8s.io/apimachinery v0.35.6
- k8s.io/client-go v0.35.6
- sigs.k8s.io/controller-runtime v0.23.3
+ k8s.io/api v0.36.3
+ k8s.io/apiextensions-apiserver v0.36.3
+ k8s.io/apimachinery v0.36.3
+ k8s.io/client-go v0.36.3
+ sigs.k8s.io/controller-runtime v0.24.1
sigs.k8s.io/yaml v1.6.0
)
require (
- github.com/Masterminds/semver/v3 v3.4.0 // indirect
+ github.com/Masterminds/semver/v3 v3.5.0 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/blang/semver/v4 v4.0.0 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
@@ -29,29 +31,29 @@ require (
github.com/distribution/reference v0.6.0 // indirect
github.com/emicklei/go-restful/v3 v3.13.0 // indirect
github.com/evanphx/json-patch/v5 v5.9.11 // indirect
- github.com/fsnotify/fsnotify v1.9.0 // indirect
- github.com/fxamacker/cbor/v2 v2.9.0 // indirect
- github.com/go-logr/logr v1.4.3 // indirect
+ github.com/fsnotify/fsnotify v1.10.0 // indirect
+ github.com/fxamacker/cbor/v2 v2.9.3 // indirect
+ github.com/go-logr/logr v1.4.4 // indirect
github.com/go-logr/zapr v1.3.0 // indirect
- github.com/go-openapi/jsonpointer v0.22.4 // indirect
- github.com/go-openapi/jsonreference v0.21.4 // indirect
- github.com/go-openapi/swag v0.25.4 // indirect
- github.com/go-openapi/swag/cmdutils v0.25.4 // indirect
- github.com/go-openapi/swag/conv v0.25.4 // indirect
- github.com/go-openapi/swag/fileutils v0.25.4 // indirect
- github.com/go-openapi/swag/jsonname v0.25.4 // indirect
- github.com/go-openapi/swag/jsonutils v0.25.4 // indirect
- github.com/go-openapi/swag/loading v0.25.4 // indirect
- github.com/go-openapi/swag/mangling v0.25.4 // indirect
- github.com/go-openapi/swag/netutils v0.25.4 // indirect
- github.com/go-openapi/swag/stringutils v0.25.4 // indirect
- github.com/go-openapi/swag/typeutils v0.25.4 // indirect
- github.com/go-openapi/swag/yamlutils v0.25.4 // indirect
+ github.com/go-openapi/jsonpointer v1.0.0 // indirect
+ github.com/go-openapi/jsonreference v1.0.0 // indirect
+ github.com/go-openapi/swag v0.28.0 // indirect
+ github.com/go-openapi/swag/cmdutils v0.28.0 // indirect
+ github.com/go-openapi/swag/conv v0.28.0 // indirect
+ github.com/go-openapi/swag/fileutils v0.28.0 // indirect
+ github.com/go-openapi/swag/jsonutils v0.28.0 // indirect
+ github.com/go-openapi/swag/loading v0.28.0 // indirect
+ github.com/go-openapi/swag/mangling v0.28.0 // indirect
+ github.com/go-openapi/swag/netutils v0.28.0 // indirect
+ github.com/go-openapi/swag/pools v0.28.0 // indirect
+ github.com/go-openapi/swag/stringutils v0.28.0 // indirect
+ github.com/go-openapi/swag/typeutils v0.28.0 // indirect
+ github.com/go-openapi/swag/yamlutils v0.28.0 // indirect
github.com/go-task/slim-sprig/v3 v3.0.0 // indirect
- github.com/google/btree v1.1.3 // indirect
+ github.com/goccy/go-yaml v1.19.2 // indirect
github.com/google/gnostic-models v0.7.1 // indirect
github.com/google/go-cmp v0.7.0 // indirect
- github.com/google/pprof v0.0.0-20260115054156-294ebfa9ad83 // indirect
+ github.com/google/pprof v0.0.0-20260802141513-ef3492d7dac3 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 // indirect
github.com/jmespath/go-jmespath v0.4.1-0.20220621161143-b0104c826a24 // indirect
@@ -61,52 +63,50 @@ require (
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
- github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect
github.com/onsi/ginkgo v1.16.5 // indirect
github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/prometheus/client_golang v1.23.2 // indirect
github.com/prometheus/client_model v0.6.2 // indirect
github.com/prometheus/common v0.67.5 // indirect
- github.com/prometheus/procfs v0.19.2 // indirect
+ github.com/prometheus/procfs v0.20.1 // indirect
github.com/robfig/cron/v3 v3.0.1 // indirect
github.com/sirupsen/logrus v1.9.4 // indirect
github.com/spf13/pflag v1.0.10 // indirect
github.com/x448/float16 v0.8.4 // indirect
- go.opentelemetry.io/otel v1.41.0 // indirect
- go.opentelemetry.io/otel/trace v1.41.0 // indirect
+ go.opentelemetry.io/otel v1.44.0 // indirect
+ go.opentelemetry.io/otel/trace v1.44.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
- go.uber.org/zap v1.27.1 // indirect
- go.yaml.in/yaml/v2 v2.4.3 // indirect
- go.yaml.in/yaml/v3 v3.0.4 // indirect
- golang.org/x/mod v0.38.0 // indirect
+ go.uber.org/zap v1.28.0 // indirect
+ go.yaml.in/yaml/v2 v2.4.4 // indirect
+ go.yaml.in/yaml/v3 v3.0.5 // indirect
+ golang.org/x/mod v0.40.0 // indirect
golang.org/x/net v0.58.0 // indirect
- golang.org/x/oauth2 v0.34.0 // indirect
+ golang.org/x/oauth2 v0.36.0 // indirect
golang.org/x/sync v0.22.0 // indirect
golang.org/x/sys v0.47.0 // indirect
golang.org/x/term v0.45.0 // indirect
golang.org/x/text v0.41.0 // indirect
- golang.org/x/time v0.14.0 // indirect
- golang.org/x/tools v0.48.0 // indirect
+ golang.org/x/time v0.15.0 // indirect
+ golang.org/x/tools v0.49.0 // indirect
gomodules.xyz/jsonpatch/v2 v2.5.0 // indirect
- google.golang.org/protobuf v1.36.12-0.20260120151049-f2248ac996af // indirect
+ google.golang.org/protobuf v1.36.12 // indirect
gopkg.in/evanphx/json-patch.v4 v4.13.0 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
- k8s.io/apiserver v0.35.6 // indirect
- k8s.io/component-base v0.35.6 // indirect
+ k8s.io/apiserver v0.36.3 // indirect
+ k8s.io/component-base v0.36.3 // indirect
k8s.io/component-helpers v0.35.6 // indirect
k8s.io/controller-manager v0.35.6 // indirect
k8s.io/klog/v2 v2.140.0 // indirect
- k8s.io/kube-openapi v0.0.0-20260317180543-43fb72c5454a // indirect
+ k8s.io/kube-openapi v0.0.0-20260721132016-d427ff9ee9ad // indirect
k8s.io/kubelet v0.32.2 // indirect
- k8s.io/kubernetes v1.35.6 // indirect
- k8s.io/utils v0.0.0-20260210185600-b8788abfbbc2 // indirect
- sigs.k8s.io/gateway-api v1.1.0 // indirect
+ k8s.io/kubernetes v1.36.3 // indirect
+ k8s.io/streaming v0.36.3 // indirect
+ k8s.io/utils v0.0.0-20260707023825-cf1189d6abe3 // indirect
+ sigs.k8s.io/gateway-api v1.6.0 // indirect
sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect
sigs.k8s.io/randfill v1.0.0 // indirect
- sigs.k8s.io/structured-merge-diff/v6 v6.3.2 // indirect
+ sigs.k8s.io/structured-merge-diff/v6 v6.4.2 // indirect
)
-
-replace github.com/openshift/external-secrets-operator => ..
diff --git a/test/go.sum b/test/go.sum
index 44dbbdbff..dbe35e0bd 100644
--- a/test/go.sum
+++ b/test/go.sum
@@ -1,5 +1,5 @@
-github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0=
-github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=
+github.com/Masterminds/semver/v3 v3.5.0 h1:kQceYJfbupGfZOKZQg0kou0DgAKhzDg2NZPAwZ/2OOE=
+github.com/Masterminds/semver/v3 v3.5.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
github.com/aws/aws-sdk-go v1.55.8 h1:JRmEUbU52aJQZ2AjX4q4Wu7t4uZjOu71uyNmaWlUkJQ=
@@ -8,8 +8,8 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM=
github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ=
-github.com/cert-manager/cert-manager v1.18.5 h1:Gx4FSpSPYcSC4MQf43QjbxDfyTEbwZgfZQs5Lq9QlBs=
-github.com/cert-manager/cert-manager v1.18.5/go.mod h1:HbPSO5MW/44wu19t84eY/K4c4/WwyPB4bA3uffOH92s=
+github.com/cert-manager/cert-manager v1.21.1 h1:0LttV37Q5c2CBNoHkjuI8sLKTXWZDC2SwQkxrBMKV9w=
+github.com/cert-manager/cert-manager v1.21.1/go.mod h1:sVwmLBWoiB1BRd0rJElBGQuiu94z4k7p3Kd0FRQyfgw=
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@@ -26,10 +26,10 @@ github.com/evanphx/json-patch/v5 v5.9.11 h1:/8HVnzMq13/3x9TPvjG08wUGqBTmZBsCWzjT
github.com/evanphx/json-patch/v5 v5.9.11/go.mod h1:3j+LviiESTElxA4p3EMKAB9HXj3/XEtnUf6OZxqIQTM=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
-github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k=
-github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
-github.com/fxamacker/cbor/v2 v2.9.0 h1:NpKPmjDBgUfBms6tr6JZkTHtfFGcMKsw3eGcmD/sapM=
-github.com/fxamacker/cbor/v2 v2.9.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ=
+github.com/fsnotify/fsnotify v1.10.0 h1:Xx/5Ydg9CeBDX/wi4VJqStNtohYjitZhhlHt4h3St1M=
+github.com/fsnotify/fsnotify v1.10.0/go.mod h1:TLheqan6HD6GBK6PrDWyDPBaEV8LspOxvPSjC+bVfgo=
+github.com/fxamacker/cbor/v2 v2.9.3 h1:oQBnFATpNdY8gJHTndDDv5Xl4QqNaz51G5LLEPhng3Q=
+github.com/fxamacker/cbor/v2 v2.9.3/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ=
github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/gkampitakis/ciinfo v0.3.2 h1:JcuOPk8ZU7nZQjdUhctuhQofk7BGHuIy0c9Ez8BNhXs=
@@ -38,49 +38,49 @@ github.com/gkampitakis/go-diff v1.3.2 h1:Qyn0J9XJSDTgnsgHRdz9Zp24RaJeKMUHg2+PDZZ
github.com/gkampitakis/go-diff v1.3.2/go.mod h1:LLgOrpqleQe26cte8s36HTWcTmMEur6OPYerdAAS9tk=
github.com/gkampitakis/go-snaps v0.5.15 h1:amyJrvM1D33cPHwVrjo9jQxX8g/7E2wYdZ+01KS3zGE=
github.com/gkampitakis/go-snaps v0.5.15/go.mod h1:HNpx/9GoKisdhw9AFOBT1N7DBs9DiHo/hGheFGBZ+mc=
-github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
-github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
+github.com/go-logr/logr v1.4.4 h1:tG4xh9yMsRCAiodLVTxyrkzSZ9+o0L1Kg/+cPVcbP/8=
+github.com/go-logr/logr v1.4.4/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ=
github.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR8/Gg=
-github.com/go-openapi/jsonpointer v0.22.4 h1:dZtK82WlNpVLDW2jlA1YCiVJFVqkED1MegOUy9kR5T4=
-github.com/go-openapi/jsonpointer v0.22.4/go.mod h1:elX9+UgznpFhgBuaMQ7iu4lvvX1nvNsesQ3oxmYTw80=
-github.com/go-openapi/jsonreference v0.21.4 h1:24qaE2y9bx/q3uRK/qN+TDwbok1NhbSmGjjySRCHtC8=
-github.com/go-openapi/jsonreference v0.21.4/go.mod h1:rIENPTjDbLpzQmQWCj5kKj3ZlmEh+EFVbz3RTUh30/4=
-github.com/go-openapi/swag v0.25.4 h1:OyUPUFYDPDBMkqyxOTkqDYFnrhuhi9NR6QVUvIochMU=
-github.com/go-openapi/swag v0.25.4/go.mod h1:zNfJ9WZABGHCFg2RnY0S4IOkAcVTzJ6z2Bi+Q4i6qFQ=
-github.com/go-openapi/swag/cmdutils v0.25.4 h1:8rYhB5n6WawR192/BfUu2iVlxqVR9aRgGJP6WaBoW+4=
-github.com/go-openapi/swag/cmdutils v0.25.4/go.mod h1:pdae/AFo6WxLl5L0rq87eRzVPm/XRHM3MoYgRMvG4A0=
-github.com/go-openapi/swag/conv v0.25.4 h1:/Dd7p0LZXczgUcC/Ikm1+YqVzkEeCc9LnOWjfkpkfe4=
-github.com/go-openapi/swag/conv v0.25.4/go.mod h1:3LXfie/lwoAv0NHoEuY1hjoFAYkvlqI/Bn5EQDD3PPU=
-github.com/go-openapi/swag/fileutils v0.25.4 h1:2oI0XNW5y6UWZTC7vAxC8hmsK/tOkWXHJQH4lKjqw+Y=
-github.com/go-openapi/swag/fileutils v0.25.4/go.mod h1:cdOT/PKbwcysVQ9Tpr0q20lQKH7MGhOEb6EwmHOirUk=
-github.com/go-openapi/swag/jsonname v0.25.4 h1:bZH0+MsS03MbnwBXYhuTttMOqk+5KcQ9869Vye1bNHI=
-github.com/go-openapi/swag/jsonname v0.25.4/go.mod h1:GPVEk9CWVhNvWhZgrnvRA6utbAltopbKwDu8mXNUMag=
-github.com/go-openapi/swag/jsonutils v0.25.4 h1:VSchfbGhD4UTf4vCdR2F4TLBdLwHyUDTd1/q4i+jGZA=
-github.com/go-openapi/swag/jsonutils v0.25.4/go.mod h1:7OYGXpvVFPn4PpaSdPHJBtF0iGnbEaTk8AvBkoWnaAY=
-github.com/go-openapi/swag/jsonutils/fixtures_test v0.25.4 h1:IACsSvBhiNJwlDix7wq39SS2Fh7lUOCJRmx/4SN4sVo=
-github.com/go-openapi/swag/jsonutils/fixtures_test v0.25.4/go.mod h1:Mt0Ost9l3cUzVv4OEZG+WSeoHwjWLnarzMePNDAOBiM=
-github.com/go-openapi/swag/loading v0.25.4 h1:jN4MvLj0X6yhCDduRsxDDw1aHe+ZWoLjW+9ZQWIKn2s=
-github.com/go-openapi/swag/loading v0.25.4/go.mod h1:rpUM1ZiyEP9+mNLIQUdMiD7dCETXvkkC30z53i+ftTE=
-github.com/go-openapi/swag/mangling v0.25.4 h1:2b9kBJk9JvPgxr36V23FxJLdwBrpijI26Bx5JH4Hp48=
-github.com/go-openapi/swag/mangling v0.25.4/go.mod h1:6dxwu6QyORHpIIApsdZgb6wBk/DPU15MdyYj/ikn0Hg=
-github.com/go-openapi/swag/netutils v0.25.4 h1:Gqe6K71bGRb3ZQLusdI8p/y1KLgV4M/k+/HzVSqT8H0=
-github.com/go-openapi/swag/netutils v0.25.4/go.mod h1:m2W8dtdaoX7oj9rEttLyTeEFFEBvnAx9qHd5nJEBzYg=
-github.com/go-openapi/swag/stringutils v0.25.4 h1:O6dU1Rd8bej4HPA3/CLPciNBBDwZj9HiEpdVsb8B5A8=
-github.com/go-openapi/swag/stringutils v0.25.4/go.mod h1:GTsRvhJW5xM5gkgiFe0fV3PUlFm0dr8vki6/VSRaZK0=
-github.com/go-openapi/swag/typeutils v0.25.4 h1:1/fbZOUN472NTc39zpa+YGHn3jzHWhv42wAJSN91wRw=
-github.com/go-openapi/swag/typeutils v0.25.4/go.mod h1:Ou7g//Wx8tTLS9vG0UmzfCsjZjKhpjxayRKTHXf2pTE=
-github.com/go-openapi/swag/yamlutils v0.25.4 h1:6jdaeSItEUb7ioS9lFoCZ65Cne1/RZtPBZ9A56h92Sw=
-github.com/go-openapi/swag/yamlutils v0.25.4/go.mod h1:MNzq1ulQu+yd8Kl7wPOut/YHAAU/H6hL91fF+E2RFwc=
-github.com/go-openapi/testify/enable/yaml/v2 v2.0.2 h1:0+Y41Pz1NkbTHz8NngxTuAXxEodtNSI1WG1c/m5Akw4=
-github.com/go-openapi/testify/enable/yaml/v2 v2.0.2/go.mod h1:kme83333GCtJQHXQ8UKX3IBZu6z8T5Dvy5+CW3NLUUg=
-github.com/go-openapi/testify/v2 v2.0.2 h1:X999g3jeLcoY8qctY/c/Z8iBHTbwLz7R2WXd6Ub6wls=
-github.com/go-openapi/testify/v2 v2.0.2/go.mod h1:HCPmvFFnheKK2BuwSA0TbbdxJ3I16pjwMkYkP4Ywn54=
+github.com/go-openapi/jsonpointer v1.0.0 h1:kR9tHqY0CtZaOPVFm622dPVNhrvYpwr4uCxgL3h1H8s=
+github.com/go-openapi/jsonpointer v1.0.0/go.mod h1:Z3rw7dWu1p9IgitXCFamSlA5lmDiklEB6vkaxcNZW5Y=
+github.com/go-openapi/jsonreference v1.0.0 h1:jlmTr6torcd1YgDQvSfNmRtKzYDO4FGBkrAdlAVWnpY=
+github.com/go-openapi/jsonreference v1.0.0/go.mod h1:jtwdyGbJk0Xhe5Y+rwtglQP6Sb1WZST4rT32LWB+sv0=
+github.com/go-openapi/swag v0.28.0 h1:xkgbOSKj6DZziNpyqRRAOt3GJGtgjgsd2RoyT30VWuw=
+github.com/go-openapi/swag v0.28.0/go.mod h1:4qYnT3Cqr1p1VknOdPo70evN4rgQnAg6jwApHyxSGIg=
+github.com/go-openapi/swag/cmdutils v0.28.0 h1:7TOeNtkYru1SG8Y34tDh9WBbLsMqGnptuxWiHREPZ4Q=
+github.com/go-openapi/swag/cmdutils v0.28.0/go.mod h1:Sm1MVFMkF6guJJ+pQqHnQA3N0j9qALV3NxzDSv6bETM=
+github.com/go-openapi/swag/conv v0.28.0 h1:GtqqbyFe7vR5Y7ehxG9W6/OvrSFdf1OLeTGp40TqxH8=
+github.com/go-openapi/swag/conv v0.28.0/go.mod h1:mbUE+mzctnhxi864m0Q07SpN8OowD9JhxmxuYvZZD/k=
+github.com/go-openapi/swag/fileutils v0.28.0 h1:Z04XWQD7R8Eq+7GnOrjovBxPPmZzsS4gt2H2GPGIViU=
+github.com/go-openapi/swag/fileutils v0.28.0/go.mod h1:VvJFZLTZS0AI854gEQz5tk7dBESdLjiNUMSZ/th2ry8=
+github.com/go-openapi/swag/jsonutils v0.28.0 h1:YIch6FwO7RXzeAnbO8Tu7dWBZeUEH+4nA0HXltVTnv4=
+github.com/go-openapi/swag/jsonutils v0.28.0/go.mod h1:CYM3WlTUcagR2ZoHdz54di/cbBqt82tuxuXgAjxw+mg=
+github.com/go-openapi/swag/jsonutils/fixtures_test v0.28.0 h1:qV+VVUAx5Oro8WjVWpZeql7YReTKhT4smR4zhcOQZr0=
+github.com/go-openapi/swag/jsonutils/fixtures_test v0.28.0/go.mod h1:mofwUWx70wvskwESqRJ//k/9kURmCgyJl5m5Ppoh5kY=
+github.com/go-openapi/swag/loading v0.28.0 h1:td8QZdZC9MIYGGSnSPKShKiK22I2tU5UQvuUhIBPRLU=
+github.com/go-openapi/swag/loading v0.28.0/go.mod h1:rXB0QiQX5mMveXEA7ouM4KiiM9jVJe4K6BVbwhD1M4k=
+github.com/go-openapi/swag/mangling v0.28.0 h1:pH8eyeNO9SLYsTMWJrurnNfKmDa28XrlA+HePVD53VM=
+github.com/go-openapi/swag/mangling v0.28.0/go.mod h1:jtBE2+V+3pILxOR7Vgce+Cwp6A2PgZbvVqfNntbVs0w=
+github.com/go-openapi/swag/netutils v0.28.0 h1:YXN6TALEi2pzts8/8GNm6T61HTAZsieukGZidap989k=
+github.com/go-openapi/swag/netutils v0.28.0/go.mod h1:J+WYyFMLtvtCGqa6jLv+YNUmIKI3ZRQRrvfNDMoQoEQ=
+github.com/go-openapi/swag/pools v0.28.0 h1:HPMZWSAfce3rdVTFcjFiCIBtDg9h4x2QlRrHipwhxeU=
+github.com/go-openapi/swag/pools v0.28.0/go.mod h1:kVQefhSK5RWuRe7BXsL8htgBPAMpN7HDGpGEknqugeE=
+github.com/go-openapi/swag/stringutils v0.28.0 h1:ixsc9iYgDPubHL/8nSkbnryEHpD2VRlBMLKpQyPXcDU=
+github.com/go-openapi/swag/stringutils v0.28.0/go.mod h1:lzRN95CxXmA03XcDWHLOb6nOMcxCqR5rGY0lOgsfRoM=
+github.com/go-openapi/swag/typeutils v0.28.0 h1:nRBKSBXjDgf01VDPB3fWeD9nQuhCOVeIYAkUx2tbkyY=
+github.com/go-openapi/swag/typeutils v0.28.0/go.mod h1:Srm0xFNRZ1Y+vCxJclo5qzx8aj+1pAKda/YfFPrG0dQ=
+github.com/go-openapi/swag/yamlutils v0.28.0 h1:TV3JXH6DS46KUroDtMLAYHGkdWf5VDq3wVWFirmzROY=
+github.com/go-openapi/swag/yamlutils v0.28.0/go.mod h1:x0q/yndZHEgk9Rx3DyDqzFUmHy55KTvIZldvF2dTJXs=
+github.com/go-openapi/testify/enable/yaml/v2 v2.6.0 h1:gGHwAJ0R/5jU8BEGDbfRNR3hL68dAVi84WuOApp29B0=
+github.com/go-openapi/testify/enable/yaml/v2 v2.6.0/go.mod h1:tY+St1SGq4NFl0QIqdTY4aEdbChAHxhyB77XQi9iJCo=
+github.com/go-openapi/testify/v2 v2.6.0 h1:5PKH2HE7YJ/LuRPQGvSxBRlFXNQhSetBLlGAgUEu3ug=
+github.com/go-openapi/testify/v2 v2.6.0/go.mod h1:SgsVHtfooshd0tublTtJ50FPKhujf47YRqauXXOUxfw=
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
-github.com/goccy/go-yaml v1.18.0 h1:8W7wMFS12Pcas7KU+VVkaiCng+kG8QiFeFwzFb+rwuw=
-github.com/goccy/go-yaml v1.18.0/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA=
+github.com/goccy/go-yaml v1.19.2 h1:PmFC1S6h8ljIz6gMRBopkjP1TVT7xuwrButHID66PoM=
+github.com/goccy/go-yaml v1.19.2/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
@@ -88,8 +88,6 @@ github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrU
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
-github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg=
-github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4=
github.com/google/gnostic-models v0.7.1 h1:SisTfuFKJSKM5CPZkffwi6coztzzeYUhc3v4yxLWH8c=
github.com/google/gnostic-models v0.7.1/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
@@ -100,8 +98,8 @@ github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
-github.com/google/pprof v0.0.0-20260115054156-294ebfa9ad83 h1:z2ogiKUYzX5Is6zr/vP9vJGqPwcdqsWjOt+V8J7+bTc=
-github.com/google/pprof v0.0.0-20260115054156-294ebfa9ad83/go.mod h1:MxpfABSjhmINe3F1It9d+8exIHFvUqtLIRCdOGNXqiI=
+github.com/google/pprof v0.0.0-20260802141513-ef3492d7dac3 h1:LMLX+LgTNWpfvCBdFebv6EsYotImrt/Ppc5cXIriCSo=
+github.com/google/pprof v0.0.0-20260802141513-ef3492d7dac3/go.mod h1:jl5iWTm0/hd5PjEYEOuwAJ57L/CibdZfrqZ5XA5GrCk=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 h1:JeSE6pjso5THxAzdVpqr6/geYxZytqFMBCOtn/ujyeo=
@@ -139,8 +137,6 @@ github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee h1:W5t00kpgFd
github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
-github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f h1:y5//uYreIhSUg3J1GEMiLbxo1LJaP8RfCpH6pymGZus=
-github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
@@ -148,12 +144,12 @@ github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+W
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU=
-github.com/onsi/ginkgo/v2 v2.27.4 h1:fcEcQW/A++6aZAZQNUmNjvA9PSOzefMJBerHJ4t8v8Y=
-github.com/onsi/ginkgo/v2 v2.27.4/go.mod h1:ArE1D/XhNXBXCBkKOLkbsb2c81dQHCRcF5zwn/ykDRo=
+github.com/onsi/ginkgo/v2 v2.32.1 h1:6tlvcDm/3sE8lGJbZ4+d4mO3RLy24/tQWOFzVSQNIfw=
+github.com/onsi/ginkgo/v2 v2.32.1/go.mod h1:+aXOY+vzZ5mu2iI2HpTZUPmM//oQfsNFX6gU9kNcA44=
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
-github.com/onsi/gomega v1.39.0 h1:y2ROC3hKFmQZJNFeGAMeHZKkjBL65mIZcvrLQBF9k6Q=
-github.com/onsi/gomega v1.39.0/go.mod h1:ZCU1pkQcXDO5Sl9/VVEGlDyp+zm0m1cmeG5TOzLgdh4=
+github.com/onsi/gomega v1.40.0 h1:Vtol0e1MghCD2ZVIilPDIg44XSL9l2QAn8ZNaljWcJc=
+github.com/onsi/gomega v1.40.0/go.mod h1:M/Uqpu/8qTjtzCLUA2zJHX9Iilrau25x1PdoSRbWh5A=
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
github.com/operator-framework/api v0.42.0 h1:rkc5V3zW8RxZMjePAe12jdL7Co/hwsYo1pLnkkhuR7s=
@@ -169,8 +165,8 @@ github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNw
github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE=
github.com/prometheus/common v0.67.5 h1:pIgK94WWlQt1WLwAC5j2ynLaBRDiinoAb86HZHTUGI4=
github.com/prometheus/common v0.67.5/go.mod h1:SjE/0MzDEEAyrdr5Gqc6G+sXI67maCxzaT3A2+HqjUw=
-github.com/prometheus/procfs v0.19.2 h1:zUMhqEW66Ex7OXIiDkll3tl9a1ZdilUOd/F6ZXw4Vws=
-github.com/prometheus/procfs v0.19.2/go.mod h1:M0aotyiemPhBCM0z5w87kL22CxfcH05ZpYlu+b4J7mw=
+github.com/prometheus/procfs v0.20.1 h1:XwbrGOIplXW/AU3YhIhLODXMJYyC1isLFfYCsTEycfc=
+github.com/prometheus/procfs v0.20.1/go.mod h1:o9EMBZGRyvDrSPH1RqdxhojkuXstoe4UlK79eF5TGGo=
github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
@@ -199,26 +195,26 @@ github.com/vmware-archive/yaml-patch v0.0.11/go.mod h1:mHWEn1O1CU3yBnN6iPFeAwAqz
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
-go.opentelemetry.io/otel v1.41.0 h1:YlEwVsGAlCvczDILpUXpIpPSL/VPugt7zHThEMLce1c=
-go.opentelemetry.io/otel v1.41.0/go.mod h1:Yt4UwgEKeT05QbLwbyHXEwhnjxNO6D8L5PQP51/46dE=
-go.opentelemetry.io/otel/trace v1.41.0 h1:Vbk2co6bhj8L59ZJ6/xFTskY+tGAbOnCtQGVVa9TIN0=
-go.opentelemetry.io/otel/trace v1.41.0/go.mod h1:U1NU4ULCoxeDKc09yCWdWe+3QoyweJcISEVa1RBzOis=
+go.opentelemetry.io/otel v1.44.0 h1:JjwHmHpA4iZ3wBxluu2fbbE7j4kqlE8jXyAyPXH7HqU=
+go.opentelemetry.io/otel v1.44.0/go.mod h1:BMgjTHL9WPRlRjL2oZCBTL4whCGtXch2H4BhOPIAyYc=
+go.opentelemetry.io/otel/trace v1.44.0 h1:jxF5CsGYCe74MCRx2X4g7WsY/VBKRqqpNvXlX/6gtIk=
+go.opentelemetry.io/otel/trace v1.44.0/go.mod h1:oLl1jrMQAVo6v3GAggN+1VH9VIz9iUSvW53sW1Q8PIE=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
-go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc=
-go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
-go.yaml.in/yaml/v2 v2.4.3 h1:6gvOSjQoTB3vt1l+CU+tSyi/HOjfOjRLJ4YwYZGwRO0=
-go.yaml.in/yaml/v2 v2.4.3/go.mod h1:zSxWcmIDjOzPXpjlTTbAsKokqkDNAVtZO0WOMiT90s8=
-go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
-go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
+go.uber.org/zap v1.28.0 h1:IZzaP1Fv73/T/pBMLk4VutPl36uNC+OSUh3JLG3FIjo=
+go.uber.org/zap v1.28.0/go.mod h1:rDLpOi171uODNm/mxFcuYWxDsqWSAVkFdX4XojSKg/Q=
+go.yaml.in/yaml/v2 v2.4.4 h1:tuyd0P+2Ont/d6e2rl3be67goVK4R6deVxCUX5vyPaQ=
+go.yaml.in/yaml/v2 v2.4.4/go.mod h1:gMZqIpDtDqOfM0uNfy0SkpRhvUryYH0Z6wdMYcacYXQ=
+go.yaml.in/yaml/v3 v3.0.5 h1:N6y/pJk8buWs9NY5ERU2HSMfm+IuD/OtfdAnq6kESPw=
+go.yaml.in/yaml/v3 v3.0.5/go.mod h1:HVTZu1O7/Vkt2N+BFy8Zza+lnLsABggaTM2ZpNIGuKg=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
-golang.org/x/mod v0.38.0 h1:MECBjubtXD7yj4HrhIUcywNaGeNVUdfVnxmPajOk4yk=
-golang.org/x/mod v0.38.0/go.mod h1:V6Xz0pq8TQ3dGqVQ1FVHuelZpAL0uNhSkk9ogYP3c40=
+golang.org/x/mod v0.40.0 h1:hUv+3cXcdRHz08UmSiOob7sadHig73uo5bkXxQ/tvUs=
+golang.org/x/mod v0.40.0/go.mod h1:0/weTWkPWGBikyTWAX3dkjVztMmBA5hM0DH6BElSupE=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
@@ -226,8 +222,8 @@ golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.58.0 h1:ynWG7rqYi4ccpTEuPZ2QGWHktVEM9DMCj9yzDE0Q7To=
golang.org/x/net v0.58.0/go.mod h1:YwCddHnFlT7eLQqVprV19OnhLGtc5xOKgE0RyqgfWAU=
-golang.org/x/oauth2 v0.34.0 h1:hqK/t4AKgbqWkdkcAeI8XLmbK+4m4G5YeQRrmiotGlw=
-golang.org/x/oauth2 v0.34.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA=
+golang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs=
+golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -250,13 +246,13 @@ golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.41.0 h1:vz/seA0lnX87Othu2f/0L24RcgrXD9/YFTSuGjj3rH8=
golang.org/x/text v0.41.0/go.mod h1:jvf1O8ajNzZqhSrQBPbutR/EB83Cc0CFrezNQIwbb5M=
-golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI=
-golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4=
+golang.org/x/time v0.15.0 h1:bbrp8t3bGUeFOx08pvsMYRTCVSMk89u4tKbNOZbp88U=
+golang.org/x/time v0.15.0/go.mod h1:Y4YMaQmXwGQZoFaVFk4YpCt4FLQMYKZe9oeV/f4MSno=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
-golang.org/x/tools v0.48.0 h1:3+hClM1aLL5mjMKm5ovokw9epgRXPuu2tILgismM6RE=
-golang.org/x/tools v0.48.0/go.mod h1:08xX0orndb/F7jJxGDicx061tyd5pcMto75YMAXr6lk=
+golang.org/x/tools v0.49.0 h1:3NI7VXzL9+1WZD52Dx2ttoPwD5DWrFGpl9mFZDlmisI=
+golang.org/x/tools v0.49.0/go.mod h1:SJNXV9DBKT0UbdttsQjbfJlAE/q+y36++zo3uL3N0Oo=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@@ -269,8 +265,8 @@ google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQ
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
-google.golang.org/protobuf v1.36.12-0.20260120151049-f2248ac996af h1:+5/Sw3GsDNlEmu7TfklWKPdQ0Ykja5VEmq2i817+jbI=
-google.golang.org/protobuf v1.36.12-0.20260120151049-f2248ac996af/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
+google.golang.org/protobuf v1.36.12 h1:pJOKDDOyeXErUroCihFAd5LQuwXBSpVnKGrj5o/fwxc=
+google.golang.org/protobuf v1.36.12/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
@@ -289,41 +285,43 @@ gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
-k8s.io/api v0.35.6 h1:phPzP79F3kcONsD2TzmDiITNCV6/1Z5U3CCEcjtsXzI=
-k8s.io/api v0.35.6/go.mod h1:GWKUaIp24fuDFigAgnhr9EJOKDqspnwPjYlpDca5B4U=
-k8s.io/apiextensions-apiserver v0.35.3 h1:2fQUhEO7P17sijylbdwt0nBdXP0TvHrHj0KeqHD8FiU=
-k8s.io/apiextensions-apiserver v0.35.3/go.mod h1:tK4Kz58ykRpwAEkXUb634HD1ZAegEElktz/B3jgETd8=
-k8s.io/apimachinery v0.35.6 h1:ASSpfmmsOArKb2Hsu8gGlIcbIcEMVTboI3FfsfYuQ8k=
-k8s.io/apimachinery v0.35.6/go.mod h1:NNi1taPOpep0jOj+oRha3mBJPqvi0hGdaV8TCqGQ+cc=
-k8s.io/apiserver v0.35.6 h1:VWYg2S0wlAmN3URFpVeuLa4PP2RCpTFg1nvlUHOy2C8=
-k8s.io/apiserver v0.35.6/go.mod h1:wajGSrXO9w+lx69jYq4SaE4Xxw5KxxwvVD1zbttYA2E=
-k8s.io/client-go v0.35.6 h1:qZQv9a5B4YlIpXhFBwsI9qPOOJC6Z8lk9lkEWmrmus8=
-k8s.io/client-go v0.35.6/go.mod h1:LOO6N1EhxdQAzYIZ/73cJVyb3gixrMY6ZDJcJ/ANfsY=
-k8s.io/component-base v0.35.6 h1:dTkck9uefkIrKn7wRCEYiDWNUvHd8UdwZCcVafmHgL4=
-k8s.io/component-base v0.35.6/go.mod h1:qcNKrspACsqR+vgUJXkWzwtgUGkURcnrus41o92jjpk=
+k8s.io/api v0.36.3 h1:NxB+05W2UGqXWFXcLO0RB5cnqnUPP5v5sVlaOH0Iz4w=
+k8s.io/api v0.36.3/go.mod h1:JzLQKqRHC5+I8RVj/lS3lCg0mg6nWI9Fo/Sk3ElxHzg=
+k8s.io/apiextensions-apiserver v0.36.3 h1:dPmOAPhwTtqb1bTxbFPsy18KHPhktQeO3WUPXunZIB0=
+k8s.io/apiextensions-apiserver v0.36.3/go.mod h1:KTXFqgXiuw2pRoL+Wpmttqc+up9Xt/GohadPWeLLOa4=
+k8s.io/apimachinery v0.36.3 h1:PkzMRBRG8joFD8EhCuQAtNPvJlxb82FwplP26HIzvAM=
+k8s.io/apimachinery v0.36.3/go.mod h1:cTSjBWgPe/6CQyBKzY/hDIRWCQQQeK0mfLbml0UYFHE=
+k8s.io/apiserver v0.36.3 h1:MGSg2SkdfuytiDEcRylT5mQFmmSsbx90XFUO67Y4bsQ=
+k8s.io/apiserver v0.36.3/go.mod h1:fVH7zv9EUNUA7Fl7LtDKh8aB9W7u1VQPSGtWV5SjUxg=
+k8s.io/client-go v0.36.3 h1:M4JdVzXxYcZk4fGpfDdYnxSwhLKWCFoQsHW6t+z8Hfg=
+k8s.io/client-go v0.36.3/go.mod h1:gcPwr0c87vjjG6HB6pWEqOeuYVoXSsREjzux2j6GF30=
+k8s.io/component-base v0.36.3 h1:vc/UFvPCkW0irPz84LAodAL1j3f4xktPM6dDJIEheAY=
+k8s.io/component-base v0.36.3/go.mod h1:hZbNFG+gCMl9EbykDGEu73feKP9/Cq6JsV4pTo9GTO8=
k8s.io/component-helpers v0.35.6 h1:AEGfqbEWjSM6Tkjtwslv2vQIGIiehvnAVoTDg74QQ0s=
k8s.io/component-helpers v0.35.6/go.mod h1:zog+ILMcmModWjoT1Vsom8sg8IW81mkzom2C/U1lgcs=
k8s.io/controller-manager v0.35.6 h1:NjgU2q6hrrHdT5/mn0tMOHYK5IB5QIVq9QnxUb4iDvU=
k8s.io/controller-manager v0.35.6/go.mod h1:Jq+7QZNSzGoiFaKnobvc0VszFHea6nJyI4U/wgiYOyo=
k8s.io/klog/v2 v2.140.0 h1:Tf+J3AH7xnUzZyVVXhTgGhEKnFqye14aadWv7bzXdzc=
k8s.io/klog/v2 v2.140.0/go.mod h1:o+/RWfJ6PwpnFn7OyAG3QnO47BFsymfEfrz6XyYSSp0=
-k8s.io/kube-openapi v0.0.0-20260317180543-43fb72c5454a h1:xCeOEAOoGYl2jnJoHkC3hkbPJgdATINPMAxaynU2Ovg=
-k8s.io/kube-openapi v0.0.0-20260317180543-43fb72c5454a/go.mod h1:uGBT7iTA6c6MvqUvSXIaYZo9ukscABYi2btjhvgKGZ0=
+k8s.io/kube-openapi v0.0.0-20260721132016-d427ff9ee9ad h1:oXImqH8mQNk7PmvzKhmN3ddJoY6OnyM225MXwGHPm0A=
+k8s.io/kube-openapi v0.0.0-20260721132016-d427ff9ee9ad/go.mod h1:0/mqHCVhlumdJ3BhCfnjSZQE037nAhNodh1/hK0T8/I=
k8s.io/kubelet v0.32.2 h1:WFTSYdt3BB1aTApDuKNI16x/4MYqqX8WBBBBh3KupDg=
k8s.io/kubelet v0.32.2/go.mod h1:cC1ms5RS+lu0ckVr6AviCQXHLSPKEBC3D5oaCBdTGkI=
-k8s.io/kubernetes v1.35.6 h1:Kh9V2tfdF+yNVZ1UX5lVfd1zNpa94vdIkfhyAmWXzQI=
-k8s.io/kubernetes v1.35.6/go.mod h1:fPfnQs8GtfrLQ+KuOcpvwQ+mV17jVcgdvPL6ZHxKp10=
-k8s.io/utils v0.0.0-20260210185600-b8788abfbbc2 h1:AZYQSJemyQB5eRxqcPky+/7EdBj0xi3g0ZcxxJ7vbWU=
-k8s.io/utils v0.0.0-20260210185600-b8788abfbbc2/go.mod h1:xDxuJ0whA3d0I4mf/C4ppKHxXynQ+fxnkmQH0vTHnuk=
-sigs.k8s.io/controller-runtime v0.23.3 h1:VjB/vhoPoA9l1kEKZHBMnQF33tdCLQKJtydy4iqwZ80=
-sigs.k8s.io/controller-runtime v0.23.3/go.mod h1:B6COOxKptp+YaUT5q4l6LqUJTRpizbgf9KSRNdQGns0=
-sigs.k8s.io/gateway-api v1.1.0 h1:DsLDXCi6jR+Xz8/xd0Z1PYl2Pn0TyaFMOPPZIj4inDM=
-sigs.k8s.io/gateway-api v1.1.0/go.mod h1:ZH4lHrL2sDi0FHZ9jjneb8kKnGzFWyrTya35sWUTrRs=
+k8s.io/kubernetes v1.36.3 h1:qDQdoMiluAE2Eab6Fa52YV+WjiGz9mZFFoagEA6cI+o=
+k8s.io/kubernetes v1.36.3/go.mod h1:6oChkQeI7Yf6lV9lFpSdRzODdbY/ECp/4zUeBk8ONaw=
+k8s.io/streaming v0.36.3 h1:9rAaqBk0C0Pc7+/fqGekj07NV+/Xrew58p647A0JT8w=
+k8s.io/streaming v0.36.3/go.mod h1:z6fV3D+NVkoeqRMtWwlUZK6U17SY/LqNzOxWL6GyR/s=
+k8s.io/utils v0.0.0-20260707023825-cf1189d6abe3 h1:jVkFFVfXdXP74B/zbO3hM3hpSFD0xvhQ5U686DPurkE=
+k8s.io/utils v0.0.0-20260707023825-cf1189d6abe3/go.mod h1:M2s5JB1lIYP3jzZdorPLHXIPJzt9vv2muW5a6L9DtNM=
+sigs.k8s.io/controller-runtime v0.24.1 h1:miPEwrmirImAvgME1L9qebGHrOnGJoVmVdtOU9fRfo4=
+sigs.k8s.io/controller-runtime v0.24.1/go.mod h1:vFkfY5fGt5xAC/sKb8IBFKgWPNKG9OUG29dR8Y2wImw=
+sigs.k8s.io/gateway-api v1.6.0 h1:735YBRj5NXFrOGX0GoSjwzUIzbz8kiEOfADsqHFmHgE=
+sigs.k8s.io/gateway-api v1.6.0/go.mod h1:FVfx3t389ybeXOqvDghLbdvJdSCfI/PReqCUI3lu3mY=
sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 h1:IpInykpT6ceI+QxKBbEflcR5EXP7sU1kvOlxwZh5txg=
sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg=
sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU=
sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY=
-sigs.k8s.io/structured-merge-diff/v6 v6.3.2 h1:kwVWMx5yS1CrnFWA/2QHyRVJ8jM6dBA80uLmm0wJkk8=
-sigs.k8s.io/structured-merge-diff/v6 v6.3.2/go.mod h1:M3W8sfWvn2HhQDIbGWj3S099YozAsymCo/wrT5ohRUE=
+sigs.k8s.io/structured-merge-diff/v6 v6.4.2 h1:qdOxHwrl2Kaag1aQEarlYcOA9vSyGCp3CIki3aW8c4Q=
+sigs.k8s.io/structured-merge-diff/v6 v6.4.2/go.mod h1:M3W8sfWvn2HhQDIbGWj3S099YozAsymCo/wrT5ohRUE=
sigs.k8s.io/yaml v1.6.0 h1:G8fkbMSAFqgEFgh4b1wmtzDnioxFCUgTZhlbj5P9QYs=
sigs.k8s.io/yaml v1.6.0/go.mod h1:796bPqUfzR/0jLAl6XjHl3Ck7MiyVv8dbTdyT3/pMf4=
diff --git a/tools/go.mod b/tools/go.mod
index 8e83dc079..6d6c23292 100644
--- a/tools/go.mod
+++ b/tools/go.mod
@@ -2,25 +2,30 @@ module github.com/openshift/external-secrets-operator/tools
go 1.26.0
+// Exclude old monolithic genproto to avoid ambiguous imports with modular versions
+exclude google.golang.org/genproto v0.0.0-20220519153652-3a47de7e79bd
+
require (
- github.com/elastic/crd-ref-docs v0.1.0
+ github.com/elastic/crd-ref-docs v0.3.0
github.com/go-bindata/go-bindata v3.1.2+incompatible
- github.com/golangci/golangci-lint/v2 v2.8.0
- github.com/maxbrunsfeld/counterfeiter/v6 v6.12.0
- github.com/onsi/ginkgo/v2 v2.27.4
- github.com/openshift/build-machinery-go v0.0.0-20250806130835-622c0378eb0d
- golang.org/x/vuln v1.1.4
- sigs.k8s.io/controller-runtime/tools/setup-envtest v0.0.0-20250308055145-5fe7bb3edc86
- sigs.k8s.io/controller-tools v0.19.0
- sigs.k8s.io/kube-api-linter v0.0.0-20251208100930-d3015c953951
- sigs.k8s.io/kustomize/kustomize/v5 v5.7.1
+ github.com/golangci/golangci-lint/v2 v2.12.2
+ github.com/maxbrunsfeld/counterfeiter/v6 v6.12.2
+ github.com/onsi/ginkgo/v2 v2.32.1
+ github.com/openshift/build-machinery-go v0.0.0-20260629141115-154a2b810491
+ golang.org/x/vuln v1.7.0
+ sigs.k8s.io/controller-runtime/tools/setup-envtest v0.24.1
+ sigs.k8s.io/controller-tools v0.21.0
+ sigs.k8s.io/kube-api-linter v0.0.0-20260716143926-092fe0c72997
+ sigs.k8s.io/kustomize/kustomize/v5 v5.8.1
)
require (
4d63.com/gocheckcompilerdirectives v1.3.0 // indirect
4d63.com/gochecknoglobals v0.2.2 // indirect
+ charm.land/lipgloss/v2 v2.0.3 // indirect
codeberg.org/chavacava/garif v0.2.0 // indirect
codeberg.org/polyfloyd/go-errorlint v1.9.0 // indirect
+ dario.cat/mergo v1.0.2 // indirect
dev.gaijin.team/go/exhaustruct/v4 v4.0.0 // indirect
dev.gaijin.team/go/golib v0.6.0 // indirect
github.com/4meepo/tagalign v1.4.3 // indirect
@@ -31,76 +36,77 @@ require (
github.com/Antonboom/nilnil v1.1.1 // indirect
github.com/Antonboom/testifylint v1.6.4 // indirect
github.com/BurntSushi/toml v1.6.0 // indirect
+ github.com/ClickHouse/clickhouse-go-linter v1.2.0 // indirect
github.com/Djarvur/go-err113 v0.1.1 // indirect
github.com/Masterminds/goutils v1.1.1 // indirect
- github.com/Masterminds/semver v1.5.0 // indirect
- github.com/Masterminds/semver/v3 v3.4.0 // indirect
- github.com/Masterminds/sprig v2.22.0+incompatible // indirect
- github.com/MirrexOne/unqueryvet v1.4.0 // indirect
+ github.com/Masterminds/semver/v3 v3.5.0 // indirect
+ github.com/Masterminds/sprig/v3 v3.3.0 // indirect
+ github.com/MirrexOne/unqueryvet v1.5.4 // indirect
github.com/OpenPeeDeeP/depguard/v2 v2.2.1 // indirect
- github.com/alecthomas/chroma/v2 v2.21.1 // indirect
+ github.com/alecthomas/chroma/v2 v2.24.1 // indirect
github.com/alecthomas/go-check-sumtype v0.3.1 // indirect
github.com/alexkohler/nakedret/v2 v2.0.6 // indirect
- github.com/alexkohler/prealloc v1.0.1 // indirect
+ github.com/alexkohler/prealloc v1.1.0 // indirect
github.com/alfatraining/structtag v1.0.0 // indirect
github.com/alingse/asasalint v0.0.11 // indirect
github.com/alingse/nilnesserr v0.2.0 // indirect
- github.com/ashanbrown/forbidigo/v2 v2.3.0 // indirect
- github.com/ashanbrown/makezero/v2 v2.1.0 // indirect
- github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
+ github.com/ashanbrown/forbidigo/v2 v2.3.1 // indirect
+ github.com/ashanbrown/makezero/v2 v2.2.1 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/bkielbasa/cyclop v1.2.3 // indirect
github.com/blang/semver/v4 v4.0.0 // indirect
github.com/blizzy78/varnamelen v0.8.0 // indirect
github.com/bombsimon/wsl/v4 v4.7.0 // indirect
- github.com/bombsimon/wsl/v5 v5.3.0 // indirect
+ github.com/bombsimon/wsl/v5 v5.8.0 // indirect
github.com/breml/bidichk v0.3.3 // indirect
github.com/breml/errchkjson v0.4.1 // indirect
- github.com/butuzov/ireturn v0.4.0 // indirect
+ github.com/butuzov/ireturn v0.4.1 // indirect
github.com/butuzov/mirror v1.3.0 // indirect
github.com/catenacyber/perfsprint v0.10.1 // indirect
github.com/ccojocar/zxcvbn-go v1.0.4 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/charithe/durationcheck v0.0.11 // indirect
- github.com/charmbracelet/colorprofile v0.3.1 // indirect
- github.com/charmbracelet/lipgloss v1.1.0 // indirect
- github.com/charmbracelet/x/ansi v0.9.2 // indirect
- github.com/charmbracelet/x/cellbuf v0.0.13 // indirect
- github.com/charmbracelet/x/term v0.2.1 // indirect
+ github.com/charmbracelet/colorprofile v0.4.3 // indirect
+ github.com/charmbracelet/ultraviolet v0.0.0-20251205161215-1948445e3318 // indirect
+ github.com/charmbracelet/x/ansi v0.11.7 // indirect
+ github.com/charmbracelet/x/term v0.2.2 // indirect
+ github.com/charmbracelet/x/termios v0.1.1 // indirect
+ github.com/charmbracelet/x/windows v0.2.2 // indirect
github.com/ckaznocha/intrange v0.3.1 // indirect
+ github.com/clipperhouse/displaywidth v0.11.0 // indirect
+ github.com/clipperhouse/uax29/v2 v2.7.0 // indirect
github.com/curioswitch/go-reassign v0.3.0 // indirect
github.com/daixiang0/gci v0.13.7 // indirect
github.com/dave/dst v0.27.3 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/denis-tingaikin/go-header v0.5.0 // indirect
- github.com/dlclark/regexp2 v1.11.5 // indirect
+ github.com/dlclark/regexp2 v1.12.0 // indirect
github.com/ettle/strcase v0.2.0 // indirect
- github.com/fatih/color v1.18.0 // indirect
+ github.com/fatih/color v1.19.0 // indirect
github.com/fatih/structtag v1.2.0 // indirect
github.com/firefart/nonamedreturns v1.0.6 // indirect
- github.com/frankban/quicktest v1.14.6 // indirect
- github.com/fsnotify/fsnotify v1.9.0 // indirect
- github.com/fxamacker/cbor/v2 v2.9.0 // indirect
+ github.com/fsnotify/fsnotify v1.10.0 // indirect
+ github.com/fxamacker/cbor/v2 v2.9.3 // indirect
github.com/fzipp/gocyclo v0.6.0 // indirect
- github.com/ghostiam/protogetter v0.3.18 // indirect
+ github.com/ghostiam/protogetter v0.3.20 // indirect
github.com/go-critic/go-critic v0.14.3 // indirect
- github.com/go-errors/errors v1.4.2 // indirect
- github.com/go-logr/logr v1.4.3 // indirect
+ github.com/go-errors/errors v1.5.1 // indirect
+ github.com/go-logr/logr v1.4.4 // indirect
github.com/go-logr/zapr v1.3.0 // indirect
- github.com/go-openapi/jsonpointer v0.22.4 // indirect
- github.com/go-openapi/jsonreference v0.21.4 // indirect
- github.com/go-openapi/swag v0.25.4 // indirect
- github.com/go-openapi/swag/cmdutils v0.25.4 // indirect
- github.com/go-openapi/swag/conv v0.25.4 // indirect
- github.com/go-openapi/swag/fileutils v0.25.4 // indirect
- github.com/go-openapi/swag/jsonname v0.25.4 // indirect
- github.com/go-openapi/swag/jsonutils v0.25.4 // indirect
- github.com/go-openapi/swag/loading v0.25.4 // indirect
- github.com/go-openapi/swag/mangling v0.25.4 // indirect
- github.com/go-openapi/swag/netutils v0.25.4 // indirect
- github.com/go-openapi/swag/stringutils v0.25.4 // indirect
- github.com/go-openapi/swag/typeutils v0.25.4 // indirect
- github.com/go-openapi/swag/yamlutils v0.25.4 // indirect
+ github.com/go-openapi/jsonpointer v1.0.0 // indirect
+ github.com/go-openapi/jsonreference v1.0.0 // indirect
+ github.com/go-openapi/swag v0.28.0 // indirect
+ github.com/go-openapi/swag/cmdutils v0.28.0 // indirect
+ github.com/go-openapi/swag/conv v0.28.0 // indirect
+ github.com/go-openapi/swag/fileutils v0.28.0 // indirect
+ github.com/go-openapi/swag/jsonutils v0.28.0 // indirect
+ github.com/go-openapi/swag/loading v0.28.0 // indirect
+ github.com/go-openapi/swag/mangling v0.28.0 // indirect
+ github.com/go-openapi/swag/netutils v0.28.0 // indirect
+ github.com/go-openapi/swag/pools v0.28.0 // indirect
+ github.com/go-openapi/swag/stringutils v0.28.0 // indirect
+ github.com/go-openapi/swag/typeutils v0.28.0 // indirect
+ github.com/go-openapi/swag/yamlutils v0.28.0 // indirect
github.com/go-task/slim-sprig/v3 v3.0.0 // indirect
github.com/go-toolsmith/astcast v1.1.0 // indirect
github.com/go-toolsmith/astcopy v1.1.0 // indirect
@@ -109,27 +115,28 @@ require (
github.com/go-toolsmith/astp v1.1.0 // indirect
github.com/go-toolsmith/strparse v1.1.0 // indirect
github.com/go-toolsmith/typep v1.1.0 // indirect
- github.com/go-viper/mapstructure/v2 v2.4.0 // indirect
+ github.com/go-viper/mapstructure/v2 v2.5.0 // indirect
github.com/go-xmlfmt/xmlfmt v1.1.3 // indirect
github.com/gobuffalo/flect v1.0.3 // indirect
github.com/gobwas/glob v0.2.3 // indirect
- github.com/goccy/go-yaml v1.18.0 // indirect
- github.com/godoc-lint/godoc-lint v0.11.1 // indirect
+ github.com/goccy/go-yaml v1.19.2 // indirect
+ github.com/godoc-lint/godoc-lint v0.11.2 // indirect
github.com/gofrs/flock v0.13.0 // indirect
github.com/golangci/asciicheck v0.5.0 // indirect
- github.com/golangci/dupl v0.0.0-20250308024227-f665c8d69b32 // indirect
+ github.com/golangci/dupl v0.0.0-20260401084720-c99c5cf5c202 // indirect
github.com/golangci/go-printf-func-name v0.1.1 // indirect
github.com/golangci/gofmt v0.0.0-20250106114630-d62b90e6713d // indirect
- github.com/golangci/golines v0.14.0 // indirect
- github.com/golangci/misspell v0.7.0 // indirect
+ github.com/golangci/golines v0.15.0 // indirect
+ github.com/golangci/misspell v0.8.0 // indirect
github.com/golangci/plugin-module-register v0.1.2 // indirect
github.com/golangci/revgrep v0.8.0 // indirect
+ github.com/golangci/rowserrcheck v0.0.0-20260419091836-c5f79b8a11ba // indirect
github.com/golangci/swaggoswag v0.0.0-20250504205917-77f2aca3143e // indirect
github.com/golangci/unconvert v0.0.0-20250410112200-a129a6e6413e // indirect
github.com/google/cel-go v0.31.0 // indirect
github.com/google/gnostic-models v0.7.1 // indirect
github.com/google/go-cmp v0.7.0 // indirect
- github.com/google/pprof v0.0.0-20260115054156-294ebfa9ad83 // indirect
+ github.com/google/pprof v0.0.0-20260802141513-ef3492d7dac3 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/gordonklaus/ineffassign v0.2.0 // indirect
github.com/gostaticanalysis/analysisutil v0.7.1 // indirect
@@ -137,20 +144,18 @@ require (
github.com/gostaticanalysis/forcetypeassert v0.2.0 // indirect
github.com/gostaticanalysis/nilerr v0.1.2 // indirect
github.com/hashicorp/go-immutable-radix/v2 v2.1.0 // indirect
- github.com/hashicorp/go-version v1.8.0 // indirect
+ github.com/hashicorp/go-version v1.9.0 // indirect
github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect
- github.com/hashicorp/hcl v1.0.1-vault-5 // indirect
+ github.com/hashicorp/hcl v1.0.1-vault-7 // indirect
github.com/hexops/gotextdiff v1.0.3 // indirect
- github.com/huandu/xstrings v1.3.3 // indirect
- github.com/imdario/mergo v0.3.16 // indirect
+ github.com/huandu/xstrings v1.5.0 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
- github.com/jgautheron/goconst v1.8.2 // indirect
- github.com/jingyugao/rowserrcheck v1.1.1 // indirect
+ github.com/jgautheron/goconst v1.10.0 // indirect
github.com/jjti/go-spancheck v0.6.5 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/julz/importas v0.2.0 // indirect
github.com/karamaru-alpha/copyloopvar v1.2.2 // indirect
- github.com/kisielk/errcheck v1.9.0 // indirect
+ github.com/kisielk/errcheck v1.10.0 // indirect
github.com/kkHAIKE/contextcheck v1.1.6 // indirect
github.com/kulti/thelper v0.7.1 // indirect
github.com/kunwardeep/paralleltest v1.0.15 // indirect
@@ -162,18 +167,18 @@ require (
github.com/ldez/tagliatelle v0.7.2 // indirect
github.com/ldez/usetesting v0.5.0 // indirect
github.com/leonklingele/grouper v1.1.2 // indirect
- github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
+ github.com/lucasb-eyer/go-colorful v1.4.0 // indirect
github.com/macabu/inamedparam v0.2.0 // indirect
github.com/magiconair/properties v1.8.6 // indirect
github.com/manuelarte/embeddedstructfieldcheck v0.4.0 // indirect
- github.com/manuelarte/funcorder v0.5.0 // indirect
+ github.com/manuelarte/funcorder v0.6.0 // indirect
github.com/maratori/testableexamples v1.0.1 // indirect
github.com/maratori/testpackage v1.1.2 // indirect
github.com/matoous/godox v1.1.0 // indirect
github.com/mattn/go-colorable v0.1.14 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
- github.com/mattn/go-runewidth v0.0.16 // indirect
- github.com/mgechev/revive v1.13.0 // indirect
+ github.com/mattn/go-runewidth v0.0.23 // indirect
+ github.com/mgechev/revive v1.15.0 // indirect
github.com/mitchellh/copystructure v1.2.0 // indirect
github.com/mitchellh/go-homedir v1.1.0 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
@@ -182,20 +187,19 @@ require (
github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect
github.com/moricho/tparallel v0.3.2 // indirect
- github.com/muesli/termenv v0.16.0 // indirect
+ github.com/muesli/cancelreader v0.2.2 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/nakabonne/nestif v0.3.1 // indirect
github.com/nishanths/exhaustive v0.12.0 // indirect
github.com/nishanths/predeclared v0.2.2 // indirect
- github.com/nunnatsa/ginkgolinter v0.21.2 // indirect
- github.com/onsi/gomega v1.39.0 // indirect
+ github.com/nunnatsa/ginkgolinter v0.23.0 // indirect
github.com/pelletier/go-toml v1.9.5 // indirect
- github.com/pelletier/go-toml/v2 v2.2.4 // indirect
+ github.com/pelletier/go-toml/v2 v2.3.1 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/prometheus/client_golang v1.23.2 // indirect
github.com/prometheus/client_model v0.6.2 // indirect
github.com/prometheus/common v0.67.5 // indirect
- github.com/prometheus/procfs v0.19.2 // indirect
+ github.com/prometheus/procfs v0.20.1 // indirect
github.com/quasilyte/go-ruleguard v0.4.5 // indirect
github.com/quasilyte/go-ruleguard/dsl v0.3.23 // indirect
github.com/quasilyte/gogrep v0.5.0 // indirect
@@ -205,19 +209,21 @@ require (
github.com/rivo/uniseg v0.4.7 // indirect
github.com/rogpeppe/go-internal v1.14.1 // indirect
github.com/ryancurrah/gomodguard v1.4.1 // indirect
- github.com/ryanrolds/sqlclosecheck v0.5.1 // indirect
+ github.com/ryancurrah/gomodguard/v2 v2.1.3 // indirect
+ github.com/ryanrolds/sqlclosecheck v0.6.0 // indirect
github.com/sanposhiho/wastedassign/v2 v2.1.0 // indirect
github.com/santhosh-tekuri/jsonschema/v6 v6.0.2 // indirect
github.com/sashamelentyev/interfacebloat v1.1.0 // indirect
github.com/sashamelentyev/usestdlibvars v1.29.0 // indirect
- github.com/securego/gosec/v2 v2.22.11 // indirect
- github.com/sergi/go-diff v1.2.0 // indirect
+ github.com/securego/gosec/v2 v2.26.1 // indirect
+ github.com/sergi/go-diff v1.4.0 // indirect
+ github.com/shopspring/decimal v1.4.0 // indirect
github.com/sirupsen/logrus v1.9.4 // indirect
github.com/sivchari/containedctx v1.0.3 // indirect
- github.com/sonatard/noctx v0.4.0 // indirect
- github.com/sourcegraph/go-diff v0.7.0 // indirect
+ github.com/sonatard/noctx v0.5.1 // indirect
+ github.com/sourcegraph/go-diff v0.8.0 // indirect
github.com/spf13/afero v1.15.0 // indirect
- github.com/spf13/cast v1.5.0 // indirect
+ github.com/spf13/cast v1.10.0 // indirect
github.com/spf13/cobra v1.10.2 // indirect
github.com/spf13/jwalterweatherman v1.1.0 // indirect
github.com/spf13/pflag v1.0.10 // indirect
@@ -227,15 +233,15 @@ require (
github.com/stretchr/objx v0.5.2 // indirect
github.com/stretchr/testify v1.11.1 // indirect
github.com/subosito/gotenv v1.4.1 // indirect
- github.com/tetafro/godot v1.5.4 // indirect
- github.com/timakin/bodyclose v0.0.0-20241222091800-1db5c5ca4d67 // indirect
+ github.com/tetafro/godot v1.5.6 // indirect
+ github.com/timakin/bodyclose v0.0.0-20260129054331-73d1f95b84b4 // indirect
github.com/timonwong/loggercheck v0.11.0 // indirect
github.com/tomarrell/wrapcheck/v2 v2.12.0 // indirect
github.com/tommy-muehle/go-mnd/v2 v2.5.1 // indirect
github.com/ultraware/funlen v0.2.0 // indirect
github.com/ultraware/whitespace v0.2.0 // indirect
- github.com/uudashr/gocognit v1.2.0 // indirect
- github.com/uudashr/iface v1.4.1 // indirect
+ github.com/uudashr/gocognit v1.2.1 // indirect
+ github.com/uudashr/iface v1.4.2 // indirect
github.com/x448/float16 v0.8.4 // indirect
github.com/xen0n/gosmopolitan v1.3.0 // indirect
github.com/xlab/treeprint v1.2.0 // indirect
@@ -245,58 +251,52 @@ require (
github.com/ykadowak/zerologlint v0.1.5 // indirect
gitlab.com/bosi/decorder v0.4.2 // indirect
go-simpler.org/musttag v0.14.0 // indirect
- go-simpler.org/sloglint v0.11.1 // indirect
- go.augendre.info/arangolint v0.3.1 // indirect
+ go-simpler.org/sloglint v0.12.0 // indirect
+ go.augendre.info/arangolint v0.4.0 // indirect
go.augendre.info/fatcontext v0.9.0 // indirect
- go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.65.0 // indirect
- go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.40.0 // indirect
- go.opentelemetry.io/otel/sdk v1.40.0 // indirect
- go.uber.org/automaxprocs v1.6.0 // indirect
+ go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.67.0 // indirect
+ go.opentelemetry.io/otel/metric v1.44.0 // indirect
+ go.opentelemetry.io/otel/sdk v1.43.0 // indirect
+ go.opentelemetry.io/otel/trace v1.44.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
- go.uber.org/zap v1.27.1 // indirect
- go.yaml.in/yaml/v2 v2.4.3 // indirect
- go.yaml.in/yaml/v3 v3.0.4 // indirect
+ go.uber.org/zap v1.28.0 // indirect
+ go.yaml.in/yaml/v2 v2.4.4 // indirect
+ go.yaml.in/yaml/v3 v3.0.5 // indirect
golang.org/x/crypto v0.55.0 // indirect
golang.org/x/exp v0.0.0-20260112195511-716be5621a96 // indirect
- golang.org/x/exp/typeparams v0.0.0-20251023183803-a4bb9ffd2546 // indirect
- golang.org/x/mod v0.38.0 // indirect
+ golang.org/x/exp/typeparams v0.0.0-20260209203927-2842357ff358 // indirect
+ golang.org/x/mod v0.40.0 // indirect
golang.org/x/net v0.58.0 // indirect
golang.org/x/sync v0.22.0 // indirect
golang.org/x/sys v0.47.0 // indirect
- golang.org/x/telemetry v0.0.0-20260708182218-49f421fb7959 // indirect
+ golang.org/x/telemetry v0.0.0-20260811182544-a038080d80e5 // indirect
golang.org/x/text v0.41.0 // indirect
- golang.org/x/time v0.14.0 // indirect
- golang.org/x/tools v0.48.0 // indirect
- google.golang.org/genproto/googleapis/api v0.0.0-20260202165425-ce8ad4cf556b // indirect
- google.golang.org/genproto/googleapis/rpc v0.0.0-20260202165425-ce8ad4cf556b // indirect
- google.golang.org/grpc v1.79.3 // indirect
- google.golang.org/protobuf v1.36.12-0.20260120151049-f2248ac996af // indirect
+ golang.org/x/tools v0.49.0 // indirect
+ google.golang.org/genproto/googleapis/api v0.0.0-20260414002931-afd174a4e478 // indirect
+ google.golang.org/genproto/googleapis/rpc v0.0.0-20260610212136-7ab31c22f7ad // indirect
+ google.golang.org/grpc v1.82.1 // indirect
+ google.golang.org/protobuf v1.36.12 // indirect
gopkg.in/evanphx/json-patch.v4 v4.13.0 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
- gopkg.in/ini.v1 v1.67.0 // indirect
+ gopkg.in/ini.v1 v1.67.1 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
- honnef.co/go/tools v0.6.1 // indirect
- k8s.io/api v0.35.6 // indirect
- k8s.io/apiextensions-apiserver v0.35.3 // indirect
- k8s.io/apimachinery v0.35.6 // indirect
- k8s.io/apiserver v0.35.6 // indirect
- k8s.io/code-generator v0.35.3 // indirect
- k8s.io/gengo/v2 v2.0.0-20250922181213-ec3ebc5fd46b // indirect
+ honnef.co/go/tools v0.7.0 // indirect
+ k8s.io/api v0.36.3 // indirect
+ k8s.io/apiextensions-apiserver v0.36.3 // indirect
+ k8s.io/apimachinery v0.36.3 // indirect
+ k8s.io/code-generator v0.36.3 // indirect
+ k8s.io/gengo/v2 v2.0.0-20260408192533-25e2208e0dc3 // indirect
k8s.io/klog/v2 v2.140.0 // indirect
- k8s.io/kube-openapi v0.0.0-20260317180543-43fb72c5454a // indirect
- k8s.io/utils v0.0.0-20260210185600-b8788abfbbc2 // indirect
+ k8s.io/kube-openapi v0.0.0-20260721132016-d427ff9ee9ad // indirect
+ k8s.io/utils v0.0.0-20260707023825-cf1189d6abe3 // indirect
mvdan.cc/gofumpt v0.9.2 // indirect
mvdan.cc/unparam v0.0.0-20251027182757-5beb8c8f8f15 // indirect
- sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.34.0 // indirect
sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect
- sigs.k8s.io/kustomize/api v0.20.1 // indirect
- sigs.k8s.io/kustomize/cmd/config v0.20.1 // indirect
- sigs.k8s.io/kustomize/kyaml v0.20.1 // indirect
+ sigs.k8s.io/kustomize/api v0.21.1 // indirect
+ sigs.k8s.io/kustomize/cmd/config v0.21.1 // indirect
+ sigs.k8s.io/kustomize/kyaml v0.21.1 // indirect
sigs.k8s.io/randfill v1.0.0 // indirect
- sigs.k8s.io/structured-merge-diff/v6 v6.3.2 // indirect
+ sigs.k8s.io/structured-merge-diff/v6 v6.4.2 // indirect
sigs.k8s.io/yaml v1.6.0 // indirect
)
-
-// Exclude old monolithic genproto to avoid ambiguous imports with modular versions
-exclude google.golang.org/genproto v0.0.0-20220519153652-3a47de7e79bd
diff --git a/tools/go.sum b/tools/go.sum
index a60986238..fed614ad2 100644
--- a/tools/go.sum
+++ b/tools/go.sum
@@ -4,10 +4,14 @@
4d63.com/gochecknoglobals v0.2.2/go.mod h1:lLxwTQjL5eIesRbvnzIP3jZtG140FnTdz+AlMa+ogt0=
cel.dev/expr v0.25.1 h1:1KrZg61W6TWSxuNZ37Xy49ps13NUovb66QLprthtwi4=
cel.dev/expr v0.25.1/go.mod h1:hrXvqGP6G6gyx8UAHSHJ5RGk//1Oj5nXQ2NI02Nrsg4=
+charm.land/lipgloss/v2 v2.0.3 h1:yM2zJ4Cf5Y51b7RHIwioil4ApI/aypFXXVHSwlM6RzU=
+charm.land/lipgloss/v2 v2.0.3/go.mod h1:7myLU9iG/3xluAWzpY/fSxYYHCgoKTie7laxk6ATwXA=
codeberg.org/chavacava/garif v0.2.0 h1:F0tVjhYbuOCnvNcU3YSpO6b3Waw6Bimy4K0mM8y6MfY=
codeberg.org/chavacava/garif v0.2.0/go.mod h1:P2BPbVbT4QcvLZrORc2T29szK3xEOlnl0GiPTJmEqBQ=
codeberg.org/polyfloyd/go-errorlint v1.9.0 h1:VkdEEmA1VBpH6ecQoMR4LdphVI3fA4RrCh2an7YmodI=
codeberg.org/polyfloyd/go-errorlint v1.9.0/go.mod h1:GPRRu2LzVijNn4YkrZYJfatQIdS+TrcK8rL5Xs24qw8=
+dario.cat/mergo v1.0.2 h1:85+piFYR1tMbRrLcDwR18y4UKJ3aH1Tbzi24VRW1TK8=
+dario.cat/mergo v1.0.2/go.mod h1:E/hbnu0NxMFBjpMIE34DRGLWqDy0g5FuKDhCb31ngxA=
dev.gaijin.team/go/exhaustruct/v4 v4.0.0 h1:873r7aNneqoBB3IaFIzhvt2RFYTuHgmMjoKfwODoI1Y=
dev.gaijin.team/go/exhaustruct/v4 v4.0.0/go.mod h1:aZ/k2o4Y05aMJtiux15x8iXaumE88YdiB0Ai4fXOzPI=
dev.gaijin.team/go/golib v0.6.0 h1:v6nnznFTs4bppib/NyU1PQxobwDHwCXXl15P7DV5Zgo=
@@ -28,32 +32,32 @@ github.com/Antonboom/testifylint v1.6.4 h1:gs9fUEy+egzxkEbq9P4cpcMB6/G0DYdMeiFS8
github.com/Antonboom/testifylint v1.6.4/go.mod h1:YO33FROXX2OoUfwjz8g+gUxQXio5i9qpVy7nXGbxDD4=
github.com/BurntSushi/toml v1.6.0 h1:dRaEfpa2VI55EwlIW72hMRHdWouJeRF7TPYhI+AUQjk=
github.com/BurntSushi/toml v1.6.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
+github.com/ClickHouse/clickhouse-go-linter v1.2.0 h1:zbm174up3hTKjp0wKZVnTzRiG7tSF5XZF0FJG/MuCBI=
+github.com/ClickHouse/clickhouse-go-linter v1.2.0/go.mod h1:pLorS7ffPTfuUV9M0SJgfHA/h/WQPQUk2FWG9x74cQ4=
github.com/Djarvur/go-err113 v0.1.1 h1:eHfopDqXRwAi+YmCUas75ZE0+hoBHJ2GQNLYRSxao4g=
github.com/Djarvur/go-err113 v0.1.1/go.mod h1:IaWJdYFLg76t2ihfflPZnM1LIQszWOsFDh2hhhAVF6k=
github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI=
github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
-github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww=
-github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
-github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0=
-github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=
-github.com/Masterminds/sprig v2.22.0+incompatible h1:z4yfnGrZ7netVz+0EDJ0Wi+5VZCSYp4Z0m2dk6cEM60=
-github.com/Masterminds/sprig v2.22.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o=
-github.com/MirrexOne/unqueryvet v1.4.0 h1:6KAkqqW2KUnkl9Z0VuTphC3IXRPoFqEkJEtyxxHj5eQ=
-github.com/MirrexOne/unqueryvet v1.4.0/go.mod h1:IWwCwMQlSWjAIteW0t+28Q5vouyktfujzYznSIWiuOg=
+github.com/Masterminds/semver/v3 v3.5.0 h1:kQceYJfbupGfZOKZQg0kou0DgAKhzDg2NZPAwZ/2OOE=
+github.com/Masterminds/semver/v3 v3.5.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=
+github.com/Masterminds/sprig/v3 v3.3.0 h1:mQh0Yrg1XPo6vjYXgtf5OtijNAKJRNcTdOOGZe3tPhs=
+github.com/Masterminds/sprig/v3 v3.3.0/go.mod h1:Zy1iXRYNqNLUolqCpL4uhk6SHUMAOSCzdgBfDb35Lz0=
+github.com/MirrexOne/unqueryvet v1.5.4 h1:38QOxShO7JmMWT+eCdDMbcUgGCOeJphVkzzRgyLJgsQ=
+github.com/MirrexOne/unqueryvet v1.5.4/go.mod h1:fs9Zq6eh1LRIhsDIsxf9PONVUjYdFHdtkHIgZdJnyPU=
github.com/OpenPeeDeeP/depguard/v2 v2.2.1 h1:vckeWVESWp6Qog7UZSARNqfu/cZqvki8zsuj3piCMx4=
github.com/OpenPeeDeeP/depguard/v2 v2.2.1/go.mod h1:q4DKzC4UcVaAvcfd41CZh0PWpGgzrVxUYBlgKNGquUo=
github.com/alecthomas/assert/v2 v2.11.0 h1:2Q9r3ki8+JYXvGsDyBXwH3LcJ+WK5D0gc5E8vS6K3D0=
github.com/alecthomas/assert/v2 v2.11.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k=
-github.com/alecthomas/chroma/v2 v2.21.1 h1:FaSDrp6N+3pphkNKU6HPCiYLgm8dbe5UXIXcoBhZSWA=
-github.com/alecthomas/chroma/v2 v2.21.1/go.mod h1:NqVhfBR0lte5Ouh3DcthuUCTUpDC9cxBOfyMbMQPs3o=
+github.com/alecthomas/chroma/v2 v2.24.1 h1:m5ffpfZbIb++k8AqFEKy9uVgY12xIQtBsQlc6DfZJQM=
+github.com/alecthomas/chroma/v2 v2.24.1/go.mod h1:l+ohZ9xRXIbGe7cIW+YZgOGbvuVLjMps/FYN/CwuabI=
github.com/alecthomas/go-check-sumtype v0.3.1 h1:u9aUvbGINJxLVXiFvHUlPEaD7VDULsrxJb4Aq31NLkU=
github.com/alecthomas/go-check-sumtype v0.3.1/go.mod h1:A8TSiN3UPRw3laIgWEUOHHLPa6/r9MtoigdlP5h3K/E=
github.com/alecthomas/repr v0.5.2 h1:SU73FTI9D1P5UNtvseffFSGmdNci/O6RsqzeXJtP0Qs=
github.com/alecthomas/repr v0.5.2/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4=
github.com/alexkohler/nakedret/v2 v2.0.6 h1:ME3Qef1/KIKr3kWX3nti3hhgNxw6aqN5pZmQiFSsuzQ=
github.com/alexkohler/nakedret/v2 v2.0.6/go.mod h1:l3RKju/IzOMQHmsEvXwkqMDzHHvurNQfAgE1eVmT40Q=
-github.com/alexkohler/prealloc v1.0.1 h1:A9P1haqowqUxWvU9nk6tQ7YktXIHf+LQM9wPRhuteEE=
-github.com/alexkohler/prealloc v1.0.1/go.mod h1:fT39Jge3bQrfA7nPMDngUfvUbQGQeJyGQnR+913SCig=
+github.com/alexkohler/prealloc v1.1.0 h1:cKGRBqlXw5iyQGLYhrXrDlcHxugXpTq4tQ5c91wkf8M=
+github.com/alexkohler/prealloc v1.1.0/go.mod h1:fT39Jge3bQrfA7nPMDngUfvUbQGQeJyGQnR+913SCig=
github.com/alfatraining/structtag v1.0.0 h1:2qmcUqNcCoyVJ0up879K614L9PazjBSFruTB0GOFjCc=
github.com/alfatraining/structtag v1.0.0/go.mod h1:p3Xi5SwzTi+Ryj64DqjLWz7XurHxbGsq6y3ubePJPus=
github.com/alingse/asasalint v0.0.11 h1:SFwnQXJ49Kx/1GghOFz1XGqHYKp21Kq1nHad/0WQRnw=
@@ -62,12 +66,10 @@ github.com/alingse/nilnesserr v0.2.0 h1:raLem5KG7EFVb4UIDAXgrv3N2JIaffeKNtcEXkEW
github.com/alingse/nilnesserr v0.2.0/go.mod h1:1xJPrXonEtX7wyTq8Dytns5P2hNzoWymVUIaKm4HNFg=
github.com/antlr4-go/antlr/v4 v4.13.1 h1:SqQKkuVZ+zWkMMNkjy5FZe5mr5WURWnlpmOuzYWrPrQ=
github.com/antlr4-go/antlr/v4 v4.13.1/go.mod h1:GKmUxMtwp6ZgGwZSva4eWPC5mS6vUAmOABFgjdkM7Nw=
-github.com/ashanbrown/forbidigo/v2 v2.3.0 h1:OZZDOchCgsX5gvToVtEBoV2UWbFfI6RKQTir2UZzSxo=
-github.com/ashanbrown/forbidigo/v2 v2.3.0/go.mod h1:5p6VmsG5/1xx3E785W9fouMxIOkvY2rRV9nMdWadd6c=
-github.com/ashanbrown/makezero/v2 v2.1.0 h1:snuKYMbqosNokUKm+R6/+vOPs8yVAi46La7Ck6QYSaE=
-github.com/ashanbrown/makezero/v2 v2.1.0/go.mod h1:aEGT/9q3S8DHeE57C88z2a6xydvgx8J5hgXIGWgo0MY=
-github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k=
-github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8=
+github.com/ashanbrown/forbidigo/v2 v2.3.1 h1:KAZijvQ7zeIBKbhikT4jCm0TLYXC4u78bTiLh/8JROI=
+github.com/ashanbrown/forbidigo/v2 v2.3.1/go.mod h1:2QDkLTzU6TV937eFROamXrW92M3paehdae4HCDCOZCM=
+github.com/ashanbrown/makezero/v2 v2.2.1 h1:A7uU8dgB1PA9aelTxHMfHIQ8Qev8AB3JLxJUBUsejqM=
+github.com/ashanbrown/makezero/v2 v2.2.1/go.mod h1:aEGT/9q3S8DHeE57C88z2a6xydvgx8J5hgXIGWgo0MY=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/bkielbasa/cyclop v1.2.3 h1:faIVMIGDIANuGPWH031CZJTi2ymOQBULs9H21HSMa5w=
@@ -78,14 +80,14 @@ github.com/blizzy78/varnamelen v0.8.0 h1:oqSblyuQvFsW1hbBHh1zfwrKe3kcSj0rnXkKzsQ
github.com/blizzy78/varnamelen v0.8.0/go.mod h1:V9TzQZ4fLJ1DSrjVDfl89H7aMnTvKkApdHeyESmyR7k=
github.com/bombsimon/wsl/v4 v4.7.0 h1:1Ilm9JBPRczjyUs6hvOPKvd7VL1Q++PL8M0SXBDf+jQ=
github.com/bombsimon/wsl/v4 v4.7.0/go.mod h1:uV/+6BkffuzSAVYD+yGyld1AChO7/EuLrCF/8xTiapg=
-github.com/bombsimon/wsl/v5 v5.3.0 h1:nZWREJFL6U3vgW/B1lfDOigl+tEF6qgs6dGGbFeR0UM=
-github.com/bombsimon/wsl/v5 v5.3.0/go.mod h1:Gp8lD04z27wm3FANIUPZycXp+8huVsn0oxc+n4qfV9I=
+github.com/bombsimon/wsl/v5 v5.8.0 h1:JTkyfs4yl8SPejrCF2GdABXE+mO1WvM7iUYzRWlsxDs=
+github.com/bombsimon/wsl/v5 v5.8.0/go.mod h1:AbOLsulgkqP4ZnitHf9gwPtCOGlrzkk0jb0uNxRSY0o=
github.com/breml/bidichk v0.3.3 h1:WSM67ztRusf1sMoqH6/c4OBCUlRVTKq+CbSeo0R17sE=
github.com/breml/bidichk v0.3.3/go.mod h1:ISbsut8OnjB367j5NseXEGGgO/th206dVa427kR8YTE=
github.com/breml/errchkjson v0.4.1 h1:keFSS8D7A2T0haP9kzZTi7o26r7kE3vymjZNeNDRDwg=
github.com/breml/errchkjson v0.4.1/go.mod h1:a23OvR6Qvcl7DG/Z4o0el6BRAjKnaReoPQFciAl9U3s=
-github.com/butuzov/ireturn v0.4.0 h1:+s76bF/PfeKEdbG8b54aCocxXmi0wvYdOVsWxVO7n8E=
-github.com/butuzov/ireturn v0.4.0/go.mod h1:ghI0FrCmap8pDWZwfPisFD1vEc56VKH4NpQUxDHta70=
+github.com/butuzov/ireturn v0.4.1 h1:vWb3NO4t77iku/sjCQ/2pHTQeOmxEhjIriJqRLg1Y+I=
+github.com/butuzov/ireturn v0.4.1/go.mod h1:q+DXKzTDV5guNuXLnIab9fKXizTn2miZHLhxH7V/GB4=
github.com/butuzov/mirror v1.3.0 h1:HdWCXzmwlQHdVhwvsfBb2Au0r3HyINry3bDWLYXiKoc=
github.com/butuzov/mirror v1.3.0/go.mod h1:AEij0Z8YMALaq4yQj9CPPVYOyJQyiexpQEQgihajRfI=
github.com/catenacyber/perfsprint v0.10.1 h1:u7Riei30bk46XsG8nknMhKLXG9BcXz3+3tl/WpKm0PQ=
@@ -98,20 +100,25 @@ github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UF
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/charithe/durationcheck v0.0.11 h1:g1/EX1eIiKS57NTWsYtHDZ/APfeXKhye1DidBcABctk=
github.com/charithe/durationcheck v0.0.11/go.mod h1:x5iZaixRNl8ctbM+3B2RrPG5t856TxRyVQEnbIEM2X4=
-github.com/charmbracelet/colorprofile v0.3.1 h1:k8dTHMd7fgw4bnFd7jXTLZrSU/CQrKnL3m+AxCzDz40=
-github.com/charmbracelet/colorprofile v0.3.1/go.mod h1:/GkGusxNs8VB/RSOh3fu0TJmQ4ICMMPApIIVn0KszZ0=
-github.com/charmbracelet/lipgloss v1.1.0 h1:vYXsiLHVkK7fp74RkV7b2kq9+zDLoEU4MZoFqR/noCY=
-github.com/charmbracelet/lipgloss v1.1.0/go.mod h1:/6Q8FR2o+kj8rz4Dq0zQc3vYf7X+B0binUUBwA0aL30=
-github.com/charmbracelet/x/ansi v0.9.2 h1:92AGsQmNTRMzuzHEYfCdjQeUzTrgE1vfO5/7fEVoXdY=
-github.com/charmbracelet/x/ansi v0.9.2/go.mod h1:3RQDQ6lDnROptfpWuUVIUG64bD2g2BgntdxH0Ya5TeE=
-github.com/charmbracelet/x/cellbuf v0.0.13 h1:/KBBKHuVRbq1lYx5BzEHBAFBP8VcQzJejZ/IA3iR28k=
-github.com/charmbracelet/x/cellbuf v0.0.13/go.mod h1:xe0nKWGd3eJgtqZRaN9RjMtK7xUYchjzPr7q6kcvCCs=
-github.com/charmbracelet/x/term v0.2.1 h1:AQeHeLZ1OqSXhrAWpYUtZyX1T3zVxfpZuEQMIQaGIAQ=
-github.com/charmbracelet/x/term v0.2.1/go.mod h1:oQ4enTYFV7QN4m0i9mzHrViD7TQKvNEEkHUMCmsxdUg=
+github.com/charmbracelet/colorprofile v0.4.3 h1:QPa1IWkYI+AOB+fE+mg/5/4HRMZcaXex9t5KX76i20Q=
+github.com/charmbracelet/colorprofile v0.4.3/go.mod h1:/zT4BhpD5aGFpqQQqw7a+VtHCzu+zrQtt1zhMt9mR4Q=
+github.com/charmbracelet/ultraviolet v0.0.0-20251205161215-1948445e3318 h1:OqDqxQZliC7C8adA7KjelW3OjtAxREfeHkNcd66wpeI=
+github.com/charmbracelet/ultraviolet v0.0.0-20251205161215-1948445e3318/go.mod h1:Y6kE2GzHfkyQQVCSL9r2hwokSrIlHGzZG+71+wDYSZI=
+github.com/charmbracelet/x/ansi v0.11.7 h1:kzv1kJvjg2S3r9KHo8hDdHFQLEqn4RBCb39dAYC84jI=
+github.com/charmbracelet/x/ansi v0.11.7/go.mod h1:9qGpnAVYz+8ACONkZBUWPtL7lulP9No6p1epAihUZwQ=
+github.com/charmbracelet/x/term v0.2.2 h1:xVRT/S2ZcKdhhOuSP4t5cLi5o+JxklsoEObBSgfgZRk=
+github.com/charmbracelet/x/term v0.2.2/go.mod h1:kF8CY5RddLWrsgVwpw4kAa6TESp6EB5y3uxGLeCqzAI=
+github.com/charmbracelet/x/termios v0.1.1 h1:o3Q2bT8eqzGnGPOYheoYS8eEleT5ZVNYNy8JawjaNZY=
+github.com/charmbracelet/x/termios v0.1.1/go.mod h1:rB7fnv1TgOPOyyKRJ9o+AsTU/vK5WHJ2ivHeut/Pcwo=
+github.com/charmbracelet/x/windows v0.2.2 h1:IofanmuvaxnKHuV04sC0eBy/smG6kIKrWG2/jYn2GuM=
+github.com/charmbracelet/x/windows v0.2.2/go.mod h1:/8XtdKZzedat74NQFn0NGlGL4soHB0YQZrETF96h75k=
github.com/ckaznocha/intrange v0.3.1 h1:j1onQyXvHUsPWujDH6WIjhyH26gkRt/txNlV7LspvJs=
github.com/ckaznocha/intrange v0.3.1/go.mod h1:QVepyz1AkUoFQkpEqksSYpNpUo3c5W7nWh/s6SHIJJk=
+github.com/clipperhouse/displaywidth v0.11.0 h1:lBc6kY44VFw+TDx4I8opi/EtL9m20WSEFgwIwO+UVM8=
+github.com/clipperhouse/displaywidth v0.11.0/go.mod h1:bkrFNkf81G8HyVqmKGxsPufD3JhNl3dSqnGhOoSD/o0=
+github.com/clipperhouse/uax29/v2 v2.7.0 h1:+gs4oBZ2gPfVrKPthwbMzWZDaAFPGYK72F0NJv2v7Vk=
+github.com/clipperhouse/uax29/v2 v2.7.0/go.mod h1:EFJ2TJMRUaplDxHKj1qAEhCtQPW2tJSwu5BF98AuoVM=
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
-github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/curioswitch/go-reassign v0.3.0 h1:dh3kpQHuADL3cobV/sSGETA8DOv457dwl+fbBAhrQPs=
github.com/curioswitch/go-reassign v0.3.0/go.mod h1:nApPCCTtqLJN/s8HfItCcKV0jIPwluBOvZP+dsJGA88=
github.com/daixiang0/gci v0.13.7 h1:+0bG5eK9vlI08J+J/NWGbWPTNiXPG4WhNLJOkSxWITQ=
@@ -126,14 +133,14 @@ github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/denis-tingaikin/go-header v0.5.0 h1:SRdnP5ZKvcO9KKRP1KJrhFR3RrlGuD+42t4429eC9k8=
github.com/denis-tingaikin/go-header v0.5.0/go.mod h1:mMenU5bWrok6Wl2UsZjy+1okegmwQ3UgWl4V1D8gjlY=
-github.com/dlclark/regexp2 v1.11.5 h1:Q/sSnsKerHeCkc/jSTNq1oCm7KiVgUMZRDUoRu0JQZQ=
-github.com/dlclark/regexp2 v1.11.5/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
-github.com/elastic/crd-ref-docs v0.1.0 h1:Cr5kz89QB3Iuuj7dhAfLMApCrChEGAaIBTxGk/xuRKw=
-github.com/elastic/crd-ref-docs v0.1.0/go.mod h1:X83mMBdJt05heJUYiS3T0yJ/JkCuliuhSUNav5Gjo/U=
+github.com/dlclark/regexp2 v1.12.0 h1:0j4c5qQmnC6XOWNjP3PIXURXN2gWx76rd3KvgdPkCz8=
+github.com/dlclark/regexp2 v1.12.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
+github.com/elastic/crd-ref-docs v0.3.0 h1:9bGSUkBR56Z7TuDGQAu3KGbBkagwwZ6RkZmS+qvDuDM=
+github.com/elastic/crd-ref-docs v0.3.0/go.mod h1:8td3UC8CaO5M+G115O3FRKLmplmX+p0EqLMLGM6uNdk=
github.com/ettle/strcase v0.2.0 h1:fGNiVF21fHXpX1niBgk0aROov1LagYsOwV/xqKDKR/Q=
github.com/ettle/strcase v0.2.0/go.mod h1:DajmHElDSaX76ITe3/VHVyMin4LWSJN5Z909Wp+ED1A=
-github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=
-github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU=
+github.com/fatih/color v1.19.0 h1:Zp3PiM21/9Ld6FzSKyL5c/BULoe/ONr9KlbYVOfG8+w=
+github.com/fatih/color v1.19.0/go.mod h1:zNk67I0ZUT1bEGsSGyCZYZNrHuTkJJB+r6Q9VuMi0LE=
github.com/fatih/structtag v1.2.0 h1:/OdNE99OxoI/PqaW/SuSK9uxxT3f/tcSZgon/ssNSx4=
github.com/fatih/structtag v1.2.0/go.mod h1:mBJUNpUnHmRKrKlQQlmCrh5PuhftFbNv8Ys4/aAZl94=
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
@@ -142,14 +149,14 @@ github.com/firefart/nonamedreturns v1.0.6 h1:vmiBcKV/3EqKY3ZiPxCINmpS431OcE1S47A
github.com/firefart/nonamedreturns v1.0.6/go.mod h1:R8NisJnSIpvPWheCq0mNRXJok6D8h7fagJTF8EMEwCo=
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
-github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k=
-github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
-github.com/fxamacker/cbor/v2 v2.9.0 h1:NpKPmjDBgUfBms6tr6JZkTHtfFGcMKsw3eGcmD/sapM=
-github.com/fxamacker/cbor/v2 v2.9.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ=
+github.com/fsnotify/fsnotify v1.10.0 h1:Xx/5Ydg9CeBDX/wi4VJqStNtohYjitZhhlHt4h3St1M=
+github.com/fsnotify/fsnotify v1.10.0/go.mod h1:TLheqan6HD6GBK6PrDWyDPBaEV8LspOxvPSjC+bVfgo=
+github.com/fxamacker/cbor/v2 v2.9.3 h1:oQBnFATpNdY8gJHTndDDv5Xl4QqNaz51G5LLEPhng3Q=
+github.com/fxamacker/cbor/v2 v2.9.3/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ=
github.com/fzipp/gocyclo v0.6.0 h1:lsblElZG7d3ALtGMx9fmxeTKZaLLpU8mET09yN4BBLo=
github.com/fzipp/gocyclo v0.6.0/go.mod h1:rXPyn8fnlpa0R2csP/31uerbiVBugk5whMdlyaLkLoA=
-github.com/ghostiam/protogetter v0.3.18 h1:yEpghRGtP9PjKvVXtEzGpYfQj1Wl/ZehAfU6fr62Lfo=
-github.com/ghostiam/protogetter v0.3.18/go.mod h1:FjIu5Yfs6FT391m+Fjp3fbAYJ6rkL/J6ySpZBfnODuI=
+github.com/ghostiam/protogetter v0.3.20 h1:oW7OPFit2FxZOpmMRPP9FffU4uUpfeE/rEdE1f+MzD0=
+github.com/ghostiam/protogetter v0.3.20/go.mod h1:FjIu5Yfs6FT391m+Fjp3fbAYJ6rkL/J6ySpZBfnODuI=
github.com/gkampitakis/ciinfo v0.3.2 h1:JcuOPk8ZU7nZQjdUhctuhQofk7BGHuIy0c9Ez8BNhXs=
github.com/gkampitakis/ciinfo v0.3.2/go.mod h1:1NIwaOcFChN4fa/B0hEBdAb6npDlFL8Bwx4dfRLRqAo=
github.com/gkampitakis/go-diff v1.3.2 h1:Qyn0J9XJSDTgnsgHRdz9Zp24RaJeKMUHg2+PDZZdC4M=
@@ -160,48 +167,48 @@ github.com/go-bindata/go-bindata v3.1.2+incompatible h1:5vjJMVhowQdPzjE1LdxyFF7Y
github.com/go-bindata/go-bindata v3.1.2+incompatible/go.mod h1:xK8Dsgwmeed+BBsSy2XTopBn/8uK2HWuGSnA11C3Joo=
github.com/go-critic/go-critic v0.14.3 h1:5R1qH2iFeo4I/RJU8vTezdqs08Egi4u5p6vOESA0pog=
github.com/go-critic/go-critic v0.14.3/go.mod h1:xwntfW6SYAd7h1OqDzmN6hBX/JxsEKl5up/Y2bsxgVQ=
-github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA=
-github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og=
-github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
-github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
+github.com/go-errors/errors v1.5.1 h1:ZwEMSLRCapFLflTpT7NKaAc7ukJ8ZPEjzlxt8rPN8bk=
+github.com/go-errors/errors v1.5.1/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og=
+github.com/go-logr/logr v1.4.4 h1:tG4xh9yMsRCAiodLVTxyrkzSZ9+o0L1Kg/+cPVcbP/8=
+github.com/go-logr/logr v1.4.4/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ=
github.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR8/Gg=
-github.com/go-openapi/jsonpointer v0.22.4 h1:dZtK82WlNpVLDW2jlA1YCiVJFVqkED1MegOUy9kR5T4=
-github.com/go-openapi/jsonpointer v0.22.4/go.mod h1:elX9+UgznpFhgBuaMQ7iu4lvvX1nvNsesQ3oxmYTw80=
-github.com/go-openapi/jsonreference v0.21.4 h1:24qaE2y9bx/q3uRK/qN+TDwbok1NhbSmGjjySRCHtC8=
-github.com/go-openapi/jsonreference v0.21.4/go.mod h1:rIENPTjDbLpzQmQWCj5kKj3ZlmEh+EFVbz3RTUh30/4=
-github.com/go-openapi/swag v0.25.4 h1:OyUPUFYDPDBMkqyxOTkqDYFnrhuhi9NR6QVUvIochMU=
-github.com/go-openapi/swag v0.25.4/go.mod h1:zNfJ9WZABGHCFg2RnY0S4IOkAcVTzJ6z2Bi+Q4i6qFQ=
-github.com/go-openapi/swag/cmdutils v0.25.4 h1:8rYhB5n6WawR192/BfUu2iVlxqVR9aRgGJP6WaBoW+4=
-github.com/go-openapi/swag/cmdutils v0.25.4/go.mod h1:pdae/AFo6WxLl5L0rq87eRzVPm/XRHM3MoYgRMvG4A0=
-github.com/go-openapi/swag/conv v0.25.4 h1:/Dd7p0LZXczgUcC/Ikm1+YqVzkEeCc9LnOWjfkpkfe4=
-github.com/go-openapi/swag/conv v0.25.4/go.mod h1:3LXfie/lwoAv0NHoEuY1hjoFAYkvlqI/Bn5EQDD3PPU=
-github.com/go-openapi/swag/fileutils v0.25.4 h1:2oI0XNW5y6UWZTC7vAxC8hmsK/tOkWXHJQH4lKjqw+Y=
-github.com/go-openapi/swag/fileutils v0.25.4/go.mod h1:cdOT/PKbwcysVQ9Tpr0q20lQKH7MGhOEb6EwmHOirUk=
-github.com/go-openapi/swag/jsonname v0.25.4 h1:bZH0+MsS03MbnwBXYhuTttMOqk+5KcQ9869Vye1bNHI=
-github.com/go-openapi/swag/jsonname v0.25.4/go.mod h1:GPVEk9CWVhNvWhZgrnvRA6utbAltopbKwDu8mXNUMag=
-github.com/go-openapi/swag/jsonutils v0.25.4 h1:VSchfbGhD4UTf4vCdR2F4TLBdLwHyUDTd1/q4i+jGZA=
-github.com/go-openapi/swag/jsonutils v0.25.4/go.mod h1:7OYGXpvVFPn4PpaSdPHJBtF0iGnbEaTk8AvBkoWnaAY=
-github.com/go-openapi/swag/jsonutils/fixtures_test v0.25.4 h1:IACsSvBhiNJwlDix7wq39SS2Fh7lUOCJRmx/4SN4sVo=
-github.com/go-openapi/swag/jsonutils/fixtures_test v0.25.4/go.mod h1:Mt0Ost9l3cUzVv4OEZG+WSeoHwjWLnarzMePNDAOBiM=
-github.com/go-openapi/swag/loading v0.25.4 h1:jN4MvLj0X6yhCDduRsxDDw1aHe+ZWoLjW+9ZQWIKn2s=
-github.com/go-openapi/swag/loading v0.25.4/go.mod h1:rpUM1ZiyEP9+mNLIQUdMiD7dCETXvkkC30z53i+ftTE=
-github.com/go-openapi/swag/mangling v0.25.4 h1:2b9kBJk9JvPgxr36V23FxJLdwBrpijI26Bx5JH4Hp48=
-github.com/go-openapi/swag/mangling v0.25.4/go.mod h1:6dxwu6QyORHpIIApsdZgb6wBk/DPU15MdyYj/ikn0Hg=
-github.com/go-openapi/swag/netutils v0.25.4 h1:Gqe6K71bGRb3ZQLusdI8p/y1KLgV4M/k+/HzVSqT8H0=
-github.com/go-openapi/swag/netutils v0.25.4/go.mod h1:m2W8dtdaoX7oj9rEttLyTeEFFEBvnAx9qHd5nJEBzYg=
-github.com/go-openapi/swag/stringutils v0.25.4 h1:O6dU1Rd8bej4HPA3/CLPciNBBDwZj9HiEpdVsb8B5A8=
-github.com/go-openapi/swag/stringutils v0.25.4/go.mod h1:GTsRvhJW5xM5gkgiFe0fV3PUlFm0dr8vki6/VSRaZK0=
-github.com/go-openapi/swag/typeutils v0.25.4 h1:1/fbZOUN472NTc39zpa+YGHn3jzHWhv42wAJSN91wRw=
-github.com/go-openapi/swag/typeutils v0.25.4/go.mod h1:Ou7g//Wx8tTLS9vG0UmzfCsjZjKhpjxayRKTHXf2pTE=
-github.com/go-openapi/swag/yamlutils v0.25.4 h1:6jdaeSItEUb7ioS9lFoCZ65Cne1/RZtPBZ9A56h92Sw=
-github.com/go-openapi/swag/yamlutils v0.25.4/go.mod h1:MNzq1ulQu+yd8Kl7wPOut/YHAAU/H6hL91fF+E2RFwc=
-github.com/go-openapi/testify/enable/yaml/v2 v2.0.2 h1:0+Y41Pz1NkbTHz8NngxTuAXxEodtNSI1WG1c/m5Akw4=
-github.com/go-openapi/testify/enable/yaml/v2 v2.0.2/go.mod h1:kme83333GCtJQHXQ8UKX3IBZu6z8T5Dvy5+CW3NLUUg=
-github.com/go-openapi/testify/v2 v2.0.2 h1:X999g3jeLcoY8qctY/c/Z8iBHTbwLz7R2WXd6Ub6wls=
-github.com/go-openapi/testify/v2 v2.0.2/go.mod h1:HCPmvFFnheKK2BuwSA0TbbdxJ3I16pjwMkYkP4Ywn54=
+github.com/go-openapi/jsonpointer v1.0.0 h1:kR9tHqY0CtZaOPVFm622dPVNhrvYpwr4uCxgL3h1H8s=
+github.com/go-openapi/jsonpointer v1.0.0/go.mod h1:Z3rw7dWu1p9IgitXCFamSlA5lmDiklEB6vkaxcNZW5Y=
+github.com/go-openapi/jsonreference v1.0.0 h1:jlmTr6torcd1YgDQvSfNmRtKzYDO4FGBkrAdlAVWnpY=
+github.com/go-openapi/jsonreference v1.0.0/go.mod h1:jtwdyGbJk0Xhe5Y+rwtglQP6Sb1WZST4rT32LWB+sv0=
+github.com/go-openapi/swag v0.28.0 h1:xkgbOSKj6DZziNpyqRRAOt3GJGtgjgsd2RoyT30VWuw=
+github.com/go-openapi/swag v0.28.0/go.mod h1:4qYnT3Cqr1p1VknOdPo70evN4rgQnAg6jwApHyxSGIg=
+github.com/go-openapi/swag/cmdutils v0.28.0 h1:7TOeNtkYru1SG8Y34tDh9WBbLsMqGnptuxWiHREPZ4Q=
+github.com/go-openapi/swag/cmdutils v0.28.0/go.mod h1:Sm1MVFMkF6guJJ+pQqHnQA3N0j9qALV3NxzDSv6bETM=
+github.com/go-openapi/swag/conv v0.28.0 h1:GtqqbyFe7vR5Y7ehxG9W6/OvrSFdf1OLeTGp40TqxH8=
+github.com/go-openapi/swag/conv v0.28.0/go.mod h1:mbUE+mzctnhxi864m0Q07SpN8OowD9JhxmxuYvZZD/k=
+github.com/go-openapi/swag/fileutils v0.28.0 h1:Z04XWQD7R8Eq+7GnOrjovBxPPmZzsS4gt2H2GPGIViU=
+github.com/go-openapi/swag/fileutils v0.28.0/go.mod h1:VvJFZLTZS0AI854gEQz5tk7dBESdLjiNUMSZ/th2ry8=
+github.com/go-openapi/swag/jsonutils v0.28.0 h1:YIch6FwO7RXzeAnbO8Tu7dWBZeUEH+4nA0HXltVTnv4=
+github.com/go-openapi/swag/jsonutils v0.28.0/go.mod h1:CYM3WlTUcagR2ZoHdz54di/cbBqt82tuxuXgAjxw+mg=
+github.com/go-openapi/swag/jsonutils/fixtures_test v0.28.0 h1:qV+VVUAx5Oro8WjVWpZeql7YReTKhT4smR4zhcOQZr0=
+github.com/go-openapi/swag/jsonutils/fixtures_test v0.28.0/go.mod h1:mofwUWx70wvskwESqRJ//k/9kURmCgyJl5m5Ppoh5kY=
+github.com/go-openapi/swag/loading v0.28.0 h1:td8QZdZC9MIYGGSnSPKShKiK22I2tU5UQvuUhIBPRLU=
+github.com/go-openapi/swag/loading v0.28.0/go.mod h1:rXB0QiQX5mMveXEA7ouM4KiiM9jVJe4K6BVbwhD1M4k=
+github.com/go-openapi/swag/mangling v0.28.0 h1:pH8eyeNO9SLYsTMWJrurnNfKmDa28XrlA+HePVD53VM=
+github.com/go-openapi/swag/mangling v0.28.0/go.mod h1:jtBE2+V+3pILxOR7Vgce+Cwp6A2PgZbvVqfNntbVs0w=
+github.com/go-openapi/swag/netutils v0.28.0 h1:YXN6TALEi2pzts8/8GNm6T61HTAZsieukGZidap989k=
+github.com/go-openapi/swag/netutils v0.28.0/go.mod h1:J+WYyFMLtvtCGqa6jLv+YNUmIKI3ZRQRrvfNDMoQoEQ=
+github.com/go-openapi/swag/pools v0.28.0 h1:HPMZWSAfce3rdVTFcjFiCIBtDg9h4x2QlRrHipwhxeU=
+github.com/go-openapi/swag/pools v0.28.0/go.mod h1:kVQefhSK5RWuRe7BXsL8htgBPAMpN7HDGpGEknqugeE=
+github.com/go-openapi/swag/stringutils v0.28.0 h1:ixsc9iYgDPubHL/8nSkbnryEHpD2VRlBMLKpQyPXcDU=
+github.com/go-openapi/swag/stringutils v0.28.0/go.mod h1:lzRN95CxXmA03XcDWHLOb6nOMcxCqR5rGY0lOgsfRoM=
+github.com/go-openapi/swag/typeutils v0.28.0 h1:nRBKSBXjDgf01VDPB3fWeD9nQuhCOVeIYAkUx2tbkyY=
+github.com/go-openapi/swag/typeutils v0.28.0/go.mod h1:Srm0xFNRZ1Y+vCxJclo5qzx8aj+1pAKda/YfFPrG0dQ=
+github.com/go-openapi/swag/yamlutils v0.28.0 h1:TV3JXH6DS46KUroDtMLAYHGkdWf5VDq3wVWFirmzROY=
+github.com/go-openapi/swag/yamlutils v0.28.0/go.mod h1:x0q/yndZHEgk9Rx3DyDqzFUmHy55KTvIZldvF2dTJXs=
+github.com/go-openapi/testify/enable/yaml/v2 v2.6.0 h1:gGHwAJ0R/5jU8BEGDbfRNR3hL68dAVi84WuOApp29B0=
+github.com/go-openapi/testify/enable/yaml/v2 v2.6.0/go.mod h1:tY+St1SGq4NFl0QIqdTY4aEdbChAHxhyB77XQi9iJCo=
+github.com/go-openapi/testify/v2 v2.6.0 h1:5PKH2HE7YJ/LuRPQGvSxBRlFXNQhSetBLlGAgUEu3ug=
+github.com/go-openapi/testify/v2 v2.6.0/go.mod h1:SgsVHtfooshd0tublTtJ50FPKhujf47YRqauXXOUxfw=
github.com/go-quicktest/qt v1.101.0 h1:O1K29Txy5P2OK0dGo59b7b0LR6wKfIhttaAhHUyn7eI=
github.com/go-quicktest/qt v1.101.0/go.mod h1:14Bz/f7NwaXPtdYEgzsx46kqSxVwTbzVZsDC26tQJow=
github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
@@ -225,38 +232,40 @@ github.com/go-toolsmith/strparse v1.1.0 h1:GAioeZUK9TGxnLS+qfdqNbA4z0SSm5zVNtCQi
github.com/go-toolsmith/strparse v1.1.0/go.mod h1:7ksGy58fsaQkGQlY8WVoBFNyEPMGuJin1rfoPS4lBSQ=
github.com/go-toolsmith/typep v1.1.0 h1:fIRYDyF+JywLfqzyhdiHzRop/GQDxxNhLGQ6gFUNHus=
github.com/go-toolsmith/typep v1.1.0/go.mod h1:fVIw+7zjdsMxDA3ITWnH1yOiw1rnTQKCsF/sk2H/qig=
-github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs=
-github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
+github.com/go-viper/mapstructure/v2 v2.5.0 h1:vM5IJoUAy3d7zRSVtIwQgBj7BiWtMPfmPEgAXnvj1Ro=
+github.com/go-viper/mapstructure/v2 v2.5.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
github.com/go-xmlfmt/xmlfmt v1.1.3 h1:t8Ey3Uy7jDSEisW2K3somuMKIpzktkWptA0iFCnRUWY=
github.com/go-xmlfmt/xmlfmt v1.1.3/go.mod h1:aUCEOzzezBEjDBbFBoSiya/gduyIiWYRP6CnSFIV8AM=
github.com/gobuffalo/flect v1.0.3 h1:xeWBM2nui+qnVvNM4S3foBhCAL2XgPU+a7FdpelbTq4=
github.com/gobuffalo/flect v1.0.3/go.mod h1:A5msMlrHtLqh9umBSnvabjsMrCcCpAyzglnDvkbYKHs=
github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y=
github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8=
-github.com/goccy/go-yaml v1.18.0 h1:8W7wMFS12Pcas7KU+VVkaiCng+kG8QiFeFwzFb+rwuw=
-github.com/goccy/go-yaml v1.18.0/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA=
-github.com/godoc-lint/godoc-lint v0.11.1 h1:z9as8Qjiy6miRIa3VRymTa+Gt2RLnGICVikcvlUVOaA=
-github.com/godoc-lint/godoc-lint v0.11.1/go.mod h1:BAqayheFSuZrEAqCRxgw9MyvsM+S/hZwJbU1s/ejRj8=
+github.com/goccy/go-yaml v1.19.2 h1:PmFC1S6h8ljIz6gMRBopkjP1TVT7xuwrButHID66PoM=
+github.com/goccy/go-yaml v1.19.2/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA=
+github.com/godoc-lint/godoc-lint v0.11.2 h1:Bp0FkJWoSdNsBikdNgIcgtaoo+xz6I/Y9s5WSBQUeeM=
+github.com/godoc-lint/godoc-lint v0.11.2/go.mod h1:iVpGdL1JCikNH2gGeAn3Hh+AgN5Gx/I/cxV+91L41jo=
github.com/gofrs/flock v0.13.0 h1:95JolYOvGMqeH31+FC7D2+uULf6mG61mEZ/A8dRYMzw=
github.com/gofrs/flock v0.13.0/go.mod h1:jxeyy9R1auM5S6JYDBhDt+E2TCo7DkratH4Pgi8P+Z0=
github.com/golangci/asciicheck v0.5.0 h1:jczN/BorERZwK8oiFBOGvlGPknhvq0bjnysTj4nUfo0=
github.com/golangci/asciicheck v0.5.0/go.mod h1:5RMNAInbNFw2krqN6ibBxN/zfRFa9S6tA1nPdM0l8qQ=
-github.com/golangci/dupl v0.0.0-20250308024227-f665c8d69b32 h1:WUvBfQL6EW/40l6OmeSBYQJNSif4O11+bmWEz+C7FYw=
-github.com/golangci/dupl v0.0.0-20250308024227-f665c8d69b32/go.mod h1:NUw9Zr2Sy7+HxzdjIULge71wI6yEg1lWQr7Evcu8K0E=
+github.com/golangci/dupl v0.0.0-20260401084720-c99c5cf5c202 h1:CbTB8KpqnViI6lIXxp03Oclc4VFHi3K4BWC1TacsZ+A=
+github.com/golangci/dupl v0.0.0-20260401084720-c99c5cf5c202/go.mod h1:NUw9Zr2Sy7+HxzdjIULge71wI6yEg1lWQr7Evcu8K0E=
github.com/golangci/go-printf-func-name v0.1.1 h1:hIYTFJqAGp1iwoIfsNTpoq1xZAarogrvjO9AfiW3B4U=
github.com/golangci/go-printf-func-name v0.1.1/go.mod h1:Es64MpWEZbh0UBtTAICOZiB+miW53w/K9Or/4QogJss=
github.com/golangci/gofmt v0.0.0-20250106114630-d62b90e6713d h1:viFft9sS/dxoYY0aiOTsLKO2aZQAPT4nlQCsimGcSGE=
github.com/golangci/gofmt v0.0.0-20250106114630-d62b90e6713d/go.mod h1:ivJ9QDg0XucIkmwhzCDsqcnxxlDStoTl89jDMIoNxKY=
-github.com/golangci/golangci-lint/v2 v2.8.0 h1:wJnr3hJWY3eVzOUcfwbDc2qbi2RDEpvLmQeNFaPSNYA=
-github.com/golangci/golangci-lint/v2 v2.8.0/go.mod h1:xl+HafQ9xoP8rzw0z5AwnO5kynxtb80e8u02Ej/47RI=
-github.com/golangci/golines v0.14.0 h1:xt9d3RKBjhasA3qpoXs99J2xN2t6eBlpLHt0TrgyyXc=
-github.com/golangci/golines v0.14.0/go.mod h1:gf555vPG2Ia7mmy2mzmhVQbVjuK8Orw0maR1G4vVAAQ=
-github.com/golangci/misspell v0.7.0 h1:4GOHr/T1lTW0hhR4tgaaV1WS/lJ+ncvYCoFKmqJsj0c=
-github.com/golangci/misspell v0.7.0/go.mod h1:WZyyI2P3hxPY2UVHs3cS8YcllAeyfquQcKfdeE9AFVg=
+github.com/golangci/golangci-lint/v2 v2.12.2 h1:7+d1uY0bq1MU2UV3R5pW5Q7QWdcoq4naMRXM+gsJKrs=
+github.com/golangci/golangci-lint/v2 v2.12.2/go.mod h1:opqHHuIcTG2R+4akzWMd4o1BnD9/1LcjICWOujr91U8=
+github.com/golangci/golines v0.15.0 h1:Qnph25g8Y1c5fdo1X7GaRDGgnMHgnxh4Gk4VfPTtRx0=
+github.com/golangci/golines v0.15.0/go.mod h1:AZjXd23tbHMpowhtnGlj9KCNsysj72aeZVVHnVcZx10=
+github.com/golangci/misspell v0.8.0 h1:qvxQhiE2/5z+BVRo1kwYA8yGz+lOlu5Jfvtx2b04Jbg=
+github.com/golangci/misspell v0.8.0/go.mod h1:WZyyI2P3hxPY2UVHs3cS8YcllAeyfquQcKfdeE9AFVg=
github.com/golangci/plugin-module-register v0.1.2 h1:e5WM6PO6NIAEcij3B053CohVp3HIYbzSuP53UAYgOpg=
github.com/golangci/plugin-module-register v0.1.2/go.mod h1:1+QGTsKBvAIvPvoY/os+G5eoqxWn70HYDm2uvUyGuVw=
github.com/golangci/revgrep v0.8.0 h1:EZBctwbVd0aMeRnNUsFogoyayvKHyxlV3CdUA46FX2s=
github.com/golangci/revgrep v0.8.0/go.mod h1:U4R/s9dlXZsg8uJmaR1GrloUr14D7qDl8gi2iPXJH8k=
+github.com/golangci/rowserrcheck v0.0.0-20260419091836-c5f79b8a11ba h1:lqtcnSMDuuJdu/LrKWi5RJzpSNLOJXYe/nzQutTI5kg=
+github.com/golangci/rowserrcheck v0.0.0-20260419091836-c5f79b8a11ba/go.mod h1:sCBNcpRmhJCtbFGz49+IM3ETTFf7QdJ30AeYCd43NKk=
github.com/golangci/swaggoswag v0.0.0-20250504205917-77f2aca3143e h1:ai0EfmVYE2bRA5htgAG9r7s3tHsfjIhN98WshBTJ9jM=
github.com/golangci/swaggoswag v0.0.0-20250504205917-77f2aca3143e/go.mod h1:Vrn4B5oR9qRwM+f54koyeH3yzphlecwERs0el27Fr/s=
github.com/golangci/unconvert v0.0.0-20250410112200-a129a6e6413e h1:gD6P7NEo7Eqtt0ssnqSJNNndxe69DOQ24A5h7+i3KpM=
@@ -270,12 +279,11 @@ github.com/google/go-cmdtest v0.4.1-0.20220921163831-55ab3332a786/go.mod h1:apVn
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
-github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
-github.com/google/pprof v0.0.0-20260115054156-294ebfa9ad83 h1:z2ogiKUYzX5Is6zr/vP9vJGqPwcdqsWjOt+V8J7+bTc=
-github.com/google/pprof v0.0.0-20260115054156-294ebfa9ad83/go.mod h1:MxpfABSjhmINe3F1It9d+8exIHFvUqtLIRCdOGNXqiI=
+github.com/google/pprof v0.0.0-20260802141513-ef3492d7dac3 h1:LMLX+LgTNWpfvCBdFebv6EsYotImrt/Ppc5cXIriCSo=
+github.com/google/pprof v0.0.0-20260802141513-ef3492d7dac3/go.mod h1:jl5iWTm0/hd5PjEYEOuwAJ57L/CibdZfrqZ5XA5GrCk=
github.com/google/renameio v0.1.0 h1:GOZbcHa3HfsPKPlmyPyN2KEohoMXOhdMbHrvbpl2QaA=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
@@ -301,24 +309,20 @@ github.com/hashicorp/go-immutable-radix/v2 v2.1.0/go.mod h1:hgdqLXA4f6NIjRVisM1T
github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8=
github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/go-version v1.2.1/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
-github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4=
-github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
+github.com/hashicorp/go-version v1.9.0 h1:CeOIz6k+LoN3qX9Z0tyQrPtiB1DFYRPfCIBtaXPSCnA=
+github.com/hashicorp/go-version v1.9.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k=
github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=
-github.com/hashicorp/hcl v1.0.1-vault-5 h1:kI3hhbbyzr4dldA8UdTb7ZlVVlI2DACdCfz31RPDgJM=
-github.com/hashicorp/hcl v1.0.1-vault-5/go.mod h1:XYhtn6ijBSAj6n4YqAaf7RBPS4I06AItNorpy+MoQNM=
+github.com/hashicorp/hcl v1.0.1-vault-7 h1:ag5OxFVy3QYTFTJODRzTKVZ6xvdfLLCA1cy/Y6xGI0I=
+github.com/hashicorp/hcl v1.0.1-vault-7/go.mod h1:XYhtn6ijBSAj6n4YqAaf7RBPS4I06AItNorpy+MoQNM=
github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM=
github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg=
-github.com/huandu/xstrings v1.3.3 h1:/Gcsuc1x8JVbJ9/rlye4xZnVAbEkGauT8lbebqcQws4=
-github.com/huandu/xstrings v1.3.3/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
-github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4=
-github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY=
+github.com/huandu/xstrings v1.5.0 h1:2ag3IFq9ZDANvthTwTiqSSZLjDc+BedvHPAp5tJy2TI=
+github.com/huandu/xstrings v1.5.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
-github.com/jgautheron/goconst v1.8.2 h1:y0XF7X8CikZ93fSNT6WBTb/NElBu9IjaY7CCYQrCMX4=
-github.com/jgautheron/goconst v1.8.2/go.mod h1:A0oxgBCHy55NQn6sYpO7UdnA9p+h7cPtoOZUmvNIako=
-github.com/jingyugao/rowserrcheck v1.1.1 h1:zibz55j/MJtLsjP1OF4bSdgXxwL1b+Vn7Tjzq7gFzUs=
-github.com/jingyugao/rowserrcheck v1.1.1/go.mod h1:4yvlZSDb3IyDTUZJUmpZfm2Hwok+Dtp+nu2qOq+er9c=
+github.com/jgautheron/goconst v1.10.0 h1:Ptt+OoE4NaEWKhLrWrrN3IpZdGLiqaf7WLnEX/iv4Jw=
+github.com/jgautheron/goconst v1.10.0/go.mod h1:0p+wv1lFOiUr0IlNNT1nrm6+8DB8u2sU6KHGzFRXHDc=
github.com/jjti/go-spancheck v0.6.5 h1:lmi7pKxa37oKYIMScialXUK6hP3iY5F1gu+mLBPgYB8=
github.com/jjti/go-spancheck v0.6.5/go.mod h1:aEogkeatBrbYsyW6y5TgDfihCulDYciL1B7rG2vSsrU=
github.com/joshdk/go-junit v1.0.0 h1:S86cUKIdwBHWwA6xCmFlf3RTLfVXYQfvanM5Uh+K6GE=
@@ -329,8 +333,8 @@ github.com/julz/importas v0.2.0 h1:y+MJN/UdL63QbFJHws9BVC5RpA2iq0kpjrFajTGivjQ=
github.com/julz/importas v0.2.0/go.mod h1:pThlt589EnCYtMnmhmRYY/qn9lCf/frPOK+WMx3xiJY=
github.com/karamaru-alpha/copyloopvar v1.2.2 h1:yfNQvP9YaGQR7VaWLYcfZUlRP2eo2vhExWKxD/fP6q0=
github.com/karamaru-alpha/copyloopvar v1.2.2/go.mod h1:oY4rGZqZ879JkJMtX3RRkcXRkmUvH0x35ykgaKgsgJY=
-github.com/kisielk/errcheck v1.9.0 h1:9xt1zI9EBfcYBvdU1nVrzMzzUPUtPKs9bVSIM3TAb3M=
-github.com/kisielk/errcheck v1.9.0/go.mod h1:kQxWMMVZgIkDq7U8xtG/n2juOjbLgZtedi0D+/VL/i8=
+github.com/kisielk/errcheck v1.10.0 h1:Lvs/YAHP24YKg08LA8oDw2z9fJVme090RAXd90S+rrw=
+github.com/kisielk/errcheck v1.10.0/go.mod h1:kQxWMMVZgIkDq7U8xtG/n2juOjbLgZtedi0D+/VL/i8=
github.com/kkHAIKE/contextcheck v1.1.6 h1:7HIyRcnyzxL9Lz06NGhiKvenXq7Zw6Q0UQu/ttjfJCE=
github.com/kkHAIKE/contextcheck v1.1.6/go.mod h1:3dDbMRNBFaq8HFXWC1JyvDSPm43CmE6IuHam8Wr0rkg=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
@@ -360,16 +364,16 @@ github.com/ldez/usetesting v0.5.0 h1:3/QtzZObBKLy1F4F8jLuKJiKBjjVFi1IavpoWbmqLwc
github.com/ldez/usetesting v0.5.0/go.mod h1:Spnb4Qppf8JTuRgblLrEWb7IE6rDmUpGvxY3iRrzvDQ=
github.com/leonklingele/grouper v1.1.2 h1:o1ARBDLOmmasUaNDesWqWCIFH3u7hoFlM84YrjT3mIY=
github.com/leonklingele/grouper v1.1.2/go.mod h1:6D0M/HVkhs2yRKRFZUoGjeDy7EZTfFBE9gl4kjmIGkA=
-github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
-github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
+github.com/lucasb-eyer/go-colorful v1.4.0 h1:UtrWVfLdarDgc44HcS7pYloGHJUjHV/4FwW4TvVgFr4=
+github.com/lucasb-eyer/go-colorful v1.4.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
github.com/macabu/inamedparam v0.2.0 h1:VyPYpOc10nkhI2qeNUdh3Zket4fcZjEWe35poddBCpE=
github.com/macabu/inamedparam v0.2.0/go.mod h1:+Pee9/YfGe5LJ62pYXqB89lJ+0k5bsR8Wgz/C0Zlq3U=
github.com/magiconair/properties v1.8.6 h1:5ibWZ6iY0NctNGWo87LalDlEZ6R41TqbbDamhfG/Qzo=
github.com/magiconair/properties v1.8.6/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
github.com/manuelarte/embeddedstructfieldcheck v0.4.0 h1:3mAIyaGRtjK6EO9E73JlXLtiy7ha80b2ZVGyacxgfww=
github.com/manuelarte/embeddedstructfieldcheck v0.4.0/go.mod h1:z8dFSyXqp+fC6NLDSljRJeNQJJDWnY7RoWFzV3PC6UM=
-github.com/manuelarte/funcorder v0.5.0 h1:llMuHXXbg7tD0i/LNw8vGnkDTHFpTnWqKPI85Rknc+8=
-github.com/manuelarte/funcorder v0.5.0/go.mod h1:Yt3CiUQthSBMBxjShjdXMexmzpP8YGvGLjrxJNkO2hA=
+github.com/manuelarte/funcorder v0.6.0 h1:0hBngc4fa1IgNiI65A7sFGkMvoMCc878RjqB5V7rWP0=
+github.com/manuelarte/funcorder v0.6.0/go.mod h1:id3NDhXdQBmeqXH7eVC6Z89xS6JxvZ8kF9xUxpArU/g=
github.com/maratori/testableexamples v1.0.1 h1:HfOQXs+XgfeRBJ+Wz0XfH+FHnoY9TVqL6Fcevpzy4q8=
github.com/maratori/testableexamples v1.0.1/go.mod h1:XE2F/nQs7B9N08JgyRmdGjYVGqxWwClLPCGSQhXQSrQ=
github.com/maratori/testpackage v1.1.2 h1:ffDSh+AgqluCLMXhM19f/cpvQAKygKAJXFl9aUjmbqs=
@@ -384,14 +388,14 @@ github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHP
github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
-github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc=
-github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
-github.com/maxbrunsfeld/counterfeiter/v6 v6.12.0 h1:aOeI7xAOVdK+R6xbVsZuU9HmCZYmQVmZgPf9xJUd2Sg=
-github.com/maxbrunsfeld/counterfeiter/v6 v6.12.0/go.mod h1:0hZWbtfeCYUQeAQdPLUzETiBhUSns7O6LDj9vH88xKA=
+github.com/mattn/go-runewidth v0.0.23 h1:7ykA0T0jkPpzSvMS5i9uoNn2Xy3R383f9HDx3RybWcw=
+github.com/mattn/go-runewidth v0.0.23/go.mod h1:XBkDxAl56ILZc9knddidhrOlY5R/pDhgLpndooCuJAs=
+github.com/maxbrunsfeld/counterfeiter/v6 v6.12.2 h1:V23nK2R2B63g2GhygF9zVGpnigmhvoZoH8d0hrZwMGY=
+github.com/maxbrunsfeld/counterfeiter/v6 v6.12.2/go.mod h1:Mr897yU9FmyKaQDPtRlVKibrjz40XXyOHUfyZBPSyZU=
github.com/mfridman/tparse v0.18.0 h1:wh6dzOKaIwkUGyKgOntDW4liXSo37qg5AXbIhkMV3vE=
github.com/mfridman/tparse v0.18.0/go.mod h1:gEvqZTuCgEhPbYk/2lS3Kcxg1GmTxxU7kTC8DvP0i/A=
-github.com/mgechev/revive v1.13.0 h1:yFbEVliCVKRXY8UgwEO7EOYNopvjb1BFbmYqm9hZjBM=
-github.com/mgechev/revive v1.13.0/go.mod h1:efJfeBVCX2JUumNQ7dtOLDja+QKj9mYGgEZA7rt5u+0=
+github.com/mgechev/revive v1.15.0 h1:vJ0HzSBzfNyPbHKolgiFjHxLek9KUijhqh42yGoqZ8Q=
+github.com/mgechev/revive v1.15.0/go.mod h1:LlAKO3QQe9OJ0pVZzI2GPa8CbXGZ/9lNpCGvK4T/a8A=
github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw=
github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s=
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
@@ -410,8 +414,8 @@ github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 h1:n6/
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00/go.mod h1:Pm3mSP3c5uWn86xMLZ5Sa7JB9GsEZySvHYXCTK4E9q4=
github.com/moricho/tparallel v0.3.2 h1:odr8aZVFA3NZrNybggMkYO3rgPRcqjeQUlBBFVxKHTI=
github.com/moricho/tparallel v0.3.2/go.mod h1:OQ+K3b4Ln3l2TZveGCywybl68glfLEwFGqvnjok8b+U=
-github.com/muesli/termenv v0.16.0 h1:S5AlUN9dENB57rsbnkPyfdGuWIlkmzJjbFf0Tf5FWUc=
-github.com/muesli/termenv v0.16.0/go.mod h1:ZRfOIKPFDYQoDFF4Olj7/QJbW60Ol/kL1pU3VfY/Cnk=
+github.com/muesli/cancelreader v0.2.2 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELUXHmA=
+github.com/muesli/cancelreader v0.2.2/go.mod h1:3XuTXfFS2VjM+HTLZY9Ak0l6eUKfijIfMUZ4EgX0QYo=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
github.com/nakabonne/nestif v0.3.1 h1:wm28nZjhQY5HyYPx+weN3Q65k6ilSBxDb8v5S81B81U=
@@ -420,18 +424,18 @@ github.com/nishanths/exhaustive v0.12.0 h1:vIY9sALmw6T/yxiASewa4TQcFsVYZQQRUQJhK
github.com/nishanths/exhaustive v0.12.0/go.mod h1:mEZ95wPIZW+x8kC4TgC+9YCUgiST7ecevsVDTgc2obs=
github.com/nishanths/predeclared v0.2.2 h1:V2EPdZPliZymNAn79T8RkNApBjMmVKh5XRpLm/w98Vk=
github.com/nishanths/predeclared v0.2.2/go.mod h1:RROzoN6TnGQupbC+lqggsOlcgysk3LMK/HI84Mp280c=
-github.com/nunnatsa/ginkgolinter v0.21.2 h1:khzWfm2/Br8ZemX8QM1pl72LwM+rMeW6VUbQ4rzh0Po=
-github.com/nunnatsa/ginkgolinter v0.21.2/go.mod h1:GItSI5fw7mCGLPmkvGYrr1kEetZe7B593jcyOpyabsY=
+github.com/nunnatsa/ginkgolinter v0.23.0 h1:x3o4DGYOWbBMP/VdNQKgSj+25aJKx2Pe6lHr8gBcgf8=
+github.com/nunnatsa/ginkgolinter v0.23.0/go.mod h1:9qN1+0akwXEccwV1CAcCDfcoBlWXHB+ML9884pL4SZ4=
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU=
-github.com/onsi/ginkgo/v2 v2.27.4 h1:fcEcQW/A++6aZAZQNUmNjvA9PSOzefMJBerHJ4t8v8Y=
-github.com/onsi/ginkgo/v2 v2.27.4/go.mod h1:ArE1D/XhNXBXCBkKOLkbsb2c81dQHCRcF5zwn/ykDRo=
-github.com/onsi/gomega v1.39.0 h1:y2ROC3hKFmQZJNFeGAMeHZKkjBL65mIZcvrLQBF9k6Q=
-github.com/onsi/gomega v1.39.0/go.mod h1:ZCU1pkQcXDO5Sl9/VVEGlDyp+zm0m1cmeG5TOzLgdh4=
-github.com/openshift/build-machinery-go v0.0.0-20250806130835-622c0378eb0d h1:iwdrJUzp+GsbCNL84aZtSYwKSjrtxUJJ0cnVH8OsIeU=
-github.com/openshift/build-machinery-go v0.0.0-20250806130835-622c0378eb0d/go.mod h1:8jcm8UPtg2mCAsxfqKil1xrmRMI3a+XU2TZ9fF8A7TE=
+github.com/onsi/ginkgo/v2 v2.32.1 h1:6tlvcDm/3sE8lGJbZ4+d4mO3RLy24/tQWOFzVSQNIfw=
+github.com/onsi/ginkgo/v2 v2.32.1/go.mod h1:+aXOY+vzZ5mu2iI2HpTZUPmM//oQfsNFX6gU9kNcA44=
+github.com/onsi/gomega v1.40.0 h1:Vtol0e1MghCD2ZVIilPDIg44XSL9l2QAn8ZNaljWcJc=
+github.com/onsi/gomega v1.40.0/go.mod h1:M/Uqpu/8qTjtzCLUA2zJHX9Iilrau25x1PdoSRbWh5A=
+github.com/openshift/build-machinery-go v0.0.0-20260629141115-154a2b810491 h1:P/vZSEsUuAHMnf89gQ6FKIl9jsbPnNJ3gIBM43xn2Bg=
+github.com/openshift/build-machinery-go v0.0.0-20260629141115-154a2b810491/go.mod h1:8jcm8UPtg2mCAsxfqKil1xrmRMI3a+XU2TZ9fF8A7TE=
github.com/otiai10/copy v1.2.0/go.mod h1:rrF5dJ5F0t/EWSYODDu4j9/vEeYHMkc8jt0zJChqQWw=
github.com/otiai10/copy v1.14.0 h1:dCI/t1iTdYGtkvCuBG2BgR6KZa83PTclw4U5n2wAllU=
github.com/otiai10/copy v1.14.0/go.mod h1:ECfuL02W+/FkTWZWgQqXPWZgW9oeKCSQ5qVfSc4qc4w=
@@ -441,22 +445,19 @@ github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT9
github.com/otiai10/mint v1.3.1/go.mod h1:/yxELlJQ0ufhjUwhshSj+wFjZ78CnZ48/1wtmBH1OTc=
github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8=
github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
-github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4=
-github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY=
-github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
+github.com/pelletier/go-toml/v2 v2.3.1 h1:MYEvvGnQjeNkRF1qUuGolNtNExTDwct51yp7olPtrEc=
+github.com/pelletier/go-toml/v2 v2.3.1/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
-github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g=
-github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U=
github.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h0RJWRi/o0o=
github.com/prometheus/client_golang v1.23.2/go.mod h1:Tb1a6LWHB3/SPIzCoaDXI4I8UHKeFTEQ1YCr+0Gyqmg=
github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk=
github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE=
github.com/prometheus/common v0.67.5 h1:pIgK94WWlQt1WLwAC5j2ynLaBRDiinoAb86HZHTUGI4=
github.com/prometheus/common v0.67.5/go.mod h1:SjE/0MzDEEAyrdr5Gqc6G+sXI67maCxzaT3A2+HqjUw=
-github.com/prometheus/procfs v0.19.2 h1:zUMhqEW66Ex7OXIiDkll3tl9a1ZdilUOd/F6ZXw4Vws=
-github.com/prometheus/procfs v0.19.2/go.mod h1:M0aotyiemPhBCM0z5w87kL22CxfcH05ZpYlu+b4J7mw=
+github.com/prometheus/procfs v0.20.1 h1:XwbrGOIplXW/AU3YhIhLODXMJYyC1isLFfYCsTEycfc=
+github.com/prometheus/procfs v0.20.1/go.mod h1:o9EMBZGRyvDrSPH1RqdxhojkuXstoe4UlK79eF5TGGo=
github.com/quasilyte/go-ruleguard v0.4.5 h1:AGY0tiOT5hJX9BTdx/xBdoCubQUAE2grkqY2lSwvZcA=
github.com/quasilyte/go-ruleguard v0.4.5/go.mod h1:Vl05zJ538vcEEwu16V/Hdu7IYZWyKSwIy4c88Ro1kRE=
github.com/quasilyte/go-ruleguard/dsl v0.3.23 h1:lxjt5B6ZCiBeeNO8/oQsegE6fLeCzuMRoVWSkXC4uvY=
@@ -469,17 +470,17 @@ github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567 h1:M8mH9eK4OUR4l
github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567/go.mod h1:DWNGW8A4Y+GyBgPuaQJuWiy0XYftx4Xm/y5Jqk9I6VQ=
github.com/raeperd/recvcheck v0.2.0 h1:GnU+NsbiCqdC2XX5+vMZzP+jAJC5fht7rcVTAhX74UI=
github.com/raeperd/recvcheck v0.2.0/go.mod h1:n04eYkwIR0JbgD73wT8wL4JjPC3wm0nFtzBnWNocnYU=
-github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
-github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/ryancurrah/gomodguard v1.4.1 h1:eWC8eUMNZ/wM/PWuZBv7JxxqT5fiIKSIyTvjb7Elr+g=
github.com/ryancurrah/gomodguard v1.4.1/go.mod h1:qnMJwV1hX9m+YJseXEBhd2s90+1Xn6x9dLz11ualI1I=
-github.com/ryanrolds/sqlclosecheck v0.5.1 h1:dibWW826u0P8jNLsLN+En7+RqWWTYrjCB9fJfSfdyCU=
-github.com/ryanrolds/sqlclosecheck v0.5.1/go.mod h1:2g3dUjoS6AL4huFdv6wn55WpLIDjY7ZgUR4J8HOO/XQ=
+github.com/ryancurrah/gomodguard/v2 v2.1.3 h1:E7sz3PJwE9Ba1reVxSpF6XLCPJZ74Kfw/LabTNM4GIA=
+github.com/ryancurrah/gomodguard/v2 v2.1.3/go.mod h1:CQicdLGatWMxLX53JzoBjYlsNZhHbmLv2AVa0s2aivU=
+github.com/ryanrolds/sqlclosecheck v0.6.0 h1:pEyL9okISdg1F1SEpJNlrEotkTGerv5BMk7U4AG0eVg=
+github.com/ryanrolds/sqlclosecheck v0.6.0/go.mod h1:xyX16hsDaCMXHrMJ3JMzGf5OpDfHTOTTQrT7HOFUmeU=
github.com/sanposhiho/wastedassign/v2 v2.1.0 h1:crurBF7fJKIORrV85u9UUpePDYGWnwvv3+A96WvwXT0=
github.com/sanposhiho/wastedassign/v2 v2.1.0/go.mod h1:+oSmSC+9bQ+VUAxA66nBb0Z7N8CK7mscKTDYC6aIek4=
github.com/santhosh-tekuri/jsonschema/v6 v6.0.2 h1:KRzFb2m7YtdldCEkzs6KqmJw4nqEVZGK7IN2kJkjTuQ=
@@ -490,24 +491,24 @@ github.com/sashamelentyev/usestdlibvars v1.29.0 h1:8J0MoRrw4/NAXtjQqTHrbW9NN+3iM
github.com/sashamelentyev/usestdlibvars v1.29.0/go.mod h1:8PpnjHMk5VdeWlVb4wCdrB8PNbLqZ3wBZTZWkrpZZL8=
github.com/sclevine/spec v1.4.0 h1:z/Q9idDcay5m5irkZ28M7PtQM4aOISzOpj4bUPkDee8=
github.com/sclevine/spec v1.4.0/go.mod h1:LvpgJaFyvQzRvc1kaDs0bulYwzC70PbiYjC4QnFHkOM=
-github.com/securego/gosec/v2 v2.22.11 h1:tW+weM/hCM/GX3iaCV91d5I6hqaRT2TPsFM1+USPXwg=
-github.com/securego/gosec/v2 v2.22.11/go.mod h1:KE4MW/eH0GLWztkbt4/7XpyH0zJBBnu7sYB4l6Wn7Mw=
-github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ=
-github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
-github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk=
-github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ=
+github.com/securego/gosec/v2 v2.26.1 h1:gdkttGhQFVehqRJ8grKH4DrpqM/QlPKNHBnl8QgcEC4=
+github.com/securego/gosec/v2 v2.26.1/go.mod h1:57UW4p0uoP3kxoTkhoo3axLdVAi+OWrLg/Ax/kdqtPE=
+github.com/sergi/go-diff v1.4.0 h1:n/SP9D5ad1fORl+llWyN+D6qoUETXNZARKjyY2/KVCw=
+github.com/sergi/go-diff v1.4.0/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4=
+github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k=
+github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME=
github.com/sirupsen/logrus v1.9.4 h1:TsZE7l11zFCLZnZ+teH4Umoq5BhEIfIzfRDZ1Uzql2w=
github.com/sirupsen/logrus v1.9.4/go.mod h1:ftWc9WdOfJ0a92nsE2jF5u5ZwH8Bv2zdeOC42RjbV2g=
github.com/sivchari/containedctx v1.0.3 h1:x+etemjbsh2fB5ewm5FeLNi5bUjK0V8n0RB+Wwfd0XE=
github.com/sivchari/containedctx v1.0.3/go.mod h1:c1RDvCbnJLtH4lLcYD/GqwiBSSf4F5Qk0xld2rBqzJ4=
-github.com/sonatard/noctx v0.4.0 h1:7MC/5Gg4SQ4lhLYR6mvOP6mQVSxCrdyiExo7atBs27o=
-github.com/sonatard/noctx v0.4.0/go.mod h1:64XdbzFb18XL4LporKXp8poqZtPKbCrqQ402CV+kJas=
-github.com/sourcegraph/go-diff v0.7.0 h1:9uLlrd5T46OXs5qpp8L/MTltk0zikUGi0sNNyCpA8G0=
-github.com/sourcegraph/go-diff v0.7.0/go.mod h1:iBszgVvyxdc8SFZ7gm69go2KDdt3ag071iBaWPF6cjs=
+github.com/sonatard/noctx v0.5.1 h1:wklWg9c9ZYugOAk7qG4yP4PBrlQsmSLPTvW1K4PRQMs=
+github.com/sonatard/noctx v0.5.1/go.mod h1:64XdbzFb18XL4LporKXp8poqZtPKbCrqQ402CV+kJas=
+github.com/sourcegraph/go-diff v0.8.0 h1:ipIyu4cTsLbIrln4l0qtHA3r0a7gyK4ntKjtQytHhvY=
+github.com/sourcegraph/go-diff v0.8.0/go.mod h1:hWlcO7Al+UZStZAP8rBumHpCK5ZHQ5BXsMls8p4+F5E=
github.com/spf13/afero v1.15.0 h1:b/YBCLWAJdFWJTN9cLhiXXcD7mzKn9Dm86dNnfyQw1I=
github.com/spf13/afero v1.15.0/go.mod h1:NC2ByUVxtQs4b3sIUphxK0NioZnmxgyCrfzeuq8lxMg=
-github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w=
-github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU=
+github.com/spf13/cast v1.10.0 h1:h2x0u2shc1QuLHfxi+cTJvs30+ZAHOGRic8uyGTDWxY=
+github.com/spf13/cast v1.10.0/go.mod h1:jNfB8QC9IA6ZuY2ZjDp0KtFO2LZZlg4S/7bzP6qqeHo=
github.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU=
github.com/spf13/cobra v1.10.2/go.mod h1:7C1pvHqHw5A4vrJfjNwvOdzYu0Gml16OCs2GRiTUUS4=
github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk=
@@ -534,6 +535,7 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
+github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
github.com/subosito/gotenv v1.4.1 h1:jyEFiXpy21Wm81FBN71l9VoMMV8H8jG+qIK3GCpY6Qs=
@@ -542,8 +544,8 @@ github.com/tenntenn/modver v1.0.1 h1:2klLppGhDgzJrScMpkj9Ujy3rXPUspSjAcev9tSEBgA
github.com/tenntenn/modver v1.0.1/go.mod h1:bePIyQPb7UeioSRkw3Q0XeMhYZSMx9B8ePqg6SAMGH0=
github.com/tenntenn/text/transform v0.0.0-20200319021203-7eef512accb3 h1:f+jULpRQGxTSkNYKJ51yaw6ChIqO+Je8UqsTKN/cDag=
github.com/tenntenn/text/transform v0.0.0-20200319021203-7eef512accb3/go.mod h1:ON8b8w4BN/kE1EOhwT0o+d62W65a6aPw1nouo9LMgyY=
-github.com/tetafro/godot v1.5.4 h1:u1ww+gqpRLiIA16yF2PV1CV1n/X3zhyezbNXC3E14Sg=
-github.com/tetafro/godot v1.5.4/go.mod h1:eOkMrVQurDui411nBY2FA05EYH01r14LuWY/NrVDVcU=
+github.com/tetafro/godot v1.5.6 h1:IEkrFCwXaYHlOn4mGzGS3F3dkP6m9t0jpwqBFPIkKiA=
+github.com/tetafro/godot v1.5.6/go.mod h1:eOkMrVQurDui411nBY2FA05EYH01r14LuWY/NrVDVcU=
github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY=
github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
@@ -552,8 +554,8 @@ github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4=
github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY=
github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28=
-github.com/timakin/bodyclose v0.0.0-20241222091800-1db5c5ca4d67 h1:9LPGD+jzxMlnk5r6+hJnar67cgpDIz/iyD+rfl5r2Vk=
-github.com/timakin/bodyclose v0.0.0-20241222091800-1db5c5ca4d67/go.mod h1:mkjARE7Yr8qU23YcGMSALbIxTQ9r9QBVahQOBRfU460=
+github.com/timakin/bodyclose v0.0.0-20260129054331-73d1f95b84b4 h1:SiHe5XLTn9sFWJ5pBwJ5FN/4j34q9ZlOAD//kMoMYp0=
+github.com/timakin/bodyclose v0.0.0-20260129054331-73d1f95b84b4/go.mod h1:sDHLK7rb/59v/ZxZ7KtymgcoxuUMxjXq8gtu9VMOK8M=
github.com/timonwong/loggercheck v0.11.0 h1:jdaMpYBl+Uq9mWPXv1r8jc5fC3gyXx4/WGwTnnNKn4M=
github.com/timonwong/loggercheck v0.11.0/go.mod h1:HEAWU8djynujaAVX7QI65Myb8qgfcZ1uKbdpg3ZzKl8=
github.com/tomarrell/wrapcheck/v2 v2.12.0 h1:H/qQ1aNWz/eeIhxKAFvkfIA+N7YDvq6TWVFL27Of9is=
@@ -564,10 +566,10 @@ github.com/ultraware/funlen v0.2.0 h1:gCHmCn+d2/1SemTdYMiKLAHFYxTYz7z9VIDRaTGyLk
github.com/ultraware/funlen v0.2.0/go.mod h1:ZE0q4TsJ8T1SQcjmkhN/w+MceuatI6pBFSxxyteHIJA=
github.com/ultraware/whitespace v0.2.0 h1:TYowo2m9Nfj1baEQBjuHzvMRbp19i+RCcRYrSWoFa+g=
github.com/ultraware/whitespace v0.2.0/go.mod h1:XcP1RLD81eV4BW8UhQlpaR+SDc2givTvyI8a586WjW8=
-github.com/uudashr/gocognit v1.2.0 h1:3BU9aMr1xbhPlvJLSydKwdLN3tEUUrzPSSM8S4hDYRA=
-github.com/uudashr/gocognit v1.2.0/go.mod h1:k/DdKPI6XBZO1q7HgoV2juESI2/Ofj9AcHPZhBBdrTU=
-github.com/uudashr/iface v1.4.1 h1:J16Xl1wyNX9ofhpHmQ9h9gk5rnv2A6lX/2+APLTo0zU=
-github.com/uudashr/iface v1.4.1/go.mod h1:pbeBPlbuU2qkNDn0mmfrxP2X+wjPMIQAy+r1MBXSXtg=
+github.com/uudashr/gocognit v1.2.1 h1:CSJynt5txTnORn/DkhiB4mZjwPuifyASC8/6Q0I/QS4=
+github.com/uudashr/gocognit v1.2.1/go.mod h1:acaubQc6xYlXFEMb9nWX2dYBzJ/bIjEkc1zzvyIZg5Q=
+github.com/uudashr/iface v1.4.2 h1:06Vq5RKVYThBsj0Bnw4oasMjD1r+7CE/bcKOA8dVSvg=
+github.com/uudashr/iface v1.4.2/go.mod h1:pbeBPlbuU2qkNDn0mmfrxP2X+wjPMIQAy+r1MBXSXtg=
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
github.com/xen0n/gosmopolitan v1.3.0 h1:zAZI1zefvo7gcpbCOrPSHJZJYA9ZgLfJqtKzZ5pHqQM=
@@ -585,7 +587,6 @@ github.com/ykadowak/zerologlint v0.1.5/go.mod h1:KaUskqF3e/v59oPmdq1U1DnKcuHokl2
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
-github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
gitlab.com/bosi/decorder v0.4.2 h1:qbQaV3zgwnBZ4zPMhGLW4KZe7A7NwxEhJx39R3shffo=
@@ -594,84 +595,74 @@ go-simpler.org/assert v0.9.0 h1:PfpmcSvL7yAnWyChSjOz6Sp6m9j5lyK8Ok9pEL31YkQ=
go-simpler.org/assert v0.9.0/go.mod h1:74Eqh5eI6vCK6Y5l3PI8ZYFXG4Sa+tkr70OIPJAUr28=
go-simpler.org/musttag v0.14.0 h1:XGySZATqQYSEV3/YTy+iX+aofbZZllJaqwFWs+RTtSo=
go-simpler.org/musttag v0.14.0/go.mod h1:uP8EymctQjJ4Z1kUnjX0u2l60WfUdQxCwSNKzE1JEOE=
-go-simpler.org/sloglint v0.11.1 h1:xRbPepLT/MHPTCA6TS/wNfZrDzkGvCCqUv4Bdwc3H7s=
-go-simpler.org/sloglint v0.11.1/go.mod h1:2PowwiCOK8mjiF+0KGifVOT8ZsCNiFzvfyJeJOIt8MQ=
-go.augendre.info/arangolint v0.3.1 h1:n2E6p8f+zfXSFLa2e2WqFPp4bfvcuRdd50y6cT65pSo=
-go.augendre.info/arangolint v0.3.1/go.mod h1:6ZKzEzIZuBQwoSvlKT+qpUfIbBfFCE5gbAoTg0/117g=
+go-simpler.org/sloglint v0.12.0 h1:UzWDlLWNE5FLqsvyq3tWYHuQMbqrervOhT8qPl4Mmw4=
+go-simpler.org/sloglint v0.12.0/go.mod h1:jBjjC2bm8rYrs88oTRlFX497kWjJsyZWYoNaXkGRI6I=
+go.augendre.info/arangolint v0.4.0 h1:xSCZjRoS93nXazBSg5d0OGCi9APPLNMmmLrC995tR50=
+go.augendre.info/arangolint v0.4.0/go.mod h1:l+f/b4plABuFISuKnTGD4RioXiCCgghv2xqst/xOvAA=
go.augendre.info/fatcontext v0.9.0 h1:Gt5jGD4Zcj8CDMVzjOJITlSb9cEch54hjRRlN3qDojE=
go.augendre.info/fatcontext v0.9.0/go.mod h1:L94brOAT1OOUNue6ph/2HnwxoNlds9aXDF2FcUntbNw=
go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64=
go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y=
-go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.65.0 h1:7iP2uCb7sGddAr30RRS6xjKy7AZ2JtTOPA3oolgVSw8=
-go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.65.0/go.mod h1:c7hN3ddxs/z6q9xwvfLPk+UHlWRQyaeR1LdgfL/66l0=
-go.opentelemetry.io/otel v1.41.0 h1:YlEwVsGAlCvczDILpUXpIpPSL/VPugt7zHThEMLce1c=
-go.opentelemetry.io/otel v1.41.0/go.mod h1:Yt4UwgEKeT05QbLwbyHXEwhnjxNO6D8L5PQP51/46dE=
+go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.67.0 h1:OyrsyzuttWTSur2qN/Lm0m2a8yqyIjUVBZcxFPuXq2o=
+go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.67.0/go.mod h1:C2NGBr+kAB4bk3xtMXfZ94gqFDtg/GkI7e9zqGh5Beg=
+go.opentelemetry.io/otel v1.44.0 h1:JjwHmHpA4iZ3wBxluu2fbbE7j4kqlE8jXyAyPXH7HqU=
+go.opentelemetry.io/otel v1.44.0/go.mod h1:BMgjTHL9WPRlRjL2oZCBTL4whCGtXch2H4BhOPIAyYc=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.40.0 h1:QKdN8ly8zEMrByybbQgv8cWBcdAarwmIPZ6FThrWXJs=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.40.0/go.mod h1:bTdK1nhqF76qiPoCCdyFIV+N/sRHYXYCTQc+3VCi3MI=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.40.0 h1:DvJDOPmSWQHWywQS6lKL+pb8s3gBLOZUtw4N+mavW1I=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.40.0/go.mod h1:EtekO9DEJb4/jRyN4v4Qjc2yA7AtfCBuz2FynRUWTXs=
-go.opentelemetry.io/otel/metric v1.41.0 h1:rFnDcs4gRzBcsO9tS8LCpgR0dxg4aaxWlJxCno7JlTQ=
-go.opentelemetry.io/otel/metric v1.41.0/go.mod h1:xPvCwd9pU0VN8tPZYzDZV/BMj9CM9vs00GuBjeKhJps=
-go.opentelemetry.io/otel/sdk v1.40.0 h1:KHW/jUzgo6wsPh9At46+h4upjtccTmuZCFAc9OJ71f8=
-go.opentelemetry.io/otel/sdk v1.40.0/go.mod h1:Ph7EFdYvxq72Y8Li9q8KebuYUr2KoeyHx0DRMKrYBUE=
-go.opentelemetry.io/otel/trace v1.41.0 h1:Vbk2co6bhj8L59ZJ6/xFTskY+tGAbOnCtQGVVa9TIN0=
-go.opentelemetry.io/otel/trace v1.41.0/go.mod h1:U1NU4ULCoxeDKc09yCWdWe+3QoyweJcISEVa1RBzOis=
+go.opentelemetry.io/otel/metric v1.44.0 h1:1w0gILTcHdr3YI+ixLyjemwrVnsMURbTZFrSYCdDdmc=
+go.opentelemetry.io/otel/metric v1.44.0/go.mod h1:8O7hanEPBNgEMmybD3s2VBKcgWOCsA6tzHBPODAiquo=
+go.opentelemetry.io/otel/sdk v1.43.0 h1:pi5mE86i5rTeLXqoF/hhiBtUNcrAGHLKQdhg4h4V9Dg=
+go.opentelemetry.io/otel/sdk v1.43.0/go.mod h1:P+IkVU3iWukmiit/Yf9AWvpyRDlUeBaRg6Y+C58QHzg=
+go.opentelemetry.io/otel/trace v1.44.0 h1:jxF5CsGYCe74MCRx2X4g7WsY/VBKRqqpNvXlX/6gtIk=
+go.opentelemetry.io/otel/trace v1.44.0/go.mod h1:oLl1jrMQAVo6v3GAggN+1VH9VIz9iUSvW53sW1Q8PIE=
go.opentelemetry.io/proto/otlp v1.9.0 h1:l706jCMITVouPOqEnii2fIAuO3IVGBRPV5ICjceRb/A=
go.opentelemetry.io/proto/otlp v1.9.0/go.mod h1:xE+Cx5E/eEHw+ISFkwPLwCZefwVjY+pqKg1qcK03+/4=
-go.uber.org/automaxprocs v1.6.0 h1:O3y2/QNTOdbF+e/dpXNNW7Rx2hZ4sTIPyybbxyNqTUs=
-go.uber.org/automaxprocs v1.6.0/go.mod h1:ifeIMSnPZuznNm6jmdzmU3/bfk01Fe2fotchwEFJ8r8=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
-go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc=
-go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
-go.yaml.in/yaml/v2 v2.4.3 h1:6gvOSjQoTB3vt1l+CU+tSyi/HOjfOjRLJ4YwYZGwRO0=
-go.yaml.in/yaml/v2 v2.4.3/go.mod h1:zSxWcmIDjOzPXpjlTTbAsKokqkDNAVtZO0WOMiT90s8=
-go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
+go.uber.org/zap v1.28.0 h1:IZzaP1Fv73/T/pBMLk4VutPl36uNC+OSUh3JLG3FIjo=
+go.uber.org/zap v1.28.0/go.mod h1:rDLpOi171uODNm/mxFcuYWxDsqWSAVkFdX4XojSKg/Q=
+go.yaml.in/yaml/v2 v2.4.4 h1:tuyd0P+2Ont/d6e2rl3be67goVK4R6deVxCUX5vyPaQ=
+go.yaml.in/yaml/v2 v2.4.4/go.mod h1:gMZqIpDtDqOfM0uNfy0SkpRhvUryYH0Z6wdMYcacYXQ=
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
+go.yaml.in/yaml/v3 v3.0.5 h1:N6y/pJk8buWs9NY5ERU2HSMfm+IuD/OtfdAnq6kESPw=
+go.yaml.in/yaml/v3 v3.0.5/go.mod h1:HVTZu1O7/Vkt2N+BFy8Zza+lnLsABggaTM2ZpNIGuKg=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
-golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
-golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
golang.org/x/crypto v0.55.0 h1:+KWHjbgOaAQ66dh/YlkZKHlz9ZUlq61AFirAR9ntP8M=
golang.org/x/crypto v0.55.0/go.mod h1:uq0V9dE/fzQuJtbnL+2EhWOE63vo164FY8xqEnV9xis=
golang.org/x/exp v0.0.0-20260112195511-716be5621a96 h1:Z/6YuSHTLOHfNFdb8zVZomZr7cqNgTJvA8+Qz75D8gU=
golang.org/x/exp v0.0.0-20260112195511-716be5621a96/go.mod h1:nzimsREAkjBCIEFtHiYkrJyT+2uy9YZJB7H1k68CXZU=
golang.org/x/exp/typeparams v0.0.0-20220428152302-39d4317da171/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk=
golang.org/x/exp/typeparams v0.0.0-20230203172020-98cc5a0785f9/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk=
-golang.org/x/exp/typeparams v0.0.0-20251023183803-a4bb9ffd2546 h1:HDjDiATsGqvuqvkDvgJjD1IgPrVekcSXVVE21JwvzGE=
-golang.org/x/exp/typeparams v0.0.0-20251023183803-a4bb9ffd2546/go.mod h1:4Mzdyp/6jzw9auFDJ3OMF5qksa7UvPnzKqTVGcb04ms=
+golang.org/x/exp/typeparams v0.0.0-20260209203927-2842357ff358 h1:qWFG1Dj7TBjOjOvhEOkmyGPVoquqUKnIU0lEVLp8xyk=
+golang.org/x/exp/typeparams v0.0.0-20260209203927-2842357ff358/go.mod h1:4Mzdyp/6jzw9auFDJ3OMF5qksa7UvPnzKqTVGcb04ms=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
-golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
-golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
-golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
-golang.org/x/mod v0.38.0 h1:MECBjubtXD7yj4HrhIUcywNaGeNVUdfVnxmPajOk4yk=
-golang.org/x/mod v0.38.0/go.mod h1:V6Xz0pq8TQ3dGqVQ1FVHuelZpAL0uNhSkk9ogYP3c40=
+golang.org/x/mod v0.40.0 h1:hUv+3cXcdRHz08UmSiOob7sadHig73uo5bkXxQ/tvUs=
+golang.org/x/mod v0.40.0/go.mod h1:0/weTWkPWGBikyTWAX3dkjVztMmBA5hM0DH6BElSupE=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
-golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
-golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
-golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
-golang.org/x/net v0.16.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
golang.org/x/net v0.58.0 h1:ynWG7rqYi4ccpTEuPZ2QGWHktVEM9DMCj9yzDE0Q7To=
golang.org/x/net v0.58.0/go.mod h1:YwCddHnFlT7eLQqVprV19OnhLGtc5xOKgE0RyqgfWAU=
-golang.org/x/oauth2 v0.34.0 h1:hqK/t4AKgbqWkdkcAeI8XLmbK+4m4G5YeQRrmiotGlw=
-golang.org/x/oauth2 v0.34.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA=
+golang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs=
+golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -679,8 +670,6 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
-golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
golang.org/x/sync v0.22.0 h1:SZjpbeLmrCk4xhRSZFNZW5gFUeCeFgjekvI/+gfScek=
golang.org/x/sync v0.22.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -689,9 +678,7 @@ golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211105183446-c75c47738b0c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@@ -699,19 +686,13 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.47.0 h1:o7XGOvZQCADBQQ4Y7VNq2dRWQR7JmOUW8Kxx4ZsNgWs=
golang.org/x/sys v0.47.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
-golang.org/x/telemetry v0.0.0-20260708182218-49f421fb7959 h1:RJhm5l6Fo4rmEIcndxDllNhhf/fAx8qIm4t6A7vpm2A=
-golang.org/x/telemetry v0.0.0-20260708182218-49f421fb7959/go.mod h1:LV7u5Oco+Z/g6XI7PqN+EUUUGGkEcmB1uj2ceI0fOVg=
+golang.org/x/telemetry v0.0.0-20260811182544-a038080d80e5 h1:ZUSxONxc981v7AW7QUg+I9WwZzSTTJ019ENBYr5pV/Q=
+golang.org/x/telemetry v0.0.0-20260811182544-a038080d80e5/go.mod h1:LVehoXe41cL5SCVQilsV7Gg6BNG+Js6P9PhSbYTIUkQ=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
-golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
-golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU=
-golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U=
golang.org/x/term v0.45.0 h1:NwWyBmoJCbfTHpxrWoZ9C6/VxOf7ic219I8xZZFdrf0=
golang.org/x/term v0.45.0/go.mod h1:9aqxs0blBcrm/n0L9QW0aRVD+ktan8ssZromtqJC43w=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -720,44 +701,39 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
-golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
-golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/text v0.41.0 h1:vz/seA0lnX87Othu2f/0L24RcgrXD9/YFTSuGjj3rH8=
golang.org/x/text v0.41.0/go.mod h1:jvf1O8ajNzZqhSrQBPbutR/EB83Cc0CFrezNQIwbb5M=
-golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI=
-golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4=
+golang.org/x/time v0.15.0 h1:bbrp8t3bGUeFOx08pvsMYRTCVSMk89u4tKbNOZbp88U=
+golang.org/x/time v0.15.0/go.mod h1:Y4YMaQmXwGQZoFaVFk4YpCt4FLQMYKZe9oeV/f4MSno=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200329025819-fd4102a86c65/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
golang.org/x/tools v0.0.0-20200724022722-7017fd6b1305/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.1.1-0.20210205202024-ef80cdb6ec6d/go.mod h1:9bzcO0MWcOuT0tm1iBGzDVPshzfwoVvREIui8C+MHqU=
golang.org/x/tools v0.1.1-0.20210302220138-2ac05c832e1a/go.mod h1:9bzcO0MWcOuT0tm1iBGzDVPshzfwoVvREIui8C+MHqU=
-golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
-golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
-golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg=
-golang.org/x/tools v0.48.0 h1:3+hClM1aLL5mjMKm5ovokw9epgRXPuu2tILgismM6RE=
-golang.org/x/tools v0.48.0/go.mod h1:08xX0orndb/F7jJxGDicx061tyd5pcMto75YMAXr6lk=
+golang.org/x/tools v0.49.0 h1:3NI7VXzL9+1WZD52Dx2ttoPwD5DWrFGpl9mFZDlmisI=
+golang.org/x/tools v0.49.0/go.mod h1:SJNXV9DBKT0UbdttsQjbfJlAE/q+y36++zo3uL3N0Oo=
golang.org/x/tools/go/expect v0.1.1-deprecated h1:jpBZDwmgPhXsKZC6WhL20P4b/wmnpsEAGHaNy0n/rJM=
golang.org/x/tools/go/expect v0.1.1-deprecated/go.mod h1:eihoPOH+FgIqa3FpoTwguz/bVUSGBlGQU67vpBeOrBY=
golang.org/x/tools/go/packages/packagestest v0.1.1-deprecated h1:1h2MnaIAIXISqTFKdENegdpAgUXz6NrPEsbIeWaBRvM=
golang.org/x/tools/go/packages/packagestest v0.1.1-deprecated/go.mod h1:RVAQXBGNv1ib0J382/DPCRS/BPnsGebyM1Gj5VSDpG8=
-golang.org/x/vuln v1.1.4 h1:Ju8QsuyhX3Hk8ma3CesTbO8vfJD9EvUBgHvkxHBzj0I=
-golang.org/x/vuln v1.1.4/go.mod h1:F+45wmU18ym/ca5PLTPLsSzr2KppzswxPP603ldA67s=
+golang.org/x/vuln v1.7.0 h1:4MQBuhmXbz2uepNJrf3v+aaZLGDqw1JluwYboegA1qg=
+golang.org/x/vuln v1.7.0/go.mod h1:Xw7zvU3e1bsCYYBXu+w4wcn2Kgn27f34WBCTw8LL5Us=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
-google.golang.org/genproto/googleapis/api v0.0.0-20260202165425-ce8ad4cf556b h1:SGYyueaEovpqmWmtTvwtVgo638V/QFE2zlTCnRrR3jg=
-google.golang.org/genproto/googleapis/api v0.0.0-20260202165425-ce8ad4cf556b/go.mod h1:ZdbssH/1SOVnjnDlXzxDHK2MCidiqXtbYccJNzNYPEE=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20260202165425-ce8ad4cf556b h1:GZxXGdFaHX27ZSMHudWc4FokdD+xl8BC2UJm1OVIEzs=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20260202165425-ce8ad4cf556b/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ=
-google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE=
-google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ=
-google.golang.org/protobuf v1.36.12-0.20260120151049-f2248ac996af h1:+5/Sw3GsDNlEmu7TfklWKPdQ0Ykja5VEmq2i817+jbI=
-google.golang.org/protobuf v1.36.12-0.20260120151049-f2248ac996af/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
+google.golang.org/genproto/googleapis/api v0.0.0-20260414002931-afd174a4e478 h1:yQugLulqltosq0B/f8l4w9VryjV+N/5gcW0jQ3N8Qec=
+google.golang.org/genproto/googleapis/api v0.0.0-20260414002931-afd174a4e478/go.mod h1:C6ADNqOxbgdUUeRTU+LCHDPB9ttAMCTff6auwCVa4uc=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20260610212136-7ab31c22f7ad h1:45WmJvIV6C2+O/jjLkPUH+F3aOj/1miDoU2DD0+NWbg=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20260610212136-7ab31c22f7ad/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8=
+google.golang.org/grpc v1.82.1 h1:NnAxzGRA0677vCa4BUkOAnO5+FfQqVl9iUXeD0IqcGE=
+google.golang.org/grpc v1.82.1/go.mod h1:yzTZ1TB1Z3SG+LIYaI+WiE8D5+PZ3ArnrSp8zF3+/ZA=
+google.golang.org/protobuf v1.36.12 h1:pJOKDDOyeXErUroCihFAd5LQuwXBSpVnKGrj5o/fwxc=
+google.golang.org/protobuf v1.36.12/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
@@ -766,66 +742,65 @@ gopkg.in/evanphx/json-patch.v4 v4.13.0 h1:czT3CmqEaQ1aanPc5SdlgQrrEIb8w/wwCvWWnf
gopkg.in/evanphx/json-patch.v4 v4.13.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M=
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
-gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
-gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
+gopkg.in/ini.v1 v1.67.1 h1:tVBILHy0R6e4wkYOn3XmiITt/hEVH4TFMYvAX2Ytz6k=
+gopkg.in/ini.v1 v1.67.1/go.mod h1:x/cyOwCgZqOkJoDIJ3c1KNHMo10+nLGAhh+kn3Zizss=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
-gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
-honnef.co/go/tools v0.6.1 h1:R094WgE8K4JirYjBaOpz/AvTyUu/3wbmAoskKN/pxTI=
-honnef.co/go/tools v0.6.1/go.mod h1:3puzxxljPCe8RGJX7BIy1plGbxEOZni5mR2aXe3/uk4=
-k8s.io/api v0.35.6 h1:phPzP79F3kcONsD2TzmDiITNCV6/1Z5U3CCEcjtsXzI=
-k8s.io/api v0.35.6/go.mod h1:GWKUaIp24fuDFigAgnhr9EJOKDqspnwPjYlpDca5B4U=
-k8s.io/apiextensions-apiserver v0.35.3 h1:2fQUhEO7P17sijylbdwt0nBdXP0TvHrHj0KeqHD8FiU=
-k8s.io/apiextensions-apiserver v0.35.3/go.mod h1:tK4Kz58ykRpwAEkXUb634HD1ZAegEElktz/B3jgETd8=
-k8s.io/apimachinery v0.35.6 h1:ASSpfmmsOArKb2Hsu8gGlIcbIcEMVTboI3FfsfYuQ8k=
-k8s.io/apimachinery v0.35.6/go.mod h1:NNi1taPOpep0jOj+oRha3mBJPqvi0hGdaV8TCqGQ+cc=
-k8s.io/apiserver v0.35.6 h1:VWYg2S0wlAmN3URFpVeuLa4PP2RCpTFg1nvlUHOy2C8=
-k8s.io/apiserver v0.35.6/go.mod h1:wajGSrXO9w+lx69jYq4SaE4Xxw5KxxwvVD1zbttYA2E=
-k8s.io/client-go v0.35.6 h1:qZQv9a5B4YlIpXhFBwsI9qPOOJC6Z8lk9lkEWmrmus8=
-k8s.io/client-go v0.35.6/go.mod h1:LOO6N1EhxdQAzYIZ/73cJVyb3gixrMY6ZDJcJ/ANfsY=
-k8s.io/code-generator v0.35.3 h1:NDGCLkEm6Ho65wTdSe2EgErmmtsrezOPwwOchlNc6FQ=
-k8s.io/code-generator v0.35.3/go.mod h1:LAVriRGXQusHQ0Ns64SE1ublSswm1KrK7cXn0GuQETg=
-k8s.io/component-base v0.35.6 h1:dTkck9uefkIrKn7wRCEYiDWNUvHd8UdwZCcVafmHgL4=
-k8s.io/component-base v0.35.6/go.mod h1:qcNKrspACsqR+vgUJXkWzwtgUGkURcnrus41o92jjpk=
-k8s.io/gengo/v2 v2.0.0-20250922181213-ec3ebc5fd46b h1:gMplByicHV/TJBizHd9aVEsTYoJBnnUAT5MHlTkbjhQ=
-k8s.io/gengo/v2 v2.0.0-20250922181213-ec3ebc5fd46b/go.mod h1:CgujABENc3KuTrcsdpGmrrASjtQsWCT7R99mEV4U/fM=
+honnef.co/go/tools v0.7.0 h1:w6WUp1VbkqPEgLz4rkBzH/CSU6HkoqNLp6GstyTx3lU=
+honnef.co/go/tools v0.7.0/go.mod h1:pm29oPxeP3P82ISxZDgIYeOaf9ta6Pi0EWvCFoLG2vc=
+k8s.io/api v0.36.3 h1:NxB+05W2UGqXWFXcLO0RB5cnqnUPP5v5sVlaOH0Iz4w=
+k8s.io/api v0.36.3/go.mod h1:JzLQKqRHC5+I8RVj/lS3lCg0mg6nWI9Fo/Sk3ElxHzg=
+k8s.io/apiextensions-apiserver v0.36.3 h1:dPmOAPhwTtqb1bTxbFPsy18KHPhktQeO3WUPXunZIB0=
+k8s.io/apiextensions-apiserver v0.36.3/go.mod h1:KTXFqgXiuw2pRoL+Wpmttqc+up9Xt/GohadPWeLLOa4=
+k8s.io/apimachinery v0.36.3 h1:PkzMRBRG8joFD8EhCuQAtNPvJlxb82FwplP26HIzvAM=
+k8s.io/apimachinery v0.36.3/go.mod h1:cTSjBWgPe/6CQyBKzY/hDIRWCQQQeK0mfLbml0UYFHE=
+k8s.io/apiserver v0.36.3 h1:MGSg2SkdfuytiDEcRylT5mQFmmSsbx90XFUO67Y4bsQ=
+k8s.io/apiserver v0.36.3/go.mod h1:fVH7zv9EUNUA7Fl7LtDKh8aB9W7u1VQPSGtWV5SjUxg=
+k8s.io/client-go v0.36.3 h1:M4JdVzXxYcZk4fGpfDdYnxSwhLKWCFoQsHW6t+z8Hfg=
+k8s.io/client-go v0.36.3/go.mod h1:gcPwr0c87vjjG6HB6pWEqOeuYVoXSsREjzux2j6GF30=
+k8s.io/code-generator v0.36.3 h1:tsiHI6NepXQncnexlTAf52w5VxZ4HYDU4ZqCNLFb9tA=
+k8s.io/code-generator v0.36.3/go.mod h1:Unn13Mp8X+H803jgZi4f4ExxK11aj0llXcSsl++UTkE=
+k8s.io/component-base v0.36.3 h1:vc/UFvPCkW0irPz84LAodAL1j3f4xktPM6dDJIEheAY=
+k8s.io/component-base v0.36.3/go.mod h1:hZbNFG+gCMl9EbykDGEu73feKP9/Cq6JsV4pTo9GTO8=
+k8s.io/gengo/v2 v2.0.0-20260408192533-25e2208e0dc3 h1:3L6PNkMLXkU/pz3jWzaaIUz0Rs2V9h+5O51AeRC7poc=
+k8s.io/gengo/v2 v2.0.0-20260408192533-25e2208e0dc3/go.mod h1:yvyl3l9E+UxlqOMUULdKTAYB0rEhsmjr7+2Vb/1pCSo=
k8s.io/klog/v2 v2.140.0 h1:Tf+J3AH7xnUzZyVVXhTgGhEKnFqye14aadWv7bzXdzc=
k8s.io/klog/v2 v2.140.0/go.mod h1:o+/RWfJ6PwpnFn7OyAG3QnO47BFsymfEfrz6XyYSSp0=
-k8s.io/kube-openapi v0.0.0-20260317180543-43fb72c5454a h1:xCeOEAOoGYl2jnJoHkC3hkbPJgdATINPMAxaynU2Ovg=
-k8s.io/kube-openapi v0.0.0-20260317180543-43fb72c5454a/go.mod h1:uGBT7iTA6c6MvqUvSXIaYZo9ukscABYi2btjhvgKGZ0=
-k8s.io/utils v0.0.0-20260210185600-b8788abfbbc2 h1:AZYQSJemyQB5eRxqcPky+/7EdBj0xi3g0ZcxxJ7vbWU=
-k8s.io/utils v0.0.0-20260210185600-b8788abfbbc2/go.mod h1:xDxuJ0whA3d0I4mf/C4ppKHxXynQ+fxnkmQH0vTHnuk=
+k8s.io/kube-openapi v0.0.0-20260721132016-d427ff9ee9ad h1:oXImqH8mQNk7PmvzKhmN3ddJoY6OnyM225MXwGHPm0A=
+k8s.io/kube-openapi v0.0.0-20260721132016-d427ff9ee9ad/go.mod h1:0/mqHCVhlumdJ3BhCfnjSZQE037nAhNodh1/hK0T8/I=
+k8s.io/utils v0.0.0-20260707023825-cf1189d6abe3 h1:jVkFFVfXdXP74B/zbO3hM3hpSFD0xvhQ5U686DPurkE=
+k8s.io/utils v0.0.0-20260707023825-cf1189d6abe3/go.mod h1:M2s5JB1lIYP3jzZdorPLHXIPJzt9vv2muW5a6L9DtNM=
mvdan.cc/gofumpt v0.9.2 h1:zsEMWL8SVKGHNztrx6uZrXdp7AX8r421Vvp23sz7ik4=
mvdan.cc/gofumpt v0.9.2/go.mod h1:iB7Hn+ai8lPvofHd9ZFGVg2GOr8sBUw1QUWjNbmIL/s=
mvdan.cc/unparam v0.0.0-20251027182757-5beb8c8f8f15 h1:ssMzja7PDPJV8FStj7hq9IKiuiKhgz9ErWw+m68e7DI=
mvdan.cc/unparam v0.0.0-20251027182757-5beb8c8f8f15/go.mod h1:4M5MMXl2kW6fivUT6yRGpLLPNfuGtU2Z0cPvFquGDYU=
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.34.0 h1:hSfpvjjTQXQY2Fol2CS0QHMNs/WI1MOSGzCm1KhM5ec=
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.34.0/go.mod h1:Ve9uj1L+deCXFrPOk1LpFXqTg7LCFzFso6PA48q/XZw=
-sigs.k8s.io/controller-runtime/tools/setup-envtest v0.0.0-20250308055145-5fe7bb3edc86 h1:96TA+X7D58V3065duUfj+p+Pp17q8U02+cSCmE3IsaU=
-sigs.k8s.io/controller-runtime/tools/setup-envtest v0.0.0-20250308055145-5fe7bb3edc86/go.mod h1:IaDsO8xSPRxRG1/rm9CP7+jPmj0nMNAuNi/yiHnLX8k=
-sigs.k8s.io/controller-tools v0.19.0 h1:OU7jrPPiZusryu6YK0jYSjPqg8Vhf8cAzluP9XGI5uk=
-sigs.k8s.io/controller-tools v0.19.0/go.mod h1:y5HY/iNDFkmFla2CfQoVb2AQXMsBk4ad84iR1PLANB0=
+sigs.k8s.io/controller-runtime/tools/setup-envtest v0.24.1 h1:l2AjyGE/PWub6EB165ij4/bpCK0TlY5NlhzIHfmGvmg=
+sigs.k8s.io/controller-runtime/tools/setup-envtest v0.24.1/go.mod h1:wpkYufRHTSw9ABET21/PkEL7kdGnmiZJ6o72t9p/1I8=
+sigs.k8s.io/controller-tools v0.21.0 h1:KXDQza3bgjlPY6xLR63tI/40gzjhyUAvkCrwzd2/6cs=
+sigs.k8s.io/controller-tools v0.21.0/go.mod h1:DLIypi3Q2+azVAP8jr/mHXJgveYYHFjhnNOUuBJ10JE=
sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 h1:IpInykpT6ceI+QxKBbEflcR5EXP7sU1kvOlxwZh5txg=
sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg=
-sigs.k8s.io/kube-api-linter v0.0.0-20251208100930-d3015c953951 h1:pjOeiLsYwEPaSRYTiMtVfdn7gSoRilw7Peyjw6kyUu4=
-sigs.k8s.io/kube-api-linter v0.0.0-20251208100930-d3015c953951/go.mod h1:5mP60UakkCye+eOcZ5p98VnV2O49qreW1gq9TdsUf7Q=
-sigs.k8s.io/kustomize/api v0.20.1 h1:iWP1Ydh3/lmldBnH/S5RXgT98vWYMaTUL1ADcr+Sv7I=
-sigs.k8s.io/kustomize/api v0.20.1/go.mod h1:t6hUFxO+Ph0VxIk1sKp1WS0dOjbPCtLJ4p8aADLwqjM=
-sigs.k8s.io/kustomize/cmd/config v0.20.1 h1:4APUORmZe2BYrsqgGfEKdd/r7gM6i43egLrUzilpiFo=
-sigs.k8s.io/kustomize/cmd/config v0.20.1/go.mod h1:R7rQ8kxknVlXWVUIbxWtMgu8DCCNVtl8V0KrmeVd/KE=
-sigs.k8s.io/kustomize/kustomize/v5 v5.7.1 h1:sYJsarwy/SDJfjjLMUqwFDGPwzUtMOQ1i1Ed49+XSbw=
-sigs.k8s.io/kustomize/kustomize/v5 v5.7.1/go.mod h1:+5/SrBcJ4agx1SJknGuR/c9thwRSKLxnKoI5BzXFaLU=
-sigs.k8s.io/kustomize/kyaml v0.20.1 h1:PCMnA2mrVbRP3NIB6v9kYCAc38uvFLVs8j/CD567A78=
-sigs.k8s.io/kustomize/kyaml v0.20.1/go.mod h1:0EmkQHRUsJxY8Ug9Niig1pUMSCGHxQ5RklbpV/Ri6po=
+sigs.k8s.io/kube-api-linter v0.0.0-20260716143926-092fe0c72997 h1:u5/qbXZq7YIrurEE6HiJKtjQ9ILcFPJJSHNY0Q1ZRhU=
+sigs.k8s.io/kube-api-linter v0.0.0-20260716143926-092fe0c72997/go.mod h1:5mP60UakkCye+eOcZ5p98VnV2O49qreW1gq9TdsUf7Q=
+sigs.k8s.io/kustomize/api v0.21.1 h1:lzqbzvz2CSvsjIUZUBNFKtIMsEw7hVLJp0JeSIVmuJs=
+sigs.k8s.io/kustomize/api v0.21.1/go.mod h1:f3wkKByTrgpgltLgySCntrYoq5d3q7aaxveSagwTlwI=
+sigs.k8s.io/kustomize/cmd/config v0.21.1 h1:/gxf3J1rQD9nfuL8fHlrTLeUL+JHWbK44eOnXJDYx0M=
+sigs.k8s.io/kustomize/cmd/config v0.21.1/go.mod h1:7yEFYBJyBJlpZQ50VaRGQRtFMn3Vzn9Fb2wts4TCok4=
+sigs.k8s.io/kustomize/kustomize/v5 v5.8.1 h1:Pgsg5psubpVEy7Nf6S89PARg5VmmWUC1l9dC6Dl4PG0=
+sigs.k8s.io/kustomize/kustomize/v5 v5.8.1/go.mod h1:0vFa5pQ/elNEQMyiAJuGku9rhAMzz7u9+61hRqFKiwY=
+sigs.k8s.io/kustomize/kyaml v0.21.1 h1:IVlbmhC076nf6foyL6Taw4BkrLuEsXUXNpsE+ScX7fI=
+sigs.k8s.io/kustomize/kyaml v0.21.1/go.mod h1:hmxADesM3yUN2vbA5z1/YTBnzLJ1dajdqpQonwBL1FQ=
sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU=
sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY=
-sigs.k8s.io/structured-merge-diff/v6 v6.3.2 h1:kwVWMx5yS1CrnFWA/2QHyRVJ8jM6dBA80uLmm0wJkk8=
-sigs.k8s.io/structured-merge-diff/v6 v6.3.2/go.mod h1:M3W8sfWvn2HhQDIbGWj3S099YozAsymCo/wrT5ohRUE=
+sigs.k8s.io/structured-merge-diff/v6 v6.4.2 h1:qdOxHwrl2Kaag1aQEarlYcOA9vSyGCp3CIki3aW8c4Q=
+sigs.k8s.io/structured-merge-diff/v6 v6.4.2/go.mod h1:M3W8sfWvn2HhQDIbGWj3S099YozAsymCo/wrT5ohRUE=
sigs.k8s.io/yaml v1.6.0 h1:G8fkbMSAFqgEFgh4b1wmtzDnioxFCUgTZhlbj5P9QYs=
sigs.k8s.io/yaml v1.6.0/go.mod h1:796bPqUfzR/0jLAl6XjHl3Ck7MiyVv8dbTdyT3/pMf4=
diff --git a/vendor/charm.land/lipgloss/v2/.editorconfig b/vendor/charm.land/lipgloss/v2/.editorconfig
new file mode 100644
index 000000000..5de2df8c5
--- /dev/null
+++ b/vendor/charm.land/lipgloss/v2/.editorconfig
@@ -0,0 +1,18 @@
+# https://editorconfig.org/
+
+root = true
+
+[*]
+charset = utf-8
+insert_final_newline = true
+trim_trailing_whitespace = true
+indent_style = space
+indent_size = 2
+
+[*.go]
+indent_style = tab
+indent_size = 8
+
+[*.golden]
+insert_final_newline = false
+trim_trailing_whitespace = false
diff --git a/vendor/charm.land/lipgloss/v2/.gitattributes b/vendor/charm.land/lipgloss/v2/.gitattributes
new file mode 100644
index 000000000..d5273520a
--- /dev/null
+++ b/vendor/charm.land/lipgloss/v2/.gitattributes
@@ -0,0 +1 @@
+*.golden linguist-generated=true -text
diff --git a/vendor/charm.land/lipgloss/v2/.gitignore b/vendor/charm.land/lipgloss/v2/.gitignore
new file mode 100644
index 000000000..3b478f575
--- /dev/null
+++ b/vendor/charm.land/lipgloss/v2/.gitignore
@@ -0,0 +1,3 @@
+ssh_example_ed25519*
+/tmp
+**/.crush/**
diff --git a/vendor/charm.land/lipgloss/v2/.golangci.yml b/vendor/charm.land/lipgloss/v2/.golangci.yml
new file mode 100644
index 000000000..c90f03161
--- /dev/null
+++ b/vendor/charm.land/lipgloss/v2/.golangci.yml
@@ -0,0 +1,47 @@
+version: "2"
+run:
+ tests: false
+linters:
+ enable:
+ - bodyclose
+ - exhaustive
+ - goconst
+ - godot
+ - gomoddirectives
+ - goprintffuncname
+ - gosec
+ - misspell
+ - nakedret
+ - nestif
+ - nilerr
+ - noctx
+ - nolintlint
+ - prealloc
+ - revive
+ - rowserrcheck
+ - sqlclosecheck
+ - tparallel
+ - unconvert
+ - unparam
+ - whitespace
+ - wrapcheck
+ exclusions:
+ rules:
+ - text: '(slog|log)\.\w+'
+ linters:
+ - noctx
+ generated: lax
+ presets:
+ - common-false-positives
+ settings:
+ exhaustive:
+ default-signifies-exhaustive: true
+issues:
+ max-issues-per-linter: 0
+ max-same-issues: 0
+formatters:
+ enable:
+ - gofumpt
+ - goimports
+ exclusions:
+ generated: lax
diff --git a/vendor/charm.land/lipgloss/v2/.goreleaser.yml b/vendor/charm.land/lipgloss/v2/.goreleaser.yml
new file mode 100644
index 000000000..c61970e07
--- /dev/null
+++ b/vendor/charm.land/lipgloss/v2/.goreleaser.yml
@@ -0,0 +1,5 @@
+includes:
+ - from_url:
+ url: charmbracelet/meta/main/goreleaser-lib.yaml
+# yaml-language-server: $schema=https://goreleaser.com/static/schema-pro.json
+
diff --git a/vendor/charm.land/lipgloss/v2/LICENSE b/vendor/charm.land/lipgloss/v2/LICENSE
new file mode 100644
index 000000000..9f60dc1fc
--- /dev/null
+++ b/vendor/charm.land/lipgloss/v2/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2021-2026 Charmbracelet, Inc.
+
+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.
diff --git a/vendor/charm.land/lipgloss/v2/README.md b/vendor/charm.land/lipgloss/v2/README.md
new file mode 100644
index 000000000..4fda64003
--- /dev/null
+++ b/vendor/charm.land/lipgloss/v2/README.md
@@ -0,0 +1,996 @@
+# Lip Gloss
+
+
+
+
+
+
+
+
+Style definitions for nice terminal layouts. Built with TUIs in mind.
+
+
+
+Lip Gloss takes an expressive, declarative approach to terminal rendering.
+Users familiar with CSS will feel at home with Lip Gloss.
+
+```go
+import "charm.land/lipgloss/v2"
+
+var style = lipgloss.NewStyle().
+ Bold(true).
+ Foreground(lipgloss.Color("#FAFAFA")).
+ Background(lipgloss.Color("#7D56F4")).
+ PaddingTop(2).
+ PaddingLeft(4).
+ Width(22)
+
+lipgloss.Println(style.Render("Hello, kitty"))
+```
+
+## Installation
+
+```bash
+go get charm.land/lipgloss/v2
+```
+
+> [!TIP]
+>
+> Upgrading from v1? Check out the [upgrade guide](./UPGRADE_GUIDE_V2.md), or
+> point your LLM at it and let it go to town.
+
+## Colors
+
+Lip Gloss supports the following color profiles:
+
+### ANSI 16 colors (4-bit)
+
+```go
+lipgloss.Color("5") // magenta
+lipgloss.Color("9") // red
+lipgloss.Color("12") // light blue
+```
+
+### ANSI 256 Colors (8-bit)
+
+```go
+lipgloss.Color("86") // aqua
+lipgloss.Color("201") // hot pink
+lipgloss.Color("202") // orange
+```
+
+### True Color (16,777,216 colors; 24-bit)
+
+```go
+lipgloss.Color("#0000FF") // good ol' 100% blue
+lipgloss.Color("#04B575") // a green
+lipgloss.Color("#3C3C3C") // a dark gray
+```
+
+...as well as a 1-bit ASCII profile, which is black and white only.
+
+There are also named constants for the 16 standard ANSI colors:
+
+```go
+lipgloss.Black
+lipgloss.Red
+lipgloss.Green
+lipgloss.Yellow
+lipgloss.Blue
+lipgloss.Magenta
+lipgloss.Cyan
+lipgloss.White
+lipgloss.BrightBlack
+lipgloss.BrightRed
+lipgloss.BrightGreen
+lipgloss.BrightYellow
+lipgloss.BrightBlue
+lipgloss.BrightMagenta
+lipgloss.BrightCyan
+lipgloss.BrightWhite
+```
+
+### Automatically Downsampling Colors
+
+Some users don't have Truecolor terminals. Other times, output might not
+support color at all (for example, in logs). Lip Gloss was designed to handle
+this gracefully by automatically downsampling colors to the best available
+profile.
+
+If you're using Lip Gloss with Bubble Tea, there’s nothing to do. If you're
+using Lip Gloss standalone, just use `lipgloss.Println` or `lipgloss.Sprint`
+(and their variants).
+
+For more, see [advanced color usage](#advanced-color-usage).
+
+### Color Utilities
+
+Lip Gloss ships with a handful of handy tools for working with colors:
+
+```go
+c := lipgloss.Color("#EB4268") // Sriracha sauce color
+dark := lipgloss.Darken(c, 0.5) // dark Sriracha sauce
+light := lipgloss.Lighten(c, 0.35) // light Sriracha sauce
+green := lipgloss.Complementary(c) // greenish Sriracha sauce
+withAlpha := lipgloss.Alpha(c, 0.2) // watered down Sriracha sauce
+```
+
+### Advanced Color Tooling
+
+Lip Gloss also supports color blending, automatically choosing light or dark
+variants of colors at runtime, and a lot more. For details, see [Advanced Color
+Usage](#advanced-color-usage) and [the docs][docs].
+
+## Inline Formatting
+
+Lip Gloss supports the usual ANSI text formatting options:
+
+```go
+var style = lipgloss.NewStyle().
+ Bold(true).
+ Italic(true).
+ Faint(true).
+ Blink(true).
+ Strikethrough(true).
+ Underline(true).
+ Reverse(true)
+```
+
+### Underline Styles
+
+Beyond simple on/off, underlines support multiple styles and custom colors:
+
+```go
+s := lipgloss.NewStyle().
+ UnderlineStyle(lipgloss.UnderlineCurly).
+ UnderlineColor(lipgloss.Color("#FF0000"))
+```
+
+Available styles: `UnderlineNone`, `UnderlineSingle`, `UnderlineDouble`,
+`UnderlineCurly`, `UnderlineDotted`, `UnderlineDashed`.
+
+### Hyperlinks
+
+Styles can render clickable hyperlinks in supporting terminals:
+
+```go
+s := lipgloss.NewStyle().
+ Foreground(lipgloss.Color("#7B2FBE")).
+ Hyperlink("https://charm.land")
+
+lipgloss.Println(s.Render("Visit Charm"))
+```
+
+In unsupported terminals this will degrade gracefully and hyperlinks will
+simply not render.
+
+## Block-Level Formatting
+
+Lip Gloss also supports rules for block-level formatting:
+
+```go
+// Padding
+var style = lipgloss.NewStyle().
+ PaddingTop(2).
+ PaddingRight(4).
+ PaddingBottom(2).
+ PaddingLeft(4)
+
+// Margins
+var style = lipgloss.NewStyle().
+ MarginTop(2).
+ MarginRight(4).
+ MarginBottom(2).
+ MarginLeft(4)
+```
+
+There is also shorthand syntax for margins and padding, which follows the same
+format as CSS:
+
+```go
+// 2 cells on all sides
+lipgloss.NewStyle().Padding(2)
+
+// 2 cells on the top and bottom, 4 cells on the left and right
+lipgloss.NewStyle().Margin(2, 4)
+
+// 1 cell on the top, 4 cells on the sides, 2 cells on the bottom
+lipgloss.NewStyle().Padding(1, 4, 2)
+
+// Clockwise, starting from the top: 2 cells on the top, 4 on the right, 3 on
+// the bottom, and 1 on the left
+lipgloss.NewStyle().Margin(2, 4, 3, 1)
+```
+
+You can also customize the characters used for padding and margin fill:
+
+```go
+s := lipgloss.NewStyle().
+ Padding(1, 2).
+ PaddingChar('·').
+ Margin(1, 2).
+ MarginChar('░')
+```
+
+## Aligning Text
+
+You can align paragraphs of text to the left, right, or center.
+
+```go
+var style = lipgloss.NewStyle().
+ Width(24).
+ Align(lipgloss.Left). // align it left
+ Align(lipgloss.Right). // no wait, align it right
+ Align(lipgloss.Center) // just kidding, align it in the center
+```
+
+## Width and Height
+
+Setting a minimum width and height is simple and straightforward.
+
+```go
+var style = lipgloss.NewStyle().
+ SetString("What’s for lunch?").
+ Width(24).
+ Height(32).
+ Foreground(lipgloss.Color("63"))
+```
+
+## Borders
+
+Adding borders is easy:
+
+```go
+// Add a purple, rectangular border
+var style = lipgloss.NewStyle().
+ BorderStyle(lipgloss.NormalBorder()).
+ BorderForeground(lipgloss.Color("63"))
+
+// Set a rounded, yellow-on-purple border to the top and left
+var anotherStyle = lipgloss.NewStyle().
+ BorderStyle(lipgloss.RoundedBorder()).
+ BorderForeground(lipgloss.Color("228")).
+ BorderBackground(lipgloss.Color("63")).
+ BorderTop(true).
+ BorderLeft(true)
+
+// Make your own border
+var myCuteBorder = lipgloss.Border{
+ Top: "._.:*:",
+ Bottom: "._.:*:",
+ Left: "|*",
+ Right: "|*",
+ TopLeft: "*",
+ TopRight: "*",
+ BottomLeft: "*",
+ BottomRight: "*",
+}
+```
+
+There are also shorthand functions for defining borders, which follow a similar
+pattern to the margin and padding shorthand functions.
+
+```go
+// Add a thick border to the top and bottom
+lipgloss.NewStyle().
+ Border(lipgloss.ThickBorder(), true, false)
+
+// Add a double border to the top and left sides. Rules are set clockwise
+// from top.
+lipgloss.NewStyle().
+ Border(lipgloss.DoubleBorder(), true, false, false, true)
+```
+
+You can also pass multiple colors to a border for a gradient effect:
+
+```go
+s := lipgloss.NewStyle().
+ Border(lipgloss.RoundedBorder()).
+ BorderForegroundBlend(lipgloss.Color("#FF0000"), lipgloss.Color("#0000FF"))
+```
+
+For more on borders see [the docs](https://pkg.go.dev/charm.land/lipgloss/v2#Border).
+
+## Copying Styles
+
+Just use assignment:
+
+```go
+style := lipgloss.NewStyle().Foreground(lipgloss.Color("219"))
+
+copiedStyle := style // this is a true copy
+
+wildStyle := style.Blink(true) // this is also true copy, with blink added
+```
+
+Since `Style` is a pure value type, assigning a style to another effectively
+creates a new copy of the style without mutating the original.
+
+## Inheritance
+
+Styles can inherit rules from other styles. When inheriting, only unset rules
+on the receiver are inherited.
+
+```go
+var styleA = lipgloss.NewStyle().
+ Foreground(lipgloss.Color("229")).
+ Background(lipgloss.Color("63"))
+
+// Only the background color will be inherited here, because the foreground
+// color will have been already set:
+var styleB = lipgloss.NewStyle().
+ Foreground(lipgloss.Color("201")).
+ Inherit(styleA)
+```
+
+## Unsetting Rules
+
+All rules can be unset:
+
+```go
+var style = lipgloss.NewStyle().
+ Bold(true). // make it bold
+ UnsetBold(). // jk don't make it bold
+ Background(lipgloss.Color("227")). // yellow background
+ UnsetBackground() // never mind
+```
+
+When a rule is unset, it won’t be inherited or copied.
+
+## Enforcing Rules
+
+Sometimes, such as when developing a component, you want to make sure style
+definitions respect their intended purpose in the UI. This is where `Inline`
+and `MaxWidth`, and `MaxHeight` come in:
+
+```go
+// Force rendering onto a single line, ignoring margins, padding, and borders.
+someStyle.Inline(true).Render("yadda yadda")
+
+// Also limit rendering to five cells
+someStyle.Inline(true).MaxWidth(5).Render("yadda yadda")
+
+// Limit rendering to a 5x5 cell block
+someStyle.MaxWidth(5).MaxHeight(5).Render("yadda yadda")
+```
+
+## Tabs
+
+The tab character (`\t`) is rendered differently in different terminals (often
+as 8 spaces, sometimes 4). Because of this inconsistency, Lip Gloss converts
+tabs to 4 spaces at render time. This behavior can be changed on a per-style
+basis, however:
+
+```go
+style := lipgloss.NewStyle() // tabs will render as 4 spaces, the default
+style = style.TabWidth(2) // render tabs as 2 spaces
+style = style.TabWidth(0) // remove tabs entirely
+style = style.TabWidth(lipgloss.NoTabConversion) // leave tabs intact
+```
+
+## Wrapping
+
+The `Wrap` function wraps text while preserving ANSI styles and hyperlinks
+across line boundaries:
+
+```go
+wrapped := lipgloss.Wrap(styledText, 40, " ")
+```
+
+## Rendering
+
+Generally, you just call the `Render(string...)` method on a `lipgloss.Style`:
+
+```go
+style := lipgloss.NewStyle().Bold(true).SetString("Hello,")
+lipgloss.Println(style.Render("kitty.")) // Hello, kitty.
+lipgloss.Println(style.Render("puppy.")) // Hello, puppy.
+```
+
+But you could also use the Stringer interface:
+
+```go
+var style = lipgloss.NewStyle().SetString("你好,猫咪。").Bold(true)
+lipgloss.Println(style) // 你好,猫咪。
+```
+
+## Utilities
+
+In addition to pure styling, Lip Gloss also ships with some utilities to help
+assemble your layouts.
+
+### Compositing
+
+
+
+Lip Gloss includes a powerful, cell-based compositor for rendering layered
+content:
+
+```go
+// Create some layers.
+a := lipgloss.NewLayer(pickles).X(4).Y(2).Z(1)
+b := lipgloss.NewLayer(bitterMelon).X(22).Y(1)
+c := lipgloss.NewLayer(sriracha).X(11).Y(7)
+
+// Composite 'em and render.
+output := compositor.Compose(a, b, c).Render()
+```
+
+For a more thorough example, see [the canvas
+example](./examples/canvas/main.go). For reference, including how to detect
+mouse clicks on layers, see [the docs][docs].
+
+### Joining Paragraphs
+
+Horizontally and vertically joining paragraphs is a cinch.
+
+```go
+// Horizontally join three paragraphs along their bottom edges
+lipgloss.JoinHorizontal(lipgloss.Bottom, paragraphA, paragraphB, paragraphC)
+
+// Vertically join two paragraphs along their center axes
+lipgloss.JoinVertical(lipgloss.Center, paragraphA, paragraphB)
+
+// Horizontally join three paragraphs, with the shorter ones aligning 20%
+// from the top of the tallest
+lipgloss.JoinHorizontal(0.2, paragraphA, paragraphB, paragraphC)
+```
+
+### Measuring Width and Height
+
+Sometimes you’ll want to know the width and height of text blocks when building
+your layouts.
+
+```go
+// Render a block of text.
+var style = lipgloss.NewStyle().
+ Width(40).
+ Padding(2)
+var block string = style.Render(someLongString)
+
+// Get the actual, physical dimensions of the text block.
+width := lipgloss.Width(block)
+height := lipgloss.Height(block)
+
+// Here's a shorthand function.
+w, h := lipgloss.Size(block)
+```
+
+### Blending Colors
+
+You can blend colors in one or two dimensions for gradient effects:
+
+```go
+// 1-dimentinoal gradient
+colors := lipgloss.Blend1D(10, lipgloss.Color("#FF0000"), lipgloss.Color("#0000FF"))
+
+// 2-dimensional gradient with rotation
+colors := lipgloss.Blend2D(80, 24, 45.0, color1, color2, color3)
+```
+
+### Placing Text in Whitespace
+
+Sometimes you’ll simply want to place a block of text in whitespace. This is
+a lightweight alternative to compositing.
+
+```go
+// Center a paragraph horizontally in a space 80 cells wide. The height of
+// the block returned will be as tall as the input paragraph.
+block := lipgloss.PlaceHorizontal(80, lipgloss.Center, fancyStyledParagraph)
+
+// Place a paragraph at the bottom of a space 30 cells tall. The width of
+// the text block returned will be as wide as the input paragraph.
+block := lipgloss.PlaceVertical(30, lipgloss.Bottom, fancyStyledParagraph)
+
+// Place a paragraph in the bottom right corner of a 30x80 cell space.
+block := lipgloss.Place(30, 80, lipgloss.Right, lipgloss.Bottom, fancyStyledParagraph)
+```
+
+You can also style the whitespace. For details, see [the docs][docs].
+
+## Rendering Tables
+
+Lip Gloss ships with a table rendering sub-package.
+
+```go
+import "charm.land/lipgloss/v2/table"
+```
+
+Define some rows of data.
+
+```go
+rows := [][]string{
+ {"Chinese", "您好", "你好"},
+ {"Japanese", "こんにちは", "やあ"},
+ {"Arabic", "أهلين", "أهلا"},
+ {"Russian", "Здравствуйте", "Привет"},
+ {"Spanish", "Hola", "¿Qué tal?"},
+}
+```
+
+Use the table package to style and render the table.
+
+```go
+var (
+ purple = lipgloss.Color("99")
+ gray = lipgloss.Color("245")
+ lightGray = lipgloss.Color("241")
+
+ headerStyle = lipgloss.NewStyle().Foreground(purple).Bold(true).Align(lipgloss.Center)
+ cellStyle = lipgloss.NewStyle().Padding(0, 1).Width(14)
+ oddRowStyle = cellStyle.Foreground(gray)
+ evenRowStyle = cellStyle.Foreground(lightGray)
+)
+
+t := table.New().
+ Border(lipgloss.NormalBorder()).
+ BorderStyle(lipgloss.NewStyle().Foreground(purple)).
+ StyleFunc(func(row, col int) lipgloss.Style {
+ switch {
+ case row == table.HeaderRow:
+ return headerStyle
+ case row%2 == 0:
+ return evenRowStyle
+ default:
+ return oddRowStyle
+ }
+ }).
+ Headers("LANGUAGE", "FORMAL", "INFORMAL").
+ Rows(rows...)
+
+// You can also add tables row-by-row
+t.Row("English", "You look absolutely fabulous.", "How's it going?")
+```
+
+Print the table.
+
+```go
+lipgloss.Println(t)
+```
+
+
+
+### Table Borders
+
+There are helpers to generate tables in markdown or ASCII style:
+
+#### Markdown Table
+
+```go
+table.New().Border(lipgloss.MarkdownBorder()).BorderTop(false).BorderBottom(false)
+```
+
+```
+| LANGUAGE | FORMAL | INFORMAL |
+|----------|--------------|-----------|
+| Chinese | Nǐn hǎo | Nǐ hǎo |
+| French | Bonjour | Salut |
+| Russian | Zdravstvuyte | Privet |
+| Spanish | Hola | ¿Qué tal? |
+```
+
+#### ASCII Table
+
+```go
+table.New().Border(lipgloss.ASCIIBorder())
+```
+
+```
++----------+--------------+-----------+
+| LANGUAGE | FORMAL | INFORMAL |
++----------+--------------+-----------+
+| Chinese | Nǐn hǎo | Nǐ hǎo |
+| French | Bonjour | Salut |
+| Russian | Zdravstvuyte | Privet |
+| Spanish | Hola | ¿Qué tal? |
++----------+--------------+-----------+
+```
+
+For more on tables see [the docs][docs] and [examples](https://github.com/charmbracelet/lipgloss/tree/master/examples/table).
+
+## Rendering Lists
+
+Lip Gloss ships with a list rendering sub-package.
+
+```go
+import "charm.land/lipgloss/v2/list"
+```
+
+Define a new list.
+
+```go
+l := list.New("A", "B", "C")
+```
+
+Print the list.
+
+```go
+lipgloss.Println(l)
+
+// • A
+// • B
+// • C
+```
+
+Lists have the ability to nest.
+
+```go
+l := list.New(
+ "A", list.New("Artichoke"),
+ "B", list.New("Baking Flour", "Bananas", "Barley", "Bean Sprouts"),
+ "C", list.New("Cashew Apple", "Cashews", "Coconut Milk", "Curry Paste", "Currywurst"),
+ "D", list.New("Dill", "Dragonfruit", "Dried Shrimp"),
+ "E", list.New("Eggs"),
+ "F", list.New("Fish Cake", "Furikake"),
+ "J", list.New("Jicama"),
+ "K", list.New("Kohlrabi"),
+ "L", list.New("Leeks", "Lentils", "Licorice Root"),
+)
+```
+
+Print the list.
+
+```go
+lipgloss.Println(l)
+```
+
+
+
+
+
+Lists can be customized via their enumeration function as well as using
+`lipgloss.Style`s.
+
+```go
+enumeratorStyle := lipgloss.NewStyle().Foreground(lipgloss.Color("99")).MarginRight(1)
+itemStyle := lipgloss.NewStyle().Foreground(lipgloss.Color("212")).MarginRight(1)
+
+l := list.New(
+ "Glossier",
+ "Claire's Boutique",
+ "Nyx",
+ "Mac",
+ "Milk",
+ ).
+ Enumerator(list.Roman).
+ EnumeratorStyle(enumeratorStyle).
+ ItemStyle(itemStyle)
+```
+
+Print the list.
+
+
+
+
+
+In addition to the predefined enumerators (`Arabic`, `Alphabet`, `Roman`, `Bullet`, `Tree`),
+you may also define your own custom enumerator:
+
+```go
+l := list.New("Duck", "Duck", "Duck", "Duck", "Goose", "Duck", "Duck")
+
+func DuckDuckGooseEnumerator(l list.Items, i int) string {
+ if l.At(i).Value() == "Goose" {
+ return "Honk →"
+ }
+ return ""
+}
+
+l = l.Enumerator(DuckDuckGooseEnumerator)
+```
+
+Print the list:
+
+
+
+
+
+If you need, you can also build lists incrementally:
+
+```go
+l := list.New()
+
+for i := 0; i < repeat; i++ {
+ l.Item("Lip Gloss")
+}
+```
+
+## Rendering Trees
+
+Lip Gloss ships with a tree rendering sub-package.
+
+```go
+import "charm.land/lipgloss/v2/tree"
+```
+
+Define a new tree.
+
+```go
+t := tree.Root(".").
+ Child("A", "B", "C")
+```
+
+Print the tree.
+
+```go
+lipgloss.Println(t)
+
+// .
+// ├── A
+// ├── B
+// └── C
+```
+
+Trees have the ability to nest.
+
+```go
+t := tree.Root(".").
+ Child("macOS").
+ Child(
+ tree.New().
+ Root("Linux").
+ Child("NixOS").
+ Child("Arch Linux (btw)").
+ Child("Void Linux"),
+ ).
+ Child(
+ tree.New().
+ Root("BSD").
+ Child("FreeBSD").
+ Child("OpenBSD"),
+ )
+```
+
+Print the tree.
+
+```go
+lipgloss.Println(t)
+```
+
+
+
+
+
+Trees can be customized via their enumeration function as well as using
+`lipgloss.Style`s.
+
+```go
+enumeratorStyle := lipgloss.NewStyle().Foreground(lipgloss.Color("63")).MarginRight(1)
+rootStyle := lipgloss.NewStyle().Foreground(lipgloss.Color("35"))
+itemStyle := lipgloss.NewStyle().Foreground(lipgloss.Color("212"))
+
+t := tree.
+ Root("⁜ Makeup").
+ Child(
+ "Glossier",
+ "Fenty Beauty",
+ tree.New().Child(
+ "Gloss Bomb Universal Lip Luminizer",
+ "Hot Cheeks Velour Blushlighter",
+ ),
+ "Nyx",
+ "Mac",
+ "Milk",
+ ).
+ Enumerator(tree.RoundedEnumerator).
+ EnumeratorStyle(enumeratorStyle).
+ RootStyle(rootStyle).
+ ItemStyle(itemStyle)
+```
+
+Print the tree.
+
+
+
+
+
+The predefined enumerators for trees are `DefaultEnumerator` and `RoundedEnumerator`.
+
+If you need, you can also build trees incrementally:
+
+```go
+t := tree.New()
+
+for i := 0; i < repeat; i++ {
+ t.Child("Lip Gloss")
+}
+```
+
+## Advanced Color Usage
+
+One of the most powerful features of Lip Gloss is the ability to render
+different colors at runtime depending on the user's terminal and environment,
+allowing you to present the best possible user experience.
+
+This section shows you how to do exactly that.
+
+
+Migrating from v1?
+
+The `compat` package provides `AdaptiveColor`, `CompleteColor`, and
+`CompleteAdaptiveColor` for a quicker migration from v1. These work by
+looking at `stdin` and `stdout` on a global basis:
+
+```go
+import "charm.land/lipgloss/v2/compat"
+
+color := compat.AdaptiveColor{
+ Light: lipgloss.Color("#f1f1f1"),
+ Dark: lipgloss.Color("#cccccc"),
+}
+```
+
+Note that we don't recommend this for new code as it removes the purity from
+Lip Gloss, computationally speaking, as it removes transparency around when
+I/O happens, which could cause Lip Gloss to compete for resources (like stdin)
+with other tools.
+
+
+
+### Adaptive Colors
+
+You can render different colors at runtime depending on whether the terminal
+has a light or dark background:
+
+```go
+hasDarkBG := lipgloss.HasDarkBackground(os.Stdin, os.Stdout)
+lightDark := lipgloss.LightDark(hasDarkBG)
+
+myColor := lightDark(lipgloss.Color("#D7FFAE"), lipgloss.Color("#D75FEE"))
+```
+
+#### With Bubble Tea
+
+In Bubble Tea, request the background color, listen for a
+`BackgroundColorMsg`, and respond accordingly:
+
+```go
+func (m model) Init() tea.Cmd {
+ // First, send a Cmd to request the terminal background color.
+ return tea.RequestBackgroundColor
+}
+
+func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
+ switch msg := msg.(type) {
+ case tea.BackgroundColorMsg:
+ // Great, we have the background color. Now we can set up our styles
+ // against the color.
+ m.styles = newStyles(msg.IsDark())
+ return m, nil
+ }
+}
+
+func newStyles(bgIsDark bool) styles {
+ // A little ternary function that will return the appropriate color
+ // based on the background color.
+ lightDark := lipgloss.LightDark(bgIsDark)
+
+ return styles{
+ myHotStyle: lipgloss.NewStyle().Foreground(lightDark(
+ lipgloss.Color("#f1f1f1"),
+ lipgloss.Color("#333333"),
+ )),
+ }
+}
+```
+
+#### Standalone
+
+If you’re not using Bubble Tea you can perform the query manually:
+
+```go
+// What's the background color?
+hasDarkBG := lipgloss.HasDarkBackground(os.Stdin, os.Stderr)
+
+// A helper function that will return the appropriate color based on the
+// background.
+lightDark := lipgloss.LightDark(hasDarkBG)
+
+// A couple colors with light and dark variants.
+thisColor := lightDark(lipgloss.Color("#C5ADF9"), lipgloss.Color("#864EFF"))
+thatColor := lightDark(lipgloss.Color("#37CD96"), lipgloss.Color("#22C78A"))
+
+a := lipgloss.NewStyle().Foreground(thisColor).Render("this")
+b := lipgloss.NewStyle().Foreground(thatColor).Render("that")
+
+// Render the appropriate colors at runtime:
+lipgloss.Fprintf(os.Stderr, "my fave colors are %s and %s", a, b)
+```
+
+### Complete Colors
+
+In some cases where you may want to specify exact values for each color profile
+(ANSI 16, ANSI 156, and TrueColor). For these cases, use the `Complete` helper:
+
+```go
+// You'll need the colorprofile package.
+import "github.com/charmbracelet/colorprofile"
+
+// Get the color profile.
+profile := colorprofile.Detect(os.Stdout, os.Environ())
+
+// Create a function for rendering the appropriate color based on the profile.
+var completeColor := lipgloss.Complete(profile)
+
+// Now we'll choose the appropriate color at runtime.
+myColor := completeColor(ansiColor, ansi256Color, trueColor)
+```
+
+### Color Downsampling
+
+One of the best things about Lip Gloss is that it can automatically downsample
+colors to the best available profile, stripping colors (and ANSI) entirely when
+output is not a TTY.
+
+If you’re using Lip Gloss with Bubble Tea there’s nothing to do here:
+downsampling is built into Bubble Tea v2. If you’re not using Bubble Tea, use
+the Lip Gloss writer functions, which are a drop-in replacement for the `fmt`
+package:
+
+```go
+s := lipgloss.NewStyle()
+ .Foreground(lipgloss.Color("#EB4268"))
+ .Render("Hello!")
+
+// Downsample if needed and print to stdout.
+lipgloss.Println(s)
+
+// Render to a variable.
+downsampled := lipgloss.Sprint(s)
+
+// Print to stderr.
+lipgloss.Fprint(os.Stderr, s)
+```
+
+The full set: `Print`, `Println`, `Printf`, `Fprint`, `Fprintln`, `Fprintf`,
+`Sprint`, `Sprintln`, `Sprintf`.
+
+Need more control? Check out
+[Colorprofile](https://github.com/charmbracelet/colorprofile), which Lip Gloss
+uses under the hood.
+
+## What about [Bubble Tea][tea]?
+
+Lip Gloss doesn’t replace Bubble Tea. Rather, it is an excellent Bubble Tea
+companion. It was designed to make assembling terminal user interface views as
+simple and fun as possible so that you can focus on building your application
+instead of concerning yourself with low-level layout details.
+
+In simple terms, you can use Lip Gloss to help build your Bubble Tea views.
+
+[tea]: https://github.com/charmbracelet/bubbletea
+
+## Rendering Markdown
+
+For a more document-centric rendering solution with support for things like
+lists, tables, and syntax-highlighted code have a look at [Glamour][glamour],
+the stylesheet-based Markdown renderer.
+
+[glamour]: https://github.com/charmbracelet/glamour
+
+## Contributing
+
+See [contributing][contribute].
+
+[contribute]: https://github.com/charmbracelet/lipgloss/contribute
+
+## Feedback
+
+We’d love to hear your thoughts on this project. Feel free to drop us a note!
+
+- [Discord](https://charm.land/chat)
+- [Matrix](https://charm.land/matrix)
+
+## License
+
+[MIT](https://github.com/charmbracelet/lipgloss/raw/master/LICENSE)
+
+---
+
+Part of [Charm](https://charm.land).
+
+
+
+Charm热爱开源 • Charm loves open source
+
+[docs]: https://pkg.go.dev/charm.land/lipgloss/v2?tab=doc
diff --git a/vendor/charm.land/lipgloss/v2/Taskfile.yaml b/vendor/charm.land/lipgloss/v2/Taskfile.yaml
new file mode 100644
index 000000000..84fcf6c66
--- /dev/null
+++ b/vendor/charm.land/lipgloss/v2/Taskfile.yaml
@@ -0,0 +1,24 @@
+# https://taskfile.dev
+
+version: "3"
+
+tasks:
+ lint:
+ desc: Run base linters
+ cmds:
+ - golangci-lint run
+
+ test:
+ desc: Run tests
+ cmds:
+ - go test ./... {{.CLI_ARGS}}
+
+ test:table:
+ desc: Run table tests
+ cmds:
+ - go test ./table {{.CLI_ARGS}}
+
+ test:tree:
+ desc: Run tree tests
+ cmds:
+ - go test ./tree {{.CLI_ARGS}}
diff --git a/vendor/charm.land/lipgloss/v2/UPGRADE_GUIDE_V2.md b/vendor/charm.land/lipgloss/v2/UPGRADE_GUIDE_V2.md
new file mode 100644
index 000000000..8f123f19d
--- /dev/null
+++ b/vendor/charm.land/lipgloss/v2/UPGRADE_GUIDE_V2.md
@@ -0,0 +1,504 @@
+# Lip Gloss v2 Upgrade Guide
+
+This guide covers migrating from Lip Gloss v1 (`github.com/charmbracelet/lipgloss`)
+to Lip Gloss v2 (`charm.land/lipgloss/v2`). It is written for both humans and
+LLMs performing automated migrations.
+
+---
+
+## Table of Contents
+
+1. [Quick Start](#quick-start)
+2. [Module Path](#module-path)
+3. [Color System](#color-system)
+4. [Renderer Removal](#renderer-removal)
+5. [Printing and Color Downsampling](#printing-and-color-downsampling)
+6. [Background Detection and Adaptive Colors](#background-detection-and-adaptive-colors)
+7. [Whitespace Options](#whitespace-options)
+8. [Underline](#underline)
+9. [Style API Changes](#style-api-changes)
+10. [Tree Subpackage](#tree-subpackage)
+11. [Removed APIs](#removed-apis)
+12. [Quick Reference Table](#quick-reference-table)
+
+---
+
+## Quick Start
+
+For the fastest possible upgrade, do these two things:
+
+### 1. Use the `compat` package for adaptive/complete colors
+
+```go
+import "charm.land/lipgloss/v2/compat"
+
+// v1
+color := lipgloss.AdaptiveColor{Light: "#f1f1f1", Dark: "#cccccc"}
+
+// v2
+color := compat.AdaptiveColor{Light: lipgloss.Color("#f1f1f1"), Dark: lipgloss.Color("#cccccc")}
+```
+
+The `compat` package reads `stdin`/`stdout` globally, just like v1. To
+customize:
+
+```go
+import (
+ "charm.land/lipgloss/v2/compat"
+ "github.com/charmbracelet/colorprofile"
+)
+
+func init() {
+ compat.HasDarkBackground = lipgloss.HasDarkBackground(os.Stdin, os.Stderr)
+ compat.Profile = colorprofile.Detect(os.Stderr, os.Environ())
+}
+```
+
+### 2. Use Lip Gloss writers for output
+
+```go
+// v1
+fmt.Println(s)
+
+// v2
+lipgloss.Println(s)
+```
+
+This ensures colors are automatically downsampled. If you're using Bubble Tea
+v2, this step is unnecessary — Bubble Tea handles it for you.
+
+**That's the quick path.** Read on for the full migration details.
+
+---
+
+## Module Path
+
+The import path has changed.
+
+```go
+// v1
+import "github.com/charmbracelet/lipgloss"
+
+// v2
+import "charm.land/lipgloss/v2"
+```
+
+**Install:**
+
+```bash
+go get charm.land/lipgloss/v2
+```
+
+All subpackages follow the same pattern:
+
+```go
+// v1
+import "github.com/charmbracelet/lipgloss/table"
+import "github.com/charmbracelet/lipgloss/tree"
+import "github.com/charmbracelet/lipgloss/list"
+
+// v2
+import "charm.land/lipgloss/v2/table"
+import "charm.land/lipgloss/v2/tree"
+import "charm.land/lipgloss/v2/list"
+```
+
+**Search-and-replace pattern:**
+
+```
+github.com/charmbracelet/lipgloss → charm.land/lipgloss/v2
+```
+
+---
+
+## Color System
+
+This is the most significant API change.
+
+### `Color` is now a function, not a type
+
+```go
+// v1 — Color is a string type
+var c lipgloss.Color = "21"
+var c lipgloss.Color = "#ff00ff"
+
+// v2 — Color is a function returning color.Color
+var c color.Color = lipgloss.Color("21")
+var c color.Color = lipgloss.Color("#ff00ff")
+```
+
+The return type is `image/color.Color` (from the standard library).
+
+### `TerminalColor` interface is removed
+
+All methods that accepted `lipgloss.TerminalColor` now accept
+`image/color.Color`:
+
+```go
+// v1
+func (s Style) Foreground(c TerminalColor) Style
+func (s Style) Background(c TerminalColor) Style
+func (s Style) BorderForeground(c ...TerminalColor) Style
+
+// v2
+func (s Style) Foreground(c color.Color) Style
+func (s Style) Background(c color.Color) Style
+func (s Style) BorderForeground(c ...color.Color) Style
+```
+
+**Migration:** Replace every `lipgloss.TerminalColor` with `color.Color` and
+add `import "image/color"`.
+
+### `ANSIColor` is now an alias
+
+```go
+// v1 — custom uint type
+type ANSIColor uint
+
+// v2 — alias for ansi.IndexedColor
+type ANSIColor = ansi.IndexedColor
+```
+
+v2 also exports named constants for the 16 basic ANSI colors:
+
+```go
+lipgloss.Black, lipgloss.Red, lipgloss.Green, lipgloss.Yellow,
+lipgloss.Blue, lipgloss.Magenta, lipgloss.Cyan, lipgloss.White,
+lipgloss.BrightBlack, lipgloss.BrightRed, lipgloss.BrightGreen,
+lipgloss.BrightYellow, lipgloss.BrightBlue, lipgloss.BrightMagenta,
+lipgloss.BrightCyan, lipgloss.BrightWhite
+```
+
+### `AdaptiveColor`, `CompleteColor`, `CompleteAdaptiveColor`
+
+These types have been moved out of the root package. Use the `compat` package
+for a drop-in replacement, or use the new `LightDark` and `Complete` helpers
+for explicit control:
+
+```go
+// v1
+color := lipgloss.AdaptiveColor{Light: "#0000ff", Dark: "#000099"}
+
+// v2 — using compat (quick path)
+color := compat.AdaptiveColor{
+ Light: lipgloss.Color("#0000ff"),
+ Dark: lipgloss.Color("#000099"),
+}
+
+// v2 — using LightDark (recommended)
+hasDark := lipgloss.HasDarkBackground(os.Stdin, os.Stdout)
+lightDark := lipgloss.LightDark(hasDark)
+color := lightDark(lipgloss.Color("#0000ff"), lipgloss.Color("#000099"))
+```
+
+```go
+// v1
+color := lipgloss.CompleteColor{TrueColor: "#ff00ff", ANSI256: "200", ANSI: "5"}
+
+// v2 — using compat
+color := compat.CompleteColor{
+ TrueColor: lipgloss.Color("#ff00ff"),
+ ANSI256: lipgloss.Color("200"),
+ ANSI: lipgloss.Color("5"),
+}
+
+// v2 — using Complete (recommended)
+profile := colorprofile.Detect(os.Stdout, os.Environ())
+complete := lipgloss.Complete(profile)
+color := complete(lipgloss.Color("5"), lipgloss.Color("200"), lipgloss.Color("#ff00ff"))
+```
+
+Note that `compat.AdaptiveColor` and friends take `color.Color` values for
+their fields, not strings.
+
+---
+
+## Renderer Removal
+
+The `Renderer` type and all associated functions are removed. In v1, every
+`Style` carried a `*Renderer` pointer and the package maintained a global
+default renderer.
+
+```go
+// v1 — these no longer exist
+lipgloss.DefaultRenderer()
+lipgloss.SetDefaultRenderer(r)
+lipgloss.NewRenderer(w, opts...)
+lipgloss.ColorProfile()
+lipgloss.SetColorProfile(p)
+renderer.NewStyle()
+```
+
+**In v2, `Style` is a plain value type.** There is no renderer. Color
+downsampling is handled at the output layer (see next section).
+
+**Migration:**
+
+- Replace `lipgloss.DefaultRenderer().NewStyle()` with `lipgloss.NewStyle()`.
+- Replace `renderer.NewStyle()` with `lipgloss.NewStyle()`.
+- Remove any `*Renderer` fields from your types.
+- Remove calls to `SetColorProfile` — use `colorprofile.Detect` at the output
+ layer instead.
+
+---
+
+## Printing and Color Downsampling
+
+In v1, color downsampling happened inside `Style.Render()` via the renderer. In
+v2, `Render()` always emits full-fidelity ANSI. Downsampling happens when you
+print.
+
+### Standalone Usage
+
+Use the Lip Gloss writer functions:
+
+```go
+s := someStyle.Render("Hello!")
+
+// Print to stdout with automatic downsampling
+lipgloss.Println(s)
+
+// Print to stderr
+lipgloss.Fprintln(os.Stderr, s)
+
+// Render to a string (downsampled for stdout's profile)
+str := lipgloss.Sprint(s)
+```
+
+The default writer targets `stdout`. To customize:
+
+```go
+lipgloss.Writer = colorprofile.NewWriter(os.Stderr, os.Environ())
+```
+
+### With Bubble Tea
+
+No changes needed. Bubble Tea v2 handles downsampling internally.
+
+---
+
+## Background Detection and Adaptive Colors
+
+### Standalone
+
+v1 detected the background color automatically via the global renderer. v2
+requires explicit queries:
+
+```go
+// v1
+hasDark := lipgloss.HasDarkBackground()
+
+// v2 — specify the input and output
+hasDark := lipgloss.HasDarkBackground(os.Stdin, os.Stdout)
+```
+
+Then use `LightDark` to pick colors:
+
+```go
+lightDark := lipgloss.LightDark(hasDark)
+fg := lightDark(lipgloss.Color("#333333"), lipgloss.Color("#f1f1f1"))
+
+s := lipgloss.NewStyle().Foreground(fg)
+```
+
+### With Bubble Tea
+
+Request the background color in `Init` and listen for the response:
+
+```go
+func (m model) Init() tea.Cmd {
+ return tea.RequestBackgroundColor
+}
+
+func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
+ switch msg := msg.(type) {
+ case tea.BackgroundColorMsg:
+ m.styles = newStyles(msg.IsDark())
+ }
+ // ...
+}
+
+func newStyles(bgIsDark bool) styles {
+ lightDark := lipgloss.LightDark(bgIsDark)
+ return styles{
+ title: lipgloss.NewStyle().Foreground(lightDark(
+ lipgloss.Color("#333333"),
+ lipgloss.Color("#f1f1f1"),
+ )),
+ }
+}
+```
+
+---
+
+## Whitespace Options
+
+The separate foreground/background whitespace options have been replaced by a
+single style option:
+
+```go
+// v1
+lipgloss.Place(width, height, hPos, vPos, str,
+ lipgloss.WithWhitespaceForeground(lipgloss.Color("#333")),
+ lipgloss.WithWhitespaceBackground(lipgloss.Color("#000")),
+)
+
+// v2
+lipgloss.Place(width, height, hPos, vPos, str,
+ lipgloss.WithWhitespaceStyle(lipgloss.NewStyle().
+ Foreground(lipgloss.Color("#333")).
+ Background(lipgloss.Color("#000")),
+ ),
+)
+```
+
+---
+
+## Underline
+
+`Underline(bool)` still works for basic on/off. v2 adds fine-grained control:
+
+```go
+// v1
+s := lipgloss.NewStyle().Underline(true)
+
+// v2 — still works
+s := lipgloss.NewStyle().Underline(true)
+
+// v2 — new: specific styles
+s := lipgloss.NewStyle().UnderlineStyle(lipgloss.UnderlineCurly)
+
+// v2 — new: colored underlines
+s := lipgloss.NewStyle().
+ UnderlineStyle(lipgloss.UnderlineSingle).
+ UnderlineColor(lipgloss.Color("#FF0000"))
+```
+
+Internally, `Underline(true)` is equivalent to `UnderlineStyle(UnderlineSingle)`
+and `Underline(false)` is equivalent to `UnderlineStyle(UnderlineNone)`.
+
+---
+
+## Style API Changes
+
+### `NewStyle()` is no longer tied to a Renderer
+
+```go
+// v1
+s := lipgloss.NewStyle() // uses global renderer
+s := renderer.NewStyle() // uses specific renderer
+
+// v2
+s := lipgloss.NewStyle() // pure value, no renderer
+```
+
+### Color getters return `color.Color`
+
+```go
+// v1
+fg := s.GetForeground() // returns TerminalColor
+
+// v2
+fg := s.GetForeground() // returns color.Color
+```
+
+### New style methods
+
+| Method | Description |
+|---|---|
+| `UnderlineStyle(Underline)` | Set underline style (single, double, curly, etc.) |
+| `UnderlineColor(color.Color)` | Set underline color |
+| `PaddingChar(rune)` | Set the character used for padding fill |
+| `MarginChar(rune)` | Set the character used for margin fill |
+| `Hyperlink(link, params...)` | Set a clickable hyperlink |
+| `BorderForegroundBlend(...color.Color)` | Apply gradient colors to borders |
+| `BorderForegroundBlendOffset(int)` | Set the offset for border gradient |
+
+Each has a corresponding `Get*`, `Unset*`, and where applicable `Get*`
+accessor.
+
+---
+
+## Tree Subpackage
+
+The import path changes and there are new styling options:
+
+```go
+// v1
+import "github.com/charmbracelet/lipgloss/tree"
+
+// v2
+import "charm.land/lipgloss/v2/tree"
+```
+
+New methods:
+
+- `IndenterStyle(lipgloss.Style)` — set a static style for tree indentation.
+- `IndenterStyleFunc(func(Children, int) lipgloss.Style)` — conditionally style
+ indentation.
+- `Width(int)` — set tree width for padding.
+
+---
+
+## Removed APIs
+
+The following types and functions no longer exist in v2. This table shows each
+removed symbol and its replacement.
+
+| v1 Symbol | v2 Replacement |
+|---|---|
+| `type Renderer` | Removed entirely |
+| `DefaultRenderer()` | Not needed |
+| `SetDefaultRenderer(r)` | Not needed |
+| `NewRenderer(w, opts...)` | Not needed |
+| `ColorProfile()` | `colorprofile.Detect(w, env)` |
+| `SetColorProfile(p)` | Set `lipgloss.Writer.Profile` |
+| `HasDarkBackground()` (no args) | `lipgloss.HasDarkBackground(in, out)` |
+| `SetHasDarkBackground(b)` | Not needed — pass bool to `LightDark` |
+| `type TerminalColor` | `image/color.Color` |
+| `type Color string` | `func Color(string) color.Color` |
+| `type ANSIColor uint` | `type ANSIColor = ansi.IndexedColor` |
+| `type AdaptiveColor` | `compat.AdaptiveColor` or `LightDark` |
+| `type CompleteColor` | `compat.CompleteColor` or `Complete` |
+| `type CompleteAdaptiveColor` | `compat.CompleteAdaptiveColor` |
+| `WithWhitespaceForeground(c)` | `WithWhitespaceStyle(s)` |
+| `WithWhitespaceBackground(c)` | `WithWhitespaceStyle(s)` |
+| `renderer.NewStyle()` | `lipgloss.NewStyle()` |
+
+---
+
+## Quick Reference Table
+
+A side-by-side summary for common patterns:
+
+| Task | v1 | v2 |
+|---|---|---|
+| Import | `"github.com/charmbracelet/lipgloss"` | `"charm.land/lipgloss/v2"` |
+| Create style | `lipgloss.NewStyle()` | `lipgloss.NewStyle()` |
+| Hex color | `lipgloss.Color("#ff00ff")` | `lipgloss.Color("#ff00ff")` |
+| ANSI color | `lipgloss.Color("5")` | `lipgloss.Color("5")` or `lipgloss.Magenta` |
+| Adaptive color | `lipgloss.AdaptiveColor{Light: "#fff", Dark: "#000"}` | `compat.AdaptiveColor{Light: lipgloss.Color("#fff"), Dark: lipgloss.Color("#000")}` |
+| Set foreground | `s.Foreground(lipgloss.Color("5"))` | `s.Foreground(lipgloss.Color("5"))` |
+| Print with downsampling | `fmt.Println(s.Render("hi"))` | `lipgloss.Println(s.Render("hi"))` |
+| Detect dark bg | `lipgloss.HasDarkBackground()` | `lipgloss.HasDarkBackground(os.Stdin, os.Stdout)` |
+| Light/dark color | `lipgloss.AdaptiveColor{...}` | `lipgloss.LightDark(isDark)(light, dark)` |
+| Whitespace styling | `WithWhitespaceForeground(c)` | `WithWhitespaceStyle(lipgloss.NewStyle().Foreground(c))` |
+| Underline | `s.Underline(true)` | `s.Underline(true)` or `s.UnderlineStyle(lipgloss.UnderlineCurly)` |
+
+---
+
+## Feedback
+
+Questions, issues, or feedback:
+
+- [Discord](https://charm.land/discord)
+- [Matrix](https://charm.land/matrix)
+- [Email](mailto:vt100@charm.land)
+
+---
+
+Part of [Charm](https://charm.land).
+
+
+
+Charm热爱开源 • Charm loves open source • نحنُ نحب المصادر المفتوحة
diff --git a/vendor/github.com/charmbracelet/lipgloss/align.go b/vendor/charm.land/lipgloss/v2/align.go
similarity index 89%
rename from vendor/github.com/charmbracelet/lipgloss/align.go
rename to vendor/charm.land/lipgloss/v2/align.go
index ce654b232..d196213b7 100644
--- a/vendor/github.com/charmbracelet/lipgloss/align.go
+++ b/vendor/charm.land/lipgloss/v2/align.go
@@ -4,13 +4,12 @@ import (
"strings"
"github.com/charmbracelet/x/ansi"
- "github.com/muesli/termenv"
)
// Perform text alignment. If the string is multi-lined, we also make all lines
-// the same width by padding them with spaces. If a termenv style is passed,
-// use that to style the spaces added.
-func alignTextHorizontal(str string, pos Position, width int, style *termenv.Style) string {
+// the same width by padding them with spaces. If a style is passed, use that
+// to style the spaces added.
+func alignTextHorizontal(str string, pos Position, width int, style *ansi.Style) string {
lines, widestLine := getLines(str)
var b strings.Builder
@@ -21,7 +20,7 @@ func alignTextHorizontal(str string, pos Position, width int, style *termenv.Sty
shortAmount += max(0, width-(shortAmount+lineWidth)) // difference from the total width, if set
if shortAmount > 0 {
- switch pos { //nolint:exhaustive
+ switch pos {
case Right:
s := strings.Repeat(" ", shortAmount)
if style != nil {
@@ -59,7 +58,7 @@ func alignTextHorizontal(str string, pos Position, width int, style *termenv.Sty
return b.String()
}
-func alignTextVertical(str string, pos Position, height int, _ *termenv.Style) string {
+func alignTextVertical(str string, pos Position, height int, _ *ansi.Style) string {
strHeight := strings.Count(str, "\n") + 1
if height < strHeight {
return str
diff --git a/vendor/charm.land/lipgloss/v2/ansi_unix.go b/vendor/charm.land/lipgloss/v2/ansi_unix.go
new file mode 100644
index 000000000..b4fca7d19
--- /dev/null
+++ b/vendor/charm.land/lipgloss/v2/ansi_unix.go
@@ -0,0 +1,8 @@
+//go:build !windows
+
+package lipgloss
+
+import "os"
+
+// EnableLegacyWindowsANSI is only needed on Windows.
+func EnableLegacyWindowsANSI(*os.File) {}
diff --git a/vendor/charm.land/lipgloss/v2/ansi_windows.go b/vendor/charm.land/lipgloss/v2/ansi_windows.go
new file mode 100644
index 000000000..8a1ef00eb
--- /dev/null
+++ b/vendor/charm.land/lipgloss/v2/ansi_windows.go
@@ -0,0 +1,30 @@
+//go:build windows
+
+package lipgloss
+
+import (
+ "os"
+
+ "golang.org/x/sys/windows"
+)
+
+// EnableLegacyWindowsANSI enables support for ANSI color sequences in the
+// Windows default console (cmd.exe and the PowerShell application). Note that
+// this only works with Windows 10 and greater. Also note that Windows Terminal
+// supports colors by default.
+func EnableLegacyWindowsANSI(f *os.File) {
+ var mode uint32
+ handle := windows.Handle(f.Fd())
+ err := windows.GetConsoleMode(handle, &mode)
+ if err != nil {
+ return
+ }
+
+ // See https://docs.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences
+ if mode&windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING != windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING {
+ vtpmode := mode | windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING
+ if err := windows.SetConsoleMode(handle, vtpmode); err != nil {
+ return
+ }
+ }
+}
diff --git a/vendor/charm.land/lipgloss/v2/blending.go b/vendor/charm.land/lipgloss/v2/blending.go
new file mode 100644
index 000000000..82830f3e4
--- /dev/null
+++ b/vendor/charm.land/lipgloss/v2/blending.go
@@ -0,0 +1,196 @@
+package lipgloss
+
+import (
+ "image/color"
+ "math"
+ "slices"
+
+ "github.com/lucasb-eyer/go-colorful"
+)
+
+// Blend1D blends a series of colors together in one linear dimension using multiple
+// stops, into the provided number of steps. Uses the "CIE L*, a*, b*" (CIELAB) color-space.
+//
+// Note that if any of the provided colors are completely transparent, we will
+// assume that the alpha value was lost in conversion from RGB -> RGBA, and we
+// will set the alpha to opaque, as it's not possible to blend something completely
+// transparent.
+func Blend1D(steps int, stops ...color.Color) []color.Color {
+ if steps < 0 {
+ steps = 0
+ }
+
+ if steps <= len(stops) {
+ return stops[:steps]
+ }
+
+ // Ensure they didn't provide any nil colors.
+ stops = slices.DeleteFunc(stops, func(c color.Color) bool {
+ return c == nil
+ })
+
+ if len(stops) == 0 {
+ return nil // We can't safely fallback.
+ }
+
+ // If they only provided one valid color (or some nil colors), we will just return
+ // an array of that color, for the amount of steps they requested.
+ if len(stops) == 1 {
+ singleColor := stops[0]
+ result := make([]color.Color, steps)
+ for i := range result {
+ result[i] = singleColor
+ }
+ return result
+ }
+
+ blended := make([]color.Color, steps)
+
+ // Convert stops to colorful.Color once
+ cstops := make([]colorful.Color, len(stops))
+ for i, k := range stops {
+ cstops[i], _ = colorful.MakeColor(ensureNotTransparent(k))
+ }
+
+ numSegments := len(cstops) - 1
+ defaultSize := steps / numSegments
+ remainingSteps := steps % numSegments
+
+ resultIndex := 0
+ for i := range numSegments {
+ from := cstops[i]
+ to := cstops[i+1]
+
+ // Calculate segment size.
+ segmentSize := defaultSize
+ if i < remainingSteps {
+ segmentSize++
+ }
+
+ divisor := float64(segmentSize - 1)
+
+ // Generate colors for this segment.
+ for j := 0; j < segmentSize; j++ {
+ var blendingFactor float64
+ if segmentSize > 1 {
+ blendingFactor = float64(j) / divisor
+ }
+ blended[resultIndex] = from.BlendLab(to, blendingFactor).Clamped()
+ resultIndex++
+ }
+ }
+
+ return blended
+}
+
+// Blend2D blends a series of colors together in two linear dimensions using
+// multiple stops, into the provided width/height. Uses the "CIE L*, a*, b*" (CIELAB)
+// color-space. The angle parameter controls the rotation of the gradient (0-360°),
+// where 0° is left-to-right, 45° is bottom-left to top-right (diagonal). The function
+// returns colors in a 1D row-major order ([row1, row2, row3, ...]).
+//
+// Example of how to iterate over the result:
+//
+// gradient := colors.Blend2D(width, height, 180, color1, color2, color3, ...)
+// gradientContent := strings.Builder{}
+// for y := range height {
+// for x := range width {
+// index := y*width + x
+// gradientContent.WriteString(
+// lipgloss.NewStyle().
+// Background(gradient[index]).
+// Render(" "),
+// )
+// }
+// if y < height-1 { // End of row.
+// gradientContent.WriteString("\n")
+// }
+// }
+//
+// Note that if any of the provided colors are completely transparent, we will
+// assume that the alpha value was lost in conversion from RGB -> RGBA, and we
+// will set the alpha to opaque, as it's not possible to blend something completely
+// transparent.
+func Blend2D(width, height int, angle float64, stops ...color.Color) []color.Color {
+ if width < 1 {
+ width = 1
+ }
+ if height < 1 {
+ height = 1
+ }
+
+ // Normalize angle to 0-360.
+ angle = math.Mod(angle, 360)
+ if angle < 0 {
+ angle += 360
+ }
+
+ // Ensure they didn't provide any nil colors.
+ stops = slices.DeleteFunc(stops, func(c color.Color) bool {
+ return c == nil
+ })
+
+ if len(stops) == 0 {
+ return nil // We can't safely fallback.
+ }
+
+ // If they only provided one valid color (or some nil colors), we will just return
+ // an array of that color, for the amount of pixels they requested.
+ if len(stops) == 1 {
+ singleColor := stops[0]
+ result := make([]color.Color, width*height)
+ for i := range result {
+ result[i] = singleColor
+ }
+ return result
+ }
+
+ // For 2D blending, we'll create a gradient along the diagonal and then sample
+ // from it based on the angle. We'll use the maximum dimension to ensure we have
+ // enough resolution for the gradient.
+ diagonalGradient := Blend1D(max(width, height), stops...)
+
+ result := make([]color.Color, width*height)
+
+ // Calculate center point for rotation.
+ centerX := float64(width-1) / 2.0
+ centerY := float64(height-1) / 2.0
+
+ angleRad := angle * math.Pi / 180.0 // -> radians.
+
+ // Pre-calculate sin and cos.
+ cosAngle := math.Cos(angleRad)
+ sinAngle := math.Sin(angleRad)
+
+ // Calculate diagonal length for proper gradient mapping.
+ diagonalLength := math.Sqrt(float64(width*width + height*height))
+
+ // Pre-calculate gradient length for index calculation.
+ gradientLen := float64(len(diagonalGradient) - 1)
+
+ for y := range height {
+ // Calculate the distance from center along the gradient direction.
+ dy := float64(y) - centerY
+
+ for x := 0; x < width; x++ {
+ // Calculate the distance from center along the gradient direction.
+ dx := float64(x) - centerX
+
+ rotX := dx*cosAngle - dy*sinAngle // Rotate the point by the angle.
+
+ // Map the rotated position to the gradient. Normalize to 0-1 range based on
+ // the diagonal length.
+ gradientPos := clamp((rotX+diagonalLength/2.0)/diagonalLength, 0, 1)
+
+ // Calculate the index in the gradient.
+ gradientIndex := int(gradientPos * gradientLen)
+ if gradientIndex >= len(diagonalGradient) {
+ gradientIndex = len(diagonalGradient) - 1
+ }
+
+ result[y*width+x] = diagonalGradient[gradientIndex] // -> row-major order.
+ }
+ }
+
+ return result
+}
diff --git a/vendor/charm.land/lipgloss/v2/borders.go b/vendor/charm.land/lipgloss/v2/borders.go
new file mode 100644
index 000000000..7f12360f6
--- /dev/null
+++ b/vendor/charm.land/lipgloss/v2/borders.go
@@ -0,0 +1,587 @@
+package lipgloss
+
+import (
+ "image/color"
+ "slices"
+ "strings"
+ "unicode/utf8"
+
+ "github.com/charmbracelet/x/ansi"
+ "github.com/clipperhouse/displaywidth"
+ "github.com/rivo/uniseg"
+)
+
+// Border contains a series of values which comprise the various parts of a
+// border.
+type Border struct {
+ Top string
+ Bottom string
+ Left string
+ Right string
+ TopLeft string
+ TopRight string
+ BottomLeft string
+ BottomRight string
+ MiddleLeft string
+ MiddleRight string
+ Middle string
+ MiddleTop string
+ MiddleBottom string
+}
+
+// GetTopSize returns the width of the top border. If borders contain runes of
+// varying widths, the widest rune is returned. If no border exists on the top
+// edge, 0 is returned.
+func (b Border) GetTopSize() int {
+ return getBorderEdgeWidth(b.TopLeft, b.Top, b.TopRight)
+}
+
+// GetRightSize returns the width of the right border. If borders contain
+// runes of varying widths, the widest rune is returned. If no border exists on
+// the right edge, 0 is returned.
+func (b Border) GetRightSize() int {
+ return getBorderEdgeWidth(b.TopRight, b.Right, b.BottomRight)
+}
+
+// GetBottomSize returns the width of the bottom border. If borders contain
+// runes of varying widths, the widest rune is returned. If no border exists on
+// the bottom edge, 0 is returned.
+func (b Border) GetBottomSize() int {
+ return getBorderEdgeWidth(b.BottomLeft, b.Bottom, b.BottomRight)
+}
+
+// GetLeftSize returns the width of the left border. If borders contain runes
+// of varying widths, the widest rune is returned. If no border exists on the
+// left edge, 0 is returned.
+func (b Border) GetLeftSize() int {
+ return getBorderEdgeWidth(b.TopLeft, b.Left, b.BottomLeft)
+}
+
+func getBorderEdgeWidth(borderParts ...string) (maxWidth int) {
+ for _, piece := range borderParts {
+ maxWidth = max(maxWidth, maxRuneWidth(piece))
+ }
+ return maxWidth
+}
+
+var (
+ noBorder = Border{}
+
+ normalBorder = Border{
+ Top: "─",
+ Bottom: "─",
+ Left: "│",
+ Right: "│",
+ TopLeft: "┌",
+ TopRight: "┐",
+ BottomLeft: "└",
+ BottomRight: "┘",
+ MiddleLeft: "├",
+ MiddleRight: "┤",
+ Middle: "┼",
+ MiddleTop: "┬",
+ MiddleBottom: "┴",
+ }
+
+ roundedBorder = Border{
+ Top: "─",
+ Bottom: "─",
+ Left: "│",
+ Right: "│",
+ TopLeft: "╭",
+ TopRight: "╮",
+ BottomLeft: "╰",
+ BottomRight: "╯",
+ MiddleLeft: "├",
+ MiddleRight: "┤",
+ Middle: "┼",
+ MiddleTop: "┬",
+ MiddleBottom: "┴",
+ }
+
+ blockBorder = Border{
+ Top: "█",
+ Bottom: "█",
+ Left: "█",
+ Right: "█",
+ TopLeft: "█",
+ TopRight: "█",
+ BottomLeft: "█",
+ BottomRight: "█",
+ MiddleLeft: "█",
+ MiddleRight: "█",
+ Middle: "█",
+ MiddleTop: "█",
+ MiddleBottom: "█",
+ }
+
+ outerHalfBlockBorder = Border{
+ Top: "▀",
+ Bottom: "▄",
+ Left: "▌",
+ Right: "▐",
+ TopLeft: "▛",
+ TopRight: "▜",
+ BottomLeft: "▙",
+ BottomRight: "▟",
+ }
+
+ innerHalfBlockBorder = Border{
+ Top: "▄",
+ Bottom: "▀",
+ Left: "▐",
+ Right: "▌",
+ TopLeft: "▗",
+ TopRight: "▖",
+ BottomLeft: "▝",
+ BottomRight: "▘",
+ }
+
+ thickBorder = Border{
+ Top: "━",
+ Bottom: "━",
+ Left: "┃",
+ Right: "┃",
+ TopLeft: "┏",
+ TopRight: "┓",
+ BottomLeft: "┗",
+ BottomRight: "┛",
+ MiddleLeft: "┣",
+ MiddleRight: "┫",
+ Middle: "╋",
+ MiddleTop: "┳",
+ MiddleBottom: "┻",
+ }
+
+ doubleBorder = Border{
+ Top: "═",
+ Bottom: "═",
+ Left: "║",
+ Right: "║",
+ TopLeft: "╔",
+ TopRight: "╗",
+ BottomLeft: "╚",
+ BottomRight: "╝",
+ MiddleLeft: "╠",
+ MiddleRight: "╣",
+ Middle: "╬",
+ MiddleTop: "╦",
+ MiddleBottom: "╩",
+ }
+
+ hiddenBorder = Border{
+ Top: " ",
+ Bottom: " ",
+ Left: " ",
+ Right: " ",
+ TopLeft: " ",
+ TopRight: " ",
+ BottomLeft: " ",
+ BottomRight: " ",
+ MiddleLeft: " ",
+ MiddleRight: " ",
+ Middle: " ",
+ MiddleTop: " ",
+ MiddleBottom: " ",
+ }
+
+ markdownBorder = Border{
+ Top: "-",
+ Bottom: "-",
+ Left: "|",
+ Right: "|",
+ TopLeft: "|",
+ TopRight: "|",
+ BottomLeft: "|",
+ BottomRight: "|",
+ MiddleLeft: "|",
+ MiddleRight: "|",
+ Middle: "|",
+ MiddleTop: "|",
+ MiddleBottom: "|",
+ }
+
+ asciiBorder = Border{
+ Top: "-",
+ Bottom: "-",
+ Left: "|",
+ Right: "|",
+ TopLeft: "+",
+ TopRight: "+",
+ BottomLeft: "+",
+ BottomRight: "+",
+ MiddleLeft: "+",
+ MiddleRight: "+",
+ Middle: "+",
+ MiddleTop: "+",
+ MiddleBottom: "+",
+ }
+)
+
+// NormalBorder returns a standard-type border with a normal weight and 90
+// degree corners.
+func NormalBorder() Border {
+ return normalBorder
+}
+
+// RoundedBorder returns a border with rounded corners.
+func RoundedBorder() Border {
+ return roundedBorder
+}
+
+// BlockBorder returns a border that takes the whole block.
+func BlockBorder() Border {
+ return blockBorder
+}
+
+// OuterHalfBlockBorder returns a half-block border that sits outside the frame.
+func OuterHalfBlockBorder() Border {
+ return outerHalfBlockBorder
+}
+
+// InnerHalfBlockBorder returns a half-block border that sits inside the frame.
+func InnerHalfBlockBorder() Border {
+ return innerHalfBlockBorder
+}
+
+// ThickBorder returns a border that's thicker than the one returned by
+// NormalBorder.
+func ThickBorder() Border {
+ return thickBorder
+}
+
+// DoubleBorder returns a border comprised of two thin strokes.
+func DoubleBorder() Border {
+ return doubleBorder
+}
+
+// HiddenBorder returns a border that renders as a series of single-cell
+// spaces. It's useful for cases when you want to remove a standard border but
+// maintain layout positioning. This said, you can still apply a background
+// color to a hidden border.
+func HiddenBorder() Border {
+ return hiddenBorder
+}
+
+// MarkdownBorder return a table border in markdown style.
+//
+// Make sure to disable top and bottom border for the best result. This will
+// ensure that the output is valid markdown.
+//
+// table.New().Border(lipgloss.MarkdownBorder()).BorderTop(false).BorderBottom(false)
+func MarkdownBorder() Border {
+ return markdownBorder
+}
+
+// ASCIIBorder returns a table border with ASCII characters.
+func ASCIIBorder() Border {
+ return asciiBorder
+}
+
+type borderBlend struct {
+ topGradient []color.Color
+ rightGradient []color.Color
+ bottomGradient []color.Color
+ leftGradient []color.Color
+}
+
+func (s Style) borderBlend(width, height int, colors ...color.Color) *borderBlend {
+ gradient := Blend1D(
+ (height+width+2)*2,
+ colors...,
+ )
+
+ // Rotate array forward or reverse based on the offset if provided.
+ if r := -s.getAsInt(borderForegroundBlendOffsetKey); r != 0 {
+ n := len(gradient)
+ r %= n
+ if r < 0 {
+ r += n
+ }
+ slices.Reverse(gradient[:r])
+ slices.Reverse(gradient[r:])
+ slices.Reverse(gradient)
+ }
+
+ offset := 0
+ getFromOffset := func(size int) (s []color.Color) {
+ s = gradient[offset : offset+size]
+ offset += size
+ return s
+ }
+
+ blend := &borderBlend{
+ topGradient: getFromOffset(width + 2),
+ rightGradient: getFromOffset(height),
+ bottomGradient: getFromOffset(width + 2),
+ leftGradient: getFromOffset(height),
+ }
+
+ // bottom and left gradients are reversed because they are drawn in reverse order.
+ slices.Reverse(blend.bottomGradient)
+ slices.Reverse(blend.leftGradient)
+
+ return blend
+}
+
+func (s Style) applyBorder(str string) string {
+ var (
+ border = s.getBorderStyle()
+ hasTop = s.getAsBool(borderTopKey, false)
+ hasRight = s.getAsBool(borderRightKey, false)
+ hasBottom = s.getAsBool(borderBottomKey, false)
+ hasLeft = s.getAsBool(borderLeftKey, false)
+ )
+
+ // If a border is set and no sides have been specifically turned on or off
+ // render borders on all sides.
+ if s.isBorderStyleSetWithoutSides() {
+ hasTop = true
+ hasRight = true
+ hasBottom = true
+ hasLeft = true
+ }
+
+ // If no border is set or all borders are been disabled, abort.
+ if border == noBorder || (!hasTop && !hasRight && !hasBottom && !hasLeft) {
+ return str
+ }
+
+ lines, width := getLines(str)
+
+ if hasLeft {
+ if border.Left == "" {
+ border.Left = " "
+ }
+ width += maxRuneWidth(border.Left)
+ }
+
+ if hasRight {
+ if border.Right == "" {
+ border.Right = " "
+ }
+ width += maxRuneWidth(border.Right)
+ }
+
+ // If corners should be rendered but are set with the empty string, fill them
+ // with a single space.
+ if hasTop && hasLeft && border.TopLeft == "" {
+ border.TopLeft = " "
+ }
+ if hasTop && hasRight && border.TopRight == "" {
+ border.TopRight = " "
+ }
+ if hasBottom && hasLeft && border.BottomLeft == "" {
+ border.BottomLeft = " "
+ }
+ if hasBottom && hasRight && border.BottomRight == "" {
+ border.BottomRight = " "
+ }
+
+ // Figure out which corners we should actually be using based on which
+ // sides are set to show.
+ if hasTop {
+ switch {
+ case !hasLeft && !hasRight:
+ border.TopLeft = ""
+ border.TopRight = ""
+ case !hasLeft:
+ border.TopLeft = ""
+ case !hasRight:
+ border.TopRight = ""
+ }
+ }
+ if hasBottom {
+ switch {
+ case !hasLeft && !hasRight:
+ border.BottomLeft = ""
+ border.BottomRight = ""
+ case !hasLeft:
+ border.BottomLeft = ""
+ case !hasRight:
+ border.BottomRight = ""
+ }
+ }
+
+ // For now, limit corners to one rune.
+ border.TopLeft = getFirstRuneAsString(border.TopLeft)
+ border.TopRight = getFirstRuneAsString(border.TopRight)
+ border.BottomRight = getFirstRuneAsString(border.BottomRight)
+ border.BottomLeft = getFirstRuneAsString(border.BottomLeft)
+
+ var topFG, rightFG, bottomFG, leftFG color.Color
+ var (
+ blendFG = s.getAsColors(borderForegroundBlendKey)
+ topBG = s.getAsColor(borderTopBackgroundKey)
+ rightBG = s.getAsColor(borderRightBackgroundKey)
+ bottomBG = s.getAsColor(borderBottomBackgroundKey)
+ leftBG = s.getAsColor(borderLeftBackgroundKey)
+ )
+
+ var blend *borderBlend
+ if len(blendFG) > 0 {
+ blend = s.borderBlend(width, len(lines), blendFG...)
+ } else {
+ topFG = s.getAsColor(borderTopForegroundKey)
+ rightFG = s.getAsColor(borderRightForegroundKey)
+ bottomFG = s.getAsColor(borderBottomForegroundKey)
+ leftFG = s.getAsColor(borderLeftForegroundKey)
+ }
+
+ var out strings.Builder
+
+ // Render top
+ if hasTop {
+ top := renderHorizontalEdge(border.TopLeft, border.Top, border.TopRight, width)
+ if blend != nil {
+ out.WriteString(s.styleBorderBlend(top, blend.topGradient, topBG))
+ } else {
+ out.WriteString(s.styleBorder(top, topFG, topBG))
+ }
+ out.WriteRune('\n')
+ }
+
+ leftRunes := []rune(border.Left)
+ leftIndex := 0
+
+ rightRunes := []rune(border.Right)
+ rightIndex := 0
+
+ // Render sides
+ var r string
+ for i, l := range lines {
+ if hasLeft {
+ r = string(leftRunes[leftIndex])
+ leftIndex++
+ if leftIndex >= len(leftRunes) {
+ leftIndex = 0
+ }
+ if blend != nil {
+ out.WriteString(s.styleBorder(r, blend.leftGradient[i], leftBG))
+ } else {
+ out.WriteString(s.styleBorder(r, leftFG, leftBG))
+ }
+ }
+ out.WriteString(l)
+ if hasRight {
+ r = string(rightRunes[rightIndex])
+ rightIndex++
+ if rightIndex >= len(rightRunes) {
+ rightIndex = 0
+ }
+ if blend != nil {
+ out.WriteString(s.styleBorder(r, blend.rightGradient[i], rightBG))
+ } else {
+ out.WriteString(s.styleBorder(r, rightFG, rightBG))
+ }
+ }
+ if i < len(lines)-1 {
+ out.WriteRune('\n')
+ }
+ }
+
+ // Render bottom
+ if hasBottom {
+ bottom := renderHorizontalEdge(border.BottomLeft, border.Bottom, border.BottomRight, width)
+ out.WriteRune('\n')
+ if blend != nil {
+ out.WriteString(s.styleBorderBlend(bottom, blend.bottomGradient, bottomBG))
+ } else {
+ out.WriteString(s.styleBorder(bottom, bottomFG, bottomBG))
+ }
+ }
+
+ return out.String()
+}
+
+// Render the horizontal (top or bottom) portion of a border.
+func renderHorizontalEdge(left, middle, right string, width int) string {
+ if middle == "" {
+ middle = " "
+ }
+
+ leftWidth := ansi.StringWidth(left)
+ rightWidth := ansi.StringWidth(right)
+
+ runes := []rune(middle)
+ j := 0
+
+ out := strings.Builder{}
+ out.WriteString(left)
+
+ for i := 0; i < width-leftWidth-rightWidth; {
+ r := runes[j]
+ out.WriteRune(r)
+ i += ansi.StringWidth(string(r))
+ j++
+ if j >= len(runes) {
+ j = 0
+ }
+ }
+
+ out.WriteString(right)
+ return out.String()
+}
+
+// styleBorder applies foreground and background styling to a border.
+func (s Style) styleBorder(border string, fg, bg color.Color) string {
+ if fg == noColor && bg == noColor {
+ return border
+ }
+ var style ansi.Style
+ if fg != noColor {
+ style = style.ForegroundColor(fg)
+ }
+ if bg != noColor {
+ style = style.BackgroundColor(bg)
+ }
+ return style.Styled(border)
+}
+
+// styleBorderBlend applies foreground and background styling to a border, using blending.
+func (s Style) styleBorderBlend(border string, fg []color.Color, bg color.Color) string {
+ var out strings.Builder
+ var style ansi.Style
+ var i int
+
+ gr := uniseg.NewGraphemes(border)
+ for gr.Next() {
+ style = style[:0]
+ if fg[i] != noColor {
+ style = style.ForegroundColor(fg[i])
+ }
+ if bg != noColor {
+ style = style.BackgroundColor(bg)
+ }
+ _, _ = out.WriteString(style.String())
+ _, _ = out.Write(gr.Bytes())
+ i++
+ }
+ _, _ = out.WriteString(ansi.ResetStyle)
+ return out.String()
+}
+
+func maxRuneWidth(str string) int {
+ switch len(str) {
+ case 0:
+ return 0
+ case 1:
+ return displaywidth.String(str)
+ }
+
+ var width int
+
+ g := displaywidth.StringGraphemes(str)
+ for g.Next() {
+ width = max(width, g.Width())
+ }
+ return width
+}
+
+func getFirstRuneAsString(str string) string {
+ if str == "" {
+ return str
+ }
+ _, size := utf8.DecodeRuneInString(str)
+ return str[:size]
+}
diff --git a/vendor/charm.land/lipgloss/v2/canvas.go b/vendor/charm.land/lipgloss/v2/canvas.go
new file mode 100644
index 000000000..396defb8b
--- /dev/null
+++ b/vendor/charm.land/lipgloss/v2/canvas.go
@@ -0,0 +1,88 @@
+package lipgloss
+
+import (
+ uv "github.com/charmbracelet/ultraviolet"
+ "github.com/charmbracelet/x/ansi"
+)
+
+// Canvas is a cell-buffer that can be used to compose and draw [uv.Drawable]s
+// like [Layer]s.
+//
+// Composed drawables are drawn onto the canvas in the order they were
+// composed, meaning later drawables will appear "on top" of earlier ones.
+//
+// A canvas can read, modify, and render its cell contents.
+//
+// It implements [uv.Screen] and [uv.Drawable].
+type Canvas struct {
+ scr uv.ScreenBuffer
+}
+
+var _ uv.Screen = (*Canvas)(nil)
+
+// NewCanvas creates a new [Canvas] with the given size.
+func NewCanvas(width, height int) *Canvas {
+ c := new(Canvas)
+ c.scr = uv.NewScreenBuffer(width, height)
+ c.scr.Method = ansi.GraphemeWidth
+ return c
+}
+
+// Resize resizes the canvas to the given width and height.
+func (c *Canvas) Resize(width, height int) {
+ c.scr.Resize(width, height)
+}
+
+// Clear clears the canvas.
+func (c *Canvas) Clear() {
+ c.scr.Clear()
+}
+
+// Bounds implements [uv.Screen].
+func (c *Canvas) Bounds() uv.Rectangle {
+ return c.scr.Bounds()
+}
+
+// Width returns the width of the canvas.
+func (c *Canvas) Width() int {
+ return c.scr.Width()
+}
+
+// Height returns the height of the canvas.
+func (c *Canvas) Height() int {
+ return c.scr.Height()
+}
+
+// CellAt implements [uv.Screen].
+func (c *Canvas) CellAt(x int, y int) *uv.Cell {
+ return c.scr.CellAt(x, y)
+}
+
+// SetCell implements [uv.Screen].
+func (c *Canvas) SetCell(x int, y int, cell *uv.Cell) {
+ c.scr.SetCell(x, y, cell)
+}
+
+// WidthMethod implements [uv.Screen].
+func (c *Canvas) WidthMethod() uv.WidthMethod {
+ return c.scr.WidthMethod()
+}
+
+// Compose composes a [Layer] or any [uv.Drawable] onto the [Canvas].
+func (c *Canvas) Compose(drawer uv.Drawable) *Canvas {
+ drawer.Draw(c, c.Bounds())
+ return c
+}
+
+// Draw draws the [Canvas] onto the given [uv.Screen] within the specified
+// area.
+//
+// It implements [uv.Drawable].
+func (c *Canvas) Draw(scr uv.Screen, area uv.Rectangle) {
+ c.scr.Draw(scr, area)
+}
+
+// Render renders the canvas into a styled string.
+func (c *Canvas) Render() string {
+ return c.scr.Render()
+}
diff --git a/vendor/charm.land/lipgloss/v2/color.go b/vendor/charm.land/lipgloss/v2/color.go
new file mode 100644
index 000000000..7443dc10b
--- /dev/null
+++ b/vendor/charm.land/lipgloss/v2/color.go
@@ -0,0 +1,359 @@
+package lipgloss
+
+import (
+ "cmp"
+ "errors"
+ "image/color"
+ "strconv"
+ "strings"
+
+ "github.com/charmbracelet/colorprofile"
+ "github.com/charmbracelet/x/ansi"
+ "github.com/lucasb-eyer/go-colorful"
+)
+
+func clamp[T cmp.Ordered](v, low, high T) T {
+ if high < low {
+ high, low = low, high
+ }
+ return min(high, max(low, v))
+}
+
+// 4-bit color constants.
+const (
+ Black ansi.BasicColor = iota
+ Red
+ Green
+ Yellow
+ Blue
+ Magenta
+ Cyan
+ White
+
+ BrightBlack
+ BrightRed
+ BrightGreen
+ BrightYellow
+ BrightBlue
+ BrightMagenta
+ BrightCyan
+ BrightWhite
+)
+
+var noColor = NoColor{}
+
+// NoColor is used to specify the absence of color styling. When this is active
+// foreground colors will be rendered with the terminal's default text color,
+// and background colors will not be drawn at all.
+//
+// Example usage:
+//
+// var style = someStyle.Background(lipgloss.NoColor{})
+type NoColor struct{}
+
+// RGBA returns the RGBA value of this color. Because we have to return
+// something, despite this color being the absence of color, we're returning
+// black with 100% opacity.
+//
+// Red: 0x0, Green: 0x0, Blue: 0x0, Alpha: 0xFFFF.
+func (n NoColor) RGBA() (r, g, b, a uint32) {
+ return 0x0, 0x0, 0x0, 0xFFFF //nolint:mnd
+}
+
+// Color specifies a color by hex or ANSI256 value. For example:
+//
+// ansiColor := lipgloss.Color("1") // The same as lipgloss.Red
+// ansi256Color := lipgloss.Color("21")
+// hexColor := lipgloss.Color("#0000ff")
+func Color(s string) color.Color {
+ if strings.HasPrefix(s, "#") {
+ c, err := parseHex(s)
+ if err != nil {
+ return noColor
+ }
+ return c
+ }
+
+ i, err := strconv.Atoi(s)
+ if err != nil {
+ return noColor
+ }
+
+ if i < 0 {
+ // Only positive numbers
+ i = -i
+ }
+
+ if i < 16 {
+ return ansi.BasicColor(i) //nolint:gosec
+ } else if i < 256 {
+ return ANSIColor(i) //nolint:gosec
+ }
+
+ r, g, b := uint8((i>>16)&0xff), uint8(i>>8&0xff), uint8(i&0xff) //nolint:gosec
+ return color.RGBA{R: r, G: g, B: b, A: 0xff}
+}
+
+var errInvalidFormat = errors.New("invalid hex format") // pre-allocated.
+
+// parseHex parses a hex color string and returns a color.RGBA. The string can be
+// in the format #RRGGBB or #RGB. This is a more performant implementation of
+// [colorful.Hex].
+func parseHex(s string) (c color.RGBA, err error) {
+ c.A = 0xff
+
+ if len(s) == 0 || s[0] != '#' {
+ return c, errInvalidFormat
+ }
+
+ hexToByte := func(b byte) byte {
+ switch {
+ case b >= '0' && b <= '9':
+ return b - '0'
+ case b >= 'a' && b <= 'f':
+ return b - 'a' + 10
+ case b >= 'A' && b <= 'F':
+ return b - 'A' + 10
+ }
+ err = errInvalidFormat
+ return 0
+ }
+
+ switch len(s) {
+ case 7:
+ c.R = hexToByte(s[1])<<4 + hexToByte(s[2])
+ c.G = hexToByte(s[3])<<4 + hexToByte(s[4])
+ c.B = hexToByte(s[5])<<4 + hexToByte(s[6])
+ case 4:
+ c.R = hexToByte(s[1]) * 17
+ c.G = hexToByte(s[2]) * 17
+ c.B = hexToByte(s[3]) * 17
+ default:
+ err = errInvalidFormat
+ }
+ return c, err
+}
+
+// RGBColor is a color specified by red, green, and blue values.
+type RGBColor struct {
+ R uint8
+ G uint8
+ B uint8
+}
+
+// RGBA returns the RGBA value of this color. This satisfies the Go Color
+// interface.
+func (c RGBColor) RGBA() (r, g, b, a uint32) {
+ const shift = 8
+ r |= uint32(c.R) << shift
+ g |= uint32(c.G) << shift
+ b |= uint32(c.B) << shift
+ a = 0xFFFF
+ return
+}
+
+// ANSIColor is a color specified by an ANSI256 color value.
+//
+// Example usage:
+//
+// colorA := lipgloss.ANSIColor(8)
+// colorB := lipgloss.ANSIColor(134)
+type ANSIColor = ansi.IndexedColor
+
+// LightDarkFunc is a function that returns a color based on whether the
+// terminal has a light or dark background. You can create one of these with
+// [LightDark].
+//
+// Example:
+//
+// lightDark := lipgloss.LightDark(hasDarkBackground)
+// red, blue := lipgloss.Color("#ff0000"), lipgloss.Color("#0000ff")
+// myHotColor := lightDark(red, blue)
+//
+// For more info see [LightDark].
+type LightDarkFunc func(light, dark color.Color) color.Color
+
+// LightDark is a simple helper type that can be used to choose the appropriate
+// color based on whether the terminal has a light or dark background.
+//
+// lightDark := lipgloss.LightDark(hasDarkBackground)
+// red, blue := lipgloss.Color("#ff0000"), lipgloss.Color("#0000ff")
+// myHotColor := lightDark(red, blue)
+//
+// In practice, there are slightly different workflows between Bubble Tea and
+// Lip Gloss standalone.
+//
+// In Bubble Tea, listen for tea.BackgroundColorMsg, which automatically
+// flows through Update on start. This message will be received whenever the
+// background color changes:
+//
+// case tea.BackgroundColorMsg:
+// m.hasDarkBackground = msg.IsDark()
+//
+// Later, when you're rendering use:
+//
+// lightDark := lipgloss.LightDark(m.hasDarkBackground)
+// red, blue := lipgloss.Color("#ff0000"), lipgloss.Color("#0000ff")
+// myHotColor := lightDark(red, blue)
+//
+// In standalone Lip Gloss, the workflow is simpler:
+//
+// hasDarkBG := lipgloss.HasDarkBackground(os.Stdin, os.Stdout)
+// lightDark := lipgloss.LightDark(hasDarkBG)
+// red, blue := lipgloss.Color("#ff0000"), lipgloss.Color("#0000ff")
+// myHotColor := lightDark(red, blue)
+func LightDark(isDark bool) LightDarkFunc {
+ return func(light, dark color.Color) color.Color {
+ if isDark {
+ return dark
+ }
+ return light
+ }
+}
+
+// isDarkColor returns whether the given color is dark (based on the luminance
+// portion of the color as interpreted as HSL).
+//
+// Example usage:
+//
+// color := lipgloss.Color("#0000ff")
+// if lipgloss.isDarkColor(color) {
+// fmt.Println("It's dark! I love darkness!")
+// } else {
+// fmt.Println("It's light! Cover your eyes!")
+// }
+func isDarkColor(c color.Color) bool {
+ col, ok := colorful.MakeColor(c)
+ if !ok {
+ return true
+ }
+
+ _, _, l := col.Hsl()
+ return l < 0.5 //nolint:mnd
+}
+
+// CompleteFunc is a function that returns the appropriate color based on the
+// given color profile.
+//
+// Example usage:
+//
+// p := colorprofile.Detect(os.Stderr, os.Environ())
+// complete := lipgloss.Complete(p)
+// color := complete(
+// lipgloss.Color(1), // ANSI
+// lipgloss.Color(124), // ANSI256
+// lipgloss.Color("#ff34ac"), // TrueColor
+// )
+// fmt.Println("Ooh, pretty color: ", color)
+//
+// For more info see [Complete].
+type CompleteFunc func(ansi, ansi256, truecolor color.Color) color.Color
+
+// Complete returns a function that will return the appropriate color based on
+// the given color profile.
+//
+// Example usage:
+//
+// p := colorprofile.Detect(os.Stderr, os.Environ())
+// complete := lipgloss.Complete(p)
+// color := complete(
+// lipgloss.Color(1), // ANSI
+// lipgloss.Color(124), // ANSI256
+// lipgloss.Color("#ff34ac"), // TrueColor
+// )
+// fmt.Println("Ooh, pretty color: ", color)
+func Complete(p colorprofile.Profile) CompleteFunc {
+ return func(ansi, ansi256, truecolor color.Color) color.Color {
+ switch p { //nolint:exhaustive
+ case colorprofile.ANSI:
+ return ansi
+ case colorprofile.ANSI256:
+ return ansi256
+ case colorprofile.TrueColor:
+ return truecolor
+ }
+ return noColor
+ }
+}
+
+// ensureNotTransparent ensures that the alpha value of a color is not 0, and if
+// it is, we will set it to 1. This is useful for when we are converting from
+// RGB -> RGBA, and the alpha value is lost in the conversion for gradient purposes.
+func ensureNotTransparent(c color.Color) color.Color {
+ _, _, _, a := c.RGBA()
+ if a == 0 {
+ return Alpha(c, 1)
+ }
+ return c
+}
+
+// Alpha adjusts the alpha value of a color using a 0-1 (clamped) float scale
+// 0 = transparent, 1 = opaque.
+func Alpha(c color.Color, alpha float64) color.Color {
+ if c == nil {
+ return nil
+ }
+
+ r, g, b, _ := c.RGBA()
+ return color.RGBA{
+ R: uint8(min(255, float64(r>>8))),
+ G: uint8(min(255, float64(g>>8))),
+ B: uint8(min(255, float64(b>>8))),
+ A: uint8(clamp(alpha, 0, 1) * 255),
+ }
+}
+
+// Complementary returns the complementary color (180° away on color wheel) of
+// the given color. This is useful for creating a contrasting color.
+func Complementary(c color.Color) color.Color {
+ if c == nil {
+ return nil
+ }
+
+ // Offset hue by 180°.
+ cf, _ := colorful.MakeColor(ensureNotTransparent(c))
+
+ h, s, v := cf.Hsv()
+ h += 180
+ if h >= 360 {
+ h -= 360
+ } else if h < 0 {
+ h += 360
+ }
+
+ return colorful.Hsv(h, s, v).Clamped()
+}
+
+// Darken takes a color and makes it darker by a specific percentage (0-1, clamped).
+func Darken(c color.Color, percent float64) color.Color {
+ if c == nil {
+ return nil
+ }
+
+ mult := 1.0 - clamp(percent, 0, 1)
+
+ r, g, b, a := c.RGBA()
+ return color.RGBA{
+ R: uint8(float64(r>>8) * mult),
+ G: uint8(float64(g>>8) * mult),
+ B: uint8(float64(b>>8) * mult),
+ A: uint8(min(255, float64(a>>8))),
+ }
+}
+
+// Lighten makes a color lighter by a specific percentage (0-1, clamped).
+func Lighten(c color.Color, percent float64) color.Color {
+ if c == nil {
+ return nil
+ }
+
+ add := 255 * (clamp(percent, 0, 1))
+
+ r, g, b, a := c.RGBA()
+ return color.RGBA{
+ R: uint8(min(255, float64(r>>8)+add)),
+ G: uint8(min(255, float64(g>>8)+add)),
+ B: uint8(min(255, float64(b>>8)+add)),
+ A: uint8(min(255, float64(a>>8))),
+ }
+}
diff --git a/vendor/github.com/charmbracelet/lipgloss/get.go b/vendor/charm.land/lipgloss/v2/get.go
similarity index 80%
rename from vendor/github.com/charmbracelet/lipgloss/get.go
rename to vendor/charm.land/lipgloss/v2/get.go
index 422b4ce95..d1fe1d669 100644
--- a/vendor/github.com/charmbracelet/lipgloss/get.go
+++ b/vendor/charm.land/lipgloss/v2/get.go
@@ -1,6 +1,7 @@
package lipgloss
import (
+ "image/color"
"strings"
"github.com/charmbracelet/x/ansi"
@@ -20,7 +21,19 @@ func (s Style) GetItalic() bool {
// GetUnderline returns the style's underline value. If no value is set false is
// returned.
func (s Style) GetUnderline() bool {
- return s.getAsBool(underlineKey, false)
+ return s.ul != UnderlineNone
+}
+
+// GetUnderlineStyle returns the style's underline style. If no value is set
+// UnderlineNone is returned.
+func (s Style) GetUnderlineStyle() Underline {
+ return s.ul
+}
+
+// GetUnderlineColor returns the style's underline color. If no value is set
+// NoColor{} is returned.
+func (s Style) GetUnderlineColor() color.Color {
+ return s.getAsColor(underlineColorKey)
}
// GetStrikethrough returns the style's strikethrough value. If no value is set false
@@ -49,13 +62,13 @@ func (s Style) GetFaint() bool {
// GetForeground returns the style's foreground color. If no value is set
// NoColor{} is returned.
-func (s Style) GetForeground() TerminalColor {
+func (s Style) GetForeground() color.Color {
return s.getAsColor(foregroundKey)
}
// GetBackground returns the style's background color. If no value is set
// NoColor{} is returned.
-func (s Style) GetBackground() TerminalColor {
+func (s Style) GetBackground() color.Color {
return s.getAsColor(backgroundKey)
}
@@ -134,6 +147,16 @@ func (s Style) GetPaddingLeft() int {
return s.getAsInt(paddingLeftKey)
}
+// GetPaddingChar returns the style's padding character. If no value is set a
+// space is returned.
+func (s Style) GetPaddingChar() rune {
+ char := s.getAsRune(paddingCharKey)
+ if char == 0 {
+ return ' '
+ }
+ return char
+}
+
// GetHorizontalPadding returns the style's left and right padding. Unset
// values are measured as 0.
func (s Style) GetHorizontalPadding() int {
@@ -185,6 +208,16 @@ func (s Style) GetMarginLeft() int {
return s.getAsInt(marginLeftKey)
}
+// GetMarginChar returns the style's padding character. If no value is set a
+// space is returned.
+func (s Style) GetMarginChar() rune {
+ char := s.getAsRune(marginCharKey)
+ if char == 0 {
+ return ' '
+ }
+ return char
+}
+
// GetHorizontalMargins returns the style's left and right margins. Unset
// values are measured as 0.
func (s Style) GetHorizontalMargins() int {
@@ -241,49 +274,61 @@ func (s Style) GetBorderLeft() bool {
// GetBorderTopForeground returns the style's border top foreground color. If
// no value is set NoColor{} is returned.
-func (s Style) GetBorderTopForeground() TerminalColor {
+func (s Style) GetBorderTopForeground() color.Color {
return s.getAsColor(borderTopForegroundKey)
}
// GetBorderRightForeground returns the style's border right foreground color.
// If no value is set NoColor{} is returned.
-func (s Style) GetBorderRightForeground() TerminalColor {
+func (s Style) GetBorderRightForeground() color.Color {
return s.getAsColor(borderRightForegroundKey)
}
// GetBorderBottomForeground returns the style's border bottom foreground
// color. If no value is set NoColor{} is returned.
-func (s Style) GetBorderBottomForeground() TerminalColor {
+func (s Style) GetBorderBottomForeground() color.Color {
return s.getAsColor(borderBottomForegroundKey)
}
// GetBorderLeftForeground returns the style's border left foreground
// color. If no value is set NoColor{} is returned.
-func (s Style) GetBorderLeftForeground() TerminalColor {
+func (s Style) GetBorderLeftForeground() color.Color {
return s.getAsColor(borderLeftForegroundKey)
}
+// GetBorderForegroundBlend returns the style's border blend foreground
+// colors. If no value is set, nil is returned.
+func (s Style) GetBorderForegroundBlend() []color.Color {
+ return s.getAsColors(borderForegroundBlendKey)
+}
+
+// GetBorderForegroundBlendOffset returns the style's border blend offset. If no
+// value is set, 0 is returned.
+func (s Style) GetBorderForegroundBlendOffset() int {
+ return s.getAsInt(borderForegroundBlendOffsetKey)
+}
+
// GetBorderTopBackground returns the style's border top background color. If
// no value is set NoColor{} is returned.
-func (s Style) GetBorderTopBackground() TerminalColor {
+func (s Style) GetBorderTopBackground() color.Color {
return s.getAsColor(borderTopBackgroundKey)
}
// GetBorderRightBackground returns the style's border right background color.
// If no value is set NoColor{} is returned.
-func (s Style) GetBorderRightBackground() TerminalColor {
+func (s Style) GetBorderRightBackground() color.Color {
return s.getAsColor(borderRightBackgroundKey)
}
// GetBorderBottomBackground returns the style's border bottom background
// color. If no value is set NoColor{} is returned.
-func (s Style) GetBorderBottomBackground() TerminalColor {
+func (s Style) GetBorderBottomBackground() color.Color {
return s.getAsColor(borderBottomBackgroundKey)
}
// GetBorderLeftBackground returns the style's border left background
// color. If no value is set NoColor{} is returned.
-func (s Style) GetBorderLeftBackground() TerminalColor {
+func (s Style) GetBorderLeftBackground() color.Color {
return s.getAsColor(borderLeftBackgroundKey)
}
@@ -300,7 +345,10 @@ func (s Style) GetBorderTopWidth() int {
// runes of varying widths, the widest rune is returned. If no border exists on
// the top edge, 0 is returned.
func (s Style) GetBorderTopSize() int {
- if !s.getAsBool(borderTopKey, false) && !s.implicitBorders() {
+ if s.isBorderStyleSetWithoutSides() {
+ return 1
+ }
+ if !s.getAsBool(borderTopKey, false) {
return 0
}
return s.getBorderStyle().GetTopSize()
@@ -310,7 +358,10 @@ func (s Style) GetBorderTopSize() int {
// runes of varying widths, the widest rune is returned. If no border exists on
// the left edge, 0 is returned.
func (s Style) GetBorderLeftSize() int {
- if !s.getAsBool(borderLeftKey, false) && !s.implicitBorders() {
+ if s.isBorderStyleSetWithoutSides() {
+ return 1
+ }
+ if !s.getAsBool(borderLeftKey, false) {
return 0
}
return s.getBorderStyle().GetLeftSize()
@@ -320,7 +371,10 @@ func (s Style) GetBorderLeftSize() int {
// contain runes of varying widths, the widest rune is returned. If no border
// exists on the left edge, 0 is returned.
func (s Style) GetBorderBottomSize() int {
- if !s.getAsBool(borderBottomKey, false) && !s.implicitBorders() {
+ if s.isBorderStyleSetWithoutSides() {
+ return 1
+ }
+ if !s.getAsBool(borderBottomKey, false) {
return 0
}
return s.getBorderStyle().GetBottomSize()
@@ -330,7 +384,10 @@ func (s Style) GetBorderBottomSize() int {
// contain runes of varying widths, the widest rune is returned. If no border
// exists on the right edge, 0 is returned.
func (s Style) GetBorderRightSize() int {
- if !s.getAsBool(borderRightKey, false) && !s.implicitBorders() {
+ if s.isBorderStyleSetWithoutSides() {
+ return 1
+ }
+ if !s.getAsBool(borderRightKey, false) {
return 0
}
return s.getBorderStyle().GetRightSize()
@@ -414,11 +471,36 @@ func (s Style) GetTransform() func(string) string {
return s.getAsTransform(transformKey)
}
+// GetHyperlink returns the hyperlink along with its parameters. If no
+// hyperlink is set, empty strings are returned.
+func (s Style) GetHyperlink() (link, params string) {
+ if s.isSet(linkKey) {
+ link = s.link
+ }
+ if s.isSet(linkParamsKey) {
+ params = s.linkParams
+ }
+ return
+}
+
// Returns whether or not the given property is set.
func (s Style) isSet(k propKey) bool {
return s.props.has(k)
}
+func (s Style) getAsRune(k propKey) rune {
+ if !s.isSet(k) {
+ return 0
+ }
+ switch k { //nolint:exhaustive
+ case paddingCharKey:
+ return s.paddingChar
+ case marginCharKey:
+ return s.marginChar
+ }
+ return 0
+}
+
func (s Style) getAsBool(k propKey, defaultVal bool) bool {
if !s.isSet(k) {
return defaultVal
@@ -426,12 +508,25 @@ func (s Style) getAsBool(k propKey, defaultVal bool) bool {
return s.attrs&int(k) != 0
}
-func (s Style) getAsColor(k propKey) TerminalColor {
+func (s Style) getAsColors(k propKey) (colors []color.Color) {
+ if !s.isSet(k) {
+ return nil
+ }
+
+ switch k { //nolint:exhaustive
+ case borderForegroundBlendKey:
+ return s.borderBlendFgColor
+ }
+
+ return nil
+}
+
+func (s Style) getAsColor(k propKey) color.Color {
if !s.isSet(k) {
return noColor
}
- var c TerminalColor
+ var c color.Color
switch k { //nolint:exhaustive
case foregroundKey:
c = s.fgColor
@@ -455,6 +550,8 @@ func (s Style) getAsColor(k propKey) TerminalColor {
c = s.borderBottomBgColor
case borderLeftBackgroundKey:
c = s.borderLeftBgColor
+ case underlineColorKey:
+ c = s.ulColor
}
if c != nil {
@@ -489,6 +586,8 @@ func (s Style) getAsInt(k propKey) int {
return s.marginBottom
case marginLeftKey:
return s.marginLeft
+ case borderForegroundBlendOffsetKey:
+ return s.borderForegroundBlendOffset
case maxWidthKey:
return s.maxWidth
case maxHeightKey:
@@ -519,20 +618,6 @@ func (s Style) getBorderStyle() Border {
return s.borderStyle
}
-// Returns whether or not the style has implicit borders. This happens when
-// a border style has been set but no border sides have been explicitly turned
-// on or off.
-func (s Style) implicitBorders() bool {
- var (
- borderStyle = s.getBorderStyle()
- topSet = s.isSet(borderTopKey)
- rightSet = s.isSet(borderRightKey)
- bottomSet = s.isSet(borderBottomKey)
- leftSet = s.isSet(borderLeftKey)
- )
- return borderStyle != noBorder && !(topSet || rightSet || bottomSet || leftSet)
-}
-
func (s Style) getAsTransform(propKey) func(string) string {
if !s.isSet(transformKey) {
return nil
@@ -543,6 +628,8 @@ func (s Style) getAsTransform(propKey) func(string) string {
// Split a string into lines, additionally returning the size of the widest
// line.
func getLines(s string) (lines []string, widest int) {
+ s = strings.ReplaceAll(s, "\t", " ")
+ s = strings.ReplaceAll(s, "\r\n", "\n")
lines = strings.Split(s, "\n")
for _, l := range lines {
@@ -554,3 +641,17 @@ func getLines(s string) (lines []string, widest int) {
return lines, widest
}
+
+// isBorderStyleSetWithoutSides returns true if the border style is set but no
+// sides are set. This is used to determine if the border should be rendered by
+// default.
+func (s Style) isBorderStyleSetWithoutSides() bool {
+ var (
+ border = s.getBorderStyle()
+ topSet = s.isSet(borderTopKey)
+ rightSet = s.isSet(borderRightKey)
+ bottomSet = s.isSet(borderBottomKey)
+ leftSet = s.isSet(borderLeftKey)
+ )
+ return border != noBorder && !(topSet || rightSet || bottomSet || leftSet) //nolint:staticcheck
+}
diff --git a/vendor/github.com/charmbracelet/lipgloss/join.go b/vendor/charm.land/lipgloss/v2/join.go
similarity index 97%
rename from vendor/github.com/charmbracelet/lipgloss/join.go
rename to vendor/charm.land/lipgloss/v2/join.go
index b0a23a546..349ae552f 100644
--- a/vendor/github.com/charmbracelet/lipgloss/join.go
+++ b/vendor/charm.land/lipgloss/v2/join.go
@@ -60,7 +60,7 @@ func JoinHorizontal(pos Position, strs ...string) string {
extraLines := make([]string, maxHeight-len(blocks[i]))
- switch pos { //nolint:exhaustive
+ switch pos {
case Top:
blocks[i] = append(blocks[i], extraLines...)
@@ -139,7 +139,7 @@ func JoinVertical(pos Position, strs ...string) string {
for j, line := range block {
w := maxWidth - ansi.StringWidth(line)
- switch pos { //nolint:exhaustive
+ switch pos {
case Left:
b.WriteString(line)
b.WriteString(strings.Repeat(" ", w))
@@ -165,7 +165,7 @@ func JoinVertical(pos Position, strs ...string) string {
// Write a newline as long as we're not on the last line of the
// last block.
- if !(i == len(blocks)-1 && j == len(block)-1) {
+ if !(i == len(blocks)-1 && j == len(block)-1) { //nolint:staticcheck
b.WriteRune('\n')
}
}
diff --git a/vendor/charm.land/lipgloss/v2/layer.go b/vendor/charm.land/lipgloss/v2/layer.go
new file mode 100644
index 000000000..e30d1ef2a
--- /dev/null
+++ b/vendor/charm.land/lipgloss/v2/layer.go
@@ -0,0 +1,327 @@
+package lipgloss
+
+import (
+ "fmt"
+ "image"
+ "slices"
+
+ uv "github.com/charmbracelet/ultraviolet"
+)
+
+// Layer represents a visual layer with content and positioning. It's a pure
+// data structure that defines the layer hierarchy without any computation.
+type Layer struct {
+ id string
+ content string
+ width, height int
+ x, y, z int
+ layers []*Layer
+}
+
+// NewLayer creates a new [Layer] with the given content and optional child layers.
+func NewLayer(content string, layers ...*Layer) *Layer {
+ l := &Layer{
+ content: content,
+ }
+ l.AddLayers(layers...)
+ return l
+}
+
+// GetContent returns the content of the Layer.
+func (l *Layer) GetContent() string {
+ return l.content
+}
+
+// Width returns the width of the Layer.
+func (l *Layer) Width() int {
+ return l.width
+}
+
+// Height returns the height of the Layer.
+func (l *Layer) Height() int {
+ return l.height
+}
+
+// GetID returns the ID of the Layer.
+func (l *Layer) GetID() string {
+ return l.id
+}
+
+// ID sets the ID of the Layer.
+func (l *Layer) ID(id string) *Layer {
+ l.id = id
+ return l
+}
+
+// X sets the x-coordinate of the Layer relative to its parent.
+func (l *Layer) X(x int) *Layer {
+ l.x = x
+ return l
+}
+
+// Y sets the y-coordinate of the Layer relative to its parent.
+func (l *Layer) Y(y int) *Layer {
+ l.y = y
+ return l
+}
+
+// Z sets the z-index of the Layer relative to its parent.
+func (l *Layer) Z(z int) *Layer {
+ l.z = z
+ return l
+}
+
+// GetX returns the x-coordinate of the Layer relative to its parent.
+func (l *Layer) GetX() int {
+ return l.x
+}
+
+// GetY returns the y-coordinate of the Layer relative to its parent.
+func (l *Layer) GetY() int {
+ return l.y
+}
+
+// GetZ returns the z-index of the Layer relative to its parent.
+func (l *Layer) GetZ() int {
+ return l.z
+}
+
+// AddLayers adds child layers to the Layer.
+func (l *Layer) AddLayers(layers ...*Layer) *Layer {
+ for i, layer := range layers {
+ if layer == nil {
+ panic(fmt.Sprintf("layer at index %d is nil", i))
+ }
+ l.layers = append(l.layers, layer)
+ }
+ area := l.boundsWithOffset(0, 0)
+ l.width = area.Dx()
+ l.height = area.Dy()
+ return l
+}
+
+// GetLayer returns a descendant layer by its ID, or nil if not found.
+// Layers with empty IDs are skipped.
+func (l *Layer) GetLayer(id string) *Layer {
+ if id == "" {
+ return nil
+ }
+ if l.id == id {
+ return l
+ }
+ for _, child := range l.layers {
+ if found := child.GetLayer(id); found != nil {
+ return found
+ }
+ }
+ return nil
+}
+
+// MaxZ returns the maximum z-index among this layer and all its descendants.
+func (l *Layer) MaxZ() int {
+ maxZ := l.z
+ for _, child := range l.layers {
+ childMaxZ := child.MaxZ()
+ if childMaxZ > maxZ {
+ maxZ = childMaxZ
+ }
+ }
+ return maxZ
+}
+
+// boundsWithOffset calculates bounds with parent offset applied.
+func (l *Layer) boundsWithOffset(parentX, parentY int) image.Rectangle {
+ absX := l.x + parentX
+ absY := l.y + parentY
+
+ width, height := Width(l.content), Height(l.content)
+ bounds := image.Rectangle{
+ Min: image.Pt(absX, absY),
+ Max: image.Pt(absX+width, absY+height),
+ }
+
+ for _, child := range l.layers {
+ bounds = bounds.Union(child.boundsWithOffset(absX, absY))
+ }
+
+ return bounds
+}
+
+var _ uv.Drawable = (*Layer)(nil)
+
+// Draw draws the content of the layer on the screen at the specified area.
+func (l *Layer) Draw(scr uv.Screen, area uv.Rectangle) {
+ content := uv.NewStyledString(l.content)
+ content.Draw(scr, area)
+}
+
+// LayerHit represents the result of a hit test on a [Layer].
+type LayerHit struct {
+ id string
+ layer *Layer
+ bounds image.Rectangle
+}
+
+// Empty returns true if the LayerHit represents no hit.
+func (lh LayerHit) Empty() bool {
+ return lh.layer == nil
+}
+
+// ID returns the ID of the hit Layer.
+func (lh LayerHit) ID() string {
+ return lh.id
+}
+
+// Layer returns the layer that was hit.
+func (lh LayerHit) Layer() *Layer {
+ return lh.layer
+}
+
+// Bounds returns the bounds of the LayerHit.
+func (lh LayerHit) Bounds() image.Rectangle {
+ return lh.bounds
+}
+
+// Compositor manages the composition of layers. It flattens a layer hierarchy
+// once and provides efficient drawing and hit testing operations. All computation
+// related to layers happens in the Compositor.
+type Compositor struct {
+ root *Layer
+ layers []compositeLayer
+ index map[string]*Layer
+ bounds image.Rectangle
+}
+
+// compositeLayer holds a flattened layer with its calculated absolute position and bounds.
+type compositeLayer struct {
+ layer *Layer
+ absX int
+ absY int
+ bounds image.Rectangle
+}
+
+// NewCompositor creates a new Compositor with an internal root layer. Optional
+// layers can be provided which will be added as children of the root. The layer
+// hierarchy is flattened and sorted by z-index for efficient rendering and hit testing.
+func NewCompositor(layers ...*Layer) *Compositor {
+ root := NewLayer("")
+ root.AddLayers(layers...)
+ c := &Compositor{
+ root: root,
+ index: make(map[string]*Layer),
+ }
+ c.flatten()
+ return c
+}
+
+// AddLayers adds layers to the compositor's root and refreshes the internal state.
+func (c *Compositor) AddLayers(layers ...*Layer) *Compositor {
+ c.root.AddLayers(layers...)
+ c.flatten()
+ return c
+}
+
+// flatten builds the internal flattened layer list and calculates overall bounds.
+func (c *Compositor) flatten() {
+ c.layers = nil
+ c.index = make(map[string]*Layer)
+ c.flattenRecursive(c.root, 0, 0)
+
+ // Sort by absolute z-index (lowest to highest for drawing)
+ slices.SortFunc(c.layers, func(a, b compositeLayer) int {
+ return a.layer.z - b.layer.z
+ })
+
+ // Calculate overall bounds
+ if len(c.layers) > 0 {
+ c.bounds = c.layers[0].bounds
+ for i := 1; i < len(c.layers); i++ {
+ c.bounds = c.bounds.Union(c.layers[i].bounds)
+ }
+ }
+}
+
+// flattenRecursive recursively collects all layers with their absolute positions.
+func (c *Compositor) flattenRecursive(layer *Layer, parentX, parentY int) {
+ absX := layer.x + parentX
+ absY := layer.y + parentY
+
+ width, height := Width(layer.content), Height(layer.content)
+ bounds := image.Rectangle{
+ Min: image.Pt(absX, absY),
+ Max: image.Pt(absX+width, absY+height),
+ }
+
+ c.layers = append(c.layers, compositeLayer{
+ layer: layer,
+ absX: absX,
+ absY: absY,
+ bounds: bounds,
+ })
+
+ // Index layer by ID if it has one
+ if layer.id != "" {
+ c.index[layer.id] = layer
+ }
+
+ for _, child := range layer.layers {
+ c.flattenRecursive(child, absX, absY)
+ }
+}
+
+// Bounds returns the overall bounds of all layers in the compositor.
+func (c *Compositor) Bounds() image.Rectangle {
+ return c.bounds
+}
+
+// Draw draws all layers onto the given [uv.Screen] in z-index order.
+func (c *Compositor) Draw(scr uv.Screen, area image.Rectangle) {
+ for _, cl := range c.layers {
+ if cl.bounds.Overlaps(area) {
+ cl.layer.Draw(scr, cl.bounds)
+ }
+ }
+}
+
+// Hit performs a hit test at the given (x, y) coordinates. If a layer is hit,
+// it returns the ID of the top-most layer at that point. Layers with empty IDs
+// are ignored. If no layer is hit, it returns an empty [LayerHit].
+func (c *Compositor) Hit(x, y int) LayerHit {
+ var hit LayerHit
+ pt := image.Pt(x, y)
+ // Check from highest z to lowest (reverse order)
+ for i := len(c.layers) - 1; i >= 0; i-- {
+ cl := c.layers[i]
+ if cl.layer.id != "" && pt.In(cl.bounds) {
+ hit.id = cl.layer.id
+ hit.layer = cl.layer
+ hit.bounds = cl.bounds
+ return hit
+ }
+ }
+ return hit
+}
+
+// GetLayer returns a layer by its ID, or nil if not found.
+// Layers with empty IDs are not indexed and cannot be retrieved.
+func (c *Compositor) GetLayer(id string) *Layer {
+ if id == "" {
+ return nil
+ }
+ return c.index[id]
+}
+
+// Refresh re-flattens the layer hierarchy. Call this after modifying the layer
+// tree structure or positions to update the compositor's internal state.
+func (c *Compositor) Refresh() {
+ c.flatten()
+}
+
+// Render renders the compositor into a styled string. This is a helper
+// function that creates a temporary canvas, draws the compositor onto it, and
+// returns the resulting string.
+func (c *Compositor) Render() string {
+ width, height := c.bounds.Dx(), c.bounds.Dy()
+ canvas := NewCanvas(width, height)
+ return canvas.Compose(c).Render()
+}
diff --git a/vendor/charm.land/lipgloss/v2/lipgloss.go b/vendor/charm.land/lipgloss/v2/lipgloss.go
new file mode 100644
index 000000000..3fb4e6f26
--- /dev/null
+++ b/vendor/charm.land/lipgloss/v2/lipgloss.go
@@ -0,0 +1,3 @@
+// Package lipgloss provides style definitions for nice terminal layouts. Built
+// with TUIs in mind.
+package lipgloss
diff --git a/vendor/charm.land/lipgloss/v2/position.go b/vendor/charm.land/lipgloss/v2/position.go
new file mode 100644
index 000000000..cea67763f
--- /dev/null
+++ b/vendor/charm.land/lipgloss/v2/position.go
@@ -0,0 +1,134 @@
+package lipgloss
+
+import (
+ "math"
+ "strings"
+
+ "github.com/charmbracelet/x/ansi"
+)
+
+// Position represents a position along a horizontal or vertical axis. It's in
+// situations where an axis is involved, like alignment, joining, placement and
+// so on.
+//
+// A value of 0 represents the start (the left or top) and 1 represents the end
+// (the right or bottom). 0.5 represents the center.
+//
+// There are constants Top, Bottom, Center, Left and Right in this package that
+// can be used to aid readability.
+type Position float64
+
+func (p Position) value() float64 {
+ return math.Min(1, math.Max(0, float64(p)))
+}
+
+// Position aliases.
+const (
+ Top Position = 0.0
+ Bottom Position = 1.0
+ Center Position = 0.5
+ Left Position = 0.0
+ Right Position = 1.0
+)
+
+// Place places a string or text block vertically in an unstyled box of a given
+// width or height.
+func Place(width, height int, hPos, vPos Position, str string, opts ...WhitespaceOption) string {
+ return PlaceVertical(height, vPos, PlaceHorizontal(width, hPos, str, opts...), opts...)
+}
+
+// PlaceHorizontal places a string or text block horizontally in an unstyled
+// block of a given width. If the given width is shorter than the max width of
+// the string (measured by its longest line) this will be a noop.
+func PlaceHorizontal(width int, pos Position, str string, opts ...WhitespaceOption) string {
+ lines, contentWidth := getLines(str)
+ gap := width - contentWidth
+
+ if gap <= 0 {
+ return str
+ }
+
+ ws := newWhitespace(opts...)
+
+ var b strings.Builder
+ for i, l := range lines {
+ // Is this line shorter than the longest line?
+ short := max(0, contentWidth-ansi.StringWidth(l))
+
+ switch pos {
+ case Left:
+ b.WriteString(l)
+ b.WriteString(ws.render(gap + short))
+
+ case Right:
+ b.WriteString(ws.render(gap + short))
+ b.WriteString(l)
+
+ default: // somewhere in the middle
+ totalGap := gap + short
+
+ split := int(math.Round(float64(totalGap) * pos.value()))
+ left := totalGap - split
+ right := totalGap - left
+
+ b.WriteString(ws.render(left))
+ b.WriteString(l)
+ b.WriteString(ws.render(right))
+ }
+
+ if i < len(lines)-1 {
+ b.WriteRune('\n')
+ }
+ }
+
+ return b.String()
+}
+
+// PlaceVertical places a string or text block vertically in an unstyled block
+// of a given height. If the given height is shorter than the height of the
+// string (measured by its newlines) then this will be a noop.
+func PlaceVertical(height int, pos Position, str string, opts ...WhitespaceOption) string {
+ contentHeight := strings.Count(str, "\n") + 1
+ gap := height - contentHeight
+
+ if gap <= 0 {
+ return str
+ }
+
+ ws := newWhitespace(opts...)
+
+ _, width := getLines(str)
+ emptyLine := ws.render(width)
+ b := strings.Builder{}
+
+ switch pos {
+ case Top:
+ b.WriteString(str)
+ b.WriteRune('\n')
+ for i := range gap {
+ b.WriteString(emptyLine)
+ if i < gap-1 {
+ b.WriteRune('\n')
+ }
+ }
+
+ case Bottom:
+ b.WriteString(strings.Repeat(emptyLine+"\n", gap))
+ b.WriteString(str)
+
+ default: // Somewhere in the middle
+ split := int(math.Round(float64(gap) * pos.value()))
+ top := gap - split
+ bottom := gap - top
+
+ b.WriteString(strings.Repeat(emptyLine+"\n", top))
+ b.WriteString(str)
+
+ for range bottom {
+ b.WriteRune('\n')
+ b.WriteString(emptyLine)
+ }
+ }
+
+ return b.String()
+}
diff --git a/vendor/charm.land/lipgloss/v2/query.go b/vendor/charm.land/lipgloss/v2/query.go
new file mode 100644
index 000000000..96cd5b945
--- /dev/null
+++ b/vendor/charm.land/lipgloss/v2/query.go
@@ -0,0 +1,92 @@
+package lipgloss
+
+import (
+ "fmt"
+ "image/color"
+ "os"
+ "runtime"
+
+ "github.com/charmbracelet/x/term"
+)
+
+func backgroundColor(in term.File, out term.File) (color.Color, error) {
+ state, err := term.MakeRaw(in.Fd())
+ if err != nil {
+ return nil, fmt.Errorf("error setting raw state to detect background color: %w", err)
+ }
+
+ defer term.Restore(in.Fd(), state) //nolint:errcheck
+
+ bg, err := queryBackgroundColor(in, out)
+ if err != nil {
+ return nil, err
+ }
+
+ return bg, nil
+}
+
+// BackgroundColor queries the terminal's background color. Typically, you'll
+// want to query against stdin and either stdout or stderr, depending on what
+// you're writing to.
+//
+// This function is intended for standalone Lip Gloss use only. If you're using
+// Bubble Tea, listen for tea.BackgroundColorMsg in your update function.
+func BackgroundColor(in term.File, out term.File) (bg color.Color, err error) {
+ if runtime.GOOS == "windows" { //nolint:nestif
+ // On Windows, when the input/output is redirected or piped, we need to
+ // open the console explicitly.
+ // See https://learn.microsoft.com/en-us/windows/console/getstdhandle#remarks
+ if !term.IsTerminal(in.Fd()) {
+ f, err := os.OpenFile("CONIN$", os.O_RDWR, 0o644) //nolint:gosec
+ if err != nil {
+ return nil, fmt.Errorf("error opening CONIN$: %w", err)
+ }
+ in = f
+ }
+ if !term.IsTerminal(out.Fd()) {
+ f, err := os.OpenFile("CONOUT$", os.O_RDWR, 0o644) //nolint:gosec
+ if err != nil {
+ return nil, fmt.Errorf("error opening CONOUT$: %w", err)
+ }
+ out = f
+ }
+ return backgroundColor(in, out)
+ }
+
+ // NOTE: On Unix, one of the given files must be a tty.
+ if !term.IsTerminal(in.Fd()) || !term.IsTerminal(out.Fd()) {
+ return nil, fmt.Errorf("input/output is not a terminal")
+ }
+ for _, f := range []term.File{in, out} {
+ if bg, err = backgroundColor(f, f); err == nil {
+ return bg, nil
+ }
+ }
+
+ return bg, err
+}
+
+// HasDarkBackground detects whether the terminal has a light or dark
+// background.
+//
+// Typically, you'll want to query against stdin and either stdout or stderr
+// depending on what you're writing to.
+//
+// hasDarkBG := HasDarkBackground(os.Stdin, os.Stdout)
+// lightDark := LightDark(hasDarkBG)
+// myHotColor := lightDark("#ff0000", "#0000ff")
+//
+// This is intended for use in standalone Lip Gloss only. In Bubble Tea, listen
+// for tea.BackgroundColorMsg in your Update function.
+//
+// case tea.BackgroundColorMsg:
+// hasDarkBackground = msg.IsDark()
+//
+// By default, this function will return true if it encounters an error.
+func HasDarkBackground(in term.File, out term.File) bool {
+ bg, err := BackgroundColor(in, out)
+ if err != nil || bg == nil {
+ return true
+ }
+ return isDarkColor(bg)
+}
diff --git a/vendor/github.com/charmbracelet/lipgloss/ranges.go b/vendor/charm.land/lipgloss/v2/ranges.go
similarity index 75%
rename from vendor/github.com/charmbracelet/lipgloss/ranges.go
rename to vendor/charm.land/lipgloss/v2/ranges.go
index d17169987..bb209f0ea 100644
--- a/vendor/github.com/charmbracelet/lipgloss/ranges.go
+++ b/vendor/charm.land/lipgloss/v2/ranges.go
@@ -6,9 +6,8 @@ import (
"github.com/charmbracelet/x/ansi"
)
-// StyleRanges allows to, given a string, style ranges of it differently.
-// The function will take into account existing styles.
-// Ranges should not overlap.
+// StyleRanges applying styling to ranges in a string. Existing styles will be
+// taken into account. Ranges should not overlap.
func StyleRanges(s string, ranges ...Range) string {
if len(ranges) == 0 {
return s
@@ -36,12 +35,13 @@ func StyleRanges(s string, ranges ...Range) string {
return buf.String()
}
-// NewRange returns a range that can be used with [StyleRanges].
+// NewRange returns a range and style that can be used with [StyleRanges].
func NewRange(start, end int, style Style) Range {
return Range{start, end, style}
}
-// Range to be used with [StyleRanges].
+// Range is a range of text and associated styling to be used with
+// [StyleRanges].
type Range struct {
Start, End int
Style Style
diff --git a/vendor/github.com/charmbracelet/lipgloss/runes.go b/vendor/charm.land/lipgloss/v2/runes.go
similarity index 100%
rename from vendor/github.com/charmbracelet/lipgloss/runes.go
rename to vendor/charm.land/lipgloss/v2/runes.go
diff --git a/vendor/github.com/charmbracelet/lipgloss/set.go b/vendor/charm.land/lipgloss/v2/set.go
similarity index 78%
rename from vendor/github.com/charmbracelet/lipgloss/set.go
rename to vendor/charm.land/lipgloss/v2/set.go
index fde38faec..f10b4538a 100644
--- a/vendor/github.com/charmbracelet/lipgloss/set.go
+++ b/vendor/charm.land/lipgloss/v2/set.go
@@ -1,16 +1,25 @@
package lipgloss
+import (
+ "image/color"
+ "strings"
+)
+
// Set a value on the underlying rules map.
-func (s *Style) set(key propKey, value interface{}) {
+func (s *Style) set(key propKey, value any) {
// We don't allow negative integers on any of our other values, so just keep
// them at zero or above. We could use uints instead, but the
// conversions are a little tedious, so we're sticking with ints for
// sake of usability.
- switch key { //nolint:exhaustive
+ switch key {
case foregroundKey:
s.fgColor = colorOrNil(value)
case backgroundKey:
s.bgColor = colorOrNil(value)
+ case underlineColorKey:
+ s.ulColor = colorOrNil(value)
+ case underlineKey:
+ s.ul = value.(Underline)
case widthKey:
s.width = max(0, value.(int))
case heightKey:
@@ -27,6 +36,8 @@ func (s *Style) set(key propKey, value interface{}) {
s.paddingBottom = max(0, value.(int))
case paddingLeftKey:
s.paddingLeft = max(0, value.(int))
+ case paddingCharKey:
+ s.paddingChar = value.(rune)
case marginTopKey:
s.marginTop = max(0, value.(int))
case marginRightKey:
@@ -37,6 +48,8 @@ func (s *Style) set(key propKey, value interface{}) {
s.marginLeft = max(0, value.(int))
case marginBackgroundKey:
s.marginBgColor = colorOrNil(value)
+ case marginCharKey:
+ s.marginChar = value.(rune)
case borderStyleKey:
s.borderStyle = value.(Border)
case borderTopForegroundKey:
@@ -47,6 +60,10 @@ func (s *Style) set(key propKey, value interface{}) {
s.borderBottomFgColor = colorOrNil(value)
case borderLeftForegroundKey:
s.borderLeftFgColor = colorOrNil(value)
+ case borderForegroundBlendKey:
+ s.borderBlendFgColor = value.([]color.Color)
+ case borderForegroundBlendOffsetKey:
+ s.borderForegroundBlendOffset = value.(int)
case borderTopBackgroundKey:
s.borderTopBgColor = colorOrNil(value)
case borderRightBackgroundKey:
@@ -65,6 +82,10 @@ func (s *Style) set(key propKey, value interface{}) {
s.tabWidth = value.(int)
case transformKey:
s.transform = value.(func(string) string)
+ case linkKey:
+ s.link = value.(string)
+ case linkParamsKey:
+ s.linkParams = value.(string)
default:
if v, ok := value.(bool); ok { //nolint:nestif
if v {
@@ -88,11 +109,15 @@ func (s *Style) set(key propKey, value interface{}) {
// setFrom sets the property from another style.
func (s *Style) setFrom(key propKey, i Style) {
- switch key { //nolint:exhaustive
+ switch key {
case foregroundKey:
s.set(foregroundKey, i.fgColor)
case backgroundKey:
s.set(backgroundKey, i.bgColor)
+ case underlineColorKey:
+ s.set(underlineColorKey, i.ulColor)
+ case underlineKey:
+ s.set(underlineKey, i.ul)
case widthKey:
s.set(widthKey, i.width)
case heightKey:
@@ -109,6 +134,8 @@ func (s *Style) setFrom(key propKey, i Style) {
s.set(paddingBottomKey, i.paddingBottom)
case paddingLeftKey:
s.set(paddingLeftKey, i.paddingLeft)
+ case paddingCharKey:
+ s.set(paddingCharKey, i.paddingChar)
case marginTopKey:
s.set(marginTopKey, i.marginTop)
case marginRightKey:
@@ -119,6 +146,8 @@ func (s *Style) setFrom(key propKey, i Style) {
s.set(marginLeftKey, i.marginLeft)
case marginBackgroundKey:
s.set(marginBackgroundKey, i.marginBgColor)
+ case marginCharKey:
+ s.set(marginCharKey, i.marginChar)
case borderStyleKey:
s.set(borderStyleKey, i.borderStyle)
case borderTopForegroundKey:
@@ -129,6 +158,10 @@ func (s *Style) setFrom(key propKey, i Style) {
s.set(borderBottomForegroundKey, i.borderBottomFgColor)
case borderLeftForegroundKey:
s.set(borderLeftForegroundKey, i.borderLeftFgColor)
+ case borderForegroundBlendKey:
+ s.set(borderForegroundBlendKey, i.borderBlendFgColor)
+ case borderForegroundBlendOffsetKey:
+ s.set(borderForegroundBlendOffsetKey, i.borderForegroundBlendOffset)
case borderTopBackgroundKey:
s.set(borderTopBackgroundKey, i.borderTopBgColor)
case borderRightBackgroundKey:
@@ -151,8 +184,8 @@ func (s *Style) setFrom(key propKey, i Style) {
}
}
-func colorOrNil(c interface{}) TerminalColor {
- if c, ok := c.(TerminalColor); ok {
+func colorOrNil(c any) color.Color {
+ if c, ok := c.(color.Color); ok {
return c
}
return nil
@@ -173,9 +206,33 @@ func (s Style) Italic(v bool) Style {
// Underline sets an underline rule. By default, underlines will not be drawn on
// whitespace like margins and padding. To change this behavior set
-// UnderlineSpaces.
+// [Style.UnderlineSpaces].
func (s Style) Underline(v bool) Style {
- s.set(underlineKey, v)
+ if v {
+ return s.UnderlineStyle(UnderlineSingle)
+ }
+ return s.UnderlineStyle(UnderlineNone)
+}
+
+// UnderlineStyle sets the underline style. This can be used to set the underline
+// to be a single, double, curly, dotted, or dashed line.
+//
+// Note that not all terminal emulators support underline styles. If a style is
+// not supported, it will typically fall back to a single underline but this is
+// not guaranteed. This depends on the terminal emulator being used.
+func (s Style) UnderlineStyle(u Underline) Style {
+ s.set(underlineKey, u)
+ return s
+}
+
+// UnderlineColor sets the color of the underline. By default, the underline
+// will be the same color as the foreground.
+//
+// Note that not all terminal emulators support colored underlines. If color is
+// not supported, it might produce unexpected results. This depends on the
+// terminal emulator being used.
+func (s Style) UnderlineColor(c color.Color) Style {
+ s.set(underlineColorKey, c)
return s
}
@@ -212,19 +269,20 @@ func (s Style) Faint(v bool) Style {
//
// // Removes the foreground color
// s.Foreground(lipgloss.NoColor)
-func (s Style) Foreground(c TerminalColor) Style {
+func (s Style) Foreground(c color.Color) Style {
s.set(foregroundKey, c)
return s
}
// Background sets a background color.
-func (s Style) Background(c TerminalColor) Style {
+func (s Style) Background(c color.Color) Style {
s.set(backgroundKey, c)
return s
}
-// Width sets the width of the block before applying margins. The width, if
-// set, also determines where text will wrap.
+// Width sets the width of the block before applying margins. This means your
+// styled content will exactly equal the size set here. Text will wrap based on
+// Padding and Borders set on the style.
func (s Style) Width(i int) Style {
s.set(widthKey, i)
return s
@@ -317,6 +375,18 @@ func (s Style) PaddingBottom(i int) Style {
return s
}
+// PaddingChar sets the character used for padding. This is useful for
+// rendering blocks with a specific character, such as a space or a dot.
+// Example of using [NBSP] as padding to prevent line breaks:
+//
+// ```go
+// s := lipgloss.NewStyle().PaddingChar(lipgloss.NBSP)
+// ```
+func (s Style) PaddingChar(r rune) Style {
+ s.set(paddingCharKey, r)
+ return s
+}
+
// ColorWhitespace determines whether or not the background color should be
// applied to the padding. This is true by default as it's more than likely the
// desired and expected behavior, but it can be disabled for certain graphic
@@ -382,11 +452,18 @@ func (s Style) MarginBottom(i int) Style {
// MarginBackground sets the background color of the margin. Note that this is
// also set when inheriting from a style with a background color. In that case
// the background color on that style will set the margin color on this style.
-func (s Style) MarginBackground(c TerminalColor) Style {
+func (s Style) MarginBackground(c color.Color) Style {
s.set(marginBackgroundKey, c)
return s
}
+// MarginChar sets the character used for the margin. This is useful for
+// rendering blocks with a specific character, such as a space or a dot.
+func (s Style) MarginChar(r rune) Style {
+ s.set(marginCharKey, r)
+ return s
+}
+
// Border is shorthand for setting the border style and which sides should
// have a border at once. The variadic argument sides works as follows:
//
@@ -487,7 +564,7 @@ func (s Style) BorderLeft(v bool) Style {
// top side, followed by the right side, then the bottom, and finally the left.
//
// With more than four arguments nothing will be set.
-func (s Style) BorderForeground(c ...TerminalColor) Style {
+func (s Style) BorderForeground(c ...color.Color) Style {
if len(c) == 0 {
return s
}
@@ -506,32 +583,80 @@ func (s Style) BorderForeground(c ...TerminalColor) Style {
}
// BorderTopForeground set the foreground color for the top of the border.
-func (s Style) BorderTopForeground(c TerminalColor) Style {
+func (s Style) BorderTopForeground(c color.Color) Style {
s.set(borderTopForegroundKey, c)
return s
}
// BorderRightForeground sets the foreground color for the right side of the
// border.
-func (s Style) BorderRightForeground(c TerminalColor) Style {
+func (s Style) BorderRightForeground(c color.Color) Style {
s.set(borderRightForegroundKey, c)
return s
}
// BorderBottomForeground sets the foreground color for the bottom of the
// border.
-func (s Style) BorderBottomForeground(c TerminalColor) Style {
+func (s Style) BorderBottomForeground(c color.Color) Style {
s.set(borderBottomForegroundKey, c)
return s
}
// BorderLeftForeground sets the foreground color for the left side of the
// border.
-func (s Style) BorderLeftForeground(c TerminalColor) Style {
+func (s Style) BorderLeftForeground(c color.Color) Style {
s.set(borderLeftForegroundKey, c)
return s
}
+// BorderForegroundBlend sets the foreground colors for the border blend. At least
+// 2 colors are required to use blending, otherwise this will no-op with 0 colors,
+// and pass to BorderForeground with 1 color. This will override all other border
+// foreground colors when used.
+//
+// When providing colors, in most cases (e.g. when all border sides are enabled),
+// you will want to provide a wrapping-set of colors, so the start and end color
+// are either the same, or very similar. For example:
+//
+// lipgloss.NewStyle().BorderForegroundBlend(
+// lipgloss.Color("#00FA68"),
+// lipgloss.Color("#9900FF"),
+// lipgloss.Color("#ED5353"),
+// lipgloss.Color("#9900FF"),
+// lipgloss.Color("#00FA68"),
+// )
+func (s Style) BorderForegroundBlend(c ...color.Color) Style {
+ if len(c) == 0 {
+ return s
+ }
+
+ // Insufficient colors to use blending, pass to BorderForeground.
+ if len(c) == 1 {
+ return s.BorderForeground(c...)
+ }
+
+ s.set(borderForegroundBlendKey, c)
+ return s
+}
+
+// BorderForegroundBlendOffset sets the border blend offset cells, starting from
+// the top left corner. Value can be positive or negative, and does not need to
+// equal the dimensions of the border region. Direction (when positive) is as
+// follows ("o" is starting point):
+//
+// o -------->
+// ┌──────────┐
+// ^ │ │ |
+// | │ │ |
+// | │ │ |
+// | │ │ v
+// └──────────┘
+// <---------
+func (s Style) BorderForegroundBlendOffset(v int) Style {
+ s.set(borderForegroundBlendOffsetKey, v)
+ return s
+}
+
// BorderBackground is a shorthand function for setting all of the
// background colors of the borders at once. The arguments work as follows:
//
@@ -547,7 +672,7 @@ func (s Style) BorderLeftForeground(c TerminalColor) Style {
// top side, followed by the right side, then the bottom, and finally the left.
//
// With more than four arguments nothing will be set.
-func (s Style) BorderBackground(c ...TerminalColor) Style {
+func (s Style) BorderBackground(c ...color.Color) Style {
if len(c) == 0 {
return s
}
@@ -566,27 +691,27 @@ func (s Style) BorderBackground(c ...TerminalColor) Style {
}
// BorderTopBackground sets the background color of the top of the border.
-func (s Style) BorderTopBackground(c TerminalColor) Style {
+func (s Style) BorderTopBackground(c color.Color) Style {
s.set(borderTopBackgroundKey, c)
return s
}
// BorderRightBackground sets the background color of right side the border.
-func (s Style) BorderRightBackground(c TerminalColor) Style {
+func (s Style) BorderRightBackground(c color.Color) Style {
s.set(borderRightBackgroundKey, c)
return s
}
// BorderBottomBackground sets the background color of the bottom of the
// border.
-func (s Style) BorderBottomBackground(c TerminalColor) Style {
+func (s Style) BorderBottomBackground(c color.Color) Style {
s.set(borderBottomBackgroundKey, c)
return s
}
// BorderLeftBackground set the background color of the left side of the
// border.
-func (s Style) BorderLeftBackground(c TerminalColor) Style {
+func (s Style) BorderLeftBackground(c color.Color) Style {
s.set(borderLeftBackgroundKey, c)
return s
}
@@ -685,10 +810,18 @@ func (s Style) Transform(fn func(string) string) Style {
return s
}
-// Renderer sets the renderer for the style. This is useful for changing the
-// renderer for a style that is being used in a different context.
-func (s Style) Renderer(r *Renderer) Style {
- s.r = r
+// Hyperlink sets a hyperlink on a style. This is useful for rendering text that
+// can be clicked on in a terminal emulator that supports hyperlinks.
+//
+// Example:
+//
+// s := lipgloss.NewStyle().Hyperlink("https://charm.sh")
+// s := lipgloss.NewStyle().Hyperlink("https://charm.sh", "id=1")
+func (s Style) Hyperlink(link string, params ...string) Style {
+ s.set(linkKey, link)
+ if len(params) > 0 {
+ s.set(linkParamsKey, strings.Join(params, ":"))
+ }
return s
}
@@ -768,7 +901,7 @@ func whichSidesBool(i ...bool) (top, right, bottom, left bool, ok bool) {
// whichSidesColor is like whichSides, except it operates on a series of
// boolean values. See the comment on whichSidesInt for details on how this
// works.
-func whichSidesColor(i ...TerminalColor) (top, right, bottom, left TerminalColor, ok bool) {
+func whichSidesColor(i ...color.Color) (top, right, bottom, left color.Color, ok bool) {
switch len(i) {
case 1:
top = i[0]
diff --git a/vendor/github.com/charmbracelet/lipgloss/size.go b/vendor/charm.land/lipgloss/v2/size.go
similarity index 75%
rename from vendor/github.com/charmbracelet/lipgloss/size.go
rename to vendor/charm.land/lipgloss/v2/size.go
index e169ff5e2..e0384d035 100644
--- a/vendor/github.com/charmbracelet/lipgloss/size.go
+++ b/vendor/charm.land/lipgloss/v2/size.go
@@ -10,10 +10,10 @@ import (
// ignored and characters wider than one cell (such as Chinese characters and
// emojis) are appropriately measured.
//
-// You should use this instead of len(string) len([]rune(string) as neither
+// You should use this instead of len(string) or len([]rune(string) as neither
// will give you accurate results.
func Width(str string) (width int) {
- for _, l := range strings.Split(str, "\n") {
+ for l := range strings.SplitSeq(str, "\n") {
w := ansi.StringWidth(l)
if w > width {
width = w
@@ -24,9 +24,8 @@ func Width(str string) (width int) {
}
// Height returns height of a string in cells. This is done simply by
-// counting \n characters. If your strings use \r\n for newlines you should
-// convert them to \n first, or simply write a separate function for measuring
-// height.
+// counting \n characters. If your output has \r\n, that sequence will be
+// replaced with a \n in [Style.Render].
func Height(str string) int {
return strings.Count(str, "\n") + 1
}
diff --git a/vendor/charm.land/lipgloss/v2/style.go b/vendor/charm.land/lipgloss/v2/style.go
new file mode 100644
index 000000000..3cd659526
--- /dev/null
+++ b/vendor/charm.land/lipgloss/v2/style.go
@@ -0,0 +1,637 @@
+package lipgloss
+
+import (
+ "image/color"
+ "strings"
+ "unicode"
+
+ "github.com/charmbracelet/x/ansi"
+)
+
+const (
+ // NBSP is the non-breaking space rune.
+ NBSP = '\u00A0'
+ tabWidthDefault = 4
+)
+
+// Property for a key.
+type propKey int64
+
+// Available properties.
+const (
+ // Boolean props come first.
+ boldKey propKey = 1 << iota
+ italicKey
+ strikethroughKey
+ reverseKey
+ blinkKey
+ faintKey
+ underlineSpacesKey
+ strikethroughSpacesKey
+ colorWhitespaceKey
+
+ // Non-boolean props.
+ underlineKey
+ foregroundKey
+ backgroundKey
+ underlineColorKey
+ widthKey
+ heightKey
+ alignHorizontalKey
+ alignVerticalKey
+
+ // Padding.
+ paddingTopKey
+ paddingRightKey
+ paddingBottomKey
+ paddingLeftKey
+ paddingCharKey
+
+ // Margins.
+ marginTopKey
+ marginRightKey
+ marginBottomKey
+ marginLeftKey
+ marginBackgroundKey
+ marginCharKey
+
+ // Border runes.
+ borderStyleKey
+
+ // Border edges.
+ borderTopKey
+ borderRightKey
+ borderBottomKey
+ borderLeftKey
+
+ // Border foreground colors.
+ borderTopForegroundKey
+ borderRightForegroundKey
+ borderBottomForegroundKey
+ borderLeftForegroundKey
+ borderForegroundBlendKey
+ borderForegroundBlendOffsetKey
+
+ // Border background colors.
+ borderTopBackgroundKey
+ borderRightBackgroundKey
+ borderBottomBackgroundKey
+ borderLeftBackgroundKey
+
+ inlineKey
+ maxWidthKey
+ maxHeightKey
+ tabWidthKey
+
+ transformKey
+
+ // Hyperlink.
+ linkKey
+ linkParamsKey
+)
+
+// props is a set of properties.
+type props int64
+
+// set sets a property.
+func (p props) set(k propKey) props {
+ return p | props(k)
+}
+
+// unset unsets a property.
+func (p props) unset(k propKey) props {
+ return p &^ props(k)
+}
+
+// has checks if a property is set.
+func (p props) has(k propKey) bool {
+ return p&props(k) != 0
+}
+
+// Underline is the style of the underline.
+//
+// Caveats:
+// - Not all terminals support all underline styles.
+// - Some terminals may render unsupported styles as standard underlines.
+// - Terminal themes may affect the visibility of different underline styles.
+type Underline = ansi.Underline
+
+const (
+ // UnderlineNone is no underline.
+ UnderlineNone = ansi.UnderlineNone
+ // UnderlineSingle is a single underline. This is the default when underline is enabled.
+ UnderlineSingle = ansi.UnderlineSingle
+ // UnderlineDouble is a double underline.
+ UnderlineDouble = ansi.UnderlineDouble
+ // UnderlineCurly is a curly underline.
+ UnderlineCurly = ansi.UnderlineCurly
+ // UnderlineDotted is a dotted underline.
+ UnderlineDotted = ansi.UnderlineDotted
+ // UnderlineDashed is a dashed underline.
+ UnderlineDashed = ansi.UnderlineDashed
+)
+
+// NewStyle returns a new, empty Style. While it's syntactic sugar for the
+// [Style]{} primitive, it's recommended to use this function for creating styles
+// in case the underlying implementation changes.
+func NewStyle() Style {
+ return Style{}
+}
+
+// Style contains a set of rules that comprise a style as a whole.
+type Style struct {
+ props props
+ value string
+
+ // hyperlink
+ link, linkParams string
+
+ // we store bool props values here
+ attrs int
+
+ // props that have values
+ fgColor color.Color
+ bgColor color.Color
+ ulColor color.Color
+
+ ul Underline
+
+ width int
+ height int
+
+ alignHorizontal Position
+ alignVertical Position
+
+ paddingTop int
+ paddingRight int
+ paddingBottom int
+ paddingLeft int
+ paddingChar rune
+
+ marginTop int
+ marginRight int
+ marginBottom int
+ marginLeft int
+ marginBgColor color.Color
+ marginChar rune
+
+ borderStyle Border
+ borderTopFgColor color.Color
+ borderRightFgColor color.Color
+ borderBottomFgColor color.Color
+ borderLeftFgColor color.Color
+ borderBlendFgColor []color.Color
+ borderForegroundBlendOffset int
+ borderTopBgColor color.Color
+ borderRightBgColor color.Color
+ borderBottomBgColor color.Color
+ borderLeftBgColor color.Color
+
+ maxWidth int
+ maxHeight int
+ tabWidth int
+
+ transform func(string) string
+}
+
+// joinString joins a list of strings into a single string separated with a
+// space.
+func joinString(strs ...string) string {
+ return strings.Join(strs, " ")
+}
+
+// SetString sets the underlying string value for this style. To render once
+// the underlying string is set, use the [Style.String]. This method is
+// a convenience for cases when having a stringer implementation is handy, such
+// as when using fmt.Sprintf. You can also simply define a style and render out
+// strings directly with [Style.Render].
+func (s Style) SetString(strs ...string) Style {
+ s.value = joinString(strs...)
+ return s
+}
+
+// Value returns the raw, unformatted, underlying string value for this style.
+func (s Style) Value() string {
+ return s.value
+}
+
+// String implements stringer for a Style, returning the rendered result based
+// on the rules in this style. An underlying string value must be set with
+// Style.SetString prior to using this method.
+func (s Style) String() string {
+ return s.Render()
+}
+
+// Copy returns a copy of this style, including any underlying string values.
+//
+// Deprecated: to copy just use assignment (i.e. a := b). All methods also
+// return a new style.
+func (s Style) Copy() Style {
+ return s
+}
+
+// Inherit overlays the style in the argument onto this style by copying each explicitly
+// set value from the argument style onto this style if it is not already explicitly set.
+// Existing set values are kept intact and not overwritten.
+//
+// Margins, padding, and underlying string values are not inherited.
+func (s Style) Inherit(i Style) Style {
+ for k := boldKey; k <= transformKey; k <<= 1 {
+ if !i.isSet(k) {
+ continue
+ }
+
+ switch k { //nolint:exhaustive
+ case marginTopKey, marginRightKey, marginBottomKey, marginLeftKey:
+ // Margins are not inherited
+ continue
+ case paddingTopKey, paddingRightKey, paddingBottomKey, paddingLeftKey:
+ // Padding is not inherited
+ continue
+ case backgroundKey:
+ // The margins also inherit the background color
+ if !s.isSet(marginBackgroundKey) && !i.isSet(marginBackgroundKey) {
+ s.set(marginBackgroundKey, i.bgColor)
+ }
+ }
+
+ if s.isSet(k) {
+ continue
+ }
+
+ s.setFrom(k, i)
+ }
+ return s
+}
+
+// Render applies the defined style formatting to a given string.
+func (s Style) Render(strs ...string) string {
+ if s.value != "" {
+ strs = append([]string{s.value}, strs...)
+ }
+
+ var (
+ str = joinString(strs...)
+
+ te ansi.Style
+ teSpace ansi.Style
+ teWhitespace ansi.Style
+
+ bold = s.getAsBool(boldKey, false)
+ italic = s.getAsBool(italicKey, false)
+ strikethrough = s.getAsBool(strikethroughKey, false)
+ reverse = s.getAsBool(reverseKey, false)
+ blink = s.getAsBool(blinkKey, false)
+ faint = s.getAsBool(faintKey, false)
+
+ fg = s.getAsColor(foregroundKey)
+ bg = s.getAsColor(backgroundKey)
+ ul = s.getAsColor(underlineColorKey)
+
+ underline = s.ul != UnderlineNone
+ width = s.getAsInt(widthKey)
+ height = s.getAsInt(heightKey)
+ horizontalAlign = s.getAsPosition(alignHorizontalKey)
+ verticalAlign = s.getAsPosition(alignVerticalKey)
+
+ topPadding = s.getAsInt(paddingTopKey)
+ rightPadding = s.getAsInt(paddingRightKey)
+ bottomPadding = s.getAsInt(paddingBottomKey)
+ leftPadding = s.getAsInt(paddingLeftKey)
+
+ horizontalBorderSize = s.GetHorizontalBorderSize()
+ verticalBorderSize = s.GetVerticalBorderSize()
+
+ colorWhitespace = s.getAsBool(colorWhitespaceKey, true)
+ inline = s.getAsBool(inlineKey, false)
+ maxWidth = s.getAsInt(maxWidthKey)
+ maxHeight = s.getAsInt(maxHeightKey)
+
+ underlineSpaces = s.getAsBool(underlineSpacesKey, false) || (underline && s.getAsBool(underlineSpacesKey, true))
+ strikethroughSpaces = s.getAsBool(strikethroughSpacesKey, false) || (strikethrough && s.getAsBool(strikethroughSpacesKey, true))
+
+ // Do we need to style whitespace (padding and space outside
+ // paragraphs) separately?
+ styleWhitespace = reverse
+
+ // Do we need to style spaces separately?
+ useSpaceStyler = (underline && !underlineSpaces) || (strikethrough && !strikethroughSpaces) || underlineSpaces || strikethroughSpaces
+
+ transform = s.getAsTransform(transformKey)
+
+ link, linkParams = s.GetHyperlink()
+ )
+
+ if transform != nil {
+ str = transform(str)
+ }
+
+ if s.props == 0 {
+ return s.maybeConvertTabs(str)
+ }
+
+ if bold {
+ te = te.Bold()
+ }
+ if italic {
+ te = te.Italic(true)
+ }
+ if underline {
+ te = te.Underline(true)
+ }
+ if reverse {
+ teWhitespace = teWhitespace.Reverse(true)
+ te = te.Reverse(true)
+ }
+ if blink {
+ te = te.Blink(true)
+ }
+ if faint {
+ te = te.Faint()
+ }
+
+ if fg != noColor {
+ te = te.ForegroundColor(fg)
+ if styleWhitespace {
+ teWhitespace = teWhitespace.ForegroundColor(fg)
+ }
+ if useSpaceStyler {
+ teSpace = teSpace.ForegroundColor(fg)
+ }
+ }
+
+ if bg != noColor {
+ te = te.BackgroundColor(bg)
+ if colorWhitespace {
+ teWhitespace = teWhitespace.BackgroundColor(bg)
+ }
+ if useSpaceStyler {
+ teSpace = teSpace.BackgroundColor(bg)
+ }
+ }
+
+ if ul != noColor {
+ te = te.UnderlineColor(ul)
+ if colorWhitespace {
+ teWhitespace = teWhitespace.UnderlineColor(ul)
+ }
+ if useSpaceStyler {
+ teSpace = teSpace.UnderlineColor(ul)
+ }
+ }
+
+ if underline {
+ te = te.UnderlineStyle(s.ul)
+ }
+ if strikethrough {
+ te = te.Strikethrough(true)
+ }
+
+ if underlineSpaces {
+ teSpace = teSpace.Underline(true)
+ }
+ if strikethroughSpaces {
+ teSpace = teSpace.Strikethrough(true)
+ }
+
+ // Potentially convert tabs to spaces
+ str = s.maybeConvertTabs(str)
+ // carriage returns can cause strange behaviour when rendering.
+ str = strings.ReplaceAll(str, "\r\n", "\n")
+
+ // Strip newlines in single line mode
+ if inline {
+ str = strings.ReplaceAll(str, "\n", "")
+ }
+
+ // Include borders in block size.
+ width -= horizontalBorderSize
+ height -= verticalBorderSize
+
+ // Word wrap
+ if !inline && width > 0 {
+ wrapAt := width - leftPadding - rightPadding
+ str = Wrap(str, wrapAt, "")
+ }
+
+ // Render core text
+ {
+ var b strings.Builder
+
+ isFirst := true
+ for line := range strings.SplitSeq(str, "\n") {
+ if isFirst {
+ isFirst = false
+ } else {
+ b.WriteRune('\n')
+ }
+ if useSpaceStyler {
+ // Look for spaces and apply a different styler
+ for _, r := range line {
+ if unicode.IsSpace(r) {
+ b.WriteString(teSpace.Styled(string(r)))
+ continue
+ }
+ b.WriteString(te.Styled(string(r)))
+ }
+ } else {
+ b.WriteString(te.Styled(line))
+ }
+ }
+
+ str = b.String()
+
+ if len(link) > 0 {
+ str = ansi.SetHyperlink(link, linkParams) + str + ansi.ResetHyperlink()
+ }
+ }
+
+ // Padding
+ if !inline { //nolint:nestif
+ padChar := s.paddingChar
+ if padChar == 0 {
+ padChar = ' '
+ }
+ if leftPadding > 0 {
+ var st *ansi.Style
+ if colorWhitespace || styleWhitespace {
+ st = &teWhitespace
+ }
+ str = padLeft(str, leftPadding, st, padChar)
+ }
+
+ if rightPadding > 0 {
+ var st *ansi.Style
+ if colorWhitespace || styleWhitespace {
+ st = &teWhitespace
+ }
+ str = padRight(str, rightPadding, st, padChar)
+ }
+
+ if topPadding > 0 {
+ str = strings.Repeat("\n", topPadding) + str
+ }
+
+ if bottomPadding > 0 {
+ str += strings.Repeat("\n", bottomPadding)
+ }
+ }
+
+ // Height
+ if height > 0 {
+ str = alignTextVertical(str, verticalAlign, height, nil)
+ }
+
+ // Set alignment. This will also pad short lines with spaces so that all
+ // lines are the same length, so we run it under a few different conditions
+ // beyond alignment.
+ {
+ numLines := strings.Count(str, "\n")
+
+ if numLines != 0 || width != 0 {
+ var st *ansi.Style
+ if colorWhitespace || styleWhitespace {
+ st = &teWhitespace
+ }
+ str = alignTextHorizontal(str, horizontalAlign, width, st)
+ }
+ }
+
+ if !inline {
+ str = s.applyBorder(str)
+ str = s.applyMargins(str, inline)
+ }
+
+ // Truncate according to MaxWidth
+ if maxWidth > 0 {
+ lines := strings.Split(str, "\n")
+
+ for i := range lines {
+ lines[i] = ansi.Truncate(lines[i], maxWidth, "")
+ }
+
+ str = strings.Join(lines, "\n")
+ }
+
+ // Truncate according to MaxHeight
+ if maxHeight > 0 {
+ lines := strings.Split(str, "\n")
+ height := min(maxHeight, len(lines))
+ if len(lines) > 0 {
+ str = strings.Join(lines[:height], "\n")
+ }
+ }
+
+ return str
+}
+
+func (s Style) maybeConvertTabs(str string) string {
+ tw := tabWidthDefault
+ if s.isSet(tabWidthKey) {
+ tw = s.getAsInt(tabWidthKey)
+ }
+ switch tw {
+ case -1:
+ return str
+ case 0:
+ return strings.ReplaceAll(str, "\t", "")
+ default:
+ return strings.ReplaceAll(str, "\t", strings.Repeat(" ", tw))
+ }
+}
+
+func (s Style) applyMargins(str string, inline bool) string {
+ var (
+ topMargin = s.getAsInt(marginTopKey)
+ rightMargin = s.getAsInt(marginRightKey)
+ bottomMargin = s.getAsInt(marginBottomKey)
+ leftMargin = s.getAsInt(marginLeftKey)
+
+ style ansi.Style
+ )
+
+ bgc := s.getAsColor(marginBackgroundKey)
+ if bgc != noColor {
+ style = style.BackgroundColor(bgc)
+ }
+
+ // Add left and right margin
+ marginChar := s.marginChar
+ if marginChar == 0 {
+ marginChar = ' '
+ }
+ str = padLeft(str, leftMargin, &style, marginChar)
+ str = padRight(str, rightMargin, &style, marginChar)
+
+ // Top/bottom margin
+ if !inline {
+ _, width := getLines(str)
+ spaces := strings.Repeat(" ", width)
+
+ if topMargin > 0 {
+ str = style.Styled(strings.Repeat(spaces+"\n", topMargin)) + str
+ }
+ if bottomMargin > 0 {
+ str += style.Styled(strings.Repeat("\n"+spaces, bottomMargin))
+ }
+ }
+
+ return str
+}
+
+// Apply left padding.
+func padLeft(str string, n int, style *ansi.Style, r rune) string {
+ return pad(str, -n, style, r)
+}
+
+// Apply right padding.
+func padRight(str string, n int, style *ansi.Style, r rune) string {
+ return pad(str, n, style, r)
+}
+
+// pad adds padding to either the left or right side of a string.
+// Positive values add to the right side while negative values
+// add to the left side.
+// r is the rune to use for padding. We use " " for margins and
+// "\u00A0" for padding so that the padding is preserved when the
+// string is copied and pasted.
+func pad(str string, n int, style *ansi.Style, r rune) string {
+ if n == 0 {
+ return str
+ }
+
+ sp := strings.Repeat(string(r), abs(n))
+ if style != nil {
+ sp = style.Styled(sp)
+ }
+
+ b := strings.Builder{}
+ isFirst := true
+ for line := range strings.SplitSeq(str, "\n") {
+ if isFirst {
+ isFirst = false
+ } else {
+ b.WriteRune('\n')
+ }
+ switch {
+ // pad right
+ case n > 0:
+ b.WriteString(line)
+ b.WriteString(sp)
+ // pad left
+ default:
+ b.WriteString(sp)
+ b.WriteString(line)
+ }
+ }
+
+ return b.String()
+}
+
+func abs(a int) int {
+ if a < 0 {
+ return -a
+ }
+
+ return a
+}
diff --git a/vendor/charm.land/lipgloss/v2/terminal.go b/vendor/charm.land/lipgloss/v2/terminal.go
new file mode 100644
index 000000000..a336abc77
--- /dev/null
+++ b/vendor/charm.land/lipgloss/v2/terminal.go
@@ -0,0 +1,124 @@
+package lipgloss
+
+import (
+ "fmt"
+ "image/color"
+ "io"
+ "strings"
+ "time"
+
+ uv "github.com/charmbracelet/ultraviolet"
+ "github.com/charmbracelet/x/ansi"
+)
+
+// queryBackgroundColor queries the terminal for the background color.
+// If the terminal does not support querying the background color, nil is
+// returned.
+//
+// Note: you will need to set the input to raw mode before calling this
+// function.
+//
+// state, _ := term.MakeRaw(in.Fd())
+// defer term.Restore(in.Fd(), state)
+//
+// copied from x/term@v0.1.3.
+func queryBackgroundColor(in io.Reader, out io.Writer) (c color.Color, err error) {
+ err = queryTerminal(in, out, defaultQueryTimeout,
+ func(seq string, pa *ansi.Parser) bool {
+ switch {
+ case ansi.HasOscPrefix(seq):
+ switch pa.Command() {
+ case 11: // OSC 11
+ parts := strings.Split(string(pa.Data()), ";")
+ if len(parts) != 2 {
+ break // invalid, but we still need to parse the next sequence
+ }
+ c = ansi.XParseColor(parts[1])
+ }
+ case ansi.HasCsiPrefix(seq):
+ switch pa.Command() {
+ case ansi.Command('?', 0, 'c'): // DA1
+ return false
+ }
+ }
+ return true
+ }, ansi.RequestBackgroundColor+ansi.RequestPrimaryDeviceAttributes)
+ return
+}
+
+const defaultQueryTimeout = time.Second * 2
+
+// queryTerminalFilter is a function that filters input events using a type
+// switch. If false is returned, the QueryTerminal function will stop reading
+// input.
+type queryTerminalFilter func(seq string, pa *ansi.Parser) bool
+
+// queryTerminal queries the terminal for support of various features and
+// returns a list of response events.
+// Most of the time, you will need to set stdin to raw mode before calling this
+// function.
+// Note: This function will block until the terminal responds or the timeout
+// is reached.
+// copied from x/term@v0.1.3.
+func queryTerminal(
+ in io.Reader,
+ out io.Writer,
+ timeout time.Duration,
+ filter queryTerminalFilter,
+ query string,
+) error {
+ // We use [uv.NewCancelReader] because it uses a different Windows
+ // implementation than the on in the [cancelreader] library, which uses
+ // the Cancel IO API to cancel reads instead of using Overlapped IO.
+ rd, err := uv.NewCancelReader(in)
+ if err != nil {
+ return fmt.Errorf("could not create cancel reader: %w", err)
+ }
+
+ defer rd.Close() //nolint: errcheck
+
+ done := make(chan struct{}, 1)
+ defer close(done)
+ go func() {
+ select {
+ case <-done:
+ case <-time.After(timeout):
+ rd.Cancel()
+ }
+ }()
+
+ if _, err := io.WriteString(out, query); err != nil {
+ return fmt.Errorf("could not write query: %w", err)
+ }
+
+ pa := ansi.GetParser()
+ defer ansi.PutParser(pa)
+
+ var acc []byte // Accumulate partial responses before filtering
+ var buf [256]byte // 256 bytes should be enough for most responses
+ var state byte
+ for {
+ n, err := rd.Read(buf[:])
+ if err != nil {
+ return fmt.Errorf("could not read from input: %w", err)
+ }
+
+ p := buf[:]
+ for n > 0 {
+ seq, _, read, newState := ansi.DecodeSequence(p[:n], state, pa)
+ acc = append(acc, seq...)
+
+ if newState == ansi.NormalState {
+ if !filter(string(acc), pa) {
+ return nil
+ }
+
+ acc = acc[:0]
+ }
+
+ state = newState
+ n -= read
+ p = p[read:]
+ }
+ }
+}
diff --git a/vendor/github.com/charmbracelet/lipgloss/unset.go b/vendor/charm.land/lipgloss/v2/unset.go
similarity index 91%
rename from vendor/github.com/charmbracelet/lipgloss/unset.go
rename to vendor/charm.land/lipgloss/v2/unset.go
index 1086e7226..b81ee882a 100644
--- a/vendor/github.com/charmbracelet/lipgloss/unset.go
+++ b/vendor/charm.land/lipgloss/v2/unset.go
@@ -19,8 +19,7 @@ func (s Style) UnsetItalic() Style {
// UnsetUnderline removes the underline style rule, if set.
func (s Style) UnsetUnderline() Style {
- s.unset(underlineKey)
- return s
+ return s.Underline(false)
}
// UnsetStrikethrough removes the strikethrough style rule, if set.
@@ -96,6 +95,13 @@ func (s Style) UnsetPadding() Style {
s.unset(paddingRightKey)
s.unset(paddingTopKey)
s.unset(paddingBottomKey)
+ s.unset(paddingCharKey)
+ return s
+}
+
+// UnsetPaddingChar removes the padding character style rule, if set.
+func (s Style) UnsetPaddingChar() Style {
+ s.unset(paddingCharKey)
return s
}
@@ -237,6 +243,20 @@ func (s Style) UnsetBorderLeftForeground() Style {
return s
}
+// UnsetBorderForegroundBlend removes the border blend foreground color rules,
+// if set.
+func (s Style) UnsetBorderForegroundBlend() Style {
+ s.unset(borderForegroundBlendKey)
+ return s
+}
+
+// UnsetBorderForegroundBlendOffset removes the border blend offset style rule,
+// if set.
+func (s Style) UnsetBorderForegroundBlendOffset() Style {
+ s.unset(borderForegroundBlendOffsetKey)
+ return s
+}
+
// UnsetBorderBackground removes all border background color styles, if
// set.
func (s Style) UnsetBorderBackground() Style {
@@ -324,6 +344,14 @@ func (s Style) UnsetTransform() Style {
return s
}
+// UnsetHyperlink removes the value set by Hyperlink.
+func (s Style) UnsetHyperlink() Style {
+ s.unset(linkKey)
+ s.unset(linkParamsKey)
+ s.link, s.linkParams = "", "" // save memory
+ return s
+}
+
// UnsetString sets the underlying string value to the empty string.
func (s Style) UnsetString() Style {
s.value = ""
diff --git a/vendor/charm.land/lipgloss/v2/whitespace.go b/vendor/charm.land/lipgloss/v2/whitespace.go
new file mode 100644
index 000000000..e353a076b
--- /dev/null
+++ b/vendor/charm.land/lipgloss/v2/whitespace.go
@@ -0,0 +1,76 @@
+package lipgloss
+
+import (
+ "strings"
+
+ "github.com/charmbracelet/x/ansi"
+)
+
+// whitespace is a whitespace renderer.
+type whitespace struct {
+ chars string
+ style Style
+}
+
+// newWhitespace creates a new whitespace renderer.
+func newWhitespace(opts ...WhitespaceOption) *whitespace {
+ w := &whitespace{}
+ for _, opt := range opts {
+ opt(w)
+ }
+ return w
+}
+
+// Render whitespaces.
+func (w whitespace) render(width int) string {
+ if w.chars == "" {
+ w.chars = " "
+ }
+
+ r := []rune(w.chars)
+ j := 0
+ b := strings.Builder{}
+
+ // Cycle through runes and print them into the whitespace.
+ for i := 0; i < width; {
+ b.WriteRune(r[j])
+ // Measure the width of the rune we just wrote, ensuring we always
+ // make progress to avoid infinite loops with zero-width characters
+ // like tabs.
+ runeWidth := ansi.StringWidth(string(r[j]))
+ if runeWidth < 1 {
+ runeWidth = 1
+ }
+ i += runeWidth
+ j++
+ if j >= len(r) {
+ j = 0
+ }
+ }
+
+ // Fill any extra gaps white spaces. This might be necessary if any runes
+ // are more than one cell wide, which could leave a one-rune gap.
+ short := width - ansi.StringWidth(b.String())
+ if short > 0 {
+ b.WriteString(strings.Repeat(" ", short))
+ }
+
+ return w.style.Render(b.String())
+}
+
+// WhitespaceOption sets a styling rule for rendering whitespace.
+type WhitespaceOption func(*whitespace)
+
+// WithWhitespaceStyle sets the style for the whitespace.
+func WithWhitespaceStyle(s Style) WhitespaceOption {
+ return func(w *whitespace) {
+ w.style = s
+ }
+}
+
+// WithWhitespaceChars sets the characters to be rendered in the whitespace.
+func WithWhitespaceChars(s string) WhitespaceOption {
+ return func(w *whitespace) {
+ w.chars = s
+ }
+}
diff --git a/vendor/charm.land/lipgloss/v2/wrap.go b/vendor/charm.land/lipgloss/v2/wrap.go
new file mode 100644
index 000000000..ca0a1e239
--- /dev/null
+++ b/vendor/charm.land/lipgloss/v2/wrap.go
@@ -0,0 +1,107 @@
+package lipgloss
+
+import (
+ "bytes"
+ "io"
+
+ uv "github.com/charmbracelet/ultraviolet"
+ "github.com/charmbracelet/x/ansi"
+)
+
+// Wrap wraps the given string to the given width, preserving ANSI styles and links.
+func Wrap(s string, width int, breakpoints string) string {
+ var buf bytes.Buffer
+ s = ansi.Wrap(s, width, breakpoints)
+ w := NewWrapWriter(&buf)
+ defer w.Close() //nolint:errcheck
+ _, _ = io.WriteString(w, s)
+ return buf.String()
+}
+
+// WrapWriter is a writer that writes to a buffer and keeps track of the
+// current pen style and link state for the purpose of wrapping with newlines.
+//
+// When it encounters a newline, it resets the style and link, writes the
+// newline, and then reapplies the style and link to the next line.
+type WrapWriter struct {
+ w io.Writer
+ p *ansi.Parser
+ style uv.Style
+ link uv.Link
+}
+
+// NewWrapWriter returns a new [WrapWriter].
+func NewWrapWriter(w io.Writer) *WrapWriter {
+ pw := &WrapWriter{w: w}
+ pw.p = ansi.GetParser()
+ handleCsi := func(cmd ansi.Cmd, params ansi.Params) {
+ if cmd == 'm' {
+ uv.ReadStyle(params, &pw.style)
+ }
+ }
+ handleOsc := func(cmd int, data []byte) {
+ if cmd == 8 {
+ uv.ReadLink(data, &pw.link)
+ }
+ }
+ pw.p.SetHandler(ansi.Handler{
+ HandleCsi: handleCsi,
+ HandleOsc: handleOsc,
+ })
+ return pw
+}
+
+// Style returns the current pen style.
+func (w *WrapWriter) Style() uv.Style {
+ return w.style
+}
+
+// Link returns the current pen link.
+func (w *WrapWriter) Link() uv.Link {
+ return w.link
+}
+
+// Write writes to the buffer.
+func (w *WrapWriter) Write(p []byte) (int, error) {
+ for i := range p {
+ b := p[i]
+ w.p.Advance(b)
+ if b == '\n' {
+ if !w.style.IsZero() {
+ _, _ = w.w.Write([]byte(ansi.ResetStyle))
+ }
+ if !w.link.IsZero() {
+ _, _ = w.w.Write([]byte(ansi.ResetHyperlink()))
+ }
+ }
+
+ _, _ = w.w.Write([]byte{b})
+ if b == '\n' {
+ if !w.link.IsZero() {
+ _, _ = w.w.Write([]byte(ansi.SetHyperlink(w.link.URL, w.link.Params)))
+ }
+ if !w.style.IsZero() {
+ _, _ = w.w.Write([]byte(w.style.String()))
+ }
+ }
+ }
+
+ return len(p), nil
+}
+
+// Close closes the writer, resets the style and link if necessary, and releases
+// its parser. Calling it is performance critical, but forgetting it does not
+// cause safety issues or leaks.
+func (w *WrapWriter) Close() error {
+ if !w.style.IsZero() {
+ _, _ = w.w.Write([]byte(ansi.ResetStyle))
+ }
+ if !w.link.IsZero() {
+ _, _ = w.w.Write([]byte(ansi.ResetHyperlink()))
+ }
+ if w.p != nil {
+ ansi.PutParser(w.p)
+ w.p = nil
+ }
+ return nil
+}
diff --git a/vendor/charm.land/lipgloss/v2/writer.go b/vendor/charm.land/lipgloss/v2/writer.go
new file mode 100644
index 000000000..78b48b8d3
--- /dev/null
+++ b/vendor/charm.land/lipgloss/v2/writer.go
@@ -0,0 +1,160 @@
+package lipgloss
+
+import (
+ "bytes"
+ "fmt"
+ "io"
+ "os"
+
+ "github.com/charmbracelet/colorprofile"
+)
+
+// Writer is the default writer that prints to stdout, automatically
+// downsampling colors when necessary.
+var Writer = colorprofile.NewWriter(os.Stdout, os.Environ())
+
+// Println to stdout, automatically downsampling colors when necessary, ending
+// with a trailing newline.
+//
+// Example:
+//
+// str := NewStyle().
+// Foreground(lipgloss.Color("#6a00ff")).
+// Render("breakfast")
+//
+// Println("Time for a", str, "sandwich!")
+func Println(v ...any) (int, error) {
+ return fmt.Fprintln(Writer, v...) //nolint:wrapcheck
+}
+
+// Printf prints formatted text to stdout, automatically downsampling colors
+// when necessary.
+//
+// Example:
+//
+// str := NewStyle().
+// Foreground(lipgloss.Color("#6a00ff")).
+// Render("knuckle")
+//
+// Printf("Time for a %s sandwich!\n", str)
+func Printf(format string, v ...any) (int, error) {
+ return fmt.Fprintf(Writer, format, v...) //nolint:wrapcheck
+}
+
+// Print to stdout, automatically downsampling colors when necessary.
+//
+// Example:
+//
+// str := NewStyle().
+// Foreground(lipgloss.Color("#6a00ff")).
+// Render("Who wants marmalade?\n")
+//
+// Print(str)
+func Print(v ...any) (int, error) {
+ return fmt.Fprint(Writer, v...) //nolint:wrapcheck
+}
+
+// Fprint pritnts to the given writer, automatically downsampling colors when
+// necessary.
+//
+// Example:
+//
+// str := NewStyle().
+// Foreground(lipgloss.Color("#6a00ff")).
+// Render("guzzle")
+//
+// Fprint(os.Stderr, "I %s horchata pretty much all the time.\n", str)
+func Fprint(w io.Writer, v ...any) (int, error) {
+ return fmt.Fprint(colorprofile.NewWriter(w, os.Environ()), v...) //nolint:wrapcheck
+}
+
+// Fprintln prints to the given writer, automatically downsampling colors when
+// necessary, and ending with a trailing newline.
+//
+// Example:
+//
+// str := NewStyle().
+// Foreground(lipgloss.Color("#6a00ff")).
+// Render("Sandwich time!")
+//
+// Fprintln(os.Stderr, str)
+func Fprintln(w io.Writer, v ...any) (int, error) {
+ return fmt.Fprintln(colorprofile.NewWriter(w, os.Environ()), v...) //nolint:wrapcheck
+}
+
+// Fprintf prints text to a writer, against the given format, automatically
+// downsampling colors when necessary.
+//
+// Example:
+//
+// str := NewStyle().
+// Foreground(lipgloss.Color("#6a00ff")).
+// Render("artichokes")
+//
+// Fprintf(os.Stderr, "I really love %s!\n", food)
+func Fprintf(w io.Writer, format string, v ...any) (int, error) {
+ return fmt.Fprintf(colorprofile.NewWriter(w, os.Environ()), format, v...) //nolint:wrapcheck
+}
+
+// Sprint returns a string for stdout, automatically downsampling colors when
+// necessary.
+//
+// Example:
+//
+// str := NewStyle().
+// Faint(true).
+// Foreground(lipgloss.Color("#6a00ff")).
+// Render("I love to eat")
+//
+// str = Sprint(str)
+func Sprint(v ...any) string {
+ var buf bytes.Buffer
+ w := colorprofile.Writer{
+ Forward: &buf,
+ Profile: Writer.Profile,
+ }
+ fmt.Fprint(&w, v...) //nolint:errcheck
+ return buf.String()
+}
+
+// Sprintln returns a string for stdout, automatically downsampling colors when
+// necessary, and ending with a trailing newline.
+//
+// Example:
+//
+// str := NewStyle().
+// Bold(true).
+// Foreground(lipgloss.Color("#6a00ff")).
+// Render("Yummy!")
+//
+// str = Sprintln(str)
+func Sprintln(v ...any) string {
+ var buf bytes.Buffer
+ w := colorprofile.Writer{
+ Forward: &buf,
+ Profile: Writer.Profile,
+ }
+ fmt.Fprintln(&w, v...) //nolint:errcheck
+ return buf.String()
+}
+
+// Sprintf returns a formatted string for stdout, automatically downsampling
+// colors when necessary.
+//
+// Example:
+//
+// str := NewStyle().
+// Bold(true).
+// Foreground(lipgloss.Color("#fccaee")).
+// Render("Cantaloupe")
+//
+// str = Sprintf("I really love %s!", str)
+func Sprintf(format string, v ...any) string {
+ var buf bytes.Buffer
+ w := colorprofile.Writer{
+ Forward: &buf,
+ Profile: Writer.Profile,
+ }
+ fmt.Fprintf(&w, format, v...) //nolint:errcheck
+ return buf.String()
+}
diff --git a/vendor/dario.cat/mergo/.deepsource.toml b/vendor/dario.cat/mergo/.deepsource.toml
new file mode 100644
index 000000000..a8bc979e0
--- /dev/null
+++ b/vendor/dario.cat/mergo/.deepsource.toml
@@ -0,0 +1,12 @@
+version = 1
+
+test_patterns = [
+ "*_test.go"
+]
+
+[[analyzers]]
+name = "go"
+enabled = true
+
+ [analyzers.meta]
+ import_path = "dario.cat/mergo"
\ No newline at end of file
diff --git a/vendor/dario.cat/mergo/.gitignore b/vendor/dario.cat/mergo/.gitignore
new file mode 100644
index 000000000..45ad0f1ae
--- /dev/null
+++ b/vendor/dario.cat/mergo/.gitignore
@@ -0,0 +1,36 @@
+#### joe made this: http://goel.io/joe
+
+#### go ####
+# Binaries for programs and plugins
+*.exe
+*.dll
+*.so
+*.dylib
+
+# Test binary, build with `go test -c`
+*.test
+
+# Output of the go coverage tool, specifically when used with LiteIDE
+*.out
+
+# Golang/Intellij
+.idea
+
+# Project-local glide cache, RE: https://github.com/Masterminds/glide/issues/736
+.glide/
+
+#### vim ####
+# Swap
+[._]*.s[a-v][a-z]
+[._]*.sw[a-p]
+[._]s[a-v][a-z]
+[._]sw[a-p]
+
+# Session
+Session.vim
+
+# Temporary
+.netrwhist
+*~
+# Auto-generated tag files
+tags
diff --git a/vendor/github.com/imdario/mergo/.travis.yml b/vendor/dario.cat/mergo/.travis.yml
similarity index 100%
rename from vendor/github.com/imdario/mergo/.travis.yml
rename to vendor/dario.cat/mergo/.travis.yml
diff --git a/vendor/github.com/imdario/mergo/CODE_OF_CONDUCT.md b/vendor/dario.cat/mergo/CODE_OF_CONDUCT.md
similarity index 100%
rename from vendor/github.com/imdario/mergo/CODE_OF_CONDUCT.md
rename to vendor/dario.cat/mergo/CODE_OF_CONDUCT.md
diff --git a/vendor/github.com/imdario/mergo/CONTRIBUTING.md b/vendor/dario.cat/mergo/CONTRIBUTING.md
similarity index 100%
rename from vendor/github.com/imdario/mergo/CONTRIBUTING.md
rename to vendor/dario.cat/mergo/CONTRIBUTING.md
diff --git a/vendor/dario.cat/mergo/FUNDING.json b/vendor/dario.cat/mergo/FUNDING.json
new file mode 100644
index 000000000..0585e1fe1
--- /dev/null
+++ b/vendor/dario.cat/mergo/FUNDING.json
@@ -0,0 +1,7 @@
+{
+ "drips": {
+ "ethereum": {
+ "ownedBy": "0x6160020e7102237aC41bdb156e94401692D76930"
+ }
+ }
+}
diff --git a/vendor/github.com/imdario/mergo/LICENSE b/vendor/dario.cat/mergo/LICENSE
similarity index 100%
rename from vendor/github.com/imdario/mergo/LICENSE
rename to vendor/dario.cat/mergo/LICENSE
diff --git a/vendor/dario.cat/mergo/README.md b/vendor/dario.cat/mergo/README.md
new file mode 100644
index 000000000..0e4a59afd
--- /dev/null
+++ b/vendor/dario.cat/mergo/README.md
@@ -0,0 +1,253 @@
+# Mergo
+
+[![GitHub release][5]][6]
+[![GoCard][7]][8]
+[![Test status][1]][2]
+[![OpenSSF Scorecard][21]][22]
+[![OpenSSF Best Practices][19]][20]
+[![Coverage status][9]][10]
+[![Sourcegraph][11]][12]
+[![FOSSA status][13]][14]
+
+[![GoDoc][3]][4]
+[![Become my sponsor][15]][16]
+[![Tidelift][17]][18]
+
+[1]: https://github.com/imdario/mergo/workflows/tests/badge.svg?branch=master
+[2]: https://github.com/imdario/mergo/actions/workflows/tests.yml
+[3]: https://godoc.org/github.com/imdario/mergo?status.svg
+[4]: https://godoc.org/github.com/imdario/mergo
+[5]: https://img.shields.io/github/release/imdario/mergo.svg
+[6]: https://github.com/imdario/mergo/releases
+[7]: https://goreportcard.com/badge/imdario/mergo
+[8]: https://goreportcard.com/report/github.com/imdario/mergo
+[9]: https://coveralls.io/repos/github/imdario/mergo/badge.svg?branch=master
+[10]: https://coveralls.io/github/imdario/mergo?branch=master
+[11]: https://sourcegraph.com/github.com/imdario/mergo/-/badge.svg
+[12]: https://sourcegraph.com/github.com/imdario/mergo?badge
+[13]: https://app.fossa.io/api/projects/git%2Bgithub.com%2Fimdario%2Fmergo.svg?type=shield
+[14]: https://app.fossa.io/projects/git%2Bgithub.com%2Fimdario%2Fmergo?ref=badge_shield
+[15]: https://img.shields.io/github/sponsors/imdario
+[16]: https://github.com/sponsors/imdario
+[17]: https://tidelift.com/badges/package/go/github.com%2Fimdario%2Fmergo
+[18]: https://tidelift.com/subscription/pkg/go-github.com-imdario-mergo
+[19]: https://bestpractices.coreinfrastructure.org/projects/7177/badge
+[20]: https://bestpractices.coreinfrastructure.org/projects/7177
+[21]: https://api.securityscorecards.dev/projects/github.com/imdario/mergo/badge
+[22]: https://api.securityscorecards.dev/projects/github.com/imdario/mergo
+
+A helper to merge structs and maps in Golang. Useful for configuration default values, avoiding messy if-statements.
+
+Mergo merges same-type structs and maps by setting default values in zero-value fields. Mergo won't merge unexported (private) fields. It will do recursively any exported one. It also won't merge structs inside maps (because they are not addressable using Go reflection).
+
+Also a lovely [comune](http://en.wikipedia.org/wiki/Mergo) (municipality) in the Province of Ancona in the Italian region of Marche.
+
+## Status
+
+Mergo is stable and frozen, ready for production. Check a short list of the projects using at large scale it [here](https://github.com/imdario/mergo#mergo-in-the-wild).
+
+No new features are accepted. They will be considered for a future v2 that improves the implementation and fixes bugs for corner cases.
+
+### Important notes
+
+#### 1.0.0
+
+In [1.0.0](//github.com/imdario/mergo/releases/tag/1.0.0) Mergo moves to a vanity URL `dario.cat/mergo`. No more v1 versions will be released.
+
+If the vanity URL is causing issues in your project due to a dependency pulling Mergo - it isn't a direct dependency in your project - it is recommended to use [replace](https://github.com/golang/go/wiki/Modules#when-should-i-use-the-replace-directive) to pin the version to the last one with the old import URL:
+
+```
+replace github.com/imdario/mergo => github.com/imdario/mergo v0.3.16
+```
+
+#### 0.3.9
+
+Please keep in mind that a problematic PR broke [0.3.9](//github.com/imdario/mergo/releases/tag/0.3.9). I reverted it in [0.3.10](//github.com/imdario/mergo/releases/tag/0.3.10), and I consider it stable but not bug-free. Also, this version adds support for go modules.
+
+Keep in mind that in [0.3.2](//github.com/imdario/mergo/releases/tag/0.3.2), Mergo changed `Merge()`and `Map()` signatures to support [transformers](#transformers). I added an optional/variadic argument so that it won't break the existing code.
+
+If you were using Mergo before April 6th, 2015, please check your project works as intended after updating your local copy with ```go get -u dario.cat/mergo```. I apologize for any issue caused by its previous behavior and any future bug that Mergo could cause in existing projects after the change (release 0.2.0).
+
+### Donations
+
+If Mergo is useful to you, consider buying me a coffee, a beer, or making a monthly donation to allow me to keep building great free software. :heart_eyes:
+
+
+
+
+### Mergo in the wild
+
+Mergo is used by [thousands](https://deps.dev/go/dario.cat%2Fmergo/v1.0.0/dependents) [of](https://deps.dev/go/github.com%2Fimdario%2Fmergo/v0.3.16/dependents) [projects](https://deps.dev/go/github.com%2Fimdario%2Fmergo/v0.3.12), including:
+
+* [containerd/containerd](https://github.com/containerd/containerd)
+* [datadog/datadog-agent](https://github.com/datadog/datadog-agent)
+* [docker/cli/](https://github.com/docker/cli/)
+* [goreleaser/goreleaser](https://github.com/goreleaser/goreleaser)
+* [go-micro/go-micro](https://github.com/go-micro/go-micro)
+* [grafana/loki](https://github.com/grafana/loki)
+* [masterminds/sprig](github.com/Masterminds/sprig)
+* [moby/moby](https://github.com/moby/moby)
+* [slackhq/nebula](https://github.com/slackhq/nebula)
+* [volcano-sh/volcano](https://github.com/volcano-sh/volcano)
+
+## Install
+
+ go get dario.cat/mergo
+
+ // use in your .go code
+ import (
+ "dario.cat/mergo"
+ )
+
+## Usage
+
+You can only merge same-type structs with exported fields initialized as zero value of their type and same-types maps. Mergo won't merge unexported (private) fields but will do recursively any exported one. It won't merge empty structs value as [they are zero values](https://golang.org/ref/spec#The_zero_value) too. Also, maps will be merged recursively except for structs inside maps (because they are not addressable using Go reflection).
+
+```go
+if err := mergo.Merge(&dst, src); err != nil {
+ // ...
+}
+```
+
+Also, you can merge overwriting values using the transformer `WithOverride`.
+
+```go
+if err := mergo.Merge(&dst, src, mergo.WithOverride); err != nil {
+ // ...
+}
+```
+
+If you need to override pointers, so the source pointer's value is assigned to the destination's pointer, you must use `WithoutDereference`:
+
+```go
+package main
+
+import (
+ "fmt"
+
+ "dario.cat/mergo"
+)
+
+type Foo struct {
+ A *string
+ B int64
+}
+
+func main() {
+ first := "first"
+ second := "second"
+ src := Foo{
+ A: &first,
+ B: 2,
+ }
+
+ dest := Foo{
+ A: &second,
+ B: 1,
+ }
+
+ mergo.Merge(&dest, src, mergo.WithOverride, mergo.WithoutDereference)
+}
+```
+
+Additionally, you can map a `map[string]interface{}` to a struct (and otherwise, from struct to map), following the same restrictions as in `Merge()`. Keys are capitalized to find each corresponding exported field.
+
+```go
+if err := mergo.Map(&dst, srcMap); err != nil {
+ // ...
+}
+```
+
+Warning: if you map a struct to map, it won't do it recursively. Don't expect Mergo to map struct members of your struct as `map[string]interface{}`. They will be just assigned as values.
+
+Here is a nice example:
+
+```go
+package main
+
+import (
+ "fmt"
+ "dario.cat/mergo"
+)
+
+type Foo struct {
+ A string
+ B int64
+}
+
+func main() {
+ src := Foo{
+ A: "one",
+ B: 2,
+ }
+ dest := Foo{
+ A: "two",
+ }
+ mergo.Merge(&dest, src)
+ fmt.Println(dest)
+ // Will print
+ // {two 2}
+}
+```
+
+### Transformers
+
+Transformers allow to merge specific types differently than in the default behavior. In other words, now you can customize how some types are merged. For example, `time.Time` is a struct; it doesn't have zero value but IsZero can return true because it has fields with zero value. How can we merge a non-zero `time.Time`?
+
+```go
+package main
+
+import (
+ "fmt"
+ "dario.cat/mergo"
+ "reflect"
+ "time"
+)
+
+type timeTransformer struct {
+}
+
+func (t timeTransformer) Transformer(typ reflect.Type) func(dst, src reflect.Value) error {
+ if typ == reflect.TypeOf(time.Time{}) {
+ return func(dst, src reflect.Value) error {
+ if dst.CanSet() {
+ isZero := dst.MethodByName("IsZero")
+ result := isZero.Call([]reflect.Value{})
+ if result[0].Bool() {
+ dst.Set(src)
+ }
+ }
+ return nil
+ }
+ }
+ return nil
+}
+
+type Snapshot struct {
+ Time time.Time
+ // ...
+}
+
+func main() {
+ src := Snapshot{time.Now()}
+ dest := Snapshot{}
+ mergo.Merge(&dest, src, mergo.WithTransformers(timeTransformer{}))
+ fmt.Println(dest)
+ // Will print
+ // { 2018-01-12 01:15:00 +0000 UTC m=+0.000000001 }
+}
+```
+
+## Contact me
+
+If I can help you, you have an idea or you are using Mergo in your projects, don't hesitate to drop me a line (or a pull request): [@im_dario](https://twitter.com/im_dario)
+
+## About
+
+Written by [Dario Castañé](http://dario.im).
+
+## License
+
+[BSD 3-Clause](http://opensource.org/licenses/BSD-3-Clause) license, as [Go language](http://golang.org/LICENSE).
+
+[](https://app.fossa.io/projects/git%2Bgithub.com%2Fimdario%2Fmergo?ref=badge_large)
diff --git a/vendor/github.com/imdario/mergo/SECURITY.md b/vendor/dario.cat/mergo/SECURITY.md
similarity index 82%
rename from vendor/github.com/imdario/mergo/SECURITY.md
rename to vendor/dario.cat/mergo/SECURITY.md
index a5de61f77..3788fcc1c 100644
--- a/vendor/github.com/imdario/mergo/SECURITY.md
+++ b/vendor/dario.cat/mergo/SECURITY.md
@@ -4,8 +4,8 @@
| Version | Supported |
| ------- | ------------------ |
-| 0.3.x | :white_check_mark: |
-| < 0.3 | :x: |
+| 1.x.x | :white_check_mark: |
+| < 1.0 | :x: |
## Security contact information
diff --git a/vendor/dario.cat/mergo/doc.go b/vendor/dario.cat/mergo/doc.go
new file mode 100644
index 000000000..7d96ec054
--- /dev/null
+++ b/vendor/dario.cat/mergo/doc.go
@@ -0,0 +1,148 @@
+// Copyright 2013 Dario Castañé. All rights reserved.
+// Copyright 2009 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.
+
+/*
+A helper to merge structs and maps in Golang. Useful for configuration default values, avoiding messy if-statements.
+
+Mergo merges same-type structs and maps by setting default values in zero-value fields. Mergo won't merge unexported (private) fields. It will do recursively any exported one. It also won't merge structs inside maps (because they are not addressable using Go reflection).
+
+# Status
+
+It is ready for production use. It is used in several projects by Docker, Google, The Linux Foundation, VMWare, Shopify, etc.
+
+# Important notes
+
+1.0.0
+
+In 1.0.0 Mergo moves to a vanity URL `dario.cat/mergo`.
+
+0.3.9
+
+Please keep in mind that a problematic PR broke 0.3.9. We reverted it in 0.3.10. We consider 0.3.10 as stable but not bug-free. . Also, this version adds suppot for go modules.
+
+Keep in mind that in 0.3.2, Mergo changed Merge() and Map() signatures to support transformers. We added an optional/variadic argument so that it won't break the existing code.
+
+If you were using Mergo before April 6th, 2015, please check your project works as intended after updating your local copy with go get -u dario.cat/mergo. I apologize for any issue caused by its previous behavior and any future bug that Mergo could cause in existing projects after the change (release 0.2.0).
+
+# Install
+
+Do your usual installation procedure:
+
+ go get dario.cat/mergo
+
+ // use in your .go code
+ import (
+ "dario.cat/mergo"
+ )
+
+# Usage
+
+You can only merge same-type structs with exported fields initialized as zero value of their type and same-types maps. Mergo won't merge unexported (private) fields but will do recursively any exported one. It won't merge empty structs value as they are zero values too. Also, maps will be merged recursively except for structs inside maps (because they are not addressable using Go reflection).
+
+ if err := mergo.Merge(&dst, src); err != nil {
+ // ...
+ }
+
+Also, you can merge overwriting values using the transformer WithOverride.
+
+ if err := mergo.Merge(&dst, src, mergo.WithOverride); err != nil {
+ // ...
+ }
+
+Additionally, you can map a map[string]interface{} to a struct (and otherwise, from struct to map), following the same restrictions as in Merge(). Keys are capitalized to find each corresponding exported field.
+
+ if err := mergo.Map(&dst, srcMap); err != nil {
+ // ...
+ }
+
+Warning: if you map a struct to map, it won't do it recursively. Don't expect Mergo to map struct members of your struct as map[string]interface{}. They will be just assigned as values.
+
+Here is a nice example:
+
+ package main
+
+ import (
+ "fmt"
+ "dario.cat/mergo"
+ )
+
+ type Foo struct {
+ A string
+ B int64
+ }
+
+ func main() {
+ src := Foo{
+ A: "one",
+ B: 2,
+ }
+ dest := Foo{
+ A: "two",
+ }
+ mergo.Merge(&dest, src)
+ fmt.Println(dest)
+ // Will print
+ // {two 2}
+ }
+
+# Transformers
+
+Transformers allow to merge specific types differently than in the default behavior. In other words, now you can customize how some types are merged. For example, time.Time is a struct; it doesn't have zero value but IsZero can return true because it has fields with zero value. How can we merge a non-zero time.Time?
+
+ package main
+
+ import (
+ "fmt"
+ "dario.cat/mergo"
+ "reflect"
+ "time"
+ )
+
+ type timeTransformer struct {
+ }
+
+ func (t timeTransformer) Transformer(typ reflect.Type) func(dst, src reflect.Value) error {
+ if typ == reflect.TypeOf(time.Time{}) {
+ return func(dst, src reflect.Value) error {
+ if dst.CanSet() {
+ isZero := dst.MethodByName("IsZero")
+ result := isZero.Call([]reflect.Value{})
+ if result[0].Bool() {
+ dst.Set(src)
+ }
+ }
+ return nil
+ }
+ }
+ return nil
+ }
+
+ type Snapshot struct {
+ Time time.Time
+ // ...
+ }
+
+ func main() {
+ src := Snapshot{time.Now()}
+ dest := Snapshot{}
+ mergo.Merge(&dest, src, mergo.WithTransformers(timeTransformer{}))
+ fmt.Println(dest)
+ // Will print
+ // { 2018-01-12 01:15:00 +0000 UTC m=+0.000000001 }
+ }
+
+# Contact me
+
+If I can help you, you have an idea or you are using Mergo in your projects, don't hesitate to drop me a line (or a pull request): https://twitter.com/im_dario
+
+# About
+
+Written by Dario Castañé: https://da.rio.hn
+
+# License
+
+BSD 3-Clause license, as Go language.
+*/
+package mergo
diff --git a/vendor/dario.cat/mergo/map.go b/vendor/dario.cat/mergo/map.go
new file mode 100644
index 000000000..759b4f74f
--- /dev/null
+++ b/vendor/dario.cat/mergo/map.go
@@ -0,0 +1,178 @@
+// Copyright 2014 Dario Castañé. All rights reserved.
+// Copyright 2009 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.
+
+// Based on src/pkg/reflect/deepequal.go from official
+// golang's stdlib.
+
+package mergo
+
+import (
+ "fmt"
+ "reflect"
+ "unicode"
+ "unicode/utf8"
+)
+
+func changeInitialCase(s string, mapper func(rune) rune) string {
+ if s == "" {
+ return s
+ }
+ r, n := utf8.DecodeRuneInString(s)
+ return string(mapper(r)) + s[n:]
+}
+
+func isExported(field reflect.StructField) bool {
+ r, _ := utf8.DecodeRuneInString(field.Name)
+ return r >= 'A' && r <= 'Z'
+}
+
+// Traverses recursively both values, assigning src's fields values to dst.
+// The map argument tracks comparisons that have already been seen, which allows
+// short circuiting on recursive types.
+func deepMap(dst, src reflect.Value, visited map[uintptr]*visit, depth int, config *Config) (err error) {
+ overwrite := config.Overwrite
+ if dst.CanAddr() {
+ addr := dst.UnsafeAddr()
+ h := 17 * addr
+ seen := visited[h]
+ typ := dst.Type()
+ for p := seen; p != nil; p = p.next {
+ if p.ptr == addr && p.typ == typ {
+ return nil
+ }
+ }
+ // Remember, remember...
+ visited[h] = &visit{typ, seen, addr}
+ }
+ zeroValue := reflect.Value{}
+ switch dst.Kind() {
+ case reflect.Map:
+ dstMap := dst.Interface().(map[string]interface{})
+ for i, n := 0, src.NumField(); i < n; i++ {
+ srcType := src.Type()
+ field := srcType.Field(i)
+ if !isExported(field) {
+ continue
+ }
+ fieldName := field.Name
+ fieldName = changeInitialCase(fieldName, unicode.ToLower)
+ if _, ok := dstMap[fieldName]; !ok || (!isEmptyValue(reflect.ValueOf(src.Field(i).Interface()), !config.ShouldNotDereference) && overwrite) || config.overwriteWithEmptyValue {
+ dstMap[fieldName] = src.Field(i).Interface()
+ }
+ }
+ case reflect.Ptr:
+ if dst.IsNil() {
+ v := reflect.New(dst.Type().Elem())
+ dst.Set(v)
+ }
+ dst = dst.Elem()
+ fallthrough
+ case reflect.Struct:
+ srcMap := src.Interface().(map[string]interface{})
+ for key := range srcMap {
+ config.overwriteWithEmptyValue = true
+ srcValue := srcMap[key]
+ fieldName := changeInitialCase(key, unicode.ToUpper)
+ dstElement := dst.FieldByName(fieldName)
+ if dstElement == zeroValue {
+ // We discard it because the field doesn't exist.
+ continue
+ }
+ srcElement := reflect.ValueOf(srcValue)
+ dstKind := dstElement.Kind()
+ srcKind := srcElement.Kind()
+ if srcKind == reflect.Ptr && dstKind != reflect.Ptr {
+ srcElement = srcElement.Elem()
+ srcKind = reflect.TypeOf(srcElement.Interface()).Kind()
+ } else if dstKind == reflect.Ptr {
+ // Can this work? I guess it can't.
+ if srcKind != reflect.Ptr && srcElement.CanAddr() {
+ srcPtr := srcElement.Addr()
+ srcElement = reflect.ValueOf(srcPtr)
+ srcKind = reflect.Ptr
+ }
+ }
+
+ if !srcElement.IsValid() {
+ continue
+ }
+ if srcKind == dstKind {
+ if err = deepMerge(dstElement, srcElement, visited, depth+1, config); err != nil {
+ return
+ }
+ } else if dstKind == reflect.Interface && dstElement.Kind() == reflect.Interface {
+ if err = deepMerge(dstElement, srcElement, visited, depth+1, config); err != nil {
+ return
+ }
+ } else if srcKind == reflect.Map {
+ if err = deepMap(dstElement, srcElement, visited, depth+1, config); err != nil {
+ return
+ }
+ } else {
+ return fmt.Errorf("type mismatch on %s field: found %v, expected %v", fieldName, srcKind, dstKind)
+ }
+ }
+ }
+ return
+}
+
+// Map sets fields' values in dst from src.
+// src can be a map with string keys or a struct. dst must be the opposite:
+// if src is a map, dst must be a valid pointer to struct. If src is a struct,
+// dst must be map[string]interface{}.
+// It won't merge unexported (private) fields and will do recursively
+// any exported field.
+// If dst is a map, keys will be src fields' names in lower camel case.
+// Missing key in src that doesn't match a field in dst will be skipped. This
+// doesn't apply if dst is a map.
+// This is separated method from Merge because it is cleaner and it keeps sane
+// semantics: merging equal types, mapping different (restricted) types.
+func Map(dst, src interface{}, opts ...func(*Config)) error {
+ return _map(dst, src, opts...)
+}
+
+// MapWithOverwrite will do the same as Map except that non-empty dst attributes will be overridden by
+// non-empty src attribute values.
+// Deprecated: Use Map(…) with WithOverride
+func MapWithOverwrite(dst, src interface{}, opts ...func(*Config)) error {
+ return _map(dst, src, append(opts, WithOverride)...)
+}
+
+func _map(dst, src interface{}, opts ...func(*Config)) error {
+ if dst != nil && reflect.ValueOf(dst).Kind() != reflect.Ptr {
+ return ErrNonPointerArgument
+ }
+ var (
+ vDst, vSrc reflect.Value
+ err error
+ )
+ config := &Config{}
+
+ for _, opt := range opts {
+ opt(config)
+ }
+
+ if vDst, vSrc, err = resolveValues(dst, src); err != nil {
+ return err
+ }
+ // To be friction-less, we redirect equal-type arguments
+ // to deepMerge. Only because arguments can be anything.
+ if vSrc.Kind() == vDst.Kind() {
+ return deepMerge(vDst, vSrc, make(map[uintptr]*visit), 0, config)
+ }
+ switch vSrc.Kind() {
+ case reflect.Struct:
+ if vDst.Kind() != reflect.Map {
+ return ErrExpectedMapAsDestination
+ }
+ case reflect.Map:
+ if vDst.Kind() != reflect.Struct {
+ return ErrExpectedStructAsDestination
+ }
+ default:
+ return ErrNotSupported
+ }
+ return deepMap(vDst, vSrc, make(map[uintptr]*visit), 0, config)
+}
diff --git a/vendor/github.com/imdario/mergo/merge.go b/vendor/dario.cat/mergo/merge.go
similarity index 99%
rename from vendor/github.com/imdario/mergo/merge.go
rename to vendor/dario.cat/mergo/merge.go
index 0ef9b2138..fd47c95b2 100644
--- a/vendor/github.com/imdario/mergo/merge.go
+++ b/vendor/dario.cat/mergo/merge.go
@@ -269,7 +269,7 @@ func deepMerge(dst, src reflect.Value, visited map[uintptr]*visit, depth int, co
if err = deepMerge(dst.Elem(), src.Elem(), visited, depth+1, config); err != nil {
return
}
- } else {
+ } else if src.Elem().Kind() != reflect.Struct {
if overwriteWithEmptySrc || (overwrite && !src.IsNil()) || dst.IsNil() {
dst.Set(src)
}
diff --git a/vendor/github.com/imdario/mergo/mergo.go b/vendor/dario.cat/mergo/mergo.go
similarity index 100%
rename from vendor/github.com/imdario/mergo/mergo.go
rename to vendor/dario.cat/mergo/mergo.go
diff --git a/vendor/github.com/ClickHouse/clickhouse-go-linter/LICENSE b/vendor/github.com/ClickHouse/clickhouse-go-linter/LICENSE
new file mode 100644
index 000000000..a7e77cb28
--- /dev/null
+++ b/vendor/github.com/ClickHouse/clickhouse-go-linter/LICENSE
@@ -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
\ No newline at end of file
diff --git a/vendor/github.com/ClickHouse/clickhouse-go-linter/internal/util/util.go b/vendor/github.com/ClickHouse/clickhouse-go-linter/internal/util/util.go
new file mode 100644
index 000000000..68d130989
--- /dev/null
+++ b/vendor/github.com/ClickHouse/clickhouse-go-linter/internal/util/util.go
@@ -0,0 +1,33 @@
+package util
+
+import (
+ "go/ast"
+ "go/types"
+
+ "golang.org/x/tools/go/analysis"
+)
+
+// IsChObj returns true if the input ast.Expr is of type clickhouse go driver
+func IsChObj(pass *analysis.Pass, expr ast.Expr, name string) bool {
+ t := pass.TypesInfo.TypeOf(expr)
+ if t == nil {
+ return false
+ }
+ named, ok := t.(*types.Named)
+ if !ok {
+ return false
+ }
+ obj := named.Obj()
+ if obj.Pkg() == nil {
+ return false
+ }
+ return obj.Pkg().Path() == "github.com/ClickHouse/clickhouse-go/v2/lib/driver" &&
+ obj.Name() == name
+}
+
+func IdentName(expr ast.Expr) string {
+ if id, ok := expr.(*ast.Ident); ok {
+ return id.Name
+ }
+ return ""
+}
diff --git a/vendor/github.com/ClickHouse/clickhouse-go-linter/passes/chbatchclose/chbatchclose.go b/vendor/github.com/ClickHouse/clickhouse-go-linter/passes/chbatchclose/chbatchclose.go
new file mode 100644
index 000000000..3da2c55d6
--- /dev/null
+++ b/vendor/github.com/ClickHouse/clickhouse-go-linter/passes/chbatchclose/chbatchclose.go
@@ -0,0 +1,182 @@
+package chbatchclose
+
+import (
+ "go/ast"
+ "go/token"
+ "os"
+ "strconv"
+
+ "github.com/ClickHouse/clickhouse-go-linter/internal/util"
+
+ "golang.org/x/tools/go/analysis"
+ "golang.org/x/tools/go/analysis/passes/inspect"
+ "golang.org/x/tools/go/ast/inspector"
+)
+
+type analyzer struct {
+ // if true, report valid usages and log spurious but valid cases.
+ debug bool
+}
+
+func NewAnalyzer() *analysis.Analyzer {
+ debug, _ := strconv.ParseBool(os.Getenv("CH_GO_LINTER_DEBUG"))
+ a := analyzer{
+ debug: debug,
+ }
+ return &analysis.Analyzer{
+ Name: "chbatchclosecheck",
+ Doc: "chbatchclosecheck checks whether defer batch.Close() is called on ClickHouse driver Batch variables",
+ Run: a.run,
+ Requires: []*analysis.Analyzer{inspect.Analyzer},
+ }
+}
+
+func (a *analyzer) run(pass *analysis.Pass) (any, error) {
+ insp := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector)
+
+ nodeFilter := []ast.Node{
+ (*ast.FuncDecl)(nil),
+ (*ast.FuncLit)(nil),
+ }
+
+ insp.Preorder(nodeFilter, func(n ast.Node) {
+ var body *ast.BlockStmt
+ switch fn := n.(type) {
+ case *ast.FuncDecl:
+ body = fn.Body
+ case *ast.FuncLit:
+ body = fn.Body
+ }
+
+ if body == nil {
+ return
+ }
+ a.checkFunc(pass, body)
+ })
+
+ return nil, nil
+}
+
+// batchUsage tracks whether a driver.Batch variable has a defer Close/Abort or is returned.
+type batchUsage struct {
+ assignPos token.Pos
+ deferredClose bool
+ returned bool
+}
+
+func (b *batchUsage) report(varName string, pass *analysis.Pass, debug bool) {
+ if b.assignPos == token.NoPos {
+ // no usage of Batch
+ return
+ }
+ if !b.deferredClose && !b.returned {
+ pass.Reportf(b.assignPos,
+ "clickhouse Batch %s must be closed defensively with defer %s.Close() after successful instantiation",
+ varName, varName)
+ } else if debug {
+ if b.deferredClose {
+ pass.Reportf(b.assignPos,
+ "clickhouse Batch %s is properly closed defensively after successful instantiation [valid]",
+ varName)
+ } else {
+ pass.Reportf(b.assignPos,
+ "clickhouse Batch %s is returned by the function [valid]",
+ varName)
+ }
+ }
+}
+
+// checkFunc analyzes a single function/closure body.
+// It does a single-pass collection of Batch assignments, defer Close/Abort calls, and return statements.
+// It does not descend into nested closures (they are handled as separate units by the Preorder visitor above).
+func (a *analyzer) checkFunc(pass *analysis.Pass, body *ast.BlockStmt) {
+ usages := map[string]*batchUsage{}
+
+ ast.Inspect(body, func(n ast.Node) bool {
+ if n == nil {
+ return false
+ }
+ // don't descend into nested closures
+ if n != body {
+ if _, ok := n.(*ast.FuncLit); ok {
+ return false
+ }
+ }
+
+ switch node := n.(type) {
+ case *ast.AssignStmt:
+ a.handleAssign(pass, node, usages)
+ case *ast.DeferStmt:
+ handleDefer(node, usages)
+ case *ast.ReturnStmt:
+ handleReturn(node, usages)
+ }
+
+ return true
+ })
+
+ // remaining usages that were not flushed
+ for varName, u := range usages {
+ u.report(varName, pass, a.debug)
+ }
+}
+
+// handleAssign checks if any LHS variable in the assignment is of type driver.Batch.
+// If a tracked variable is reassigned, it flushes/reports the previous tracking first.
+func (a *analyzer) handleAssign(pass *analysis.Pass, assign *ast.AssignStmt, usages map[string]*batchUsage) {
+ for _, lhs := range assign.Lhs {
+ name := util.IdentName(lhs)
+ if name == "" {
+ continue
+ }
+ if name == "_" && util.IsChObj(pass, lhs, "Batch") {
+ pass.Reportf(assign.Pos(), "clickhouse Batch assigned to blank identifier. Connection leak. clickhouse Batch must be instantiated and closed defensively with defer batch.Close() after successful instantiation")
+ continue
+ }
+
+ // if this var was already tracked, flush previous usage before re-tracking
+ if u, ok := usages[name]; ok {
+ u.report(name, pass, a.debug)
+ delete(usages, name)
+ }
+
+ if util.IsChObj(pass, lhs, "Batch") {
+ usages[name] = &batchUsage{assignPos: assign.Pos()}
+ }
+ }
+}
+
+// handleDefer checks if a defer statement calls Close() or Abort() on a tracked Batch variable.
+func handleDefer(deferStmt *ast.DeferStmt, usages map[string]*batchUsage) {
+ call := deferStmt.Call
+ sel, ok := call.Fun.(*ast.SelectorExpr)
+ if !ok {
+ return
+ }
+ varName := util.IdentName(sel.X)
+ if varName == "" {
+ return
+ }
+ u, exists := usages[varName]
+ if !exists {
+ return
+ }
+
+ switch sel.Sel.Name {
+ case "Close":
+ u.deferredClose = true
+ }
+}
+
+// handleReturn checks if any return value is a tracked Batch variable.
+func handleReturn(ret *ast.ReturnStmt, usages map[string]*batchUsage) {
+ for _, result := range ret.Results {
+ name := util.IdentName(result)
+ if name == "" {
+ continue
+ }
+ if u, exists := usages[name]; exists {
+ u.returned = true
+ }
+ }
+}
diff --git a/vendor/github.com/ClickHouse/clickhouse-go-linter/passes/chrowserr/chrowserr.go b/vendor/github.com/ClickHouse/clickhouse-go-linter/passes/chrowserr/chrowserr.go
new file mode 100644
index 000000000..bba0f82ad
--- /dev/null
+++ b/vendor/github.com/ClickHouse/clickhouse-go-linter/passes/chrowserr/chrowserr.go
@@ -0,0 +1,162 @@
+package chrowserr
+
+import (
+ "go/ast"
+ "go/token"
+ "log"
+ "os"
+ "strconv"
+
+ "github.com/ClickHouse/clickhouse-go-linter/internal/util"
+ "golang.org/x/tools/go/analysis"
+ "golang.org/x/tools/go/analysis/passes/inspect"
+ "golang.org/x/tools/go/ast/inspector"
+)
+
+type analyzer struct {
+ // if true, report valid usages and log spurious but valid cases.
+ debug bool
+}
+
+func NewAnalyzer() *analysis.Analyzer {
+ debug, _ := strconv.ParseBool(os.Getenv("CH_GO_LINTER_DEBUG"))
+ a := analyzer{
+ debug: debug,
+ }
+ return &analysis.Analyzer{
+ Name: "chrowserrcheck",
+ Doc: "chrowserrcheck checks whether ClickHouse driver Rows.Err is called after Rows.Next()",
+ Run: a.run,
+ Requires: []*analysis.Analyzer{inspect.Analyzer},
+ }
+}
+
+func (a *analyzer) run(pass *analysis.Pass) (any, error) {
+ insp := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector)
+
+ nodeFilter := []ast.Node{
+ (*ast.FuncDecl)(nil),
+ (*ast.FuncLit)(nil),
+ }
+
+ insp.Preorder(nodeFilter, func(n ast.Node) {
+ var body *ast.BlockStmt
+ switch fn := n.(type) {
+ case *ast.FuncDecl:
+ body = fn.Body
+ case *ast.FuncLit:
+ body = fn.Body
+ }
+
+ if body == nil {
+ return
+ }
+ a.checkFunc(pass, body)
+ })
+
+ return nil, nil
+}
+
+// rowsUsage tracks Next/Err usage observations for a single Rows variable within a function.
+type rowsUsage struct {
+ nextPos token.Pos
+ errCalled bool
+}
+
+func (r *rowsUsage) report(varName string, pass *analysis.Pass, debug bool) {
+ if r.nextPos == token.NoPos {
+ // no usage of rows.Next()
+ return
+ }
+ // rows.Next() was called
+ if !r.errCalled {
+ pass.Reportf(r.nextPos,
+ "clickhouse %s.Err() must be checked after %s.Next()",
+ varName, varName)
+ } else if debug {
+ // for dev purpose - list valid usages
+ pass.Reportf(r.nextPos,
+ "clickhouse %s.Err() is properly called after %s.Next() [valid]",
+ varName, varName)
+ }
+}
+
+// checkFunc analyzes a single function/closure body.
+// It does a single-pass collection of Next() and Err() calls,
+// it does not descend into nested closures (they are handled as separate units by the Preorder visitor above).
+func (a *analyzer) checkFunc(pass *analysis.Pass, body *ast.BlockStmt) {
+ usages := map[string]*rowsUsage{}
+ ast.Inspect(body, func(n ast.Node) bool {
+ if n == nil {
+ return false
+ }
+ // don't descend into nested closures
+ if n != body {
+ if _, ok := n.(*ast.FuncLit); ok {
+ return false
+ }
+ }
+
+ // if a tracked var appears in an assignment, it means it is re-assigned - run lint report and flush var from usages.
+ if assign, ok := n.(*ast.AssignStmt); ok {
+ for _, lhs := range assign.Lhs {
+ name := util.IdentName(lhs)
+ if name == "" {
+ continue
+ }
+ if s, ok := usages[name]; ok {
+ s.report(name, pass, a.debug)
+ }
+ delete(usages, name)
+ }
+ // let ast.Inspect continue
+ return true
+ }
+
+ // handle CH driver method calls Next() and Err() - skip everything else
+ call, ok := n.(*ast.CallExpr)
+ if !ok {
+ return true
+ }
+ sel, ok := call.Fun.(*ast.SelectorExpr)
+ if !ok {
+ return true
+ }
+ varName := util.IdentName(sel.X)
+ if varName == "" {
+ return true
+ }
+ if !util.IsChObj(pass, sel.X, "Rows") {
+ return true
+ }
+
+ // call is a CH driver Rows method call
+ switch sel.Sel.Name {
+ case "Next":
+ if _, exists := usages[varName]; !exists {
+ usages[varName] = &rowsUsage{nextPos: call.Pos()}
+ } else if a.debug {
+ log.Printf("Rows.Next() is written multiple times with no re-assignment. Valid but rare usage. If this observation is not correct, it is a bug in this linter library. Please reach out to maintainer.")
+ // in particular could be a bug in the re-assignment detection
+ }
+ case "Err":
+ if s, exists := usages[varName]; exists {
+ s.errCalled = true
+ s.report(varName, pass, a.debug)
+ delete(usages, varName)
+ } else if a.debug {
+ log.Printf("%s.Err() is called on ClickHouse Rows %s but %s.Next() was never called. Valid but unexpected usage. If this observation is not correct, it is a bug in this linter library. Please reach out to maintainer.",
+ varName, varName, varName)
+ // in particular could be a bug in the re-assignment detection
+ }
+
+ }
+
+ return true
+ })
+
+ // remaining usages that were not flushed (misusages only, as correct usages are flushed already)
+ for varName, s := range usages {
+ s.report(varName, pass, a.debug)
+ }
+}
diff --git a/vendor/github.com/Masterminds/semver/.travis.yml b/vendor/github.com/Masterminds/semver/.travis.yml
deleted file mode 100644
index 096369d44..000000000
--- a/vendor/github.com/Masterminds/semver/.travis.yml
+++ /dev/null
@@ -1,29 +0,0 @@
-language: go
-
-go:
- - 1.6.x
- - 1.7.x
- - 1.8.x
- - 1.9.x
- - 1.10.x
- - 1.11.x
- - 1.12.x
- - tip
-
-# Setting sudo access to false will let Travis CI use containers rather than
-# VMs to run the tests. For more details see:
-# - http://docs.travis-ci.com/user/workers/container-based-infrastructure/
-# - http://docs.travis-ci.com/user/workers/standard-infrastructure/
-sudo: false
-
-script:
- - make setup
- - make test
-
-notifications:
- webhooks:
- urls:
- - https://webhooks.gitter.im/e/06e3328629952dabe3e0
- on_success: change # options: [always|never|change] default: always
- on_failure: always # options: [always|never|change] default: always
- on_start: never # options: [always|never|change] default: always
diff --git a/vendor/github.com/Masterminds/semver/CHANGELOG.md b/vendor/github.com/Masterminds/semver/CHANGELOG.md
deleted file mode 100644
index e405c9a84..000000000
--- a/vendor/github.com/Masterminds/semver/CHANGELOG.md
+++ /dev/null
@@ -1,109 +0,0 @@
-# 1.5.0 (2019-09-11)
-
-## Added
-
-- #103: Add basic fuzzing for `NewVersion()` (thanks @jesse-c)
-
-## Changed
-
-- #82: Clarify wildcard meaning in range constraints and update tests for it (thanks @greysteil)
-- #83: Clarify caret operator range for pre-1.0.0 dependencies (thanks @greysteil)
-- #72: Adding docs comment pointing to vert for a cli
-- #71: Update the docs on pre-release comparator handling
-- #89: Test with new go versions (thanks @thedevsaddam)
-- #87: Added $ to ValidPrerelease for better validation (thanks @jeremycarroll)
-
-## Fixed
-
-- #78: Fix unchecked error in example code (thanks @ravron)
-- #70: Fix the handling of pre-releases and the 0.0.0 release edge case
-- #97: Fixed copyright file for proper display on GitHub
-- #107: Fix handling prerelease when sorting alphanum and num
-- #109: Fixed where Validate sometimes returns wrong message on error
-
-# 1.4.2 (2018-04-10)
-
-## Changed
-- #72: Updated the docs to point to vert for a console appliaction
-- #71: Update the docs on pre-release comparator handling
-
-## Fixed
-- #70: Fix the handling of pre-releases and the 0.0.0 release edge case
-
-# 1.4.1 (2018-04-02)
-
-## Fixed
-- Fixed #64: Fix pre-release precedence issue (thanks @uudashr)
-
-# 1.4.0 (2017-10-04)
-
-## Changed
-- #61: Update NewVersion to parse ints with a 64bit int size (thanks @zknill)
-
-# 1.3.1 (2017-07-10)
-
-## Fixed
-- Fixed #57: number comparisons in prerelease sometimes inaccurate
-
-# 1.3.0 (2017-05-02)
-
-## Added
-- #45: Added json (un)marshaling support (thanks @mh-cbon)
-- Stability marker. See https://masterminds.github.io/stability/
-
-## Fixed
-- #51: Fix handling of single digit tilde constraint (thanks @dgodd)
-
-## Changed
-- #55: The godoc icon moved from png to svg
-
-# 1.2.3 (2017-04-03)
-
-## Fixed
-- #46: Fixed 0.x.x and 0.0.x in constraints being treated as *
-
-# Release 1.2.2 (2016-12-13)
-
-## Fixed
-- #34: Fixed issue where hyphen range was not working with pre-release parsing.
-
-# Release 1.2.1 (2016-11-28)
-
-## Fixed
-- #24: Fixed edge case issue where constraint "> 0" does not handle "0.0.1-alpha"
- properly.
-
-# Release 1.2.0 (2016-11-04)
-
-## Added
-- #20: Added MustParse function for versions (thanks @adamreese)
-- #15: Added increment methods on versions (thanks @mh-cbon)
-
-## Fixed
-- Issue #21: Per the SemVer spec (section 9) a pre-release is unstable and
- might not satisfy the intended compatibility. The change here ignores pre-releases
- on constraint checks (e.g., ~ or ^) when a pre-release is not part of the
- constraint. For example, `^1.2.3` will ignore pre-releases while
- `^1.2.3-alpha` will include them.
-
-# Release 1.1.1 (2016-06-30)
-
-## Changed
-- Issue #9: Speed up version comparison performance (thanks @sdboyer)
-- Issue #8: Added benchmarks (thanks @sdboyer)
-- Updated Go Report Card URL to new location
-- Updated Readme to add code snippet formatting (thanks @mh-cbon)
-- Updating tagging to v[SemVer] structure for compatibility with other tools.
-
-# Release 1.1.0 (2016-03-11)
-
-- Issue #2: Implemented validation to provide reasons a versions failed a
- constraint.
-
-# Release 1.0.1 (2015-12-31)
-
-- Fixed #1: * constraint failing on valid versions.
-
-# Release 1.0.0 (2015-10-20)
-
-- Initial release
diff --git a/vendor/github.com/Masterminds/semver/LICENSE.txt b/vendor/github.com/Masterminds/semver/LICENSE.txt
deleted file mode 100644
index 9ff7da9c4..000000000
--- a/vendor/github.com/Masterminds/semver/LICENSE.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-Copyright (C) 2014-2019, Matt Butcher and Matt Farina
-
-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.
diff --git a/vendor/github.com/Masterminds/semver/Makefile b/vendor/github.com/Masterminds/semver/Makefile
deleted file mode 100644
index a7a1b4e36..000000000
--- a/vendor/github.com/Masterminds/semver/Makefile
+++ /dev/null
@@ -1,36 +0,0 @@
-.PHONY: setup
-setup:
- go get -u gopkg.in/alecthomas/gometalinter.v1
- gometalinter.v1 --install
-
-.PHONY: test
-test: validate lint
- @echo "==> Running tests"
- go test -v
-
-.PHONY: validate
-validate:
- @echo "==> Running static validations"
- @gometalinter.v1 \
- --disable-all \
- --enable deadcode \
- --severity deadcode:error \
- --enable gofmt \
- --enable gosimple \
- --enable ineffassign \
- --enable misspell \
- --enable vet \
- --tests \
- --vendor \
- --deadline 60s \
- ./... || exit_code=1
-
-.PHONY: lint
-lint:
- @echo "==> Running linters"
- @gometalinter.v1 \
- --disable-all \
- --enable golint \
- --vendor \
- --deadline 60s \
- ./... || :
diff --git a/vendor/github.com/Masterminds/semver/README.md b/vendor/github.com/Masterminds/semver/README.md
deleted file mode 100644
index 1b52d2f43..000000000
--- a/vendor/github.com/Masterminds/semver/README.md
+++ /dev/null
@@ -1,194 +0,0 @@
-# SemVer
-
-The `semver` package provides the ability to work with [Semantic Versions](http://semver.org) in Go. Specifically it provides the ability to:
-
-* Parse semantic versions
-* Sort semantic versions
-* Check if a semantic version fits within a set of constraints
-* Optionally work with a `v` prefix
-
-[](https://masterminds.github.io/stability/active.html)
-[](https://travis-ci.org/Masterminds/semver) [](https://ci.appveyor.com/project/mattfarina/semver/branch/master) [](https://godoc.org/github.com/Masterminds/semver) [](https://goreportcard.com/report/github.com/Masterminds/semver)
-
-If you are looking for a command line tool for version comparisons please see
-[vert](https://github.com/Masterminds/vert) which uses this library.
-
-## Parsing Semantic Versions
-
-To parse a semantic version use the `NewVersion` function. For example,
-
-```go
- v, err := semver.NewVersion("1.2.3-beta.1+build345")
-```
-
-If there is an error the version wasn't parseable. The version object has methods
-to get the parts of the version, compare it to other versions, convert the
-version back into a string, and get the original string. For more details
-please see the [documentation](https://godoc.org/github.com/Masterminds/semver).
-
-## Sorting Semantic Versions
-
-A set of versions can be sorted using the [`sort`](https://golang.org/pkg/sort/)
-package from the standard library. For example,
-
-```go
- raw := []string{"1.2.3", "1.0", "1.3", "2", "0.4.2",}
- vs := make([]*semver.Version, len(raw))
- for i, r := range raw {
- v, err := semver.NewVersion(r)
- if err != nil {
- t.Errorf("Error parsing version: %s", err)
- }
-
- vs[i] = v
- }
-
- sort.Sort(semver.Collection(vs))
-```
-
-## Checking Version Constraints
-
-Checking a version against version constraints is one of the most featureful
-parts of the package.
-
-```go
- c, err := semver.NewConstraint(">= 1.2.3")
- if err != nil {
- // Handle constraint not being parseable.
- }
-
- v, _ := semver.NewVersion("1.3")
- if err != nil {
- // Handle version not being parseable.
- }
- // Check if the version meets the constraints. The a variable will be true.
- a := c.Check(v)
-```
-
-## Basic Comparisons
-
-There are two elements to the comparisons. First, a comparison string is a list
-of comma separated and comparisons. These are then separated by || separated or
-comparisons. For example, `">= 1.2, < 3.0.0 || >= 4.2.3"` is looking for a
-comparison that's greater than or equal to 1.2 and less than 3.0.0 or is
-greater than or equal to 4.2.3.
-
-The basic comparisons are:
-
-* `=`: equal (aliased to no operator)
-* `!=`: not equal
-* `>`: greater than
-* `<`: less than
-* `>=`: greater than or equal to
-* `<=`: less than or equal to
-
-## Working With Pre-release Versions
-
-Pre-releases, for those not familiar with them, are used for software releases
-prior to stable or generally available releases. Examples of pre-releases include
-development, alpha, beta, and release candidate releases. A pre-release may be
-a version such as `1.2.3-beta.1` while the stable release would be `1.2.3`. In the
-order of precidence, pre-releases come before their associated releases. In this
-example `1.2.3-beta.1 < 1.2.3`.
-
-According to the Semantic Version specification pre-releases may not be
-API compliant with their release counterpart. It says,
-
-> A pre-release version indicates that the version is unstable and might not satisfy the intended compatibility requirements as denoted by its associated normal version.
-
-SemVer comparisons without a pre-release comparator will skip pre-release versions.
-For example, `>=1.2.3` will skip pre-releases when looking at a list of releases
-while `>=1.2.3-0` will evaluate and find pre-releases.
-
-The reason for the `0` as a pre-release version in the example comparison is
-because pre-releases can only contain ASCII alphanumerics and hyphens (along with
-`.` separators), per the spec. Sorting happens in ASCII sort order, again per the spec. The lowest character is a `0` in ASCII sort order (see an [ASCII Table](http://www.asciitable.com/))
-
-Understanding ASCII sort ordering is important because A-Z comes before a-z. That
-means `>=1.2.3-BETA` will return `1.2.3-alpha`. What you might expect from case
-sensitivity doesn't apply here. This is due to ASCII sort ordering which is what
-the spec specifies.
-
-## Hyphen Range Comparisons
-
-There are multiple methods to handle ranges and the first is hyphens ranges.
-These look like:
-
-* `1.2 - 1.4.5` which is equivalent to `>= 1.2, <= 1.4.5`
-* `2.3.4 - 4.5` which is equivalent to `>= 2.3.4, <= 4.5`
-
-## Wildcards In Comparisons
-
-The `x`, `X`, and `*` characters can be used as a wildcard character. This works
-for all comparison operators. When used on the `=` operator it falls
-back to the pack level comparison (see tilde below). For example,
-
-* `1.2.x` is equivalent to `>= 1.2.0, < 1.3.0`
-* `>= 1.2.x` is equivalent to `>= 1.2.0`
-* `<= 2.x` is equivalent to `< 3`
-* `*` is equivalent to `>= 0.0.0`
-
-## Tilde Range Comparisons (Patch)
-
-The tilde (`~`) comparison operator is for patch level ranges when a minor
-version is specified and major level changes when the minor number is missing.
-For example,
-
-* `~1.2.3` is equivalent to `>= 1.2.3, < 1.3.0`
-* `~1` is equivalent to `>= 1, < 2`
-* `~2.3` is equivalent to `>= 2.3, < 2.4`
-* `~1.2.x` is equivalent to `>= 1.2.0, < 1.3.0`
-* `~1.x` is equivalent to `>= 1, < 2`
-
-## Caret Range Comparisons (Major)
-
-The caret (`^`) comparison operator is for major level changes. This is useful
-when comparisons of API versions as a major change is API breaking. For example,
-
-* `^1.2.3` is equivalent to `>= 1.2.3, < 2.0.0`
-* `^0.0.1` is equivalent to `>= 0.0.1, < 1.0.0`
-* `^1.2.x` is equivalent to `>= 1.2.0, < 2.0.0`
-* `^2.3` is equivalent to `>= 2.3, < 3`
-* `^2.x` is equivalent to `>= 2.0.0, < 3`
-
-# Validation
-
-In addition to testing a version against a constraint, a version can be validated
-against a constraint. When validation fails a slice of errors containing why a
-version didn't meet the constraint is returned. For example,
-
-```go
- c, err := semver.NewConstraint("<= 1.2.3, >= 1.4")
- if err != nil {
- // Handle constraint not being parseable.
- }
-
- v, _ := semver.NewVersion("1.3")
- if err != nil {
- // Handle version not being parseable.
- }
-
- // Validate a version against a constraint.
- a, msgs := c.Validate(v)
- // a is false
- for _, m := range msgs {
- fmt.Println(m)
-
- // Loops over the errors which would read
- // "1.3 is greater than 1.2.3"
- // "1.3 is less than 1.4"
- }
-```
-
-# Fuzzing
-
- [dvyukov/go-fuzz](https://github.com/dvyukov/go-fuzz) is used for fuzzing.
-
-1. `go-fuzz-build`
-2. `go-fuzz -workdir=fuzz`
-
-# Contribute
-
-If you find an issue or want to contribute please file an [issue](https://github.com/Masterminds/semver/issues)
-or [create a pull request](https://github.com/Masterminds/semver/pulls).
diff --git a/vendor/github.com/Masterminds/semver/appveyor.yml b/vendor/github.com/Masterminds/semver/appveyor.yml
deleted file mode 100644
index b2778df15..000000000
--- a/vendor/github.com/Masterminds/semver/appveyor.yml
+++ /dev/null
@@ -1,44 +0,0 @@
-version: build-{build}.{branch}
-
-clone_folder: C:\gopath\src\github.com\Masterminds\semver
-shallow_clone: true
-
-environment:
- GOPATH: C:\gopath
-
-platform:
- - x64
-
-install:
- - go version
- - go env
- - go get -u gopkg.in/alecthomas/gometalinter.v1
- - set PATH=%PATH%;%GOPATH%\bin
- - gometalinter.v1.exe --install
-
-build_script:
- - go install -v ./...
-
-test_script:
- - "gometalinter.v1 \
- --disable-all \
- --enable deadcode \
- --severity deadcode:error \
- --enable gofmt \
- --enable gosimple \
- --enable ineffassign \
- --enable misspell \
- --enable vet \
- --tests \
- --vendor \
- --deadline 60s \
- ./... || exit_code=1"
- - "gometalinter.v1 \
- --disable-all \
- --enable golint \
- --vendor \
- --deadline 60s \
- ./... || :"
- - go test -v
-
-deploy: off
diff --git a/vendor/github.com/Masterminds/semver/collection.go b/vendor/github.com/Masterminds/semver/collection.go
deleted file mode 100644
index a78235895..000000000
--- a/vendor/github.com/Masterminds/semver/collection.go
+++ /dev/null
@@ -1,24 +0,0 @@
-package semver
-
-// Collection is a collection of Version instances and implements the sort
-// interface. See the sort package for more details.
-// https://golang.org/pkg/sort/
-type Collection []*Version
-
-// Len returns the length of a collection. The number of Version instances
-// on the slice.
-func (c Collection) Len() int {
- return len(c)
-}
-
-// Less is needed for the sort interface to compare two Version objects on the
-// slice. If checks if one is less than the other.
-func (c Collection) Less(i, j int) bool {
- return c[i].LessThan(c[j])
-}
-
-// Swap is needed for the sort interface to replace the Version objects
-// at two different positions in the slice.
-func (c Collection) Swap(i, j int) {
- c[i], c[j] = c[j], c[i]
-}
diff --git a/vendor/github.com/Masterminds/semver/constraints.go b/vendor/github.com/Masterminds/semver/constraints.go
deleted file mode 100644
index b94b93413..000000000
--- a/vendor/github.com/Masterminds/semver/constraints.go
+++ /dev/null
@@ -1,423 +0,0 @@
-package semver
-
-import (
- "errors"
- "fmt"
- "regexp"
- "strings"
-)
-
-// Constraints is one or more constraint that a semantic version can be
-// checked against.
-type Constraints struct {
- constraints [][]*constraint
-}
-
-// NewConstraint returns a Constraints instance that a Version instance can
-// be checked against. If there is a parse error it will be returned.
-func NewConstraint(c string) (*Constraints, error) {
-
- // Rewrite - ranges into a comparison operation.
- c = rewriteRange(c)
-
- ors := strings.Split(c, "||")
- or := make([][]*constraint, len(ors))
- for k, v := range ors {
- cs := strings.Split(v, ",")
- result := make([]*constraint, len(cs))
- for i, s := range cs {
- pc, err := parseConstraint(s)
- if err != nil {
- return nil, err
- }
-
- result[i] = pc
- }
- or[k] = result
- }
-
- o := &Constraints{constraints: or}
- return o, nil
-}
-
-// Check tests if a version satisfies the constraints.
-func (cs Constraints) Check(v *Version) bool {
- // loop over the ORs and check the inner ANDs
- for _, o := range cs.constraints {
- joy := true
- for _, c := range o {
- if !c.check(v) {
- joy = false
- break
- }
- }
-
- if joy {
- return true
- }
- }
-
- return false
-}
-
-// Validate checks if a version satisfies a constraint. If not a slice of
-// reasons for the failure are returned in addition to a bool.
-func (cs Constraints) Validate(v *Version) (bool, []error) {
- // loop over the ORs and check the inner ANDs
- var e []error
-
- // Capture the prerelease message only once. When it happens the first time
- // this var is marked
- var prerelesase bool
- for _, o := range cs.constraints {
- joy := true
- for _, c := range o {
- // Before running the check handle the case there the version is
- // a prerelease and the check is not searching for prereleases.
- if c.con.pre == "" && v.pre != "" {
- if !prerelesase {
- em := fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v)
- e = append(e, em)
- prerelesase = true
- }
- joy = false
-
- } else {
-
- if !c.check(v) {
- em := fmt.Errorf(c.msg, v, c.orig)
- e = append(e, em)
- joy = false
- }
- }
- }
-
- if joy {
- return true, []error{}
- }
- }
-
- return false, e
-}
-
-var constraintOps map[string]cfunc
-var constraintMsg map[string]string
-var constraintRegex *regexp.Regexp
-
-func init() {
- constraintOps = map[string]cfunc{
- "": constraintTildeOrEqual,
- "=": constraintTildeOrEqual,
- "!=": constraintNotEqual,
- ">": constraintGreaterThan,
- "<": constraintLessThan,
- ">=": constraintGreaterThanEqual,
- "=>": constraintGreaterThanEqual,
- "<=": constraintLessThanEqual,
- "=<": constraintLessThanEqual,
- "~": constraintTilde,
- "~>": constraintTilde,
- "^": constraintCaret,
- }
-
- constraintMsg = map[string]string{
- "": "%s is not equal to %s",
- "=": "%s is not equal to %s",
- "!=": "%s is equal to %s",
- ">": "%s is less than or equal to %s",
- "<": "%s is greater than or equal to %s",
- ">=": "%s is less than %s",
- "=>": "%s is less than %s",
- "<=": "%s is greater than %s",
- "=<": "%s is greater than %s",
- "~": "%s does not have same major and minor version as %s",
- "~>": "%s does not have same major and minor version as %s",
- "^": "%s does not have same major version as %s",
- }
-
- ops := make([]string, 0, len(constraintOps))
- for k := range constraintOps {
- ops = append(ops, regexp.QuoteMeta(k))
- }
-
- constraintRegex = regexp.MustCompile(fmt.Sprintf(
- `^\s*(%s)\s*(%s)\s*$`,
- strings.Join(ops, "|"),
- cvRegex))
-
- constraintRangeRegex = regexp.MustCompile(fmt.Sprintf(
- `\s*(%s)\s+-\s+(%s)\s*`,
- cvRegex, cvRegex))
-}
-
-// An individual constraint
-type constraint struct {
- // The callback function for the restraint. It performs the logic for
- // the constraint.
- function cfunc
-
- msg string
-
- // The version used in the constraint check. For example, if a constraint
- // is '<= 2.0.0' the con a version instance representing 2.0.0.
- con *Version
-
- // The original parsed version (e.g., 4.x from != 4.x)
- orig string
-
- // When an x is used as part of the version (e.g., 1.x)
- minorDirty bool
- dirty bool
- patchDirty bool
-}
-
-// Check if a version meets the constraint
-func (c *constraint) check(v *Version) bool {
- return c.function(v, c)
-}
-
-type cfunc func(v *Version, c *constraint) bool
-
-func parseConstraint(c string) (*constraint, error) {
- m := constraintRegex.FindStringSubmatch(c)
- if m == nil {
- return nil, fmt.Errorf("improper constraint: %s", c)
- }
-
- ver := m[2]
- orig := ver
- minorDirty := false
- patchDirty := false
- dirty := false
- if isX(m[3]) {
- ver = "0.0.0"
- dirty = true
- } else if isX(strings.TrimPrefix(m[4], ".")) || m[4] == "" {
- minorDirty = true
- dirty = true
- ver = fmt.Sprintf("%s.0.0%s", m[3], m[6])
- } else if isX(strings.TrimPrefix(m[5], ".")) {
- dirty = true
- patchDirty = true
- ver = fmt.Sprintf("%s%s.0%s", m[3], m[4], m[6])
- }
-
- con, err := NewVersion(ver)
- if err != nil {
-
- // The constraintRegex should catch any regex parsing errors. So,
- // we should never get here.
- return nil, errors.New("constraint Parser Error")
- }
-
- cs := &constraint{
- function: constraintOps[m[1]],
- msg: constraintMsg[m[1]],
- con: con,
- orig: orig,
- minorDirty: minorDirty,
- patchDirty: patchDirty,
- dirty: dirty,
- }
- return cs, nil
-}
-
-// Constraint functions
-func constraintNotEqual(v *Version, c *constraint) bool {
- if c.dirty {
-
- // If there is a pre-release on the version but the constraint isn't looking
- // for them assume that pre-releases are not compatible. See issue 21 for
- // more details.
- if v.Prerelease() != "" && c.con.Prerelease() == "" {
- return false
- }
-
- if c.con.Major() != v.Major() {
- return true
- }
- if c.con.Minor() != v.Minor() && !c.minorDirty {
- return true
- } else if c.minorDirty {
- return false
- }
-
- return false
- }
-
- return !v.Equal(c.con)
-}
-
-func constraintGreaterThan(v *Version, c *constraint) bool {
-
- // If there is a pre-release on the version but the constraint isn't looking
- // for them assume that pre-releases are not compatible. See issue 21 for
- // more details.
- if v.Prerelease() != "" && c.con.Prerelease() == "" {
- return false
- }
-
- return v.Compare(c.con) == 1
-}
-
-func constraintLessThan(v *Version, c *constraint) bool {
- // If there is a pre-release on the version but the constraint isn't looking
- // for them assume that pre-releases are not compatible. See issue 21 for
- // more details.
- if v.Prerelease() != "" && c.con.Prerelease() == "" {
- return false
- }
-
- if !c.dirty {
- return v.Compare(c.con) < 0
- }
-
- if v.Major() > c.con.Major() {
- return false
- } else if v.Minor() > c.con.Minor() && !c.minorDirty {
- return false
- }
-
- return true
-}
-
-func constraintGreaterThanEqual(v *Version, c *constraint) bool {
-
- // If there is a pre-release on the version but the constraint isn't looking
- // for them assume that pre-releases are not compatible. See issue 21 for
- // more details.
- if v.Prerelease() != "" && c.con.Prerelease() == "" {
- return false
- }
-
- return v.Compare(c.con) >= 0
-}
-
-func constraintLessThanEqual(v *Version, c *constraint) bool {
- // If there is a pre-release on the version but the constraint isn't looking
- // for them assume that pre-releases are not compatible. See issue 21 for
- // more details.
- if v.Prerelease() != "" && c.con.Prerelease() == "" {
- return false
- }
-
- if !c.dirty {
- return v.Compare(c.con) <= 0
- }
-
- if v.Major() > c.con.Major() {
- return false
- } else if v.Minor() > c.con.Minor() && !c.minorDirty {
- return false
- }
-
- return true
-}
-
-// ~*, ~>* --> >= 0.0.0 (any)
-// ~2, ~2.x, ~2.x.x, ~>2, ~>2.x ~>2.x.x --> >=2.0.0, <3.0.0
-// ~2.0, ~2.0.x, ~>2.0, ~>2.0.x --> >=2.0.0, <2.1.0
-// ~1.2, ~1.2.x, ~>1.2, ~>1.2.x --> >=1.2.0, <1.3.0
-// ~1.2.3, ~>1.2.3 --> >=1.2.3, <1.3.0
-// ~1.2.0, ~>1.2.0 --> >=1.2.0, <1.3.0
-func constraintTilde(v *Version, c *constraint) bool {
- // If there is a pre-release on the version but the constraint isn't looking
- // for them assume that pre-releases are not compatible. See issue 21 for
- // more details.
- if v.Prerelease() != "" && c.con.Prerelease() == "" {
- return false
- }
-
- if v.LessThan(c.con) {
- return false
- }
-
- // ~0.0.0 is a special case where all constraints are accepted. It's
- // equivalent to >= 0.0.0.
- if c.con.Major() == 0 && c.con.Minor() == 0 && c.con.Patch() == 0 &&
- !c.minorDirty && !c.patchDirty {
- return true
- }
-
- if v.Major() != c.con.Major() {
- return false
- }
-
- if v.Minor() != c.con.Minor() && !c.minorDirty {
- return false
- }
-
- return true
-}
-
-// When there is a .x (dirty) status it automatically opts in to ~. Otherwise
-// it's a straight =
-func constraintTildeOrEqual(v *Version, c *constraint) bool {
- // If there is a pre-release on the version but the constraint isn't looking
- // for them assume that pre-releases are not compatible. See issue 21 for
- // more details.
- if v.Prerelease() != "" && c.con.Prerelease() == "" {
- return false
- }
-
- if c.dirty {
- c.msg = constraintMsg["~"]
- return constraintTilde(v, c)
- }
-
- return v.Equal(c.con)
-}
-
-// ^* --> (any)
-// ^2, ^2.x, ^2.x.x --> >=2.0.0, <3.0.0
-// ^2.0, ^2.0.x --> >=2.0.0, <3.0.0
-// ^1.2, ^1.2.x --> >=1.2.0, <2.0.0
-// ^1.2.3 --> >=1.2.3, <2.0.0
-// ^1.2.0 --> >=1.2.0, <2.0.0
-func constraintCaret(v *Version, c *constraint) bool {
- // If there is a pre-release on the version but the constraint isn't looking
- // for them assume that pre-releases are not compatible. See issue 21 for
- // more details.
- if v.Prerelease() != "" && c.con.Prerelease() == "" {
- return false
- }
-
- if v.LessThan(c.con) {
- return false
- }
-
- if v.Major() != c.con.Major() {
- return false
- }
-
- return true
-}
-
-var constraintRangeRegex *regexp.Regexp
-
-const cvRegex string = `v?([0-9|x|X|\*]+)(\.[0-9|x|X|\*]+)?(\.[0-9|x|X|\*]+)?` +
- `(-([0-9A-Za-z\-]+(\.[0-9A-Za-z\-]+)*))?` +
- `(\+([0-9A-Za-z\-]+(\.[0-9A-Za-z\-]+)*))?`
-
-func isX(x string) bool {
- switch x {
- case "x", "*", "X":
- return true
- default:
- return false
- }
-}
-
-func rewriteRange(i string) string {
- m := constraintRangeRegex.FindAllStringSubmatch(i, -1)
- if m == nil {
- return i
- }
- o := i
- for _, v := range m {
- t := fmt.Sprintf(">= %s, <= %s", v[1], v[11])
- o = strings.Replace(o, v[0], t, 1)
- }
-
- return o
-}
diff --git a/vendor/github.com/Masterminds/semver/doc.go b/vendor/github.com/Masterminds/semver/doc.go
deleted file mode 100644
index 6a6c24c6d..000000000
--- a/vendor/github.com/Masterminds/semver/doc.go
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
-Package semver provides the ability to work with Semantic Versions (http://semver.org) in Go.
-
-Specifically it provides the ability to:
-
- * Parse semantic versions
- * Sort semantic versions
- * Check if a semantic version fits within a set of constraints
- * Optionally work with a `v` prefix
-
-Parsing Semantic Versions
-
-To parse a semantic version use the `NewVersion` function. For example,
-
- v, err := semver.NewVersion("1.2.3-beta.1+build345")
-
-If there is an error the version wasn't parseable. The version object has methods
-to get the parts of the version, compare it to other versions, convert the
-version back into a string, and get the original string. For more details
-please see the documentation at https://godoc.org/github.com/Masterminds/semver.
-
-Sorting Semantic Versions
-
-A set of versions can be sorted using the `sort` package from the standard library.
-For example,
-
- raw := []string{"1.2.3", "1.0", "1.3", "2", "0.4.2",}
- vs := make([]*semver.Version, len(raw))
- for i, r := range raw {
- v, err := semver.NewVersion(r)
- if err != nil {
- t.Errorf("Error parsing version: %s", err)
- }
-
- vs[i] = v
- }
-
- sort.Sort(semver.Collection(vs))
-
-Checking Version Constraints
-
-Checking a version against version constraints is one of the most featureful
-parts of the package.
-
- c, err := semver.NewConstraint(">= 1.2.3")
- if err != nil {
- // Handle constraint not being parseable.
- }
-
- v, err := semver.NewVersion("1.3")
- if err != nil {
- // Handle version not being parseable.
- }
- // Check if the version meets the constraints. The a variable will be true.
- a := c.Check(v)
-
-Basic Comparisons
-
-There are two elements to the comparisons. First, a comparison string is a list
-of comma separated and comparisons. These are then separated by || separated or
-comparisons. For example, `">= 1.2, < 3.0.0 || >= 4.2.3"` is looking for a
-comparison that's greater than or equal to 1.2 and less than 3.0.0 or is
-greater than or equal to 4.2.3.
-
-The basic comparisons are:
-
- * `=`: equal (aliased to no operator)
- * `!=`: not equal
- * `>`: greater than
- * `<`: less than
- * `>=`: greater than or equal to
- * `<=`: less than or equal to
-
-Hyphen Range Comparisons
-
-There are multiple methods to handle ranges and the first is hyphens ranges.
-These look like:
-
- * `1.2 - 1.4.5` which is equivalent to `>= 1.2, <= 1.4.5`
- * `2.3.4 - 4.5` which is equivalent to `>= 2.3.4, <= 4.5`
-
-Wildcards In Comparisons
-
-The `x`, `X`, and `*` characters can be used as a wildcard character. This works
-for all comparison operators. When used on the `=` operator it falls
-back to the pack level comparison (see tilde below). For example,
-
- * `1.2.x` is equivalent to `>= 1.2.0, < 1.3.0`
- * `>= 1.2.x` is equivalent to `>= 1.2.0`
- * `<= 2.x` is equivalent to `<= 3`
- * `*` is equivalent to `>= 0.0.0`
-
-Tilde Range Comparisons (Patch)
-
-The tilde (`~`) comparison operator is for patch level ranges when a minor
-version is specified and major level changes when the minor number is missing.
-For example,
-
- * `~1.2.3` is equivalent to `>= 1.2.3, < 1.3.0`
- * `~1` is equivalent to `>= 1, < 2`
- * `~2.3` is equivalent to `>= 2.3, < 2.4`
- * `~1.2.x` is equivalent to `>= 1.2.0, < 1.3.0`
- * `~1.x` is equivalent to `>= 1, < 2`
-
-Caret Range Comparisons (Major)
-
-The caret (`^`) comparison operator is for major level changes. This is useful
-when comparisons of API versions as a major change is API breaking. For example,
-
- * `^1.2.3` is equivalent to `>= 1.2.3, < 2.0.0`
- * `^1.2.x` is equivalent to `>= 1.2.0, < 2.0.0`
- * `^2.3` is equivalent to `>= 2.3, < 3`
- * `^2.x` is equivalent to `>= 2.0.0, < 3`
-*/
-package semver
diff --git a/vendor/github.com/Masterminds/semver/v3/.gitignore b/vendor/github.com/Masterminds/semver/v3/.gitignore
index 6b061e617..35f0e5a3a 100644
--- a/vendor/github.com/Masterminds/semver/v3/.gitignore
+++ b/vendor/github.com/Masterminds/semver/v3/.gitignore
@@ -1 +1,2 @@
-_fuzz/
\ No newline at end of file
+_fuzz/
+.devcontainer/
\ No newline at end of file
diff --git a/vendor/github.com/Masterminds/semver/v3/.golangci.yml b/vendor/github.com/Masterminds/semver/v3/.golangci.yml
index fbc633259..24277f3ac 100644
--- a/vendor/github.com/Masterminds/semver/v3/.golangci.yml
+++ b/vendor/github.com/Masterminds/semver/v3/.golangci.yml
@@ -1,27 +1,42 @@
-run:
- deadline: 2m
-
+version: "2"
linters:
- disable-all: true
+ default: none
enable:
- - misspell
- - govet
- - staticcheck
+ - dupl
- errcheck
- - unparam
+ - gocyclo
+ - gosec
+ - govet
- ineffassign
+ - misspell
- nakedret
- - gocyclo
- - dupl
- - goimports
- revive
- - gosec
- - gosimple
- - typecheck
+ - staticcheck
+ - unparam
- unused
-
-linters-settings:
- gofmt:
- simplify: true
- dupl:
- threshold: 600
+ settings:
+ dupl:
+ threshold: 600
+ exclusions:
+ generated: lax
+ presets:
+ - comments
+ - common-false-positives
+ - legacy
+ - std-error-handling
+ paths:
+ - third_party$
+ - builtin$
+ - examples$
+formatters:
+ enable:
+ - goimports
+ settings:
+ gofmt:
+ simplify: true
+ exclusions:
+ generated: lax
+ paths:
+ - third_party$
+ - builtin$
+ - examples$
diff --git a/vendor/github.com/Masterminds/semver/v3/constraints.go b/vendor/github.com/Masterminds/semver/v3/constraints.go
index 8b7a10f83..e8353bc46 100644
--- a/vendor/github.com/Masterminds/semver/v3/constraints.go
+++ b/vendor/github.com/Masterminds/semver/v3/constraints.go
@@ -21,21 +21,43 @@ type Constraints struct {
IncludePrerelease bool
}
+// MaxConstraintLen is the maximum allowed length of a constraint string.
+const MaxConstraintLen = 512
+
+// MaxConstraintGroups is the maximum number of OR groups allowed in a
+// constraint string.
+const MaxConstraintGroups = 32
+
+// ErrConstraintTooLong is returned when a constraint string exceeds the
+// maximum allowed length.
+var ErrConstraintTooLong = fmt.Errorf("constraint string is too long (max %d bytes)", MaxConstraintLen)
+
+// ErrTooManyConstraintGroups is returned when a constraint string contains
+// too many OR groups.
+var ErrTooManyConstraintGroups = fmt.Errorf("too many constraint groups (max %d)", MaxConstraintGroups)
+
// NewConstraint returns a Constraints instance that a Version instance can
// be checked against. If there is a parse error it will be returned.
func NewConstraint(c string) (*Constraints, error) {
+ if len(c) > MaxConstraintLen {
+ return nil, ErrConstraintTooLong
+ }
+
// Rewrite - ranges into a comparison operation.
c = rewriteRange(c)
ors := strings.Split(c, "||")
+ if len(ors) > MaxConstraintGroups {
+ return nil, ErrTooManyConstraintGroups
+ }
lenors := len(ors)
or := make([][]*constraint, lenors)
hasPre := make([]bool, lenors)
for k, v := range ors {
// Validate the segment
if !validConstraintRegex.MatchString(v) {
- return nil, fmt.Errorf("improper constraint: %s", v)
+ return nil, fmt.Errorf("improper constraint: %q", v)
}
cs := findConstraintRegex.FindAllString(v, -1)
@@ -104,9 +126,9 @@ func (cs Constraints) Validate(v *Version) (bool, []error) {
for _, c := range o {
// Before running the check handle the case there the version is
// a prerelease and the check is not searching for prereleases.
- if !(cs.IncludePrerelease || cs.containsPre[i]) && v.pre != "" {
+ if !cs.IncludePrerelease && !cs.containsPre[i] && v.pre != "" {
if !prerelesase {
- em := fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v)
+ em := fmt.Errorf("%q is a prerelease version and the constraint is only looking for release versions", v)
e = append(e, em)
prerelesase = true
}
@@ -258,7 +280,7 @@ func parseConstraint(c string) (*constraint, error) {
if len(c) > 0 {
m := constraintRegex.FindStringSubmatch(c)
if m == nil {
- return nil, fmt.Errorf("improper constraint: %s", c)
+ return nil, fmt.Errorf("improper constraint: %q", c)
}
cs := &constraint{
@@ -325,7 +347,7 @@ func constraintNotEqual(v *Version, c *constraint, includePre bool) (bool, error
// The existence of prereleases is checked at the group level and passed in.
// Exit early if the version has a prerelease but those are to be ignored.
if v.Prerelease() != "" && !includePre {
- return false, fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v)
+ return false, fmt.Errorf("%q is a prerelease version and the constraint is only looking for release versions", v)
}
if c.dirty {
@@ -335,7 +357,7 @@ func constraintNotEqual(v *Version, c *constraint, includePre bool) (bool, error
if c.con.Minor() != v.Minor() && !c.minorDirty {
return true, nil
} else if c.minorDirty {
- return false, fmt.Errorf("%s is equal to %s", v, c.orig)
+ return false, fmt.Errorf("%q is equal to %q", v, c.orig)
} else if c.con.Patch() != v.Patch() && !c.patchDirty {
return true, nil
} else if c.patchDirty {
@@ -345,15 +367,15 @@ func constraintNotEqual(v *Version, c *constraint, includePre bool) (bool, error
if eq {
return true, nil
}
- return false, fmt.Errorf("%s is equal to %s", v, c.orig)
+ return false, fmt.Errorf("%q is equal to %q", v, c.orig)
}
- return false, fmt.Errorf("%s is equal to %s", v, c.orig)
+ return false, fmt.Errorf("%q is equal to %q", v, c.orig)
}
}
eq := v.Equal(c.con)
if eq {
- return false, fmt.Errorf("%s is equal to %s", v, c.orig)
+ return false, fmt.Errorf("%q is equal to %q", v, c.orig)
}
return true, nil
@@ -364,7 +386,7 @@ func constraintGreaterThan(v *Version, c *constraint, includePre bool) (bool, er
// The existence of prereleases is checked at the group level and passed in.
// Exit early if the version has a prerelease but those are to be ignored.
if v.Prerelease() != "" && !includePre {
- return false, fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v)
+ return false, fmt.Errorf("%q is a prerelease version and the constraint is only looking for release versions", v)
}
var eq bool
@@ -374,17 +396,17 @@ func constraintGreaterThan(v *Version, c *constraint, includePre bool) (bool, er
if eq {
return true, nil
}
- return false, fmt.Errorf("%s is less than or equal to %s", v, c.orig)
+ return false, fmt.Errorf("%q is less than or equal to %q", v, c.orig)
}
if v.Major() > c.con.Major() {
return true, nil
} else if v.Major() < c.con.Major() {
- return false, fmt.Errorf("%s is less than or equal to %s", v, c.orig)
+ return false, fmt.Errorf("%q is less than or equal to %q", v, c.orig)
} else if c.minorDirty {
// This is a range case such as >11. When the version is something like
// 11.1.0 is it not > 11. For that we would need 12 or higher
- return false, fmt.Errorf("%s is less than or equal to %s", v, c.orig)
+ return false, fmt.Errorf("%q is less than or equal to %q", v, c.orig)
} else if c.patchDirty {
// This is for ranges such as >11.1. A version of 11.1.1 is not greater
// which one of 11.2.1 is greater
@@ -392,7 +414,7 @@ func constraintGreaterThan(v *Version, c *constraint, includePre bool) (bool, er
if eq {
return true, nil
}
- return false, fmt.Errorf("%s is less than or equal to %s", v, c.orig)
+ return false, fmt.Errorf("%q is less than or equal to %q", v, c.orig)
}
// If we have gotten here we are not comparing pre-preleases and can use the
@@ -401,21 +423,21 @@ func constraintGreaterThan(v *Version, c *constraint, includePre bool) (bool, er
if eq {
return true, nil
}
- return false, fmt.Errorf("%s is less than or equal to %s", v, c.orig)
+ return false, fmt.Errorf("%q is less than or equal to %q", v, c.orig)
}
func constraintLessThan(v *Version, c *constraint, includePre bool) (bool, error) {
// The existence of prereleases is checked at the group level and passed in.
// Exit early if the version has a prerelease but those are to be ignored.
if v.Prerelease() != "" && !includePre {
- return false, fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v)
+ return false, fmt.Errorf("%q is a prerelease version and the constraint is only looking for release versions", v)
}
eq := v.Compare(c.con) < 0
if eq {
return true, nil
}
- return false, fmt.Errorf("%s is greater than or equal to %s", v, c.orig)
+ return false, fmt.Errorf("%q is greater than or equal to %q", v, c.orig)
}
func constraintGreaterThanEqual(v *Version, c *constraint, includePre bool) (bool, error) {
@@ -423,21 +445,21 @@ func constraintGreaterThanEqual(v *Version, c *constraint, includePre bool) (boo
// The existence of prereleases is checked at the group level and passed in.
// Exit early if the version has a prerelease but those are to be ignored.
if v.Prerelease() != "" && !includePre {
- return false, fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v)
+ return false, fmt.Errorf("%q is a prerelease version and the constraint is only looking for release versions", v)
}
eq := v.Compare(c.con) >= 0
if eq {
return true, nil
}
- return false, fmt.Errorf("%s is less than %s", v, c.orig)
+ return false, fmt.Errorf("%q is less than %q", v, c.orig)
}
func constraintLessThanEqual(v *Version, c *constraint, includePre bool) (bool, error) {
// The existence of prereleases is checked at the group level and passed in.
// Exit early if the version has a prerelease but those are to be ignored.
if v.Prerelease() != "" && !includePre {
- return false, fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v)
+ return false, fmt.Errorf("%q is a prerelease version and the constraint is only looking for release versions", v)
}
var eq bool
@@ -447,13 +469,13 @@ func constraintLessThanEqual(v *Version, c *constraint, includePre bool) (bool,
if eq {
return true, nil
}
- return false, fmt.Errorf("%s is greater than %s", v, c.orig)
+ return false, fmt.Errorf("%q is greater than %q", v, c.orig)
}
if v.Major() > c.con.Major() {
- return false, fmt.Errorf("%s is greater than %s", v, c.orig)
+ return false, fmt.Errorf("%q is greater than %q", v, c.orig)
} else if v.Major() == c.con.Major() && v.Minor() > c.con.Minor() && !c.minorDirty {
- return false, fmt.Errorf("%s is greater than %s", v, c.orig)
+ return false, fmt.Errorf("%q is greater than %q", v, c.orig)
}
return true, nil
@@ -469,11 +491,11 @@ func constraintTilde(v *Version, c *constraint, includePre bool) (bool, error) {
// The existence of prereleases is checked at the group level and passed in.
// Exit early if the version has a prerelease but those are to be ignored.
if v.Prerelease() != "" && !includePre {
- return false, fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v)
+ return false, fmt.Errorf("%q is a prerelease version and the constraint is only looking for release versions", v)
}
if v.LessThan(c.con) {
- return false, fmt.Errorf("%s is less than %s", v, c.orig)
+ return false, fmt.Errorf("%q is less than %q", v, c.orig)
}
// ~0.0.0 is a special case where all constraints are accepted. It's
@@ -484,11 +506,11 @@ func constraintTilde(v *Version, c *constraint, includePre bool) (bool, error) {
}
if v.Major() != c.con.Major() {
- return false, fmt.Errorf("%s does not have same major version as %s", v, c.orig)
+ return false, fmt.Errorf("%q does not have same major version as %q", v, c.orig)
}
if v.Minor() != c.con.Minor() && !c.minorDirty {
- return false, fmt.Errorf("%s does not have same major and minor version as %s", v, c.orig)
+ return false, fmt.Errorf("%q does not have same major and minor version as %q", v, c.orig)
}
return true, nil
@@ -500,7 +522,7 @@ func constraintTildeOrEqual(v *Version, c *constraint, includePre bool) (bool, e
// The existence of prereleases is checked at the group level and passed in.
// Exit early if the version has a prerelease but those are to be ignored.
if v.Prerelease() != "" && !includePre {
- return false, fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v)
+ return false, fmt.Errorf("%q is a prerelease version and the constraint is only looking for release versions", v)
}
if c.dirty {
@@ -512,7 +534,7 @@ func constraintTildeOrEqual(v *Version, c *constraint, includePre bool) (bool, e
return true, nil
}
- return false, fmt.Errorf("%s is not equal to %s", v, c.orig)
+ return false, fmt.Errorf("%q is not equal to %q", v, c.orig)
}
// ^* --> (any)
@@ -528,12 +550,12 @@ func constraintCaret(v *Version, c *constraint, includePre bool) (bool, error) {
// The existence of prereleases is checked at the group level and passed in.
// Exit early if the version has a prerelease but those are to be ignored.
if v.Prerelease() != "" && !includePre {
- return false, fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v)
+ return false, fmt.Errorf("%q is a prerelease version and the constraint is only looking for release versions", v)
}
// This less than handles prereleases
if v.LessThan(c.con) {
- return false, fmt.Errorf("%s is less than %s", v, c.orig)
+ return false, fmt.Errorf("%q is less than %q", v, c.orig)
}
var eq bool
@@ -548,12 +570,12 @@ func constraintCaret(v *Version, c *constraint, includePre bool) (bool, error) {
if eq {
return true, nil
}
- return false, fmt.Errorf("%s does not have same major version as %s", v, c.orig)
+ return false, fmt.Errorf("%q does not have same major version as %q", v, c.orig)
}
// ^ when the major is 0 and minor > 0 is >=0.y.z < 0.y+1
if c.con.Major() == 0 && v.Major() > 0 {
- return false, fmt.Errorf("%s does not have same major version as %s", v, c.orig)
+ return false, fmt.Errorf("%q does not have same major version as %q", v, c.orig)
}
// If the con Minor is > 0 it is not dirty
if c.con.Minor() > 0 || c.patchDirty {
@@ -561,11 +583,11 @@ func constraintCaret(v *Version, c *constraint, includePre bool) (bool, error) {
if eq {
return true, nil
}
- return false, fmt.Errorf("%s does not have same minor version as %s. Expected minor versions to match when constraint major version is 0", v, c.orig)
+ return false, fmt.Errorf("%q does not have same minor version as %q. Expected minor versions to match when constraint major version is 0", v, c.orig)
}
// ^ when the minor is 0 and minor > 0 is =0.0.z
if c.con.Minor() == 0 && v.Minor() > 0 {
- return false, fmt.Errorf("%s does not have same minor version as %s", v, c.orig)
+ return false, fmt.Errorf("%q does not have same minor version as %q", v, c.orig)
}
// At this point the major is 0 and the minor is 0 and not dirty. The patch
@@ -574,7 +596,7 @@ func constraintCaret(v *Version, c *constraint, includePre bool) (bool, error) {
if eq {
return true, nil
}
- return false, fmt.Errorf("%s does not equal %s. Expect version and constraint to equal when major and minor versions are 0", v, c.orig)
+ return false, fmt.Errorf("%q does not equal %q. Expect version and constraint to equal when major and minor versions are 0", v, c.orig)
}
func isX(x string) bool {
diff --git a/vendor/github.com/Masterminds/semver/v3/version.go b/vendor/github.com/Masterminds/semver/v3/version.go
index 7a3ba7388..da428760c 100644
--- a/vendor/github.com/Masterminds/semver/v3/version.go
+++ b/vendor/github.com/Masterminds/semver/v3/version.go
@@ -6,6 +6,7 @@ import (
"encoding/json"
"errors"
"fmt"
+ "math"
"regexp"
"strconv"
"strings"
@@ -48,8 +49,16 @@ var (
// ErrInvalidPrerelease is returned when the pre-release is an invalid format
ErrInvalidPrerelease = errors.New("invalid prerelease string")
+
+ // ErrVersionTooLong is returned when a version string exceeds the
+ // maximum allowed length.
+ ErrVersionTooLong = fmt.Errorf("version string is too long (max %d bytes)", MaxVersionLen)
)
+// MaxVersionLen is the maximum allowed length of a version string. This guards
+// against unbounded input causing excessive memory allocations during parsing.
+const MaxVersionLen = 256
+
// semVerRegex is the regular expression used to parse a semantic version.
// This is not the official regex from the semver spec. It has been modified to allow for loose handling
// where versions like 2.1 are detected.
@@ -94,6 +103,10 @@ func StrictNewVersion(v string) (*Version, error) {
return nil, ErrEmptyString
}
+ if len(v) > MaxVersionLen {
+ return nil, ErrVersionTooLong
+ }
+
// Split the parts into [0]major, [1]minor, and [2]patch,prerelease,build
parts := strings.SplitN(v, ".", 3)
if len(parts) != 3 {
@@ -161,6 +174,9 @@ func StrictNewVersion(v string) (*Version, error) {
// attempts to convert it to SemVer. If you want to validate it was a strict
// semantic version at parse time see StrictNewVersion().
func NewVersion(v string) (*Version, error) {
+ if len(v) > MaxVersionLen {
+ return nil, ErrVersionTooLong
+ }
if CoerceNewVersion {
return coerceNewVersion(v)
}
@@ -289,6 +305,8 @@ func coerceNewVersion(v string) (*Version, error) {
// New creates a new instance of Version with each of the parts passed in as
// arguments instead of parsing a version string.
+// Note, New does not validate prerelease or metadata. Incorrect information can
+// be passed in.
func New(major, minor, patch uint64, pre, metadata string) *Version {
v := Version{
major: major,
@@ -301,6 +319,7 @@ func New(major, minor, patch uint64, pre, metadata string) *Version {
v.original = v.String()
+ // TODO: In the next semver major version validate the pre and metadata. Return error if there is one.
return &v
}
@@ -388,6 +407,9 @@ func (v Version) IncPatch() Version {
} else {
vNext.metadata = ""
vNext.pre = ""
+ if v.patch == math.MaxUint64 {
+ panic("patch version increment would overflow uint64")
+ }
vNext.patch = v.patch + 1
}
vNext.original = v.originalVPrefix() + "" + vNext.String()
@@ -404,6 +426,9 @@ func (v Version) IncMinor() Version {
vNext.metadata = ""
vNext.pre = ""
vNext.patch = 0
+ if v.minor == math.MaxUint64 {
+ panic("minor version increment would overflow uint64")
+ }
vNext.minor = v.minor + 1
vNext.original = v.originalVPrefix() + "" + vNext.String()
return vNext
@@ -421,6 +446,9 @@ func (v Version) IncMajor() Version {
vNext.pre = ""
vNext.patch = 0
vNext.minor = 0
+ if v.major == math.MaxUint64 {
+ panic("major version increment would overflow uint64")
+ }
vNext.major = v.major + 1
vNext.original = v.originalVPrefix() + "" + vNext.String()
return vNext
@@ -568,7 +596,16 @@ func (v Version) MarshalText() ([]byte, error) {
// Scan implements the SQL.Scanner interface.
func (v *Version) Scan(value interface{}) error {
var s string
- s, _ = value.(string)
+ switch t := value.(type) {
+ case string:
+ s = t
+ case []byte:
+ s = string(t)
+ case nil:
+ return fmt.Errorf("cannot scan nil into Version")
+ default:
+ return fmt.Errorf("unsupported Scan type %T", value)
+ }
temp, err := NewVersion(s)
if err != nil {
return err
diff --git a/vendor/github.com/Masterminds/semver/version.go b/vendor/github.com/Masterminds/semver/version.go
deleted file mode 100644
index 400d4f934..000000000
--- a/vendor/github.com/Masterminds/semver/version.go
+++ /dev/null
@@ -1,425 +0,0 @@
-package semver
-
-import (
- "bytes"
- "encoding/json"
- "errors"
- "fmt"
- "regexp"
- "strconv"
- "strings"
-)
-
-// The compiled version of the regex created at init() is cached here so it
-// only needs to be created once.
-var versionRegex *regexp.Regexp
-var validPrereleaseRegex *regexp.Regexp
-
-var (
- // ErrInvalidSemVer is returned a version is found to be invalid when
- // being parsed.
- ErrInvalidSemVer = errors.New("Invalid Semantic Version")
-
- // ErrInvalidMetadata is returned when the metadata is an invalid format
- ErrInvalidMetadata = errors.New("Invalid Metadata string")
-
- // ErrInvalidPrerelease is returned when the pre-release is an invalid format
- ErrInvalidPrerelease = errors.New("Invalid Prerelease string")
-)
-
-// SemVerRegex is the regular expression used to parse a semantic version.
-const SemVerRegex string = `v?([0-9]+)(\.[0-9]+)?(\.[0-9]+)?` +
- `(-([0-9A-Za-z\-]+(\.[0-9A-Za-z\-]+)*))?` +
- `(\+([0-9A-Za-z\-]+(\.[0-9A-Za-z\-]+)*))?`
-
-// ValidPrerelease is the regular expression which validates
-// both prerelease and metadata values.
-const ValidPrerelease string = `^([0-9A-Za-z\-]+(\.[0-9A-Za-z\-]+)*)$`
-
-// Version represents a single semantic version.
-type Version struct {
- major, minor, patch int64
- pre string
- metadata string
- original string
-}
-
-func init() {
- versionRegex = regexp.MustCompile("^" + SemVerRegex + "$")
- validPrereleaseRegex = regexp.MustCompile(ValidPrerelease)
-}
-
-// NewVersion parses a given version and returns an instance of Version or
-// an error if unable to parse the version.
-func NewVersion(v string) (*Version, error) {
- m := versionRegex.FindStringSubmatch(v)
- if m == nil {
- return nil, ErrInvalidSemVer
- }
-
- sv := &Version{
- metadata: m[8],
- pre: m[5],
- original: v,
- }
-
- var temp int64
- temp, err := strconv.ParseInt(m[1], 10, 64)
- if err != nil {
- return nil, fmt.Errorf("Error parsing version segment: %s", err)
- }
- sv.major = temp
-
- if m[2] != "" {
- temp, err = strconv.ParseInt(strings.TrimPrefix(m[2], "."), 10, 64)
- if err != nil {
- return nil, fmt.Errorf("Error parsing version segment: %s", err)
- }
- sv.minor = temp
- } else {
- sv.minor = 0
- }
-
- if m[3] != "" {
- temp, err = strconv.ParseInt(strings.TrimPrefix(m[3], "."), 10, 64)
- if err != nil {
- return nil, fmt.Errorf("Error parsing version segment: %s", err)
- }
- sv.patch = temp
- } else {
- sv.patch = 0
- }
-
- return sv, nil
-}
-
-// MustParse parses a given version and panics on error.
-func MustParse(v string) *Version {
- sv, err := NewVersion(v)
- if err != nil {
- panic(err)
- }
- return sv
-}
-
-// String converts a Version object to a string.
-// Note, if the original version contained a leading v this version will not.
-// See the Original() method to retrieve the original value. Semantic Versions
-// don't contain a leading v per the spec. Instead it's optional on
-// implementation.
-func (v *Version) String() string {
- var buf bytes.Buffer
-
- fmt.Fprintf(&buf, "%d.%d.%d", v.major, v.minor, v.patch)
- if v.pre != "" {
- fmt.Fprintf(&buf, "-%s", v.pre)
- }
- if v.metadata != "" {
- fmt.Fprintf(&buf, "+%s", v.metadata)
- }
-
- return buf.String()
-}
-
-// Original returns the original value passed in to be parsed.
-func (v *Version) Original() string {
- return v.original
-}
-
-// Major returns the major version.
-func (v *Version) Major() int64 {
- return v.major
-}
-
-// Minor returns the minor version.
-func (v *Version) Minor() int64 {
- return v.minor
-}
-
-// Patch returns the patch version.
-func (v *Version) Patch() int64 {
- return v.patch
-}
-
-// Prerelease returns the pre-release version.
-func (v *Version) Prerelease() string {
- return v.pre
-}
-
-// Metadata returns the metadata on the version.
-func (v *Version) Metadata() string {
- return v.metadata
-}
-
-// originalVPrefix returns the original 'v' prefix if any.
-func (v *Version) originalVPrefix() string {
-
- // Note, only lowercase v is supported as a prefix by the parser.
- if v.original != "" && v.original[:1] == "v" {
- return v.original[:1]
- }
- return ""
-}
-
-// IncPatch produces the next patch version.
-// If the current version does not have prerelease/metadata information,
-// it unsets metadata and prerelease values, increments patch number.
-// If the current version has any of prerelease or metadata information,
-// it unsets both values and keeps curent patch value
-func (v Version) IncPatch() Version {
- vNext := v
- // according to http://semver.org/#spec-item-9
- // Pre-release versions have a lower precedence than the associated normal version.
- // according to http://semver.org/#spec-item-10
- // Build metadata SHOULD be ignored when determining version precedence.
- if v.pre != "" {
- vNext.metadata = ""
- vNext.pre = ""
- } else {
- vNext.metadata = ""
- vNext.pre = ""
- vNext.patch = v.patch + 1
- }
- vNext.original = v.originalVPrefix() + "" + vNext.String()
- return vNext
-}
-
-// IncMinor produces the next minor version.
-// Sets patch to 0.
-// Increments minor number.
-// Unsets metadata.
-// Unsets prerelease status.
-func (v Version) IncMinor() Version {
- vNext := v
- vNext.metadata = ""
- vNext.pre = ""
- vNext.patch = 0
- vNext.minor = v.minor + 1
- vNext.original = v.originalVPrefix() + "" + vNext.String()
- return vNext
-}
-
-// IncMajor produces the next major version.
-// Sets patch to 0.
-// Sets minor to 0.
-// Increments major number.
-// Unsets metadata.
-// Unsets prerelease status.
-func (v Version) IncMajor() Version {
- vNext := v
- vNext.metadata = ""
- vNext.pre = ""
- vNext.patch = 0
- vNext.minor = 0
- vNext.major = v.major + 1
- vNext.original = v.originalVPrefix() + "" + vNext.String()
- return vNext
-}
-
-// SetPrerelease defines the prerelease value.
-// Value must not include the required 'hypen' prefix.
-func (v Version) SetPrerelease(prerelease string) (Version, error) {
- vNext := v
- if len(prerelease) > 0 && !validPrereleaseRegex.MatchString(prerelease) {
- return vNext, ErrInvalidPrerelease
- }
- vNext.pre = prerelease
- vNext.original = v.originalVPrefix() + "" + vNext.String()
- return vNext, nil
-}
-
-// SetMetadata defines metadata value.
-// Value must not include the required 'plus' prefix.
-func (v Version) SetMetadata(metadata string) (Version, error) {
- vNext := v
- if len(metadata) > 0 && !validPrereleaseRegex.MatchString(metadata) {
- return vNext, ErrInvalidMetadata
- }
- vNext.metadata = metadata
- vNext.original = v.originalVPrefix() + "" + vNext.String()
- return vNext, nil
-}
-
-// LessThan tests if one version is less than another one.
-func (v *Version) LessThan(o *Version) bool {
- return v.Compare(o) < 0
-}
-
-// GreaterThan tests if one version is greater than another one.
-func (v *Version) GreaterThan(o *Version) bool {
- return v.Compare(o) > 0
-}
-
-// Equal tests if two versions are equal to each other.
-// Note, versions can be equal with different metadata since metadata
-// is not considered part of the comparable version.
-func (v *Version) Equal(o *Version) bool {
- return v.Compare(o) == 0
-}
-
-// Compare compares this version to another one. It returns -1, 0, or 1 if
-// the version smaller, equal, or larger than the other version.
-//
-// Versions are compared by X.Y.Z. Build metadata is ignored. Prerelease is
-// lower than the version without a prerelease.
-func (v *Version) Compare(o *Version) int {
- // Compare the major, minor, and patch version for differences. If a
- // difference is found return the comparison.
- if d := compareSegment(v.Major(), o.Major()); d != 0 {
- return d
- }
- if d := compareSegment(v.Minor(), o.Minor()); d != 0 {
- return d
- }
- if d := compareSegment(v.Patch(), o.Patch()); d != 0 {
- return d
- }
-
- // At this point the major, minor, and patch versions are the same.
- ps := v.pre
- po := o.Prerelease()
-
- if ps == "" && po == "" {
- return 0
- }
- if ps == "" {
- return 1
- }
- if po == "" {
- return -1
- }
-
- return comparePrerelease(ps, po)
-}
-
-// UnmarshalJSON implements JSON.Unmarshaler interface.
-func (v *Version) UnmarshalJSON(b []byte) error {
- var s string
- if err := json.Unmarshal(b, &s); err != nil {
- return err
- }
- temp, err := NewVersion(s)
- if err != nil {
- return err
- }
- v.major = temp.major
- v.minor = temp.minor
- v.patch = temp.patch
- v.pre = temp.pre
- v.metadata = temp.metadata
- v.original = temp.original
- temp = nil
- return nil
-}
-
-// MarshalJSON implements JSON.Marshaler interface.
-func (v *Version) MarshalJSON() ([]byte, error) {
- return json.Marshal(v.String())
-}
-
-func compareSegment(v, o int64) int {
- if v < o {
- return -1
- }
- if v > o {
- return 1
- }
-
- return 0
-}
-
-func comparePrerelease(v, o string) int {
-
- // split the prelease versions by their part. The separator, per the spec,
- // is a .
- sparts := strings.Split(v, ".")
- oparts := strings.Split(o, ".")
-
- // Find the longer length of the parts to know how many loop iterations to
- // go through.
- slen := len(sparts)
- olen := len(oparts)
-
- l := slen
- if olen > slen {
- l = olen
- }
-
- // Iterate over each part of the prereleases to compare the differences.
- for i := 0; i < l; i++ {
- // Since the lentgh of the parts can be different we need to create
- // a placeholder. This is to avoid out of bounds issues.
- stemp := ""
- if i < slen {
- stemp = sparts[i]
- }
-
- otemp := ""
- if i < olen {
- otemp = oparts[i]
- }
-
- d := comparePrePart(stemp, otemp)
- if d != 0 {
- return d
- }
- }
-
- // Reaching here means two versions are of equal value but have different
- // metadata (the part following a +). They are not identical in string form
- // but the version comparison finds them to be equal.
- return 0
-}
-
-func comparePrePart(s, o string) int {
- // Fastpath if they are equal
- if s == o {
- return 0
- }
-
- // When s or o are empty we can use the other in an attempt to determine
- // the response.
- if s == "" {
- if o != "" {
- return -1
- }
- return 1
- }
-
- if o == "" {
- if s != "" {
- return 1
- }
- return -1
- }
-
- // When comparing strings "99" is greater than "103". To handle
- // cases like this we need to detect numbers and compare them. According
- // to the semver spec, numbers are always positive. If there is a - at the
- // start like -99 this is to be evaluated as an alphanum. numbers always
- // have precedence over alphanum. Parsing as Uints because negative numbers
- // are ignored.
-
- oi, n1 := strconv.ParseUint(o, 10, 64)
- si, n2 := strconv.ParseUint(s, 10, 64)
-
- // The case where both are strings compare the strings
- if n1 != nil && n2 != nil {
- if s > o {
- return 1
- }
- return -1
- } else if n1 != nil {
- // o is a string and s is a number
- return -1
- } else if n2 != nil {
- // s is a string and o is a number
- return 1
- }
- // Both are numbers
- if si > oi {
- return 1
- }
- return -1
-
-}
diff --git a/vendor/github.com/Masterminds/semver/version_fuzz.go b/vendor/github.com/Masterminds/semver/version_fuzz.go
deleted file mode 100644
index b42bcd62b..000000000
--- a/vendor/github.com/Masterminds/semver/version_fuzz.go
+++ /dev/null
@@ -1,10 +0,0 @@
-// +build gofuzz
-
-package semver
-
-func Fuzz(data []byte) int {
- if _, err := NewVersion(string(data)); err != nil {
- return 0
- }
- return 1
-}
diff --git a/vendor/github.com/Masterminds/sprig/.travis.yml b/vendor/github.com/Masterminds/sprig/.travis.yml
deleted file mode 100644
index b9da8b825..000000000
--- a/vendor/github.com/Masterminds/sprig/.travis.yml
+++ /dev/null
@@ -1,26 +0,0 @@
-language: go
-
-go:
- - 1.9.x
- - 1.10.x
- - 1.11.x
- - 1.12.x
- - 1.13.x
- - tip
-
-# Setting sudo access to false will let Travis CI use containers rather than
-# VMs to run the tests. For more details see:
-# - http://docs.travis-ci.com/user/workers/container-based-infrastructure/
-# - http://docs.travis-ci.com/user/workers/standard-infrastructure/
-sudo: false
-
-script:
- - make setup test
-
-notifications:
- webhooks:
- urls:
- - https://webhooks.gitter.im/e/06e3328629952dabe3e0
- on_success: change # options: [always|never|change] default: always
- on_failure: always # options: [always|never|change] default: always
- on_start: never # options: [always|never|change] default: always
diff --git a/vendor/github.com/Masterminds/sprig/CHANGELOG.md b/vendor/github.com/Masterminds/sprig/CHANGELOG.md
deleted file mode 100644
index 6a79fbde4..000000000
--- a/vendor/github.com/Masterminds/sprig/CHANGELOG.md
+++ /dev/null
@@ -1,282 +0,0 @@
-# Changelog
-
-## Release 2.22.0 (2019-10-02)
-
-### Added
-
-- #173: Added getHostByName function to resolve dns names to ips (thanks @fcgravalos)
-- #195: Added deepCopy function for use with dicts
-
-### Changed
-
-- Updated merge and mergeOverwrite documentation to explain copying and how to
- use deepCopy with it
-
-## Release 2.21.0 (2019-09-18)
-
-### Added
-
-- #122: Added encryptAES/decryptAES functions (thanks @n0madic)
-- #128: Added toDecimal support (thanks @Dean-Coakley)
-- #169: Added list contcat (thanks @astorath)
-- #174: Added deepEqual function (thanks @bonifaido)
-- #170: Added url parse and join functions (thanks @astorath)
-
-### Changed
-
-- #171: Updated glide config for Google UUID to v1 and to add ranges to semver and testify
-
-### Fixed
-
-- #172: Fix semver wildcard example (thanks @piepmatz)
-- #175: Fix dateInZone doc example (thanks @s3than)
-
-## Release 2.20.0 (2019-06-18)
-
-### Added
-
-- #164: Adding function to get unix epoch for a time (@mattfarina)
-- #166: Adding tests for date_in_zone (@mattfarina)
-
-### Changed
-
-- #144: Fix function comments based on best practices from Effective Go (@CodeLingoTeam)
-- #150: Handles pointer type for time.Time in "htmlDate" (@mapreal19)
-- #161, #157, #160, #153, #158, #156, #155, #159, #152 documentation updates (@badeadan)
-
-### Fixed
-
-## Release 2.19.0 (2019-03-02)
-
-IMPORTANT: This release reverts a change from 2.18.0
-
-In the previous release (2.18), we prematurely merged a partial change to the crypto functions that led to creating two sets of crypto functions (I blame @technosophos -- since that's me). This release rolls back that change, and does what was originally intended: It alters the existing crypto functions to use secure random.
-
-We debated whether this classifies as a change worthy of major revision, but given the proximity to the last release, we have decided that treating 2.18 as a faulty release is the correct course of action. We apologize for any inconvenience.
-
-### Changed
-
-- Fix substr panic 35fb796 (Alexey igrychev)
-- Remove extra period 1eb7729 (Matthew Lorimor)
-- Make random string functions use crypto by default 6ceff26 (Matthew Lorimor)
-- README edits/fixes/suggestions 08fe136 (Lauri Apple)
-
-
-## Release 2.18.0 (2019-02-12)
-
-### Added
-
-- Added mergeOverwrite function
-- cryptographic functions that use secure random (see fe1de12)
-
-### Changed
-
-- Improve documentation of regexMatch function, resolves #139 90b89ce (Jan Tagscherer)
-- Handle has for nil list 9c10885 (Daniel Cohen)
-- Document behaviour of mergeOverwrite fe0dbe9 (Lukas Rieder)
-- doc: adds missing documentation. 4b871e6 (Fernandez Ludovic)
-- Replace outdated goutils imports 01893d2 (Matthew Lorimor)
-- Surface crypto secure random strings from goutils fe1de12 (Matthew Lorimor)
-- Handle untyped nil values as paramters to string functions 2b2ec8f (Morten Torkildsen)
-
-### Fixed
-
-- Fix dict merge issue and provide mergeOverwrite .dst .src1 to overwrite from src -> dst 4c59c12 (Lukas Rieder)
-- Fix substr var names and comments d581f80 (Dean Coakley)
-- Fix substr documentation 2737203 (Dean Coakley)
-
-## Release 2.17.1 (2019-01-03)
-
-### Fixed
-
-The 2.17.0 release did not have a version pinned for xstrings, which caused compilation failures when xstrings < 1.2 was used. This adds the correct version string to glide.yaml.
-
-## Release 2.17.0 (2019-01-03)
-
-### Added
-
-- adds alder32sum function and test 6908fc2 (marshallford)
-- Added kebabcase function ca331a1 (Ilyes512)
-
-### Changed
-
-- Update goutils to 1.1.0 4e1125d (Matt Butcher)
-
-### Fixed
-
-- Fix 'has' documentation e3f2a85 (dean-coakley)
-- docs(dict): fix typo in pick example dc424f9 (Dustin Specker)
-- fixes spelling errors... not sure how that happened 4cf188a (marshallford)
-
-## Release 2.16.0 (2018-08-13)
-
-### Added
-
-- add splitn function fccb0b0 (Helgi Þorbjörnsson)
-- Add slice func df28ca7 (gongdo)
-- Generate serial number a3bdffd (Cody Coons)
-- Extract values of dict with values function df39312 (Lawrence Jones)
-
-### Changed
-
-- Modify panic message for list.slice ae38335 (gongdo)
-- Minor improvement in code quality - Removed an unreachable piece of code at defaults.go#L26:6 - Resolve formatting issues. 5834241 (Abhishek Kashyap)
-- Remove duplicated documentation 1d97af1 (Matthew Fisher)
-- Test on go 1.11 49df809 (Helgi Þormar Þorbjörnsson)
-
-### Fixed
-
-- Fix file permissions c5f40b5 (gongdo)
-- Fix example for buildCustomCert 7779e0d (Tin Lam)
-
-## Release 2.15.0 (2018-04-02)
-
-### Added
-
-- #68 and #69: Add json helpers to docs (thanks @arunvelsriram)
-- #66: Add ternary function (thanks @binoculars)
-- #67: Allow keys function to take multiple dicts (thanks @binoculars)
-- #89: Added sha1sum to crypto function (thanks @benkeil)
-- #81: Allow customizing Root CA that used by genSignedCert (thanks @chenzhiwei)
-- #92: Add travis testing for go 1.10
-- #93: Adding appveyor config for windows testing
-
-### Changed
-
-- #90: Updating to more recent dependencies
-- #73: replace satori/go.uuid with google/uuid (thanks @petterw)
-
-### Fixed
-
-- #76: Fixed documentation typos (thanks @Thiht)
-- Fixed rounding issue on the `ago` function. Note, the removes support for Go 1.8 and older
-
-## Release 2.14.1 (2017-12-01)
-
-### Fixed
-
-- #60: Fix typo in function name documentation (thanks @neil-ca-moore)
-- #61: Removing line with {{ due to blocking github pages genertion
-- #64: Update the list functions to handle int, string, and other slices for compatibility
-
-## Release 2.14.0 (2017-10-06)
-
-This new version of Sprig adds a set of functions for generating and working with SSL certificates.
-
-- `genCA` generates an SSL Certificate Authority
-- `genSelfSignedCert` generates an SSL self-signed certificate
-- `genSignedCert` generates an SSL certificate and key based on a given CA
-
-## Release 2.13.0 (2017-09-18)
-
-This release adds new functions, including:
-
-- `regexMatch`, `regexFindAll`, `regexFind`, `regexReplaceAll`, `regexReplaceAllLiteral`, and `regexSplit` to work with regular expressions
-- `floor`, `ceil`, and `round` math functions
-- `toDate` converts a string to a date
-- `nindent` is just like `indent` but also prepends a new line
-- `ago` returns the time from `time.Now`
-
-### Added
-
-- #40: Added basic regex functionality (thanks @alanquillin)
-- #41: Added ceil floor and round functions (thanks @alanquillin)
-- #48: Added toDate function (thanks @andreynering)
-- #50: Added nindent function (thanks @binoculars)
-- #46: Added ago function (thanks @slayer)
-
-### Changed
-
-- #51: Updated godocs to include new string functions (thanks @curtisallen)
-- #49: Added ability to merge multiple dicts (thanks @binoculars)
-
-## Release 2.12.0 (2017-05-17)
-
-- `snakecase`, `camelcase`, and `shuffle` are three new string functions
-- `fail` allows you to bail out of a template render when conditions are not met
-
-## Release 2.11.0 (2017-05-02)
-
-- Added `toJson` and `toPrettyJson`
-- Added `merge`
-- Refactored documentation
-
-## Release 2.10.0 (2017-03-15)
-
-- Added `semver` and `semverCompare` for Semantic Versions
-- `list` replaces `tuple`
-- Fixed issue with `join`
-- Added `first`, `last`, `intial`, `rest`, `prepend`, `append`, `toString`, `toStrings`, `sortAlpha`, `reverse`, `coalesce`, `pluck`, `pick`, `compact`, `keys`, `omit`, `uniq`, `has`, `without`
-
-## Release 2.9.0 (2017-02-23)
-
-- Added `splitList` to split a list
-- Added crypto functions of `genPrivateKey` and `derivePassword`
-
-## Release 2.8.0 (2016-12-21)
-
-- Added access to several path functions (`base`, `dir`, `clean`, `ext`, and `abs`)
-- Added functions for _mutating_ dictionaries (`set`, `unset`, `hasKey`)
-
-## Release 2.7.0 (2016-12-01)
-
-- Added `sha256sum` to generate a hash of an input
-- Added functions to convert a numeric or string to `int`, `int64`, `float64`
-
-## Release 2.6.0 (2016-10-03)
-
-- Added a `uuidv4` template function for generating UUIDs inside of a template.
-
-## Release 2.5.0 (2016-08-19)
-
-- New `trimSuffix`, `trimPrefix`, `hasSuffix`, and `hasPrefix` functions
-- New aliases have been added for a few functions that didn't follow the naming conventions (`trimAll` and `abbrevBoth`)
-- `trimall` and `abbrevboth` (notice the case) are deprecated and will be removed in 3.0.0
-
-## Release 2.4.0 (2016-08-16)
-
-- Adds two functions: `until` and `untilStep`
-
-## Release 2.3.0 (2016-06-21)
-
-- cat: Concatenate strings with whitespace separators.
-- replace: Replace parts of a string: `replace " " "-" "Me First"` renders "Me-First"
-- plural: Format plurals: `len "foo" | plural "one foo" "many foos"` renders "many foos"
-- indent: Indent blocks of text in a way that is sensitive to "\n" characters.
-
-## Release 2.2.0 (2016-04-21)
-
-- Added a `genPrivateKey` function (Thanks @bacongobbler)
-
-## Release 2.1.0 (2016-03-30)
-
-- `default` now prints the default value when it does not receive a value down the pipeline. It is much safer now to do `{{.Foo | default "bar"}}`.
-- Added accessors for "hermetic" functions. These return only functions that, when given the same input, produce the same output.
-
-## Release 2.0.0 (2016-03-29)
-
-Because we switched from `int` to `int64` as the return value for all integer math functions, the library's major version number has been incremented.
-
-- `min` complements `max` (formerly `biggest`)
-- `empty` indicates that a value is the empty value for its type
-- `tuple` creates a tuple inside of a template: `{{$t := tuple "a", "b" "c"}}`
-- `dict` creates a dictionary inside of a template `{{$d := dict "key1" "val1" "key2" "val2"}}`
-- Date formatters have been added for HTML dates (as used in `date` input fields)
-- Integer math functions can convert from a number of types, including `string` (via `strconv.ParseInt`).
-
-## Release 1.2.0 (2016-02-01)
-
-- Added quote and squote
-- Added b32enc and b32dec
-- add now takes varargs
-- biggest now takes varargs
-
-## Release 1.1.0 (2015-12-29)
-
-- Added #4: Added contains function. strings.Contains, but with the arguments
- switched to simplify common pipelines. (thanks krancour)
-- Added Travis-CI testing support
-
-## Release 1.0.0 (2015-12-23)
-
-- Initial release
diff --git a/vendor/github.com/Masterminds/sprig/LICENSE.txt b/vendor/github.com/Masterminds/sprig/LICENSE.txt
deleted file mode 100644
index 5c95accc2..000000000
--- a/vendor/github.com/Masterminds/sprig/LICENSE.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-Sprig
-Copyright (C) 2013 Masterminds
-
-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.
diff --git a/vendor/github.com/Masterminds/sprig/Makefile b/vendor/github.com/Masterminds/sprig/Makefile
deleted file mode 100644
index 63a93fdf7..000000000
--- a/vendor/github.com/Masterminds/sprig/Makefile
+++ /dev/null
@@ -1,13 +0,0 @@
-
-HAS_GLIDE := $(shell command -v glide;)
-
-.PHONY: test
-test:
- go test -v .
-
-.PHONY: setup
-setup:
-ifndef HAS_GLIDE
- go get -u github.com/Masterminds/glide
-endif
- glide install
diff --git a/vendor/github.com/Masterminds/sprig/README.md b/vendor/github.com/Masterminds/sprig/README.md
deleted file mode 100644
index b70569585..000000000
--- a/vendor/github.com/Masterminds/sprig/README.md
+++ /dev/null
@@ -1,78 +0,0 @@
-# Sprig: Template functions for Go templates
-[](https://masterminds.github.io/stability/sustained.html)
-[](https://travis-ci.org/Masterminds/sprig)
-
-The Go language comes with a [built-in template
-language](http://golang.org/pkg/text/template/), but not
-very many template functions. Sprig is a library that provides more than 100 commonly
-used template functions.
-
-It is inspired by the template functions found in
-[Twig](http://twig.sensiolabs.org/documentation) and in various
-JavaScript libraries, such as [underscore.js](http://underscorejs.org/).
-
-## Usage
-
-**Template developers**: Please use Sprig's [function documentation](http://masterminds.github.io/sprig/) for
-detailed instructions and code snippets for the >100 template functions available.
-
-**Go developers**: If you'd like to include Sprig as a library in your program,
-our API documentation is available [at GoDoc.org](http://godoc.org/github.com/Masterminds/sprig).
-
-For standard usage, read on.
-
-### Load the Sprig library
-
-To load the Sprig `FuncMap`:
-
-```go
-
-import (
- "github.com/Masterminds/sprig"
- "html/template"
-)
-
-// This example illustrates that the FuncMap *must* be set before the
-// templates themselves are loaded.
-tpl := template.Must(
- template.New("base").Funcs(sprig.FuncMap()).ParseGlob("*.html")
-)
-
-
-```
-
-### Calling the functions inside of templates
-
-By convention, all functions are lowercase. This seems to follow the Go
-idiom for template functions (as opposed to template methods, which are
-TitleCase). For example, this:
-
-```
-{{ "hello!" | upper | repeat 5 }}
-```
-
-produces this:
-
-```
-HELLO!HELLO!HELLO!HELLO!HELLO!
-```
-
-## Principles Driving Our Function Selection
-
-We followed these principles to decide which functions to add and how to implement them:
-
-- Use template functions to build layout. The following
- types of operations are within the domain of template functions:
- - Formatting
- - Layout
- - Simple type conversions
- - Utilities that assist in handling common formatting and layout needs (e.g. arithmetic)
-- Template functions should not return errors unless there is no way to print
- a sensible value. For example, converting a string to an integer should not
- produce an error if conversion fails. Instead, it should display a default
- value.
-- Simple math is necessary for grid layouts, pagers, and so on. Complex math
- (anything other than arithmetic) should be done outside of templates.
-- Template functions only deal with the data passed into them. They never retrieve
- data from a source.
-- Finally, do not override core Go template functions.
diff --git a/vendor/github.com/Masterminds/sprig/appveyor.yml b/vendor/github.com/Masterminds/sprig/appveyor.yml
deleted file mode 100644
index d545a987a..000000000
--- a/vendor/github.com/Masterminds/sprig/appveyor.yml
+++ /dev/null
@@ -1,26 +0,0 @@
-
-version: build-{build}.{branch}
-
-clone_folder: C:\gopath\src\github.com\Masterminds\sprig
-shallow_clone: true
-
-environment:
- GOPATH: C:\gopath
-
-platform:
- - x64
-
-install:
- - go get -u github.com/Masterminds/glide
- - set PATH=%GOPATH%\bin;%PATH%
- - go version
- - go env
-
-build_script:
- - glide install
- - go install ./...
-
-test_script:
- - go test -v
-
-deploy: off
diff --git a/vendor/github.com/Masterminds/sprig/crypto.go b/vendor/github.com/Masterminds/sprig/crypto.go
deleted file mode 100644
index 7a418ba88..000000000
--- a/vendor/github.com/Masterminds/sprig/crypto.go
+++ /dev/null
@@ -1,502 +0,0 @@
-package sprig
-
-import (
- "bytes"
- "crypto/aes"
- "crypto/cipher"
- "crypto/dsa"
- "crypto/ecdsa"
- "crypto/elliptic"
- "crypto/hmac"
- "crypto/rand"
- "crypto/rsa"
- "crypto/sha1"
- "crypto/sha256"
- "crypto/x509"
- "crypto/x509/pkix"
- "encoding/asn1"
- "encoding/base64"
- "encoding/binary"
- "encoding/hex"
- "encoding/pem"
- "errors"
- "fmt"
- "io"
- "hash/adler32"
- "math/big"
- "net"
- "time"
-
- "github.com/google/uuid"
- "golang.org/x/crypto/scrypt"
-)
-
-func sha256sum(input string) string {
- hash := sha256.Sum256([]byte(input))
- return hex.EncodeToString(hash[:])
-}
-
-func sha1sum(input string) string {
- hash := sha1.Sum([]byte(input))
- return hex.EncodeToString(hash[:])
-}
-
-func adler32sum(input string) string {
- hash := adler32.Checksum([]byte(input))
- return fmt.Sprintf("%d", hash)
-}
-
-// uuidv4 provides a safe and secure UUID v4 implementation
-func uuidv4() string {
- return fmt.Sprintf("%s", uuid.New())
-}
-
-var master_password_seed = "com.lyndir.masterpassword"
-
-var password_type_templates = map[string][][]byte{
- "maximum": {[]byte("anoxxxxxxxxxxxxxxxxx"), []byte("axxxxxxxxxxxxxxxxxno")},
- "long": {[]byte("CvcvnoCvcvCvcv"), []byte("CvcvCvcvnoCvcv"), []byte("CvcvCvcvCvcvno"), []byte("CvccnoCvcvCvcv"), []byte("CvccCvcvnoCvcv"),
- []byte("CvccCvcvCvcvno"), []byte("CvcvnoCvccCvcv"), []byte("CvcvCvccnoCvcv"), []byte("CvcvCvccCvcvno"), []byte("CvcvnoCvcvCvcc"),
- []byte("CvcvCvcvnoCvcc"), []byte("CvcvCvcvCvccno"), []byte("CvccnoCvccCvcv"), []byte("CvccCvccnoCvcv"), []byte("CvccCvccCvcvno"),
- []byte("CvcvnoCvccCvcc"), []byte("CvcvCvccnoCvcc"), []byte("CvcvCvccCvccno"), []byte("CvccnoCvcvCvcc"), []byte("CvccCvcvnoCvcc"),
- []byte("CvccCvcvCvccno")},
- "medium": {[]byte("CvcnoCvc"), []byte("CvcCvcno")},
- "short": {[]byte("Cvcn")},
- "basic": {[]byte("aaanaaan"), []byte("aannaaan"), []byte("aaannaaa")},
- "pin": {[]byte("nnnn")},
-}
-
-var template_characters = map[byte]string{
- 'V': "AEIOU",
- 'C': "BCDFGHJKLMNPQRSTVWXYZ",
- 'v': "aeiou",
- 'c': "bcdfghjklmnpqrstvwxyz",
- 'A': "AEIOUBCDFGHJKLMNPQRSTVWXYZ",
- 'a': "AEIOUaeiouBCDFGHJKLMNPQRSTVWXYZbcdfghjklmnpqrstvwxyz",
- 'n': "0123456789",
- 'o': "@&%?,=[]_:-+*$#!'^~;()/.",
- 'x': "AEIOUaeiouBCDFGHJKLMNPQRSTVWXYZbcdfghjklmnpqrstvwxyz0123456789!@#$%^&*()",
-}
-
-func derivePassword(counter uint32, password_type, password, user, site string) string {
- var templates = password_type_templates[password_type]
- if templates == nil {
- return fmt.Sprintf("cannot find password template %s", password_type)
- }
-
- var buffer bytes.Buffer
- buffer.WriteString(master_password_seed)
- binary.Write(&buffer, binary.BigEndian, uint32(len(user)))
- buffer.WriteString(user)
-
- salt := buffer.Bytes()
- key, err := scrypt.Key([]byte(password), salt, 32768, 8, 2, 64)
- if err != nil {
- return fmt.Sprintf("failed to derive password: %s", err)
- }
-
- buffer.Truncate(len(master_password_seed))
- binary.Write(&buffer, binary.BigEndian, uint32(len(site)))
- buffer.WriteString(site)
- binary.Write(&buffer, binary.BigEndian, counter)
-
- var hmacv = hmac.New(sha256.New, key)
- hmacv.Write(buffer.Bytes())
- var seed = hmacv.Sum(nil)
- var temp = templates[int(seed[0])%len(templates)]
-
- buffer.Truncate(0)
- for i, element := range temp {
- pass_chars := template_characters[element]
- pass_char := pass_chars[int(seed[i+1])%len(pass_chars)]
- buffer.WriteByte(pass_char)
- }
-
- return buffer.String()
-}
-
-func generatePrivateKey(typ string) string {
- var priv interface{}
- var err error
- switch typ {
- case "", "rsa":
- // good enough for government work
- priv, err = rsa.GenerateKey(rand.Reader, 4096)
- case "dsa":
- key := new(dsa.PrivateKey)
- // again, good enough for government work
- if err = dsa.GenerateParameters(&key.Parameters, rand.Reader, dsa.L2048N256); err != nil {
- return fmt.Sprintf("failed to generate dsa params: %s", err)
- }
- err = dsa.GenerateKey(key, rand.Reader)
- priv = key
- case "ecdsa":
- // again, good enough for government work
- priv, err = ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
- default:
- return "Unknown type " + typ
- }
- if err != nil {
- return fmt.Sprintf("failed to generate private key: %s", err)
- }
-
- return string(pem.EncodeToMemory(pemBlockForKey(priv)))
-}
-
-type DSAKeyFormat struct {
- Version int
- P, Q, G, Y, X *big.Int
-}
-
-func pemBlockForKey(priv interface{}) *pem.Block {
- switch k := priv.(type) {
- case *rsa.PrivateKey:
- return &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(k)}
- case *dsa.PrivateKey:
- val := DSAKeyFormat{
- P: k.P, Q: k.Q, G: k.G,
- Y: k.Y, X: k.X,
- }
- bytes, _ := asn1.Marshal(val)
- return &pem.Block{Type: "DSA PRIVATE KEY", Bytes: bytes}
- case *ecdsa.PrivateKey:
- b, _ := x509.MarshalECPrivateKey(k)
- return &pem.Block{Type: "EC PRIVATE KEY", Bytes: b}
- default:
- return nil
- }
-}
-
-type certificate struct {
- Cert string
- Key string
-}
-
-func buildCustomCertificate(b64cert string, b64key string) (certificate, error) {
- crt := certificate{}
-
- cert, err := base64.StdEncoding.DecodeString(b64cert)
- if err != nil {
- return crt, errors.New("unable to decode base64 certificate")
- }
-
- key, err := base64.StdEncoding.DecodeString(b64key)
- if err != nil {
- return crt, errors.New("unable to decode base64 private key")
- }
-
- decodedCert, _ := pem.Decode(cert)
- if decodedCert == nil {
- return crt, errors.New("unable to decode certificate")
- }
- _, err = x509.ParseCertificate(decodedCert.Bytes)
- if err != nil {
- return crt, fmt.Errorf(
- "error parsing certificate: decodedCert.Bytes: %s",
- err,
- )
- }
-
- decodedKey, _ := pem.Decode(key)
- if decodedKey == nil {
- return crt, errors.New("unable to decode key")
- }
- _, err = x509.ParsePKCS1PrivateKey(decodedKey.Bytes)
- if err != nil {
- return crt, fmt.Errorf(
- "error parsing prive key: decodedKey.Bytes: %s",
- err,
- )
- }
-
- crt.Cert = string(cert)
- crt.Key = string(key)
-
- return crt, nil
-}
-
-func generateCertificateAuthority(
- cn string,
- daysValid int,
-) (certificate, error) {
- ca := certificate{}
-
- template, err := getBaseCertTemplate(cn, nil, nil, daysValid)
- if err != nil {
- return ca, err
- }
- // Override KeyUsage and IsCA
- template.KeyUsage = x509.KeyUsageKeyEncipherment |
- x509.KeyUsageDigitalSignature |
- x509.KeyUsageCertSign
- template.IsCA = true
-
- priv, err := rsa.GenerateKey(rand.Reader, 2048)
- if err != nil {
- return ca, fmt.Errorf("error generating rsa key: %s", err)
- }
-
- ca.Cert, ca.Key, err = getCertAndKey(template, priv, template, priv)
- if err != nil {
- return ca, err
- }
-
- return ca, nil
-}
-
-func generateSelfSignedCertificate(
- cn string,
- ips []interface{},
- alternateDNS []interface{},
- daysValid int,
-) (certificate, error) {
- cert := certificate{}
-
- template, err := getBaseCertTemplate(cn, ips, alternateDNS, daysValid)
- if err != nil {
- return cert, err
- }
-
- priv, err := rsa.GenerateKey(rand.Reader, 2048)
- if err != nil {
- return cert, fmt.Errorf("error generating rsa key: %s", err)
- }
-
- cert.Cert, cert.Key, err = getCertAndKey(template, priv, template, priv)
- if err != nil {
- return cert, err
- }
-
- return cert, nil
-}
-
-func generateSignedCertificate(
- cn string,
- ips []interface{},
- alternateDNS []interface{},
- daysValid int,
- ca certificate,
-) (certificate, error) {
- cert := certificate{}
-
- decodedSignerCert, _ := pem.Decode([]byte(ca.Cert))
- if decodedSignerCert == nil {
- return cert, errors.New("unable to decode certificate")
- }
- signerCert, err := x509.ParseCertificate(decodedSignerCert.Bytes)
- if err != nil {
- return cert, fmt.Errorf(
- "error parsing certificate: decodedSignerCert.Bytes: %s",
- err,
- )
- }
- decodedSignerKey, _ := pem.Decode([]byte(ca.Key))
- if decodedSignerKey == nil {
- return cert, errors.New("unable to decode key")
- }
- signerKey, err := x509.ParsePKCS1PrivateKey(decodedSignerKey.Bytes)
- if err != nil {
- return cert, fmt.Errorf(
- "error parsing prive key: decodedSignerKey.Bytes: %s",
- err,
- )
- }
-
- template, err := getBaseCertTemplate(cn, ips, alternateDNS, daysValid)
- if err != nil {
- return cert, err
- }
-
- priv, err := rsa.GenerateKey(rand.Reader, 2048)
- if err != nil {
- return cert, fmt.Errorf("error generating rsa key: %s", err)
- }
-
- cert.Cert, cert.Key, err = getCertAndKey(
- template,
- priv,
- signerCert,
- signerKey,
- )
- if err != nil {
- return cert, err
- }
-
- return cert, nil
-}
-
-func getCertAndKey(
- template *x509.Certificate,
- signeeKey *rsa.PrivateKey,
- parent *x509.Certificate,
- signingKey *rsa.PrivateKey,
-) (string, string, error) {
- derBytes, err := x509.CreateCertificate(
- rand.Reader,
- template,
- parent,
- &signeeKey.PublicKey,
- signingKey,
- )
- if err != nil {
- return "", "", fmt.Errorf("error creating certificate: %s", err)
- }
-
- certBuffer := bytes.Buffer{}
- if err := pem.Encode(
- &certBuffer,
- &pem.Block{Type: "CERTIFICATE", Bytes: derBytes},
- ); err != nil {
- return "", "", fmt.Errorf("error pem-encoding certificate: %s", err)
- }
-
- keyBuffer := bytes.Buffer{}
- if err := pem.Encode(
- &keyBuffer,
- &pem.Block{
- Type: "RSA PRIVATE KEY",
- Bytes: x509.MarshalPKCS1PrivateKey(signeeKey),
- },
- ); err != nil {
- return "", "", fmt.Errorf("error pem-encoding key: %s", err)
- }
-
- return string(certBuffer.Bytes()), string(keyBuffer.Bytes()), nil
-}
-
-func getBaseCertTemplate(
- cn string,
- ips []interface{},
- alternateDNS []interface{},
- daysValid int,
-) (*x509.Certificate, error) {
- ipAddresses, err := getNetIPs(ips)
- if err != nil {
- return nil, err
- }
- dnsNames, err := getAlternateDNSStrs(alternateDNS)
- if err != nil {
- return nil, err
- }
- serialNumberUpperBound := new(big.Int).Lsh(big.NewInt(1), 128)
- serialNumber, err := rand.Int(rand.Reader, serialNumberUpperBound)
- if err != nil {
- return nil, err
- }
- return &x509.Certificate{
- SerialNumber: serialNumber,
- Subject: pkix.Name{
- CommonName: cn,
- },
- IPAddresses: ipAddresses,
- DNSNames: dnsNames,
- NotBefore: time.Now(),
- NotAfter: time.Now().Add(time.Hour * 24 * time.Duration(daysValid)),
- KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
- ExtKeyUsage: []x509.ExtKeyUsage{
- x509.ExtKeyUsageServerAuth,
- x509.ExtKeyUsageClientAuth,
- },
- BasicConstraintsValid: true,
- }, nil
-}
-
-func getNetIPs(ips []interface{}) ([]net.IP, error) {
- if ips == nil {
- return []net.IP{}, nil
- }
- var ipStr string
- var ok bool
- var netIP net.IP
- netIPs := make([]net.IP, len(ips))
- for i, ip := range ips {
- ipStr, ok = ip.(string)
- if !ok {
- return nil, fmt.Errorf("error parsing ip: %v is not a string", ip)
- }
- netIP = net.ParseIP(ipStr)
- if netIP == nil {
- return nil, fmt.Errorf("error parsing ip: %s", ipStr)
- }
- netIPs[i] = netIP
- }
- return netIPs, nil
-}
-
-func getAlternateDNSStrs(alternateDNS []interface{}) ([]string, error) {
- if alternateDNS == nil {
- return []string{}, nil
- }
- var dnsStr string
- var ok bool
- alternateDNSStrs := make([]string, len(alternateDNS))
- for i, dns := range alternateDNS {
- dnsStr, ok = dns.(string)
- if !ok {
- return nil, fmt.Errorf(
- "error processing alternate dns name: %v is not a string",
- dns,
- )
- }
- alternateDNSStrs[i] = dnsStr
- }
- return alternateDNSStrs, nil
-}
-
-func encryptAES(password string, plaintext string) (string, error) {
- if plaintext == "" {
- return "", nil
- }
-
- key := make([]byte, 32)
- copy(key, []byte(password))
- block, err := aes.NewCipher(key)
- if err != nil {
- return "", err
- }
-
- content := []byte(plaintext)
- blockSize := block.BlockSize()
- padding := blockSize - len(content)%blockSize
- padtext := bytes.Repeat([]byte{byte(padding)}, padding)
- content = append(content, padtext...)
-
- ciphertext := make([]byte, aes.BlockSize+len(content))
-
- iv := ciphertext[:aes.BlockSize]
- if _, err := io.ReadFull(rand.Reader, iv); err != nil {
- return "", err
- }
-
- mode := cipher.NewCBCEncrypter(block, iv)
- mode.CryptBlocks(ciphertext[aes.BlockSize:], content)
-
- return base64.StdEncoding.EncodeToString(ciphertext), nil
-}
-
-func decryptAES(password string, crypt64 string) (string, error) {
- if crypt64 == "" {
- return "", nil
- }
-
- key := make([]byte, 32)
- copy(key, []byte(password))
-
- crypt, err := base64.StdEncoding.DecodeString(crypt64)
- if err != nil {
- return "", err
- }
-
- block, err := aes.NewCipher(key)
- if err != nil {
- return "", err
- }
-
- iv := crypt[:aes.BlockSize]
- crypt = crypt[aes.BlockSize:]
- decrypted := make([]byte, len(crypt))
- mode := cipher.NewCBCDecrypter(block, iv)
- mode.CryptBlocks(decrypted, crypt)
-
- return string(decrypted[:len(decrypted)-int(decrypted[len(decrypted)-1])]), nil
-}
diff --git a/vendor/github.com/Masterminds/sprig/date.go b/vendor/github.com/Masterminds/sprig/date.go
deleted file mode 100644
index d1d6155d7..000000000
--- a/vendor/github.com/Masterminds/sprig/date.go
+++ /dev/null
@@ -1,83 +0,0 @@
-package sprig
-
-import (
- "strconv"
- "time"
-)
-
-// Given a format and a date, format the date string.
-//
-// Date can be a `time.Time` or an `int, int32, int64`.
-// In the later case, it is treated as seconds since UNIX
-// epoch.
-func date(fmt string, date interface{}) string {
- return dateInZone(fmt, date, "Local")
-}
-
-func htmlDate(date interface{}) string {
- return dateInZone("2006-01-02", date, "Local")
-}
-
-func htmlDateInZone(date interface{}, zone string) string {
- return dateInZone("2006-01-02", date, zone)
-}
-
-func dateInZone(fmt string, date interface{}, zone string) string {
- var t time.Time
- switch date := date.(type) {
- default:
- t = time.Now()
- case time.Time:
- t = date
- case *time.Time:
- t = *date
- case int64:
- t = time.Unix(date, 0)
- case int:
- t = time.Unix(int64(date), 0)
- case int32:
- t = time.Unix(int64(date), 0)
- }
-
- loc, err := time.LoadLocation(zone)
- if err != nil {
- loc, _ = time.LoadLocation("UTC")
- }
-
- return t.In(loc).Format(fmt)
-}
-
-func dateModify(fmt string, date time.Time) time.Time {
- d, err := time.ParseDuration(fmt)
- if err != nil {
- return date
- }
- return date.Add(d)
-}
-
-func dateAgo(date interface{}) string {
- var t time.Time
-
- switch date := date.(type) {
- default:
- t = time.Now()
- case time.Time:
- t = date
- case int64:
- t = time.Unix(date, 0)
- case int:
- t = time.Unix(int64(date), 0)
- }
- // Drop resolution to seconds
- duration := time.Since(t).Round(time.Second)
- return duration.String()
-}
-
-func toDate(fmt, str string) time.Time {
- t, _ := time.ParseInLocation(fmt, str, time.Local)
- return t
-}
-
-func unixEpoch(date time.Time) string {
- return strconv.FormatInt(date.Unix(), 10)
-}
diff --git a/vendor/github.com/Masterminds/sprig/defaults.go b/vendor/github.com/Masterminds/sprig/defaults.go
deleted file mode 100644
index ed6a8ab29..000000000
--- a/vendor/github.com/Masterminds/sprig/defaults.go
+++ /dev/null
@@ -1,83 +0,0 @@
-package sprig
-
-import (
- "encoding/json"
- "reflect"
-)
-
-// dfault checks whether `given` is set, and returns default if not set.
-//
-// This returns `d` if `given` appears not to be set, and `given` otherwise.
-//
-// For numeric types 0 is unset.
-// For strings, maps, arrays, and slices, len() = 0 is considered unset.
-// For bool, false is unset.
-// Structs are never considered unset.
-//
-// For everything else, including pointers, a nil value is unset.
-func dfault(d interface{}, given ...interface{}) interface{} {
-
- if empty(given) || empty(given[0]) {
- return d
- }
- return given[0]
-}
-
-// empty returns true if the given value has the zero value for its type.
-func empty(given interface{}) bool {
- g := reflect.ValueOf(given)
- if !g.IsValid() {
- return true
- }
-
- // Basically adapted from text/template.isTrue
- switch g.Kind() {
- default:
- return g.IsNil()
- case reflect.Array, reflect.Slice, reflect.Map, reflect.String:
- return g.Len() == 0
- case reflect.Bool:
- return g.Bool() == false
- case reflect.Complex64, reflect.Complex128:
- return g.Complex() == 0
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- return g.Int() == 0
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
- return g.Uint() == 0
- case reflect.Float32, reflect.Float64:
- return g.Float() == 0
- case reflect.Struct:
- return false
- }
-}
-
-// coalesce returns the first non-empty value.
-func coalesce(v ...interface{}) interface{} {
- for _, val := range v {
- if !empty(val) {
- return val
- }
- }
- return nil
-}
-
-// toJson encodes an item into a JSON string
-func toJson(v interface{}) string {
- output, _ := json.Marshal(v)
- return string(output)
-}
-
-// toPrettyJson encodes an item into a pretty (indented) JSON string
-func toPrettyJson(v interface{}) string {
- output, _ := json.MarshalIndent(v, "", " ")
- return string(output)
-}
-
-// ternary returns the first value if the last value is true, otherwise returns the second value.
-func ternary(vt interface{}, vf interface{}, v bool) interface{} {
- if v {
- return vt
- }
-
- return vf
-}
diff --git a/vendor/github.com/Masterminds/sprig/dict.go b/vendor/github.com/Masterminds/sprig/dict.go
deleted file mode 100644
index 738405b43..000000000
--- a/vendor/github.com/Masterminds/sprig/dict.go
+++ /dev/null
@@ -1,119 +0,0 @@
-package sprig
-
-import (
- "github.com/imdario/mergo"
- "github.com/mitchellh/copystructure"
-)
-
-func set(d map[string]interface{}, key string, value interface{}) map[string]interface{} {
- d[key] = value
- return d
-}
-
-func unset(d map[string]interface{}, key string) map[string]interface{} {
- delete(d, key)
- return d
-}
-
-func hasKey(d map[string]interface{}, key string) bool {
- _, ok := d[key]
- return ok
-}
-
-func pluck(key string, d ...map[string]interface{}) []interface{} {
- res := []interface{}{}
- for _, dict := range d {
- if val, ok := dict[key]; ok {
- res = append(res, val)
- }
- }
- return res
-}
-
-func keys(dicts ...map[string]interface{}) []string {
- k := []string{}
- for _, dict := range dicts {
- for key := range dict {
- k = append(k, key)
- }
- }
- return k
-}
-
-func pick(dict map[string]interface{}, keys ...string) map[string]interface{} {
- res := map[string]interface{}{}
- for _, k := range keys {
- if v, ok := dict[k]; ok {
- res[k] = v
- }
- }
- return res
-}
-
-func omit(dict map[string]interface{}, keys ...string) map[string]interface{} {
- res := map[string]interface{}{}
-
- omit := make(map[string]bool, len(keys))
- for _, k := range keys {
- omit[k] = true
- }
-
- for k, v := range dict {
- if _, ok := omit[k]; !ok {
- res[k] = v
- }
- }
- return res
-}
-
-func dict(v ...interface{}) map[string]interface{} {
- dict := map[string]interface{}{}
- lenv := len(v)
- for i := 0; i < lenv; i += 2 {
- key := strval(v[i])
- if i+1 >= lenv {
- dict[key] = ""
- continue
- }
- dict[key] = v[i+1]
- }
- return dict
-}
-
-func merge(dst map[string]interface{}, srcs ...map[string]interface{}) interface{} {
- for _, src := range srcs {
- if err := mergo.Merge(&dst, src); err != nil {
- // Swallow errors inside of a template.
- return ""
- }
- }
- return dst
-}
-
-func mergeOverwrite(dst map[string]interface{}, srcs ...map[string]interface{}) interface{} {
- for _, src := range srcs {
- if err := mergo.MergeWithOverwrite(&dst, src); err != nil {
- // Swallow errors inside of a template.
- return ""
- }
- }
- return dst
-}
-
-func values(dict map[string]interface{}) []interface{} {
- values := []interface{}{}
- for _, value := range dict {
- values = append(values, value)
- }
-
- return values
-}
-
-func deepCopy(i interface{}) interface{} {
- c, err := copystructure.Copy(i)
- if err != nil {
- panic("deepCopy error: " + err.Error())
- }
-
- return c
-}
diff --git a/vendor/github.com/Masterminds/sprig/doc.go b/vendor/github.com/Masterminds/sprig/doc.go
deleted file mode 100644
index 8f8f1d737..000000000
--- a/vendor/github.com/Masterminds/sprig/doc.go
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
-Sprig: Template functions for Go.
-
-This package contains a number of utility functions for working with data
-inside of Go `html/template` and `text/template` files.
-
-To add these functions, use the `template.Funcs()` method:
-
- t := templates.New("foo").Funcs(sprig.FuncMap())
-
-Note that you should add the function map before you parse any template files.
-
- In several cases, Sprig reverses the order of arguments from the way they
- appear in the standard library. This is to make it easier to pipe
- arguments into functions.
-
-See http://masterminds.github.io/sprig/ for more detailed documentation on each of the available functions.
-*/
-package sprig
diff --git a/vendor/github.com/Masterminds/sprig/functions.go b/vendor/github.com/Masterminds/sprig/functions.go
deleted file mode 100644
index 7b5b0af86..000000000
--- a/vendor/github.com/Masterminds/sprig/functions.go
+++ /dev/null
@@ -1,306 +0,0 @@
-package sprig
-
-import (
- "errors"
- "html/template"
- "os"
- "path"
- "reflect"
- "strconv"
- "strings"
- ttemplate "text/template"
- "time"
-
- util "github.com/Masterminds/goutils"
- "github.com/huandu/xstrings"
-)
-
-// Produce the function map.
-//
-// Use this to pass the functions into the template engine:
-//
-// tpl := template.New("foo").Funcs(sprig.FuncMap()))
-//
-func FuncMap() template.FuncMap {
- return HtmlFuncMap()
-}
-
-// HermeticTxtFuncMap returns a 'text/template'.FuncMap with only repeatable functions.
-func HermeticTxtFuncMap() ttemplate.FuncMap {
- r := TxtFuncMap()
- for _, name := range nonhermeticFunctions {
- delete(r, name)
- }
- return r
-}
-
-// HermeticHtmlFuncMap returns an 'html/template'.Funcmap with only repeatable functions.
-func HermeticHtmlFuncMap() template.FuncMap {
- r := HtmlFuncMap()
- for _, name := range nonhermeticFunctions {
- delete(r, name)
- }
- return r
-}
-
-// TxtFuncMap returns a 'text/template'.FuncMap
-func TxtFuncMap() ttemplate.FuncMap {
- return ttemplate.FuncMap(GenericFuncMap())
-}
-
-// HtmlFuncMap returns an 'html/template'.Funcmap
-func HtmlFuncMap() template.FuncMap {
- return template.FuncMap(GenericFuncMap())
-}
-
-// GenericFuncMap returns a copy of the basic function map as a map[string]interface{}.
-func GenericFuncMap() map[string]interface{} {
- gfm := make(map[string]interface{}, len(genericMap))
- for k, v := range genericMap {
- gfm[k] = v
- }
- return gfm
-}
-
-// These functions are not guaranteed to evaluate to the same result for given input, because they
-// refer to the environemnt or global state.
-var nonhermeticFunctions = []string{
- // Date functions
- "date",
- "date_in_zone",
- "date_modify",
- "now",
- "htmlDate",
- "htmlDateInZone",
- "dateInZone",
- "dateModify",
-
- // Strings
- "randAlphaNum",
- "randAlpha",
- "randAscii",
- "randNumeric",
- "uuidv4",
-
- // OS
- "env",
- "expandenv",
-
- // Network
- "getHostByName",
-}
-
-var genericMap = map[string]interface{}{
- "hello": func() string { return "Hello!" },
-
- // Date functions
- "date": date,
- "date_in_zone": dateInZone,
- "date_modify": dateModify,
- "now": func() time.Time { return time.Now() },
- "htmlDate": htmlDate,
- "htmlDateInZone": htmlDateInZone,
- "dateInZone": dateInZone,
- "dateModify": dateModify,
- "ago": dateAgo,
- "toDate": toDate,
- "unixEpoch": unixEpoch,
-
- // Strings
- "abbrev": abbrev,
- "abbrevboth": abbrevboth,
- "trunc": trunc,
- "trim": strings.TrimSpace,
- "upper": strings.ToUpper,
- "lower": strings.ToLower,
- "title": strings.Title,
- "untitle": untitle,
- "substr": substring,
- // Switch order so that "foo" | repeat 5
- "repeat": func(count int, str string) string { return strings.Repeat(str, count) },
- // Deprecated: Use trimAll.
- "trimall": func(a, b string) string { return strings.Trim(b, a) },
- // Switch order so that "$foo" | trimall "$"
- "trimAll": func(a, b string) string { return strings.Trim(b, a) },
- "trimSuffix": func(a, b string) string { return strings.TrimSuffix(b, a) },
- "trimPrefix": func(a, b string) string { return strings.TrimPrefix(b, a) },
- "nospace": util.DeleteWhiteSpace,
- "initials": initials,
- "randAlphaNum": randAlphaNumeric,
- "randAlpha": randAlpha,
- "randAscii": randAscii,
- "randNumeric": randNumeric,
- "swapcase": util.SwapCase,
- "shuffle": xstrings.Shuffle,
- "snakecase": xstrings.ToSnakeCase,
- "camelcase": xstrings.ToCamelCase,
- "kebabcase": xstrings.ToKebabCase,
- "wrap": func(l int, s string) string { return util.Wrap(s, l) },
- "wrapWith": func(l int, sep, str string) string { return util.WrapCustom(str, l, sep, true) },
- // Switch order so that "foobar" | contains "foo"
- "contains": func(substr string, str string) bool { return strings.Contains(str, substr) },
- "hasPrefix": func(substr string, str string) bool { return strings.HasPrefix(str, substr) },
- "hasSuffix": func(substr string, str string) bool { return strings.HasSuffix(str, substr) },
- "quote": quote,
- "squote": squote,
- "cat": cat,
- "indent": indent,
- "nindent": nindent,
- "replace": replace,
- "plural": plural,
- "sha1sum": sha1sum,
- "sha256sum": sha256sum,
- "adler32sum": adler32sum,
- "toString": strval,
-
- // Wrap Atoi to stop errors.
- "atoi": func(a string) int { i, _ := strconv.Atoi(a); return i },
- "int64": toInt64,
- "int": toInt,
- "float64": toFloat64,
- "toDecimal": toDecimal,
-
- //"gt": func(a, b int) bool {return a > b},
- //"gte": func(a, b int) bool {return a >= b},
- //"lt": func(a, b int) bool {return a < b},
- //"lte": func(a, b int) bool {return a <= b},
-
- // split "/" foo/bar returns map[int]string{0: foo, 1: bar}
- "split": split,
- "splitList": func(sep, orig string) []string { return strings.Split(orig, sep) },
- // splitn "/" foo/bar/fuu returns map[int]string{0: foo, 1: bar/fuu}
- "splitn": splitn,
- "toStrings": strslice,
-
- "until": until,
- "untilStep": untilStep,
-
- // VERY basic arithmetic.
- "add1": func(i interface{}) int64 { return toInt64(i) + 1 },
- "add": func(i ...interface{}) int64 {
- var a int64 = 0
- for _, b := range i {
- a += toInt64(b)
- }
- return a
- },
- "sub": func(a, b interface{}) int64 { return toInt64(a) - toInt64(b) },
- "div": func(a, b interface{}) int64 { return toInt64(a) / toInt64(b) },
- "mod": func(a, b interface{}) int64 { return toInt64(a) % toInt64(b) },
- "mul": func(a interface{}, v ...interface{}) int64 {
- val := toInt64(a)
- for _, b := range v {
- val = val * toInt64(b)
- }
- return val
- },
- "biggest": max,
- "max": max,
- "min": min,
- "ceil": ceil,
- "floor": floor,
- "round": round,
-
- // string slices. Note that we reverse the order b/c that's better
- // for template processing.
- "join": join,
- "sortAlpha": sortAlpha,
-
- // Defaults
- "default": dfault,
- "empty": empty,
- "coalesce": coalesce,
- "compact": compact,
- "deepCopy": deepCopy,
- "toJson": toJson,
- "toPrettyJson": toPrettyJson,
- "ternary": ternary,
-
- // Reflection
- "typeOf": typeOf,
- "typeIs": typeIs,
- "typeIsLike": typeIsLike,
- "kindOf": kindOf,
- "kindIs": kindIs,
- "deepEqual": reflect.DeepEqual,
-
- // OS:
- "env": func(s string) string { return os.Getenv(s) },
- "expandenv": func(s string) string { return os.ExpandEnv(s) },
-
- // Network:
- "getHostByName": getHostByName,
-
- // File Paths:
- "base": path.Base,
- "dir": path.Dir,
- "clean": path.Clean,
- "ext": path.Ext,
- "isAbs": path.IsAbs,
-
- // Encoding:
- "b64enc": base64encode,
- "b64dec": base64decode,
- "b32enc": base32encode,
- "b32dec": base32decode,
-
- // Data Structures:
- "tuple": list, // FIXME: with the addition of append/prepend these are no longer immutable.
- "list": list,
- "dict": dict,
- "set": set,
- "unset": unset,
- "hasKey": hasKey,
- "pluck": pluck,
- "keys": keys,
- "pick": pick,
- "omit": omit,
- "merge": merge,
- "mergeOverwrite": mergeOverwrite,
- "values": values,
-
- "append": push, "push": push,
- "prepend": prepend,
- "first": first,
- "rest": rest,
- "last": last,
- "initial": initial,
- "reverse": reverse,
- "uniq": uniq,
- "without": without,
- "has": has,
- "slice": slice,
- "concat": concat,
-
- // Crypto:
- "genPrivateKey": generatePrivateKey,
- "derivePassword": derivePassword,
- "buildCustomCert": buildCustomCertificate,
- "genCA": generateCertificateAuthority,
- "genSelfSignedCert": generateSelfSignedCertificate,
- "genSignedCert": generateSignedCertificate,
- "encryptAES": encryptAES,
- "decryptAES": decryptAES,
-
- // UUIDs:
- "uuidv4": uuidv4,
-
- // SemVer:
- "semver": semver,
- "semverCompare": semverCompare,
-
- // Flow Control:
- "fail": func(msg string) (string, error) { return "", errors.New(msg) },
-
- // Regex
- "regexMatch": regexMatch,
- "regexFindAll": regexFindAll,
- "regexFind": regexFind,
- "regexReplaceAll": regexReplaceAll,
- "regexReplaceAllLiteral": regexReplaceAllLiteral,
- "regexSplit": regexSplit,
-
- // URLs:
- "urlParse": urlParse,
- "urlJoin": urlJoin,
-}
diff --git a/vendor/github.com/Masterminds/sprig/glide.yaml b/vendor/github.com/Masterminds/sprig/glide.yaml
deleted file mode 100644
index f317d2b2b..000000000
--- a/vendor/github.com/Masterminds/sprig/glide.yaml
+++ /dev/null
@@ -1,19 +0,0 @@
-package: github.com/Masterminds/sprig
-import:
-- package: github.com/Masterminds/goutils
- version: ^1.0.0
-- package: github.com/google/uuid
- version: ^1.0.0
-- package: golang.org/x/crypto
- subpackages:
- - scrypt
-- package: github.com/Masterminds/semver
- version: ^v1.2.2
-- package: github.com/stretchr/testify
- version: ^v1.2.2
-- package: github.com/imdario/mergo
- version: ~0.3.7
-- package: github.com/huandu/xstrings
- version: ^1.2
-- package: github.com/mitchellh/copystructure
- version: ^1.0.0
diff --git a/vendor/github.com/Masterminds/sprig/list.go b/vendor/github.com/Masterminds/sprig/list.go
deleted file mode 100644
index c0381bbb6..000000000
--- a/vendor/github.com/Masterminds/sprig/list.go
+++ /dev/null
@@ -1,311 +0,0 @@
-package sprig
-
-import (
- "fmt"
- "reflect"
- "sort"
-)
-
-// Reflection is used in these functions so that slices and arrays of strings,
-// ints, and other types not implementing []interface{} can be worked with.
-// For example, this is useful if you need to work on the output of regexs.
-
-func list(v ...interface{}) []interface{} {
- return v
-}
-
-func push(list interface{}, v interface{}) []interface{} {
- tp := reflect.TypeOf(list).Kind()
- switch tp {
- case reflect.Slice, reflect.Array:
- l2 := reflect.ValueOf(list)
-
- l := l2.Len()
- nl := make([]interface{}, l)
- for i := 0; i < l; i++ {
- nl[i] = l2.Index(i).Interface()
- }
-
- return append(nl, v)
-
- default:
- panic(fmt.Sprintf("Cannot push on type %s", tp))
- }
-}
-
-func prepend(list interface{}, v interface{}) []interface{} {
- //return append([]interface{}{v}, list...)
-
- tp := reflect.TypeOf(list).Kind()
- switch tp {
- case reflect.Slice, reflect.Array:
- l2 := reflect.ValueOf(list)
-
- l := l2.Len()
- nl := make([]interface{}, l)
- for i := 0; i < l; i++ {
- nl[i] = l2.Index(i).Interface()
- }
-
- return append([]interface{}{v}, nl...)
-
- default:
- panic(fmt.Sprintf("Cannot prepend on type %s", tp))
- }
-}
-
-func last(list interface{}) interface{} {
- tp := reflect.TypeOf(list).Kind()
- switch tp {
- case reflect.Slice, reflect.Array:
- l2 := reflect.ValueOf(list)
-
- l := l2.Len()
- if l == 0 {
- return nil
- }
-
- return l2.Index(l - 1).Interface()
- default:
- panic(fmt.Sprintf("Cannot find last on type %s", tp))
- }
-}
-
-func first(list interface{}) interface{} {
- tp := reflect.TypeOf(list).Kind()
- switch tp {
- case reflect.Slice, reflect.Array:
- l2 := reflect.ValueOf(list)
-
- l := l2.Len()
- if l == 0 {
- return nil
- }
-
- return l2.Index(0).Interface()
- default:
- panic(fmt.Sprintf("Cannot find first on type %s", tp))
- }
-}
-
-func rest(list interface{}) []interface{} {
- tp := reflect.TypeOf(list).Kind()
- switch tp {
- case reflect.Slice, reflect.Array:
- l2 := reflect.ValueOf(list)
-
- l := l2.Len()
- if l == 0 {
- return nil
- }
-
- nl := make([]interface{}, l-1)
- for i := 1; i < l; i++ {
- nl[i-1] = l2.Index(i).Interface()
- }
-
- return nl
- default:
- panic(fmt.Sprintf("Cannot find rest on type %s", tp))
- }
-}
-
-func initial(list interface{}) []interface{} {
- tp := reflect.TypeOf(list).Kind()
- switch tp {
- case reflect.Slice, reflect.Array:
- l2 := reflect.ValueOf(list)
-
- l := l2.Len()
- if l == 0 {
- return nil
- }
-
- nl := make([]interface{}, l-1)
- for i := 0; i < l-1; i++ {
- nl[i] = l2.Index(i).Interface()
- }
-
- return nl
- default:
- panic(fmt.Sprintf("Cannot find initial on type %s", tp))
- }
-}
-
-func sortAlpha(list interface{}) []string {
- k := reflect.Indirect(reflect.ValueOf(list)).Kind()
- switch k {
- case reflect.Slice, reflect.Array:
- a := strslice(list)
- s := sort.StringSlice(a)
- s.Sort()
- return s
- }
- return []string{strval(list)}
-}
-
-func reverse(v interface{}) []interface{} {
- tp := reflect.TypeOf(v).Kind()
- switch tp {
- case reflect.Slice, reflect.Array:
- l2 := reflect.ValueOf(v)
-
- l := l2.Len()
- // We do not sort in place because the incoming array should not be altered.
- nl := make([]interface{}, l)
- for i := 0; i < l; i++ {
- nl[l-i-1] = l2.Index(i).Interface()
- }
-
- return nl
- default:
- panic(fmt.Sprintf("Cannot find reverse on type %s", tp))
- }
-}
-
-func compact(list interface{}) []interface{} {
- tp := reflect.TypeOf(list).Kind()
- switch tp {
- case reflect.Slice, reflect.Array:
- l2 := reflect.ValueOf(list)
-
- l := l2.Len()
- nl := []interface{}{}
- var item interface{}
- for i := 0; i < l; i++ {
- item = l2.Index(i).Interface()
- if !empty(item) {
- nl = append(nl, item)
- }
- }
-
- return nl
- default:
- panic(fmt.Sprintf("Cannot compact on type %s", tp))
- }
-}
-
-func uniq(list interface{}) []interface{} {
- tp := reflect.TypeOf(list).Kind()
- switch tp {
- case reflect.Slice, reflect.Array:
- l2 := reflect.ValueOf(list)
-
- l := l2.Len()
- dest := []interface{}{}
- var item interface{}
- for i := 0; i < l; i++ {
- item = l2.Index(i).Interface()
- if !inList(dest, item) {
- dest = append(dest, item)
- }
- }
-
- return dest
- default:
- panic(fmt.Sprintf("Cannot find uniq on type %s", tp))
- }
-}
-
-func inList(haystack []interface{}, needle interface{}) bool {
- for _, h := range haystack {
- if reflect.DeepEqual(needle, h) {
- return true
- }
- }
- return false
-}
-
-func without(list interface{}, omit ...interface{}) []interface{} {
- tp := reflect.TypeOf(list).Kind()
- switch tp {
- case reflect.Slice, reflect.Array:
- l2 := reflect.ValueOf(list)
-
- l := l2.Len()
- res := []interface{}{}
- var item interface{}
- for i := 0; i < l; i++ {
- item = l2.Index(i).Interface()
- if !inList(omit, item) {
- res = append(res, item)
- }
- }
-
- return res
- default:
- panic(fmt.Sprintf("Cannot find without on type %s", tp))
- }
-}
-
-func has(needle interface{}, haystack interface{}) bool {
- if haystack == nil {
- return false
- }
- tp := reflect.TypeOf(haystack).Kind()
- switch tp {
- case reflect.Slice, reflect.Array:
- l2 := reflect.ValueOf(haystack)
- var item interface{}
- l := l2.Len()
- for i := 0; i < l; i++ {
- item = l2.Index(i).Interface()
- if reflect.DeepEqual(needle, item) {
- return true
- }
- }
-
- return false
- default:
- panic(fmt.Sprintf("Cannot find has on type %s", tp))
- }
-}
-
-// $list := [1, 2, 3, 4, 5]
-// slice $list -> list[0:5] = list[:]
-// slice $list 0 3 -> list[0:3] = list[:3]
-// slice $list 3 5 -> list[3:5]
-// slice $list 3 -> list[3:5] = list[3:]
-func slice(list interface{}, indices ...interface{}) interface{} {
- tp := reflect.TypeOf(list).Kind()
- switch tp {
- case reflect.Slice, reflect.Array:
- l2 := reflect.ValueOf(list)
-
- l := l2.Len()
- if l == 0 {
- return nil
- }
-
- var start, end int
- if len(indices) > 0 {
- start = toInt(indices[0])
- }
- if len(indices) < 2 {
- end = l
- } else {
- end = toInt(indices[1])
- }
-
- return l2.Slice(start, end).Interface()
- default:
- panic(fmt.Sprintf("list should be type of slice or array but %s", tp))
- }
-}
-
-func concat(lists ...interface{}) interface{} {
- var res []interface{}
- for _, list := range lists {
- tp := reflect.TypeOf(list).Kind()
- switch tp {
- case reflect.Slice, reflect.Array:
- l2 := reflect.ValueOf(list)
- for i := 0; i < l2.Len(); i++ {
- res = append(res, l2.Index(i).Interface())
- }
- default:
- panic(fmt.Sprintf("Cannot concat type %s as list", tp))
- }
- }
- return res
-}
diff --git a/vendor/github.com/Masterminds/sprig/numeric.go b/vendor/github.com/Masterminds/sprig/numeric.go
deleted file mode 100644
index f4af4af2a..000000000
--- a/vendor/github.com/Masterminds/sprig/numeric.go
+++ /dev/null
@@ -1,169 +0,0 @@
-package sprig
-
-import (
- "fmt"
- "math"
- "reflect"
- "strconv"
-)
-
-// toFloat64 converts 64-bit floats
-func toFloat64(v interface{}) float64 {
- if str, ok := v.(string); ok {
- iv, err := strconv.ParseFloat(str, 64)
- if err != nil {
- return 0
- }
- return iv
- }
-
- val := reflect.Indirect(reflect.ValueOf(v))
- switch val.Kind() {
- case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int:
- return float64(val.Int())
- case reflect.Uint8, reflect.Uint16, reflect.Uint32:
- return float64(val.Uint())
- case reflect.Uint, reflect.Uint64:
- return float64(val.Uint())
- case reflect.Float32, reflect.Float64:
- return val.Float()
- case reflect.Bool:
- if val.Bool() == true {
- return 1
- }
- return 0
- default:
- return 0
- }
-}
-
-func toInt(v interface{}) int {
- //It's not optimal. Bud I don't want duplicate toInt64 code.
- return int(toInt64(v))
-}
-
-// toInt64 converts integer types to 64-bit integers
-func toInt64(v interface{}) int64 {
- if str, ok := v.(string); ok {
- iv, err := strconv.ParseInt(str, 10, 64)
- if err != nil {
- return 0
- }
- return iv
- }
-
- val := reflect.Indirect(reflect.ValueOf(v))
- switch val.Kind() {
- case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int:
- return val.Int()
- case reflect.Uint8, reflect.Uint16, reflect.Uint32:
- return int64(val.Uint())
- case reflect.Uint, reflect.Uint64:
- tv := val.Uint()
- if tv <= math.MaxInt64 {
- return int64(tv)
- }
- // TODO: What is the sensible thing to do here?
- return math.MaxInt64
- case reflect.Float32, reflect.Float64:
- return int64(val.Float())
- case reflect.Bool:
- if val.Bool() == true {
- return 1
- }
- return 0
- default:
- return 0
- }
-}
-
-func max(a interface{}, i ...interface{}) int64 {
- aa := toInt64(a)
- for _, b := range i {
- bb := toInt64(b)
- if bb > aa {
- aa = bb
- }
- }
- return aa
-}
-
-func min(a interface{}, i ...interface{}) int64 {
- aa := toInt64(a)
- for _, b := range i {
- bb := toInt64(b)
- if bb < aa {
- aa = bb
- }
- }
- return aa
-}
-
-func until(count int) []int {
- step := 1
- if count < 0 {
- step = -1
- }
- return untilStep(0, count, step)
-}
-
-func untilStep(start, stop, step int) []int {
- v := []int{}
-
- if stop < start {
- if step >= 0 {
- return v
- }
- for i := start; i > stop; i += step {
- v = append(v, i)
- }
- return v
- }
-
- if step <= 0 {
- return v
- }
- for i := start; i < stop; i += step {
- v = append(v, i)
- }
- return v
-}
-
-func floor(a interface{}) float64 {
- aa := toFloat64(a)
- return math.Floor(aa)
-}
-
-func ceil(a interface{}) float64 {
- aa := toFloat64(a)
- return math.Ceil(aa)
-}
-
-func round(a interface{}, p int, r_opt ...float64) float64 {
- roundOn := .5
- if len(r_opt) > 0 {
- roundOn = r_opt[0]
- }
- val := toFloat64(a)
- places := toFloat64(p)
-
- var round float64
- pow := math.Pow(10, places)
- digit := pow * val
- _, div := math.Modf(digit)
- if div >= roundOn {
- round = math.Ceil(digit)
- } else {
- round = math.Floor(digit)
- }
- return round / pow
-}
-
-// converts unix octal to decimal
-func toDecimal(v interface{}) int64 {
- result, err := strconv.ParseInt(fmt.Sprint(v), 8, 64)
- if err != nil {
- return 0
- }
- return result
-}
diff --git a/vendor/github.com/Masterminds/sprig/regex.go b/vendor/github.com/Masterminds/sprig/regex.go
deleted file mode 100644
index 2016f6633..000000000
--- a/vendor/github.com/Masterminds/sprig/regex.go
+++ /dev/null
@@ -1,35 +0,0 @@
-package sprig
-
-import (
- "regexp"
-)
-
-func regexMatch(regex string, s string) bool {
- match, _ := regexp.MatchString(regex, s)
- return match
-}
-
-func regexFindAll(regex string, s string, n int) []string {
- r := regexp.MustCompile(regex)
- return r.FindAllString(s, n)
-}
-
-func regexFind(regex string, s string) string {
- r := regexp.MustCompile(regex)
- return r.FindString(s)
-}
-
-func regexReplaceAll(regex string, s string, repl string) string {
- r := regexp.MustCompile(regex)
- return r.ReplaceAllString(s, repl)
-}
-
-func regexReplaceAllLiteral(regex string, s string, repl string) string {
- r := regexp.MustCompile(regex)
- return r.ReplaceAllLiteralString(s, repl)
-}
-
-func regexSplit(regex string, s string, n int) []string {
- r := regexp.MustCompile(regex)
- return r.Split(s, n)
-}
diff --git a/vendor/github.com/Masterminds/sprig/url.go b/vendor/github.com/Masterminds/sprig/url.go
deleted file mode 100644
index 5f22d801f..000000000
--- a/vendor/github.com/Masterminds/sprig/url.go
+++ /dev/null
@@ -1,66 +0,0 @@
-package sprig
-
-import (
- "fmt"
- "net/url"
- "reflect"
-)
-
-func dictGetOrEmpty(dict map[string]interface{}, key string) string {
- value, ok := dict[key]; if !ok {
- return ""
- }
- tp := reflect.TypeOf(value).Kind()
- if tp != reflect.String {
- panic(fmt.Sprintf("unable to parse %s key, must be of type string, but %s found", key, tp.String()))
- }
- return reflect.ValueOf(value).String()
-}
-
-// parses given URL to return dict object
-func urlParse(v string) map[string]interface{} {
- dict := map[string]interface{}{}
- parsedUrl, err := url.Parse(v)
- if err != nil {
- panic(fmt.Sprintf("unable to parse url: %s", err))
- }
- dict["scheme"] = parsedUrl.Scheme
- dict["host"] = parsedUrl.Host
- dict["hostname"] = parsedUrl.Hostname()
- dict["path"] = parsedUrl.Path
- dict["query"] = parsedUrl.RawQuery
- dict["opaque"] = parsedUrl.Opaque
- dict["fragment"] = parsedUrl.Fragment
- if parsedUrl.User != nil {
- dict["userinfo"] = parsedUrl.User.String()
- } else {
- dict["userinfo"] = ""
- }
-
- return dict
-}
-
-// join given dict to URL string
-func urlJoin(d map[string]interface{}) string {
- resUrl := url.URL{
- Scheme: dictGetOrEmpty(d, "scheme"),
- Host: dictGetOrEmpty(d, "host"),
- Path: dictGetOrEmpty(d, "path"),
- RawQuery: dictGetOrEmpty(d, "query"),
- Opaque: dictGetOrEmpty(d, "opaque"),
- Fragment: dictGetOrEmpty(d, "fragment"),
-
- }
- userinfo := dictGetOrEmpty(d, "userinfo")
- var user *url.Userinfo = nil
- if userinfo != "" {
- tempUrl, err := url.Parse(fmt.Sprintf("proto://%s@host", userinfo))
- if err != nil {
- panic(fmt.Sprintf("unable to parse userinfo in dict: %s", err))
- }
- user = tempUrl.User
- }
-
- resUrl.User = user
- return resUrl.String()
-}
diff --git a/vendor/github.com/Masterminds/sprig/.gitignore b/vendor/github.com/Masterminds/sprig/v3/.gitignore
similarity index 100%
rename from vendor/github.com/Masterminds/sprig/.gitignore
rename to vendor/github.com/Masterminds/sprig/v3/.gitignore
diff --git a/vendor/github.com/Masterminds/sprig/v3/CHANGELOG.md b/vendor/github.com/Masterminds/sprig/v3/CHANGELOG.md
new file mode 100644
index 000000000..b5ef766a7
--- /dev/null
+++ b/vendor/github.com/Masterminds/sprig/v3/CHANGELOG.md
@@ -0,0 +1,401 @@
+# Changelog
+
+## Release 3.3.0 (2024-08-29)
+
+### Added
+
+- #400: added sha512sum function (thanks @itzik-elayev)
+
+### Changed
+
+- #407: Removed duplicate documentation (functions were documentated in 2 places)
+- #290: Corrected copy/paster oops in math documentation (thanks @zzhu41)
+- #369: Corrected template reference in docs (thanks @chey)
+- #375: Added link to URL documenation (thanks @carlpett)
+- #406: Updated the mergo dependency which had a breaking change (which was accounted for)
+- #376: Fixed documentation error (thanks @jheyduk)
+- #404: Updated dependency tree
+- #391: Fixed misspelling (thanks @chrishalbert)
+- #405: Updated Go versions used in testing
+
+## Release 3.2.3 (2022-11-29)
+
+### Changed
+
+- Updated docs (thanks @book987 @aJetHorn @neelayu @pellizzetti @apricote @SaigyoujiYuyuko233 @AlekSi)
+- #348: Updated huandu/xstrings which fixed a snake case bug (thanks @yxxhero)
+- #353: Updated masterminds/semver which included bug fixes
+- #354: Updated golang.org/x/crypto which included bug fixes
+
+## Release 3.2.2 (2021-02-04)
+
+This is a re-release of 3.2.1 to satisfy something with the Go module system.
+
+## Release 3.2.1 (2021-02-04)
+
+### Changed
+
+- Upgraded `Masterminds/goutils` to `v1.1.1`. see the [Security Advisory](https://github.com/Masterminds/goutils/security/advisories/GHSA-xg2h-wx96-xgxr)
+
+## Release 3.2.0 (2020-12-14)
+
+### Added
+
+- #211: Added randInt function (thanks @kochurovro)
+- #223: Added fromJson and mustFromJson functions (thanks @mholt)
+- #242: Added a bcrypt function (thanks @robbiet480)
+- #253: Added randBytes function (thanks @MikaelSmith)
+- #254: Added dig function for dicts (thanks @nyarly)
+- #257: Added regexQuoteMeta for quoting regex metadata (thanks @rheaton)
+- #261: Added filepath functions osBase, osDir, osExt, osClean, osIsAbs (thanks @zugl)
+- #268: Added and and all functions for testing conditions (thanks @phuslu)
+- #181: Added float64 arithmetic addf, add1f, subf, divf, mulf, maxf, and minf
+ (thanks @andrewmostello)
+- #265: Added chunk function to split array into smaller arrays (thanks @karelbilek)
+- #270: Extend certificate functions to handle non-RSA keys + add support for
+ ed25519 keys (thanks @misberner)
+
+### Changed
+
+- Removed testing and support for Go 1.12. ed25519 support requires Go 1.13 or newer
+- Using semver 3.1.1 and mergo 0.3.11
+
+### Fixed
+
+- #249: Fix htmlDateInZone example (thanks @spawnia)
+
+NOTE: The dependency github.com/imdario/mergo reverted the breaking change in
+0.3.9 via 0.3.10 release.
+
+## Release 3.1.0 (2020-04-16)
+
+NOTE: The dependency github.com/imdario/mergo made a behavior change in 0.3.9
+that impacts sprig functionality. Do not use sprig with a version newer than 0.3.8.
+
+### Added
+
+- #225: Added support for generating htpasswd hash (thanks @rustycl0ck)
+- #224: Added duration filter (thanks @frebib)
+- #205: Added `seq` function (thanks @thadc23)
+
+### Changed
+
+- #203: Unlambda functions with correct signature (thanks @muesli)
+- #236: Updated the license formatting for GitHub display purposes
+- #238: Updated package dependency versions. Note, mergo not updated to 0.3.9
+ as it causes a breaking change for sprig. That issue is tracked at
+ https://github.com/imdario/mergo/issues/139
+
+### Fixed
+
+- #229: Fix `seq` example in docs (thanks @kalmant)
+
+## Release 3.0.2 (2019-12-13)
+
+### Fixed
+
+- #220: Updating to semver v3.0.3 to fix issue with <= ranges
+- #218: fix typo elyptical->elliptic in ecdsa key description (thanks @laverya)
+
+## Release 3.0.1 (2019-12-08)
+
+### Fixed
+
+- #212: Updated semver fixing broken constraint checking with ^0.0
+
+## Release 3.0.0 (2019-10-02)
+
+### Added
+
+- #187: Added durationRound function (thanks @yjp20)
+- #189: Added numerous template functions that return errors rather than panic (thanks @nrvnrvn)
+- #193: Added toRawJson support (thanks @Dean-Coakley)
+- #197: Added get support to dicts (thanks @Dean-Coakley)
+
+### Changed
+
+- #186: Moving dependency management to Go modules
+- #186: Updated semver to v3. This has changes in the way ^ is handled
+- #194: Updated documentation on merging and how it copies. Added example using deepCopy
+- #196: trunc now supports negative values (thanks @Dean-Coakley)
+
+## Release 2.22.0 (2019-10-02)
+
+### Added
+
+- #173: Added getHostByName function to resolve dns names to ips (thanks @fcgravalos)
+- #195: Added deepCopy function for use with dicts
+
+### Changed
+
+- Updated merge and mergeOverwrite documentation to explain copying and how to
+ use deepCopy with it
+
+## Release 2.21.0 (2019-09-18)
+
+### Added
+
+- #122: Added encryptAES/decryptAES functions (thanks @n0madic)
+- #128: Added toDecimal support (thanks @Dean-Coakley)
+- #169: Added list contcat (thanks @astorath)
+- #174: Added deepEqual function (thanks @bonifaido)
+- #170: Added url parse and join functions (thanks @astorath)
+
+### Changed
+
+- #171: Updated glide config for Google UUID to v1 and to add ranges to semver and testify
+
+### Fixed
+
+- #172: Fix semver wildcard example (thanks @piepmatz)
+- #175: Fix dateInZone doc example (thanks @s3than)
+
+## Release 2.20.0 (2019-06-18)
+
+### Added
+
+- #164: Adding function to get unix epoch for a time (@mattfarina)
+- #166: Adding tests for date_in_zone (@mattfarina)
+
+### Changed
+
+- #144: Fix function comments based on best practices from Effective Go (@CodeLingoTeam)
+- #150: Handles pointer type for time.Time in "htmlDate" (@mapreal19)
+- #161, #157, #160, #153, #158, #156, #155, #159, #152 documentation updates (@badeadan)
+
+### Fixed
+
+## Release 2.19.0 (2019-03-02)
+
+IMPORTANT: This release reverts a change from 2.18.0
+
+In the previous release (2.18), we prematurely merged a partial change to the crypto functions that led to creating two sets of crypto functions (I blame @technosophos -- since that's me). This release rolls back that change, and does what was originally intended: It alters the existing crypto functions to use secure random.
+
+We debated whether this classifies as a change worthy of major revision, but given the proximity to the last release, we have decided that treating 2.18 as a faulty release is the correct course of action. We apologize for any inconvenience.
+
+### Changed
+
+- Fix substr panic 35fb796 (Alexey igrychev)
+- Remove extra period 1eb7729 (Matthew Lorimor)
+- Make random string functions use crypto by default 6ceff26 (Matthew Lorimor)
+- README edits/fixes/suggestions 08fe136 (Lauri Apple)
+
+
+## Release 2.18.0 (2019-02-12)
+
+### Added
+
+- Added mergeOverwrite function
+- cryptographic functions that use secure random (see fe1de12)
+
+### Changed
+
+- Improve documentation of regexMatch function, resolves #139 90b89ce (Jan Tagscherer)
+- Handle has for nil list 9c10885 (Daniel Cohen)
+- Document behaviour of mergeOverwrite fe0dbe9 (Lukas Rieder)
+- doc: adds missing documentation. 4b871e6 (Fernandez Ludovic)
+- Replace outdated goutils imports 01893d2 (Matthew Lorimor)
+- Surface crypto secure random strings from goutils fe1de12 (Matthew Lorimor)
+- Handle untyped nil values as paramters to string functions 2b2ec8f (Morten Torkildsen)
+
+### Fixed
+
+- Fix dict merge issue and provide mergeOverwrite .dst .src1 to overwrite from src -> dst 4c59c12 (Lukas Rieder)
+- Fix substr var names and comments d581f80 (Dean Coakley)
+- Fix substr documentation 2737203 (Dean Coakley)
+
+## Release 2.17.1 (2019-01-03)
+
+### Fixed
+
+The 2.17.0 release did not have a version pinned for xstrings, which caused compilation failures when xstrings < 1.2 was used. This adds the correct version string to glide.yaml.
+
+## Release 2.17.0 (2019-01-03)
+
+### Added
+
+- adds alder32sum function and test 6908fc2 (marshallford)
+- Added kebabcase function ca331a1 (Ilyes512)
+
+### Changed
+
+- Update goutils to 1.1.0 4e1125d (Matt Butcher)
+
+### Fixed
+
+- Fix 'has' documentation e3f2a85 (dean-coakley)
+- docs(dict): fix typo in pick example dc424f9 (Dustin Specker)
+- fixes spelling errors... not sure how that happened 4cf188a (marshallford)
+
+## Release 2.16.0 (2018-08-13)
+
+### Added
+
+- add splitn function fccb0b0 (Helgi Þorbjörnsson)
+- Add slice func df28ca7 (gongdo)
+- Generate serial number a3bdffd (Cody Coons)
+- Extract values of dict with values function df39312 (Lawrence Jones)
+
+### Changed
+
+- Modify panic message for list.slice ae38335 (gongdo)
+- Minor improvement in code quality - Removed an unreachable piece of code at defaults.go#L26:6 - Resolve formatting issues. 5834241 (Abhishek Kashyap)
+- Remove duplicated documentation 1d97af1 (Matthew Fisher)
+- Test on go 1.11 49df809 (Helgi Þormar Þorbjörnsson)
+
+### Fixed
+
+- Fix file permissions c5f40b5 (gongdo)
+- Fix example for buildCustomCert 7779e0d (Tin Lam)
+
+## Release 2.15.0 (2018-04-02)
+
+### Added
+
+- #68 and #69: Add json helpers to docs (thanks @arunvelsriram)
+- #66: Add ternary function (thanks @binoculars)
+- #67: Allow keys function to take multiple dicts (thanks @binoculars)
+- #89: Added sha1sum to crypto function (thanks @benkeil)
+- #81: Allow customizing Root CA that used by genSignedCert (thanks @chenzhiwei)
+- #92: Add travis testing for go 1.10
+- #93: Adding appveyor config for windows testing
+
+### Changed
+
+- #90: Updating to more recent dependencies
+- #73: replace satori/go.uuid with google/uuid (thanks @petterw)
+
+### Fixed
+
+- #76: Fixed documentation typos (thanks @Thiht)
+- Fixed rounding issue on the `ago` function. Note, the removes support for Go 1.8 and older
+
+## Release 2.14.1 (2017-12-01)
+
+### Fixed
+
+- #60: Fix typo in function name documentation (thanks @neil-ca-moore)
+- #61: Removing line with {{ due to blocking github pages genertion
+- #64: Update the list functions to handle int, string, and other slices for compatibility
+
+## Release 2.14.0 (2017-10-06)
+
+This new version of Sprig adds a set of functions for generating and working with SSL certificates.
+
+- `genCA` generates an SSL Certificate Authority
+- `genSelfSignedCert` generates an SSL self-signed certificate
+- `genSignedCert` generates an SSL certificate and key based on a given CA
+
+## Release 2.13.0 (2017-09-18)
+
+This release adds new functions, including:
+
+- `regexMatch`, `regexFindAll`, `regexFind`, `regexReplaceAll`, `regexReplaceAllLiteral`, and `regexSplit` to work with regular expressions
+- `floor`, `ceil`, and `round` math functions
+- `toDate` converts a string to a date
+- `nindent` is just like `indent` but also prepends a new line
+- `ago` returns the time from `time.Now`
+
+### Added
+
+- #40: Added basic regex functionality (thanks @alanquillin)
+- #41: Added ceil floor and round functions (thanks @alanquillin)
+- #48: Added toDate function (thanks @andreynering)
+- #50: Added nindent function (thanks @binoculars)
+- #46: Added ago function (thanks @slayer)
+
+### Changed
+
+- #51: Updated godocs to include new string functions (thanks @curtisallen)
+- #49: Added ability to merge multiple dicts (thanks @binoculars)
+
+## Release 2.12.0 (2017-05-17)
+
+- `snakecase`, `camelcase`, and `shuffle` are three new string functions
+- `fail` allows you to bail out of a template render when conditions are not met
+
+## Release 2.11.0 (2017-05-02)
+
+- Added `toJson` and `toPrettyJson`
+- Added `merge`
+- Refactored documentation
+
+## Release 2.10.0 (2017-03-15)
+
+- Added `semver` and `semverCompare` for Semantic Versions
+- `list` replaces `tuple`
+- Fixed issue with `join`
+- Added `first`, `last`, `initial`, `rest`, `prepend`, `append`, `toString`, `toStrings`, `sortAlpha`, `reverse`, `coalesce`, `pluck`, `pick`, `compact`, `keys`, `omit`, `uniq`, `has`, `without`
+
+## Release 2.9.0 (2017-02-23)
+
+- Added `splitList` to split a list
+- Added crypto functions of `genPrivateKey` and `derivePassword`
+
+## Release 2.8.0 (2016-12-21)
+
+- Added access to several path functions (`base`, `dir`, `clean`, `ext`, and `abs`)
+- Added functions for _mutating_ dictionaries (`set`, `unset`, `hasKey`)
+
+## Release 2.7.0 (2016-12-01)
+
+- Added `sha256sum` to generate a hash of an input
+- Added functions to convert a numeric or string to `int`, `int64`, `float64`
+
+## Release 2.6.0 (2016-10-03)
+
+- Added a `uuidv4` template function for generating UUIDs inside of a template.
+
+## Release 2.5.0 (2016-08-19)
+
+- New `trimSuffix`, `trimPrefix`, `hasSuffix`, and `hasPrefix` functions
+- New aliases have been added for a few functions that didn't follow the naming conventions (`trimAll` and `abbrevBoth`)
+- `trimall` and `abbrevboth` (notice the case) are deprecated and will be removed in 3.0.0
+
+## Release 2.4.0 (2016-08-16)
+
+- Adds two functions: `until` and `untilStep`
+
+## Release 2.3.0 (2016-06-21)
+
+- cat: Concatenate strings with whitespace separators.
+- replace: Replace parts of a string: `replace " " "-" "Me First"` renders "Me-First"
+- plural: Format plurals: `len "foo" | plural "one foo" "many foos"` renders "many foos"
+- indent: Indent blocks of text in a way that is sensitive to "\n" characters.
+
+## Release 2.2.0 (2016-04-21)
+
+- Added a `genPrivateKey` function (Thanks @bacongobbler)
+
+## Release 2.1.0 (2016-03-30)
+
+- `default` now prints the default value when it does not receive a value down the pipeline. It is much safer now to do `{{.Foo | default "bar"}}`.
+- Added accessors for "hermetic" functions. These return only functions that, when given the same input, produce the same output.
+
+## Release 2.0.0 (2016-03-29)
+
+Because we switched from `int` to `int64` as the return value for all integer math functions, the library's major version number has been incremented.
+
+- `min` complements `max` (formerly `biggest`)
+- `empty` indicates that a value is the empty value for its type
+- `tuple` creates a tuple inside of a template: `{{$t := tuple "a", "b" "c"}}`
+- `dict` creates a dictionary inside of a template `{{$d := dict "key1" "val1" "key2" "val2"}}`
+- Date formatters have been added for HTML dates (as used in `date` input fields)
+- Integer math functions can convert from a number of types, including `string` (via `strconv.ParseInt`).
+
+## Release 1.2.0 (2016-02-01)
+
+- Added quote and squote
+- Added b32enc and b32dec
+- add now takes varargs
+- biggest now takes varargs
+
+## Release 1.1.0 (2015-12-29)
+
+- Added #4: Added contains function. strings.Contains, but with the arguments
+ switched to simplify common pipelines. (thanks krancour)
+- Added Travis-CI testing support
+
+## Release 1.0.0 (2015-12-23)
+
+- Initial release
diff --git a/vendor/github.com/Masterminds/sprig/v3/LICENSE.txt b/vendor/github.com/Masterminds/sprig/v3/LICENSE.txt
new file mode 100644
index 000000000..f311b1eaa
--- /dev/null
+++ b/vendor/github.com/Masterminds/sprig/v3/LICENSE.txt
@@ -0,0 +1,19 @@
+Copyright (C) 2013-2020 Masterminds
+
+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.
diff --git a/vendor/github.com/Masterminds/sprig/v3/Makefile b/vendor/github.com/Masterminds/sprig/v3/Makefile
new file mode 100644
index 000000000..78d409cde
--- /dev/null
+++ b/vendor/github.com/Masterminds/sprig/v3/Makefile
@@ -0,0 +1,9 @@
+.PHONY: test
+test:
+ @echo "==> Running tests"
+ GO111MODULE=on go test -v
+
+.PHONY: test-cover
+test-cover:
+ @echo "==> Running Tests with coverage"
+ GO111MODULE=on go test -cover .
diff --git a/vendor/github.com/Masterminds/sprig/v3/README.md b/vendor/github.com/Masterminds/sprig/v3/README.md
new file mode 100644
index 000000000..3e22c60e1
--- /dev/null
+++ b/vendor/github.com/Masterminds/sprig/v3/README.md
@@ -0,0 +1,100 @@
+# Sprig: Template functions for Go templates
+
+[](https://pkg.go.dev/github.com/Masterminds/sprig/v3)
+[](https://goreportcard.com/report/github.com/Masterminds/sprig)
+[](https://masterminds.github.io/stability/sustained.html)
+[](https://github.com/Masterminds/sprig/actions)
+
+The Go language comes with a [built-in template
+language](http://golang.org/pkg/text/template/), but not
+very many template functions. Sprig is a library that provides more than 100 commonly
+used template functions.
+
+It is inspired by the template functions found in
+[Twig](http://twig.sensiolabs.org/documentation) and in various
+JavaScript libraries, such as [underscore.js](http://underscorejs.org/).
+
+## IMPORTANT NOTES
+
+Sprig leverages [mergo](https://github.com/imdario/mergo) to handle merges. In
+its v0.3.9 release, there was a behavior change that impacts merging template
+functions in sprig. It is currently recommended to use v0.3.10 or later of that package.
+Using v0.3.9 will cause sprig tests to fail.
+
+## Package Versions
+
+There are two active major versions of the `sprig` package.
+
+* v3 is currently stable release series on the `master` branch. The Go API should
+ remain compatible with v2, the current stable version. Behavior change behind
+ some functions is the reason for the new major version.
+* v2 is the previous stable release series. It has been more than three years since
+ the initial release of v2. You can read the documentation and see the code
+ on the [release-2](https://github.com/Masterminds/sprig/tree/release-2) branch.
+ Bug fixes to this major version will continue for some time.
+
+## Usage
+
+**Template developers**: Please use Sprig's [function documentation](http://masterminds.github.io/sprig/) for
+detailed instructions and code snippets for the >100 template functions available.
+
+**Go developers**: If you'd like to include Sprig as a library in your program,
+our API documentation is available [at GoDoc.org](http://godoc.org/github.com/Masterminds/sprig).
+
+For standard usage, read on.
+
+### Load the Sprig library
+
+To load the Sprig `FuncMap`:
+
+```go
+
+import (
+ "github.com/Masterminds/sprig/v3"
+ "html/template"
+)
+
+// This example illustrates that the FuncMap *must* be set before the
+// templates themselves are loaded.
+tpl := template.Must(
+ template.New("base").Funcs(sprig.FuncMap()).ParseGlob("*.html")
+)
+
+
+```
+
+### Calling the functions inside of templates
+
+By convention, all functions are lowercase. This seems to follow the Go
+idiom for template functions (as opposed to template methods, which are
+TitleCase). For example, this:
+
+```
+{{ "hello!" | upper | repeat 5 }}
+```
+
+produces this:
+
+```
+HELLO!HELLO!HELLO!HELLO!HELLO!
+```
+
+## Principles Driving Our Function Selection
+
+We followed these principles to decide which functions to add and how to implement them:
+
+- Use template functions to build layout. The following
+ types of operations are within the domain of template functions:
+ - Formatting
+ - Layout
+ - Simple type conversions
+ - Utilities that assist in handling common formatting and layout needs (e.g. arithmetic)
+- Template functions should not return errors unless there is no way to print
+ a sensible value. For example, converting a string to an integer should not
+ produce an error if conversion fails. Instead, it should display a default
+ value.
+- Simple math is necessary for grid layouts, pagers, and so on. Complex math
+ (anything other than arithmetic) should be done outside of templates.
+- Template functions only deal with the data passed into them. They never retrieve
+ data from a source.
+- Finally, do not override core Go template functions.
diff --git a/vendor/github.com/Masterminds/sprig/v3/crypto.go b/vendor/github.com/Masterminds/sprig/v3/crypto.go
new file mode 100644
index 000000000..75fe027e4
--- /dev/null
+++ b/vendor/github.com/Masterminds/sprig/v3/crypto.go
@@ -0,0 +1,659 @@
+package sprig
+
+import (
+ "bytes"
+ "crypto"
+ "crypto/aes"
+ "crypto/cipher"
+ "crypto/dsa"
+ "crypto/ecdsa"
+ "crypto/ed25519"
+ "crypto/elliptic"
+ "crypto/hmac"
+ "crypto/rand"
+ "crypto/rsa"
+ "crypto/sha1"
+ "crypto/sha256"
+ "crypto/sha512"
+ "crypto/x509"
+ "crypto/x509/pkix"
+ "encoding/asn1"
+ "encoding/base64"
+ "encoding/binary"
+ "encoding/hex"
+ "encoding/pem"
+ "errors"
+ "fmt"
+ "hash/adler32"
+ "io"
+ "math/big"
+ "net"
+ "time"
+
+ "strings"
+
+ "github.com/google/uuid"
+ bcrypt_lib "golang.org/x/crypto/bcrypt"
+ "golang.org/x/crypto/scrypt"
+)
+
+func sha512sum(input string) string {
+ hash := sha512.Sum512([]byte(input))
+ return hex.EncodeToString(hash[:])
+}
+
+func sha256sum(input string) string {
+ hash := sha256.Sum256([]byte(input))
+ return hex.EncodeToString(hash[:])
+}
+
+func sha1sum(input string) string {
+ hash := sha1.Sum([]byte(input))
+ return hex.EncodeToString(hash[:])
+}
+
+func adler32sum(input string) string {
+ hash := adler32.Checksum([]byte(input))
+ return fmt.Sprintf("%d", hash)
+}
+
+func bcrypt(input string) string {
+ hash, err := bcrypt_lib.GenerateFromPassword([]byte(input), bcrypt_lib.DefaultCost)
+ if err != nil {
+ return fmt.Sprintf("failed to encrypt string with bcrypt: %s", err)
+ }
+
+ return string(hash)
+}
+
+func htpasswd(username string, password string) string {
+ if strings.Contains(username, ":") {
+ return fmt.Sprintf("invalid username: %s", username)
+ }
+ return fmt.Sprintf("%s:%s", username, bcrypt(password))
+}
+
+func randBytes(count int) (string, error) {
+ buf := make([]byte, count)
+ if _, err := rand.Read(buf); err != nil {
+ return "", err
+ }
+ return base64.StdEncoding.EncodeToString(buf), nil
+}
+
+// uuidv4 provides a safe and secure UUID v4 implementation
+func uuidv4() string {
+ return uuid.New().String()
+}
+
+var masterPasswordSeed = "com.lyndir.masterpassword"
+
+var passwordTypeTemplates = map[string][][]byte{
+ "maximum": {[]byte("anoxxxxxxxxxxxxxxxxx"), []byte("axxxxxxxxxxxxxxxxxno")},
+ "long": {[]byte("CvcvnoCvcvCvcv"), []byte("CvcvCvcvnoCvcv"), []byte("CvcvCvcvCvcvno"), []byte("CvccnoCvcvCvcv"), []byte("CvccCvcvnoCvcv"),
+ []byte("CvccCvcvCvcvno"), []byte("CvcvnoCvccCvcv"), []byte("CvcvCvccnoCvcv"), []byte("CvcvCvccCvcvno"), []byte("CvcvnoCvcvCvcc"),
+ []byte("CvcvCvcvnoCvcc"), []byte("CvcvCvcvCvccno"), []byte("CvccnoCvccCvcv"), []byte("CvccCvccnoCvcv"), []byte("CvccCvccCvcvno"),
+ []byte("CvcvnoCvccCvcc"), []byte("CvcvCvccnoCvcc"), []byte("CvcvCvccCvccno"), []byte("CvccnoCvcvCvcc"), []byte("CvccCvcvnoCvcc"),
+ []byte("CvccCvcvCvccno")},
+ "medium": {[]byte("CvcnoCvc"), []byte("CvcCvcno")},
+ "short": {[]byte("Cvcn")},
+ "basic": {[]byte("aaanaaan"), []byte("aannaaan"), []byte("aaannaaa")},
+ "pin": {[]byte("nnnn")},
+}
+
+var templateCharacters = map[byte]string{
+ 'V': "AEIOU",
+ 'C': "BCDFGHJKLMNPQRSTVWXYZ",
+ 'v': "aeiou",
+ 'c': "bcdfghjklmnpqrstvwxyz",
+ 'A': "AEIOUBCDFGHJKLMNPQRSTVWXYZ",
+ 'a': "AEIOUaeiouBCDFGHJKLMNPQRSTVWXYZbcdfghjklmnpqrstvwxyz",
+ 'n': "0123456789",
+ 'o': "@&%?,=[]_:-+*$#!'^~;()/.",
+ 'x': "AEIOUaeiouBCDFGHJKLMNPQRSTVWXYZbcdfghjklmnpqrstvwxyz0123456789!@#$%^&*()",
+}
+
+func derivePassword(counter uint32, passwordType, password, user, site string) string {
+ var templates = passwordTypeTemplates[passwordType]
+ if templates == nil {
+ return fmt.Sprintf("cannot find password template %s", passwordType)
+ }
+
+ var buffer bytes.Buffer
+ buffer.WriteString(masterPasswordSeed)
+ binary.Write(&buffer, binary.BigEndian, uint32(len(user)))
+ buffer.WriteString(user)
+
+ salt := buffer.Bytes()
+ key, err := scrypt.Key([]byte(password), salt, 32768, 8, 2, 64)
+ if err != nil {
+ return fmt.Sprintf("failed to derive password: %s", err)
+ }
+
+ buffer.Truncate(len(masterPasswordSeed))
+ binary.Write(&buffer, binary.BigEndian, uint32(len(site)))
+ buffer.WriteString(site)
+ binary.Write(&buffer, binary.BigEndian, counter)
+
+ var hmacv = hmac.New(sha256.New, key)
+ hmacv.Write(buffer.Bytes())
+ var seed = hmacv.Sum(nil)
+ var temp = templates[int(seed[0])%len(templates)]
+
+ buffer.Truncate(0)
+ for i, element := range temp {
+ passChars := templateCharacters[element]
+ passChar := passChars[int(seed[i+1])%len(passChars)]
+ buffer.WriteByte(passChar)
+ }
+
+ return buffer.String()
+}
+
+func generatePrivateKey(typ string) string {
+ var priv interface{}
+ var err error
+ switch typ {
+ case "", "rsa":
+ // good enough for government work
+ priv, err = rsa.GenerateKey(rand.Reader, 4096)
+ case "dsa":
+ key := new(dsa.PrivateKey)
+ // again, good enough for government work
+ if err = dsa.GenerateParameters(&key.Parameters, rand.Reader, dsa.L2048N256); err != nil {
+ return fmt.Sprintf("failed to generate dsa params: %s", err)
+ }
+ err = dsa.GenerateKey(key, rand.Reader)
+ priv = key
+ case "ecdsa":
+ // again, good enough for government work
+ priv, err = ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
+ case "ed25519":
+ _, priv, err = ed25519.GenerateKey(rand.Reader)
+ default:
+ return "Unknown type " + typ
+ }
+ if err != nil {
+ return fmt.Sprintf("failed to generate private key: %s", err)
+ }
+
+ return string(pem.EncodeToMemory(pemBlockForKey(priv)))
+}
+
+// DSAKeyFormat stores the format for DSA keys.
+// Used by pemBlockForKey
+type DSAKeyFormat struct {
+ Version int
+ P, Q, G, Y, X *big.Int
+}
+
+func pemBlockForKey(priv interface{}) *pem.Block {
+ switch k := priv.(type) {
+ case *rsa.PrivateKey:
+ return &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(k)}
+ case *dsa.PrivateKey:
+ val := DSAKeyFormat{
+ P: k.P, Q: k.Q, G: k.G,
+ Y: k.Y, X: k.X,
+ }
+ bytes, _ := asn1.Marshal(val)
+ return &pem.Block{Type: "DSA PRIVATE KEY", Bytes: bytes}
+ case *ecdsa.PrivateKey:
+ b, _ := x509.MarshalECPrivateKey(k)
+ return &pem.Block{Type: "EC PRIVATE KEY", Bytes: b}
+ default:
+ // attempt PKCS#8 format for all other keys
+ b, err := x509.MarshalPKCS8PrivateKey(k)
+ if err != nil {
+ return nil
+ }
+ return &pem.Block{Type: "PRIVATE KEY", Bytes: b}
+ }
+}
+
+func parsePrivateKeyPEM(pemBlock string) (crypto.PrivateKey, error) {
+ block, _ := pem.Decode([]byte(pemBlock))
+ if block == nil {
+ return nil, errors.New("no PEM data in input")
+ }
+
+ if block.Type == "PRIVATE KEY" {
+ priv, err := x509.ParsePKCS8PrivateKey(block.Bytes)
+ if err != nil {
+ return nil, fmt.Errorf("decoding PEM as PKCS#8: %s", err)
+ }
+ return priv, nil
+ } else if !strings.HasSuffix(block.Type, " PRIVATE KEY") {
+ return nil, fmt.Errorf("no private key data in PEM block of type %s", block.Type)
+ }
+
+ switch block.Type[:len(block.Type)-12] { // strip " PRIVATE KEY"
+ case "RSA":
+ priv, err := x509.ParsePKCS1PrivateKey(block.Bytes)
+ if err != nil {
+ return nil, fmt.Errorf("parsing RSA private key from PEM: %s", err)
+ }
+ return priv, nil
+ case "EC":
+ priv, err := x509.ParseECPrivateKey(block.Bytes)
+ if err != nil {
+ return nil, fmt.Errorf("parsing EC private key from PEM: %s", err)
+ }
+ return priv, nil
+ case "DSA":
+ var k DSAKeyFormat
+ _, err := asn1.Unmarshal(block.Bytes, &k)
+ if err != nil {
+ return nil, fmt.Errorf("parsing DSA private key from PEM: %s", err)
+ }
+ priv := &dsa.PrivateKey{
+ PublicKey: dsa.PublicKey{
+ Parameters: dsa.Parameters{
+ P: k.P, Q: k.Q, G: k.G,
+ },
+ Y: k.Y,
+ },
+ X: k.X,
+ }
+ return priv, nil
+ default:
+ return nil, fmt.Errorf("invalid private key type %s", block.Type)
+ }
+}
+
+func getPublicKey(priv crypto.PrivateKey) (crypto.PublicKey, error) {
+ switch k := priv.(type) {
+ case interface{ Public() crypto.PublicKey }:
+ return k.Public(), nil
+ case *dsa.PrivateKey:
+ return &k.PublicKey, nil
+ default:
+ return nil, fmt.Errorf("unable to get public key for type %T", priv)
+ }
+}
+
+type certificate struct {
+ Cert string
+ Key string
+}
+
+func buildCustomCertificate(b64cert string, b64key string) (certificate, error) {
+ crt := certificate{}
+
+ cert, err := base64.StdEncoding.DecodeString(b64cert)
+ if err != nil {
+ return crt, errors.New("unable to decode base64 certificate")
+ }
+
+ key, err := base64.StdEncoding.DecodeString(b64key)
+ if err != nil {
+ return crt, errors.New("unable to decode base64 private key")
+ }
+
+ decodedCert, _ := pem.Decode(cert)
+ if decodedCert == nil {
+ return crt, errors.New("unable to decode certificate")
+ }
+ _, err = x509.ParseCertificate(decodedCert.Bytes)
+ if err != nil {
+ return crt, fmt.Errorf(
+ "error parsing certificate: decodedCert.Bytes: %s",
+ err,
+ )
+ }
+
+ _, err = parsePrivateKeyPEM(string(key))
+ if err != nil {
+ return crt, fmt.Errorf(
+ "error parsing private key: %s",
+ err,
+ )
+ }
+
+ crt.Cert = string(cert)
+ crt.Key = string(key)
+
+ return crt, nil
+}
+
+func generateCertificateAuthority(
+ cn string,
+ daysValid int,
+) (certificate, error) {
+ priv, err := rsa.GenerateKey(rand.Reader, 2048)
+ if err != nil {
+ return certificate{}, fmt.Errorf("error generating rsa key: %s", err)
+ }
+
+ return generateCertificateAuthorityWithKeyInternal(cn, daysValid, priv)
+}
+
+func generateCertificateAuthorityWithPEMKey(
+ cn string,
+ daysValid int,
+ privPEM string,
+) (certificate, error) {
+ priv, err := parsePrivateKeyPEM(privPEM)
+ if err != nil {
+ return certificate{}, fmt.Errorf("parsing private key: %s", err)
+ }
+ return generateCertificateAuthorityWithKeyInternal(cn, daysValid, priv)
+}
+
+func generateCertificateAuthorityWithKeyInternal(
+ cn string,
+ daysValid int,
+ priv crypto.PrivateKey,
+) (certificate, error) {
+ ca := certificate{}
+
+ template, err := getBaseCertTemplate(cn, nil, nil, daysValid)
+ if err != nil {
+ return ca, err
+ }
+ // Override KeyUsage and IsCA
+ template.KeyUsage = x509.KeyUsageKeyEncipherment |
+ x509.KeyUsageDigitalSignature |
+ x509.KeyUsageCertSign
+ template.IsCA = true
+
+ ca.Cert, ca.Key, err = getCertAndKey(template, priv, template, priv)
+
+ return ca, err
+}
+
+func generateSelfSignedCertificate(
+ cn string,
+ ips []interface{},
+ alternateDNS []interface{},
+ daysValid int,
+) (certificate, error) {
+ priv, err := rsa.GenerateKey(rand.Reader, 2048)
+ if err != nil {
+ return certificate{}, fmt.Errorf("error generating rsa key: %s", err)
+ }
+ return generateSelfSignedCertificateWithKeyInternal(cn, ips, alternateDNS, daysValid, priv)
+}
+
+func generateSelfSignedCertificateWithPEMKey(
+ cn string,
+ ips []interface{},
+ alternateDNS []interface{},
+ daysValid int,
+ privPEM string,
+) (certificate, error) {
+ priv, err := parsePrivateKeyPEM(privPEM)
+ if err != nil {
+ return certificate{}, fmt.Errorf("parsing private key: %s", err)
+ }
+ return generateSelfSignedCertificateWithKeyInternal(cn, ips, alternateDNS, daysValid, priv)
+}
+
+func generateSelfSignedCertificateWithKeyInternal(
+ cn string,
+ ips []interface{},
+ alternateDNS []interface{},
+ daysValid int,
+ priv crypto.PrivateKey,
+) (certificate, error) {
+ cert := certificate{}
+
+ template, err := getBaseCertTemplate(cn, ips, alternateDNS, daysValid)
+ if err != nil {
+ return cert, err
+ }
+
+ cert.Cert, cert.Key, err = getCertAndKey(template, priv, template, priv)
+
+ return cert, err
+}
+
+func generateSignedCertificate(
+ cn string,
+ ips []interface{},
+ alternateDNS []interface{},
+ daysValid int,
+ ca certificate,
+) (certificate, error) {
+ priv, err := rsa.GenerateKey(rand.Reader, 2048)
+ if err != nil {
+ return certificate{}, fmt.Errorf("error generating rsa key: %s", err)
+ }
+ return generateSignedCertificateWithKeyInternal(cn, ips, alternateDNS, daysValid, ca, priv)
+}
+
+func generateSignedCertificateWithPEMKey(
+ cn string,
+ ips []interface{},
+ alternateDNS []interface{},
+ daysValid int,
+ ca certificate,
+ privPEM string,
+) (certificate, error) {
+ priv, err := parsePrivateKeyPEM(privPEM)
+ if err != nil {
+ return certificate{}, fmt.Errorf("parsing private key: %s", err)
+ }
+ return generateSignedCertificateWithKeyInternal(cn, ips, alternateDNS, daysValid, ca, priv)
+}
+
+func generateSignedCertificateWithKeyInternal(
+ cn string,
+ ips []interface{},
+ alternateDNS []interface{},
+ daysValid int,
+ ca certificate,
+ priv crypto.PrivateKey,
+) (certificate, error) {
+ cert := certificate{}
+
+ decodedSignerCert, _ := pem.Decode([]byte(ca.Cert))
+ if decodedSignerCert == nil {
+ return cert, errors.New("unable to decode certificate")
+ }
+ signerCert, err := x509.ParseCertificate(decodedSignerCert.Bytes)
+ if err != nil {
+ return cert, fmt.Errorf(
+ "error parsing certificate: decodedSignerCert.Bytes: %s",
+ err,
+ )
+ }
+ signerKey, err := parsePrivateKeyPEM(ca.Key)
+ if err != nil {
+ return cert, fmt.Errorf(
+ "error parsing private key: %s",
+ err,
+ )
+ }
+
+ template, err := getBaseCertTemplate(cn, ips, alternateDNS, daysValid)
+ if err != nil {
+ return cert, err
+ }
+
+ cert.Cert, cert.Key, err = getCertAndKey(
+ template,
+ priv,
+ signerCert,
+ signerKey,
+ )
+
+ return cert, err
+}
+
+func getCertAndKey(
+ template *x509.Certificate,
+ signeeKey crypto.PrivateKey,
+ parent *x509.Certificate,
+ signingKey crypto.PrivateKey,
+) (string, string, error) {
+ signeePubKey, err := getPublicKey(signeeKey)
+ if err != nil {
+ return "", "", fmt.Errorf("error retrieving public key from signee key: %s", err)
+ }
+ derBytes, err := x509.CreateCertificate(
+ rand.Reader,
+ template,
+ parent,
+ signeePubKey,
+ signingKey,
+ )
+ if err != nil {
+ return "", "", fmt.Errorf("error creating certificate: %s", err)
+ }
+
+ certBuffer := bytes.Buffer{}
+ if err := pem.Encode(
+ &certBuffer,
+ &pem.Block{Type: "CERTIFICATE", Bytes: derBytes},
+ ); err != nil {
+ return "", "", fmt.Errorf("error pem-encoding certificate: %s", err)
+ }
+
+ keyBuffer := bytes.Buffer{}
+ if err := pem.Encode(
+ &keyBuffer,
+ pemBlockForKey(signeeKey),
+ ); err != nil {
+ return "", "", fmt.Errorf("error pem-encoding key: %s", err)
+ }
+
+ return certBuffer.String(), keyBuffer.String(), nil
+}
+
+func getBaseCertTemplate(
+ cn string,
+ ips []interface{},
+ alternateDNS []interface{},
+ daysValid int,
+) (*x509.Certificate, error) {
+ ipAddresses, err := getNetIPs(ips)
+ if err != nil {
+ return nil, err
+ }
+ dnsNames, err := getAlternateDNSStrs(alternateDNS)
+ if err != nil {
+ return nil, err
+ }
+ serialNumberUpperBound := new(big.Int).Lsh(big.NewInt(1), 128)
+ serialNumber, err := rand.Int(rand.Reader, serialNumberUpperBound)
+ if err != nil {
+ return nil, err
+ }
+ return &x509.Certificate{
+ SerialNumber: serialNumber,
+ Subject: pkix.Name{
+ CommonName: cn,
+ },
+ IPAddresses: ipAddresses,
+ DNSNames: dnsNames,
+ NotBefore: time.Now(),
+ NotAfter: time.Now().Add(time.Hour * 24 * time.Duration(daysValid)),
+ KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
+ ExtKeyUsage: []x509.ExtKeyUsage{
+ x509.ExtKeyUsageServerAuth,
+ x509.ExtKeyUsageClientAuth,
+ },
+ BasicConstraintsValid: true,
+ }, nil
+}
+
+func getNetIPs(ips []interface{}) ([]net.IP, error) {
+ if ips == nil {
+ return []net.IP{}, nil
+ }
+ var ipStr string
+ var ok bool
+ var netIP net.IP
+ netIPs := make([]net.IP, len(ips))
+ for i, ip := range ips {
+ ipStr, ok = ip.(string)
+ if !ok {
+ return nil, fmt.Errorf("error parsing ip: %v is not a string", ip)
+ }
+ netIP = net.ParseIP(ipStr)
+ if netIP == nil {
+ return nil, fmt.Errorf("error parsing ip: %s", ipStr)
+ }
+ netIPs[i] = netIP
+ }
+ return netIPs, nil
+}
+
+func getAlternateDNSStrs(alternateDNS []interface{}) ([]string, error) {
+ if alternateDNS == nil {
+ return []string{}, nil
+ }
+ var dnsStr string
+ var ok bool
+ alternateDNSStrs := make([]string, len(alternateDNS))
+ for i, dns := range alternateDNS {
+ dnsStr, ok = dns.(string)
+ if !ok {
+ return nil, fmt.Errorf(
+ "error processing alternate dns name: %v is not a string",
+ dns,
+ )
+ }
+ alternateDNSStrs[i] = dnsStr
+ }
+ return alternateDNSStrs, nil
+}
+
+func encryptAES(password string, plaintext string) (string, error) {
+ if plaintext == "" {
+ return "", nil
+ }
+
+ key := make([]byte, 32)
+ copy(key, []byte(password))
+ block, err := aes.NewCipher(key)
+ if err != nil {
+ return "", err
+ }
+
+ content := []byte(plaintext)
+ blockSize := block.BlockSize()
+ padding := blockSize - len(content)%blockSize
+ padtext := bytes.Repeat([]byte{byte(padding)}, padding)
+ content = append(content, padtext...)
+
+ ciphertext := make([]byte, aes.BlockSize+len(content))
+
+ iv := ciphertext[:aes.BlockSize]
+ if _, err := io.ReadFull(rand.Reader, iv); err != nil {
+ return "", err
+ }
+
+ mode := cipher.NewCBCEncrypter(block, iv)
+ mode.CryptBlocks(ciphertext[aes.BlockSize:], content)
+
+ return base64.StdEncoding.EncodeToString(ciphertext), nil
+}
+
+func decryptAES(password string, crypt64 string) (string, error) {
+ if crypt64 == "" {
+ return "", nil
+ }
+
+ key := make([]byte, 32)
+ copy(key, []byte(password))
+
+ crypt, err := base64.StdEncoding.DecodeString(crypt64)
+ if err != nil {
+ return "", err
+ }
+
+ block, err := aes.NewCipher(key)
+ if err != nil {
+ return "", err
+ }
+
+ iv := crypt[:aes.BlockSize]
+ crypt = crypt[aes.BlockSize:]
+ decrypted := make([]byte, len(crypt))
+ mode := cipher.NewCBCDecrypter(block, iv)
+ mode.CryptBlocks(decrypted, crypt)
+
+ return string(decrypted[:len(decrypted)-int(decrypted[len(decrypted)-1])]), nil
+}
diff --git a/vendor/github.com/Masterminds/sprig/v3/date.go b/vendor/github.com/Masterminds/sprig/v3/date.go
new file mode 100644
index 000000000..ed022ddac
--- /dev/null
+++ b/vendor/github.com/Masterminds/sprig/v3/date.go
@@ -0,0 +1,152 @@
+package sprig
+
+import (
+ "strconv"
+ "time"
+)
+
+// Given a format and a date, format the date string.
+//
+// Date can be a `time.Time` or an `int, int32, int64`.
+// In the later case, it is treated as seconds since UNIX
+// epoch.
+func date(fmt string, date interface{}) string {
+ return dateInZone(fmt, date, "Local")
+}
+
+func htmlDate(date interface{}) string {
+ return dateInZone("2006-01-02", date, "Local")
+}
+
+func htmlDateInZone(date interface{}, zone string) string {
+ return dateInZone("2006-01-02", date, zone)
+}
+
+func dateInZone(fmt string, date interface{}, zone string) string {
+ var t time.Time
+ switch date := date.(type) {
+ default:
+ t = time.Now()
+ case time.Time:
+ t = date
+ case *time.Time:
+ t = *date
+ case int64:
+ t = time.Unix(date, 0)
+ case int:
+ t = time.Unix(int64(date), 0)
+ case int32:
+ t = time.Unix(int64(date), 0)
+ }
+
+ loc, err := time.LoadLocation(zone)
+ if err != nil {
+ loc, _ = time.LoadLocation("UTC")
+ }
+
+ return t.In(loc).Format(fmt)
+}
+
+func dateModify(fmt string, date time.Time) time.Time {
+ d, err := time.ParseDuration(fmt)
+ if err != nil {
+ return date
+ }
+ return date.Add(d)
+}
+
+func mustDateModify(fmt string, date time.Time) (time.Time, error) {
+ d, err := time.ParseDuration(fmt)
+ if err != nil {
+ return time.Time{}, err
+ }
+ return date.Add(d), nil
+}
+
+func dateAgo(date interface{}) string {
+ var t time.Time
+
+ switch date := date.(type) {
+ default:
+ t = time.Now()
+ case time.Time:
+ t = date
+ case int64:
+ t = time.Unix(date, 0)
+ case int:
+ t = time.Unix(int64(date), 0)
+ }
+ // Drop resolution to seconds
+ duration := time.Since(t).Round(time.Second)
+ return duration.String()
+}
+
+func duration(sec interface{}) string {
+ var n int64
+ switch value := sec.(type) {
+ default:
+ n = 0
+ case string:
+ n, _ = strconv.ParseInt(value, 10, 64)
+ case int64:
+ n = value
+ }
+ return (time.Duration(n) * time.Second).String()
+}
+
+func durationRound(duration interface{}) string {
+ var d time.Duration
+ switch duration := duration.(type) {
+ default:
+ d = 0
+ case string:
+ d, _ = time.ParseDuration(duration)
+ case int64:
+ d = time.Duration(duration)
+ case time.Time:
+ d = time.Since(duration)
+ }
+
+ u := uint64(d)
+ neg := d < 0
+ if neg {
+ u = -u
+ }
+
+ var (
+ year = uint64(time.Hour) * 24 * 365
+ month = uint64(time.Hour) * 24 * 30
+ day = uint64(time.Hour) * 24
+ hour = uint64(time.Hour)
+ minute = uint64(time.Minute)
+ second = uint64(time.Second)
+ )
+ switch {
+ case u > year:
+ return strconv.FormatUint(u/year, 10) + "y"
+ case u > month:
+ return strconv.FormatUint(u/month, 10) + "mo"
+ case u > day:
+ return strconv.FormatUint(u/day, 10) + "d"
+ case u > hour:
+ return strconv.FormatUint(u/hour, 10) + "h"
+ case u > minute:
+ return strconv.FormatUint(u/minute, 10) + "m"
+ case u > second:
+ return strconv.FormatUint(u/second, 10) + "s"
+ }
+ return "0s"
+}
+
+func toDate(fmt, str string) time.Time {
+ t, _ := time.ParseInLocation(fmt, str, time.Local)
+ return t
+}
+
+func mustToDate(fmt, str string) (time.Time, error) {
+ return time.ParseInLocation(fmt, str, time.Local)
+}
+
+func unixEpoch(date time.Time) string {
+ return strconv.FormatInt(date.Unix(), 10)
+}
diff --git a/vendor/github.com/Masterminds/sprig/v3/defaults.go b/vendor/github.com/Masterminds/sprig/v3/defaults.go
new file mode 100644
index 000000000..b9f979666
--- /dev/null
+++ b/vendor/github.com/Masterminds/sprig/v3/defaults.go
@@ -0,0 +1,163 @@
+package sprig
+
+import (
+ "bytes"
+ "encoding/json"
+ "math/rand"
+ "reflect"
+ "strings"
+ "time"
+)
+
+func init() {
+ rand.Seed(time.Now().UnixNano())
+}
+
+// dfault checks whether `given` is set, and returns default if not set.
+//
+// This returns `d` if `given` appears not to be set, and `given` otherwise.
+//
+// For numeric types 0 is unset.
+// For strings, maps, arrays, and slices, len() = 0 is considered unset.
+// For bool, false is unset.
+// Structs are never considered unset.
+//
+// For everything else, including pointers, a nil value is unset.
+func dfault(d interface{}, given ...interface{}) interface{} {
+
+ if empty(given) || empty(given[0]) {
+ return d
+ }
+ return given[0]
+}
+
+// empty returns true if the given value has the zero value for its type.
+func empty(given interface{}) bool {
+ g := reflect.ValueOf(given)
+ if !g.IsValid() {
+ return true
+ }
+
+ // Basically adapted from text/template.isTrue
+ switch g.Kind() {
+ default:
+ return g.IsNil()
+ case reflect.Array, reflect.Slice, reflect.Map, reflect.String:
+ return g.Len() == 0
+ case reflect.Bool:
+ return !g.Bool()
+ case reflect.Complex64, reflect.Complex128:
+ return g.Complex() == 0
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ return g.Int() == 0
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+ return g.Uint() == 0
+ case reflect.Float32, reflect.Float64:
+ return g.Float() == 0
+ case reflect.Struct:
+ return false
+ }
+}
+
+// coalesce returns the first non-empty value.
+func coalesce(v ...interface{}) interface{} {
+ for _, val := range v {
+ if !empty(val) {
+ return val
+ }
+ }
+ return nil
+}
+
+// all returns true if empty(x) is false for all values x in the list.
+// If the list is empty, return true.
+func all(v ...interface{}) bool {
+ for _, val := range v {
+ if empty(val) {
+ return false
+ }
+ }
+ return true
+}
+
+// any returns true if empty(x) is false for any x in the list.
+// If the list is empty, return false.
+func any(v ...interface{}) bool {
+ for _, val := range v {
+ if !empty(val) {
+ return true
+ }
+ }
+ return false
+}
+
+// fromJson decodes JSON into a structured value, ignoring errors.
+func fromJson(v string) interface{} {
+ output, _ := mustFromJson(v)
+ return output
+}
+
+// mustFromJson decodes JSON into a structured value, returning errors.
+func mustFromJson(v string) (interface{}, error) {
+ var output interface{}
+ err := json.Unmarshal([]byte(v), &output)
+ return output, err
+}
+
+// toJson encodes an item into a JSON string
+func toJson(v interface{}) string {
+ output, _ := json.Marshal(v)
+ return string(output)
+}
+
+func mustToJson(v interface{}) (string, error) {
+ output, err := json.Marshal(v)
+ if err != nil {
+ return "", err
+ }
+ return string(output), nil
+}
+
+// toPrettyJson encodes an item into a pretty (indented) JSON string
+func toPrettyJson(v interface{}) string {
+ output, _ := json.MarshalIndent(v, "", " ")
+ return string(output)
+}
+
+func mustToPrettyJson(v interface{}) (string, error) {
+ output, err := json.MarshalIndent(v, "", " ")
+ if err != nil {
+ return "", err
+ }
+ return string(output), nil
+}
+
+// toRawJson encodes an item into a JSON string with no escaping of HTML characters.
+func toRawJson(v interface{}) string {
+ output, err := mustToRawJson(v)
+ if err != nil {
+ panic(err)
+ }
+ return string(output)
+}
+
+// mustToRawJson encodes an item into a JSON string with no escaping of HTML characters.
+func mustToRawJson(v interface{}) (string, error) {
+ buf := new(bytes.Buffer)
+ enc := json.NewEncoder(buf)
+ enc.SetEscapeHTML(false)
+ err := enc.Encode(&v)
+ if err != nil {
+ return "", err
+ }
+ return strings.TrimSuffix(buf.String(), "\n"), nil
+}
+
+// ternary returns the first value if the last value is true, otherwise returns the second value.
+func ternary(vt interface{}, vf interface{}, v bool) interface{} {
+ if v {
+ return vt
+ }
+
+ return vf
+}
diff --git a/vendor/github.com/Masterminds/sprig/v3/dict.go b/vendor/github.com/Masterminds/sprig/v3/dict.go
new file mode 100644
index 000000000..4315b3542
--- /dev/null
+++ b/vendor/github.com/Masterminds/sprig/v3/dict.go
@@ -0,0 +1,174 @@
+package sprig
+
+import (
+ "dario.cat/mergo"
+ "github.com/mitchellh/copystructure"
+)
+
+func get(d map[string]interface{}, key string) interface{} {
+ if val, ok := d[key]; ok {
+ return val
+ }
+ return ""
+}
+
+func set(d map[string]interface{}, key string, value interface{}) map[string]interface{} {
+ d[key] = value
+ return d
+}
+
+func unset(d map[string]interface{}, key string) map[string]interface{} {
+ delete(d, key)
+ return d
+}
+
+func hasKey(d map[string]interface{}, key string) bool {
+ _, ok := d[key]
+ return ok
+}
+
+func pluck(key string, d ...map[string]interface{}) []interface{} {
+ res := []interface{}{}
+ for _, dict := range d {
+ if val, ok := dict[key]; ok {
+ res = append(res, val)
+ }
+ }
+ return res
+}
+
+func keys(dicts ...map[string]interface{}) []string {
+ k := []string{}
+ for _, dict := range dicts {
+ for key := range dict {
+ k = append(k, key)
+ }
+ }
+ return k
+}
+
+func pick(dict map[string]interface{}, keys ...string) map[string]interface{} {
+ res := map[string]interface{}{}
+ for _, k := range keys {
+ if v, ok := dict[k]; ok {
+ res[k] = v
+ }
+ }
+ return res
+}
+
+func omit(dict map[string]interface{}, keys ...string) map[string]interface{} {
+ res := map[string]interface{}{}
+
+ omit := make(map[string]bool, len(keys))
+ for _, k := range keys {
+ omit[k] = true
+ }
+
+ for k, v := range dict {
+ if _, ok := omit[k]; !ok {
+ res[k] = v
+ }
+ }
+ return res
+}
+
+func dict(v ...interface{}) map[string]interface{} {
+ dict := map[string]interface{}{}
+ lenv := len(v)
+ for i := 0; i < lenv; i += 2 {
+ key := strval(v[i])
+ if i+1 >= lenv {
+ dict[key] = ""
+ continue
+ }
+ dict[key] = v[i+1]
+ }
+ return dict
+}
+
+func merge(dst map[string]interface{}, srcs ...map[string]interface{}) interface{} {
+ for _, src := range srcs {
+ if err := mergo.Merge(&dst, src); err != nil {
+ // Swallow errors inside of a template.
+ return ""
+ }
+ }
+ return dst
+}
+
+func mustMerge(dst map[string]interface{}, srcs ...map[string]interface{}) (interface{}, error) {
+ for _, src := range srcs {
+ if err := mergo.Merge(&dst, src); err != nil {
+ return nil, err
+ }
+ }
+ return dst, nil
+}
+
+func mergeOverwrite(dst map[string]interface{}, srcs ...map[string]interface{}) interface{} {
+ for _, src := range srcs {
+ if err := mergo.MergeWithOverwrite(&dst, src); err != nil {
+ // Swallow errors inside of a template.
+ return ""
+ }
+ }
+ return dst
+}
+
+func mustMergeOverwrite(dst map[string]interface{}, srcs ...map[string]interface{}) (interface{}, error) {
+ for _, src := range srcs {
+ if err := mergo.MergeWithOverwrite(&dst, src); err != nil {
+ return nil, err
+ }
+ }
+ return dst, nil
+}
+
+func values(dict map[string]interface{}) []interface{} {
+ values := []interface{}{}
+ for _, value := range dict {
+ values = append(values, value)
+ }
+
+ return values
+}
+
+func deepCopy(i interface{}) interface{} {
+ c, err := mustDeepCopy(i)
+ if err != nil {
+ panic("deepCopy error: " + err.Error())
+ }
+
+ return c
+}
+
+func mustDeepCopy(i interface{}) (interface{}, error) {
+ return copystructure.Copy(i)
+}
+
+func dig(ps ...interface{}) (interface{}, error) {
+ if len(ps) < 3 {
+ panic("dig needs at least three arguments")
+ }
+ dict := ps[len(ps)-1].(map[string]interface{})
+ def := ps[len(ps)-2]
+ ks := make([]string, len(ps)-2)
+ for i := 0; i < len(ks); i++ {
+ ks[i] = ps[i].(string)
+ }
+
+ return digFromDict(dict, def, ks)
+}
+
+func digFromDict(dict map[string]interface{}, d interface{}, ks []string) (interface{}, error) {
+ k, ns := ks[0], ks[1:len(ks)]
+ step, has := dict[k]
+ if !has {
+ return d, nil
+ }
+ if len(ns) == 0 {
+ return step, nil
+ }
+ return digFromDict(step.(map[string]interface{}), d, ns)
+}
diff --git a/vendor/github.com/Masterminds/sprig/v3/doc.go b/vendor/github.com/Masterminds/sprig/v3/doc.go
new file mode 100644
index 000000000..91031d6d1
--- /dev/null
+++ b/vendor/github.com/Masterminds/sprig/v3/doc.go
@@ -0,0 +1,19 @@
+/*
+Package sprig provides template functions for Go.
+
+This package contains a number of utility functions for working with data
+inside of Go `html/template` and `text/template` files.
+
+To add these functions, use the `template.Funcs()` method:
+
+ t := template.New("foo").Funcs(sprig.FuncMap())
+
+Note that you should add the function map before you parse any template files.
+
+ In several cases, Sprig reverses the order of arguments from the way they
+ appear in the standard library. This is to make it easier to pipe
+ arguments into functions.
+
+See http://masterminds.github.io/sprig/ for more detailed documentation on each of the available functions.
+*/
+package sprig
diff --git a/vendor/github.com/Masterminds/sprig/v3/functions.go b/vendor/github.com/Masterminds/sprig/v3/functions.go
new file mode 100644
index 000000000..cda47d26f
--- /dev/null
+++ b/vendor/github.com/Masterminds/sprig/v3/functions.go
@@ -0,0 +1,385 @@
+package sprig
+
+import (
+ "errors"
+ "html/template"
+ "math/rand"
+ "os"
+ "path"
+ "path/filepath"
+ "reflect"
+ "strconv"
+ "strings"
+ ttemplate "text/template"
+ "time"
+
+ util "github.com/Masterminds/goutils"
+ "github.com/huandu/xstrings"
+ "github.com/shopspring/decimal"
+)
+
+// FuncMap produces the function map.
+//
+// Use this to pass the functions into the template engine:
+//
+// tpl := template.New("foo").Funcs(sprig.FuncMap()))
+func FuncMap() template.FuncMap {
+ return HtmlFuncMap()
+}
+
+// HermeticTxtFuncMap returns a 'text/template'.FuncMap with only repeatable functions.
+func HermeticTxtFuncMap() ttemplate.FuncMap {
+ r := TxtFuncMap()
+ for _, name := range nonhermeticFunctions {
+ delete(r, name)
+ }
+ return r
+}
+
+// HermeticHtmlFuncMap returns an 'html/template'.Funcmap with only repeatable functions.
+func HermeticHtmlFuncMap() template.FuncMap {
+ r := HtmlFuncMap()
+ for _, name := range nonhermeticFunctions {
+ delete(r, name)
+ }
+ return r
+}
+
+// TxtFuncMap returns a 'text/template'.FuncMap
+func TxtFuncMap() ttemplate.FuncMap {
+ return ttemplate.FuncMap(GenericFuncMap())
+}
+
+// HtmlFuncMap returns an 'html/template'.Funcmap
+func HtmlFuncMap() template.FuncMap {
+ return template.FuncMap(GenericFuncMap())
+}
+
+// GenericFuncMap returns a copy of the basic function map as a map[string]interface{}.
+func GenericFuncMap() map[string]interface{} {
+ gfm := make(map[string]interface{}, len(genericMap))
+ for k, v := range genericMap {
+ gfm[k] = v
+ }
+ return gfm
+}
+
+// These functions are not guaranteed to evaluate to the same result for given input, because they
+// refer to the environment or global state.
+var nonhermeticFunctions = []string{
+ // Date functions
+ "date",
+ "date_in_zone",
+ "date_modify",
+ "now",
+ "htmlDate",
+ "htmlDateInZone",
+ "dateInZone",
+ "dateModify",
+
+ // Strings
+ "randAlphaNum",
+ "randAlpha",
+ "randAscii",
+ "randNumeric",
+ "randBytes",
+ "uuidv4",
+
+ // OS
+ "env",
+ "expandenv",
+
+ // Network
+ "getHostByName",
+}
+
+var genericMap = map[string]interface{}{
+ "hello": func() string { return "Hello!" },
+
+ // Date functions
+ "ago": dateAgo,
+ "date": date,
+ "date_in_zone": dateInZone,
+ "date_modify": dateModify,
+ "dateInZone": dateInZone,
+ "dateModify": dateModify,
+ "duration": duration,
+ "durationRound": durationRound,
+ "htmlDate": htmlDate,
+ "htmlDateInZone": htmlDateInZone,
+ "must_date_modify": mustDateModify,
+ "mustDateModify": mustDateModify,
+ "mustToDate": mustToDate,
+ "now": time.Now,
+ "toDate": toDate,
+ "unixEpoch": unixEpoch,
+
+ // Strings
+ "abbrev": abbrev,
+ "abbrevboth": abbrevboth,
+ "trunc": trunc,
+ "trim": strings.TrimSpace,
+ "upper": strings.ToUpper,
+ "lower": strings.ToLower,
+ "title": strings.Title,
+ "untitle": untitle,
+ "substr": substring,
+ // Switch order so that "foo" | repeat 5
+ "repeat": func(count int, str string) string { return strings.Repeat(str, count) },
+ // Deprecated: Use trimAll.
+ "trimall": func(a, b string) string { return strings.Trim(b, a) },
+ // Switch order so that "$foo" | trimall "$"
+ "trimAll": func(a, b string) string { return strings.Trim(b, a) },
+ "trimSuffix": func(a, b string) string { return strings.TrimSuffix(b, a) },
+ "trimPrefix": func(a, b string) string { return strings.TrimPrefix(b, a) },
+ "nospace": util.DeleteWhiteSpace,
+ "initials": initials,
+ "randAlphaNum": randAlphaNumeric,
+ "randAlpha": randAlpha,
+ "randAscii": randAscii,
+ "randNumeric": randNumeric,
+ "swapcase": util.SwapCase,
+ "shuffle": xstrings.Shuffle,
+ "snakecase": xstrings.ToSnakeCase,
+ // camelcase used to call xstrings.ToCamelCase, but that function had a breaking change in version
+ // 1.5 that moved it from upper camel case to lower camel case. This is a breaking change for sprig.
+ // A new xstrings.ToPascalCase function was added that provided upper camel case.
+ "camelcase": xstrings.ToPascalCase,
+ "kebabcase": xstrings.ToKebabCase,
+ "wrap": func(l int, s string) string { return util.Wrap(s, l) },
+ "wrapWith": func(l int, sep, str string) string { return util.WrapCustom(str, l, sep, true) },
+ // Switch order so that "foobar" | contains "foo"
+ "contains": func(substr string, str string) bool { return strings.Contains(str, substr) },
+ "hasPrefix": func(substr string, str string) bool { return strings.HasPrefix(str, substr) },
+ "hasSuffix": func(substr string, str string) bool { return strings.HasSuffix(str, substr) },
+ "quote": quote,
+ "squote": squote,
+ "cat": cat,
+ "indent": indent,
+ "nindent": nindent,
+ "replace": replace,
+ "plural": plural,
+ "sha1sum": sha1sum,
+ "sha256sum": sha256sum,
+ "sha512sum": sha512sum,
+ "adler32sum": adler32sum,
+ "toString": strval,
+
+ // Wrap Atoi to stop errors.
+ "atoi": func(a string) int { i, _ := strconv.Atoi(a); return i },
+ "int64": toInt64,
+ "int": toInt,
+ "float64": toFloat64,
+ "seq": seq,
+ "toDecimal": toDecimal,
+
+ //"gt": func(a, b int) bool {return a > b},
+ //"gte": func(a, b int) bool {return a >= b},
+ //"lt": func(a, b int) bool {return a < b},
+ //"lte": func(a, b int) bool {return a <= b},
+
+ // split "/" foo/bar returns map[int]string{0: foo, 1: bar}
+ "split": split,
+ "splitList": func(sep, orig string) []string { return strings.Split(orig, sep) },
+ // splitn "/" foo/bar/fuu returns map[int]string{0: foo, 1: bar/fuu}
+ "splitn": splitn,
+ "toStrings": strslice,
+
+ "until": until,
+ "untilStep": untilStep,
+
+ // VERY basic arithmetic.
+ "add1": func(i interface{}) int64 { return toInt64(i) + 1 },
+ "add": func(i ...interface{}) int64 {
+ var a int64 = 0
+ for _, b := range i {
+ a += toInt64(b)
+ }
+ return a
+ },
+ "sub": func(a, b interface{}) int64 { return toInt64(a) - toInt64(b) },
+ "div": func(a, b interface{}) int64 { return toInt64(a) / toInt64(b) },
+ "mod": func(a, b interface{}) int64 { return toInt64(a) % toInt64(b) },
+ "mul": func(a interface{}, v ...interface{}) int64 {
+ val := toInt64(a)
+ for _, b := range v {
+ val = val * toInt64(b)
+ }
+ return val
+ },
+ "randInt": func(min, max int) int { return rand.Intn(max-min) + min },
+ "add1f": func(i interface{}) float64 {
+ return execDecimalOp(i, []interface{}{1}, func(d1, d2 decimal.Decimal) decimal.Decimal { return d1.Add(d2) })
+ },
+ "addf": func(i ...interface{}) float64 {
+ a := interface{}(float64(0))
+ return execDecimalOp(a, i, func(d1, d2 decimal.Decimal) decimal.Decimal { return d1.Add(d2) })
+ },
+ "subf": func(a interface{}, v ...interface{}) float64 {
+ return execDecimalOp(a, v, func(d1, d2 decimal.Decimal) decimal.Decimal { return d1.Sub(d2) })
+ },
+ "divf": func(a interface{}, v ...interface{}) float64 {
+ return execDecimalOp(a, v, func(d1, d2 decimal.Decimal) decimal.Decimal { return d1.Div(d2) })
+ },
+ "mulf": func(a interface{}, v ...interface{}) float64 {
+ return execDecimalOp(a, v, func(d1, d2 decimal.Decimal) decimal.Decimal { return d1.Mul(d2) })
+ },
+ "biggest": max,
+ "max": max,
+ "min": min,
+ "maxf": maxf,
+ "minf": minf,
+ "ceil": ceil,
+ "floor": floor,
+ "round": round,
+
+ // string slices. Note that we reverse the order b/c that's better
+ // for template processing.
+ "join": join,
+ "sortAlpha": sortAlpha,
+
+ // Defaults
+ "default": dfault,
+ "empty": empty,
+ "coalesce": coalesce,
+ "all": all,
+ "any": any,
+ "compact": compact,
+ "mustCompact": mustCompact,
+ "fromJson": fromJson,
+ "toJson": toJson,
+ "toPrettyJson": toPrettyJson,
+ "toRawJson": toRawJson,
+ "mustFromJson": mustFromJson,
+ "mustToJson": mustToJson,
+ "mustToPrettyJson": mustToPrettyJson,
+ "mustToRawJson": mustToRawJson,
+ "ternary": ternary,
+ "deepCopy": deepCopy,
+ "mustDeepCopy": mustDeepCopy,
+
+ // Reflection
+ "typeOf": typeOf,
+ "typeIs": typeIs,
+ "typeIsLike": typeIsLike,
+ "kindOf": kindOf,
+ "kindIs": kindIs,
+ "deepEqual": reflect.DeepEqual,
+
+ // OS:
+ "env": os.Getenv,
+ "expandenv": os.ExpandEnv,
+
+ // Network:
+ "getHostByName": getHostByName,
+
+ // Paths:
+ "base": path.Base,
+ "dir": path.Dir,
+ "clean": path.Clean,
+ "ext": path.Ext,
+ "isAbs": path.IsAbs,
+
+ // Filepaths:
+ "osBase": filepath.Base,
+ "osClean": filepath.Clean,
+ "osDir": filepath.Dir,
+ "osExt": filepath.Ext,
+ "osIsAbs": filepath.IsAbs,
+
+ // Encoding:
+ "b64enc": base64encode,
+ "b64dec": base64decode,
+ "b32enc": base32encode,
+ "b32dec": base32decode,
+
+ // Data Structures:
+ "tuple": list, // FIXME: with the addition of append/prepend these are no longer immutable.
+ "list": list,
+ "dict": dict,
+ "get": get,
+ "set": set,
+ "unset": unset,
+ "hasKey": hasKey,
+ "pluck": pluck,
+ "keys": keys,
+ "pick": pick,
+ "omit": omit,
+ "merge": merge,
+ "mergeOverwrite": mergeOverwrite,
+ "mustMerge": mustMerge,
+ "mustMergeOverwrite": mustMergeOverwrite,
+ "values": values,
+
+ "append": push, "push": push,
+ "mustAppend": mustPush, "mustPush": mustPush,
+ "prepend": prepend,
+ "mustPrepend": mustPrepend,
+ "first": first,
+ "mustFirst": mustFirst,
+ "rest": rest,
+ "mustRest": mustRest,
+ "last": last,
+ "mustLast": mustLast,
+ "initial": initial,
+ "mustInitial": mustInitial,
+ "reverse": reverse,
+ "mustReverse": mustReverse,
+ "uniq": uniq,
+ "mustUniq": mustUniq,
+ "without": without,
+ "mustWithout": mustWithout,
+ "has": has,
+ "mustHas": mustHas,
+ "slice": slice,
+ "mustSlice": mustSlice,
+ "concat": concat,
+ "dig": dig,
+ "chunk": chunk,
+ "mustChunk": mustChunk,
+
+ // Crypto:
+ "bcrypt": bcrypt,
+ "htpasswd": htpasswd,
+ "genPrivateKey": generatePrivateKey,
+ "derivePassword": derivePassword,
+ "buildCustomCert": buildCustomCertificate,
+ "genCA": generateCertificateAuthority,
+ "genCAWithKey": generateCertificateAuthorityWithPEMKey,
+ "genSelfSignedCert": generateSelfSignedCertificate,
+ "genSelfSignedCertWithKey": generateSelfSignedCertificateWithPEMKey,
+ "genSignedCert": generateSignedCertificate,
+ "genSignedCertWithKey": generateSignedCertificateWithPEMKey,
+ "encryptAES": encryptAES,
+ "decryptAES": decryptAES,
+ "randBytes": randBytes,
+
+ // UUIDs:
+ "uuidv4": uuidv4,
+
+ // SemVer:
+ "semver": semver,
+ "semverCompare": semverCompare,
+
+ // Flow Control:
+ "fail": func(msg string) (string, error) { return "", errors.New(msg) },
+
+ // Regex
+ "regexMatch": regexMatch,
+ "mustRegexMatch": mustRegexMatch,
+ "regexFindAll": regexFindAll,
+ "mustRegexFindAll": mustRegexFindAll,
+ "regexFind": regexFind,
+ "mustRegexFind": mustRegexFind,
+ "regexReplaceAll": regexReplaceAll,
+ "mustRegexReplaceAll": mustRegexReplaceAll,
+ "regexReplaceAllLiteral": regexReplaceAllLiteral,
+ "mustRegexReplaceAllLiteral": mustRegexReplaceAllLiteral,
+ "regexSplit": regexSplit,
+ "mustRegexSplit": mustRegexSplit,
+ "regexQuoteMeta": regexQuoteMeta,
+
+ // URLs:
+ "urlParse": urlParse,
+ "urlJoin": urlJoin,
+}
diff --git a/vendor/github.com/Masterminds/sprig/v3/list.go b/vendor/github.com/Masterminds/sprig/v3/list.go
new file mode 100644
index 000000000..ca0fbb789
--- /dev/null
+++ b/vendor/github.com/Masterminds/sprig/v3/list.go
@@ -0,0 +1,464 @@
+package sprig
+
+import (
+ "fmt"
+ "math"
+ "reflect"
+ "sort"
+)
+
+// Reflection is used in these functions so that slices and arrays of strings,
+// ints, and other types not implementing []interface{} can be worked with.
+// For example, this is useful if you need to work on the output of regexs.
+
+func list(v ...interface{}) []interface{} {
+ return v
+}
+
+func push(list interface{}, v interface{}) []interface{} {
+ l, err := mustPush(list, v)
+ if err != nil {
+ panic(err)
+ }
+
+ return l
+}
+
+func mustPush(list interface{}, v interface{}) ([]interface{}, error) {
+ tp := reflect.TypeOf(list).Kind()
+ switch tp {
+ case reflect.Slice, reflect.Array:
+ l2 := reflect.ValueOf(list)
+
+ l := l2.Len()
+ nl := make([]interface{}, l)
+ for i := 0; i < l; i++ {
+ nl[i] = l2.Index(i).Interface()
+ }
+
+ return append(nl, v), nil
+
+ default:
+ return nil, fmt.Errorf("Cannot push on type %s", tp)
+ }
+}
+
+func prepend(list interface{}, v interface{}) []interface{} {
+ l, err := mustPrepend(list, v)
+ if err != nil {
+ panic(err)
+ }
+
+ return l
+}
+
+func mustPrepend(list interface{}, v interface{}) ([]interface{}, error) {
+ //return append([]interface{}{v}, list...)
+
+ tp := reflect.TypeOf(list).Kind()
+ switch tp {
+ case reflect.Slice, reflect.Array:
+ l2 := reflect.ValueOf(list)
+
+ l := l2.Len()
+ nl := make([]interface{}, l)
+ for i := 0; i < l; i++ {
+ nl[i] = l2.Index(i).Interface()
+ }
+
+ return append([]interface{}{v}, nl...), nil
+
+ default:
+ return nil, fmt.Errorf("Cannot prepend on type %s", tp)
+ }
+}
+
+func chunk(size int, list interface{}) [][]interface{} {
+ l, err := mustChunk(size, list)
+ if err != nil {
+ panic(err)
+ }
+
+ return l
+}
+
+func mustChunk(size int, list interface{}) ([][]interface{}, error) {
+ tp := reflect.TypeOf(list).Kind()
+ switch tp {
+ case reflect.Slice, reflect.Array:
+ l2 := reflect.ValueOf(list)
+
+ l := l2.Len()
+
+ cs := int(math.Floor(float64(l-1)/float64(size)) + 1)
+ nl := make([][]interface{}, cs)
+
+ for i := 0; i < cs; i++ {
+ clen := size
+ if i == cs-1 {
+ clen = int(math.Floor(math.Mod(float64(l), float64(size))))
+ if clen == 0 {
+ clen = size
+ }
+ }
+
+ nl[i] = make([]interface{}, clen)
+
+ for j := 0; j < clen; j++ {
+ ix := i*size + j
+ nl[i][j] = l2.Index(ix).Interface()
+ }
+ }
+
+ return nl, nil
+
+ default:
+ return nil, fmt.Errorf("Cannot chunk type %s", tp)
+ }
+}
+
+func last(list interface{}) interface{} {
+ l, err := mustLast(list)
+ if err != nil {
+ panic(err)
+ }
+
+ return l
+}
+
+func mustLast(list interface{}) (interface{}, error) {
+ tp := reflect.TypeOf(list).Kind()
+ switch tp {
+ case reflect.Slice, reflect.Array:
+ l2 := reflect.ValueOf(list)
+
+ l := l2.Len()
+ if l == 0 {
+ return nil, nil
+ }
+
+ return l2.Index(l - 1).Interface(), nil
+ default:
+ return nil, fmt.Errorf("Cannot find last on type %s", tp)
+ }
+}
+
+func first(list interface{}) interface{} {
+ l, err := mustFirst(list)
+ if err != nil {
+ panic(err)
+ }
+
+ return l
+}
+
+func mustFirst(list interface{}) (interface{}, error) {
+ tp := reflect.TypeOf(list).Kind()
+ switch tp {
+ case reflect.Slice, reflect.Array:
+ l2 := reflect.ValueOf(list)
+
+ l := l2.Len()
+ if l == 0 {
+ return nil, nil
+ }
+
+ return l2.Index(0).Interface(), nil
+ default:
+ return nil, fmt.Errorf("Cannot find first on type %s", tp)
+ }
+}
+
+func rest(list interface{}) []interface{} {
+ l, err := mustRest(list)
+ if err != nil {
+ panic(err)
+ }
+
+ return l
+}
+
+func mustRest(list interface{}) ([]interface{}, error) {
+ tp := reflect.TypeOf(list).Kind()
+ switch tp {
+ case reflect.Slice, reflect.Array:
+ l2 := reflect.ValueOf(list)
+
+ l := l2.Len()
+ if l == 0 {
+ return nil, nil
+ }
+
+ nl := make([]interface{}, l-1)
+ for i := 1; i < l; i++ {
+ nl[i-1] = l2.Index(i).Interface()
+ }
+
+ return nl, nil
+ default:
+ return nil, fmt.Errorf("Cannot find rest on type %s", tp)
+ }
+}
+
+func initial(list interface{}) []interface{} {
+ l, err := mustInitial(list)
+ if err != nil {
+ panic(err)
+ }
+
+ return l
+}
+
+func mustInitial(list interface{}) ([]interface{}, error) {
+ tp := reflect.TypeOf(list).Kind()
+ switch tp {
+ case reflect.Slice, reflect.Array:
+ l2 := reflect.ValueOf(list)
+
+ l := l2.Len()
+ if l == 0 {
+ return nil, nil
+ }
+
+ nl := make([]interface{}, l-1)
+ for i := 0; i < l-1; i++ {
+ nl[i] = l2.Index(i).Interface()
+ }
+
+ return nl, nil
+ default:
+ return nil, fmt.Errorf("Cannot find initial on type %s", tp)
+ }
+}
+
+func sortAlpha(list interface{}) []string {
+ k := reflect.Indirect(reflect.ValueOf(list)).Kind()
+ switch k {
+ case reflect.Slice, reflect.Array:
+ a := strslice(list)
+ s := sort.StringSlice(a)
+ s.Sort()
+ return s
+ }
+ return []string{strval(list)}
+}
+
+func reverse(v interface{}) []interface{} {
+ l, err := mustReverse(v)
+ if err != nil {
+ panic(err)
+ }
+
+ return l
+}
+
+func mustReverse(v interface{}) ([]interface{}, error) {
+ tp := reflect.TypeOf(v).Kind()
+ switch tp {
+ case reflect.Slice, reflect.Array:
+ l2 := reflect.ValueOf(v)
+
+ l := l2.Len()
+ // We do not sort in place because the incoming array should not be altered.
+ nl := make([]interface{}, l)
+ for i := 0; i < l; i++ {
+ nl[l-i-1] = l2.Index(i).Interface()
+ }
+
+ return nl, nil
+ default:
+ return nil, fmt.Errorf("Cannot find reverse on type %s", tp)
+ }
+}
+
+func compact(list interface{}) []interface{} {
+ l, err := mustCompact(list)
+ if err != nil {
+ panic(err)
+ }
+
+ return l
+}
+
+func mustCompact(list interface{}) ([]interface{}, error) {
+ tp := reflect.TypeOf(list).Kind()
+ switch tp {
+ case reflect.Slice, reflect.Array:
+ l2 := reflect.ValueOf(list)
+
+ l := l2.Len()
+ nl := []interface{}{}
+ var item interface{}
+ for i := 0; i < l; i++ {
+ item = l2.Index(i).Interface()
+ if !empty(item) {
+ nl = append(nl, item)
+ }
+ }
+
+ return nl, nil
+ default:
+ return nil, fmt.Errorf("Cannot compact on type %s", tp)
+ }
+}
+
+func uniq(list interface{}) []interface{} {
+ l, err := mustUniq(list)
+ if err != nil {
+ panic(err)
+ }
+
+ return l
+}
+
+func mustUniq(list interface{}) ([]interface{}, error) {
+ tp := reflect.TypeOf(list).Kind()
+ switch tp {
+ case reflect.Slice, reflect.Array:
+ l2 := reflect.ValueOf(list)
+
+ l := l2.Len()
+ dest := []interface{}{}
+ var item interface{}
+ for i := 0; i < l; i++ {
+ item = l2.Index(i).Interface()
+ if !inList(dest, item) {
+ dest = append(dest, item)
+ }
+ }
+
+ return dest, nil
+ default:
+ return nil, fmt.Errorf("Cannot find uniq on type %s", tp)
+ }
+}
+
+func inList(haystack []interface{}, needle interface{}) bool {
+ for _, h := range haystack {
+ if reflect.DeepEqual(needle, h) {
+ return true
+ }
+ }
+ return false
+}
+
+func without(list interface{}, omit ...interface{}) []interface{} {
+ l, err := mustWithout(list, omit...)
+ if err != nil {
+ panic(err)
+ }
+
+ return l
+}
+
+func mustWithout(list interface{}, omit ...interface{}) ([]interface{}, error) {
+ tp := reflect.TypeOf(list).Kind()
+ switch tp {
+ case reflect.Slice, reflect.Array:
+ l2 := reflect.ValueOf(list)
+
+ l := l2.Len()
+ res := []interface{}{}
+ var item interface{}
+ for i := 0; i < l; i++ {
+ item = l2.Index(i).Interface()
+ if !inList(omit, item) {
+ res = append(res, item)
+ }
+ }
+
+ return res, nil
+ default:
+ return nil, fmt.Errorf("Cannot find without on type %s", tp)
+ }
+}
+
+func has(needle interface{}, haystack interface{}) bool {
+ l, err := mustHas(needle, haystack)
+ if err != nil {
+ panic(err)
+ }
+
+ return l
+}
+
+func mustHas(needle interface{}, haystack interface{}) (bool, error) {
+ if haystack == nil {
+ return false, nil
+ }
+ tp := reflect.TypeOf(haystack).Kind()
+ switch tp {
+ case reflect.Slice, reflect.Array:
+ l2 := reflect.ValueOf(haystack)
+ var item interface{}
+ l := l2.Len()
+ for i := 0; i < l; i++ {
+ item = l2.Index(i).Interface()
+ if reflect.DeepEqual(needle, item) {
+ return true, nil
+ }
+ }
+
+ return false, nil
+ default:
+ return false, fmt.Errorf("Cannot find has on type %s", tp)
+ }
+}
+
+// $list := [1, 2, 3, 4, 5]
+// slice $list -> list[0:5] = list[:]
+// slice $list 0 3 -> list[0:3] = list[:3]
+// slice $list 3 5 -> list[3:5]
+// slice $list 3 -> list[3:5] = list[3:]
+func slice(list interface{}, indices ...interface{}) interface{} {
+ l, err := mustSlice(list, indices...)
+ if err != nil {
+ panic(err)
+ }
+
+ return l
+}
+
+func mustSlice(list interface{}, indices ...interface{}) (interface{}, error) {
+ tp := reflect.TypeOf(list).Kind()
+ switch tp {
+ case reflect.Slice, reflect.Array:
+ l2 := reflect.ValueOf(list)
+
+ l := l2.Len()
+ if l == 0 {
+ return nil, nil
+ }
+
+ var start, end int
+ if len(indices) > 0 {
+ start = toInt(indices[0])
+ }
+ if len(indices) < 2 {
+ end = l
+ } else {
+ end = toInt(indices[1])
+ }
+
+ return l2.Slice(start, end).Interface(), nil
+ default:
+ return nil, fmt.Errorf("list should be type of slice or array but %s", tp)
+ }
+}
+
+func concat(lists ...interface{}) interface{} {
+ var res []interface{}
+ for _, list := range lists {
+ tp := reflect.TypeOf(list).Kind()
+ switch tp {
+ case reflect.Slice, reflect.Array:
+ l2 := reflect.ValueOf(list)
+ for i := 0; i < l2.Len(); i++ {
+ res = append(res, l2.Index(i).Interface())
+ }
+ default:
+ panic(fmt.Sprintf("Cannot concat type %s as list", tp))
+ }
+ }
+ return res
+}
diff --git a/vendor/github.com/Masterminds/sprig/network.go b/vendor/github.com/Masterminds/sprig/v3/network.go
similarity index 75%
rename from vendor/github.com/Masterminds/sprig/network.go
rename to vendor/github.com/Masterminds/sprig/v3/network.go
index d786cc736..108d78a94 100644
--- a/vendor/github.com/Masterminds/sprig/network.go
+++ b/vendor/github.com/Masterminds/sprig/v3/network.go
@@ -7,6 +7,6 @@ import (
func getHostByName(name string) string {
addrs, _ := net.LookupHost(name)
- //TODO: add error handing when release v3 cames out
+ //TODO: add error handing when release v3 comes out
return addrs[rand.Intn(len(addrs))]
}
diff --git a/vendor/github.com/Masterminds/sprig/v3/numeric.go b/vendor/github.com/Masterminds/sprig/v3/numeric.go
new file mode 100644
index 000000000..f68e4182e
--- /dev/null
+++ b/vendor/github.com/Masterminds/sprig/v3/numeric.go
@@ -0,0 +1,186 @@
+package sprig
+
+import (
+ "fmt"
+ "math"
+ "strconv"
+ "strings"
+
+ "github.com/spf13/cast"
+ "github.com/shopspring/decimal"
+)
+
+// toFloat64 converts 64-bit floats
+func toFloat64(v interface{}) float64 {
+ return cast.ToFloat64(v)
+}
+
+func toInt(v interface{}) int {
+ return cast.ToInt(v)
+}
+
+// toInt64 converts integer types to 64-bit integers
+func toInt64(v interface{}) int64 {
+ return cast.ToInt64(v)
+}
+
+func max(a interface{}, i ...interface{}) int64 {
+ aa := toInt64(a)
+ for _, b := range i {
+ bb := toInt64(b)
+ if bb > aa {
+ aa = bb
+ }
+ }
+ return aa
+}
+
+func maxf(a interface{}, i ...interface{}) float64 {
+ aa := toFloat64(a)
+ for _, b := range i {
+ bb := toFloat64(b)
+ aa = math.Max(aa, bb)
+ }
+ return aa
+}
+
+func min(a interface{}, i ...interface{}) int64 {
+ aa := toInt64(a)
+ for _, b := range i {
+ bb := toInt64(b)
+ if bb < aa {
+ aa = bb
+ }
+ }
+ return aa
+}
+
+func minf(a interface{}, i ...interface{}) float64 {
+ aa := toFloat64(a)
+ for _, b := range i {
+ bb := toFloat64(b)
+ aa = math.Min(aa, bb)
+ }
+ return aa
+}
+
+func until(count int) []int {
+ step := 1
+ if count < 0 {
+ step = -1
+ }
+ return untilStep(0, count, step)
+}
+
+func untilStep(start, stop, step int) []int {
+ v := []int{}
+
+ if stop < start {
+ if step >= 0 {
+ return v
+ }
+ for i := start; i > stop; i += step {
+ v = append(v, i)
+ }
+ return v
+ }
+
+ if step <= 0 {
+ return v
+ }
+ for i := start; i < stop; i += step {
+ v = append(v, i)
+ }
+ return v
+}
+
+func floor(a interface{}) float64 {
+ aa := toFloat64(a)
+ return math.Floor(aa)
+}
+
+func ceil(a interface{}) float64 {
+ aa := toFloat64(a)
+ return math.Ceil(aa)
+}
+
+func round(a interface{}, p int, rOpt ...float64) float64 {
+ roundOn := .5
+ if len(rOpt) > 0 {
+ roundOn = rOpt[0]
+ }
+ val := toFloat64(a)
+ places := toFloat64(p)
+
+ var round float64
+ pow := math.Pow(10, places)
+ digit := pow * val
+ _, div := math.Modf(digit)
+ if div >= roundOn {
+ round = math.Ceil(digit)
+ } else {
+ round = math.Floor(digit)
+ }
+ return round / pow
+}
+
+// converts unix octal to decimal
+func toDecimal(v interface{}) int64 {
+ result, err := strconv.ParseInt(fmt.Sprint(v), 8, 64)
+ if err != nil {
+ return 0
+ }
+ return result
+}
+
+func seq(params ...int) string {
+ increment := 1
+ switch len(params) {
+ case 0:
+ return ""
+ case 1:
+ start := 1
+ end := params[0]
+ if end < start {
+ increment = -1
+ }
+ return intArrayToString(untilStep(start, end+increment, increment), " ")
+ case 3:
+ start := params[0]
+ end := params[2]
+ step := params[1]
+ if end < start {
+ increment = -1
+ if step > 0 {
+ return ""
+ }
+ }
+ return intArrayToString(untilStep(start, end+increment, step), " ")
+ case 2:
+ start := params[0]
+ end := params[1]
+ step := 1
+ if end < start {
+ step = -1
+ }
+ return intArrayToString(untilStep(start, end+step, step), " ")
+ default:
+ return ""
+ }
+}
+
+func intArrayToString(slice []int, delimeter string) string {
+ return strings.Trim(strings.Join(strings.Fields(fmt.Sprint(slice)), delimeter), "[]")
+}
+
+// performs a float and subsequent decimal.Decimal conversion on inputs,
+// and iterates through a and b executing the mathmetical operation f
+func execDecimalOp(a interface{}, b []interface{}, f func(d1, d2 decimal.Decimal) decimal.Decimal) float64 {
+ prt := decimal.NewFromFloat(toFloat64(a))
+ for _, x := range b {
+ dx := decimal.NewFromFloat(toFloat64(x))
+ prt = f(prt, dx)
+ }
+ rslt, _ := prt.Float64()
+ return rslt
+}
diff --git a/vendor/github.com/Masterminds/sprig/reflect.go b/vendor/github.com/Masterminds/sprig/v3/reflect.go
similarity index 100%
rename from vendor/github.com/Masterminds/sprig/reflect.go
rename to vendor/github.com/Masterminds/sprig/v3/reflect.go
diff --git a/vendor/github.com/Masterminds/sprig/v3/regex.go b/vendor/github.com/Masterminds/sprig/v3/regex.go
new file mode 100644
index 000000000..fab551018
--- /dev/null
+++ b/vendor/github.com/Masterminds/sprig/v3/regex.go
@@ -0,0 +1,83 @@
+package sprig
+
+import (
+ "regexp"
+)
+
+func regexMatch(regex string, s string) bool {
+ match, _ := regexp.MatchString(regex, s)
+ return match
+}
+
+func mustRegexMatch(regex string, s string) (bool, error) {
+ return regexp.MatchString(regex, s)
+}
+
+func regexFindAll(regex string, s string, n int) []string {
+ r := regexp.MustCompile(regex)
+ return r.FindAllString(s, n)
+}
+
+func mustRegexFindAll(regex string, s string, n int) ([]string, error) {
+ r, err := regexp.Compile(regex)
+ if err != nil {
+ return []string{}, err
+ }
+ return r.FindAllString(s, n), nil
+}
+
+func regexFind(regex string, s string) string {
+ r := regexp.MustCompile(regex)
+ return r.FindString(s)
+}
+
+func mustRegexFind(regex string, s string) (string, error) {
+ r, err := regexp.Compile(regex)
+ if err != nil {
+ return "", err
+ }
+ return r.FindString(s), nil
+}
+
+func regexReplaceAll(regex string, s string, repl string) string {
+ r := regexp.MustCompile(regex)
+ return r.ReplaceAllString(s, repl)
+}
+
+func mustRegexReplaceAll(regex string, s string, repl string) (string, error) {
+ r, err := regexp.Compile(regex)
+ if err != nil {
+ return "", err
+ }
+ return r.ReplaceAllString(s, repl), nil
+}
+
+func regexReplaceAllLiteral(regex string, s string, repl string) string {
+ r := regexp.MustCompile(regex)
+ return r.ReplaceAllLiteralString(s, repl)
+}
+
+func mustRegexReplaceAllLiteral(regex string, s string, repl string) (string, error) {
+ r, err := regexp.Compile(regex)
+ if err != nil {
+ return "", err
+ }
+ return r.ReplaceAllLiteralString(s, repl), nil
+}
+
+func regexSplit(regex string, s string, n int) []string {
+ r := regexp.MustCompile(regex)
+ return r.Split(s, n)
+}
+
+func mustRegexSplit(regex string, s string, n int) ([]string, error) {
+ r, err := regexp.Compile(regex)
+ if err != nil {
+ return []string{}, err
+ }
+ return r.Split(s, n), nil
+}
+
+func regexQuoteMeta(s string) string {
+ return regexp.QuoteMeta(s)
+}
diff --git a/vendor/github.com/Masterminds/sprig/semver.go b/vendor/github.com/Masterminds/sprig/v3/semver.go
similarity index 90%
rename from vendor/github.com/Masterminds/sprig/semver.go
rename to vendor/github.com/Masterminds/sprig/v3/semver.go
index c2bf8a1fd..3fbe08aa6 100644
--- a/vendor/github.com/Masterminds/sprig/semver.go
+++ b/vendor/github.com/Masterminds/sprig/v3/semver.go
@@ -1,7 +1,7 @@
package sprig
import (
- sv2 "github.com/Masterminds/semver"
+ sv2 "github.com/Masterminds/semver/v3"
)
func semverCompare(constraint, version string) (bool, error) {
diff --git a/vendor/github.com/Masterminds/sprig/strings.go b/vendor/github.com/Masterminds/sprig/v3/strings.go
similarity index 97%
rename from vendor/github.com/Masterminds/sprig/strings.go
rename to vendor/github.com/Masterminds/sprig/v3/strings.go
index 943fa3e8a..e0ae628c8 100644
--- a/vendor/github.com/Masterminds/sprig/strings.go
+++ b/vendor/github.com/Masterminds/sprig/v3/strings.go
@@ -154,9 +154,9 @@ func strslice(v interface{}) []string {
default:
if v == nil {
return []string{}
- } else {
- return []string{strval(v)}
}
+
+ return []string{strval(v)}
}
}
}
@@ -187,10 +187,13 @@ func strval(v interface{}) string {
}
func trunc(c int, s string) string {
- if len(s) <= c {
- return s
+ if c < 0 && len(s)+c > 0 {
+ return s[len(s)+c:]
+ }
+ if c >= 0 && len(s) > c {
+ return s[:c]
}
- return s[0:c]
+ return s
}
func join(sep string, v interface{}) string {
diff --git a/vendor/github.com/Masterminds/sprig/v3/url.go b/vendor/github.com/Masterminds/sprig/v3/url.go
new file mode 100644
index 000000000..b8e120e19
--- /dev/null
+++ b/vendor/github.com/Masterminds/sprig/v3/url.go
@@ -0,0 +1,66 @@
+package sprig
+
+import (
+ "fmt"
+ "net/url"
+ "reflect"
+)
+
+func dictGetOrEmpty(dict map[string]interface{}, key string) string {
+ value, ok := dict[key]
+ if !ok {
+ return ""
+ }
+ tp := reflect.TypeOf(value).Kind()
+ if tp != reflect.String {
+ panic(fmt.Sprintf("unable to parse %s key, must be of type string, but %s found", key, tp.String()))
+ }
+ return reflect.ValueOf(value).String()
+}
+
+// parses given URL to return dict object
+func urlParse(v string) map[string]interface{} {
+ dict := map[string]interface{}{}
+ parsedURL, err := url.Parse(v)
+ if err != nil {
+ panic(fmt.Sprintf("unable to parse url: %s", err))
+ }
+ dict["scheme"] = parsedURL.Scheme
+ dict["host"] = parsedURL.Host
+ dict["hostname"] = parsedURL.Hostname()
+ dict["path"] = parsedURL.Path
+ dict["query"] = parsedURL.RawQuery
+ dict["opaque"] = parsedURL.Opaque
+ dict["fragment"] = parsedURL.Fragment
+ if parsedURL.User != nil {
+ dict["userinfo"] = parsedURL.User.String()
+ } else {
+ dict["userinfo"] = ""
+ }
+
+ return dict
+}
+
+// join given dict to URL string
+func urlJoin(d map[string]interface{}) string {
+ resURL := url.URL{
+ Scheme: dictGetOrEmpty(d, "scheme"),
+ Host: dictGetOrEmpty(d, "host"),
+ Path: dictGetOrEmpty(d, "path"),
+ RawQuery: dictGetOrEmpty(d, "query"),
+ Opaque: dictGetOrEmpty(d, "opaque"),
+ Fragment: dictGetOrEmpty(d, "fragment"),
+ }
+ userinfo := dictGetOrEmpty(d, "userinfo")
+ var user *url.Userinfo
+ if userinfo != "" {
+ tempURL, err := url.Parse(fmt.Sprintf("proto://%s@host", userinfo))
+ if err != nil {
+ panic(fmt.Sprintf("unable to parse userinfo in dict: %s", err))
+ }
+ user = tempURL.User
+ }
+
+ resURL.User = user
+ return resURL.String()
+}
diff --git a/vendor/github.com/MirrexOne/unqueryvet/.gitignore b/vendor/github.com/MirrexOne/unqueryvet/.gitignore
index bd2a78774..23f505c0f 100644
--- a/vendor/github.com/MirrexOne/unqueryvet/.gitignore
+++ b/vendor/github.com/MirrexOne/unqueryvet/.gitignore
@@ -41,3 +41,16 @@ Thumbs.db
*.log
go.work
.golangci.local.yml
+
+# Build tools (downloaded by Taskfile/Gradle)
+.tools/
+.task/
+
+# VS Code extension build artifacts
+extensions/vscode/node_modules/
+extensions/vscode/out/
+extensions/vscode/*.vsix
+*.vsix
+
+# Claude Code
+.claude/
diff --git a/vendor/github.com/MirrexOne/unqueryvet/.unqueryvet.example.yaml b/vendor/github.com/MirrexOne/unqueryvet/.unqueryvet.example.yaml
new file mode 100644
index 000000000..e3327ee7e
--- /dev/null
+++ b/vendor/github.com/MirrexOne/unqueryvet/.unqueryvet.example.yaml
@@ -0,0 +1,165 @@
+# Unqueryvet Configuration File
+# This is an example configuration showing all available options
+#
+# JSON Schema validation is automatically provided by SchemaStore.org
+# for editors that support it (VS Code, GoLand, Neovim, etc.)
+
+# ==============================================================================
+# LEVEL 1: Simple Configuration (quick setup)
+# ==============================================================================
+
+# Built-in rules severity configuration
+# Available rules: select-star, n1-queries, sql-injection, tx-leak
+# Severity values: error, warning, info, ignore
+rules:
+ select-star: warning
+ n1-queries: warning
+ sql-injection: error
+ tx-leak: warning
+
+# Files to ignore (glob patterns)
+ignore:
+ - "*_test.go"
+ - "testdata/**"
+ - "vendor/**"
+
+# SQL patterns to whitelist (won't trigger warnings)
+allow:
+ - "COUNT(*)"
+ - "information_schema.*"
+
+# ==============================================================================
+# LEVEL 2: Detailed Configuration (existing options)
+# ==============================================================================
+
+# Enable/disable SQL builder checking (default: true)
+check-sql-builders: true
+
+# Enable/disable aliased wildcard detection like SELECT t.* (default: true)
+check-aliased-wildcard: true
+
+# Enable/disable string concatenation analysis (default: true)
+check-string-concat: true
+
+# Enable/disable format string analysis like fmt.Sprintf (default: true)
+check-format-strings: true
+
+# Enable/disable strings.Builder analysis (default: true)
+check-string-builder: true
+
+# Enable/disable subquery analysis (default: true)
+check-subqueries: true
+
+# Diagnostic severity: "error" or "warning" (default: "warning")
+severity: warning
+
+# SQL builder libraries to check (all enabled by default)
+sql-builders:
+ squirrel: true
+ gorm: true
+ sqlx: true
+ ent: true
+ pgx: true
+ bun: true
+ sqlboiler: true
+ jet: true
+ sqlc: true
+ goqu: true
+ rel: true
+ reform: true
+
+# Legacy: Patterns for files to ignore (use 'ignore' instead)
+# ignored-files:
+# - "*_test.go"
+
+# Legacy: Functions to ignore (regex patterns)
+# ignored-functions:
+# - "debug\\..*"
+# - "test.*"
+
+# Legacy: Regex patterns to allow (use 'allow' instead)
+# allowed-patterns:
+# - "SELECT \\* FROM temp_.*"
+
+# ==============================================================================
+# LEVEL 3: Custom Rules with DSL (advanced)
+# ==============================================================================
+
+# Define your own analysis rules using patterns and conditions
+custom-rules:
+ # Example 1: Allow SELECT * for temporary tables
+ - id: allow-temp-tables
+ pattern: SELECT * FROM $TABLE
+ when: isTempTable(table)
+ action: allow
+
+ # Example 2: Detect N+1 queries in loops
+ - id: n1-in-loop
+ pattern: $DB.Query($QUERY)
+ when: in_loop && !contains(function, "batch")
+ message: "Potential N+1 query detected in loop"
+ severity: warning
+ fix: "Consider using batch query or preloading"
+
+ # Example 3: Require WHERE clause for DELETE/UPDATE
+ - id: require-where
+ patterns:
+ - DELETE FROM $TABLE
+ - UPDATE $TABLE SET $COLS
+ when: "!has_where"
+ message: "Dangerous query without WHERE clause"
+ severity: error
+
+ # Example 4: Context-aware rules (strict in prod code, relaxed in tests)
+ - id: strict-select-star
+ pattern: SELECT * FROM $TABLE
+ when: |
+ !matches(file, "_test.go$") &&
+ !matches(file, "testdata/") &&
+ !isSystemTable(table) &&
+ !isTempTable(table)
+ message: "Avoid SELECT * in production code - specify columns explicitly"
+ severity: error
+
+# ==============================================================================
+# DSL Reference
+# ==============================================================================
+#
+# Pattern Metavariables:
+# $TABLE - matches table name (with optional schema)
+# $VAR - matches identifier/variable
+# $QUERY - matches string literal
+# $COLS - matches column list
+# $EXPR - matches any expression
+# $DB - matches database object
+#
+# Condition Variables:
+# file - current file path
+# package - current package name
+# function - current function name
+# query - SQL query text
+# query_type - SELECT, INSERT, UPDATE, DELETE
+# table - primary table name
+# tables - list of all tables
+# columns - list of columns
+# has_join - true if query has JOIN
+# has_where - true if query has WHERE
+# in_loop - true if inside a loop
+# loop_depth - nesting depth of loops
+# builder - SQL builder type (gorm, squirrel, etc.)
+#
+# Built-in Functions:
+# contains(str, substr) - check if string contains substring
+# matches(str, regex) - check if string matches regex
+# startsWith(str, prefix) - check if string starts with prefix
+# endsWith(str, suffix) - check if string ends with suffix
+# isSystemTable(table) - check if table is system/catalog table
+# isTempTable(table) - check if table looks like temp table
+# isAggregate(query) - check if query has aggregate functions
+#
+# Operators:
+# =~ - regex match (e.g., file =~ "_test.go$")
+# !~ - regex not match
+# && - logical AND
+# || - logical OR
+# ! - logical NOT
diff --git a/vendor/github.com/MirrexOne/unqueryvet/CONTRIBUTING.md b/vendor/github.com/MirrexOne/unqueryvet/CONTRIBUTING.md
new file mode 100644
index 000000000..dacc30734
--- /dev/null
+++ b/vendor/github.com/MirrexOne/unqueryvet/CONTRIBUTING.md
@@ -0,0 +1,341 @@
+# Contributing to unqueryvet
+
+Thank you for your interest in contributing to unqueryvet! This document provides guidelines and instructions for contributing.
+
+## Table of Contents
+
+- [Getting Started](#getting-started)
+- [Development Setup](#development-setup)
+- [Project Structure](#project-structure)
+- [Running Tests](#running-tests)
+- [Code Style](#code-style)
+- [Pull Request Process](#pull-request-process)
+- [Adding New SQL Builders](#adding-new-sql-builders)
+- [Reporting Issues](#reporting-issues)
+
+---
+
+## Getting Started
+
+1. Fork the repository on GitHub
+2. Clone your fork locally:
+ ```bash
+ git clone https://github.com/YOUR_USERNAME/unqueryvet.git
+ cd unqueryvet
+ ```
+3. Add the upstream remote:
+ ```bash
+ git remote add upstream https://github.com/MirrexOne/unqueryvet.git
+ ```
+4. Create a new branch for your feature:
+ ```bash
+ git checkout -b feature/your-feature-name
+ ```
+
+---
+
+## Development Setup
+
+### Prerequisites
+
+- Go 1.24 or later
+- [Task](https://taskfile.dev/) (optional, but recommended)
+- golangci-lint (for linting)
+
+### Install Dependencies
+
+```bash
+go mod download
+```
+
+### Build
+
+Using Task:
+```bash
+task build # Build CLI
+task build:lsp # Build LSP server
+task build:all # Build both
+```
+
+Using Go directly:
+```bash
+go build ./cmd/unqueryvet
+go build ./cmd/unqueryvet-lsp
+```
+
+### Install Locally
+
+```bash
+task install:all
+# or
+go install ./cmd/unqueryvet
+go install ./cmd/unqueryvet-lsp
+```
+
+---
+
+## Project Structure
+
+```
+unqueryvet/
+├── cmd/
+│ ├── unqueryvet/ # CLI entry point
+│ └── unqueryvet-lsp/ # LSP server entry point
+├── internal/
+│ ├── analyzer/ # Core analysis engine
+│ │ ├── sqlbuilders/ # SQL builder support (12 builders)
+│ │ ├── n1detector.go # N+1 query detection
+│ │ └── sqli_scanner.go # SQL injection scanner
+│ ├── cli/ # CLI output utilities
+│ ├── configloader/ # Configuration loading
+│ ├── dsl/ # Custom Rules DSL engine
+│ ├── lsp/ # LSP server implementation
+│ ├── messages/ # Error messages
+│ ├── runner/ # Analysis runner
+│ ├── tui/ # Interactive TUI (Bubble Tea)
+│ └── version/ # Version information
+├── pkg/
+│ └── config/ # Public configuration API
+├── extensions/
+│ ├── goland/ # GoLand/IntelliJ plugin (Kotlin)
+│ └── vscode/ # VS Code extension (TypeScript)
+├── docs/ # Documentation
+├── _examples/ # Example configurations
+└── testdata/ # Test fixtures
+```
+
+### Key Packages
+
+| Package | Description |
+|---------|-------------|
+| `internal/analyzer` | Core detection logic (SELECT *, N+1, SQL Injection) |
+| `internal/analyzer/sqlbuilders` | Support for 12 SQL builder libraries |
+| `internal/dsl` | Custom rules DSL using expr-lang |
+| `internal/lsp` | Language Server Protocol implementation |
+| `internal/tui` | Interactive terminal UI with Bubble Tea |
+| `pkg/config` | Configuration with default rules |
+
+> **Note**: All three detection rules (SELECT *, N+1, SQL Injection) are enabled by default.
+
+---
+
+## Running Tests
+
+Using Task:
+```bash
+task test # Run all tests
+task test:race # Run with race detection (requires CGO)
+task test:short # Run short tests only
+task test:unit # Run unit tests only
+task test:integration # Run integration tests
+task coverage # Generate coverage report
+```
+
+Using Go directly:
+```bash
+go test ./...
+go test -v -race ./...
+go test -coverprofile=coverage.out ./...
+```
+
+### Running Benchmarks
+
+```bash
+task bench
+# or
+go test -bench=. -benchmem ./internal/analyzer
+```
+
+---
+
+## Code Style
+
+### Formatting
+
+```bash
+task fmt # Format code
+task fmt:check # Check formatting
+```
+
+### Linting
+
+```bash
+task lint # Run golangci-lint
+task lint:fix # Run with auto-fix
+task vet # Run go vet
+```
+
+### All Checks
+
+```bash
+task check:all # fmt:check + vet + lint + test
+```
+
+### Guidelines
+
+1. **Follow Go conventions** - Use `gofmt`, follow [Effective Go](https://go.dev/doc/effective_go)
+2. **Write tests** - All new features should have tests
+3. **Document exports** - All exported functions/types need documentation comments
+4. **Keep it simple** - Prefer simple, readable code over clever solutions
+5. **No breaking changes** - Maintain backward compatibility for public APIs
+
+---
+
+## Pull Request Process
+
+1. **Sync with upstream**
+ ```bash
+ git fetch upstream
+ git rebase upstream/main
+ ```
+
+2. **Ensure tests pass**
+ ```bash
+ task check:all
+ ```
+
+3. **Write meaningful commit messages**
+ ```
+ feat: add support for new SQL builder XYZ
+
+ - Add XYZ builder detection in internal/analyzer/sqlbuilders/
+ - Add tests for common XYZ patterns
+ - Update documentation
+ ```
+
+4. **Push and create PR**
+ ```bash
+ git push origin feature/your-feature-name
+ ```
+
+5. **PR Requirements**
+ - Clear description of changes
+ - Tests for new functionality
+ - Documentation updates if needed
+ - Passing CI checks
+
+---
+
+## Adding New SQL Builders
+
+To add support for a new SQL builder library:
+
+### 1. Create Builder File
+
+Create `internal/analyzer/sqlbuilders/yourbuilder.go`:
+
+```go
+package sqlbuilders
+
+import (
+ "go/ast"
+)
+
+// YourBuilderChecker checks for SELECT * in YourBuilder queries.
+type YourBuilderChecker struct {
+ BaseChecker
+}
+
+// NewYourBuilderChecker creates a new checker for YourBuilder.
+func NewYourBuilderChecker() *YourBuilderChecker {
+ return &YourBuilderChecker{
+ BaseChecker: BaseChecker{
+ name: "yourbuilder",
+ packagePath: "github.com/example/yourbuilder",
+ },
+ }
+}
+
+func (c *YourBuilderChecker) Name() string {
+ return c.name
+}
+
+func (c *YourBuilderChecker) IsApplicable(call *ast.CallExpr) bool {
+ // Check if this call is from yourbuilder package
+ return c.isPackageCall(call, "yourbuilder")
+}
+
+func (c *YourBuilderChecker) CheckSelectStar(call *ast.CallExpr) *Violation {
+ // Implement SELECT * detection logic
+ return nil
+}
+
+func (c *YourBuilderChecker) CheckChainedCalls(call *ast.CallExpr) []*Violation {
+ // Check method chains for SELECT *
+ return nil
+}
+```
+
+### 2. Register in Registry
+
+Update `internal/analyzer/sqlbuilders/interface.go`:
+
+```go
+func NewRegistry(cfg *config.SQLBuildersConfig) *Registry {
+ r := &Registry{checkers: make([]SQLBuilderChecker, 0)}
+
+ // ... existing builders ...
+
+ if cfg.YourBuilder {
+ r.checkers = append(r.checkers, NewYourBuilderChecker())
+ }
+
+ return r
+}
+```
+
+### 3. Add Configuration
+
+Update `pkg/config/config.go`:
+
+```go
+type SQLBuildersConfig struct {
+ // ... existing fields ...
+ YourBuilder bool `yaml:"yourbuilder"`
+}
+
+func DefaultSQLBuildersConfig() SQLBuildersConfig {
+ return SQLBuildersConfig{
+ // ... existing defaults ...
+ YourBuilder: true,
+ }
+}
+```
+
+### 4. Write Tests
+
+Create `internal/analyzer/sqlbuilders/yourbuilder_test.go` with test cases.
+
+### 5. Update Documentation
+
+- Add to README.md SQL builders table
+- Add example in `` block
+- Update `.unqueryvet.example.yaml`
+
+---
+
+## Reporting Issues
+
+### Bug Reports
+
+Please include:
+- Go version (`go version`)
+- unqueryvet version (`unqueryvet -version`)
+- Operating system
+- Minimal reproducible example
+- Expected vs actual behavior
+
+### Feature Requests
+
+Please include:
+- Use case description
+- Proposed solution (if any)
+- Examples of desired behavior
+
+---
+
+## Questions?
+
+- Open a [GitHub Issue](https://github.com/MirrexOne/unqueryvet/issues)
+
+Thank you for contributing!
diff --git a/vendor/github.com/MirrexOne/unqueryvet/Dockerfile b/vendor/github.com/MirrexOne/unqueryvet/Dockerfile
new file mode 100644
index 000000000..58383d2d1
--- /dev/null
+++ b/vendor/github.com/MirrexOne/unqueryvet/Dockerfile
@@ -0,0 +1,42 @@
+# Build stage
+FROM golang:1.24-alpine AS builder
+
+RUN apk add --no-cache git gcc musl-dev
+
+WORKDIR /app
+
+# Copy go mod files
+COPY go.mod go.sum ./
+RUN go mod download
+
+# Copy source
+COPY . .
+
+# Build binaries
+RUN CGO_ENABLED=1 go build -ldflags="-s -w" -o /unqueryvet ./cmd/unqueryvet
+RUN CGO_ENABLED=1 go build -ldflags="-s -w" -o /unqueryvet-lsp ./cmd/unqueryvet-lsp
+
+# Final stage
+FROM alpine:3.19
+
+RUN apk add --no-cache ca-certificates tzdata
+
+# Create non-root user
+RUN adduser -D -u 1000 unqueryvet
+USER unqueryvet
+
+WORKDIR /workspace
+
+# Copy binaries
+COPY --from=builder /unqueryvet /usr/local/bin/
+COPY --from=builder /unqueryvet-lsp /usr/local/bin/
+
+# Default command
+ENTRYPOINT ["unqueryvet"]
+CMD ["./..."]
+
+# Labels
+LABEL org.opencontainers.image.title="Unqueryvet"
+LABEL org.opencontainers.image.description="SQL SELECT * linter for Go"
+LABEL org.opencontainers.image.source="https://github.com/MirrexOne/unqueryvet"
+LABEL org.opencontainers.image.licenses="MIT"
diff --git a/vendor/github.com/MirrexOne/unqueryvet/Makefile b/vendor/github.com/MirrexOne/unqueryvet/Makefile
deleted file mode 100644
index d92d30681..000000000
--- a/vendor/github.com/MirrexOne/unqueryvet/Makefile
+++ /dev/null
@@ -1,93 +0,0 @@
-.PHONY: all test build fmt fmt-check lint clean install help
-
-# Default target
-all: fmt test build
-
-# Run tests
-test:
- @echo "Running tests..."
- @go test -v -race -coverprofile=coverage.out ./...
-
-# Build the binary
-build:
- @echo "Building unqueryvet..."
- @go build -v ./cmd/unqueryvet
-
-# Format code with gofmt -s
-fmt:
- @echo "Formatting code..."
- @find . -name "*.go" -not -path "./vendor/*" -exec gofmt -s -w {} +
- @go fmt ./...
-
-# Check if code is formatted
-fmt-check:
- @echo "Checking code formatting..."
- @if [ -n "$$(find . -name '*.go' -not -path './vendor/*' -exec gofmt -s -l {} +)" ]; then \
- echo "The following files need formatting:"; \
- find . -name '*.go' -not -path './vendor/*' -exec gofmt -s -l {} +; \
- exit 1; \
- else \
- echo "All files are properly formatted"; \
- fi
-
-# Run linter
-lint:
- @echo "Running linter..."
- @if command -v golangci-lint > /dev/null 2>&1; then \
- ./lint-local.sh ./...; \
- else \
- echo "golangci-lint not installed. Install it from https://golangci-lint.run/usage/install/"; \
- exit 1; \
- fi
-
-# Clean build artifacts
-clean:
- @echo "Cleaning..."
- @rm -f unqueryvet
- @rm -f coverage.out
- @rm -f .golangci.local.yml
- @go clean
-
-# Install the binary
-install:
- @echo "Installing unqueryvet..."
- @go install ./cmd/unqueryvet
-
-# Run unqueryvet on the project itself
-check:
- @echo "Running unqueryvet on project..."
- @go run ./cmd/unqueryvet ./...
-
-# Generate coverage report
-coverage: test
- @echo "Generating coverage report..."
- @go tool cover -html=coverage.out -o coverage.html
- @echo "Coverage report generated: coverage.html"
-
-# Run benchmarks
-bench:
- @echo "Running benchmarks..."
- @go test -bench=. -benchmem ./internal/analyzer
-
-# Update dependencies
-deps:
- @echo "Updating dependencies..."
- @go mod tidy
- @go mod verify
-
-# Help target
-help:
- @echo "Available targets:"
- @echo " make - Format, test, and build"
- @echo " make test - Run tests with race detection"
- @echo " make build - Build the unqueryvet binary"
- @echo " make fmt - Format all Go files with gofmt -s"
- @echo " make fmt-check - Check if files are formatted"
- @echo " make lint - Run golangci-lint"
- @echo " make clean - Remove build artifacts"
- @echo " make install - Install unqueryvet binary"
- @echo " make check - Run unqueryvet on the project"
- @echo " make coverage - Generate coverage report"
- @echo " make bench - Run benchmarks"
- @echo " make deps - Update and verify dependencies"
- @echo " make help - Show this help message"
diff --git a/vendor/github.com/MirrexOne/unqueryvet/README.md b/vendor/github.com/MirrexOne/unqueryvet/README.md
index a5b2a3aed..faa5e7b66 100644
--- a/vendor/github.com/MirrexOne/unqueryvet/README.md
+++ b/vendor/github.com/MirrexOne/unqueryvet/README.md
@@ -1,80 +1,57 @@
# unqueryvet
[](https://goreportcard.com/report/github.com/MirrexOne/unqueryvet)
-[](https://godoc.org/github.com/MirrexOne/unqueryvet)
+[](https://pkg.go.dev/github.com/MirrexOne/unqueryvet)
[](LICENSE)
-unqueryvet is a Go static analysis tool (linter) that detects `SELECT *` usage in SQL queries and SQL builders, encouraging explicit column selection for better performance, maintainability, and API stability.
+[](https://plugins.jetbrains.com/plugin/29733-unqueryvet)
+[](https://plugins.jetbrains.com/plugin/29733-unqueryvet)
-## Features
+[](https://marketplace.visualstudio.com/items?itemName=mirrexdev.unqueryvet)
+[](https://marketplace.visualstudio.com/items?itemName=mirrexdev.unqueryvet)
-- **Detects `SELECT *` in string literals** - Finds problematic queries in your Go code
-- **Constants and variables support** - Detects `SELECT *` in const and var declarations
-- **String concatenation analysis** - Detects `SELECT *` in concatenated strings like `"SELECT * " + "FROM users"`
-- **Format string analysis** - Detects `SELECT *` in `fmt.Sprintf`, `log.Printf`, and other format functions
-- **Aliased wildcard detection** - Catches `SELECT t.*`, `SELECT alias.*` patterns
-- **Subquery detection** - Finds `SELECT *` inside subqueries and nested queries
-- **SQL Builder support** - Works with 8 popular SQL builders: Squirrel, GORM, SQLx, Ent, PGX, Bun, SQLBoiler, Jet
-- **Auto-fix suggestions** - Provides suggested fixes for detected violations
-- **File and function filtering** - Ignore specific files or functions using glob patterns
-- **Configurable severity** - Set diagnostic severity to "error" or "warning"
-- **Highly configurable** - Extensive configuration options for different use cases
-- **Supports `//nolint:unqueryvet`** - Standard Go linting suppression
-- **golangci-lint integration** - Works seamlessly with golangci-lint
-- **Zero false positives** - Smart pattern recognition for acceptable `SELECT *` usage
-- **Fast and lightweight** - Built on golang.org/x/tools/go/analysis
+[](https://plugins.jetbrains.com/plugin/29733-unqueryvet)
+[](https://marketplace.visualstudio.com/items?itemName=mirrexdev.unqueryvet)
-## Why avoid `SELECT *`?
+**unqueryvet** is a comprehensive Go linter for SQL queries. It detects `SELECT *` usage, N+1 query problems, SQL injection vulnerabilities, and provides suggestions for query optimization.
-- **Performance**: Selecting unnecessary columns wastes network bandwidth and memory
-- **Maintainability**: Schema changes can break your application unexpectedly
-- **Security**: May expose sensitive data that shouldn't be returned
-- **API Stability**: Adding new columns can break clients that depend on column order
+## Key Features
-## Informative Error Messages
+| Feature | Description |
+| ----------------------------- | ---------------------------------------------------------------------------- |
+| **SELECT \* Detection** | Finds `SELECT *` in raw SQL, SQL builders, and templates |
+| **N+1 Query Detection** | Identifies queries inside loops |
+| **SQL Injection Scanner** | Detects `fmt.Sprintf` and string concatenation vulnerabilities |
+| **Transaction Leak Detection**| Detects unclosed transactions and improper lifecycle management |
+| **12 SQL Builder Support** | Squirrel, GORM, SQLx, Ent, PGX, Bun, SQLBoiler, Jet, sqlc, goqu, rel, reform |
+| **Custom Rules DSL** | Define your own analysis rules |
+| **LSP Server** | Real-time IDE integration |
+| **Interactive TUI** | Fix issues interactively |
-Unqueryvet provides context-specific messages that explain WHY you should avoid `SELECT *`:
+---
-```go
-// Basic queries
-query := "SELECT * FROM users"
-// avoid SELECT * - explicitly specify needed columns for better performance, maintainability and stability
-
-// Aliased wildcards
-query := "SELECT t.* FROM users t"
-// avoid SELECT alias.* - explicitly specify columns like t.id, t.name for better maintainability
-
-// String concatenation
-query := "SELECT * " + "FROM users"
-// avoid SELECT * in concatenated string - explicitly specify needed columns
+## Installation
-// Format strings
-query := fmt.Sprintf("SELECT * FROM %s", tableName)
-// avoid SELECT * in format string - explicitly specify needed columns
+### Standalone Tool
-// Subqueries
-query := "SELECT id FROM (SELECT * FROM users)"
-// avoid SELECT * in subquery - explicitly specify needed columns
+```bash
+go install github.com/MirrexOne/unqueryvet/cmd/unqueryvet@latest
+```
-// SQL Builders
-query := squirrel.Select("*").From("users")
-// avoid SELECT * in SQL builder - explicitly specify columns to prevent unnecessary data transfer and schema change issues
+### LSP Server (for IDE integration)
-// Empty Select()
-query := squirrel.Select()
-// SQL builder Select() without columns defaults to SELECT * - add specific columns with .Columns() method
+```bash
+go install github.com/MirrexOne/unqueryvet/cmd/unqueryvet-lsp@latest
```
-## Quick Start
-
-### As a standalone tool
+### Docker
```bash
-go install github.com/MirrexOne/unqueryvet/cmd/unqueryvet@latest
-unqueryvet ./...
+docker pull ghcr.io/mirrexone/unqueryvet:latest
+docker run --rm -v $(pwd):/app ghcr.io/mirrexone/unqueryvet /app/...
```
-### With golangci-lint (Recommended)
+### With golangci-lint
Add to your `.golangci.yml`:
@@ -88,278 +65,836 @@ linters:
settings:
unqueryvet:
check-sql-builders: true
- # By default, no functions are ignored - minimal configuration
- # ignored-functions:
- # - "fmt.Printf"
- # - "log.Printf"
- # allowed-patterns:
- # - "SELECT \\* FROM information_schema\\..*"
- # - "SELECT \\* FROM pg_catalog\\..*"
```
-## Examples
+---
-### Problematic code (will trigger warnings)
+## Quick Start
-```go
-// Constants with SELECT *
-const QueryUsers = "SELECT * FROM users"
+### Basic Usage
+
+```bash
+# Analyze all packages (all rules enabled by default)
+unqueryvet ./...
+
+# Verbose output with explanations
+unqueryvet -verbose ./...
+
+# Quiet mode (errors only) for CI/CD
+unqueryvet -quiet ./...
+
+# Show statistics
+unqueryvet -stats ./...
+
+# Interactive fix mode
+unqueryvet -fix ./...
+
+# Show version
+unqueryvet -version
+```
+
+### Default Rules
+
+All detection rules are **enabled by default**:
+
+| Rule | Default Severity | Description |
+|------|-----------------|-------------|
+| `select-star` | warning | Detects `SELECT *` usage |
+| `n1-queries` | warning | Detects N+1 query patterns (queries in loops) |
+| `sql-injection` | error | Detects SQL injection vulnerabilities |
+| `tx-leak` | warning | Detects unclosed SQL transactions |
+
+To disable a rule, set its severity to `ignore` in your `.unqueryvet.yaml`:
+
+```yaml
+rules:
+ n1-queries: ignore # Disable N+1 detection
+```
+
+### CLI Flags
+
+| Flag | Description |
+|------|-------------|
+| `-version` | Print version information |
+| `-verbose` | Enable verbose output with detailed explanations |
+| `-quiet` | Quiet mode (only errors) |
+| `-stats` | Show analysis statistics |
+| `-no-color` | Disable colored output |
+| `-n1` | Force enable N+1 detection (overrides config) |
+| `-sqli` | Force enable SQL injection detection (overrides config) |
+| `-tx-leak` | Force enable transaction leak detection (overrides config) |
+| `-fix` | Interactive fix mode - step through issues and apply fixes |
+
+### With Configuration File
+
+```bash
+# Create config file
+cat > .unqueryvet.yaml << 'EOF'
+severity: warning
+check-sql-builders: true
+
+# Rules are enabled by default - configure severity if needed
+rules:
+ select-star: warning
+ n1-queries: warning
+ sql-injection: error
+
+ignore:
+ - "*_test.go"
+ - "vendor/**"
+EOF
+
+# Run (auto-loads config)
+unqueryvet ./...
+```
+
+---
+
+## Detection Examples
-// Variables with SELECT *
-var QueryOrders = "SELECT * FROM orders"
+### 1. SELECT \* Detection
-// String literals with SELECT *
+**Bad code:**
+
+```go
+// Direct SELECT *
query := "SELECT * FROM users"
-rows, err := db.Query("SELECT * FROM orders WHERE status = ?", "active")
-// Aliased wildcards
+// Aliased wildcard
query := "SELECT t.* FROM users t"
-query := "SELECT u.*, o.* FROM users u JOIN orders o ON u.id = o.user_id"
+
+// In subquery
+query := "SELECT id FROM (SELECT * FROM users)"
// String concatenation
-query := "SELECT * " + "FROM users " + "WHERE id = ?"
+query := "SELECT * " + "FROM users"
-// Format strings
-query := fmt.Sprintf("SELECT * FROM %s WHERE id = %d", table, id)
+// Format string
+query := fmt.Sprintf("SELECT * FROM %s", table)
-// Subqueries
-query := "SELECT id FROM (SELECT * FROM users)"
-query := "SELECT * FROM users WHERE id IN (SELECT * FROM orders)"
+// SQL builders
+squirrel.Select("*").From("users")
+db.Model(&User{}).Select("*")
+goqu.From("users").Select(goqu.Star())
+```
+
+**Good code:**
-// SQL builders with SELECT *
-query := squirrel.Select("*").From("products")
-query := builder.Select().Columns("*").From("inventory")
+```go
+// Explicit columns
+query := "SELECT id, name, email FROM users"
+
+// SQL builders
+squirrel.Select("id", "name", "email").From("users")
+db.Model(&User{}).Select("id", "name", "email")
+goqu.From("users").Select("id", "name", "email")
```
-### Good code (recommended)
+### 2. N+1 Query Detection
+
+**Bad code (triggers warning):**
```go
-// Constants with explicit columns
-const QueryUsers = "SELECT id, name, email FROM users"
+users, _ := db.Query("SELECT id, name FROM users")
+for users.Next() {
+ var user User
+ users.Scan(&user.ID, &user.Name)
+
+ // N+1 problem: query inside loop
+ orders, _ := db.Query("SELECT * FROM orders WHERE user_id = ?", user.ID)
+}
+```
-// Variables with explicit columns
-var QueryOrders = "SELECT id, status, total FROM orders"
+**Good code:**
-// String literals with explicit column selection
-query := "SELECT id, name, email FROM users"
-rows, err := db.Query("SELECT id, total FROM orders WHERE status = ?", "active")
+```go
+// Use JOIN
+query := `
+ SELECT u.id, u.name, o.id, o.total
+ FROM users u
+ LEFT JOIN orders o ON u.id = o.user_id
+`
+
+// Or use IN clause
+userIDs := []int{1, 2, 3, 4, 5}
+query := "SELECT * FROM orders WHERE user_id IN (?)"
+db.Query(query, userIDs)
+```
+
+### 3. SQL Injection Detection
+
+**Bad code (triggers warning):**
+
+```go
+// String concatenation with user input
+query := "SELECT * FROM users WHERE name = '" + userName + "'"
+
+// fmt.Sprintf with user input
+query := fmt.Sprintf("SELECT * FROM users WHERE id = %s", userID)
+```
+
+**Good code:**
+
+```go
+// Parameterized query
+query := "SELECT id, name FROM users WHERE name = ?"
+db.Query(query, userName)
-// SQL builders with explicit columns
-query := squirrel.Select("id", "name", "price").From("products")
-query := builder.Select().Columns("id", "quantity", "location").From("inventory")
+// Named parameters
+query := "SELECT id, name FROM users WHERE id = :id"
+db.NamedQuery(query, map[string]interface{}{"id": userID})
```
-### Acceptable SELECT * usage (won't trigger warnings)
+### 4. Transaction Leak Detection
+
+Detects unclosed SQL transactions using 19-phase AST analysis. Supports multiple transaction begin methods across different libraries.
+
+**Supported Begin Methods:**
+
+| Library | Methods |
+|---------|---------|
+| database/sql | `Begin`, `BeginTx` |
+| sqlx | `Beginx`, `BeginTxx`, `MustBegin`, `MustBeginTx` |
+| pgx | `BeginFunc`, `BeginTxFunc` |
+| bun | `RunInTx` |
+| ent | `Tx`, `NewTx` |
+
+**Detection Patterns:**
+
+| Violation Type | Severity | Description |
+|----------------|----------|-------------|
+| `no_commit_rollback` | critical | Transaction has neither Commit() nor Rollback() |
+| `no_rollback` | high | Transaction has Commit() but no Rollback() for error paths |
+| `no_commit` | medium | Transaction has Rollback() but no Commit() |
+| `early_return` | high | Early return paths bypass Commit() without defer |
+| `defer_in_loop` | high | Defer inside loop - defers pile up until function returns |
+| `shadowed_transaction` | high | Transaction variable shadowed in inner scope |
+| `goroutine_capture` | high | Transaction captured by goroutine without defer |
+| `variable_reassignment` | high | Transaction variable reassigned - previous tx may leak |
+| `fatal_without_defer` | high | Transaction may leak if os.Exit/log.Fatal called |
+| `panic_without_defer` | medium | Transaction may leak if panic() called |
+| `conditional_commit` | medium | Commit() inside conditional - may not execute |
+| `commit_in_switch` | medium | Commit() in switch/case - may not execute in all cases |
+| `commit_in_select` | medium | Commit() in select/case - may not execute |
+| `commit_in_loop` | medium | Commit() in loop - may not execute if loop doesn't iterate |
+| `deferred_commit` | medium | Using defer Commit() is an antipattern |
+| `commit_error_ignored` | low | Commit() error ignored with blank identifier |
+| `rollback_error_ignored` | low | Rollback() error ignored with blank identifier |
+
+**Bad code (triggers error):**
```go
-// System/meta queries
-"SELECT * FROM information_schema.tables"
-"SELECT * FROM pg_catalog.pg_tables"
+func createUser(db *sql.DB, name string) error {
+ tx, err := db.Begin()
+ if err != nil {
+ return err
+ }
+ // Missing defer tx.Rollback() and missing tx.Commit()!
+
+ _, err = tx.Exec("INSERT INTO users (name) VALUES (?)", name)
+ if err != nil {
+ return err // Transaction leaked!
+ }
+ return nil
+}
+
+func deferInLoop(db *sql.DB, items []string) error {
+ for _, item := range items {
+ tx, _ := db.Begin()
+ defer tx.Rollback() // Defers pile up until function returns!
+ tx.Exec("INSERT...", item)
+ tx.Commit()
+ }
+ return nil
+}
+```
-// Aggregate functions
-"SELECT COUNT(*) FROM users"
-"SELECT MAX(*) FROM scores"
+**Good code:**
-// With nolint suppression
-query := "SELECT * FROM debug_table" //nolint:unqueryvet
+```go
+func createUser(db *sql.DB, name string) error {
+ tx, err := db.Begin()
+ if err != nil {
+ return err
+ }
+ defer tx.Rollback() // Safe: called after Commit() is a no-op
+
+ _, err = tx.Exec("INSERT INTO users (name) VALUES (?)", name)
+ if err != nil {
+ return err // Rollback will be called via defer
+ }
+
+ return tx.Commit()
+}
+
+// Using callback pattern (automatically handled)
+func createUserCallback(db *pgx.Conn, name string) error {
+ return db.BeginFunc(ctx, func(tx pgx.Tx) error {
+ _, err := tx.Exec(ctx, "INSERT INTO users (name) VALUES ($1)", name)
+ return err // Commit/Rollback handled automatically
+ })
+}
```
+---
+
## Configuration
-Unqueryvet is highly configurable to fit your project's needs:
+### Full Configuration File (.unqueryvet.yaml)
```yaml
-version: "2"
+# Built-in rules severity (all enabled by default)
+# Available values: error, warning, info, ignore
+rules:
+ select-star: warning # SELECT * detection
+ n1-queries: warning # N+1 query detection
+ sql-injection: error # SQL injection scanning
+ tx-leak: warning # Transaction leak detection
+
+# Diagnostic severity for legacy options: "error" or "warning"
+severity: warning
+
+# Core analysis options
+check-sql-builders: true
+check-aliased-wildcard: true
+check-string-concat: true
+check-format-strings: true
+check-string-builder: true
+check-subqueries: true
+
+# SQL builder libraries to check
+sql-builders:
+ squirrel: true
+ gorm: true
+ sqlx: true
+ ent: true
+ pgx: true
+ bun: true
+ sqlboiler: true
+ jet: true
+ sqlc: true
+ goqu: true
+ rel: true
+ reform: true
+
+# File patterns to ignore (glob)
+ignored-files:
+ - "*_test.go"
+ - "testdata/**"
+ - "vendor/**"
+ - "mock_*.go"
+
+# Function patterns to ignore (regex)
+ignored-functions:
+ - "debug\\..*"
+ - "test.*"
+
+# Allowed SELECT * patterns (regex)
+allowed-patterns:
+ - "SELECT \\* FROM information_schema\\..*"
+ - "SELECT \\* FROM pg_catalog\\..*"
+ - "SELECT \\* FROM temp_.*"
+```
-linters:
- settings:
- unqueryvet:
- # Enable/disable SQL builder checking (default: true)
- check-sql-builders: true
+---
+
+## Custom Rules DSL
+
+Define your own analysis rules using a powerful DSL with three levels of complexity.
+
+### Level 1: Simple Configuration
+
+```yaml
+# .unqueryvet.yaml
+rules:
+ select-star: error # Built-in rule severity
+ n1-queries: warning
+ sql-injection: error
+
+ignore:
+ - "*_test.go"
+ - "testdata/**"
+
+allow:
+ - "COUNT(*)"
+ - "information_schema.*"
+```
+
+### Level 2: Pattern Matching
+
+```yaml
+custom-rules:
+ - id: allow-temp-tables
+ pattern: SELECT * FROM $TABLE
+ when: isTempTable(table)
+ action: allow
+
+ - id: dangerous-delete
+ pattern: DELETE FROM $TABLE
+ when: "!has_where"
+ message: "DELETE without WHERE clause"
+ severity: error
+
+ - id: require-tx-timeout
+ pattern: db.BeginTx($CTX, $OPTS)
+ when: "!contains(opts, 'Timeout')"
+ message: "Transaction should have timeout set"
+ severity: warning
+```
+
+### Level 3: Advanced Conditions
+
+```yaml
+custom-rules:
+ - id: n1-detection
+ pattern: $DB.Query($QUERY)
+ when: |
+ in_loop &&
+ !contains(function, "batch") &&
+ !matches(file, "_test.go$")
+ message: "N+1 query in loop"
+ severity: warning
+ fix: "Use batch query or preloading"
+```
- # Enable/disable aliased wildcard detection like SELECT t.* (default: true)
- check-aliased-wildcard: true
+### DSL Reference
- # Enable/disable string concatenation analysis (default: true)
- check-string-concat: true
+| **Metavariables** | **Description** |
+|-------------------|-----------------|
+| `$TABLE` | Table name (with optional schema) |
+| `$VAR` | Identifier/variable |
+| `$QUERY` | String literal |
+| `$COLS` | Column list |
+| `$DB` | Database object |
- # Enable/disable format string analysis like fmt.Sprintf (default: true)
- check-format-strings: true
+| **Variables** | **Description** |
+|---------------|-----------------|
+| `file`, `package`, `function` | Code context |
+| `query`, `query_type`, `table` | SQL context |
+| `has_where`, `has_join` | Query structure |
+| `in_loop`, `loop_depth` | Loop context |
+| `builder` | SQL builder type |
- # Enable/disable strings.Builder analysis (default: true)
- check-string-builder: true
+| **Functions** | **Description** |
+|---------------|-----------------|
+| `contains(s, sub)` | String contains |
+| `matches(s, regex)` | Regex match |
+| `isSystemTable(t)` | System table check |
+| `isTempTable(t)` | Temp table check |
+| `isAggregate(q)` | Aggregate function check |
- # Enable/disable subquery analysis (default: true)
- check-subqueries: true
+| **Operators** | **Description** |
+|---------------|-----------------|
+| `=~`, `!~` | Regex match/not match |
+| `&&`, `\|\|`, `!` | Logical operators |
- # Diagnostic severity: "error" or "warning" (default: "warning")
- severity: warning
+Full documentation: [docs/DSL.md](docs/DSL.md)
- # SQL builder libraries to check (all enabled by default)
- sql-builders:
- squirrel: true
- gorm: true
- sqlx: true
- ent: true
- pgx: true
- bun: true
- sqlboiler: true
- jet: true
+---
- # Patterns for files to ignore (glob patterns)
- # ignored-files:
- # - "*_test.go"
- # - "testdata/**"
- # - "mock_*.go"
+## LSP Server (IDE Integration)
- # Functions to ignore (regex patterns)
- # ignored-functions:
- # - "debug\\..*"
- # - "test.*"
+The LSP server provides real-time analysis in your IDE.
- # Default allowed patterns (automatically included):
- # - COUNT(*), MAX(*), MIN(*) functions
- # - information_schema, pg_catalog, sys schema queries
- # You can add more patterns if needed:
- # allowed-patterns:
- # - "SELECT \\* FROM temp_.*"
+### Starting the Server
+
+```bash
+unqueryvet-lsp
```
+### VS Code Setup
+
+Install the extension from `extensions/vscode/` or configure manually:
+
+```json
+// .vscode/settings.json
+{
+ "unqueryvet.enable": true,
+ "unqueryvet.path": "unqueryvet-lsp",
+ // All rules enabled by default, args optional
+ "unqueryvet.trace.server": "verbose"
+}
+```
+
+### Features
+
+- **Real-time diagnostics** - See issues as you type
+- **Hover information** - Explanations on hover
+- **Quick fixes** - One-click fixes for SELECT \*
+- **Code completion** - Column name suggestions
+
+### GoLand/IntelliJ Setup
+
+1. Build the plugin: `cd extensions/goland && ./gradlew buildPlugin`
+2. Install from disk: Settings → Plugins → Install from disk
+3. Configure: Settings → Tools → unqueryvet
+
+---
+
+## Interactive TUI Mode
+
+Fix issues interactively with a terminal UI.
+
+```bash
+unqueryvet -fix ./...
+```
+
+### Controls
+
+| Category | Key | Action |
+|----------|-----|--------|
+| **Navigation** | `↑/k` | Previous issue |
+| | `↓/j` | Next issue |
+| | `g` | Go to first issue |
+| | `G` | Go to last issue |
+| **Actions** | `Enter/a` | Apply fix |
+| | `s` | Skip issue |
+| | `u` | Undo last action |
+| | `p` | Toggle preview |
+| **Batch** | `A` | Apply all remaining |
+| | `S` | Skip all remaining |
+| | `R` | Reset all actions |
+| **Other** | `e` | Export results to JSON |
+| | `?` | Toggle help |
+| | `q/Esc` | Quit |
+
+### Example Session
+
+```
+Found 15 issues. Review each one:
+
+[1/15] internal/api/users.go:42:15
+─────────────────────────────────────
+ 41 | func getUsers(db *sql.DB) {
+ 42 | query := "SELECT * FROM users"
+ | ^^^^^^^^^^^^^^^^^^^^^ avoid SELECT *
+ 43 | rows, _ := db.Query(query)
+
+Suggestions:
+ 1. SELECT id, username, email, created_at (from struct User)
+ 2. SELECT id, username, email
+ 3. Skip this issue
+ 4. Edit manually
+
+Your choice [1-4]: _
+```
+
+---
+
## Supported SQL Builders
-Unqueryvet supports 8 popular SQL builders out of the box:
+### Full Support (12 builders)
+
+| Builder | Package | Patterns Detected |
+| ------------- | ----------------------------------- | -------------------------------------------- |
+| **Squirrel** | `github.com/Masterminds/squirrel` | `Select("*")`, `Columns("*")` |
+| **GORM** | `gorm.io/gorm` | `Select("*")`, `Find(&users)` without Select |
+| **SQLx** | `github.com/jmoiron/sqlx` | `Select()`, raw queries |
+| **Ent** | `entgo.io/ent` | Query builder patterns |
+| **PGX** | `github.com/jackc/pgx` | `Query()`, `QueryRow()` |
+| **Bun** | `github.com/uptrace/bun` | `NewSelect()`, raw queries |
+| **SQLBoiler** | `github.com/volatiletech/sqlboiler` | Generated query methods |
+| **Jet** | `github.com/go-jet/jet` | `SELECT()`, `STAR` |
+| **sqlc** | Generated code | SELECT \* in .sql files |
+| **goqu** | `github.com/doug-martin/goqu` | `Select(goqu.Star())`, `SelectAll()` |
+| **rel** | `github.com/go-rel/rel` | `Find()`, `FindAll()` without Select |
+| **reform** | `gopkg.in/reform.v1` | `FindByPrimaryKeyFrom()`, `SelectAllFrom()` |
+
+### Examples by Builder
+
+
+Squirrel
-| Library | Package | Detection |
-|---------|---------|-----------|
-| **Squirrel** | `github.com/Masterminds/squirrel` | `Select("*")`, `Columns("*")` |
-| **GORM** | `gorm.io/gorm` | `Select("*")`, raw queries |
-| **SQLx** | `github.com/jmoiron/sqlx` | `Select()`, raw queries |
-| **Ent** | `entgo.io/ent` | Query builder patterns |
-| **PGX** | `github.com/jackc/pgx` | `Query()`, `QueryRow()` |
-| **Bun** | `github.com/uptrace/bun` | `NewSelect()`, raw queries |
-| **SQLBoiler** | `github.com/volatiletech/sqlboiler` | Generated query methods |
-| **Jet** | `github.com/go-jet/jet` | `SELECT()`, `STAR` |
+```go
+// Bad
+sq.Select("*").From("users")
+sq.Select().Columns("*").From("users")
-Each checker can be individually enabled/disabled via configuration.
+// Good
+sq.Select("id", "name", "email").From("users")
+```
-## Auto-Fix Suggestions
+
-Unqueryvet provides automatic fix suggestions for detected violations. When used with editors that support LSP or with `golangci-lint --fix`, you can quickly fix issues:
+
+GORM
```go
-// Before (violation detected)
-query := "SELECT * FROM users"
+// Bad
+db.Select("*").Find(&users)
+db.Table("users").Find(&users) // implicit SELECT *
-// After auto-fix (with TODO placeholder)
-query := "SELECT id, /* TODO: specify columns */ FROM users"
+// Good
+db.Select("id", "name", "email").Find(&users)
+```
-// SQL builder before
-squirrel.Select("*").From("users")
+
+
+
+goqu
+
+```go
+// Bad
+goqu.From("users").Select(goqu.Star())
+goqu.From("users").SelectAll()
+
+// Good
+goqu.From("users").Select("id", "name", "email")
+```
+
+
+
+
+rel
+
+```go
+// Bad
+repo.Find(ctx, &user) // loads all columns
+repo.FindAll(ctx, &users)
+
+// Good
+repo.Find(ctx, &user, rel.Select("id", "name", "email"))
+```
+
+
+
+
+reform
+
+```go
+// Bad
+db.FindByPrimaryKeyFrom(UserTable, id, &user)
+db.FindAllFrom(UserTable, "status", "active")
+
+// Good
+db.SelectOneFrom(UserTable, "id, name, email WHERE id = ?", id)
+```
+
+
+
+
+SQLx
+
+```go
+// Bad
+db.Select(&users, "SELECT * FROM users")
+db.Get(&user, "SELECT * FROM users WHERE id = ?", id)
-// SQL builder after auto-fix
-squirrel.Select("id", /* TODO: specify columns */).From("users")
+// Good
+db.Select(&users, "SELECT id, name, email FROM users")
+db.Get(&user, "SELECT id, name, email FROM users WHERE id = ?", id)
```
-The auto-fix adds `/* TODO: specify columns */` as a reminder to manually specify the columns you actually need.
+
-## Integration Examples
+
+Ent
+
+```go
+// Bad - implicit SELECT *
+users, err := client.User.Query().All(ctx)
+
+// Good - explicit column selection
+users, err := client.User.Query().
+ Select(user.FieldID, user.FieldName, user.FieldEmail).
+ All(ctx)
+```
+
+
+
+
+PGX
+
+```go
+// Bad
+rows, err := conn.Query(ctx, "SELECT * FROM users")
+
+// Good
+rows, err := conn.Query(ctx, "SELECT id, name, email FROM users")
+```
+
+
+
+
+Bun
+
+```go
+// Bad
+db.NewSelect().Model(&users).Scan(ctx)
+db.NewSelect().TableExpr("users").Scan(ctx, &users)
+
+// Good
+db.NewSelect().Model(&users).Column("id", "name", "email").Scan(ctx)
+```
+
+
+
+
+SQLBoiler
+
+```go
+// Bad - loads all columns
+users, err := models.Users().All(ctx, db)
+user, err := models.FindUser(ctx, db, userID)
+
+// Good - explicit column selection
+users, err := models.Users(
+ qm.Select("id", "name", "email"),
+).All(ctx, db)
+```
+
+
+
+
+Jet
+
+```go
+// Bad
+stmt := SELECT(User.AllColumns).FROM(User)
+
+// Good
+stmt := SELECT(User.ID, User.Name, User.Email).FROM(User)
+```
+
+
+
+
+sqlc
+
+```sql
+-- Bad (in .sql file)
+-- name: GetUsers :many
+SELECT * FROM users;
+
+-- Good
+-- name: GetUsers :many
+SELECT id, name, email FROM users;
+```
+
+
+
+---
+
+## Docker & CI/CD
+
+### Dockerfile
+
+```dockerfile
+FROM golang:1.24-alpine AS builder
+RUN go install github.com/MirrexOne/unqueryvet/cmd/unqueryvet@latest
+
+FROM alpine:latest
+COPY --from=builder /go/bin/unqueryvet /usr/local/bin/
+ENTRYPOINT ["unqueryvet"]
+```
### GitHub Actions
```yaml
-name: Lint
+name: SQL Lint
+
on: [push, pull_request]
+
jobs:
lint:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v5
- - uses: actions/setup-go@v6
- - name: golangci-lint
- uses: golangci/golangci-lint-action@v8
- with:
- version: latest
- args: --enable unqueryvet
-```
+ - uses: actions/checkout@v4
-## Command Line Options
+ - uses: actions/setup-go@v6
+ with:
+ go-version: '1.24'
-When used as a standalone tool:
+ - name: Install unqueryvet
+ run: go install github.com/MirrexOne/unqueryvet/cmd/unqueryvet@latest
-```bash
-# Check all packages
-unqueryvet ./...
-
-# Check specific packages
-unqueryvet ./cmd/... ./internal/...
+ - name: Run unqueryvet
+ run: unqueryvet -n1 -sqli -tx-leak ./...
+```
-# With custom config file
-unqueryvet -config=.unqueryvet.yml ./...
+### GitLab CI
-# Verbose output
-unqueryvet -v ./...
+```yaml
+sql-lint:
+ image: ghcr.io/mirrexone/unqueryvet:latest
+ script:
+ - unqueryvet -quiet -n1 -sqli -tx-leak ./...
+ rules:
+ - if: $CI_PIPELINE_SOURCE == "merge_request_event"
```
-## Performance
-
-Unqueryvet is designed to be fast and lightweight:
+---
-- **Parallel processing**: Analyzes multiple files concurrently
-- **Incremental analysis**: Only analyzes changed files when possible
-- **Minimal memory footprint**: Efficient AST traversal
-- **Smart caching**: Reuses analysis results when appropriate
+## Exit Codes
-## Advanced Usage
+| Code | Meaning |
+|------|---------|
+| 0 | No issues found |
+| 1 | Warnings found |
+| 2 | Errors found |
+| 3 | Analysis failed |
-### Custom Patterns
+---
-You can define custom regex patterns for acceptable `SELECT *` usage:
+## Documentation
-```yaml
-allowed-patterns:
- # Allow SELECT * from temporary tables
- - "SELECT \\* FROM temp_\\w+"
- # Allow SELECT * in migration scripts
- - "SELECT \\* FROM.*-- migration"
- # Allow SELECT * for specific schemas
- - "SELECT \\* FROM audit\\..+"
-```
+- [CLI Features Guide](docs/CLI_FEATURES.md)
+- [Custom Rules DSL](docs/DSL.md)
+- [IDE Integration Guide](docs/IDE_INTEGRATION.md)
-### Integration with Custom SQL Builders
+---
-For custom SQL builders, Unqueryvet looks for these patterns:
+## Development
-```go
-// Method chaining
-builder.Select("*") // Direct SELECT *
-builder.Select().Columns("*") // Chained SELECT *
+### Build
-// Variable tracking
-query := builder.Select() // Empty select
-// If no .Columns() call follows, triggers warning
+```bash
+go build ./cmd/unqueryvet
+go build ./cmd/unqueryvet-lsp
```
-### Running Tests
+### Test
```bash
go test ./...
-go test -race ./...
-go test -bench=. ./...
```
-### Development Setup
+### Install locally
+
+```bash
+go install ./cmd/unqueryvet
+go install ./cmd/unqueryvet-lsp
+```
+
+---
+
+## Contributing
```bash
git clone https://github.com/MirrexOne/unqueryvet.git
cd unqueryvet
-go mod tidy
+go mod download
go test ./...
+go build ./...
```
+See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.
+
+---
+
## License
MIT License - see [LICENSE](LICENSE) file for details.
+---
+
+## Acknowledgments
+
+- Built on [golang.org/x/tools/go/analysis](https://pkg.go.dev/golang.org/x/tools/go/analysis)
+- TUI powered by [Bubbletea](https://github.com/charmbracelet/bubbletea)
+
+---
+
## Support
- **Bug Reports**: [GitHub Issues](https://github.com/MirrexOne/unqueryvet/issues)
diff --git a/vendor/github.com/MirrexOne/unqueryvet/RELEASE.md b/vendor/github.com/MirrexOne/unqueryvet/RELEASE.md
new file mode 100644
index 000000000..e1a797ede
--- /dev/null
+++ b/vendor/github.com/MirrexOne/unqueryvet/RELEASE.md
@@ -0,0 +1,203 @@
+# Release Process
+
+This document describes how to create a new release of Unqueryvet and its VS Code extension.
+
+## Prerequisites
+
+- Push access to the repository
+- Go 1.21+ installed
+- Node.js 20+ installed
+- Git configured
+
+## Release Workflow
+
+### Option 1: Fully Automated (Recommended)
+
+1. **Create a Git tag:**
+ ```bash
+ git tag -a v1.0.0 -m "Release v1.0.0"
+ git push origin v1.0.0
+ ```
+
+2. **Create GitHub Release:**
+ - Go to https://github.com/MirrexOne/unqueryvet/releases/new
+ - Select the tag you just pushed (v1.0.0)
+ - Title: `v1.0.0`
+ - Description: List of changes
+ - Click "Publish release"
+
+3. **What happens automatically:**
+ - ✅ GitHub Actions builds LSP binaries for all platforms
+ - ✅ Binaries are attached to the release
+ - ✅ Checksums file is generated
+ - ✅ VS Code extension is built
+ - ✅ VS Code extension is published to Marketplace
+ - ✅ Extension .vsix is attached to the release
+
+4. **Wait 5-10 minutes** for workflows to complete
+
+5. **Verify:**
+ - Check release has all LSP binaries attached
+ - Check VS Code Marketplace: https://marketplace.visualstudio.com/items?itemName=mirrexdev.unqueryvet
+ - Test automatic LSP download in a fresh VS Code instance
+
+### Option 2: Manual Build
+
+If you need to build locally:
+
+1. **Build LSP binaries:**
+ ```bash
+ # Using Task
+ task build:lsp:release
+
+ # Or using script directly
+ ./scripts/build-lsp.sh v1.0.0 # Linux/macOS
+ # OR
+ powershell ./scripts/build-lsp.ps1 -Version v1.0.0 # Windows
+ ```
+
+2. **Check dist/ folder:**
+ ```bash
+ ls -lh dist/
+ ```
+
+ You should see:
+ - unqueryvet-lsp-windows-amd64.exe
+ - unqueryvet-lsp-windows-arm64.exe
+ - unqueryvet-lsp-linux-amd64
+ - unqueryvet-lsp-linux-arm64
+ - unqueryvet-lsp-darwin-amd64
+ - unqueryvet-lsp-darwin-arm64
+ - checksums.txt
+
+3. **Upload to GitHub Release manually:**
+ - Create release on GitHub
+ - Upload all files from dist/
+
+4. **Build VS Code extension:**
+ ```bash
+ cd extensions/vscode
+ npm install
+ npm run compile
+ npx @vscode/vsce package
+ ```
+
+5. **Publish VS Code extension:**
+ ```bash
+ npx @vscode/vsce publish -p YOUR_PAT_TOKEN
+ ```
+
+## Platform Support
+
+LSP binaries are built for:
+
+| Platform | Architecture | File |
+|----------|-------------|------|
+| Windows | amd64 | unqueryvet-lsp-windows-amd64.exe |
+| Windows | arm64 | unqueryvet-lsp-windows-arm64.exe |
+| Linux | amd64 | unqueryvet-lsp-linux-amd64 |
+| Linux | arm64 | unqueryvet-lsp-linux-arm64 |
+| macOS | amd64 | unqueryvet-lsp-darwin-amd64 |
+| macOS | arm64 (M1+) | unqueryvet-lsp-darwin-arm64 |
+
+## Version Numbering
+
+Follow Semantic Versioning (semver):
+
+- **Major** (v2.0.0): Breaking changes
+- **Minor** (v1.1.0): New features, backward compatible
+- **Patch** (v1.0.1): Bug fixes, backward compatible
+
+## Checklist Before Release
+
+- [ ] All tests passing (`task test`)
+- [ ] Code formatted (`task fmt`)
+- [ ] Linter passing (`task lint`)
+- [ ] CHANGELOG.md updated
+- [ ] Version bumped in:
+ - [ ] extensions/vscode/package.json
+ - [ ] extensions/vscode/CHANGELOG.md
+- [ ] README.md up to date
+- [ ] All PRs merged
+- [ ] No breaking changes (or documented)
+
+## Post-Release
+
+1. **Test installation:**
+ ```bash
+ # Test Go installation
+ go install github.com/MirrexOne/unqueryvet/cmd/unqueryvet@latest
+
+ # Test LSP installation
+ go install github.com/MirrexOne/unqueryvet/cmd/unqueryvet-lsp@latest
+ ```
+
+2. **Test VS Code extension:**
+ - Install from Marketplace
+ - Open a Go file
+ - Verify automatic LSP download works
+ - Verify diagnostics appear
+
+3. **Update documentation** if needed
+
+4. **Announce release:**
+ - Twitter/X
+ - Reddit r/golang
+ - LinkedIn
+ - Discord communities
+
+## Troubleshooting
+
+### GitHub Actions fails
+
+- Check workflow logs: https://github.com/MirrexOne/unqueryvet/actions
+- Common issues:
+ - VSCE_PAT expired → regenerate in Azure DevOps
+ - Build error → test locally first
+ - Permission error → check GITHUB_TOKEN permissions
+
+### VS Code extension not publishing
+
+- Verify VSCE_PAT secret is set in GitHub
+- Check publisher ID matches in package.json (mirrexdev)
+- Ensure version number is incremented
+
+### LSP binaries missing
+
+- Check GitHub Actions workflow completed
+- Verify tag was pushed correctly
+- Check release was published (not draft)
+
+## Emergency Rollback
+
+If a release has critical bugs:
+
+1. **Mark as pre-release** on GitHub
+2. **Unpublish VS Code extension:**
+ ```bash
+ npx @vscode/vsce unpublish mirrexdev.unqueryvet@VERSION
+ ```
+3. **Fix issues** and create new patch release
+4. **Communicate** to users about the issue
+
+## Files Modified Per Release
+
+- `extensions/vscode/package.json` - bump version
+- `extensions/vscode/CHANGELOG.md` - add release notes
+- `CHANGELOG.md` - add release notes (if exists)
+- Git tag - create new tag
+
+## Automation Scripts
+
+| Script | Purpose |
+|--------|---------|
+| `scripts/build-lsp.sh` | Build LSP for all platforms (Unix) |
+| `scripts/build-lsp.ps1` | Build LSP for all platforms (Windows) |
+| `.github/workflows/release-lsp.yml` | Auto-build LSP on release |
+| `.github/workflows/publish-vscode-extension.yml` | Auto-publish VS Code extension |
+
+## Support
+
+For issues with releases:
+- GitHub Issues: https://github.com/MirrexOne/unqueryvet/issues
+- GitHub Discussions: https://github.com/MirrexOne/unqueryvet/discussions
diff --git a/vendor/github.com/MirrexOne/unqueryvet/Taskfile.yml b/vendor/github.com/MirrexOne/unqueryvet/Taskfile.yml
new file mode 100644
index 000000000..b93402fe4
--- /dev/null
+++ b/vendor/github.com/MirrexOne/unqueryvet/Taskfile.yml
@@ -0,0 +1,398 @@
+# https://taskfile.dev
+version: "3"
+
+vars:
+ VERSION:
+ sh: git describe --tags --always --dirty 2>/dev/null || echo "dev"
+ COMMIT:
+ sh: git rev-parse --short HEAD 2>/dev/null || echo "unknown"
+ DATE:
+ sh: date -u +"%Y-%m-%dT%H:%M:%SZ"
+ BUILT_BY:
+ sh: echo "$(whoami)@$(hostname)"
+ LDFLAGS: >-
+ -X 'github.com/MirrexOne/unqueryvet/internal/version.Version={{.VERSION}}'
+ -X 'github.com/MirrexOne/unqueryvet/internal/version.Commit={{.COMMIT}}'
+ -X 'github.com/MirrexOne/unqueryvet/internal/version.Date={{.DATE}}'
+ -X 'github.com/MirrexOne/unqueryvet/internal/version.BuiltBy={{.BUILT_BY}}'
+ BINARY_NAME: unqueryvet
+ BINARY_EXT:
+ sh: if [ "$(go env GOOS)" = "windows" ]; then echo ".exe"; fi
+
+tasks:
+ default:
+ desc: Format, test, and build
+ cmds:
+ - task: fmt
+ - task: test
+ - task: build
+
+ # ============================================================================
+ # BUILD TASKS
+ # ============================================================================
+
+ build:
+ desc: Build the unqueryvet binary
+ cmds:
+ - echo "Building {{.BINARY_NAME}}..."
+ - go build -v -ldflags "{{.LDFLAGS}}" -o {{.BINARY_NAME}}{{.BINARY_EXT}} ./cmd/unqueryvet
+ sources:
+ - "**/*.go"
+ - go.mod
+ - go.sum
+ generates:
+ - "{{.BINARY_NAME}}{{.BINARY_EXT}}"
+
+ build:lsp:
+ desc: Build the LSP server binary
+ cmds:
+ - echo "Building unqueryvet-lsp..."
+ - go build -v -ldflags "{{.LDFLAGS}}" -o unqueryvet-lsp{{.BINARY_EXT}} ./cmd/unqueryvet-lsp
+ sources:
+ - "**/*.go"
+ - go.mod
+ generates:
+ - "unqueryvet-lsp{{.BINARY_EXT}}"
+
+ build:all:
+ desc: Build all binaries
+ cmds:
+ - task: build
+ - task: build:lsp
+
+ build:lsp:all:
+ desc: Build LSP server for all platforms (cross-compile)
+ cmds:
+ - echo "Building LSP for all platforms..."
+ - |
+ if [ "$(go env GOOS)" = "windows" ]; then
+ powershell -ExecutionPolicy Bypass -File ./scripts/build-lsp.ps1 -Version "{{.VERSION}}"
+ else
+ chmod +x ./scripts/build-lsp.sh
+ ./scripts/build-lsp.sh "{{.VERSION}}"
+ fi
+ - echo "Binaries available in dist/"
+
+ build:lsp:release:
+ desc: Build LSP for all platforms with release optimizations
+ cmds:
+ - echo "Building LSP release binaries..."
+ - |
+ if [ "$(go env GOOS)" = "windows" ]; then
+ powershell -ExecutionPolicy Bypass -File ./scripts/build-lsp.ps1 -Version "{{.VERSION}}"
+ else
+ chmod +x ./scripts/build-lsp.sh
+ ./scripts/build-lsp.sh "{{.VERSION}}"
+ fi
+ - cd dist && sha256sum * > checksums.txt
+ - echo "Release binaries with checksums in dist/"
+
+ install:
+ desc: Install unqueryvet binary to GOPATH/bin
+ cmds:
+ - echo "Installing unqueryvet..."
+ - go install -ldflags "{{.LDFLAGS}}" ./cmd/unqueryvet
+
+ install:all:
+ desc: Install all binaries to GOPATH/bin
+ cmds:
+ - echo "Installing all binaries..."
+ - go install -ldflags "{{.LDFLAGS}}" ./cmd/unqueryvet
+ - go install -ldflags "{{.LDFLAGS}}" ./cmd/unqueryvet-lsp
+
+ # ============================================================================
+ # TEST TASKS
+ # ============================================================================
+
+ test:
+ desc: Run tests with race detection (requires CGO on Windows)
+ cmds:
+ - echo "Running tests..."
+ - go test -v -coverprofile=coverage.out ./...
+
+ test:race:
+ desc: Run tests with race detection (requires CGO_ENABLED=1)
+ cmds:
+ - echo "Running tests with race detection..."
+ - go test -v -race -coverprofile=coverage.out ./...
+
+ test:short:
+ desc: Run short tests (skip long-running tests)
+ cmds:
+ - echo "Running short tests..."
+ - go test -v -short ./...
+
+ test:unit:
+ desc: Run unit tests only
+ cmds:
+ - echo "Running unit tests..."
+ - go test -v ./internal/...
+
+ test:integration:
+ desc: Run integration tests
+ cmds:
+ - echo "Running integration tests..."
+ - go test -v -tags=integration ./...
+
+ bench:
+ desc: Run benchmarks
+ cmds:
+ - echo "Running benchmarks..."
+ - go test -bench=. -benchmem ./internal/analyzer
+
+ bench:all:
+ desc: Run all benchmarks with comparison
+ cmds:
+ - echo "Running all benchmarks..."
+ - go test -bench=. -benchmem -count=5 ./... | tee bench.txt
+
+ coverage:
+ desc: Generate coverage report
+ deps: [test]
+ cmds:
+ - echo "Generating coverage report..."
+ - go tool cover -html=coverage.out -o coverage.html
+ - echo "Coverage report generated - coverage.html"
+
+ coverage:func:
+ desc: Show function coverage
+ deps: [test]
+ cmds:
+ - go tool cover -func=coverage.out
+
+ # ============================================================================
+ # FORMAT & LINT TASKS
+ # ============================================================================
+
+ fmt:
+ desc: Format all Go files
+ cmds:
+ - echo "Formatting code..."
+ - gofmt -s -w .
+ - go fmt ./...
+
+ fmt:check:
+ desc: Check if code is formatted
+ cmds:
+ - echo "Checking code formatting..."
+ - |
+ UNFORMATTED=$(gofmt -s -l .)
+ if [ -n "$UNFORMATTED" ]; then
+ echo "The following files need formatting:"
+ echo "$UNFORMATTED"
+ exit 1
+ else
+ echo "All files are properly formatted"
+ fi
+
+ lint:
+ desc: Run golangci-lint
+ cmds:
+ - echo "Running linter..."
+ - golangci-lint run ./...
+
+ lint:fix:
+ desc: Run golangci-lint with auto-fix
+ cmds:
+ - echo "Running linter with auto-fix..."
+ - golangci-lint run --fix ./...
+
+ vet:
+ desc: Run go vet
+ cmds:
+ - echo "Running go vet..."
+ - go vet ./...
+
+ check:
+ desc: Run unqueryvet on the project itself
+ cmds:
+ - echo "Running unqueryvet on project..."
+ - go run ./cmd/unqueryvet ./...
+
+ check:all:
+ desc: Run all checks (fmt, vet, lint, test)
+ cmds:
+ - task: fmt:check
+ - task: vet
+ - task: lint
+ - task: test
+
+ # ============================================================================
+ # DEPENDENCY TASKS
+ # ============================================================================
+
+ deps:
+ desc: Update and verify dependencies
+ cmds:
+ - echo "Updating dependencies..."
+ - go mod tidy
+ - go mod verify
+
+ deps:download:
+ desc: Download all dependencies
+ cmds:
+ - echo "Downloading dependencies..."
+ - go mod download
+
+ deps:upgrade:
+ desc: Upgrade all dependencies to latest
+ cmds:
+ - echo "Upgrading dependencies..."
+ - go get -u ./...
+ - go mod tidy
+
+ deps:graph:
+ desc: Show dependency graph
+ cmds:
+ - go mod graph
+
+ # ============================================================================
+ # DOCKER TASKS
+ # ============================================================================
+
+ docker:build:
+ desc: Build Docker image
+ cmds:
+ - echo "Building Docker image..."
+ - docker build -t unqueryvet:{{.VERSION}} -t unqueryvet:latest .
+
+ docker:run:
+ desc: Run unqueryvet in Docker
+ cmds:
+ - docker run --rm -v $(pwd):/app unqueryvet:latest /app/...
+
+ docker:push:
+ desc: Push Docker image to registry
+ vars:
+ REGISTRY: '{{.REGISTRY | default "ghcr.io/mirrexone"}}'
+ cmds:
+ - docker tag unqueryvet:{{.VERSION}} {{.REGISTRY}}/unqueryvet:{{.VERSION}}
+ - docker tag unqueryvet:latest {{.REGISTRY}}/unqueryvet:latest
+ - docker push {{.REGISTRY}}/unqueryvet:{{.VERSION}}
+ - docker push {{.REGISTRY}}/unqueryvet:latest
+
+ # ============================================================================
+ # RELEASE TASKS
+ # ============================================================================
+
+ release:snapshot:
+ desc: Create a snapshot release (no publish)
+ cmds:
+ - echo "Creating snapshot release..."
+ - goreleaser release --snapshot --clean
+
+ release:
+ desc: Create and publish a release
+ cmds:
+ - echo "Creating release..."
+ - goreleaser release --clean
+ preconditions:
+ - sh: test -n "$GITHUB_TOKEN"
+ msg: "GITHUB_TOKEN is required"
+
+ # ============================================================================
+ # DEVELOPMENT TASKS
+ # ============================================================================
+
+ dev:
+ desc: Run in development mode with watch
+ cmds:
+ - echo "Starting development mode..."
+ - go run ./cmd/unqueryvet -watch ./...
+
+ dev:lsp:
+ desc: Run LSP server in development mode
+ cmds:
+ - echo "Starting LSP server..."
+ - go run ./cmd/unqueryvet-lsp
+
+ generate:
+ desc: Run go generate
+ cmds:
+ - echo "Running go generate..."
+ - go generate ./...
+
+ # ============================================================================
+ # CLEAN TASKS
+ # ============================================================================
+
+ clean:
+ desc: Remove build artifacts
+ cmds:
+ - echo "Cleaning..."
+ - rm -f {{.BINARY_NAME}}{{.BINARY_EXT}}
+ - rm -f unqueryvet-lsp{{.BINARY_EXT}}
+ - rm -f coverage.out coverage.html
+ - rm -f bench.txt
+ - rm -rf dist/
+ - go clean
+
+ clean:cache:
+ desc: Clean Go build cache
+ cmds:
+ - echo "Cleaning Go cache..."
+ - go clean -cache
+
+ clean:testcache:
+ desc: Clean Go test cache
+ cmds:
+ - echo "Cleaning test cache..."
+ - go clean -testcache
+
+ clean:all:
+ desc: Clean everything
+ cmds:
+ - task: clean
+ - task: clean:cache
+ - task: clean:testcache
+
+ # ============================================================================
+ # EXTENSION TASKS
+ # ============================================================================
+
+ ext:vscode:build:
+ desc: Build VS Code extension
+ dir: extensions/vscode
+ cmds:
+ - echo "Building VS Code extension..."
+ - npm install
+ - npm run compile
+
+ ext:vscode:package:
+ desc: Package VS Code extension
+ dir: extensions/vscode
+ cmds:
+ - echo "Packaging VS Code extension..."
+ - npm run package
+
+ ext:goland:build:
+ desc: Build GoLand plugin
+ dir: extensions/goland
+ cmds:
+ - echo "Building GoLand plugin..."
+ - ./gradlew buildPlugin
+
+ # ============================================================================
+ # DOCUMENTATION TASKS
+ # ============================================================================
+
+ docs:serve:
+ desc: Serve documentation locally
+ cmds:
+ - echo "Serving docs on http://localhost:8000"
+ - python -m http.server 8000 --directory docs
+
+ docs:godoc:
+ desc: Run godoc server
+ cmds:
+ - echo "Starting godoc on http://localhost:6060"
+ - godoc -http=:6060
+
+ # ============================================================================
+ # HELP
+ # ============================================================================
+
+ help:
+ desc: Show all available tasks
+ cmds:
+ - task --list-all
diff --git a/vendor/github.com/MirrexOne/unqueryvet/action.yml b/vendor/github.com/MirrexOne/unqueryvet/action.yml
new file mode 100644
index 000000000..d01b9ae95
--- /dev/null
+++ b/vendor/github.com/MirrexOne/unqueryvet/action.yml
@@ -0,0 +1,92 @@
+name: "Unqueryvet"
+description: "Detect inconsistencies in Go SQL queries"
+author: "MirrexOne"
+
+branding:
+ icon: "search"
+ color: "blue"
+
+inputs:
+ version:
+ description: "Version of unqueryvet to use"
+ required: false
+ default: "latest"
+ working-directory:
+ description: "Working directory"
+ required: false
+ default: "."
+ args:
+ description: "Arguments to pass to unqueryvet"
+ required: false
+ default: "./..."
+ fail-on-issues:
+ description: "Fail the action if issues are found"
+ required: false
+ default: "true"
+ check-n1:
+ description: "Enable N+1 query detection"
+ required: false
+ default: "false"
+ check-sqli:
+ description: "Enable SQL injection detection"
+ required: false
+ default: "false"
+
+outputs:
+ issues-found:
+ description: "Number of issues found"
+ value: ${{ steps.run.outputs.issues }}
+ exit-code:
+ description: "Exit code from unqueryvet"
+ value: ${{ steps.run.outputs.exit_code }}
+
+runs:
+ using: "composite"
+ steps:
+ - name: Install unqueryvet
+ shell: bash
+ run: |
+ if [ "${{ inputs.version }}" = "latest" ]; then
+ go install github.com/MirrexOne/unqueryvet/cmd/unqueryvet@latest
+ else
+ go install github.com/MirrexOne/unqueryvet/cmd/unqueryvet@${{ inputs.version }}
+ fi
+
+ - name: Run unqueryvet
+ id: run
+ shell: bash
+ working-directory: ${{ inputs.working-directory }}
+ run: |
+ set +e
+
+ ARGS="${{ inputs.args }}"
+
+ if [ "${{ inputs.check-n1 }}" = "true" ]; then
+ ARGS="-n1 $ARGS"
+ fi
+
+ if [ "${{ inputs.check-sqli }}" = "true" ]; then
+ ARGS="-sqli $ARGS"
+ fi
+
+ OUTPUT=$(unqueryvet $ARGS 2>&1)
+ EXIT_CODE=$?
+
+ echo "$OUTPUT"
+
+ # Count issues (lines with file:line:column pattern)
+ ISSUES=$(echo "$OUTPUT" | grep -c ":[0-9]*:[0-9]*:" || true)
+
+ echo "issues=$ISSUES" >> $GITHUB_OUTPUT
+ echo "exit_code=$EXIT_CODE" >> $GITHUB_OUTPUT
+
+ if [ "${{ inputs.fail-on-issues }}" = "true" ] && [ $EXIT_CODE -ne 0 ]; then
+ echo "::error::Unqueryvet found $ISSUES issues"
+ exit 1
+ fi
+
+ if [ $ISSUES -eq 0 ]; then
+ echo "::notice::No SELECT * issues found!"
+ else
+ echo "::warning::Found $ISSUES SELECT * issues"
+ fi
diff --git a/vendor/github.com/MirrexOne/unqueryvet/internal/analyzer/analyzer.go b/vendor/github.com/MirrexOne/unqueryvet/internal/analyzer/analyzer.go
index 023aa358c..b10e9657c 100644
--- a/vendor/github.com/MirrexOne/unqueryvet/internal/analyzer/analyzer.go
+++ b/vendor/github.com/MirrexOne/unqueryvet/internal/analyzer/analyzer.go
@@ -17,12 +17,6 @@ import (
)
const (
- // selectKeyword is the SQL SELECT method name in builders
- selectKeyword = "Select"
- // columnKeyword is the SQL Column method name in builders
- columnKeyword = "Column"
- // columnsKeyword is the SQL Columns method name in builders
- columnsKeyword = "Columns"
// defaultWarningMessage is the standard warning for SELECT * usage
defaultWarningMessage = "avoid SELECT * - explicitly specify needed columns for better performance, maintainability and stability"
)
@@ -38,12 +32,7 @@ var (
// NewAnalyzer creates the Unqueryvet analyzer with enhanced logic for production use
func NewAnalyzer() *analysis.Analyzer {
- return &analysis.Analyzer{
- Name: "unqueryvet",
- Doc: "detects SELECT * in SQL queries and SQL builders, preventing performance issues and encouraging explicit column selection",
- Run: run,
- Requires: []*analysis.Analyzer{inspect.Analyzer},
- }
+ return NewAnalyzerWithSettings(config.DefaultSettings())
}
// NewAnalyzerWithSettings creates analyzer with provided settings for golangci-lint integration
@@ -58,6 +47,14 @@ func NewAnalyzerWithSettings(s config.UnqueryvetSettings) *analysis.Analyzer {
}
}
+// analysisContext holds the context for AST analysis
+type analysisContext struct {
+ pass *analysis.Pass
+ cfg *config.UnqueryvetSettings
+ filter *FilterContext
+ builderRegistry *sqlbuilders.Registry
+}
+
// RunWithConfig performs analysis with provided configuration
// This is the main entry point for configured analysis
func RunWithConfig(pass *analysis.Pass, cfg *config.UnqueryvetSettings) (any, error) {
@@ -90,6 +87,13 @@ func RunWithConfig(pass *analysis.Pass, cfg *config.UnqueryvetSettings) (any, er
builderRegistry = sqlbuilders.NewRegistry(&cfg.SQLBuilders)
}
+ ctx := &analysisContext{
+ pass: pass,
+ cfg: cfg,
+ filter: filter,
+ builderRegistry: builderRegistry,
+ }
+
// Define AST node types we're interested in
nodeFilter := []ast.Node{
(*ast.CallExpr)(nil), // Function/method calls
@@ -100,103 +104,86 @@ func RunWithConfig(pass *analysis.Pass, cfg *config.UnqueryvetSettings) (any, er
}
// Walk through all AST nodes and analyze them
- insp.Preorder(nodeFilter, func(n ast.Node) {
- switch node := n.(type) {
- case *ast.File:
- // Analyze SQL builders only if enabled in configuration
- if cfg.CheckSQLBuilders {
- analyzeSQLBuilders(pass, node)
- }
- case *ast.AssignStmt:
- // Check assignment statements for standalone SQL literals
- checkAssignStmt(pass, node, cfg)
- case *ast.GenDecl:
- // Check constant and variable declarations
- checkGenDecl(pass, node, cfg)
- case *ast.CallExpr:
- // Check if function should be ignored
- if filter != nil && filter.IsIgnoredFunction(node) {
- return
- }
-
- // Check format functions (fmt.Sprintf, etc.)
- if cfg.CheckFormatStrings && CheckFormatFunction(pass, node, cfg) {
- pass.Report(analysis.Diagnostic{
- Pos: node.Pos(),
- Message: getDetailedWarningMessage("format_string"),
- })
- return
- }
+ insp.Preorder(nodeFilter, ctx.handleNode)
- // Check SQL builder patterns
- if builderRegistry != nil && builderRegistry.HasCheckers() {
- violations := builderRegistry.Check(node)
- for _, v := range violations {
- pass.Report(analysis.Diagnostic{
- Pos: v.Pos,
- End: v.End,
- Message: v.Message,
- })
- }
- if len(violations) > 0 {
- return
- }
- }
+ return nil, nil
+}
- // Analyze function calls for SQL with SELECT * usage
- checkCallExpr(pass, node, cfg)
+// handleNode dispatches AST node to appropriate handler
+func (ctx *analysisContext) handleNode(n ast.Node) {
+ switch node := n.(type) {
+ case *ast.File:
+ ctx.handleFileNode(node)
+ case *ast.AssignStmt:
+ // Check assignment statements for standalone SQL literals
+ checkAssignStmt(ctx.pass, node, ctx.cfg)
+ case *ast.GenDecl:
+ // Check constant and variable declarations
+ checkGenDecl(ctx.pass, node, ctx.cfg)
+ case *ast.CallExpr:
+ ctx.handleCallExpr(node)
+ // Analyze function calls for SQL with SELECT * usage
+ case *ast.BinaryExpr:
+ ctx.handleBinaryExpr(node)
+ }
+}
- case *ast.BinaryExpr:
- // Check string concatenation for SELECT *
- if cfg.CheckStringConcat && CheckConcatenation(pass, node, cfg) {
- pass.Report(analysis.Diagnostic{
- Pos: node.Pos(),
- Message: getDetailedWarningMessage("concat"),
- })
- }
- }
- })
+// handleFileNode processes file-level analysis
+func (ctx *analysisContext) handleFileNode(node *ast.File) {
+ // Note: SQL builder analysis with type checking is done by Registry.Check() in handleCallExpr.
+ // The old analyzeSQLBuilders() function was removed because it didn't use type checking
+ // and caused false positives (issue #5).
- return nil, nil
+ if ctx.cfg.N1DetectionEnabled {
+ AnalyzeN1(ctx.pass, node)
+ }
+ if ctx.cfg.SQLInjectionDetectionEnabled {
+ AnalyzeSQLInjection(ctx.pass, node)
+ }
+ if ctx.cfg.TxLeakDetectionEnabled {
+ AnalyzeTxLeaks(ctx.pass, node)
+ }
}
-// run performs the main analysis of Go code files for SELECT * usage
-func run(pass *analysis.Pass) (any, error) {
- insp := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector)
-
- // Define AST node types we're interested in
- nodeFilter := []ast.Node{
- (*ast.CallExpr)(nil), // Function/method calls
- (*ast.File)(nil), // Files (for SQL builder analysis)
- (*ast.AssignStmt)(nil), // Assignment statements for standalone literals
- (*ast.GenDecl)(nil), // General declarations (const, var)
+// handleCallExpr processes function/method call expressions
+func (ctx *analysisContext) handleCallExpr(node *ast.CallExpr) {
+ if ctx.filter != nil && ctx.filter.IsIgnoredFunction(node) {
+ return
}
- // Always use default settings since passing settings through ResultOf doesn't work reliably
- defaultSettings := config.DefaultSettings()
- cfg := &defaultSettings
+ if ctx.cfg.CheckFormatStrings && CheckFormatFunction(ctx.pass, node, ctx.cfg) {
+ ctx.pass.Report(analysis.Diagnostic{
+ Pos: node.Pos(),
+ Message: getDetailedWarningMessage("format_string"),
+ })
+ return
+ }
- // Walk through all AST nodes and analyze them
- insp.Preorder(nodeFilter, func(n ast.Node) {
- switch node := n.(type) {
- case *ast.File:
- // Analyze SQL builders only if enabled in configuration
- if cfg.CheckSQLBuilders {
- analyzeSQLBuilders(pass, node)
- }
- case *ast.AssignStmt:
- // Check assignment statements for standalone SQL literals
- checkAssignStmt(pass, node, cfg)
- case *ast.GenDecl:
- // Check constant and variable declarations
- checkGenDecl(pass, node, cfg)
- case *ast.CallExpr:
- // Analyze function calls for SQL with SELECT * usage
- checkCallExpr(pass, node, cfg)
+ if ctx.builderRegistry != nil && ctx.builderRegistry.HasCheckers() {
+ violations := ctx.builderRegistry.Check(ctx.pass.TypesInfo, node)
+ for _, v := range violations {
+ ctx.pass.Report(analysis.Diagnostic{
+ Pos: v.Pos,
+ End: v.End,
+ Message: v.Message,
+ })
+ }
+ if len(violations) > 0 {
+ return
}
- })
+ }
- return nil, nil
+ checkCallExpr(ctx.pass, node, ctx.cfg)
+}
+
+// handleBinaryExpr processes binary expressions (string concatenation)
+func (ctx *analysisContext) handleBinaryExpr(node *ast.BinaryExpr) {
+ if ctx.cfg.CheckStringConcat && CheckConcatenation(ctx.pass, node, ctx.cfg) {
+ ctx.pass.Report(analysis.Diagnostic{
+ Pos: node.Pos(),
+ Message: getDetailedWarningMessage("concat"),
+ })
+ }
}
// checkAssignStmt checks assignment statements for standalone SQL literals
@@ -248,17 +235,9 @@ func checkGenDecl(pass *analysis.Pass, decl *ast.GenDecl, cfg *config.Unqueryvet
}
// checkCallExpr analyzes function calls for SQL with SELECT * usage
-// Includes checking arguments and SQL builders
+// Note: SQL builder checking with type verification is done by Registry.Check() in handleCallExpr.
+// This function only checks raw SQL strings in function arguments.
func checkCallExpr(pass *analysis.Pass, call *ast.CallExpr, cfg *config.UnqueryvetSettings) {
- // Check SQL builders for SELECT * in arguments
- if cfg.CheckSQLBuilders && isSQLBuilderSelectStar(call) {
- pass.Report(analysis.Diagnostic{
- Pos: call.Pos(),
- Message: getDetailedWarningMessage("sql_builder"),
- })
- return
- }
-
// Check function call arguments for strings with SELECT *
for _, arg := range call.Args {
if lit, ok := arg.(*ast.BasicLit); ok && lit.Kind == token.STRING {
@@ -416,150 +395,20 @@ func getDetailedWarningMessage(context string) string {
}
}
-// isSQLBuilderSelectStar checks SQL builder method calls for SELECT * usage
-func isSQLBuilderSelectStar(call *ast.CallExpr) bool {
- fun, ok := call.Fun.(*ast.SelectorExpr)
- if !ok {
+// IsRuleEnabledExported checks if a rule is enabled in the configuration.
+// A rule is enabled if it exists in the Rules map and its severity is not "ignore".
+func IsRuleEnabledExported(rules config.RuleSeverity, ruleID string) bool {
+ if rules == nil {
return false
}
-
- // Check that this is a Select method call
- if fun.Sel == nil || fun.Sel.Name != selectKeyword {
- return false
- }
-
- if len(call.Args) == 0 {
+ severity, exists := rules[ruleID]
+ if !exists {
return false
}
-
- // Check Select method arguments for "*" or empty strings
- for _, arg := range call.Args {
- if lit, ok := arg.(*ast.BasicLit); ok && lit.Kind == token.STRING {
- value := strings.Trim(lit.Value, "`\"")
- // Consider both "*" and empty strings in Select() as problematic
- if value == "*" || value == "" {
- return true
- }
- }
- }
-
- return false
-}
-
-// analyzeSQLBuilders performs advanced SQL builder analysis
-// Key logic for handling edge-cases like Select().Columns("*")
-func analyzeSQLBuilders(pass *analysis.Pass, file *ast.File) {
- // Track SQL builder variables and their state
- builderVars := make(map[string]*ast.CallExpr) // Variables with empty Select() calls
- hasColumns := make(map[string]bool) // Flag: were columns added for variable
-
- // First pass: find variables created with empty Select() calls
- ast.Inspect(file, func(n ast.Node) bool {
- switch node := n.(type) {
- case *ast.AssignStmt:
- // Analyze assignments like: query := builder.Select()
- for i, expr := range node.Rhs {
- if call, ok := expr.(*ast.CallExpr); ok {
- if isEmptySelectCall(call) {
- // Found empty Select() call, remember the variable
- if i < len(node.Lhs) {
- if ident, ok := node.Lhs[i].(*ast.Ident); ok {
- builderVars[ident.Name] = call
- hasColumns[ident.Name] = false
- }
- }
- }
- }
- }
- }
- return true
- })
-
- // Second pass: check usage of Columns/Column methods
- ast.Inspect(file, func(n ast.Node) bool {
- switch node := n.(type) {
- case *ast.CallExpr:
- if sel, ok := node.Fun.(*ast.SelectorExpr); ok {
- // Check calls to Columns() or Column() methods
- if sel.Sel != nil && (sel.Sel.Name == columnsKeyword || sel.Sel.Name == columnKeyword) {
- // Check for "*" in arguments
- if hasStarInColumns(node) {
- pass.Report(analysis.Diagnostic{
- Pos: node.Pos(),
- Message: getDetailedWarningMessage("sql_builder"),
- })
- }
-
- // Update variable state - columns were added
- if ident, ok := sel.X.(*ast.Ident); ok {
- if _, exists := builderVars[ident.Name]; exists {
- if !hasStarInColumns(node) {
- hasColumns[ident.Name] = true
- }
- }
- }
- }
- }
-
- // Check call chains like builder.Select().Columns("*")
- if isSelectWithColumns(node) {
- if hasStarInColumns(node) {
- if sel, ok := node.Fun.(*ast.SelectorExpr); ok && sel.Sel != nil {
- pass.Report(analysis.Diagnostic{
- Pos: node.Pos(),
- Message: getDetailedWarningMessage("sql_builder"),
- })
- }
- }
- return true
- }
- }
- return true
- })
-
- // Final check: warn about builders with empty Select() without subsequent columns
- for varName, call := range builderVars {
- if !hasColumns[varName] {
- pass.Report(analysis.Diagnostic{
- Pos: call.Pos(),
- Message: getDetailedWarningMessage("empty_select"),
- })
- }
- }
-}
-
-// isEmptySelectCall checks if call is an empty Select()
-func isEmptySelectCall(call *ast.CallExpr) bool {
- if sel, ok := call.Fun.(*ast.SelectorExpr); ok {
- if sel.Sel != nil && sel.Sel.Name == selectKeyword && len(call.Args) == 0 {
- return true
- }
- }
- return false
-}
-
-// isSelectWithColumns checks call chains like Select().Columns()
-func isSelectWithColumns(call *ast.CallExpr) bool {
- if sel, ok := call.Fun.(*ast.SelectorExpr); ok {
- if sel.Sel != nil && (sel.Sel.Name == columnsKeyword || sel.Sel.Name == columnKeyword) {
- // Check that previous call in chain is Select()
- if innerCall, ok := sel.X.(*ast.CallExpr); ok {
- return isEmptySelectCall(innerCall)
- }
- }
- }
- return false
+ return severity != "ignore"
}
-// hasStarInColumns checks if call arguments contain "*" symbol
-func hasStarInColumns(call *ast.CallExpr) bool {
- for _, arg := range call.Args {
- if lit, ok := arg.(*ast.BasicLit); ok && lit.Kind == token.STRING {
- value := strings.Trim(lit.Value, "`\"")
- if value == "*" {
- return true
- }
- }
- }
- return false
+// isRuleEnabled is an internal helper for checking rule enablement.
+func isRuleEnabled(rules config.RuleSeverity, ruleID string) bool {
+ return IsRuleEnabledExported(rules, ruleID)
}
diff --git a/vendor/github.com/MirrexOne/unqueryvet/internal/analyzer/format.go b/vendor/github.com/MirrexOne/unqueryvet/internal/analyzer/format.go
index 5fc827ed8..c96636706 100644
--- a/vendor/github.com/MirrexOne/unqueryvet/internal/analyzer/format.go
+++ b/vendor/github.com/MirrexOne/unqueryvet/internal/analyzer/format.go
@@ -15,39 +15,39 @@ import (
// Index -1 means the format string is the last argument (for variadic functions).
var formatFunctions = map[string]int{
// fmt package
- "fmt.Sprintf": 0,
- "fmt.Printf": 0,
- "fmt.Fprintf": 1, // first arg is io.Writer
- "fmt.Errorf": 0,
- "fmt.Fscanf": 1,
- "fmt.Sscanf": 1,
- "Sprintf": 0, // direct call after import
- "Printf": 0,
- "Errorf": 0,
+ "fmt.Sprintf": 0,
+ "fmt.Printf": 0,
+ "fmt.Fprintf": 1, // first arg is io.Writer
+ "fmt.Errorf": 0,
+ "fmt.Fscanf": 1,
+ "fmt.Sscanf": 1,
+ "Sprintf": 0, // direct call after import
+ "Printf": 0,
+ "Errorf": 0,
// log package
- "log.Printf": 0,
- "log.Fatalf": 0,
- "log.Panicf": 0,
- "log.Logf": 1, // first arg is log level
+ "log.Printf": 0,
+ "log.Fatalf": 0,
+ "log.Panicf": 0,
+ "log.Logf": 1, // first arg is log level
"Logger.Printf": 0,
- "Logger.Fatalf": 0,
- "Logger.Panicf": 0,
+ "Logger.Fatalf": 0,
+ "Logger.Panicf": 0,
// testing package
- "testing.T.Logf": 0,
- "testing.T.Errorf": 0,
- "testing.T.Fatalf": 0,
- "testing.T.Skipf": 0,
- "testing.B.Logf": 0,
- "testing.B.Errorf": 0,
- "testing.B.Fatalf": 0,
- "T.Logf": 0,
- "T.Errorf": 0,
- "T.Fatalf": 0,
- "B.Logf": 0,
- "B.Errorf": 0,
- "B.Fatalf": 0,
+ "testing.T.Logf": 0,
+ "testing.T.Errorf": 0,
+ "testing.T.Fatalf": 0,
+ "testing.T.Skipf": 0,
+ "testing.B.Logf": 0,
+ "testing.B.Errorf": 0,
+ "testing.B.Fatalf": 0,
+ "T.Logf": 0,
+ "T.Errorf": 0,
+ "T.Fatalf": 0,
+ "B.Logf": 0,
+ "B.Errorf": 0,
+ "B.Fatalf": 0,
// errors package
"errors.Errorf": 0,
@@ -57,26 +57,26 @@ var formatFunctions = map[string]int{
"errors.WithMessagef": 1,
// logrus
- "logrus.Infof": 0,
- "logrus.Warnf": 0,
- "logrus.Errorf": 0,
- "logrus.Debugf": 0,
- "logrus.Fatalf": 0,
- "logrus.Panicf": 0,
- "logrus.Tracef": 0,
- "logrus.Printf": 0,
- "Entry.Infof": 0,
- "Entry.Warnf": 0,
- "Entry.Errorf": 0,
- "Entry.Debugf": 0,
+ "logrus.Infof": 0,
+ "logrus.Warnf": 0,
+ "logrus.Errorf": 0,
+ "logrus.Debugf": 0,
+ "logrus.Fatalf": 0,
+ "logrus.Panicf": 0,
+ "logrus.Tracef": 0,
+ "logrus.Printf": 0,
+ "Entry.Infof": 0,
+ "Entry.Warnf": 0,
+ "Entry.Errorf": 0,
+ "Entry.Debugf": 0,
// zap
- "zap.S.Infof": 0,
- "zap.S.Warnf": 0,
- "zap.S.Errorf": 0,
- "zap.S.Debugf": 0,
- "zap.S.Fatalf": 0,
- "zap.S.Panicf": 0,
+ "zap.S.Infof": 0,
+ "zap.S.Warnf": 0,
+ "zap.S.Errorf": 0,
+ "zap.S.Debugf": 0,
+ "zap.S.Fatalf": 0,
+ "zap.S.Panicf": 0,
"SugaredLogger.Infof": 0,
"SugaredLogger.Warnf": 0,
"SugaredLogger.Errorf": 0,
diff --git a/vendor/github.com/MirrexOne/unqueryvet/internal/analyzer/n1detector.go b/vendor/github.com/MirrexOne/unqueryvet/internal/analyzer/n1detector.go
new file mode 100644
index 000000000..cf0331129
--- /dev/null
+++ b/vendor/github.com/MirrexOne/unqueryvet/internal/analyzer/n1detector.go
@@ -0,0 +1,546 @@
+package analyzer
+
+import (
+ "go/ast"
+ "go/token"
+ "strings"
+
+ "golang.org/x/tools/go/analysis"
+)
+
+// N1Detector detects potential N+1 query problems.
+// An N+1 query problem occurs when a SQL query is executed inside a loop,
+// causing one query per iteration instead of a single batch query.
+type N1Detector struct {
+ // loopDepth tracks how deeply nested we are in loops
+ loopDepth int
+ // queryMethods are method names that typically execute SQL queries
+ queryMethods map[string]bool
+ // ormMethods are ORM-specific methods that indicate queries
+ ormMethods map[string]bool
+ // transactionMethods are methods that indicate transaction usage
+ transactionMethods map[string]bool
+ // functionCallsInLoop tracks function calls made inside loops for indirect N+1 detection
+ functionCallsInLoop map[string]bool
+ // knownQueryFunctions are user-defined functions known to execute queries
+ knownQueryFunctions map[string]bool
+}
+
+// NewN1Detector creates a new N+1 query detector.
+func NewN1Detector() *N1Detector {
+ return &N1Detector{
+ queryMethods: map[string]bool{
+ // Standard database/sql
+ "Query": true,
+ "QueryRow": true,
+ "Exec": true,
+ "ExecContext": true,
+ "QueryContext": true,
+ "QueryRowContext": true,
+ // SQLx
+ "QueryRowx": true,
+ "Queryx": true,
+ "SelectContext": true,
+ "GetContext": true,
+ "NamedQuery": true,
+ "NamedQueryContext": true,
+ "NamedExec": true,
+ "NamedExecContext": true,
+ // General
+ "Select": true,
+ "Get": true,
+ "Find": true,
+ "First": true,
+ "Where": true,
+ "Raw": true,
+ },
+ ormMethods: map[string]bool{
+ // GORM
+ "Preload": true,
+ "Association": true,
+ "Related": true,
+ "Model": true,
+ "Table": true,
+ "Joins": true,
+ "InnerJoins": true,
+ "Pluck": true,
+ "Count": true,
+ "Take": true,
+ "Last": true,
+ "Scan": true,
+ "Row": true,
+ "Rows": true,
+ // Bun
+ "NewSelect": true,
+ "NewInsert": true,
+ "NewUpdate": true,
+ "NewDelete": true,
+ "Column": true,
+ "ColumnExpr": true,
+ "Relation": true,
+ // Ent
+ "Only": true,
+ "OnlyX": true,
+ "AllX": true,
+ "FirstX": true,
+ // SQLBoiler
+ "One": true,
+ "OneP": true,
+ "AllP": true,
+ "Exists": true,
+ "ExistsP": true,
+ // PGX
+ "SendBatch": true,
+ },
+ transactionMethods: map[string]bool{
+ "Begin": true,
+ "BeginTx": true,
+ "BeginTxx": true,
+ "Transaction": true,
+ "WithContext": true,
+ "RunInTransaction": true,
+ "Tx": true,
+ "NewTx": true,
+ },
+ functionCallsInLoop: make(map[string]bool),
+ knownQueryFunctions: make(map[string]bool),
+ }
+}
+
+// N1Severity represents the severity level of an N+1 violation.
+type N1Severity string
+
+const (
+ N1SeverityCritical N1Severity = "critical" // Direct query in loop
+ N1SeverityHigh N1Severity = "high" // ORM method in loop
+ N1SeverityMedium N1Severity = "medium" // Indirect query via function call
+ N1SeverityLow N1Severity = "low" // Potential issue, needs review
+)
+
+// N1Violation represents a detected N+1 query problem.
+type N1Violation struct {
+ Pos token.Pos
+ End token.Pos
+ Message string
+ LoopType string // "for", "range", or "while-like"
+ QueryType string // The method name that was called
+ Severity N1Severity // Severity level
+ Suggestion string // Suggested fix
+ IsIndirect bool // True if detected via function call
+ FunctionName string // Name of the function if indirect
+}
+
+// CheckN1Queries analyzes the file for N+1 query patterns.
+func (d *N1Detector) CheckN1Queries(pass *analysis.Pass, file *ast.File) []N1Violation {
+ var violations []N1Violation
+
+ ast.Inspect(file, func(n ast.Node) bool {
+ switch node := n.(type) {
+ case *ast.ForStmt:
+ // Entering a for loop
+ d.loopDepth++
+ defer func() { d.loopDepth-- }()
+
+ // Check the body for queries
+ if node.Body != nil {
+ violations = append(violations, d.checkBlockForQueries(pass, node.Body, "for")...)
+ }
+ return true
+
+ case *ast.RangeStmt:
+ // Entering a range loop
+ d.loopDepth++
+ defer func() { d.loopDepth-- }()
+
+ // Check the body for queries
+ if node.Body != nil {
+ violations = append(violations, d.checkBlockForQueries(pass, node.Body, "range")...)
+ }
+ return true
+ }
+ return true
+ })
+
+ return violations
+}
+
+// checkBlockForQueries checks a block statement for SQL query calls.
+func (d *N1Detector) checkBlockForQueries(pass *analysis.Pass, block *ast.BlockStmt, loopType string) []N1Violation {
+ var violations []N1Violation
+
+ ast.Inspect(block, func(n ast.Node) bool {
+ // Skip nested loops - they'll be handled separately
+ switch n.(type) {
+ case *ast.ForStmt, *ast.RangeStmt:
+ return false
+ }
+
+ call, ok := n.(*ast.CallExpr)
+ if !ok {
+ return true
+ }
+
+ methodName := d.getMethodName(call)
+ if methodName == "" {
+ return true
+ }
+
+ // Check 1: Direct query method call
+ if d.queryMethods[methodName] {
+ if v := d.checkDirectQueryCall(call, methodName, loopType); v != nil {
+ violations = append(violations, *v)
+ }
+ return true
+ }
+
+ // Check 2: ORM-specific method call
+ if d.ormMethods[methodName] {
+ if v := d.checkORMMethodCall(call, methodName, loopType); v != nil {
+ violations = append(violations, *v)
+ }
+ return true
+ }
+
+ // Check 3: Transaction method in loop (potential issue)
+ if d.transactionMethods[methodName] {
+ violations = append(violations, N1Violation{
+ Pos: call.Pos(),
+ End: call.End(),
+ Message: "transaction started inside loop - consider batching operations",
+ LoopType: loopType,
+ QueryType: methodName,
+ Severity: N1SeverityMedium,
+ Suggestion: "Move transaction outside the loop and batch operations, or use a single transaction for all iterations",
+ })
+ return true
+ }
+
+ // Check 4: Indirect query via function call
+ if v := d.checkIndirectQueryCall(call, methodName, loopType); v != nil {
+ violations = append(violations, *v)
+ }
+
+ return true
+ })
+
+ return violations
+}
+
+// checkDirectQueryCall checks for direct database query calls.
+func (d *N1Detector) checkDirectQueryCall(call *ast.CallExpr, methodName, loopType string) *N1Violation {
+ // Check if any argument contains SELECT or other SQL keywords
+ hasSQLKeyword := false
+ for _, arg := range call.Args {
+ if lit, ok := arg.(*ast.BasicLit); ok {
+ if lit.Kind == token.STRING {
+ value := strings.ToUpper(lit.Value)
+ if strings.Contains(value, "SELECT") || strings.Contains(value, "INSERT") ||
+ strings.Contains(value, "UPDATE") || strings.Contains(value, "DELETE") {
+ hasSQLKeyword = true
+ break
+ }
+ }
+ }
+ }
+
+ // Also check if it's a method on a database variable
+ if !hasSQLKeyword {
+ hasSQLKeyword = d.mightBeQueryCall(call)
+ }
+
+ if hasSQLKeyword {
+ return &N1Violation{
+ Pos: call.Pos(),
+ End: call.End(),
+ Message: n1Message(methodName, loopType),
+ LoopType: loopType,
+ QueryType: methodName,
+ Severity: N1SeverityCritical,
+ Suggestion: n1Suggestion(loopType),
+ }
+ }
+
+ return nil
+}
+
+// checkORMMethodCall checks for ORM-specific method calls that might cause N+1.
+func (d *N1Detector) checkORMMethodCall(call *ast.CallExpr, methodName, loopType string) *N1Violation {
+ // ORM methods like Preload, Association, Related are often N+1 sources
+ suspiciousMethods := map[string]bool{
+ "Preload": true,
+ "Association": true,
+ "Related": true,
+ "Relation": true,
+ }
+
+ if suspiciousMethods[methodName] {
+ return &N1Violation{
+ Pos: call.Pos(),
+ End: call.End(),
+ Message: "ORM relation loading inside loop: " + methodName + "() - this causes N+1 queries",
+ LoopType: loopType,
+ QueryType: methodName,
+ Severity: N1SeverityHigh,
+ Suggestion: "Use eager loading (Preload) before the loop, or fetch all related data in a single query with JOIN",
+ }
+ }
+
+ // Check for query execution methods
+ executionMethods := map[string]bool{
+ "Find": true, "First": true, "Take": true, "Last": true,
+ "One": true, "All": true, "Only": true, "Scan": true,
+ }
+
+ if executionMethods[methodName] && d.mightBeQueryCall(call) {
+ return &N1Violation{
+ Pos: call.Pos(),
+ End: call.End(),
+ Message: "ORM query execution inside loop: " + methodName + "() - potential N+1 problem",
+ LoopType: loopType,
+ QueryType: methodName,
+ Severity: N1SeverityHigh,
+ Suggestion: "Collect IDs first, then use WHERE IN clause or batch loading",
+ }
+ }
+
+ return nil
+}
+
+// checkIndirectQueryCall checks for function calls that might execute queries.
+func (d *N1Detector) checkIndirectQueryCall(call *ast.CallExpr, methodName, loopType string) *N1Violation {
+ // Check for suspicious function names that might contain queries
+ lowerName := strings.ToLower(methodName)
+ suspiciousPatterns := []string{
+ "get", "fetch", "find", "load", "query", "select",
+ "retrieve", "lookup", "read", "search",
+ }
+
+ for _, pattern := range suspiciousPatterns {
+ if strings.Contains(lowerName, pattern) {
+ // Check if it's called on a repository/store/dao object
+ if d.isRepositoryCall(call) {
+ return &N1Violation{
+ Pos: call.Pos(),
+ End: call.End(),
+ Message: "potential N+1: function " + methodName + "() called inside loop may execute database query",
+ LoopType: loopType,
+ QueryType: methodName,
+ Severity: N1SeverityMedium,
+ Suggestion: "Review this function - if it executes a query, consider batch loading or caching",
+ IsIndirect: true,
+ FunctionName: methodName,
+ }
+ }
+ }
+ }
+
+ return nil
+}
+
+// isRepositoryCall checks if the call is on a repository-like object.
+func (d *N1Detector) isRepositoryCall(call *ast.CallExpr) bool {
+ sel, ok := call.Fun.(*ast.SelectorExpr)
+ if !ok {
+ return false
+ }
+
+ if ident, ok := sel.X.(*ast.Ident); ok {
+ name := strings.ToLower(ident.Name)
+ repositoryPatterns := []string{
+ "repo", "repository", "store", "dao", "service",
+ "handler", "manager", "provider", "client",
+ }
+ for _, pattern := range repositoryPatterns {
+ if strings.Contains(name, pattern) {
+ return true
+ }
+ }
+ }
+
+ return false
+}
+
+// n1Suggestion generates a suggestion based on loop type.
+func n1Suggestion(loopType string) string {
+ switch loopType {
+ case "range":
+ return "Collect all IDs before the loop, then use a single query with IN clause:\n" +
+ " ids := make([]int, 0, len(items))\n" +
+ " for _, item := range items { ids = append(ids, item.ID) }\n" +
+ " db.Query(\"SELECT * FROM table WHERE id IN (?)\", ids)"
+ case "for":
+ return "Consider using batch query with IN clause or JOIN instead of querying in each iteration"
+ default:
+ return "Refactor to execute a single batch query instead of multiple queries in loop"
+ }
+}
+
+// getMethodName extracts the method name from a call expression.
+func (d *N1Detector) getMethodName(call *ast.CallExpr) string {
+ switch fun := call.Fun.(type) {
+ case *ast.SelectorExpr:
+ return fun.Sel.Name
+ case *ast.Ident:
+ return fun.Name
+ }
+ return ""
+}
+
+// mightBeQueryCall checks if a call might be a database query.
+func (d *N1Detector) mightBeQueryCall(call *ast.CallExpr) bool {
+ sel, ok := call.Fun.(*ast.SelectorExpr)
+ if !ok {
+ return false
+ }
+
+ // Check for common database variable names
+ if ident, ok := sel.X.(*ast.Ident); ok {
+ name := strings.ToLower(ident.Name)
+ return name == "db" || name == "conn" || name == "tx" ||
+ strings.Contains(name, "database") ||
+ strings.Contains(name, "repo") ||
+ strings.Contains(name, "store")
+ }
+
+ return false
+}
+
+// n1Message generates a helpful message for N+1 detection.
+func n1Message(methodName, loopType string) string {
+ suggestion := ""
+ switch loopType {
+ case "range":
+ suggestion = "Consider using a batch query with IN clause or JOIN"
+ case "for":
+ suggestion = "Consider collecting IDs first, then executing a single query with IN clause"
+ }
+
+ return "potential N+1 query: " + methodName + "() called inside loop - " + suggestion
+}
+
+// AnalyzeN1 is a convenience function to run N+1 detection on a file.
+func AnalyzeN1(pass *analysis.Pass, file *ast.File) {
+ detector := NewN1Detector()
+ violations := detector.CheckN1Queries(pass, file)
+
+ for _, v := range violations {
+ message := v.Message
+ if v.Suggestion != "" {
+ message += "\n Suggestion: " + v.Suggestion
+ }
+ if v.Severity != "" {
+ message = "[" + string(v.Severity) + "] " + message
+ }
+
+ pass.Report(analysis.Diagnostic{
+ Pos: v.Pos,
+ End: v.End,
+ Message: message,
+ })
+ }
+}
+
+// GetN1Violations returns all N+1 violations for external use.
+func GetN1Violations(pass *analysis.Pass, file *ast.File) []N1Violation {
+ detector := NewN1Detector()
+ return detector.CheckN1Queries(pass, file)
+}
+
+// CheckN1QueriesNoPass is a method to check for N+1 queries without analysis.Pass.
+// This is useful for testing.
+func (d *N1Detector) CheckN1QueriesNoPass(file *ast.File) []N1Violation {
+ return DetectN1InAST(nil, file)
+}
+
+// DetectN1InAST detects N+1 query problems in an AST file without analysis.Pass.
+// This is designed for use in LSP server where we don't have a full analysis pass.
+func DetectN1InAST(fset *token.FileSet, file *ast.File) []N1Violation {
+ detector := NewN1Detector()
+ var violations []N1Violation
+
+ ast.Inspect(file, func(n ast.Node) bool {
+ switch node := n.(type) {
+ case *ast.ForStmt:
+ detector.loopDepth++
+ defer func() { detector.loopDepth-- }()
+
+ if node.Body != nil {
+ violations = append(violations, detector.checkBlockForQueriesNoPass(node.Body, "for")...)
+ }
+ return true
+
+ case *ast.RangeStmt:
+ detector.loopDepth++
+ defer func() { detector.loopDepth-- }()
+
+ if node.Body != nil {
+ violations = append(violations, detector.checkBlockForQueriesNoPass(node.Body, "range")...)
+ }
+ return true
+ }
+ return true
+ })
+
+ return violations
+}
+
+// checkBlockForQueriesNoPass checks a block statement for SQL query calls without analysis.Pass.
+func (d *N1Detector) checkBlockForQueriesNoPass(block *ast.BlockStmt, loopType string) []N1Violation {
+ var violations []N1Violation
+
+ ast.Inspect(block, func(n ast.Node) bool {
+ switch n.(type) {
+ case *ast.ForStmt, *ast.RangeStmt:
+ return false
+ }
+
+ call, ok := n.(*ast.CallExpr)
+ if !ok {
+ return true
+ }
+
+ methodName := d.getMethodName(call)
+ if methodName == "" {
+ return true
+ }
+
+ // Check 1: Direct query method call
+ if d.queryMethods[methodName] {
+ if v := d.checkDirectQueryCall(call, methodName, loopType); v != nil {
+ violations = append(violations, *v)
+ }
+ return true
+ }
+
+ // Check 2: ORM-specific method call
+ if d.ormMethods[methodName] {
+ if v := d.checkORMMethodCall(call, methodName, loopType); v != nil {
+ violations = append(violations, *v)
+ }
+ return true
+ }
+
+ // Check 3: Transaction method in loop
+ if d.transactionMethods[methodName] {
+ violations = append(violations, N1Violation{
+ Pos: call.Pos(),
+ End: call.End(),
+ Message: "transaction started inside loop - consider batching operations",
+ LoopType: loopType,
+ QueryType: methodName,
+ Severity: N1SeverityMedium,
+ Suggestion: "Move transaction outside the loop and batch operations, or use a single transaction for all iterations",
+ })
+ return true
+ }
+
+ // Check 4: Indirect query via function call
+ if v := d.checkIndirectQueryCall(call, methodName, loopType); v != nil {
+ violations = append(violations, *v)
+ }
+
+ return true
+ })
+
+ return violations
+}
diff --git a/vendor/github.com/MirrexOne/unqueryvet/internal/analyzer/sqlbuilders/bun.go b/vendor/github.com/MirrexOne/unqueryvet/internal/analyzer/sqlbuilders/bun.go
index 62bd63bde..a25f559a1 100644
--- a/vendor/github.com/MirrexOne/unqueryvet/internal/analyzer/sqlbuilders/bun.go
+++ b/vendor/github.com/MirrexOne/unqueryvet/internal/analyzer/sqlbuilders/bun.go
@@ -4,9 +4,12 @@ package sqlbuilders
import (
"go/ast"
"go/token"
+ "go/types"
"strings"
)
+const bunPkgPath = "github.com/uptrace/bun"
+
// BunChecker checks github.com/uptrace/bun for SELECT * patterns.
type BunChecker struct{}
@@ -20,28 +23,15 @@ func (c *BunChecker) Name() string {
return "bun"
}
-// IsApplicable checks if the call might be from bun.
-func (c *BunChecker) IsApplicable(call *ast.CallExpr) bool {
+// IsApplicable checks if the call is from bun using type information.
+func (c *BunChecker) IsApplicable(info *types.Info, call *ast.CallExpr) bool {
sel, ok := call.Fun.(*ast.SelectorExpr)
if !ok {
return false
}
- // bun methods to check
- bunMethods := []string{
- "NewSelect", "NewInsert", "NewUpdate", "NewDelete",
- "Column", "ColumnExpr", "ExcludeColumn",
- "Model", "Scan", "Exec",
- "NewRaw", "Raw",
- }
-
- for _, method := range bunMethods {
- if sel.Sel.Name == method {
- return true
- }
- }
-
- return false
+ // Check if the receiver type is from bun package
+ return IsTypeFromPackage(info, sel.X, bunPkgPath)
}
// CheckSelectStar checks for SELECT * in bun calls.
diff --git a/vendor/github.com/MirrexOne/unqueryvet/internal/analyzer/sqlbuilders/ent.go b/vendor/github.com/MirrexOne/unqueryvet/internal/analyzer/sqlbuilders/ent.go
index f514bbb1c..c3f184894 100644
--- a/vendor/github.com/MirrexOne/unqueryvet/internal/analyzer/sqlbuilders/ent.go
+++ b/vendor/github.com/MirrexOne/unqueryvet/internal/analyzer/sqlbuilders/ent.go
@@ -3,8 +3,11 @@ package sqlbuilders
import (
"go/ast"
+ "go/types"
)
+const entPkgPath = "entgo.io/ent"
+
// EntChecker checks entgo.io/ent for SELECT * patterns.
type EntChecker struct{}
@@ -18,26 +21,15 @@ func (c *EntChecker) Name() string {
return "ent"
}
-// IsApplicable checks if the call might be from ent.
-func (c *EntChecker) IsApplicable(call *ast.CallExpr) bool {
+// IsApplicable checks if the call is from ent using type information.
+func (c *EntChecker) IsApplicable(info *types.Info, call *ast.CallExpr) bool {
sel, ok := call.Fun.(*ast.SelectorExpr)
if !ok {
return false
}
- // ent methods that could result in SELECT *
- entMethods := []string{
- "Query", "All", "Only", "OnlyX", "First", "FirstX",
- "QueryContext", "Select",
- }
-
- for _, method := range entMethods {
- if sel.Sel.Name == method {
- return true
- }
- }
-
- return false
+ // Check if the receiver type is from ent package
+ return IsTypeFromPackage(info, sel.X, entPkgPath)
}
// CheckSelectStar checks for SELECT * in ent calls.
diff --git a/vendor/github.com/MirrexOne/unqueryvet/internal/analyzer/sqlbuilders/goqu.go b/vendor/github.com/MirrexOne/unqueryvet/internal/analyzer/sqlbuilders/goqu.go
new file mode 100644
index 000000000..a923c1f19
--- /dev/null
+++ b/vendor/github.com/MirrexOne/unqueryvet/internal/analyzer/sqlbuilders/goqu.go
@@ -0,0 +1,120 @@
+package sqlbuilders
+
+import (
+ "go/ast"
+ "go/token"
+ "go/types"
+ "strings"
+)
+
+const goquPkgPath = "github.com/doug-martin/goqu"
+
+// GoquChecker checks for SELECT * in goqu queries.
+type GoquChecker struct{}
+
+// NewGoquChecker creates a new goqu checker.
+func NewGoquChecker() *GoquChecker {
+ return &GoquChecker{}
+}
+
+// Name returns the checker name.
+func (c *GoquChecker) Name() string {
+ return "goqu"
+}
+
+// IsApplicable checks if the call is from goqu using type information.
+func (c *GoquChecker) IsApplicable(info *types.Info, call *ast.CallExpr) bool {
+ sel, ok := call.Fun.(*ast.SelectorExpr)
+ if !ok {
+ return false
+ }
+
+ // Check if the receiver type is from goqu package
+ if IsTypeFromPackage(info, sel.X, goquPkgPath) {
+ return true
+ }
+
+ // Check for package-level function calls like goqu.From()
+ if ident, ok := sel.X.(*ast.Ident); ok {
+ if info != nil {
+ if obj := info.Uses[ident]; obj != nil {
+ if pkgName, ok := obj.(*types.PkgName); ok {
+ pkgPath := pkgName.Imported().Path()
+ if len(pkgPath) >= len(goquPkgPath) && pkgPath[:len(goquPkgPath)] == goquPkgPath {
+ return true
+ }
+ }
+ }
+ }
+ }
+
+ return false
+}
+
+// CheckSelectStar checks for SELECT * patterns in goqu.
+func (c *GoquChecker) CheckSelectStar(call *ast.CallExpr) *SelectStarViolation {
+ sel, ok := call.Fun.(*ast.SelectorExpr)
+ if !ok {
+ return nil
+ }
+
+ methodName := sel.Sel.Name
+
+ // goqu.From("table").SelectAll() - this selects all columns
+ if methodName == "SelectAll" {
+ return &SelectStarViolation{
+ Pos: call.Pos(),
+ End: call.End(),
+ Message: "goqu SelectAll() selects all columns - use Select() with explicit column names",
+ }
+ }
+
+ // goqu.From("table").Select("*")
+ if methodName == "Select" {
+ for _, arg := range call.Args {
+ if lit, ok := arg.(*ast.BasicLit); ok && lit.Kind == token.STRING {
+ value := strings.Trim(lit.Value, "`\"'")
+ if value == "*" {
+ return &SelectStarViolation{
+ Pos: lit.Pos(),
+ End: lit.End(),
+ Message: "goqu Select(\"*\") - specify columns explicitly",
+ }
+ }
+ }
+ }
+
+ // goqu.From("table").Select() without arguments also selects all
+ if len(call.Args) == 0 {
+ return &SelectStarViolation{
+ Pos: call.Pos(),
+ End: call.End(),
+ Message: "goqu Select() without arguments selects all columns",
+ }
+ }
+ }
+
+ return nil
+}
+
+// CheckChainedCalls checks chained method calls.
+func (c *GoquChecker) CheckChainedCalls(call *ast.CallExpr) []*SelectStarViolation {
+ var violations []*SelectStarViolation
+
+ // Walk up the chain
+ current := call
+ for current != nil {
+ if v := c.CheckSelectStar(current); v != nil {
+ violations = append(violations, v)
+ }
+
+ // Move to the receiver if it's also a call
+ sel, ok := current.Fun.(*ast.SelectorExpr)
+ if !ok {
+ break
+ }
+ current, _ = sel.X.(*ast.CallExpr)
+ }
+
+ return violations
+}
diff --git a/vendor/github.com/MirrexOne/unqueryvet/internal/analyzer/sqlbuilders/gorm.go b/vendor/github.com/MirrexOne/unqueryvet/internal/analyzer/sqlbuilders/gorm.go
index 1946ad252..6275eaf5e 100644
--- a/vendor/github.com/MirrexOne/unqueryvet/internal/analyzer/sqlbuilders/gorm.go
+++ b/vendor/github.com/MirrexOne/unqueryvet/internal/analyzer/sqlbuilders/gorm.go
@@ -4,9 +4,12 @@ package sqlbuilders
import (
"go/ast"
"go/token"
+ "go/types"
"strings"
)
+const gormPkgPath = "gorm.io/gorm"
+
// GORMChecker checks gorm.io/gorm for SELECT * patterns.
type GORMChecker struct{}
@@ -20,35 +23,15 @@ func (c *GORMChecker) Name() string {
return "gorm"
}
-// IsApplicable checks if the call might be from GORM.
-func (c *GORMChecker) IsApplicable(call *ast.CallExpr) bool {
+// IsApplicable checks if the call is from GORM using type information.
+func (c *GORMChecker) IsApplicable(info *types.Info, call *ast.CallExpr) bool {
sel, ok := call.Fun.(*ast.SelectorExpr)
if !ok {
return false
}
- // GORM methods to check
- gormMethods := []string{
- "Select", "Find", "First", "Last", "Take", "Scan",
- "Model", "Table", "Raw", "Exec", "Pluck",
- "Preload", "Joins", "Where", "Or", "Not",
- }
-
- for _, method := range gormMethods {
- if sel.Sel.Name == method {
- return true
- }
- }
-
- // Check for gorm package or DB type
- if ident, ok := sel.X.(*ast.Ident); ok {
- lowerName := strings.ToLower(ident.Name)
- if lowerName == "gorm" || lowerName == "db" {
- return true
- }
- }
-
- return false
+ // Check if the receiver type is from gorm package
+ return IsTypeFromPackage(info, sel.X, gormPkgPath)
}
// CheckSelectStar checks for SELECT * in GORM calls.
@@ -58,88 +41,84 @@ func (c *GORMChecker) CheckSelectStar(call *ast.CallExpr) *SelectStarViolation {
return nil
}
- methodName := sel.Sel.Name
-
- // Check db.Select("*")
- if methodName == "Select" {
- for _, arg := range call.Args {
- if lit, ok := arg.(*ast.BasicLit); ok && lit.Kind == token.STRING {
- value := strings.Trim(lit.Value, "`\"")
- if value == "*" {
- return &SelectStarViolation{
- Pos: call.Pos(),
- End: call.End(),
- Message: "GORM Select(\"*\") - explicitly specify columns",
- Builder: "gorm",
- Context: "explicit_star",
- }
- }
- // Check for SELECT * in raw SQL inside Select
- upperValue := strings.ToUpper(value)
- if strings.Contains(upperValue, "SELECT *") {
- return &SelectStarViolation{
- Pos: call.Pos(),
- End: call.End(),
- Message: "GORM Select() contains SELECT * - specify columns explicitly",
- Builder: "gorm",
- Context: "raw_select_star",
- }
- }
+ switch sel.Sel.Name {
+ case "Select":
+ return c.checkSelectMethod(call)
+ case "Raw":
+ return c.checkRawMethod(call, "GORM Raw() with SELECT * - specify columns explicitly")
+ case "Exec":
+ return c.checkRawMethod(call, "GORM Exec() with SELECT * - specify columns explicitly")
+ }
+
+ return nil
+}
+
+// checkSelectMethod checks db.Select() for star patterns
+func (c *GORMChecker) checkSelectMethod(call *ast.CallExpr) *SelectStarViolation {
+ for _, arg := range call.Args {
+ lit, ok := arg.(*ast.BasicLit)
+ if !ok || lit.Kind != token.STRING {
+ continue
+ }
+
+ value := strings.Trim(lit.Value, "`\"")
+ if value == "*" {
+ return &SelectStarViolation{
+ Pos: call.Pos(),
+ End: call.End(),
+ Message: "GORM Select(\"*\") - explicitly specify columns",
+ Builder: "gorm",
+ Context: "explicit_star",
}
}
- }
- // Check db.Raw("SELECT * FROM ...")
- if methodName == "Raw" {
- for _, arg := range call.Args {
- if lit, ok := arg.(*ast.BasicLit); ok && lit.Kind == token.STRING {
- value := strings.Trim(lit.Value, "`\"")
- upperValue := strings.ToUpper(value)
- if strings.Contains(upperValue, "SELECT *") {
- return &SelectStarViolation{
- Pos: call.Pos(),
- End: call.End(),
- Message: "GORM Raw() with SELECT * - specify columns explicitly",
- Builder: "gorm",
- Context: "raw_select_star",
- }
- }
+ if strings.Contains(strings.ToUpper(value), "SELECT *") {
+ return &SelectStarViolation{
+ Pos: call.Pos(),
+ End: call.End(),
+ Message: "GORM Select() contains SELECT * - specify columns explicitly",
+ Builder: "gorm",
+ Context: "raw_select_star",
}
}
}
+ return nil
+}
- // Check db.Exec("SELECT * FROM ...")
- if methodName == "Exec" {
- for _, arg := range call.Args {
- if lit, ok := arg.(*ast.BasicLit); ok && lit.Kind == token.STRING {
- value := strings.Trim(lit.Value, "`\"")
- upperValue := strings.ToUpper(value)
- if strings.Contains(upperValue, "SELECT *") {
- return &SelectStarViolation{
- Pos: call.Pos(),
- End: call.End(),
- Message: "GORM Exec() with SELECT * - specify columns explicitly",
- Builder: "gorm",
- Context: "raw_select_star",
- }
- }
+// checkRawMethod checks db.Raw() or db.Exec() for SELECT * patterns
+func (c *GORMChecker) checkRawMethod(call *ast.CallExpr, message string) *SelectStarViolation {
+ for _, arg := range call.Args {
+ lit, ok := arg.(*ast.BasicLit)
+ if !ok || lit.Kind != token.STRING {
+ continue
+ }
+
+ value := strings.Trim(lit.Value, "`\"")
+ if strings.Contains(strings.ToUpper(value), "SELECT *") {
+ return &SelectStarViolation{
+ Pos: call.Pos(),
+ End: call.End(),
+ Message: message,
+ Builder: "gorm",
+ Context: "raw_select_star",
}
}
}
-
return nil
}
// CheckChainedCalls checks method chains for SELECT * patterns.
+// gormChainState tracks state while traversing GORM call chain
+type gormChainState struct {
+ hasModel bool
+ hasSelect bool
+ modelCall *ast.CallExpr
+}
+
func (c *GORMChecker) CheckChainedCalls(call *ast.CallExpr) []*SelectStarViolation {
var violations []*SelectStarViolation
+ state := &gormChainState{}
- // Track chain state
- hasModel := false
- hasSelect := false
- var modelCall *ast.CallExpr
-
- // Traverse the call chain
current := call
for current != nil {
sel, ok := current.Fun.(*ast.SelectorExpr)
@@ -147,49 +126,10 @@ func (c *GORMChecker) CheckChainedCalls(call *ast.CallExpr) []*SelectStarViolati
break
}
- switch sel.Sel.Name {
- case "Model", "Table":
- hasModel = true
- modelCall = current
- case "Select":
- hasSelect = true
- // Check for "*" argument
- for _, arg := range current.Args {
- if lit, ok := arg.(*ast.BasicLit); ok && lit.Kind == token.STRING {
- value := strings.Trim(lit.Value, "`\"")
- if value == "*" {
- violations = append(violations, &SelectStarViolation{
- Pos: current.Pos(),
- End: current.End(),
- Message: "GORM Select(\"*\") in chain - specify columns explicitly",
- Builder: "gorm",
- Context: "chained_star",
- })
- }
- }
- }
- case "Find", "First", "Last", "Take", "Scan":
- // Terminal methods - check if we have Model without Select
- if hasModel && !hasSelect && modelCall != nil {
- violations = append(violations, &SelectStarViolation{
- Pos: modelCall.Pos(),
- End: current.End(),
- Message: "GORM Model() with Find/First without Select() defaults to SELECT *",
- Builder: "gorm",
- Context: "implicit_star",
- })
- }
- case "Preload":
- // Preload often uses SELECT * for eager loading - this is common but worth flagging
- if len(current.Args) > 0 {
- // Only flag if there's no second argument (no custom SQL)
- if len(current.Args) == 1 {
- // Could add a warning about Preload SELECT *
- }
- }
+ if v := c.processGormChainMethod(sel.Sel.Name, current, state); v != nil {
+ violations = append(violations, v)
}
- // Move to the next call in the chain
if innerCall, ok := sel.X.(*ast.CallExpr); ok {
current = innerCall
} else {
@@ -199,3 +139,52 @@ func (c *GORMChecker) CheckChainedCalls(call *ast.CallExpr) []*SelectStarViolati
return violations
}
+
+// processGormChainMethod processes a single method in the GORM call chain
+func (c *GORMChecker) processGormChainMethod(methodName string, current *ast.CallExpr, state *gormChainState) *SelectStarViolation {
+ switch methodName {
+ case "Model", "Table":
+ state.hasModel = true
+ state.modelCall = current
+ case "Select":
+ state.hasSelect = true
+ return c.checkGormSelectArgs(current)
+ case "Find", "First", "Last", "Take", "Scan":
+ return c.checkGormTerminalMethod(current, state)
+ }
+ return nil
+}
+
+// checkGormSelectArgs checks Select() arguments for "*"
+func (c *GORMChecker) checkGormSelectArgs(current *ast.CallExpr) *SelectStarViolation {
+ for _, arg := range current.Args {
+ lit, ok := arg.(*ast.BasicLit)
+ if !ok || lit.Kind != token.STRING {
+ continue
+ }
+ if strings.Trim(lit.Value, "`\"") == "*" {
+ return &SelectStarViolation{
+ Pos: current.Pos(),
+ End: current.End(),
+ Message: "GORM Select(\"*\") in chain - specify columns explicitly",
+ Builder: "gorm",
+ Context: "chained_star",
+ }
+ }
+ }
+ return nil
+}
+
+// checkGormTerminalMethod checks terminal methods (Find, First, etc.) for implicit SELECT *
+func (c *GORMChecker) checkGormTerminalMethod(current *ast.CallExpr, state *gormChainState) *SelectStarViolation {
+ if state.hasModel && !state.hasSelect && state.modelCall != nil {
+ return &SelectStarViolation{
+ Pos: state.modelCall.Pos(),
+ End: current.End(),
+ Message: "GORM Model() with Find/First without Select() defaults to SELECT *",
+ Builder: "gorm",
+ Context: "implicit_star",
+ }
+ }
+ return nil
+}
diff --git a/vendor/github.com/MirrexOne/unqueryvet/internal/analyzer/sqlbuilders/interface.go b/vendor/github.com/MirrexOne/unqueryvet/internal/analyzer/sqlbuilders/interface.go
index ba7646fb4..4670d6155 100644
--- a/vendor/github.com/MirrexOne/unqueryvet/internal/analyzer/sqlbuilders/interface.go
+++ b/vendor/github.com/MirrexOne/unqueryvet/internal/analyzer/sqlbuilders/interface.go
@@ -4,6 +4,7 @@ package sqlbuilders
import (
"go/ast"
"go/token"
+ "go/types"
"github.com/MirrexOne/unqueryvet/pkg/config"
)
@@ -28,8 +29,9 @@ type SQLBuilderChecker interface {
// Name returns the name of the SQL builder library
Name() string
- // IsApplicable checks if the call expression might be from this SQL builder
- IsApplicable(call *ast.CallExpr) bool
+ // IsApplicable checks if the call expression is from this SQL builder.
+ // It uses type information to verify the receiver type belongs to the correct package.
+ IsApplicable(info *types.Info, call *ast.CallExpr) bool
// CheckSelectStar checks a single call expression for SELECT * usage
CheckSelectStar(call *ast.CallExpr) *SelectStarViolation
@@ -74,17 +76,30 @@ func NewRegistry(cfg *config.SQLBuildersConfig) *Registry {
if cfg.Jet {
r.checkers = append(r.checkers, NewJetChecker())
}
+ if cfg.Sqlc {
+ r.checkers = append(r.checkers, NewSQLCChecker())
+ }
+ if cfg.Goqu {
+ r.checkers = append(r.checkers, NewGoquChecker())
+ }
+ if cfg.Rel {
+ r.checkers = append(r.checkers, NewRelChecker())
+ }
+ if cfg.Reform {
+ r.checkers = append(r.checkers, NewReformChecker())
+ }
return r
}
// Check analyzes a call expression against all registered checkers.
// Returns all violations found across all applicable checkers.
-func (r *Registry) Check(call *ast.CallExpr) []*SelectStarViolation {
+// The info parameter provides type information for accurate type checking.
+func (r *Registry) Check(info *types.Info, call *ast.CallExpr) []*SelectStarViolation {
var violations []*SelectStarViolation
for _, checker := range r.checkers {
- if !checker.IsApplicable(call) {
+ if !checker.IsApplicable(info, call) {
continue
}
@@ -105,3 +120,37 @@ func (r *Registry) Check(call *ast.CallExpr) []*SelectStarViolation {
func (r *Registry) HasCheckers() bool {
return len(r.checkers) > 0
}
+
+// IsTypeFromPackage checks if the type of an expression belongs to a package
+// with the given path prefix. This is used to verify that a method call
+// is actually from the expected SQL builder library.
+func IsTypeFromPackage(info *types.Info, expr ast.Expr, pkgPathPrefix string) bool {
+ if info == nil {
+ return false
+ }
+
+ typ := info.TypeOf(expr)
+ if typ == nil {
+ return false
+ }
+
+ return isTypeFromPackageRecursive(typ, pkgPathPrefix)
+}
+
+// isTypeFromPackageRecursive recursively checks if a type belongs to a package.
+func isTypeFromPackageRecursive(typ types.Type, pkgPathPrefix string) bool {
+ switch t := typ.(type) {
+ case *types.Named:
+ if obj := t.Obj(); obj != nil {
+ if pkg := obj.Pkg(); pkg != nil {
+ pkgPath := pkg.Path()
+ if len(pkgPath) >= len(pkgPathPrefix) && pkgPath[:len(pkgPathPrefix)] == pkgPathPrefix {
+ return true
+ }
+ }
+ }
+ case *types.Pointer:
+ return isTypeFromPackageRecursive(t.Elem(), pkgPathPrefix)
+ }
+ return false
+}
diff --git a/vendor/github.com/MirrexOne/unqueryvet/internal/analyzer/sqlbuilders/jet.go b/vendor/github.com/MirrexOne/unqueryvet/internal/analyzer/sqlbuilders/jet.go
index ff5f123de..9e28021be 100644
--- a/vendor/github.com/MirrexOne/unqueryvet/internal/analyzer/sqlbuilders/jet.go
+++ b/vendor/github.com/MirrexOne/unqueryvet/internal/analyzer/sqlbuilders/jet.go
@@ -4,9 +4,13 @@ package sqlbuilders
import (
"go/ast"
"go/token"
+ "go/types"
+ "slices"
"strings"
)
+const jetPkgPath = "github.com/go-jet/jet"
+
// JetChecker checks github.com/go-jet/jet for SELECT * patterns.
type JetChecker struct{}
@@ -20,81 +24,70 @@ func (c *JetChecker) Name() string {
return "jet"
}
-// IsApplicable checks if the call might be from jet.
-func (c *JetChecker) IsApplicable(call *ast.CallExpr) bool {
+// IsApplicable checks if the call is from jet using type information.
+func (c *JetChecker) IsApplicable(info *types.Info, call *ast.CallExpr) bool {
sel, ok := call.Fun.(*ast.SelectorExpr)
if !ok {
- // Check for direct SELECT call
+ // Check for direct SELECT call - verify via type info
if ident, ok := call.Fun.(*ast.Ident); ok {
- return ident.Name == "SELECT" || ident.Name == "RawStatement"
+ if info != nil {
+ if obj := info.Uses[ident]; obj != nil {
+ if pkg := obj.Pkg(); pkg != nil {
+ pkgPath := pkg.Path()
+ if len(pkgPath) >= len(jetPkgPath) && pkgPath[:len(jetPkgPath)] == jetPkgPath {
+ return true
+ }
+ }
+ }
+ }
}
return false
}
- // jet methods to check
- jetMethods := []string{
- "SELECT", "FROM", "WHERE",
- "AllColumns", "Star",
- "RawStatement", "Raw",
- }
-
- for _, method := range jetMethods {
- if sel.Sel.Name == method {
- return true
- }
- }
-
- return false
+ // Check if the receiver type is from jet package
+ return IsTypeFromPackage(info, sel.X, jetPkgPath)
}
// CheckSelectStar checks for SELECT * in jet calls.
func (c *JetChecker) CheckSelectStar(call *ast.CallExpr) *SelectStarViolation {
- // Check for direct SELECT function call
+ // Check for direct function calls (SELECT, RawStatement)
if ident, ok := call.Fun.(*ast.Ident); ok {
- if ident.Name == "SELECT" {
- // Check arguments for AllColumns or STAR
- for _, arg := range call.Args {
- if c.isAllColumnsOrStar(arg) {
- return &SelectStarViolation{
- Pos: call.Pos(),
- End: call.End(),
- Message: "Jet SELECT with AllColumns/STAR - specify columns explicitly",
- Builder: "jet",
- Context: "explicit_star",
- }
- }
- }
- }
+ return c.checkIdentCall(call, ident)
+ }
- if ident.Name == "RawStatement" {
- // Check for SELECT * in raw statement
- for _, arg := range call.Args {
- if lit, ok := arg.(*ast.BasicLit); ok && lit.Kind == token.STRING {
- value := strings.Trim(lit.Value, "`\"")
- upperValue := strings.ToUpper(value)
- if strings.Contains(upperValue, "SELECT *") {
- return &SelectStarViolation{
- Pos: call.Pos(),
- End: call.End(),
- Message: "Jet RawStatement with SELECT * - specify columns explicitly",
- Builder: "jet",
- Context: "raw_select_star",
- }
- }
- }
- }
- }
+ // Check for selector calls (table.AllColumns, pkg.Star, etc.)
+ if sel, ok := call.Fun.(*ast.SelectorExpr); ok {
+ return c.checkSelectorCall(call, sel)
}
- sel, ok := call.Fun.(*ast.SelectorExpr)
- if !ok {
- return nil
+ return nil
+}
+
+// checkIdentCall handles direct function calls like SELECT() or RawStatement()
+func (c *JetChecker) checkIdentCall(call *ast.CallExpr, ident *ast.Ident) *SelectStarViolation {
+ switch ident.Name {
+ case "SELECT":
+ if slices.ContainsFunc(call.Args, c.isAllColumnsOrStar) {
+ return &SelectStarViolation{
+ Pos: call.Pos(),
+ End: call.End(),
+ Message: "Jet SELECT with AllColumns/STAR - specify columns explicitly",
+ Builder: "jet",
+ Context: "explicit_star",
+ }
+ }
+ case "RawStatement":
+ return c.checkRawStatementArgs(call, "Jet RawStatement with SELECT * - specify columns explicitly")
}
+ return nil
+}
+// checkSelectorCall handles selector calls like table.AllColumns or pkg.Star
+func (c *JetChecker) checkSelectorCall(call *ast.CallExpr, sel *ast.SelectorExpr) *SelectStarViolation {
methodName := sel.Sel.Name
- // Check for table.AllColumns
- if methodName == "AllColumns" {
+ switch methodName {
+ case "AllColumns":
return &SelectStarViolation{
Pos: call.Pos(),
End: call.End(),
@@ -102,10 +95,7 @@ func (c *JetChecker) CheckSelectStar(call *ast.CallExpr) *SelectStarViolation {
Builder: "jet",
Context: "all_columns",
}
- }
-
- // Check for STAR constant usage
- if methodName == "Star" {
+ case "Star":
return &SelectStarViolation{
Pos: call.Pos(),
End: call.End(),
@@ -113,27 +103,29 @@ func (c *JetChecker) CheckSelectStar(call *ast.CallExpr) *SelectStarViolation {
Builder: "jet",
Context: "explicit_star",
}
+ case "RawStatement", "Raw":
+ return c.checkRawStatementArgs(call, "Jet Raw/RawStatement with SELECT * - specify columns explicitly")
}
- // Check RawStatement
- if methodName == "RawStatement" || methodName == "Raw" {
- for _, arg := range call.Args {
- if lit, ok := arg.(*ast.BasicLit); ok && lit.Kind == token.STRING {
- value := strings.Trim(lit.Value, "`\"")
- upperValue := strings.ToUpper(value)
- if strings.Contains(upperValue, "SELECT *") {
- return &SelectStarViolation{
- Pos: call.Pos(),
- End: call.End(),
- Message: "Jet Raw/RawStatement with SELECT * - specify columns explicitly",
- Builder: "jet",
- Context: "raw_select_star",
- }
+ return nil
+}
+
+// checkRawStatementArgs checks for SELECT * in raw statement arguments
+func (c *JetChecker) checkRawStatementArgs(call *ast.CallExpr, message string) *SelectStarViolation {
+ for _, arg := range call.Args {
+ if lit, ok := arg.(*ast.BasicLit); ok && lit.Kind == token.STRING {
+ value := strings.Trim(lit.Value, "`\"")
+ if strings.Contains(strings.ToUpper(value), "SELECT *") {
+ return &SelectStarViolation{
+ Pos: call.Pos(),
+ End: call.End(),
+ Message: message,
+ Builder: "jet",
+ Context: "raw_select_star",
}
}
}
}
-
return nil
}
diff --git a/vendor/github.com/MirrexOne/unqueryvet/internal/analyzer/sqlbuilders/pgx.go b/vendor/github.com/MirrexOne/unqueryvet/internal/analyzer/sqlbuilders/pgx.go
index 9b44fc156..394cd6596 100644
--- a/vendor/github.com/MirrexOne/unqueryvet/internal/analyzer/sqlbuilders/pgx.go
+++ b/vendor/github.com/MirrexOne/unqueryvet/internal/analyzer/sqlbuilders/pgx.go
@@ -4,9 +4,12 @@ package sqlbuilders
import (
"go/ast"
"go/token"
+ "go/types"
"strings"
)
+const pgxPkgPath = "github.com/jackc/pgx"
+
// PGXChecker checks github.com/jackc/pgx for SELECT * patterns.
type PGXChecker struct{}
@@ -20,27 +23,15 @@ func (c *PGXChecker) Name() string {
return "pgx"
}
-// IsApplicable checks if the call might be from pgx.
-func (c *PGXChecker) IsApplicable(call *ast.CallExpr) bool {
+// IsApplicable checks if the call is from pgx using type information.
+func (c *PGXChecker) IsApplicable(info *types.Info, call *ast.CallExpr) bool {
sel, ok := call.Fun.(*ast.SelectorExpr)
if !ok {
return false
}
- // pgx methods that take SQL queries
- pgxMethods := []string{
- "Query", "QueryRow", "QueryFunc",
- "Exec", "SendBatch",
- "Prepare", "CopyFrom",
- }
-
- for _, method := range pgxMethods {
- if sel.Sel.Name == method {
- return true
- }
- }
-
- return false
+ // Check if the receiver type is from pgx package
+ return IsTypeFromPackage(info, sel.X, pgxPkgPath)
}
// CheckSelectStar checks for SELECT * in pgx calls.
@@ -53,18 +44,15 @@ func (c *PGXChecker) CheckSelectStar(call *ast.CallExpr) *SelectStarViolation {
methodName := sel.Sel.Name
// pgx methods where the SQL query is typically the second argument (after context)
- queryArgIndex := 1
+ // conn.Query(ctx, sql, args...), conn.QueryFunc(ctx, sql, args, func...)
switch methodName {
- case "Query", "QueryRow", "Exec", "Prepare":
- // conn.Query(ctx, sql, args...)
- queryArgIndex = 1
- case "QueryFunc":
- // conn.QueryFunc(ctx, sql, args, func...)
- queryArgIndex = 1
+ case "Query", "QueryRow", "Exec", "Prepare", "QueryFunc":
+ // supported methods
default:
return nil
}
+ const queryArgIndex = 1
if queryArgIndex >= len(call.Args) {
return nil
}
diff --git a/vendor/github.com/MirrexOne/unqueryvet/internal/analyzer/sqlbuilders/reform.go b/vendor/github.com/MirrexOne/unqueryvet/internal/analyzer/sqlbuilders/reform.go
new file mode 100644
index 000000000..ff7a139c0
--- /dev/null
+++ b/vendor/github.com/MirrexOne/unqueryvet/internal/analyzer/sqlbuilders/reform.go
@@ -0,0 +1,238 @@
+package sqlbuilders
+
+import (
+ "go/ast"
+ "go/token"
+ "go/types"
+ "strings"
+
+ "golang.org/x/tools/go/analysis"
+)
+
+const reformPkgPath = "gopkg.in/reform.v1"
+
+// ReformChecker detects SELECT * patterns in gopkg.in/reform.v1 queries.
+// https://github.com/go-reform/reform
+type ReformChecker struct{}
+
+// NewReformChecker creates a new reform checker.
+func NewReformChecker() *ReformChecker {
+ return &ReformChecker{}
+}
+
+// Name returns the name of the SQL builder.
+func (c *ReformChecker) Name() string {
+ return "reform"
+}
+
+// IsApplicable checks if the call is from reform using type information.
+func (c *ReformChecker) IsApplicable(info *types.Info, call *ast.CallExpr) bool {
+ sel, ok := call.Fun.(*ast.SelectorExpr)
+ if !ok {
+ return false
+ }
+
+ // Check if the receiver type is from reform package
+ return IsTypeFromPackage(info, sel.X, reformPkgPath)
+}
+
+// CheckSelectStar checks a single call expression for SELECT * usage.
+func (c *ReformChecker) CheckSelectStar(call *ast.CallExpr) *SelectStarViolation {
+ v := c.checkCall(call)
+ if v == nil {
+ return nil
+ }
+
+ return &SelectStarViolation{
+ Pos: v.Pos,
+ End: v.End,
+ Message: v.Message,
+ Builder: "reform",
+ Context: v.Method,
+ }
+}
+
+// CheckChainedCalls analyzes method chains for SELECT * patterns.
+func (c *ReformChecker) CheckChainedCalls(call *ast.CallExpr) []*SelectStarViolation {
+ // reform doesn't typically use method chaining for SELECT *
+ return nil
+}
+
+// Check analyzes a file for reform SELECT * patterns.
+func (c *ReformChecker) Check(pass *analysis.Pass, file *ast.File) {
+ ast.Inspect(file, func(n ast.Node) bool {
+ call, ok := n.(*ast.CallExpr)
+ if !ok {
+ return true
+ }
+
+ if v := c.checkCall(call); v != nil {
+ pass.Report(analysis.Diagnostic{
+ Pos: v.Pos,
+ End: v.End,
+ Message: v.Message,
+ })
+ }
+
+ return true
+ })
+}
+
+// ReformViolation represents a reform SELECT * violation.
+type ReformViolation struct {
+ Pos token.Pos
+ End token.Pos
+ Message string
+ Method string
+}
+
+// checkCall checks a call expression for reform SELECT * patterns.
+func (c *ReformChecker) checkCall(call *ast.CallExpr) *ReformViolation {
+ sel, ok := call.Fun.(*ast.SelectorExpr)
+ if !ok {
+ return nil
+ }
+
+ method := sel.Sel.Name
+
+ // reform patterns that load all columns:
+ // - db.FindByPrimaryKeyFrom(table, pk, &record)
+ // - db.FindOneFrom(table, column, value, &record)
+ // - db.FindAllFrom(table, column, values...)
+ // - db.SelectOneFrom(table, tail, args...) - if tail doesn't specify columns
+ // - db.SelectAllFrom(table, tail, args...) - if tail doesn't specify columns
+ // - querier.SelectRows(tail, args...) - may need column specification
+
+ switch method {
+ case "FindByPrimaryKeyFrom", "FindOneFrom", "FindAllFrom":
+ // These methods always load all columns
+ if c.isReformDB(sel.X) {
+ return &ReformViolation{
+ Pos: call.Pos(),
+ End: call.End(),
+ Message: "reform: " + method + " loads all columns - consider using SelectAllFrom with specific columns",
+ Method: method,
+ }
+ }
+
+ case "SelectOneFrom", "SelectAllFrom":
+ // Check if the tail argument specifies columns
+ if c.isReformDB(sel.X) && !c.hasColumnSpecification(call) {
+ return &ReformViolation{
+ Pos: call.Pos(),
+ End: call.End(),
+ Message: "reform: " + method + " should specify columns in the tail argument",
+ Method: method,
+ }
+ }
+
+ case "SelectRows":
+ // Check querier.SelectRows
+ if c.isQuerier(sel.X) && !c.hasSelectClause(call) {
+ return &ReformViolation{
+ Pos: call.Pos(),
+ End: call.End(),
+ Message: "reform: SelectRows query may select all columns - verify column specification",
+ Method: method,
+ }
+ }
+ }
+
+ return nil
+}
+
+// isReformDB checks if the expression is a reform DB.
+func (c *ReformChecker) isReformDB(expr ast.Expr) bool {
+ if ident, ok := expr.(*ast.Ident); ok {
+ name := ident.Name
+ return name == "db" || name == "DB" || name == "querier" ||
+ name == "tx" || name == "Tx"
+ }
+
+ if sel, ok := expr.(*ast.SelectorExpr); ok {
+ return sel.Sel.Name == "DB" || sel.Sel.Name == "Querier"
+ }
+
+ return false
+}
+
+// isQuerier checks if the expression is a reform Querier.
+func (c *ReformChecker) isQuerier(expr ast.Expr) bool {
+ if ident, ok := expr.(*ast.Ident); ok {
+ name := ident.Name
+ return name == "querier" || name == "q" || name == "db" || name == "tx"
+ }
+
+ return false
+}
+
+// hasColumnSpecification checks if the call specifies columns.
+func (c *ReformChecker) hasColumnSpecification(call *ast.CallExpr) bool {
+ // The tail argument (usually second) should specify columns
+ // e.g., "WHERE id = ? ORDER BY name" doesn't specify columns
+ // but "id, name WHERE id = ?" does
+
+ // Find the tail argument (string)
+ for _, arg := range call.Args {
+ if lit, ok := arg.(*ast.BasicLit); ok && lit.Kind == token.STRING {
+ tail := strings.Trim(lit.Value, "`\"")
+ tailUpper := strings.ToUpper(tail)
+
+ // Check if tail starts with column names (not WHERE, ORDER BY, etc.)
+ if strings.HasPrefix(tailUpper, "WHERE") ||
+ strings.HasPrefix(tailUpper, "ORDER") ||
+ strings.HasPrefix(tailUpper, "LIMIT") ||
+ strings.HasPrefix(tailUpper, "GROUP") ||
+ strings.HasPrefix(tailUpper, "HAVING") ||
+ tail == "" {
+ return false
+ }
+
+ // If it doesn't start with common clauses, assume it has columns
+ return true
+ }
+ }
+
+ return false
+}
+
+// hasSelectClause checks if a SelectRows call has a proper SELECT clause.
+func (c *ReformChecker) hasSelectClause(call *ast.CallExpr) bool {
+ for _, arg := range call.Args {
+ if lit, ok := arg.(*ast.BasicLit); ok && lit.Kind == token.STRING {
+ query := strings.ToUpper(strings.Trim(lit.Value, "`\""))
+
+ // Check if query has SELECT with specific columns (not *)
+ if strings.Contains(query, "SELECT") {
+ if strings.Contains(query, "SELECT *") ||
+ strings.Contains(query, "SELECT\t*") ||
+ strings.Contains(query, "SELECT\n*") {
+ return false
+ }
+ return true
+ }
+ }
+ }
+
+ return false
+}
+
+// CheckFile checks a file and returns violations.
+func (c *ReformChecker) CheckFile(file *ast.File, fset *token.FileSet) []ReformViolation {
+ var violations []ReformViolation
+
+ ast.Inspect(file, func(n ast.Node) bool {
+ call, ok := n.(*ast.CallExpr)
+ if !ok {
+ return true
+ }
+
+ if v := c.checkCall(call); v != nil {
+ violations = append(violations, *v)
+ }
+
+ return true
+ })
+
+ return violations
+}
diff --git a/vendor/github.com/MirrexOne/unqueryvet/internal/analyzer/sqlbuilders/rel.go b/vendor/github.com/MirrexOne/unqueryvet/internal/analyzer/sqlbuilders/rel.go
new file mode 100644
index 000000000..bf98bc8b9
--- /dev/null
+++ b/vendor/github.com/MirrexOne/unqueryvet/internal/analyzer/sqlbuilders/rel.go
@@ -0,0 +1,227 @@
+package sqlbuilders
+
+import (
+ "go/ast"
+ "go/token"
+ "go/types"
+
+ "golang.org/x/tools/go/analysis"
+)
+
+const relPkgPath = "github.com/go-rel/rel"
+
+// RelChecker detects SELECT * patterns in go-rel/rel queries.
+// https://github.com/go-rel/rel
+type RelChecker struct{}
+
+// NewRelChecker creates a new rel checker.
+func NewRelChecker() *RelChecker {
+ return &RelChecker{}
+}
+
+// Name returns the name of the SQL builder.
+func (c *RelChecker) Name() string {
+ return "rel"
+}
+
+// IsApplicable checks if the call is from rel using type information.
+func (c *RelChecker) IsApplicable(info *types.Info, call *ast.CallExpr) bool {
+ sel, ok := call.Fun.(*ast.SelectorExpr)
+ if !ok {
+ return false
+ }
+
+ // Check if the receiver type is from rel package
+ return IsTypeFromPackage(info, sel.X, relPkgPath)
+}
+
+// CheckSelectStar checks a single call expression for SELECT * usage.
+func (c *RelChecker) CheckSelectStar(call *ast.CallExpr) *SelectStarViolation {
+ if !c.isSelectAllPattern(call) {
+ return nil
+ }
+
+ sel := call.Fun.(*ast.SelectorExpr)
+ return &SelectStarViolation{
+ Pos: call.Pos(),
+ End: call.End(),
+ Message: "rel: query loads all columns - consider using Select() to specify columns",
+ Builder: "rel",
+ Context: sel.Sel.Name,
+ }
+}
+
+// CheckChainedCalls analyzes method chains for SELECT * patterns.
+func (c *RelChecker) CheckChainedCalls(call *ast.CallExpr) []*SelectStarViolation {
+ // rel doesn't typically use method chaining for SELECT *
+ return nil
+}
+
+// Check analyzes a file for rel SELECT * patterns.
+func (c *RelChecker) Check(pass *analysis.Pass, file *ast.File) {
+ ast.Inspect(file, func(n ast.Node) bool {
+ call, ok := n.(*ast.CallExpr)
+ if !ok {
+ return true
+ }
+
+ // Check for rel patterns that load all columns
+ if c.isSelectAllPattern(call) {
+ pass.Report(analysis.Diagnostic{
+ Pos: call.Pos(),
+ End: call.End(),
+ Message: "rel: query loads all columns - consider using Select() to specify columns",
+ })
+ }
+
+ return true
+ })
+}
+
+// isSelectAllPattern checks if a call represents a SELECT * pattern in rel.
+func (c *RelChecker) isSelectAllPattern(call *ast.CallExpr) bool {
+ sel, ok := call.Fun.(*ast.SelectorExpr)
+ if !ok {
+ return false
+ }
+
+ method := sel.Sel.Name
+
+ // rel patterns that load all columns by default:
+ // - repo.Find(ctx, &user) - loads all columns
+ // - repo.FindAll(ctx, &users) - loads all columns
+ // - repo.FindAndCountAll(ctx, &users) - loads all columns
+ // - rel.From("users").All(ctx, &users) - loads all columns without Select()
+
+ switch method {
+ case "Find", "FindAll", "FindAndCountAll":
+ // These methods load all columns unless combined with Select()
+ // Check if this is a call on a rel repository
+ if c.isRelRepository(sel.X) {
+ // Check if the query chain includes Select()
+ if !c.hasSelectInChain(call) {
+ return true
+ }
+ }
+
+ case "All", "One":
+ // Check if this is part of a query builder chain without Select()
+ if c.isQueryBuilderWithoutSelect(sel.X) {
+ return true
+ }
+ }
+
+ return false
+}
+
+// isRelRepository checks if the expression is a rel repository.
+func (c *RelChecker) isRelRepository(expr ast.Expr) bool {
+ // Check for common rel repository variable names
+ if ident, ok := expr.(*ast.Ident); ok {
+ name := ident.Name
+ return name == "repo" || name == "repository" ||
+ name == "r" || name == "db"
+ }
+
+ // Check for selector on repo
+ if sel, ok := expr.(*ast.SelectorExpr); ok {
+ return c.isRelRepository(sel.X)
+ }
+
+ return false
+}
+
+// hasSelectInChain checks if Select() is used in the query chain.
+func (c *RelChecker) hasSelectInChain(call *ast.CallExpr) bool {
+ // Walk up the chain looking for Select()
+ current := call.Fun
+ for {
+ sel, ok := current.(*ast.SelectorExpr)
+ if !ok {
+ break
+ }
+
+ if sel.Sel.Name == "Select" {
+ return true
+ }
+
+ // Check if the receiver is a call expression (method chain)
+ if callExpr, ok := sel.X.(*ast.CallExpr); ok {
+ if innerSel, ok := callExpr.Fun.(*ast.SelectorExpr); ok {
+ if innerSel.Sel.Name == "Select" {
+ return true
+ }
+ }
+ current = callExpr.Fun
+ } else {
+ break
+ }
+ }
+
+ return false
+}
+
+// isQueryBuilderWithoutSelect checks if an expression is a query builder without Select().
+func (c *RelChecker) isQueryBuilderWithoutSelect(expr ast.Expr) bool {
+ // Walk the call chain looking for From() without Select()
+ hasFrom := false
+ hasSelect := false
+
+ current := expr
+ for {
+ call, ok := current.(*ast.CallExpr)
+ if !ok {
+ break
+ }
+
+ sel, ok := call.Fun.(*ast.SelectorExpr)
+ if !ok {
+ break
+ }
+
+ switch sel.Sel.Name {
+ case "From":
+ hasFrom = true
+ case "Select":
+ hasSelect = true
+ }
+
+ current = sel.X
+ }
+
+ return hasFrom && !hasSelect
+}
+
+// RelViolation represents a rel SELECT * violation.
+type RelViolation struct {
+ Pos token.Pos
+ End token.Pos
+ Message string
+ Method string
+}
+
+// CheckFile checks a file and returns violations.
+func (c *RelChecker) CheckFile(file *ast.File, fset *token.FileSet) []RelViolation {
+ var violations []RelViolation
+
+ ast.Inspect(file, func(n ast.Node) bool {
+ call, ok := n.(*ast.CallExpr)
+ if !ok {
+ return true
+ }
+
+ if c.isSelectAllPattern(call) {
+ sel := call.Fun.(*ast.SelectorExpr)
+ violations = append(violations, RelViolation{
+ Pos: call.Pos(),
+ End: call.End(),
+ Message: "rel: query loads all columns - consider using Select()",
+ Method: sel.Sel.Name,
+ })
+ }
+
+ return true
+ })
+
+ return violations
+}
diff --git a/vendor/github.com/MirrexOne/unqueryvet/internal/analyzer/sqlbuilders/sqlboiler.go b/vendor/github.com/MirrexOne/unqueryvet/internal/analyzer/sqlbuilders/sqlboiler.go
index f4394c602..1ecbe1e3d 100644
--- a/vendor/github.com/MirrexOne/unqueryvet/internal/analyzer/sqlbuilders/sqlboiler.go
+++ b/vendor/github.com/MirrexOne/unqueryvet/internal/analyzer/sqlbuilders/sqlboiler.go
@@ -4,9 +4,12 @@ package sqlbuilders
import (
"go/ast"
"go/token"
+ "go/types"
"strings"
)
+const sqlboilerPkgPath = "github.com/volatiletech/sqlboiler"
+
// SQLBoilerChecker checks github.com/volatiletech/sqlboiler for SELECT * patterns.
type SQLBoilerChecker struct{}
@@ -20,29 +23,30 @@ func (c *SQLBoilerChecker) Name() string {
return "sqlboiler"
}
-// IsApplicable checks if the call might be from sqlboiler.
-func (c *SQLBoilerChecker) IsApplicable(call *ast.CallExpr) bool {
+// IsApplicable checks if the call is from sqlboiler using type information.
+func (c *SQLBoilerChecker) IsApplicable(info *types.Info, call *ast.CallExpr) bool {
sel, ok := call.Fun.(*ast.SelectorExpr)
if !ok {
return false
}
- // SQLBoiler methods
- sqlboilerMethods := []string{
- "All", "One", "Count", "Exists",
- "Select", "Load", "Reload",
- }
-
- for _, method := range sqlboilerMethods {
- if sel.Sel.Name == method {
- return true
- }
+ // Check if the receiver type is from sqlboiler package
+ if IsTypeFromPackage(info, sel.X, sqlboilerPkgPath) {
+ return true
}
- // Check for qm (query mods) package
+ // Check for qm (query mods) package - verify via type info
if ident, ok := sel.X.(*ast.Ident); ok {
- if ident.Name == "qm" {
- return true
+ if info != nil {
+ if obj := info.Uses[ident]; obj != nil {
+ // For package-level function calls like qm.Select(), obj is *types.PkgName
+ if pkgName, ok := obj.(*types.PkgName); ok {
+ pkgPath := pkgName.Imported().Path()
+ if len(pkgPath) >= len(sqlboilerPkgPath) && pkgPath[:len(sqlboilerPkgPath)] == sqlboilerPkgPath {
+ return true
+ }
+ }
+ }
}
}
@@ -98,29 +102,16 @@ func (c *SQLBoilerChecker) CheckChainedCalls(call *ast.CallExpr) []*SelectStarVi
if sel.Sel.Name == "All" || sel.Sel.Name == "One" {
// Look for the model call that might have query mods
if innerCall, ok := sel.X.(*ast.CallExpr); ok {
- // Check query mod arguments for Select("*")
+ // Check if there's a qm.Select in the arguments
+ // Note: qm.Select("*") is already detected by CheckSelectStar when
+ // the analyzer visits that CallExpr, so we only check for hasSelect here
hasSelect := false
for _, arg := range innerCall.Args {
- // Check if this is a qm.Select call
if callExpr, ok := arg.(*ast.CallExpr); ok {
if innerSel, ok := callExpr.Fun.(*ast.SelectorExpr); ok {
if innerSel.Sel.Name == "Select" {
hasSelect = true
- // Check for "*"
- for _, selectArg := range callExpr.Args {
- if lit, ok := selectArg.(*ast.BasicLit); ok && lit.Kind == token.STRING {
- value := strings.Trim(lit.Value, "`\"")
- if value == "*" {
- violations = append(violations, &SelectStarViolation{
- Pos: callExpr.Pos(),
- End: callExpr.End(),
- Message: "SQLBoiler qm.Select(\"*\") - specify columns explicitly",
- Builder: "sqlboiler",
- Context: "explicit_star",
- })
- }
- }
- }
+ break
}
}
}
diff --git a/vendor/github.com/MirrexOne/unqueryvet/internal/analyzer/sqlbuilders/sqlc.go b/vendor/github.com/MirrexOne/unqueryvet/internal/analyzer/sqlbuilders/sqlc.go
new file mode 100644
index 000000000..d98a52bd4
--- /dev/null
+++ b/vendor/github.com/MirrexOne/unqueryvet/internal/analyzer/sqlbuilders/sqlc.go
@@ -0,0 +1,87 @@
+package sqlbuilders
+
+import (
+ "go/ast"
+ "go/token"
+ "go/types"
+ "strings"
+)
+
+// sqlc generates code, so we check if the package path contains "sqlc"
+const sqlcPkgPath = "sqlc"
+
+// SQLCChecker checks for SELECT * in sqlc generated code.
+type SQLCChecker struct{}
+
+// NewSQLCChecker creates a new sqlc checker.
+func NewSQLCChecker() *SQLCChecker {
+ return &SQLCChecker{}
+}
+
+// Name returns the checker name.
+func (c *SQLCChecker) Name() string {
+ return "sqlc"
+}
+
+// IsApplicable checks if the call is from sqlc generated code using type information.
+func (c *SQLCChecker) IsApplicable(info *types.Info, call *ast.CallExpr) bool {
+ sel, ok := call.Fun.(*ast.SelectorExpr)
+ if !ok {
+ return false
+ }
+
+ // sqlc generates code, check if receiver type's package contains "sqlc"
+ if info != nil {
+ typ := info.TypeOf(sel.X)
+ if typ != nil {
+ if named, ok := typ.(*types.Named); ok {
+ if obj := named.Obj(); obj != nil {
+ if pkg := obj.Pkg(); pkg != nil {
+ if strings.Contains(pkg.Path(), sqlcPkgPath) {
+ return true
+ }
+ }
+ }
+ }
+ // Check pointer types
+ if ptr, ok := typ.(*types.Pointer); ok {
+ if named, ok := ptr.Elem().(*types.Named); ok {
+ if obj := named.Obj(); obj != nil {
+ if pkg := obj.Pkg(); pkg != nil {
+ if strings.Contains(pkg.Path(), sqlcPkgPath) {
+ return true
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return false
+}
+
+// CheckSelectStar checks for SELECT * in the call.
+func (c *SQLCChecker) CheckSelectStar(call *ast.CallExpr) *SelectStarViolation {
+ // sqlc doesn't typically have SELECT * visible in Go code
+ // but we can check string arguments
+ for _, arg := range call.Args {
+ if lit, ok := arg.(*ast.BasicLit); ok && lit.Kind == token.STRING {
+ value := strings.ToUpper(lit.Value)
+ if strings.Contains(value, "SELECT *") || strings.Contains(value, "SELECT\t*") {
+ return &SelectStarViolation{
+ Pos: lit.Pos(),
+ End: lit.End(),
+ Message: "sqlc query contains SELECT * - specify columns explicitly in your .sql file",
+ }
+ }
+ }
+ }
+ return nil
+}
+
+// CheckChainedCalls checks chained method calls.
+func (c *SQLCChecker) CheckChainedCalls(call *ast.CallExpr) []*SelectStarViolation {
+ // sqlc doesn't typically use chained calls
+ return nil
+}
diff --git a/vendor/github.com/MirrexOne/unqueryvet/internal/analyzer/sqlbuilders/sqlx.go b/vendor/github.com/MirrexOne/unqueryvet/internal/analyzer/sqlbuilders/sqlx.go
index 21e7ba804..1daf4c6ca 100644
--- a/vendor/github.com/MirrexOne/unqueryvet/internal/analyzer/sqlbuilders/sqlx.go
+++ b/vendor/github.com/MirrexOne/unqueryvet/internal/analyzer/sqlbuilders/sqlx.go
@@ -4,9 +4,12 @@ package sqlbuilders
import (
"go/ast"
"go/token"
+ "go/types"
"strings"
)
+const sqlxPkgPath = "github.com/jmoiron/sqlx"
+
// SQLxChecker checks github.com/jmoiron/sqlx for SELECT * patterns.
type SQLxChecker struct{}
@@ -20,28 +23,15 @@ func (c *SQLxChecker) Name() string {
return "sqlx"
}
-// IsApplicable checks if the call might be from sqlx.
-func (c *SQLxChecker) IsApplicable(call *ast.CallExpr) bool {
+// IsApplicable checks if the call is from sqlx using type information.
+func (c *SQLxChecker) IsApplicable(info *types.Info, call *ast.CallExpr) bool {
sel, ok := call.Fun.(*ast.SelectorExpr)
if !ok {
return false
}
- // sqlx methods that take SQL queries
- sqlxMethods := []string{
- "Select", "Get", "Queryx", "QueryRowx",
- "NamedQuery", "NamedExec", "MustExec",
- "Preparex", "PreparexContext", "PrepareNamed",
- "Rebind", "In",
- }
-
- for _, method := range sqlxMethods {
- if sel.Sel.Name == method {
- return true
- }
- }
-
- return false
+ // Check if the receiver type is from sqlx package
+ return IsTypeFromPackage(info, sel.X, sqlxPkgPath)
}
// CheckSelectStar checks for SELECT * in sqlx calls.
diff --git a/vendor/github.com/MirrexOne/unqueryvet/internal/analyzer/sqlbuilders/squirrel.go b/vendor/github.com/MirrexOne/unqueryvet/internal/analyzer/sqlbuilders/squirrel.go
index cb2e4ccaf..33f1f9069 100644
--- a/vendor/github.com/MirrexOne/unqueryvet/internal/analyzer/sqlbuilders/squirrel.go
+++ b/vendor/github.com/MirrexOne/unqueryvet/internal/analyzer/sqlbuilders/squirrel.go
@@ -4,9 +4,12 @@ package sqlbuilders
import (
"go/ast"
"go/token"
+ "go/types"
"strings"
)
+const squirrelPkgPath = "github.com/Masterminds/squirrel"
+
// SquirrelChecker checks github.com/Masterminds/squirrel for SELECT * patterns.
type SquirrelChecker struct{}
@@ -20,29 +23,29 @@ func (c *SquirrelChecker) Name() string {
return "squirrel"
}
-// IsApplicable checks if the call might be from Squirrel.
-func (c *SquirrelChecker) IsApplicable(call *ast.CallExpr) bool {
+// IsApplicable checks if the call is from Squirrel using type information.
+func (c *SquirrelChecker) IsApplicable(info *types.Info, call *ast.CallExpr) bool {
sel, ok := call.Fun.(*ast.SelectorExpr)
if !ok {
return false
}
- // Squirrel methods to check
- squirrelMethods := []string{
- "Select", "Columns", "Column",
- "SelectBuilder", "InsertBuilder", "UpdateBuilder", "DeleteBuilder",
- }
-
- for _, method := range squirrelMethods {
- if sel.Sel.Name == method {
- return true
- }
+ // Check if the receiver type is from squirrel package
+ if IsTypeFromPackage(info, sel.X, squirrelPkgPath) {
+ return true
}
- // Check for squirrel package prefix
+ // Check for package-level function calls like squirrel.Select()
if ident, ok := sel.X.(*ast.Ident); ok {
- if ident.Name == "squirrel" || ident.Name == "sq" {
- return true
+ if info != nil {
+ if obj := info.Uses[ident]; obj != nil {
+ if pkgName, ok := obj.(*types.PkgName); ok {
+ pkgPath := pkgName.Imported().Path()
+ if len(pkgPath) >= len(squirrelPkgPath) && pkgPath[:len(squirrelPkgPath)] == squirrelPkgPath {
+ return true
+ }
+ }
+ }
}
}
@@ -110,75 +113,28 @@ func (c *SquirrelChecker) CheckSelectStar(call *ast.CallExpr) *SelectStarViolati
}
// CheckChainedCalls checks method chains for SELECT * patterns.
+// squirrelChainState tracks state while traversing call chain
+type squirrelChainState struct {
+ hasSelect bool
+ hasColumns bool
+ selectCall *ast.CallExpr
+}
+
func (c *SquirrelChecker) CheckChainedCalls(call *ast.CallExpr) []*SelectStarViolation {
var violations []*SelectStarViolation
+ state := &squirrelChainState{}
- // Traverse the call chain
current := call
- hasSelect := false
- hasColumns := false
- var selectCall *ast.CallExpr
-
for current != nil {
sel, ok := current.Fun.(*ast.SelectorExpr)
if !ok {
break
}
- switch sel.Sel.Name {
- case "Select":
- hasSelect = true
- selectCall = current
- // Check if Select has arguments
- if len(current.Args) > 0 {
- hasColumns = true
- // Check for "*" argument
- for _, arg := range current.Args {
- if lit, ok := arg.(*ast.BasicLit); ok && lit.Kind == token.STRING {
- value := strings.Trim(lit.Value, "`\"")
- if value == "*" {
- violations = append(violations, &SelectStarViolation{
- Pos: current.Pos(),
- End: current.End(),
- Message: "Squirrel Select(\"*\") in chain - specify columns explicitly",
- Builder: "squirrel",
- Context: "chained_star",
- })
- }
- }
- }
- }
- case "Columns", "Column":
- hasColumns = true
- // Check for "*" in Columns/Column
- for _, arg := range current.Args {
- if lit, ok := arg.(*ast.BasicLit); ok && lit.Kind == token.STRING {
- value := strings.Trim(lit.Value, "`\"")
- if value == "*" {
- violations = append(violations, &SelectStarViolation{
- Pos: current.Pos(),
- End: current.End(),
- Message: "Squirrel Columns(\"*\") in chain - specify columns explicitly",
- Builder: "squirrel",
- Context: "chained_star",
- })
- }
- }
- }
- case "From", "Where", "Join", "LeftJoin", "RightJoin", "InnerJoin":
- // Terminal methods - check if we have Select without columns
- if hasSelect && !hasColumns && selectCall != nil && len(selectCall.Args) == 0 {
- violations = append(violations, &SelectStarViolation{
- Pos: selectCall.Pos(),
- End: selectCall.End(),
- Message: "Squirrel Select() without columns in chain defaults to SELECT *",
- Builder: "squirrel",
- Context: "empty_select_chain",
- })
- }
+ if v := c.processChainMethod(sel.Sel.Name, current, state); v != nil {
+ violations = append(violations, v)
}
- // Move to the next call in the chain
if innerCall, ok := sel.X.(*ast.CallExpr); ok {
current = innerCall
} else {
@@ -188,3 +144,71 @@ func (c *SquirrelChecker) CheckChainedCalls(call *ast.CallExpr) []*SelectStarVio
return violations
}
+
+// processChainMethod processes a single method in the call chain
+func (c *SquirrelChecker) processChainMethod(methodName string, current *ast.CallExpr, state *squirrelChainState) *SelectStarViolation {
+ switch methodName {
+ case "Select":
+ return c.handleSelectMethod(current, state)
+ case "Columns", "Column":
+ return c.handleColumnsMethod(current, state)
+ case "From", "Where", "Join", "LeftJoin", "RightJoin", "InnerJoin":
+ return c.handleTerminalMethod(state)
+ }
+ return nil
+}
+
+// handleSelectMethod handles Select() calls in chain
+func (c *SquirrelChecker) handleSelectMethod(current *ast.CallExpr, state *squirrelChainState) *SelectStarViolation {
+ state.hasSelect = true
+ state.selectCall = current
+
+ if len(current.Args) == 0 {
+ return nil
+ }
+
+ state.hasColumns = true
+ if v := c.checkArgsForStar(current, "Squirrel Select(\"*\") in chain - specify columns explicitly"); v != nil {
+ return v
+ }
+ return nil
+}
+
+// handleColumnsMethod handles Columns()/Column() calls in chain
+func (c *SquirrelChecker) handleColumnsMethod(current *ast.CallExpr, state *squirrelChainState) *SelectStarViolation {
+ state.hasColumns = true
+ return c.checkArgsForStar(current, "Squirrel Columns(\"*\") in chain - specify columns explicitly")
+}
+
+// handleTerminalMethod handles terminal methods (From, Where, Join, etc.)
+func (c *SquirrelChecker) handleTerminalMethod(state *squirrelChainState) *SelectStarViolation {
+ if state.hasSelect && !state.hasColumns && state.selectCall != nil && len(state.selectCall.Args) == 0 {
+ return &SelectStarViolation{
+ Pos: state.selectCall.Pos(),
+ End: state.selectCall.End(),
+ Message: "Squirrel Select() without columns in chain defaults to SELECT *",
+ Builder: "squirrel",
+ Context: "empty_select_chain",
+ }
+ }
+ return nil
+}
+
+// checkArgsForStar checks if any argument is "*"
+func (c *SquirrelChecker) checkArgsForStar(call *ast.CallExpr, message string) *SelectStarViolation {
+ for _, arg := range call.Args {
+ if lit, ok := arg.(*ast.BasicLit); ok && lit.Kind == token.STRING {
+ value := strings.Trim(lit.Value, "`\"")
+ if value == "*" {
+ return &SelectStarViolation{
+ Pos: call.Pos(),
+ End: call.End(),
+ Message: message,
+ Builder: "squirrel",
+ Context: "chained_star",
+ }
+ }
+ }
+ }
+ return nil
+}
diff --git a/vendor/github.com/MirrexOne/unqueryvet/internal/analyzer/sqli_scanner.go b/vendor/github.com/MirrexOne/unqueryvet/internal/analyzer/sqli_scanner.go
new file mode 100644
index 000000000..7f3d1fe79
--- /dev/null
+++ b/vendor/github.com/MirrexOne/unqueryvet/internal/analyzer/sqli_scanner.go
@@ -0,0 +1,750 @@
+package analyzer
+
+import (
+ "fmt"
+ "go/ast"
+ "go/token"
+ "go/types"
+ "regexp"
+ "strings"
+
+ "golang.org/x/tools/go/analysis"
+)
+
+// SQLISeverity represents the severity level of SQL injection vulnerability.
+type SQLISeverity string
+
+const (
+ SQLISeverityCritical SQLISeverity = "critical" // Direct user input in query
+ SQLISeverityHigh SQLISeverity = "high" // Format string with variables
+ SQLISeverityMedium SQLISeverity = "medium" // String concatenation
+ SQLISeverityLow SQLISeverity = "low" // Potential issue, needs review
+)
+
+// SQLInjectionScanner detects potential SQL injection vulnerabilities.
+type SQLInjectionScanner struct {
+ // dangerousFuncs are functions that format strings (potential SQL injection vectors)
+ dangerousFuncs map[string]map[string]bool // package -> function -> bool
+ // queryFuncs are database query functions
+ queryFuncs map[string]bool
+ // ormQueryMethods are ORM-specific query methods
+ ormQueryMethods map[string]bool
+ // taintedVariables tracks variables that might contain user input
+ taintedVariables map[string]bool
+ // userInputPatterns are variable name patterns that suggest user input
+ userInputPatterns []string
+ // httpInputFuncs are functions that read HTTP input
+ httpInputFuncs map[string]map[string]bool
+ // pass is the current analysis pass
+ pass *analysis.Pass
+}
+
+// SQLInjectionViolation represents a detected SQL injection vulnerability.
+type SQLInjectionViolation struct {
+ Pos token.Pos
+ End token.Pos
+ Message string
+ Severity SQLISeverity
+ VulnType string // "concat", "sprintf", "exec", "tainted", "orm_raw"
+ Suggestion string
+ CodeFix string // Suggested code fix
+}
+
+// NewSQLInjectionScanner creates a new SQL injection scanner.
+func NewSQLInjectionScanner() *SQLInjectionScanner {
+ return &SQLInjectionScanner{
+ dangerousFuncs: map[string]map[string]bool{
+ "fmt": {
+ "Sprintf": true,
+ "Fprintf": true,
+ "Printf": true,
+ "Errorf": true,
+ "Sscanf": true,
+ },
+ "strings": {
+ "Join": true,
+ "Replace": true,
+ "ReplaceAll": true,
+ "Builder": true,
+ },
+ "strconv": {
+ "Itoa": true,
+ "FormatInt": true,
+ },
+ },
+ queryFuncs: map[string]bool{
+ // Standard database/sql
+ "Query": true,
+ "QueryRow": true,
+ "Exec": true,
+ "ExecContext": true,
+ "QueryContext": true,
+ "QueryRowContext": true,
+ "Prepare": true,
+ "PrepareContext": true,
+ // SQLx
+ "QueryRowx": true,
+ "Queryx": true,
+ "MustExec": true,
+ "NamedExec": true,
+ "NamedQuery": true,
+ "NamedExecContext": true,
+ "NamedQueryContext": true,
+ "Get": true,
+ "Select": true,
+ "GetContext": true,
+ "SelectContext": true,
+ // GORM
+ "Raw": true,
+ "Where": true,
+ "Having": true,
+ "Order": true,
+ "Group": true,
+ "Joins": true,
+ // Bun
+ "NewRaw": true,
+ "ColumnExpr": true,
+ "WhereOr": true,
+ // PGX
+ "SendBatch": true,
+ },
+ ormQueryMethods: map[string]bool{
+ // GORM dangerous methods when used with string concat
+ "Raw": true,
+ "Exec": true,
+ "Where": true,
+ "Or": true,
+ "Not": true,
+ "Having": true,
+ "Order": true,
+ "Group": true,
+ "Joins": true,
+ // Bun
+ "NewRaw": true,
+ "WhereOr": true,
+ "ColumnExpr": true,
+ "TableExpr": true,
+ },
+ taintedVariables: make(map[string]bool),
+ userInputPatterns: []string{
+ "user", "input", "param", "query", "search", "filter",
+ "id", "name", "email", "password", "username", "request",
+ "body", "form", "data", "value", "arg", "args",
+ "term", "keyword", "text", "content",
+ },
+ httpInputFuncs: map[string]map[string]bool{
+ "http": {
+ "Request": true,
+ },
+ "gin": {
+ "Param": true,
+ "Query": true,
+ "PostForm": true,
+ "DefaultQuery": true,
+ "GetQuery": true,
+ "BindJSON": true,
+ "ShouldBind": true,
+ },
+ "echo": {
+ "Param": true,
+ "QueryParam": true,
+ "FormValue": true,
+ "Bind": true,
+ },
+ "fiber": {
+ "Params": true,
+ "Query": true,
+ "FormValue": true,
+ "BodyParser": true,
+ },
+ "chi": {
+ "URLParam": true,
+ },
+ "mux": {
+ "Vars": true,
+ },
+ },
+ }
+}
+
+// SQL pattern for identifying SQL-like strings
+var sqlPattern = regexp.MustCompile(`(?i)(SELECT|INSERT|UPDATE|DELETE|DROP|CREATE|ALTER|TRUNCATE)\s+`)
+
+// Placeholder patterns for parameterized queries
+var placeholderPattern = regexp.MustCompile(`(\?|\$\d+|:\w+|@\w+)`)
+
+// ScanFile scans a file for SQL injection vulnerabilities.
+func (s *SQLInjectionScanner) ScanFile(pass *analysis.Pass, file *ast.File) []SQLInjectionViolation {
+ s.pass = pass
+ var violations []SQLInjectionViolation
+
+ ast.Inspect(file, func(n ast.Node) bool {
+ switch node := n.(type) {
+ case *ast.CallExpr:
+ // Check for dangerous patterns
+ if v := s.checkCallExpr(node); v != nil {
+ violations = append(violations, *v)
+ }
+ case *ast.BinaryExpr:
+ // Check for string concatenation in SQL context
+ if v := s.checkBinaryExpr(node); v != nil {
+ violations = append(violations, *v)
+ }
+ }
+ return true
+ })
+
+ return violations
+}
+
+// checkCallExpr checks a function call for SQL injection patterns.
+func (s *SQLInjectionScanner) checkCallExpr(call *ast.CallExpr) *SQLInjectionViolation {
+ // Check if this is a query function call
+ methodName := s.getMethodName(call)
+ if !s.queryFuncs[methodName] && !s.ormQueryMethods[methodName] {
+ return nil
+ }
+
+ // Ignore *sql.Stmt calls since they don't take queries
+ if s.isStmtMethod(call) {
+ return nil
+ }
+
+ // If this is a parameterized query (first arg is string literal with placeholders,
+ // subsequent args are parameters), it's safe
+ if s.isParameterizedQuery(call) {
+ return nil
+ }
+
+ // Determine which argument is the query string
+ queryIdx := 0
+ if strings.HasSuffix(methodName, "Context") {
+ queryIdx = 1
+ }
+
+ if len(call.Args) <= queryIdx {
+ return nil
+ }
+
+ // Only check the query argument for dangerous patterns
+ arg := call.Args[queryIdx]
+
+ // Pattern 1: fmt.Sprintf result used as query
+ if innerCall, ok := arg.(*ast.CallExpr); ok {
+ if s.isDangerousFormatCall(innerCall) {
+ if s.containsUserInput(innerCall) {
+ return &SQLInjectionViolation{
+ Pos: call.Pos(),
+ End: call.End(),
+ Message: "SQL INJECTION: fmt.Sprintf with user input passed to " + methodName + "()",
+ Severity: SQLISeverityCritical,
+ VulnType: "sprintf",
+ Suggestion: "Use parameterized queries with placeholders (?, $1, :name)",
+ CodeFix: s.generateParameterizedFix(methodName, arg),
+ }
+ }
+ // Even without detected user input, format strings are suspicious
+ return &SQLInjectionViolation{
+ Pos: call.Pos(),
+ End: call.End(),
+ Message: "potential SQL injection: fmt.Sprintf result passed to " + methodName + "() - use parameterized queries",
+ Severity: SQLISeverityHigh,
+ VulnType: "sprintf",
+ Suggestion: "Replace fmt.Sprintf with parameterized query using placeholders",
+ CodeFix: s.generateParameterizedFix(methodName, arg),
+ }
+ }
+ // Check for HTTP input functions
+ if s.isHTTPInputCall(innerCall) {
+ return &SQLInjectionViolation{
+ Pos: call.Pos(),
+ End: call.End(),
+ Message: "SQL INJECTION: HTTP input directly used in " + methodName + "()",
+ Severity: SQLISeverityCritical,
+ VulnType: "tainted",
+ Suggestion: "Never use HTTP input directly in SQL - always use parameterized queries",
+ }
+ }
+ }
+
+ // Pattern 2: String concatenation used as query
+ if binExpr, ok := arg.(*ast.BinaryExpr); ok {
+ if binExpr.Op == token.ADD {
+ if s.containsTaintedVariable(binExpr) {
+ return &SQLInjectionViolation{
+ Pos: call.Pos(),
+ End: call.End(),
+ Message: "SQL INJECTION: string concatenation with user input in " + methodName + "()",
+ Severity: SQLISeverityCritical,
+ VulnType: "concat",
+ Suggestion: "Use parameterized queries instead of string concatenation",
+ CodeFix: "Replace: db." + methodName + "(\"SELECT * FROM users WHERE id = \" + id)\nWith: db." + methodName + "(\"SELECT * FROM users WHERE id = ?\", id)",
+ }
+ }
+ if s.containsStringVariable(binExpr) {
+ return &SQLInjectionViolation{
+ Pos: call.Pos(),
+ End: call.End(),
+ Message: "potential SQL injection: string concatenation in " + methodName + "()",
+ Severity: SQLISeverityHigh,
+ VulnType: "concat",
+ Suggestion: "Use parameterized queries instead of string concatenation",
+ }
+ }
+ }
+ }
+
+ // Pattern 3: Tainted variable used directly
+ if ident := getIdent(arg); ident != nil {
+ if s.isTaintedVariable(ident.Name) && !s.isConstant(arg) {
+ return &SQLInjectionViolation{
+ Pos: call.Pos(),
+ End: call.End(),
+ Message: fmt.Sprintf("SQL INJECTION: potentially tainted variable '%s' used in %s ()", ident.Name, methodName),
+ Severity: SQLISeverityHigh,
+ VulnType: "tainted",
+ Suggestion: fmt.Sprintf("Validate and sanitize '%s' or use parameterized queries", ident.Name),
+ }
+ }
+ if s.mightBeDynamicQuery(ident) && !s.isConstant(arg) {
+ return &SQLInjectionViolation{
+ Pos: call.Pos(),
+ End: call.End(),
+ Message: "review SQL query in " + methodName + "(): ensure '" + ident.Name + "' is not built with user input",
+ Severity: SQLISeverityMedium,
+ VulnType: "variable",
+ Suggestion: "Audit the construction of '" + ident.Name + "' to ensure it doesn't contain user input",
+ }
+ }
+ }
+
+ // Pattern 4: ORM Raw methods with string variables
+ if s.ormQueryMethods[methodName] {
+ if v := s.checkORMRawMethod(call, methodName); v != nil {
+ return v
+ }
+ }
+
+ return nil
+}
+
+// checkORMRawMethod checks ORM-specific raw SQL methods.
+func (s *SQLInjectionScanner) checkORMRawMethod(call *ast.CallExpr, methodName string) *SQLInjectionViolation {
+ // Methods like db.Raw(), db.Where() with string concatenation
+ if len(call.Args) == 0 {
+ return nil
+ }
+
+ firstArg := call.Args[0]
+
+ // Check if first argument is a string literal (safe) or variable (needs review)
+ if _, ok := firstArg.(*ast.BasicLit); !ok {
+ // Not a string literal - might be dangerous
+ if ident := getIdent(firstArg); ident != nil {
+ if s.isTaintedVariable(ident.Name) && !s.isConstant(firstArg) {
+ return &SQLInjectionViolation{
+ Pos: call.Pos(),
+ End: call.End(),
+ Message: "SQL INJECTION risk: " + methodName + "() with potentially tainted variable",
+ Severity: SQLISeverityHigh,
+ VulnType: "orm_raw",
+ Suggestion: "Use parameterized syntax: db." + methodName + "(\"field = ?\", value)",
+ }
+ }
+ }
+ }
+
+ return nil
+}
+
+// generateParameterizedFix generates a suggested fix for sprintf patterns.
+func (s *SQLInjectionScanner) generateParameterizedFix(methodName string, arg ast.Expr) string {
+ return "Replace fmt.Sprintf with parameterized query:\n" +
+ " Before: db." + methodName + "(fmt.Sprintf(\"SELECT * FROM users WHERE id = %d\", id))\n" +
+ " After: db." + methodName + "(\"SELECT * FROM users WHERE id = ?\", id)"
+}
+
+// isHTTPInputCall checks if a call is reading HTTP input.
+func (s *SQLInjectionScanner) isHTTPInputCall(call *ast.CallExpr) bool {
+ sel, ok := call.Fun.(*ast.SelectorExpr)
+ if !ok {
+ return false
+ }
+
+ methodName := sel.Sel.Name
+
+ // Check for common HTTP input methods
+ httpMethods := map[string]bool{
+ "Param": true, "Query": true, "PostForm": true,
+ "FormValue": true, "QueryParam": true, "Params": true,
+ "GetQuery": true, "DefaultQuery": true, "BodyParser": true,
+ "Bind": true, "BindJSON": true, "ShouldBind": true,
+ "URLParam": true, "Vars": true,
+ }
+
+ return httpMethods[methodName]
+}
+
+// isConstant checks if an expression refers to a constant.
+func (s *SQLInjectionScanner) isConstant(expr ast.Expr) bool {
+ if expr == nil {
+ return false
+ }
+ if s.pass != nil && s.pass.TypesInfo != nil {
+ if ident := getIdent(expr); ident != nil {
+ if obj := s.pass.TypesInfo.ObjectOf(ident); obj != nil {
+ _, ok := obj.(*types.Const)
+ return ok
+ }
+ }
+ }
+ if ident, ok := expr.(*ast.Ident); ok {
+ if ident.Obj != nil && ident.Obj.Kind == ast.Con {
+ return true
+ }
+ }
+ return false
+}
+
+// getIdent extracts an identifier from an expression (Ident or SelectorExpr).
+func getIdent(expr ast.Expr) *ast.Ident {
+ switch e := expr.(type) {
+ case *ast.Ident:
+ return e
+ case *ast.SelectorExpr:
+ return e.Sel
+ default:
+ return nil
+ }
+}
+
+// getConstantValue attempts to get the string value of a constant expression.
+func (s *SQLInjectionScanner) getConstantValue(expr ast.Expr) (string, bool) {
+ if expr == nil {
+ return "", false
+ }
+ if s.pass != nil && s.pass.TypesInfo != nil {
+ if ident := getIdent(expr); ident != nil {
+ if obj := s.pass.TypesInfo.ObjectOf(ident); obj != nil {
+ if c, ok := obj.(*types.Const); ok {
+ val := c.Val().ExactString()
+ // Remove quotes if it's a string constant
+ if strings.HasPrefix(val, "\"") && strings.HasSuffix(val, "\"") {
+ return val[1 : len(val)-1], true
+ }
+ return val, true
+ }
+ }
+ }
+ }
+ if ident, ok := expr.(*ast.Ident); ok {
+ if ident.Obj != nil && ident.Obj.Kind == ast.Con {
+ if vs, ok := ident.Obj.Decl.(*ast.ValueSpec); ok {
+ for i, name := range vs.Names {
+ if name.Name == ident.Name && i < len(vs.Values) {
+ if lit, ok := vs.Values[i].(*ast.BasicLit); ok && lit.Kind == token.STRING {
+ val := lit.Value
+ if strings.HasPrefix(val, "\"") && strings.HasSuffix(val, "\"") {
+ return val[1 : len(val)-1], true
+ }
+ return val, true
+ }
+ }
+ }
+ }
+ }
+ }
+ return "", false
+}
+
+// isTaintedVariable checks if a variable name suggests user input.
+func (s *SQLInjectionScanner) isTaintedVariable(name string) bool {
+ lowerName := strings.ToLower(name)
+ for _, pattern := range s.userInputPatterns {
+ if strings.Contains(lowerName, pattern) {
+ return true
+ }
+ }
+ return s.taintedVariables[name]
+}
+
+// containsTaintedVariable checks if an expression contains tainted variables.
+func (s *SQLInjectionScanner) containsTaintedVariable(expr ast.Expr) bool {
+ hasTainted := false
+
+ ast.Inspect(expr, func(n ast.Node) bool {
+ if ident, ok := n.(*ast.Ident); ok {
+ if s.isTaintedVariable(ident.Name) && !s.isConstant(ident) {
+ hasTainted = true
+ return false
+ }
+ }
+ return true
+ })
+
+ return hasTainted
+}
+
+// MarkVariableAsTainted marks a variable as containing user input.
+func (s *SQLInjectionScanner) MarkVariableAsTainted(name string) {
+ s.taintedVariables[name] = true
+}
+
+// isStmtMethod checks if a call is a method on a prepared statement (e.g., *sql.Stmt).
+func (s *SQLInjectionScanner) isStmtMethod(call *ast.CallExpr) bool {
+ if sel, ok := call.Fun.(*ast.SelectorExpr); ok {
+ if s.pass != nil && s.pass.TypesInfo != nil {
+ if selObj := s.pass.TypesInfo.Uses[sel.Sel]; selObj != nil {
+ if sig, ok := selObj.Type().(*types.Signature); ok {
+ if recv := sig.Recv(); recv != nil {
+ recvType := recv.Type().String()
+ if strings.Contains(recvType, "sql.Stmt") || strings.Contains(recvType, "sqlx.Stmt") || strings.Contains(recvType, "NamedStmt") {
+ return true
+ }
+ }
+ }
+ }
+ } else {
+ // Fallback heuristic: if the receiver is named "stmt", assume it's a statement
+ if ident, ok := sel.X.(*ast.Ident); ok {
+ name := strings.ToLower(ident.Name)
+ if strings.Contains(name, "stmt") {
+ return true
+ }
+ }
+ }
+ }
+ return false
+}
+
+// isParameterizedQuery checks if a call uses parameterized query syntax.
+// A parameterized query has a string literal or constant with placeholders (?, $1, :name, @param)
+// as the query argument, with subsequent arguments providing the values.
+func (s *SQLInjectionScanner) isParameterizedQuery(call *ast.CallExpr) bool {
+ methodName := s.getMethodName(call)
+ queryIdx := 0
+ // Context-aware methods usually have the query as the second argument
+ if strings.HasSuffix(methodName, "Context") {
+ queryIdx = 1
+ }
+
+ if len(call.Args) <= queryIdx+1 {
+ return false
+ }
+
+ // Query argument should be a string literal or constant
+ queryArg := call.Args[queryIdx]
+ var queryStr string
+ if lit, ok := queryArg.(*ast.BasicLit); ok && lit.Kind == token.STRING {
+ queryStr = lit.Value
+ } else if val, ok := s.getConstantValue(queryArg); ok {
+ queryStr = val
+ }
+
+ if queryStr == "" {
+ return false
+ }
+
+ // Check if the string contains placeholder patterns
+ return placeholderPattern.MatchString(queryStr)
+}
+
+// checkBinaryExpr checks string concatenation for SQL injection.
+func (s *SQLInjectionScanner) checkBinaryExpr(expr *ast.BinaryExpr) *SQLInjectionViolation {
+ if expr.Op != token.ADD {
+ return nil
+ }
+
+ // Check if this looks like SQL concatenation
+ if s.isSQLStringConcat(expr) && s.containsStringVariable(expr) {
+ return &SQLInjectionViolation{
+ Pos: expr.Pos(),
+ End: expr.End(),
+ Message: "potential SQL injection: string concatenation with SQL keywords - use parameterized queries",
+ Severity: SQLISeverityMedium,
+ VulnType: "concat",
+ }
+ }
+
+ return nil
+}
+
+// getMethodName extracts the method name from a call expression.
+func (s *SQLInjectionScanner) getMethodName(call *ast.CallExpr) string {
+ switch fun := call.Fun.(type) {
+ case *ast.SelectorExpr:
+ return fun.Sel.Name
+ case *ast.Ident:
+ return fun.Name
+ }
+ return ""
+}
+
+// isDangerousFormatCall checks if a call is to a dangerous format function.
+func (s *SQLInjectionScanner) isDangerousFormatCall(call *ast.CallExpr) bool {
+ sel, ok := call.Fun.(*ast.SelectorExpr)
+ if !ok {
+ return false
+ }
+
+ pkgIdent, ok := sel.X.(*ast.Ident)
+ if !ok {
+ return false
+ }
+
+ if funcs, ok := s.dangerousFuncs[pkgIdent.Name]; ok {
+ return funcs[sel.Sel.Name]
+ }
+
+ return false
+}
+
+// containsUserInput checks if a format call might contain user input.
+func (s *SQLInjectionScanner) containsUserInput(call *ast.CallExpr) bool {
+ if len(call.Args) < 2 {
+ return false
+ }
+
+ // Check if any argument is a variable (not a literal)
+ for i, arg := range call.Args {
+ if i == 0 {
+ // Skip format string
+ continue
+ }
+ // If argument is not a literal, it might be user input
+ if _, ok := arg.(*ast.BasicLit); !ok {
+ // Check if it's a constant (including exported constants from other packages)
+ if s.isConstant(arg) {
+ continue
+ }
+ return true
+ }
+ }
+
+ return false
+}
+
+// containsStringVariable checks if an expression contains string variables.
+func (s *SQLInjectionScanner) containsStringVariable(expr ast.Expr) bool {
+ hasVariable := false
+
+ ast.Inspect(expr, func(n ast.Node) bool {
+ switch node := n.(type) {
+ case *ast.Ident:
+ // Check if this is a variable (not a constant)
+ if s.isConstant(node) {
+ return true
+ }
+ if node.Obj != nil {
+ hasVariable = true
+ return false
+ }
+ case *ast.CallExpr:
+ // Function call results are considered dynamic
+ hasVariable = true
+ return false
+ }
+ return true
+ })
+
+ return hasVariable
+}
+
+// isSQLStringConcat checks if a binary expression looks like SQL concatenation.
+func (s *SQLInjectionScanner) isSQLStringConcat(expr *ast.BinaryExpr) bool {
+ // Check left operand
+ if s.isQueryString(expr.X) {
+ return true
+ }
+ // Check right operand
+ if s.isQueryString(expr.Y) {
+ return true
+ }
+ return false
+}
+
+// isQueryString checks if an expression looks like a SQL query string.
+func (s *SQLInjectionScanner) isQueryString(expr ast.Expr) bool {
+ var val string
+ if lit, ok := expr.(*ast.BasicLit); ok && lit.Kind == token.STRING {
+ val = lit.Value
+ } else if v, ok := s.getConstantValue(expr); ok {
+ val = v
+ }
+
+ if val == "" {
+ return false
+ }
+
+ value := strings.ToUpper(val)
+ return sqlPattern.MatchString(value)
+}
+
+// mightBeDynamicQuery checks if an identifier might be a dynamically built query.
+func (s *SQLInjectionScanner) mightBeDynamicQuery(ident *ast.Ident) bool {
+ name := strings.ToLower(ident.Name)
+ return strings.Contains(name, "query") ||
+ strings.Contains(name, "sql") ||
+ strings.Contains(name, "stmt")
+}
+
+// AnalyzeSQLInjection is a convenience function to run SQL injection scanning.
+func AnalyzeSQLInjection(pass *analysis.Pass, file *ast.File) {
+ scanner := NewSQLInjectionScanner()
+ violations := scanner.ScanFile(pass, file)
+
+ for _, v := range violations {
+ message := v.Message
+ if v.Suggestion != "" {
+ message += "\n Suggestion: " + v.Suggestion
+ }
+ if v.CodeFix != "" {
+ message += "\n Fix: " + v.CodeFix
+ }
+ if v.Severity != "" {
+ message = "[" + string(v.Severity) + "] " + message
+ }
+
+ pass.Report(analysis.Diagnostic{
+ Pos: v.Pos,
+ End: v.End,
+ Message: message,
+ })
+ }
+}
+
+// GetSQLInjectionViolations returns all SQL injection violations for external use.
+func GetSQLInjectionViolations(pass *analysis.Pass, file *ast.File) []SQLInjectionViolation {
+ scanner := NewSQLInjectionScanner()
+ return scanner.ScanFile(pass, file)
+}
+
+// ScanFileAST scans a file for SQL injection vulnerabilities without analysis.Pass.
+// This is designed for use in LSP server where we don't have a full analysis pass.
+func ScanFileAST(fset *token.FileSet, file *ast.File) []SQLInjectionViolation {
+ scanner := NewSQLInjectionScanner()
+ return scanner.ScanFileNoPass(fset, file)
+}
+
+// ScanFileNoPass scans a file for SQL injection vulnerabilities without analysis.Pass.
+// This is a method version for testing purposes.
+func (s *SQLInjectionScanner) ScanFileNoPass(fset *token.FileSet, file *ast.File) []SQLInjectionViolation {
+ s.pass = nil
+ var violations []SQLInjectionViolation
+
+ ast.Inspect(file, func(n ast.Node) bool {
+ switch node := n.(type) {
+ case *ast.CallExpr:
+ if v := s.checkCallExpr(node); v != nil {
+ violations = append(violations, *v)
+ }
+ case *ast.BinaryExpr:
+ if v := s.checkBinaryExpr(node); v != nil {
+ violations = append(violations, *v)
+ }
+ }
+ return true
+ })
+
+ return violations
+}
diff --git a/vendor/github.com/MirrexOne/unqueryvet/internal/analyzer/tx_leak_detector.go b/vendor/github.com/MirrexOne/unqueryvet/internal/analyzer/tx_leak_detector.go
new file mode 100644
index 000000000..afa3b68a4
--- /dev/null
+++ b/vendor/github.com/MirrexOne/unqueryvet/internal/analyzer/tx_leak_detector.go
@@ -0,0 +1,1665 @@
+package analyzer
+
+import (
+ "fmt"
+ "go/ast"
+ "go/token"
+ "strings"
+
+ "golang.org/x/tools/go/analysis"
+)
+
+// TxLeakSeverity represents the severity level of a transaction leak.
+type TxLeakSeverity string
+
+const (
+ TxLeakSeverityCritical TxLeakSeverity = "critical" // Begin without any Commit/Rollback
+ TxLeakSeverityHigh TxLeakSeverity = "high" // Begin with Commit but no Rollback in error path
+ TxLeakSeverityMedium TxLeakSeverity = "medium" // Begin with Rollback but no Commit
+ TxLeakSeverityLow TxLeakSeverity = "low" // Informational - potential issue
+)
+
+// TxLeakViolation represents a detected unclosed transaction.
+type TxLeakViolation struct {
+ Pos token.Pos
+ End token.Pos
+ Message string
+ Severity TxLeakSeverity
+ ViolationType string // violation type identifier
+ TxVarName string // Name of the transaction variable
+ Suggestion string
+}
+
+// TxState tracks the state of a transaction variable within a function.
+type TxState struct {
+ VarName string
+ BeginPos token.Pos
+ BeginEnd token.Pos
+ HasCommit bool
+ HasRollback bool
+ HasDefer bool // Rollback/Commit in defer
+ HasDeferredCommit bool // Commit() is in defer - antipattern
+ IsReturned bool // Transaction returned to caller
+ IsReturnedInClosure bool // Transaction captured by returned closure
+ IsCallback bool // Transaction used in callback pattern
+ IsPassedToFunc bool // Transaction passed to another function
+ IsSentToChannel bool // Transaction sent through channel (ch <- tx)
+ IsStoredInStruct bool // Transaction stored in struct field
+ IsStoredInCollection bool // Transaction stored in map or slice
+ IsCapturedByGoroutine bool // Transaction captured by goroutine
+ IsShadowed bool // Variable is shadowed in inner scope
+ ShadowedBy token.Pos // Position where shadowing occurs
+ HasPanicPath bool // Function has panic() without deferred rollback
+ HasFatalPath bool // Function has os.Exit/log.Fatal without deferred rollback
+ HasEarlyReturn bool // Has return before commit without defer
+ CommitInConditional bool // Commit is inside conditional block
+ CommitInSwitch bool // Commit is inside switch/case that might not execute
+ CommitInSelect bool // Commit is inside select/case that might not execute
+ CommitInLoop bool // Commit is inside loop that might not iterate
+ IsReassigned bool // Transaction variable is reassigned
+ CommitErrorIgnored bool // Commit() error is ignored with blank identifier
+ RollbackErrorIgnored bool // Rollback() error is ignored with blank identifier
+ HasDeferInLoop bool // Transaction has defer inside a loop (antipattern)
+ Scope int // Scope depth where transaction was created
+}
+
+// TxLeakDetector detects unclosed SQL transactions.
+type TxLeakDetector struct {
+ // beginMethods are methods that start a transaction
+ beginMethods map[string]bool
+ // commitMethods are methods that commit a transaction
+ commitMethods map[string]bool
+ // rollbackMethods are methods that rollback a transaction
+ rollbackMethods map[string]bool
+ // callbackMethods are methods that handle tx lifecycle automatically
+ callbackMethods map[string]bool
+ // txStates tracks all transaction states in current function
+ txStates map[string]*TxState
+ // scopeDepth tracks current scope depth for shadowing detection
+ scopeDepth int
+ // txScopes maps variable names to their scope depths for shadowing detection
+ txScopes map[string][]int
+}
+
+// NewTxLeakDetector creates a new transaction leak detector.
+func NewTxLeakDetector() *TxLeakDetector {
+ return &TxLeakDetector{
+ beginMethods: map[string]bool{
+ // database/sql
+ "Begin": true,
+ "BeginTx": true,
+ // sqlx
+ "BeginTxx": true,
+ "Beginx": true,
+ "MustBegin": true,
+ "MustBeginTx": true,
+ // pgx
+ "BeginFunc": true, // callback pattern - also in callbackMethods
+ // bun
+ "RunInTx": true, // callback pattern - also in callbackMethods
+ // ent ORM
+ "Tx": true,
+ // General
+ "NewTx": true,
+ },
+ commitMethods: map[string]bool{
+ "Commit": true,
+ },
+ rollbackMethods: map[string]bool{
+ "Rollback": true,
+ },
+ callbackMethods: map[string]bool{
+ // These handle tx lifecycle automatically
+ "Transaction": true,
+ "RunInTransaction": true,
+ "BeginFunc": true,
+ "BeginTxFunc": true, // pgx conn.BeginTxFunc
+ "RunInTx": true,
+ "WithTx": true,
+ "InTransaction": true,
+ "Transactional": true,
+ "ExecTx": true,
+ "DoInTx": true,
+ },
+ txStates: make(map[string]*TxState),
+ txScopes: make(map[string][]int),
+ }
+}
+
+// CheckTxLeaks analyzes a file for unclosed transaction patterns.
+func (d *TxLeakDetector) CheckTxLeaks(pass *analysis.Pass, file *ast.File) []TxLeakViolation {
+ var violations []TxLeakViolation
+
+ // Analyze each function declaration
+ for _, decl := range file.Decls {
+ funcDecl, ok := decl.(*ast.FuncDecl)
+ if !ok || funcDecl.Body == nil {
+ continue
+ }
+
+ // Skip test functions (TestXxx, BenchmarkXxx, FuzzXxx, ExampleXxx)
+ if isTestFunction(funcDecl) {
+ continue
+ }
+
+ // Skip test helper functions (functions with *testing.T as first param)
+ if isTestHelperFunction(funcDecl) {
+ continue
+ }
+
+ violations = append(violations, d.analyzeFunction(funcDecl)...)
+ }
+
+ return violations
+}
+
+// isTestFunction checks if a function declaration is a test function.
+// A test function has a name starting with Test/Benchmark/Fuzz/Example AND
+// the appropriate parameter signature (or no params for Example).
+func isTestFunction(funcDecl *ast.FuncDecl) bool {
+ name := funcDecl.Name.Name
+
+ // Check for Example functions (no required parameters)
+ if strings.HasPrefix(name, "Example") {
+ return true
+ }
+
+ // Check for Test, Benchmark, Fuzz functions
+ isTestPrefix := strings.HasPrefix(name, "Test") ||
+ strings.HasPrefix(name, "Benchmark") ||
+ strings.HasPrefix(name, "Fuzz")
+
+ if !isTestPrefix {
+ return false
+ }
+
+ // Must have at least one parameter
+ if funcDecl.Type.Params == nil || len(funcDecl.Type.Params.List) == 0 {
+ return false
+ }
+
+ // Check first parameter type
+ firstParam := funcDecl.Type.Params.List[0]
+ if firstParam.Type == nil {
+ return false
+ }
+
+ // Check for *testing.T, *testing.B, *testing.F
+ starExpr, ok := firstParam.Type.(*ast.StarExpr)
+ if !ok {
+ return false
+ }
+
+ selExpr, ok := starExpr.X.(*ast.SelectorExpr)
+ if !ok {
+ return false
+ }
+
+ ident, ok := selExpr.X.(*ast.Ident)
+ if !ok {
+ return false
+ }
+
+ if ident.Name != "testing" {
+ return false
+ }
+
+ expectedType := ""
+ if strings.HasPrefix(name, "Test") {
+ expectedType = "T"
+ } else if strings.HasPrefix(name, "Benchmark") {
+ expectedType = "B"
+ } else if strings.HasPrefix(name, "Fuzz") {
+ expectedType = "F"
+ }
+
+ return selExpr.Sel.Name == expectedType
+}
+
+// isTestHelperFunction checks if a function is a test helper by looking at its parameters.
+// Test helpers typically take *testing.T, *testing.B, or *testing.F as the first parameter.
+func isTestHelperFunction(funcDecl *ast.FuncDecl) bool {
+ if funcDecl.Type.Params == nil || len(funcDecl.Type.Params.List) == 0 {
+ return false
+ }
+
+ // Check first parameter
+ firstParam := funcDecl.Type.Params.List[0]
+ if firstParam.Type == nil {
+ return false
+ }
+
+ // Check for *testing.T, *testing.B, *testing.F
+ starExpr, ok := firstParam.Type.(*ast.StarExpr)
+ if !ok {
+ return false
+ }
+
+ selExpr, ok := starExpr.X.(*ast.SelectorExpr)
+ if !ok {
+ return false
+ }
+
+ ident, ok := selExpr.X.(*ast.Ident)
+ if !ok {
+ return false
+ }
+
+ if ident.Name == "testing" {
+ switch selExpr.Sel.Name {
+ case "T", "B", "F", "M":
+ return true
+ }
+ }
+
+ return false
+}
+
+// analyzeFunction analyzes a single function for transaction leaks.
+func (d *TxLeakDetector) analyzeFunction(funcDecl *ast.FuncDecl) []TxLeakViolation {
+ // Reset state for each function
+ d.txStates = make(map[string]*TxState)
+ d.txScopes = make(map[string][]int)
+ d.scopeDepth = 0
+
+ // Phase 1: Find transaction Begin points with scope tracking
+ d.findTransactionBeginsWithScope(funcDecl)
+
+ if len(d.txStates) == 0 {
+ return nil
+ }
+
+ // Phase 2: Check for callback patterns (handled automatically)
+ d.detectCallbackPatterns(funcDecl)
+
+ // Phase 3: Track Commit/Rollback calls
+ d.trackCommitRollback(funcDecl)
+
+ // Phase 4: Check for returned transactions
+ d.checkReturnStatements(funcDecl)
+
+ // Phase 5: Check for transactions passed to other functions
+ d.checkFunctionParameters(funcDecl)
+
+ // Phase 6: Check for transactions stored in struct fields
+ d.checkStructFieldStorage(funcDecl)
+
+ // Phase 6.5: Check for transactions sent through channels
+ d.checkChannelSend(funcDecl)
+
+ // Phase 7: Check for goroutine captures
+ d.checkGoroutineCaptures(funcDecl)
+
+ // Phase 8: Check for panic paths without defer
+ d.checkPanicPaths(funcDecl)
+
+ // Phase 9: Check for early returns without defer
+ d.checkEarlyReturns(funcDecl)
+
+ // Phase 10: Check for conditional commits
+ d.checkConditionalCommits(funcDecl)
+
+ // Phase 11: Check for switch/case commits
+ d.checkSwitchCaseCommits(funcDecl)
+
+ // Phase 12: Check for select/case commits
+ d.checkSelectCaseCommits(funcDecl)
+
+ // Phase 13: Check for os.Exit/log.Fatal paths
+ d.checkFatalPaths(funcDecl)
+
+ // Phase 14: Check for commit in loops
+ d.checkLoopCommits(funcDecl)
+
+ // Phase 15: Check for variable reassignment
+ d.checkVariableReassignment(funcDecl)
+
+ // Phase 16: Check for ignored commit errors
+ d.checkCommitErrorIgnored(funcDecl)
+
+ // Phase 17: Check for ignored rollback errors
+ d.checkRollbackErrorIgnored(funcDecl)
+
+ // Phase 18: Check for defer inside loop (antipattern)
+ d.checkDeferInLoop(funcDecl)
+
+ // Phase 19: Generate violations
+ return d.generateViolations()
+}
+
+// findTransactionBeginsWithScope finds all transaction Begin calls with scope tracking.
+func (d *TxLeakDetector) findTransactionBeginsWithScope(funcDecl *ast.FuncDecl) {
+ // First pass: find all transaction begins and their scopes
+ d.findBeginsRecursive(funcDecl.Body, 0)
+}
+
+// findBeginsRecursive recursively finds Begin calls with scope tracking.
+func (d *TxLeakDetector) findBeginsRecursive(node ast.Node, depth int) {
+ if node == nil {
+ return
+ }
+
+ ast.Inspect(node, func(n ast.Node) bool {
+ switch stmt := n.(type) {
+ case *ast.BlockStmt:
+ // Process block with increased depth
+ for _, s := range stmt.List {
+ d.findBeginsRecursive(s, depth+1)
+ }
+ return false // Don't recurse further, we handled it
+
+ case *ast.IfStmt:
+ // Process if statement parts with proper scoping
+ // The if body creates a new scope
+ if stmt.Init != nil {
+ d.findBeginsRecursive(stmt.Init, depth)
+ }
+ d.findBeginsRecursive(stmt.Body, depth+1) // if body is a new scope
+ if stmt.Else != nil {
+ d.findBeginsRecursive(stmt.Else, depth+1) // else is also a new scope
+ }
+ return false
+
+ case *ast.ForStmt:
+ if stmt.Init != nil {
+ d.findBeginsRecursive(stmt.Init, depth)
+ }
+ d.findBeginsRecursive(stmt.Body, depth+1) // for body is a new scope
+ return false
+
+ case *ast.RangeStmt:
+ d.findBeginsRecursive(stmt.Body, depth+1) // range body is a new scope
+ return false
+
+ case *ast.AssignStmt:
+ d.processAssignmentWithDepth(stmt, depth)
+ return true
+ }
+ return true
+ })
+}
+
+// processAssignmentWithDepth processes an assignment with explicit depth.
+func (d *TxLeakDetector) processAssignmentWithDepth(assignStmt *ast.AssignStmt, depth int) {
+ for i, rhs := range assignStmt.Rhs {
+ call, ok := rhs.(*ast.CallExpr)
+ if !ok {
+ continue
+ }
+
+ if d.isBeginCall(call) {
+ // Skip if this is a callback pattern method
+ if d.isCallbackMethod(call) {
+ continue
+ }
+
+ // Extract variable name from LHS
+ if i < len(assignStmt.Lhs) {
+ if ident, ok := assignStmt.Lhs[i].(*ast.Ident); ok {
+ // Skip error variables
+ if ident.Name == "err" || ident.Name == "_" {
+ continue
+ }
+
+ varName := ident.Name
+
+ // Check for shadowing - if variable exists in outer scope
+ if existingScopes, exists := d.txScopes[varName]; exists {
+ for _, existingScope := range existingScopes {
+ if existingScope < depth {
+ // This is shadowing - mark the outer transaction
+ // Find the state for the outer variable
+ for key, state := range d.txStates {
+ if state.VarName == varName && state.Scope == existingScope {
+ state.IsShadowed = true
+ state.ShadowedBy = assignStmt.Pos()
+ _ = key // used in iteration
+ break
+ }
+ }
+ }
+ }
+ }
+
+ // Track scope for this variable
+ d.txScopes[varName] = append(d.txScopes[varName], depth)
+
+ // Create unique key for this transaction
+ key := d.createTxKey(varName, depth, assignStmt.Pos())
+ d.txStates[key] = &TxState{
+ VarName: varName,
+ BeginPos: assignStmt.Pos(),
+ BeginEnd: assignStmt.End(),
+ Scope: depth,
+ }
+ }
+ }
+ }
+ }
+}
+
+// createTxKey creates a unique key for a transaction state.
+func (d *TxLeakDetector) createTxKey(varName string, scope int, pos token.Pos) string {
+ // Use position to create unique key for shadowed variables
+ return fmt.Sprintf("%s_%d_%d", varName, scope, pos)
+}
+
+// isBeginCall checks if a call expression is a transaction Begin method.
+func (d *TxLeakDetector) isBeginCall(call *ast.CallExpr) bool {
+ sel, ok := call.Fun.(*ast.SelectorExpr)
+ if !ok {
+ return false
+ }
+ return d.beginMethods[sel.Sel.Name]
+}
+
+// isCallbackMethod checks if a call expression is a callback-based transaction method.
+func (d *TxLeakDetector) isCallbackMethod(call *ast.CallExpr) bool {
+ sel, ok := call.Fun.(*ast.SelectorExpr)
+ if !ok {
+ return false
+ }
+ return d.callbackMethods[sel.Sel.Name]
+}
+
+// detectCallbackPatterns marks transactions that are used in callback patterns.
+func (d *TxLeakDetector) detectCallbackPatterns(funcDecl *ast.FuncDecl) {
+ ast.Inspect(funcDecl.Body, func(n ast.Node) bool {
+ call, ok := n.(*ast.CallExpr)
+ if !ok {
+ return true
+ }
+
+ sel, ok := call.Fun.(*ast.SelectorExpr)
+ if !ok {
+ return true
+ }
+
+ // Check if this is a callback transaction method
+ if d.callbackMethods[sel.Sel.Name] {
+ // Mark any tx parameters in the callback as handled
+ for _, arg := range call.Args {
+ if funcLit, ok := arg.(*ast.FuncLit); ok {
+ // Check parameters of the callback function
+ for _, param := range funcLit.Type.Params.List {
+ for _, name := range param.Names {
+ d.markAllStatesWithName(name.Name, func(s *TxState) {
+ s.IsCallback = true
+ })
+ }
+ }
+ }
+ }
+ }
+
+ return true
+ })
+}
+
+// markAllStatesWithName applies a function to all states with the given variable name.
+func (d *TxLeakDetector) markAllStatesWithName(varName string, fn func(*TxState)) {
+ for _, state := range d.txStates {
+ if state.VarName == varName {
+ fn(state)
+ }
+ }
+}
+
+// trackCommitRollback scans for Commit and Rollback calls on tracked transaction variables.
+func (d *TxLeakDetector) trackCommitRollback(funcDecl *ast.FuncDecl) {
+ ast.Inspect(funcDecl.Body, func(n ast.Node) bool {
+ switch node := n.(type) {
+ case *ast.GoStmt:
+ // Skip goroutines - defers inside goroutines don't protect the main function
+ // We track goroutine captures separately in checkGoroutineCaptures
+ return false
+
+ case *ast.DeferStmt:
+ // Check defer statements
+ d.checkDeferStatement(node)
+ return true
+
+ case *ast.CallExpr:
+ // Check direct Commit/Rollback calls
+ d.checkCommitRollbackCall(node, false)
+ return true
+ }
+ return true
+ })
+}
+
+// checkDeferStatement checks a defer statement for Commit/Rollback calls.
+func (d *TxLeakDetector) checkDeferStatement(deferStmt *ast.DeferStmt) {
+ call := deferStmt.Call
+ // Check for direct defer tx.Rollback()
+ d.checkCommitRollbackCall(call, true)
+
+ // Check for defer func() { ... }()
+ if funcLit, ok := call.Fun.(*ast.FuncLit); ok {
+ d.checkDeferredClosure(funcLit)
+ }
+
+ // Check for defer someFunc(tx) - function call with tx as argument
+ d.checkDeferredFunctionCall(call)
+}
+
+// checkDeferredFunctionCall checks if a deferred function call takes a transaction as argument.
+// This handles patterns like: defer cleanup(tx) where cleanup() might do Rollback.
+func (d *TxLeakDetector) checkDeferredFunctionCall(call *ast.CallExpr) {
+ // Check each argument to see if it's a tracked transaction variable
+ for _, arg := range call.Args {
+ switch a := arg.(type) {
+ case *ast.Ident:
+ // Direct variable: defer cleanup(tx)
+ d.markAllStatesWithName(a.Name, func(s *TxState) {
+ s.HasDefer = true
+ // We assume the function handles rollback since tx is passed to deferred call
+ })
+ case *ast.UnaryExpr:
+ // Pointer: defer cleanup(&tx)
+ if ident, ok := a.X.(*ast.Ident); ok {
+ d.markAllStatesWithName(ident.Name, func(s *TxState) {
+ s.HasDefer = true
+ })
+ }
+ }
+ }
+}
+
+// checkDeferredClosure checks a deferred closure for Commit/Rollback calls.
+func (d *TxLeakDetector) checkDeferredClosure(funcLit *ast.FuncLit) {
+ ast.Inspect(funcLit.Body, func(n ast.Node) bool {
+ if call, ok := n.(*ast.CallExpr); ok {
+ d.checkCommitRollbackCall(call, true)
+ }
+ return true
+ })
+}
+
+// checkCommitRollbackCall checks if a call is Commit or Rollback on a tracked transaction.
+func (d *TxLeakDetector) checkCommitRollbackCall(call *ast.CallExpr, inDefer bool) {
+ sel, ok := call.Fun.(*ast.SelectorExpr)
+ if !ok {
+ return
+ }
+
+ methodName := sel.Sel.Name
+
+ // Get the variable name being called on
+ var varName string
+ if ident, ok := sel.X.(*ast.Ident); ok {
+ varName = ident.Name
+ }
+
+ if varName == "" {
+ return
+ }
+
+ // Mark all states with this variable name
+ d.markAllStatesWithName(varName, func(state *TxState) {
+ if d.commitMethods[methodName] {
+ state.HasCommit = true
+ // Deferred commit is an antipattern
+ if inDefer {
+ state.HasDeferredCommit = true
+ }
+ }
+
+ if d.rollbackMethods[methodName] {
+ state.HasRollback = true
+ if inDefer {
+ state.HasDefer = true
+ }
+ }
+ })
+}
+
+// checkReturnStatements checks if any transaction variable is returned.
+func (d *TxLeakDetector) checkReturnStatements(funcDecl *ast.FuncDecl) {
+ ast.Inspect(funcDecl.Body, func(n ast.Node) bool {
+ retStmt, ok := n.(*ast.ReturnStmt)
+ if !ok {
+ return true
+ }
+
+ for _, result := range retStmt.Results {
+ switch r := result.(type) {
+ case *ast.Ident:
+ d.markAllStatesWithName(r.Name, func(s *TxState) {
+ s.IsReturned = true
+ })
+ case *ast.UnaryExpr:
+ // Handle &tx case (returning pointer)
+ if ident, ok := r.X.(*ast.Ident); ok {
+ d.markAllStatesWithName(ident.Name, func(s *TxState) {
+ s.IsReturned = true
+ })
+ }
+ case *ast.FuncLit:
+ // Handle closure return: return func() { tx.Commit() }
+ // Check if closure captures any tracked tx variables
+ d.checkClosureCaptures(r)
+ }
+ }
+ return true
+ })
+}
+
+// checkClosureCaptures checks if a closure captures any tracked transaction variables.
+func (d *TxLeakDetector) checkClosureCaptures(funcLit *ast.FuncLit) {
+ ast.Inspect(funcLit.Body, func(inner ast.Node) bool {
+ if ident, ok := inner.(*ast.Ident); ok {
+ d.markAllStatesWithName(ident.Name, func(s *TxState) {
+ s.IsReturnedInClosure = true
+ })
+ }
+ return true
+ })
+}
+
+// checkFunctionParameters checks if transaction is passed to another function.
+func (d *TxLeakDetector) checkFunctionParameters(funcDecl *ast.FuncDecl) {
+ ast.Inspect(funcDecl.Body, func(n ast.Node) bool {
+ call, ok := n.(*ast.CallExpr)
+ if !ok {
+ return true
+ }
+
+ // Skip if this is a Commit/Rollback call
+ if sel, ok := call.Fun.(*ast.SelectorExpr); ok {
+ if d.commitMethods[sel.Sel.Name] || d.rollbackMethods[sel.Sel.Name] {
+ return true
+ }
+ }
+
+ // Check each argument
+ for _, arg := range call.Args {
+ switch a := arg.(type) {
+ case *ast.Ident:
+ d.markAllStatesWithName(a.Name, func(s *TxState) {
+ s.IsPassedToFunc = true
+ })
+ case *ast.UnaryExpr:
+ if ident, ok := a.X.(*ast.Ident); ok {
+ d.markAllStatesWithName(ident.Name, func(s *TxState) {
+ s.IsPassedToFunc = true
+ })
+ }
+ }
+ }
+ return true
+ })
+}
+
+// checkStructFieldStorage checks if transaction is stored in a struct field.
+func (d *TxLeakDetector) checkStructFieldStorage(funcDecl *ast.FuncDecl) {
+ ast.Inspect(funcDecl.Body, func(n ast.Node) bool {
+ assignStmt, ok := n.(*ast.AssignStmt)
+ if !ok {
+ return true
+ }
+
+ for i, lhs := range assignStmt.Lhs {
+ // Check for struct field assignment: s.tx = tx
+ if sel, ok := lhs.(*ast.SelectorExpr); ok {
+ _ = sel // We have a selector on the left side
+ if i < len(assignStmt.Rhs) {
+ if ident, ok := assignStmt.Rhs[i].(*ast.Ident); ok {
+ d.markAllStatesWithName(ident.Name, func(s *TxState) {
+ s.IsStoredInStruct = true
+ })
+ }
+ }
+ }
+
+ // Check for map/slice assignment: txMap[key] = tx or txSlice[i] = tx
+ if indexExpr, ok := lhs.(*ast.IndexExpr); ok {
+ _ = indexExpr
+ if i < len(assignStmt.Rhs) {
+ if ident, ok := assignStmt.Rhs[i].(*ast.Ident); ok {
+ d.markAllStatesWithName(ident.Name, func(s *TxState) {
+ s.IsStoredInCollection = true
+ })
+ }
+ }
+ }
+ }
+
+ // Check for append: txSlice = append(txSlice, tx)
+ for _, rhs := range assignStmt.Rhs {
+ if call, ok := rhs.(*ast.CallExpr); ok {
+ if ident, ok := call.Fun.(*ast.Ident); ok && ident.Name == "append" {
+ // Check arguments after the first one
+ for j := 1; j < len(call.Args); j++ {
+ if argIdent, ok := call.Args[j].(*ast.Ident); ok {
+ d.markAllStatesWithName(argIdent.Name, func(s *TxState) {
+ s.IsStoredInCollection = true
+ })
+ }
+ }
+ }
+ }
+ }
+
+ return true
+ })
+}
+
+// checkChannelSend checks if transaction is sent through a channel.
+func (d *TxLeakDetector) checkChannelSend(funcDecl *ast.FuncDecl) {
+ ast.Inspect(funcDecl.Body, func(n ast.Node) bool {
+ sendStmt, ok := n.(*ast.SendStmt)
+ if !ok {
+ return true
+ }
+
+ // Check if value being sent is a tracked transaction: ch <- tx
+ if ident, ok := sendStmt.Value.(*ast.Ident); ok {
+ d.markAllStatesWithName(ident.Name, func(s *TxState) {
+ s.IsSentToChannel = true
+ })
+ }
+
+ // Also check for pointer: ch <- &tx
+ if unary, ok := sendStmt.Value.(*ast.UnaryExpr); ok {
+ if ident, ok := unary.X.(*ast.Ident); ok {
+ d.markAllStatesWithName(ident.Name, func(s *TxState) {
+ s.IsSentToChannel = true
+ })
+ }
+ }
+
+ return true
+ })
+}
+
+// checkGoroutineCaptures checks if transaction is captured by a goroutine.
+func (d *TxLeakDetector) checkGoroutineCaptures(funcDecl *ast.FuncDecl) {
+ ast.Inspect(funcDecl.Body, func(n ast.Node) bool {
+ goStmt, ok := n.(*ast.GoStmt)
+ if !ok {
+ return true
+ }
+
+ // Check what variables the goroutine captures
+ ast.Inspect(goStmt.Call, func(inner ast.Node) bool {
+ if ident, ok := inner.(*ast.Ident); ok {
+ d.markAllStatesWithName(ident.Name, func(s *TxState) {
+ s.IsCapturedByGoroutine = true
+ })
+ }
+ return true
+ })
+
+ return true
+ })
+}
+
+// checkPanicPaths checks if function has panic() without deferred rollback.
+func (d *TxLeakDetector) checkPanicPaths(funcDecl *ast.FuncDecl) {
+ hasPanic := false
+ ast.Inspect(funcDecl.Body, func(n ast.Node) bool {
+ call, ok := n.(*ast.CallExpr)
+ if !ok {
+ return true
+ }
+
+ if ident, ok := call.Fun.(*ast.Ident); ok {
+ if ident.Name == "panic" {
+ hasPanic = true
+ }
+ }
+ return true
+ })
+
+ if hasPanic {
+ for _, state := range d.txStates {
+ if !state.HasDefer {
+ state.HasPanicPath = true
+ }
+ }
+ }
+}
+
+// checkEarlyReturns checks for early returns before commit without defer.
+func (d *TxLeakDetector) checkEarlyReturns(funcDecl *ast.FuncDecl) {
+ // Track position of each tx Begin
+ txPositions := make(map[string]token.Pos)
+ for name, state := range d.txStates {
+ txPositions[name] = state.BeginPos
+ }
+
+ var returnPositions []token.Pos
+ var commitPositions []token.Pos
+
+ ast.Inspect(funcDecl.Body, func(n ast.Node) bool {
+ switch node := n.(type) {
+ case *ast.ReturnStmt:
+ returnPositions = append(returnPositions, node.Pos())
+ case *ast.CallExpr:
+ if sel, ok := node.Fun.(*ast.SelectorExpr); ok {
+ if d.commitMethods[sel.Sel.Name] {
+ commitPositions = append(commitPositions, node.Pos())
+ }
+ }
+ }
+ return true
+ })
+
+ // Check if there are returns before any commit
+ for _, state := range d.txStates {
+ if state.HasDefer {
+ continue // Defer handles early returns
+ }
+
+ for _, retPos := range returnPositions {
+ // If return is after Begin but before Commit
+ hasCommitBefore := false
+ for _, commitPos := range commitPositions {
+ if commitPos < retPos {
+ hasCommitBefore = true
+ break
+ }
+ }
+ if retPos > state.BeginPos && !hasCommitBefore {
+ state.HasEarlyReturn = true
+ break
+ }
+ }
+ }
+}
+
+// checkSwitchCaseCommits checks if Commit is inside switch/case that might not execute.
+func (d *TxLeakDetector) checkSwitchCaseCommits(funcDecl *ast.FuncDecl) {
+ ast.Inspect(funcDecl.Body, func(n ast.Node) bool {
+ switchStmt, ok := n.(*ast.SwitchStmt)
+ if !ok {
+ return true
+ }
+
+ // Count cases with commit
+ casesWithCommit := 0
+ totalCases := 0
+ hasDefault := false
+
+ for _, stmt := range switchStmt.Body.List {
+ caseClause, ok := stmt.(*ast.CaseClause)
+ if !ok {
+ continue
+ }
+ totalCases++
+
+ if caseClause.List == nil {
+ hasDefault = true
+ }
+
+ hasCommitInCase := false
+ ast.Inspect(caseClause, func(inner ast.Node) bool {
+ if call, ok := inner.(*ast.CallExpr); ok {
+ if sel, ok := call.Fun.(*ast.SelectorExpr); ok {
+ if d.commitMethods[sel.Sel.Name] {
+ hasCommitInCase = true
+ }
+ }
+ }
+ return true
+ })
+
+ if hasCommitInCase {
+ casesWithCommit++
+ }
+ }
+
+ // If commit is not in all cases (including default), it's problematic
+ if casesWithCommit > 0 && (casesWithCommit < totalCases || !hasDefault) {
+ for _, state := range d.txStates {
+ if state.HasCommit && !state.HasDefer {
+ state.CommitInSwitch = true
+ }
+ }
+ }
+
+ return true
+ })
+}
+
+// checkSelectCaseCommits checks if Commit is inside select/case that might not execute.
+func (d *TxLeakDetector) checkSelectCaseCommits(funcDecl *ast.FuncDecl) {
+ ast.Inspect(funcDecl.Body, func(n ast.Node) bool {
+ selectStmt, ok := n.(*ast.SelectStmt)
+ if !ok {
+ return true
+ }
+
+ // Count cases with commit
+ casesWithCommit := 0
+ totalCases := 0
+ hasDefault := false
+
+ for _, stmt := range selectStmt.Body.List {
+ commClause, ok := stmt.(*ast.CommClause)
+ if !ok {
+ continue
+ }
+ totalCases++
+
+ if commClause.Comm == nil {
+ hasDefault = true
+ }
+
+ hasCommitInCase := false
+ for _, bodyStmt := range commClause.Body {
+ ast.Inspect(bodyStmt, func(inner ast.Node) bool {
+ if call, ok := inner.(*ast.CallExpr); ok {
+ if sel, ok := call.Fun.(*ast.SelectorExpr); ok {
+ if d.commitMethods[sel.Sel.Name] {
+ hasCommitInCase = true
+ }
+ }
+ }
+ return true
+ })
+ }
+
+ if hasCommitInCase {
+ casesWithCommit++
+ }
+ }
+
+ // If commit is not in all cases (including default), it's problematic
+ if casesWithCommit > 0 && (casesWithCommit < totalCases || !hasDefault) {
+ for _, state := range d.txStates {
+ if state.HasCommit && !state.HasDefer {
+ state.CommitInSelect = true
+ }
+ }
+ }
+
+ return true
+ })
+}
+
+// checkFatalPaths checks if function has os.Exit or log.Fatal without deferred rollback.
+func (d *TxLeakDetector) checkFatalPaths(funcDecl *ast.FuncDecl) {
+ hasFatal := false
+ ast.Inspect(funcDecl.Body, func(n ast.Node) bool {
+ call, ok := n.(*ast.CallExpr)
+ if !ok {
+ return true
+ }
+
+ // Check for os.Exit
+ if sel, ok := call.Fun.(*ast.SelectorExpr); ok {
+ if ident, ok := sel.X.(*ast.Ident); ok {
+ // os.Exit, log.Fatal, log.Fatalf, log.Fatalln
+ if (ident.Name == "os" && sel.Sel.Name == "Exit") ||
+ (ident.Name == "log" && strings.HasPrefix(sel.Sel.Name, "Fatal")) {
+ hasFatal = true
+ }
+ }
+ }
+
+ return true
+ })
+
+ if hasFatal {
+ for _, state := range d.txStates {
+ if !state.HasDefer {
+ state.HasFatalPath = true
+ }
+ }
+ }
+}
+
+// checkLoopCommits checks if Commit is inside a loop that might not iterate.
+func (d *TxLeakDetector) checkLoopCommits(funcDecl *ast.FuncDecl) {
+ ast.Inspect(funcDecl.Body, func(n ast.Node) bool {
+ var loopBody *ast.BlockStmt
+
+ switch stmt := n.(type) {
+ case *ast.ForStmt:
+ loopBody = stmt.Body
+ case *ast.RangeStmt:
+ loopBody = stmt.Body
+ default:
+ return true
+ }
+
+ if loopBody == nil {
+ return true
+ }
+
+ // Check if Commit is inside the loop body
+ hasCommitInLoop := false
+ ast.Inspect(loopBody, func(inner ast.Node) bool {
+ if call, ok := inner.(*ast.CallExpr); ok {
+ if sel, ok := call.Fun.(*ast.SelectorExpr); ok {
+ if d.commitMethods[sel.Sel.Name] {
+ hasCommitInLoop = true
+ }
+ }
+ }
+ return true
+ })
+
+ if hasCommitInLoop {
+ for _, state := range d.txStates {
+ if state.HasCommit && !state.HasDefer {
+ state.CommitInLoop = true
+ }
+ }
+ }
+
+ return true
+ })
+}
+
+// checkVariableReassignment checks if transaction variable is reassigned.
+func (d *TxLeakDetector) checkVariableReassignment(funcDecl *ast.FuncDecl) {
+ // Track all Begin calls per variable name
+ beginCounts := make(map[string]int)
+
+ ast.Inspect(funcDecl.Body, func(n ast.Node) bool {
+ assignStmt, ok := n.(*ast.AssignStmt)
+ if !ok {
+ return true
+ }
+
+ for i, rhs := range assignStmt.Rhs {
+ call, ok := rhs.(*ast.CallExpr)
+ if !ok {
+ continue
+ }
+
+ if d.isBeginCall(call) {
+ if i < len(assignStmt.Lhs) {
+ if ident, ok := assignStmt.Lhs[i].(*ast.Ident); ok {
+ if ident.Name != "err" && ident.Name != "_" {
+ beginCounts[ident.Name]++
+ }
+ }
+ }
+ }
+ }
+ return true
+ })
+
+ // Mark variables that have multiple Begin calls as reassigned
+ for varName, count := range beginCounts {
+ if count > 1 {
+ d.markAllStatesWithName(varName, func(s *TxState) {
+ s.IsReassigned = true
+ })
+ }
+ }
+}
+
+// checkCommitErrorIgnored checks if Commit() error is ignored with blank identifier.
+func (d *TxLeakDetector) checkCommitErrorIgnored(funcDecl *ast.FuncDecl) {
+ ast.Inspect(funcDecl.Body, func(n ast.Node) bool {
+ assignStmt, ok := n.(*ast.AssignStmt)
+ if !ok {
+ return true
+ }
+
+ // Look for: _ = tx.Commit() or result, _ := tx.Commit()
+ for i, rhs := range assignStmt.Rhs {
+ call, ok := rhs.(*ast.CallExpr)
+ if !ok {
+ continue
+ }
+
+ sel, ok := call.Fun.(*ast.SelectorExpr)
+ if !ok {
+ continue
+ }
+
+ if d.commitMethods[sel.Sel.Name] {
+ // Check if the error is ignored
+ // For single assignment: _ = tx.Commit()
+ if len(assignStmt.Lhs) == 1 {
+ if ident, ok := assignStmt.Lhs[0].(*ast.Ident); ok && ident.Name == "_" {
+ if varIdent, ok := sel.X.(*ast.Ident); ok {
+ d.markAllStatesWithName(varIdent.Name, func(s *TxState) {
+ s.CommitErrorIgnored = true
+ })
+ }
+ }
+ }
+ // For tuple assignment: result, _ := someFunc() - check if error position is _
+ if len(assignStmt.Lhs) > i+1 {
+ if ident, ok := assignStmt.Lhs[i+1].(*ast.Ident); ok && ident.Name == "_" {
+ if varIdent, ok := sel.X.(*ast.Ident); ok {
+ d.markAllStatesWithName(varIdent.Name, func(s *TxState) {
+ s.CommitErrorIgnored = true
+ })
+ }
+ }
+ }
+ }
+ }
+ return true
+ })
+}
+
+// checkRollbackErrorIgnored checks if Rollback() error is ignored with blank identifier.
+func (d *TxLeakDetector) checkRollbackErrorIgnored(funcDecl *ast.FuncDecl) {
+ ast.Inspect(funcDecl.Body, func(n ast.Node) bool {
+ assignStmt, ok := n.(*ast.AssignStmt)
+ if !ok {
+ return true
+ }
+
+ // Look for: _ = tx.Rollback() or result, _ := tx.Rollback()
+ for i, rhs := range assignStmt.Rhs {
+ call, ok := rhs.(*ast.CallExpr)
+ if !ok {
+ continue
+ }
+
+ sel, ok := call.Fun.(*ast.SelectorExpr)
+ if !ok {
+ continue
+ }
+
+ if d.rollbackMethods[sel.Sel.Name] {
+ // Check if the error is ignored
+ // For single assignment: _ = tx.Rollback()
+ if len(assignStmt.Lhs) == 1 {
+ if ident, ok := assignStmt.Lhs[0].(*ast.Ident); ok && ident.Name == "_" {
+ if varIdent, ok := sel.X.(*ast.Ident); ok {
+ d.markAllStatesWithName(varIdent.Name, func(s *TxState) {
+ s.RollbackErrorIgnored = true
+ })
+ }
+ }
+ }
+ // For tuple assignment: result, _ := someFunc() - check if error position is _
+ if len(assignStmt.Lhs) > i+1 {
+ if ident, ok := assignStmt.Lhs[i+1].(*ast.Ident); ok && ident.Name == "_" {
+ if varIdent, ok := sel.X.(*ast.Ident); ok {
+ d.markAllStatesWithName(varIdent.Name, func(s *TxState) {
+ s.RollbackErrorIgnored = true
+ })
+ }
+ }
+ }
+ }
+ }
+ return true
+ })
+}
+
+// checkDeferInLoop checks if defer with transaction is inside a loop (antipattern).
+func (d *TxLeakDetector) checkDeferInLoop(funcDecl *ast.FuncDecl) {
+ // We need to track loop depth manually since ast.Inspect doesn't give us exit notification
+ var processNode func(n ast.Node, loopDepth int)
+ processNode = func(n ast.Node, loopDepth int) {
+ if n == nil {
+ return
+ }
+
+ switch node := n.(type) {
+ case *ast.ForStmt:
+ // Enter for loop - process body with increased depth
+ if node.Body != nil {
+ for _, stmt := range node.Body.List {
+ processNode(stmt, loopDepth+1)
+ }
+ }
+ case *ast.RangeStmt:
+ // Enter range loop - process body with increased depth
+ if node.Body != nil {
+ for _, stmt := range node.Body.List {
+ processNode(stmt, loopDepth+1)
+ }
+ }
+ case *ast.DeferStmt:
+ if loopDepth > 0 {
+ // Defer is inside a loop - check if it involves a tracked transaction
+ call := node.Call
+ if sel, ok := call.Fun.(*ast.SelectorExpr); ok {
+ if d.rollbackMethods[sel.Sel.Name] || d.commitMethods[sel.Sel.Name] {
+ if ident, ok := sel.X.(*ast.Ident); ok {
+ d.markAllStatesWithName(ident.Name, func(s *TxState) {
+ s.HasDeferInLoop = true
+ })
+ }
+ }
+ }
+ // Also check defer func() { tx.Rollback() }()
+ if funcLit, ok := call.Fun.(*ast.FuncLit); ok {
+ ast.Inspect(funcLit.Body, func(inner ast.Node) bool {
+ if innerCall, ok := inner.(*ast.CallExpr); ok {
+ if sel, ok := innerCall.Fun.(*ast.SelectorExpr); ok {
+ if d.rollbackMethods[sel.Sel.Name] || d.commitMethods[sel.Sel.Name] {
+ if ident, ok := sel.X.(*ast.Ident); ok {
+ d.markAllStatesWithName(ident.Name, func(s *TxState) {
+ s.HasDeferInLoop = true
+ })
+ }
+ }
+ }
+ }
+ return true
+ })
+ }
+ }
+ case *ast.BlockStmt:
+ for _, stmt := range node.List {
+ processNode(stmt, loopDepth)
+ }
+ case *ast.IfStmt:
+ if node.Init != nil {
+ processNode(node.Init, loopDepth)
+ }
+ processNode(node.Body, loopDepth)
+ if node.Else != nil {
+ processNode(node.Else, loopDepth)
+ }
+ case *ast.SwitchStmt:
+ processNode(node.Body, loopDepth)
+ case *ast.TypeSwitchStmt:
+ processNode(node.Body, loopDepth)
+ case *ast.SelectStmt:
+ processNode(node.Body, loopDepth)
+ case *ast.CaseClause:
+ for _, stmt := range node.Body {
+ processNode(stmt, loopDepth)
+ }
+ case *ast.CommClause:
+ for _, stmt := range node.Body {
+ processNode(stmt, loopDepth)
+ }
+ }
+ }
+
+ if funcDecl.Body != nil {
+ for _, stmt := range funcDecl.Body.List {
+ processNode(stmt, 0)
+ }
+ }
+}
+
+// checkConditionalCommits checks if Commit is inside a conditional block.
+func (d *TxLeakDetector) checkConditionalCommits(funcDecl *ast.FuncDecl) {
+ ast.Inspect(funcDecl.Body, func(n ast.Node) bool {
+ ifStmt, ok := n.(*ast.IfStmt)
+ if !ok {
+ return true
+ }
+
+ // Check if Commit is inside the if body
+ hasCommitInIf := false
+ ast.Inspect(ifStmt.Body, func(inner ast.Node) bool {
+ if call, ok := inner.(*ast.CallExpr); ok {
+ if sel, ok := call.Fun.(*ast.SelectorExpr); ok {
+ if d.commitMethods[sel.Sel.Name] {
+ hasCommitInIf = true
+ }
+ }
+ }
+ return true
+ })
+
+ // Check if Commit is NOT in else (meaning it might not execute)
+ hasCommitInElse := false
+ if ifStmt.Else != nil {
+ ast.Inspect(ifStmt.Else, func(inner ast.Node) bool {
+ if call, ok := inner.(*ast.CallExpr); ok {
+ if sel, ok := call.Fun.(*ast.SelectorExpr); ok {
+ if d.commitMethods[sel.Sel.Name] {
+ hasCommitInElse = true
+ }
+ }
+ }
+ return true
+ })
+ }
+
+ // If commit is only in one branch, it's conditional
+ if hasCommitInIf != hasCommitInElse {
+ for _, state := range d.txStates {
+ if state.HasCommit && !state.HasDefer {
+ state.CommitInConditional = true
+ }
+ }
+ }
+
+ return true
+ })
+}
+
+// generateViolations creates violations for unclosed transactions.
+func (d *TxLeakDetector) generateViolations() []TxLeakViolation {
+ var violations []TxLeakViolation
+
+ for _, state := range d.txStates {
+ // Skip if transaction is returned to caller
+ if state.IsReturned {
+ continue
+ }
+
+ // Skip if transaction is returned in a closure (lifecycle managed by caller)
+ if state.IsReturnedInClosure {
+ continue
+ }
+
+ // Skip if transaction is sent through a channel (lifecycle managed by receiver)
+ if state.IsSentToChannel {
+ continue
+ }
+
+ // Skip if using callback pattern
+ if state.IsCallback {
+ continue
+ }
+
+ // Skip if passed to another function (can't track inter-procedural)
+ // But warn if there's no defer as a safety net
+ if state.IsPassedToFunc && state.HasDefer {
+ continue
+ }
+
+ // Skip if stored in struct (can't track field lifecycle)
+ // But warn if there's no defer as a safety net
+ if state.IsStoredInStruct && state.HasDefer {
+ continue
+ }
+
+ // Skip if stored in collection (map/slice) with defer
+ // But warn if there's no defer as a safety net
+ if state.IsStoredInCollection && state.HasDefer {
+ continue
+ }
+
+ // Handle shadowing - this is always a problem
+ if state.IsShadowed {
+ violations = append(violations, TxLeakViolation{
+ Pos: state.BeginPos,
+ End: state.BeginEnd,
+ Message: "transaction " + state.VarName + " is shadowed by another transaction in inner scope",
+ Severity: TxLeakSeverityHigh,
+ ViolationType: "shadowed_transaction",
+ TxVarName: state.VarName,
+ Suggestion: "Use different variable names for nested transactions to avoid shadowing",
+ })
+ continue
+ }
+
+ // Handle goroutine capture - warn about potential issues
+ if state.IsCapturedByGoroutine && !state.HasDefer {
+ violations = append(violations, TxLeakViolation{
+ Pos: state.BeginPos,
+ End: state.BeginEnd,
+ Message: "transaction " + state.VarName + " is captured by goroutine without defer",
+ Severity: TxLeakSeverityHigh,
+ ViolationType: "goroutine_capture",
+ TxVarName: state.VarName,
+ Suggestion: "Ensure transaction is properly handled in goroutine with defer Rollback()",
+ })
+ continue
+ }
+
+ // Handle panic paths
+ if state.HasPanicPath && !state.HasDefer {
+ violations = append(violations, TxLeakViolation{
+ Pos: state.BeginPos,
+ End: state.BeginEnd,
+ Message: "transaction " + state.VarName + " may leak if panic() is called",
+ Severity: TxLeakSeverityMedium,
+ ViolationType: "panic_without_defer",
+ TxVarName: state.VarName,
+ Suggestion: "Add defer " + state.VarName + ".Rollback() to handle panic scenarios",
+ })
+ }
+
+ // Handle conditional commits
+ if state.CommitInConditional && !state.HasDefer {
+ violations = append(violations, TxLeakViolation{
+ Pos: state.BeginPos,
+ End: state.BeginEnd,
+ Message: "transaction " + state.VarName + " Commit() is inside conditional - may not execute",
+ Severity: TxLeakSeverityMedium,
+ ViolationType: "conditional_commit",
+ TxVarName: state.VarName,
+ Suggestion: "Ensure Commit() is called on all success paths or use defer pattern",
+ })
+ }
+
+ // Handle switch/case commits
+ if state.CommitInSwitch && !state.HasDefer {
+ violations = append(violations, TxLeakViolation{
+ Pos: state.BeginPos,
+ End: state.BeginEnd,
+ Message: "transaction " + state.VarName + " Commit() is inside switch/case - may not execute in all cases",
+ Severity: TxLeakSeverityMedium,
+ ViolationType: "commit_in_switch",
+ TxVarName: state.VarName,
+ Suggestion: "Ensure Commit() is called in all switch cases or use defer pattern",
+ })
+ }
+
+ // Handle select/case commits
+ if state.CommitInSelect && !state.HasDefer {
+ violations = append(violations, TxLeakViolation{
+ Pos: state.BeginPos,
+ End: state.BeginEnd,
+ Message: "transaction " + state.VarName + " Commit() is inside select/case - may not execute in all cases",
+ Severity: TxLeakSeverityMedium,
+ ViolationType: "commit_in_select",
+ TxVarName: state.VarName,
+ Suggestion: "Ensure Commit() is called in all select cases or use defer pattern",
+ })
+ }
+
+ // Handle fatal paths (os.Exit, log.Fatal)
+ if state.HasFatalPath && !state.HasDefer {
+ violations = append(violations, TxLeakViolation{
+ Pos: state.BeginPos,
+ End: state.BeginEnd,
+ Message: "transaction " + state.VarName + " may leak if os.Exit() or log.Fatal() is called",
+ Severity: TxLeakSeverityHigh,
+ ViolationType: "fatal_without_defer",
+ TxVarName: state.VarName,
+ Suggestion: "Add defer " + state.VarName + ".Rollback() to handle fatal exit scenarios (note: defers don't run on os.Exit)",
+ })
+ }
+
+ // Handle commit in loop
+ if state.CommitInLoop && !state.HasDefer {
+ violations = append(violations, TxLeakViolation{
+ Pos: state.BeginPos,
+ End: state.BeginEnd,
+ Message: "transaction " + state.VarName + " Commit() is inside loop - may not execute if loop doesn't iterate",
+ Severity: TxLeakSeverityMedium,
+ ViolationType: "commit_in_loop",
+ TxVarName: state.VarName,
+ Suggestion: "Move Commit() outside loop or ensure loop always iterates at least once",
+ })
+ }
+
+ // Handle variable reassignment
+ if state.IsReassigned {
+ violations = append(violations, TxLeakViolation{
+ Pos: state.BeginPos,
+ End: state.BeginEnd,
+ Message: "transaction variable " + state.VarName + " is reassigned - previous transaction may leak",
+ Severity: TxLeakSeverityHigh,
+ ViolationType: "variable_reassignment",
+ TxVarName: state.VarName,
+ Suggestion: "Commit or Rollback the first transaction before starting a new one, or use different variable names",
+ })
+ }
+
+ // Handle ignored commit error
+ if state.CommitErrorIgnored {
+ violations = append(violations, TxLeakViolation{
+ Pos: state.BeginPos,
+ End: state.BeginEnd,
+ Message: "transaction " + state.VarName + " Commit() error is ignored with blank identifier",
+ Severity: TxLeakSeverityLow,
+ ViolationType: "commit_error_ignored",
+ TxVarName: state.VarName,
+ Suggestion: "Handle the Commit() error - if it fails, the transaction is rolled back automatically",
+ })
+ }
+
+ // Handle deferred commit - antipattern
+ if state.HasDeferredCommit {
+ violations = append(violations, TxLeakViolation{
+ Pos: state.BeginPos,
+ End: state.BeginEnd,
+ Message: "transaction " + state.VarName + " uses defer Commit() - this is an antipattern",
+ Severity: TxLeakSeverityMedium,
+ ViolationType: "deferred_commit",
+ TxVarName: state.VarName,
+ Suggestion: "Use defer " + state.VarName + ".Rollback() and explicit Commit() at the end of the function",
+ })
+ }
+
+ // Handle ignored rollback error
+ if state.RollbackErrorIgnored {
+ violations = append(violations, TxLeakViolation{
+ Pos: state.BeginPos,
+ End: state.BeginEnd,
+ Message: "transaction " + state.VarName + " Rollback() error is ignored with blank identifier",
+ Severity: TxLeakSeverityLow,
+ ViolationType: "rollback_error_ignored",
+ TxVarName: state.VarName,
+ Suggestion: "Consider logging Rollback() errors for debugging - silent failures can hide issues",
+ })
+ }
+
+ // Handle defer inside loop - antipattern
+ if state.HasDeferInLoop {
+ violations = append(violations, TxLeakViolation{
+ Pos: state.BeginPos,
+ End: state.BeginEnd,
+ Message: "transaction " + state.VarName + " has defer inside loop - defers pile up until function returns",
+ Severity: TxLeakSeverityHigh,
+ ViolationType: "defer_in_loop",
+ TxVarName: state.VarName,
+ Suggestion: "Move transaction handling outside loop or use explicit Rollback()/Commit() in each iteration",
+ })
+ }
+
+ // Case 1: No Commit and no Rollback - Critical
+ if !state.HasCommit && !state.HasRollback {
+ msg := "unclosed transaction: " + state.VarName + " - missing both Commit() and Rollback()"
+ if state.IsPassedToFunc {
+ msg += " (passed to function - ensure it handles the transaction)"
+ }
+ if state.IsStoredInStruct {
+ msg += " (stored in struct - ensure lifecycle is managed)"
+ }
+
+ violations = append(violations, TxLeakViolation{
+ Pos: state.BeginPos,
+ End: state.BeginEnd,
+ Message: msg,
+ Severity: TxLeakSeverityCritical,
+ ViolationType: "no_commit_rollback",
+ TxVarName: state.VarName,
+ Suggestion: "Add defer " + state.VarName + ".Rollback() immediately after Begin(), then call Commit() on success",
+ })
+ continue
+ }
+
+ // Case 2: Has Commit but no Rollback - High
+ if state.HasCommit && !state.HasRollback {
+ violations = append(violations, TxLeakViolation{
+ Pos: state.BeginPos,
+ End: state.BeginEnd,
+ Message: "transaction " + state.VarName + " has Commit() but no Rollback() for error paths",
+ Severity: TxLeakSeverityHigh,
+ ViolationType: "no_rollback",
+ TxVarName: state.VarName,
+ Suggestion: "Add defer " + state.VarName + ".Rollback() to handle errors - it's safe to call after Commit()",
+ })
+ continue
+ }
+
+ // Case 3: Has Rollback but no Commit - Medium
+ if state.HasRollback && !state.HasCommit {
+ violations = append(violations, TxLeakViolation{
+ Pos: state.BeginPos,
+ End: state.BeginEnd,
+ Message: "transaction " + state.VarName + " has Rollback() but missing Commit()",
+ Severity: TxLeakSeverityMedium,
+ ViolationType: "no_commit",
+ TxVarName: state.VarName,
+ Suggestion: "Ensure Commit() is called on success path",
+ })
+ }
+
+ // Case 4: Early return without defer
+ if state.HasEarlyReturn && !state.HasDefer && state.HasCommit {
+ violations = append(violations, TxLeakViolation{
+ Pos: state.BeginPos,
+ End: state.BeginEnd,
+ Message: "transaction " + state.VarName + " has early return paths that bypass Commit()",
+ Severity: TxLeakSeverityHigh,
+ ViolationType: "early_return",
+ TxVarName: state.VarName,
+ Suggestion: "Add defer " + state.VarName + ".Rollback() to handle early returns safely",
+ })
+ }
+ }
+
+ return violations
+}
+
+// AnalyzeTxLeaks is a convenience function to run transaction leak detection on a file.
+func AnalyzeTxLeaks(pass *analysis.Pass, file *ast.File) {
+ detector := NewTxLeakDetector()
+ violations := detector.CheckTxLeaks(pass, file)
+
+ for _, v := range violations {
+ message := "[" + string(v.Severity) + "] " + v.Message
+ if v.Suggestion != "" {
+ message += "\n Suggestion: " + v.Suggestion
+ }
+
+ pass.Report(analysis.Diagnostic{
+ Pos: v.Pos,
+ End: v.End,
+ Message: message,
+ })
+ }
+}
+
+// GetTxLeakViolations returns all transaction leak violations for external use.
+func GetTxLeakViolations(pass *analysis.Pass, file *ast.File) []TxLeakViolation {
+ detector := NewTxLeakDetector()
+ return detector.CheckTxLeaks(pass, file)
+}
+
+// DetectTxLeaksInAST detects transaction leak problems in an AST file without analysis.Pass.
+// This is designed for use in LSP server where we don't have a full analysis pass.
+func DetectTxLeaksInAST(fset *token.FileSet, file *ast.File) []TxLeakViolation {
+ detector := NewTxLeakDetector()
+ var violations []TxLeakViolation
+
+ // Analyze each function declaration
+ for _, decl := range file.Decls {
+ funcDecl, ok := decl.(*ast.FuncDecl)
+ if !ok || funcDecl.Body == nil {
+ continue
+ }
+
+ // Skip test functions (TestXxx, BenchmarkXxx, FuzzXxx, ExampleXxx)
+ if isTestFunction(funcDecl) {
+ continue
+ }
+
+ // Skip test helper functions (functions with *testing.T as first param)
+ if isTestHelperFunction(funcDecl) {
+ continue
+ }
+
+ violations = append(violations, detector.analyzeFunction(funcDecl)...)
+ }
+
+ return violations
+}
diff --git a/vendor/github.com/MirrexOne/unqueryvet/pkg/config/config.go b/vendor/github.com/MirrexOne/unqueryvet/pkg/config/config.go
index 1f201b526..06b564f12 100644
--- a/vendor/github.com/MirrexOne/unqueryvet/pkg/config/config.go
+++ b/vendor/github.com/MirrexOne/unqueryvet/pkg/config/config.go
@@ -1,6 +1,38 @@
// Package config provides configuration structures for Unqueryvet analyzer.
package config
+// CustomRule represents a user-defined DSL rule for SQL analysis.
+type CustomRule struct {
+ // ID is a unique identifier for the rule.
+ ID string `mapstructure:"id" json:"id" yaml:"id"`
+
+ // Pattern is the SQL or code pattern to match.
+ // Supports metavariables like $TABLE, $VAR, etc.
+ Pattern string `mapstructure:"pattern" json:"pattern" yaml:"pattern"`
+
+ // Patterns allows multiple patterns for a single rule.
+ Patterns []string `mapstructure:"patterns" json:"patterns" yaml:"patterns,omitempty"`
+
+ // When is an optional condition expression (evaluated with expr-lang).
+ // Available variables: file, package, function, query, table, in_loop, etc.
+ When string `mapstructure:"when" json:"when" yaml:"when,omitempty"`
+
+ // Message is the diagnostic message shown when the rule triggers.
+ Message string `mapstructure:"message" json:"message" yaml:"message,omitempty"`
+
+ // Severity is the severity level (error, warning, info, ignore).
+ Severity string `mapstructure:"severity" json:"severity" yaml:"severity,omitempty"`
+
+ // Action determines what to do when the pattern matches (report, allow, ignore).
+ Action string `mapstructure:"action" json:"action" yaml:"action,omitempty"`
+
+ // Fix is an optional suggested fix message.
+ Fix string `mapstructure:"fix" json:"fix" yaml:"fix,omitempty"`
+}
+
+// RuleSeverity maps built-in rule IDs to their severity levels.
+type RuleSeverity map[string]string
+
// UnqueryvetSettings holds the configuration for the Unqueryvet analyzer.
type UnqueryvetSettings struct {
// CheckSQLBuilders enables checking SQL builders like Squirrel for SELECT * usage
@@ -38,6 +70,29 @@ type UnqueryvetSettings struct {
// SQLBuilders defines which SQL builder libraries to check
SQLBuilders SQLBuildersConfig `mapstructure:"sql-builders" json:"sql-builders" yaml:"sql-builders"`
+
+ // Rules is a map of built-in rule IDs to their severity (error, warning, info, ignore).
+ // Example: {"select-star": "error", "n1-queries": "warning"}
+ Rules RuleSeverity `mapstructure:"rules" json:"rules" yaml:"rules,omitempty"`
+
+ // CustomRules is a list of user-defined DSL rules.
+ CustomRules []CustomRule `mapstructure:"custom-rules" json:"custom-rules" yaml:"custom-rules,omitempty"`
+
+ // Allow is a list of SQL patterns to allow (whitelist).
+ // These patterns will not trigger any warnings.
+ Allow []string `mapstructure:"allow" json:"allow" yaml:"allow,omitempty"`
+
+ // Ignore is a list of file patterns to ignore (in addition to IgnoredFiles).
+ Ignore []string `mapstructure:"ignore" json:"ignore" yaml:"ignore,omitempty"`
+
+ // N1DetectionEnabled global flag for N+1 detection
+ N1DetectionEnabled bool `mapstructure:"check-n1-queries" json:"check-n1-queries" yaml:"check-n1-queries,omitempty"`
+
+ // SQLInjectionDetectionEnabled global flag for SQL injection detection
+ SQLInjectionDetectionEnabled bool `mapstructure:"check-sql-injection" json:"check-sql-injection" yaml:"check-sql-injection,omitempty"`
+
+ // TxLeakDetectionEnabled global flag for unclosed transaction detection
+ TxLeakDetectionEnabled bool `mapstructure:"check-tx-leaks" json:"check-tx-leaks" yaml:"check-tx-leaks,omitempty"`
}
// SQLBuildersConfig defines which SQL builder libraries to analyze.
@@ -65,6 +120,18 @@ type SQLBuildersConfig struct {
// Jet enables checking github.com/go-jet/jet
Jet bool `mapstructure:"jet" json:"jet" yaml:"jet"`
+
+ // Sqlc enables checking github.com/sqlc-dev/sqlc generated code
+ Sqlc bool `mapstructure:"sqlc" json:"sqlc" yaml:"sqlc"`
+
+ // Goqu enables checking github.com/doug-martin/goqu
+ Goqu bool `mapstructure:"goqu" json:"goqu" yaml:"goqu"`
+
+ // Rel enables checking github.com/go-rel/rel
+ Rel bool `mapstructure:"rel" json:"rel" yaml:"rel"`
+
+ // Reform enables checking gopkg.in/reform.v1
+ Reform bool `mapstructure:"reform" json:"reform" yaml:"reform"`
}
// DefaultSQLBuildersConfig returns the default SQL builders configuration with all checkers enabled.
@@ -78,6 +145,10 @@ func DefaultSQLBuildersConfig() SQLBuildersConfig {
Bun: true,
SQLBoiler: true,
Jet: true,
+ Sqlc: true,
+ Goqu: true,
+ Rel: true,
+ Reform: true,
}
}
@@ -85,13 +156,16 @@ func DefaultSQLBuildersConfig() SQLBuildersConfig {
// By default, all detection features are enabled for maximum coverage.
func DefaultSettings() UnqueryvetSettings {
return UnqueryvetSettings{
- CheckSQLBuilders: true,
- CheckAliasedWildcard: true,
- CheckStringConcat: true,
- CheckFormatStrings: true,
- CheckStringBuilder: true,
- CheckSubqueries: true,
- Severity: "warning",
+ CheckSQLBuilders: true,
+ CheckAliasedWildcard: true,
+ CheckStringConcat: true,
+ CheckFormatStrings: true,
+ CheckStringBuilder: true,
+ CheckSubqueries: true,
+ N1DetectionEnabled: true,
+ SQLInjectionDetectionEnabled: true,
+ TxLeakDetectionEnabled: true,
+ Severity: "warning",
AllowedPatterns: []string{
`(?i)COUNT\(\s*\*\s*\)`,
`(?i)MAX\(\s*\*\s*\)`,
@@ -103,5 +177,11 @@ func DefaultSettings() UnqueryvetSettings {
IgnoredFunctions: []string{},
IgnoredFiles: []string{},
SQLBuilders: DefaultSQLBuildersConfig(),
+ Rules: RuleSeverity{
+ "select-star": "warning",
+ "n1-queries": "warning",
+ "sql-injection": "error",
+ "tx-leak": "warning",
+ },
}
}
diff --git a/vendor/github.com/MirrexOne/unqueryvet/schema.json b/vendor/github.com/MirrexOne/unqueryvet/schema.json
new file mode 100644
index 000000000..f4df7b18a
--- /dev/null
+++ b/vendor/github.com/MirrexOne/unqueryvet/schema.json
@@ -0,0 +1,270 @@
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "$id": "https://raw.githubusercontent.com/MirrexOne/unqueryvet/main/schema.json",
+ "title": "unqueryvet configuration",
+ "description": "Configuration schema for unqueryvet - a Go static analysis tool for SQL queries",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "rules": {
+ "type": "object",
+ "description": "Built-in rules severity configuration",
+ "additionalProperties": false,
+ "properties": {
+ "select-star": {
+ "$ref": "#/definitions/severity",
+ "description": "Severity for SELECT * detection"
+ },
+ "n1-queries": {
+ "$ref": "#/definitions/severity",
+ "description": "Severity for N+1 query detection"
+ },
+ "sql-injection": {
+ "$ref": "#/definitions/severity",
+ "description": "Severity for SQL injection detection"
+ },
+ "tx-leak": {
+ "$ref": "#/definitions/severity",
+ "description": "Severity for transaction leak detection"
+ }
+ }
+ },
+ "ignore": {
+ "type": "array",
+ "description": "File patterns to ignore (glob syntax)",
+ "items": {
+ "type": "string"
+ },
+ "examples": [["*_test.go", "testdata/**", "vendor/**"]]
+ },
+ "allow": {
+ "type": "array",
+ "description": "SQL patterns to whitelist (won't trigger warnings)",
+ "items": {
+ "type": "string"
+ },
+ "examples": [["COUNT(*)", "information_schema.*"]]
+ },
+ "severity": {
+ "$ref": "#/definitions/severityLevel",
+ "description": "Default diagnostic severity: 'error' or 'warning'",
+ "default": "warning"
+ },
+ "check-sql-builders": {
+ "type": "boolean",
+ "description": "Enable SQL builder library checking",
+ "default": true
+ },
+ "check-aliased-wildcard": {
+ "type": "boolean",
+ "description": "Enable aliased wildcard detection (e.g., SELECT t.*)",
+ "default": true
+ },
+ "check-string-concat": {
+ "type": "boolean",
+ "description": "Enable string concatenation analysis",
+ "default": true
+ },
+ "check-format-strings": {
+ "type": "boolean",
+ "description": "Enable format string analysis (e.g., fmt.Sprintf)",
+ "default": true
+ },
+ "check-string-builder": {
+ "type": "boolean",
+ "description": "Enable strings.Builder analysis",
+ "default": true
+ },
+ "check-subqueries": {
+ "type": "boolean",
+ "description": "Enable SELECT * detection in subqueries",
+ "default": true
+ },
+ "sql-builders": {
+ "type": "object",
+ "description": "SQL builder libraries to check",
+ "additionalProperties": false,
+ "properties": {
+ "squirrel": {
+ "type": "boolean",
+ "description": "Check github.com/Masterminds/squirrel",
+ "default": true
+ },
+ "gorm": {
+ "type": "boolean",
+ "description": "Check gorm.io/gorm",
+ "default": true
+ },
+ "sqlx": {
+ "type": "boolean",
+ "description": "Check github.com/jmoiron/sqlx",
+ "default": true
+ },
+ "ent": {
+ "type": "boolean",
+ "description": "Check entgo.io/ent",
+ "default": true
+ },
+ "pgx": {
+ "type": "boolean",
+ "description": "Check github.com/jackc/pgx",
+ "default": true
+ },
+ "bun": {
+ "type": "boolean",
+ "description": "Check github.com/uptrace/bun",
+ "default": true
+ },
+ "sqlboiler": {
+ "type": "boolean",
+ "description": "Check github.com/volatiletech/sqlboiler",
+ "default": true
+ },
+ "jet": {
+ "type": "boolean",
+ "description": "Check github.com/go-jet/jet",
+ "default": true
+ },
+ "sqlc": {
+ "type": "boolean",
+ "description": "Check sqlc generated code",
+ "default": true
+ },
+ "goqu": {
+ "type": "boolean",
+ "description": "Check github.com/doug-martin/goqu",
+ "default": true
+ },
+ "rel": {
+ "type": "boolean",
+ "description": "Check github.com/go-rel/rel",
+ "default": true
+ },
+ "reform": {
+ "type": "boolean",
+ "description": "Check gopkg.in/reform.v1",
+ "default": true
+ }
+ }
+ },
+ "ignored-files": {
+ "type": "array",
+ "description": "Legacy: File patterns to ignore (use 'ignore' instead)",
+ "items": {
+ "type": "string"
+ },
+ "deprecated": true
+ },
+ "ignored-functions": {
+ "type": "array",
+ "description": "Function patterns to ignore (regex)",
+ "items": {
+ "type": "string"
+ },
+ "examples": [["debug\\..*", "test.*"]]
+ },
+ "allowed-patterns": {
+ "type": "array",
+ "description": "Legacy: Regex patterns to allow (use 'allow' instead)",
+ "items": {
+ "type": "string"
+ },
+ "deprecated": true
+ },
+ "custom-rules": {
+ "type": "array",
+ "description": "Custom analysis rules using DSL",
+ "items": {
+ "$ref": "#/definitions/customRule"
+ }
+ },
+ "output": {
+ "type": "object",
+ "description": "Output configuration options",
+ "additionalProperties": false,
+ "properties": {
+ "format": {
+ "type": "string",
+ "enum": ["text", "json", "sarif"],
+ "description": "Output format",
+ "default": "text"
+ },
+ "color": {
+ "type": "string",
+ "enum": ["auto", "always", "never"],
+ "description": "Color output mode",
+ "default": "auto"
+ },
+ "verbose": {
+ "type": "boolean",
+ "description": "Enable verbose output",
+ "default": false
+ },
+ "quiet": {
+ "type": "boolean",
+ "description": "Quiet mode (only errors)",
+ "default": false
+ }
+ }
+ }
+ },
+ "definitions": {
+ "severity": {
+ "type": "string",
+ "enum": ["error", "warning", "info", "ignore"],
+ "description": "Severity level for a rule"
+ },
+ "severityLevel": {
+ "type": "string",
+ "enum": ["error", "warning"],
+ "description": "Default severity level"
+ },
+ "customRule": {
+ "type": "object",
+ "description": "Custom analysis rule definition",
+ "required": ["id"],
+ "additionalProperties": false,
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "Unique identifier for the rule",
+ "pattern": "^[a-z][a-z0-9-]*$"
+ },
+ "pattern": {
+ "type": "string",
+ "description": "SQL/code pattern to match (supports metavariables: $TABLE, $VAR, $QUERY, $COLS, $DB, $EXPR)"
+ },
+ "patterns": {
+ "type": "array",
+ "description": "Multiple patterns (any match triggers the rule)",
+ "items": {
+ "type": "string"
+ }
+ },
+ "when": {
+ "type": "string",
+ "description": "Condition expression using expr-lang syntax. Available variables: file, package, function, query, query_type, table, tables, columns, has_join, has_where, in_loop, loop_depth, builder"
+ },
+ "message": {
+ "type": "string",
+ "description": "Diagnostic message to display when rule matches"
+ },
+ "severity": {
+ "$ref": "#/definitions/severity",
+ "description": "Severity level for this rule"
+ },
+ "action": {
+ "type": "string",
+ "enum": ["report", "allow", "ignore"],
+ "description": "Action to take when rule matches",
+ "default": "report"
+ },
+ "fix": {
+ "type": "string",
+ "description": "Suggested fix message"
+ }
+ },
+ "oneOf": [{ "required": ["pattern"] }, { "required": ["patterns"] }]
+ }
+ }
+}
diff --git a/vendor/github.com/alecthomas/chroma/v2/AGENTS.md b/vendor/github.com/alecthomas/chroma/v2/AGENTS.md
new file mode 100644
index 000000000..0d3b6ee49
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/AGENTS.md
@@ -0,0 +1,11 @@
+Chroma is a syntax highlighting library, tool and web playground for Go. It is based on Pygments and includes importers for it, so most of the same concepts from Pygments apply to Chroma.
+
+This project is written in Go, uses Hermit to manage tooling, and Just for helper commands. Helper scripts are in ./scripts.
+
+Language definitions are XML files defined in ./lexers/embedded/*.xml.
+
+Styles/themes are defined in ./styles/*.xml.
+
+The CLI can be run with `chroma`.
+
+The web playground can be run with `chromad --csrf-key=moo`. It blocks, so should generally be run in the background. It also does not hot reload, so has to be manually restarted. The playground has two modes - for local development it uses the server itself to render, while for production running `just chromad` will compile ./cmd/libchromawasm into a WASM module that is bundled into `chromad`.
diff --git a/vendor/github.com/alecthomas/chroma/v2/COPYING b/vendor/github.com/alecthomas/chroma/v2/COPYING
index 92dc39f70..33da48981 100644
--- a/vendor/github.com/alecthomas/chroma/v2/COPYING
+++ b/vendor/github.com/alecthomas/chroma/v2/COPYING
@@ -17,3 +17,102 @@ 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.
+
+
+// formatters/svg/font_liberation_mono.go
+
+Digitized data copyright (c) 2010 Google Corporation
+with Reserved Font Arimo, Tinos and Cousine.
+Copyright (c) 2012 Red Hat, Inc.
+with Reserved Font Name Liberation.
+
+This Font Software is licensed under the SIL Open Font License, Version 1.1.
+This license is copied below, and is also available with a FAQ at:
+https://openfontlicense.org
+
+-----------------------------------------------------------
+SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
+-----------------------------------------------------------
+
+PREAMBLE
+The goals of the Open Font License (OFL) are to stimulate worldwide
+development of collaborative font projects, to support the font creation
+efforts of academic and linguistic communities, and to provide a free and
+open framework in which fonts may be shared and improved in partnership
+with others.
+
+The OFL allows the licensed fonts to be used, studied, modified and
+redistributed freely as long as they are not sold by themselves. The
+fonts, including any derivative works, can be bundled, embedded,
+redistributed and/or sold with any software provided that any reserved
+names are not used by derivative works. The fonts and derivatives,
+however, cannot be released under any other type of license. The
+requirement for fonts to remain under this license does not apply
+to any document created using the fonts or their derivatives.
+
+DEFINITIONS
+"Font Software" refers to the set of files released by the Copyright
+Holder(s) under this license and clearly marked as such. This may
+include source files, build scripts and documentation.
+
+"Reserved Font Name" refers to any names specified as such after the
+copyright statement(s).
+
+"Original Version" refers to the collection of Font Software components as
+distributed by the Copyright Holder(s).
+
+"Modified Version" refers to any derivative made by adding to, deleting,
+or substituting -- in part or in whole -- any of the components of the
+Original Version, by changing formats or by porting the Font Software to a
+new environment.
+
+"Author" refers to any designer, engineer, programmer, technical
+writer or other person who contributed to the Font Software.
+
+PERMISSION & CONDITIONS
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of the Font Software, to use, study, copy, merge, embed, modify,
+redistribute, and sell modified and unmodified copies of the Font
+Software, subject to the following conditions:
+
+1) Neither the Font Software nor any of its individual components,
+in Original or Modified Versions, may be sold by itself.
+
+2) Original or Modified Versions of the Font Software may be bundled,
+redistributed and/or sold with any software, provided that each copy
+contains the above copyright notice and this license. These can be
+included either as stand-alone text files, human-readable headers or
+in the appropriate machine-readable metadata fields within text or
+binary files as long as those fields can be easily viewed by the user.
+
+3) No Modified Version of the Font Software may use the Reserved Font
+Name(s) unless explicit written permission is granted by the corresponding
+Copyright Holder. This restriction only applies to the primary font name as
+presented to the users.
+
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
+Software shall not be used to promote, endorse or advertise any
+Modified Version, except to acknowledge the contribution(s) of the
+Copyright Holder(s) and the Author(s) or with their explicit written
+permission.
+
+5) The Font Software, modified or unmodified, in part or in whole,
+must be distributed entirely under this license, and must not be
+distributed under any other license. The requirement for fonts to
+remain under this license does not apply to any document created
+using the Font Software.
+
+TERMINATION
+This license becomes null and void if any of the above conditions are
+not met.
+
+DISCLAIMER
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
+DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
+OTHER DEALINGS IN THE FONT SOFTWARE.
diff --git a/vendor/github.com/alecthomas/chroma/v2/Dockerfile b/vendor/github.com/alecthomas/chroma/v2/Dockerfile
index bd55da067..8a706766d 100644
--- a/vendor/github.com/alecthomas/chroma/v2/Dockerfile
+++ b/vendor/github.com/alecthomas/chroma/v2/Dockerfile
@@ -1,13 +1,12 @@
# Multi-stage Dockerfile for chromad Go application using Hermit-managed tools
# Build stage
-FROM ubuntu:24.04 AS builder
+FROM ubuntu:26.04 AS builder
# Install system dependencies
RUN apt-get update && apt-get install -y \
curl \
git \
- make \
ca-certificates \
&& rm -rf /var/lib/apt/lists/*
@@ -25,8 +24,8 @@ ENV CGO_ENABLED=0
ENV GOOS=linux
ENV GOARCH=amd64
-# Build the application using make
-RUN make build/chromad
+# Build the application using just
+RUN just chromad
# Runtime stage
FROM alpine:3.23 AS runtime
diff --git a/vendor/github.com/alecthomas/chroma/v2/Justfile b/vendor/github.com/alecthomas/chroma/v2/Justfile
new file mode 100644
index 000000000..24e3816f1
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/Justfile
@@ -0,0 +1,55 @@
+set positional-arguments := true
+set shell := ["bash", "-c"]
+
+version := `git describe --tags --dirty --always`
+export GOOS := env("GOOS", "linux")
+export GOARCH := env("GOARCH", "amd64")
+
+_help:
+ @just -l
+
+# Generate README.md from lexer definitions
+readme:
+ #!/usr/bin/env bash
+ GOOS= GOARCH= ./table.py
+
+# Generate tokentype_string.go
+tokentype-string:
+ go generate
+
+# Format JavaScript files
+format-js:
+ biome format --write cmd/chromad/static/index.js cmd/chromad/static/chroma.js
+
+# Build chromad binary
+chromad: wasm-exec chroma-wasm
+ #!/usr/bin/env bash
+ rm -rf build
+ mk cmd/chromad/static/index.min.js : cmd/chromad/static/{index,chroma}.js -- \
+ esbuild --platform=browser --format=esm --bundle cmd/chromad/static/index.js --minify --external:./wasm_exec.js --outfile=cmd/chromad/static/index.min.js
+ mk cmd/chromad/static/index.min.css : cmd/chromad/static/index.css -- \
+ esbuild --bundle cmd/chromad/static/index.css --minify --outfile=cmd/chromad/static/index.min.css
+ cd cmd/chromad && CGOENABLED=0 go build -ldflags="-X 'main.version={{ version }}'" -o ../../build/chromad .
+
+# Copy wasm_exec.js from TinyGo
+wasm-exec:
+ #!/usr/bin/env bash
+ tinygoroot=$(tinygo env TINYGOROOT)
+ mk cmd/chromad/static/wasm_exec.js : "$tinygoroot/targets/wasm_exec.js" -- \
+ install -m644 "$tinygoroot/targets/wasm_exec.js" cmd/chromad/static/wasm_exec.js
+
+# Build WASM binary
+chroma-wasm:
+ #!/usr/bin/env bash
+ if type tinygo > /dev/null 2>&1; then
+ mk cmd/chromad/static/chroma.wasm : cmd/libchromawasm/main.go -- \
+ tinygo build -no-debug -target wasm -o cmd/chromad/static/chroma.wasm cmd/libchromawasm/main.go
+ else
+ mk cmd/chromad/static/chroma.wasm : cmd/libchromawasm/main.go -- \
+ GOOS=js GOARCH=wasm go build -o cmd/chromad/static/chroma.wasm cmd/libchromawasm/main.go
+ fi
+
+# Upload chromad to server
+upload: chromad
+ scp build/chromad root@swapoff.org:
+ ssh root@swapoff.org 'install -m755 ./chromad /srv/http/swapoff.org/bin && service chromad restart'
diff --git a/vendor/github.com/alecthomas/chroma/v2/Makefile b/vendor/github.com/alecthomas/chroma/v2/Makefile
deleted file mode 100644
index ca89f7cb0..000000000
--- a/vendor/github.com/alecthomas/chroma/v2/Makefile
+++ /dev/null
@@ -1,42 +0,0 @@
-.PHONY: chromad upload all
-
-VERSION ?= $(shell git describe --tags --dirty --always)
-export GOOS ?= linux
-export GOARCH ?= amd64
-
-all: README.md tokentype_string.go
-
-README.md: lexers/*.go lexers/embedded/*.xml
- GOOS= GOARCH= ./table.py
-
-tokentype_string.go: types.go
- go generate
-
-.PHONY: format-js
-format-js:
- biome format --write cmd/chromad/static/{index.js,chroma.js}
-
-.PHONY: chromad
-chromad: build/chromad
-
-build/chromad: $(shell find cmd/chromad -name '*.go' -o -name '*.html' -o -name '*.css' -o -name '*.js') \
- cmd/chromad/static/wasm_exec.js \
- cmd/chromad/static/chroma.wasm
- rm -rf build
- esbuild --platform=node --bundle cmd/chromad/static/index.js --minify --outfile=cmd/chromad/static/index.min.js
- esbuild --bundle cmd/chromad/static/index.css --minify --outfile=cmd/chromad/static/index.min.css
- (export CGOENABLED=0 ; go build -C cmd/chromad -ldflags="-X 'main.version=$(VERSION)'" -o ../../build/chromad .)
-
-cmd/chromad/static/wasm_exec.js: $(shell tinygo env TINYGOROOT)/targets/wasm_exec.js
- install -m644 $< $@
-
-cmd/chromad/static/chroma.wasm: $(shell git ls-files | grep '\.go|\.xml')
- if type tinygo > /dev/null; then \
- tinygo build -no-debug -target wasm -o $@ cmd/libchromawasm/main.go; \
- else \
- GOOS=js GOARCH=wasm go build -o $@ cmd/libchromawasm/main.go; \
- fi
-
-upload: build/chromad
- scp build/chromad root@swapoff.org: && \
- ssh root@swapoff.org 'install -m755 ./chromad /srv/http/swapoff.org/bin && service chromad restart'
diff --git a/vendor/github.com/alecthomas/chroma/v2/README.md b/vendor/github.com/alecthomas/chroma/v2/README.md
index 0cfa07f41..d67476958 100644
--- a/vendor/github.com/alecthomas/chroma/v2/README.md
+++ b/vendor/github.com/alecthomas/chroma/v2/README.md
@@ -36,25 +36,25 @@ translators for Pygments lexers and styles.
| Prefix | Language
| :----: | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-| A | ABAP, ABNF, ActionScript, ActionScript 3, Ada, Agda, AL, Alloy, Angular2, ANTLR, ApacheConf, APL, AppleScript, ArangoDB AQL, Arduino, ArmAsm, ATL, AutoHotkey, AutoIt, Awk
+| A | ABAP, ABNF, ActionScript, ActionScript 3, Ada, Agda, AL, Alloy, AMPL, Angular2, ANTLR, ApacheConf, APL, AppleScript, ArangoDB AQL, Arduino, ArmAsm, ATL, AutoHotkey, AutoIt, Awk
| B | Ballerina, Bash, Bash Session, Batchfile, Beef, BibTeX, Bicep, BlitzBasic, BNF, BQN, Brainfuck
| C | C, C#, C++, C3, Caddyfile, Caddyfile Directives, Cap'n Proto, Cassandra CQL, Ceylon, CFEngine3, cfstatement, ChaiScript, Chapel, Cheetah, Clojure, CMake, COBOL, CoffeeScript, Common Lisp, Coq, Core, Crystal, CSS, CSV, CUE, Cython
| D | D, Dart, Dax, Desktop file, Diff, Django/Jinja, dns, Docker, DTD, Dylan
| E | EBNF, Elixir, Elm, EmacsLisp, Erlang
| F | Factor, Fennel, Fish, Forth, Fortran, FortranFixed, FSharp
-| G | GAS, GDScript, GDScript3, Gemtext, Genshi, Genshi HTML, Genshi Text, Gherkin, Gleam, GLSL, Gnuplot, Go, Go HTML Template, Go Template, Go Text Template, GraphQL, Groff, Groovy
+| G | GAS, GDScript, GDScript3, Gemtext, Genshi, Genshi HTML, Genshi Text, Gettext, Gherkin, Gleam, GLSL, Gnuplot, Go, Go HTML Template, Go Template, Go Text Template, GraphQL, Groff, Groovy
| H | Handlebars, Hare, Haskell, Haxe, HCL, Hexdump, HLB, HLSL, HolyC, HTML, HTTP, Hy
| I | Idris, Igor, INI, Io, ISCdhcpd
| J | J, Janet, Java, JavaScript, JSON, JSONata, Jsonnet, Julia, Jungle
| K | Kakoune, Kotlin
-| L | Lean4, Lighttpd configuration file, LLVM, lox, Lua
-| M | Makefile, Mako, markdown, Mason, Materialize SQL dialect, Mathematica, Matlab, MCFunction, Meson, Metal, MiniZinc, MLIR, Modelica, Modula-2, Mojo, MonkeyC, MoonScript, MorrowindScript, Myghty, MySQL
+| L | Lean4, Lighttpd configuration file, LLVM, lox, Lua, Luau
+| M | Makefile, Mako, markdown, Markless, Mason, Materialize SQL dialect, Mathematica, Matlab, MCFunction, Meson, Metal, MiniZinc, MLIR, Modelica, Modula-2, Mojo, MonkeyC, MoonScript, MorrowindScript, Myghty, MySQL
| N | NASM, Natural, NDISASM, Newspeak, Nginx configuration file, Nim, Nix, NSIS, Nu
| O | Objective-C, ObjectPascal, OCaml, Octave, Odin, OnesEnterprise, OpenEdge ABL, OpenSCAD, Org Mode
| P | PacmanConf, Perl, PHP, PHTML, Pig, PkgConfig, PL/pgSQL, plaintext, Plutus Core, Pony, PostgreSQL SQL dialect, PostScript, POVRay, PowerQuery, PowerShell, Prolog, Promela, PromQL, properties, Protocol Buffer, Protocol Buffer Text Format, PRQL, PSL, Puppet, Python, Python 2
| Q | QBasic, QML
| R | R, Racket, Ragel, Raku, react, ReasonML, reg, Rego, reStructuredText, Rexx, RGBDS Assembly, Ring, RPGLE, RPMSpec, Ruby, Rust
-| S | SAS, Sass, Scala, Scheme, Scilab, SCSS, Sed, Sieve, Smali, Smalltalk, Smarty, SNBT, Snobol, Solidity, SourcePawn, SPARQL, SQL, SquidConf, Standard ML, stas, Stylus, Svelte, Swift, SYSTEMD, systemverilog
+| S | SAS, Sass, Scala, Scheme, Scilab, SCSS, Sed, Sieve, Smali, Smalltalk, Smarty, SNBT, Snobol, Solidity, SourcePawn, Spade, SPARQL, SQL, SquidConf, Standard ML, stas, Stylus, Svelte, Swift, SYSTEMD, systemverilog
| T | TableGen, Tal, TASM, Tcl, Tcsh, Termcap, Terminfo, Terraform, TeX, Thrift, TOML, TradingView, Transact-SQL, Turing, Turtle, Twig, TypeScript, TypoScript, TypoScriptCssData, TypoScriptHtmlData, Typst
| U | ucode
| V | V, V shell, Vala, VB.net, verilog, VHDL, VHS, VimL, vue
@@ -226,11 +226,11 @@ formatter outputs raw tokens. The latter is useful for debugging lexers.
### Styles
Chroma styles are defined in XML. The style entries use the
-[same syntax](http://pygments.org/docs/styles/) as Pygments.
-
-All Pygments styles have been converted to Chroma using the `_tools/style.py`
+[same syntax](http://pygments.org/docs/styles/) as Pygments. All Pygments styles have been converted to Chroma using the `_tools/style.py`
script.
+Style names are case-insensitive. For example, `monokai` and `Monokai` are treated as the same style.
+
When you work with one of [Chroma's styles](https://github.com/alecthomas/chroma/tree/master/styles),
know that the `Background` token type provides the default style for tokens. It does so
by defining a foreground color and background color.
diff --git a/vendor/github.com/alecthomas/chroma/v2/formatters/html/html.go b/vendor/github.com/alecthomas/chroma/v2/formatters/html/html.go
index c1c8875b2..1aaafd0f4 100644
--- a/vendor/github.com/alecthomas/chroma/v2/formatters/html/html.go
+++ b/vendor/github.com/alecthomas/chroma/v2/formatters/html/html.go
@@ -528,6 +528,7 @@ func (f *Formatter) styleToCSS(style *chroma.Style) map[chroma.TokenType]string
}
classes[chroma.Background] += `;` + f.tabWidthStyle()
classes[chroma.PreWrapper] += classes[chroma.Background]
+ classes[chroma.PreWrapper] += ` -webkit-text-size-adjust: none;`
// Make PreWrapper a grid to show highlight style with full width.
if len(f.highlightRanges) > 0 && f.customCSS[chroma.PreWrapper] == `` {
classes[chroma.PreWrapper] += `display: grid;`
diff --git a/vendor/github.com/alecthomas/chroma/v2/formatters/svg/font_liberation_mono.go b/vendor/github.com/alecthomas/chroma/v2/formatters/svg/font_liberation_mono.go
index 70d692ec4..416208a73 100644
--- a/vendor/github.com/alecthomas/chroma/v2/formatters/svg/font_liberation_mono.go
+++ b/vendor/github.com/alecthomas/chroma/v2/formatters/svg/font_liberation_mono.go
@@ -4,7 +4,7 @@
// with Reserved Font Name Liberation.
//
// This Font Software is licensed under the SIL Open Font License, Version 1.1.
-// This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL
+// This license is copied below, and is also available with a FAQ at: https://openfontlicense.org
//
// -----------------------------------------------------------
// SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/ampl.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/ampl.xml
new file mode 100644
index 000000000..8c2479e50
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/ampl.xml
@@ -0,0 +1,98 @@
+
+
+ AMPL
+ ampl
+ *.mod
+ *.run
+ text/x-ampl
+ false
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/bash.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/bash.xml
index d704a8ffa..6163cc613 100644
--- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/bash.xml
+++ b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/bash.xml
@@ -12,6 +12,7 @@
*.ebuild
*.eclass
.env
+ .env.*
*.env
*.exheres-0
*.exlib
@@ -23,6 +24,7 @@
bash_*
zshrc
.zshrc
+ APKBUILD
PKGBUILD
application/x-sh
application/x-shellscript
@@ -217,4 +219,4 @@
-
\ No newline at end of file
+
diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/erb.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/erb.xml
new file mode 100644
index 000000000..e597cd8a9
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/erb.xml
@@ -0,0 +1,37 @@
+
+
+ ERB
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/gas.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/gas.xml
index 7557bce0f..399cdd008 100644
--- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/gas.xml
+++ b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/gas.xml
@@ -56,7 +56,7 @@
-
+
@@ -114,7 +114,7 @@
-
+
@@ -139,7 +139,7 @@
-
+
diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/gettext.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/gettext.xml
new file mode 100644
index 000000000..38c0c21b4
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/gettext.xml
@@ -0,0 +1,24 @@
+
+
+
+ Gettext
+ pot
+ po
+ *.pot
+ *.po
+ application/x-gettext
+ text/x-gettext
+ text/gettext
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/graphql.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/graphql.xml
index b06227357..b40422f22 100644
--- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/graphql.xml
+++ b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/graphql.xml
@@ -76,6 +76,10 @@
+
+
+
+
diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/javascript.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/javascript.xml
index efe80ed37..0e475c53e 100644
--- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/javascript.xml
+++ b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/javascript.xml
@@ -133,7 +133,7 @@
-
+
diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/json.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/json.xml
index a34abfa49..0057aa1b6 100644
--- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/json.xml
+++ b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/json.xml
@@ -4,7 +4,9 @@
json
*.json
*.jsonc
+ *.json5
*.avsc
+ .luaurc
application/json
true
true
diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/kdl.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/kdl.xml
new file mode 100644
index 000000000..bc6ebfb80
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/kdl.xml
@@ -0,0 +1,75 @@
+
+
+ KDL
+ kdl
+ *.kdl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/lateralus.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/lateralus.xml
new file mode 100644
index 000000000..cea10eba7
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/lateralus.xml
@@ -0,0 +1,184 @@
+
+
+ Lateralus
+ lateralus
+ ltl
+ *.ltl
+ text/x-lateralus
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/lua.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/lua.xml
index e3d778f12..903d4581f 100644
--- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/lua.xml
+++ b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/lua.xml
@@ -2,10 +2,8 @@
Lua
lua
- luau
*.lua
*.wlua
- *.luau
text/x-lua
application/x-lua
diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/luau.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/luau.xml
new file mode 100644
index 000000000..79a60949a
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/luau.xml
@@ -0,0 +1,173 @@
+
+
+ Luau
+ luau
+ *.luau
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/materialize_sql_dialect.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/materialize_sql_dialect.xml
index 7094ddc3e..616d7ae4c 100644
--- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/materialize_sql_dialect.xml
+++ b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/materialize_sql_dialect.xml
@@ -45,7 +45,7 @@
-
+
diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/meson.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/meson.xml
index 130047df6..fcfbda115 100644
--- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/meson.xml
+++ b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/meson.xml
@@ -4,6 +4,7 @@
meson
meson.build
meson.build
+ meson.options
meson_options.txt
text/x-meson
diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/microcad.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/microcad.xml
new file mode 100644
index 000000000..6de71ef0a
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/microcad.xml
@@ -0,0 +1,139 @@
+
+
+ microcad
+ µcad
+ *.µcad
+ *.ucad
+ *.mcad
+ text/microcad
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/moonbit.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/moonbit.xml
new file mode 100644
index 000000000..846e724dc
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/moonbit.xml
@@ -0,0 +1,75 @@
+
+
+ MoonBit
+ moonbit
+ mbt
+ *.mbt
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/mysql.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/mysql.xml
index b6c2046d5..0517ec8f7 100644
--- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/mysql.xml
+++ b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/mysql.xml
@@ -38,7 +38,7 @@
-
+
diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/php.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/php.xml
index c9e22ea57..774bb79be 100644
--- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/php.xml
+++ b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/php.xml
@@ -54,7 +54,7 @@
-
+
@@ -82,12 +82,46 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
@@ -101,6 +135,10 @@
+
+
+
+
@@ -116,7 +154,7 @@
-
+
@@ -132,6 +170,13 @@
+
+
+
+
+
+
+
@@ -161,7 +206,7 @@
-
+
@@ -170,8 +215,9 @@
-
+
+
@@ -185,7 +231,7 @@
-
+
@@ -194,7 +240,7 @@
-
+
diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/scdoc.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/scdoc.xml
new file mode 100644
index 000000000..1b3a876ef
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/scdoc.xml
@@ -0,0 +1,115 @@
+
+
+ scdoc
+ scdoc
+ *.scd
+ *.scdoc
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/spade.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/spade.xml
new file mode 100644
index 000000000..4dfe3292b
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/spade.xml
@@ -0,0 +1,292 @@
+
+
+ Spade
+ spade
+ *.spade
+ text/spade
+ text/x-spade
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/typescript.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/typescript.xml
index a3e3be239..b39c9649c 100644
--- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/typescript.xml
+++ b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/typescript.xml
@@ -226,7 +226,7 @@
diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/xml.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/xml.xml
index 2c6a4d990..99d5d5302 100644
--- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/xml.xml
+++ b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/xml.xml
@@ -10,6 +10,7 @@
*.wsdl
*.wsf
*.svg
+ *.qrc
*.csproj
*.vcxproj
*.fsproj
diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/zig.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/zig.xml
index 6f17bcafc..5617f9141 100644
--- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/zig.xml
+++ b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/zig.xml
@@ -8,7 +8,13 @@
-
+
+
+
+
+
+
+
@@ -18,99 +24,164 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
-
+
+
-
+
+
-
+
+
+
-
+
+
-
+
+
-
+
+
-
+
+
-
-
-
-
+
+
-
+
+
-
-
-
-
+
+
-
+
+
-
+
+
-
+
+
-
-
+
+
+
+
-
+
+
-
-
-
-
-
+
+
+
-
-
+
+
+
-
-
+
+
+
+
-
-
-
-
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
-
\ No newline at end of file
+
diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/erb.go b/vendor/github.com/alecthomas/chroma/v2/lexers/erb.go
new file mode 100644
index 000000000..2d141ed9e
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/lexers/erb.go
@@ -0,0 +1,29 @@
+package lexers
+
+import (
+ "strings"
+
+ . "github.com/alecthomas/chroma/v2" // nolint
+)
+
+// ERB lexer is Ruby embedded in HTML.
+var ERB = Register(DelegatingLexer(HTML, MustNewXMLLexer(
+ embedded,
+ "embedded/erb.xml",
+).SetConfig(
+ &Config{
+ Name: "ERB",
+ Aliases: []string{"erb", "html+erb", "html+ruby", "rhtml"},
+ Filenames: []string{"*.erb", "*.html.erb", "*.xml.erb", "*.rhtml"},
+ MimeTypes: []string{"application/x-ruby-templating"},
+ DotAll: true,
+ },
+).SetAnalyser(func(text string) float32 {
+ if strings.Contains(text, "<%=") && strings.Contains(text, "%>") {
+ return 0.4
+ }
+ if strings.Contains(text, "<%") {
+ return 0.1
+ }
+ return 0.0
+})))
diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/markless.go b/vendor/github.com/alecthomas/chroma/v2/lexers/markless.go
new file mode 100644
index 000000000..508513d78
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/lexers/markless.go
@@ -0,0 +1,168 @@
+package lexers
+
+import (
+ . "github.com/alecthomas/chroma/v2" // nolint
+)
+
+// Markless lexer.
+var Markless = Register(MustNewLexer(
+ &Config{
+ Name: "Markless",
+ Aliases: []string{"mess"},
+ Filenames: []string{"*.mess", "*.markless"},
+ MimeTypes: []string{"text/x-markless"},
+ },
+ marklessRules,
+))
+
+func marklessRules() Rules {
+ return Rules{
+ "root": {
+ Include("block"),
+ },
+ // Block directives
+ "block": {
+ Include("header"),
+ Include("ordered-list"),
+ Include("unordered-list"),
+ Include("code-block"),
+ Include("blockquote"),
+ Include("blockquote-header"),
+ Include("align"),
+ Include("comment"),
+ Include("instruction"),
+ Include("embed"),
+ Include("footnote"),
+ Include("horizontal-rule"),
+ Include("paragraph"),
+ },
+ "header": {
+ {`(# )(.*)$`, ByGroups(Keyword, GenericHeading), Push("inline")},
+ {`(##+)(.*)$`, ByGroups(Keyword, GenericSubheading), Push("inline")},
+ },
+ "ordered-list": {
+ {`([0-9]+\.)`, Keyword, nil},
+ },
+ "unordered-list": {
+ {`(- )`, Keyword, nil},
+ },
+ "code-block": {
+ {`(::+)( *)(\w*)([^\n]*)(\n)([\w\W]*?)(^\1$)`, UsingByGroup(3, 6, Keyword, TextWhitespace, NameFunction, String, TextWhitespace, Text, Keyword), nil},
+ },
+ "blockquote": {
+ {`(\| )(.*)$`, ByGroups(Keyword, GenericInserted), nil},
+ },
+ "blockquote-header": {
+ {`(~ )([^|\n]+)(\| )(.*?\n)`, ByGroups(Keyword, NameEntity, Keyword, GenericInserted), Push("inline-blockquote")},
+ {`(~ )(.*)$`, ByGroups(Keyword, NameEntity), nil},
+ },
+ "inline-blockquote": {
+ {`^( +)(\| )(.*$)`, ByGroups(TextWhitespace, Keyword, GenericInserted), nil},
+ Default(Pop(1)),
+ },
+ "align": {
+ {`(\|\|)|(\|<)|(\|>)|(><)`, Keyword, nil},
+ },
+ "comment": {
+ {`(;[; ]).*?$`, CommentSingle, nil},
+ },
+ "instruction": {
+ {`(! )([^ ]+)(.+?)$`, ByGroups(Keyword, NameFunction, NameVariable), nil},
+ },
+ "embed": {
+ {`(\[ )([^ ]+)( )([^,]+)`, ByGroups(Keyword, NameFunction, TextWhitespace, String), Push("embed-options")},
+ },
+ "embed-options": {
+ {`\\.`, Text, nil},
+ {`,`, Punctuation, nil},
+ {`\]?$`, Keyword, Pop(1)},
+ // Generic key or key/value pair
+ {`( *)([^, \]]+)([^,\]]+)?`, ByGroups(TextWhitespace, NameFunction, String), nil},
+ {`.`, Text, nil},
+ },
+ "footnote": {
+ {`(\[)([0-9]+)(\])`, ByGroups(Keyword, NameVariable, Keyword), Push("inline")},
+ },
+ "horizontal-rule": {
+ {`(==+)$`, LiteralOther, nil},
+ },
+ "paragraph": {
+ {` *`, TextWhitespace, Push("inline")},
+ },
+ // Inline directives
+ "inline": {
+ Include("escapes"),
+ Include("dashes"),
+ Include("newline"),
+ Include("italic"),
+ Include("underline"),
+ Include("bold"),
+ Include("strikethrough"),
+ Include("code"),
+ Include("compound"),
+ Include("footnote-reference"),
+ Include("subtext"),
+ Include("subtext"),
+ Include("url"),
+ {`.`, Text, nil},
+ {`\n`, TextWhitespace, Pop(1)},
+ },
+ "escapes": {
+ {`\\.`, Text, nil},
+ },
+ "dashes": {
+ {`-{2,3}`, TextPunctuation, nil},
+ },
+ "newline": {
+ {`-/-`, TextWhitespace, nil},
+ },
+ "italic": {
+ {`(//)(.*?)(\1)`, ByGroups(Keyword, GenericEmph, Keyword), nil},
+ },
+ "underline": {
+ {`(__)(.*?)(\1)`, ByGroups(Keyword, GenericUnderline, Keyword), nil},
+ },
+ "bold": {
+ {`(\*\*)(.*?)(\1)`, ByGroups(Keyword, GenericStrong, Keyword), nil},
+ },
+ "strikethrough": {
+ {`(<-)(.*?)(->)`, ByGroups(Keyword, GenericDeleted, Keyword), nil},
+ },
+ "code": {
+ {"(``+)(.*?)(\\1)", ByGroups(Keyword, LiteralStringBacktick, Keyword), nil},
+ },
+ "compound": {
+ {`(''+)(.*?)(''\()`, ByGroups(Keyword, UsingSelf("inline"), Keyword), Push("compound-options")},
+ },
+ "compound-options": {
+ {`\\.`, Text, nil},
+ {`,`, Punctuation, nil},
+ {`\)`, Keyword, Pop(1)},
+ // Hex Color
+ {` *#[0-9A-Fa-f]{3,6} *`, LiteralNumberHex, nil},
+ // Named Color
+ {` *(indian-red|light-coral|salmon|dark-salmon|light-salmon|crimson|red|firebrick|dark-red|pink|light-pink|hot-pink|deep-pink|medium-violet-red|pale-violet-red|coral|tomato|orange-red|dark-orange|orange|gold|yellow|light-yellow|lemon-chiffon|light-goldenrod-yellow|papayawhip|moccasin|peachpuff|pale-goldenrod|khaki|dark-khaki|lavender|thistle|plum|violet|orchid|fuchsia|magenta|medium-orchid|medium-purple|rebecca-purple|blue-violet|dark-violet|dark-orchid|dark-magenta|purple|indigo|slate-blue|dark-slate-blue|medium-slate-blue|green-yellow|chartreuse|lawn-green|lime|lime-green|pale-green|light-green|medium-spring-green|spring-green|medium-sea-green|sea-green|forest-green|green|dark-green|yellow-green|olive-drab|olive|dark-olive-green|medium-aquamarine|dark-sea-green|light-sea-green|dark-cyan|teal|aqua|cyan|light-cyan|pale-turquoise|aquamarine|turquoise|medium-turquoise|dark-turquoise|cadet-blue|steel-blue|light-steel-blue|powder-blue|light-blue|sky-blue|light-sky-blue|deep-sky-blue|dodger-blue|cornflower-blue|royal-blue|blue|medium-blue|dark-blue|navy|midnight-blue|cornsilk|blanched-almond|bisque|navajo-white|wheat|burlywood|tan|rosy-brown|sandy-brown|goldenrod|dark-goldenrod|peru|chocolate|saddle-brown|sienna|brown|maroon|white|snow|honeydew|mintcream|azure|alice-blue|ghost-white|white-smoke|seashell|beige|oldlace|floral-white|ivory|antique-white|linen|lavenderblush|mistyrose|gainsboro|light-gray|silver|dark-gray|gray|dim-gray|light-slate-gray|slate-gray|dark-slate-gray) *`, LiteralOther, nil},
+ // Named size
+ {` *(microscopic|tiny|small|normal|big|large|huge|gigantic) *`, NameTag, nil},
+ // Options
+ {` *(bold|italic|underline|strikethrough|subtext|supertext|spoiler) *`, NameBuiltin, nil},
+ // URL. Note the missing ) and , in the match.
+ {` *\w[-\w+.]*://[\w$\-_.+!*'(&/:;=?@z%#\\]+ *`, String, nil},
+ // Generic key or key/value pair
+ {`( *)([^, )]+)( [^,)]+)?`, ByGroups(TextWhitespace, NameFunction, String), nil},
+ {`.`, Text, nil},
+ },
+ "footnote-reference": {
+ {`(\[)([0-9]+)(\])`, ByGroups(Keyword, NameVariable, Keyword), nil},
+ },
+ "subtext": {
+ {`(v\()(.*?)(\))`, ByGroups(Keyword, UsingSelf("inline"), Keyword), nil},
+ },
+ "supertext": {
+ {`(\^\()(.*?)(\))`, ByGroups(Keyword, UsingSelf("inline"), Keyword), nil},
+ },
+ "url": {
+ {`\w[-\w+.]*://[\w\$\-_.+!*'()&,/:;=?@z%#\\]+`, String, nil},
+ },
+ }
+}
diff --git a/vendor/github.com/alecthomas/chroma/v2/regexp.go b/vendor/github.com/alecthomas/chroma/v2/regexp.go
index c0e5e1081..d183fa5dc 100644
--- a/vendor/github.com/alecthomas/chroma/v2/regexp.go
+++ b/vendor/github.com/alecthomas/chroma/v2/regexp.go
@@ -308,6 +308,7 @@ type RegexLexer struct {
rules map[string][]*CompiledRule
fetchRulesFunc func() (Rules, error)
compileOnce sync.Once
+ compileError error
}
func (r *RegexLexer) String() string {
@@ -446,8 +447,11 @@ func (r *RegexLexer) needRules() error {
var err error
if r.fetchRulesFunc != nil {
r.compileOnce.Do(func() {
- err = r.fetchRules()
+ r.compileError = r.fetchRules()
})
+ if r.compileError != nil {
+ return r.compileError
+ }
}
if err := r.maybeCompile(); err != nil {
return err
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/api.go b/vendor/github.com/alecthomas/chroma/v2/styles/api.go
index e26d6f0a5..9e21c8844 100644
--- a/vendor/github.com/alecthomas/chroma/v2/styles/api.go
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/api.go
@@ -4,6 +4,7 @@ import (
"embed"
"io/fs"
"sort"
+ "strings"
"github.com/alecthomas/chroma/v2"
)
@@ -31,7 +32,7 @@ var Registry = func() map[string]*chroma.Style {
if err != nil {
panic(err)
}
- registry[style.Name] = style
+ registry[strings.ToLower(style.Name)] = style
_ = r.Close()
}
return registry
@@ -42,7 +43,7 @@ var Fallback = Registry["swapoff"]
// Register a chroma.Style.
func Register(style *chroma.Style) *chroma.Style {
- Registry[style.Name] = style
+ Registry[strings.ToLower(style.Name)] = style
return style
}
@@ -58,7 +59,7 @@ func Names() []string {
// Get named style, or Fallback.
func Get(name string) *chroma.Style {
- if style, ok := Registry[name]; ok {
+ if style, ok := Registry[strings.ToLower(name)]; ok {
return style
}
return Fallback
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/aura-theme-dark-soft.xml b/vendor/github.com/alecthomas/chroma/v2/styles/aura-theme-dark-soft.xml
index 37f589f98..ee7f1257f 100644
--- a/vendor/github.com/alecthomas/chroma/v2/styles/aura-theme-dark-soft.xml
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/aura-theme-dark-soft.xml
@@ -101,7 +101,7 @@
-
+
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/aura-theme-dark.xml b/vendor/github.com/alecthomas/chroma/v2/styles/aura-theme-dark.xml
index fd1cd880c..85e8ec936 100644
--- a/vendor/github.com/alecthomas/chroma/v2/styles/aura-theme-dark.xml
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/aura-theme-dark.xml
@@ -101,7 +101,7 @@
-
+
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/compat.go b/vendor/github.com/alecthomas/chroma/v2/styles/compat.go
index 4a6aaa665..030985367 100644
--- a/vendor/github.com/alecthomas/chroma/v2/styles/compat.go
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/compat.go
@@ -31,6 +31,9 @@ var (
HrDark = Registry["hrdark"]
HrHighContrast = Registry["hr_high_contrast"]
Igor = Registry["igor"]
+ KanagawaDragon = Registry["kanagawa-dragon"]
+ KanagawaLotus = Registry["kanagawa-lotus"]
+ KanagawaWave = Registry["kanagawa-wave"]
Lovelace = Registry["lovelace"]
Manni = Registry["manni"]
ModusOperandi = Registry["modus-operandi"]
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/darcula.xml b/vendor/github.com/alecthomas/chroma/v2/styles/darcula.xml
new file mode 100644
index 000000000..4c3550623
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/darcula.xml
@@ -0,0 +1,83 @@
+
\ No newline at end of file
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/github-dark.xml b/vendor/github.com/alecthomas/chroma/v2/styles/github-dark.xml
index 711aeafc4..c5b0dbb5e 100644
--- a/vendor/github.com/alecthomas/chroma/v2/styles/github-dark.xml
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/github-dark.xml
@@ -15,6 +15,7 @@
+
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/kanagawa-dragon.xml b/vendor/github.com/alecthomas/chroma/v2/styles/kanagawa-dragon.xml
new file mode 100644
index 000000000..114d1651d
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/kanagawa-dragon.xml
@@ -0,0 +1,83 @@
+
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/kanagawa-lotus.xml b/vendor/github.com/alecthomas/chroma/v2/styles/kanagawa-lotus.xml
new file mode 100644
index 000000000..dde3bc8ef
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/kanagawa-lotus.xml
@@ -0,0 +1,83 @@
+
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/kanagawa-wave.xml b/vendor/github.com/alecthomas/chroma/v2/styles/kanagawa-wave.xml
new file mode 100644
index 000000000..cebcda1b5
--- /dev/null
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/kanagawa-wave.xml
@@ -0,0 +1,83 @@
+
diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/solarized-light.xml b/vendor/github.com/alecthomas/chroma/v2/styles/solarized-light.xml
index 4fbc1d4a6..8839e7602 100644
--- a/vendor/github.com/alecthomas/chroma/v2/styles/solarized-light.xml
+++ b/vendor/github.com/alecthomas/chroma/v2/styles/solarized-light.xml
@@ -1,5 +1,5 @@
`)
diff --git a/vendor/github.com/golangci/dupl/suffixtree/dupl.go b/vendor/github.com/golangci/dupl/suffixtree/dupl.go
index ab145b4f3..0263203ed 100644
--- a/vendor/github.com/golangci/dupl/suffixtree/dupl.go
+++ b/vendor/github.com/golangci/dupl/suffixtree/dupl.go
@@ -54,7 +54,7 @@ func (c *contextList) append(c2 *contextList) {
}
}
-// FindDuplOver find pairs of maximal duplicities over a threshold
+// FindDuplOver finds pairs of maximal duplicities over a threshold
// length.
func (t *STree) FindDuplOver(threshold int) <-chan Match {
auxTran := newTran(0, 0, t.root)
diff --git a/vendor/github.com/golangci/dupl/suffixtree/suffixtree.go b/vendor/github.com/golangci/dupl/suffixtree/suffixtree.go
index 871469e8d..30aaa6f4e 100644
--- a/vendor/github.com/golangci/dupl/suffixtree/suffixtree.go
+++ b/vendor/github.com/golangci/dupl/suffixtree/suffixtree.go
@@ -38,7 +38,7 @@ func New() *STree {
return t
}
-// Update refreshes the suffix tree to by new data.
+// Update refreshes the suffix tree with new data.
func (t *STree) Update(data ...Token) {
t.data = append(t.data, data...)
for range data {
@@ -79,8 +79,8 @@ func (t *STree) update() {
}
// testAndSplit tests whether a state with canonical ref. pair
-// (s, (start, end)) is the end point, that is, a state that have
-// a c-transition. If not, then state (exs, (start, end)) is made
+// (s, (start, end)) is the end point, that is, a state that has
+// a c-transition. If not, then the state (exs, (start, end)) is made
// explicit (if not already so).
func (t *STree) testAndSplit(s *state, start, end Pos) (exs *state, endPoint bool) {
c := t.data[t.end]
@@ -148,11 +148,11 @@ func (t *STree) String() string {
return buf.String()
}
-func printState(buf *bytes.Buffer, s *state, ident int) {
+func printState(buf *bytes.Buffer, s *state, indent int) {
for _, tr := range s.trans {
- fmt.Fprint(buf, strings.Repeat(" ", ident))
+ fmt.Fprint(buf, strings.Repeat(" ", indent))
fmt.Fprintf(buf, "* (%d, %d)\n", tr.start, tr.ActEnd())
- printState(buf, tr.state, ident+1)
+ printState(buf, tr.state, indent+1)
}
}
diff --git a/vendor/github.com/golangci/dupl/syntax/golang/golang.go b/vendor/github.com/golangci/dupl/syntax/golang/golang.go
index a0b1e77e1..ff3e51b2e 100644
--- a/vendor/github.com/golangci/dupl/syntax/golang/golang.go
+++ b/vendor/github.com/golangci/dupl/syntax/golang/golang.go
@@ -39,6 +39,7 @@ const (
IfStmt
IncDecStmt
IndexExpr
+ IndexListExpr
InterfaceType
KeyValueExpr
LabeledStmt
@@ -234,6 +235,9 @@ func (t *transformer) trans(node ast.Node) (o *syntax.Node) {
case *ast.FuncType:
o.Type = FuncType
+ if n.TypeParams != nil {
+ o.AddChildren(t.trans(n.TypeParams))
+ }
o.AddChildren(t.trans(n.Params))
if n.Results != nil {
o.AddChildren(t.trans(n.Results))
@@ -270,6 +274,13 @@ func (t *transformer) trans(node ast.Node) (o *syntax.Node) {
o.Type = IndexExpr
o.AddChildren(t.trans(n.X), t.trans(n.Index))
+ case *ast.IndexListExpr:
+ o.Type = IndexListExpr
+ o.AddChildren(t.trans(n.X))
+ for _, idx := range n.Indices {
+ o.AddChildren(t.trans(idx))
+ }
+
case *ast.InterfaceType:
o.Type = InterfaceType
o.AddChildren(t.trans(n.Methods))
@@ -358,7 +369,11 @@ func (t *transformer) trans(node ast.Node) (o *syntax.Node) {
case *ast.TypeSpec:
o.Type = TypeSpec
- o.AddChildren(t.trans(n.Name), t.trans(n.Type))
+ o.AddChildren(t.trans(n.Name))
+ if n.TypeParams != nil {
+ o.AddChildren(t.trans(n.TypeParams))
+ }
+ o.AddChildren(t.trans(n.Type))
case *ast.TypeSwitchStmt:
o.Type = TypeSwitchStmt
diff --git a/vendor/github.com/golangci/dupl/syntax/syntax.go b/vendor/github.com/golangci/dupl/syntax/syntax.go
index 9b11d3119..871f67186 100644
--- a/vendor/github.com/golangci/dupl/syntax/syntax.go
+++ b/vendor/github.com/golangci/dupl/syntax/syntax.go
@@ -129,8 +129,8 @@ func getUnitsIndexes(nodeSeq []*Node, threshold int) []int {
return indexes
}
-// isCyclic finds out whether there is a repetive pattern in the found clone. If positive,
-// it return false to point out that the clone would be redundant.
+// isCyclic finds out whether there is a repetitive pattern in the found clone. If positive,
+// it returns true to point out that the clone would be redundant.
func isCyclic(indexes []int, nodes []*Node) bool {
cnt := len(indexes)
if cnt <= 1 {
diff --git a/vendor/github.com/golangci/golangci-lint/v2/internal/cache/cache.go b/vendor/github.com/golangci/golangci-lint/v2/internal/cache/cache.go
index 138a36148..f299afe7c 100644
--- a/vendor/github.com/golangci/golangci-lint/v2/internal/cache/cache.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/internal/cache/cache.go
@@ -7,6 +7,7 @@ import (
"errors"
"fmt"
"maps"
+ "path/filepath"
"runtime"
"slices"
"strings"
@@ -172,6 +173,11 @@ func (c *Cache) computePkgHash(pkg *packages.Package) (hashResults, error) {
return nil, fmt.Errorf("failed to calculate file %s hash: %w", f, fErr)
}
+ // This is the current module (the project to analyze).
+ if pkg.Module != nil && pkg.Module.Version == "" {
+ f = pkg.Module.Path + strings.TrimPrefix(filepath.ToSlash(f), filepath.ToSlash(pkg.Module.Dir))
+ }
+
fmt.Fprintf(key, "file %s %x\n", f, h)
}
diff --git a/vendor/github.com/golangci/golangci-lint/v2/internal/x/tools/analysisflags/readme.md b/vendor/github.com/golangci/golangci-lint/v2/internal/x/tools/analysisflags/readme.md
deleted file mode 100644
index 6035c2226..000000000
--- a/vendor/github.com/golangci/golangci-lint/v2/internal/x/tools/analysisflags/readme.md
+++ /dev/null
@@ -1,11 +0,0 @@
-# analysisflags
-
-Extracted from `/go/analysis/internal/analysisflags` (related to `checker`).
-This is just a copy of the code without any changes.
-
-## History
-
-- https://github.com/golangci/golangci-lint/pull/6076
- - sync with https://github.com/golang/tools/blob/v0.37.0/go/analysis/internal/analysisflags
-- https://github.com/golangci/golangci-lint/pull/5576
- - sync with https://github.com/golang/tools/blob/v0.28.0/go/analysis/internal/analysisflags
diff --git a/vendor/github.com/golangci/golangci-lint/v2/internal/x/tools/analysisflags/url.go b/vendor/github.com/golangci/golangci-lint/v2/internal/x/tools/analysisflags/url.go
deleted file mode 100644
index 26a917a99..000000000
--- a/vendor/github.com/golangci/golangci-lint/v2/internal/x/tools/analysisflags/url.go
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright 2023 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 analysisflags
-
-import (
- "fmt"
- "net/url"
-
- "golang.org/x/tools/go/analysis"
-)
-
-// ResolveURL resolves the URL field for a Diagnostic from an Analyzer
-// and returns the URL. See Diagnostic.URL for details.
-func ResolveURL(a *analysis.Analyzer, d analysis.Diagnostic) (string, error) {
- if d.URL == "" && d.Category == "" && a.URL == "" {
- return "", nil // do nothing
- }
- raw := d.URL
- if d.URL == "" && d.Category != "" {
- raw = "#" + d.Category
- }
- u, err := url.Parse(raw)
- if err != nil {
- return "", fmt.Errorf("invalid Diagnostic.URL %q: %s", raw, err)
- }
- base, err := url.Parse(a.URL)
- if err != nil {
- return "", fmt.Errorf("invalid Analyzer.URL %q: %s", a.URL, err)
- }
- return base.ResolveReference(u).String(), nil
-}
diff --git a/vendor/github.com/golangci/golangci-lint/v2/internal/x/tools/analysisinternal/analysis.go b/vendor/github.com/golangci/golangci-lint/v2/internal/x/tools/analysisinternal/analysis.go
deleted file mode 100644
index b613d1673..000000000
--- a/vendor/github.com/golangci/golangci-lint/v2/internal/x/tools/analysisinternal/analysis.go
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright 2020 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 analysisinternal provides gopls' internal analyses with a
-// number of helper functions that operate on typed syntax trees.
-package analysisinternal
-
-import (
- "fmt"
- "slices"
-
- "golang.org/x/tools/go/analysis"
-)
-
-// A ReadFileFunc is a function that returns the
-// contents of a file, such as [os.ReadFile].
-type ReadFileFunc = func(filename string) ([]byte, error)
-
-// CheckedReadFile returns a wrapper around a Pass.ReadFile
-// function that performs the appropriate checks.
-func CheckedReadFile(pass *analysis.Pass, readFile ReadFileFunc) ReadFileFunc {
- return func(filename string) ([]byte, error) {
- if err := CheckReadable(pass, filename); err != nil {
- return nil, err
- }
- return readFile(filename)
- }
-}
-
-// CheckReadable enforces the access policy defined by the ReadFile field of [analysis.Pass].
-func CheckReadable(pass *analysis.Pass, filename string) error {
- if slices.Contains(pass.OtherFiles, filename) ||
- slices.Contains(pass.IgnoredFiles, filename) {
- return nil
- }
- for _, f := range pass.Files {
- if pass.Fset.File(f.FileStart).Name() == filename {
- return nil
- }
- }
- return fmt.Errorf("Pass.ReadFile: %s is not among OtherFiles, IgnoredFiles, or names of Files", filename)
-}
diff --git a/vendor/github.com/golangci/golangci-lint/v2/internal/x/tools/analysisinternal/readme.md b/vendor/github.com/golangci/golangci-lint/v2/internal/x/tools/analysisinternal/readme.md
deleted file mode 100644
index 6c54592d9..000000000
--- a/vendor/github.com/golangci/golangci-lint/v2/internal/x/tools/analysisinternal/readme.md
+++ /dev/null
@@ -1,11 +0,0 @@
-# analysisinternal
-
-Extracted from `/internal/analysisinternal/` (related to `checker`).
-This is just a copy of the code without any changes.
-
-## History
-
-- https://github.com/golangci/golangci-lint/pull/6076
- - sync with https://github.com/golang/tools/blob/v0.37.0/internal/analysisinternal/
-- https://github.com/golangci/golangci-lint/pull/5576
- - sync with https://github.com/golang/tools/blob/v0.28.0/internal/analysisinternal/
diff --git a/vendor/github.com/golangci/golangci-lint/v2/internal/x/tools/driverutil/readfile.go b/vendor/github.com/golangci/golangci-lint/v2/internal/x/tools/driverutil/readfile.go
new file mode 100644
index 000000000..dc1d54dd8
--- /dev/null
+++ b/vendor/github.com/golangci/golangci-lint/v2/internal/x/tools/driverutil/readfile.go
@@ -0,0 +1,43 @@
+// Copyright 2020 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 driverutil
+
+// This file defines helpers for implementing [analysis.Pass.ReadFile].
+
+import (
+ "fmt"
+ "slices"
+
+ "golang.org/x/tools/go/analysis"
+)
+
+// A ReadFileFunc is a function that returns the
+// contents of a file, such as [os.ReadFile].
+type ReadFileFunc = func(filename string) ([]byte, error)
+
+// CheckedReadFile returns a wrapper around a Pass.ReadFile
+// function that performs the appropriate checks.
+func CheckedReadFile(pass *analysis.Pass, readFile ReadFileFunc) ReadFileFunc {
+ return func(filename string) ([]byte, error) {
+ if err := CheckReadable(pass, filename); err != nil {
+ return nil, err
+ }
+ return readFile(filename)
+ }
+}
+
+// CheckReadable enforces the access policy defined by the ReadFile field of [analysis.Pass].
+func CheckReadable(pass *analysis.Pass, filename string) error {
+ if slices.Contains(pass.OtherFiles, filename) ||
+ slices.Contains(pass.IgnoredFiles, filename) {
+ return nil
+ }
+ for _, f := range pass.Files {
+ if pass.Fset.File(f.FileStart).Name() == filename {
+ return nil
+ }
+ }
+ return fmt.Errorf("Pass.ReadFile: %s is not among OtherFiles, IgnoredFiles, or names of Files", filename)
+}
diff --git a/vendor/github.com/golangci/golangci-lint/v2/internal/x/tools/driverutil/readme.md b/vendor/github.com/golangci/golangci-lint/v2/internal/x/tools/driverutil/readme.md
new file mode 100644
index 000000000..8720fb6ff
--- /dev/null
+++ b/vendor/github.com/golangci/golangci-lint/v2/internal/x/tools/driverutil/readme.md
@@ -0,0 +1,25 @@
+# driverutil
+
+Extracted from `/internal/analysis/driverutil/` (related to `checker`).
+This is just a copy of `readfile.go` and `url.go` without any changes.
+
+Previously, it was `analysisinternal` and `analysisflags` packages.
+
+## History
+
+- https://github.com/golangci/golangci-lint/pull/6434
+ - sync with https://github.com/golang/tools/blob/v0.43.0/internal/analysis/driverutil/readfile.go
+
+## analysisinternal History
+
+- https://github.com/golangci/golangci-lint/pull/6076
+ - sync with https://github.com/golang/tools/blob/v0.37.0/internal/analysisinternal/
+- https://github.com/golangci/golangci-lint/pull/5576
+ - sync with https://github.com/golang/tools/blob/v0.28.0/internal/analysisinternal/
+
+## analysisflags History
+
+- https://github.com/golangci/golangci-lint/pull/6076
+ - sync with https://github.com/golang/tools/blob/v0.37.0/go/analysis/internal/analysisflags
+- https://github.com/golangci/golangci-lint/pull/5576
+ - sync with https://github.com/golang/tools/blob/v0.28.0/go/analysis/internal/analysisflags
diff --git a/vendor/github.com/golangci/golangci-lint/v2/internal/x/tools/driverutil/url.go b/vendor/github.com/golangci/golangci-lint/v2/internal/x/tools/driverutil/url.go
new file mode 100644
index 000000000..93b3ecfd4
--- /dev/null
+++ b/vendor/github.com/golangci/golangci-lint/v2/internal/x/tools/driverutil/url.go
@@ -0,0 +1,33 @@
+// Copyright 2023 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 driverutil
+
+import (
+ "fmt"
+ "net/url"
+
+ "golang.org/x/tools/go/analysis"
+)
+
+// ResolveURL resolves the URL field for a Diagnostic from an Analyzer
+// and returns the URL. See Diagnostic.URL for details.
+func ResolveURL(a *analysis.Analyzer, d analysis.Diagnostic) (string, error) {
+ if d.URL == "" && d.Category == "" && a.URL == "" {
+ return "", nil // do nothing
+ }
+ raw := d.URL
+ if d.URL == "" && d.Category != "" {
+ raw = "#" + d.Category
+ }
+ u, err := url.Parse(raw)
+ if err != nil {
+ return "", fmt.Errorf("invalid Diagnostic.URL %q: %s", raw, err)
+ }
+ base, err := url.Parse(a.URL)
+ if err != nil {
+ return "", fmt.Errorf("invalid Analyzer.URL %q: %s", a.URL, err)
+ }
+ return base.ResolveReference(u).String(), nil
+}
diff --git a/vendor/github.com/golangci/golangci-lint/v2/jsonschema/custom-gcl.jsonschema.json b/vendor/github.com/golangci/golangci-lint/v2/jsonschema/custom-gcl.jsonschema.json
new file mode 100644
index 000000000..71ea3e98d
--- /dev/null
+++ b/vendor/github.com/golangci/golangci-lint/v2/jsonschema/custom-gcl.jsonschema.json
@@ -0,0 +1,76 @@
+{
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "$ref": "#/$defs/Configuration",
+ "$defs": {
+ "Configuration": {
+ "properties": {
+ "version": {
+ "type": "string",
+ "description": "golangci-lint version."
+ },
+ "name": {
+ "type": "string",
+ "description": "Name of the binary."
+ },
+ "destination": {
+ "type": "string",
+ "description": "Destination is the path to a directory to store the binary."
+ },
+ "plugins": {
+ "items": {
+ "$ref": "#/$defs/Plugin"
+ },
+ "type": "array",
+ "description": "Plugins information."
+ }
+ },
+ "additionalProperties": false,
+ "type": "object",
+ "required": [
+ "version"
+ ],
+ "description": "Configuration represents the configuration file."
+ },
+ "Plugin": {
+ "oneOf": [
+ {
+ "required": [
+ "version"
+ ],
+ "title": "version"
+ },
+ {
+ "required": [
+ "path"
+ ],
+ "title": "path"
+ }
+ ],
+ "properties": {
+ "module": {
+ "type": "string",
+ "description": "Module name."
+ },
+ "import": {
+ "type": "string",
+ "description": "Import to use."
+ },
+ "version": {
+ "type": "string",
+ "description": "Version of the module.\nOnly for module available through a Go proxy."
+ },
+ "path": {
+ "type": "string",
+ "description": "Path to the local module.\nOnly for local module."
+ }
+ },
+ "additionalProperties": false,
+ "type": "object",
+ "required": [
+ "module"
+ ],
+ "description": "Plugin represents information about a plugin."
+ }
+ },
+ "description": "mygcl configuration definition file"
+}
\ No newline at end of file
diff --git a/vendor/github.com/golangci/golangci-lint/v2/jsonschema/golangci.jsonschema.json b/vendor/github.com/golangci/golangci-lint/v2/jsonschema/golangci.jsonschema.json
new file mode 100644
index 000000000..0ac9d577e
--- /dev/null
+++ b/vendor/github.com/golangci/golangci-lint/v2/jsonschema/golangci.jsonschema.json
@@ -0,0 +1,5438 @@
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "$id": "https://json.schemastore.org/golangci-lint.json",
+ "definitions": {
+ "gocritic-checks": {
+ "enum": [
+ "appendAssign",
+ "appendCombine",
+ "argOrder",
+ "assignOp",
+ "badCall",
+ "badCond",
+ "badLock",
+ "badRegexp",
+ "badSorting",
+ "badSyncOnceFunc",
+ "boolExprSimplify",
+ "builtinShadow",
+ "builtinShadowDecl",
+ "captLocal",
+ "caseOrder",
+ "codegenComment",
+ "commentFormatting",
+ "commentedOutCode",
+ "commentedOutImport",
+ "defaultCaseOrder",
+ "deferInLoop",
+ "deferUnlambda",
+ "deprecatedComment",
+ "docStub",
+ "dupArg",
+ "dupBranchBody",
+ "dupCase",
+ "dupImport",
+ "dupOption",
+ "dupSubExpr",
+ "dynamicFmtString",
+ "elseif",
+ "emptyDecl",
+ "emptyFallthrough",
+ "emptyStringTest",
+ "equalFold",
+ "evalOrder",
+ "exitAfterDefer",
+ "exposedSyncMutex",
+ "externalErrorReassign",
+ "filepathJoin",
+ "flagDeref",
+ "flagName",
+ "hexLiteral",
+ "httpNoBody",
+ "hugeParam",
+ "ifElseChain",
+ "importShadow",
+ "indexAlloc",
+ "initClause",
+ "mapKey",
+ "methodExprCall",
+ "nestingReduce",
+ "newDeref",
+ "nilValReturn",
+ "octalLiteral",
+ "offBy1",
+ "paramTypeCombine",
+ "preferDecodeRune",
+ "preferFilepathJoin",
+ "preferFprint",
+ "preferStringWriter",
+ "preferWriteByte",
+ "ptrToRefParam",
+ "rangeAppendAll",
+ "rangeExprCopy",
+ "rangeValCopy",
+ "redundantSprint",
+ "regexpMust",
+ "regexpPattern",
+ "regexpSimplify",
+ "returnAfterHttpError",
+ "ruleguard",
+ "singleCaseSwitch",
+ "sliceClear",
+ "sloppyLen",
+ "sloppyReassign",
+ "sloppyTypeAssert",
+ "sortSlice",
+ "sprintfQuotedString",
+ "sqlQuery",
+ "stringConcatSimplify",
+ "stringXbytes",
+ "stringsCompare",
+ "switchTrue",
+ "syncMapLoadAndDelete",
+ "timeExprSimplify",
+ "todoCommentWithoutDetail",
+ "tooManyResultsChecker",
+ "truncateCmp",
+ "typeAssertChain",
+ "typeDefFirst",
+ "typeSwitchVar",
+ "typeUnparen",
+ "uncheckedInlineErr",
+ "underef",
+ "unlabelStmt",
+ "unlambda",
+ "unnamedResult",
+ "unnecessaryBlock",
+ "unnecessaryDefer",
+ "unslice",
+ "valSwap",
+ "weakCond",
+ "whyNoLint",
+ "wrapperFunc",
+ "yodaStyleExpr",
+ "zeroByteRepeat"
+ ]
+ },
+ "gocritic-tags": {
+ "enum": [
+ "diagnostic",
+ "style",
+ "performance",
+ "experimental",
+ "opinionated",
+ "security"
+ ]
+ },
+ "staticcheck-checks": {
+ "enum": [
+ "*",
+ "all",
+ "SA*",
+ "-SA*",
+ "SA1*",
+ "-SA1*",
+ "SA1000",
+ "-SA1000",
+ "SA1001",
+ "-SA1001",
+ "SA1002",
+ "-SA1002",
+ "SA1003",
+ "-SA1003",
+ "SA1004",
+ "-SA1004",
+ "SA1005",
+ "-SA1005",
+ "SA1006",
+ "-SA1006",
+ "SA1007",
+ "-SA1007",
+ "SA1008",
+ "-SA1008",
+ "SA1010",
+ "-SA1010",
+ "SA1011",
+ "-SA1011",
+ "SA1012",
+ "-SA1012",
+ "SA1013",
+ "-SA1013",
+ "SA1014",
+ "-SA1014",
+ "SA1015",
+ "-SA1015",
+ "SA1016",
+ "-SA1016",
+ "SA1017",
+ "-SA1017",
+ "SA1018",
+ "-SA1018",
+ "SA1019",
+ "-SA1019",
+ "SA1020",
+ "-SA1020",
+ "SA1021",
+ "-SA1021",
+ "SA1023",
+ "-SA1023",
+ "SA1024",
+ "-SA1024",
+ "SA1025",
+ "-SA1025",
+ "SA1026",
+ "-SA1026",
+ "SA1027",
+ "-SA1027",
+ "SA1028",
+ "-SA1028",
+ "SA1029",
+ "-SA1029",
+ "SA1030",
+ "-SA1030",
+ "SA1031",
+ "-SA1031",
+ "SA1032",
+ "-SA1032",
+ "SA2*",
+ "-SA2*",
+ "SA2000",
+ "-SA2000",
+ "SA2001",
+ "-SA2001",
+ "SA2002",
+ "-SA2002",
+ "SA2003",
+ "-SA2003",
+ "SA3*",
+ "-SA3*",
+ "SA3000",
+ "-SA3000",
+ "SA3001",
+ "-SA3001",
+ "SA4*",
+ "-SA4*",
+ "SA4000",
+ "-SA4000",
+ "SA4001",
+ "-SA4001",
+ "SA4003",
+ "-SA4003",
+ "SA4004",
+ "-SA4004",
+ "SA4005",
+ "-SA4005",
+ "SA4006",
+ "-SA4006",
+ "SA4008",
+ "-SA4008",
+ "SA4009",
+ "-SA4009",
+ "SA4010",
+ "-SA4010",
+ "SA4011",
+ "-SA4011",
+ "SA4012",
+ "-SA4012",
+ "SA4013",
+ "-SA4013",
+ "SA4014",
+ "-SA4014",
+ "SA4015",
+ "-SA4015",
+ "SA4016",
+ "-SA4016",
+ "SA4017",
+ "-SA4017",
+ "SA4018",
+ "-SA4018",
+ "SA4019",
+ "-SA4019",
+ "SA4020",
+ "-SA4020",
+ "SA4021",
+ "-SA4021",
+ "SA4022",
+ "-SA4022",
+ "SA4023",
+ "-SA4023",
+ "SA4024",
+ "-SA4024",
+ "SA4025",
+ "-SA4025",
+ "SA4026",
+ "-SA4026",
+ "SA4027",
+ "-SA4027",
+ "SA4028",
+ "-SA4028",
+ "SA4029",
+ "-SA4029",
+ "SA4030",
+ "-SA4030",
+ "SA4031",
+ "-SA4031",
+ "SA4032",
+ "-SA4032",
+ "SA5*",
+ "-SA5*",
+ "SA5000",
+ "-SA5000",
+ "SA5001",
+ "-SA5001",
+ "SA5002",
+ "-SA5002",
+ "SA5003",
+ "-SA5003",
+ "SA5004",
+ "-SA5004",
+ "SA5005",
+ "-SA5005",
+ "SA5007",
+ "-SA5007",
+ "SA5008",
+ "-SA5008",
+ "SA5009",
+ "-SA5009",
+ "SA5010",
+ "-SA5010",
+ "SA5011",
+ "-SA5011",
+ "SA5012",
+ "-SA5012",
+ "SA6*",
+ "-SA6*",
+ "SA6000",
+ "-SA6000",
+ "SA6001",
+ "-SA6001",
+ "SA6002",
+ "-SA6002",
+ "SA6003",
+ "-SA6003",
+ "SA6005",
+ "-SA6005",
+ "SA6006",
+ "-SA6006",
+ "SA9*",
+ "-SA9*",
+ "SA9001",
+ "-SA9001",
+ "SA9002",
+ "-SA9002",
+ "SA9003",
+ "-SA9003",
+ "SA9004",
+ "-SA9004",
+ "SA9005",
+ "-SA9005",
+ "SA9006",
+ "-SA9006",
+ "SA9007",
+ "-SA9007",
+ "SA9008",
+ "-SA9008",
+ "SA9009",
+ "-SA9009",
+ "ST*",
+ "-ST*",
+ "ST1*",
+ "-ST1*",
+ "ST1000",
+ "-ST1000",
+ "ST1001",
+ "-ST1001",
+ "ST1003",
+ "-ST1003",
+ "ST1005",
+ "-ST1005",
+ "ST1006",
+ "-ST1006",
+ "ST1008",
+ "-ST1008",
+ "ST1011",
+ "-ST1011",
+ "ST1012",
+ "-ST1012",
+ "ST1013",
+ "-ST1013",
+ "ST1015",
+ "-ST1015",
+ "ST1016",
+ "-ST1016",
+ "ST1017",
+ "-ST1017",
+ "ST1018",
+ "-ST1018",
+ "ST1019",
+ "-ST1019",
+ "ST1020",
+ "-ST1020",
+ "ST1021",
+ "-ST1021",
+ "ST1022",
+ "-ST1022",
+ "ST1023",
+ "-ST1023",
+ "S*",
+ "-S*",
+ "S1*",
+ "-S1*",
+ "S1000",
+ "-S1000",
+ "S1001",
+ "-S1001",
+ "S1002",
+ "-S1002",
+ "S1003",
+ "-S1003",
+ "S1004",
+ "-S1004",
+ "S1005",
+ "-S1005",
+ "S1006",
+ "-S1006",
+ "S1007",
+ "-S1007",
+ "S1008",
+ "-S1008",
+ "S1009",
+ "-S1009",
+ "S1010",
+ "-S1010",
+ "S1011",
+ "-S1011",
+ "S1012",
+ "-S1012",
+ "S1016",
+ "-S1016",
+ "S1017",
+ "-S1017",
+ "S1018",
+ "-S1018",
+ "S1019",
+ "-S1019",
+ "S1020",
+ "-S1020",
+ "S1021",
+ "-S1021",
+ "S1023",
+ "-S1023",
+ "S1024",
+ "-S1024",
+ "S1025",
+ "-S1025",
+ "S1028",
+ "-S1028",
+ "S1029",
+ "-S1029",
+ "S1030",
+ "-S1030",
+ "S1031",
+ "-S1031",
+ "S1032",
+ "-S1032",
+ "S1033",
+ "-S1033",
+ "S1034",
+ "-S1034",
+ "S1035",
+ "-S1035",
+ "S1036",
+ "-S1036",
+ "S1037",
+ "-S1037",
+ "S1038",
+ "-S1038",
+ "S1039",
+ "-S1039",
+ "S1040",
+ "-S1040",
+ "QF*",
+ "-QF*",
+ "QF1*",
+ "-QF1*",
+ "QF1001",
+ "-QF1001",
+ "QF1002",
+ "-QF1002",
+ "QF1003",
+ "-QF1003",
+ "QF1004",
+ "-QF1004",
+ "QF1005",
+ "-QF1005",
+ "QF1006",
+ "-QF1006",
+ "QF1007",
+ "-QF1007",
+ "QF1008",
+ "-QF1008",
+ "QF1009",
+ "-QF1009",
+ "QF1010",
+ "-QF1010",
+ "QF1011",
+ "-QF1011",
+ "QF1012",
+ "-QF1012"
+ ]
+ },
+ "godoclint-rules": {
+ "enum": [
+ "pkg-doc",
+ "single-pkg-doc",
+ "require-pkg-doc",
+ "start-with-name",
+ "require-doc",
+ "deprecated",
+ "max-len",
+ "no-unused-link",
+ "require-stdlib-doclink"
+ ]
+ },
+ "gosec-rules": {
+ "enum": [
+ "G101",
+ "G102",
+ "G103",
+ "G104",
+ "G106",
+ "G107",
+ "G108",
+ "G109",
+ "G110",
+ "G111",
+ "G112",
+ "G113",
+ "G114",
+ "G115",
+ "G116",
+ "G117",
+ "G118",
+ "G119",
+ "G120",
+ "G121",
+ "G122",
+ "G123",
+ "G124",
+ "G201",
+ "G202",
+ "G203",
+ "G204",
+ "G301",
+ "G302",
+ "G303",
+ "G304",
+ "G305",
+ "G306",
+ "G307",
+ "G401",
+ "G402",
+ "G403",
+ "G404",
+ "G405",
+ "G406",
+ "G408",
+ "G501",
+ "G502",
+ "G503",
+ "G504",
+ "G505",
+ "G506",
+ "G507",
+ "G601",
+ "G602",
+ "G701",
+ "G702",
+ "G703",
+ "G704",
+ "G705",
+ "G706",
+ "G707",
+ "G708",
+ "G709",
+ "G710"
+ ]
+ },
+ "govet-analyzers": {
+ "enum": [
+ "appends",
+ "asmdecl",
+ "assign",
+ "atomic",
+ "atomicalign",
+ "bools",
+ "buildtag",
+ "cgocall",
+ "composites",
+ "copylocks",
+ "deepequalerrors",
+ "defers",
+ "directive",
+ "errorsas",
+ "fieldalignment",
+ "findcall",
+ "framepointer",
+ "hostport",
+ "httpmux",
+ "httpresponse",
+ "ifaceassert",
+ "inline",
+ "loopclosure",
+ "lostcancel",
+ "nilfunc",
+ "nilness",
+ "printf",
+ "reflectvaluecompare",
+ "shadow",
+ "shift",
+ "sigchanyzer",
+ "slog",
+ "sortslice",
+ "stdmethods",
+ "stdversion",
+ "stringintconv",
+ "structtag",
+ "testinggoroutine",
+ "tests",
+ "timeformat",
+ "unmarshal",
+ "unreachable",
+ "unsafeptr",
+ "unusedresult",
+ "unusedwrite",
+ "waitgroup"
+ ]
+ },
+ "revive-rules": {
+ "enum": [
+ "add-constant",
+ "argument-limit",
+ "atomic",
+ "banned-characters",
+ "bare-return",
+ "blank-imports",
+ "bool-literal-in-expr",
+ "call-to-gc",
+ "cognitive-complexity",
+ "comment-spacings",
+ "comments-density",
+ "confusing-naming",
+ "confusing-results",
+ "constant-logical-expr",
+ "context-as-argument",
+ "context-keys-type",
+ "cyclomatic",
+ "datarace",
+ "deep-exit",
+ "defer",
+ "dot-imports",
+ "duplicated-imports",
+ "early-return",
+ "empty-block",
+ "empty-lines",
+ "enforce-map-style",
+ "enforce-repeated-arg-type-style",
+ "enforce-slice-style",
+ "enforce-switch-style",
+ "epoch-naming",
+ "error-naming",
+ "error-return",
+ "error-strings",
+ "errorf",
+ "exported",
+ "file-header",
+ "file-length-limit",
+ "filename-format",
+ "flag-parameter",
+ "forbidden-call-in-wg-go",
+ "function-length",
+ "function-result-limit",
+ "get-return",
+ "identical-branches",
+ "identical-ifelseif-branches",
+ "identical-ifelseif-conditions",
+ "identical-switch-branches",
+ "identical-switch-conditions",
+ "if-return",
+ "import-alias-naming",
+ "import-shadowing",
+ "imports-blocklist",
+ "increment-decrement",
+ "indent-error-flow",
+ "inefficient-map-lookup",
+ "line-length-limit",
+ "max-control-nesting",
+ "max-public-structs",
+ "modifies-parameter",
+ "modifies-value-receiver",
+ "nested-structs",
+ "optimize-operands-order",
+ "package-comments",
+ "package-naming",
+ "package-directory-mismatch",
+ "range-val-address",
+ "range-val-in-closure",
+ "range",
+ "receiver-naming",
+ "redefines-builtin-id",
+ "redundant-build-tag",
+ "redundant-import-alias",
+ "redundant-test-main-exit",
+ "string-format",
+ "string-of-int",
+ "struct-tag",
+ "superfluous-else",
+ "time-date",
+ "time-equal",
+ "time-naming",
+ "unchecked-type-assertion",
+ "unconditional-recursion",
+ "unexported-naming",
+ "unexported-return",
+ "unhandled-error",
+ "unnecessary-format",
+ "unnecessary-if",
+ "unnecessary-stmt",
+ "unreachable-code",
+ "unsecure-url-scheme",
+ "unused-parameter",
+ "unused-receiver",
+ "use-any",
+ "use-errors-new",
+ "use-fmt-print",
+ "use-slices-sort",
+ "use-waitgroup-go",
+ "useless-break",
+ "useless-fallthrough",
+ "var-declaration",
+ "var-naming",
+ "waitgroup-by-value"
+ ]
+ },
+ "iface-analyzers": {
+ "enum": [
+ "identical",
+ "unused",
+ "opaque",
+ "unexported"
+ ]
+ },
+ "tagliatelle-cases": {
+ "enum": [
+ "",
+ "camel",
+ "pascal",
+ "kebab",
+ "snake",
+ "goCamel",
+ "goPascal",
+ "goKebab",
+ "goSnake",
+ "upper",
+ "upperSnake",
+ "lower",
+ "header"
+ ]
+ },
+ "modernize-analyzers": {
+ "enum": [
+ "any",
+ "fmtappendf",
+ "forvar",
+ "mapsloop",
+ "minmax",
+ "newexpr",
+ "omitzero",
+ "plusbuild",
+ "rangeint",
+ "reflecttypefor",
+ "slicescontains",
+ "slicessort",
+ "stditerators",
+ "stringscut",
+ "stringscutprefix",
+ "stringsseq",
+ "stringsbuilder",
+ "testingcontext",
+ "unsafefuncs",
+ "waitgroup"
+ ]
+ },
+ "wsl-checks": {
+ "enum": [
+ "after-block",
+ "after-decl",
+ "after-defer",
+ "after-expr",
+ "after-go",
+ "append",
+ "assign-exclusive",
+ "assign-expr",
+ "assign",
+ "branch",
+ "cuddle-group",
+ "decl",
+ "defer",
+ "err",
+ "expr",
+ "for",
+ "go",
+ "if",
+ "inc-dec",
+ "label",
+ "leading-whitespace",
+ "range",
+ "return",
+ "select",
+ "send",
+ "switch",
+ "trailing-whitespace",
+ "type-switch"
+ ]
+ },
+ "relative-path-modes": {
+ "enum": [
+ "gomod",
+ "gitroot",
+ "cfg",
+ "wd"
+ ]
+ },
+ "simple-format": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "path": {
+ "$ref": "#/definitions/formats-path",
+ "default": "stdout"
+ }
+ }
+ },
+ "formats-path" : {
+ "anyOf": [
+ {
+ "enum": [
+ "stdout",
+ "stderr"
+ ]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ },
+ "linter-names": {
+ "$comment": "anyOf with enum is used to allow auto-completion of non-custom linters",
+ "description": "Usable linter names.",
+ "anyOf": [
+ {
+ "enum": [
+ "arangolint",
+ "asasalint",
+ "asciicheck",
+ "bidichk",
+ "bodyclose",
+ "canonicalheader",
+ "clickhouselint",
+ "containedctx",
+ "contextcheck",
+ "copyloopvar",
+ "cyclop",
+ "decorder",
+ "depguard",
+ "dogsled",
+ "dupl",
+ "dupword",
+ "durationcheck",
+ "embeddedstructfieldcheck",
+ "errcheck",
+ "errchkjson",
+ "errname",
+ "errorlint",
+ "exhaustive",
+ "exhaustruct",
+ "exptostd",
+ "fatcontext",
+ "forbidigo",
+ "forcetypeassert",
+ "funcorder",
+ "funlen",
+ "ginkgolinter",
+ "gocheckcompilerdirectives",
+ "gochecknoglobals",
+ "gochecknoinits",
+ "gochecksumtype",
+ "gocognit",
+ "goconst",
+ "gocritic",
+ "gocyclo",
+ "godoclint",
+ "godot",
+ "godox",
+ "err113",
+ "goheader",
+ "gomoddirectives",
+ "gomodguard",
+ "gomodguard_v2",
+ "goprintffuncname",
+ "gosec",
+ "gosimple",
+ "gosmopolitan",
+ "govet",
+ "grouper",
+ "iface",
+ "importas",
+ "inamedparam",
+ "ineffassign",
+ "interfacebloat",
+ "intrange",
+ "iotamixing",
+ "ireturn",
+ "lll",
+ "loggercheck",
+ "maintidx",
+ "makezero",
+ "mirror",
+ "misspell",
+ "mnd",
+ "modernize",
+ "musttag",
+ "nakedret",
+ "nestif",
+ "nilerr",
+ "nilnesserr",
+ "nilnil",
+ "nlreturn",
+ "noctx",
+ "noinlineerr",
+ "nolintlint",
+ "nonamedreturns",
+ "nosprintfhostport",
+ "paralleltest",
+ "perfsprint",
+ "prealloc",
+ "predeclared",
+ "promlinter",
+ "protogetter",
+ "reassign",
+ "recvcheck",
+ "revive",
+ "rowserrcheck",
+ "sloglint",
+ "sqlclosecheck",
+ "staticcheck",
+ "stylecheck",
+ "tagalign",
+ "tagliatelle",
+ "testableexamples",
+ "testifylint",
+ "testpackage",
+ "thelper",
+ "tparallel",
+ "unconvert",
+ "unparam",
+ "unused",
+ "usestdlibvars",
+ "usetesting",
+ "varnamelen",
+ "wastedassign",
+ "whitespace",
+ "wrapcheck",
+ "wsl",
+ "wsl_v5",
+ "zerologlint"
+ ]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ },
+ "formatter-names": {
+ "description": "Usable formatter names.",
+ "enum": [
+ "gci",
+ "gofmt",
+ "gofumpt",
+ "goimports",
+ "golines",
+ "swaggo"
+ ]
+ },
+ "settings": {
+ "definitions": {
+ "dupwordSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "keywords": {
+ "description": "Keywords for detecting duplicate words. If this list is not empty, only the words defined in this list will be detected.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["the", "and", "a"]
+ }
+ },
+ "ignore": {
+ "description": "Keywords used to ignore detection.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["0C0C"]
+ }
+ },
+ "comments-only": {
+ "description": "Checks only comments, skip strings.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "asasalintSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "exclude": {
+ "description": "To specify a set of function names to exclude.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["\\.Wrapf"]
+ }
+ },
+ "use-builtin-exclusions": {
+ "description": "To enable/disable the asasalint builtin exclusions of function names.",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "bidichkSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "left-to-right-embedding": {
+ "description": "Disallow: LEFT-TO-RIGHT-EMBEDDING",
+ "type": "boolean",
+ "default": false
+ },
+ "right-to-left-embedding": {
+ "description": "Disallow: RIGHT-TO-LEFT-EMBEDDING",
+ "type": "boolean",
+ "default": false
+ },
+ "pop-directional-formatting": {
+ "description": "Disallow: POP-DIRECTIONAL-FORMATTING",
+ "type": "boolean",
+ "default": false
+ },
+ "left-to-right-override": {
+ "description": "Disallow: LEFT-TO-RIGHT-OVERRIDE",
+ "type": "boolean",
+ "default": false
+ },
+ "right-to-left-override": {
+ "description": "Disallow: RIGHT-TO-LEFT-OVERRIDE",
+ "type": "boolean",
+ "default": false
+ },
+ "left-to-right-isolate": {
+ "description": "Disallow: LEFT-TO-RIGHT-ISOLATE",
+ "type": "boolean",
+ "default": false
+ },
+ "right-to-left-isolate": {
+ "description": "Disallow: RIGHT-TO-LEFT-ISOLATE",
+ "type": "boolean",
+ "default": false
+ },
+ "first-strong-isolate": {
+ "description": "Disallow: FIRST-STRONG-ISOLATE",
+ "type": "boolean",
+ "default": false
+ },
+ "pop-directional-isolate": {
+ "description": "Disallow: POP-DIRECTIONAL-ISOLATE",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "bodycloseSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-consumption": {
+ "description": "Check that the response body is consumed.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "cyclopSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-complexity": {
+ "description": "Max complexity the function can have",
+ "type": "integer",
+ "default": 10,
+ "minimum": 0
+ },
+ "package-average": {
+ "description": "Max average complexity in package",
+ "type": "number",
+ "default": 0,
+ "minimum": 0
+ }
+ }
+ },
+ "decorderSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "dec-order": {
+ "type": "array",
+ "default": [["type", "const", "var", "func"]],
+ "items": {
+ "enum": ["type", "const", "var", "func"]
+ }
+ },
+ "ignore-underscore-vars": {
+ "description": "Underscore vars (vars with \"_\" as the name) will be ignored at all checks",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-dec-order-check": {
+ "description": "Order of declarations is not checked",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-init-func-first-check": {
+ "description": "Allow init func to be anywhere in file",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-dec-num-check": {
+ "description": "Multiple global type, const and var declarations are allowed",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-type-dec-num-check": {
+ "description": "Type declarations will be ignored for dec num check",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-const-dec-num-check": {
+ "description": "Const declarations will be ignored for dec num check",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-var-dec-num-check": {
+ "description": "Var declarations will be ignored for dec num check",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ },
+ "depguardSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "rules": {
+ "description": "Rules to apply.",
+ "type": "object",
+ "additionalProperties": false,
+ "patternProperties": {
+ "^[^.]+$": {
+ "description": "Name of a rule.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "list-mode": {
+ "description": "Used to determine the package matching priority.",
+ "enum": ["original", "strict", "lax"],
+ "default": "original"
+ },
+ "files": {
+ "description": "List of file globs that will match this list of settings to compare against.",
+ "additionalProperties": false,
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "allow": {
+ "description": "List of allowed packages.",
+ "additionalProperties": false,
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "deny": {
+ "description": "Packages that are not allowed where the value is a suggestion.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "desc": {
+ "description": "Description",
+ "type": "string"
+ },
+ "pkg": {
+ "description": "Package",
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "dogsledSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-blank-identifiers": {
+ "description": "Check assignments with too many blank identifiers.",
+ "type": "integer",
+ "default": 2,
+ "minimum": 0
+ }
+ }
+ },
+ "duplSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "threshold": {
+ "description": "Tokens count to trigger issue.",
+ "type": "integer",
+ "default": 150,
+ "minimum": 0
+ }
+ }
+ },
+ "embeddedstructfieldcheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "empty-line": {
+ "description": "Checks that there is an empty space between the embedded fields and regular fields.",
+ "type": "boolean",
+ "default": false
+ },
+ "forbid-mutex": {
+ "description": "Checks that sync.Mutex and sync.RWMutex are not used as embedded fields.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "errcheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-type-assertions": {
+ "description": "Report about not checking errors in type assertions, i.e.: `a := b.(MyStruct)`",
+ "type": "boolean",
+ "default": false
+ },
+ "check-blank": {
+ "description": "Report about assignment of errors to blank identifier",
+ "type": "boolean",
+ "default": false
+ },
+ "exclude-functions": {
+ "description": "List of functions to exclude from checking, where each entry is a single function to exclude",
+ "type": "array",
+ "examples": ["io/ioutil.ReadFile", "io.Copy(*bytes.Buffer)"],
+ "items": {
+ "type": "string"
+ }
+ },
+ "disable-default-exclusions": {
+ "description": "To disable the errcheck built-in exclude list",
+ "type": "boolean",
+ "default": false
+ },
+ "verbose": {
+ "description": "Display function signature instead of selector",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "errchkjsonSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-error-free-encoding": {
+ "type": "boolean",
+ "default": false
+ },
+ "report-no-exported": {
+ "description": "Issue on struct that doesn't have exported fields.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "errorlintSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "errorf": {
+ "description": "Check whether fmt.Errorf uses the %w verb for formatting errors",
+ "type": "boolean",
+ "default": true
+ },
+ "errorf-multi": {
+ "description": "Permit more than 1 %w verb, valid per Go 1.20",
+ "type": "boolean",
+ "default": true
+ },
+ "asserts": {
+ "description": "Check for plain type assertions and type switches.",
+ "type": "boolean",
+ "default": true
+ },
+ "comparison": {
+ "description": "Check for plain error comparisons",
+ "type": "boolean",
+ "default": true
+ },
+ "allowed-errors": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "err": {
+ "type": "string"
+ },
+ "fun": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "allowed-errors-wildcard": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "err": {
+ "type": "string"
+ },
+ "fun": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "exhaustiveSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check": {
+ "description": "Program elements to check for exhaustiveness.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["switch", "map"]
+ }
+ },
+ "explicit-exhaustive-switch": {
+ "description": "Only run exhaustive check on switches with \"//exhaustive:enforce\" comment.",
+ "type": "boolean",
+ "default": false
+ },
+ "explicit-exhaustive-map": {
+ "description": "Only run exhaustive check on map literals with \"//exhaustive:enforce\" comment.",
+ "type": "boolean",
+ "default": false
+ },
+ "default-case-required": {
+ "description": "Switch statement requires default case even if exhaustive.",
+ "type": "boolean",
+ "default": false
+ },
+ "default-signifies-exhaustive": {
+ "description": "Presence of `default` case in switch statements satisfies exhaustiveness, even if all enum members are not listed.",
+ "type": "boolean",
+ "default": false
+ },
+ "ignore-enum-members": {
+ "description": "Enum members matching `regex` do not have to be listed in switch statements to satisfy exhaustiveness",
+ "type": "string"
+ },
+ "ignore-enum-types": {
+ "description": "Enum types matching the supplied regex do not have to be listed in switch statements to satisfy exhaustiveness.",
+ "type": "string"
+ },
+ "package-scope-only": {
+ "description": "Consider enums only in package scopes, not in inner scopes.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "exhaustructSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "include": {
+ "description": "List of regular expressions to match struct packages and names.",
+ "type": "array",
+ "examples": [".*\\.Test"],
+ "items": {
+ "type": "string"
+ }
+ },
+ "exclude": {
+ "description": "List of regular expressions to exclude struct packages and names from check.",
+ "type": "array",
+ "examples": ["cobra\\.Command$"],
+ "items": {
+ "type": "string"
+ }
+ },
+ "allow-empty": {
+ "description": "Allows empty structures, effectively excluding them from the check.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-empty-rx": {
+ "description": "List of regular expressions to match type names that should be allowed to be empty.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "allow-empty-returns": {
+ "description": "Allows empty structures in return statements.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-empty-declarations": {
+ "description": "Allows empty structures in variable declarations.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "fatcontextSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-struct-pointers": {
+ "description": "Check for potential fat contexts in struct pointers.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "forbidigoSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "exclude-godoc-examples": {
+ "description": "Exclude code in godoc examples.",
+ "type": "boolean",
+ "default": true
+ },
+ "analyze-types": {
+ "description": "Instead of matching the literal source code, use type information to replace expressions with strings that contain the package name and (for methods and fields) the type name.",
+ "type": "boolean",
+ "default": true
+ },
+ "forbid": {
+ "description": "List of identifiers to forbid (written using `regexp`)",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "pattern": {
+ "description": "Pattern",
+ "type": "string"
+ },
+ "pkg": {
+ "description": "Package",
+ "type": "string"
+ },
+ "msg": {
+ "description": "Message",
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "funcorderSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "constructor": {
+ "description": "Checks that constructors are placed after the structure declaration.",
+ "type": "boolean",
+ "default": true
+ },
+ "struct-method": {
+ "description": "Checks if the exported methods of a structure are placed before the non-exported ones.",
+ "type": "boolean",
+ "default": true
+ },
+ "alphabetical": {
+ "description": "Checks if the constructors and/or structure methods are sorted alphabetically.",
+ "type": "boolean",
+ "default": false
+ },
+ "function": {
+ "description": "Checks that exported functions are placed before unexported functions.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "funlenSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "lines": {
+ "description": "Limit lines number per function.",
+ "type": "integer",
+ "default": 60
+ },
+ "statements": {
+ "description": "Limit statements number per function.",
+ "type": "integer",
+ "default": 40
+ },
+ "ignore-comments": {
+ "description": "Ignore comments when counting lines.",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "gciSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "sections": {
+ "description": "Section configuration to compare against.",
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "enum": [
+ "standard",
+ "default",
+ "blank",
+ "dot",
+ "alias",
+ "localmodule"
+ ]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ },
+ "default": ["standard", "default"]
+ },
+ "no-inline-comments": {
+ "description": "Checks that no inline Comments are present.",
+ "type": "boolean",
+ "default": false
+ },
+ "no-prefix-comments": {
+ "description": "Checks that no prefix Comments(comment lines above an import) are present.",
+ "type": "boolean",
+ "default": false
+ },
+ "custom-order": {
+ "description": "Enable custom order of sections.",
+ "type": "boolean",
+ "default": false
+ },
+ "no-lex-order": {
+ "description": "Drops lexical ordering for custom sections.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "ginkgolinterSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "suppress-len-assertion": {
+ "description": "Suppress the wrong length assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-nil-assertion": {
+ "description": "Suppress the wrong nil assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-err-assertion": {
+ "description": "Suppress the wrong error assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-compare-assertion": {
+ "description": "Suppress the wrong comparison assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-async-assertion": {
+ "description": "Suppress the function all in async assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-type-compare-assertion": {
+ "description": "Suppress warning for comparing values from different types, like int32 and uint32.",
+ "type": "boolean",
+ "default": false
+ },
+ "forbid-focus-container": {
+ "description": "Trigger warning for ginkgo focus containers like FDescribe, FContext, FWhen or FIt.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-havelen-zero": {
+ "description": "Don't trigger warnings for HaveLen(0).",
+ "type": "boolean",
+ "default": false
+ },
+ "force-expect-to": {
+ "description": "Force using `Expect` with `To`, `ToNot` or `NotTo`",
+ "type": "boolean",
+ "default": false
+ },
+ "validate-async-intervals": {
+ "description": "Best effort validation of async intervals (timeout and polling).",
+ "type": "boolean",
+ "default": false
+ },
+ "forbid-spec-pollution": {
+ "description": "Trigger a warning for variable assignments in ginkgo containers like `Describe`, `Context` and `When`, instead of in `BeforeEach()`.",
+ "type": "boolean",
+ "default": false
+ },
+ "force-succeed": {
+ "description": "Force using the Succeed matcher for error functions, and the HaveOccurred matcher for non-function error values.",
+ "type": "boolean",
+ "default": false
+ },
+ "force-assertion-description": {
+ "description": "Force adding assertion descriptions to gomega matchers.",
+ "type": "boolean",
+ "default": false
+ },
+ "force-tonot": {
+ "description": "Force using `ToNot`, `ShouldNot` instead of `To(Not())`.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "gochecksumtypeSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "default-signifies-exhaustive": {
+ "description": "Presence of `default` case in switch statements satisfies exhaustiveness, if all members are not listed.",
+ "type": "boolean",
+ "default": true
+ },
+ "include-shared-interfaces": {
+ "description": "Include shared interfaces in the exhaustiviness check.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "gocognitSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "min-complexity": {
+ "description": "Minimal code complexity to report (we recommend 10-20).",
+ "type": "integer",
+ "default": 30
+ }
+ }
+ },
+ "goconstSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "match-constant": {
+ "description": "Look for existing constants matching the values",
+ "type": "boolean",
+ "default": true
+ },
+ "min-len": {
+ "description": "Minimum length of string constant.",
+ "type": "integer",
+ "default": 3
+ },
+ "min-occurrences": {
+ "description": "Minimum occurrences count to trigger.",
+ "type": "integer",
+ "default": 3
+ },
+ "ignore-calls": {
+ "description": "Ignore when constant is not used as function argument",
+ "type": "boolean",
+ "default": true
+ },
+ "ignore-string-values": {
+ "description": "Exclude strings matching the given regular expression",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "numbers": {
+ "description": "Search also for duplicated numbers.",
+ "type": "boolean",
+ "default": false
+ },
+ "min": {
+ "description": "Minimum value, only works with `numbers`",
+ "type": "integer",
+ "default": 3
+ },
+ "max": {
+ "description": "Maximum value, only works with `numbers`",
+ "type": "integer",
+ "default": 3
+ },
+ "find-duplicates": {
+ "description": "Detects constants with identical values",
+ "type": "boolean",
+ "default": false
+ },
+ "eval-const-expressions": {
+ "description": "Evaluates of constant expressions like Prefix + \"suffix\"",
+ "type": "boolean",
+ "default": false
+ },
+ "ignore-tests": {
+ "description": "Ignore strings from test files",
+ "type": "boolean",
+ "default": false
+ },
+ "ignore-functions": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "gocriticSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "enabled-checks": {
+ "description": "Which checks should be enabled. By default, a list of stable checks is used. To see it, run `GL_DEBUG=gocritic golangci-lint run`.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/gocritic-checks"
+ }
+ },
+ "disabled-checks": {
+ "description": "Which checks should be disabled.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/gocritic-checks"
+ },
+ "default": []
+ },
+ "enabled-tags": {
+ "description": "Enable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/gocritic-tags"
+ }
+ },
+ "disabled-tags": {
+ "description": "Disable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/gocritic-tags"
+ }
+ },
+ "settings": {
+ "description": "Settings passed to gocritic. Properties must be valid and enabled check names.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "captLocal": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "paramsOnly" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "commentedOutCode": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "minLength" : {
+ "type": "number",
+ "default": 15
+ }
+ }
+ },
+ "elseif": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skipBalanced" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "hugeParam": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "sizeThreshold" : {
+ "type": "number",
+ "default": 80
+ }
+ }
+ },
+ "ifElseChain": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "minThreshold" : {
+ "type": "number",
+ "default": 2
+ }
+ }
+ },
+ "nestingReduce": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "bodyWidth" : {
+ "type": "number",
+ "default": 5
+ }
+ }
+ },
+ "rangeExprCopy": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "sizeThreshold" : {
+ "type": "number",
+ "default": 512
+ },
+ "skipTestFuncs" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "rangeValCopy": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "sizeThreshold" : {
+ "type": "number",
+ "default": 128
+ },
+ "skipTestFuncs" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "ruleguard": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "debug" : {
+ "type": "string"
+ },
+ "enable" : {
+ "type": "string"
+ },
+ "disable" : {
+ "type": "string"
+ },
+ "failOn" : {
+ "type": "string"
+ },
+ "rules" : {
+ "type": "string"
+ }
+ }
+ },
+ "tooManyResultsChecker": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "maxResults" : {
+ "type": "number",
+ "default": 5
+ }
+ }
+ },
+ "truncateCmp": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skipArchDependent" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "underef": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skipRecvDeref" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "unnamedResult": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "checkExported" : {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ }
+ }
+ },
+ "disable-all": {
+ "type": "boolean",
+ "default": false
+ },
+ "enable-all": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "gocycloSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "min-complexity": {
+ "description": "Minimum code complexity to report (we recommend 10-20).",
+ "type": "integer",
+ "default": 30
+ }
+ }
+ },
+ "godoclintSettings": {
+ "type": "object",
+ "properties": {
+ "default": {
+ "type": "string",
+ "enum": ["all", "basic", "none"],
+ "default": "basic",
+ "description": "Default set of rules to enable."
+ },
+ "enable": {
+ "description": "List of rules to enable in addition to the default set.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "$ref": "#/definitions/godoclint-rules"
+ }
+ },
+ "disable": {
+ "description": "List of rules to disable.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "$ref": "#/definitions/godoclint-rules"
+ }
+ },
+ "options": {
+ "type": "object",
+ "description": "A map for setting individual rule options.",
+ "properties": {
+ "max-len": {
+ "type": "object",
+ "properties": {
+ "length": {
+ "type": "integer",
+ "description": "Maximum line length for godocs, not including the `//`, `/*` or `*/` tokens.",
+ "default": 77
+ }
+ }
+ },
+ "require-doc": {
+ "type": "object",
+ "properties": {
+ "ignore-exported": {
+ "type": "boolean",
+ "description": "Ignore exported (public) symbols when applying the `require-doc` rule.",
+ "default": false
+ },
+ "ignore-unexported": {
+ "type": "boolean",
+ "description": "Ignore unexported (private) symbols when applying the `require-doc` rule.",
+ "default": true
+ }
+ }
+ },
+ "start-with-name": {
+ "type": "object",
+ "properties": {
+ "include-unexported": {
+ "type": "boolean",
+ "description": "Include unexported symbols when applying the `start-with-name` rule.",
+ "default": false
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "godotSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "scope": {
+ "description": "Comments to be checked.",
+ "enum": ["declarations", "toplevel", "all", "noinline"],
+ "default": "declarations"
+ },
+ "exclude": {
+ "description": "List of regexps for excluding particular comment lines from check.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "period": {
+ "description": "Check that each sentence ends with a period.",
+ "type": "boolean",
+ "default": true
+ },
+ "capital": {
+ "description": "Check that each sentence starts with a capital letter.",
+ "type": "boolean",
+ "default": false
+ },
+ "check-all": {
+ "description": "DEPRECATED: Check all top-level comments, not only declarations.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "godoxSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "keywords": {
+ "description": "Report any comments starting with one of these keywords. This is useful for TODO or FIXME comments that might be left in the code accidentally and should be resolved before merging.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "default": ["TODO", "BUG", "FIXME"]
+ }
+ }
+ },
+ "gofmtSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "simplify": {
+ "description": "Simplify code.",
+ "type": "boolean",
+ "default": true
+ },
+ "rewrite-rules": {
+ "description": "Apply the rewrite rules to the source before reformatting.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "pattern": {
+ "type": "string"
+ },
+ "replacement": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "golinesSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-len": {
+ "type": "integer",
+ "default": 100
+ },
+ "tab-len": {
+ "type": "integer",
+ "default": 4
+ },
+ "shorten-comments": {
+ "type": "boolean",
+ "default": false
+ },
+ "reformat-tags": {
+ "type": "boolean",
+ "default": true
+ },
+ "chain-split-dots": {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "interfacebloatSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max": {
+ "description": "The maximum number of methods allowed for an interface.",
+ "type": "integer"
+ }
+ }
+ },
+ "gofumptSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "extra-rules": {
+ "description": "Choose whether or not to use the extra rules that are disabled by default.",
+ "type": "boolean",
+ "default": false
+ },
+ "module-path": {
+ "description": " Module path which contains the source code being formatted.",
+ "type": "string"
+ }
+ }
+ },
+ "goheaderSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "values": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "const": {
+ "description": "Constants to use in the template.",
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "description": "Value for the constant.",
+ "type": "string"
+ }
+ },
+ "additionalProperties": false,
+ "examples": [
+ {
+ "YEAR": "2030",
+ "COMPANY": "MY FUTURISTIC COMPANY"
+ }
+ ]
+ },
+ "regexp": {
+ "description": "Regular expressions to use in your template.",
+ "type": "object",
+ "additionalProperties": false,
+ "patternProperties": {
+ "^.+$": {
+ "type": "string"
+ }
+ },
+ "examples": [
+ {
+ "AUTHOR": ".*@mycompany\\.com"
+ }
+ ]
+ }
+ }
+ },
+ "template": {
+ "description": "Template to put on top of every file.",
+ "type": "string",
+ "examples": [
+ "{{ MY COMPANY }}\nSPDX-License-Identifier: Apache-2.0\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at:\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License."
+ ]
+ },
+ "template-path": {
+ "description": "Path to the file containing the template source.",
+ "type": "string",
+ "examples": ["my_header_template.txt"]
+ }
+ },
+ "oneOf": [
+ { "required": ["template"] },
+ { "required": ["template-path"] }
+ ]
+ },
+ "goimportsSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "local-prefixes": {
+ "description": "Put imports beginning with prefix after 3rd-party packages. It is a list of prefixes.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "gomoddirectivesSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "replace-local": {
+ "description": "Allow local `replace` directives.",
+ "type": "boolean",
+ "default": true
+ },
+ "replace-allow-list": {
+ "description": "List of allowed `replace` directives.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "retract-allow-no-explanation": {
+ "description": "Allow to not explain why the version has been retracted in the `retract` directives.",
+ "type": "boolean",
+ "default": false
+ },
+ "exclude-forbidden": {
+ "description": "Forbid the use of the `exclude` directives.",
+ "type": "boolean",
+ "default": false
+ },
+ "ignore-forbidden": {
+ "description": "Forbid the use of the `ignore` directives. (>= go1.25)",
+ "type": "boolean",
+ "default": false
+ },
+ "toolchain-forbidden": {
+ "description": "Forbid the use of the `toolchain` directive.",
+ "type": "boolean",
+ "default": false
+ },
+ "toolchain-pattern": {
+ "description": "Defines a pattern to validate `toolchain` directive.",
+ "type": "string"
+ },
+ "tool-forbidden": {
+ "description": "Forbid the use of the `tool` directives.",
+ "type": "boolean",
+ "default": false
+ },
+ "go-debug-forbidden": {
+ "description": "Forbid the use of the `godebug` directive.",
+ "type": "boolean",
+ "default": false
+ },
+ "go-version-pattern": {
+ "description": "Defines a pattern to validate `go` minimum version directive.",
+ "type": "string",
+ "default": ""
+ },
+ "check-module-path": {
+ "description": "Check the validity of the module path.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "gomodguardv2Settings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "local-replace-directives": {
+ "type": "boolean"
+ },
+ "allowed": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["module"],
+ "properties": {
+ "module": {
+ "type": "string"
+ },
+ "version": {
+ "type": "string"
+ },
+ "match-type": {
+ "enum": ["", "exact", "prefix", "regex"],
+ "default": "exact"
+ }
+ }
+ }
+ },
+ "blocked": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["module"],
+ "properties": {
+ "module": {
+ "type": "string"
+ },
+ "version": {
+ "type": "string"
+ },
+ "match-type": {
+ "type": "string"
+ },
+ "reason": {
+ "type": "string"
+ },
+ "recommendations": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "gomodguardSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "allowed": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "modules": {
+ "description": "List of allowed modules.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["gopkg.in/yaml.v2"]
+ }
+ },
+ "domains": {
+ "description": "List of allowed module domains.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["golang.org"]
+ }
+ }
+ }
+ },
+ "blocked": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "modules": {
+ "description": "List of blocked modules.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "recommendations": {
+ "description": "Recommended modules that should be used instead.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "reason": {
+ "description": "Reason why the recommended module should be used.",
+ "type": "string"
+ }
+ }
+ }
+ },
+ "additionalProperties": false
+ }
+ },
+ "versions": {
+ "description": "List of blocked module version constraints.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "patternProperties": {
+ "^.*$": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "version": {
+ "description": "Version constraint.",
+ "type": "string"
+ },
+ "reason": {
+ "description": "Reason why the version constraint exists.",
+ "type": "string"
+ }
+ },
+ "required": ["reason"]
+ }
+ }
+ }
+ },
+ "local-replace-directives": {
+ "description": "Raise lint issues if loading local path with replace directive",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ }
+ }
+ },
+ "gosecSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "includes": {
+ "type": "array",
+ "description": "To select a subset of rules to run",
+ "examples": [["G401"]],
+ "items": {
+ "$ref": "#/definitions/gosec-rules"
+ }
+ },
+ "excludes": {
+ "type": "array",
+ "description": "To specify a set of rules to explicitly exclude",
+ "examples": [["G401"]],
+ "items": {
+ "$ref": "#/definitions/gosec-rules"
+ }
+ },
+ "severity": {
+ "description": "Filter out the issues with a lower severity than the given value",
+ "type": "string",
+ "enum": ["low", "medium", "high"],
+ "default": "low"
+ },
+ "confidence": {
+ "description": "Filter out the issues with a lower confidence than the given value",
+ "type": "string",
+ "enum": ["low", "medium", "high"],
+ "default": "low"
+ },
+ "config": {
+ "description": "To specify the configuration of rules",
+ "type": "object"
+ },
+ "concurrency": {
+ "description": "Concurrency value",
+ "type": "integer"
+ }
+ }
+ },
+ "gosmopolitanSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "allow-time-local": {
+ "description": "Allow and ignore `time.Local` usages.",
+ "type": "boolean",
+ "default": false
+ },
+ "escape-hatches": {
+ "description": "List of fully qualified names in the `full/pkg/path.name` form, to act as \"i18n escape hatches\".",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "watch-for-scripts": {
+ "description": "List of Unicode scripts to watch for any usage in string literals.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "govetSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "settings": {
+ "description": "Settings per analyzer. Map of analyzer name to specific settings.\nRun `go tool vet help` to find out more.",
+ "type": "object",
+ "propertyNames": {
+ "$ref": "#/definitions/govet-analyzers"
+ },
+ "patternProperties": {
+ "^.*$": {
+ "description": "Run `go tool vet help ` to see all settings.",
+ "type": "object"
+ }
+ }
+ },
+ "enable": {
+ "description": "Enable analyzers by name.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/govet-analyzers"
+ }
+ },
+ "disable": {
+ "description": "Disable analyzers by name.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/govet-analyzers"
+ }
+ },
+ "enable-all": {
+ "description": "Enable all analyzers.",
+ "type": "boolean",
+ "default": false
+ },
+ "disable-all": {
+ "description": "Disable all analyzers.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "grouperSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "const-require-single-const": {
+ "type": "boolean",
+ "default": false
+ },
+ "const-require-grouping": {
+ "type": "boolean",
+ "default": false
+ },
+ "import-require-single-import": {
+ "type": "boolean",
+ "default": false
+ },
+ "import-require-grouping": {
+ "type": "boolean",
+ "default": false
+ },
+ "type-require-single-type": {
+ "type": "boolean",
+ "default": false
+ },
+ "type-require-grouping": {
+ "type": "boolean",
+ "default": false
+ },
+ "var-require-single-var": {
+ "type": "boolean",
+ "default": false
+ },
+ "var-require-grouping": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "ifaceSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "enable": {
+ "description": "Enable analyzers by name.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/iface-analyzers"
+ }
+ },
+ "settings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "unused": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "exclude": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "importasSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "no-unaliased": {
+ "description": "Do not allow unaliased imports of aliased packages.",
+ "type": "boolean",
+ "default": false
+ },
+ "no-extra-aliases": {
+ "description": "Do not allow non-required aliases.",
+ "type": "boolean",
+ "default": false
+ },
+ "alias": {
+ "description": "List of aliases",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "pkg": {
+ "description": "Package path e.g. knative.dev/serving/pkg/apis/autoscaling/v1alpha1",
+ "type": "string"
+ },
+ "alias": {
+ "description": "Package alias e.g. autoscalingv1alpha1",
+ "type": "string"
+ }
+ },
+ "required": ["pkg", "alias"]
+ }
+ }
+ }
+ },
+ "inamedparamSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skip-single-param": {
+ "description": "Skips check for interface methods with only a single parameter.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "ineffassignSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-escaping-errors": {
+ "description": "Check escaping variables of type error, may cause false positives.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "iotamixingSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "report-individual": {
+ "description": "Whether to report individual consts rather than just the const block.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "ireturnSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "description": "Use either `reject` or `allow` properties for interfaces matching.",
+ "properties": {
+ "allow": {
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "enum": ["anon", "error", "empty", "stdlib"]
+ }
+ ]
+ }
+ },
+ "reject": {
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "enum": ["anon", "error", "empty", "stdlib"]
+ }
+ ]
+ }
+ }
+ },
+ "anyOf": [
+ {
+ "not": {
+ "properties": {
+ "allow": {
+ "const": "reject"
+ }
+ }
+ },
+ "required": ["allow"]
+ },
+ {
+ "required": ["reject"]
+ }
+ ]
+ },
+ "lllSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "tab-width": {
+ "description": "Width of \"\\t\" in spaces.",
+ "type": "integer",
+ "minimum": 0,
+ "default": 1
+ },
+ "line-length": {
+ "description": "Maximum allowed line length, lines longer will be reported.",
+ "type": "integer",
+ "minimum": 1,
+ "default": 120
+ }
+ }
+ },
+ "maintidxSettings": {
+ "description": "Maintainability index https://docs.microsoft.com/en-us/visualstudio/code-quality/code-metrics-maintainability-index-range-and-meaning?view=vs-2022",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "under": {
+ "description": "Minimum accatpable maintainability index level (see https://docs.microsoft.com/en-us/visualstudio/code-quality/code-metrics-maintainability-index-range-and-meaning?view=vs-2022)",
+ "type": "number",
+ "default": 20
+ }
+ }
+ },
+ "makezeroSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "always": {
+ "description": "Allow only slices initialized with a length of zero.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "loggercheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "kitlog": {
+ "description": "Allow check for the github.com/go-kit/log library.",
+ "type": "boolean",
+ "default": true
+ },
+ "klog": {
+ "description": "Allow check for the k8s.io/klog/v2 library.",
+ "type": "boolean",
+ "default": true
+ },
+ "logr": {
+ "description": "Allow check for the github.com/go-logr/logr library.",
+ "type": "boolean",
+ "default": true
+ },
+ "slog": {
+ "description": "Allow check for the log/slog library.",
+ "type": "boolean",
+ "default": true
+ },
+ "zap": {
+ "description": "Allow check for the \"sugar logger\" from go.uber.org/zap library.",
+ "type": "boolean",
+ "default": true
+ },
+ "require-string-key": {
+ "description": "Require all logging keys to be inlined constant strings.",
+ "type": "boolean",
+ "default": false
+ },
+ "no-printf-like": {
+ "description": "Require printf-like format specifier (%s, %d for example) not present.",
+ "type": "boolean",
+ "default": false
+ },
+ "rules": {
+ "description": "List of custom rules to check against, where each rule is a single logger pattern, useful for wrapped loggers.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "misspellSettings": {
+ "description": "Correct spellings using locale preferences for US or UK. Default is to use a neutral variety of English.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "locale": {
+ "enum": ["US", "UK"]
+ },
+ "ignore-rules": {
+ "description": "List of rules to ignore.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "mode": {
+ "description": "Mode of the analysis.",
+ "enum": ["restricted", "", "default"],
+ "default": ""
+ },
+ "extra-words": {
+ "description": "Extra word corrections.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "correction": {
+ "type": "string"
+ },
+ "typo": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "musttagSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "functions": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "tag": {
+ "type": "string"
+ },
+ "arg-pos": {
+ "type": "integer"
+ }
+ }
+ }
+ }
+ }
+ },
+ "nakedretSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-func-lines": {
+ "description": "Report if a function has more lines of code than this value and it has naked returns.",
+ "type": "integer",
+ "minimum": 0,
+ "default": 30
+ }
+ }
+ },
+ "nestifSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "min-complexity": {
+ "description": "Minimum complexity of \"if\" statements to report.",
+ "type": "integer",
+ "default": 5
+ }
+ }
+ },
+ "nilnilSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "only-two": {
+ "type": "boolean",
+ "description": "To check functions with only two return values.",
+ "default": true
+ },
+ "detect-opposite": {
+ "type": "boolean",
+ "description": "In addition, detect opposite situation (simultaneous return of non-nil error and valid value).",
+ "default": false
+ },
+ "checked-types": {
+ "type": "array",
+ "description": "List of return types to check.",
+ "items": {
+ "enum": ["chan", "func", "iface", "map", "ptr", "uintptr", "unsafeptr"]
+ },
+ "default": ["chan", "func", "iface", "map", "ptr", "uintptr", "unsafeptr"]
+ }
+ }
+ },
+ "nlreturnSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "block-size": {
+ "description": "set block size that is still ok",
+ "type": "number",
+ "default": 0,
+ "minimum": 0
+ }
+ }
+ },
+ "mndSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignored-files": {
+ "description": "List of file patterns to exclude from analysis.",
+ "examples": [["magic1_.*.go"]],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignored-functions": {
+ "description": "Comma-separated list of function patterns to exclude from the analysis.",
+ "examples": [["math.*", "http.StatusText", "make"]],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignored-numbers": {
+ "description": "List of numbers to exclude from analysis.",
+ "examples": [["1000", "1234_567_890", "3.14159264"]],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "checks": {
+ "description": "The list of enabled checks, see https://github.com/tommy-muehle/go-mnd/#checks for description.",
+ "type": "array",
+ "items": {
+ "enum": [
+ "argument",
+ "case",
+ "condition",
+ "operation",
+ "return",
+ "assign"
+ ]
+ }
+ }
+ }
+ },
+ "modernizeSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "disable": {
+ "description": "List of analyzers to disable.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/modernize-analyzers"
+ }
+ }
+ }
+ },
+ "nolintlintSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "allow-unused": {
+ "description": "Enable to ensure that nolint directives are all used.",
+ "type": "boolean",
+ "default": true
+ },
+ "allow-no-explanation": {
+ "description": "Exclude these linters from requiring an explanation.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linter-names"
+ },
+ "default": []
+ },
+ "require-explanation": {
+ "description": "Enable to require an explanation of nonzero length after each nolint directive.",
+ "type": "boolean",
+ "default": false
+ },
+ "require-specific": {
+ "description": "Enable to require nolint directives to mention the specific linter being suppressed.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "reassignSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "patterns": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "recvcheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "disable-builtin": {
+ "description": "Disables the built-in method exclusions.",
+ "type": "boolean",
+ "default": true
+ },
+ "exclusions": {
+ "description": "User-defined method exclusions.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "nonamedreturnsSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "report-error-in-defer": {
+ "description": "Report named error if it is assigned inside defer.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "paralleltestSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignore-missing": {
+ "description": "Ignore missing calls to `t.Parallel()` and only report incorrect uses of it.",
+ "type": "boolean",
+ "default": false
+ },
+ "ignore-missing-subtests": {
+ "description": "Ignore missing calls to `t.Parallel()` in subtests. Top-level tests are still required to have `t.Parallel`, but subtests are allowed to skip it.",
+ "type": "boolean",
+ "default": false
+ },
+ "check-cleanup": {
+ "description": "Check that defer is not used with t.Parallel (use t.Cleanup instead).",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "perfsprintSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "integer-format": {
+ "description": "Enable/disable optimization of integer formatting.",
+ "type": "boolean",
+ "default": true
+ },
+ "int-conversion": {
+ "description": "Optimizes even if it requires an int or uint type cast.",
+ "type": "boolean",
+ "default": true
+ },
+ "error-format": {
+ "description": "Enable/disable optimization of error formatting.",
+ "type": "boolean",
+ "default": true
+ },
+ "err-error": {
+ "description": "Optimizes into `err.Error()` even if it is only equivalent for non-nil errors.",
+ "type": "boolean",
+ "default": false
+ },
+ "errorf": {
+ "description": "Optimizes `fmt.Errorf`.",
+ "type": "boolean",
+ "default": true
+ },
+ "string-format": {
+ "description": "Enable/disable optimization of string formatting.",
+ "type": "boolean",
+ "default": true
+ },
+ "sprintf1": {
+ "description": "Optimizes `fmt.Sprintf` with only one argument.",
+ "type": "boolean",
+ "default": true
+ },
+ "strconcat": {
+ "description": "Optimizes into strings concatenation.",
+ "type": "boolean",
+ "default": true
+ },
+ "bool-format": {
+ "description": "Enable/disable optimization of bool formatting.",
+ "type": "boolean",
+ "default": true
+ },
+ "hex-format": {
+ "description": "Enable/disable optimization of hex formatting.",
+ "type": "boolean",
+ "default": true
+ },
+ "concat-loop": {
+ "description": "Enable/disable optimization of concat loop.",
+ "type": "boolean",
+ "default": true
+ },
+ "loop-other-ops": {
+ "description": "Optimization of `concat-loop` even with other operations.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "preallocSettings": {
+ "description": "We do not recommend using this linter before doing performance profiling.\nFor most programs usage of `prealloc` will be premature optimization.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "simple": {
+ "description": "Report preallocation suggestions only on simple loops that have no returns/breaks/continues/gotos in them.",
+ "type": "boolean",
+ "default": true
+ },
+ "range-loops": {
+ "description": "Report preallocation suggestions on range loops.",
+ "type": "boolean",
+ "default": true
+ },
+ "for-loops": {
+ "description": "Report preallocation suggestions on for loops.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "predeclaredSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignore": {
+ "description": "List of predeclared identifiers to not report on.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "qualified-name": {
+ "description": "Include method names and field names in checks.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "promlinterSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "strict": {},
+ "disabled-linters": {
+ "type": "array",
+ "items": {
+ "enum": [
+ "Help",
+ "MetricUnits",
+ "Counter",
+ "HistogramSummaryReserved",
+ "MetricTypeInName",
+ "ReservedChars",
+ "CamelCase",
+ "UnitAbbreviations"
+ ]
+ }
+ }
+ }
+ },
+ "protogetterSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skip-generated-by": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["protoc-gen-go-my-own-generator"]
+ }
+ },
+ "skip-files": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["*.pb.go"]
+ }
+ },
+ "skip-any-generated": {
+ "description": "Skip any generated files from the checking.",
+ "type": "boolean",
+ "default": false
+ },
+ "replace-first-arg-in-append": {
+ "description": "Skip first argument of append function.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "reviveSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "examples": [
+ {
+ "ignore-generated-header": true,
+ "severity": "warning",
+ "rules": [
+ {
+ "name": "indent-error-flow",
+ "severity": "warning"
+ },
+ {
+ "name": "add-constant",
+ "severity": "warning",
+ "arguments": [
+ {
+ "maxLitCount": "3",
+ "allowStrs": "\"\"",
+ "allowInts": "0,1,2",
+ "allowFloats": "0.0,0.,1.0,1.,2.0,2."
+ }
+ ]
+ }
+ ]
+ }
+ ],
+ "properties": {
+ "max-open-files": {
+ "type": "integer"
+ },
+ "confidence": {
+ "type": "number"
+ },
+ "severity": {
+ "type": "string",
+ "enum": ["warning", "error"]
+ },
+ "enable-all-rules": {
+ "type": "boolean",
+ "default": false
+ },
+ "enable-default-rules": {
+ "type": "boolean",
+ "default": false
+ },
+ "directives": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "name": {
+ "type": "string",
+ "enum": ["specify-disable-reason"]
+ },
+ "severity": {
+ "type": "string",
+ "enum": ["warning", "error"]
+ },
+ "exclude": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "arguments": {
+ "type": "array"
+ }
+ }
+ }
+ },
+ "rules": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["name"],
+ "properties": {
+ "name": {
+ "$ref": "#/definitions/revive-rules",
+ "title": "The rule name"
+ },
+ "disabled": {
+ "type": "boolean"
+ },
+ "severity": {
+ "type": "string",
+ "enum": ["warning", "error"]
+ },
+ "exclude": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "arguments": {
+ "type": "array"
+ }
+ }
+ }
+ }
+ }
+ },
+ "rowserrcheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "packages": {
+ "type": "array",
+ "items": {
+ "description": "",
+ "type": "string",
+ "examples": ["github.com/jmoiron/sqlx"]
+ }
+ }
+ }
+ },
+ "sloglintSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "no-global": {
+ "description": "Report the use of global loggers.",
+ "enum": ["", "all", "default"],
+ "default": ""
+ },
+ "context": {
+ "description": "Report the use of functions without a context.Context.",
+ "enum": ["", "all", "scope"],
+ "default": ""
+ },
+ "static-msg": {
+ "description": "Report dynamic log messages, such as those that are built with fmt.Sprintf.",
+ "type": "boolean",
+ "default": false
+ },
+ "msg-style": {
+ "description": "Report log messages that do not match a particular style.",
+ "enum": ["", "lowercased", "capitalized"],
+ "default": ""
+ },
+ "no-mixed-args": {
+ "description": "Report the use of both key-value pairs and attributes within a single function call.",
+ "type": "boolean",
+ "default": true
+ },
+ "kv-only": {
+ "description": "Report any use of attributes as function call arguments.",
+ "type": "boolean",
+ "default": false
+ },
+ "attr-only": {
+ "description": "Report any use of key-value pairs as function call arguments.",
+ "type": "boolean",
+ "default": false
+ },
+ "args-on-sep-lines": {
+ "description": "Report two or more arguments on the same line.",
+ "type": "boolean",
+ "default": false
+ },
+ "no-raw-keys": {
+ "description": "Report the use of string literals as log keys.",
+ "type": "boolean",
+ "default": false
+ },
+ "allowed-keys": {
+ "description": "Report the use of log keys that are not explicitly allowed.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "forbidden-keys": {
+ "description": "Report the use of forbidden log keys.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "key-naming-case": {
+ "description": "Report log keys that do not match a particular naming case.",
+ "enum": ["snake", "kebab", "camel", "pascal"]
+ },
+ "custom-funcs": {
+ "description": "Analyze custom functions in addition to the standard log/slog functions.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/settings/definitions/sloglintCustomFunc"
+ }
+ }
+ }
+ },
+ "sloglintCustomFunc": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "name": {
+ "description": "The full name of the function, including the package. If the function is a method, the receiver type must be wrapped in parentheses.",
+ "type": "string"
+ },
+ "msg-pos": {
+ "description": "The position of the \"msg string\" argument in the function signature, starting from 0. If there is no message in the function, a negative value must be passed.",
+ "type": "integer"
+ },
+ "args-pos": {
+ "description": "The position of the \"args ...any\" argument in the function signature, starting from 0. If there are no arguments in the function, a negative value must be passed.",
+ "type": "integer"
+ }
+ }
+ },
+ "spancheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "checks": {
+ "description": "Checks to enable.",
+ "type": "array",
+ "items": {
+ "enum": ["end", "record-error", "set-status"]
+ }
+ },
+ "ignore-check-signatures": {
+ "description": "A list of regexes for function signatures that silence `record-error` and `set-status` reports if found in the call path to a returned error.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "extra-start-span-signatures": {
+ "description": "A list of regexes for additional function signatures that create spans.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "staticcheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "checks": {
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "$ref": "#/definitions/staticcheck-checks"
+ },
+ {
+ "type": "string"
+ }
+ ]
+ }
+ },
+ "dot-import-whitelist": {
+ "description": "By default, ST1001 forbids all uses of dot imports in non-test packages. This setting allows setting a whitelist of import paths that can be dot-imported anywhere.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "http-status-code-whitelist": {
+ "description": "ST1013 recommends using constants from the net/http package instead of hard-coding numeric HTTP status codes. This setting specifies a list of numeric status codes that this check does not complain about.",
+ "default": ["200", "400", "404", "500"],
+ "type": "array",
+ "items": {
+ "enum": [
+ "100",
+ "101",
+ "102",
+ "103",
+ "200",
+ "201",
+ "202",
+ "203",
+ "204",
+ "205",
+ "206",
+ "207",
+ "208",
+ "226",
+ "300",
+ "301",
+ "302",
+ "303",
+ "304",
+ "305",
+ "306",
+ "307",
+ "308",
+ "400",
+ "401",
+ "402",
+ "403",
+ "404",
+ "405",
+ "406",
+ "407",
+ "408",
+ "409",
+ "410",
+ "411",
+ "412",
+ "413",
+ "414",
+ "415",
+ "416",
+ "417",
+ "418",
+ "421",
+ "422",
+ "423",
+ "424",
+ "425",
+ "426",
+ "428",
+ "429",
+ "431",
+ "451",
+ "500",
+ "501",
+ "502",
+ "503",
+ "504",
+ "505",
+ "506",
+ "507",
+ "508",
+ "510",
+ "511"
+ ]
+ }
+ },
+ "initialisms": {
+ "description": "ST1003 check, among other things, for the correct capitalization of initialisms. The set of known initialisms can be configured with this option.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "default": [
+ "ACL",
+ "API",
+ "ASCII",
+ "CPU",
+ "CSS",
+ "DNS",
+ "EOF",
+ "GUID",
+ "HTML",
+ "HTTP",
+ "HTTPS",
+ "ID",
+ "IP",
+ "JSON",
+ "QPS",
+ "RAM",
+ "RPC",
+ "SLA",
+ "SMTP",
+ "SQL",
+ "SSH",
+ "TCP",
+ "TLS",
+ "TTL",
+ "UDP",
+ "UI",
+ "GID",
+ "UID",
+ "UUID",
+ "URI",
+ "URL",
+ "UTF8",
+ "VM",
+ "XML",
+ "XMPP",
+ "XSRF",
+ "XSS",
+ "SIP",
+ "RTP",
+ "AMQP",
+ "DB",
+ "TS"
+ ]
+ }
+ }
+ }
+ },
+ "tagalignSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "align": {
+ "description": "Align and sort can be used together or separately.",
+ "type": "boolean",
+ "default": true
+ },
+ "sort": {
+ "description": "Whether enable tags sort.",
+ "type": "boolean",
+ "default": true
+ },
+ "order": {
+ "description": "Specify the order of tags, the other tags will be sorted by name.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "default": [],
+ "examples": [
+ [
+ "json",
+ "yaml",
+ "yml",
+ "toml",
+ "mapstructure",
+ "binding",
+ "validate"
+ ]
+ ]
+ },
+ "strict": {
+ "description": "Whether enable strict style.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "tagliatelleSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "case": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "use-field-name": {
+ "description": "Use the struct field name to check the name of the struct tag.",
+ "type": "boolean",
+ "default": false
+ },
+ "ignored-fields": {
+ "description": "The field names to ignore.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["example"]
+ }
+ },
+ "rules": {
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "$ref": "#/definitions/tagliatelle-cases"
+ }
+ }
+ },
+ "extended-rules": {
+ "description": "Defines the association between tag name and case.",
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["case"],
+ "properties": {
+ "case": {
+ "$ref": "#/definitions/tagliatelle-cases"
+ },
+ "extra-initialisms": {
+ "type": "boolean",
+ "default": false
+ },
+ "initialism-overrides": {
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "overrides": {
+ "description": "Overrides the default/root configuration.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["pkg"],
+ "properties": {
+ "pkg": {
+ "description": "A package path.",
+ "type": "string"
+ },
+ "use-field-name": {
+ "description": "Use the struct field name to check the name of the struct tag.",
+ "type": "boolean",
+ "default": false
+ },
+ "ignored-fields": {
+ "description": "The field names to ignore.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["example"]
+ }
+ },
+ "ignore": {
+ "description": "Ignore the package (takes precedence over all other configurations).",
+ "type": "boolean",
+ "default": false
+ },
+ "rules": {
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "$ref": "#/definitions/tagliatelle-cases"
+ }
+ }
+ },
+ "extended-rules": {
+ "description": "Defines the association between tag name and case.",
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["case"],
+ "properties": {
+ "case": {
+ "$ref": "#/definitions/tagliatelle-cases"
+ },
+ "extra-initialisms": {
+ "type": "boolean",
+ "default": false
+ },
+ "initialism-overrides": {
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "testifylintSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "enable-all": {
+ "description": "Enable all checkers.",
+ "type": "boolean",
+ "default": false
+ },
+ "disable-all": {
+ "description": "Disable all checkers.",
+ "type": "boolean",
+ "default": false
+ },
+ "enable": {
+ "description": "Enable specific checkers.",
+ "type": "array",
+ "items": {
+ "enum": [
+ "blank-import",
+ "bool-compare",
+ "compares",
+ "contains",
+ "empty",
+ "encoded-compare",
+ "equal-values",
+ "error-is-as",
+ "error-nil",
+ "expected-actual",
+ "float-compare",
+ "formatter",
+ "go-require",
+ "len",
+ "negative-positive",
+ "nil-compare",
+ "regexp",
+ "require-error",
+ "suite-broken-parallel",
+ "suite-dont-use-pkg",
+ "suite-extra-assert-call",
+ "suite-method-signature",
+ "suite-subtest-run",
+ "suite-thelper",
+ "useless-assert"
+ ]
+ },
+ "default": [
+ "blank-import",
+ "bool-compare",
+ "compares",
+ "contains",
+ "empty",
+ "encoded-compare",
+ "equal-values",
+ "error-is-as",
+ "error-nil",
+ "expected-actual",
+ "float-compare",
+ "formatter",
+ "go-require",
+ "len",
+ "negative-positive",
+ "nil-compare",
+ "regexp",
+ "require-error",
+ "suite-broken-parallel",
+ "suite-dont-use-pkg",
+ "suite-extra-assert-call",
+ "suite-method-signature",
+ "suite-subtest-run",
+ "useless-assert"
+ ]
+ },
+ "disable": {
+ "description": "Disable specific checkers.",
+ "type": "array",
+ "items": {
+ "enum": [
+ "blank-import",
+ "bool-compare",
+ "compares",
+ "contains",
+ "empty",
+ "encoded-compare",
+ "equal-values",
+ "error-is-as",
+ "error-nil",
+ "expected-actual",
+ "float-compare",
+ "formatter",
+ "go-require",
+ "len",
+ "negative-positive",
+ "nil-compare",
+ "regexp",
+ "require-error",
+ "suite-broken-parallel",
+ "suite-dont-use-pkg",
+ "suite-extra-assert-call",
+ "suite-method-signature",
+ "suite-subtest-run",
+ "suite-thelper",
+ "useless-assert"
+ ],
+ "default": [
+ "suite-thelper"
+ ]
+ }
+ },
+ "bool-compare": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignore-custom-types": {
+ "description": "To ignore user defined types (over builtin bool).",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "expected-actual": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "pattern": {
+ "description": "Regexp for expected variable name.",
+ "type": "string",
+ "default": "(^(exp(ected)?|want(ed)?)([A-Z]\\w*)?$)|(^(\\w*[a-z])?(Exp(ected)?|Want(ed)?)$)"
+ }
+ }
+ },
+ "formatter": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-format-string": {
+ "description": "To enable go vet's printf checks.",
+ "type": "boolean",
+ "default": true
+ },
+ "require-f-funcs": {
+ "description": "To require f-assertions (e.g. assert.Equalf) if format string is used, even if there are no variable-length variables.",
+ "type": "boolean",
+ "default": false
+ },
+ "require-string-msg": {
+ "description": "To require that the first element of msgAndArgs (msg) has a string type.",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "go-require": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignore-http-handlers": {
+ "description": "To ignore HTTP handlers (like http.HandlerFunc).",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "require-error": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "fn-pattern": {
+ "description": "Regexp for assertions to analyze. If defined, then only matched error assertions will be reported.",
+ "type": "string",
+ "default": ""
+ }
+ }
+ },
+ "suite-extra-assert-call": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "mode": {
+ "description": "To require or remove extra Assert() call?",
+ "type": "string",
+ "enum": ["remove", "require"],
+ "default": "remove"
+ }
+ }
+ }
+ }
+ },
+ "testpackageSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skip-regexp": {
+ "description": "Files with names matching this regular expression are skipped.",
+ "type": "string",
+ "examples": ["(export|internal)_test\\.go"]
+ },
+ "allow-packages": {
+ "description": "List of packages that don't end with _test that tests are allowed to be in.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["example"]
+ }
+ }
+ }
+ },
+ "thelperSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "test": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "begin": {
+ "description": "Check if `t.Helper()` begins helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "first": {
+ "description": "Check if *testing.T is first param of helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "name": {
+ "description": "Check if *testing.T param has t name.",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ },
+ "benchmark": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "begin": {
+ "description": "Check if `b.Helper()` begins helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "first": {
+ "description": "Check if *testing.B is first param of helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "name": {
+ "description": "Check if *testing.B param has b name.",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ },
+ "tb": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "begin": {
+ "description": "Check if `tb.Helper()` begins helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "first": {
+ "description": "Check if *testing.TB is first param of helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "name": {
+ "description": "Check if *testing.TB param has tb name.",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ },
+ "fuzz": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "begin": {
+ "description": "Check if `f.Helper()` begins helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "first": {
+ "description": "Check if *testing.F is first param of helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "name": {
+ "description": "Check if *testing.F param has f name.",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ }
+ }
+ },
+ "usestdlibvarsSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "http-method": {
+ "description": "Suggest the use of http.MethodXX.",
+ "type": "boolean",
+ "default": true
+ },
+ "http-status-code": {
+ "description": "Suggest the use of http.StatusXX.",
+ "type": "boolean",
+ "default": true
+ },
+ "time-weekday": {
+ "description": "Suggest the use of time.Weekday.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "time-month": {
+ "description": "Suggest the use of time.Month.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "time-layout": {
+ "description": "Suggest the use of time.Layout.",
+ "type": "boolean",
+ "default": false
+ },
+ "time-date-month": {
+ "description": "Suggest the use of time.Month in time.Date.",
+ "type": "boolean",
+ "default": false
+ },
+ "crypto-hash": {
+ "description": "Suggest the use of crypto.Hash.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "default-rpc-path": {
+ "description": "Suggest the use of rpc.DefaultXXPath.",
+ "type": "boolean",
+ "default": false
+ },
+ "sql-isolation-level": {
+ "description": "Suggest the use of sql.LevelXX.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "tls-signature-scheme": {
+ "description": "Suggest the use of tls.SignatureScheme.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "constant-kind": {
+ "description": "Suggest the use of constant.Kind.String().",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "usetestingSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "context-background": {
+ "type": "boolean",
+ "default": false
+ },
+ "context-todo": {
+ "type": "boolean",
+ "default": false
+ },
+ "os-chdir": {
+ "type": "boolean",
+ "default": true
+ },
+ "os-mkdir-temp": {
+ "type": "boolean",
+ "default": true
+ },
+ "os-setenv": {
+ "type": "boolean",
+ "default": true
+ },
+ "os-create-temp": {
+ "type": "boolean",
+ "default": true
+ },
+ "os-temp-dir": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "unconvertSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "fast-math": {
+ "type": "boolean",
+ "default": false
+ },
+ "safe": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "unparamSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-exported": {
+ "description": "Inspect exported functions. Set to true if no external program/library imports your code.\n\nWARNING: if you enable this setting, unparam will report a lot of false-positives in text editors:\nif it's called for subdir of a project it can't find external interfaces. All text editor integrations\nwith golangci-lint call it on a directory with the changed file.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "unqueryvetSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-sql-builders": {
+ "description": "Enable SQL builder checking.",
+ "type": "boolean",
+ "default": true
+ },
+ "check-aliased-wildcard": {
+ "description": "Enable aliased wildcard detection like SELECT t.*.",
+ "type": "boolean",
+ "default": true
+ },
+ "check-string-concat": {
+ "description": "Enable string concatenation analysis.",
+ "type": "boolean",
+ "default": true
+ },
+ "check-format-strings": {
+ "description": "Enable format string analysis like fmt.Sprintf.",
+ "type": "boolean",
+ "default": true
+ },
+ "check-string-builder": {
+ "description": "Enable strings.Builder analysis.",
+ "type": "boolean",
+ "default": true
+ },
+ "check-subqueries": {
+ "description": "Enable subquery analysis.",
+ "type": "boolean",
+ "default": true
+ },
+ "check-n1": {
+ "type": "boolean",
+ "default": false
+ },
+ "check-sql-injection": {
+ "type": "boolean",
+ "default": false
+ },
+ "check-tx-leaks": {
+ "type": "boolean",
+ "default": false
+ },
+ "allowed-patterns": {
+ "description": "Regex patterns for acceptable SELECT * usage.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "allow": {
+ "description": "Allow is a list of SQL patterns to allow (whitelist).",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignored-functions": {
+ "description": "Functions to ignore.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "sql-builders": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "squirrel": {
+ "type": "boolean",
+ "default": true
+ },
+ "gorm": {
+ "type": "boolean",
+ "default": true
+ },
+ "sqlx": {
+ "type": "boolean",
+ "default": true
+ },
+ "ent": {
+ "type": "boolean",
+ "default": true
+ },
+ "pgx": {
+ "type": "boolean",
+ "default": true
+ },
+ "bun": {
+ "type": "boolean",
+ "default": true
+ },
+ "sqlboiler": {
+ "type": "boolean",
+ "default": true
+ },
+ "jet": {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "custom-rules": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "id": {
+ "type": "string"
+ },
+ "pattern": {
+ "type": "string"
+ },
+ "patterns": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "when": {
+ "type": "string"
+ },
+ "message": {
+ "type": "string"
+ },
+ "action": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "unusedSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "field-writes-are-uses": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ },
+ "post-statements-are-reads": {
+ "description": "",
+ "type": "boolean",
+ "default": false
+ },
+ "exported-fields-are-used": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ },
+ "parameters-are-used": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ },
+ "local-variables-are-used": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ },
+ "generated-is-used": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "varnamelenSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-distance": {
+ "description": "Variables used in at most this N-many lines will be ignored.",
+ "type": "integer",
+ "default": 5
+ },
+ "min-name-length": {
+ "description": "The minimum length of a variable's name that is considered `long`.",
+ "type": "integer",
+ "default": 3
+ },
+ "check-receiver": {
+ "description": "Check method receiver names.",
+ "default": false,
+ "type": "boolean"
+ },
+ "check-return": {
+ "description": "Check named return values.",
+ "default": false,
+ "type": "boolean"
+ },
+ "check-type-param": {
+ "description": "Check type parameters.",
+ "default": false,
+ "type": "boolean"
+ },
+ "ignore-type-assert-ok": {
+ "description": "Ignore `ok` variables that hold the bool return value of a type assertion",
+ "default": false,
+ "type": "boolean"
+ },
+ "ignore-map-index-ok": {
+ "description": "Ignore `ok` variables that hold the bool return value of a map index.",
+ "default": false,
+ "type": "boolean"
+ },
+ "ignore-chan-recv-ok": {
+ "description": "Ignore `ok` variables that hold the bool return value of a channel receive.",
+ "default": false,
+ "type": "boolean"
+ },
+ "ignore-names": {
+ "description": "Optional list of variable names that should be ignored completely.",
+ "default": [[]],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignore-decls": {
+ "description": "Optional list of variable declarations that should be ignored completely.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "examples": [
+ ["c echo.Context", "t testing.T", "f *foo.Bar", "const C"]
+ ]
+ }
+ }
+ },
+ "whitespaceSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "multi-if": {
+ "description": "Enforces newlines (or comments) after every multi-line if statement",
+ "type": "boolean",
+ "default": false
+ },
+ "multi-func": {
+ "description": "Enforces newlines (or comments) after every multi-line function signature",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "wrapcheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "extra-ignore-sigs": {
+ "description": "An array of strings specifying additional substrings of signatures to ignore.",
+ "default": [
+ ".CustomError(",
+ ".SpecificWrap("
+ ],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignore-sigs": {
+ "description": "An array of strings which specify substrings of signatures to ignore.",
+ "default": [
+ ".Errorf(",
+ "errors.New(",
+ "errors.Unwrap(",
+ ".Wrap(",
+ ".Wrapf(",
+ ".WithMessage(",
+ ".WithMessagef(",
+ ".WithStack("
+ ],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignore-sig-regexps": {
+ "description": "An array of strings which specify regular expressions of signatures to ignore.",
+ "default": [""],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignore-package-globs": {
+ "description": "An array of glob patterns which, if any match the package of the function returning the error, will skip wrapcheck analysis for this error.",
+ "default": [""],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignore-interface-regexps": {
+ "description": "An array of glob patterns which, if matched to an underlying interface name, will ignore unwrapped errors returned from a function whose call is defined on the given interface.",
+ "default": [""],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "report-internal-errors": {
+ "description": "Determines whether wrapcheck should report errors returned from inside the package.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "wslSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "allow-assign-and-anything": {
+ "description": "Controls if you may cuddle assignments and anything without needing an empty line between them.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-assign-and-call": {
+ "description": "Allow calls and assignments to be cuddled as long as the lines have any matching variables, fields or types.",
+ "type": "boolean",
+ "default": true
+ },
+ "allow-cuddle-declarations": {
+ "description": "Allow declarations (var) to be cuddled.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-cuddle-with-calls": {
+ "description": "A list of call idents that everything can be cuddled with.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "allow-cuddle-with-rhs": {
+ "description": "AllowCuddleWithRHS is a list of right hand side variables that is allowed to be cuddled with anything.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "allow-cuddle-used-in-block": {
+ "description": "Allow cuddling with any block as long as the variable is used somewhere in the block",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-multiline-assign": {
+ "description": "Allow multiline assignments to be cuddled.",
+ "type": "boolean",
+ "default": true
+ },
+ "allow-separated-leading-comment": {
+ "description": "Allow leading comments to be separated with empty lines.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-trailing-comment": {
+ "description": "Allow trailing comments in ending of blocks.",
+ "type": "boolean",
+ "default": false
+ },
+ "error-variable-names": {
+ "description": "When force-err-cuddling is enabled this is a list of names used for error variables to check for in the conditional.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "force-case-trailing-whitespace": {
+ "description": "Force newlines in end of case at this limit (0 = never).",
+ "type": "integer",
+ "minimum": 0,
+ "default": 0
+ },
+ "force-err-cuddling": {
+ "description": "Causes an error when an If statement that checks an error variable doesn't cuddle with the assignment of that variable.",
+ "type": "boolean",
+ "default": false
+ },
+ "force-short-decl-cuddling": {
+ "description": "Causes an error if a short declaration (:=) cuddles with anything other than another short declaration.",
+ "type": "boolean",
+ "default": false
+ },
+ "strict-append": {
+ "description": "If true, append is only allowed to be cuddled if appending value is matching variables, fields or types on line above.",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "wslSettingsV5": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "allow-first-in-block": {
+ "type": "boolean",
+ "default": true
+ },
+ "allow-whole-block": {
+ "type": "boolean",
+ "default": false
+ },
+ "branch-max-lines": {
+ "type": "integer",
+ "default": 2
+ },
+ "case-max-lines": {
+ "type": "integer",
+ "default": 0
+ },
+ "cuddle-max-statements": {
+ "type": "integer",
+ "default": 1
+ },
+ "default": {
+ "enum": ["all", "none", "default", ""],
+ "default": "default"
+ },
+ "enable": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/wsl-checks"
+ }
+ },
+ "disable": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/wsl-checks"
+ }
+ }
+ }
+ },
+ "copyloopvarSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-alias": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "customSettings": {
+ "description": "The custom section can be used to define linter plugins to be loaded at runtime. See README of golangci-lint for more information.\nEach custom linter should have a unique name.",
+ "type": "object",
+ "patternProperties": {
+ "^.*$": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "type": {
+ "description": "The plugin type.",
+ "enum": ["module", "goplugin"],
+ "default": "goplugin"
+ },
+ "path": {
+ "description": "The path to the plugin *.so. Can be absolute or local.",
+ "type": "string",
+ "examples": ["/path/to/example.so"]
+ },
+ "description": {
+ "description": "The description of the linter, for documentation purposes only.",
+ "type": "string"
+ },
+ "original-url": {
+ "description": "Intended to point to the repo location of the linter, for documentation purposes only.",
+ "type": "string"
+ },
+ "settings": {
+ "description": "Plugins settings/configuration. Only work with plugin based on `linterdb.PluginConstructor`.",
+ "type": "object"
+ }
+ },
+ "oneOf": [
+ {
+ "properties": {
+ "type": {"enum": ["module"] }
+ },
+ "required": ["type"]
+ },
+ {
+ "required": ["path"]
+ }
+ ]
+ }
+ }
+ }
+ }
+ }
+ },
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["version"],
+ "properties": {
+ "version": {
+ "type": "string",
+ "default": "2"
+ },
+ "run": {
+ "description": "Options for analysis running,",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "concurrency": {
+ "description": "Number of concurrent runners. Defaults to the number of available CPU cores.",
+ "type": "integer",
+ "minimum": 0,
+ "examples": [4]
+ },
+ "timeout": {
+ "description": "Timeout for the analysis.",
+ "type": "string",
+ "pattern": "^((\\d+h)?(\\d+m)?(\\d+(?:\\.\\d)?s)?|0)$",
+ "default": "1m",
+ "examples": ["30s", "5m", "5m30s"]
+ },
+ "issues-exit-code": {
+ "description": "Exit code when at least one issue was found.",
+ "type": "integer",
+ "default": 1
+ },
+ "tests": {
+ "description": "Enable inclusion of test files.",
+ "type": "boolean",
+ "default": true
+ },
+ "build-tags": {
+ "description": "List of build tags to pass to all linters.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "default": [],
+ "examples": [["mytag"]]
+ },
+ "modules-download-mode": {
+ "description": "Option to pass to \"go list -mod={option}\".\nSee \"go help modules\" for more information.",
+ "enum": ["mod", "readonly", "vendor"]
+ },
+ "enable-build-vcs": {
+ "type": "boolean",
+ "default": false
+ },
+ "allow-parallel-runners": {
+ "description": "Allow multiple parallel golangci-lint instances running. If disabled, golangci-lint acquires file lock on start.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-serial-runners": {
+ "description": "Allow multiple golangci-lint instances running, but serialize them around a lock.",
+ "type": "boolean",
+ "default": false
+ },
+ "go": {
+ "description": "Targeted Go version.",
+ "type": "string",
+ "default": "1.17"
+ },
+ "relative-path-mode": {
+ "description": "The mode used to evaluate relative paths.",
+ "type": "string",
+ "$ref": "#/definitions/relative-path-modes",
+ "default": "wd"
+ }
+ }
+ },
+ "output": {
+ "description": "Output configuration options.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "formats": {
+ "description": "Output formats to use.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "text": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "path": {
+ "$ref": "#/definitions/formats-path",
+ "default": "stdout"
+ },
+ "print-linter-name": {
+ "type": "boolean",
+ "default": true
+ },
+ "print-issued-lines": {
+ "type": "boolean",
+ "default": true
+ },
+ "colors": {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "json": {
+ "$ref": "#/definitions/simple-format"
+ },
+ "tab": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "path": {
+ "$ref": "#/definitions/formats-path",
+ "default": "stdout"
+ },
+ "print-linter-name": {
+ "type": "boolean",
+ "default": true
+ },
+ "colors": {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "html": {
+ "$ref": "#/definitions/simple-format"
+ },
+ "checkstyle": {
+ "$ref": "#/definitions/simple-format"
+ },
+ "code-climate": {
+ "$ref": "#/definitions/simple-format"
+ },
+ "junit-xml": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "path": {
+ "$ref": "#/definitions/formats-path",
+ "default": "stdout"
+ },
+ "extended": {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "teamcity": {
+ "$ref": "#/definitions/simple-format"
+ },
+ "sarif": {
+ "$ref": "#/definitions/simple-format"
+ }
+ }
+ },
+ "path-mode": {
+ "type": "string",
+ "default": "",
+ "examples": ["abs"]
+ },
+ "path-prefix": {
+ "description": "Add a prefix to the output file references.",
+ "type": "string",
+ "default": ""
+ },
+ "show-stats": {
+ "description": "Show statistics per linter.",
+ "type": "boolean",
+ "default": true
+ },
+ "sort-order": {
+ "type": "array",
+ "items": {
+ "enum": ["linter", "severity", "file"]
+ }
+ }
+ }
+ },
+ "linters": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "default": {
+ "enum": [
+ "standard",
+ "all",
+ "none",
+ "fast"
+ ]
+ },
+ "enable": {
+ "description": "List of enabled linters.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linter-names"
+ }
+ },
+ "disable": {
+ "description": "List of disabled linters.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linter-names"
+ }
+ },
+ "settings": {
+ "description": "All available settings of specific linters.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "dupword": {
+ "$ref": "#/definitions/settings/definitions/dupwordSettings"
+ },
+ "asasalint": {
+ "$ref": "#/definitions/settings/definitions/asasalintSettings"
+ },
+ "bidichk": {
+ "$ref": "#/definitions/settings/definitions/bidichkSettings"
+ },
+ "bodyclose": {
+ "$ref": "#/definitions/settings/definitions/bodycloseSettings"
+ },
+ "cyclop": {
+ "$ref": "#/definitions/settings/definitions/cyclopSettings"
+ },
+ "decorder": {
+ "$ref": "#/definitions/settings/definitions/decorderSettings"
+ },
+ "depguard":{
+ "$ref": "#/definitions/settings/definitions/depguardSettings"
+ },
+ "dogsled": {
+ "$ref": "#/definitions/settings/definitions/dogsledSettings"
+ },
+ "dupl": {
+ "$ref": "#/definitions/settings/definitions/duplSettings"
+ },
+ "embeddedstructfieldcheck": {
+ "$ref": "#/definitions/settings/definitions/embeddedstructfieldcheckSettings"
+ },
+ "errcheck": {
+ "$ref": "#/definitions/settings/definitions/errcheckSettings"
+ },
+ "errchkjson": {
+ "$ref": "#/definitions/settings/definitions/errchkjsonSettings"
+ },
+ "errorlint": {
+ "$ref": "#/definitions/settings/definitions/errorlintSettings"
+ },
+ "exhaustive": {
+ "$ref": "#/definitions/settings/definitions/exhaustiveSettings"
+ },
+ "exhaustruct": {
+ "$ref": "#/definitions/settings/definitions/exhaustructSettings"
+ },
+ "fatcontext": {
+ "$ref": "#/definitions/settings/definitions/fatcontextSettings"
+ },
+ "forbidigo": {
+ "$ref": "#/definitions/settings/definitions/forbidigoSettings"
+ },
+ "funcorder": {
+ "$ref": "#/definitions/settings/definitions/funcorderSettings"
+ },
+ "funlen": {
+ "$ref": "#/definitions/settings/definitions/funlenSettings"
+ },
+ "ginkgolinter": {
+ "$ref": "#/definitions/settings/definitions/ginkgolinterSettings"
+ },
+ "gochecksumtype": {
+ "$ref": "#/definitions/settings/definitions/gochecksumtypeSettings"
+ },
+ "gocognit": {
+ "$ref": "#/definitions/settings/definitions/gocognitSettings"
+ },
+ "goconst": {
+ "$ref": "#/definitions/settings/definitions/goconstSettings"
+ },
+ "gocritic": {
+ "$ref": "#/definitions/settings/definitions/gocriticSettings"
+ },
+ "gocyclo": {
+ "$ref": "#/definitions/settings/definitions/gocycloSettings"
+ },
+ "godoclint": {
+ "$ref": "#/definitions/settings/definitions/godoclintSettings"
+ },
+ "godot": {
+ "$ref": "#/definitions/settings/definitions/godotSettings"
+ },
+ "godox": {
+ "$ref": "#/definitions/settings/definitions/godoxSettings"
+ },
+ "interfacebloat":{
+ "$ref": "#/definitions/settings/definitions/interfacebloatSettings"
+ },
+ "goheader": {
+ "$ref": "#/definitions/settings/definitions/goheaderSettings"
+ },
+ "gomoddirectives": {
+ "$ref": "#/definitions/settings/definitions/gomoddirectivesSettings"
+ },
+ "gomodguard": {
+ "$ref": "#/definitions/settings/definitions/gomodguardSettings"
+ },
+ "gomodguard_v2": {
+ "$ref": "#/definitions/settings/definitions/gomodguardv2Settings"
+ },
+ "gosec": {
+ "$ref": "#/definitions/settings/definitions/gosecSettings"
+ },
+ "gosmopolitan": {
+ "$ref": "#/definitions/settings/definitions/gosmopolitanSettings"
+ },
+ "govet": {
+ "$ref": "#/definitions/settings/definitions/govetSettings"
+ },
+ "grouper": {
+ "$ref": "#/definitions/settings/definitions/grouperSettings"
+ },
+ "iface": {
+ "$ref": "#/definitions/settings/definitions/ifaceSettings"
+ },
+ "importas": {
+ "$ref": "#/definitions/settings/definitions/importasSettings"
+ },
+ "inamedparam": {
+ "$ref": "#/definitions/settings/definitions/inamedparamSettings"
+ },
+ "ineffassign": {
+ "$ref": "#/definitions/settings/definitions/ineffassignSettings"
+ },
+ "iotamixing": {
+ "$ref": "#/definitions/settings/definitions/iotamixingSettings"
+ },
+ "ireturn": {
+ "$ref": "#/definitions/settings/definitions/ireturnSettings"
+ },
+ "lll": {
+ "$ref": "#/definitions/settings/definitions/lllSettings"
+ },
+ "maintidx": {
+ "$ref": "#/definitions/settings/definitions/maintidxSettings"
+ },
+ "makezero":{
+ "$ref": "#/definitions/settings/definitions/makezeroSettings"
+ },
+ "loggercheck": {
+ "$ref": "#/definitions/settings/definitions/loggercheckSettings"
+ },
+ "misspell": {
+ "$ref": "#/definitions/settings/definitions/misspellSettings"
+ },
+ "musttag": {
+ "$ref": "#/definitions/settings/definitions/musttagSettings"
+ },
+ "nakedret": {
+ "$ref": "#/definitions/settings/definitions/nakedretSettings"
+ },
+ "nestif": {
+ "$ref": "#/definitions/settings/definitions/nestifSettings"
+ },
+ "nilnil": {
+ "$ref": "#/definitions/settings/definitions/nilnilSettings"
+ },
+ "nlreturn": {
+ "$ref": "#/definitions/settings/definitions/nlreturnSettings"
+ },
+ "mnd": {
+ "$ref": "#/definitions/settings/definitions/mndSettings"
+ },
+ "modernize": {
+ "$ref": "#/definitions/settings/definitions/modernizeSettings"
+ },
+ "nolintlint":{
+ "$ref": "#/definitions/settings/definitions/nolintlintSettings"
+ },
+ "reassign": {
+ "$ref": "#/definitions/settings/definitions/reassignSettings"
+ },
+ "recvcheck": {
+ "$ref": "#/definitions/settings/definitions/recvcheckSettings"
+ },
+ "nonamedreturns": {
+ "$ref": "#/definitions/settings/definitions/nonamedreturnsSettings"
+ },
+ "paralleltest": {
+ "$ref": "#/definitions/settings/definitions/paralleltestSettings"
+ },
+ "perfsprint": {
+ "$ref": "#/definitions/settings/definitions/perfsprintSettings"
+ },
+ "prealloc": {
+ "$ref": "#/definitions/settings/definitions/preallocSettings"
+ },
+ "predeclared": {
+ "$ref": "#/definitions/settings/definitions/predeclaredSettings"
+ },
+ "promlinter": {
+ "$ref": "#/definitions/settings/definitions/promlinterSettings"
+ },
+ "protogetter": {
+ "$ref": "#/definitions/settings/definitions/protogetterSettings"
+ },
+ "revive": {
+ "$ref": "#/definitions/settings/definitions/reviveSettings"
+ },
+ "rowserrcheck": {
+ "$ref": "#/definitions/settings/definitions/rowserrcheckSettings"
+ },
+ "sloglint": {
+ "$ref": "#/definitions/settings/definitions/sloglintSettings"
+ },
+ "spancheck": {
+ "$ref": "#/definitions/settings/definitions/spancheckSettings"
+ },
+ "staticcheck":{
+ "$ref": "#/definitions/settings/definitions/staticcheckSettings"
+ },
+ "tagalign": {
+ "$ref": "#/definitions/settings/definitions/tagalignSettings"
+ },
+ "tagliatelle": {
+ "$ref": "#/definitions/settings/definitions/tagliatelleSettings"
+ },
+ "testifylint": {
+ "$ref": "#/definitions/settings/definitions/testifylintSettings"
+ },
+ "testpackage": {
+ "$ref": "#/definitions/settings/definitions/testpackageSettings"
+ },
+ "thelper": {
+ "$ref": "#/definitions/settings/definitions/thelperSettings"
+ },
+ "usestdlibvars": {
+ "$ref": "#/definitions/settings/definitions/usestdlibvarsSettings"
+ },
+ "usetesting": {
+ "$ref": "#/definitions/settings/definitions/usetestingSettings"
+ },
+ "unconvert": {
+ "$ref": "#/definitions/settings/definitions/unconvertSettings"
+ },
+ "unparam": {
+ "$ref": "#/definitions/settings/definitions/unparamSettings"
+ },
+ "unqueryvet": {
+ "$ref": "#/definitions/settings/definitions/unqueryvetSettings"
+ },
+ "unused": {
+ "$ref": "#/definitions/settings/definitions/unusedSettings"
+ },
+ "varnamelen": {
+ "$ref": "#/definitions/settings/definitions/varnamelenSettings"
+ },
+ "whitespace": {
+ "$ref": "#/definitions/settings/definitions/whitespaceSettings"
+ },
+ "wrapcheck": {
+ "$ref": "#/definitions/settings/definitions/wrapcheckSettings"
+ },
+ "wsl": {
+ "$ref": "#/definitions/settings/definitions/wslSettings"
+ },
+ "wsl_v5": {
+ "$ref": "#/definitions/settings/definitions/wslSettingsV5"
+ },
+ "copyloopvar": {
+ "$ref": "#/definitions/settings/definitions/copyloopvarSettings"
+ },
+ "custom":{
+ "$ref": "#/definitions/settings/definitions/customSettings"
+ }
+ }
+ },
+ "exclusions":{
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "generated": {
+ "enum": ["strict", "lax", "disable"],
+ "default": "strict"
+ },
+ "warn-unused": {
+ "type": "boolean",
+ "default": false
+ },
+ "presets": {
+ "type": "array",
+ "items": {
+ "enum": [
+ "comments",
+ "std-error-handling",
+ "common-false-positives",
+ "legacy"
+ ]
+ }
+ },
+ "rules": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "path": {
+ "type": "string"
+ },
+ "path-except": {
+ "type": "string"
+ },
+ "linters": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linter-names"
+ }
+ },
+ "text": {
+ "type": "string"
+ },
+ "source": {
+ "type": "string"
+ }
+ },
+ "anyOf": [
+ { "required": ["path"] },
+ { "required": ["path-except"] },
+ { "required": ["linters"] },
+ { "required": ["text"] },
+ { "required": ["source"] }
+ ]
+ }
+ },
+ "paths": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "paths-except": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "formatters": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "enable": {
+ "description": "List of enabled formatters.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/formatter-names"
+ }
+ },
+ "settings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "gci": {
+ "$ref": "#/definitions/settings/definitions/gciSettings"
+ },
+ "gofmt": {
+ "$ref": "#/definitions/settings/definitions/gofmtSettings"
+ },
+ "gofumpt": {
+ "$ref": "#/definitions/settings/definitions/gofumptSettings"
+ },
+ "goimports": {
+ "$ref": "#/definitions/settings/definitions/goimportsSettings"
+ },
+ "golines": {
+ "$ref": "#/definitions/settings/definitions/golinesSettings"
+ }
+ }
+ },
+ "exclusions": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "generated": {
+ "enum": ["strict", "lax", "disable"],
+ "default": "strict"
+ },
+ "paths": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "warn-unused": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ }
+ }
+ },
+ "issues": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-issues-per-linter": {
+ "description": "Maximum issues count per one linter. Set to 0 to disable.",
+ "type": "integer",
+ "default": 50,
+ "minimum": 0
+ },
+ "max-same-issues": {
+ "description": "Maximum count of issues with the same text. Set to 0 to disable.",
+ "type": "integer",
+ "default": 3,
+ "minimum": 0
+ },
+ "new": {
+ "description": "Show only new issues: if there are unstaged changes or untracked files, only those changes are analyzed, else only changes in HEAD~ are analyzed.",
+ "type": "boolean",
+ "default": false
+ },
+ "new-from-merge-base": {
+ "description": "Show only new issues created after the best common ancestor (merge-base against HEAD).",
+ "type": "string"
+ },
+ "new-from-rev": {
+ "description": "Show only new issues created after this git revision.",
+ "type": "string"
+ },
+ "new-from-patch": {
+ "description": "Show only new issues created in git patch with this file path.",
+ "type": "string",
+ "examples": ["path/to/patch/file"]
+ },
+ "fix": {
+ "description": "Apply the fixes detected by the linters and formatters (if it's supported by the linter).",
+ "type": "boolean",
+ "default": false
+ },
+ "uniq-by-line": {
+ "description": "Make issues output unique by line.",
+ "type": "boolean",
+ "default": true
+ },
+ "whole-files": {
+ "description": "Show issues in any part of update files (requires new-from-rev or new-from-patch).",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "severity": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "default": {
+ "description": "Set the default severity for issues. If severity rules are defined and the issues do not match or no severity is provided to the rule this will be the default severity applied. Severities should match the supported severity names of the selected out format.",
+ "type": "string",
+ "default": ""
+ },
+ "rules": {
+ "description": "When a list of severity rules are provided, severity information will be added to lint issues. Severity rules have the same filtering capability as exclude rules except you are allowed to specify one matcher per severity rule.\nOnly affects out formats that support setting severity information.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "severity": {
+ "type": "string"
+ },
+ "path": {
+ "type": "string"
+ },
+ "path-except": {
+ "type": "string"
+ },
+ "linters": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linter-names"
+ }
+ },
+ "text": {
+ "type": "string"
+ },
+ "source": {
+ "type": "string"
+ }
+ },
+ "required": ["severity"],
+ "anyOf": [
+ { "required": ["path"] },
+ { "required": ["path-except"] },
+ { "required": ["linters"] },
+ { "required": ["text"] },
+ { "required": ["source"] }
+ ]
+ },
+ "default": []
+ }
+ },
+ "required": ["default"]
+ }
+ }
+}
diff --git a/vendor/github.com/golangci/golangci-lint/v2/jsonschema/golangci.next.jsonschema.json b/vendor/github.com/golangci/golangci-lint/v2/jsonschema/golangci.next.jsonschema.json
new file mode 100644
index 000000000..0ac9d577e
--- /dev/null
+++ b/vendor/github.com/golangci/golangci-lint/v2/jsonschema/golangci.next.jsonschema.json
@@ -0,0 +1,5438 @@
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "$id": "https://json.schemastore.org/golangci-lint.json",
+ "definitions": {
+ "gocritic-checks": {
+ "enum": [
+ "appendAssign",
+ "appendCombine",
+ "argOrder",
+ "assignOp",
+ "badCall",
+ "badCond",
+ "badLock",
+ "badRegexp",
+ "badSorting",
+ "badSyncOnceFunc",
+ "boolExprSimplify",
+ "builtinShadow",
+ "builtinShadowDecl",
+ "captLocal",
+ "caseOrder",
+ "codegenComment",
+ "commentFormatting",
+ "commentedOutCode",
+ "commentedOutImport",
+ "defaultCaseOrder",
+ "deferInLoop",
+ "deferUnlambda",
+ "deprecatedComment",
+ "docStub",
+ "dupArg",
+ "dupBranchBody",
+ "dupCase",
+ "dupImport",
+ "dupOption",
+ "dupSubExpr",
+ "dynamicFmtString",
+ "elseif",
+ "emptyDecl",
+ "emptyFallthrough",
+ "emptyStringTest",
+ "equalFold",
+ "evalOrder",
+ "exitAfterDefer",
+ "exposedSyncMutex",
+ "externalErrorReassign",
+ "filepathJoin",
+ "flagDeref",
+ "flagName",
+ "hexLiteral",
+ "httpNoBody",
+ "hugeParam",
+ "ifElseChain",
+ "importShadow",
+ "indexAlloc",
+ "initClause",
+ "mapKey",
+ "methodExprCall",
+ "nestingReduce",
+ "newDeref",
+ "nilValReturn",
+ "octalLiteral",
+ "offBy1",
+ "paramTypeCombine",
+ "preferDecodeRune",
+ "preferFilepathJoin",
+ "preferFprint",
+ "preferStringWriter",
+ "preferWriteByte",
+ "ptrToRefParam",
+ "rangeAppendAll",
+ "rangeExprCopy",
+ "rangeValCopy",
+ "redundantSprint",
+ "regexpMust",
+ "regexpPattern",
+ "regexpSimplify",
+ "returnAfterHttpError",
+ "ruleguard",
+ "singleCaseSwitch",
+ "sliceClear",
+ "sloppyLen",
+ "sloppyReassign",
+ "sloppyTypeAssert",
+ "sortSlice",
+ "sprintfQuotedString",
+ "sqlQuery",
+ "stringConcatSimplify",
+ "stringXbytes",
+ "stringsCompare",
+ "switchTrue",
+ "syncMapLoadAndDelete",
+ "timeExprSimplify",
+ "todoCommentWithoutDetail",
+ "tooManyResultsChecker",
+ "truncateCmp",
+ "typeAssertChain",
+ "typeDefFirst",
+ "typeSwitchVar",
+ "typeUnparen",
+ "uncheckedInlineErr",
+ "underef",
+ "unlabelStmt",
+ "unlambda",
+ "unnamedResult",
+ "unnecessaryBlock",
+ "unnecessaryDefer",
+ "unslice",
+ "valSwap",
+ "weakCond",
+ "whyNoLint",
+ "wrapperFunc",
+ "yodaStyleExpr",
+ "zeroByteRepeat"
+ ]
+ },
+ "gocritic-tags": {
+ "enum": [
+ "diagnostic",
+ "style",
+ "performance",
+ "experimental",
+ "opinionated",
+ "security"
+ ]
+ },
+ "staticcheck-checks": {
+ "enum": [
+ "*",
+ "all",
+ "SA*",
+ "-SA*",
+ "SA1*",
+ "-SA1*",
+ "SA1000",
+ "-SA1000",
+ "SA1001",
+ "-SA1001",
+ "SA1002",
+ "-SA1002",
+ "SA1003",
+ "-SA1003",
+ "SA1004",
+ "-SA1004",
+ "SA1005",
+ "-SA1005",
+ "SA1006",
+ "-SA1006",
+ "SA1007",
+ "-SA1007",
+ "SA1008",
+ "-SA1008",
+ "SA1010",
+ "-SA1010",
+ "SA1011",
+ "-SA1011",
+ "SA1012",
+ "-SA1012",
+ "SA1013",
+ "-SA1013",
+ "SA1014",
+ "-SA1014",
+ "SA1015",
+ "-SA1015",
+ "SA1016",
+ "-SA1016",
+ "SA1017",
+ "-SA1017",
+ "SA1018",
+ "-SA1018",
+ "SA1019",
+ "-SA1019",
+ "SA1020",
+ "-SA1020",
+ "SA1021",
+ "-SA1021",
+ "SA1023",
+ "-SA1023",
+ "SA1024",
+ "-SA1024",
+ "SA1025",
+ "-SA1025",
+ "SA1026",
+ "-SA1026",
+ "SA1027",
+ "-SA1027",
+ "SA1028",
+ "-SA1028",
+ "SA1029",
+ "-SA1029",
+ "SA1030",
+ "-SA1030",
+ "SA1031",
+ "-SA1031",
+ "SA1032",
+ "-SA1032",
+ "SA2*",
+ "-SA2*",
+ "SA2000",
+ "-SA2000",
+ "SA2001",
+ "-SA2001",
+ "SA2002",
+ "-SA2002",
+ "SA2003",
+ "-SA2003",
+ "SA3*",
+ "-SA3*",
+ "SA3000",
+ "-SA3000",
+ "SA3001",
+ "-SA3001",
+ "SA4*",
+ "-SA4*",
+ "SA4000",
+ "-SA4000",
+ "SA4001",
+ "-SA4001",
+ "SA4003",
+ "-SA4003",
+ "SA4004",
+ "-SA4004",
+ "SA4005",
+ "-SA4005",
+ "SA4006",
+ "-SA4006",
+ "SA4008",
+ "-SA4008",
+ "SA4009",
+ "-SA4009",
+ "SA4010",
+ "-SA4010",
+ "SA4011",
+ "-SA4011",
+ "SA4012",
+ "-SA4012",
+ "SA4013",
+ "-SA4013",
+ "SA4014",
+ "-SA4014",
+ "SA4015",
+ "-SA4015",
+ "SA4016",
+ "-SA4016",
+ "SA4017",
+ "-SA4017",
+ "SA4018",
+ "-SA4018",
+ "SA4019",
+ "-SA4019",
+ "SA4020",
+ "-SA4020",
+ "SA4021",
+ "-SA4021",
+ "SA4022",
+ "-SA4022",
+ "SA4023",
+ "-SA4023",
+ "SA4024",
+ "-SA4024",
+ "SA4025",
+ "-SA4025",
+ "SA4026",
+ "-SA4026",
+ "SA4027",
+ "-SA4027",
+ "SA4028",
+ "-SA4028",
+ "SA4029",
+ "-SA4029",
+ "SA4030",
+ "-SA4030",
+ "SA4031",
+ "-SA4031",
+ "SA4032",
+ "-SA4032",
+ "SA5*",
+ "-SA5*",
+ "SA5000",
+ "-SA5000",
+ "SA5001",
+ "-SA5001",
+ "SA5002",
+ "-SA5002",
+ "SA5003",
+ "-SA5003",
+ "SA5004",
+ "-SA5004",
+ "SA5005",
+ "-SA5005",
+ "SA5007",
+ "-SA5007",
+ "SA5008",
+ "-SA5008",
+ "SA5009",
+ "-SA5009",
+ "SA5010",
+ "-SA5010",
+ "SA5011",
+ "-SA5011",
+ "SA5012",
+ "-SA5012",
+ "SA6*",
+ "-SA6*",
+ "SA6000",
+ "-SA6000",
+ "SA6001",
+ "-SA6001",
+ "SA6002",
+ "-SA6002",
+ "SA6003",
+ "-SA6003",
+ "SA6005",
+ "-SA6005",
+ "SA6006",
+ "-SA6006",
+ "SA9*",
+ "-SA9*",
+ "SA9001",
+ "-SA9001",
+ "SA9002",
+ "-SA9002",
+ "SA9003",
+ "-SA9003",
+ "SA9004",
+ "-SA9004",
+ "SA9005",
+ "-SA9005",
+ "SA9006",
+ "-SA9006",
+ "SA9007",
+ "-SA9007",
+ "SA9008",
+ "-SA9008",
+ "SA9009",
+ "-SA9009",
+ "ST*",
+ "-ST*",
+ "ST1*",
+ "-ST1*",
+ "ST1000",
+ "-ST1000",
+ "ST1001",
+ "-ST1001",
+ "ST1003",
+ "-ST1003",
+ "ST1005",
+ "-ST1005",
+ "ST1006",
+ "-ST1006",
+ "ST1008",
+ "-ST1008",
+ "ST1011",
+ "-ST1011",
+ "ST1012",
+ "-ST1012",
+ "ST1013",
+ "-ST1013",
+ "ST1015",
+ "-ST1015",
+ "ST1016",
+ "-ST1016",
+ "ST1017",
+ "-ST1017",
+ "ST1018",
+ "-ST1018",
+ "ST1019",
+ "-ST1019",
+ "ST1020",
+ "-ST1020",
+ "ST1021",
+ "-ST1021",
+ "ST1022",
+ "-ST1022",
+ "ST1023",
+ "-ST1023",
+ "S*",
+ "-S*",
+ "S1*",
+ "-S1*",
+ "S1000",
+ "-S1000",
+ "S1001",
+ "-S1001",
+ "S1002",
+ "-S1002",
+ "S1003",
+ "-S1003",
+ "S1004",
+ "-S1004",
+ "S1005",
+ "-S1005",
+ "S1006",
+ "-S1006",
+ "S1007",
+ "-S1007",
+ "S1008",
+ "-S1008",
+ "S1009",
+ "-S1009",
+ "S1010",
+ "-S1010",
+ "S1011",
+ "-S1011",
+ "S1012",
+ "-S1012",
+ "S1016",
+ "-S1016",
+ "S1017",
+ "-S1017",
+ "S1018",
+ "-S1018",
+ "S1019",
+ "-S1019",
+ "S1020",
+ "-S1020",
+ "S1021",
+ "-S1021",
+ "S1023",
+ "-S1023",
+ "S1024",
+ "-S1024",
+ "S1025",
+ "-S1025",
+ "S1028",
+ "-S1028",
+ "S1029",
+ "-S1029",
+ "S1030",
+ "-S1030",
+ "S1031",
+ "-S1031",
+ "S1032",
+ "-S1032",
+ "S1033",
+ "-S1033",
+ "S1034",
+ "-S1034",
+ "S1035",
+ "-S1035",
+ "S1036",
+ "-S1036",
+ "S1037",
+ "-S1037",
+ "S1038",
+ "-S1038",
+ "S1039",
+ "-S1039",
+ "S1040",
+ "-S1040",
+ "QF*",
+ "-QF*",
+ "QF1*",
+ "-QF1*",
+ "QF1001",
+ "-QF1001",
+ "QF1002",
+ "-QF1002",
+ "QF1003",
+ "-QF1003",
+ "QF1004",
+ "-QF1004",
+ "QF1005",
+ "-QF1005",
+ "QF1006",
+ "-QF1006",
+ "QF1007",
+ "-QF1007",
+ "QF1008",
+ "-QF1008",
+ "QF1009",
+ "-QF1009",
+ "QF1010",
+ "-QF1010",
+ "QF1011",
+ "-QF1011",
+ "QF1012",
+ "-QF1012"
+ ]
+ },
+ "godoclint-rules": {
+ "enum": [
+ "pkg-doc",
+ "single-pkg-doc",
+ "require-pkg-doc",
+ "start-with-name",
+ "require-doc",
+ "deprecated",
+ "max-len",
+ "no-unused-link",
+ "require-stdlib-doclink"
+ ]
+ },
+ "gosec-rules": {
+ "enum": [
+ "G101",
+ "G102",
+ "G103",
+ "G104",
+ "G106",
+ "G107",
+ "G108",
+ "G109",
+ "G110",
+ "G111",
+ "G112",
+ "G113",
+ "G114",
+ "G115",
+ "G116",
+ "G117",
+ "G118",
+ "G119",
+ "G120",
+ "G121",
+ "G122",
+ "G123",
+ "G124",
+ "G201",
+ "G202",
+ "G203",
+ "G204",
+ "G301",
+ "G302",
+ "G303",
+ "G304",
+ "G305",
+ "G306",
+ "G307",
+ "G401",
+ "G402",
+ "G403",
+ "G404",
+ "G405",
+ "G406",
+ "G408",
+ "G501",
+ "G502",
+ "G503",
+ "G504",
+ "G505",
+ "G506",
+ "G507",
+ "G601",
+ "G602",
+ "G701",
+ "G702",
+ "G703",
+ "G704",
+ "G705",
+ "G706",
+ "G707",
+ "G708",
+ "G709",
+ "G710"
+ ]
+ },
+ "govet-analyzers": {
+ "enum": [
+ "appends",
+ "asmdecl",
+ "assign",
+ "atomic",
+ "atomicalign",
+ "bools",
+ "buildtag",
+ "cgocall",
+ "composites",
+ "copylocks",
+ "deepequalerrors",
+ "defers",
+ "directive",
+ "errorsas",
+ "fieldalignment",
+ "findcall",
+ "framepointer",
+ "hostport",
+ "httpmux",
+ "httpresponse",
+ "ifaceassert",
+ "inline",
+ "loopclosure",
+ "lostcancel",
+ "nilfunc",
+ "nilness",
+ "printf",
+ "reflectvaluecompare",
+ "shadow",
+ "shift",
+ "sigchanyzer",
+ "slog",
+ "sortslice",
+ "stdmethods",
+ "stdversion",
+ "stringintconv",
+ "structtag",
+ "testinggoroutine",
+ "tests",
+ "timeformat",
+ "unmarshal",
+ "unreachable",
+ "unsafeptr",
+ "unusedresult",
+ "unusedwrite",
+ "waitgroup"
+ ]
+ },
+ "revive-rules": {
+ "enum": [
+ "add-constant",
+ "argument-limit",
+ "atomic",
+ "banned-characters",
+ "bare-return",
+ "blank-imports",
+ "bool-literal-in-expr",
+ "call-to-gc",
+ "cognitive-complexity",
+ "comment-spacings",
+ "comments-density",
+ "confusing-naming",
+ "confusing-results",
+ "constant-logical-expr",
+ "context-as-argument",
+ "context-keys-type",
+ "cyclomatic",
+ "datarace",
+ "deep-exit",
+ "defer",
+ "dot-imports",
+ "duplicated-imports",
+ "early-return",
+ "empty-block",
+ "empty-lines",
+ "enforce-map-style",
+ "enforce-repeated-arg-type-style",
+ "enforce-slice-style",
+ "enforce-switch-style",
+ "epoch-naming",
+ "error-naming",
+ "error-return",
+ "error-strings",
+ "errorf",
+ "exported",
+ "file-header",
+ "file-length-limit",
+ "filename-format",
+ "flag-parameter",
+ "forbidden-call-in-wg-go",
+ "function-length",
+ "function-result-limit",
+ "get-return",
+ "identical-branches",
+ "identical-ifelseif-branches",
+ "identical-ifelseif-conditions",
+ "identical-switch-branches",
+ "identical-switch-conditions",
+ "if-return",
+ "import-alias-naming",
+ "import-shadowing",
+ "imports-blocklist",
+ "increment-decrement",
+ "indent-error-flow",
+ "inefficient-map-lookup",
+ "line-length-limit",
+ "max-control-nesting",
+ "max-public-structs",
+ "modifies-parameter",
+ "modifies-value-receiver",
+ "nested-structs",
+ "optimize-operands-order",
+ "package-comments",
+ "package-naming",
+ "package-directory-mismatch",
+ "range-val-address",
+ "range-val-in-closure",
+ "range",
+ "receiver-naming",
+ "redefines-builtin-id",
+ "redundant-build-tag",
+ "redundant-import-alias",
+ "redundant-test-main-exit",
+ "string-format",
+ "string-of-int",
+ "struct-tag",
+ "superfluous-else",
+ "time-date",
+ "time-equal",
+ "time-naming",
+ "unchecked-type-assertion",
+ "unconditional-recursion",
+ "unexported-naming",
+ "unexported-return",
+ "unhandled-error",
+ "unnecessary-format",
+ "unnecessary-if",
+ "unnecessary-stmt",
+ "unreachable-code",
+ "unsecure-url-scheme",
+ "unused-parameter",
+ "unused-receiver",
+ "use-any",
+ "use-errors-new",
+ "use-fmt-print",
+ "use-slices-sort",
+ "use-waitgroup-go",
+ "useless-break",
+ "useless-fallthrough",
+ "var-declaration",
+ "var-naming",
+ "waitgroup-by-value"
+ ]
+ },
+ "iface-analyzers": {
+ "enum": [
+ "identical",
+ "unused",
+ "opaque",
+ "unexported"
+ ]
+ },
+ "tagliatelle-cases": {
+ "enum": [
+ "",
+ "camel",
+ "pascal",
+ "kebab",
+ "snake",
+ "goCamel",
+ "goPascal",
+ "goKebab",
+ "goSnake",
+ "upper",
+ "upperSnake",
+ "lower",
+ "header"
+ ]
+ },
+ "modernize-analyzers": {
+ "enum": [
+ "any",
+ "fmtappendf",
+ "forvar",
+ "mapsloop",
+ "minmax",
+ "newexpr",
+ "omitzero",
+ "plusbuild",
+ "rangeint",
+ "reflecttypefor",
+ "slicescontains",
+ "slicessort",
+ "stditerators",
+ "stringscut",
+ "stringscutprefix",
+ "stringsseq",
+ "stringsbuilder",
+ "testingcontext",
+ "unsafefuncs",
+ "waitgroup"
+ ]
+ },
+ "wsl-checks": {
+ "enum": [
+ "after-block",
+ "after-decl",
+ "after-defer",
+ "after-expr",
+ "after-go",
+ "append",
+ "assign-exclusive",
+ "assign-expr",
+ "assign",
+ "branch",
+ "cuddle-group",
+ "decl",
+ "defer",
+ "err",
+ "expr",
+ "for",
+ "go",
+ "if",
+ "inc-dec",
+ "label",
+ "leading-whitespace",
+ "range",
+ "return",
+ "select",
+ "send",
+ "switch",
+ "trailing-whitespace",
+ "type-switch"
+ ]
+ },
+ "relative-path-modes": {
+ "enum": [
+ "gomod",
+ "gitroot",
+ "cfg",
+ "wd"
+ ]
+ },
+ "simple-format": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "path": {
+ "$ref": "#/definitions/formats-path",
+ "default": "stdout"
+ }
+ }
+ },
+ "formats-path" : {
+ "anyOf": [
+ {
+ "enum": [
+ "stdout",
+ "stderr"
+ ]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ },
+ "linter-names": {
+ "$comment": "anyOf with enum is used to allow auto-completion of non-custom linters",
+ "description": "Usable linter names.",
+ "anyOf": [
+ {
+ "enum": [
+ "arangolint",
+ "asasalint",
+ "asciicheck",
+ "bidichk",
+ "bodyclose",
+ "canonicalheader",
+ "clickhouselint",
+ "containedctx",
+ "contextcheck",
+ "copyloopvar",
+ "cyclop",
+ "decorder",
+ "depguard",
+ "dogsled",
+ "dupl",
+ "dupword",
+ "durationcheck",
+ "embeddedstructfieldcheck",
+ "errcheck",
+ "errchkjson",
+ "errname",
+ "errorlint",
+ "exhaustive",
+ "exhaustruct",
+ "exptostd",
+ "fatcontext",
+ "forbidigo",
+ "forcetypeassert",
+ "funcorder",
+ "funlen",
+ "ginkgolinter",
+ "gocheckcompilerdirectives",
+ "gochecknoglobals",
+ "gochecknoinits",
+ "gochecksumtype",
+ "gocognit",
+ "goconst",
+ "gocritic",
+ "gocyclo",
+ "godoclint",
+ "godot",
+ "godox",
+ "err113",
+ "goheader",
+ "gomoddirectives",
+ "gomodguard",
+ "gomodguard_v2",
+ "goprintffuncname",
+ "gosec",
+ "gosimple",
+ "gosmopolitan",
+ "govet",
+ "grouper",
+ "iface",
+ "importas",
+ "inamedparam",
+ "ineffassign",
+ "interfacebloat",
+ "intrange",
+ "iotamixing",
+ "ireturn",
+ "lll",
+ "loggercheck",
+ "maintidx",
+ "makezero",
+ "mirror",
+ "misspell",
+ "mnd",
+ "modernize",
+ "musttag",
+ "nakedret",
+ "nestif",
+ "nilerr",
+ "nilnesserr",
+ "nilnil",
+ "nlreturn",
+ "noctx",
+ "noinlineerr",
+ "nolintlint",
+ "nonamedreturns",
+ "nosprintfhostport",
+ "paralleltest",
+ "perfsprint",
+ "prealloc",
+ "predeclared",
+ "promlinter",
+ "protogetter",
+ "reassign",
+ "recvcheck",
+ "revive",
+ "rowserrcheck",
+ "sloglint",
+ "sqlclosecheck",
+ "staticcheck",
+ "stylecheck",
+ "tagalign",
+ "tagliatelle",
+ "testableexamples",
+ "testifylint",
+ "testpackage",
+ "thelper",
+ "tparallel",
+ "unconvert",
+ "unparam",
+ "unused",
+ "usestdlibvars",
+ "usetesting",
+ "varnamelen",
+ "wastedassign",
+ "whitespace",
+ "wrapcheck",
+ "wsl",
+ "wsl_v5",
+ "zerologlint"
+ ]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ },
+ "formatter-names": {
+ "description": "Usable formatter names.",
+ "enum": [
+ "gci",
+ "gofmt",
+ "gofumpt",
+ "goimports",
+ "golines",
+ "swaggo"
+ ]
+ },
+ "settings": {
+ "definitions": {
+ "dupwordSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "keywords": {
+ "description": "Keywords for detecting duplicate words. If this list is not empty, only the words defined in this list will be detected.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["the", "and", "a"]
+ }
+ },
+ "ignore": {
+ "description": "Keywords used to ignore detection.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["0C0C"]
+ }
+ },
+ "comments-only": {
+ "description": "Checks only comments, skip strings.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "asasalintSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "exclude": {
+ "description": "To specify a set of function names to exclude.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["\\.Wrapf"]
+ }
+ },
+ "use-builtin-exclusions": {
+ "description": "To enable/disable the asasalint builtin exclusions of function names.",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "bidichkSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "left-to-right-embedding": {
+ "description": "Disallow: LEFT-TO-RIGHT-EMBEDDING",
+ "type": "boolean",
+ "default": false
+ },
+ "right-to-left-embedding": {
+ "description": "Disallow: RIGHT-TO-LEFT-EMBEDDING",
+ "type": "boolean",
+ "default": false
+ },
+ "pop-directional-formatting": {
+ "description": "Disallow: POP-DIRECTIONAL-FORMATTING",
+ "type": "boolean",
+ "default": false
+ },
+ "left-to-right-override": {
+ "description": "Disallow: LEFT-TO-RIGHT-OVERRIDE",
+ "type": "boolean",
+ "default": false
+ },
+ "right-to-left-override": {
+ "description": "Disallow: RIGHT-TO-LEFT-OVERRIDE",
+ "type": "boolean",
+ "default": false
+ },
+ "left-to-right-isolate": {
+ "description": "Disallow: LEFT-TO-RIGHT-ISOLATE",
+ "type": "boolean",
+ "default": false
+ },
+ "right-to-left-isolate": {
+ "description": "Disallow: RIGHT-TO-LEFT-ISOLATE",
+ "type": "boolean",
+ "default": false
+ },
+ "first-strong-isolate": {
+ "description": "Disallow: FIRST-STRONG-ISOLATE",
+ "type": "boolean",
+ "default": false
+ },
+ "pop-directional-isolate": {
+ "description": "Disallow: POP-DIRECTIONAL-ISOLATE",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "bodycloseSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-consumption": {
+ "description": "Check that the response body is consumed.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "cyclopSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-complexity": {
+ "description": "Max complexity the function can have",
+ "type": "integer",
+ "default": 10,
+ "minimum": 0
+ },
+ "package-average": {
+ "description": "Max average complexity in package",
+ "type": "number",
+ "default": 0,
+ "minimum": 0
+ }
+ }
+ },
+ "decorderSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "dec-order": {
+ "type": "array",
+ "default": [["type", "const", "var", "func"]],
+ "items": {
+ "enum": ["type", "const", "var", "func"]
+ }
+ },
+ "ignore-underscore-vars": {
+ "description": "Underscore vars (vars with \"_\" as the name) will be ignored at all checks",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-dec-order-check": {
+ "description": "Order of declarations is not checked",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-init-func-first-check": {
+ "description": "Allow init func to be anywhere in file",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-dec-num-check": {
+ "description": "Multiple global type, const and var declarations are allowed",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-type-dec-num-check": {
+ "description": "Type declarations will be ignored for dec num check",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-const-dec-num-check": {
+ "description": "Const declarations will be ignored for dec num check",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-var-dec-num-check": {
+ "description": "Var declarations will be ignored for dec num check",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ },
+ "depguardSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "rules": {
+ "description": "Rules to apply.",
+ "type": "object",
+ "additionalProperties": false,
+ "patternProperties": {
+ "^[^.]+$": {
+ "description": "Name of a rule.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "list-mode": {
+ "description": "Used to determine the package matching priority.",
+ "enum": ["original", "strict", "lax"],
+ "default": "original"
+ },
+ "files": {
+ "description": "List of file globs that will match this list of settings to compare against.",
+ "additionalProperties": false,
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "allow": {
+ "description": "List of allowed packages.",
+ "additionalProperties": false,
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "deny": {
+ "description": "Packages that are not allowed where the value is a suggestion.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "desc": {
+ "description": "Description",
+ "type": "string"
+ },
+ "pkg": {
+ "description": "Package",
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "dogsledSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-blank-identifiers": {
+ "description": "Check assignments with too many blank identifiers.",
+ "type": "integer",
+ "default": 2,
+ "minimum": 0
+ }
+ }
+ },
+ "duplSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "threshold": {
+ "description": "Tokens count to trigger issue.",
+ "type": "integer",
+ "default": 150,
+ "minimum": 0
+ }
+ }
+ },
+ "embeddedstructfieldcheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "empty-line": {
+ "description": "Checks that there is an empty space between the embedded fields and regular fields.",
+ "type": "boolean",
+ "default": false
+ },
+ "forbid-mutex": {
+ "description": "Checks that sync.Mutex and sync.RWMutex are not used as embedded fields.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "errcheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-type-assertions": {
+ "description": "Report about not checking errors in type assertions, i.e.: `a := b.(MyStruct)`",
+ "type": "boolean",
+ "default": false
+ },
+ "check-blank": {
+ "description": "Report about assignment of errors to blank identifier",
+ "type": "boolean",
+ "default": false
+ },
+ "exclude-functions": {
+ "description": "List of functions to exclude from checking, where each entry is a single function to exclude",
+ "type": "array",
+ "examples": ["io/ioutil.ReadFile", "io.Copy(*bytes.Buffer)"],
+ "items": {
+ "type": "string"
+ }
+ },
+ "disable-default-exclusions": {
+ "description": "To disable the errcheck built-in exclude list",
+ "type": "boolean",
+ "default": false
+ },
+ "verbose": {
+ "description": "Display function signature instead of selector",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "errchkjsonSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-error-free-encoding": {
+ "type": "boolean",
+ "default": false
+ },
+ "report-no-exported": {
+ "description": "Issue on struct that doesn't have exported fields.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "errorlintSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "errorf": {
+ "description": "Check whether fmt.Errorf uses the %w verb for formatting errors",
+ "type": "boolean",
+ "default": true
+ },
+ "errorf-multi": {
+ "description": "Permit more than 1 %w verb, valid per Go 1.20",
+ "type": "boolean",
+ "default": true
+ },
+ "asserts": {
+ "description": "Check for plain type assertions and type switches.",
+ "type": "boolean",
+ "default": true
+ },
+ "comparison": {
+ "description": "Check for plain error comparisons",
+ "type": "boolean",
+ "default": true
+ },
+ "allowed-errors": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "err": {
+ "type": "string"
+ },
+ "fun": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "allowed-errors-wildcard": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "err": {
+ "type": "string"
+ },
+ "fun": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "exhaustiveSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check": {
+ "description": "Program elements to check for exhaustiveness.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["switch", "map"]
+ }
+ },
+ "explicit-exhaustive-switch": {
+ "description": "Only run exhaustive check on switches with \"//exhaustive:enforce\" comment.",
+ "type": "boolean",
+ "default": false
+ },
+ "explicit-exhaustive-map": {
+ "description": "Only run exhaustive check on map literals with \"//exhaustive:enforce\" comment.",
+ "type": "boolean",
+ "default": false
+ },
+ "default-case-required": {
+ "description": "Switch statement requires default case even if exhaustive.",
+ "type": "boolean",
+ "default": false
+ },
+ "default-signifies-exhaustive": {
+ "description": "Presence of `default` case in switch statements satisfies exhaustiveness, even if all enum members are not listed.",
+ "type": "boolean",
+ "default": false
+ },
+ "ignore-enum-members": {
+ "description": "Enum members matching `regex` do not have to be listed in switch statements to satisfy exhaustiveness",
+ "type": "string"
+ },
+ "ignore-enum-types": {
+ "description": "Enum types matching the supplied regex do not have to be listed in switch statements to satisfy exhaustiveness.",
+ "type": "string"
+ },
+ "package-scope-only": {
+ "description": "Consider enums only in package scopes, not in inner scopes.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "exhaustructSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "include": {
+ "description": "List of regular expressions to match struct packages and names.",
+ "type": "array",
+ "examples": [".*\\.Test"],
+ "items": {
+ "type": "string"
+ }
+ },
+ "exclude": {
+ "description": "List of regular expressions to exclude struct packages and names from check.",
+ "type": "array",
+ "examples": ["cobra\\.Command$"],
+ "items": {
+ "type": "string"
+ }
+ },
+ "allow-empty": {
+ "description": "Allows empty structures, effectively excluding them from the check.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-empty-rx": {
+ "description": "List of regular expressions to match type names that should be allowed to be empty.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "allow-empty-returns": {
+ "description": "Allows empty structures in return statements.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-empty-declarations": {
+ "description": "Allows empty structures in variable declarations.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "fatcontextSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-struct-pointers": {
+ "description": "Check for potential fat contexts in struct pointers.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "forbidigoSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "exclude-godoc-examples": {
+ "description": "Exclude code in godoc examples.",
+ "type": "boolean",
+ "default": true
+ },
+ "analyze-types": {
+ "description": "Instead of matching the literal source code, use type information to replace expressions with strings that contain the package name and (for methods and fields) the type name.",
+ "type": "boolean",
+ "default": true
+ },
+ "forbid": {
+ "description": "List of identifiers to forbid (written using `regexp`)",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "pattern": {
+ "description": "Pattern",
+ "type": "string"
+ },
+ "pkg": {
+ "description": "Package",
+ "type": "string"
+ },
+ "msg": {
+ "description": "Message",
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "funcorderSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "constructor": {
+ "description": "Checks that constructors are placed after the structure declaration.",
+ "type": "boolean",
+ "default": true
+ },
+ "struct-method": {
+ "description": "Checks if the exported methods of a structure are placed before the non-exported ones.",
+ "type": "boolean",
+ "default": true
+ },
+ "alphabetical": {
+ "description": "Checks if the constructors and/or structure methods are sorted alphabetically.",
+ "type": "boolean",
+ "default": false
+ },
+ "function": {
+ "description": "Checks that exported functions are placed before unexported functions.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "funlenSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "lines": {
+ "description": "Limit lines number per function.",
+ "type": "integer",
+ "default": 60
+ },
+ "statements": {
+ "description": "Limit statements number per function.",
+ "type": "integer",
+ "default": 40
+ },
+ "ignore-comments": {
+ "description": "Ignore comments when counting lines.",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "gciSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "sections": {
+ "description": "Section configuration to compare against.",
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "enum": [
+ "standard",
+ "default",
+ "blank",
+ "dot",
+ "alias",
+ "localmodule"
+ ]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ },
+ "default": ["standard", "default"]
+ },
+ "no-inline-comments": {
+ "description": "Checks that no inline Comments are present.",
+ "type": "boolean",
+ "default": false
+ },
+ "no-prefix-comments": {
+ "description": "Checks that no prefix Comments(comment lines above an import) are present.",
+ "type": "boolean",
+ "default": false
+ },
+ "custom-order": {
+ "description": "Enable custom order of sections.",
+ "type": "boolean",
+ "default": false
+ },
+ "no-lex-order": {
+ "description": "Drops lexical ordering for custom sections.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "ginkgolinterSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "suppress-len-assertion": {
+ "description": "Suppress the wrong length assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-nil-assertion": {
+ "description": "Suppress the wrong nil assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-err-assertion": {
+ "description": "Suppress the wrong error assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-compare-assertion": {
+ "description": "Suppress the wrong comparison assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-async-assertion": {
+ "description": "Suppress the function all in async assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-type-compare-assertion": {
+ "description": "Suppress warning for comparing values from different types, like int32 and uint32.",
+ "type": "boolean",
+ "default": false
+ },
+ "forbid-focus-container": {
+ "description": "Trigger warning for ginkgo focus containers like FDescribe, FContext, FWhen or FIt.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-havelen-zero": {
+ "description": "Don't trigger warnings for HaveLen(0).",
+ "type": "boolean",
+ "default": false
+ },
+ "force-expect-to": {
+ "description": "Force using `Expect` with `To`, `ToNot` or `NotTo`",
+ "type": "boolean",
+ "default": false
+ },
+ "validate-async-intervals": {
+ "description": "Best effort validation of async intervals (timeout and polling).",
+ "type": "boolean",
+ "default": false
+ },
+ "forbid-spec-pollution": {
+ "description": "Trigger a warning for variable assignments in ginkgo containers like `Describe`, `Context` and `When`, instead of in `BeforeEach()`.",
+ "type": "boolean",
+ "default": false
+ },
+ "force-succeed": {
+ "description": "Force using the Succeed matcher for error functions, and the HaveOccurred matcher for non-function error values.",
+ "type": "boolean",
+ "default": false
+ },
+ "force-assertion-description": {
+ "description": "Force adding assertion descriptions to gomega matchers.",
+ "type": "boolean",
+ "default": false
+ },
+ "force-tonot": {
+ "description": "Force using `ToNot`, `ShouldNot` instead of `To(Not())`.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "gochecksumtypeSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "default-signifies-exhaustive": {
+ "description": "Presence of `default` case in switch statements satisfies exhaustiveness, if all members are not listed.",
+ "type": "boolean",
+ "default": true
+ },
+ "include-shared-interfaces": {
+ "description": "Include shared interfaces in the exhaustiviness check.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "gocognitSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "min-complexity": {
+ "description": "Minimal code complexity to report (we recommend 10-20).",
+ "type": "integer",
+ "default": 30
+ }
+ }
+ },
+ "goconstSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "match-constant": {
+ "description": "Look for existing constants matching the values",
+ "type": "boolean",
+ "default": true
+ },
+ "min-len": {
+ "description": "Minimum length of string constant.",
+ "type": "integer",
+ "default": 3
+ },
+ "min-occurrences": {
+ "description": "Minimum occurrences count to trigger.",
+ "type": "integer",
+ "default": 3
+ },
+ "ignore-calls": {
+ "description": "Ignore when constant is not used as function argument",
+ "type": "boolean",
+ "default": true
+ },
+ "ignore-string-values": {
+ "description": "Exclude strings matching the given regular expression",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "numbers": {
+ "description": "Search also for duplicated numbers.",
+ "type": "boolean",
+ "default": false
+ },
+ "min": {
+ "description": "Minimum value, only works with `numbers`",
+ "type": "integer",
+ "default": 3
+ },
+ "max": {
+ "description": "Maximum value, only works with `numbers`",
+ "type": "integer",
+ "default": 3
+ },
+ "find-duplicates": {
+ "description": "Detects constants with identical values",
+ "type": "boolean",
+ "default": false
+ },
+ "eval-const-expressions": {
+ "description": "Evaluates of constant expressions like Prefix + \"suffix\"",
+ "type": "boolean",
+ "default": false
+ },
+ "ignore-tests": {
+ "description": "Ignore strings from test files",
+ "type": "boolean",
+ "default": false
+ },
+ "ignore-functions": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "gocriticSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "enabled-checks": {
+ "description": "Which checks should be enabled. By default, a list of stable checks is used. To see it, run `GL_DEBUG=gocritic golangci-lint run`.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/gocritic-checks"
+ }
+ },
+ "disabled-checks": {
+ "description": "Which checks should be disabled.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/gocritic-checks"
+ },
+ "default": []
+ },
+ "enabled-tags": {
+ "description": "Enable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/gocritic-tags"
+ }
+ },
+ "disabled-tags": {
+ "description": "Disable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/gocritic-tags"
+ }
+ },
+ "settings": {
+ "description": "Settings passed to gocritic. Properties must be valid and enabled check names.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "captLocal": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "paramsOnly" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "commentedOutCode": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "minLength" : {
+ "type": "number",
+ "default": 15
+ }
+ }
+ },
+ "elseif": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skipBalanced" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "hugeParam": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "sizeThreshold" : {
+ "type": "number",
+ "default": 80
+ }
+ }
+ },
+ "ifElseChain": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "minThreshold" : {
+ "type": "number",
+ "default": 2
+ }
+ }
+ },
+ "nestingReduce": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "bodyWidth" : {
+ "type": "number",
+ "default": 5
+ }
+ }
+ },
+ "rangeExprCopy": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "sizeThreshold" : {
+ "type": "number",
+ "default": 512
+ },
+ "skipTestFuncs" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "rangeValCopy": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "sizeThreshold" : {
+ "type": "number",
+ "default": 128
+ },
+ "skipTestFuncs" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "ruleguard": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "debug" : {
+ "type": "string"
+ },
+ "enable" : {
+ "type": "string"
+ },
+ "disable" : {
+ "type": "string"
+ },
+ "failOn" : {
+ "type": "string"
+ },
+ "rules" : {
+ "type": "string"
+ }
+ }
+ },
+ "tooManyResultsChecker": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "maxResults" : {
+ "type": "number",
+ "default": 5
+ }
+ }
+ },
+ "truncateCmp": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skipArchDependent" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "underef": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skipRecvDeref" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "unnamedResult": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "checkExported" : {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ }
+ }
+ },
+ "disable-all": {
+ "type": "boolean",
+ "default": false
+ },
+ "enable-all": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "gocycloSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "min-complexity": {
+ "description": "Minimum code complexity to report (we recommend 10-20).",
+ "type": "integer",
+ "default": 30
+ }
+ }
+ },
+ "godoclintSettings": {
+ "type": "object",
+ "properties": {
+ "default": {
+ "type": "string",
+ "enum": ["all", "basic", "none"],
+ "default": "basic",
+ "description": "Default set of rules to enable."
+ },
+ "enable": {
+ "description": "List of rules to enable in addition to the default set.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "$ref": "#/definitions/godoclint-rules"
+ }
+ },
+ "disable": {
+ "description": "List of rules to disable.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "$ref": "#/definitions/godoclint-rules"
+ }
+ },
+ "options": {
+ "type": "object",
+ "description": "A map for setting individual rule options.",
+ "properties": {
+ "max-len": {
+ "type": "object",
+ "properties": {
+ "length": {
+ "type": "integer",
+ "description": "Maximum line length for godocs, not including the `//`, `/*` or `*/` tokens.",
+ "default": 77
+ }
+ }
+ },
+ "require-doc": {
+ "type": "object",
+ "properties": {
+ "ignore-exported": {
+ "type": "boolean",
+ "description": "Ignore exported (public) symbols when applying the `require-doc` rule.",
+ "default": false
+ },
+ "ignore-unexported": {
+ "type": "boolean",
+ "description": "Ignore unexported (private) symbols when applying the `require-doc` rule.",
+ "default": true
+ }
+ }
+ },
+ "start-with-name": {
+ "type": "object",
+ "properties": {
+ "include-unexported": {
+ "type": "boolean",
+ "description": "Include unexported symbols when applying the `start-with-name` rule.",
+ "default": false
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "godotSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "scope": {
+ "description": "Comments to be checked.",
+ "enum": ["declarations", "toplevel", "all", "noinline"],
+ "default": "declarations"
+ },
+ "exclude": {
+ "description": "List of regexps for excluding particular comment lines from check.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "period": {
+ "description": "Check that each sentence ends with a period.",
+ "type": "boolean",
+ "default": true
+ },
+ "capital": {
+ "description": "Check that each sentence starts with a capital letter.",
+ "type": "boolean",
+ "default": false
+ },
+ "check-all": {
+ "description": "DEPRECATED: Check all top-level comments, not only declarations.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "godoxSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "keywords": {
+ "description": "Report any comments starting with one of these keywords. This is useful for TODO or FIXME comments that might be left in the code accidentally and should be resolved before merging.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "default": ["TODO", "BUG", "FIXME"]
+ }
+ }
+ },
+ "gofmtSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "simplify": {
+ "description": "Simplify code.",
+ "type": "boolean",
+ "default": true
+ },
+ "rewrite-rules": {
+ "description": "Apply the rewrite rules to the source before reformatting.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "pattern": {
+ "type": "string"
+ },
+ "replacement": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "golinesSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-len": {
+ "type": "integer",
+ "default": 100
+ },
+ "tab-len": {
+ "type": "integer",
+ "default": 4
+ },
+ "shorten-comments": {
+ "type": "boolean",
+ "default": false
+ },
+ "reformat-tags": {
+ "type": "boolean",
+ "default": true
+ },
+ "chain-split-dots": {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "interfacebloatSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max": {
+ "description": "The maximum number of methods allowed for an interface.",
+ "type": "integer"
+ }
+ }
+ },
+ "gofumptSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "extra-rules": {
+ "description": "Choose whether or not to use the extra rules that are disabled by default.",
+ "type": "boolean",
+ "default": false
+ },
+ "module-path": {
+ "description": " Module path which contains the source code being formatted.",
+ "type": "string"
+ }
+ }
+ },
+ "goheaderSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "values": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "const": {
+ "description": "Constants to use in the template.",
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "description": "Value for the constant.",
+ "type": "string"
+ }
+ },
+ "additionalProperties": false,
+ "examples": [
+ {
+ "YEAR": "2030",
+ "COMPANY": "MY FUTURISTIC COMPANY"
+ }
+ ]
+ },
+ "regexp": {
+ "description": "Regular expressions to use in your template.",
+ "type": "object",
+ "additionalProperties": false,
+ "patternProperties": {
+ "^.+$": {
+ "type": "string"
+ }
+ },
+ "examples": [
+ {
+ "AUTHOR": ".*@mycompany\\.com"
+ }
+ ]
+ }
+ }
+ },
+ "template": {
+ "description": "Template to put on top of every file.",
+ "type": "string",
+ "examples": [
+ "{{ MY COMPANY }}\nSPDX-License-Identifier: Apache-2.0\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at:\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License."
+ ]
+ },
+ "template-path": {
+ "description": "Path to the file containing the template source.",
+ "type": "string",
+ "examples": ["my_header_template.txt"]
+ }
+ },
+ "oneOf": [
+ { "required": ["template"] },
+ { "required": ["template-path"] }
+ ]
+ },
+ "goimportsSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "local-prefixes": {
+ "description": "Put imports beginning with prefix after 3rd-party packages. It is a list of prefixes.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "gomoddirectivesSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "replace-local": {
+ "description": "Allow local `replace` directives.",
+ "type": "boolean",
+ "default": true
+ },
+ "replace-allow-list": {
+ "description": "List of allowed `replace` directives.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "retract-allow-no-explanation": {
+ "description": "Allow to not explain why the version has been retracted in the `retract` directives.",
+ "type": "boolean",
+ "default": false
+ },
+ "exclude-forbidden": {
+ "description": "Forbid the use of the `exclude` directives.",
+ "type": "boolean",
+ "default": false
+ },
+ "ignore-forbidden": {
+ "description": "Forbid the use of the `ignore` directives. (>= go1.25)",
+ "type": "boolean",
+ "default": false
+ },
+ "toolchain-forbidden": {
+ "description": "Forbid the use of the `toolchain` directive.",
+ "type": "boolean",
+ "default": false
+ },
+ "toolchain-pattern": {
+ "description": "Defines a pattern to validate `toolchain` directive.",
+ "type": "string"
+ },
+ "tool-forbidden": {
+ "description": "Forbid the use of the `tool` directives.",
+ "type": "boolean",
+ "default": false
+ },
+ "go-debug-forbidden": {
+ "description": "Forbid the use of the `godebug` directive.",
+ "type": "boolean",
+ "default": false
+ },
+ "go-version-pattern": {
+ "description": "Defines a pattern to validate `go` minimum version directive.",
+ "type": "string",
+ "default": ""
+ },
+ "check-module-path": {
+ "description": "Check the validity of the module path.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "gomodguardv2Settings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "local-replace-directives": {
+ "type": "boolean"
+ },
+ "allowed": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["module"],
+ "properties": {
+ "module": {
+ "type": "string"
+ },
+ "version": {
+ "type": "string"
+ },
+ "match-type": {
+ "enum": ["", "exact", "prefix", "regex"],
+ "default": "exact"
+ }
+ }
+ }
+ },
+ "blocked": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["module"],
+ "properties": {
+ "module": {
+ "type": "string"
+ },
+ "version": {
+ "type": "string"
+ },
+ "match-type": {
+ "type": "string"
+ },
+ "reason": {
+ "type": "string"
+ },
+ "recommendations": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "gomodguardSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "allowed": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "modules": {
+ "description": "List of allowed modules.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["gopkg.in/yaml.v2"]
+ }
+ },
+ "domains": {
+ "description": "List of allowed module domains.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["golang.org"]
+ }
+ }
+ }
+ },
+ "blocked": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "modules": {
+ "description": "List of blocked modules.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "recommendations": {
+ "description": "Recommended modules that should be used instead.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "reason": {
+ "description": "Reason why the recommended module should be used.",
+ "type": "string"
+ }
+ }
+ }
+ },
+ "additionalProperties": false
+ }
+ },
+ "versions": {
+ "description": "List of blocked module version constraints.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "patternProperties": {
+ "^.*$": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "version": {
+ "description": "Version constraint.",
+ "type": "string"
+ },
+ "reason": {
+ "description": "Reason why the version constraint exists.",
+ "type": "string"
+ }
+ },
+ "required": ["reason"]
+ }
+ }
+ }
+ },
+ "local-replace-directives": {
+ "description": "Raise lint issues if loading local path with replace directive",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ }
+ }
+ },
+ "gosecSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "includes": {
+ "type": "array",
+ "description": "To select a subset of rules to run",
+ "examples": [["G401"]],
+ "items": {
+ "$ref": "#/definitions/gosec-rules"
+ }
+ },
+ "excludes": {
+ "type": "array",
+ "description": "To specify a set of rules to explicitly exclude",
+ "examples": [["G401"]],
+ "items": {
+ "$ref": "#/definitions/gosec-rules"
+ }
+ },
+ "severity": {
+ "description": "Filter out the issues with a lower severity than the given value",
+ "type": "string",
+ "enum": ["low", "medium", "high"],
+ "default": "low"
+ },
+ "confidence": {
+ "description": "Filter out the issues with a lower confidence than the given value",
+ "type": "string",
+ "enum": ["low", "medium", "high"],
+ "default": "low"
+ },
+ "config": {
+ "description": "To specify the configuration of rules",
+ "type": "object"
+ },
+ "concurrency": {
+ "description": "Concurrency value",
+ "type": "integer"
+ }
+ }
+ },
+ "gosmopolitanSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "allow-time-local": {
+ "description": "Allow and ignore `time.Local` usages.",
+ "type": "boolean",
+ "default": false
+ },
+ "escape-hatches": {
+ "description": "List of fully qualified names in the `full/pkg/path.name` form, to act as \"i18n escape hatches\".",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "watch-for-scripts": {
+ "description": "List of Unicode scripts to watch for any usage in string literals.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "govetSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "settings": {
+ "description": "Settings per analyzer. Map of analyzer name to specific settings.\nRun `go tool vet help` to find out more.",
+ "type": "object",
+ "propertyNames": {
+ "$ref": "#/definitions/govet-analyzers"
+ },
+ "patternProperties": {
+ "^.*$": {
+ "description": "Run `go tool vet help ` to see all settings.",
+ "type": "object"
+ }
+ }
+ },
+ "enable": {
+ "description": "Enable analyzers by name.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/govet-analyzers"
+ }
+ },
+ "disable": {
+ "description": "Disable analyzers by name.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/govet-analyzers"
+ }
+ },
+ "enable-all": {
+ "description": "Enable all analyzers.",
+ "type": "boolean",
+ "default": false
+ },
+ "disable-all": {
+ "description": "Disable all analyzers.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "grouperSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "const-require-single-const": {
+ "type": "boolean",
+ "default": false
+ },
+ "const-require-grouping": {
+ "type": "boolean",
+ "default": false
+ },
+ "import-require-single-import": {
+ "type": "boolean",
+ "default": false
+ },
+ "import-require-grouping": {
+ "type": "boolean",
+ "default": false
+ },
+ "type-require-single-type": {
+ "type": "boolean",
+ "default": false
+ },
+ "type-require-grouping": {
+ "type": "boolean",
+ "default": false
+ },
+ "var-require-single-var": {
+ "type": "boolean",
+ "default": false
+ },
+ "var-require-grouping": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "ifaceSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "enable": {
+ "description": "Enable analyzers by name.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/iface-analyzers"
+ }
+ },
+ "settings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "unused": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "exclude": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "importasSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "no-unaliased": {
+ "description": "Do not allow unaliased imports of aliased packages.",
+ "type": "boolean",
+ "default": false
+ },
+ "no-extra-aliases": {
+ "description": "Do not allow non-required aliases.",
+ "type": "boolean",
+ "default": false
+ },
+ "alias": {
+ "description": "List of aliases",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "pkg": {
+ "description": "Package path e.g. knative.dev/serving/pkg/apis/autoscaling/v1alpha1",
+ "type": "string"
+ },
+ "alias": {
+ "description": "Package alias e.g. autoscalingv1alpha1",
+ "type": "string"
+ }
+ },
+ "required": ["pkg", "alias"]
+ }
+ }
+ }
+ },
+ "inamedparamSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skip-single-param": {
+ "description": "Skips check for interface methods with only a single parameter.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "ineffassignSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-escaping-errors": {
+ "description": "Check escaping variables of type error, may cause false positives.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "iotamixingSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "report-individual": {
+ "description": "Whether to report individual consts rather than just the const block.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "ireturnSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "description": "Use either `reject` or `allow` properties for interfaces matching.",
+ "properties": {
+ "allow": {
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "enum": ["anon", "error", "empty", "stdlib"]
+ }
+ ]
+ }
+ },
+ "reject": {
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "enum": ["anon", "error", "empty", "stdlib"]
+ }
+ ]
+ }
+ }
+ },
+ "anyOf": [
+ {
+ "not": {
+ "properties": {
+ "allow": {
+ "const": "reject"
+ }
+ }
+ },
+ "required": ["allow"]
+ },
+ {
+ "required": ["reject"]
+ }
+ ]
+ },
+ "lllSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "tab-width": {
+ "description": "Width of \"\\t\" in spaces.",
+ "type": "integer",
+ "minimum": 0,
+ "default": 1
+ },
+ "line-length": {
+ "description": "Maximum allowed line length, lines longer will be reported.",
+ "type": "integer",
+ "minimum": 1,
+ "default": 120
+ }
+ }
+ },
+ "maintidxSettings": {
+ "description": "Maintainability index https://docs.microsoft.com/en-us/visualstudio/code-quality/code-metrics-maintainability-index-range-and-meaning?view=vs-2022",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "under": {
+ "description": "Minimum accatpable maintainability index level (see https://docs.microsoft.com/en-us/visualstudio/code-quality/code-metrics-maintainability-index-range-and-meaning?view=vs-2022)",
+ "type": "number",
+ "default": 20
+ }
+ }
+ },
+ "makezeroSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "always": {
+ "description": "Allow only slices initialized with a length of zero.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "loggercheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "kitlog": {
+ "description": "Allow check for the github.com/go-kit/log library.",
+ "type": "boolean",
+ "default": true
+ },
+ "klog": {
+ "description": "Allow check for the k8s.io/klog/v2 library.",
+ "type": "boolean",
+ "default": true
+ },
+ "logr": {
+ "description": "Allow check for the github.com/go-logr/logr library.",
+ "type": "boolean",
+ "default": true
+ },
+ "slog": {
+ "description": "Allow check for the log/slog library.",
+ "type": "boolean",
+ "default": true
+ },
+ "zap": {
+ "description": "Allow check for the \"sugar logger\" from go.uber.org/zap library.",
+ "type": "boolean",
+ "default": true
+ },
+ "require-string-key": {
+ "description": "Require all logging keys to be inlined constant strings.",
+ "type": "boolean",
+ "default": false
+ },
+ "no-printf-like": {
+ "description": "Require printf-like format specifier (%s, %d for example) not present.",
+ "type": "boolean",
+ "default": false
+ },
+ "rules": {
+ "description": "List of custom rules to check against, where each rule is a single logger pattern, useful for wrapped loggers.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "misspellSettings": {
+ "description": "Correct spellings using locale preferences for US or UK. Default is to use a neutral variety of English.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "locale": {
+ "enum": ["US", "UK"]
+ },
+ "ignore-rules": {
+ "description": "List of rules to ignore.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "mode": {
+ "description": "Mode of the analysis.",
+ "enum": ["restricted", "", "default"],
+ "default": ""
+ },
+ "extra-words": {
+ "description": "Extra word corrections.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "correction": {
+ "type": "string"
+ },
+ "typo": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "musttagSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "functions": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "tag": {
+ "type": "string"
+ },
+ "arg-pos": {
+ "type": "integer"
+ }
+ }
+ }
+ }
+ }
+ },
+ "nakedretSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-func-lines": {
+ "description": "Report if a function has more lines of code than this value and it has naked returns.",
+ "type": "integer",
+ "minimum": 0,
+ "default": 30
+ }
+ }
+ },
+ "nestifSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "min-complexity": {
+ "description": "Minimum complexity of \"if\" statements to report.",
+ "type": "integer",
+ "default": 5
+ }
+ }
+ },
+ "nilnilSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "only-two": {
+ "type": "boolean",
+ "description": "To check functions with only two return values.",
+ "default": true
+ },
+ "detect-opposite": {
+ "type": "boolean",
+ "description": "In addition, detect opposite situation (simultaneous return of non-nil error and valid value).",
+ "default": false
+ },
+ "checked-types": {
+ "type": "array",
+ "description": "List of return types to check.",
+ "items": {
+ "enum": ["chan", "func", "iface", "map", "ptr", "uintptr", "unsafeptr"]
+ },
+ "default": ["chan", "func", "iface", "map", "ptr", "uintptr", "unsafeptr"]
+ }
+ }
+ },
+ "nlreturnSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "block-size": {
+ "description": "set block size that is still ok",
+ "type": "number",
+ "default": 0,
+ "minimum": 0
+ }
+ }
+ },
+ "mndSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignored-files": {
+ "description": "List of file patterns to exclude from analysis.",
+ "examples": [["magic1_.*.go"]],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignored-functions": {
+ "description": "Comma-separated list of function patterns to exclude from the analysis.",
+ "examples": [["math.*", "http.StatusText", "make"]],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignored-numbers": {
+ "description": "List of numbers to exclude from analysis.",
+ "examples": [["1000", "1234_567_890", "3.14159264"]],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "checks": {
+ "description": "The list of enabled checks, see https://github.com/tommy-muehle/go-mnd/#checks for description.",
+ "type": "array",
+ "items": {
+ "enum": [
+ "argument",
+ "case",
+ "condition",
+ "operation",
+ "return",
+ "assign"
+ ]
+ }
+ }
+ }
+ },
+ "modernizeSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "disable": {
+ "description": "List of analyzers to disable.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/modernize-analyzers"
+ }
+ }
+ }
+ },
+ "nolintlintSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "allow-unused": {
+ "description": "Enable to ensure that nolint directives are all used.",
+ "type": "boolean",
+ "default": true
+ },
+ "allow-no-explanation": {
+ "description": "Exclude these linters from requiring an explanation.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linter-names"
+ },
+ "default": []
+ },
+ "require-explanation": {
+ "description": "Enable to require an explanation of nonzero length after each nolint directive.",
+ "type": "boolean",
+ "default": false
+ },
+ "require-specific": {
+ "description": "Enable to require nolint directives to mention the specific linter being suppressed.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "reassignSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "patterns": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "recvcheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "disable-builtin": {
+ "description": "Disables the built-in method exclusions.",
+ "type": "boolean",
+ "default": true
+ },
+ "exclusions": {
+ "description": "User-defined method exclusions.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "nonamedreturnsSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "report-error-in-defer": {
+ "description": "Report named error if it is assigned inside defer.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "paralleltestSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignore-missing": {
+ "description": "Ignore missing calls to `t.Parallel()` and only report incorrect uses of it.",
+ "type": "boolean",
+ "default": false
+ },
+ "ignore-missing-subtests": {
+ "description": "Ignore missing calls to `t.Parallel()` in subtests. Top-level tests are still required to have `t.Parallel`, but subtests are allowed to skip it.",
+ "type": "boolean",
+ "default": false
+ },
+ "check-cleanup": {
+ "description": "Check that defer is not used with t.Parallel (use t.Cleanup instead).",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "perfsprintSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "integer-format": {
+ "description": "Enable/disable optimization of integer formatting.",
+ "type": "boolean",
+ "default": true
+ },
+ "int-conversion": {
+ "description": "Optimizes even if it requires an int or uint type cast.",
+ "type": "boolean",
+ "default": true
+ },
+ "error-format": {
+ "description": "Enable/disable optimization of error formatting.",
+ "type": "boolean",
+ "default": true
+ },
+ "err-error": {
+ "description": "Optimizes into `err.Error()` even if it is only equivalent for non-nil errors.",
+ "type": "boolean",
+ "default": false
+ },
+ "errorf": {
+ "description": "Optimizes `fmt.Errorf`.",
+ "type": "boolean",
+ "default": true
+ },
+ "string-format": {
+ "description": "Enable/disable optimization of string formatting.",
+ "type": "boolean",
+ "default": true
+ },
+ "sprintf1": {
+ "description": "Optimizes `fmt.Sprintf` with only one argument.",
+ "type": "boolean",
+ "default": true
+ },
+ "strconcat": {
+ "description": "Optimizes into strings concatenation.",
+ "type": "boolean",
+ "default": true
+ },
+ "bool-format": {
+ "description": "Enable/disable optimization of bool formatting.",
+ "type": "boolean",
+ "default": true
+ },
+ "hex-format": {
+ "description": "Enable/disable optimization of hex formatting.",
+ "type": "boolean",
+ "default": true
+ },
+ "concat-loop": {
+ "description": "Enable/disable optimization of concat loop.",
+ "type": "boolean",
+ "default": true
+ },
+ "loop-other-ops": {
+ "description": "Optimization of `concat-loop` even with other operations.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "preallocSettings": {
+ "description": "We do not recommend using this linter before doing performance profiling.\nFor most programs usage of `prealloc` will be premature optimization.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "simple": {
+ "description": "Report preallocation suggestions only on simple loops that have no returns/breaks/continues/gotos in them.",
+ "type": "boolean",
+ "default": true
+ },
+ "range-loops": {
+ "description": "Report preallocation suggestions on range loops.",
+ "type": "boolean",
+ "default": true
+ },
+ "for-loops": {
+ "description": "Report preallocation suggestions on for loops.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "predeclaredSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignore": {
+ "description": "List of predeclared identifiers to not report on.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "qualified-name": {
+ "description": "Include method names and field names in checks.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "promlinterSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "strict": {},
+ "disabled-linters": {
+ "type": "array",
+ "items": {
+ "enum": [
+ "Help",
+ "MetricUnits",
+ "Counter",
+ "HistogramSummaryReserved",
+ "MetricTypeInName",
+ "ReservedChars",
+ "CamelCase",
+ "UnitAbbreviations"
+ ]
+ }
+ }
+ }
+ },
+ "protogetterSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skip-generated-by": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["protoc-gen-go-my-own-generator"]
+ }
+ },
+ "skip-files": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["*.pb.go"]
+ }
+ },
+ "skip-any-generated": {
+ "description": "Skip any generated files from the checking.",
+ "type": "boolean",
+ "default": false
+ },
+ "replace-first-arg-in-append": {
+ "description": "Skip first argument of append function.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "reviveSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "examples": [
+ {
+ "ignore-generated-header": true,
+ "severity": "warning",
+ "rules": [
+ {
+ "name": "indent-error-flow",
+ "severity": "warning"
+ },
+ {
+ "name": "add-constant",
+ "severity": "warning",
+ "arguments": [
+ {
+ "maxLitCount": "3",
+ "allowStrs": "\"\"",
+ "allowInts": "0,1,2",
+ "allowFloats": "0.0,0.,1.0,1.,2.0,2."
+ }
+ ]
+ }
+ ]
+ }
+ ],
+ "properties": {
+ "max-open-files": {
+ "type": "integer"
+ },
+ "confidence": {
+ "type": "number"
+ },
+ "severity": {
+ "type": "string",
+ "enum": ["warning", "error"]
+ },
+ "enable-all-rules": {
+ "type": "boolean",
+ "default": false
+ },
+ "enable-default-rules": {
+ "type": "boolean",
+ "default": false
+ },
+ "directives": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "name": {
+ "type": "string",
+ "enum": ["specify-disable-reason"]
+ },
+ "severity": {
+ "type": "string",
+ "enum": ["warning", "error"]
+ },
+ "exclude": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "arguments": {
+ "type": "array"
+ }
+ }
+ }
+ },
+ "rules": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["name"],
+ "properties": {
+ "name": {
+ "$ref": "#/definitions/revive-rules",
+ "title": "The rule name"
+ },
+ "disabled": {
+ "type": "boolean"
+ },
+ "severity": {
+ "type": "string",
+ "enum": ["warning", "error"]
+ },
+ "exclude": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "arguments": {
+ "type": "array"
+ }
+ }
+ }
+ }
+ }
+ },
+ "rowserrcheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "packages": {
+ "type": "array",
+ "items": {
+ "description": "",
+ "type": "string",
+ "examples": ["github.com/jmoiron/sqlx"]
+ }
+ }
+ }
+ },
+ "sloglintSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "no-global": {
+ "description": "Report the use of global loggers.",
+ "enum": ["", "all", "default"],
+ "default": ""
+ },
+ "context": {
+ "description": "Report the use of functions without a context.Context.",
+ "enum": ["", "all", "scope"],
+ "default": ""
+ },
+ "static-msg": {
+ "description": "Report dynamic log messages, such as those that are built with fmt.Sprintf.",
+ "type": "boolean",
+ "default": false
+ },
+ "msg-style": {
+ "description": "Report log messages that do not match a particular style.",
+ "enum": ["", "lowercased", "capitalized"],
+ "default": ""
+ },
+ "no-mixed-args": {
+ "description": "Report the use of both key-value pairs and attributes within a single function call.",
+ "type": "boolean",
+ "default": true
+ },
+ "kv-only": {
+ "description": "Report any use of attributes as function call arguments.",
+ "type": "boolean",
+ "default": false
+ },
+ "attr-only": {
+ "description": "Report any use of key-value pairs as function call arguments.",
+ "type": "boolean",
+ "default": false
+ },
+ "args-on-sep-lines": {
+ "description": "Report two or more arguments on the same line.",
+ "type": "boolean",
+ "default": false
+ },
+ "no-raw-keys": {
+ "description": "Report the use of string literals as log keys.",
+ "type": "boolean",
+ "default": false
+ },
+ "allowed-keys": {
+ "description": "Report the use of log keys that are not explicitly allowed.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "forbidden-keys": {
+ "description": "Report the use of forbidden log keys.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "key-naming-case": {
+ "description": "Report log keys that do not match a particular naming case.",
+ "enum": ["snake", "kebab", "camel", "pascal"]
+ },
+ "custom-funcs": {
+ "description": "Analyze custom functions in addition to the standard log/slog functions.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/settings/definitions/sloglintCustomFunc"
+ }
+ }
+ }
+ },
+ "sloglintCustomFunc": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "name": {
+ "description": "The full name of the function, including the package. If the function is a method, the receiver type must be wrapped in parentheses.",
+ "type": "string"
+ },
+ "msg-pos": {
+ "description": "The position of the \"msg string\" argument in the function signature, starting from 0. If there is no message in the function, a negative value must be passed.",
+ "type": "integer"
+ },
+ "args-pos": {
+ "description": "The position of the \"args ...any\" argument in the function signature, starting from 0. If there are no arguments in the function, a negative value must be passed.",
+ "type": "integer"
+ }
+ }
+ },
+ "spancheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "checks": {
+ "description": "Checks to enable.",
+ "type": "array",
+ "items": {
+ "enum": ["end", "record-error", "set-status"]
+ }
+ },
+ "ignore-check-signatures": {
+ "description": "A list of regexes for function signatures that silence `record-error` and `set-status` reports if found in the call path to a returned error.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "extra-start-span-signatures": {
+ "description": "A list of regexes for additional function signatures that create spans.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "staticcheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "checks": {
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "$ref": "#/definitions/staticcheck-checks"
+ },
+ {
+ "type": "string"
+ }
+ ]
+ }
+ },
+ "dot-import-whitelist": {
+ "description": "By default, ST1001 forbids all uses of dot imports in non-test packages. This setting allows setting a whitelist of import paths that can be dot-imported anywhere.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "http-status-code-whitelist": {
+ "description": "ST1013 recommends using constants from the net/http package instead of hard-coding numeric HTTP status codes. This setting specifies a list of numeric status codes that this check does not complain about.",
+ "default": ["200", "400", "404", "500"],
+ "type": "array",
+ "items": {
+ "enum": [
+ "100",
+ "101",
+ "102",
+ "103",
+ "200",
+ "201",
+ "202",
+ "203",
+ "204",
+ "205",
+ "206",
+ "207",
+ "208",
+ "226",
+ "300",
+ "301",
+ "302",
+ "303",
+ "304",
+ "305",
+ "306",
+ "307",
+ "308",
+ "400",
+ "401",
+ "402",
+ "403",
+ "404",
+ "405",
+ "406",
+ "407",
+ "408",
+ "409",
+ "410",
+ "411",
+ "412",
+ "413",
+ "414",
+ "415",
+ "416",
+ "417",
+ "418",
+ "421",
+ "422",
+ "423",
+ "424",
+ "425",
+ "426",
+ "428",
+ "429",
+ "431",
+ "451",
+ "500",
+ "501",
+ "502",
+ "503",
+ "504",
+ "505",
+ "506",
+ "507",
+ "508",
+ "510",
+ "511"
+ ]
+ }
+ },
+ "initialisms": {
+ "description": "ST1003 check, among other things, for the correct capitalization of initialisms. The set of known initialisms can be configured with this option.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "default": [
+ "ACL",
+ "API",
+ "ASCII",
+ "CPU",
+ "CSS",
+ "DNS",
+ "EOF",
+ "GUID",
+ "HTML",
+ "HTTP",
+ "HTTPS",
+ "ID",
+ "IP",
+ "JSON",
+ "QPS",
+ "RAM",
+ "RPC",
+ "SLA",
+ "SMTP",
+ "SQL",
+ "SSH",
+ "TCP",
+ "TLS",
+ "TTL",
+ "UDP",
+ "UI",
+ "GID",
+ "UID",
+ "UUID",
+ "URI",
+ "URL",
+ "UTF8",
+ "VM",
+ "XML",
+ "XMPP",
+ "XSRF",
+ "XSS",
+ "SIP",
+ "RTP",
+ "AMQP",
+ "DB",
+ "TS"
+ ]
+ }
+ }
+ }
+ },
+ "tagalignSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "align": {
+ "description": "Align and sort can be used together or separately.",
+ "type": "boolean",
+ "default": true
+ },
+ "sort": {
+ "description": "Whether enable tags sort.",
+ "type": "boolean",
+ "default": true
+ },
+ "order": {
+ "description": "Specify the order of tags, the other tags will be sorted by name.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "default": [],
+ "examples": [
+ [
+ "json",
+ "yaml",
+ "yml",
+ "toml",
+ "mapstructure",
+ "binding",
+ "validate"
+ ]
+ ]
+ },
+ "strict": {
+ "description": "Whether enable strict style.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "tagliatelleSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "case": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "use-field-name": {
+ "description": "Use the struct field name to check the name of the struct tag.",
+ "type": "boolean",
+ "default": false
+ },
+ "ignored-fields": {
+ "description": "The field names to ignore.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["example"]
+ }
+ },
+ "rules": {
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "$ref": "#/definitions/tagliatelle-cases"
+ }
+ }
+ },
+ "extended-rules": {
+ "description": "Defines the association between tag name and case.",
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["case"],
+ "properties": {
+ "case": {
+ "$ref": "#/definitions/tagliatelle-cases"
+ },
+ "extra-initialisms": {
+ "type": "boolean",
+ "default": false
+ },
+ "initialism-overrides": {
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "overrides": {
+ "description": "Overrides the default/root configuration.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["pkg"],
+ "properties": {
+ "pkg": {
+ "description": "A package path.",
+ "type": "string"
+ },
+ "use-field-name": {
+ "description": "Use the struct field name to check the name of the struct tag.",
+ "type": "boolean",
+ "default": false
+ },
+ "ignored-fields": {
+ "description": "The field names to ignore.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["example"]
+ }
+ },
+ "ignore": {
+ "description": "Ignore the package (takes precedence over all other configurations).",
+ "type": "boolean",
+ "default": false
+ },
+ "rules": {
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "$ref": "#/definitions/tagliatelle-cases"
+ }
+ }
+ },
+ "extended-rules": {
+ "description": "Defines the association between tag name and case.",
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["case"],
+ "properties": {
+ "case": {
+ "$ref": "#/definitions/tagliatelle-cases"
+ },
+ "extra-initialisms": {
+ "type": "boolean",
+ "default": false
+ },
+ "initialism-overrides": {
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "testifylintSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "enable-all": {
+ "description": "Enable all checkers.",
+ "type": "boolean",
+ "default": false
+ },
+ "disable-all": {
+ "description": "Disable all checkers.",
+ "type": "boolean",
+ "default": false
+ },
+ "enable": {
+ "description": "Enable specific checkers.",
+ "type": "array",
+ "items": {
+ "enum": [
+ "blank-import",
+ "bool-compare",
+ "compares",
+ "contains",
+ "empty",
+ "encoded-compare",
+ "equal-values",
+ "error-is-as",
+ "error-nil",
+ "expected-actual",
+ "float-compare",
+ "formatter",
+ "go-require",
+ "len",
+ "negative-positive",
+ "nil-compare",
+ "regexp",
+ "require-error",
+ "suite-broken-parallel",
+ "suite-dont-use-pkg",
+ "suite-extra-assert-call",
+ "suite-method-signature",
+ "suite-subtest-run",
+ "suite-thelper",
+ "useless-assert"
+ ]
+ },
+ "default": [
+ "blank-import",
+ "bool-compare",
+ "compares",
+ "contains",
+ "empty",
+ "encoded-compare",
+ "equal-values",
+ "error-is-as",
+ "error-nil",
+ "expected-actual",
+ "float-compare",
+ "formatter",
+ "go-require",
+ "len",
+ "negative-positive",
+ "nil-compare",
+ "regexp",
+ "require-error",
+ "suite-broken-parallel",
+ "suite-dont-use-pkg",
+ "suite-extra-assert-call",
+ "suite-method-signature",
+ "suite-subtest-run",
+ "useless-assert"
+ ]
+ },
+ "disable": {
+ "description": "Disable specific checkers.",
+ "type": "array",
+ "items": {
+ "enum": [
+ "blank-import",
+ "bool-compare",
+ "compares",
+ "contains",
+ "empty",
+ "encoded-compare",
+ "equal-values",
+ "error-is-as",
+ "error-nil",
+ "expected-actual",
+ "float-compare",
+ "formatter",
+ "go-require",
+ "len",
+ "negative-positive",
+ "nil-compare",
+ "regexp",
+ "require-error",
+ "suite-broken-parallel",
+ "suite-dont-use-pkg",
+ "suite-extra-assert-call",
+ "suite-method-signature",
+ "suite-subtest-run",
+ "suite-thelper",
+ "useless-assert"
+ ],
+ "default": [
+ "suite-thelper"
+ ]
+ }
+ },
+ "bool-compare": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignore-custom-types": {
+ "description": "To ignore user defined types (over builtin bool).",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "expected-actual": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "pattern": {
+ "description": "Regexp for expected variable name.",
+ "type": "string",
+ "default": "(^(exp(ected)?|want(ed)?)([A-Z]\\w*)?$)|(^(\\w*[a-z])?(Exp(ected)?|Want(ed)?)$)"
+ }
+ }
+ },
+ "formatter": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-format-string": {
+ "description": "To enable go vet's printf checks.",
+ "type": "boolean",
+ "default": true
+ },
+ "require-f-funcs": {
+ "description": "To require f-assertions (e.g. assert.Equalf) if format string is used, even if there are no variable-length variables.",
+ "type": "boolean",
+ "default": false
+ },
+ "require-string-msg": {
+ "description": "To require that the first element of msgAndArgs (msg) has a string type.",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "go-require": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignore-http-handlers": {
+ "description": "To ignore HTTP handlers (like http.HandlerFunc).",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "require-error": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "fn-pattern": {
+ "description": "Regexp for assertions to analyze. If defined, then only matched error assertions will be reported.",
+ "type": "string",
+ "default": ""
+ }
+ }
+ },
+ "suite-extra-assert-call": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "mode": {
+ "description": "To require or remove extra Assert() call?",
+ "type": "string",
+ "enum": ["remove", "require"],
+ "default": "remove"
+ }
+ }
+ }
+ }
+ },
+ "testpackageSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skip-regexp": {
+ "description": "Files with names matching this regular expression are skipped.",
+ "type": "string",
+ "examples": ["(export|internal)_test\\.go"]
+ },
+ "allow-packages": {
+ "description": "List of packages that don't end with _test that tests are allowed to be in.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["example"]
+ }
+ }
+ }
+ },
+ "thelperSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "test": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "begin": {
+ "description": "Check if `t.Helper()` begins helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "first": {
+ "description": "Check if *testing.T is first param of helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "name": {
+ "description": "Check if *testing.T param has t name.",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ },
+ "benchmark": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "begin": {
+ "description": "Check if `b.Helper()` begins helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "first": {
+ "description": "Check if *testing.B is first param of helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "name": {
+ "description": "Check if *testing.B param has b name.",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ },
+ "tb": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "begin": {
+ "description": "Check if `tb.Helper()` begins helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "first": {
+ "description": "Check if *testing.TB is first param of helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "name": {
+ "description": "Check if *testing.TB param has tb name.",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ },
+ "fuzz": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "begin": {
+ "description": "Check if `f.Helper()` begins helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "first": {
+ "description": "Check if *testing.F is first param of helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "name": {
+ "description": "Check if *testing.F param has f name.",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ }
+ }
+ },
+ "usestdlibvarsSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "http-method": {
+ "description": "Suggest the use of http.MethodXX.",
+ "type": "boolean",
+ "default": true
+ },
+ "http-status-code": {
+ "description": "Suggest the use of http.StatusXX.",
+ "type": "boolean",
+ "default": true
+ },
+ "time-weekday": {
+ "description": "Suggest the use of time.Weekday.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "time-month": {
+ "description": "Suggest the use of time.Month.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "time-layout": {
+ "description": "Suggest the use of time.Layout.",
+ "type": "boolean",
+ "default": false
+ },
+ "time-date-month": {
+ "description": "Suggest the use of time.Month in time.Date.",
+ "type": "boolean",
+ "default": false
+ },
+ "crypto-hash": {
+ "description": "Suggest the use of crypto.Hash.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "default-rpc-path": {
+ "description": "Suggest the use of rpc.DefaultXXPath.",
+ "type": "boolean",
+ "default": false
+ },
+ "sql-isolation-level": {
+ "description": "Suggest the use of sql.LevelXX.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "tls-signature-scheme": {
+ "description": "Suggest the use of tls.SignatureScheme.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "constant-kind": {
+ "description": "Suggest the use of constant.Kind.String().",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "usetestingSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "context-background": {
+ "type": "boolean",
+ "default": false
+ },
+ "context-todo": {
+ "type": "boolean",
+ "default": false
+ },
+ "os-chdir": {
+ "type": "boolean",
+ "default": true
+ },
+ "os-mkdir-temp": {
+ "type": "boolean",
+ "default": true
+ },
+ "os-setenv": {
+ "type": "boolean",
+ "default": true
+ },
+ "os-create-temp": {
+ "type": "boolean",
+ "default": true
+ },
+ "os-temp-dir": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "unconvertSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "fast-math": {
+ "type": "boolean",
+ "default": false
+ },
+ "safe": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "unparamSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-exported": {
+ "description": "Inspect exported functions. Set to true if no external program/library imports your code.\n\nWARNING: if you enable this setting, unparam will report a lot of false-positives in text editors:\nif it's called for subdir of a project it can't find external interfaces. All text editor integrations\nwith golangci-lint call it on a directory with the changed file.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "unqueryvetSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-sql-builders": {
+ "description": "Enable SQL builder checking.",
+ "type": "boolean",
+ "default": true
+ },
+ "check-aliased-wildcard": {
+ "description": "Enable aliased wildcard detection like SELECT t.*.",
+ "type": "boolean",
+ "default": true
+ },
+ "check-string-concat": {
+ "description": "Enable string concatenation analysis.",
+ "type": "boolean",
+ "default": true
+ },
+ "check-format-strings": {
+ "description": "Enable format string analysis like fmt.Sprintf.",
+ "type": "boolean",
+ "default": true
+ },
+ "check-string-builder": {
+ "description": "Enable strings.Builder analysis.",
+ "type": "boolean",
+ "default": true
+ },
+ "check-subqueries": {
+ "description": "Enable subquery analysis.",
+ "type": "boolean",
+ "default": true
+ },
+ "check-n1": {
+ "type": "boolean",
+ "default": false
+ },
+ "check-sql-injection": {
+ "type": "boolean",
+ "default": false
+ },
+ "check-tx-leaks": {
+ "type": "boolean",
+ "default": false
+ },
+ "allowed-patterns": {
+ "description": "Regex patterns for acceptable SELECT * usage.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "allow": {
+ "description": "Allow is a list of SQL patterns to allow (whitelist).",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignored-functions": {
+ "description": "Functions to ignore.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "sql-builders": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "squirrel": {
+ "type": "boolean",
+ "default": true
+ },
+ "gorm": {
+ "type": "boolean",
+ "default": true
+ },
+ "sqlx": {
+ "type": "boolean",
+ "default": true
+ },
+ "ent": {
+ "type": "boolean",
+ "default": true
+ },
+ "pgx": {
+ "type": "boolean",
+ "default": true
+ },
+ "bun": {
+ "type": "boolean",
+ "default": true
+ },
+ "sqlboiler": {
+ "type": "boolean",
+ "default": true
+ },
+ "jet": {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "custom-rules": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "id": {
+ "type": "string"
+ },
+ "pattern": {
+ "type": "string"
+ },
+ "patterns": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "when": {
+ "type": "string"
+ },
+ "message": {
+ "type": "string"
+ },
+ "action": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "unusedSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "field-writes-are-uses": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ },
+ "post-statements-are-reads": {
+ "description": "",
+ "type": "boolean",
+ "default": false
+ },
+ "exported-fields-are-used": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ },
+ "parameters-are-used": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ },
+ "local-variables-are-used": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ },
+ "generated-is-used": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "varnamelenSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-distance": {
+ "description": "Variables used in at most this N-many lines will be ignored.",
+ "type": "integer",
+ "default": 5
+ },
+ "min-name-length": {
+ "description": "The minimum length of a variable's name that is considered `long`.",
+ "type": "integer",
+ "default": 3
+ },
+ "check-receiver": {
+ "description": "Check method receiver names.",
+ "default": false,
+ "type": "boolean"
+ },
+ "check-return": {
+ "description": "Check named return values.",
+ "default": false,
+ "type": "boolean"
+ },
+ "check-type-param": {
+ "description": "Check type parameters.",
+ "default": false,
+ "type": "boolean"
+ },
+ "ignore-type-assert-ok": {
+ "description": "Ignore `ok` variables that hold the bool return value of a type assertion",
+ "default": false,
+ "type": "boolean"
+ },
+ "ignore-map-index-ok": {
+ "description": "Ignore `ok` variables that hold the bool return value of a map index.",
+ "default": false,
+ "type": "boolean"
+ },
+ "ignore-chan-recv-ok": {
+ "description": "Ignore `ok` variables that hold the bool return value of a channel receive.",
+ "default": false,
+ "type": "boolean"
+ },
+ "ignore-names": {
+ "description": "Optional list of variable names that should be ignored completely.",
+ "default": [[]],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignore-decls": {
+ "description": "Optional list of variable declarations that should be ignored completely.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "examples": [
+ ["c echo.Context", "t testing.T", "f *foo.Bar", "const C"]
+ ]
+ }
+ }
+ },
+ "whitespaceSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "multi-if": {
+ "description": "Enforces newlines (or comments) after every multi-line if statement",
+ "type": "boolean",
+ "default": false
+ },
+ "multi-func": {
+ "description": "Enforces newlines (or comments) after every multi-line function signature",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "wrapcheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "extra-ignore-sigs": {
+ "description": "An array of strings specifying additional substrings of signatures to ignore.",
+ "default": [
+ ".CustomError(",
+ ".SpecificWrap("
+ ],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignore-sigs": {
+ "description": "An array of strings which specify substrings of signatures to ignore.",
+ "default": [
+ ".Errorf(",
+ "errors.New(",
+ "errors.Unwrap(",
+ ".Wrap(",
+ ".Wrapf(",
+ ".WithMessage(",
+ ".WithMessagef(",
+ ".WithStack("
+ ],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignore-sig-regexps": {
+ "description": "An array of strings which specify regular expressions of signatures to ignore.",
+ "default": [""],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignore-package-globs": {
+ "description": "An array of glob patterns which, if any match the package of the function returning the error, will skip wrapcheck analysis for this error.",
+ "default": [""],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignore-interface-regexps": {
+ "description": "An array of glob patterns which, if matched to an underlying interface name, will ignore unwrapped errors returned from a function whose call is defined on the given interface.",
+ "default": [""],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "report-internal-errors": {
+ "description": "Determines whether wrapcheck should report errors returned from inside the package.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "wslSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "allow-assign-and-anything": {
+ "description": "Controls if you may cuddle assignments and anything without needing an empty line between them.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-assign-and-call": {
+ "description": "Allow calls and assignments to be cuddled as long as the lines have any matching variables, fields or types.",
+ "type": "boolean",
+ "default": true
+ },
+ "allow-cuddle-declarations": {
+ "description": "Allow declarations (var) to be cuddled.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-cuddle-with-calls": {
+ "description": "A list of call idents that everything can be cuddled with.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "allow-cuddle-with-rhs": {
+ "description": "AllowCuddleWithRHS is a list of right hand side variables that is allowed to be cuddled with anything.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "allow-cuddle-used-in-block": {
+ "description": "Allow cuddling with any block as long as the variable is used somewhere in the block",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-multiline-assign": {
+ "description": "Allow multiline assignments to be cuddled.",
+ "type": "boolean",
+ "default": true
+ },
+ "allow-separated-leading-comment": {
+ "description": "Allow leading comments to be separated with empty lines.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-trailing-comment": {
+ "description": "Allow trailing comments in ending of blocks.",
+ "type": "boolean",
+ "default": false
+ },
+ "error-variable-names": {
+ "description": "When force-err-cuddling is enabled this is a list of names used for error variables to check for in the conditional.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "force-case-trailing-whitespace": {
+ "description": "Force newlines in end of case at this limit (0 = never).",
+ "type": "integer",
+ "minimum": 0,
+ "default": 0
+ },
+ "force-err-cuddling": {
+ "description": "Causes an error when an If statement that checks an error variable doesn't cuddle with the assignment of that variable.",
+ "type": "boolean",
+ "default": false
+ },
+ "force-short-decl-cuddling": {
+ "description": "Causes an error if a short declaration (:=) cuddles with anything other than another short declaration.",
+ "type": "boolean",
+ "default": false
+ },
+ "strict-append": {
+ "description": "If true, append is only allowed to be cuddled if appending value is matching variables, fields or types on line above.",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "wslSettingsV5": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "allow-first-in-block": {
+ "type": "boolean",
+ "default": true
+ },
+ "allow-whole-block": {
+ "type": "boolean",
+ "default": false
+ },
+ "branch-max-lines": {
+ "type": "integer",
+ "default": 2
+ },
+ "case-max-lines": {
+ "type": "integer",
+ "default": 0
+ },
+ "cuddle-max-statements": {
+ "type": "integer",
+ "default": 1
+ },
+ "default": {
+ "enum": ["all", "none", "default", ""],
+ "default": "default"
+ },
+ "enable": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/wsl-checks"
+ }
+ },
+ "disable": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/wsl-checks"
+ }
+ }
+ }
+ },
+ "copyloopvarSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-alias": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "customSettings": {
+ "description": "The custom section can be used to define linter plugins to be loaded at runtime. See README of golangci-lint for more information.\nEach custom linter should have a unique name.",
+ "type": "object",
+ "patternProperties": {
+ "^.*$": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "type": {
+ "description": "The plugin type.",
+ "enum": ["module", "goplugin"],
+ "default": "goplugin"
+ },
+ "path": {
+ "description": "The path to the plugin *.so. Can be absolute or local.",
+ "type": "string",
+ "examples": ["/path/to/example.so"]
+ },
+ "description": {
+ "description": "The description of the linter, for documentation purposes only.",
+ "type": "string"
+ },
+ "original-url": {
+ "description": "Intended to point to the repo location of the linter, for documentation purposes only.",
+ "type": "string"
+ },
+ "settings": {
+ "description": "Plugins settings/configuration. Only work with plugin based on `linterdb.PluginConstructor`.",
+ "type": "object"
+ }
+ },
+ "oneOf": [
+ {
+ "properties": {
+ "type": {"enum": ["module"] }
+ },
+ "required": ["type"]
+ },
+ {
+ "required": ["path"]
+ }
+ ]
+ }
+ }
+ }
+ }
+ }
+ },
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["version"],
+ "properties": {
+ "version": {
+ "type": "string",
+ "default": "2"
+ },
+ "run": {
+ "description": "Options for analysis running,",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "concurrency": {
+ "description": "Number of concurrent runners. Defaults to the number of available CPU cores.",
+ "type": "integer",
+ "minimum": 0,
+ "examples": [4]
+ },
+ "timeout": {
+ "description": "Timeout for the analysis.",
+ "type": "string",
+ "pattern": "^((\\d+h)?(\\d+m)?(\\d+(?:\\.\\d)?s)?|0)$",
+ "default": "1m",
+ "examples": ["30s", "5m", "5m30s"]
+ },
+ "issues-exit-code": {
+ "description": "Exit code when at least one issue was found.",
+ "type": "integer",
+ "default": 1
+ },
+ "tests": {
+ "description": "Enable inclusion of test files.",
+ "type": "boolean",
+ "default": true
+ },
+ "build-tags": {
+ "description": "List of build tags to pass to all linters.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "default": [],
+ "examples": [["mytag"]]
+ },
+ "modules-download-mode": {
+ "description": "Option to pass to \"go list -mod={option}\".\nSee \"go help modules\" for more information.",
+ "enum": ["mod", "readonly", "vendor"]
+ },
+ "enable-build-vcs": {
+ "type": "boolean",
+ "default": false
+ },
+ "allow-parallel-runners": {
+ "description": "Allow multiple parallel golangci-lint instances running. If disabled, golangci-lint acquires file lock on start.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-serial-runners": {
+ "description": "Allow multiple golangci-lint instances running, but serialize them around a lock.",
+ "type": "boolean",
+ "default": false
+ },
+ "go": {
+ "description": "Targeted Go version.",
+ "type": "string",
+ "default": "1.17"
+ },
+ "relative-path-mode": {
+ "description": "The mode used to evaluate relative paths.",
+ "type": "string",
+ "$ref": "#/definitions/relative-path-modes",
+ "default": "wd"
+ }
+ }
+ },
+ "output": {
+ "description": "Output configuration options.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "formats": {
+ "description": "Output formats to use.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "text": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "path": {
+ "$ref": "#/definitions/formats-path",
+ "default": "stdout"
+ },
+ "print-linter-name": {
+ "type": "boolean",
+ "default": true
+ },
+ "print-issued-lines": {
+ "type": "boolean",
+ "default": true
+ },
+ "colors": {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "json": {
+ "$ref": "#/definitions/simple-format"
+ },
+ "tab": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "path": {
+ "$ref": "#/definitions/formats-path",
+ "default": "stdout"
+ },
+ "print-linter-name": {
+ "type": "boolean",
+ "default": true
+ },
+ "colors": {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "html": {
+ "$ref": "#/definitions/simple-format"
+ },
+ "checkstyle": {
+ "$ref": "#/definitions/simple-format"
+ },
+ "code-climate": {
+ "$ref": "#/definitions/simple-format"
+ },
+ "junit-xml": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "path": {
+ "$ref": "#/definitions/formats-path",
+ "default": "stdout"
+ },
+ "extended": {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "teamcity": {
+ "$ref": "#/definitions/simple-format"
+ },
+ "sarif": {
+ "$ref": "#/definitions/simple-format"
+ }
+ }
+ },
+ "path-mode": {
+ "type": "string",
+ "default": "",
+ "examples": ["abs"]
+ },
+ "path-prefix": {
+ "description": "Add a prefix to the output file references.",
+ "type": "string",
+ "default": ""
+ },
+ "show-stats": {
+ "description": "Show statistics per linter.",
+ "type": "boolean",
+ "default": true
+ },
+ "sort-order": {
+ "type": "array",
+ "items": {
+ "enum": ["linter", "severity", "file"]
+ }
+ }
+ }
+ },
+ "linters": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "default": {
+ "enum": [
+ "standard",
+ "all",
+ "none",
+ "fast"
+ ]
+ },
+ "enable": {
+ "description": "List of enabled linters.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linter-names"
+ }
+ },
+ "disable": {
+ "description": "List of disabled linters.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linter-names"
+ }
+ },
+ "settings": {
+ "description": "All available settings of specific linters.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "dupword": {
+ "$ref": "#/definitions/settings/definitions/dupwordSettings"
+ },
+ "asasalint": {
+ "$ref": "#/definitions/settings/definitions/asasalintSettings"
+ },
+ "bidichk": {
+ "$ref": "#/definitions/settings/definitions/bidichkSettings"
+ },
+ "bodyclose": {
+ "$ref": "#/definitions/settings/definitions/bodycloseSettings"
+ },
+ "cyclop": {
+ "$ref": "#/definitions/settings/definitions/cyclopSettings"
+ },
+ "decorder": {
+ "$ref": "#/definitions/settings/definitions/decorderSettings"
+ },
+ "depguard":{
+ "$ref": "#/definitions/settings/definitions/depguardSettings"
+ },
+ "dogsled": {
+ "$ref": "#/definitions/settings/definitions/dogsledSettings"
+ },
+ "dupl": {
+ "$ref": "#/definitions/settings/definitions/duplSettings"
+ },
+ "embeddedstructfieldcheck": {
+ "$ref": "#/definitions/settings/definitions/embeddedstructfieldcheckSettings"
+ },
+ "errcheck": {
+ "$ref": "#/definitions/settings/definitions/errcheckSettings"
+ },
+ "errchkjson": {
+ "$ref": "#/definitions/settings/definitions/errchkjsonSettings"
+ },
+ "errorlint": {
+ "$ref": "#/definitions/settings/definitions/errorlintSettings"
+ },
+ "exhaustive": {
+ "$ref": "#/definitions/settings/definitions/exhaustiveSettings"
+ },
+ "exhaustruct": {
+ "$ref": "#/definitions/settings/definitions/exhaustructSettings"
+ },
+ "fatcontext": {
+ "$ref": "#/definitions/settings/definitions/fatcontextSettings"
+ },
+ "forbidigo": {
+ "$ref": "#/definitions/settings/definitions/forbidigoSettings"
+ },
+ "funcorder": {
+ "$ref": "#/definitions/settings/definitions/funcorderSettings"
+ },
+ "funlen": {
+ "$ref": "#/definitions/settings/definitions/funlenSettings"
+ },
+ "ginkgolinter": {
+ "$ref": "#/definitions/settings/definitions/ginkgolinterSettings"
+ },
+ "gochecksumtype": {
+ "$ref": "#/definitions/settings/definitions/gochecksumtypeSettings"
+ },
+ "gocognit": {
+ "$ref": "#/definitions/settings/definitions/gocognitSettings"
+ },
+ "goconst": {
+ "$ref": "#/definitions/settings/definitions/goconstSettings"
+ },
+ "gocritic": {
+ "$ref": "#/definitions/settings/definitions/gocriticSettings"
+ },
+ "gocyclo": {
+ "$ref": "#/definitions/settings/definitions/gocycloSettings"
+ },
+ "godoclint": {
+ "$ref": "#/definitions/settings/definitions/godoclintSettings"
+ },
+ "godot": {
+ "$ref": "#/definitions/settings/definitions/godotSettings"
+ },
+ "godox": {
+ "$ref": "#/definitions/settings/definitions/godoxSettings"
+ },
+ "interfacebloat":{
+ "$ref": "#/definitions/settings/definitions/interfacebloatSettings"
+ },
+ "goheader": {
+ "$ref": "#/definitions/settings/definitions/goheaderSettings"
+ },
+ "gomoddirectives": {
+ "$ref": "#/definitions/settings/definitions/gomoddirectivesSettings"
+ },
+ "gomodguard": {
+ "$ref": "#/definitions/settings/definitions/gomodguardSettings"
+ },
+ "gomodguard_v2": {
+ "$ref": "#/definitions/settings/definitions/gomodguardv2Settings"
+ },
+ "gosec": {
+ "$ref": "#/definitions/settings/definitions/gosecSettings"
+ },
+ "gosmopolitan": {
+ "$ref": "#/definitions/settings/definitions/gosmopolitanSettings"
+ },
+ "govet": {
+ "$ref": "#/definitions/settings/definitions/govetSettings"
+ },
+ "grouper": {
+ "$ref": "#/definitions/settings/definitions/grouperSettings"
+ },
+ "iface": {
+ "$ref": "#/definitions/settings/definitions/ifaceSettings"
+ },
+ "importas": {
+ "$ref": "#/definitions/settings/definitions/importasSettings"
+ },
+ "inamedparam": {
+ "$ref": "#/definitions/settings/definitions/inamedparamSettings"
+ },
+ "ineffassign": {
+ "$ref": "#/definitions/settings/definitions/ineffassignSettings"
+ },
+ "iotamixing": {
+ "$ref": "#/definitions/settings/definitions/iotamixingSettings"
+ },
+ "ireturn": {
+ "$ref": "#/definitions/settings/definitions/ireturnSettings"
+ },
+ "lll": {
+ "$ref": "#/definitions/settings/definitions/lllSettings"
+ },
+ "maintidx": {
+ "$ref": "#/definitions/settings/definitions/maintidxSettings"
+ },
+ "makezero":{
+ "$ref": "#/definitions/settings/definitions/makezeroSettings"
+ },
+ "loggercheck": {
+ "$ref": "#/definitions/settings/definitions/loggercheckSettings"
+ },
+ "misspell": {
+ "$ref": "#/definitions/settings/definitions/misspellSettings"
+ },
+ "musttag": {
+ "$ref": "#/definitions/settings/definitions/musttagSettings"
+ },
+ "nakedret": {
+ "$ref": "#/definitions/settings/definitions/nakedretSettings"
+ },
+ "nestif": {
+ "$ref": "#/definitions/settings/definitions/nestifSettings"
+ },
+ "nilnil": {
+ "$ref": "#/definitions/settings/definitions/nilnilSettings"
+ },
+ "nlreturn": {
+ "$ref": "#/definitions/settings/definitions/nlreturnSettings"
+ },
+ "mnd": {
+ "$ref": "#/definitions/settings/definitions/mndSettings"
+ },
+ "modernize": {
+ "$ref": "#/definitions/settings/definitions/modernizeSettings"
+ },
+ "nolintlint":{
+ "$ref": "#/definitions/settings/definitions/nolintlintSettings"
+ },
+ "reassign": {
+ "$ref": "#/definitions/settings/definitions/reassignSettings"
+ },
+ "recvcheck": {
+ "$ref": "#/definitions/settings/definitions/recvcheckSettings"
+ },
+ "nonamedreturns": {
+ "$ref": "#/definitions/settings/definitions/nonamedreturnsSettings"
+ },
+ "paralleltest": {
+ "$ref": "#/definitions/settings/definitions/paralleltestSettings"
+ },
+ "perfsprint": {
+ "$ref": "#/definitions/settings/definitions/perfsprintSettings"
+ },
+ "prealloc": {
+ "$ref": "#/definitions/settings/definitions/preallocSettings"
+ },
+ "predeclared": {
+ "$ref": "#/definitions/settings/definitions/predeclaredSettings"
+ },
+ "promlinter": {
+ "$ref": "#/definitions/settings/definitions/promlinterSettings"
+ },
+ "protogetter": {
+ "$ref": "#/definitions/settings/definitions/protogetterSettings"
+ },
+ "revive": {
+ "$ref": "#/definitions/settings/definitions/reviveSettings"
+ },
+ "rowserrcheck": {
+ "$ref": "#/definitions/settings/definitions/rowserrcheckSettings"
+ },
+ "sloglint": {
+ "$ref": "#/definitions/settings/definitions/sloglintSettings"
+ },
+ "spancheck": {
+ "$ref": "#/definitions/settings/definitions/spancheckSettings"
+ },
+ "staticcheck":{
+ "$ref": "#/definitions/settings/definitions/staticcheckSettings"
+ },
+ "tagalign": {
+ "$ref": "#/definitions/settings/definitions/tagalignSettings"
+ },
+ "tagliatelle": {
+ "$ref": "#/definitions/settings/definitions/tagliatelleSettings"
+ },
+ "testifylint": {
+ "$ref": "#/definitions/settings/definitions/testifylintSettings"
+ },
+ "testpackage": {
+ "$ref": "#/definitions/settings/definitions/testpackageSettings"
+ },
+ "thelper": {
+ "$ref": "#/definitions/settings/definitions/thelperSettings"
+ },
+ "usestdlibvars": {
+ "$ref": "#/definitions/settings/definitions/usestdlibvarsSettings"
+ },
+ "usetesting": {
+ "$ref": "#/definitions/settings/definitions/usetestingSettings"
+ },
+ "unconvert": {
+ "$ref": "#/definitions/settings/definitions/unconvertSettings"
+ },
+ "unparam": {
+ "$ref": "#/definitions/settings/definitions/unparamSettings"
+ },
+ "unqueryvet": {
+ "$ref": "#/definitions/settings/definitions/unqueryvetSettings"
+ },
+ "unused": {
+ "$ref": "#/definitions/settings/definitions/unusedSettings"
+ },
+ "varnamelen": {
+ "$ref": "#/definitions/settings/definitions/varnamelenSettings"
+ },
+ "whitespace": {
+ "$ref": "#/definitions/settings/definitions/whitespaceSettings"
+ },
+ "wrapcheck": {
+ "$ref": "#/definitions/settings/definitions/wrapcheckSettings"
+ },
+ "wsl": {
+ "$ref": "#/definitions/settings/definitions/wslSettings"
+ },
+ "wsl_v5": {
+ "$ref": "#/definitions/settings/definitions/wslSettingsV5"
+ },
+ "copyloopvar": {
+ "$ref": "#/definitions/settings/definitions/copyloopvarSettings"
+ },
+ "custom":{
+ "$ref": "#/definitions/settings/definitions/customSettings"
+ }
+ }
+ },
+ "exclusions":{
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "generated": {
+ "enum": ["strict", "lax", "disable"],
+ "default": "strict"
+ },
+ "warn-unused": {
+ "type": "boolean",
+ "default": false
+ },
+ "presets": {
+ "type": "array",
+ "items": {
+ "enum": [
+ "comments",
+ "std-error-handling",
+ "common-false-positives",
+ "legacy"
+ ]
+ }
+ },
+ "rules": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "path": {
+ "type": "string"
+ },
+ "path-except": {
+ "type": "string"
+ },
+ "linters": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linter-names"
+ }
+ },
+ "text": {
+ "type": "string"
+ },
+ "source": {
+ "type": "string"
+ }
+ },
+ "anyOf": [
+ { "required": ["path"] },
+ { "required": ["path-except"] },
+ { "required": ["linters"] },
+ { "required": ["text"] },
+ { "required": ["source"] }
+ ]
+ }
+ },
+ "paths": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "paths-except": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "formatters": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "enable": {
+ "description": "List of enabled formatters.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/formatter-names"
+ }
+ },
+ "settings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "gci": {
+ "$ref": "#/definitions/settings/definitions/gciSettings"
+ },
+ "gofmt": {
+ "$ref": "#/definitions/settings/definitions/gofmtSettings"
+ },
+ "gofumpt": {
+ "$ref": "#/definitions/settings/definitions/gofumptSettings"
+ },
+ "goimports": {
+ "$ref": "#/definitions/settings/definitions/goimportsSettings"
+ },
+ "golines": {
+ "$ref": "#/definitions/settings/definitions/golinesSettings"
+ }
+ }
+ },
+ "exclusions": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "generated": {
+ "enum": ["strict", "lax", "disable"],
+ "default": "strict"
+ },
+ "paths": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "warn-unused": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ }
+ }
+ },
+ "issues": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-issues-per-linter": {
+ "description": "Maximum issues count per one linter. Set to 0 to disable.",
+ "type": "integer",
+ "default": 50,
+ "minimum": 0
+ },
+ "max-same-issues": {
+ "description": "Maximum count of issues with the same text. Set to 0 to disable.",
+ "type": "integer",
+ "default": 3,
+ "minimum": 0
+ },
+ "new": {
+ "description": "Show only new issues: if there are unstaged changes or untracked files, only those changes are analyzed, else only changes in HEAD~ are analyzed.",
+ "type": "boolean",
+ "default": false
+ },
+ "new-from-merge-base": {
+ "description": "Show only new issues created after the best common ancestor (merge-base against HEAD).",
+ "type": "string"
+ },
+ "new-from-rev": {
+ "description": "Show only new issues created after this git revision.",
+ "type": "string"
+ },
+ "new-from-patch": {
+ "description": "Show only new issues created in git patch with this file path.",
+ "type": "string",
+ "examples": ["path/to/patch/file"]
+ },
+ "fix": {
+ "description": "Apply the fixes detected by the linters and formatters (if it's supported by the linter).",
+ "type": "boolean",
+ "default": false
+ },
+ "uniq-by-line": {
+ "description": "Make issues output unique by line.",
+ "type": "boolean",
+ "default": true
+ },
+ "whole-files": {
+ "description": "Show issues in any part of update files (requires new-from-rev or new-from-patch).",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "severity": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "default": {
+ "description": "Set the default severity for issues. If severity rules are defined and the issues do not match or no severity is provided to the rule this will be the default severity applied. Severities should match the supported severity names of the selected out format.",
+ "type": "string",
+ "default": ""
+ },
+ "rules": {
+ "description": "When a list of severity rules are provided, severity information will be added to lint issues. Severity rules have the same filtering capability as exclude rules except you are allowed to specify one matcher per severity rule.\nOnly affects out formats that support setting severity information.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "severity": {
+ "type": "string"
+ },
+ "path": {
+ "type": "string"
+ },
+ "path-except": {
+ "type": "string"
+ },
+ "linters": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linter-names"
+ }
+ },
+ "text": {
+ "type": "string"
+ },
+ "source": {
+ "type": "string"
+ }
+ },
+ "required": ["severity"],
+ "anyOf": [
+ { "required": ["path"] },
+ { "required": ["path-except"] },
+ { "required": ["linters"] },
+ { "required": ["text"] },
+ { "required": ["source"] }
+ ]
+ },
+ "default": []
+ }
+ },
+ "required": ["default"]
+ }
+ }
+}
diff --git a/vendor/github.com/golangci/golangci-lint/v2/jsonschema/golangci.v1.57.jsonschema.json b/vendor/github.com/golangci/golangci-lint/v2/jsonschema/golangci.v1.57.jsonschema.json
new file mode 100644
index 000000000..a97c0d429
--- /dev/null
+++ b/vendor/github.com/golangci/golangci-lint/v2/jsonschema/golangci.v1.57.jsonschema.json
@@ -0,0 +1,3480 @@
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "$id": "https://json.schemastore.org/golangci-lint.json",
+ "definitions": {
+ "gocritic-checks": {
+ "enum": [
+ "appendAssign",
+ "appendCombine",
+ "argOrder",
+ "assignOp",
+ "badCall",
+ "badCond",
+ "badLock",
+ "badRegexp",
+ "badSorting",
+ "boolExprSimplify",
+ "builtinShadow",
+ "builtinShadowDecl",
+ "captLocal",
+ "caseOrder",
+ "codegenComment",
+ "commentedOutCode",
+ "commentedOutImport",
+ "commentFormatting",
+ "defaultCaseOrder",
+ "deferUnlambda",
+ "deferInLoop",
+ "deprecatedComment",
+ "docStub",
+ "dupArg",
+ "dupBranchBody",
+ "dupCase",
+ "dupImport",
+ "dupSubExpr",
+ "dynamicFmtString",
+ "elseif",
+ "emptyDecl",
+ "emptyFallthrough",
+ "emptyStringTest",
+ "equalFold",
+ "evalOrder",
+ "exitAfterDefer",
+ "exposedSyncMutex",
+ "externalErrorReassign",
+ "filepathJoin",
+ "flagDeref",
+ "flagName",
+ "hexLiteral",
+ "httpNoBody",
+ "hugeParam",
+ "ifElseChain",
+ "importShadow",
+ "indexAlloc",
+ "initClause",
+ "ioutilDeprecated",
+ "mapKey",
+ "methodExprCall",
+ "nestingReduce",
+ "newDeref",
+ "nilValReturn",
+ "octalLiteral",
+ "offBy1",
+ "paramTypeCombine",
+ "preferDecodeRune",
+ "preferFilepathJoin",
+ "preferFprint",
+ "preferStringWriter",
+ "preferWriteByte",
+ "ptrToRefParam",
+ "rangeExprCopy",
+ "rangeValCopy",
+ "redundantSprint",
+ "regexpMust",
+ "regexpPattern",
+ "regexpSimplify",
+ "returnAfterHttpError",
+ "ruleguard",
+ "singleCaseSwitch",
+ "sliceClear",
+ "sloppyLen",
+ "sloppyReassign",
+ "sloppyTypeAssert",
+ "sortSlice",
+ "sprintfQuotedString",
+ "sqlQuery",
+ "stringConcatSimplify",
+ "stringsCompare",
+ "stringXbytes",
+ "suspiciousSorting",
+ "switchTrue",
+ "syncMapLoadAndDelete",
+ "timeCmpSimplify",
+ "timeExprSimplify",
+ "tooManyResultsChecker",
+ "truncateCmp",
+ "typeAssertChain",
+ "typeDefFirst",
+ "typeSwitchVar",
+ "typeUnparen",
+ "uncheckedInlineErr",
+ "underef",
+ "unlabelStmt",
+ "unlambda",
+ "unnamedResult",
+ "unnecessaryBlock",
+ "unnecessaryDefer",
+ "unslice",
+ "valSwap",
+ "weakCond",
+ "whyNoLint",
+ "wrapperFunc",
+ "yodaStyleExpr"
+ ]
+ },
+ "gocritic-tags": {
+ "enum": [
+ "diagnostic",
+ "style",
+ "performance",
+ "experimental",
+ "opinionated",
+ "security"
+ ]
+ },
+ "gosec-rules": {
+ "enum": [
+ "G101",
+ "G102",
+ "G103",
+ "G104",
+ "G106",
+ "G107",
+ "G108",
+ "G109",
+ "G110",
+ "G111",
+ "G112",
+ "G113",
+ "G114",
+ "G201",
+ "G202",
+ "G203",
+ "G204",
+ "G301",
+ "G302",
+ "G303",
+ "G304",
+ "G305",
+ "G306",
+ "G307",
+ "G401",
+ "G402",
+ "G403",
+ "G404",
+ "G501",
+ "G502",
+ "G503",
+ "G504",
+ "G505",
+ "G601",
+ "G602"
+ ]
+ },
+ "govet-analyzers": {
+ "enum": [
+ "appends",
+ "asmdecl",
+ "assign",
+ "atomic",
+ "atomicalign",
+ "bools",
+ "buildtag",
+ "cgocall",
+ "composites",
+ "copylocks",
+ "deepequalerrors",
+ "defers",
+ "directive",
+ "errorsas",
+ "fieldalignment",
+ "findcall",
+ "framepointer",
+ "httpresponse",
+ "ifaceassert",
+ "loopclosure",
+ "lostcancel",
+ "nilfunc",
+ "nilness",
+ "printf",
+ "reflectvaluecompare",
+ "shadow",
+ "shift",
+ "sigchanyzer",
+ "slog",
+ "sortslice",
+ "stdmethods",
+ "stringintconv",
+ "structtag",
+ "testinggoroutine",
+ "tests",
+ "unmarshal",
+ "unreachable",
+ "unsafeptr",
+ "unusedresult",
+ "unusedwrite"
+ ]
+ },
+ "linters": {
+ "$comment": "anyOf with enum is used to allow auto completion of non-custom linters",
+ "description": "Linters usable.",
+ "anyOf": [
+ {
+ "enum": [
+ "asasalint",
+ "asciicheck",
+ "bidichk",
+ "bodyclose",
+ "containedctx",
+ "contextcheck",
+ "copyloopvar",
+ "cyclop",
+ "deadcode",
+ "decorder",
+ "depguard",
+ "dogsled",
+ "dupl",
+ "dupword",
+ "durationcheck",
+ "errcheck",
+ "errchkjson",
+ "errname",
+ "errorlint",
+ "execinquery",
+ "exhaustive",
+ "exhaustivestruct",
+ "exhaustruct",
+ "exportloopref",
+ "forbidigo",
+ "forcetypeassert",
+ "funlen",
+ "gci",
+ "ginkgolinter",
+ "gocheckcompilerdirectives",
+ "gochecknoglobals",
+ "gochecknoinits",
+ "gochecksumtype",
+ "gocognit",
+ "goconst",
+ "gocritic",
+ "gocyclo",
+ "godot",
+ "godox",
+ "goerr113",
+ "gofmt",
+ "gofumpt",
+ "goheader",
+ "goimports",
+ "golint",
+ "gomnd",
+ "gomoddirectives",
+ "gomodguard",
+ "goprintffuncname",
+ "gosec",
+ "gosimple",
+ "gosmopolitan",
+ "govet",
+ "grouper",
+ "ifshort",
+ "importas",
+ "inamedparam",
+ "ineffassign",
+ "interfacebloat",
+ "interfacer",
+ "intrange",
+ "ireturn",
+ "lll",
+ "loggercheck",
+ "maintidx",
+ "makezero",
+ "maligned",
+ "mirror",
+ "misspell",
+ "musttag",
+ "nakedret",
+ "nestif",
+ "nilerr",
+ "nilnil",
+ "nlreturn",
+ "noctx",
+ "nolintlint",
+ "nonamedreturns",
+ "nosnakecase",
+ "nosprintfhostport",
+ "paralleltest",
+ "perfsprint",
+ "prealloc",
+ "predeclared",
+ "promlinter",
+ "protogetter",
+ "reassign",
+ "revive",
+ "rowserrcheck",
+ "scopelint",
+ "sloglint",
+ "sqlclosecheck",
+ "staticcheck",
+ "structcheck",
+ "stylecheck",
+ "tagalign",
+ "tagliatelle",
+ "tenv",
+ "testableexamples",
+ "testifylint",
+ "testpackage",
+ "thelper",
+ "tparallel",
+ "typecheck",
+ "unconvert",
+ "unparam",
+ "unused",
+ "usestdlibvars",
+ "varcheck",
+ "varnamelen",
+ "wastedassign",
+ "whitespace",
+ "wrapcheck",
+ "wsl",
+ "zerologlint"
+ ]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ }
+ },
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "run": {
+ "description": "Options for analysis running,",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "concurrency": {
+ "description": "Number of concurrent runners. Defaults to the number of available CPU cores.",
+ "type": "integer",
+ "minimum": 0,
+ "examples": [4]
+ },
+ "timeout": {
+ "description": "Timeout for the analysis.",
+ "type": "string",
+ "pattern": "^((\\d+h)?(\\d+m)?(\\d+(?:\\.\\d)?s)?|0)$",
+ "default": "1m",
+ "examples": ["30s", "5m", "5m30s"]
+ },
+ "issues-exit-code": {
+ "description": "Exit code when at least one issue was found.",
+ "type": "integer",
+ "default": 1
+ },
+ "tests": {
+ "description": "Enable inclusion of test files.",
+ "type": "boolean",
+ "default": true
+ },
+ "build-tags": {
+ "description": "List of build tags to pass to all linters.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "default": [],
+ "examples": [["mytag"]]
+ },
+ "modules-download-mode": {
+ "description": "Option to pass to \"go list -mod={option}\".\nSee \"go help modules\" for more information.",
+ "enum": ["mod", "readonly", "vendor"]
+ },
+ "allow-parallel-runners": {
+ "description": "Allow multiple parallel golangci-lint instances running. If disabled, golangci-lint acquires file lock on start.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-serial-runners": {
+ "description": "Allow multiple golangci-lint instances running, but serialize them around a lock.",
+ "type": "boolean",
+ "default": false
+ },
+ "go": {
+ "description": "Targeted Go version.",
+ "type": "string",
+ "default": "1.17"
+ }
+ }
+ },
+ "output": {
+ "description": "Output configuration options.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "formats": {
+ "description": "Output formats to use.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "path": {
+ "default": "stdout",
+ "anyOf": [
+ {
+ "enum": [ "stdout", "stderr" ]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ },
+ "format": {
+ "default": "colored-line-number",
+ "enum": [
+ "colored-line-number",
+ "line-number",
+ "json",
+ "colored-tab",
+ "tab",
+ "checkstyle",
+ "code-climate",
+ "junit-xml",
+ "github-actions",
+ "teamcity"
+ ]
+ }
+ },
+ "required": ["format"]
+ }
+ },
+ "print-issued-lines": {
+ "description": "Print lines of code with issue.",
+ "type": "boolean",
+ "default": true
+ },
+ "print-linter-name": {
+ "description": "Print linter name in the end of issue text.",
+ "type": "boolean",
+ "default": true
+ },
+ "uniq-by-line": {
+ "description": "Make issues output unique by line.",
+ "type": "boolean",
+ "default": true
+ },
+ "path-prefix": {
+ "description": "Add a prefix to the output file references.",
+ "type": "string",
+ "default": ""
+ },
+ "show-stats": {
+ "description": "Show statistics per linter.",
+ "type": "boolean",
+ "default": false
+ },
+ "sort-order": {
+ "type": "array",
+ "items": {
+ "enum": ["linter", "severity", "file"]
+ }
+ },
+ "sort-results": {
+ "description": "Sort results by: filepath, line and column.",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "linters-settings": {
+ "description": "All available settings of specific linters.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "dupword": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "keywords": {
+ "description": "Keywords for detecting duplicate words. If this list is not empty, only the words defined in this list will be detected.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["the", "and", "a"]
+ }
+ },
+ "ignore": {
+ "description": "Keywords used to ignore detection.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["0C0C"]
+ }
+ }
+ }
+ },
+ "asasalint": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "exclude": {
+ "description": "To specify a set of function names to exclude.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["\\.Wrapf"]
+ }
+ },
+ "use-builtin-exclusions": {
+ "description": "To enable/disable the asasalint builtin exclusions of function names.",
+ "type": "boolean",
+ "default": true
+ },
+ "ignore-test": {
+ "description": "Ignore *_test.go files.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "bidichk": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "left-to-right-embedding": {
+ "description": "Disallow: LEFT-TO-RIGHT-EMBEDDING",
+ "type": "boolean",
+ "default": false
+ },
+ "right-to-left-embedding": {
+ "description": "Disallow: RIGHT-TO-LEFT-EMBEDDING",
+ "type": "boolean",
+ "default": false
+ },
+ "pop-directional-formatting": {
+ "description": "Disallow: POP-DIRECTIONAL-FORMATTING",
+ "type": "boolean",
+ "default": false
+ },
+ "left-to-right-override": {
+ "description": "Disallow: LEFT-TO-RIGHT-OVERRIDE",
+ "type": "boolean",
+ "default": false
+ },
+ "right-to-left-override": {
+ "description": "Disallow: RIGHT-TO-LEFT-OVERRIDE",
+ "type": "boolean",
+ "default": false
+ },
+ "left-to-right-isolate": {
+ "description": "Disallow: LEFT-TO-RIGHT-ISOLATE",
+ "type": "boolean",
+ "default": false
+ },
+ "right-to-left-isolate": {
+ "description": "Disallow: RIGHT-TO-LEFT-ISOLATE",
+ "type": "boolean",
+ "default": false
+ },
+ "first-strong-isolate": {
+ "description": "Disallow: FIRST-STRONG-ISOLATE",
+ "type": "boolean",
+ "default": false
+ },
+ "pop-directional-isolate": {
+ "description": "Disallow: POP-DIRECTIONAL-ISOLATE",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "cyclop": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skip-tests": {
+ "description": "Should the linter execute on test files as well",
+ "type": "boolean",
+ "default": false
+ },
+ "max-complexity": {
+ "description": "Max complexity the function can have",
+ "type": "integer",
+ "default": 10,
+ "minimum": 0
+ },
+ "package-average": {
+ "description": "Max average complexity in package",
+ "type": "number",
+ "default": 0,
+ "minimum": 0
+ }
+ }
+ },
+ "decorder": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "dec-order": {
+ "type": "array",
+ "default": [["type", "const", "var", "func"]],
+ "items": {
+ "enum": ["type", "const", "var", "func"]
+ }
+ },
+ "ignore-underscore-vars": {
+ "description": "Underscore vars (vars with \"_\" as the name) will be ignored at all checks",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-dec-order-check": {
+ "description": "Order of declarations is not checked",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-init-func-first-check": {
+ "description": "Allow init func to be anywhere in file",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-dec-num-check": {
+ "description": "Multiple global type, const and var declarations are allowed",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-type-dec-num-check": {
+ "description": "Type declarations will be ignored for dec num check",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-const-dec-num-check": {
+ "description": "Const declarations will be ignored for dec num check",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-var-dec-num-check": {
+ "description": "Var declarations will be ignored for dec num check",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ },
+ "depguard": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "rules": {
+ "description": "Rules to apply.",
+ "type": "object",
+ "additionalProperties": false,
+ "patternProperties": {
+ "^[^.]+$": {
+ "description": "Name of a rule.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "list-mode": {
+ "description": "Used to determine the package matching priority.",
+ "enum": ["original", "strict", "lax"],
+ "default": "original"
+ },
+ "files": {
+ "description": "List of file globs that will match this list of settings to compare against.",
+ "additionalProperties": false,
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "allow": {
+ "description": "List of allowed packages.",
+ "additionalProperties": false,
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "deny": {
+ "description": "Packages that are not allowed where the value is a suggestion.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "desc": {
+ "description": "Description",
+ "type": "string"
+ },
+ "pkg": {
+ "description": "Package",
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "dogsled": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-blank-identifiers": {
+ "description": "Check assignments with too many blank identifiers.",
+ "type": "integer",
+ "default": 2,
+ "minimum": 0
+ }
+ }
+ },
+ "dupl": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "threshold": {
+ "description": "Tokens count to trigger issue.",
+ "type": "integer",
+ "default": 150,
+ "minimum": 0
+ }
+ }
+ },
+ "errcheck": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-type-assertions": {
+ "description": "Report about not checking errors in type assertions, i.e.: `a := b.(MyStruct)`",
+ "type": "boolean",
+ "default": false
+ },
+ "check-blank": {
+ "description": "Report about assignment of errors to blank identifier",
+ "type": "boolean",
+ "default": false
+ },
+ "ignore": {
+ "description": "DEPRECATED: use `exclude-functions` instead. Comma-separated list of pairs of the form \"pkg:regex\".",
+ "type": "string",
+ "default": "fmt:.*"
+ },
+ "exclude": {
+ "description": "DEPRECATED: use `exclude-functions` instead. Path to a file containing a list of functions to exclude from checking.",
+ "type": "string",
+ "examples": ["/path/to/file.txt"]
+ },
+ "exclude-functions": {
+ "description": "List of functions to exclude from checking, where each entry is a single function to exclude",
+ "type": "array",
+ "examples": ["io/ioutil.ReadFile", "io.Copy(*bytes.Buffer)"],
+ "items": {
+ "type": "string"
+ }
+ },
+ "disable-default-exclusions": {
+ "description": "To disable the errcheck built-in exclude list",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "errchkjson": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-error-free-encoding": {
+ "type": "boolean",
+ "default": false
+ },
+ "report-no-exported": {
+ "description": "Issue on struct that doesn't have exported fields.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "errorlint": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "errorf": {
+ "description": "Check whether fmt.Errorf uses the %w verb for formatting errors",
+ "type": "boolean",
+ "default": true
+ },
+ "errorf-multi": {
+ "description": "Permit more than 1 %w verb, valid per Go 1.20",
+ "type": "boolean",
+ "default": true
+ },
+ "asserts": {
+ "description": "Check for plain type assertions and type switches.",
+ "type": "boolean",
+ "default": true
+ },
+ "comparison": {
+ "description": "Check for plain error comparisons",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "exhaustive": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check": {
+ "description": "Program elements to check for exhaustiveness.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["switch", "map"]
+ }
+ },
+ "check-generated": {
+ "description": "Check switch statements in generated files",
+ "type": "boolean",
+ "default": false
+ },
+ "explicit-exhaustive-switch": {
+ "description": "Only run exhaustive check on switches with \"//exhaustive:enforce\" comment.",
+ "type": "boolean",
+ "default": false
+ },
+ "explicit-exhaustive-map": {
+ "description": "Only run exhaustive check on map literals with \"//exhaustive:enforce\" comment.",
+ "type": "boolean",
+ "default": false
+ },
+ "default-case-required": {
+ "description": "Switch statement requires default case even if exhaustive.",
+ "type": "boolean",
+ "default": false
+ },
+ "default-signifies-exhaustive": {
+ "description": "Presence of `default` case in switch statements satisfies exhaustiveness, even if all enum members are not listed.",
+ "type": "boolean",
+ "default": false
+ },
+ "ignore-enum-members": {
+ "description": "Enum members matching `regex` do not have to be listed in switch statements to satisfy exhaustiveness",
+ "type": "string"
+ },
+ "ignore-enum-types": {
+ "description": "Enum types matching the supplied regex do not have to be listed in switch statements to satisfy exhaustiveness.",
+ "type": "string"
+ },
+ "package-scope-only": {
+ "description": "Consider enums only in package scopes, not in inner scopes.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "exhaustruct": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "include": {
+ "description": "List of regular expressions to match struct packages and names.",
+ "type": "array",
+ "examples": [".*\\.Test"],
+ "items": {
+ "type": "string"
+ }
+ },
+ "exclude": {
+ "description": "List of regular expressions to exclude struct packages and names from check.",
+ "type": "array",
+ "examples": ["cobra\\.Command$"],
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "forbidigo": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "exclude-godoc-examples": {
+ "description": "Exclude code in godoc examples.",
+ "type": "boolean",
+ "default": true
+ },
+ "analyze-types": {
+ "description": "Instead of matching the literal source code, use type information to replace expressions with strings that contain the package name and (for methods and fields) the type name.",
+ "type": "boolean",
+ "default": true
+ },
+ "forbid": {
+ "description": "List of identifiers to forbid (written using `regexp`)",
+ "type": "array",
+ "examples": ["^print.*$"],
+ "items": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "p": {
+ "description": "Pattern",
+ "type": "string"
+ },
+ "pkg": {
+ "description": "Package",
+ "type": "string"
+ },
+ "msg": {
+ "description": "Message",
+ "type": "string"
+ }
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ "funlen": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "lines": {
+ "description": "Limit lines number per function.",
+ "type": "integer",
+ "default": 60
+ },
+ "statements": {
+ "description": "Limit statements number per function.",
+ "type": "integer",
+ "default": 40
+ },
+ "ignore-comments": {
+ "description": "Ignore comments when counting lines.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "gci": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "local-prefixes": {
+ "description": "DEPRECATED: use 'sections' and 'prefix(github.com/org/project)' instead.",
+ "type": "string",
+ "examples": ["github.com/org/project"]
+ },
+ "sections": {
+ "description": "Section configuration to compare against.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "default": ["standard", "default"]
+ },
+ "skip-generated": {
+ "description": "Skip generated files.",
+ "type": "boolean",
+ "default": true
+ },
+ "custom-order": {
+ "description": "Enable custom order of sections.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "ginkgolinter": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "suppress-len-assertion": {
+ "description": "Suppress the wrong length assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-nil-assertion": {
+ "description": "Suppress the wrong nil assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-err-assertion": {
+ "description": "Suppress the wrong error assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-compare-assertion": {
+ "description": "Suppress the wrong comparison assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-async-assertion": {
+ "description": "Suppress the function all in async assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-type-compare-assertion": {
+ "description": "Suppress warning for comparing values from different types, like int32 and uint32.",
+ "type": "boolean",
+ "default": false
+ },
+ "forbid-focus-container": {
+ "description": "Trigger warning for ginkgo focus containers like FDescribe, FContext, FWhen or FIt.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-havelen-zero": {
+ "description": "Don't trigger warnings for HaveLen(0).",
+ "type": "boolean",
+ "default": false
+ },
+ "force-expect-to": {
+ "description": "Force using `Expect` with `To`, `ToNot` or `NotTo`",
+ "type": "boolean",
+ "default": false
+ },
+ "validate-async-intervals": {
+ "description": "Best effort validation of async intervals (timeout and polling).",
+ "type": "boolean",
+ "default": false
+ },
+ "forbid-spec-pollution": {
+ "description": "Trigger a warning for variable assignments in ginkgo containers like `Describe`, `Context` and `When`, instead of in `BeforeEach()`.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "gocognit": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "min-complexity": {
+ "description": "Minimal code complexity to report (we recommend 10-20).",
+ "type": "integer",
+ "default": 30
+ }
+ }
+ },
+ "goconst": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "match-constant": {
+ "description": "Look for existing constants matching the values",
+ "type": "boolean",
+ "default": true
+ },
+ "min-len": {
+ "description": "Minimum length of string constant.",
+ "type": "integer",
+ "default": 3
+ },
+ "min-occurrences": {
+ "description": "Minimum occurrences count to trigger.",
+ "type": "integer",
+ "default": 3
+ },
+ "ignore-tests": {
+ "description": "Ignore test files.",
+ "type": "boolean",
+ "default": false
+ },
+ "ignore-calls": {
+ "description": "Ignore when constant is not used as function argument",
+ "type": "boolean",
+ "default": true
+ },
+ "ignore-strings": {
+ "description": "Exclude strings matching the given regular expression",
+ "type": "string"
+ },
+ "numbers": {
+ "description": "Search also for duplicated numbers.",
+ "type": "boolean",
+ "default": false
+ },
+ "min": {
+ "description": "Minimum value, only works with `numbers`",
+ "type": "integer",
+ "default": 3
+ },
+ "max": {
+ "description": "Maximum value, only works with `numbers`",
+ "type": "integer",
+ "default": 3
+ }
+ }
+ },
+ "gocritic": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "enabled-checks": {
+ "description": "Which checks should be enabled. By default, a list of stable checks is used. To see it, run `GL_DEBUG=gocritic golangci-lint run`.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/gocritic-checks"
+ }
+ },
+ "disabled-checks": {
+ "description": "Which checks should be disabled.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/gocritic-checks"
+ },
+ "default": []
+ },
+ "enabled-tags": {
+ "description": "Enable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/gocritic-tags"
+ }
+ },
+ "disabled-tags": {
+ "description": "Disable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/gocritic-tags"
+ }
+ },
+ "settings": {
+ "description": "Settings passed to gocritic. Properties must be valid and enabled check names.",
+ "type": "object",
+ "propertyNames": {
+ "$ref": "#/definitions/gocritic-checks"
+ }
+ },
+ "disable-all": {
+ "type": "boolean",
+ "default": false
+ },
+ "enable-all": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "gocyclo": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "min-complexity": {
+ "description": "Minimum code complexity to report (we recommend 10-20).",
+ "type": "integer",
+ "default": 30
+ }
+ }
+ },
+ "godot": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "scope": {
+ "description": "Comments to be checked.",
+ "enum": ["declarations", "toplevel", "all"],
+ "default": "declarations"
+ },
+ "exclude": {
+ "description": "List of regexps for excluding particular comment lines from check.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "period": {
+ "description": "Check that each sentence ends with a period.",
+ "type": "boolean",
+ "default": true
+ },
+ "capital": {
+ "description": "Check that each sentence starts with a capital letter.",
+ "type": "boolean",
+ "default": false
+ },
+ "check-all": {
+ "description": "DEPRECATED: Check all top-level comments, not only declarations.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "godox": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "keywords": {
+ "description": "Report any comments starting with one of these keywords. This is useful for TODO or FIXME comments that might be left in the code accidentally and should be resolved before merging.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "default": ["TODO", "BUG", "FIXME"]
+ }
+ }
+ },
+ "gofmt": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "simplify": {
+ "description": "Simplify code.",
+ "type": "boolean",
+ "default": true
+ },
+ "rewrite-rules": {
+ "description": "Apply the rewrite rules to the source before reformatting.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "pattern": {
+ "type": "string"
+ },
+ "replacement": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "interfacebloat": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max": {
+ "description": "The maximum number of methods allowed for an interface.",
+ "type": "integer"
+ }
+ }
+ },
+ "gofumpt": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "extra-rules": {
+ "description": "Choose whether or not to use the extra rules that are disabled by default.",
+ "type": "boolean",
+ "default": false
+ },
+ "lang-version": {
+ "description": "Select the Go version to target.",
+ "type": "string",
+ "default": "1.15"
+ },
+ "module-path": {
+ "description": " Module path which contains the source code being formatted.",
+ "type": "string"
+ }
+ }
+ },
+ "goheader": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "values": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "const": {
+ "description": "Constants to use in the template.",
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "description": "Value for the constant.",
+ "type": "string"
+ }
+ },
+ "additionalProperties": false,
+ "examples": [
+ {
+ "YEAR": "2030",
+ "COMPANY": "MY FUTURISTIC COMPANY"
+ }
+ ]
+ },
+ "regexp": {
+ "description": "Regular expressions to use in your template.",
+ "type": "object",
+ "additionalProperties": false,
+ "patternProperties": {
+ "^.+$": {
+ "type": "string"
+ }
+ },
+ "examples": [
+ {
+ "AUTHOR": ".*@mycompany\\.com"
+ }
+ ]
+ }
+ }
+ },
+ "template": {
+ "description": "Template to put on top of every file.",
+ "type": "string",
+ "examples": [
+ "{{ MY COMPANY }}\nSPDX-License-Identifier: Apache-2.0\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at:\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License."
+ ]
+ },
+ "template-path": {
+ "description": "Path to the file containing the template source.",
+ "type": "string",
+ "examples": ["my_header_template.txt"]
+ }
+ },
+ "oneOf": [
+ { "required": ["template"] },
+ { "required": ["template-path"] }
+ ]
+ },
+ "goimports": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "local-prefixes": {
+ "description": "Put imports beginning with prefix after 3rd-party packages. It is a comma-separated list of prefixes.",
+ "type": "string",
+ "examples": ["github.com/org/project"]
+ }
+ }
+ },
+ "gomnd": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignored-files": {
+ "description": "List of file patterns to exclude from analysis.",
+ "examples": [["magic1_.*.go"]],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignored-functions": {
+ "description": "Comma-separated list of function patterns to exclude from the analysis.",
+ "examples": [["math.*", "http.StatusText", "make"]],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignored-numbers": {
+ "description": "List of numbers to exclude from analysis.",
+ "examples": [["1000", "1234_567_890", "3.14159264"]],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "checks": {
+ "description": "The list of enabled checks, see https://github.com/tommy-muehle/go-mnd/#checks for description.",
+ "type": "array",
+ "items": {
+ "enum": [
+ "argument",
+ "case",
+ "condition",
+ "operation",
+ "return",
+ "assign"
+ ]
+ }
+ }
+ }
+ },
+ "gomoddirectives": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "replace-local": {
+ "description": "Allow local `replace` directives.",
+ "type": "boolean",
+ "default": true
+ },
+ "replace-allow-list": {
+ "description": "List of allowed `replace` directives.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "retract-allow-no-explanation": {
+ "description": "Allow to not explain why the version has been retracted in the `retract` directives.",
+ "type": "boolean",
+ "default": true
+ },
+ "exclude-forbidden": {
+ "description": "Forbid the use of the `exclude` directives.",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "gomodguard": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "allowed": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "modules": {
+ "description": "List of allowed modules.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["gopkg.in/yaml.v2"]
+ }
+ },
+ "domains": {
+ "description": "List of allowed module domains.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["golang.org"]
+ }
+ }
+ }
+ },
+ "blocked": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "modules": {
+ "description": "List of blocked modules.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "recommendations": {
+ "description": "Recommended modules that should be used instead.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "reason": {
+ "description": "Reason why the recommended module should be used.",
+ "type": "string"
+ }
+ }
+ }
+ },
+ "additionalProperties": false
+ }
+ },
+ "versions": {
+ "description": "List of blocked module version constraints.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "patternProperties": {
+ "^.*$": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "version": {
+ "description": "Version constraint.",
+ "type": "string"
+ },
+ "reason": {
+ "description": "Reason why the version constraint exists.",
+ "type": "string"
+ }
+ },
+ "required": ["reason"]
+ }
+ }
+ }
+ },
+ "local_replace_directives": {
+ "description": "Raise lint issues if loading local path with replace directive",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ }
+ }
+ },
+ "gosimple": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "go": {
+ "description": "Targeted Go version",
+ "type": "string",
+ "default": "1.13"
+ },
+ "checks": {
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "enum": ["all"]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ }
+ }
+ }
+ },
+ "gosec": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "includes": {
+ "type": "array",
+ "description": "To select a subset of rules to run",
+ "examples": [["G401"]],
+ "items": {
+ "$ref": "#/definitions/gosec-rules"
+ }
+ },
+ "excludes": {
+ "type": "array",
+ "description": "To specify a set of rules to explicitly exclude",
+ "examples": [["G401"]],
+ "items": {
+ "$ref": "#/definitions/gosec-rules"
+ }
+ },
+ "exclude-generated": {
+ "description": "Exclude generated files",
+ "type": "boolean",
+ "default": false
+ },
+ "severity": {
+ "description": "Filter out the issues with a lower severity than the given value",
+ "type": "string",
+ "enum": ["low", "medium", "high"],
+ "default": "low"
+ },
+ "confidence": {
+ "description": "Filter out the issues with a lower confidence than the given value",
+ "type": "string",
+ "enum": ["low", "medium", "high"],
+ "default": "low"
+ },
+ "config": {
+ "description": "To specify the configuration of rules",
+ "type": "object"
+ },
+ "concurrency": {
+ "description": "Concurrency value",
+ "type": "integer"
+ }
+ }
+ },
+ "gosmopolitan": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "allow-time-local": {
+ "description": "Allow and ignore `time.Local` usages.",
+ "type": "boolean",
+ "default": false
+ },
+ "escape-hatches": {
+ "description": "List of fully qualified names in the `full/pkg/path.name` form, to act as \"i18n escape hatches\".",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignore-tests": {
+ "description": "Ignore test files.",
+ "type": "boolean",
+ "default": false
+ },
+ "watch-for-scripts": {
+ "description": "List of Unicode scripts to watch for any usage in string literals.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "govet": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "settings": {
+ "description": "Settings per analyzer. Map of analyzer name to specific settings.\nRun `go tool vet help` to find out more.",
+ "type": "object",
+ "propertyNames": {
+ "$ref": "#/definitions/govet-analyzers"
+ },
+ "patternProperties": {
+ "^.*$": {
+ "description": "Run `go tool vet help ` to see all settings.",
+ "type": "object"
+ }
+ }
+ },
+ "enable": {
+ "description": "Enable analyzers by name.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/govet-analyzers"
+ }
+ },
+ "disable": {
+ "description": "Disable analyzers by name.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/govet-analyzers"
+ }
+ },
+ "enable-all": {
+ "description": "Enable all analyzers.",
+ "type": "boolean",
+ "default": false
+ },
+ "disable-all": {
+ "description": "Disable all analyzers.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "grouper": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "const-require-single-const": {
+ "type": "boolean",
+ "default": false
+ },
+ "const-require-grouping": {
+ "type": "boolean",
+ "default": false
+ },
+ "import-require-single-import": {
+ "type": "boolean",
+ "default": false
+ },
+ "import-require-grouping": {
+ "type": "boolean",
+ "default": false
+ },
+ "type-require-single-type": {
+ "type": "boolean",
+ "default": false
+ },
+ "type-require-grouping": {
+ "type": "boolean",
+ "default": false
+ },
+ "var-require-single-var": {
+ "type": "boolean",
+ "default": false
+ },
+ "var-require-grouping": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "importas": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "no-unaliased": {
+ "description": "Do not allow unaliased imports of aliased packages.",
+ "type": "boolean",
+ "default": false
+ },
+ "no-extra-aliases": {
+ "description": "Do not allow non-required aliases.",
+ "type": "boolean",
+ "default": false
+ },
+ "alias": {
+ "description": "List of aliases",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "pkg": {
+ "description": "Package path e.g. knative.dev/serving/pkg/apis/autoscaling/v1alpha1",
+ "type": "string"
+ },
+ "alias": {
+ "description": "Package alias e.g. autoscalingv1alpha1",
+ "type": "string"
+ }
+ },
+ "required": ["pkg", "alias"]
+ }
+ }
+ }
+ },
+ "inamedparam": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skip-single-param": {
+ "description": "Skips check for interface methods with only a single parameter.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "ireturn": {
+ "type": "object",
+ "additionalProperties": false,
+ "description": "Use either `reject` or `allow` properties for interfaces matching.",
+ "properties": {
+ "allow": {
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "enum": ["anon", "error", "empty", "stdlib"]
+ }
+ ]
+ }
+ },
+ "reject": {
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "enum": ["anon", "error", "empty", "stdlib"]
+ }
+ ]
+ }
+ }
+ },
+ "anyOf": [
+ {
+ "not": {
+ "properties": {
+ "allow": {
+ "const": "reject"
+ }
+ }
+ },
+ "required": ["allow"]
+ },
+ {
+ "required": ["reject"]
+ }
+ ]
+ },
+ "lll": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "tab-width": {
+ "description": "Width of \"\\t\" in spaces.",
+ "type": "integer",
+ "minimum": 0,
+ "default": 1
+ },
+ "line-length": {
+ "description": "Maximum allowed line length, lines longer will be reported.",
+ "type": "integer",
+ "minimum": 1,
+ "default": 120
+ }
+ }
+ },
+ "maintidx": {
+ "description": "Maintainability index https://docs.microsoft.com/en-us/visualstudio/code-quality/code-metrics-maintainability-index-range-and-meaning?view=vs-2022",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "under": {
+ "description": "Minimum accatpable maintainability index level (see https://docs.microsoft.com/en-us/visualstudio/code-quality/code-metrics-maintainability-index-range-and-meaning?view=vs-2022)",
+ "type": "number",
+ "default": 20
+ }
+ }
+ },
+ "makezero": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "always": {
+ "description": "Allow only slices initialized with a length of zero.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "loggercheck": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "kitlog": {
+ "description": "Allow check for the github.com/go-kit/log library.",
+ "type": "boolean",
+ "default": true
+ },
+ "klog": {
+ "description": "Allow check for the k8s.io/klog/v2 library.",
+ "type": "boolean",
+ "default": true
+ },
+ "logr": {
+ "description": "Allow check for the github.com/go-logr/logr library.",
+ "type": "boolean",
+ "default": true
+ },
+ "zap": {
+ "description": "Allow check for the \"sugar logger\" from go.uber.org/zap library.",
+ "type": "boolean",
+ "default": true
+ },
+ "require-string-key": {
+ "description": "Require all logging keys to be inlined constant strings.",
+ "type": "boolean",
+ "default": false
+ },
+ "no-printf-like": {
+ "description": "Require printf-like format specifier (%s, %d for example) not present.",
+ "type": "boolean",
+ "default": false
+ },
+ "rules": {
+ "description": "List of custom rules to check against, where each rule is a single logger pattern, useful for wrapped loggers.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "misspell": {
+ "description": "Correct spellings using locale preferences for US or UK. Default is to use a neutral variety of English.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "locale": {
+ "enum": ["US", "UK"]
+ },
+ "ignore-words": {
+ "description": "List of words to ignore.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "mode": {
+ "description": "Mode of the analysis.",
+ "enum": ["restricted", "", "default"],
+ "default": ""
+ },
+ "extra-words": {
+ "description": "Extra word corrections.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "correction": {
+ "type": "string"
+ },
+ "typo": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "musttag": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "functions": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "tag": {
+ "type": "string"
+ },
+ "arg-pos": {
+ "type": "integer"
+ }
+ }
+ }
+ }
+ }
+ },
+ "nakedret": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-func-lines": {
+ "description": "Report if a function has more lines of code than this value and it has naked returns.",
+ "type": "integer",
+ "minimum": 0,
+ "default": 30
+ }
+ }
+ },
+ "nestif": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "min-complexity": {
+ "description": "Minimum complexity of \"if\" statements to report.",
+ "type": "integer",
+ "default": 5
+ }
+ }
+ },
+ "nilnil": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "checked-types": {
+ "type": "array",
+ "description": "Order of return types to check.",
+ "items": {
+ "enum": ["ptr", "func", "iface", "map", "chan"]
+ },
+ "default": ["ptr", "func", "iface", "map", "chan"]
+ }
+ }
+ },
+ "nlreturn": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "block-size": {
+ "description": "set block size that is still ok",
+ "type": "number",
+ "default": 0,
+ "minimum": 0
+ }
+ }
+ },
+ "nolintlint": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "allow-unused": {
+ "description": "Enable to ensure that nolint directives are all used.",
+ "type": "boolean",
+ "default": true
+ },
+ "allow-no-explanation": {
+ "description": "Exclude these linters from requiring an explanation.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linters"
+ },
+ "default": []
+ },
+ "require-explanation": {
+ "description": "Enable to require an explanation of nonzero length after each nolint directive.",
+ "type": "boolean",
+ "default": false
+ },
+ "require-specific": {
+ "description": "Enable to require nolint directives to mention the specific linter being suppressed.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "reassign": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "patterns": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "nonamedreturns": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "report-error-in-defer": {
+ "description": "Report named error if it is assigned inside defer.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "paralleltest": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignore-missing": {
+ "description": "Ignore missing calls to `t.Parallel()` and only report incorrect uses of it.",
+ "type": "boolean",
+ "default": false
+ },
+ "ignore-missing-subtests": {
+ "description": "Ignore missing calls to `t.Parallel()` in subtests. Top-level tests are still required to have `t.Parallel`, but subtests are allowed to skip it.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "perfsprint": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "int-conversion": {
+ "description": "Optimizes even if it requires an int or uint type cast.",
+ "type": "boolean",
+ "default": true
+ },
+ "err-error": {
+ "description": "Optimizes into `err.Error()` even if it is only equivalent for non-nil errors.",
+ "type": "boolean",
+ "default": false
+ },
+ "errorf": {
+ "description": "Optimizes `fmt.Errorf`.",
+ "type": "boolean",
+ "default": true
+ },
+ "sprintf1": {
+ "description": "Optimizes `fmt.Sprintf` with only one argument.",
+ "type": "boolean",
+ "default": true
+ },
+ "strconcat": {
+ "description": "Optimizes into strings concatenation.",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "prealloc": {
+ "description": "We do not recommend using this linter before doing performance profiling.\nFor most programs usage of `prealloc` will be premature optimization.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "simple": {
+ "description": "Report preallocation suggestions only on simple loops that have no returns/breaks/continues/gotos in them.",
+ "type": "boolean",
+ "default": true
+ },
+ "range-loops": {
+ "description": "Report preallocation suggestions on range loops.",
+ "type": "boolean",
+ "default": true
+ },
+ "for-loops": {
+ "description": "Report preallocation suggestions on for loops.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "predeclared": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignore": {
+ "description": "Comma-separated list of predeclared identifiers to not report on.",
+ "type": "string"
+ },
+ "q": {
+ "description": "Include method names and field names (i.e., qualified names) in checks.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "promlinter": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "strict": {},
+ "disabled-linters": {
+ "type": "array",
+ "items": {
+ "enum": [
+ "Help",
+ "MetricUnits",
+ "Counter",
+ "HistogramSummaryReserved",
+ "MetricTypeInName",
+ "ReservedChars",
+ "CamelCase",
+ "UnitAbbreviations"
+ ]
+ }
+ }
+ }
+ },
+ "protogetter": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skip-generated-by": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["protoc-gen-go-my-own-generator"]
+ }
+ },
+ "skip-files": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["*.pb.go"]
+ }
+ },
+ "skip-any-generated": {
+ "description": "Skip any generated files from the checking.",
+ "type": "boolean",
+ "default": false
+ },
+ "replace-first-arg-in-append": {
+ "description": "Skip first argument of append function.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "revive": {
+ "type": "object",
+ "additionalProperties": false,
+ "examples": [
+ {
+ "ignore-generated-header": true,
+ "severity": "warning",
+ "rules": [
+ {
+ "name": "indent-error-flow",
+ "severity": "warning"
+ },
+ {
+ "name": "add-constant",
+ "severity": "warning",
+ "arguments": [
+ {
+ "maxLitCount": "3",
+ "allowStrs": "\"\"",
+ "allowInts": "0,1,2",
+ "allowFloats": "0.0,0.,1.0,1.,2.0,2."
+ }
+ ]
+ }
+ ]
+ }
+ ],
+ "properties": {
+ "max-open-files": {
+ "type": "integer"
+ },
+ "ignore-generated-header": {
+ "type": "boolean"
+ },
+ "confidence": {
+ "type": "number"
+ },
+ "severity": {
+ "type": "string",
+ "enum": ["warning", "error"]
+ },
+ "enable-all-rules": {
+ "type": "boolean",
+ "default": false
+ },
+ "directives": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "name": {
+ "type": "string",
+ "enum": ["specify-disable-reason"]
+ },
+ "severity": {
+ "type": "string",
+ "enum": ["warning", "error"]
+ },
+ "exclude": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "arguments": {
+ "type": "array"
+ }
+ }
+ }
+ },
+ "rules": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["name"],
+ "properties": {
+ "name": {
+ "type": "string",
+ "title": "The rule name"
+ },
+ "disabled": {
+ "type": "boolean"
+ },
+ "severity": {
+ "type": "string",
+ "enum": ["warning", "error"]
+ },
+ "exclude": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "arguments": {
+ "type": "array"
+ }
+ }
+ }
+ }
+ }
+ },
+ "rowserrcheck": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "packages": {
+ "type": "array",
+ "items": {
+ "description": "",
+ "type": "string",
+ "examples": ["github.com/jmoiron/sqlx"]
+ }
+ }
+ }
+ },
+ "sloglint": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "kv-only": {
+ "description": "Enforce using key-value pairs only (incompatible with attr-only).",
+ "type": "boolean",
+ "default": false
+ },
+ "no-global": {
+ "description": "Enforce not using global loggers.",
+ "enum": ["", "all", "default"],
+ "default": ""
+ },
+ "no-mixed-args": {
+ "description": "Enforce not mixing key-value pairs and attributes.",
+ "type": "boolean",
+ "default": true
+ },
+ "context-only": {
+ "description": "Enforce using methods that accept a context.",
+ "type": "boolean",
+ "default": false
+ },
+ "static-msg": {
+ "description": "Enforce using static values for log messages.",
+ "type": "boolean",
+ "default": false
+ },
+ "key-naming-case": {
+ "description": "Enforce a single key naming convention.",
+ "enum": ["snake", "kebab", "camel", "pascal"]
+ },
+ "attr-only": {
+ "description": "Enforce using attributes only (incompatible with kv-only).",
+ "type": "boolean",
+ "default": false
+ },
+ "no-raw-keys": {
+ "description": "Enforce using constants instead of raw keys.",
+ "type": "boolean",
+ "default": false
+ },
+ "args-on-sep-lines": {
+ "description": "Enforce putting arguments on separate lines.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "spancheck": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "checks": {
+ "description": "Checks to enable.",
+ "type": "array",
+ "items": {
+ "enum": ["end", "record-error", "set-status"]
+ }
+ },
+ "ignore-check-signatures": {
+ "description": "A list of regexes for function signatures that silence `record-error` and `set-status` reports if found in the call path to a returned error.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "staticcheck": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "go": {
+ "description": "Targeted Go version",
+ "type": "string",
+ "default": "1.13"
+ },
+ "checks": {
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "enum": ["all"]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ }
+ }
+ }
+ },
+ "stylecheck": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "go": {
+ "description": "Targeted Go version",
+ "type": "string",
+ "default": "1.13"
+ },
+ "checks": {
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "enum": ["all"]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ },
+ "default": [
+ "all",
+ "-ST1000",
+ "-ST1003",
+ "-ST1016",
+ "-ST1020",
+ "-ST1021",
+ "-ST1022"
+ ]
+ },
+ "dot-import-whitelist": {
+ "description": "By default, ST1001 forbids all uses of dot imports in non-test packages. This setting allows setting a whitelist of import paths that can be dot-imported anywhere.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "http-status-code-whitelist": {
+ "description": "ST1013 recommends using constants from the net/http package instead of hard-coding numeric HTTP status codes. This setting specifies a list of numeric status codes that this check does not complain about.",
+ "default": ["200", "400", "404", "500"],
+ "type": "array",
+ "items": {
+ "enum": [
+ "100",
+ "101",
+ "102",
+ "103",
+ "200",
+ "201",
+ "202",
+ "203",
+ "204",
+ "205",
+ "206",
+ "207",
+ "208",
+ "226",
+ "300",
+ "301",
+ "302",
+ "303",
+ "304",
+ "305",
+ "306",
+ "307",
+ "308",
+ "400",
+ "401",
+ "402",
+ "403",
+ "404",
+ "405",
+ "406",
+ "407",
+ "408",
+ "409",
+ "410",
+ "411",
+ "412",
+ "413",
+ "414",
+ "415",
+ "416",
+ "417",
+ "418",
+ "421",
+ "422",
+ "423",
+ "424",
+ "425",
+ "426",
+ "428",
+ "429",
+ "431",
+ "451",
+ "500",
+ "501",
+ "502",
+ "503",
+ "504",
+ "505",
+ "506",
+ "507",
+ "508",
+ "510",
+ "511"
+ ]
+ }
+ },
+ "initialisms": {
+ "description": "ST1003 check, among other things, for the correct capitalization of initialisms. The set of known initialisms can be configured with this option.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "default": [
+ "ACL",
+ "API",
+ "ASCII",
+ "CPU",
+ "CSS",
+ "DNS",
+ "EOF",
+ "GUID",
+ "HTML",
+ "HTTP",
+ "HTTPS",
+ "ID",
+ "IP",
+ "JSON",
+ "QPS",
+ "RAM",
+ "RPC",
+ "SLA",
+ "SMTP",
+ "SQL",
+ "SSH",
+ "TCP",
+ "TLS",
+ "TTL",
+ "UDP",
+ "UI",
+ "GID",
+ "UID",
+ "UUID",
+ "URI",
+ "URL",
+ "UTF8",
+ "VM",
+ "XML",
+ "XMPP",
+ "XSRF",
+ "XSS",
+ "SIP",
+ "RTP",
+ "AMQP",
+ "DB",
+ "TS"
+ ]
+ }
+ }
+ }
+ },
+ "tagalign": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "align": {
+ "description": "Align and sort can be used together or separately.",
+ "type": "boolean",
+ "default": true
+ },
+ "sort": {
+ "description": "Whether enable tags sort.",
+ "type": "boolean",
+ "default": true
+ },
+ "order": {
+ "description": "Specify the order of tags, the other tags will be sorted by name.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "default": [],
+ "examples": [
+ [
+ "json",
+ "yaml",
+ "yml",
+ "toml",
+ "mapstructure",
+ "binding",
+ "validate"
+ ]
+ ]
+ },
+ "strict": {
+ "description": "Whether enable strict style.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "tagliatelle": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "case": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "use-field-name": {
+ "description": "Use the struct field name to check the name of the struct tag.",
+ "type": "boolean",
+ "default": false
+ },
+ "rules": {
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "enum": [
+ "camel",
+ "pascal",
+ "kebab",
+ "snake",
+ "goCamel",
+ "goPascal",
+ "goKebab",
+ "goSnake",
+ "upper",
+ "upperSnake",
+ "lower",
+ "header"
+ ]
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "tenv": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "all": {
+ "description": "The option `all` will run against whole test files (`_test.go`) regardless of method/function signatures.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "testifylint": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "bool-compare": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignore-custom-types": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "enable-all": {
+ "description": "Enable all checkers.",
+ "type": "boolean",
+ "default": false
+ },
+ "disable-all": {
+ "description": "Disable all checkers.",
+ "type": "boolean",
+ "default": false
+ },
+ "enable": {
+ "description": "Enable specific checkers.",
+ "type": "array",
+ "items": {
+ "enum": [
+ "blank-import",
+ "bool-compare",
+ "compares",
+ "empty",
+ "error-is-as",
+ "error-nil",
+ "expected-actual",
+ "go-require",
+ "float-compare",
+ "len",
+ "nil-compare",
+ "require-error",
+ "suite-dont-use-pkg",
+ "suite-extra-assert-call",
+ "suite-thelper",
+ "useless-assert"
+ ]
+ }
+ },
+ "disable": {
+ "description": "Enable specific checkers.",
+ "type": "array",
+ "items": {
+ "enum": [
+ "blank-import",
+ "bool-compare",
+ "compares",
+ "empty",
+ "error-is-as",
+ "error-nil",
+ "expected-actual",
+ "go-require",
+ "float-compare",
+ "len",
+ "nil-compare",
+ "require-error",
+ "suite-dont-use-pkg",
+ "suite-extra-assert-call",
+ "suite-thelper",
+ "useless-assert"
+ ]
+ }
+ },
+ "expected-actual": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "pattern": {
+ "description": "Regexp for expected variable name.",
+ "type": "string"
+ }
+ }
+ },
+ "require-error": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "fn-pattern": {
+ "description": "Regexp for expected variable name.",
+ "type": "string"
+ }
+ }
+ },
+ "suite-extra-assert-call": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "mode": {
+ "description": "To require or remove extra Assert() call?",
+ "type": "string",
+ "enum": ["remove", "require"]
+ }
+ }
+ }
+ }
+ },
+ "testpackage": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skip-regexp": {
+ "description": "Files with names matching this regular expression are skipped.",
+ "type": "string",
+ "examples": ["(export|internal)_test\\.go"]
+ },
+ "allow-packages": {
+ "description": "List of packages that don't end with _test that tests are allowed to be in.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["example"]
+ }
+ }
+ }
+ },
+ "thelper": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "test": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "begin": {
+ "description": "Check if `t.Helper()` begins helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "first": {
+ "description": "Check if *testing.T is first param of helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "name": {
+ "description": "Check if *testing.T param has t name.",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ },
+ "benchmark": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "begin": {
+ "description": "Check if `b.Helper()` begins helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "first": {
+ "description": "Check if *testing.B is first param of helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "name": {
+ "description": "Check if *testing.B param has b name.",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ },
+ "tb": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "begin": {
+ "description": "Check if `tb.Helper()` begins helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "first": {
+ "description": "Check if *testing.TB is first param of helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "name": {
+ "description": "Check if *testing.TB param has tb name.",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ },
+ "fuzz": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "begin": {
+ "description": "Check if `f.Helper()` begins helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "first": {
+ "description": "Check if *testing.F is first param of helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "name": {
+ "description": "Check if *testing.F param has f name.",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ }
+ }
+ },
+ "usestdlibvars": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "http-method": {
+ "description": "Suggest the use of http.MethodXX.",
+ "type": "boolean",
+ "default": true
+ },
+ "http-status-code": {
+ "description": "Suggest the use of http.StatusXX.",
+ "type": "boolean",
+ "default": true
+ },
+ "time-weekday": {
+ "description": "Suggest the use of time.Weekday.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "time-month": {
+ "description": "Suggest the use of time.Month.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "time-layout": {
+ "description": "Suggest the use of time.Layout.",
+ "type": "boolean",
+ "default": false
+ },
+ "crypto-hash": {
+ "description": "Suggest the use of crypto.Hash.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "default-rpc-path": {
+ "description": "Suggest the use of rpc.DefaultXXPath.",
+ "type": "boolean",
+ "default": false
+ },
+ "os-dev-null": {
+ "description": "Suggest the use of os.DevNull.",
+ "type": "boolean",
+ "default": false
+ },
+ "sql-isolation-level": {
+ "description": "Suggest the use of sql.LevelXX.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "tls-signature-scheme": {
+ "description": "Suggest the use of tls.SignatureScheme.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "constant-kind": {
+ "description": "Suggest the use of constant.Kind.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "syslog-priority": {
+ "description": "Suggest the use of syslog.Priority.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "unconvert": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "fast-math": {
+ "type": "boolean",
+ "default": false
+ },
+ "safe": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "unparam": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-exported": {
+ "description": "Inspect exported functions. Set to true if no external program/library imports your code.\n\nWARNING: if you enable this setting, unparam will report a lot of false-positives in text editors:\nif it's called for subdir of a project it can't find external interfaces. All text editor integrations\nwith golangci-lint call it on a directory with the changed file.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "unused": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "field-writes-are-uses": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ },
+ "post-statements-are-reads": {
+ "description": "",
+ "type": "boolean",
+ "default": false
+ },
+ "exported-is-used": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ },
+ "exported-fields-are-used": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ },
+ "parameters-are-used": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ },
+ "local-variables-are-used": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ },
+ "generated-is-used": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "varnamelen": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-distance": {
+ "description": "Variables used in at most this N-many lines will be ignored.",
+ "type": "integer",
+ "default": 5
+ },
+ "min-name-length": {
+ "description": "The minimum length of a variable's name that is considered `long`.",
+ "type": "integer",
+ "default": 3
+ },
+ "check-receiver": {
+ "description": "Check method receiver names.",
+ "default": false,
+ "type": "boolean"
+ },
+ "check-return": {
+ "description": "Check named return values.",
+ "default": false,
+ "type": "boolean"
+ },
+ "check-type-param": {
+ "description": "Check type parameters.",
+ "default": false,
+ "type": "boolean"
+ },
+ "ignore-type-assert-ok": {
+ "description": "Ignore `ok` variables that hold the bool return value of a type assertion",
+ "default": false,
+ "type": "boolean"
+ },
+ "ignore-map-index-ok": {
+ "description": "Ignore `ok` variables that hold the bool return value of a map index.",
+ "default": false,
+ "type": "boolean"
+ },
+ "ignore-chan-recv-ok": {
+ "description": "Ignore `ok` variables that hold the bool return value of a channel receive.",
+ "default": false,
+ "type": "boolean"
+ },
+ "ignore-names": {
+ "description": "Optional list of variable names that should be ignored completely.",
+ "default": [[]],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignore-decls": {
+ "description": "Optional list of variable declarations that should be ignored completely.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "examples": [
+ ["c echo.Context", "t testing.T", "f *foo.Bar", "const C"]
+ ]
+ }
+ }
+ },
+ "whitespace": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "multi-if": {
+ "description": "Enforces newlines (or comments) after every multi-line if statement",
+ "type": "boolean",
+ "default": false
+ },
+ "multi-func": {
+ "description": "Enforces newlines (or comments) after every multi-line function signature",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "wrapcheck": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignoreSigs": {
+ "description": "An array of strings which specify substrings of signatures to ignore.",
+ "default": [
+ ".Errorf(",
+ "errors.New(",
+ "errors.Unwrap(",
+ ".Wrap(",
+ ".Wrapf(",
+ ".WithMessage(",
+ ".WithMessagef(",
+ ".WithStack("
+ ],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignoreSigRegexps": {
+ "description": "An array of strings which specify regular expressions of signatures to ignore.",
+ "default": [""],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignorePackageGlobs": {
+ "description": "An array of glob patterns which, if any match the package of the function returning the error, will skip wrapcheck analysis for this error.",
+ "default": [""],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignoreInterfaceRegexps": {
+ "description": "An array of glob patterns which, if matched to an underlying interface name, will ignore unwrapped errors returned from a function whose call is defined on the given interface.",
+ "default": [""],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "wsl": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "allow-assign-and-anything": {
+ "description": "Controls if you may cuddle assignments and anything without needing an empty line between them.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-assign-and-call": {
+ "description": "Allow calls and assignments to be cuddled as long as the lines have any matching variables, fields or types.",
+ "type": "boolean",
+ "default": true
+ },
+ "allow-cuddle-declarations": {
+ "description": "Allow declarations (var) to be cuddled.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-cuddle-with-calls": {
+ "description": "A list of call idents that everything can be cuddled with.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "allow-cuddle-with-rhs": {
+ "description": "AllowCuddleWithRHS is a list of right hand side variables that is allowed to be cuddled with anything.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "allow-multiline-assign": {
+ "description": "Allow multiline assignments to be cuddled.",
+ "type": "boolean",
+ "default": true
+ },
+ "allow-separated-leading-comment": {
+ "description": "Allow leading comments to be separated with empty lines.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-trailing-comment": {
+ "description": "Allow trailing comments in ending of blocks.",
+ "type": "boolean",
+ "default": false
+ },
+ "error-variable-names": {
+ "description": "When force-err-cuddling is enabled this is a list of names used for error variables to check for in the conditional.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "force-case-trailing-whitespace": {
+ "description": "Force newlines in end of case at this limit (0 = never).",
+ "type": "integer",
+ "minimum": 0,
+ "default": 0
+ },
+ "force-err-cuddling": {
+ "description": "Causes an error when an If statement that checks an error variable doesn't cuddle with the assignment of that variable.",
+ "type": "boolean",
+ "default": false
+ },
+ "force-short-decl-cuddling": {
+ "description": "Causes an error if a short declaration (:=) cuddles with anything other than another short declaration.",
+ "type": "boolean",
+ "default": false
+ },
+ "strict-append": {
+ "description": "If true, append is only allowed to be cuddled if appending value is matching variables, fields or types on line above.",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "copyloopvar": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignore-alias": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "custom": {
+ "description": "The custom section can be used to define linter plugins to be loaded at runtime. See README of golangci-lint for more information.\nEach custom linter should have a unique name.",
+ "type": "object",
+ "patternProperties": {
+ "^.*$": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "type": {
+ "description": "The plugin type.",
+ "enum": ["module", "goplugin"],
+ "default": "goplugin"
+ },
+ "path": {
+ "description": "The path to the plugin *.so. Can be absolute or local.",
+ "type": "string",
+ "examples": ["/path/to/example.so"]
+ },
+ "description": {
+ "description": "The description of the linter, for documentation purposes only.",
+ "type": "string"
+ },
+ "original-url": {
+ "description": "Intended to point to the repo location of the linter, for documentation purposes only.",
+ "type": "string"
+ },
+ "settings": {
+ "description": "Plugins settings/configuration. Only work with plugin based on `linterdb.PluginConstructor`.",
+ "type": "object"
+ }
+ },
+ "oneOf": [
+ {
+ "properties": {
+ "type": {"enum": ["module"] }
+ },
+ "required": ["type"]
+ },
+ {
+ "required": ["path"]
+ }
+ ]
+ }
+ }
+ }
+ }
+ },
+ "linters": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "enable": {
+ "description": "List of enabled linters.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linters"
+ }
+ },
+ "disable": {
+ "description": "List of disabled linters.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linters"
+ }
+ },
+ "enable-all": {
+ "description": "Whether to enable all linters. You can re-disable them with `disable` explicitly.",
+ "type": "boolean",
+ "default": false
+ },
+ "disable-all": {
+ "description": "Whether to disable all linters. You can re-enable them with `enable` explicitly.",
+ "type": "boolean",
+ "default": false
+ },
+ "presets": {
+ "description": "Allow to use different presets of linters",
+ "type": "array",
+ "items": {
+ "enum": [
+ "bugs",
+ "comment",
+ "complexity",
+ "error",
+ "format",
+ "import",
+ "metalinter",
+ "module",
+ "performance",
+ "sql",
+ "style",
+ "test",
+ "unused"
+ ]
+ }
+ },
+ "fast": {
+ "description": "Enable run of fast linters.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "issues": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "exclude": {
+ "description": "List of regular expressions of issue texts to exclude.\nBut independently from this option we use default exclude patterns. Their usage can be controlled through `exclude-use-default`.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "exclude-rules": {
+ "description": "Exclude configuration per-path, per-linter, per-text and per-source",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "path": {
+ "type": "string"
+ },
+ "path-except": {
+ "type": "string"
+ },
+ "linters": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linters"
+ }
+ },
+ "text": {
+ "type": "string"
+ },
+ "source": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "exclude-use-default": {
+ "description": "Independently from option `exclude` we use default exclude patterns. This behavior can be disabled by this option.",
+ "type": "boolean",
+ "default": true
+ },
+ "exclude-case-sensitive": {
+ "description": "If set to true, exclude and exclude-rules regular expressions become case sensitive.",
+ "type": "boolean",
+ "default": false
+ },
+ "exclude-generated-strict": {
+ "description": "To follow strict Go generated file convention",
+ "type": "boolean",
+ "default": false
+ },
+ "exclude-dirs": {
+ "description": "Which directories to exclude: issues from them won't be reported.",
+ "type": "array",
+ "items": {
+ "description": "You can use regexp here. The regexp is applied on the full path.\n\"/\" will be replaced by current OS file path separator to properly work on Windows.",
+ "type": "string",
+ "examples": ["generated.*"]
+ },
+ "default": [],
+ "examples": [["src/external_libs", "autogenerated_by_my_lib"]]
+ },
+ "exclude-dirs-use-default": {
+ "description": "Enable exclusion of directories \"vendor\", \"third_party\", \"testdata\", \"examples\", \"Godeps\", and \"builtin\".",
+ "type": "boolean",
+ "default": true
+ },
+ "exclude-files": {
+ "description": "Which files to exclude: they will be analyzed, but issues from them will not be reported.",
+ "type": "array",
+ "items": {
+ "description": "You can use regexp here. There is no need to include all autogenerated files, we confidently recognize them. If that is not the case, please let us know.\n\"/\" will be replaced by current OS file path separator to properly work on Windows.",
+ "type": "string",
+ "examples": [".*\\.my\\.go$"]
+ },
+ "default": [],
+ "examples": [[".*\\.my\\.go$", "lib/bad.go"]]
+ },
+ "include": {
+ "description": "The list of ids of default excludes to include or disable.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "default": []
+ },
+ "max-issues-per-linter": {
+ "description": "Maximum issues count per one linter. Set to 0 to disable.",
+ "type": "integer",
+ "default": 50,
+ "minimum": 0
+ },
+ "max-same-issues": {
+ "description": "Maximum count of issues with the same text. Set to 0 to disable.",
+ "type": "integer",
+ "default": 3,
+ "minimum": 0
+ },
+ "new": {
+ "description": "Show only new issues: if there are unstaged changes or untracked files, only those changes are analyzed, else only changes in HEAD~ are analyzed.",
+ "type": "boolean",
+ "default": false
+ },
+ "new-from-rev": {
+ "description": "Show only new issues created after this git revision.",
+ "type": "string"
+ },
+ "new-from-patch": {
+ "description": "Show only new issues created in git patch with this file path.",
+ "type": "string",
+ "examples": ["path/to/patch/file"]
+ },
+ "fix": {
+ "description": "Fix found issues (if it's supported by the linter).",
+ "type": "boolean",
+ "default": false
+ },
+ "whole-files": {
+ "description": "Show issues in any part of update files (requires new-from-rev or new-from-patch).",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "severity": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "default-severity": {
+ "description": "Set the default severity for issues. If severity rules are defined and the issues do not match or no severity is provided to the rule this will be the default severity applied. Severities should match the supported severity names of the selected out format.",
+ "type": "string",
+ "default": ""
+ },
+ "case-sensitive": {
+ "description": "If set to true, severity-rules regular expressions become case sensitive.",
+ "type": "boolean",
+ "default": false
+ },
+ "rules": {
+ "description": "When a list of severity rules are provided, severity information will be added to lint issues. Severity rules have the same filtering capability as exclude rules except you are allowed to specify one matcher per severity rule.\nOnly affects out formats that support setting severity information.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "severity": {
+ "type": "string"
+ },
+ "path": {
+ "type": "string"
+ },
+ "path-except": {
+ "type": "string"
+ },
+ "linters": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linters"
+ }
+ },
+ "text": {
+ "type": "string"
+ },
+ "source": {
+ "type": "string"
+ }
+ },
+ "required": ["severity"],
+ "anyOf": [
+ { "required": ["path"] },
+ { "required": ["path-except"] },
+ { "required": ["linters"] },
+ { "required": ["text"] },
+ { "required": ["source"] }
+ ]
+ },
+ "default": []
+ }
+ },
+ "required": ["default-severity"]
+ }
+ }
+}
diff --git a/vendor/github.com/golangci/golangci-lint/v2/jsonschema/golangci.v1.58.jsonschema.json b/vendor/github.com/golangci/golangci-lint/v2/jsonschema/golangci.v1.58.jsonschema.json
new file mode 100644
index 000000000..d0bdc8d7b
--- /dev/null
+++ b/vendor/github.com/golangci/golangci-lint/v2/jsonschema/golangci.v1.58.jsonschema.json
@@ -0,0 +1,3638 @@
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "$id": "https://json.schemastore.org/golangci-lint.json",
+ "definitions": {
+ "gocritic-checks": {
+ "enum": [
+ "appendAssign",
+ "appendCombine",
+ "argOrder",
+ "assignOp",
+ "badCall",
+ "badCond",
+ "badLock",
+ "badRegexp",
+ "badSorting",
+ "boolExprSimplify",
+ "builtinShadow",
+ "builtinShadowDecl",
+ "captLocal",
+ "caseOrder",
+ "codegenComment",
+ "commentedOutCode",
+ "commentedOutImport",
+ "commentFormatting",
+ "defaultCaseOrder",
+ "deferUnlambda",
+ "deferInLoop",
+ "deprecatedComment",
+ "docStub",
+ "dupArg",
+ "dupBranchBody",
+ "dupCase",
+ "dupImport",
+ "dupSubExpr",
+ "dynamicFmtString",
+ "elseif",
+ "emptyDecl",
+ "emptyFallthrough",
+ "emptyStringTest",
+ "equalFold",
+ "evalOrder",
+ "exitAfterDefer",
+ "exposedSyncMutex",
+ "externalErrorReassign",
+ "filepathJoin",
+ "flagDeref",
+ "flagName",
+ "hexLiteral",
+ "httpNoBody",
+ "hugeParam",
+ "ifElseChain",
+ "importShadow",
+ "indexAlloc",
+ "initClause",
+ "ioutilDeprecated",
+ "mapKey",
+ "methodExprCall",
+ "nestingReduce",
+ "newDeref",
+ "nilValReturn",
+ "octalLiteral",
+ "offBy1",
+ "paramTypeCombine",
+ "preferDecodeRune",
+ "preferFilepathJoin",
+ "preferFprint",
+ "preferStringWriter",
+ "preferWriteByte",
+ "ptrToRefParam",
+ "rangeExprCopy",
+ "rangeValCopy",
+ "redundantSprint",
+ "regexpMust",
+ "regexpPattern",
+ "regexpSimplify",
+ "returnAfterHttpError",
+ "ruleguard",
+ "singleCaseSwitch",
+ "sliceClear",
+ "sloppyLen",
+ "sloppyReassign",
+ "sloppyTypeAssert",
+ "sortSlice",
+ "sprintfQuotedString",
+ "sqlQuery",
+ "stringConcatSimplify",
+ "stringsCompare",
+ "stringXbytes",
+ "suspiciousSorting",
+ "switchTrue",
+ "syncMapLoadAndDelete",
+ "timeCmpSimplify",
+ "timeExprSimplify",
+ "tooManyResultsChecker",
+ "truncateCmp",
+ "typeAssertChain",
+ "typeDefFirst",
+ "typeSwitchVar",
+ "typeUnparen",
+ "uncheckedInlineErr",
+ "underef",
+ "unlabelStmt",
+ "unlambda",
+ "unnamedResult",
+ "unnecessaryBlock",
+ "unnecessaryDefer",
+ "unslice",
+ "valSwap",
+ "weakCond",
+ "whyNoLint",
+ "wrapperFunc",
+ "yodaStyleExpr"
+ ]
+ },
+ "gocritic-tags": {
+ "enum": [
+ "diagnostic",
+ "style",
+ "performance",
+ "experimental",
+ "opinionated",
+ "security"
+ ]
+ },
+ "gosec-rules": {
+ "enum": [
+ "G101",
+ "G102",
+ "G103",
+ "G104",
+ "G106",
+ "G107",
+ "G108",
+ "G109",
+ "G110",
+ "G111",
+ "G112",
+ "G113",
+ "G114",
+ "G201",
+ "G202",
+ "G203",
+ "G204",
+ "G301",
+ "G302",
+ "G303",
+ "G304",
+ "G305",
+ "G306",
+ "G307",
+ "G401",
+ "G402",
+ "G403",
+ "G404",
+ "G501",
+ "G502",
+ "G503",
+ "G504",
+ "G505",
+ "G601",
+ "G602"
+ ]
+ },
+ "govet-analyzers": {
+ "enum": [
+ "appends",
+ "asmdecl",
+ "assign",
+ "atomic",
+ "atomicalign",
+ "bools",
+ "buildtag",
+ "cgocall",
+ "composites",
+ "copylocks",
+ "deepequalerrors",
+ "defers",
+ "directive",
+ "errorsas",
+ "fieldalignment",
+ "findcall",
+ "framepointer",
+ "httpresponse",
+ "ifaceassert",
+ "loopclosure",
+ "lostcancel",
+ "nilfunc",
+ "nilness",
+ "printf",
+ "reflectvaluecompare",
+ "shadow",
+ "shift",
+ "sigchanyzer",
+ "slog",
+ "sortslice",
+ "stdmethods",
+ "stringintconv",
+ "structtag",
+ "testinggoroutine",
+ "tests",
+ "unmarshal",
+ "unreachable",
+ "unsafeptr",
+ "unusedresult",
+ "unusedwrite"
+ ]
+ },
+ "linters": {
+ "$comment": "anyOf with enum is used to allow auto completion of non-custom linters",
+ "description": "Linters usable.",
+ "anyOf": [
+ {
+ "enum": [
+ "asasalint",
+ "asciicheck",
+ "bidichk",
+ "bodyclose",
+ "canonicalheader",
+ "containedctx",
+ "contextcheck",
+ "copyloopvar",
+ "cyclop",
+ "deadcode",
+ "decorder",
+ "depguard",
+ "dogsled",
+ "dupl",
+ "dupword",
+ "durationcheck",
+ "errcheck",
+ "errchkjson",
+ "errname",
+ "errorlint",
+ "execinquery",
+ "exhaustive",
+ "exhaustivestruct",
+ "exhaustruct",
+ "exportloopref",
+ "fatcontext",
+ "forbidigo",
+ "forcetypeassert",
+ "funlen",
+ "gci",
+ "ginkgolinter",
+ "gocheckcompilerdirectives",
+ "gochecknoglobals",
+ "gochecknoinits",
+ "gochecksumtype",
+ "gocognit",
+ "goconst",
+ "gocritic",
+ "gocyclo",
+ "godot",
+ "godox",
+ "err113",
+ "gofmt",
+ "gofumpt",
+ "goheader",
+ "goimports",
+ "golint",
+ "gomoddirectives",
+ "gomodguard",
+ "goprintffuncname",
+ "gosec",
+ "gosimple",
+ "gosmopolitan",
+ "govet",
+ "grouper",
+ "ifshort",
+ "importas",
+ "inamedparam",
+ "ineffassign",
+ "interfacebloat",
+ "interfacer",
+ "intrange",
+ "ireturn",
+ "lll",
+ "loggercheck",
+ "maintidx",
+ "makezero",
+ "maligned",
+ "mirror",
+ "misspell",
+ "mnd",
+ "musttag",
+ "nakedret",
+ "nestif",
+ "nilerr",
+ "nilnil",
+ "nlreturn",
+ "noctx",
+ "nolintlint",
+ "nonamedreturns",
+ "nosnakecase",
+ "nosprintfhostport",
+ "paralleltest",
+ "perfsprint",
+ "prealloc",
+ "predeclared",
+ "promlinter",
+ "protogetter",
+ "reassign",
+ "revive",
+ "rowserrcheck",
+ "scopelint",
+ "sloglint",
+ "sqlclosecheck",
+ "staticcheck",
+ "structcheck",
+ "stylecheck",
+ "tagalign",
+ "tagliatelle",
+ "tenv",
+ "testableexamples",
+ "testifylint",
+ "testpackage",
+ "thelper",
+ "tparallel",
+ "typecheck",
+ "unconvert",
+ "unparam",
+ "unused",
+ "usestdlibvars",
+ "varcheck",
+ "varnamelen",
+ "wastedassign",
+ "whitespace",
+ "wrapcheck",
+ "wsl",
+ "zerologlint"
+ ]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ }
+ },
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "run": {
+ "description": "Options for analysis running,",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "concurrency": {
+ "description": "Number of concurrent runners. Defaults to the number of available CPU cores.",
+ "type": "integer",
+ "minimum": 0,
+ "examples": [4]
+ },
+ "timeout": {
+ "description": "Timeout for the analysis.",
+ "type": "string",
+ "pattern": "^((\\d+h)?(\\d+m)?(\\d+(?:\\.\\d)?s)?|0)$",
+ "default": "1m",
+ "examples": ["30s", "5m", "5m30s"]
+ },
+ "issues-exit-code": {
+ "description": "Exit code when at least one issue was found.",
+ "type": "integer",
+ "default": 1
+ },
+ "tests": {
+ "description": "Enable inclusion of test files.",
+ "type": "boolean",
+ "default": true
+ },
+ "build-tags": {
+ "description": "List of build tags to pass to all linters.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "default": [],
+ "examples": [["mytag"]]
+ },
+ "modules-download-mode": {
+ "description": "Option to pass to \"go list -mod={option}\".\nSee \"go help modules\" for more information.",
+ "enum": ["mod", "readonly", "vendor"]
+ },
+ "allow-parallel-runners": {
+ "description": "Allow multiple parallel golangci-lint instances running. If disabled, golangci-lint acquires file lock on start.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-serial-runners": {
+ "description": "Allow multiple golangci-lint instances running, but serialize them around a lock.",
+ "type": "boolean",
+ "default": false
+ },
+ "go": {
+ "description": "Targeted Go version.",
+ "type": "string",
+ "default": "1.17"
+ }
+ }
+ },
+ "output": {
+ "description": "Output configuration options.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "formats": {
+ "description": "Output formats to use.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "path": {
+ "default": "stdout",
+ "anyOf": [
+ {
+ "enum": [ "stdout", "stderr" ]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ },
+ "format": {
+ "default": "colored-line-number",
+ "enum": [
+ "colored-line-number",
+ "line-number",
+ "json",
+ "colored-tab",
+ "tab",
+ "html",
+ "checkstyle",
+ "code-climate",
+ "junit-xml",
+ "github-actions",
+ "teamcity"
+ ]
+ }
+ },
+ "required": ["format"]
+ }
+ },
+ "print-issued-lines": {
+ "description": "Print lines of code with issue.",
+ "type": "boolean",
+ "default": true
+ },
+ "print-linter-name": {
+ "description": "Print linter name in the end of issue text.",
+ "type": "boolean",
+ "default": true
+ },
+ "uniq-by-line": {
+ "description": "Make issues output unique by line.",
+ "type": "boolean",
+ "default": true
+ },
+ "path-prefix": {
+ "description": "Add a prefix to the output file references.",
+ "type": "string",
+ "default": ""
+ },
+ "show-stats": {
+ "description": "Show statistics per linter.",
+ "type": "boolean",
+ "default": false
+ },
+ "sort-order": {
+ "type": "array",
+ "items": {
+ "enum": ["linter", "severity", "file"]
+ }
+ },
+ "sort-results": {
+ "description": "Sort results by: filepath, line and column.",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "linters-settings": {
+ "description": "All available settings of specific linters.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "dupword": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "keywords": {
+ "description": "Keywords for detecting duplicate words. If this list is not empty, only the words defined in this list will be detected.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["the", "and", "a"]
+ }
+ },
+ "ignore": {
+ "description": "Keywords used to ignore detection.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["0C0C"]
+ }
+ }
+ }
+ },
+ "asasalint": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "exclude": {
+ "description": "To specify a set of function names to exclude.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["\\.Wrapf"]
+ }
+ },
+ "use-builtin-exclusions": {
+ "description": "To enable/disable the asasalint builtin exclusions of function names.",
+ "type": "boolean",
+ "default": true
+ },
+ "ignore-test": {
+ "description": "Ignore *_test.go files.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "bidichk": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "left-to-right-embedding": {
+ "description": "Disallow: LEFT-TO-RIGHT-EMBEDDING",
+ "type": "boolean",
+ "default": false
+ },
+ "right-to-left-embedding": {
+ "description": "Disallow: RIGHT-TO-LEFT-EMBEDDING",
+ "type": "boolean",
+ "default": false
+ },
+ "pop-directional-formatting": {
+ "description": "Disallow: POP-DIRECTIONAL-FORMATTING",
+ "type": "boolean",
+ "default": false
+ },
+ "left-to-right-override": {
+ "description": "Disallow: LEFT-TO-RIGHT-OVERRIDE",
+ "type": "boolean",
+ "default": false
+ },
+ "right-to-left-override": {
+ "description": "Disallow: RIGHT-TO-LEFT-OVERRIDE",
+ "type": "boolean",
+ "default": false
+ },
+ "left-to-right-isolate": {
+ "description": "Disallow: LEFT-TO-RIGHT-ISOLATE",
+ "type": "boolean",
+ "default": false
+ },
+ "right-to-left-isolate": {
+ "description": "Disallow: RIGHT-TO-LEFT-ISOLATE",
+ "type": "boolean",
+ "default": false
+ },
+ "first-strong-isolate": {
+ "description": "Disallow: FIRST-STRONG-ISOLATE",
+ "type": "boolean",
+ "default": false
+ },
+ "pop-directional-isolate": {
+ "description": "Disallow: POP-DIRECTIONAL-ISOLATE",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "cyclop": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skip-tests": {
+ "description": "Should the linter execute on test files as well",
+ "type": "boolean",
+ "default": false
+ },
+ "max-complexity": {
+ "description": "Max complexity the function can have",
+ "type": "integer",
+ "default": 10,
+ "minimum": 0
+ },
+ "package-average": {
+ "description": "Max average complexity in package",
+ "type": "number",
+ "default": 0,
+ "minimum": 0
+ }
+ }
+ },
+ "decorder": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "dec-order": {
+ "type": "array",
+ "default": [["type", "const", "var", "func"]],
+ "items": {
+ "enum": ["type", "const", "var", "func"]
+ }
+ },
+ "ignore-underscore-vars": {
+ "description": "Underscore vars (vars with \"_\" as the name) will be ignored at all checks",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-dec-order-check": {
+ "description": "Order of declarations is not checked",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-init-func-first-check": {
+ "description": "Allow init func to be anywhere in file",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-dec-num-check": {
+ "description": "Multiple global type, const and var declarations are allowed",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-type-dec-num-check": {
+ "description": "Type declarations will be ignored for dec num check",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-const-dec-num-check": {
+ "description": "Const declarations will be ignored for dec num check",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-var-dec-num-check": {
+ "description": "Var declarations will be ignored for dec num check",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ },
+ "depguard": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "rules": {
+ "description": "Rules to apply.",
+ "type": "object",
+ "additionalProperties": false,
+ "patternProperties": {
+ "^[^.]+$": {
+ "description": "Name of a rule.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "list-mode": {
+ "description": "Used to determine the package matching priority.",
+ "enum": ["original", "strict", "lax"],
+ "default": "original"
+ },
+ "files": {
+ "description": "List of file globs that will match this list of settings to compare against.",
+ "additionalProperties": false,
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "allow": {
+ "description": "List of allowed packages.",
+ "additionalProperties": false,
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "deny": {
+ "description": "Packages that are not allowed where the value is a suggestion.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "desc": {
+ "description": "Description",
+ "type": "string"
+ },
+ "pkg": {
+ "description": "Package",
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "dogsled": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-blank-identifiers": {
+ "description": "Check assignments with too many blank identifiers.",
+ "type": "integer",
+ "default": 2,
+ "minimum": 0
+ }
+ }
+ },
+ "dupl": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "threshold": {
+ "description": "Tokens count to trigger issue.",
+ "type": "integer",
+ "default": 150,
+ "minimum": 0
+ }
+ }
+ },
+ "errcheck": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-type-assertions": {
+ "description": "Report about not checking errors in type assertions, i.e.: `a := b.(MyStruct)`",
+ "type": "boolean",
+ "default": false
+ },
+ "check-blank": {
+ "description": "Report about assignment of errors to blank identifier",
+ "type": "boolean",
+ "default": false
+ },
+ "exclude-functions": {
+ "description": "List of functions to exclude from checking, where each entry is a single function to exclude",
+ "type": "array",
+ "examples": ["io/ioutil.ReadFile", "io.Copy(*bytes.Buffer)"],
+ "items": {
+ "type": "string"
+ }
+ },
+ "disable-default-exclusions": {
+ "description": "To disable the errcheck built-in exclude list",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "errchkjson": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-error-free-encoding": {
+ "type": "boolean",
+ "default": false
+ },
+ "report-no-exported": {
+ "description": "Issue on struct that doesn't have exported fields.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "errorlint": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "errorf": {
+ "description": "Check whether fmt.Errorf uses the %w verb for formatting errors",
+ "type": "boolean",
+ "default": true
+ },
+ "errorf-multi": {
+ "description": "Permit more than 1 %w verb, valid per Go 1.20",
+ "type": "boolean",
+ "default": true
+ },
+ "asserts": {
+ "description": "Check for plain type assertions and type switches.",
+ "type": "boolean",
+ "default": true
+ },
+ "comparison": {
+ "description": "Check for plain error comparisons",
+ "type": "boolean",
+ "default": true
+ },
+ "allowed-errors": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "err": {
+ "type": "string"
+ },
+ "fun": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "allowed-errors-wildcard": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "err": {
+ "type": "string"
+ },
+ "fun": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "exhaustive": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check": {
+ "description": "Program elements to check for exhaustiveness.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["switch", "map"]
+ }
+ },
+ "check-generated": {
+ "description": "Check switch statements in generated files",
+ "type": "boolean",
+ "default": false
+ },
+ "explicit-exhaustive-switch": {
+ "description": "Only run exhaustive check on switches with \"//exhaustive:enforce\" comment.",
+ "type": "boolean",
+ "default": false
+ },
+ "explicit-exhaustive-map": {
+ "description": "Only run exhaustive check on map literals with \"//exhaustive:enforce\" comment.",
+ "type": "boolean",
+ "default": false
+ },
+ "default-case-required": {
+ "description": "Switch statement requires default case even if exhaustive.",
+ "type": "boolean",
+ "default": false
+ },
+ "default-signifies-exhaustive": {
+ "description": "Presence of `default` case in switch statements satisfies exhaustiveness, even if all enum members are not listed.",
+ "type": "boolean",
+ "default": false
+ },
+ "ignore-enum-members": {
+ "description": "Enum members matching `regex` do not have to be listed in switch statements to satisfy exhaustiveness",
+ "type": "string"
+ },
+ "ignore-enum-types": {
+ "description": "Enum types matching the supplied regex do not have to be listed in switch statements to satisfy exhaustiveness.",
+ "type": "string"
+ },
+ "package-scope-only": {
+ "description": "Consider enums only in package scopes, not in inner scopes.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "exhaustruct": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "include": {
+ "description": "List of regular expressions to match struct packages and names.",
+ "type": "array",
+ "examples": [".*\\.Test"],
+ "items": {
+ "type": "string"
+ }
+ },
+ "exclude": {
+ "description": "List of regular expressions to exclude struct packages and names from check.",
+ "type": "array",
+ "examples": ["cobra\\.Command$"],
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "forbidigo": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "exclude-godoc-examples": {
+ "description": "Exclude code in godoc examples.",
+ "type": "boolean",
+ "default": true
+ },
+ "analyze-types": {
+ "description": "Instead of matching the literal source code, use type information to replace expressions with strings that contain the package name and (for methods and fields) the type name.",
+ "type": "boolean",
+ "default": true
+ },
+ "forbid": {
+ "description": "List of identifiers to forbid (written using `regexp`)",
+ "type": "array",
+ "examples": ["^print.*$"],
+ "items": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "p": {
+ "description": "Pattern",
+ "type": "string"
+ },
+ "pkg": {
+ "description": "Package",
+ "type": "string"
+ },
+ "msg": {
+ "description": "Message",
+ "type": "string"
+ }
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ "funlen": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "lines": {
+ "description": "Limit lines number per function.",
+ "type": "integer",
+ "default": 60
+ },
+ "statements": {
+ "description": "Limit statements number per function.",
+ "type": "integer",
+ "default": 40
+ },
+ "ignore-comments": {
+ "description": "Ignore comments when counting lines.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "gci": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "sections": {
+ "description": "Section configuration to compare against.",
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "enum": [
+ "standard",
+ "default",
+ "blank",
+ "dot",
+ "alias",
+ "localmodule"
+ ]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ },
+ "default": ["standard", "default"]
+ },
+ "skip-generated": {
+ "description": "Skip generated files.",
+ "type": "boolean",
+ "default": true
+ },
+ "custom-order": {
+ "description": "Enable custom order of sections.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "ginkgolinter": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "suppress-len-assertion": {
+ "description": "Suppress the wrong length assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-nil-assertion": {
+ "description": "Suppress the wrong nil assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-err-assertion": {
+ "description": "Suppress the wrong error assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-compare-assertion": {
+ "description": "Suppress the wrong comparison assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-async-assertion": {
+ "description": "Suppress the function all in async assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-type-compare-assertion": {
+ "description": "Suppress warning for comparing values from different types, like int32 and uint32.",
+ "type": "boolean",
+ "default": false
+ },
+ "forbid-focus-container": {
+ "description": "Trigger warning for ginkgo focus containers like FDescribe, FContext, FWhen or FIt.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-havelen-zero": {
+ "description": "Don't trigger warnings for HaveLen(0).",
+ "type": "boolean",
+ "default": false
+ },
+ "force-expect-to": {
+ "description": "Force using `Expect` with `To`, `ToNot` or `NotTo`",
+ "type": "boolean",
+ "default": false
+ },
+ "validate-async-intervals": {
+ "description": "Best effort validation of async intervals (timeout and polling).",
+ "type": "boolean",
+ "default": false
+ },
+ "forbid-spec-pollution": {
+ "description": "Trigger a warning for variable assignments in ginkgo containers like `Describe`, `Context` and `When`, instead of in `BeforeEach()`.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "gocognit": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "min-complexity": {
+ "description": "Minimal code complexity to report (we recommend 10-20).",
+ "type": "integer",
+ "default": 30
+ }
+ }
+ },
+ "goconst": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "match-constant": {
+ "description": "Look for existing constants matching the values",
+ "type": "boolean",
+ "default": true
+ },
+ "min-len": {
+ "description": "Minimum length of string constant.",
+ "type": "integer",
+ "default": 3
+ },
+ "min-occurrences": {
+ "description": "Minimum occurrences count to trigger.",
+ "type": "integer",
+ "default": 3
+ },
+ "ignore-tests": {
+ "description": "Ignore test files.",
+ "type": "boolean",
+ "default": false
+ },
+ "ignore-calls": {
+ "description": "Ignore when constant is not used as function argument",
+ "type": "boolean",
+ "default": true
+ },
+ "ignore-strings": {
+ "description": "Exclude strings matching the given regular expression",
+ "type": "string"
+ },
+ "numbers": {
+ "description": "Search also for duplicated numbers.",
+ "type": "boolean",
+ "default": false
+ },
+ "min": {
+ "description": "Minimum value, only works with `numbers`",
+ "type": "integer",
+ "default": 3
+ },
+ "max": {
+ "description": "Maximum value, only works with `numbers`",
+ "type": "integer",
+ "default": 3
+ }
+ }
+ },
+ "gocritic": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "enabled-checks": {
+ "description": "Which checks should be enabled. By default, a list of stable checks is used. To see it, run `GL_DEBUG=gocritic golangci-lint run`.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/gocritic-checks"
+ }
+ },
+ "disabled-checks": {
+ "description": "Which checks should be disabled.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/gocritic-checks"
+ },
+ "default": []
+ },
+ "enabled-tags": {
+ "description": "Enable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/gocritic-tags"
+ }
+ },
+ "disabled-tags": {
+ "description": "Disable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/gocritic-tags"
+ }
+ },
+ "settings": {
+ "description": "Settings passed to gocritic. Properties must be valid and enabled check names.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "captLocal": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "paramsOnly" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "commentedOutCode": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "minLength" : {
+ "type": "number",
+ "default": 15
+ }
+ }
+ },
+ "elseif": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skipBalanced" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "hugeParam": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "sizeThreshold" : {
+ "type": "number",
+ "default": 80
+ }
+ }
+ },
+ "ifElseChain": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "minThreshold" : {
+ "type": "number",
+ "default": 2
+ }
+ }
+ },
+ "nestingReduce": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "bodyWidth" : {
+ "type": "number",
+ "default": 5
+ }
+ }
+ },
+ "rangeExprCopy": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "sizeThreshold" : {
+ "type": "number",
+ "default": 512
+ },
+ "skipTestFuncs" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "rangeValCopy": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "sizeThreshold" : {
+ "type": "number",
+ "default": 128
+ },
+ "skipTestFuncs" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "ruleguard": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "debug" : {
+ "type": "string"
+ },
+ "enable" : {
+ "type": "string"
+ },
+ "disable" : {
+ "type": "string"
+ },
+ "failOn" : {
+ "type": "string"
+ },
+ "rules" : {
+ "type": "string"
+ }
+ }
+ },
+ "tooManyResultsChecker": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "maxResults" : {
+ "type": "number",
+ "default": 5
+ }
+ }
+ },
+ "truncateCmp": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skipArchDependent" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "underef": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skipRecvDeref" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "unnamedResult": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "checkExported" : {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ }
+ }
+ },
+ "disable-all": {
+ "type": "boolean",
+ "default": false
+ },
+ "enable-all": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "gocyclo": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "min-complexity": {
+ "description": "Minimum code complexity to report (we recommend 10-20).",
+ "type": "integer",
+ "default": 30
+ }
+ }
+ },
+ "godot": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "scope": {
+ "description": "Comments to be checked.",
+ "enum": ["declarations", "toplevel", "all"],
+ "default": "declarations"
+ },
+ "exclude": {
+ "description": "List of regexps for excluding particular comment lines from check.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "period": {
+ "description": "Check that each sentence ends with a period.",
+ "type": "boolean",
+ "default": true
+ },
+ "capital": {
+ "description": "Check that each sentence starts with a capital letter.",
+ "type": "boolean",
+ "default": false
+ },
+ "check-all": {
+ "description": "DEPRECATED: Check all top-level comments, not only declarations.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "godox": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "keywords": {
+ "description": "Report any comments starting with one of these keywords. This is useful for TODO or FIXME comments that might be left in the code accidentally and should be resolved before merging.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "default": ["TODO", "BUG", "FIXME"]
+ }
+ }
+ },
+ "gofmt": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "simplify": {
+ "description": "Simplify code.",
+ "type": "boolean",
+ "default": true
+ },
+ "rewrite-rules": {
+ "description": "Apply the rewrite rules to the source before reformatting.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "pattern": {
+ "type": "string"
+ },
+ "replacement": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "interfacebloat": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max": {
+ "description": "The maximum number of methods allowed for an interface.",
+ "type": "integer"
+ }
+ }
+ },
+ "gofumpt": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "extra-rules": {
+ "description": "Choose whether or not to use the extra rules that are disabled by default.",
+ "type": "boolean",
+ "default": false
+ },
+ "module-path": {
+ "description": " Module path which contains the source code being formatted.",
+ "type": "string"
+ }
+ }
+ },
+ "goheader": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "values": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "const": {
+ "description": "Constants to use in the template.",
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "description": "Value for the constant.",
+ "type": "string"
+ }
+ },
+ "additionalProperties": false,
+ "examples": [
+ {
+ "YEAR": "2030",
+ "COMPANY": "MY FUTURISTIC COMPANY"
+ }
+ ]
+ },
+ "regexp": {
+ "description": "Regular expressions to use in your template.",
+ "type": "object",
+ "additionalProperties": false,
+ "patternProperties": {
+ "^.+$": {
+ "type": "string"
+ }
+ },
+ "examples": [
+ {
+ "AUTHOR": ".*@mycompany\\.com"
+ }
+ ]
+ }
+ }
+ },
+ "template": {
+ "description": "Template to put on top of every file.",
+ "type": "string",
+ "examples": [
+ "{{ MY COMPANY }}\nSPDX-License-Identifier: Apache-2.0\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at:\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License."
+ ]
+ },
+ "template-path": {
+ "description": "Path to the file containing the template source.",
+ "type": "string",
+ "examples": ["my_header_template.txt"]
+ }
+ },
+ "oneOf": [
+ { "required": ["template"] },
+ { "required": ["template-path"] }
+ ]
+ },
+ "goimports": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "local-prefixes": {
+ "description": "Put imports beginning with prefix after 3rd-party packages. It is a comma-separated list of prefixes.",
+ "type": "string",
+ "examples": ["github.com/org/project"]
+ }
+ }
+ },
+ "gomoddirectives": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "replace-local": {
+ "description": "Allow local `replace` directives.",
+ "type": "boolean",
+ "default": true
+ },
+ "replace-allow-list": {
+ "description": "List of allowed `replace` directives.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "retract-allow-no-explanation": {
+ "description": "Allow to not explain why the version has been retracted in the `retract` directives.",
+ "type": "boolean",
+ "default": true
+ },
+ "exclude-forbidden": {
+ "description": "Forbid the use of the `exclude` directives.",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "gomodguard": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "allowed": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "modules": {
+ "description": "List of allowed modules.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["gopkg.in/yaml.v2"]
+ }
+ },
+ "domains": {
+ "description": "List of allowed module domains.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["golang.org"]
+ }
+ }
+ }
+ },
+ "blocked": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "modules": {
+ "description": "List of blocked modules.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "recommendations": {
+ "description": "Recommended modules that should be used instead.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "reason": {
+ "description": "Reason why the recommended module should be used.",
+ "type": "string"
+ }
+ }
+ }
+ },
+ "additionalProperties": false
+ }
+ },
+ "versions": {
+ "description": "List of blocked module version constraints.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "patternProperties": {
+ "^.*$": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "version": {
+ "description": "Version constraint.",
+ "type": "string"
+ },
+ "reason": {
+ "description": "Reason why the version constraint exists.",
+ "type": "string"
+ }
+ },
+ "required": ["reason"]
+ }
+ }
+ }
+ },
+ "local_replace_directives": {
+ "description": "Raise lint issues if loading local path with replace directive",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ }
+ }
+ },
+ "gosimple": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "checks": {
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "enum": ["all"]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ }
+ }
+ }
+ },
+ "gosec": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "includes": {
+ "type": "array",
+ "description": "To select a subset of rules to run",
+ "examples": [["G401"]],
+ "items": {
+ "$ref": "#/definitions/gosec-rules"
+ }
+ },
+ "excludes": {
+ "type": "array",
+ "description": "To specify a set of rules to explicitly exclude",
+ "examples": [["G401"]],
+ "items": {
+ "$ref": "#/definitions/gosec-rules"
+ }
+ },
+ "exclude-generated": {
+ "description": "Exclude generated files",
+ "type": "boolean",
+ "default": false
+ },
+ "severity": {
+ "description": "Filter out the issues with a lower severity than the given value",
+ "type": "string",
+ "enum": ["low", "medium", "high"],
+ "default": "low"
+ },
+ "confidence": {
+ "description": "Filter out the issues with a lower confidence than the given value",
+ "type": "string",
+ "enum": ["low", "medium", "high"],
+ "default": "low"
+ },
+ "config": {
+ "description": "To specify the configuration of rules",
+ "type": "object"
+ },
+ "concurrency": {
+ "description": "Concurrency value",
+ "type": "integer"
+ }
+ }
+ },
+ "gosmopolitan": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "allow-time-local": {
+ "description": "Allow and ignore `time.Local` usages.",
+ "type": "boolean",
+ "default": false
+ },
+ "escape-hatches": {
+ "description": "List of fully qualified names in the `full/pkg/path.name` form, to act as \"i18n escape hatches\".",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignore-tests": {
+ "description": "Ignore test files.",
+ "type": "boolean",
+ "default": false
+ },
+ "watch-for-scripts": {
+ "description": "List of Unicode scripts to watch for any usage in string literals.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "govet": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "settings": {
+ "description": "Settings per analyzer. Map of analyzer name to specific settings.\nRun `go tool vet help` to find out more.",
+ "type": "object",
+ "propertyNames": {
+ "$ref": "#/definitions/govet-analyzers"
+ },
+ "patternProperties": {
+ "^.*$": {
+ "description": "Run `go tool vet help ` to see all settings.",
+ "type": "object"
+ }
+ }
+ },
+ "enable": {
+ "description": "Enable analyzers by name.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/govet-analyzers"
+ }
+ },
+ "disable": {
+ "description": "Disable analyzers by name.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/govet-analyzers"
+ }
+ },
+ "enable-all": {
+ "description": "Enable all analyzers.",
+ "type": "boolean",
+ "default": false
+ },
+ "disable-all": {
+ "description": "Disable all analyzers.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "grouper": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "const-require-single-const": {
+ "type": "boolean",
+ "default": false
+ },
+ "const-require-grouping": {
+ "type": "boolean",
+ "default": false
+ },
+ "import-require-single-import": {
+ "type": "boolean",
+ "default": false
+ },
+ "import-require-grouping": {
+ "type": "boolean",
+ "default": false
+ },
+ "type-require-single-type": {
+ "type": "boolean",
+ "default": false
+ },
+ "type-require-grouping": {
+ "type": "boolean",
+ "default": false
+ },
+ "var-require-single-var": {
+ "type": "boolean",
+ "default": false
+ },
+ "var-require-grouping": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "importas": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "no-unaliased": {
+ "description": "Do not allow unaliased imports of aliased packages.",
+ "type": "boolean",
+ "default": false
+ },
+ "no-extra-aliases": {
+ "description": "Do not allow non-required aliases.",
+ "type": "boolean",
+ "default": false
+ },
+ "alias": {
+ "description": "List of aliases",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "pkg": {
+ "description": "Package path e.g. knative.dev/serving/pkg/apis/autoscaling/v1alpha1",
+ "type": "string"
+ },
+ "alias": {
+ "description": "Package alias e.g. autoscalingv1alpha1",
+ "type": "string"
+ }
+ },
+ "required": ["pkg", "alias"]
+ }
+ }
+ }
+ },
+ "inamedparam": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skip-single-param": {
+ "description": "Skips check for interface methods with only a single parameter.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "ireturn": {
+ "type": "object",
+ "additionalProperties": false,
+ "description": "Use either `reject` or `allow` properties for interfaces matching.",
+ "properties": {
+ "allow": {
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "enum": ["anon", "error", "empty", "stdlib"]
+ }
+ ]
+ }
+ },
+ "reject": {
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "enum": ["anon", "error", "empty", "stdlib"]
+ }
+ ]
+ }
+ }
+ },
+ "anyOf": [
+ {
+ "not": {
+ "properties": {
+ "allow": {
+ "const": "reject"
+ }
+ }
+ },
+ "required": ["allow"]
+ },
+ {
+ "required": ["reject"]
+ }
+ ]
+ },
+ "lll": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "tab-width": {
+ "description": "Width of \"\\t\" in spaces.",
+ "type": "integer",
+ "minimum": 0,
+ "default": 1
+ },
+ "line-length": {
+ "description": "Maximum allowed line length, lines longer will be reported.",
+ "type": "integer",
+ "minimum": 1,
+ "default": 120
+ }
+ }
+ },
+ "maintidx": {
+ "description": "Maintainability index https://docs.microsoft.com/en-us/visualstudio/code-quality/code-metrics-maintainability-index-range-and-meaning?view=vs-2022",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "under": {
+ "description": "Minimum accatpable maintainability index level (see https://docs.microsoft.com/en-us/visualstudio/code-quality/code-metrics-maintainability-index-range-and-meaning?view=vs-2022)",
+ "type": "number",
+ "default": 20
+ }
+ }
+ },
+ "makezero": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "always": {
+ "description": "Allow only slices initialized with a length of zero.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "loggercheck": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "kitlog": {
+ "description": "Allow check for the github.com/go-kit/log library.",
+ "type": "boolean",
+ "default": true
+ },
+ "klog": {
+ "description": "Allow check for the k8s.io/klog/v2 library.",
+ "type": "boolean",
+ "default": true
+ },
+ "logr": {
+ "description": "Allow check for the github.com/go-logr/logr library.",
+ "type": "boolean",
+ "default": true
+ },
+ "zap": {
+ "description": "Allow check for the \"sugar logger\" from go.uber.org/zap library.",
+ "type": "boolean",
+ "default": true
+ },
+ "require-string-key": {
+ "description": "Require all logging keys to be inlined constant strings.",
+ "type": "boolean",
+ "default": false
+ },
+ "no-printf-like": {
+ "description": "Require printf-like format specifier (%s, %d for example) not present.",
+ "type": "boolean",
+ "default": false
+ },
+ "rules": {
+ "description": "List of custom rules to check against, where each rule is a single logger pattern, useful for wrapped loggers.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "misspell": {
+ "description": "Correct spellings using locale preferences for US or UK. Default is to use a neutral variety of English.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "locale": {
+ "enum": ["US", "UK"]
+ },
+ "ignore-words": {
+ "description": "List of words to ignore.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "mode": {
+ "description": "Mode of the analysis.",
+ "enum": ["restricted", "", "default"],
+ "default": ""
+ },
+ "extra-words": {
+ "description": "Extra word corrections.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "correction": {
+ "type": "string"
+ },
+ "typo": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "musttag": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "functions": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "tag": {
+ "type": "string"
+ },
+ "arg-pos": {
+ "type": "integer"
+ }
+ }
+ }
+ }
+ }
+ },
+ "nakedret": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-func-lines": {
+ "description": "Report if a function has more lines of code than this value and it has naked returns.",
+ "type": "integer",
+ "minimum": 0,
+ "default": 30
+ }
+ }
+ },
+ "nestif": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "min-complexity": {
+ "description": "Minimum complexity of \"if\" statements to report.",
+ "type": "integer",
+ "default": 5
+ }
+ }
+ },
+ "nilnil": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "checked-types": {
+ "type": "array",
+ "description": "Order of return types to check.",
+ "items": {
+ "enum": ["ptr", "func", "iface", "map", "chan"]
+ },
+ "default": ["ptr", "func", "iface", "map", "chan"]
+ }
+ }
+ },
+ "nlreturn": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "block-size": {
+ "description": "set block size that is still ok",
+ "type": "number",
+ "default": 0,
+ "minimum": 0
+ }
+ }
+ },
+ "mnd": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignored-files": {
+ "description": "List of file patterns to exclude from analysis.",
+ "examples": [["magic1_.*.go"]],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignored-functions": {
+ "description": "Comma-separated list of function patterns to exclude from the analysis.",
+ "examples": [["math.*", "http.StatusText", "make"]],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignored-numbers": {
+ "description": "List of numbers to exclude from analysis.",
+ "examples": [["1000", "1234_567_890", "3.14159264"]],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "checks": {
+ "description": "The list of enabled checks, see https://github.com/tommy-muehle/go-mnd/#checks for description.",
+ "type": "array",
+ "items": {
+ "enum": [
+ "argument",
+ "case",
+ "condition",
+ "operation",
+ "return",
+ "assign"
+ ]
+ }
+ }
+ }
+ },
+ "nolintlint": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "allow-unused": {
+ "description": "Enable to ensure that nolint directives are all used.",
+ "type": "boolean",
+ "default": true
+ },
+ "allow-no-explanation": {
+ "description": "Exclude these linters from requiring an explanation.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linters"
+ },
+ "default": []
+ },
+ "require-explanation": {
+ "description": "Enable to require an explanation of nonzero length after each nolint directive.",
+ "type": "boolean",
+ "default": false
+ },
+ "require-specific": {
+ "description": "Enable to require nolint directives to mention the specific linter being suppressed.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "reassign": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "patterns": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "nonamedreturns": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "report-error-in-defer": {
+ "description": "Report named error if it is assigned inside defer.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "paralleltest": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignore-missing": {
+ "description": "Ignore missing calls to `t.Parallel()` and only report incorrect uses of it.",
+ "type": "boolean",
+ "default": false
+ },
+ "ignore-missing-subtests": {
+ "description": "Ignore missing calls to `t.Parallel()` in subtests. Top-level tests are still required to have `t.Parallel`, but subtests are allowed to skip it.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "perfsprint": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "int-conversion": {
+ "description": "Optimizes even if it requires an int or uint type cast.",
+ "type": "boolean",
+ "default": true
+ },
+ "err-error": {
+ "description": "Optimizes into `err.Error()` even if it is only equivalent for non-nil errors.",
+ "type": "boolean",
+ "default": false
+ },
+ "errorf": {
+ "description": "Optimizes `fmt.Errorf`.",
+ "type": "boolean",
+ "default": true
+ },
+ "sprintf1": {
+ "description": "Optimizes `fmt.Sprintf` with only one argument.",
+ "type": "boolean",
+ "default": true
+ },
+ "strconcat": {
+ "description": "Optimizes into strings concatenation.",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "prealloc": {
+ "description": "We do not recommend using this linter before doing performance profiling.\nFor most programs usage of `prealloc` will be premature optimization.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "simple": {
+ "description": "Report preallocation suggestions only on simple loops that have no returns/breaks/continues/gotos in them.",
+ "type": "boolean",
+ "default": true
+ },
+ "range-loops": {
+ "description": "Report preallocation suggestions on range loops.",
+ "type": "boolean",
+ "default": true
+ },
+ "for-loops": {
+ "description": "Report preallocation suggestions on for loops.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "predeclared": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignore": {
+ "description": "Comma-separated list of predeclared identifiers to not report on.",
+ "type": "string"
+ },
+ "q": {
+ "description": "Include method names and field names (i.e., qualified names) in checks.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "promlinter": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "strict": {},
+ "disabled-linters": {
+ "type": "array",
+ "items": {
+ "enum": [
+ "Help",
+ "MetricUnits",
+ "Counter",
+ "HistogramSummaryReserved",
+ "MetricTypeInName",
+ "ReservedChars",
+ "CamelCase",
+ "UnitAbbreviations"
+ ]
+ }
+ }
+ }
+ },
+ "protogetter": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skip-generated-by": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["protoc-gen-go-my-own-generator"]
+ }
+ },
+ "skip-files": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["*.pb.go"]
+ }
+ },
+ "skip-any-generated": {
+ "description": "Skip any generated files from the checking.",
+ "type": "boolean",
+ "default": false
+ },
+ "replace-first-arg-in-append": {
+ "description": "Skip first argument of append function.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "revive": {
+ "type": "object",
+ "additionalProperties": false,
+ "examples": [
+ {
+ "ignore-generated-header": true,
+ "severity": "warning",
+ "rules": [
+ {
+ "name": "indent-error-flow",
+ "severity": "warning"
+ },
+ {
+ "name": "add-constant",
+ "severity": "warning",
+ "arguments": [
+ {
+ "maxLitCount": "3",
+ "allowStrs": "\"\"",
+ "allowInts": "0,1,2",
+ "allowFloats": "0.0,0.,1.0,1.,2.0,2."
+ }
+ ]
+ }
+ ]
+ }
+ ],
+ "properties": {
+ "max-open-files": {
+ "type": "integer"
+ },
+ "ignore-generated-header": {
+ "type": "boolean"
+ },
+ "confidence": {
+ "type": "number"
+ },
+ "severity": {
+ "type": "string",
+ "enum": ["warning", "error"]
+ },
+ "enable-all-rules": {
+ "type": "boolean",
+ "default": false
+ },
+ "directives": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "name": {
+ "type": "string",
+ "enum": ["specify-disable-reason"]
+ },
+ "severity": {
+ "type": "string",
+ "enum": ["warning", "error"]
+ },
+ "exclude": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "arguments": {
+ "type": "array"
+ }
+ }
+ }
+ },
+ "rules": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["name"],
+ "properties": {
+ "name": {
+ "type": "string",
+ "title": "The rule name"
+ },
+ "disabled": {
+ "type": "boolean"
+ },
+ "severity": {
+ "type": "string",
+ "enum": ["warning", "error"]
+ },
+ "exclude": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "arguments": {
+ "type": "array"
+ }
+ }
+ }
+ }
+ }
+ },
+ "rowserrcheck": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "packages": {
+ "type": "array",
+ "items": {
+ "description": "",
+ "type": "string",
+ "examples": ["github.com/jmoiron/sqlx"]
+ }
+ }
+ }
+ },
+ "sloglint": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "kv-only": {
+ "description": "Enforce using key-value pairs only (incompatible with attr-only).",
+ "type": "boolean",
+ "default": false
+ },
+ "no-global": {
+ "description": "Enforce not using global loggers.",
+ "enum": ["", "all", "default"],
+ "default": ""
+ },
+ "no-mixed-args": {
+ "description": "Enforce not mixing key-value pairs and attributes.",
+ "type": "boolean",
+ "default": true
+ },
+ "context": {
+ "description": "Enforce using methods that accept a context.",
+ "enum": ["", "all", "scope"],
+ "default": ""
+ },
+ "static-msg": {
+ "description": "Enforce using static values for log messages.",
+ "type": "boolean",
+ "default": false
+ },
+ "key-naming-case": {
+ "description": "Enforce a single key naming convention.",
+ "enum": ["snake", "kebab", "camel", "pascal"]
+ },
+ "attr-only": {
+ "description": "Enforce using attributes only (incompatible with kv-only).",
+ "type": "boolean",
+ "default": false
+ },
+ "no-raw-keys": {
+ "description": "Enforce using constants instead of raw keys.",
+ "type": "boolean",
+ "default": false
+ },
+ "args-on-sep-lines": {
+ "description": "Enforce putting arguments on separate lines.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "spancheck": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "checks": {
+ "description": "Checks to enable.",
+ "type": "array",
+ "items": {
+ "enum": ["end", "record-error", "set-status"]
+ }
+ },
+ "ignore-check-signatures": {
+ "description": "A list of regexes for function signatures that silence `record-error` and `set-status` reports if found in the call path to a returned error.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "extra-start-span-signatures": {
+ "description": "A list of regexes for additional function signatures that create spans.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "staticcheck": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "checks": {
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "enum": ["all"]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ }
+ }
+ }
+ },
+ "stylecheck": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "checks": {
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "enum": ["all"]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ },
+ "default": [
+ "all",
+ "-ST1000",
+ "-ST1003",
+ "-ST1016",
+ "-ST1020",
+ "-ST1021",
+ "-ST1022"
+ ]
+ },
+ "dot-import-whitelist": {
+ "description": "By default, ST1001 forbids all uses of dot imports in non-test packages. This setting allows setting a whitelist of import paths that can be dot-imported anywhere.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "http-status-code-whitelist": {
+ "description": "ST1013 recommends using constants from the net/http package instead of hard-coding numeric HTTP status codes. This setting specifies a list of numeric status codes that this check does not complain about.",
+ "default": ["200", "400", "404", "500"],
+ "type": "array",
+ "items": {
+ "enum": [
+ "100",
+ "101",
+ "102",
+ "103",
+ "200",
+ "201",
+ "202",
+ "203",
+ "204",
+ "205",
+ "206",
+ "207",
+ "208",
+ "226",
+ "300",
+ "301",
+ "302",
+ "303",
+ "304",
+ "305",
+ "306",
+ "307",
+ "308",
+ "400",
+ "401",
+ "402",
+ "403",
+ "404",
+ "405",
+ "406",
+ "407",
+ "408",
+ "409",
+ "410",
+ "411",
+ "412",
+ "413",
+ "414",
+ "415",
+ "416",
+ "417",
+ "418",
+ "421",
+ "422",
+ "423",
+ "424",
+ "425",
+ "426",
+ "428",
+ "429",
+ "431",
+ "451",
+ "500",
+ "501",
+ "502",
+ "503",
+ "504",
+ "505",
+ "506",
+ "507",
+ "508",
+ "510",
+ "511"
+ ]
+ }
+ },
+ "initialisms": {
+ "description": "ST1003 check, among other things, for the correct capitalization of initialisms. The set of known initialisms can be configured with this option.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "default": [
+ "ACL",
+ "API",
+ "ASCII",
+ "CPU",
+ "CSS",
+ "DNS",
+ "EOF",
+ "GUID",
+ "HTML",
+ "HTTP",
+ "HTTPS",
+ "ID",
+ "IP",
+ "JSON",
+ "QPS",
+ "RAM",
+ "RPC",
+ "SLA",
+ "SMTP",
+ "SQL",
+ "SSH",
+ "TCP",
+ "TLS",
+ "TTL",
+ "UDP",
+ "UI",
+ "GID",
+ "UID",
+ "UUID",
+ "URI",
+ "URL",
+ "UTF8",
+ "VM",
+ "XML",
+ "XMPP",
+ "XSRF",
+ "XSS",
+ "SIP",
+ "RTP",
+ "AMQP",
+ "DB",
+ "TS"
+ ]
+ }
+ }
+ }
+ },
+ "tagalign": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "align": {
+ "description": "Align and sort can be used together or separately.",
+ "type": "boolean",
+ "default": true
+ },
+ "sort": {
+ "description": "Whether enable tags sort.",
+ "type": "boolean",
+ "default": true
+ },
+ "order": {
+ "description": "Specify the order of tags, the other tags will be sorted by name.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "default": [],
+ "examples": [
+ [
+ "json",
+ "yaml",
+ "yml",
+ "toml",
+ "mapstructure",
+ "binding",
+ "validate"
+ ]
+ ]
+ },
+ "strict": {
+ "description": "Whether enable strict style.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "tagliatelle": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "case": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "use-field-name": {
+ "description": "Use the struct field name to check the name of the struct tag.",
+ "type": "boolean",
+ "default": false
+ },
+ "rules": {
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "enum": [
+ "camel",
+ "pascal",
+ "kebab",
+ "snake",
+ "goCamel",
+ "goPascal",
+ "goKebab",
+ "goSnake",
+ "upper",
+ "upperSnake",
+ "lower",
+ "header"
+ ]
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "tenv": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "all": {
+ "description": "The option `all` will run against whole test files (`_test.go`) regardless of method/function signatures.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "testifylint": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "bool-compare": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignore-custom-types": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "enable-all": {
+ "description": "Enable all checkers.",
+ "type": "boolean",
+ "default": false
+ },
+ "disable-all": {
+ "description": "Disable all checkers.",
+ "type": "boolean",
+ "default": false
+ },
+ "enable": {
+ "description": "Enable specific checkers.",
+ "type": "array",
+ "items": {
+ "enum": [
+ "blank-import",
+ "bool-compare",
+ "compares",
+ "empty",
+ "error-is-as",
+ "error-nil",
+ "expected-actual",
+ "go-require",
+ "float-compare",
+ "len",
+ "nil-compare",
+ "require-error",
+ "suite-dont-use-pkg",
+ "suite-extra-assert-call",
+ "suite-thelper",
+ "useless-assert"
+ ]
+ }
+ },
+ "disable": {
+ "description": "Enable specific checkers.",
+ "type": "array",
+ "items": {
+ "enum": [
+ "blank-import",
+ "bool-compare",
+ "compares",
+ "empty",
+ "error-is-as",
+ "error-nil",
+ "expected-actual",
+ "go-require",
+ "float-compare",
+ "len",
+ "nil-compare",
+ "require-error",
+ "suite-dont-use-pkg",
+ "suite-extra-assert-call",
+ "suite-thelper",
+ "useless-assert"
+ ]
+ }
+ },
+ "expected-actual": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "pattern": {
+ "description": "Regexp for expected variable name.",
+ "type": "string"
+ }
+ }
+ },
+ "require-error": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "fn-pattern": {
+ "description": "Regexp for expected variable name.",
+ "type": "string"
+ }
+ }
+ },
+ "suite-extra-assert-call": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "mode": {
+ "description": "To require or remove extra Assert() call?",
+ "type": "string",
+ "enum": ["remove", "require"]
+ }
+ }
+ }
+ }
+ },
+ "testpackage": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skip-regexp": {
+ "description": "Files with names matching this regular expression are skipped.",
+ "type": "string",
+ "examples": ["(export|internal)_test\\.go"]
+ },
+ "allow-packages": {
+ "description": "List of packages that don't end with _test that tests are allowed to be in.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["example"]
+ }
+ }
+ }
+ },
+ "thelper": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "test": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "begin": {
+ "description": "Check if `t.Helper()` begins helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "first": {
+ "description": "Check if *testing.T is first param of helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "name": {
+ "description": "Check if *testing.T param has t name.",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ },
+ "benchmark": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "begin": {
+ "description": "Check if `b.Helper()` begins helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "first": {
+ "description": "Check if *testing.B is first param of helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "name": {
+ "description": "Check if *testing.B param has b name.",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ },
+ "tb": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "begin": {
+ "description": "Check if `tb.Helper()` begins helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "first": {
+ "description": "Check if *testing.TB is first param of helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "name": {
+ "description": "Check if *testing.TB param has tb name.",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ },
+ "fuzz": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "begin": {
+ "description": "Check if `f.Helper()` begins helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "first": {
+ "description": "Check if *testing.F is first param of helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "name": {
+ "description": "Check if *testing.F param has f name.",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ }
+ }
+ },
+ "usestdlibvars": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "http-method": {
+ "description": "Suggest the use of http.MethodXX.",
+ "type": "boolean",
+ "default": true
+ },
+ "http-status-code": {
+ "description": "Suggest the use of http.StatusXX.",
+ "type": "boolean",
+ "default": true
+ },
+ "time-weekday": {
+ "description": "Suggest the use of time.Weekday.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "time-month": {
+ "description": "Suggest the use of time.Month.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "time-layout": {
+ "description": "Suggest the use of time.Layout.",
+ "type": "boolean",
+ "default": false
+ },
+ "crypto-hash": {
+ "description": "Suggest the use of crypto.Hash.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "default-rpc-path": {
+ "description": "Suggest the use of rpc.DefaultXXPath.",
+ "type": "boolean",
+ "default": false
+ },
+ "sql-isolation-level": {
+ "description": "Suggest the use of sql.LevelXX.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "tls-signature-scheme": {
+ "description": "Suggest the use of tls.SignatureScheme.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "constant-kind": {
+ "description": "Suggest the use of constant.Kind.String().",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "unconvert": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "fast-math": {
+ "type": "boolean",
+ "default": false
+ },
+ "safe": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "unparam": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-exported": {
+ "description": "Inspect exported functions. Set to true if no external program/library imports your code.\n\nWARNING: if you enable this setting, unparam will report a lot of false-positives in text editors:\nif it's called for subdir of a project it can't find external interfaces. All text editor integrations\nwith golangci-lint call it on a directory with the changed file.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "unused": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "field-writes-are-uses": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ },
+ "post-statements-are-reads": {
+ "description": "",
+ "type": "boolean",
+ "default": false
+ },
+ "exported-is-used": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ },
+ "exported-fields-are-used": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ },
+ "parameters-are-used": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ },
+ "local-variables-are-used": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ },
+ "generated-is-used": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "varnamelen": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-distance": {
+ "description": "Variables used in at most this N-many lines will be ignored.",
+ "type": "integer",
+ "default": 5
+ },
+ "min-name-length": {
+ "description": "The minimum length of a variable's name that is considered `long`.",
+ "type": "integer",
+ "default": 3
+ },
+ "check-receiver": {
+ "description": "Check method receiver names.",
+ "default": false,
+ "type": "boolean"
+ },
+ "check-return": {
+ "description": "Check named return values.",
+ "default": false,
+ "type": "boolean"
+ },
+ "check-type-param": {
+ "description": "Check type parameters.",
+ "default": false,
+ "type": "boolean"
+ },
+ "ignore-type-assert-ok": {
+ "description": "Ignore `ok` variables that hold the bool return value of a type assertion",
+ "default": false,
+ "type": "boolean"
+ },
+ "ignore-map-index-ok": {
+ "description": "Ignore `ok` variables that hold the bool return value of a map index.",
+ "default": false,
+ "type": "boolean"
+ },
+ "ignore-chan-recv-ok": {
+ "description": "Ignore `ok` variables that hold the bool return value of a channel receive.",
+ "default": false,
+ "type": "boolean"
+ },
+ "ignore-names": {
+ "description": "Optional list of variable names that should be ignored completely.",
+ "default": [[]],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignore-decls": {
+ "description": "Optional list of variable declarations that should be ignored completely.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "examples": [
+ ["c echo.Context", "t testing.T", "f *foo.Bar", "const C"]
+ ]
+ }
+ }
+ },
+ "whitespace": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "multi-if": {
+ "description": "Enforces newlines (or comments) after every multi-line if statement",
+ "type": "boolean",
+ "default": false
+ },
+ "multi-func": {
+ "description": "Enforces newlines (or comments) after every multi-line function signature",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "wrapcheck": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignoreSigs": {
+ "description": "An array of strings which specify substrings of signatures to ignore.",
+ "default": [
+ ".Errorf(",
+ "errors.New(",
+ "errors.Unwrap(",
+ ".Wrap(",
+ ".Wrapf(",
+ ".WithMessage(",
+ ".WithMessagef(",
+ ".WithStack("
+ ],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignoreSigRegexps": {
+ "description": "An array of strings which specify regular expressions of signatures to ignore.",
+ "default": [""],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignorePackageGlobs": {
+ "description": "An array of glob patterns which, if any match the package of the function returning the error, will skip wrapcheck analysis for this error.",
+ "default": [""],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignoreInterfaceRegexps": {
+ "description": "An array of glob patterns which, if matched to an underlying interface name, will ignore unwrapped errors returned from a function whose call is defined on the given interface.",
+ "default": [""],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "wsl": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "allow-assign-and-anything": {
+ "description": "Controls if you may cuddle assignments and anything without needing an empty line between them.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-assign-and-call": {
+ "description": "Allow calls and assignments to be cuddled as long as the lines have any matching variables, fields or types.",
+ "type": "boolean",
+ "default": true
+ },
+ "allow-cuddle-declarations": {
+ "description": "Allow declarations (var) to be cuddled.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-cuddle-with-calls": {
+ "description": "A list of call idents that everything can be cuddled with.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "allow-cuddle-with-rhs": {
+ "description": "AllowCuddleWithRHS is a list of right hand side variables that is allowed to be cuddled with anything.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "allow-multiline-assign": {
+ "description": "Allow multiline assignments to be cuddled.",
+ "type": "boolean",
+ "default": true
+ },
+ "allow-separated-leading-comment": {
+ "description": "Allow leading comments to be separated with empty lines.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-trailing-comment": {
+ "description": "Allow trailing comments in ending of blocks.",
+ "type": "boolean",
+ "default": false
+ },
+ "error-variable-names": {
+ "description": "When force-err-cuddling is enabled this is a list of names used for error variables to check for in the conditional.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "force-case-trailing-whitespace": {
+ "description": "Force newlines in end of case at this limit (0 = never).",
+ "type": "integer",
+ "minimum": 0,
+ "default": 0
+ },
+ "force-err-cuddling": {
+ "description": "Causes an error when an If statement that checks an error variable doesn't cuddle with the assignment of that variable.",
+ "type": "boolean",
+ "default": false
+ },
+ "force-short-decl-cuddling": {
+ "description": "Causes an error if a short declaration (:=) cuddles with anything other than another short declaration.",
+ "type": "boolean",
+ "default": false
+ },
+ "strict-append": {
+ "description": "If true, append is only allowed to be cuddled if appending value is matching variables, fields or types on line above.",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "copyloopvar": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-alias": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "custom": {
+ "description": "The custom section can be used to define linter plugins to be loaded at runtime. See README of golangci-lint for more information.\nEach custom linter should have a unique name.",
+ "type": "object",
+ "patternProperties": {
+ "^.*$": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "type": {
+ "description": "The plugin type.",
+ "enum": ["module", "goplugin"],
+ "default": "goplugin"
+ },
+ "path": {
+ "description": "The path to the plugin *.so. Can be absolute or local.",
+ "type": "string",
+ "examples": ["/path/to/example.so"]
+ },
+ "description": {
+ "description": "The description of the linter, for documentation purposes only.",
+ "type": "string"
+ },
+ "original-url": {
+ "description": "Intended to point to the repo location of the linter, for documentation purposes only.",
+ "type": "string"
+ },
+ "settings": {
+ "description": "Plugins settings/configuration. Only work with plugin based on `linterdb.PluginConstructor`.",
+ "type": "object"
+ }
+ },
+ "oneOf": [
+ {
+ "properties": {
+ "type": {"enum": ["module"] }
+ },
+ "required": ["type"]
+ },
+ {
+ "required": ["path"]
+ }
+ ]
+ }
+ }
+ }
+ }
+ },
+ "linters": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "enable": {
+ "description": "List of enabled linters.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linters"
+ }
+ },
+ "disable": {
+ "description": "List of disabled linters.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linters"
+ }
+ },
+ "enable-all": {
+ "description": "Whether to enable all linters. You can re-disable them with `disable` explicitly.",
+ "type": "boolean",
+ "default": false
+ },
+ "disable-all": {
+ "description": "Whether to disable all linters. You can re-enable them with `enable` explicitly.",
+ "type": "boolean",
+ "default": false
+ },
+ "presets": {
+ "description": "Allow to use different presets of linters",
+ "type": "array",
+ "items": {
+ "enum": [
+ "bugs",
+ "comment",
+ "complexity",
+ "error",
+ "format",
+ "import",
+ "metalinter",
+ "module",
+ "performance",
+ "sql",
+ "style",
+ "test",
+ "unused"
+ ]
+ }
+ },
+ "fast": {
+ "description": "Enable run of fast linters.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "issues": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "exclude": {
+ "description": "List of regular expressions of issue texts to exclude.\nBut independently from this option we use default exclude patterns. Their usage can be controlled through `exclude-use-default`.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "exclude-rules": {
+ "description": "Exclude configuration per-path, per-linter, per-text and per-source",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "path": {
+ "type": "string"
+ },
+ "path-except": {
+ "type": "string"
+ },
+ "linters": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linters"
+ }
+ },
+ "text": {
+ "type": "string"
+ },
+ "source": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "exclude-use-default": {
+ "description": "Independently from option `exclude` we use default exclude patterns. This behavior can be disabled by this option.",
+ "type": "boolean",
+ "default": true
+ },
+ "exclude-case-sensitive": {
+ "description": "If set to true, exclude and exclude-rules regular expressions become case sensitive.",
+ "type": "boolean",
+ "default": false
+ },
+ "exclude-generated-strict": {
+ "description": "To follow strict Go generated file convention",
+ "type": "boolean",
+ "default": false
+ },
+ "exclude-dirs": {
+ "description": "Which directories to exclude: issues from them won't be reported.",
+ "type": "array",
+ "items": {
+ "description": "You can use regexp here. The regexp is applied on the full path.\n\"/\" will be replaced by current OS file path separator to properly work on Windows.",
+ "type": "string",
+ "examples": ["generated.*"]
+ },
+ "default": [],
+ "examples": [["src/external_libs", "autogenerated_by_my_lib"]]
+ },
+ "exclude-dirs-use-default": {
+ "description": "Enable exclusion of directories \"vendor\", \"third_party\", \"testdata\", \"examples\", \"Godeps\", and \"builtin\".",
+ "type": "boolean",
+ "default": true
+ },
+ "exclude-files": {
+ "description": "Which files to exclude: they will be analyzed, but issues from them will not be reported.",
+ "type": "array",
+ "items": {
+ "description": "You can use regexp here. There is no need to include all autogenerated files, we confidently recognize them. If that is not the case, please let us know.\n\"/\" will be replaced by current OS file path separator to properly work on Windows.",
+ "type": "string",
+ "examples": [".*\\.my\\.go$"]
+ },
+ "default": [],
+ "examples": [[".*\\.my\\.go$", "lib/bad.go"]]
+ },
+ "include": {
+ "description": "The list of ids of default excludes to include or disable.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "default": []
+ },
+ "max-issues-per-linter": {
+ "description": "Maximum issues count per one linter. Set to 0 to disable.",
+ "type": "integer",
+ "default": 50,
+ "minimum": 0
+ },
+ "max-same-issues": {
+ "description": "Maximum count of issues with the same text. Set to 0 to disable.",
+ "type": "integer",
+ "default": 3,
+ "minimum": 0
+ },
+ "new": {
+ "description": "Show only new issues: if there are unstaged changes or untracked files, only those changes are analyzed, else only changes in HEAD~ are analyzed.",
+ "type": "boolean",
+ "default": false
+ },
+ "new-from-rev": {
+ "description": "Show only new issues created after this git revision.",
+ "type": "string"
+ },
+ "new-from-patch": {
+ "description": "Show only new issues created in git patch with this file path.",
+ "type": "string",
+ "examples": ["path/to/patch/file"]
+ },
+ "fix": {
+ "description": "Fix found issues (if it's supported by the linter).",
+ "type": "boolean",
+ "default": false
+ },
+ "whole-files": {
+ "description": "Show issues in any part of update files (requires new-from-rev or new-from-patch).",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "severity": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "default-severity": {
+ "description": "Set the default severity for issues. If severity rules are defined and the issues do not match or no severity is provided to the rule this will be the default severity applied. Severities should match the supported severity names of the selected out format.",
+ "type": "string",
+ "default": ""
+ },
+ "case-sensitive": {
+ "description": "If set to true, severity-rules regular expressions become case sensitive.",
+ "type": "boolean",
+ "default": false
+ },
+ "rules": {
+ "description": "When a list of severity rules are provided, severity information will be added to lint issues. Severity rules have the same filtering capability as exclude rules except you are allowed to specify one matcher per severity rule.\nOnly affects out formats that support setting severity information.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "severity": {
+ "type": "string"
+ },
+ "path": {
+ "type": "string"
+ },
+ "path-except": {
+ "type": "string"
+ },
+ "linters": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linters"
+ }
+ },
+ "text": {
+ "type": "string"
+ },
+ "source": {
+ "type": "string"
+ }
+ },
+ "required": ["severity"],
+ "anyOf": [
+ { "required": ["path"] },
+ { "required": ["path-except"] },
+ { "required": ["linters"] },
+ { "required": ["text"] },
+ { "required": ["source"] }
+ ]
+ },
+ "default": []
+ }
+ },
+ "required": ["default-severity"]
+ }
+ }
+}
diff --git a/vendor/github.com/golangci/golangci-lint/v2/jsonschema/golangci.v1.59.jsonschema.json b/vendor/github.com/golangci/golangci-lint/v2/jsonschema/golangci.v1.59.jsonschema.json
new file mode 100644
index 000000000..cc3e63655
--- /dev/null
+++ b/vendor/github.com/golangci/golangci-lint/v2/jsonschema/golangci.v1.59.jsonschema.json
@@ -0,0 +1,3766 @@
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "$id": "https://json.schemastore.org/golangci-lint.json",
+ "definitions": {
+ "gocritic-checks": {
+ "enum": [
+ "appendAssign",
+ "appendCombine",
+ "argOrder",
+ "assignOp",
+ "badCall",
+ "badCond",
+ "badLock",
+ "badRegexp",
+ "badSorting",
+ "boolExprSimplify",
+ "builtinShadow",
+ "builtinShadowDecl",
+ "captLocal",
+ "caseOrder",
+ "codegenComment",
+ "commentedOutCode",
+ "commentedOutImport",
+ "commentFormatting",
+ "defaultCaseOrder",
+ "deferUnlambda",
+ "deferInLoop",
+ "deprecatedComment",
+ "docStub",
+ "dupArg",
+ "dupBranchBody",
+ "dupCase",
+ "dupImport",
+ "dupSubExpr",
+ "dynamicFmtString",
+ "elseif",
+ "emptyDecl",
+ "emptyFallthrough",
+ "emptyStringTest",
+ "equalFold",
+ "evalOrder",
+ "exitAfterDefer",
+ "exposedSyncMutex",
+ "externalErrorReassign",
+ "filepathJoin",
+ "flagDeref",
+ "flagName",
+ "hexLiteral",
+ "httpNoBody",
+ "hugeParam",
+ "ifElseChain",
+ "importShadow",
+ "indexAlloc",
+ "initClause",
+ "ioutilDeprecated",
+ "mapKey",
+ "methodExprCall",
+ "nestingReduce",
+ "newDeref",
+ "nilValReturn",
+ "octalLiteral",
+ "offBy1",
+ "paramTypeCombine",
+ "preferDecodeRune",
+ "preferFilepathJoin",
+ "preferFprint",
+ "preferStringWriter",
+ "preferWriteByte",
+ "ptrToRefParam",
+ "rangeExprCopy",
+ "rangeValCopy",
+ "redundantSprint",
+ "regexpMust",
+ "regexpPattern",
+ "regexpSimplify",
+ "returnAfterHttpError",
+ "ruleguard",
+ "singleCaseSwitch",
+ "sliceClear",
+ "sloppyLen",
+ "sloppyReassign",
+ "sloppyTypeAssert",
+ "sortSlice",
+ "sprintfQuotedString",
+ "sqlQuery",
+ "stringConcatSimplify",
+ "stringsCompare",
+ "stringXbytes",
+ "suspiciousSorting",
+ "switchTrue",
+ "syncMapLoadAndDelete",
+ "timeCmpSimplify",
+ "timeExprSimplify",
+ "tooManyResultsChecker",
+ "truncateCmp",
+ "typeAssertChain",
+ "typeDefFirst",
+ "typeSwitchVar",
+ "typeUnparen",
+ "uncheckedInlineErr",
+ "underef",
+ "unlabelStmt",
+ "unlambda",
+ "unnamedResult",
+ "unnecessaryBlock",
+ "unnecessaryDefer",
+ "unslice",
+ "valSwap",
+ "weakCond",
+ "whyNoLint",
+ "wrapperFunc",
+ "yodaStyleExpr"
+ ]
+ },
+ "gocritic-tags": {
+ "enum": [
+ "diagnostic",
+ "style",
+ "performance",
+ "experimental",
+ "opinionated",
+ "security"
+ ]
+ },
+ "gosec-rules": {
+ "enum": [
+ "G101",
+ "G102",
+ "G103",
+ "G104",
+ "G106",
+ "G107",
+ "G108",
+ "G109",
+ "G110",
+ "G111",
+ "G112",
+ "G113",
+ "G114",
+ "G201",
+ "G202",
+ "G203",
+ "G204",
+ "G301",
+ "G302",
+ "G303",
+ "G304",
+ "G305",
+ "G306",
+ "G307",
+ "G401",
+ "G402",
+ "G403",
+ "G404",
+ "G501",
+ "G502",
+ "G503",
+ "G504",
+ "G505",
+ "G601",
+ "G602"
+ ]
+ },
+ "govet-analyzers": {
+ "enum": [
+ "appends",
+ "asmdecl",
+ "assign",
+ "atomic",
+ "atomicalign",
+ "bools",
+ "buildtag",
+ "cgocall",
+ "composites",
+ "copylocks",
+ "deepequalerrors",
+ "defers",
+ "directive",
+ "errorsas",
+ "fieldalignment",
+ "findcall",
+ "framepointer",
+ "httpresponse",
+ "ifaceassert",
+ "loopclosure",
+ "lostcancel",
+ "nilfunc",
+ "nilness",
+ "printf",
+ "reflectvaluecompare",
+ "shadow",
+ "shift",
+ "sigchanyzer",
+ "slog",
+ "sortslice",
+ "stdmethods",
+ "stringintconv",
+ "structtag",
+ "testinggoroutine",
+ "tests",
+ "unmarshal",
+ "unreachable",
+ "unsafeptr",
+ "unusedresult",
+ "unusedwrite"
+ ]
+ },
+ "revive-rules": {
+ "enum": [
+ "add-constant",
+ "argument-limit",
+ "atomic",
+ "banned-characters",
+ "bare-return",
+ "blank-imports",
+ "bool-literal-in-expr",
+ "call-to-gc",
+ "cognitive-complexity",
+ "comment-spacings",
+ "confusing-naming",
+ "confusing-results",
+ "constant-logical-expr",
+ "context-as-argument",
+ "context-keys-type",
+ "cyclomatic",
+ "datarace",
+ "deep-exit",
+ "defer",
+ "dot-imports",
+ "duplicated-imports",
+ "early-return",
+ "empty-block",
+ "empty-lines",
+ "enforce-map-style",
+ "enforce-repeated-arg-type-style",
+ "enforce-slice-style",
+ "error-naming",
+ "error-return",
+ "error-strings",
+ "errorf",
+ "exported",
+ "file-header",
+ "flag-parameter",
+ "function-length",
+ "function-result-limit",
+ "get-return",
+ "identical-branches",
+ "if-return",
+ "import-alias-naming",
+ "import-shadowing",
+ "imports-blocklist",
+ "increment-decrement",
+ "indent-error-flow",
+ "line-length-limit",
+ "max-control-nesting",
+ "max-public-structs",
+ "modifies-parameter",
+ "modifies-value-receiver",
+ "nested-structs",
+ "optimize-operands-order",
+ "package-comments",
+ "range",
+ "range-val-address",
+ "range-val-in-closure",
+ "receiver-naming",
+ "redefines-builtin-id",
+ "redundant-import-alias",
+ "string-format",
+ "string-of-int",
+ "struct-tag",
+ "superfluous-else",
+ "time-equal",
+ "time-naming",
+ "unchecked-type-assertion",
+ "unconditional-recursion",
+ "unexported-naming",
+ "unexported-return",
+ "unhandled-error",
+ "unnecessary-stmt",
+ "unreachable-code",
+ "unused-parameter",
+ "unused-receiver",
+ "use-any",
+ "useless-break",
+ "var-declaration",
+ "var-naming",
+ "waitgroup-by-value"
+ ]
+ },
+ "linters": {
+ "$comment": "anyOf with enum is used to allow auto completion of non-custom linters",
+ "description": "Linters usable.",
+ "anyOf": [
+ {
+ "enum": [
+ "asasalint",
+ "asciicheck",
+ "bidichk",
+ "bodyclose",
+ "canonicalheader",
+ "containedctx",
+ "contextcheck",
+ "copyloopvar",
+ "cyclop",
+ "deadcode",
+ "decorder",
+ "depguard",
+ "dogsled",
+ "dupl",
+ "dupword",
+ "durationcheck",
+ "errcheck",
+ "errchkjson",
+ "errname",
+ "errorlint",
+ "execinquery",
+ "exhaustive",
+ "exhaustivestruct",
+ "exhaustruct",
+ "exportloopref",
+ "fatcontext",
+ "forbidigo",
+ "forcetypeassert",
+ "funlen",
+ "gci",
+ "ginkgolinter",
+ "gocheckcompilerdirectives",
+ "gochecknoglobals",
+ "gochecknoinits",
+ "gochecksumtype",
+ "gocognit",
+ "goconst",
+ "gocritic",
+ "gocyclo",
+ "godot",
+ "godox",
+ "err113",
+ "gofmt",
+ "gofumpt",
+ "goheader",
+ "goimports",
+ "golint",
+ "gomoddirectives",
+ "gomodguard",
+ "goprintffuncname",
+ "gosec",
+ "gosimple",
+ "gosmopolitan",
+ "govet",
+ "grouper",
+ "ifshort",
+ "importas",
+ "inamedparam",
+ "ineffassign",
+ "interfacebloat",
+ "interfacer",
+ "intrange",
+ "ireturn",
+ "lll",
+ "loggercheck",
+ "maintidx",
+ "makezero",
+ "maligned",
+ "mirror",
+ "misspell",
+ "mnd",
+ "musttag",
+ "nakedret",
+ "nestif",
+ "nilerr",
+ "nilnil",
+ "nlreturn",
+ "noctx",
+ "nolintlint",
+ "nonamedreturns",
+ "nosnakecase",
+ "nosprintfhostport",
+ "paralleltest",
+ "perfsprint",
+ "prealloc",
+ "predeclared",
+ "promlinter",
+ "protogetter",
+ "reassign",
+ "revive",
+ "rowserrcheck",
+ "scopelint",
+ "sloglint",
+ "sqlclosecheck",
+ "staticcheck",
+ "structcheck",
+ "stylecheck",
+ "tagalign",
+ "tagliatelle",
+ "tenv",
+ "testableexamples",
+ "testifylint",
+ "testpackage",
+ "thelper",
+ "tparallel",
+ "typecheck",
+ "unconvert",
+ "unparam",
+ "unused",
+ "usestdlibvars",
+ "varcheck",
+ "varnamelen",
+ "wastedassign",
+ "whitespace",
+ "wrapcheck",
+ "wsl",
+ "zerologlint"
+ ]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ }
+ },
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "run": {
+ "description": "Options for analysis running,",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "concurrency": {
+ "description": "Number of concurrent runners. Defaults to the number of available CPU cores.",
+ "type": "integer",
+ "minimum": 0,
+ "examples": [4]
+ },
+ "timeout": {
+ "description": "Timeout for the analysis.",
+ "type": "string",
+ "pattern": "^((\\d+h)?(\\d+m)?(\\d+(?:\\.\\d)?s)?|0)$",
+ "default": "1m",
+ "examples": ["30s", "5m", "5m30s"]
+ },
+ "issues-exit-code": {
+ "description": "Exit code when at least one issue was found.",
+ "type": "integer",
+ "default": 1
+ },
+ "tests": {
+ "description": "Enable inclusion of test files.",
+ "type": "boolean",
+ "default": true
+ },
+ "build-tags": {
+ "description": "List of build tags to pass to all linters.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "default": [],
+ "examples": [["mytag"]]
+ },
+ "modules-download-mode": {
+ "description": "Option to pass to \"go list -mod={option}\".\nSee \"go help modules\" for more information.",
+ "enum": ["mod", "readonly", "vendor"]
+ },
+ "allow-parallel-runners": {
+ "description": "Allow multiple parallel golangci-lint instances running. If disabled, golangci-lint acquires file lock on start.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-serial-runners": {
+ "description": "Allow multiple golangci-lint instances running, but serialize them around a lock.",
+ "type": "boolean",
+ "default": false
+ },
+ "go": {
+ "description": "Targeted Go version.",
+ "type": "string",
+ "default": "1.17"
+ }
+ }
+ },
+ "output": {
+ "description": "Output configuration options.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "formats": {
+ "description": "Output formats to use.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "path": {
+ "default": "stdout",
+ "anyOf": [
+ {
+ "enum": [ "stdout", "stderr" ]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ },
+ "format": {
+ "default": "colored-line-number",
+ "enum": [
+ "colored-line-number",
+ "line-number",
+ "json",
+ "colored-tab",
+ "tab",
+ "html",
+ "checkstyle",
+ "code-climate",
+ "junit-xml",
+ "github-actions",
+ "teamcity",
+ "sarif"
+ ]
+ }
+ },
+ "required": ["format"]
+ }
+ },
+ "print-issued-lines": {
+ "description": "Print lines of code with issue.",
+ "type": "boolean",
+ "default": true
+ },
+ "print-linter-name": {
+ "description": "Print linter name in the end of issue text.",
+ "type": "boolean",
+ "default": true
+ },
+ "uniq-by-line": {
+ "description": "Make issues output unique by line.",
+ "type": "boolean",
+ "default": true
+ },
+ "path-prefix": {
+ "description": "Add a prefix to the output file references.",
+ "type": "string",
+ "default": ""
+ },
+ "show-stats": {
+ "description": "Show statistics per linter.",
+ "type": "boolean",
+ "default": false
+ },
+ "sort-order": {
+ "type": "array",
+ "items": {
+ "enum": ["linter", "severity", "file"]
+ }
+ },
+ "sort-results": {
+ "description": "Sort results by: filepath, line and column.",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "linters-settings": {
+ "description": "All available settings of specific linters.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "dupword": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "keywords": {
+ "description": "Keywords for detecting duplicate words. If this list is not empty, only the words defined in this list will be detected.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["the", "and", "a"]
+ }
+ },
+ "ignore": {
+ "description": "Keywords used to ignore detection.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["0C0C"]
+ }
+ }
+ }
+ },
+ "asasalint": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "exclude": {
+ "description": "To specify a set of function names to exclude.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["\\.Wrapf"]
+ }
+ },
+ "use-builtin-exclusions": {
+ "description": "To enable/disable the asasalint builtin exclusions of function names.",
+ "type": "boolean",
+ "default": true
+ },
+ "ignore-test": {
+ "description": "Ignore *_test.go files.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "bidichk": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "left-to-right-embedding": {
+ "description": "Disallow: LEFT-TO-RIGHT-EMBEDDING",
+ "type": "boolean",
+ "default": false
+ },
+ "right-to-left-embedding": {
+ "description": "Disallow: RIGHT-TO-LEFT-EMBEDDING",
+ "type": "boolean",
+ "default": false
+ },
+ "pop-directional-formatting": {
+ "description": "Disallow: POP-DIRECTIONAL-FORMATTING",
+ "type": "boolean",
+ "default": false
+ },
+ "left-to-right-override": {
+ "description": "Disallow: LEFT-TO-RIGHT-OVERRIDE",
+ "type": "boolean",
+ "default": false
+ },
+ "right-to-left-override": {
+ "description": "Disallow: RIGHT-TO-LEFT-OVERRIDE",
+ "type": "boolean",
+ "default": false
+ },
+ "left-to-right-isolate": {
+ "description": "Disallow: LEFT-TO-RIGHT-ISOLATE",
+ "type": "boolean",
+ "default": false
+ },
+ "right-to-left-isolate": {
+ "description": "Disallow: RIGHT-TO-LEFT-ISOLATE",
+ "type": "boolean",
+ "default": false
+ },
+ "first-strong-isolate": {
+ "description": "Disallow: FIRST-STRONG-ISOLATE",
+ "type": "boolean",
+ "default": false
+ },
+ "pop-directional-isolate": {
+ "description": "Disallow: POP-DIRECTIONAL-ISOLATE",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "cyclop": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skip-tests": {
+ "description": "Should the linter execute on test files as well",
+ "type": "boolean",
+ "default": false
+ },
+ "max-complexity": {
+ "description": "Max complexity the function can have",
+ "type": "integer",
+ "default": 10,
+ "minimum": 0
+ },
+ "package-average": {
+ "description": "Max average complexity in package",
+ "type": "number",
+ "default": 0,
+ "minimum": 0
+ }
+ }
+ },
+ "decorder": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "dec-order": {
+ "type": "array",
+ "default": [["type", "const", "var", "func"]],
+ "items": {
+ "enum": ["type", "const", "var", "func"]
+ }
+ },
+ "ignore-underscore-vars": {
+ "description": "Underscore vars (vars with \"_\" as the name) will be ignored at all checks",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-dec-order-check": {
+ "description": "Order of declarations is not checked",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-init-func-first-check": {
+ "description": "Allow init func to be anywhere in file",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-dec-num-check": {
+ "description": "Multiple global type, const and var declarations are allowed",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-type-dec-num-check": {
+ "description": "Type declarations will be ignored for dec num check",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-const-dec-num-check": {
+ "description": "Const declarations will be ignored for dec num check",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-var-dec-num-check": {
+ "description": "Var declarations will be ignored for dec num check",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ },
+ "depguard": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "rules": {
+ "description": "Rules to apply.",
+ "type": "object",
+ "additionalProperties": false,
+ "patternProperties": {
+ "^[^.]+$": {
+ "description": "Name of a rule.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "list-mode": {
+ "description": "Used to determine the package matching priority.",
+ "enum": ["original", "strict", "lax"],
+ "default": "original"
+ },
+ "files": {
+ "description": "List of file globs that will match this list of settings to compare against.",
+ "additionalProperties": false,
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "allow": {
+ "description": "List of allowed packages.",
+ "additionalProperties": false,
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "deny": {
+ "description": "Packages that are not allowed where the value is a suggestion.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "desc": {
+ "description": "Description",
+ "type": "string"
+ },
+ "pkg": {
+ "description": "Package",
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "dogsled": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-blank-identifiers": {
+ "description": "Check assignments with too many blank identifiers.",
+ "type": "integer",
+ "default": 2,
+ "minimum": 0
+ }
+ }
+ },
+ "dupl": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "threshold": {
+ "description": "Tokens count to trigger issue.",
+ "type": "integer",
+ "default": 150,
+ "minimum": 0
+ }
+ }
+ },
+ "errcheck": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-type-assertions": {
+ "description": "Report about not checking errors in type assertions, i.e.: `a := b.(MyStruct)`",
+ "type": "boolean",
+ "default": false
+ },
+ "check-blank": {
+ "description": "Report about assignment of errors to blank identifier",
+ "type": "boolean",
+ "default": false
+ },
+ "exclude-functions": {
+ "description": "List of functions to exclude from checking, where each entry is a single function to exclude",
+ "type": "array",
+ "examples": ["io/ioutil.ReadFile", "io.Copy(*bytes.Buffer)"],
+ "items": {
+ "type": "string"
+ }
+ },
+ "disable-default-exclusions": {
+ "description": "To disable the errcheck built-in exclude list",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "errchkjson": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-error-free-encoding": {
+ "type": "boolean",
+ "default": false
+ },
+ "report-no-exported": {
+ "description": "Issue on struct that doesn't have exported fields.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "errorlint": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "errorf": {
+ "description": "Check whether fmt.Errorf uses the %w verb for formatting errors",
+ "type": "boolean",
+ "default": true
+ },
+ "errorf-multi": {
+ "description": "Permit more than 1 %w verb, valid per Go 1.20",
+ "type": "boolean",
+ "default": true
+ },
+ "asserts": {
+ "description": "Check for plain type assertions and type switches.",
+ "type": "boolean",
+ "default": true
+ },
+ "comparison": {
+ "description": "Check for plain error comparisons",
+ "type": "boolean",
+ "default": true
+ },
+ "allowed-errors": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "err": {
+ "type": "string"
+ },
+ "fun": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "allowed-errors-wildcard": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "err": {
+ "type": "string"
+ },
+ "fun": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "exhaustive": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check": {
+ "description": "Program elements to check for exhaustiveness.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["switch", "map"]
+ }
+ },
+ "check-generated": {
+ "description": "Check switch statements in generated files",
+ "type": "boolean",
+ "default": false
+ },
+ "explicit-exhaustive-switch": {
+ "description": "Only run exhaustive check on switches with \"//exhaustive:enforce\" comment.",
+ "type": "boolean",
+ "default": false
+ },
+ "explicit-exhaustive-map": {
+ "description": "Only run exhaustive check on map literals with \"//exhaustive:enforce\" comment.",
+ "type": "boolean",
+ "default": false
+ },
+ "default-case-required": {
+ "description": "Switch statement requires default case even if exhaustive.",
+ "type": "boolean",
+ "default": false
+ },
+ "default-signifies-exhaustive": {
+ "description": "Presence of `default` case in switch statements satisfies exhaustiveness, even if all enum members are not listed.",
+ "type": "boolean",
+ "default": false
+ },
+ "ignore-enum-members": {
+ "description": "Enum members matching `regex` do not have to be listed in switch statements to satisfy exhaustiveness",
+ "type": "string"
+ },
+ "ignore-enum-types": {
+ "description": "Enum types matching the supplied regex do not have to be listed in switch statements to satisfy exhaustiveness.",
+ "type": "string"
+ },
+ "package-scope-only": {
+ "description": "Consider enums only in package scopes, not in inner scopes.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "exhaustruct": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "include": {
+ "description": "List of regular expressions to match struct packages and names.",
+ "type": "array",
+ "examples": [".*\\.Test"],
+ "items": {
+ "type": "string"
+ }
+ },
+ "exclude": {
+ "description": "List of regular expressions to exclude struct packages and names from check.",
+ "type": "array",
+ "examples": ["cobra\\.Command$"],
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "forbidigo": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "exclude-godoc-examples": {
+ "description": "Exclude code in godoc examples.",
+ "type": "boolean",
+ "default": true
+ },
+ "analyze-types": {
+ "description": "Instead of matching the literal source code, use type information to replace expressions with strings that contain the package name and (for methods and fields) the type name.",
+ "type": "boolean",
+ "default": true
+ },
+ "forbid": {
+ "description": "List of identifiers to forbid (written using `regexp`)",
+ "type": "array",
+ "examples": ["^print.*$"],
+ "items": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "p": {
+ "description": "Pattern",
+ "type": "string"
+ },
+ "pkg": {
+ "description": "Package",
+ "type": "string"
+ },
+ "msg": {
+ "description": "Message",
+ "type": "string"
+ }
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ "funlen": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "lines": {
+ "description": "Limit lines number per function.",
+ "type": "integer",
+ "default": 60
+ },
+ "statements": {
+ "description": "Limit statements number per function.",
+ "type": "integer",
+ "default": 40
+ },
+ "ignore-comments": {
+ "description": "Ignore comments when counting lines.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "gci": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "sections": {
+ "description": "Section configuration to compare against.",
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "enum": [
+ "standard",
+ "default",
+ "blank",
+ "dot",
+ "alias",
+ "localmodule"
+ ]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ },
+ "default": ["standard", "default"]
+ },
+ "skip-generated": {
+ "description": "Skip generated files.",
+ "type": "boolean",
+ "default": true
+ },
+ "custom-order": {
+ "description": "Enable custom order of sections.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "ginkgolinter": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "suppress-len-assertion": {
+ "description": "Suppress the wrong length assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-nil-assertion": {
+ "description": "Suppress the wrong nil assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-err-assertion": {
+ "description": "Suppress the wrong error assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-compare-assertion": {
+ "description": "Suppress the wrong comparison assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-async-assertion": {
+ "description": "Suppress the function all in async assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-type-compare-assertion": {
+ "description": "Suppress warning for comparing values from different types, like int32 and uint32.",
+ "type": "boolean",
+ "default": false
+ },
+ "forbid-focus-container": {
+ "description": "Trigger warning for ginkgo focus containers like FDescribe, FContext, FWhen or FIt.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-havelen-zero": {
+ "description": "Don't trigger warnings for HaveLen(0).",
+ "type": "boolean",
+ "default": false
+ },
+ "force-expect-to": {
+ "description": "Force using `Expect` with `To`, `ToNot` or `NotTo`",
+ "type": "boolean",
+ "default": false
+ },
+ "validate-async-intervals": {
+ "description": "Best effort validation of async intervals (timeout and polling).",
+ "type": "boolean",
+ "default": false
+ },
+ "forbid-spec-pollution": {
+ "description": "Trigger a warning for variable assignments in ginkgo containers like `Describe`, `Context` and `When`, instead of in `BeforeEach()`.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "gocognit": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "min-complexity": {
+ "description": "Minimal code complexity to report (we recommend 10-20).",
+ "type": "integer",
+ "default": 30
+ }
+ }
+ },
+ "goconst": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "match-constant": {
+ "description": "Look for existing constants matching the values",
+ "type": "boolean",
+ "default": true
+ },
+ "min-len": {
+ "description": "Minimum length of string constant.",
+ "type": "integer",
+ "default": 3
+ },
+ "min-occurrences": {
+ "description": "Minimum occurrences count to trigger.",
+ "type": "integer",
+ "default": 3
+ },
+ "ignore-tests": {
+ "description": "Ignore test files.",
+ "type": "boolean",
+ "default": false
+ },
+ "ignore-calls": {
+ "description": "Ignore when constant is not used as function argument",
+ "type": "boolean",
+ "default": true
+ },
+ "ignore-strings": {
+ "description": "Exclude strings matching the given regular expression",
+ "type": "string"
+ },
+ "numbers": {
+ "description": "Search also for duplicated numbers.",
+ "type": "boolean",
+ "default": false
+ },
+ "min": {
+ "description": "Minimum value, only works with `numbers`",
+ "type": "integer",
+ "default": 3
+ },
+ "max": {
+ "description": "Maximum value, only works with `numbers`",
+ "type": "integer",
+ "default": 3
+ }
+ }
+ },
+ "gocritic": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "enabled-checks": {
+ "description": "Which checks should be enabled. By default, a list of stable checks is used. To see it, run `GL_DEBUG=gocritic golangci-lint run`.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/gocritic-checks"
+ }
+ },
+ "disabled-checks": {
+ "description": "Which checks should be disabled.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/gocritic-checks"
+ },
+ "default": []
+ },
+ "enabled-tags": {
+ "description": "Enable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/gocritic-tags"
+ }
+ },
+ "disabled-tags": {
+ "description": "Disable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/gocritic-tags"
+ }
+ },
+ "settings": {
+ "description": "Settings passed to gocritic. Properties must be valid and enabled check names.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "captLocal": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "paramsOnly" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "commentedOutCode": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "minLength" : {
+ "type": "number",
+ "default": 15
+ }
+ }
+ },
+ "elseif": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skipBalanced" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "hugeParam": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "sizeThreshold" : {
+ "type": "number",
+ "default": 80
+ }
+ }
+ },
+ "ifElseChain": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "minThreshold" : {
+ "type": "number",
+ "default": 2
+ }
+ }
+ },
+ "nestingReduce": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "bodyWidth" : {
+ "type": "number",
+ "default": 5
+ }
+ }
+ },
+ "rangeExprCopy": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "sizeThreshold" : {
+ "type": "number",
+ "default": 512
+ },
+ "skipTestFuncs" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "rangeValCopy": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "sizeThreshold" : {
+ "type": "number",
+ "default": 128
+ },
+ "skipTestFuncs" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "ruleguard": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "debug" : {
+ "type": "string"
+ },
+ "enable" : {
+ "type": "string"
+ },
+ "disable" : {
+ "type": "string"
+ },
+ "failOn" : {
+ "type": "string"
+ },
+ "rules" : {
+ "type": "string"
+ }
+ }
+ },
+ "tooManyResultsChecker": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "maxResults" : {
+ "type": "number",
+ "default": 5
+ }
+ }
+ },
+ "truncateCmp": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skipArchDependent" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "underef": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skipRecvDeref" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "unnamedResult": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "checkExported" : {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ }
+ }
+ },
+ "disable-all": {
+ "type": "boolean",
+ "default": false
+ },
+ "enable-all": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "gocyclo": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "min-complexity": {
+ "description": "Minimum code complexity to report (we recommend 10-20).",
+ "type": "integer",
+ "default": 30
+ }
+ }
+ },
+ "godot": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "scope": {
+ "description": "Comments to be checked.",
+ "enum": ["declarations", "toplevel", "all"],
+ "default": "declarations"
+ },
+ "exclude": {
+ "description": "List of regexps for excluding particular comment lines from check.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "period": {
+ "description": "Check that each sentence ends with a period.",
+ "type": "boolean",
+ "default": true
+ },
+ "capital": {
+ "description": "Check that each sentence starts with a capital letter.",
+ "type": "boolean",
+ "default": false
+ },
+ "check-all": {
+ "description": "DEPRECATED: Check all top-level comments, not only declarations.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "godox": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "keywords": {
+ "description": "Report any comments starting with one of these keywords. This is useful for TODO or FIXME comments that might be left in the code accidentally and should be resolved before merging.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "default": ["TODO", "BUG", "FIXME"]
+ }
+ }
+ },
+ "gofmt": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "simplify": {
+ "description": "Simplify code.",
+ "type": "boolean",
+ "default": true
+ },
+ "rewrite-rules": {
+ "description": "Apply the rewrite rules to the source before reformatting.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "pattern": {
+ "type": "string"
+ },
+ "replacement": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "interfacebloat": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max": {
+ "description": "The maximum number of methods allowed for an interface.",
+ "type": "integer"
+ }
+ }
+ },
+ "gofumpt": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "extra-rules": {
+ "description": "Choose whether or not to use the extra rules that are disabled by default.",
+ "type": "boolean",
+ "default": false
+ },
+ "module-path": {
+ "description": " Module path which contains the source code being formatted.",
+ "type": "string"
+ }
+ }
+ },
+ "goheader": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "values": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "const": {
+ "description": "Constants to use in the template.",
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "description": "Value for the constant.",
+ "type": "string"
+ }
+ },
+ "additionalProperties": false,
+ "examples": [
+ {
+ "YEAR": "2030",
+ "COMPANY": "MY FUTURISTIC COMPANY"
+ }
+ ]
+ },
+ "regexp": {
+ "description": "Regular expressions to use in your template.",
+ "type": "object",
+ "additionalProperties": false,
+ "patternProperties": {
+ "^.+$": {
+ "type": "string"
+ }
+ },
+ "examples": [
+ {
+ "AUTHOR": ".*@mycompany\\.com"
+ }
+ ]
+ }
+ }
+ },
+ "template": {
+ "description": "Template to put on top of every file.",
+ "type": "string",
+ "examples": [
+ "{{ MY COMPANY }}\nSPDX-License-Identifier: Apache-2.0\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at:\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License."
+ ]
+ },
+ "template-path": {
+ "description": "Path to the file containing the template source.",
+ "type": "string",
+ "examples": ["my_header_template.txt"]
+ }
+ },
+ "oneOf": [
+ { "required": ["template"] },
+ { "required": ["template-path"] }
+ ]
+ },
+ "goimports": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "local-prefixes": {
+ "description": "Put imports beginning with prefix after 3rd-party packages. It is a comma-separated list of prefixes.",
+ "type": "string",
+ "examples": ["github.com/org/project"]
+ }
+ }
+ },
+ "gomoddirectives": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "replace-local": {
+ "description": "Allow local `replace` directives.",
+ "type": "boolean",
+ "default": true
+ },
+ "replace-allow-list": {
+ "description": "List of allowed `replace` directives.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "retract-allow-no-explanation": {
+ "description": "Allow to not explain why the version has been retracted in the `retract` directives.",
+ "type": "boolean",
+ "default": true
+ },
+ "exclude-forbidden": {
+ "description": "Forbid the use of the `exclude` directives.",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "gomodguard": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "allowed": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "modules": {
+ "description": "List of allowed modules.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["gopkg.in/yaml.v2"]
+ }
+ },
+ "domains": {
+ "description": "List of allowed module domains.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["golang.org"]
+ }
+ }
+ }
+ },
+ "blocked": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "modules": {
+ "description": "List of blocked modules.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "recommendations": {
+ "description": "Recommended modules that should be used instead.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "reason": {
+ "description": "Reason why the recommended module should be used.",
+ "type": "string"
+ }
+ }
+ }
+ },
+ "additionalProperties": false
+ }
+ },
+ "versions": {
+ "description": "List of blocked module version constraints.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "patternProperties": {
+ "^.*$": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "version": {
+ "description": "Version constraint.",
+ "type": "string"
+ },
+ "reason": {
+ "description": "Reason why the version constraint exists.",
+ "type": "string"
+ }
+ },
+ "required": ["reason"]
+ }
+ }
+ }
+ },
+ "local_replace_directives": {
+ "description": "Raise lint issues if loading local path with replace directive",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ }
+ }
+ },
+ "gosimple": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "checks": {
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "enum": ["all"]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ }
+ }
+ }
+ },
+ "gosec": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "includes": {
+ "type": "array",
+ "description": "To select a subset of rules to run",
+ "examples": [["G401"]],
+ "items": {
+ "$ref": "#/definitions/gosec-rules"
+ }
+ },
+ "excludes": {
+ "type": "array",
+ "description": "To specify a set of rules to explicitly exclude",
+ "examples": [["G401"]],
+ "items": {
+ "$ref": "#/definitions/gosec-rules"
+ }
+ },
+ "exclude-generated": {
+ "description": "Exclude generated files",
+ "type": "boolean",
+ "default": false
+ },
+ "severity": {
+ "description": "Filter out the issues with a lower severity than the given value",
+ "type": "string",
+ "enum": ["low", "medium", "high"],
+ "default": "low"
+ },
+ "confidence": {
+ "description": "Filter out the issues with a lower confidence than the given value",
+ "type": "string",
+ "enum": ["low", "medium", "high"],
+ "default": "low"
+ },
+ "config": {
+ "description": "To specify the configuration of rules",
+ "type": "object"
+ },
+ "concurrency": {
+ "description": "Concurrency value",
+ "type": "integer"
+ }
+ }
+ },
+ "gosmopolitan": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "allow-time-local": {
+ "description": "Allow and ignore `time.Local` usages.",
+ "type": "boolean",
+ "default": false
+ },
+ "escape-hatches": {
+ "description": "List of fully qualified names in the `full/pkg/path.name` form, to act as \"i18n escape hatches\".",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignore-tests": {
+ "description": "Ignore test files.",
+ "type": "boolean",
+ "default": false
+ },
+ "watch-for-scripts": {
+ "description": "List of Unicode scripts to watch for any usage in string literals.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "govet": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "settings": {
+ "description": "Settings per analyzer. Map of analyzer name to specific settings.\nRun `go tool vet help` to find out more.",
+ "type": "object",
+ "propertyNames": {
+ "$ref": "#/definitions/govet-analyzers"
+ },
+ "patternProperties": {
+ "^.*$": {
+ "description": "Run `go tool vet help ` to see all settings.",
+ "type": "object"
+ }
+ }
+ },
+ "enable": {
+ "description": "Enable analyzers by name.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/govet-analyzers"
+ }
+ },
+ "disable": {
+ "description": "Disable analyzers by name.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/govet-analyzers"
+ }
+ },
+ "enable-all": {
+ "description": "Enable all analyzers.",
+ "type": "boolean",
+ "default": false
+ },
+ "disable-all": {
+ "description": "Disable all analyzers.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "grouper": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "const-require-single-const": {
+ "type": "boolean",
+ "default": false
+ },
+ "const-require-grouping": {
+ "type": "boolean",
+ "default": false
+ },
+ "import-require-single-import": {
+ "type": "boolean",
+ "default": false
+ },
+ "import-require-grouping": {
+ "type": "boolean",
+ "default": false
+ },
+ "type-require-single-type": {
+ "type": "boolean",
+ "default": false
+ },
+ "type-require-grouping": {
+ "type": "boolean",
+ "default": false
+ },
+ "var-require-single-var": {
+ "type": "boolean",
+ "default": false
+ },
+ "var-require-grouping": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "importas": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "no-unaliased": {
+ "description": "Do not allow unaliased imports of aliased packages.",
+ "type": "boolean",
+ "default": false
+ },
+ "no-extra-aliases": {
+ "description": "Do not allow non-required aliases.",
+ "type": "boolean",
+ "default": false
+ },
+ "alias": {
+ "description": "List of aliases",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "pkg": {
+ "description": "Package path e.g. knative.dev/serving/pkg/apis/autoscaling/v1alpha1",
+ "type": "string"
+ },
+ "alias": {
+ "description": "Package alias e.g. autoscalingv1alpha1",
+ "type": "string"
+ }
+ },
+ "required": ["pkg", "alias"]
+ }
+ }
+ }
+ },
+ "inamedparam": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skip-single-param": {
+ "description": "Skips check for interface methods with only a single parameter.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "ireturn": {
+ "type": "object",
+ "additionalProperties": false,
+ "description": "Use either `reject` or `allow` properties for interfaces matching.",
+ "properties": {
+ "allow": {
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "enum": ["anon", "error", "empty", "stdlib"]
+ }
+ ]
+ }
+ },
+ "reject": {
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "enum": ["anon", "error", "empty", "stdlib"]
+ }
+ ]
+ }
+ }
+ },
+ "anyOf": [
+ {
+ "not": {
+ "properties": {
+ "allow": {
+ "const": "reject"
+ }
+ }
+ },
+ "required": ["allow"]
+ },
+ {
+ "required": ["reject"]
+ }
+ ]
+ },
+ "lll": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "tab-width": {
+ "description": "Width of \"\\t\" in spaces.",
+ "type": "integer",
+ "minimum": 0,
+ "default": 1
+ },
+ "line-length": {
+ "description": "Maximum allowed line length, lines longer will be reported.",
+ "type": "integer",
+ "minimum": 1,
+ "default": 120
+ }
+ }
+ },
+ "maintidx": {
+ "description": "Maintainability index https://docs.microsoft.com/en-us/visualstudio/code-quality/code-metrics-maintainability-index-range-and-meaning?view=vs-2022",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "under": {
+ "description": "Minimum accatpable maintainability index level (see https://docs.microsoft.com/en-us/visualstudio/code-quality/code-metrics-maintainability-index-range-and-meaning?view=vs-2022)",
+ "type": "number",
+ "default": 20
+ }
+ }
+ },
+ "makezero": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "always": {
+ "description": "Allow only slices initialized with a length of zero.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "loggercheck": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "kitlog": {
+ "description": "Allow check for the github.com/go-kit/log library.",
+ "type": "boolean",
+ "default": true
+ },
+ "klog": {
+ "description": "Allow check for the k8s.io/klog/v2 library.",
+ "type": "boolean",
+ "default": true
+ },
+ "logr": {
+ "description": "Allow check for the github.com/go-logr/logr library.",
+ "type": "boolean",
+ "default": true
+ },
+ "zap": {
+ "description": "Allow check for the \"sugar logger\" from go.uber.org/zap library.",
+ "type": "boolean",
+ "default": true
+ },
+ "require-string-key": {
+ "description": "Require all logging keys to be inlined constant strings.",
+ "type": "boolean",
+ "default": false
+ },
+ "no-printf-like": {
+ "description": "Require printf-like format specifier (%s, %d for example) not present.",
+ "type": "boolean",
+ "default": false
+ },
+ "rules": {
+ "description": "List of custom rules to check against, where each rule is a single logger pattern, useful for wrapped loggers.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "misspell": {
+ "description": "Correct spellings using locale preferences for US or UK. Default is to use a neutral variety of English.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "locale": {
+ "enum": ["US", "UK"]
+ },
+ "ignore-words": {
+ "description": "List of words to ignore.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "mode": {
+ "description": "Mode of the analysis.",
+ "enum": ["restricted", "", "default"],
+ "default": ""
+ },
+ "extra-words": {
+ "description": "Extra word corrections.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "correction": {
+ "type": "string"
+ },
+ "typo": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "musttag": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "functions": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "tag": {
+ "type": "string"
+ },
+ "arg-pos": {
+ "type": "integer"
+ }
+ }
+ }
+ }
+ }
+ },
+ "nakedret": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-func-lines": {
+ "description": "Report if a function has more lines of code than this value and it has naked returns.",
+ "type": "integer",
+ "minimum": 0,
+ "default": 30
+ }
+ }
+ },
+ "nestif": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "min-complexity": {
+ "description": "Minimum complexity of \"if\" statements to report.",
+ "type": "integer",
+ "default": 5
+ }
+ }
+ },
+ "nilnil": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "checked-types": {
+ "type": "array",
+ "description": "List of return types to check.",
+ "items": {
+ "enum": ["ptr", "func", "iface", "map", "chan", "uintptr", "unsafeptr"]
+ },
+ "default": ["ptr", "func", "iface", "map", "chan", "uintptr", "unsafeptr"]
+ }
+ }
+ },
+ "nlreturn": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "block-size": {
+ "description": "set block size that is still ok",
+ "type": "number",
+ "default": 0,
+ "minimum": 0
+ }
+ }
+ },
+ "mnd": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignored-files": {
+ "description": "List of file patterns to exclude from analysis.",
+ "examples": [["magic1_.*.go"]],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignored-functions": {
+ "description": "Comma-separated list of function patterns to exclude from the analysis.",
+ "examples": [["math.*", "http.StatusText", "make"]],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignored-numbers": {
+ "description": "List of numbers to exclude from analysis.",
+ "examples": [["1000", "1234_567_890", "3.14159264"]],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "checks": {
+ "description": "The list of enabled checks, see https://github.com/tommy-muehle/go-mnd/#checks for description.",
+ "type": "array",
+ "items": {
+ "enum": [
+ "argument",
+ "case",
+ "condition",
+ "operation",
+ "return",
+ "assign"
+ ]
+ }
+ }
+ }
+ },
+ "nolintlint": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "allow-unused": {
+ "description": "Enable to ensure that nolint directives are all used.",
+ "type": "boolean",
+ "default": true
+ },
+ "allow-no-explanation": {
+ "description": "Exclude these linters from requiring an explanation.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linters"
+ },
+ "default": []
+ },
+ "require-explanation": {
+ "description": "Enable to require an explanation of nonzero length after each nolint directive.",
+ "type": "boolean",
+ "default": false
+ },
+ "require-specific": {
+ "description": "Enable to require nolint directives to mention the specific linter being suppressed.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "reassign": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "patterns": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "nonamedreturns": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "report-error-in-defer": {
+ "description": "Report named error if it is assigned inside defer.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "paralleltest": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignore-missing": {
+ "description": "Ignore missing calls to `t.Parallel()` and only report incorrect uses of it.",
+ "type": "boolean",
+ "default": false
+ },
+ "ignore-missing-subtests": {
+ "description": "Ignore missing calls to `t.Parallel()` in subtests. Top-level tests are still required to have `t.Parallel`, but subtests are allowed to skip it.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "perfsprint": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "int-conversion": {
+ "description": "Optimizes even if it requires an int or uint type cast.",
+ "type": "boolean",
+ "default": true
+ },
+ "err-error": {
+ "description": "Optimizes into `err.Error()` even if it is only equivalent for non-nil errors.",
+ "type": "boolean",
+ "default": false
+ },
+ "errorf": {
+ "description": "Optimizes `fmt.Errorf`.",
+ "type": "boolean",
+ "default": true
+ },
+ "sprintf1": {
+ "description": "Optimizes `fmt.Sprintf` with only one argument.",
+ "type": "boolean",
+ "default": true
+ },
+ "strconcat": {
+ "description": "Optimizes into strings concatenation.",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "prealloc": {
+ "description": "We do not recommend using this linter before doing performance profiling.\nFor most programs usage of `prealloc` will be premature optimization.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "simple": {
+ "description": "Report preallocation suggestions only on simple loops that have no returns/breaks/continues/gotos in them.",
+ "type": "boolean",
+ "default": true
+ },
+ "range-loops": {
+ "description": "Report preallocation suggestions on range loops.",
+ "type": "boolean",
+ "default": true
+ },
+ "for-loops": {
+ "description": "Report preallocation suggestions on for loops.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "predeclared": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignore": {
+ "description": "Comma-separated list of predeclared identifiers to not report on.",
+ "type": "string"
+ },
+ "q": {
+ "description": "Include method names and field names (i.e., qualified names) in checks.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "promlinter": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "strict": {},
+ "disabled-linters": {
+ "type": "array",
+ "items": {
+ "enum": [
+ "Help",
+ "MetricUnits",
+ "Counter",
+ "HistogramSummaryReserved",
+ "MetricTypeInName",
+ "ReservedChars",
+ "CamelCase",
+ "UnitAbbreviations"
+ ]
+ }
+ }
+ }
+ },
+ "protogetter": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skip-generated-by": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["protoc-gen-go-my-own-generator"]
+ }
+ },
+ "skip-files": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["*.pb.go"]
+ }
+ },
+ "skip-any-generated": {
+ "description": "Skip any generated files from the checking.",
+ "type": "boolean",
+ "default": false
+ },
+ "replace-first-arg-in-append": {
+ "description": "Skip first argument of append function.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "revive": {
+ "type": "object",
+ "additionalProperties": false,
+ "examples": [
+ {
+ "ignore-generated-header": true,
+ "severity": "warning",
+ "rules": [
+ {
+ "name": "indent-error-flow",
+ "severity": "warning"
+ },
+ {
+ "name": "add-constant",
+ "severity": "warning",
+ "arguments": [
+ {
+ "maxLitCount": "3",
+ "allowStrs": "\"\"",
+ "allowInts": "0,1,2",
+ "allowFloats": "0.0,0.,1.0,1.,2.0,2."
+ }
+ ]
+ }
+ ]
+ }
+ ],
+ "properties": {
+ "max-open-files": {
+ "type": "integer"
+ },
+ "ignore-generated-header": {
+ "type": "boolean"
+ },
+ "confidence": {
+ "type": "number"
+ },
+ "severity": {
+ "type": "string",
+ "enum": ["warning", "error"]
+ },
+ "enable-all-rules": {
+ "type": "boolean",
+ "default": false
+ },
+ "directives": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "name": {
+ "type": "string",
+ "enum": ["specify-disable-reason"]
+ },
+ "severity": {
+ "type": "string",
+ "enum": ["warning", "error"]
+ },
+ "exclude": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "arguments": {
+ "type": "array"
+ }
+ }
+ }
+ },
+ "rules": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["name"],
+ "properties": {
+ "name": {
+ "$ref": "#/definitions/revive-rules",
+ "title": "The rule name"
+ },
+ "disabled": {
+ "type": "boolean"
+ },
+ "severity": {
+ "type": "string",
+ "enum": ["warning", "error"]
+ },
+ "exclude": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "arguments": {
+ "type": "array"
+ }
+ }
+ }
+ }
+ }
+ },
+ "rowserrcheck": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "packages": {
+ "type": "array",
+ "items": {
+ "description": "",
+ "type": "string",
+ "examples": ["github.com/jmoiron/sqlx"]
+ }
+ }
+ }
+ },
+ "sloglint": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "kv-only": {
+ "description": "Enforce using key-value pairs only (incompatible with attr-only).",
+ "type": "boolean",
+ "default": false
+ },
+ "no-global": {
+ "description": "Enforce not using global loggers.",
+ "enum": ["", "all", "default"],
+ "default": ""
+ },
+ "no-mixed-args": {
+ "description": "Enforce not mixing key-value pairs and attributes.",
+ "type": "boolean",
+ "default": true
+ },
+ "context": {
+ "description": "Enforce using methods that accept a context.",
+ "enum": ["", "all", "scope"],
+ "default": ""
+ },
+ "static-msg": {
+ "description": "Enforce using static values for log messages.",
+ "type": "boolean",
+ "default": false
+ },
+ "key-naming-case": {
+ "description": "Enforce a single key naming convention.",
+ "enum": ["snake", "kebab", "camel", "pascal"]
+ },
+ "attr-only": {
+ "description": "Enforce using attributes only (incompatible with kv-only).",
+ "type": "boolean",
+ "default": false
+ },
+ "no-raw-keys": {
+ "description": "Enforce using constants instead of raw keys.",
+ "type": "boolean",
+ "default": false
+ },
+ "forbidden-keys": {
+ "description": "Enforce not using specific keys.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "args-on-sep-lines": {
+ "description": "Enforce putting arguments on separate lines.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "spancheck": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "checks": {
+ "description": "Checks to enable.",
+ "type": "array",
+ "items": {
+ "enum": ["end", "record-error", "set-status"]
+ }
+ },
+ "ignore-check-signatures": {
+ "description": "A list of regexes for function signatures that silence `record-error` and `set-status` reports if found in the call path to a returned error.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "extra-start-span-signatures": {
+ "description": "A list of regexes for additional function signatures that create spans.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "staticcheck": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "checks": {
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "enum": ["all"]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ }
+ }
+ }
+ },
+ "stylecheck": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "checks": {
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "enum": ["all"]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ },
+ "default": [
+ "all",
+ "-ST1000",
+ "-ST1003",
+ "-ST1016",
+ "-ST1020",
+ "-ST1021",
+ "-ST1022"
+ ]
+ },
+ "dot-import-whitelist": {
+ "description": "By default, ST1001 forbids all uses of dot imports in non-test packages. This setting allows setting a whitelist of import paths that can be dot-imported anywhere.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "http-status-code-whitelist": {
+ "description": "ST1013 recommends using constants from the net/http package instead of hard-coding numeric HTTP status codes. This setting specifies a list of numeric status codes that this check does not complain about.",
+ "default": ["200", "400", "404", "500"],
+ "type": "array",
+ "items": {
+ "enum": [
+ "100",
+ "101",
+ "102",
+ "103",
+ "200",
+ "201",
+ "202",
+ "203",
+ "204",
+ "205",
+ "206",
+ "207",
+ "208",
+ "226",
+ "300",
+ "301",
+ "302",
+ "303",
+ "304",
+ "305",
+ "306",
+ "307",
+ "308",
+ "400",
+ "401",
+ "402",
+ "403",
+ "404",
+ "405",
+ "406",
+ "407",
+ "408",
+ "409",
+ "410",
+ "411",
+ "412",
+ "413",
+ "414",
+ "415",
+ "416",
+ "417",
+ "418",
+ "421",
+ "422",
+ "423",
+ "424",
+ "425",
+ "426",
+ "428",
+ "429",
+ "431",
+ "451",
+ "500",
+ "501",
+ "502",
+ "503",
+ "504",
+ "505",
+ "506",
+ "507",
+ "508",
+ "510",
+ "511"
+ ]
+ }
+ },
+ "initialisms": {
+ "description": "ST1003 check, among other things, for the correct capitalization of initialisms. The set of known initialisms can be configured with this option.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "default": [
+ "ACL",
+ "API",
+ "ASCII",
+ "CPU",
+ "CSS",
+ "DNS",
+ "EOF",
+ "GUID",
+ "HTML",
+ "HTTP",
+ "HTTPS",
+ "ID",
+ "IP",
+ "JSON",
+ "QPS",
+ "RAM",
+ "RPC",
+ "SLA",
+ "SMTP",
+ "SQL",
+ "SSH",
+ "TCP",
+ "TLS",
+ "TTL",
+ "UDP",
+ "UI",
+ "GID",
+ "UID",
+ "UUID",
+ "URI",
+ "URL",
+ "UTF8",
+ "VM",
+ "XML",
+ "XMPP",
+ "XSRF",
+ "XSS",
+ "SIP",
+ "RTP",
+ "AMQP",
+ "DB",
+ "TS"
+ ]
+ }
+ }
+ }
+ },
+ "tagalign": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "align": {
+ "description": "Align and sort can be used together or separately.",
+ "type": "boolean",
+ "default": true
+ },
+ "sort": {
+ "description": "Whether enable tags sort.",
+ "type": "boolean",
+ "default": true
+ },
+ "order": {
+ "description": "Specify the order of tags, the other tags will be sorted by name.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "default": [],
+ "examples": [
+ [
+ "json",
+ "yaml",
+ "yml",
+ "toml",
+ "mapstructure",
+ "binding",
+ "validate"
+ ]
+ ]
+ },
+ "strict": {
+ "description": "Whether enable strict style.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "tagliatelle": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "case": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "use-field-name": {
+ "description": "Use the struct field name to check the name of the struct tag.",
+ "type": "boolean",
+ "default": false
+ },
+ "rules": {
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "enum": [
+ "camel",
+ "pascal",
+ "kebab",
+ "snake",
+ "goCamel",
+ "goPascal",
+ "goKebab",
+ "goSnake",
+ "upper",
+ "upperSnake",
+ "lower",
+ "header"
+ ]
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "tenv": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "all": {
+ "description": "The option `all` will run against whole test files (`_test.go`) regardless of method/function signatures.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "testifylint": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "enable-all": {
+ "description": "Enable all checkers.",
+ "type": "boolean",
+ "default": false
+ },
+ "disable-all": {
+ "description": "Disable all checkers.",
+ "type": "boolean",
+ "default": false
+ },
+ "enable": {
+ "description": "Enable specific checkers.",
+ "type": "array",
+ "items": {
+ "enum": [
+ "blank-import",
+ "bool-compare",
+ "compares",
+ "empty",
+ "error-is-as",
+ "error-nil",
+ "expected-actual",
+ "float-compare",
+ "go-require",
+ "len",
+ "negative-positive",
+ "nil-compare",
+ "require-error",
+ "suite-dont-use-pkg",
+ "suite-extra-assert-call",
+ "suite-thelper",
+ "useless-assert"
+ ]
+ },
+ "default": [
+ "blank-import",
+ "bool-compare",
+ "compares",
+ "empty",
+ "error-is-as",
+ "error-nil",
+ "expected-actual",
+ "float-compare",
+ "go-require",
+ "len",
+ "negative-positive",
+ "nil-compare",
+ "require-error",
+ "suite-dont-use-pkg",
+ "suite-extra-assert-call",
+ "useless-assert"
+ ]
+ },
+ "disable": {
+ "description": "Disable specific checkers.",
+ "type": "array",
+ "items": {
+ "enum": [
+ "blank-import",
+ "bool-compare",
+ "compares",
+ "empty",
+ "error-is-as",
+ "error-nil",
+ "expected-actual",
+ "float-compare",
+ "go-require",
+ "len",
+ "negative-positive",
+ "nil-compare",
+ "require-error",
+ "suite-dont-use-pkg",
+ "suite-extra-assert-call",
+ "suite-thelper",
+ "useless-assert"
+ ],
+ "default": [
+ "suite-thelper"
+ ]
+ }
+ },
+ "bool-compare": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignore-custom-types": {
+ "description": "To ignore user defined types (over builtin bool).",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "expected-actual": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "pattern": {
+ "description": "Regexp for expected variable name.",
+ "type": "string",
+ "default": "(^(exp(ected)?|want(ed)?)([A-Z]\\w*)?$)|(^(\\w*[a-z])?(Exp(ected)?|Want(ed)?)$)"
+ }
+ }
+ },
+ "go-require": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignore-http-handlers": {
+ "description": "To ignore HTTP handlers (like http.HandlerFunc).",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "require-error": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "fn-pattern": {
+ "description": "Regexp for assertions to analyze. If defined, then only matched error assertions will be reported.",
+ "type": "string",
+ "default": ""
+ }
+ }
+ },
+ "suite-extra-assert-call": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "mode": {
+ "description": "To require or remove extra Assert() call?",
+ "type": "string",
+ "enum": ["remove", "require"],
+ "default": "remove"
+ }
+ }
+ }
+ }
+ },
+ "testpackage": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skip-regexp": {
+ "description": "Files with names matching this regular expression are skipped.",
+ "type": "string",
+ "examples": ["(export|internal)_test\\.go"]
+ },
+ "allow-packages": {
+ "description": "List of packages that don't end with _test that tests are allowed to be in.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["example"]
+ }
+ }
+ }
+ },
+ "thelper": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "test": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "begin": {
+ "description": "Check if `t.Helper()` begins helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "first": {
+ "description": "Check if *testing.T is first param of helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "name": {
+ "description": "Check if *testing.T param has t name.",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ },
+ "benchmark": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "begin": {
+ "description": "Check if `b.Helper()` begins helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "first": {
+ "description": "Check if *testing.B is first param of helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "name": {
+ "description": "Check if *testing.B param has b name.",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ },
+ "tb": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "begin": {
+ "description": "Check if `tb.Helper()` begins helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "first": {
+ "description": "Check if *testing.TB is first param of helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "name": {
+ "description": "Check if *testing.TB param has tb name.",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ },
+ "fuzz": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "begin": {
+ "description": "Check if `f.Helper()` begins helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "first": {
+ "description": "Check if *testing.F is first param of helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "name": {
+ "description": "Check if *testing.F param has f name.",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ }
+ }
+ },
+ "usestdlibvars": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "http-method": {
+ "description": "Suggest the use of http.MethodXX.",
+ "type": "boolean",
+ "default": true
+ },
+ "http-status-code": {
+ "description": "Suggest the use of http.StatusXX.",
+ "type": "boolean",
+ "default": true
+ },
+ "time-weekday": {
+ "description": "Suggest the use of time.Weekday.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "time-month": {
+ "description": "Suggest the use of time.Month.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "time-layout": {
+ "description": "Suggest the use of time.Layout.",
+ "type": "boolean",
+ "default": false
+ },
+ "crypto-hash": {
+ "description": "Suggest the use of crypto.Hash.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "default-rpc-path": {
+ "description": "Suggest the use of rpc.DefaultXXPath.",
+ "type": "boolean",
+ "default": false
+ },
+ "sql-isolation-level": {
+ "description": "Suggest the use of sql.LevelXX.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "tls-signature-scheme": {
+ "description": "Suggest the use of tls.SignatureScheme.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "constant-kind": {
+ "description": "Suggest the use of constant.Kind.String().",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "unconvert": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "fast-math": {
+ "type": "boolean",
+ "default": false
+ },
+ "safe": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "unparam": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-exported": {
+ "description": "Inspect exported functions. Set to true if no external program/library imports your code.\n\nWARNING: if you enable this setting, unparam will report a lot of false-positives in text editors:\nif it's called for subdir of a project it can't find external interfaces. All text editor integrations\nwith golangci-lint call it on a directory with the changed file.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "unused": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "field-writes-are-uses": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ },
+ "post-statements-are-reads": {
+ "description": "",
+ "type": "boolean",
+ "default": false
+ },
+ "exported-is-used": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ },
+ "exported-fields-are-used": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ },
+ "parameters-are-used": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ },
+ "local-variables-are-used": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ },
+ "generated-is-used": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "varnamelen": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-distance": {
+ "description": "Variables used in at most this N-many lines will be ignored.",
+ "type": "integer",
+ "default": 5
+ },
+ "min-name-length": {
+ "description": "The minimum length of a variable's name that is considered `long`.",
+ "type": "integer",
+ "default": 3
+ },
+ "check-receiver": {
+ "description": "Check method receiver names.",
+ "default": false,
+ "type": "boolean"
+ },
+ "check-return": {
+ "description": "Check named return values.",
+ "default": false,
+ "type": "boolean"
+ },
+ "check-type-param": {
+ "description": "Check type parameters.",
+ "default": false,
+ "type": "boolean"
+ },
+ "ignore-type-assert-ok": {
+ "description": "Ignore `ok` variables that hold the bool return value of a type assertion",
+ "default": false,
+ "type": "boolean"
+ },
+ "ignore-map-index-ok": {
+ "description": "Ignore `ok` variables that hold the bool return value of a map index.",
+ "default": false,
+ "type": "boolean"
+ },
+ "ignore-chan-recv-ok": {
+ "description": "Ignore `ok` variables that hold the bool return value of a channel receive.",
+ "default": false,
+ "type": "boolean"
+ },
+ "ignore-names": {
+ "description": "Optional list of variable names that should be ignored completely.",
+ "default": [[]],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignore-decls": {
+ "description": "Optional list of variable declarations that should be ignored completely.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "examples": [
+ ["c echo.Context", "t testing.T", "f *foo.Bar", "const C"]
+ ]
+ }
+ }
+ },
+ "whitespace": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "multi-if": {
+ "description": "Enforces newlines (or comments) after every multi-line if statement",
+ "type": "boolean",
+ "default": false
+ },
+ "multi-func": {
+ "description": "Enforces newlines (or comments) after every multi-line function signature",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "wrapcheck": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignoreSigs": {
+ "description": "An array of strings which specify substrings of signatures to ignore.",
+ "default": [
+ ".Errorf(",
+ "errors.New(",
+ "errors.Unwrap(",
+ ".Wrap(",
+ ".Wrapf(",
+ ".WithMessage(",
+ ".WithMessagef(",
+ ".WithStack("
+ ],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignoreSigRegexps": {
+ "description": "An array of strings which specify regular expressions of signatures to ignore.",
+ "default": [""],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignorePackageGlobs": {
+ "description": "An array of glob patterns which, if any match the package of the function returning the error, will skip wrapcheck analysis for this error.",
+ "default": [""],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignoreInterfaceRegexps": {
+ "description": "An array of glob patterns which, if matched to an underlying interface name, will ignore unwrapped errors returned from a function whose call is defined on the given interface.",
+ "default": [""],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "wsl": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "allow-assign-and-anything": {
+ "description": "Controls if you may cuddle assignments and anything without needing an empty line between them.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-assign-and-call": {
+ "description": "Allow calls and assignments to be cuddled as long as the lines have any matching variables, fields or types.",
+ "type": "boolean",
+ "default": true
+ },
+ "allow-cuddle-declarations": {
+ "description": "Allow declarations (var) to be cuddled.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-cuddle-with-calls": {
+ "description": "A list of call idents that everything can be cuddled with.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "allow-cuddle-with-rhs": {
+ "description": "AllowCuddleWithRHS is a list of right hand side variables that is allowed to be cuddled with anything.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "allow-multiline-assign": {
+ "description": "Allow multiline assignments to be cuddled.",
+ "type": "boolean",
+ "default": true
+ },
+ "allow-separated-leading-comment": {
+ "description": "Allow leading comments to be separated with empty lines.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-trailing-comment": {
+ "description": "Allow trailing comments in ending of blocks.",
+ "type": "boolean",
+ "default": false
+ },
+ "error-variable-names": {
+ "description": "When force-err-cuddling is enabled this is a list of names used for error variables to check for in the conditional.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "force-case-trailing-whitespace": {
+ "description": "Force newlines in end of case at this limit (0 = never).",
+ "type": "integer",
+ "minimum": 0,
+ "default": 0
+ },
+ "force-err-cuddling": {
+ "description": "Causes an error when an If statement that checks an error variable doesn't cuddle with the assignment of that variable.",
+ "type": "boolean",
+ "default": false
+ },
+ "force-short-decl-cuddling": {
+ "description": "Causes an error if a short declaration (:=) cuddles with anything other than another short declaration.",
+ "type": "boolean",
+ "default": false
+ },
+ "strict-append": {
+ "description": "If true, append is only allowed to be cuddled if appending value is matching variables, fields or types on line above.",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "copyloopvar": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-alias": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "custom": {
+ "description": "The custom section can be used to define linter plugins to be loaded at runtime. See README of golangci-lint for more information.\nEach custom linter should have a unique name.",
+ "type": "object",
+ "patternProperties": {
+ "^.*$": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "type": {
+ "description": "The plugin type.",
+ "enum": ["module", "goplugin"],
+ "default": "goplugin"
+ },
+ "path": {
+ "description": "The path to the plugin *.so. Can be absolute or local.",
+ "type": "string",
+ "examples": ["/path/to/example.so"]
+ },
+ "description": {
+ "description": "The description of the linter, for documentation purposes only.",
+ "type": "string"
+ },
+ "original-url": {
+ "description": "Intended to point to the repo location of the linter, for documentation purposes only.",
+ "type": "string"
+ },
+ "settings": {
+ "description": "Plugins settings/configuration. Only work with plugin based on `linterdb.PluginConstructor`.",
+ "type": "object"
+ }
+ },
+ "oneOf": [
+ {
+ "properties": {
+ "type": {"enum": ["module"] }
+ },
+ "required": ["type"]
+ },
+ {
+ "required": ["path"]
+ }
+ ]
+ }
+ }
+ }
+ }
+ },
+ "linters": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "enable": {
+ "description": "List of enabled linters.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linters"
+ }
+ },
+ "disable": {
+ "description": "List of disabled linters.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linters"
+ }
+ },
+ "enable-all": {
+ "description": "Whether to enable all linters. You can re-disable them with `disable` explicitly.",
+ "type": "boolean",
+ "default": false
+ },
+ "disable-all": {
+ "description": "Whether to disable all linters. You can re-enable them with `enable` explicitly.",
+ "type": "boolean",
+ "default": false
+ },
+ "presets": {
+ "description": "Allow to use different presets of linters",
+ "type": "array",
+ "items": {
+ "enum": [
+ "bugs",
+ "comment",
+ "complexity",
+ "error",
+ "format",
+ "import",
+ "metalinter",
+ "module",
+ "performance",
+ "sql",
+ "style",
+ "test",
+ "unused"
+ ]
+ }
+ },
+ "fast": {
+ "description": "Enable run of fast linters.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "issues": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "exclude": {
+ "description": "List of regular expressions of issue texts to exclude.\nBut independently from this option we use default exclude patterns. Their usage can be controlled through `exclude-use-default`.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "exclude-rules": {
+ "description": "Exclude configuration per-path, per-linter, per-text and per-source",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "path": {
+ "type": "string"
+ },
+ "path-except": {
+ "type": "string"
+ },
+ "linters": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linters"
+ }
+ },
+ "text": {
+ "type": "string"
+ },
+ "source": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "exclude-use-default": {
+ "description": "Independently from option `exclude` we use default exclude patterns. This behavior can be disabled by this option.",
+ "type": "boolean",
+ "default": true
+ },
+ "exclude-case-sensitive": {
+ "description": "If set to true, exclude and exclude-rules regular expressions become case sensitive.",
+ "type": "boolean",
+ "default": false
+ },
+ "exclude-generated": {
+ "description": "Mode of the generated files analysis.",
+ "enum": ["lax", "strict", "disable"],
+ "default": "lax"
+ },
+ "exclude-dirs": {
+ "description": "Which directories to exclude: issues from them won't be reported.",
+ "type": "array",
+ "items": {
+ "description": "You can use regexp here. The regexp is applied on the full path.\n\"/\" will be replaced by current OS file path separator to properly work on Windows.",
+ "type": "string",
+ "examples": ["generated.*"]
+ },
+ "default": [],
+ "examples": [["src/external_libs", "autogenerated_by_my_lib"]]
+ },
+ "exclude-dirs-use-default": {
+ "description": "Enable exclusion of directories \"vendor\", \"third_party\", \"testdata\", \"examples\", \"Godeps\", and \"builtin\".",
+ "type": "boolean",
+ "default": true
+ },
+ "exclude-files": {
+ "description": "Which files to exclude: they will be analyzed, but issues from them will not be reported.",
+ "type": "array",
+ "items": {
+ "description": "You can use regexp here. There is no need to include all autogenerated files, we confidently recognize them. If that is not the case, please let us know.\n\"/\" will be replaced by current OS file path separator to properly work on Windows.",
+ "type": "string",
+ "examples": [".*\\.my\\.go$"]
+ },
+ "default": [],
+ "examples": [[".*\\.my\\.go$", "lib/bad.go"]]
+ },
+ "include": {
+ "description": "The list of ids of default excludes to include or disable.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "default": []
+ },
+ "max-issues-per-linter": {
+ "description": "Maximum issues count per one linter. Set to 0 to disable.",
+ "type": "integer",
+ "default": 50,
+ "minimum": 0
+ },
+ "max-same-issues": {
+ "description": "Maximum count of issues with the same text. Set to 0 to disable.",
+ "type": "integer",
+ "default": 3,
+ "minimum": 0
+ },
+ "new": {
+ "description": "Show only new issues: if there are unstaged changes or untracked files, only those changes are analyzed, else only changes in HEAD~ are analyzed.",
+ "type": "boolean",
+ "default": false
+ },
+ "new-from-rev": {
+ "description": "Show only new issues created after this git revision.",
+ "type": "string"
+ },
+ "new-from-patch": {
+ "description": "Show only new issues created in git patch with this file path.",
+ "type": "string",
+ "examples": ["path/to/patch/file"]
+ },
+ "fix": {
+ "description": "Fix found issues (if it's supported by the linter).",
+ "type": "boolean",
+ "default": false
+ },
+ "whole-files": {
+ "description": "Show issues in any part of update files (requires new-from-rev or new-from-patch).",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "severity": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "default-severity": {
+ "description": "Set the default severity for issues. If severity rules are defined and the issues do not match or no severity is provided to the rule this will be the default severity applied. Severities should match the supported severity names of the selected out format.",
+ "type": "string",
+ "default": ""
+ },
+ "case-sensitive": {
+ "description": "If set to true, severity-rules regular expressions become case sensitive.",
+ "type": "boolean",
+ "default": false
+ },
+ "rules": {
+ "description": "When a list of severity rules are provided, severity information will be added to lint issues. Severity rules have the same filtering capability as exclude rules except you are allowed to specify one matcher per severity rule.\nOnly affects out formats that support setting severity information.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "severity": {
+ "type": "string"
+ },
+ "path": {
+ "type": "string"
+ },
+ "path-except": {
+ "type": "string"
+ },
+ "linters": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linters"
+ }
+ },
+ "text": {
+ "type": "string"
+ },
+ "source": {
+ "type": "string"
+ }
+ },
+ "required": ["severity"],
+ "anyOf": [
+ { "required": ["path"] },
+ { "required": ["path-except"] },
+ { "required": ["linters"] },
+ { "required": ["text"] },
+ { "required": ["source"] }
+ ]
+ },
+ "default": []
+ }
+ },
+ "required": ["default-severity"]
+ }
+ }
+}
diff --git a/vendor/github.com/golangci/golangci-lint/v2/jsonschema/golangci.v1.60.jsonschema.json b/vendor/github.com/golangci/golangci-lint/v2/jsonschema/golangci.v1.60.jsonschema.json
new file mode 100644
index 000000000..b8920ae06
--- /dev/null
+++ b/vendor/github.com/golangci/golangci-lint/v2/jsonschema/golangci.v1.60.jsonschema.json
@@ -0,0 +1,3792 @@
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "$id": "https://json.schemastore.org/golangci-lint.json",
+ "definitions": {
+ "gocritic-checks": {
+ "enum": [
+ "appendAssign",
+ "appendCombine",
+ "argOrder",
+ "assignOp",
+ "badCall",
+ "badCond",
+ "badLock",
+ "badRegexp",
+ "badSorting",
+ "boolExprSimplify",
+ "builtinShadow",
+ "builtinShadowDecl",
+ "captLocal",
+ "caseOrder",
+ "codegenComment",
+ "commentedOutCode",
+ "commentedOutImport",
+ "commentFormatting",
+ "defaultCaseOrder",
+ "deferUnlambda",
+ "deferInLoop",
+ "deprecatedComment",
+ "docStub",
+ "dupArg",
+ "dupBranchBody",
+ "dupCase",
+ "dupImport",
+ "dupSubExpr",
+ "dynamicFmtString",
+ "elseif",
+ "emptyDecl",
+ "emptyFallthrough",
+ "emptyStringTest",
+ "equalFold",
+ "evalOrder",
+ "exitAfterDefer",
+ "exposedSyncMutex",
+ "externalErrorReassign",
+ "filepathJoin",
+ "flagDeref",
+ "flagName",
+ "hexLiteral",
+ "httpNoBody",
+ "hugeParam",
+ "ifElseChain",
+ "importShadow",
+ "indexAlloc",
+ "initClause",
+ "ioutilDeprecated",
+ "mapKey",
+ "methodExprCall",
+ "nestingReduce",
+ "newDeref",
+ "nilValReturn",
+ "octalLiteral",
+ "offBy1",
+ "paramTypeCombine",
+ "preferDecodeRune",
+ "preferFilepathJoin",
+ "preferFprint",
+ "preferStringWriter",
+ "preferWriteByte",
+ "ptrToRefParam",
+ "rangeExprCopy",
+ "rangeValCopy",
+ "redundantSprint",
+ "regexpMust",
+ "regexpPattern",
+ "regexpSimplify",
+ "returnAfterHttpError",
+ "ruleguard",
+ "singleCaseSwitch",
+ "sliceClear",
+ "sloppyLen",
+ "sloppyReassign",
+ "sloppyTypeAssert",
+ "sortSlice",
+ "sprintfQuotedString",
+ "sqlQuery",
+ "stringConcatSimplify",
+ "stringsCompare",
+ "stringXbytes",
+ "suspiciousSorting",
+ "switchTrue",
+ "syncMapLoadAndDelete",
+ "timeCmpSimplify",
+ "timeExprSimplify",
+ "tooManyResultsChecker",
+ "truncateCmp",
+ "typeAssertChain",
+ "typeDefFirst",
+ "typeSwitchVar",
+ "typeUnparen",
+ "uncheckedInlineErr",
+ "underef",
+ "unlabelStmt",
+ "unlambda",
+ "unnamedResult",
+ "unnecessaryBlock",
+ "unnecessaryDefer",
+ "unslice",
+ "valSwap",
+ "weakCond",
+ "whyNoLint",
+ "wrapperFunc",
+ "yodaStyleExpr"
+ ]
+ },
+ "gocritic-tags": {
+ "enum": [
+ "diagnostic",
+ "style",
+ "performance",
+ "experimental",
+ "opinionated",
+ "security"
+ ]
+ },
+ "gosec-rules": {
+ "enum": [
+ "G101",
+ "G102",
+ "G103",
+ "G104",
+ "G106",
+ "G107",
+ "G108",
+ "G109",
+ "G110",
+ "G111",
+ "G112",
+ "G113",
+ "G114",
+ "G115",
+ "G201",
+ "G202",
+ "G203",
+ "G204",
+ "G301",
+ "G302",
+ "G303",
+ "G304",
+ "G305",
+ "G306",
+ "G307",
+ "G401",
+ "G402",
+ "G403",
+ "G404",
+ "G405",
+ "G406",
+ "G501",
+ "G502",
+ "G503",
+ "G504",
+ "G505",
+ "G506",
+ "G507",
+ "G601",
+ "G602"
+ ]
+ },
+ "govet-analyzers": {
+ "enum": [
+ "appends",
+ "asmdecl",
+ "assign",
+ "atomic",
+ "atomicalign",
+ "bools",
+ "buildtag",
+ "cgocall",
+ "composites",
+ "copylocks",
+ "deepequalerrors",
+ "defers",
+ "directive",
+ "errorsas",
+ "fieldalignment",
+ "findcall",
+ "framepointer",
+ "httpresponse",
+ "ifaceassert",
+ "loopclosure",
+ "lostcancel",
+ "nilfunc",
+ "nilness",
+ "printf",
+ "reflectvaluecompare",
+ "shadow",
+ "shift",
+ "sigchanyzer",
+ "slog",
+ "sortslice",
+ "stdmethods",
+ "stringintconv",
+ "structtag",
+ "testinggoroutine",
+ "tests",
+ "unmarshal",
+ "unreachable",
+ "unsafeptr",
+ "unusedresult",
+ "unusedwrite"
+ ]
+ },
+ "revive-rules": {
+ "enum": [
+ "add-constant",
+ "argument-limit",
+ "atomic",
+ "banned-characters",
+ "bare-return",
+ "blank-imports",
+ "bool-literal-in-expr",
+ "call-to-gc",
+ "cognitive-complexity",
+ "comment-spacings",
+ "comments-density",
+ "confusing-naming",
+ "confusing-results",
+ "constant-logical-expr",
+ "context-as-argument",
+ "context-keys-type",
+ "cyclomatic",
+ "datarace",
+ "deep-exit",
+ "defer",
+ "dot-imports",
+ "duplicated-imports",
+ "early-return",
+ "empty-block",
+ "empty-lines",
+ "enforce-map-style",
+ "enforce-repeated-arg-type-style",
+ "enforce-slice-style",
+ "error-naming",
+ "error-return",
+ "error-strings",
+ "errorf",
+ "exported",
+ "file-header",
+ "flag-parameter",
+ "function-length",
+ "function-result-limit",
+ "get-return",
+ "identical-branches",
+ "if-return",
+ "import-alias-naming",
+ "import-shadowing",
+ "imports-blocklist",
+ "increment-decrement",
+ "indent-error-flow",
+ "line-length-limit",
+ "max-control-nesting",
+ "max-public-structs",
+ "modifies-parameter",
+ "modifies-value-receiver",
+ "nested-structs",
+ "optimize-operands-order",
+ "package-comments",
+ "range",
+ "range-val-address",
+ "range-val-in-closure",
+ "receiver-naming",
+ "redefines-builtin-id",
+ "redundant-import-alias",
+ "string-format",
+ "string-of-int",
+ "struct-tag",
+ "superfluous-else",
+ "time-equal",
+ "time-naming",
+ "unchecked-type-assertion",
+ "unconditional-recursion",
+ "unexported-naming",
+ "unexported-return",
+ "unhandled-error",
+ "unnecessary-stmt",
+ "unreachable-code",
+ "unused-parameter",
+ "unused-receiver",
+ "use-any",
+ "useless-break",
+ "var-declaration",
+ "var-naming",
+ "waitgroup-by-value"
+ ]
+ },
+ "linters": {
+ "$comment": "anyOf with enum is used to allow auto completion of non-custom linters",
+ "description": "Linters usable.",
+ "anyOf": [
+ {
+ "enum": [
+ "asasalint",
+ "asciicheck",
+ "bidichk",
+ "bodyclose",
+ "canonicalheader",
+ "containedctx",
+ "contextcheck",
+ "copyloopvar",
+ "cyclop",
+ "deadcode",
+ "decorder",
+ "depguard",
+ "dogsled",
+ "dupl",
+ "dupword",
+ "durationcheck",
+ "errcheck",
+ "errchkjson",
+ "errname",
+ "errorlint",
+ "execinquery",
+ "exhaustive",
+ "exhaustivestruct",
+ "exhaustruct",
+ "exportloopref",
+ "fatcontext",
+ "forbidigo",
+ "forcetypeassert",
+ "funlen",
+ "gci",
+ "ginkgolinter",
+ "gocheckcompilerdirectives",
+ "gochecknoglobals",
+ "gochecknoinits",
+ "gochecksumtype",
+ "gocognit",
+ "goconst",
+ "gocritic",
+ "gocyclo",
+ "godot",
+ "godox",
+ "err113",
+ "gofmt",
+ "gofumpt",
+ "goheader",
+ "goimports",
+ "golint",
+ "gomoddirectives",
+ "gomodguard",
+ "goprintffuncname",
+ "gosec",
+ "gosimple",
+ "gosmopolitan",
+ "govet",
+ "grouper",
+ "ifshort",
+ "importas",
+ "inamedparam",
+ "ineffassign",
+ "interfacebloat",
+ "interfacer",
+ "intrange",
+ "ireturn",
+ "lll",
+ "loggercheck",
+ "maintidx",
+ "makezero",
+ "maligned",
+ "mirror",
+ "misspell",
+ "mnd",
+ "musttag",
+ "nakedret",
+ "nestif",
+ "nilerr",
+ "nilnil",
+ "nlreturn",
+ "noctx",
+ "nolintlint",
+ "nonamedreturns",
+ "nosnakecase",
+ "nosprintfhostport",
+ "paralleltest",
+ "perfsprint",
+ "prealloc",
+ "predeclared",
+ "promlinter",
+ "protogetter",
+ "reassign",
+ "revive",
+ "rowserrcheck",
+ "scopelint",
+ "sloglint",
+ "sqlclosecheck",
+ "staticcheck",
+ "structcheck",
+ "stylecheck",
+ "tagalign",
+ "tagliatelle",
+ "tenv",
+ "testableexamples",
+ "testifylint",
+ "testpackage",
+ "thelper",
+ "tparallel",
+ "typecheck",
+ "unconvert",
+ "unparam",
+ "unused",
+ "usestdlibvars",
+ "varcheck",
+ "varnamelen",
+ "wastedassign",
+ "whitespace",
+ "wrapcheck",
+ "wsl",
+ "zerologlint"
+ ]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ }
+ },
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "run": {
+ "description": "Options for analysis running,",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "concurrency": {
+ "description": "Number of concurrent runners. Defaults to the number of available CPU cores.",
+ "type": "integer",
+ "minimum": 0,
+ "examples": [4]
+ },
+ "timeout": {
+ "description": "Timeout for the analysis.",
+ "type": "string",
+ "pattern": "^((\\d+h)?(\\d+m)?(\\d+(?:\\.\\d)?s)?|0)$",
+ "default": "1m",
+ "examples": ["30s", "5m", "5m30s"]
+ },
+ "issues-exit-code": {
+ "description": "Exit code when at least one issue was found.",
+ "type": "integer",
+ "default": 1
+ },
+ "tests": {
+ "description": "Enable inclusion of test files.",
+ "type": "boolean",
+ "default": true
+ },
+ "build-tags": {
+ "description": "List of build tags to pass to all linters.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "default": [],
+ "examples": [["mytag"]]
+ },
+ "modules-download-mode": {
+ "description": "Option to pass to \"go list -mod={option}\".\nSee \"go help modules\" for more information.",
+ "enum": ["mod", "readonly", "vendor"]
+ },
+ "allow-parallel-runners": {
+ "description": "Allow multiple parallel golangci-lint instances running. If disabled, golangci-lint acquires file lock on start.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-serial-runners": {
+ "description": "Allow multiple golangci-lint instances running, but serialize them around a lock.",
+ "type": "boolean",
+ "default": false
+ },
+ "go": {
+ "description": "Targeted Go version.",
+ "type": "string",
+ "default": "1.17"
+ }
+ }
+ },
+ "output": {
+ "description": "Output configuration options.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "formats": {
+ "description": "Output formats to use.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "path": {
+ "default": "stdout",
+ "anyOf": [
+ {
+ "enum": [ "stdout", "stderr" ]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ },
+ "format": {
+ "default": "colored-line-number",
+ "enum": [
+ "colored-line-number",
+ "line-number",
+ "json",
+ "colored-tab",
+ "tab",
+ "html",
+ "checkstyle",
+ "code-climate",
+ "junit-xml",
+ "github-actions",
+ "teamcity",
+ "sarif"
+ ]
+ }
+ },
+ "required": ["format"]
+ }
+ },
+ "print-issued-lines": {
+ "description": "Print lines of code with issue.",
+ "type": "boolean",
+ "default": true
+ },
+ "print-linter-name": {
+ "description": "Print linter name in the end of issue text.",
+ "type": "boolean",
+ "default": true
+ },
+ "uniq-by-line": {
+ "description": "Make issues output unique by line.",
+ "type": "boolean",
+ "default": true
+ },
+ "path-prefix": {
+ "description": "Add a prefix to the output file references.",
+ "type": "string",
+ "default": ""
+ },
+ "show-stats": {
+ "description": "Show statistics per linter.",
+ "type": "boolean",
+ "default": false
+ },
+ "sort-order": {
+ "type": "array",
+ "items": {
+ "enum": ["linter", "severity", "file"]
+ }
+ },
+ "sort-results": {
+ "description": "Sort results by: filepath, line and column.",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "linters-settings": {
+ "description": "All available settings of specific linters.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "dupword": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "keywords": {
+ "description": "Keywords for detecting duplicate words. If this list is not empty, only the words defined in this list will be detected.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["the", "and", "a"]
+ }
+ },
+ "ignore": {
+ "description": "Keywords used to ignore detection.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["0C0C"]
+ }
+ }
+ }
+ },
+ "asasalint": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "exclude": {
+ "description": "To specify a set of function names to exclude.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["\\.Wrapf"]
+ }
+ },
+ "use-builtin-exclusions": {
+ "description": "To enable/disable the asasalint builtin exclusions of function names.",
+ "type": "boolean",
+ "default": true
+ },
+ "ignore-test": {
+ "description": "Ignore *_test.go files.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "bidichk": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "left-to-right-embedding": {
+ "description": "Disallow: LEFT-TO-RIGHT-EMBEDDING",
+ "type": "boolean",
+ "default": false
+ },
+ "right-to-left-embedding": {
+ "description": "Disallow: RIGHT-TO-LEFT-EMBEDDING",
+ "type": "boolean",
+ "default": false
+ },
+ "pop-directional-formatting": {
+ "description": "Disallow: POP-DIRECTIONAL-FORMATTING",
+ "type": "boolean",
+ "default": false
+ },
+ "left-to-right-override": {
+ "description": "Disallow: LEFT-TO-RIGHT-OVERRIDE",
+ "type": "boolean",
+ "default": false
+ },
+ "right-to-left-override": {
+ "description": "Disallow: RIGHT-TO-LEFT-OVERRIDE",
+ "type": "boolean",
+ "default": false
+ },
+ "left-to-right-isolate": {
+ "description": "Disallow: LEFT-TO-RIGHT-ISOLATE",
+ "type": "boolean",
+ "default": false
+ },
+ "right-to-left-isolate": {
+ "description": "Disallow: RIGHT-TO-LEFT-ISOLATE",
+ "type": "boolean",
+ "default": false
+ },
+ "first-strong-isolate": {
+ "description": "Disallow: FIRST-STRONG-ISOLATE",
+ "type": "boolean",
+ "default": false
+ },
+ "pop-directional-isolate": {
+ "description": "Disallow: POP-DIRECTIONAL-ISOLATE",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "cyclop": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skip-tests": {
+ "description": "Should the linter execute on test files as well",
+ "type": "boolean",
+ "default": false
+ },
+ "max-complexity": {
+ "description": "Max complexity the function can have",
+ "type": "integer",
+ "default": 10,
+ "minimum": 0
+ },
+ "package-average": {
+ "description": "Max average complexity in package",
+ "type": "number",
+ "default": 0,
+ "minimum": 0
+ }
+ }
+ },
+ "decorder": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "dec-order": {
+ "type": "array",
+ "default": [["type", "const", "var", "func"]],
+ "items": {
+ "enum": ["type", "const", "var", "func"]
+ }
+ },
+ "ignore-underscore-vars": {
+ "description": "Underscore vars (vars with \"_\" as the name) will be ignored at all checks",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-dec-order-check": {
+ "description": "Order of declarations is not checked",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-init-func-first-check": {
+ "description": "Allow init func to be anywhere in file",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-dec-num-check": {
+ "description": "Multiple global type, const and var declarations are allowed",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-type-dec-num-check": {
+ "description": "Type declarations will be ignored for dec num check",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-const-dec-num-check": {
+ "description": "Const declarations will be ignored for dec num check",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-var-dec-num-check": {
+ "description": "Var declarations will be ignored for dec num check",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ },
+ "depguard": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "rules": {
+ "description": "Rules to apply.",
+ "type": "object",
+ "additionalProperties": false,
+ "patternProperties": {
+ "^[^.]+$": {
+ "description": "Name of a rule.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "list-mode": {
+ "description": "Used to determine the package matching priority.",
+ "enum": ["original", "strict", "lax"],
+ "default": "original"
+ },
+ "files": {
+ "description": "List of file globs that will match this list of settings to compare against.",
+ "additionalProperties": false,
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "allow": {
+ "description": "List of allowed packages.",
+ "additionalProperties": false,
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "deny": {
+ "description": "Packages that are not allowed where the value is a suggestion.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "desc": {
+ "description": "Description",
+ "type": "string"
+ },
+ "pkg": {
+ "description": "Package",
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "dogsled": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-blank-identifiers": {
+ "description": "Check assignments with too many blank identifiers.",
+ "type": "integer",
+ "default": 2,
+ "minimum": 0
+ }
+ }
+ },
+ "dupl": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "threshold": {
+ "description": "Tokens count to trigger issue.",
+ "type": "integer",
+ "default": 150,
+ "minimum": 0
+ }
+ }
+ },
+ "errcheck": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-type-assertions": {
+ "description": "Report about not checking errors in type assertions, i.e.: `a := b.(MyStruct)`",
+ "type": "boolean",
+ "default": false
+ },
+ "check-blank": {
+ "description": "Report about assignment of errors to blank identifier",
+ "type": "boolean",
+ "default": false
+ },
+ "exclude-functions": {
+ "description": "List of functions to exclude from checking, where each entry is a single function to exclude",
+ "type": "array",
+ "examples": ["io/ioutil.ReadFile", "io.Copy(*bytes.Buffer)"],
+ "items": {
+ "type": "string"
+ }
+ },
+ "disable-default-exclusions": {
+ "description": "To disable the errcheck built-in exclude list",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "errchkjson": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-error-free-encoding": {
+ "type": "boolean",
+ "default": false
+ },
+ "report-no-exported": {
+ "description": "Issue on struct that doesn't have exported fields.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "errorlint": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "errorf": {
+ "description": "Check whether fmt.Errorf uses the %w verb for formatting errors",
+ "type": "boolean",
+ "default": true
+ },
+ "errorf-multi": {
+ "description": "Permit more than 1 %w verb, valid per Go 1.20",
+ "type": "boolean",
+ "default": true
+ },
+ "asserts": {
+ "description": "Check for plain type assertions and type switches.",
+ "type": "boolean",
+ "default": true
+ },
+ "comparison": {
+ "description": "Check for plain error comparisons",
+ "type": "boolean",
+ "default": true
+ },
+ "allowed-errors": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "err": {
+ "type": "string"
+ },
+ "fun": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "allowed-errors-wildcard": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "err": {
+ "type": "string"
+ },
+ "fun": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "exhaustive": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check": {
+ "description": "Program elements to check for exhaustiveness.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["switch", "map"]
+ }
+ },
+ "check-generated": {
+ "description": "Check switch statements in generated files",
+ "type": "boolean",
+ "default": false
+ },
+ "explicit-exhaustive-switch": {
+ "description": "Only run exhaustive check on switches with \"//exhaustive:enforce\" comment.",
+ "type": "boolean",
+ "default": false
+ },
+ "explicit-exhaustive-map": {
+ "description": "Only run exhaustive check on map literals with \"//exhaustive:enforce\" comment.",
+ "type": "boolean",
+ "default": false
+ },
+ "default-case-required": {
+ "description": "Switch statement requires default case even if exhaustive.",
+ "type": "boolean",
+ "default": false
+ },
+ "default-signifies-exhaustive": {
+ "description": "Presence of `default` case in switch statements satisfies exhaustiveness, even if all enum members are not listed.",
+ "type": "boolean",
+ "default": false
+ },
+ "ignore-enum-members": {
+ "description": "Enum members matching `regex` do not have to be listed in switch statements to satisfy exhaustiveness",
+ "type": "string"
+ },
+ "ignore-enum-types": {
+ "description": "Enum types matching the supplied regex do not have to be listed in switch statements to satisfy exhaustiveness.",
+ "type": "string"
+ },
+ "package-scope-only": {
+ "description": "Consider enums only in package scopes, not in inner scopes.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "exhaustruct": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "include": {
+ "description": "List of regular expressions to match struct packages and names.",
+ "type": "array",
+ "examples": [".*\\.Test"],
+ "items": {
+ "type": "string"
+ }
+ },
+ "exclude": {
+ "description": "List of regular expressions to exclude struct packages and names from check.",
+ "type": "array",
+ "examples": ["cobra\\.Command$"],
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "forbidigo": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "exclude-godoc-examples": {
+ "description": "Exclude code in godoc examples.",
+ "type": "boolean",
+ "default": true
+ },
+ "analyze-types": {
+ "description": "Instead of matching the literal source code, use type information to replace expressions with strings that contain the package name and (for methods and fields) the type name.",
+ "type": "boolean",
+ "default": true
+ },
+ "forbid": {
+ "description": "List of identifiers to forbid (written using `regexp`)",
+ "type": "array",
+ "examples": ["^print.*$"],
+ "items": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "p": {
+ "description": "Pattern",
+ "type": "string"
+ },
+ "pkg": {
+ "description": "Package",
+ "type": "string"
+ },
+ "msg": {
+ "description": "Message",
+ "type": "string"
+ }
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ "funlen": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "lines": {
+ "description": "Limit lines number per function.",
+ "type": "integer",
+ "default": 60
+ },
+ "statements": {
+ "description": "Limit statements number per function.",
+ "type": "integer",
+ "default": 40
+ },
+ "ignore-comments": {
+ "description": "Ignore comments when counting lines.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "gci": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "sections": {
+ "description": "Section configuration to compare against.",
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "enum": [
+ "standard",
+ "default",
+ "blank",
+ "dot",
+ "alias",
+ "localmodule"
+ ]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ },
+ "default": ["standard", "default"]
+ },
+ "skip-generated": {
+ "description": "Skip generated files.",
+ "type": "boolean",
+ "default": true
+ },
+ "custom-order": {
+ "description": "Enable custom order of sections.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "ginkgolinter": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "suppress-len-assertion": {
+ "description": "Suppress the wrong length assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-nil-assertion": {
+ "description": "Suppress the wrong nil assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-err-assertion": {
+ "description": "Suppress the wrong error assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-compare-assertion": {
+ "description": "Suppress the wrong comparison assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-async-assertion": {
+ "description": "Suppress the function all in async assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-type-compare-assertion": {
+ "description": "Suppress warning for comparing values from different types, like int32 and uint32.",
+ "type": "boolean",
+ "default": false
+ },
+ "forbid-focus-container": {
+ "description": "Trigger warning for ginkgo focus containers like FDescribe, FContext, FWhen or FIt.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-havelen-zero": {
+ "description": "Don't trigger warnings for HaveLen(0).",
+ "type": "boolean",
+ "default": false
+ },
+ "force-expect-to": {
+ "description": "Force using `Expect` with `To`, `ToNot` or `NotTo`",
+ "type": "boolean",
+ "default": false
+ },
+ "validate-async-intervals": {
+ "description": "Best effort validation of async intervals (timeout and polling).",
+ "type": "boolean",
+ "default": false
+ },
+ "forbid-spec-pollution": {
+ "description": "Trigger a warning for variable assignments in ginkgo containers like `Describe`, `Context` and `When`, instead of in `BeforeEach()`.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "gocognit": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "min-complexity": {
+ "description": "Minimal code complexity to report (we recommend 10-20).",
+ "type": "integer",
+ "default": 30
+ }
+ }
+ },
+ "goconst": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "match-constant": {
+ "description": "Look for existing constants matching the values",
+ "type": "boolean",
+ "default": true
+ },
+ "min-len": {
+ "description": "Minimum length of string constant.",
+ "type": "integer",
+ "default": 3
+ },
+ "min-occurrences": {
+ "description": "Minimum occurrences count to trigger.",
+ "type": "integer",
+ "default": 3
+ },
+ "ignore-tests": {
+ "description": "Ignore test files.",
+ "type": "boolean",
+ "default": false
+ },
+ "ignore-calls": {
+ "description": "Ignore when constant is not used as function argument",
+ "type": "boolean",
+ "default": true
+ },
+ "ignore-strings": {
+ "description": "Exclude strings matching the given regular expression",
+ "type": "string"
+ },
+ "numbers": {
+ "description": "Search also for duplicated numbers.",
+ "type": "boolean",
+ "default": false
+ },
+ "min": {
+ "description": "Minimum value, only works with `numbers`",
+ "type": "integer",
+ "default": 3
+ },
+ "max": {
+ "description": "Maximum value, only works with `numbers`",
+ "type": "integer",
+ "default": 3
+ }
+ }
+ },
+ "gocritic": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "enabled-checks": {
+ "description": "Which checks should be enabled. By default, a list of stable checks is used. To see it, run `GL_DEBUG=gocritic golangci-lint run`.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/gocritic-checks"
+ }
+ },
+ "disabled-checks": {
+ "description": "Which checks should be disabled.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/gocritic-checks"
+ },
+ "default": []
+ },
+ "enabled-tags": {
+ "description": "Enable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/gocritic-tags"
+ }
+ },
+ "disabled-tags": {
+ "description": "Disable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/gocritic-tags"
+ }
+ },
+ "settings": {
+ "description": "Settings passed to gocritic. Properties must be valid and enabled check names.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "captLocal": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "paramsOnly" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "commentedOutCode": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "minLength" : {
+ "type": "number",
+ "default": 15
+ }
+ }
+ },
+ "elseif": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skipBalanced" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "hugeParam": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "sizeThreshold" : {
+ "type": "number",
+ "default": 80
+ }
+ }
+ },
+ "ifElseChain": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "minThreshold" : {
+ "type": "number",
+ "default": 2
+ }
+ }
+ },
+ "nestingReduce": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "bodyWidth" : {
+ "type": "number",
+ "default": 5
+ }
+ }
+ },
+ "rangeExprCopy": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "sizeThreshold" : {
+ "type": "number",
+ "default": 512
+ },
+ "skipTestFuncs" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "rangeValCopy": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "sizeThreshold" : {
+ "type": "number",
+ "default": 128
+ },
+ "skipTestFuncs" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "ruleguard": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "debug" : {
+ "type": "string"
+ },
+ "enable" : {
+ "type": "string"
+ },
+ "disable" : {
+ "type": "string"
+ },
+ "failOn" : {
+ "type": "string"
+ },
+ "rules" : {
+ "type": "string"
+ }
+ }
+ },
+ "tooManyResultsChecker": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "maxResults" : {
+ "type": "number",
+ "default": 5
+ }
+ }
+ },
+ "truncateCmp": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skipArchDependent" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "underef": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skipRecvDeref" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "unnamedResult": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "checkExported" : {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ }
+ }
+ },
+ "disable-all": {
+ "type": "boolean",
+ "default": false
+ },
+ "enable-all": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "gocyclo": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "min-complexity": {
+ "description": "Minimum code complexity to report (we recommend 10-20).",
+ "type": "integer",
+ "default": 30
+ }
+ }
+ },
+ "godot": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "scope": {
+ "description": "Comments to be checked.",
+ "enum": ["declarations", "toplevel", "all"],
+ "default": "declarations"
+ },
+ "exclude": {
+ "description": "List of regexps for excluding particular comment lines from check.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "period": {
+ "description": "Check that each sentence ends with a period.",
+ "type": "boolean",
+ "default": true
+ },
+ "capital": {
+ "description": "Check that each sentence starts with a capital letter.",
+ "type": "boolean",
+ "default": false
+ },
+ "check-all": {
+ "description": "DEPRECATED: Check all top-level comments, not only declarations.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "godox": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "keywords": {
+ "description": "Report any comments starting with one of these keywords. This is useful for TODO or FIXME comments that might be left in the code accidentally and should be resolved before merging.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "default": ["TODO", "BUG", "FIXME"]
+ }
+ }
+ },
+ "gofmt": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "simplify": {
+ "description": "Simplify code.",
+ "type": "boolean",
+ "default": true
+ },
+ "rewrite-rules": {
+ "description": "Apply the rewrite rules to the source before reformatting.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "pattern": {
+ "type": "string"
+ },
+ "replacement": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "interfacebloat": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max": {
+ "description": "The maximum number of methods allowed for an interface.",
+ "type": "integer"
+ }
+ }
+ },
+ "gofumpt": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "extra-rules": {
+ "description": "Choose whether or not to use the extra rules that are disabled by default.",
+ "type": "boolean",
+ "default": false
+ },
+ "module-path": {
+ "description": " Module path which contains the source code being formatted.",
+ "type": "string"
+ }
+ }
+ },
+ "goheader": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "values": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "const": {
+ "description": "Constants to use in the template.",
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "description": "Value for the constant.",
+ "type": "string"
+ }
+ },
+ "additionalProperties": false,
+ "examples": [
+ {
+ "YEAR": "2030",
+ "COMPANY": "MY FUTURISTIC COMPANY"
+ }
+ ]
+ },
+ "regexp": {
+ "description": "Regular expressions to use in your template.",
+ "type": "object",
+ "additionalProperties": false,
+ "patternProperties": {
+ "^.+$": {
+ "type": "string"
+ }
+ },
+ "examples": [
+ {
+ "AUTHOR": ".*@mycompany\\.com"
+ }
+ ]
+ }
+ }
+ },
+ "template": {
+ "description": "Template to put on top of every file.",
+ "type": "string",
+ "examples": [
+ "{{ MY COMPANY }}\nSPDX-License-Identifier: Apache-2.0\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at:\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License."
+ ]
+ },
+ "template-path": {
+ "description": "Path to the file containing the template source.",
+ "type": "string",
+ "examples": ["my_header_template.txt"]
+ }
+ },
+ "oneOf": [
+ { "required": ["template"] },
+ { "required": ["template-path"] }
+ ]
+ },
+ "goimports": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "local-prefixes": {
+ "description": "Put imports beginning with prefix after 3rd-party packages. It is a comma-separated list of prefixes.",
+ "type": "string",
+ "examples": ["github.com/org/project"]
+ }
+ }
+ },
+ "gomoddirectives": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "replace-local": {
+ "description": "Allow local `replace` directives.",
+ "type": "boolean",
+ "default": true
+ },
+ "replace-allow-list": {
+ "description": "List of allowed `replace` directives.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "retract-allow-no-explanation": {
+ "description": "Allow to not explain why the version has been retracted in the `retract` directives.",
+ "type": "boolean",
+ "default": true
+ },
+ "exclude-forbidden": {
+ "description": "Forbid the use of the `exclude` directives.",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "gomodguard": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "allowed": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "modules": {
+ "description": "List of allowed modules.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["gopkg.in/yaml.v2"]
+ }
+ },
+ "domains": {
+ "description": "List of allowed module domains.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["golang.org"]
+ }
+ }
+ }
+ },
+ "blocked": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "modules": {
+ "description": "List of blocked modules.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "recommendations": {
+ "description": "Recommended modules that should be used instead.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "reason": {
+ "description": "Reason why the recommended module should be used.",
+ "type": "string"
+ }
+ }
+ }
+ },
+ "additionalProperties": false
+ }
+ },
+ "versions": {
+ "description": "List of blocked module version constraints.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "patternProperties": {
+ "^.*$": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "version": {
+ "description": "Version constraint.",
+ "type": "string"
+ },
+ "reason": {
+ "description": "Reason why the version constraint exists.",
+ "type": "string"
+ }
+ },
+ "required": ["reason"]
+ }
+ }
+ }
+ },
+ "local_replace_directives": {
+ "description": "Raise lint issues if loading local path with replace directive",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ }
+ }
+ },
+ "gosimple": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "checks": {
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "enum": ["all"]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ }
+ }
+ }
+ },
+ "gosec": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "includes": {
+ "type": "array",
+ "description": "To select a subset of rules to run",
+ "examples": [["G401"]],
+ "items": {
+ "$ref": "#/definitions/gosec-rules"
+ }
+ },
+ "excludes": {
+ "type": "array",
+ "description": "To specify a set of rules to explicitly exclude",
+ "examples": [["G401"]],
+ "items": {
+ "$ref": "#/definitions/gosec-rules"
+ }
+ },
+ "exclude-generated": {
+ "description": "Exclude generated files",
+ "type": "boolean",
+ "default": false
+ },
+ "severity": {
+ "description": "Filter out the issues with a lower severity than the given value",
+ "type": "string",
+ "enum": ["low", "medium", "high"],
+ "default": "low"
+ },
+ "confidence": {
+ "description": "Filter out the issues with a lower confidence than the given value",
+ "type": "string",
+ "enum": ["low", "medium", "high"],
+ "default": "low"
+ },
+ "config": {
+ "description": "To specify the configuration of rules",
+ "type": "object"
+ },
+ "concurrency": {
+ "description": "Concurrency value",
+ "type": "integer"
+ }
+ }
+ },
+ "gosmopolitan": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "allow-time-local": {
+ "description": "Allow and ignore `time.Local` usages.",
+ "type": "boolean",
+ "default": false
+ },
+ "escape-hatches": {
+ "description": "List of fully qualified names in the `full/pkg/path.name` form, to act as \"i18n escape hatches\".",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignore-tests": {
+ "description": "Ignore test files.",
+ "type": "boolean",
+ "default": false
+ },
+ "watch-for-scripts": {
+ "description": "List of Unicode scripts to watch for any usage in string literals.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "govet": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "settings": {
+ "description": "Settings per analyzer. Map of analyzer name to specific settings.\nRun `go tool vet help` to find out more.",
+ "type": "object",
+ "propertyNames": {
+ "$ref": "#/definitions/govet-analyzers"
+ },
+ "patternProperties": {
+ "^.*$": {
+ "description": "Run `go tool vet help ` to see all settings.",
+ "type": "object"
+ }
+ }
+ },
+ "enable": {
+ "description": "Enable analyzers by name.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/govet-analyzers"
+ }
+ },
+ "disable": {
+ "description": "Disable analyzers by name.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/govet-analyzers"
+ }
+ },
+ "enable-all": {
+ "description": "Enable all analyzers.",
+ "type": "boolean",
+ "default": false
+ },
+ "disable-all": {
+ "description": "Disable all analyzers.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "grouper": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "const-require-single-const": {
+ "type": "boolean",
+ "default": false
+ },
+ "const-require-grouping": {
+ "type": "boolean",
+ "default": false
+ },
+ "import-require-single-import": {
+ "type": "boolean",
+ "default": false
+ },
+ "import-require-grouping": {
+ "type": "boolean",
+ "default": false
+ },
+ "type-require-single-type": {
+ "type": "boolean",
+ "default": false
+ },
+ "type-require-grouping": {
+ "type": "boolean",
+ "default": false
+ },
+ "var-require-single-var": {
+ "type": "boolean",
+ "default": false
+ },
+ "var-require-grouping": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "importas": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "no-unaliased": {
+ "description": "Do not allow unaliased imports of aliased packages.",
+ "type": "boolean",
+ "default": false
+ },
+ "no-extra-aliases": {
+ "description": "Do not allow non-required aliases.",
+ "type": "boolean",
+ "default": false
+ },
+ "alias": {
+ "description": "List of aliases",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "pkg": {
+ "description": "Package path e.g. knative.dev/serving/pkg/apis/autoscaling/v1alpha1",
+ "type": "string"
+ },
+ "alias": {
+ "description": "Package alias e.g. autoscalingv1alpha1",
+ "type": "string"
+ }
+ },
+ "required": ["pkg", "alias"]
+ }
+ }
+ }
+ },
+ "inamedparam": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skip-single-param": {
+ "description": "Skips check for interface methods with only a single parameter.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "ireturn": {
+ "type": "object",
+ "additionalProperties": false,
+ "description": "Use either `reject` or `allow` properties for interfaces matching.",
+ "properties": {
+ "allow": {
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "enum": ["anon", "error", "empty", "stdlib"]
+ }
+ ]
+ }
+ },
+ "reject": {
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "enum": ["anon", "error", "empty", "stdlib"]
+ }
+ ]
+ }
+ }
+ },
+ "anyOf": [
+ {
+ "not": {
+ "properties": {
+ "allow": {
+ "const": "reject"
+ }
+ }
+ },
+ "required": ["allow"]
+ },
+ {
+ "required": ["reject"]
+ }
+ ]
+ },
+ "lll": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "tab-width": {
+ "description": "Width of \"\\t\" in spaces.",
+ "type": "integer",
+ "minimum": 0,
+ "default": 1
+ },
+ "line-length": {
+ "description": "Maximum allowed line length, lines longer will be reported.",
+ "type": "integer",
+ "minimum": 1,
+ "default": 120
+ }
+ }
+ },
+ "maintidx": {
+ "description": "Maintainability index https://docs.microsoft.com/en-us/visualstudio/code-quality/code-metrics-maintainability-index-range-and-meaning?view=vs-2022",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "under": {
+ "description": "Minimum accatpable maintainability index level (see https://docs.microsoft.com/en-us/visualstudio/code-quality/code-metrics-maintainability-index-range-and-meaning?view=vs-2022)",
+ "type": "number",
+ "default": 20
+ }
+ }
+ },
+ "makezero": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "always": {
+ "description": "Allow only slices initialized with a length of zero.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "loggercheck": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "kitlog": {
+ "description": "Allow check for the github.com/go-kit/log library.",
+ "type": "boolean",
+ "default": true
+ },
+ "klog": {
+ "description": "Allow check for the k8s.io/klog/v2 library.",
+ "type": "boolean",
+ "default": true
+ },
+ "logr": {
+ "description": "Allow check for the github.com/go-logr/logr library.",
+ "type": "boolean",
+ "default": true
+ },
+ "zap": {
+ "description": "Allow check for the \"sugar logger\" from go.uber.org/zap library.",
+ "type": "boolean",
+ "default": true
+ },
+ "require-string-key": {
+ "description": "Require all logging keys to be inlined constant strings.",
+ "type": "boolean",
+ "default": false
+ },
+ "no-printf-like": {
+ "description": "Require printf-like format specifier (%s, %d for example) not present.",
+ "type": "boolean",
+ "default": false
+ },
+ "rules": {
+ "description": "List of custom rules to check against, where each rule is a single logger pattern, useful for wrapped loggers.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "misspell": {
+ "description": "Correct spellings using locale preferences for US or UK. Default is to use a neutral variety of English.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "locale": {
+ "enum": ["US", "UK"]
+ },
+ "ignore-words": {
+ "description": "List of words to ignore.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "mode": {
+ "description": "Mode of the analysis.",
+ "enum": ["restricted", "", "default"],
+ "default": ""
+ },
+ "extra-words": {
+ "description": "Extra word corrections.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "correction": {
+ "type": "string"
+ },
+ "typo": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "musttag": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "functions": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "tag": {
+ "type": "string"
+ },
+ "arg-pos": {
+ "type": "integer"
+ }
+ }
+ }
+ }
+ }
+ },
+ "nakedret": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-func-lines": {
+ "description": "Report if a function has more lines of code than this value and it has naked returns.",
+ "type": "integer",
+ "minimum": 0,
+ "default": 30
+ }
+ }
+ },
+ "nestif": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "min-complexity": {
+ "description": "Minimum complexity of \"if\" statements to report.",
+ "type": "integer",
+ "default": 5
+ }
+ }
+ },
+ "nilnil": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "checked-types": {
+ "type": "array",
+ "description": "List of return types to check.",
+ "items": {
+ "enum": ["ptr", "func", "iface", "map", "chan", "uintptr", "unsafeptr"]
+ },
+ "default": ["ptr", "func", "iface", "map", "chan", "uintptr", "unsafeptr"]
+ }
+ }
+ },
+ "nlreturn": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "block-size": {
+ "description": "set block size that is still ok",
+ "type": "number",
+ "default": 0,
+ "minimum": 0
+ }
+ }
+ },
+ "mnd": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignored-files": {
+ "description": "List of file patterns to exclude from analysis.",
+ "examples": [["magic1_.*.go"]],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignored-functions": {
+ "description": "Comma-separated list of function patterns to exclude from the analysis.",
+ "examples": [["math.*", "http.StatusText", "make"]],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignored-numbers": {
+ "description": "List of numbers to exclude from analysis.",
+ "examples": [["1000", "1234_567_890", "3.14159264"]],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "checks": {
+ "description": "The list of enabled checks, see https://github.com/tommy-muehle/go-mnd/#checks for description.",
+ "type": "array",
+ "items": {
+ "enum": [
+ "argument",
+ "case",
+ "condition",
+ "operation",
+ "return",
+ "assign"
+ ]
+ }
+ }
+ }
+ },
+ "nolintlint": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "allow-unused": {
+ "description": "Enable to ensure that nolint directives are all used.",
+ "type": "boolean",
+ "default": true
+ },
+ "allow-no-explanation": {
+ "description": "Exclude these linters from requiring an explanation.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linters"
+ },
+ "default": []
+ },
+ "require-explanation": {
+ "description": "Enable to require an explanation of nonzero length after each nolint directive.",
+ "type": "boolean",
+ "default": false
+ },
+ "require-specific": {
+ "description": "Enable to require nolint directives to mention the specific linter being suppressed.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "reassign": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "patterns": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "nonamedreturns": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "report-error-in-defer": {
+ "description": "Report named error if it is assigned inside defer.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "paralleltest": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignore-missing": {
+ "description": "Ignore missing calls to `t.Parallel()` and only report incorrect uses of it.",
+ "type": "boolean",
+ "default": false
+ },
+ "ignore-missing-subtests": {
+ "description": "Ignore missing calls to `t.Parallel()` in subtests. Top-level tests are still required to have `t.Parallel`, but subtests are allowed to skip it.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "perfsprint": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "int-conversion": {
+ "description": "Optimizes even if it requires an int or uint type cast.",
+ "type": "boolean",
+ "default": true
+ },
+ "err-error": {
+ "description": "Optimizes into `err.Error()` even if it is only equivalent for non-nil errors.",
+ "type": "boolean",
+ "default": false
+ },
+ "errorf": {
+ "description": "Optimizes `fmt.Errorf`.",
+ "type": "boolean",
+ "default": true
+ },
+ "sprintf1": {
+ "description": "Optimizes `fmt.Sprintf` with only one argument.",
+ "type": "boolean",
+ "default": true
+ },
+ "strconcat": {
+ "description": "Optimizes into strings concatenation.",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "prealloc": {
+ "description": "We do not recommend using this linter before doing performance profiling.\nFor most programs usage of `prealloc` will be premature optimization.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "simple": {
+ "description": "Report preallocation suggestions only on simple loops that have no returns/breaks/continues/gotos in them.",
+ "type": "boolean",
+ "default": true
+ },
+ "range-loops": {
+ "description": "Report preallocation suggestions on range loops.",
+ "type": "boolean",
+ "default": true
+ },
+ "for-loops": {
+ "description": "Report preallocation suggestions on for loops.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "predeclared": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignore": {
+ "description": "Comma-separated list of predeclared identifiers to not report on.",
+ "type": "string"
+ },
+ "q": {
+ "description": "Include method names and field names (i.e., qualified names) in checks.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "promlinter": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "strict": {},
+ "disabled-linters": {
+ "type": "array",
+ "items": {
+ "enum": [
+ "Help",
+ "MetricUnits",
+ "Counter",
+ "HistogramSummaryReserved",
+ "MetricTypeInName",
+ "ReservedChars",
+ "CamelCase",
+ "UnitAbbreviations"
+ ]
+ }
+ }
+ }
+ },
+ "protogetter": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skip-generated-by": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["protoc-gen-go-my-own-generator"]
+ }
+ },
+ "skip-files": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["*.pb.go"]
+ }
+ },
+ "skip-any-generated": {
+ "description": "Skip any generated files from the checking.",
+ "type": "boolean",
+ "default": false
+ },
+ "replace-first-arg-in-append": {
+ "description": "Skip first argument of append function.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "revive": {
+ "type": "object",
+ "additionalProperties": false,
+ "examples": [
+ {
+ "ignore-generated-header": true,
+ "severity": "warning",
+ "rules": [
+ {
+ "name": "indent-error-flow",
+ "severity": "warning"
+ },
+ {
+ "name": "add-constant",
+ "severity": "warning",
+ "arguments": [
+ {
+ "maxLitCount": "3",
+ "allowStrs": "\"\"",
+ "allowInts": "0,1,2",
+ "allowFloats": "0.0,0.,1.0,1.,2.0,2."
+ }
+ ]
+ }
+ ]
+ }
+ ],
+ "properties": {
+ "max-open-files": {
+ "type": "integer"
+ },
+ "ignore-generated-header": {
+ "type": "boolean"
+ },
+ "confidence": {
+ "type": "number"
+ },
+ "severity": {
+ "type": "string",
+ "enum": ["warning", "error"]
+ },
+ "enable-all-rules": {
+ "type": "boolean",
+ "default": false
+ },
+ "directives": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "name": {
+ "type": "string",
+ "enum": ["specify-disable-reason"]
+ },
+ "severity": {
+ "type": "string",
+ "enum": ["warning", "error"]
+ },
+ "exclude": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "arguments": {
+ "type": "array"
+ }
+ }
+ }
+ },
+ "rules": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["name"],
+ "properties": {
+ "name": {
+ "$ref": "#/definitions/revive-rules",
+ "title": "The rule name"
+ },
+ "disabled": {
+ "type": "boolean"
+ },
+ "severity": {
+ "type": "string",
+ "enum": ["warning", "error"]
+ },
+ "exclude": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "arguments": {
+ "type": "array"
+ }
+ }
+ }
+ }
+ }
+ },
+ "rowserrcheck": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "packages": {
+ "type": "array",
+ "items": {
+ "description": "",
+ "type": "string",
+ "examples": ["github.com/jmoiron/sqlx"]
+ }
+ }
+ }
+ },
+ "sloglint": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "kv-only": {
+ "description": "Enforce using key-value pairs only (incompatible with attr-only).",
+ "type": "boolean",
+ "default": false
+ },
+ "no-global": {
+ "description": "Enforce not using global loggers.",
+ "enum": ["", "all", "default"],
+ "default": ""
+ },
+ "no-mixed-args": {
+ "description": "Enforce not mixing key-value pairs and attributes.",
+ "type": "boolean",
+ "default": true
+ },
+ "context": {
+ "description": "Enforce using methods that accept a context.",
+ "enum": ["", "all", "scope"],
+ "default": ""
+ },
+ "static-msg": {
+ "description": "Enforce using static values for log messages.",
+ "type": "boolean",
+ "default": false
+ },
+ "key-naming-case": {
+ "description": "Enforce a single key naming convention.",
+ "enum": ["snake", "kebab", "camel", "pascal"]
+ },
+ "attr-only": {
+ "description": "Enforce using attributes only (incompatible with kv-only).",
+ "type": "boolean",
+ "default": false
+ },
+ "no-raw-keys": {
+ "description": "Enforce using constants instead of raw keys.",
+ "type": "boolean",
+ "default": false
+ },
+ "forbidden-keys": {
+ "description": "Enforce not using specific keys.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "args-on-sep-lines": {
+ "description": "Enforce putting arguments on separate lines.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "spancheck": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "checks": {
+ "description": "Checks to enable.",
+ "type": "array",
+ "items": {
+ "enum": ["end", "record-error", "set-status"]
+ }
+ },
+ "ignore-check-signatures": {
+ "description": "A list of regexes for function signatures that silence `record-error` and `set-status` reports if found in the call path to a returned error.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "extra-start-span-signatures": {
+ "description": "A list of regexes for additional function signatures that create spans.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "staticcheck": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "checks": {
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "enum": ["all"]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ }
+ }
+ }
+ },
+ "stylecheck": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "checks": {
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "enum": ["all"]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ },
+ "default": [
+ "all",
+ "-ST1000",
+ "-ST1003",
+ "-ST1016",
+ "-ST1020",
+ "-ST1021",
+ "-ST1022"
+ ]
+ },
+ "dot-import-whitelist": {
+ "description": "By default, ST1001 forbids all uses of dot imports in non-test packages. This setting allows setting a whitelist of import paths that can be dot-imported anywhere.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "http-status-code-whitelist": {
+ "description": "ST1013 recommends using constants from the net/http package instead of hard-coding numeric HTTP status codes. This setting specifies a list of numeric status codes that this check does not complain about.",
+ "default": ["200", "400", "404", "500"],
+ "type": "array",
+ "items": {
+ "enum": [
+ "100",
+ "101",
+ "102",
+ "103",
+ "200",
+ "201",
+ "202",
+ "203",
+ "204",
+ "205",
+ "206",
+ "207",
+ "208",
+ "226",
+ "300",
+ "301",
+ "302",
+ "303",
+ "304",
+ "305",
+ "306",
+ "307",
+ "308",
+ "400",
+ "401",
+ "402",
+ "403",
+ "404",
+ "405",
+ "406",
+ "407",
+ "408",
+ "409",
+ "410",
+ "411",
+ "412",
+ "413",
+ "414",
+ "415",
+ "416",
+ "417",
+ "418",
+ "421",
+ "422",
+ "423",
+ "424",
+ "425",
+ "426",
+ "428",
+ "429",
+ "431",
+ "451",
+ "500",
+ "501",
+ "502",
+ "503",
+ "504",
+ "505",
+ "506",
+ "507",
+ "508",
+ "510",
+ "511"
+ ]
+ }
+ },
+ "initialisms": {
+ "description": "ST1003 check, among other things, for the correct capitalization of initialisms. The set of known initialisms can be configured with this option.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "default": [
+ "ACL",
+ "API",
+ "ASCII",
+ "CPU",
+ "CSS",
+ "DNS",
+ "EOF",
+ "GUID",
+ "HTML",
+ "HTTP",
+ "HTTPS",
+ "ID",
+ "IP",
+ "JSON",
+ "QPS",
+ "RAM",
+ "RPC",
+ "SLA",
+ "SMTP",
+ "SQL",
+ "SSH",
+ "TCP",
+ "TLS",
+ "TTL",
+ "UDP",
+ "UI",
+ "GID",
+ "UID",
+ "UUID",
+ "URI",
+ "URL",
+ "UTF8",
+ "VM",
+ "XML",
+ "XMPP",
+ "XSRF",
+ "XSS",
+ "SIP",
+ "RTP",
+ "AMQP",
+ "DB",
+ "TS"
+ ]
+ }
+ }
+ }
+ },
+ "tagalign": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "align": {
+ "description": "Align and sort can be used together or separately.",
+ "type": "boolean",
+ "default": true
+ },
+ "sort": {
+ "description": "Whether enable tags sort.",
+ "type": "boolean",
+ "default": true
+ },
+ "order": {
+ "description": "Specify the order of tags, the other tags will be sorted by name.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "default": [],
+ "examples": [
+ [
+ "json",
+ "yaml",
+ "yml",
+ "toml",
+ "mapstructure",
+ "binding",
+ "validate"
+ ]
+ ]
+ },
+ "strict": {
+ "description": "Whether enable strict style.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "tagliatelle": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "case": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "use-field-name": {
+ "description": "Use the struct field name to check the name of the struct tag.",
+ "type": "boolean",
+ "default": false
+ },
+ "rules": {
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "enum": [
+ "camel",
+ "pascal",
+ "kebab",
+ "snake",
+ "goCamel",
+ "goPascal",
+ "goKebab",
+ "goSnake",
+ "upper",
+ "upperSnake",
+ "lower",
+ "header"
+ ]
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "tenv": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "all": {
+ "description": "The option `all` will run against whole test files (`_test.go`) regardless of method/function signatures.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "testifylint": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "enable-all": {
+ "description": "Enable all checkers.",
+ "type": "boolean",
+ "default": false
+ },
+ "disable-all": {
+ "description": "Disable all checkers.",
+ "type": "boolean",
+ "default": false
+ },
+ "enable": {
+ "description": "Enable specific checkers.",
+ "type": "array",
+ "items": {
+ "enum": [
+ "blank-import",
+ "bool-compare",
+ "compares",
+ "empty",
+ "error-is-as",
+ "error-nil",
+ "expected-actual",
+ "float-compare",
+ "formatter",
+ "go-require",
+ "len",
+ "negative-positive",
+ "nil-compare",
+ "require-error",
+ "suite-broken-parallel",
+ "suite-dont-use-pkg",
+ "suite-extra-assert-call",
+ "suite-subtest-run",
+ "suite-thelper",
+ "useless-assert"
+ ]
+ },
+ "default": [
+ "blank-import",
+ "bool-compare",
+ "compares",
+ "empty",
+ "error-is-as",
+ "error-nil",
+ "expected-actual",
+ "float-compare",
+ "float-compare",
+ "go-require",
+ "len",
+ "negative-positive",
+ "nil-compare",
+ "require-error",
+ "suite-broken-parallel",
+ "suite-dont-use-pkg",
+ "suite-extra-assert-call",
+ "suite-subtest-run",
+ "useless-assert"
+ ]
+ },
+ "disable": {
+ "description": "Disable specific checkers.",
+ "type": "array",
+ "items": {
+ "enum": [
+ "blank-import",
+ "bool-compare",
+ "compares",
+ "empty",
+ "error-is-as",
+ "error-nil",
+ "expected-actual",
+ "float-compare",
+ "formatter",
+ "go-require",
+ "len",
+ "negative-positive",
+ "nil-compare",
+ "require-error",
+ "suite-broken-parallel",
+ "suite-dont-use-pkg",
+ "suite-extra-assert-call",
+ "suite-subtest-run",
+ "suite-thelper",
+ "useless-assert"
+ ],
+ "default": [
+ "suite-thelper"
+ ]
+ }
+ },
+ "bool-compare": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignore-custom-types": {
+ "description": "To ignore user defined types (over builtin bool).",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "expected-actual": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "pattern": {
+ "description": "Regexp for expected variable name.",
+ "type": "string",
+ "default": "(^(exp(ected)?|want(ed)?)([A-Z]\\w*)?$)|(^(\\w*[a-z])?(Exp(ected)?|Want(ed)?)$)"
+ }
+ }
+ },
+ "formatter": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-format-string": {
+ "description": "To enable go vet's printf checks.",
+ "type": "boolean",
+ "default": true
+ },
+ "require-f-funcs": {
+ "description": "To require f-assertions if format string is used.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "go-require": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignore-http-handlers": {
+ "description": "To ignore HTTP handlers (like http.HandlerFunc).",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "require-error": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "fn-pattern": {
+ "description": "Regexp for assertions to analyze. If defined, then only matched error assertions will be reported.",
+ "type": "string",
+ "default": ""
+ }
+ }
+ },
+ "suite-extra-assert-call": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "mode": {
+ "description": "To require or remove extra Assert() call?",
+ "type": "string",
+ "enum": ["remove", "require"],
+ "default": "remove"
+ }
+ }
+ }
+ }
+ },
+ "testpackage": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skip-regexp": {
+ "description": "Files with names matching this regular expression are skipped.",
+ "type": "string",
+ "examples": ["(export|internal)_test\\.go"]
+ },
+ "allow-packages": {
+ "description": "List of packages that don't end with _test that tests are allowed to be in.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["example"]
+ }
+ }
+ }
+ },
+ "thelper": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "test": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "begin": {
+ "description": "Check if `t.Helper()` begins helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "first": {
+ "description": "Check if *testing.T is first param of helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "name": {
+ "description": "Check if *testing.T param has t name.",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ },
+ "benchmark": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "begin": {
+ "description": "Check if `b.Helper()` begins helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "first": {
+ "description": "Check if *testing.B is first param of helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "name": {
+ "description": "Check if *testing.B param has b name.",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ },
+ "tb": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "begin": {
+ "description": "Check if `tb.Helper()` begins helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "first": {
+ "description": "Check if *testing.TB is first param of helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "name": {
+ "description": "Check if *testing.TB param has tb name.",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ },
+ "fuzz": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "begin": {
+ "description": "Check if `f.Helper()` begins helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "first": {
+ "description": "Check if *testing.F is first param of helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "name": {
+ "description": "Check if *testing.F param has f name.",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ }
+ }
+ },
+ "usestdlibvars": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "http-method": {
+ "description": "Suggest the use of http.MethodXX.",
+ "type": "boolean",
+ "default": true
+ },
+ "http-status-code": {
+ "description": "Suggest the use of http.StatusXX.",
+ "type": "boolean",
+ "default": true
+ },
+ "time-weekday": {
+ "description": "Suggest the use of time.Weekday.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "time-month": {
+ "description": "Suggest the use of time.Month.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "time-layout": {
+ "description": "Suggest the use of time.Layout.",
+ "type": "boolean",
+ "default": false
+ },
+ "crypto-hash": {
+ "description": "Suggest the use of crypto.Hash.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "default-rpc-path": {
+ "description": "Suggest the use of rpc.DefaultXXPath.",
+ "type": "boolean",
+ "default": false
+ },
+ "sql-isolation-level": {
+ "description": "Suggest the use of sql.LevelXX.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "tls-signature-scheme": {
+ "description": "Suggest the use of tls.SignatureScheme.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "constant-kind": {
+ "description": "Suggest the use of constant.Kind.String().",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "unconvert": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "fast-math": {
+ "type": "boolean",
+ "default": false
+ },
+ "safe": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "unparam": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-exported": {
+ "description": "Inspect exported functions. Set to true if no external program/library imports your code.\n\nWARNING: if you enable this setting, unparam will report a lot of false-positives in text editors:\nif it's called for subdir of a project it can't find external interfaces. All text editor integrations\nwith golangci-lint call it on a directory with the changed file.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "unused": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "field-writes-are-uses": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ },
+ "post-statements-are-reads": {
+ "description": "",
+ "type": "boolean",
+ "default": false
+ },
+ "exported-fields-are-used": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ },
+ "parameters-are-used": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ },
+ "local-variables-are-used": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ },
+ "generated-is-used": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "varnamelen": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-distance": {
+ "description": "Variables used in at most this N-many lines will be ignored.",
+ "type": "integer",
+ "default": 5
+ },
+ "min-name-length": {
+ "description": "The minimum length of a variable's name that is considered `long`.",
+ "type": "integer",
+ "default": 3
+ },
+ "check-receiver": {
+ "description": "Check method receiver names.",
+ "default": false,
+ "type": "boolean"
+ },
+ "check-return": {
+ "description": "Check named return values.",
+ "default": false,
+ "type": "boolean"
+ },
+ "check-type-param": {
+ "description": "Check type parameters.",
+ "default": false,
+ "type": "boolean"
+ },
+ "ignore-type-assert-ok": {
+ "description": "Ignore `ok` variables that hold the bool return value of a type assertion",
+ "default": false,
+ "type": "boolean"
+ },
+ "ignore-map-index-ok": {
+ "description": "Ignore `ok` variables that hold the bool return value of a map index.",
+ "default": false,
+ "type": "boolean"
+ },
+ "ignore-chan-recv-ok": {
+ "description": "Ignore `ok` variables that hold the bool return value of a channel receive.",
+ "default": false,
+ "type": "boolean"
+ },
+ "ignore-names": {
+ "description": "Optional list of variable names that should be ignored completely.",
+ "default": [[]],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignore-decls": {
+ "description": "Optional list of variable declarations that should be ignored completely.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "examples": [
+ ["c echo.Context", "t testing.T", "f *foo.Bar", "const C"]
+ ]
+ }
+ }
+ },
+ "whitespace": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "multi-if": {
+ "description": "Enforces newlines (or comments) after every multi-line if statement",
+ "type": "boolean",
+ "default": false
+ },
+ "multi-func": {
+ "description": "Enforces newlines (or comments) after every multi-line function signature",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "wrapcheck": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignoreSigs": {
+ "description": "An array of strings which specify substrings of signatures to ignore.",
+ "default": [
+ ".Errorf(",
+ "errors.New(",
+ "errors.Unwrap(",
+ ".Wrap(",
+ ".Wrapf(",
+ ".WithMessage(",
+ ".WithMessagef(",
+ ".WithStack("
+ ],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignoreSigRegexps": {
+ "description": "An array of strings which specify regular expressions of signatures to ignore.",
+ "default": [""],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignorePackageGlobs": {
+ "description": "An array of glob patterns which, if any match the package of the function returning the error, will skip wrapcheck analysis for this error.",
+ "default": [""],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignoreInterfaceRegexps": {
+ "description": "An array of glob patterns which, if matched to an underlying interface name, will ignore unwrapped errors returned from a function whose call is defined on the given interface.",
+ "default": [""],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "wsl": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "allow-assign-and-anything": {
+ "description": "Controls if you may cuddle assignments and anything without needing an empty line between them.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-assign-and-call": {
+ "description": "Allow calls and assignments to be cuddled as long as the lines have any matching variables, fields or types.",
+ "type": "boolean",
+ "default": true
+ },
+ "allow-cuddle-declarations": {
+ "description": "Allow declarations (var) to be cuddled.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-cuddle-with-calls": {
+ "description": "A list of call idents that everything can be cuddled with.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "allow-cuddle-with-rhs": {
+ "description": "AllowCuddleWithRHS is a list of right hand side variables that is allowed to be cuddled with anything.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "allow-multiline-assign": {
+ "description": "Allow multiline assignments to be cuddled.",
+ "type": "boolean",
+ "default": true
+ },
+ "allow-separated-leading-comment": {
+ "description": "Allow leading comments to be separated with empty lines.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-trailing-comment": {
+ "description": "Allow trailing comments in ending of blocks.",
+ "type": "boolean",
+ "default": false
+ },
+ "error-variable-names": {
+ "description": "When force-err-cuddling is enabled this is a list of names used for error variables to check for in the conditional.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "force-case-trailing-whitespace": {
+ "description": "Force newlines in end of case at this limit (0 = never).",
+ "type": "integer",
+ "minimum": 0,
+ "default": 0
+ },
+ "force-err-cuddling": {
+ "description": "Causes an error when an If statement that checks an error variable doesn't cuddle with the assignment of that variable.",
+ "type": "boolean",
+ "default": false
+ },
+ "force-short-decl-cuddling": {
+ "description": "Causes an error if a short declaration (:=) cuddles with anything other than another short declaration.",
+ "type": "boolean",
+ "default": false
+ },
+ "strict-append": {
+ "description": "If true, append is only allowed to be cuddled if appending value is matching variables, fields or types on line above.",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "copyloopvar": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-alias": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "custom": {
+ "description": "The custom section can be used to define linter plugins to be loaded at runtime. See README of golangci-lint for more information.\nEach custom linter should have a unique name.",
+ "type": "object",
+ "patternProperties": {
+ "^.*$": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "type": {
+ "description": "The plugin type.",
+ "enum": ["module", "goplugin"],
+ "default": "goplugin"
+ },
+ "path": {
+ "description": "The path to the plugin *.so. Can be absolute or local.",
+ "type": "string",
+ "examples": ["/path/to/example.so"]
+ },
+ "description": {
+ "description": "The description of the linter, for documentation purposes only.",
+ "type": "string"
+ },
+ "original-url": {
+ "description": "Intended to point to the repo location of the linter, for documentation purposes only.",
+ "type": "string"
+ },
+ "settings": {
+ "description": "Plugins settings/configuration. Only work with plugin based on `linterdb.PluginConstructor`.",
+ "type": "object"
+ }
+ },
+ "oneOf": [
+ {
+ "properties": {
+ "type": {"enum": ["module"] }
+ },
+ "required": ["type"]
+ },
+ {
+ "required": ["path"]
+ }
+ ]
+ }
+ }
+ }
+ }
+ },
+ "linters": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "enable": {
+ "description": "List of enabled linters.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linters"
+ }
+ },
+ "disable": {
+ "description": "List of disabled linters.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linters"
+ }
+ },
+ "enable-all": {
+ "description": "Whether to enable all linters. You can re-disable them with `disable` explicitly.",
+ "type": "boolean",
+ "default": false
+ },
+ "disable-all": {
+ "description": "Whether to disable all linters. You can re-enable them with `enable` explicitly.",
+ "type": "boolean",
+ "default": false
+ },
+ "presets": {
+ "description": "Allow to use different presets of linters",
+ "type": "array",
+ "items": {
+ "enum": [
+ "bugs",
+ "comment",
+ "complexity",
+ "error",
+ "format",
+ "import",
+ "metalinter",
+ "module",
+ "performance",
+ "sql",
+ "style",
+ "test",
+ "unused"
+ ]
+ }
+ },
+ "fast": {
+ "description": "Enable run of fast linters.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "issues": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "exclude": {
+ "description": "List of regular expressions of issue texts to exclude.\nBut independently from this option we use default exclude patterns. Their usage can be controlled through `exclude-use-default`.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "exclude-rules": {
+ "description": "Exclude configuration per-path, per-linter, per-text and per-source",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "path": {
+ "type": "string"
+ },
+ "path-except": {
+ "type": "string"
+ },
+ "linters": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linters"
+ }
+ },
+ "text": {
+ "type": "string"
+ },
+ "source": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "exclude-use-default": {
+ "description": "Independently from option `exclude` we use default exclude patterns. This behavior can be disabled by this option.",
+ "type": "boolean",
+ "default": true
+ },
+ "exclude-case-sensitive": {
+ "description": "If set to true, exclude and exclude-rules regular expressions become case sensitive.",
+ "type": "boolean",
+ "default": false
+ },
+ "exclude-generated": {
+ "description": "Mode of the generated files analysis.",
+ "enum": ["lax", "strict", "disable"],
+ "default": "lax"
+ },
+ "exclude-dirs": {
+ "description": "Which directories to exclude: issues from them won't be reported.",
+ "type": "array",
+ "items": {
+ "description": "You can use regexp here. The regexp is applied on the full path.\n\"/\" will be replaced by current OS file path separator to properly work on Windows.",
+ "type": "string",
+ "examples": ["generated.*"]
+ },
+ "default": [],
+ "examples": [["src/external_libs", "autogenerated_by_my_lib"]]
+ },
+ "exclude-dirs-use-default": {
+ "description": "Enable exclusion of directories \"vendor\", \"third_party\", \"testdata\", \"examples\", \"Godeps\", and \"builtin\".",
+ "type": "boolean",
+ "default": true
+ },
+ "exclude-files": {
+ "description": "Which files to exclude: they will be analyzed, but issues from them will not be reported.",
+ "type": "array",
+ "items": {
+ "description": "You can use regexp here. There is no need to include all autogenerated files, we confidently recognize them. If that is not the case, please let us know.\n\"/\" will be replaced by current OS file path separator to properly work on Windows.",
+ "type": "string",
+ "examples": [".*\\.my\\.go$"]
+ },
+ "default": [],
+ "examples": [[".*\\.my\\.go$", "lib/bad.go"]]
+ },
+ "include": {
+ "description": "The list of ids of default excludes to include or disable.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "default": []
+ },
+ "max-issues-per-linter": {
+ "description": "Maximum issues count per one linter. Set to 0 to disable.",
+ "type": "integer",
+ "default": 50,
+ "minimum": 0
+ },
+ "max-same-issues": {
+ "description": "Maximum count of issues with the same text. Set to 0 to disable.",
+ "type": "integer",
+ "default": 3,
+ "minimum": 0
+ },
+ "new": {
+ "description": "Show only new issues: if there are unstaged changes or untracked files, only those changes are analyzed, else only changes in HEAD~ are analyzed.",
+ "type": "boolean",
+ "default": false
+ },
+ "new-from-rev": {
+ "description": "Show only new issues created after this git revision.",
+ "type": "string"
+ },
+ "new-from-patch": {
+ "description": "Show only new issues created in git patch with this file path.",
+ "type": "string",
+ "examples": ["path/to/patch/file"]
+ },
+ "fix": {
+ "description": "Fix found issues (if it's supported by the linter).",
+ "type": "boolean",
+ "default": false
+ },
+ "whole-files": {
+ "description": "Show issues in any part of update files (requires new-from-rev or new-from-patch).",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "severity": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "default-severity": {
+ "description": "Set the default severity for issues. If severity rules are defined and the issues do not match or no severity is provided to the rule this will be the default severity applied. Severities should match the supported severity names of the selected out format.",
+ "type": "string",
+ "default": ""
+ },
+ "case-sensitive": {
+ "description": "If set to true, severity-rules regular expressions become case sensitive.",
+ "type": "boolean",
+ "default": false
+ },
+ "rules": {
+ "description": "When a list of severity rules are provided, severity information will be added to lint issues. Severity rules have the same filtering capability as exclude rules except you are allowed to specify one matcher per severity rule.\nOnly affects out formats that support setting severity information.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "severity": {
+ "type": "string"
+ },
+ "path": {
+ "type": "string"
+ },
+ "path-except": {
+ "type": "string"
+ },
+ "linters": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linters"
+ }
+ },
+ "text": {
+ "type": "string"
+ },
+ "source": {
+ "type": "string"
+ }
+ },
+ "required": ["severity"],
+ "anyOf": [
+ { "required": ["path"] },
+ { "required": ["path-except"] },
+ { "required": ["linters"] },
+ { "required": ["text"] },
+ { "required": ["source"] }
+ ]
+ },
+ "default": []
+ }
+ },
+ "required": ["default-severity"]
+ }
+ }
+}
diff --git a/vendor/github.com/golangci/golangci-lint/v2/jsonschema/golangci.v1.61.jsonschema.json b/vendor/github.com/golangci/golangci-lint/v2/jsonschema/golangci.v1.61.jsonschema.json
new file mode 100644
index 000000000..a574b0195
--- /dev/null
+++ b/vendor/github.com/golangci/golangci-lint/v2/jsonschema/golangci.v1.61.jsonschema.json
@@ -0,0 +1,3797 @@
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "$id": "https://json.schemastore.org/golangci-lint.json",
+ "definitions": {
+ "gocritic-checks": {
+ "enum": [
+ "appendAssign",
+ "appendCombine",
+ "argOrder",
+ "assignOp",
+ "badCall",
+ "badCond",
+ "badLock",
+ "badRegexp",
+ "badSorting",
+ "boolExprSimplify",
+ "builtinShadow",
+ "builtinShadowDecl",
+ "captLocal",
+ "caseOrder",
+ "codegenComment",
+ "commentedOutCode",
+ "commentedOutImport",
+ "commentFormatting",
+ "defaultCaseOrder",
+ "deferUnlambda",
+ "deferInLoop",
+ "deprecatedComment",
+ "docStub",
+ "dupArg",
+ "dupBranchBody",
+ "dupCase",
+ "dupImport",
+ "dupSubExpr",
+ "dynamicFmtString",
+ "elseif",
+ "emptyDecl",
+ "emptyFallthrough",
+ "emptyStringTest",
+ "equalFold",
+ "evalOrder",
+ "exitAfterDefer",
+ "exposedSyncMutex",
+ "externalErrorReassign",
+ "filepathJoin",
+ "flagDeref",
+ "flagName",
+ "hexLiteral",
+ "httpNoBody",
+ "hugeParam",
+ "ifElseChain",
+ "importShadow",
+ "indexAlloc",
+ "initClause",
+ "ioutilDeprecated",
+ "mapKey",
+ "methodExprCall",
+ "nestingReduce",
+ "newDeref",
+ "nilValReturn",
+ "octalLiteral",
+ "offBy1",
+ "paramTypeCombine",
+ "preferDecodeRune",
+ "preferFilepathJoin",
+ "preferFprint",
+ "preferStringWriter",
+ "preferWriteByte",
+ "ptrToRefParam",
+ "rangeExprCopy",
+ "rangeValCopy",
+ "redundantSprint",
+ "regexpMust",
+ "regexpPattern",
+ "regexpSimplify",
+ "returnAfterHttpError",
+ "ruleguard",
+ "singleCaseSwitch",
+ "sliceClear",
+ "sloppyLen",
+ "sloppyReassign",
+ "sloppyTypeAssert",
+ "sortSlice",
+ "sprintfQuotedString",
+ "sqlQuery",
+ "stringConcatSimplify",
+ "stringsCompare",
+ "stringXbytes",
+ "suspiciousSorting",
+ "switchTrue",
+ "syncMapLoadAndDelete",
+ "timeCmpSimplify",
+ "timeExprSimplify",
+ "tooManyResultsChecker",
+ "truncateCmp",
+ "typeAssertChain",
+ "typeDefFirst",
+ "typeSwitchVar",
+ "typeUnparen",
+ "uncheckedInlineErr",
+ "underef",
+ "unlabelStmt",
+ "unlambda",
+ "unnamedResult",
+ "unnecessaryBlock",
+ "unnecessaryDefer",
+ "unslice",
+ "valSwap",
+ "weakCond",
+ "whyNoLint",
+ "wrapperFunc",
+ "yodaStyleExpr"
+ ]
+ },
+ "gocritic-tags": {
+ "enum": [
+ "diagnostic",
+ "style",
+ "performance",
+ "experimental",
+ "opinionated",
+ "security"
+ ]
+ },
+ "gosec-rules": {
+ "enum": [
+ "G101",
+ "G102",
+ "G103",
+ "G104",
+ "G106",
+ "G107",
+ "G108",
+ "G109",
+ "G110",
+ "G111",
+ "G112",
+ "G113",
+ "G114",
+ "G115",
+ "G201",
+ "G202",
+ "G203",
+ "G204",
+ "G301",
+ "G302",
+ "G303",
+ "G304",
+ "G305",
+ "G306",
+ "G307",
+ "G401",
+ "G402",
+ "G403",
+ "G404",
+ "G405",
+ "G406",
+ "G501",
+ "G502",
+ "G503",
+ "G504",
+ "G505",
+ "G506",
+ "G507",
+ "G601",
+ "G602"
+ ]
+ },
+ "govet-analyzers": {
+ "enum": [
+ "appends",
+ "asmdecl",
+ "assign",
+ "atomic",
+ "atomicalign",
+ "bools",
+ "buildtag",
+ "cgocall",
+ "composites",
+ "copylocks",
+ "deepequalerrors",
+ "defers",
+ "directive",
+ "errorsas",
+ "fieldalignment",
+ "findcall",
+ "framepointer",
+ "httpresponse",
+ "ifaceassert",
+ "loopclosure",
+ "lostcancel",
+ "nilfunc",
+ "nilness",
+ "printf",
+ "reflectvaluecompare",
+ "shadow",
+ "shift",
+ "sigchanyzer",
+ "slog",
+ "sortslice",
+ "stdmethods",
+ "stringintconv",
+ "structtag",
+ "testinggoroutine",
+ "tests",
+ "unmarshal",
+ "unreachable",
+ "unsafeptr",
+ "unusedresult",
+ "unusedwrite"
+ ]
+ },
+ "revive-rules": {
+ "enum": [
+ "add-constant",
+ "argument-limit",
+ "atomic",
+ "banned-characters",
+ "bare-return",
+ "blank-imports",
+ "bool-literal-in-expr",
+ "call-to-gc",
+ "cognitive-complexity",
+ "comment-spacings",
+ "comments-density",
+ "confusing-naming",
+ "confusing-results",
+ "constant-logical-expr",
+ "context-as-argument",
+ "context-keys-type",
+ "cyclomatic",
+ "datarace",
+ "deep-exit",
+ "defer",
+ "dot-imports",
+ "duplicated-imports",
+ "early-return",
+ "empty-block",
+ "empty-lines",
+ "enforce-map-style",
+ "enforce-repeated-arg-type-style",
+ "enforce-slice-style",
+ "error-naming",
+ "error-return",
+ "error-strings",
+ "errorf",
+ "exported",
+ "file-header",
+ "flag-parameter",
+ "function-length",
+ "function-result-limit",
+ "get-return",
+ "identical-branches",
+ "if-return",
+ "import-alias-naming",
+ "import-shadowing",
+ "imports-blocklist",
+ "increment-decrement",
+ "indent-error-flow",
+ "line-length-limit",
+ "max-control-nesting",
+ "max-public-structs",
+ "modifies-parameter",
+ "modifies-value-receiver",
+ "nested-structs",
+ "optimize-operands-order",
+ "package-comments",
+ "range",
+ "range-val-address",
+ "range-val-in-closure",
+ "receiver-naming",
+ "redefines-builtin-id",
+ "redundant-import-alias",
+ "string-format",
+ "string-of-int",
+ "struct-tag",
+ "superfluous-else",
+ "time-equal",
+ "time-naming",
+ "unchecked-type-assertion",
+ "unconditional-recursion",
+ "unexported-naming",
+ "unexported-return",
+ "unhandled-error",
+ "unnecessary-stmt",
+ "unreachable-code",
+ "unused-parameter",
+ "unused-receiver",
+ "use-any",
+ "useless-break",
+ "var-declaration",
+ "var-naming",
+ "waitgroup-by-value"
+ ]
+ },
+ "linters": {
+ "$comment": "anyOf with enum is used to allow auto completion of non-custom linters",
+ "description": "Linters usable.",
+ "anyOf": [
+ {
+ "enum": [
+ "asasalint",
+ "asciicheck",
+ "bidichk",
+ "bodyclose",
+ "canonicalheader",
+ "containedctx",
+ "contextcheck",
+ "copyloopvar",
+ "cyclop",
+ "deadcode",
+ "decorder",
+ "depguard",
+ "dogsled",
+ "dupl",
+ "dupword",
+ "durationcheck",
+ "errcheck",
+ "errchkjson",
+ "errname",
+ "errorlint",
+ "execinquery",
+ "exhaustive",
+ "exhaustivestruct",
+ "exhaustruct",
+ "exportloopref",
+ "fatcontext",
+ "forbidigo",
+ "forcetypeassert",
+ "funlen",
+ "gci",
+ "ginkgolinter",
+ "gocheckcompilerdirectives",
+ "gochecknoglobals",
+ "gochecknoinits",
+ "gochecksumtype",
+ "gocognit",
+ "goconst",
+ "gocritic",
+ "gocyclo",
+ "godot",
+ "godox",
+ "err113",
+ "gofmt",
+ "gofumpt",
+ "goheader",
+ "goimports",
+ "golint",
+ "gomoddirectives",
+ "gomodguard",
+ "goprintffuncname",
+ "gosec",
+ "gosimple",
+ "gosmopolitan",
+ "govet",
+ "grouper",
+ "ifshort",
+ "importas",
+ "inamedparam",
+ "ineffassign",
+ "interfacebloat",
+ "interfacer",
+ "intrange",
+ "ireturn",
+ "lll",
+ "loggercheck",
+ "maintidx",
+ "makezero",
+ "maligned",
+ "mirror",
+ "misspell",
+ "mnd",
+ "musttag",
+ "nakedret",
+ "nestif",
+ "nilerr",
+ "nilnil",
+ "nlreturn",
+ "noctx",
+ "nolintlint",
+ "nonamedreturns",
+ "nosnakecase",
+ "nosprintfhostport",
+ "paralleltest",
+ "perfsprint",
+ "prealloc",
+ "predeclared",
+ "promlinter",
+ "protogetter",
+ "reassign",
+ "revive",
+ "rowserrcheck",
+ "scopelint",
+ "sloglint",
+ "sqlclosecheck",
+ "staticcheck",
+ "structcheck",
+ "stylecheck",
+ "tagalign",
+ "tagliatelle",
+ "tenv",
+ "testableexamples",
+ "testifylint",
+ "testpackage",
+ "thelper",
+ "tparallel",
+ "unconvert",
+ "unparam",
+ "unused",
+ "usestdlibvars",
+ "varcheck",
+ "varnamelen",
+ "wastedassign",
+ "whitespace",
+ "wrapcheck",
+ "wsl",
+ "zerologlint"
+ ]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ }
+ },
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "run": {
+ "description": "Options for analysis running,",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "concurrency": {
+ "description": "Number of concurrent runners. Defaults to the number of available CPU cores.",
+ "type": "integer",
+ "minimum": 0,
+ "examples": [4]
+ },
+ "timeout": {
+ "description": "Timeout for the analysis.",
+ "type": "string",
+ "pattern": "^((\\d+h)?(\\d+m)?(\\d+(?:\\.\\d)?s)?|0)$",
+ "default": "1m",
+ "examples": ["30s", "5m", "5m30s"]
+ },
+ "issues-exit-code": {
+ "description": "Exit code when at least one issue was found.",
+ "type": "integer",
+ "default": 1
+ },
+ "tests": {
+ "description": "Enable inclusion of test files.",
+ "type": "boolean",
+ "default": true
+ },
+ "build-tags": {
+ "description": "List of build tags to pass to all linters.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "default": [],
+ "examples": [["mytag"]]
+ },
+ "modules-download-mode": {
+ "description": "Option to pass to \"go list -mod={option}\".\nSee \"go help modules\" for more information.",
+ "enum": ["mod", "readonly", "vendor"]
+ },
+ "allow-parallel-runners": {
+ "description": "Allow multiple parallel golangci-lint instances running. If disabled, golangci-lint acquires file lock on start.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-serial-runners": {
+ "description": "Allow multiple golangci-lint instances running, but serialize them around a lock.",
+ "type": "boolean",
+ "default": false
+ },
+ "go": {
+ "description": "Targeted Go version.",
+ "type": "string",
+ "default": "1.17"
+ }
+ }
+ },
+ "output": {
+ "description": "Output configuration options.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "formats": {
+ "description": "Output formats to use.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "path": {
+ "default": "stdout",
+ "anyOf": [
+ {
+ "enum": [ "stdout", "stderr" ]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ },
+ "format": {
+ "default": "colored-line-number",
+ "enum": [
+ "colored-line-number",
+ "line-number",
+ "json",
+ "colored-tab",
+ "tab",
+ "html",
+ "checkstyle",
+ "code-climate",
+ "junit-xml",
+ "junit-xml-extended",
+ "github-actions",
+ "teamcity",
+ "sarif"
+ ]
+ }
+ },
+ "required": ["format"]
+ }
+ },
+ "print-issued-lines": {
+ "description": "Print lines of code with issue.",
+ "type": "boolean",
+ "default": true
+ },
+ "print-linter-name": {
+ "description": "Print linter name in the end of issue text.",
+ "type": "boolean",
+ "default": true
+ },
+ "uniq-by-line": {
+ "description": "Make issues output unique by line.",
+ "type": "boolean",
+ "default": true
+ },
+ "path-prefix": {
+ "description": "Add a prefix to the output file references.",
+ "type": "string",
+ "default": ""
+ },
+ "show-stats": {
+ "description": "Show statistics per linter.",
+ "type": "boolean",
+ "default": false
+ },
+ "sort-order": {
+ "type": "array",
+ "items": {
+ "enum": ["linter", "severity", "file"]
+ }
+ },
+ "sort-results": {
+ "description": "Sort results by: filepath, line and column.",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "linters-settings": {
+ "description": "All available settings of specific linters.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "dupword": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "keywords": {
+ "description": "Keywords for detecting duplicate words. If this list is not empty, only the words defined in this list will be detected.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["the", "and", "a"]
+ }
+ },
+ "ignore": {
+ "description": "Keywords used to ignore detection.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["0C0C"]
+ }
+ }
+ }
+ },
+ "asasalint": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "exclude": {
+ "description": "To specify a set of function names to exclude.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["\\.Wrapf"]
+ }
+ },
+ "use-builtin-exclusions": {
+ "description": "To enable/disable the asasalint builtin exclusions of function names.",
+ "type": "boolean",
+ "default": true
+ },
+ "ignore-test": {
+ "description": "Ignore *_test.go files.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "bidichk": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "left-to-right-embedding": {
+ "description": "Disallow: LEFT-TO-RIGHT-EMBEDDING",
+ "type": "boolean",
+ "default": false
+ },
+ "right-to-left-embedding": {
+ "description": "Disallow: RIGHT-TO-LEFT-EMBEDDING",
+ "type": "boolean",
+ "default": false
+ },
+ "pop-directional-formatting": {
+ "description": "Disallow: POP-DIRECTIONAL-FORMATTING",
+ "type": "boolean",
+ "default": false
+ },
+ "left-to-right-override": {
+ "description": "Disallow: LEFT-TO-RIGHT-OVERRIDE",
+ "type": "boolean",
+ "default": false
+ },
+ "right-to-left-override": {
+ "description": "Disallow: RIGHT-TO-LEFT-OVERRIDE",
+ "type": "boolean",
+ "default": false
+ },
+ "left-to-right-isolate": {
+ "description": "Disallow: LEFT-TO-RIGHT-ISOLATE",
+ "type": "boolean",
+ "default": false
+ },
+ "right-to-left-isolate": {
+ "description": "Disallow: RIGHT-TO-LEFT-ISOLATE",
+ "type": "boolean",
+ "default": false
+ },
+ "first-strong-isolate": {
+ "description": "Disallow: FIRST-STRONG-ISOLATE",
+ "type": "boolean",
+ "default": false
+ },
+ "pop-directional-isolate": {
+ "description": "Disallow: POP-DIRECTIONAL-ISOLATE",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "cyclop": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skip-tests": {
+ "description": "Should the linter execute on test files as well",
+ "type": "boolean",
+ "default": false
+ },
+ "max-complexity": {
+ "description": "Max complexity the function can have",
+ "type": "integer",
+ "default": 10,
+ "minimum": 0
+ },
+ "package-average": {
+ "description": "Max average complexity in package",
+ "type": "number",
+ "default": 0,
+ "minimum": 0
+ }
+ }
+ },
+ "decorder": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "dec-order": {
+ "type": "array",
+ "default": [["type", "const", "var", "func"]],
+ "items": {
+ "enum": ["type", "const", "var", "func"]
+ }
+ },
+ "ignore-underscore-vars": {
+ "description": "Underscore vars (vars with \"_\" as the name) will be ignored at all checks",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-dec-order-check": {
+ "description": "Order of declarations is not checked",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-init-func-first-check": {
+ "description": "Allow init func to be anywhere in file",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-dec-num-check": {
+ "description": "Multiple global type, const and var declarations are allowed",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-type-dec-num-check": {
+ "description": "Type declarations will be ignored for dec num check",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-const-dec-num-check": {
+ "description": "Const declarations will be ignored for dec num check",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-var-dec-num-check": {
+ "description": "Var declarations will be ignored for dec num check",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ },
+ "depguard": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "rules": {
+ "description": "Rules to apply.",
+ "type": "object",
+ "additionalProperties": false,
+ "patternProperties": {
+ "^[^.]+$": {
+ "description": "Name of a rule.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "list-mode": {
+ "description": "Used to determine the package matching priority.",
+ "enum": ["original", "strict", "lax"],
+ "default": "original"
+ },
+ "files": {
+ "description": "List of file globs that will match this list of settings to compare against.",
+ "additionalProperties": false,
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "allow": {
+ "description": "List of allowed packages.",
+ "additionalProperties": false,
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "deny": {
+ "description": "Packages that are not allowed where the value is a suggestion.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "desc": {
+ "description": "Description",
+ "type": "string"
+ },
+ "pkg": {
+ "description": "Package",
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "dogsled": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-blank-identifiers": {
+ "description": "Check assignments with too many blank identifiers.",
+ "type": "integer",
+ "default": 2,
+ "minimum": 0
+ }
+ }
+ },
+ "dupl": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "threshold": {
+ "description": "Tokens count to trigger issue.",
+ "type": "integer",
+ "default": 150,
+ "minimum": 0
+ }
+ }
+ },
+ "errcheck": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-type-assertions": {
+ "description": "Report about not checking errors in type assertions, i.e.: `a := b.(MyStruct)`",
+ "type": "boolean",
+ "default": false
+ },
+ "check-blank": {
+ "description": "Report about assignment of errors to blank identifier",
+ "type": "boolean",
+ "default": false
+ },
+ "exclude-functions": {
+ "description": "List of functions to exclude from checking, where each entry is a single function to exclude",
+ "type": "array",
+ "examples": ["io/ioutil.ReadFile", "io.Copy(*bytes.Buffer)"],
+ "items": {
+ "type": "string"
+ }
+ },
+ "disable-default-exclusions": {
+ "description": "To disable the errcheck built-in exclude list",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "errchkjson": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-error-free-encoding": {
+ "type": "boolean",
+ "default": false
+ },
+ "report-no-exported": {
+ "description": "Issue on struct that doesn't have exported fields.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "errorlint": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "errorf": {
+ "description": "Check whether fmt.Errorf uses the %w verb for formatting errors",
+ "type": "boolean",
+ "default": true
+ },
+ "errorf-multi": {
+ "description": "Permit more than 1 %w verb, valid per Go 1.20",
+ "type": "boolean",
+ "default": true
+ },
+ "asserts": {
+ "description": "Check for plain type assertions and type switches.",
+ "type": "boolean",
+ "default": true
+ },
+ "comparison": {
+ "description": "Check for plain error comparisons",
+ "type": "boolean",
+ "default": true
+ },
+ "allowed-errors": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "err": {
+ "type": "string"
+ },
+ "fun": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "allowed-errors-wildcard": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "err": {
+ "type": "string"
+ },
+ "fun": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "exhaustive": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check": {
+ "description": "Program elements to check for exhaustiveness.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["switch", "map"]
+ }
+ },
+ "check-generated": {
+ "description": "Check switch statements in generated files",
+ "type": "boolean",
+ "default": false
+ },
+ "explicit-exhaustive-switch": {
+ "description": "Only run exhaustive check on switches with \"//exhaustive:enforce\" comment.",
+ "type": "boolean",
+ "default": false
+ },
+ "explicit-exhaustive-map": {
+ "description": "Only run exhaustive check on map literals with \"//exhaustive:enforce\" comment.",
+ "type": "boolean",
+ "default": false
+ },
+ "default-case-required": {
+ "description": "Switch statement requires default case even if exhaustive.",
+ "type": "boolean",
+ "default": false
+ },
+ "default-signifies-exhaustive": {
+ "description": "Presence of `default` case in switch statements satisfies exhaustiveness, even if all enum members are not listed.",
+ "type": "boolean",
+ "default": false
+ },
+ "ignore-enum-members": {
+ "description": "Enum members matching `regex` do not have to be listed in switch statements to satisfy exhaustiveness",
+ "type": "string"
+ },
+ "ignore-enum-types": {
+ "description": "Enum types matching the supplied regex do not have to be listed in switch statements to satisfy exhaustiveness.",
+ "type": "string"
+ },
+ "package-scope-only": {
+ "description": "Consider enums only in package scopes, not in inner scopes.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "exhaustruct": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "include": {
+ "description": "List of regular expressions to match struct packages and names.",
+ "type": "array",
+ "examples": [".*\\.Test"],
+ "items": {
+ "type": "string"
+ }
+ },
+ "exclude": {
+ "description": "List of regular expressions to exclude struct packages and names from check.",
+ "type": "array",
+ "examples": ["cobra\\.Command$"],
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "forbidigo": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "exclude-godoc-examples": {
+ "description": "Exclude code in godoc examples.",
+ "type": "boolean",
+ "default": true
+ },
+ "analyze-types": {
+ "description": "Instead of matching the literal source code, use type information to replace expressions with strings that contain the package name and (for methods and fields) the type name.",
+ "type": "boolean",
+ "default": true
+ },
+ "forbid": {
+ "description": "List of identifiers to forbid (written using `regexp`)",
+ "type": "array",
+ "examples": ["^print(ln)?$"],
+ "items": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "p": {
+ "description": "Pattern",
+ "type": "string"
+ },
+ "pkg": {
+ "description": "Package",
+ "type": "string"
+ },
+ "msg": {
+ "description": "Message",
+ "type": "string"
+ }
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ "funlen": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "lines": {
+ "description": "Limit lines number per function.",
+ "type": "integer",
+ "default": 60
+ },
+ "statements": {
+ "description": "Limit statements number per function.",
+ "type": "integer",
+ "default": 40
+ },
+ "ignore-comments": {
+ "description": "Ignore comments when counting lines.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "gci": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "sections": {
+ "description": "Section configuration to compare against.",
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "enum": [
+ "standard",
+ "default",
+ "blank",
+ "dot",
+ "alias",
+ "localmodule"
+ ]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ },
+ "default": ["standard", "default"]
+ },
+ "skip-generated": {
+ "description": "Skip generated files.",
+ "type": "boolean",
+ "default": true
+ },
+ "custom-order": {
+ "description": "Enable custom order of sections.",
+ "type": "boolean",
+ "default": false
+ },
+ "no-lex-order": {
+ "description": "Drops lexical ordering for custom sections.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "ginkgolinter": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "suppress-len-assertion": {
+ "description": "Suppress the wrong length assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-nil-assertion": {
+ "description": "Suppress the wrong nil assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-err-assertion": {
+ "description": "Suppress the wrong error assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-compare-assertion": {
+ "description": "Suppress the wrong comparison assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-async-assertion": {
+ "description": "Suppress the function all in async assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-type-compare-assertion": {
+ "description": "Suppress warning for comparing values from different types, like int32 and uint32.",
+ "type": "boolean",
+ "default": false
+ },
+ "forbid-focus-container": {
+ "description": "Trigger warning for ginkgo focus containers like FDescribe, FContext, FWhen or FIt.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-havelen-zero": {
+ "description": "Don't trigger warnings for HaveLen(0).",
+ "type": "boolean",
+ "default": false
+ },
+ "force-expect-to": {
+ "description": "Force using `Expect` with `To`, `ToNot` or `NotTo`",
+ "type": "boolean",
+ "default": false
+ },
+ "validate-async-intervals": {
+ "description": "Best effort validation of async intervals (timeout and polling).",
+ "type": "boolean",
+ "default": false
+ },
+ "forbid-spec-pollution": {
+ "description": "Trigger a warning for variable assignments in ginkgo containers like `Describe`, `Context` and `When`, instead of in `BeforeEach()`.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "gocognit": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "min-complexity": {
+ "description": "Minimal code complexity to report (we recommend 10-20).",
+ "type": "integer",
+ "default": 30
+ }
+ }
+ },
+ "goconst": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "match-constant": {
+ "description": "Look for existing constants matching the values",
+ "type": "boolean",
+ "default": true
+ },
+ "min-len": {
+ "description": "Minimum length of string constant.",
+ "type": "integer",
+ "default": 3
+ },
+ "min-occurrences": {
+ "description": "Minimum occurrences count to trigger.",
+ "type": "integer",
+ "default": 3
+ },
+ "ignore-tests": {
+ "description": "Ignore test files.",
+ "type": "boolean",
+ "default": false
+ },
+ "ignore-calls": {
+ "description": "Ignore when constant is not used as function argument",
+ "type": "boolean",
+ "default": true
+ },
+ "ignore-strings": {
+ "description": "Exclude strings matching the given regular expression",
+ "type": "string"
+ },
+ "numbers": {
+ "description": "Search also for duplicated numbers.",
+ "type": "boolean",
+ "default": false
+ },
+ "min": {
+ "description": "Minimum value, only works with `numbers`",
+ "type": "integer",
+ "default": 3
+ },
+ "max": {
+ "description": "Maximum value, only works with `numbers`",
+ "type": "integer",
+ "default": 3
+ }
+ }
+ },
+ "gocritic": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "enabled-checks": {
+ "description": "Which checks should be enabled. By default, a list of stable checks is used. To see it, run `GL_DEBUG=gocritic golangci-lint run`.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/gocritic-checks"
+ }
+ },
+ "disabled-checks": {
+ "description": "Which checks should be disabled.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/gocritic-checks"
+ },
+ "default": []
+ },
+ "enabled-tags": {
+ "description": "Enable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/gocritic-tags"
+ }
+ },
+ "disabled-tags": {
+ "description": "Disable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/gocritic-tags"
+ }
+ },
+ "settings": {
+ "description": "Settings passed to gocritic. Properties must be valid and enabled check names.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "captLocal": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "paramsOnly" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "commentedOutCode": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "minLength" : {
+ "type": "number",
+ "default": 15
+ }
+ }
+ },
+ "elseif": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skipBalanced" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "hugeParam": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "sizeThreshold" : {
+ "type": "number",
+ "default": 80
+ }
+ }
+ },
+ "ifElseChain": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "minThreshold" : {
+ "type": "number",
+ "default": 2
+ }
+ }
+ },
+ "nestingReduce": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "bodyWidth" : {
+ "type": "number",
+ "default": 5
+ }
+ }
+ },
+ "rangeExprCopy": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "sizeThreshold" : {
+ "type": "number",
+ "default": 512
+ },
+ "skipTestFuncs" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "rangeValCopy": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "sizeThreshold" : {
+ "type": "number",
+ "default": 128
+ },
+ "skipTestFuncs" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "ruleguard": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "debug" : {
+ "type": "string"
+ },
+ "enable" : {
+ "type": "string"
+ },
+ "disable" : {
+ "type": "string"
+ },
+ "failOn" : {
+ "type": "string"
+ },
+ "rules" : {
+ "type": "string"
+ }
+ }
+ },
+ "tooManyResultsChecker": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "maxResults" : {
+ "type": "number",
+ "default": 5
+ }
+ }
+ },
+ "truncateCmp": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skipArchDependent" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "underef": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skipRecvDeref" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "unnamedResult": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "checkExported" : {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ }
+ }
+ },
+ "disable-all": {
+ "type": "boolean",
+ "default": false
+ },
+ "enable-all": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "gocyclo": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "min-complexity": {
+ "description": "Minimum code complexity to report (we recommend 10-20).",
+ "type": "integer",
+ "default": 30
+ }
+ }
+ },
+ "godot": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "scope": {
+ "description": "Comments to be checked.",
+ "enum": ["declarations", "toplevel", "all"],
+ "default": "declarations"
+ },
+ "exclude": {
+ "description": "List of regexps for excluding particular comment lines from check.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "period": {
+ "description": "Check that each sentence ends with a period.",
+ "type": "boolean",
+ "default": true
+ },
+ "capital": {
+ "description": "Check that each sentence starts with a capital letter.",
+ "type": "boolean",
+ "default": false
+ },
+ "check-all": {
+ "description": "DEPRECATED: Check all top-level comments, not only declarations.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "godox": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "keywords": {
+ "description": "Report any comments starting with one of these keywords. This is useful for TODO or FIXME comments that might be left in the code accidentally and should be resolved before merging.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "default": ["TODO", "BUG", "FIXME"]
+ }
+ }
+ },
+ "gofmt": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "simplify": {
+ "description": "Simplify code.",
+ "type": "boolean",
+ "default": true
+ },
+ "rewrite-rules": {
+ "description": "Apply the rewrite rules to the source before reformatting.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "pattern": {
+ "type": "string"
+ },
+ "replacement": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "interfacebloat": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max": {
+ "description": "The maximum number of methods allowed for an interface.",
+ "type": "integer"
+ }
+ }
+ },
+ "gofumpt": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "extra-rules": {
+ "description": "Choose whether or not to use the extra rules that are disabled by default.",
+ "type": "boolean",
+ "default": false
+ },
+ "module-path": {
+ "description": " Module path which contains the source code being formatted.",
+ "type": "string"
+ }
+ }
+ },
+ "goheader": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "values": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "const": {
+ "description": "Constants to use in the template.",
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "description": "Value for the constant.",
+ "type": "string"
+ }
+ },
+ "additionalProperties": false,
+ "examples": [
+ {
+ "YEAR": "2030",
+ "COMPANY": "MY FUTURISTIC COMPANY"
+ }
+ ]
+ },
+ "regexp": {
+ "description": "Regular expressions to use in your template.",
+ "type": "object",
+ "additionalProperties": false,
+ "patternProperties": {
+ "^.+$": {
+ "type": "string"
+ }
+ },
+ "examples": [
+ {
+ "AUTHOR": ".*@mycompany\\.com"
+ }
+ ]
+ }
+ }
+ },
+ "template": {
+ "description": "Template to put on top of every file.",
+ "type": "string",
+ "examples": [
+ "{{ MY COMPANY }}\nSPDX-License-Identifier: Apache-2.0\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at:\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License."
+ ]
+ },
+ "template-path": {
+ "description": "Path to the file containing the template source.",
+ "type": "string",
+ "examples": ["my_header_template.txt"]
+ }
+ },
+ "oneOf": [
+ { "required": ["template"] },
+ { "required": ["template-path"] }
+ ]
+ },
+ "goimports": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "local-prefixes": {
+ "description": "Put imports beginning with prefix after 3rd-party packages. It is a comma-separated list of prefixes.",
+ "type": "string",
+ "examples": ["github.com/org/project"]
+ }
+ }
+ },
+ "gomoddirectives": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "replace-local": {
+ "description": "Allow local `replace` directives.",
+ "type": "boolean",
+ "default": true
+ },
+ "replace-allow-list": {
+ "description": "List of allowed `replace` directives.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "retract-allow-no-explanation": {
+ "description": "Allow to not explain why the version has been retracted in the `retract` directives.",
+ "type": "boolean",
+ "default": true
+ },
+ "exclude-forbidden": {
+ "description": "Forbid the use of the `exclude` directives.",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "gomodguard": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "allowed": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "modules": {
+ "description": "List of allowed modules.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["gopkg.in/yaml.v2"]
+ }
+ },
+ "domains": {
+ "description": "List of allowed module domains.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["golang.org"]
+ }
+ }
+ }
+ },
+ "blocked": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "modules": {
+ "description": "List of blocked modules.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "recommendations": {
+ "description": "Recommended modules that should be used instead.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "reason": {
+ "description": "Reason why the recommended module should be used.",
+ "type": "string"
+ }
+ }
+ }
+ },
+ "additionalProperties": false
+ }
+ },
+ "versions": {
+ "description": "List of blocked module version constraints.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "patternProperties": {
+ "^.*$": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "version": {
+ "description": "Version constraint.",
+ "type": "string"
+ },
+ "reason": {
+ "description": "Reason why the version constraint exists.",
+ "type": "string"
+ }
+ },
+ "required": ["reason"]
+ }
+ }
+ }
+ },
+ "local_replace_directives": {
+ "description": "Raise lint issues if loading local path with replace directive",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ }
+ }
+ },
+ "gosimple": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "checks": {
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "enum": ["all"]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ }
+ }
+ }
+ },
+ "gosec": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "includes": {
+ "type": "array",
+ "description": "To select a subset of rules to run",
+ "examples": [["G401"]],
+ "items": {
+ "$ref": "#/definitions/gosec-rules"
+ }
+ },
+ "excludes": {
+ "type": "array",
+ "description": "To specify a set of rules to explicitly exclude",
+ "examples": [["G401"]],
+ "items": {
+ "$ref": "#/definitions/gosec-rules"
+ }
+ },
+ "exclude-generated": {
+ "description": "Exclude generated files",
+ "type": "boolean",
+ "default": false
+ },
+ "severity": {
+ "description": "Filter out the issues with a lower severity than the given value",
+ "type": "string",
+ "enum": ["low", "medium", "high"],
+ "default": "low"
+ },
+ "confidence": {
+ "description": "Filter out the issues with a lower confidence than the given value",
+ "type": "string",
+ "enum": ["low", "medium", "high"],
+ "default": "low"
+ },
+ "config": {
+ "description": "To specify the configuration of rules",
+ "type": "object"
+ },
+ "concurrency": {
+ "description": "Concurrency value",
+ "type": "integer"
+ }
+ }
+ },
+ "gosmopolitan": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "allow-time-local": {
+ "description": "Allow and ignore `time.Local` usages.",
+ "type": "boolean",
+ "default": false
+ },
+ "escape-hatches": {
+ "description": "List of fully qualified names in the `full/pkg/path.name` form, to act as \"i18n escape hatches\".",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignore-tests": {
+ "description": "Ignore test files.",
+ "type": "boolean",
+ "default": false
+ },
+ "watch-for-scripts": {
+ "description": "List of Unicode scripts to watch for any usage in string literals.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "govet": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "settings": {
+ "description": "Settings per analyzer. Map of analyzer name to specific settings.\nRun `go tool vet help` to find out more.",
+ "type": "object",
+ "propertyNames": {
+ "$ref": "#/definitions/govet-analyzers"
+ },
+ "patternProperties": {
+ "^.*$": {
+ "description": "Run `go tool vet help ` to see all settings.",
+ "type": "object"
+ }
+ }
+ },
+ "enable": {
+ "description": "Enable analyzers by name.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/govet-analyzers"
+ }
+ },
+ "disable": {
+ "description": "Disable analyzers by name.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/govet-analyzers"
+ }
+ },
+ "enable-all": {
+ "description": "Enable all analyzers.",
+ "type": "boolean",
+ "default": false
+ },
+ "disable-all": {
+ "description": "Disable all analyzers.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "grouper": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "const-require-single-const": {
+ "type": "boolean",
+ "default": false
+ },
+ "const-require-grouping": {
+ "type": "boolean",
+ "default": false
+ },
+ "import-require-single-import": {
+ "type": "boolean",
+ "default": false
+ },
+ "import-require-grouping": {
+ "type": "boolean",
+ "default": false
+ },
+ "type-require-single-type": {
+ "type": "boolean",
+ "default": false
+ },
+ "type-require-grouping": {
+ "type": "boolean",
+ "default": false
+ },
+ "var-require-single-var": {
+ "type": "boolean",
+ "default": false
+ },
+ "var-require-grouping": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "importas": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "no-unaliased": {
+ "description": "Do not allow unaliased imports of aliased packages.",
+ "type": "boolean",
+ "default": false
+ },
+ "no-extra-aliases": {
+ "description": "Do not allow non-required aliases.",
+ "type": "boolean",
+ "default": false
+ },
+ "alias": {
+ "description": "List of aliases",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "pkg": {
+ "description": "Package path e.g. knative.dev/serving/pkg/apis/autoscaling/v1alpha1",
+ "type": "string"
+ },
+ "alias": {
+ "description": "Package alias e.g. autoscalingv1alpha1",
+ "type": "string"
+ }
+ },
+ "required": ["pkg", "alias"]
+ }
+ }
+ }
+ },
+ "inamedparam": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skip-single-param": {
+ "description": "Skips check for interface methods with only a single parameter.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "ireturn": {
+ "type": "object",
+ "additionalProperties": false,
+ "description": "Use either `reject` or `allow` properties for interfaces matching.",
+ "properties": {
+ "allow": {
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "enum": ["anon", "error", "empty", "stdlib"]
+ }
+ ]
+ }
+ },
+ "reject": {
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "enum": ["anon", "error", "empty", "stdlib"]
+ }
+ ]
+ }
+ }
+ },
+ "anyOf": [
+ {
+ "not": {
+ "properties": {
+ "allow": {
+ "const": "reject"
+ }
+ }
+ },
+ "required": ["allow"]
+ },
+ {
+ "required": ["reject"]
+ }
+ ]
+ },
+ "lll": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "tab-width": {
+ "description": "Width of \"\\t\" in spaces.",
+ "type": "integer",
+ "minimum": 0,
+ "default": 1
+ },
+ "line-length": {
+ "description": "Maximum allowed line length, lines longer will be reported.",
+ "type": "integer",
+ "minimum": 1,
+ "default": 120
+ }
+ }
+ },
+ "maintidx": {
+ "description": "Maintainability index https://docs.microsoft.com/en-us/visualstudio/code-quality/code-metrics-maintainability-index-range-and-meaning?view=vs-2022",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "under": {
+ "description": "Minimum accatpable maintainability index level (see https://docs.microsoft.com/en-us/visualstudio/code-quality/code-metrics-maintainability-index-range-and-meaning?view=vs-2022)",
+ "type": "number",
+ "default": 20
+ }
+ }
+ },
+ "makezero": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "always": {
+ "description": "Allow only slices initialized with a length of zero.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "loggercheck": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "kitlog": {
+ "description": "Allow check for the github.com/go-kit/log library.",
+ "type": "boolean",
+ "default": true
+ },
+ "klog": {
+ "description": "Allow check for the k8s.io/klog/v2 library.",
+ "type": "boolean",
+ "default": true
+ },
+ "logr": {
+ "description": "Allow check for the github.com/go-logr/logr library.",
+ "type": "boolean",
+ "default": true
+ },
+ "zap": {
+ "description": "Allow check for the \"sugar logger\" from go.uber.org/zap library.",
+ "type": "boolean",
+ "default": true
+ },
+ "require-string-key": {
+ "description": "Require all logging keys to be inlined constant strings.",
+ "type": "boolean",
+ "default": false
+ },
+ "no-printf-like": {
+ "description": "Require printf-like format specifier (%s, %d for example) not present.",
+ "type": "boolean",
+ "default": false
+ },
+ "rules": {
+ "description": "List of custom rules to check against, where each rule is a single logger pattern, useful for wrapped loggers.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "misspell": {
+ "description": "Correct spellings using locale preferences for US or UK. Default is to use a neutral variety of English.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "locale": {
+ "enum": ["US", "UK"]
+ },
+ "ignore-words": {
+ "description": "List of words to ignore.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "mode": {
+ "description": "Mode of the analysis.",
+ "enum": ["restricted", "", "default"],
+ "default": ""
+ },
+ "extra-words": {
+ "description": "Extra word corrections.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "correction": {
+ "type": "string"
+ },
+ "typo": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "musttag": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "functions": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "tag": {
+ "type": "string"
+ },
+ "arg-pos": {
+ "type": "integer"
+ }
+ }
+ }
+ }
+ }
+ },
+ "nakedret": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-func-lines": {
+ "description": "Report if a function has more lines of code than this value and it has naked returns.",
+ "type": "integer",
+ "minimum": 0,
+ "default": 30
+ }
+ }
+ },
+ "nestif": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "min-complexity": {
+ "description": "Minimum complexity of \"if\" statements to report.",
+ "type": "integer",
+ "default": 5
+ }
+ }
+ },
+ "nilnil": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "checked-types": {
+ "type": "array",
+ "description": "List of return types to check.",
+ "items": {
+ "enum": ["ptr", "func", "iface", "map", "chan", "uintptr", "unsafeptr"]
+ },
+ "default": ["ptr", "func", "iface", "map", "chan", "uintptr", "unsafeptr"]
+ }
+ }
+ },
+ "nlreturn": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "block-size": {
+ "description": "set block size that is still ok",
+ "type": "number",
+ "default": 0,
+ "minimum": 0
+ }
+ }
+ },
+ "mnd": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignored-files": {
+ "description": "List of file patterns to exclude from analysis.",
+ "examples": [["magic1_.*.go"]],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignored-functions": {
+ "description": "Comma-separated list of function patterns to exclude from the analysis.",
+ "examples": [["math.*", "http.StatusText", "make"]],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignored-numbers": {
+ "description": "List of numbers to exclude from analysis.",
+ "examples": [["1000", "1234_567_890", "3.14159264"]],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "checks": {
+ "description": "The list of enabled checks, see https://github.com/tommy-muehle/go-mnd/#checks for description.",
+ "type": "array",
+ "items": {
+ "enum": [
+ "argument",
+ "case",
+ "condition",
+ "operation",
+ "return",
+ "assign"
+ ]
+ }
+ }
+ }
+ },
+ "nolintlint": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "allow-unused": {
+ "description": "Enable to ensure that nolint directives are all used.",
+ "type": "boolean",
+ "default": true
+ },
+ "allow-no-explanation": {
+ "description": "Exclude these linters from requiring an explanation.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linters"
+ },
+ "default": []
+ },
+ "require-explanation": {
+ "description": "Enable to require an explanation of nonzero length after each nolint directive.",
+ "type": "boolean",
+ "default": false
+ },
+ "require-specific": {
+ "description": "Enable to require nolint directives to mention the specific linter being suppressed.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "reassign": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "patterns": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "nonamedreturns": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "report-error-in-defer": {
+ "description": "Report named error if it is assigned inside defer.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "paralleltest": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignore-missing": {
+ "description": "Ignore missing calls to `t.Parallel()` and only report incorrect uses of it.",
+ "type": "boolean",
+ "default": false
+ },
+ "ignore-missing-subtests": {
+ "description": "Ignore missing calls to `t.Parallel()` in subtests. Top-level tests are still required to have `t.Parallel`, but subtests are allowed to skip it.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "perfsprint": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "int-conversion": {
+ "description": "Optimizes even if it requires an int or uint type cast.",
+ "type": "boolean",
+ "default": true
+ },
+ "err-error": {
+ "description": "Optimizes into `err.Error()` even if it is only equivalent for non-nil errors.",
+ "type": "boolean",
+ "default": false
+ },
+ "errorf": {
+ "description": "Optimizes `fmt.Errorf`.",
+ "type": "boolean",
+ "default": true
+ },
+ "sprintf1": {
+ "description": "Optimizes `fmt.Sprintf` with only one argument.",
+ "type": "boolean",
+ "default": true
+ },
+ "strconcat": {
+ "description": "Optimizes into strings concatenation.",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "prealloc": {
+ "description": "We do not recommend using this linter before doing performance profiling.\nFor most programs usage of `prealloc` will be premature optimization.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "simple": {
+ "description": "Report preallocation suggestions only on simple loops that have no returns/breaks/continues/gotos in them.",
+ "type": "boolean",
+ "default": true
+ },
+ "range-loops": {
+ "description": "Report preallocation suggestions on range loops.",
+ "type": "boolean",
+ "default": true
+ },
+ "for-loops": {
+ "description": "Report preallocation suggestions on for loops.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "predeclared": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignore": {
+ "description": "Comma-separated list of predeclared identifiers to not report on.",
+ "type": "string"
+ },
+ "q": {
+ "description": "Include method names and field names (i.e., qualified names) in checks.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "promlinter": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "strict": {},
+ "disabled-linters": {
+ "type": "array",
+ "items": {
+ "enum": [
+ "Help",
+ "MetricUnits",
+ "Counter",
+ "HistogramSummaryReserved",
+ "MetricTypeInName",
+ "ReservedChars",
+ "CamelCase",
+ "UnitAbbreviations"
+ ]
+ }
+ }
+ }
+ },
+ "protogetter": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skip-generated-by": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["protoc-gen-go-my-own-generator"]
+ }
+ },
+ "skip-files": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["*.pb.go"]
+ }
+ },
+ "skip-any-generated": {
+ "description": "Skip any generated files from the checking.",
+ "type": "boolean",
+ "default": false
+ },
+ "replace-first-arg-in-append": {
+ "description": "Skip first argument of append function.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "revive": {
+ "type": "object",
+ "additionalProperties": false,
+ "examples": [
+ {
+ "ignore-generated-header": true,
+ "severity": "warning",
+ "rules": [
+ {
+ "name": "indent-error-flow",
+ "severity": "warning"
+ },
+ {
+ "name": "add-constant",
+ "severity": "warning",
+ "arguments": [
+ {
+ "maxLitCount": "3",
+ "allowStrs": "\"\"",
+ "allowInts": "0,1,2",
+ "allowFloats": "0.0,0.,1.0,1.,2.0,2."
+ }
+ ]
+ }
+ ]
+ }
+ ],
+ "properties": {
+ "max-open-files": {
+ "type": "integer"
+ },
+ "ignore-generated-header": {
+ "type": "boolean"
+ },
+ "confidence": {
+ "type": "number"
+ },
+ "severity": {
+ "type": "string",
+ "enum": ["warning", "error"]
+ },
+ "enable-all-rules": {
+ "type": "boolean",
+ "default": false
+ },
+ "directives": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "name": {
+ "type": "string",
+ "enum": ["specify-disable-reason"]
+ },
+ "severity": {
+ "type": "string",
+ "enum": ["warning", "error"]
+ },
+ "exclude": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "arguments": {
+ "type": "array"
+ }
+ }
+ }
+ },
+ "rules": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["name"],
+ "properties": {
+ "name": {
+ "$ref": "#/definitions/revive-rules",
+ "title": "The rule name"
+ },
+ "disabled": {
+ "type": "boolean"
+ },
+ "severity": {
+ "type": "string",
+ "enum": ["warning", "error"]
+ },
+ "exclude": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "arguments": {
+ "type": "array"
+ }
+ }
+ }
+ }
+ }
+ },
+ "rowserrcheck": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "packages": {
+ "type": "array",
+ "items": {
+ "description": "",
+ "type": "string",
+ "examples": ["github.com/jmoiron/sqlx"]
+ }
+ }
+ }
+ },
+ "sloglint": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "kv-only": {
+ "description": "Enforce using key-value pairs only (incompatible with attr-only).",
+ "type": "boolean",
+ "default": false
+ },
+ "no-global": {
+ "description": "Enforce not using global loggers.",
+ "enum": ["", "all", "default"],
+ "default": ""
+ },
+ "no-mixed-args": {
+ "description": "Enforce not mixing key-value pairs and attributes.",
+ "type": "boolean",
+ "default": true
+ },
+ "context": {
+ "description": "Enforce using methods that accept a context.",
+ "enum": ["", "all", "scope"],
+ "default": ""
+ },
+ "static-msg": {
+ "description": "Enforce using static values for log messages.",
+ "type": "boolean",
+ "default": false
+ },
+ "key-naming-case": {
+ "description": "Enforce a single key naming convention.",
+ "enum": ["snake", "kebab", "camel", "pascal"]
+ },
+ "attr-only": {
+ "description": "Enforce using attributes only (incompatible with kv-only).",
+ "type": "boolean",
+ "default": false
+ },
+ "no-raw-keys": {
+ "description": "Enforce using constants instead of raw keys.",
+ "type": "boolean",
+ "default": false
+ },
+ "forbidden-keys": {
+ "description": "Enforce not using specific keys.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "args-on-sep-lines": {
+ "description": "Enforce putting arguments on separate lines.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "spancheck": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "checks": {
+ "description": "Checks to enable.",
+ "type": "array",
+ "items": {
+ "enum": ["end", "record-error", "set-status"]
+ }
+ },
+ "ignore-check-signatures": {
+ "description": "A list of regexes for function signatures that silence `record-error` and `set-status` reports if found in the call path to a returned error.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "extra-start-span-signatures": {
+ "description": "A list of regexes for additional function signatures that create spans.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "staticcheck": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "checks": {
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "enum": ["all"]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ }
+ }
+ }
+ },
+ "stylecheck": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "checks": {
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "enum": ["all"]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ },
+ "default": [
+ "all",
+ "-ST1000",
+ "-ST1003",
+ "-ST1016",
+ "-ST1020",
+ "-ST1021",
+ "-ST1022"
+ ]
+ },
+ "dot-import-whitelist": {
+ "description": "By default, ST1001 forbids all uses of dot imports in non-test packages. This setting allows setting a whitelist of import paths that can be dot-imported anywhere.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "http-status-code-whitelist": {
+ "description": "ST1013 recommends using constants from the net/http package instead of hard-coding numeric HTTP status codes. This setting specifies a list of numeric status codes that this check does not complain about.",
+ "default": ["200", "400", "404", "500"],
+ "type": "array",
+ "items": {
+ "enum": [
+ "100",
+ "101",
+ "102",
+ "103",
+ "200",
+ "201",
+ "202",
+ "203",
+ "204",
+ "205",
+ "206",
+ "207",
+ "208",
+ "226",
+ "300",
+ "301",
+ "302",
+ "303",
+ "304",
+ "305",
+ "306",
+ "307",
+ "308",
+ "400",
+ "401",
+ "402",
+ "403",
+ "404",
+ "405",
+ "406",
+ "407",
+ "408",
+ "409",
+ "410",
+ "411",
+ "412",
+ "413",
+ "414",
+ "415",
+ "416",
+ "417",
+ "418",
+ "421",
+ "422",
+ "423",
+ "424",
+ "425",
+ "426",
+ "428",
+ "429",
+ "431",
+ "451",
+ "500",
+ "501",
+ "502",
+ "503",
+ "504",
+ "505",
+ "506",
+ "507",
+ "508",
+ "510",
+ "511"
+ ]
+ }
+ },
+ "initialisms": {
+ "description": "ST1003 check, among other things, for the correct capitalization of initialisms. The set of known initialisms can be configured with this option.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "default": [
+ "ACL",
+ "API",
+ "ASCII",
+ "CPU",
+ "CSS",
+ "DNS",
+ "EOF",
+ "GUID",
+ "HTML",
+ "HTTP",
+ "HTTPS",
+ "ID",
+ "IP",
+ "JSON",
+ "QPS",
+ "RAM",
+ "RPC",
+ "SLA",
+ "SMTP",
+ "SQL",
+ "SSH",
+ "TCP",
+ "TLS",
+ "TTL",
+ "UDP",
+ "UI",
+ "GID",
+ "UID",
+ "UUID",
+ "URI",
+ "URL",
+ "UTF8",
+ "VM",
+ "XML",
+ "XMPP",
+ "XSRF",
+ "XSS",
+ "SIP",
+ "RTP",
+ "AMQP",
+ "DB",
+ "TS"
+ ]
+ }
+ }
+ }
+ },
+ "tagalign": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "align": {
+ "description": "Align and sort can be used together or separately.",
+ "type": "boolean",
+ "default": true
+ },
+ "sort": {
+ "description": "Whether enable tags sort.",
+ "type": "boolean",
+ "default": true
+ },
+ "order": {
+ "description": "Specify the order of tags, the other tags will be sorted by name.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "default": [],
+ "examples": [
+ [
+ "json",
+ "yaml",
+ "yml",
+ "toml",
+ "mapstructure",
+ "binding",
+ "validate"
+ ]
+ ]
+ },
+ "strict": {
+ "description": "Whether enable strict style.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "tagliatelle": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "case": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "use-field-name": {
+ "description": "Use the struct field name to check the name of the struct tag.",
+ "type": "boolean",
+ "default": false
+ },
+ "rules": {
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "enum": [
+ "camel",
+ "pascal",
+ "kebab",
+ "snake",
+ "goCamel",
+ "goPascal",
+ "goKebab",
+ "goSnake",
+ "upper",
+ "upperSnake",
+ "lower",
+ "header"
+ ]
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "tenv": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "all": {
+ "description": "The option `all` will run against whole test files (`_test.go`) regardless of method/function signatures.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "testifylint": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "enable-all": {
+ "description": "Enable all checkers.",
+ "type": "boolean",
+ "default": false
+ },
+ "disable-all": {
+ "description": "Disable all checkers.",
+ "type": "boolean",
+ "default": false
+ },
+ "enable": {
+ "description": "Enable specific checkers.",
+ "type": "array",
+ "items": {
+ "enum": [
+ "blank-import",
+ "bool-compare",
+ "compares",
+ "empty",
+ "error-is-as",
+ "error-nil",
+ "expected-actual",
+ "float-compare",
+ "formatter",
+ "go-require",
+ "len",
+ "negative-positive",
+ "nil-compare",
+ "require-error",
+ "suite-broken-parallel",
+ "suite-dont-use-pkg",
+ "suite-extra-assert-call",
+ "suite-subtest-run",
+ "suite-thelper",
+ "useless-assert"
+ ]
+ },
+ "default": [
+ "blank-import",
+ "bool-compare",
+ "compares",
+ "empty",
+ "error-is-as",
+ "error-nil",
+ "expected-actual",
+ "float-compare",
+ "float-compare",
+ "go-require",
+ "len",
+ "negative-positive",
+ "nil-compare",
+ "require-error",
+ "suite-broken-parallel",
+ "suite-dont-use-pkg",
+ "suite-extra-assert-call",
+ "suite-subtest-run",
+ "useless-assert"
+ ]
+ },
+ "disable": {
+ "description": "Disable specific checkers.",
+ "type": "array",
+ "items": {
+ "enum": [
+ "blank-import",
+ "bool-compare",
+ "compares",
+ "empty",
+ "error-is-as",
+ "error-nil",
+ "expected-actual",
+ "float-compare",
+ "formatter",
+ "go-require",
+ "len",
+ "negative-positive",
+ "nil-compare",
+ "require-error",
+ "suite-broken-parallel",
+ "suite-dont-use-pkg",
+ "suite-extra-assert-call",
+ "suite-subtest-run",
+ "suite-thelper",
+ "useless-assert"
+ ],
+ "default": [
+ "suite-thelper"
+ ]
+ }
+ },
+ "bool-compare": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignore-custom-types": {
+ "description": "To ignore user defined types (over builtin bool).",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "expected-actual": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "pattern": {
+ "description": "Regexp for expected variable name.",
+ "type": "string",
+ "default": "(^(exp(ected)?|want(ed)?)([A-Z]\\w*)?$)|(^(\\w*[a-z])?(Exp(ected)?|Want(ed)?)$)"
+ }
+ }
+ },
+ "formatter": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-format-string": {
+ "description": "To enable go vet's printf checks.",
+ "type": "boolean",
+ "default": true
+ },
+ "require-f-funcs": {
+ "description": "To require f-assertions if format string is used.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "go-require": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignore-http-handlers": {
+ "description": "To ignore HTTP handlers (like http.HandlerFunc).",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "require-error": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "fn-pattern": {
+ "description": "Regexp for assertions to analyze. If defined, then only matched error assertions will be reported.",
+ "type": "string",
+ "default": ""
+ }
+ }
+ },
+ "suite-extra-assert-call": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "mode": {
+ "description": "To require or remove extra Assert() call?",
+ "type": "string",
+ "enum": ["remove", "require"],
+ "default": "remove"
+ }
+ }
+ }
+ }
+ },
+ "testpackage": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skip-regexp": {
+ "description": "Files with names matching this regular expression are skipped.",
+ "type": "string",
+ "examples": ["(export|internal)_test\\.go"]
+ },
+ "allow-packages": {
+ "description": "List of packages that don't end with _test that tests are allowed to be in.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["example"]
+ }
+ }
+ }
+ },
+ "thelper": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "test": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "begin": {
+ "description": "Check if `t.Helper()` begins helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "first": {
+ "description": "Check if *testing.T is first param of helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "name": {
+ "description": "Check if *testing.T param has t name.",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ },
+ "benchmark": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "begin": {
+ "description": "Check if `b.Helper()` begins helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "first": {
+ "description": "Check if *testing.B is first param of helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "name": {
+ "description": "Check if *testing.B param has b name.",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ },
+ "tb": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "begin": {
+ "description": "Check if `tb.Helper()` begins helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "first": {
+ "description": "Check if *testing.TB is first param of helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "name": {
+ "description": "Check if *testing.TB param has tb name.",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ },
+ "fuzz": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "begin": {
+ "description": "Check if `f.Helper()` begins helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "first": {
+ "description": "Check if *testing.F is first param of helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "name": {
+ "description": "Check if *testing.F param has f name.",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ }
+ }
+ },
+ "usestdlibvars": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "http-method": {
+ "description": "Suggest the use of http.MethodXX.",
+ "type": "boolean",
+ "default": true
+ },
+ "http-status-code": {
+ "description": "Suggest the use of http.StatusXX.",
+ "type": "boolean",
+ "default": true
+ },
+ "time-weekday": {
+ "description": "Suggest the use of time.Weekday.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "time-month": {
+ "description": "Suggest the use of time.Month.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "time-layout": {
+ "description": "Suggest the use of time.Layout.",
+ "type": "boolean",
+ "default": false
+ },
+ "crypto-hash": {
+ "description": "Suggest the use of crypto.Hash.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "default-rpc-path": {
+ "description": "Suggest the use of rpc.DefaultXXPath.",
+ "type": "boolean",
+ "default": false
+ },
+ "sql-isolation-level": {
+ "description": "Suggest the use of sql.LevelXX.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "tls-signature-scheme": {
+ "description": "Suggest the use of tls.SignatureScheme.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "constant-kind": {
+ "description": "Suggest the use of constant.Kind.String().",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "unconvert": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "fast-math": {
+ "type": "boolean",
+ "default": false
+ },
+ "safe": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "unparam": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-exported": {
+ "description": "Inspect exported functions. Set to true if no external program/library imports your code.\n\nWARNING: if you enable this setting, unparam will report a lot of false-positives in text editors:\nif it's called for subdir of a project it can't find external interfaces. All text editor integrations\nwith golangci-lint call it on a directory with the changed file.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "unused": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "field-writes-are-uses": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ },
+ "post-statements-are-reads": {
+ "description": "",
+ "type": "boolean",
+ "default": false
+ },
+ "exported-fields-are-used": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ },
+ "parameters-are-used": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ },
+ "local-variables-are-used": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ },
+ "generated-is-used": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "varnamelen": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-distance": {
+ "description": "Variables used in at most this N-many lines will be ignored.",
+ "type": "integer",
+ "default": 5
+ },
+ "min-name-length": {
+ "description": "The minimum length of a variable's name that is considered `long`.",
+ "type": "integer",
+ "default": 3
+ },
+ "check-receiver": {
+ "description": "Check method receiver names.",
+ "default": false,
+ "type": "boolean"
+ },
+ "check-return": {
+ "description": "Check named return values.",
+ "default": false,
+ "type": "boolean"
+ },
+ "check-type-param": {
+ "description": "Check type parameters.",
+ "default": false,
+ "type": "boolean"
+ },
+ "ignore-type-assert-ok": {
+ "description": "Ignore `ok` variables that hold the bool return value of a type assertion",
+ "default": false,
+ "type": "boolean"
+ },
+ "ignore-map-index-ok": {
+ "description": "Ignore `ok` variables that hold the bool return value of a map index.",
+ "default": false,
+ "type": "boolean"
+ },
+ "ignore-chan-recv-ok": {
+ "description": "Ignore `ok` variables that hold the bool return value of a channel receive.",
+ "default": false,
+ "type": "boolean"
+ },
+ "ignore-names": {
+ "description": "Optional list of variable names that should be ignored completely.",
+ "default": [[]],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignore-decls": {
+ "description": "Optional list of variable declarations that should be ignored completely.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "examples": [
+ ["c echo.Context", "t testing.T", "f *foo.Bar", "const C"]
+ ]
+ }
+ }
+ },
+ "whitespace": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "multi-if": {
+ "description": "Enforces newlines (or comments) after every multi-line if statement",
+ "type": "boolean",
+ "default": false
+ },
+ "multi-func": {
+ "description": "Enforces newlines (or comments) after every multi-line function signature",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "wrapcheck": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignoreSigs": {
+ "description": "An array of strings which specify substrings of signatures to ignore.",
+ "default": [
+ ".Errorf(",
+ "errors.New(",
+ "errors.Unwrap(",
+ ".Wrap(",
+ ".Wrapf(",
+ ".WithMessage(",
+ ".WithMessagef(",
+ ".WithStack("
+ ],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignoreSigRegexps": {
+ "description": "An array of strings which specify regular expressions of signatures to ignore.",
+ "default": [""],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignorePackageGlobs": {
+ "description": "An array of glob patterns which, if any match the package of the function returning the error, will skip wrapcheck analysis for this error.",
+ "default": [""],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignoreInterfaceRegexps": {
+ "description": "An array of glob patterns which, if matched to an underlying interface name, will ignore unwrapped errors returned from a function whose call is defined on the given interface.",
+ "default": [""],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "wsl": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "allow-assign-and-anything": {
+ "description": "Controls if you may cuddle assignments and anything without needing an empty line between them.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-assign-and-call": {
+ "description": "Allow calls and assignments to be cuddled as long as the lines have any matching variables, fields or types.",
+ "type": "boolean",
+ "default": true
+ },
+ "allow-cuddle-declarations": {
+ "description": "Allow declarations (var) to be cuddled.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-cuddle-with-calls": {
+ "description": "A list of call idents that everything can be cuddled with.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "allow-cuddle-with-rhs": {
+ "description": "AllowCuddleWithRHS is a list of right hand side variables that is allowed to be cuddled with anything.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "allow-multiline-assign": {
+ "description": "Allow multiline assignments to be cuddled.",
+ "type": "boolean",
+ "default": true
+ },
+ "allow-separated-leading-comment": {
+ "description": "Allow leading comments to be separated with empty lines.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-trailing-comment": {
+ "description": "Allow trailing comments in ending of blocks.",
+ "type": "boolean",
+ "default": false
+ },
+ "error-variable-names": {
+ "description": "When force-err-cuddling is enabled this is a list of names used for error variables to check for in the conditional.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "force-case-trailing-whitespace": {
+ "description": "Force newlines in end of case at this limit (0 = never).",
+ "type": "integer",
+ "minimum": 0,
+ "default": 0
+ },
+ "force-err-cuddling": {
+ "description": "Causes an error when an If statement that checks an error variable doesn't cuddle with the assignment of that variable.",
+ "type": "boolean",
+ "default": false
+ },
+ "force-short-decl-cuddling": {
+ "description": "Causes an error if a short declaration (:=) cuddles with anything other than another short declaration.",
+ "type": "boolean",
+ "default": false
+ },
+ "strict-append": {
+ "description": "If true, append is only allowed to be cuddled if appending value is matching variables, fields or types on line above.",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "copyloopvar": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-alias": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "custom": {
+ "description": "The custom section can be used to define linter plugins to be loaded at runtime. See README of golangci-lint for more information.\nEach custom linter should have a unique name.",
+ "type": "object",
+ "patternProperties": {
+ "^.*$": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "type": {
+ "description": "The plugin type.",
+ "enum": ["module", "goplugin"],
+ "default": "goplugin"
+ },
+ "path": {
+ "description": "The path to the plugin *.so. Can be absolute or local.",
+ "type": "string",
+ "examples": ["/path/to/example.so"]
+ },
+ "description": {
+ "description": "The description of the linter, for documentation purposes only.",
+ "type": "string"
+ },
+ "original-url": {
+ "description": "Intended to point to the repo location of the linter, for documentation purposes only.",
+ "type": "string"
+ },
+ "settings": {
+ "description": "Plugins settings/configuration. Only work with plugin based on `linterdb.PluginConstructor`.",
+ "type": "object"
+ }
+ },
+ "oneOf": [
+ {
+ "properties": {
+ "type": {"enum": ["module"] }
+ },
+ "required": ["type"]
+ },
+ {
+ "required": ["path"]
+ }
+ ]
+ }
+ }
+ }
+ }
+ },
+ "linters": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "enable": {
+ "description": "List of enabled linters.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linters"
+ }
+ },
+ "disable": {
+ "description": "List of disabled linters.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linters"
+ }
+ },
+ "enable-all": {
+ "description": "Whether to enable all linters. You can re-disable them with `disable` explicitly.",
+ "type": "boolean",
+ "default": false
+ },
+ "disable-all": {
+ "description": "Whether to disable all linters. You can re-enable them with `enable` explicitly.",
+ "type": "boolean",
+ "default": false
+ },
+ "presets": {
+ "description": "Allow to use different presets of linters",
+ "type": "array",
+ "items": {
+ "enum": [
+ "bugs",
+ "comment",
+ "complexity",
+ "error",
+ "format",
+ "import",
+ "metalinter",
+ "module",
+ "performance",
+ "sql",
+ "style",
+ "test",
+ "unused"
+ ]
+ }
+ },
+ "fast": {
+ "description": "Enable run of fast linters.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "issues": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "exclude": {
+ "description": "List of regular expressions of issue texts to exclude.\nBut independently from this option we use default exclude patterns. Their usage can be controlled through `exclude-use-default`.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "exclude-rules": {
+ "description": "Exclude configuration per-path, per-linter, per-text and per-source",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "path": {
+ "type": "string"
+ },
+ "path-except": {
+ "type": "string"
+ },
+ "linters": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linters"
+ }
+ },
+ "text": {
+ "type": "string"
+ },
+ "source": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "exclude-use-default": {
+ "description": "Independently from option `exclude` we use default exclude patterns. This behavior can be disabled by this option.",
+ "type": "boolean",
+ "default": true
+ },
+ "exclude-case-sensitive": {
+ "description": "If set to true, exclude and exclude-rules regular expressions become case sensitive.",
+ "type": "boolean",
+ "default": false
+ },
+ "exclude-generated": {
+ "description": "Mode of the generated files analysis.",
+ "enum": ["lax", "strict", "disable"],
+ "default": "lax"
+ },
+ "exclude-dirs": {
+ "description": "Which directories to exclude: issues from them won't be reported.",
+ "type": "array",
+ "items": {
+ "description": "You can use regexp here. The regexp is applied on the full path.\n\"/\" will be replaced by current OS file path separator to properly work on Windows.",
+ "type": "string",
+ "examples": ["generated.*"]
+ },
+ "default": [],
+ "examples": [["src/external_libs", "autogenerated_by_my_lib"]]
+ },
+ "exclude-dirs-use-default": {
+ "description": "Enable exclusion of directories \"vendor\", \"third_party\", \"testdata\", \"examples\", \"Godeps\", and \"builtin\".",
+ "type": "boolean",
+ "default": true
+ },
+ "exclude-files": {
+ "description": "Which files to exclude: they will be analyzed, but issues from them will not be reported.",
+ "type": "array",
+ "items": {
+ "description": "You can use regexp here. There is no need to include all autogenerated files, we confidently recognize them. If that is not the case, please let us know.\n\"/\" will be replaced by current OS file path separator to properly work on Windows.",
+ "type": "string",
+ "examples": [".*\\.my\\.go$"]
+ },
+ "default": [],
+ "examples": [[".*\\.my\\.go$", "lib/bad.go"]]
+ },
+ "include": {
+ "description": "The list of ids of default excludes to include or disable.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "default": []
+ },
+ "max-issues-per-linter": {
+ "description": "Maximum issues count per one linter. Set to 0 to disable.",
+ "type": "integer",
+ "default": 50,
+ "minimum": 0
+ },
+ "max-same-issues": {
+ "description": "Maximum count of issues with the same text. Set to 0 to disable.",
+ "type": "integer",
+ "default": 3,
+ "minimum": 0
+ },
+ "new": {
+ "description": "Show only new issues: if there are unstaged changes or untracked files, only those changes are analyzed, else only changes in HEAD~ are analyzed.",
+ "type": "boolean",
+ "default": false
+ },
+ "new-from-rev": {
+ "description": "Show only new issues created after this git revision.",
+ "type": "string"
+ },
+ "new-from-patch": {
+ "description": "Show only new issues created in git patch with this file path.",
+ "type": "string",
+ "examples": ["path/to/patch/file"]
+ },
+ "fix": {
+ "description": "Fix found issues (if it's supported by the linter).",
+ "type": "boolean",
+ "default": false
+ },
+ "whole-files": {
+ "description": "Show issues in any part of update files (requires new-from-rev or new-from-patch).",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "severity": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "default-severity": {
+ "description": "Set the default severity for issues. If severity rules are defined and the issues do not match or no severity is provided to the rule this will be the default severity applied. Severities should match the supported severity names of the selected out format.",
+ "type": "string",
+ "default": ""
+ },
+ "case-sensitive": {
+ "description": "If set to true, severity-rules regular expressions become case sensitive.",
+ "type": "boolean",
+ "default": false
+ },
+ "rules": {
+ "description": "When a list of severity rules are provided, severity information will be added to lint issues. Severity rules have the same filtering capability as exclude rules except you are allowed to specify one matcher per severity rule.\nOnly affects out formats that support setting severity information.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "severity": {
+ "type": "string"
+ },
+ "path": {
+ "type": "string"
+ },
+ "path-except": {
+ "type": "string"
+ },
+ "linters": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linters"
+ }
+ },
+ "text": {
+ "type": "string"
+ },
+ "source": {
+ "type": "string"
+ }
+ },
+ "required": ["severity"],
+ "anyOf": [
+ { "required": ["path"] },
+ { "required": ["path-except"] },
+ { "required": ["linters"] },
+ { "required": ["text"] },
+ { "required": ["source"] }
+ ]
+ },
+ "default": []
+ }
+ },
+ "required": ["default-severity"]
+ }
+ }
+}
diff --git a/vendor/github.com/golangci/golangci-lint/v2/jsonschema/golangci.v1.62.jsonschema.json b/vendor/github.com/golangci/golangci-lint/v2/jsonschema/golangci.v1.62.jsonschema.json
new file mode 100644
index 000000000..3ca3593b2
--- /dev/null
+++ b/vendor/github.com/golangci/golangci-lint/v2/jsonschema/golangci.v1.62.jsonschema.json
@@ -0,0 +1,3860 @@
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "$id": "https://json.schemastore.org/golangci-lint.json",
+ "definitions": {
+ "gocritic-checks": {
+ "enum": [
+ "appendAssign",
+ "appendCombine",
+ "argOrder",
+ "assignOp",
+ "badCall",
+ "badCond",
+ "badLock",
+ "badRegexp",
+ "badSorting",
+ "badSyncOnceFunc",
+ "boolExprSimplify",
+ "builtinShadow",
+ "builtinShadowDecl",
+ "captLocal",
+ "caseOrder",
+ "codegenComment",
+ "commentFormatting",
+ "commentedOutCode",
+ "commentedOutImport",
+ "defaultCaseOrder",
+ "deferInLoop",
+ "deferUnlambda",
+ "deprecatedComment",
+ "docStub",
+ "dupArg",
+ "dupBranchBody",
+ "dupCase",
+ "dupImport",
+ "dupSubExpr",
+ "dynamicFmtString",
+ "elseif",
+ "emptyDecl",
+ "emptyFallthrough",
+ "emptyStringTest",
+ "equalFold",
+ "evalOrder",
+ "exitAfterDefer",
+ "exposedSyncMutex",
+ "externalErrorReassign",
+ "filepathJoin",
+ "flagDeref",
+ "flagName",
+ "hexLiteral",
+ "httpNoBody",
+ "hugeParam",
+ "ifElseChain",
+ "importShadow",
+ "indexAlloc",
+ "initClause",
+ "ioutilDeprecated",
+ "mapKey",
+ "methodExprCall",
+ "nestingReduce",
+ "newDeref",
+ "nilValReturn",
+ "octalLiteral",
+ "offBy1",
+ "paramTypeCombine",
+ "preferDecodeRune",
+ "preferFilepathJoin",
+ "preferFprint",
+ "preferStringWriter",
+ "preferWriteByte",
+ "ptrToRefParam",
+ "rangeAppendAll",
+ "rangeExprCopy",
+ "rangeValCopy",
+ "redundantSprint",
+ "regexpMust",
+ "regexpPattern",
+ "regexpSimplify",
+ "returnAfterHttpError",
+ "ruleguard",
+ "singleCaseSwitch",
+ "sliceClear",
+ "sloppyLen",
+ "sloppyReassign",
+ "sloppyTypeAssert",
+ "sortSlice",
+ "sprintfQuotedString",
+ "sqlQuery",
+ "stringConcatSimplify",
+ "stringXbytes",
+ "stringsCompare",
+ "switchTrue",
+ "syncMapLoadAndDelete",
+ "timeExprSimplify",
+ "todoCommentWithoutDetail",
+ "tooManyResultsChecker",
+ "truncateCmp",
+ "typeAssertChain",
+ "typeDefFirst",
+ "typeSwitchVar",
+ "typeUnparen",
+ "uncheckedInlineErr",
+ "underef",
+ "unlabelStmt",
+ "unlambda",
+ "unnamedResult",
+ "unnecessaryBlock",
+ "unnecessaryDefer",
+ "unslice",
+ "valSwap",
+ "weakCond",
+ "whyNoLint",
+ "wrapperFunc",
+ "yodaStyleExpr"
+ ]
+ },
+ "gocritic-tags": {
+ "enum": [
+ "diagnostic",
+ "style",
+ "performance",
+ "experimental",
+ "opinionated",
+ "security"
+ ]
+ },
+ "gosec-rules": {
+ "enum": [
+ "G101",
+ "G102",
+ "G103",
+ "G104",
+ "G106",
+ "G107",
+ "G108",
+ "G109",
+ "G110",
+ "G111",
+ "G112",
+ "G113",
+ "G114",
+ "G115",
+ "G201",
+ "G202",
+ "G203",
+ "G204",
+ "G301",
+ "G302",
+ "G303",
+ "G304",
+ "G305",
+ "G306",
+ "G307",
+ "G401",
+ "G402",
+ "G403",
+ "G404",
+ "G405",
+ "G406",
+ "G501",
+ "G502",
+ "G503",
+ "G504",
+ "G505",
+ "G506",
+ "G507",
+ "G601",
+ "G602"
+ ]
+ },
+ "govet-analyzers": {
+ "enum": [
+ "appends",
+ "asmdecl",
+ "assign",
+ "atomic",
+ "atomicalign",
+ "bools",
+ "buildtag",
+ "cgocall",
+ "composites",
+ "copylocks",
+ "deepequalerrors",
+ "defers",
+ "directive",
+ "errorsas",
+ "fieldalignment",
+ "findcall",
+ "framepointer",
+ "httpresponse",
+ "ifaceassert",
+ "loopclosure",
+ "lostcancel",
+ "nilfunc",
+ "nilness",
+ "printf",
+ "reflectvaluecompare",
+ "shadow",
+ "shift",
+ "sigchanyzer",
+ "slog",
+ "sortslice",
+ "stdmethods",
+ "stringintconv",
+ "structtag",
+ "testinggoroutine",
+ "tests",
+ "timeformat",
+ "unmarshal",
+ "unreachable",
+ "unsafeptr",
+ "unusedresult",
+ "unusedwrite"
+ ]
+ },
+ "revive-rules": {
+ "enum": [
+ "add-constant",
+ "argument-limit",
+ "atomic",
+ "banned-characters",
+ "bare-return",
+ "blank-imports",
+ "bool-literal-in-expr",
+ "call-to-gc",
+ "cognitive-complexity",
+ "comment-spacings",
+ "comments-density",
+ "confusing-naming",
+ "confusing-results",
+ "constant-logical-expr",
+ "context-as-argument",
+ "context-keys-type",
+ "cyclomatic",
+ "datarace",
+ "deep-exit",
+ "defer",
+ "dot-imports",
+ "duplicated-imports",
+ "early-return",
+ "empty-block",
+ "empty-lines",
+ "enforce-map-style",
+ "enforce-repeated-arg-type-style",
+ "enforce-slice-style",
+ "error-naming",
+ "error-return",
+ "error-strings",
+ "errorf",
+ "exported",
+ "file-header",
+ "file-length-limit",
+ "filename-format",
+ "flag-parameter",
+ "function-length",
+ "function-result-limit",
+ "get-return",
+ "identical-branches",
+ "if-return",
+ "import-alias-naming",
+ "import-shadowing",
+ "imports-blocklist",
+ "increment-decrement",
+ "indent-error-flow",
+ "line-length-limit",
+ "max-control-nesting",
+ "max-public-structs",
+ "modifies-parameter",
+ "modifies-value-receiver",
+ "nested-structs",
+ "optimize-operands-order",
+ "package-comments",
+ "range",
+ "range-val-address",
+ "range-val-in-closure",
+ "receiver-naming",
+ "redefines-builtin-id",
+ "redundant-import-alias",
+ "string-format",
+ "string-of-int",
+ "struct-tag",
+ "superfluous-else",
+ "time-equal",
+ "time-naming",
+ "unchecked-type-assertion",
+ "unconditional-recursion",
+ "unexported-naming",
+ "unexported-return",
+ "unhandled-error",
+ "unnecessary-stmt",
+ "unreachable-code",
+ "unused-parameter",
+ "unused-receiver",
+ "use-any",
+ "useless-break",
+ "var-declaration",
+ "var-naming",
+ "waitgroup-by-value"
+ ]
+ },
+ "iface-analyzers": {
+ "enum": [
+ "identical",
+ "unused",
+ "opaque"
+ ]
+ },
+ "linters": {
+ "$comment": "anyOf with enum is used to allow auto completion of non-custom linters",
+ "description": "Linters usable.",
+ "anyOf": [
+ {
+ "enum": [
+ "asasalint",
+ "asciicheck",
+ "bidichk",
+ "bodyclose",
+ "canonicalheader",
+ "containedctx",
+ "contextcheck",
+ "copyloopvar",
+ "cyclop",
+ "decorder",
+ "depguard",
+ "dogsled",
+ "dupl",
+ "dupword",
+ "durationcheck",
+ "errcheck",
+ "errchkjson",
+ "errname",
+ "errorlint",
+ "exhaustive",
+ "exhaustruct",
+ "exportloopref",
+ "fatcontext",
+ "forbidigo",
+ "forcetypeassert",
+ "funlen",
+ "gci",
+ "ginkgolinter",
+ "gocheckcompilerdirectives",
+ "gochecknoglobals",
+ "gochecknoinits",
+ "gochecksumtype",
+ "gocognit",
+ "goconst",
+ "gocritic",
+ "gocyclo",
+ "godot",
+ "godox",
+ "err113",
+ "gofmt",
+ "gofumpt",
+ "goheader",
+ "goimports",
+ "gomoddirectives",
+ "gomodguard",
+ "goprintffuncname",
+ "gosec",
+ "gosimple",
+ "gosmopolitan",
+ "govet",
+ "grouper",
+ "iface",
+ "importas",
+ "inamedparam",
+ "ineffassign",
+ "interfacebloat",
+ "intrange",
+ "ireturn",
+ "lll",
+ "loggercheck",
+ "maintidx",
+ "makezero",
+ "mirror",
+ "misspell",
+ "mnd",
+ "musttag",
+ "nakedret",
+ "nestif",
+ "nilerr",
+ "nilnil",
+ "nlreturn",
+ "noctx",
+ "nolintlint",
+ "nonamedreturns",
+ "nosprintfhostport",
+ "paralleltest",
+ "perfsprint",
+ "prealloc",
+ "predeclared",
+ "promlinter",
+ "protogetter",
+ "reassign",
+ "recvcheck",
+ "revive",
+ "rowserrcheck",
+ "sloglint",
+ "sqlclosecheck",
+ "staticcheck",
+ "stylecheck",
+ "tagalign",
+ "tagliatelle",
+ "tenv",
+ "testableexamples",
+ "testifylint",
+ "testpackage",
+ "thelper",
+ "tparallel",
+ "unconvert",
+ "unparam",
+ "unused",
+ "usestdlibvars",
+ "varnamelen",
+ "wastedassign",
+ "whitespace",
+ "wrapcheck",
+ "wsl",
+ "zerologlint"
+ ]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ }
+ },
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "run": {
+ "description": "Options for analysis running,",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "concurrency": {
+ "description": "Number of concurrent runners. Defaults to the number of available CPU cores.",
+ "type": "integer",
+ "minimum": 0,
+ "examples": [4]
+ },
+ "timeout": {
+ "description": "Timeout for the analysis.",
+ "type": "string",
+ "pattern": "^((\\d+h)?(\\d+m)?(\\d+(?:\\.\\d)?s)?|0)$",
+ "default": "1m",
+ "examples": ["30s", "5m", "5m30s"]
+ },
+ "issues-exit-code": {
+ "description": "Exit code when at least one issue was found.",
+ "type": "integer",
+ "default": 1
+ },
+ "tests": {
+ "description": "Enable inclusion of test files.",
+ "type": "boolean",
+ "default": true
+ },
+ "build-tags": {
+ "description": "List of build tags to pass to all linters.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "default": [],
+ "examples": [["mytag"]]
+ },
+ "modules-download-mode": {
+ "description": "Option to pass to \"go list -mod={option}\".\nSee \"go help modules\" for more information.",
+ "enum": ["mod", "readonly", "vendor"]
+ },
+ "allow-parallel-runners": {
+ "description": "Allow multiple parallel golangci-lint instances running. If disabled, golangci-lint acquires file lock on start.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-serial-runners": {
+ "description": "Allow multiple golangci-lint instances running, but serialize them around a lock.",
+ "type": "boolean",
+ "default": false
+ },
+ "go": {
+ "description": "Targeted Go version.",
+ "type": "string",
+ "default": "1.17"
+ }
+ }
+ },
+ "output": {
+ "description": "Output configuration options.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "formats": {
+ "description": "Output formats to use.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "path": {
+ "default": "stdout",
+ "anyOf": [
+ {
+ "enum": [ "stdout", "stderr" ]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ },
+ "format": {
+ "default": "colored-line-number",
+ "enum": [
+ "colored-line-number",
+ "line-number",
+ "json",
+ "colored-tab",
+ "tab",
+ "html",
+ "checkstyle",
+ "code-climate",
+ "junit-xml",
+ "junit-xml-extended",
+ "github-actions",
+ "teamcity",
+ "sarif"
+ ]
+ }
+ },
+ "required": ["format"]
+ }
+ },
+ "print-issued-lines": {
+ "description": "Print lines of code with issue.",
+ "type": "boolean",
+ "default": true
+ },
+ "print-linter-name": {
+ "description": "Print linter name in the end of issue text.",
+ "type": "boolean",
+ "default": true
+ },
+ "uniq-by-line": {
+ "description": "Make issues output unique by line.",
+ "type": "boolean",
+ "default": true
+ },
+ "path-prefix": {
+ "description": "Add a prefix to the output file references.",
+ "type": "string",
+ "default": ""
+ },
+ "show-stats": {
+ "description": "Show statistics per linter.",
+ "type": "boolean",
+ "default": false
+ },
+ "sort-order": {
+ "type": "array",
+ "items": {
+ "enum": ["linter", "severity", "file"]
+ }
+ },
+ "sort-results": {
+ "description": "Sort results by: filepath, line and column.",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "linters-settings": {
+ "description": "All available settings of specific linters.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "dupword": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "keywords": {
+ "description": "Keywords for detecting duplicate words. If this list is not empty, only the words defined in this list will be detected.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["the", "and", "a"]
+ }
+ },
+ "ignore": {
+ "description": "Keywords used to ignore detection.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["0C0C"]
+ }
+ }
+ }
+ },
+ "asasalint": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "exclude": {
+ "description": "To specify a set of function names to exclude.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["\\.Wrapf"]
+ }
+ },
+ "use-builtin-exclusions": {
+ "description": "To enable/disable the asasalint builtin exclusions of function names.",
+ "type": "boolean",
+ "default": true
+ },
+ "ignore-test": {
+ "description": "Ignore *_test.go files.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "bidichk": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "left-to-right-embedding": {
+ "description": "Disallow: LEFT-TO-RIGHT-EMBEDDING",
+ "type": "boolean",
+ "default": false
+ },
+ "right-to-left-embedding": {
+ "description": "Disallow: RIGHT-TO-LEFT-EMBEDDING",
+ "type": "boolean",
+ "default": false
+ },
+ "pop-directional-formatting": {
+ "description": "Disallow: POP-DIRECTIONAL-FORMATTING",
+ "type": "boolean",
+ "default": false
+ },
+ "left-to-right-override": {
+ "description": "Disallow: LEFT-TO-RIGHT-OVERRIDE",
+ "type": "boolean",
+ "default": false
+ },
+ "right-to-left-override": {
+ "description": "Disallow: RIGHT-TO-LEFT-OVERRIDE",
+ "type": "boolean",
+ "default": false
+ },
+ "left-to-right-isolate": {
+ "description": "Disallow: LEFT-TO-RIGHT-ISOLATE",
+ "type": "boolean",
+ "default": false
+ },
+ "right-to-left-isolate": {
+ "description": "Disallow: RIGHT-TO-LEFT-ISOLATE",
+ "type": "boolean",
+ "default": false
+ },
+ "first-strong-isolate": {
+ "description": "Disallow: FIRST-STRONG-ISOLATE",
+ "type": "boolean",
+ "default": false
+ },
+ "pop-directional-isolate": {
+ "description": "Disallow: POP-DIRECTIONAL-ISOLATE",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "cyclop": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skip-tests": {
+ "description": "Should the linter execute on test files as well",
+ "type": "boolean",
+ "default": false
+ },
+ "max-complexity": {
+ "description": "Max complexity the function can have",
+ "type": "integer",
+ "default": 10,
+ "minimum": 0
+ },
+ "package-average": {
+ "description": "Max average complexity in package",
+ "type": "number",
+ "default": 0,
+ "minimum": 0
+ }
+ }
+ },
+ "decorder": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "dec-order": {
+ "type": "array",
+ "default": [["type", "const", "var", "func"]],
+ "items": {
+ "enum": ["type", "const", "var", "func"]
+ }
+ },
+ "ignore-underscore-vars": {
+ "description": "Underscore vars (vars with \"_\" as the name) will be ignored at all checks",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-dec-order-check": {
+ "description": "Order of declarations is not checked",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-init-func-first-check": {
+ "description": "Allow init func to be anywhere in file",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-dec-num-check": {
+ "description": "Multiple global type, const and var declarations are allowed",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-type-dec-num-check": {
+ "description": "Type declarations will be ignored for dec num check",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-const-dec-num-check": {
+ "description": "Const declarations will be ignored for dec num check",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-var-dec-num-check": {
+ "description": "Var declarations will be ignored for dec num check",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ },
+ "depguard": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "rules": {
+ "description": "Rules to apply.",
+ "type": "object",
+ "additionalProperties": false,
+ "patternProperties": {
+ "^[^.]+$": {
+ "description": "Name of a rule.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "list-mode": {
+ "description": "Used to determine the package matching priority.",
+ "enum": ["original", "strict", "lax"],
+ "default": "original"
+ },
+ "files": {
+ "description": "List of file globs that will match this list of settings to compare against.",
+ "additionalProperties": false,
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "allow": {
+ "description": "List of allowed packages.",
+ "additionalProperties": false,
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "deny": {
+ "description": "Packages that are not allowed where the value is a suggestion.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "desc": {
+ "description": "Description",
+ "type": "string"
+ },
+ "pkg": {
+ "description": "Package",
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "dogsled": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-blank-identifiers": {
+ "description": "Check assignments with too many blank identifiers.",
+ "type": "integer",
+ "default": 2,
+ "minimum": 0
+ }
+ }
+ },
+ "dupl": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "threshold": {
+ "description": "Tokens count to trigger issue.",
+ "type": "integer",
+ "default": 150,
+ "minimum": 0
+ }
+ }
+ },
+ "errcheck": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-type-assertions": {
+ "description": "Report about not checking errors in type assertions, i.e.: `a := b.(MyStruct)`",
+ "type": "boolean",
+ "default": false
+ },
+ "check-blank": {
+ "description": "Report about assignment of errors to blank identifier",
+ "type": "boolean",
+ "default": false
+ },
+ "exclude-functions": {
+ "description": "List of functions to exclude from checking, where each entry is a single function to exclude",
+ "type": "array",
+ "examples": ["io/ioutil.ReadFile", "io.Copy(*bytes.Buffer)"],
+ "items": {
+ "type": "string"
+ }
+ },
+ "disable-default-exclusions": {
+ "description": "To disable the errcheck built-in exclude list",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "errchkjson": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-error-free-encoding": {
+ "type": "boolean",
+ "default": false
+ },
+ "report-no-exported": {
+ "description": "Issue on struct that doesn't have exported fields.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "errorlint": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "errorf": {
+ "description": "Check whether fmt.Errorf uses the %w verb for formatting errors",
+ "type": "boolean",
+ "default": true
+ },
+ "errorf-multi": {
+ "description": "Permit more than 1 %w verb, valid per Go 1.20",
+ "type": "boolean",
+ "default": true
+ },
+ "asserts": {
+ "description": "Check for plain type assertions and type switches.",
+ "type": "boolean",
+ "default": true
+ },
+ "comparison": {
+ "description": "Check for plain error comparisons",
+ "type": "boolean",
+ "default": true
+ },
+ "allowed-errors": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "err": {
+ "type": "string"
+ },
+ "fun": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "allowed-errors-wildcard": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "err": {
+ "type": "string"
+ },
+ "fun": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "exhaustive": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check": {
+ "description": "Program elements to check for exhaustiveness.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["switch", "map"]
+ }
+ },
+ "check-generated": {
+ "description": "Check switch statements in generated files",
+ "type": "boolean",
+ "default": false
+ },
+ "explicit-exhaustive-switch": {
+ "description": "Only run exhaustive check on switches with \"//exhaustive:enforce\" comment.",
+ "type": "boolean",
+ "default": false
+ },
+ "explicit-exhaustive-map": {
+ "description": "Only run exhaustive check on map literals with \"//exhaustive:enforce\" comment.",
+ "type": "boolean",
+ "default": false
+ },
+ "default-case-required": {
+ "description": "Switch statement requires default case even if exhaustive.",
+ "type": "boolean",
+ "default": false
+ },
+ "default-signifies-exhaustive": {
+ "description": "Presence of `default` case in switch statements satisfies exhaustiveness, even if all enum members are not listed.",
+ "type": "boolean",
+ "default": false
+ },
+ "ignore-enum-members": {
+ "description": "Enum members matching `regex` do not have to be listed in switch statements to satisfy exhaustiveness",
+ "type": "string"
+ },
+ "ignore-enum-types": {
+ "description": "Enum types matching the supplied regex do not have to be listed in switch statements to satisfy exhaustiveness.",
+ "type": "string"
+ },
+ "package-scope-only": {
+ "description": "Consider enums only in package scopes, not in inner scopes.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "exhaustruct": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "include": {
+ "description": "List of regular expressions to match struct packages and names.",
+ "type": "array",
+ "examples": [".*\\.Test"],
+ "items": {
+ "type": "string"
+ }
+ },
+ "exclude": {
+ "description": "List of regular expressions to exclude struct packages and names from check.",
+ "type": "array",
+ "examples": ["cobra\\.Command$"],
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "forbidigo": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "exclude-godoc-examples": {
+ "description": "Exclude code in godoc examples.",
+ "type": "boolean",
+ "default": true
+ },
+ "analyze-types": {
+ "description": "Instead of matching the literal source code, use type information to replace expressions with strings that contain the package name and (for methods and fields) the type name.",
+ "type": "boolean",
+ "default": true
+ },
+ "forbid": {
+ "description": "List of identifiers to forbid (written using `regexp`)",
+ "type": "array",
+ "examples": ["^print(ln)?$"],
+ "items": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "p": {
+ "description": "Pattern",
+ "type": "string"
+ },
+ "pkg": {
+ "description": "Package",
+ "type": "string"
+ },
+ "msg": {
+ "description": "Message",
+ "type": "string"
+ }
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ "funlen": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "lines": {
+ "description": "Limit lines number per function.",
+ "type": "integer",
+ "default": 60
+ },
+ "statements": {
+ "description": "Limit statements number per function.",
+ "type": "integer",
+ "default": 40
+ },
+ "ignore-comments": {
+ "description": "Ignore comments when counting lines.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "gci": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "sections": {
+ "description": "Section configuration to compare against.",
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "enum": [
+ "standard",
+ "default",
+ "blank",
+ "dot",
+ "alias",
+ "localmodule"
+ ]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ },
+ "default": ["standard", "default"]
+ },
+ "skip-generated": {
+ "description": "Skip generated files.",
+ "type": "boolean",
+ "default": true
+ },
+ "custom-order": {
+ "description": "Enable custom order of sections.",
+ "type": "boolean",
+ "default": false
+ },
+ "no-lex-order": {
+ "description": "Drops lexical ordering for custom sections.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "ginkgolinter": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "suppress-len-assertion": {
+ "description": "Suppress the wrong length assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-nil-assertion": {
+ "description": "Suppress the wrong nil assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-err-assertion": {
+ "description": "Suppress the wrong error assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-compare-assertion": {
+ "description": "Suppress the wrong comparison assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-async-assertion": {
+ "description": "Suppress the function all in async assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-type-compare-assertion": {
+ "description": "Suppress warning for comparing values from different types, like int32 and uint32.",
+ "type": "boolean",
+ "default": false
+ },
+ "forbid-focus-container": {
+ "description": "Trigger warning for ginkgo focus containers like FDescribe, FContext, FWhen or FIt.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-havelen-zero": {
+ "description": "Don't trigger warnings for HaveLen(0).",
+ "type": "boolean",
+ "default": false
+ },
+ "force-expect-to": {
+ "description": "Force using `Expect` with `To`, `ToNot` or `NotTo`",
+ "type": "boolean",
+ "default": false
+ },
+ "validate-async-intervals": {
+ "description": "Best effort validation of async intervals (timeout and polling).",
+ "type": "boolean",
+ "default": false
+ },
+ "forbid-spec-pollution": {
+ "description": "Trigger a warning for variable assignments in ginkgo containers like `Describe`, `Context` and `When`, instead of in `BeforeEach()`.",
+ "type": "boolean",
+ "default": false
+ },
+ "force-succeed": {
+ "description": "Force using the Succeed matcher for error functions, and the HaveOccurred matcher for non-function error values.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "gochecksumtype": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "default-signifies-exhaustive": {
+ "description": "Presence of `default` case in switch statements satisfies exhaustiveness, if all members are not listed.",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "gocognit": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "min-complexity": {
+ "description": "Minimal code complexity to report (we recommend 10-20).",
+ "type": "integer",
+ "default": 30
+ }
+ }
+ },
+ "goconst": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "match-constant": {
+ "description": "Look for existing constants matching the values",
+ "type": "boolean",
+ "default": true
+ },
+ "min-len": {
+ "description": "Minimum length of string constant.",
+ "type": "integer",
+ "default": 3
+ },
+ "min-occurrences": {
+ "description": "Minimum occurrences count to trigger.",
+ "type": "integer",
+ "default": 3
+ },
+ "ignore-tests": {
+ "description": "Ignore test files.",
+ "type": "boolean",
+ "default": false
+ },
+ "ignore-calls": {
+ "description": "Ignore when constant is not used as function argument",
+ "type": "boolean",
+ "default": true
+ },
+ "ignore-strings": {
+ "description": "Exclude strings matching the given regular expression",
+ "type": "string"
+ },
+ "numbers": {
+ "description": "Search also for duplicated numbers.",
+ "type": "boolean",
+ "default": false
+ },
+ "min": {
+ "description": "Minimum value, only works with `numbers`",
+ "type": "integer",
+ "default": 3
+ },
+ "max": {
+ "description": "Maximum value, only works with `numbers`",
+ "type": "integer",
+ "default": 3
+ }
+ }
+ },
+ "gocritic": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "enabled-checks": {
+ "description": "Which checks should be enabled. By default, a list of stable checks is used. To see it, run `GL_DEBUG=gocritic golangci-lint run`.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/gocritic-checks"
+ }
+ },
+ "disabled-checks": {
+ "description": "Which checks should be disabled.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/gocritic-checks"
+ },
+ "default": []
+ },
+ "enabled-tags": {
+ "description": "Enable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/gocritic-tags"
+ }
+ },
+ "disabled-tags": {
+ "description": "Disable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/gocritic-tags"
+ }
+ },
+ "settings": {
+ "description": "Settings passed to gocritic. Properties must be valid and enabled check names.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "captLocal": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "paramsOnly" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "commentedOutCode": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "minLength" : {
+ "type": "number",
+ "default": 15
+ }
+ }
+ },
+ "elseif": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skipBalanced" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "hugeParam": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "sizeThreshold" : {
+ "type": "number",
+ "default": 80
+ }
+ }
+ },
+ "ifElseChain": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "minThreshold" : {
+ "type": "number",
+ "default": 2
+ }
+ }
+ },
+ "nestingReduce": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "bodyWidth" : {
+ "type": "number",
+ "default": 5
+ }
+ }
+ },
+ "rangeExprCopy": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "sizeThreshold" : {
+ "type": "number",
+ "default": 512
+ },
+ "skipTestFuncs" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "rangeValCopy": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "sizeThreshold" : {
+ "type": "number",
+ "default": 128
+ },
+ "skipTestFuncs" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "ruleguard": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "debug" : {
+ "type": "string"
+ },
+ "enable" : {
+ "type": "string"
+ },
+ "disable" : {
+ "type": "string"
+ },
+ "failOn" : {
+ "type": "string"
+ },
+ "rules" : {
+ "type": "string"
+ }
+ }
+ },
+ "tooManyResultsChecker": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "maxResults" : {
+ "type": "number",
+ "default": 5
+ }
+ }
+ },
+ "truncateCmp": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skipArchDependent" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "underef": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skipRecvDeref" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "unnamedResult": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "checkExported" : {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ }
+ }
+ },
+ "disable-all": {
+ "type": "boolean",
+ "default": false
+ },
+ "enable-all": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "gocyclo": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "min-complexity": {
+ "description": "Minimum code complexity to report (we recommend 10-20).",
+ "type": "integer",
+ "default": 30
+ }
+ }
+ },
+ "godot": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "scope": {
+ "description": "Comments to be checked.",
+ "enum": ["declarations", "toplevel", "all"],
+ "default": "declarations"
+ },
+ "exclude": {
+ "description": "List of regexps for excluding particular comment lines from check.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "period": {
+ "description": "Check that each sentence ends with a period.",
+ "type": "boolean",
+ "default": true
+ },
+ "capital": {
+ "description": "Check that each sentence starts with a capital letter.",
+ "type": "boolean",
+ "default": false
+ },
+ "check-all": {
+ "description": "DEPRECATED: Check all top-level comments, not only declarations.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "godox": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "keywords": {
+ "description": "Report any comments starting with one of these keywords. This is useful for TODO or FIXME comments that might be left in the code accidentally and should be resolved before merging.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "default": ["TODO", "BUG", "FIXME"]
+ }
+ }
+ },
+ "gofmt": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "simplify": {
+ "description": "Simplify code.",
+ "type": "boolean",
+ "default": true
+ },
+ "rewrite-rules": {
+ "description": "Apply the rewrite rules to the source before reformatting.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "pattern": {
+ "type": "string"
+ },
+ "replacement": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "interfacebloat": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max": {
+ "description": "The maximum number of methods allowed for an interface.",
+ "type": "integer"
+ }
+ }
+ },
+ "gofumpt": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "extra-rules": {
+ "description": "Choose whether or not to use the extra rules that are disabled by default.",
+ "type": "boolean",
+ "default": false
+ },
+ "module-path": {
+ "description": " Module path which contains the source code being formatted.",
+ "type": "string"
+ }
+ }
+ },
+ "goheader": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "values": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "const": {
+ "description": "Constants to use in the template.",
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "description": "Value for the constant.",
+ "type": "string"
+ }
+ },
+ "additionalProperties": false,
+ "examples": [
+ {
+ "YEAR": "2030",
+ "COMPANY": "MY FUTURISTIC COMPANY"
+ }
+ ]
+ },
+ "regexp": {
+ "description": "Regular expressions to use in your template.",
+ "type": "object",
+ "additionalProperties": false,
+ "patternProperties": {
+ "^.+$": {
+ "type": "string"
+ }
+ },
+ "examples": [
+ {
+ "AUTHOR": ".*@mycompany\\.com"
+ }
+ ]
+ }
+ }
+ },
+ "template": {
+ "description": "Template to put on top of every file.",
+ "type": "string",
+ "examples": [
+ "{{ MY COMPANY }}\nSPDX-License-Identifier: Apache-2.0\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at:\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License."
+ ]
+ },
+ "template-path": {
+ "description": "Path to the file containing the template source.",
+ "type": "string",
+ "examples": ["my_header_template.txt"]
+ }
+ },
+ "oneOf": [
+ { "required": ["template"] },
+ { "required": ["template-path"] }
+ ]
+ },
+ "goimports": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "local-prefixes": {
+ "description": "Put imports beginning with prefix after 3rd-party packages. It is a comma-separated list of prefixes.",
+ "type": "string",
+ "examples": ["github.com/org/project"]
+ }
+ }
+ },
+ "gomoddirectives": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "replace-local": {
+ "description": "Allow local `replace` directives.",
+ "type": "boolean",
+ "default": false
+ },
+ "replace-allow-list": {
+ "description": "List of allowed `replace` directives.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "retract-allow-no-explanation": {
+ "description": "Allow to not explain why the version has been retracted in the `retract` directives.",
+ "type": "boolean",
+ "default": false
+ },
+ "exclude-forbidden": {
+ "description": "Forbid the use of the `exclude` directives.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "gomodguard": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "allowed": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "modules": {
+ "description": "List of allowed modules.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["gopkg.in/yaml.v2"]
+ }
+ },
+ "domains": {
+ "description": "List of allowed module domains.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["golang.org"]
+ }
+ }
+ }
+ },
+ "blocked": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "modules": {
+ "description": "List of blocked modules.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "recommendations": {
+ "description": "Recommended modules that should be used instead.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "reason": {
+ "description": "Reason why the recommended module should be used.",
+ "type": "string"
+ }
+ }
+ }
+ },
+ "additionalProperties": false
+ }
+ },
+ "versions": {
+ "description": "List of blocked module version constraints.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "patternProperties": {
+ "^.*$": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "version": {
+ "description": "Version constraint.",
+ "type": "string"
+ },
+ "reason": {
+ "description": "Reason why the version constraint exists.",
+ "type": "string"
+ }
+ },
+ "required": ["reason"]
+ }
+ }
+ }
+ },
+ "local_replace_directives": {
+ "description": "Raise lint issues if loading local path with replace directive",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ }
+ }
+ },
+ "gosimple": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "checks": {
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "enum": ["all"]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ }
+ }
+ }
+ },
+ "gosec": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "includes": {
+ "type": "array",
+ "description": "To select a subset of rules to run",
+ "examples": [["G401"]],
+ "items": {
+ "$ref": "#/definitions/gosec-rules"
+ }
+ },
+ "excludes": {
+ "type": "array",
+ "description": "To specify a set of rules to explicitly exclude",
+ "examples": [["G401"]],
+ "items": {
+ "$ref": "#/definitions/gosec-rules"
+ }
+ },
+ "exclude-generated": {
+ "description": "Exclude generated files",
+ "type": "boolean",
+ "default": false
+ },
+ "severity": {
+ "description": "Filter out the issues with a lower severity than the given value",
+ "type": "string",
+ "enum": ["low", "medium", "high"],
+ "default": "low"
+ },
+ "confidence": {
+ "description": "Filter out the issues with a lower confidence than the given value",
+ "type": "string",
+ "enum": ["low", "medium", "high"],
+ "default": "low"
+ },
+ "config": {
+ "description": "To specify the configuration of rules",
+ "type": "object"
+ },
+ "concurrency": {
+ "description": "Concurrency value",
+ "type": "integer"
+ }
+ }
+ },
+ "gosmopolitan": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "allow-time-local": {
+ "description": "Allow and ignore `time.Local` usages.",
+ "type": "boolean",
+ "default": false
+ },
+ "escape-hatches": {
+ "description": "List of fully qualified names in the `full/pkg/path.name` form, to act as \"i18n escape hatches\".",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignore-tests": {
+ "description": "Ignore test files.",
+ "type": "boolean",
+ "default": false
+ },
+ "watch-for-scripts": {
+ "description": "List of Unicode scripts to watch for any usage in string literals.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "govet": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "settings": {
+ "description": "Settings per analyzer. Map of analyzer name to specific settings.\nRun `go tool vet help` to find out more.",
+ "type": "object",
+ "propertyNames": {
+ "$ref": "#/definitions/govet-analyzers"
+ },
+ "patternProperties": {
+ "^.*$": {
+ "description": "Run `go tool vet help ` to see all settings.",
+ "type": "object"
+ }
+ }
+ },
+ "enable": {
+ "description": "Enable analyzers by name.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/govet-analyzers"
+ }
+ },
+ "disable": {
+ "description": "Disable analyzers by name.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/govet-analyzers"
+ }
+ },
+ "enable-all": {
+ "description": "Enable all analyzers.",
+ "type": "boolean",
+ "default": false
+ },
+ "disable-all": {
+ "description": "Disable all analyzers.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "grouper": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "const-require-single-const": {
+ "type": "boolean",
+ "default": false
+ },
+ "const-require-grouping": {
+ "type": "boolean",
+ "default": false
+ },
+ "import-require-single-import": {
+ "type": "boolean",
+ "default": false
+ },
+ "import-require-grouping": {
+ "type": "boolean",
+ "default": false
+ },
+ "type-require-single-type": {
+ "type": "boolean",
+ "default": false
+ },
+ "type-require-grouping": {
+ "type": "boolean",
+ "default": false
+ },
+ "var-require-single-var": {
+ "type": "boolean",
+ "default": false
+ },
+ "var-require-grouping": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "iface": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "enable": {
+ "description": "Enable analyzers by name.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/iface-analyzers"
+ }
+ },
+ "settings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "unused": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "exclude": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "importas": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "no-unaliased": {
+ "description": "Do not allow unaliased imports of aliased packages.",
+ "type": "boolean",
+ "default": false
+ },
+ "no-extra-aliases": {
+ "description": "Do not allow non-required aliases.",
+ "type": "boolean",
+ "default": false
+ },
+ "alias": {
+ "description": "List of aliases",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "pkg": {
+ "description": "Package path e.g. knative.dev/serving/pkg/apis/autoscaling/v1alpha1",
+ "type": "string"
+ },
+ "alias": {
+ "description": "Package alias e.g. autoscalingv1alpha1",
+ "type": "string"
+ }
+ },
+ "required": ["pkg", "alias"]
+ }
+ }
+ }
+ },
+ "inamedparam": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skip-single-param": {
+ "description": "Skips check for interface methods with only a single parameter.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "ireturn": {
+ "type": "object",
+ "additionalProperties": false,
+ "description": "Use either `reject` or `allow` properties for interfaces matching.",
+ "properties": {
+ "allow": {
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "enum": ["anon", "error", "empty", "stdlib"]
+ }
+ ]
+ }
+ },
+ "reject": {
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "enum": ["anon", "error", "empty", "stdlib"]
+ }
+ ]
+ }
+ }
+ },
+ "anyOf": [
+ {
+ "not": {
+ "properties": {
+ "allow": {
+ "const": "reject"
+ }
+ }
+ },
+ "required": ["allow"]
+ },
+ {
+ "required": ["reject"]
+ }
+ ]
+ },
+ "lll": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "tab-width": {
+ "description": "Width of \"\\t\" in spaces.",
+ "type": "integer",
+ "minimum": 0,
+ "default": 1
+ },
+ "line-length": {
+ "description": "Maximum allowed line length, lines longer will be reported.",
+ "type": "integer",
+ "minimum": 1,
+ "default": 120
+ }
+ }
+ },
+ "maintidx": {
+ "description": "Maintainability index https://docs.microsoft.com/en-us/visualstudio/code-quality/code-metrics-maintainability-index-range-and-meaning?view=vs-2022",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "under": {
+ "description": "Minimum accatpable maintainability index level (see https://docs.microsoft.com/en-us/visualstudio/code-quality/code-metrics-maintainability-index-range-and-meaning?view=vs-2022)",
+ "type": "number",
+ "default": 20
+ }
+ }
+ },
+ "makezero": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "always": {
+ "description": "Allow only slices initialized with a length of zero.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "loggercheck": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "kitlog": {
+ "description": "Allow check for the github.com/go-kit/log library.",
+ "type": "boolean",
+ "default": true
+ },
+ "klog": {
+ "description": "Allow check for the k8s.io/klog/v2 library.",
+ "type": "boolean",
+ "default": true
+ },
+ "logr": {
+ "description": "Allow check for the github.com/go-logr/logr library.",
+ "type": "boolean",
+ "default": true
+ },
+ "zap": {
+ "description": "Allow check for the \"sugar logger\" from go.uber.org/zap library.",
+ "type": "boolean",
+ "default": true
+ },
+ "require-string-key": {
+ "description": "Require all logging keys to be inlined constant strings.",
+ "type": "boolean",
+ "default": false
+ },
+ "no-printf-like": {
+ "description": "Require printf-like format specifier (%s, %d for example) not present.",
+ "type": "boolean",
+ "default": false
+ },
+ "rules": {
+ "description": "List of custom rules to check against, where each rule is a single logger pattern, useful for wrapped loggers.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "misspell": {
+ "description": "Correct spellings using locale preferences for US or UK. Default is to use a neutral variety of English.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "locale": {
+ "enum": ["US", "UK"]
+ },
+ "ignore-words": {
+ "description": "List of words to ignore.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "mode": {
+ "description": "Mode of the analysis.",
+ "enum": ["restricted", "", "default"],
+ "default": ""
+ },
+ "extra-words": {
+ "description": "Extra word corrections.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "correction": {
+ "type": "string"
+ },
+ "typo": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "musttag": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "functions": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "tag": {
+ "type": "string"
+ },
+ "arg-pos": {
+ "type": "integer"
+ }
+ }
+ }
+ }
+ }
+ },
+ "nakedret": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-func-lines": {
+ "description": "Report if a function has more lines of code than this value and it has naked returns.",
+ "type": "integer",
+ "minimum": 0,
+ "default": 30
+ }
+ }
+ },
+ "nestif": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "min-complexity": {
+ "description": "Minimum complexity of \"if\" statements to report.",
+ "type": "integer",
+ "default": 5
+ }
+ }
+ },
+ "nilnil": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "detect-opposite": {
+ "type": "boolean",
+ "description": "In addition, detect opposite situation (simultaneous return of non-nil error and valid value).",
+ "default": false
+ },
+ "checked-types": {
+ "type": "array",
+ "description": "List of return types to check.",
+ "items": {
+ "enum": ["chan", "func", "iface", "map", "ptr", "uintptr", "unsafeptr"]
+ },
+ "default": ["chan", "func", "iface", "map", "ptr", "uintptr", "unsafeptr"]
+ }
+ }
+ },
+ "nlreturn": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "block-size": {
+ "description": "set block size that is still ok",
+ "type": "number",
+ "default": 0,
+ "minimum": 0
+ }
+ }
+ },
+ "mnd": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignored-files": {
+ "description": "List of file patterns to exclude from analysis.",
+ "examples": [["magic1_.*.go"]],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignored-functions": {
+ "description": "Comma-separated list of function patterns to exclude from the analysis.",
+ "examples": [["math.*", "http.StatusText", "make"]],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignored-numbers": {
+ "description": "List of numbers to exclude from analysis.",
+ "examples": [["1000", "1234_567_890", "3.14159264"]],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "checks": {
+ "description": "The list of enabled checks, see https://github.com/tommy-muehle/go-mnd/#checks for description.",
+ "type": "array",
+ "items": {
+ "enum": [
+ "argument",
+ "case",
+ "condition",
+ "operation",
+ "return",
+ "assign"
+ ]
+ }
+ }
+ }
+ },
+ "nolintlint": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "allow-unused": {
+ "description": "Enable to ensure that nolint directives are all used.",
+ "type": "boolean",
+ "default": true
+ },
+ "allow-no-explanation": {
+ "description": "Exclude these linters from requiring an explanation.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linters"
+ },
+ "default": []
+ },
+ "require-explanation": {
+ "description": "Enable to require an explanation of nonzero length after each nolint directive.",
+ "type": "boolean",
+ "default": false
+ },
+ "require-specific": {
+ "description": "Enable to require nolint directives to mention the specific linter being suppressed.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "reassign": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "patterns": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "nonamedreturns": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "report-error-in-defer": {
+ "description": "Report named error if it is assigned inside defer.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "paralleltest": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignore-missing": {
+ "description": "Ignore missing calls to `t.Parallel()` and only report incorrect uses of it.",
+ "type": "boolean",
+ "default": false
+ },
+ "ignore-missing-subtests": {
+ "description": "Ignore missing calls to `t.Parallel()` in subtests. Top-level tests are still required to have `t.Parallel`, but subtests are allowed to skip it.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "perfsprint": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "int-conversion": {
+ "description": "Optimizes even if it requires an int or uint type cast.",
+ "type": "boolean",
+ "default": true
+ },
+ "err-error": {
+ "description": "Optimizes into `err.Error()` even if it is only equivalent for non-nil errors.",
+ "type": "boolean",
+ "default": false
+ },
+ "errorf": {
+ "description": "Optimizes `fmt.Errorf`.",
+ "type": "boolean",
+ "default": true
+ },
+ "sprintf1": {
+ "description": "Optimizes `fmt.Sprintf` with only one argument.",
+ "type": "boolean",
+ "default": true
+ },
+ "strconcat": {
+ "description": "Optimizes into strings concatenation.",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "prealloc": {
+ "description": "We do not recommend using this linter before doing performance profiling.\nFor most programs usage of `prealloc` will be premature optimization.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "simple": {
+ "description": "Report preallocation suggestions only on simple loops that have no returns/breaks/continues/gotos in them.",
+ "type": "boolean",
+ "default": true
+ },
+ "range-loops": {
+ "description": "Report preallocation suggestions on range loops.",
+ "type": "boolean",
+ "default": true
+ },
+ "for-loops": {
+ "description": "Report preallocation suggestions on for loops.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "predeclared": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignore": {
+ "description": "Comma-separated list of predeclared identifiers to not report on.",
+ "type": "string"
+ },
+ "q": {
+ "description": "Include method names and field names (i.e., qualified names) in checks.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "promlinter": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "strict": {},
+ "disabled-linters": {
+ "type": "array",
+ "items": {
+ "enum": [
+ "Help",
+ "MetricUnits",
+ "Counter",
+ "HistogramSummaryReserved",
+ "MetricTypeInName",
+ "ReservedChars",
+ "CamelCase",
+ "UnitAbbreviations"
+ ]
+ }
+ }
+ }
+ },
+ "protogetter": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skip-generated-by": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["protoc-gen-go-my-own-generator"]
+ }
+ },
+ "skip-files": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["*.pb.go"]
+ }
+ },
+ "skip-any-generated": {
+ "description": "Skip any generated files from the checking.",
+ "type": "boolean",
+ "default": false
+ },
+ "replace-first-arg-in-append": {
+ "description": "Skip first argument of append function.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "revive": {
+ "type": "object",
+ "additionalProperties": false,
+ "examples": [
+ {
+ "ignore-generated-header": true,
+ "severity": "warning",
+ "rules": [
+ {
+ "name": "indent-error-flow",
+ "severity": "warning"
+ },
+ {
+ "name": "add-constant",
+ "severity": "warning",
+ "arguments": [
+ {
+ "maxLitCount": "3",
+ "allowStrs": "\"\"",
+ "allowInts": "0,1,2",
+ "allowFloats": "0.0,0.,1.0,1.,2.0,2."
+ }
+ ]
+ }
+ ]
+ }
+ ],
+ "properties": {
+ "max-open-files": {
+ "type": "integer"
+ },
+ "ignore-generated-header": {
+ "type": "boolean"
+ },
+ "confidence": {
+ "type": "number"
+ },
+ "severity": {
+ "type": "string",
+ "enum": ["warning", "error"]
+ },
+ "enable-all-rules": {
+ "type": "boolean",
+ "default": false
+ },
+ "directives": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "name": {
+ "type": "string",
+ "enum": ["specify-disable-reason"]
+ },
+ "severity": {
+ "type": "string",
+ "enum": ["warning", "error"]
+ },
+ "exclude": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "arguments": {
+ "type": "array"
+ }
+ }
+ }
+ },
+ "rules": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["name"],
+ "properties": {
+ "name": {
+ "$ref": "#/definitions/revive-rules",
+ "title": "The rule name"
+ },
+ "disabled": {
+ "type": "boolean"
+ },
+ "severity": {
+ "type": "string",
+ "enum": ["warning", "error"]
+ },
+ "exclude": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "arguments": {
+ "type": "array"
+ }
+ }
+ }
+ }
+ }
+ },
+ "rowserrcheck": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "packages": {
+ "type": "array",
+ "items": {
+ "description": "",
+ "type": "string",
+ "examples": ["github.com/jmoiron/sqlx"]
+ }
+ }
+ }
+ },
+ "sloglint": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "kv-only": {
+ "description": "Enforce using key-value pairs only (incompatible with attr-only).",
+ "type": "boolean",
+ "default": false
+ },
+ "no-global": {
+ "description": "Enforce not using global loggers.",
+ "enum": ["", "all", "default"],
+ "default": ""
+ },
+ "no-mixed-args": {
+ "description": "Enforce not mixing key-value pairs and attributes.",
+ "type": "boolean",
+ "default": true
+ },
+ "context": {
+ "description": "Enforce using methods that accept a context.",
+ "enum": ["", "all", "scope"],
+ "default": ""
+ },
+ "static-msg": {
+ "description": "Enforce using static values for log messages.",
+ "type": "boolean",
+ "default": false
+ },
+ "key-naming-case": {
+ "description": "Enforce a single key naming convention.",
+ "enum": ["snake", "kebab", "camel", "pascal"]
+ },
+ "attr-only": {
+ "description": "Enforce using attributes only (incompatible with kv-only).",
+ "type": "boolean",
+ "default": false
+ },
+ "no-raw-keys": {
+ "description": "Enforce using constants instead of raw keys.",
+ "type": "boolean",
+ "default": false
+ },
+ "forbidden-keys": {
+ "description": "Enforce not using specific keys.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "args-on-sep-lines": {
+ "description": "Enforce putting arguments on separate lines.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "spancheck": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "checks": {
+ "description": "Checks to enable.",
+ "type": "array",
+ "items": {
+ "enum": ["end", "record-error", "set-status"]
+ }
+ },
+ "ignore-check-signatures": {
+ "description": "A list of regexes for function signatures that silence `record-error` and `set-status` reports if found in the call path to a returned error.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "extra-start-span-signatures": {
+ "description": "A list of regexes for additional function signatures that create spans.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "staticcheck": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "checks": {
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "enum": ["all"]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ }
+ }
+ }
+ },
+ "stylecheck": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "checks": {
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "enum": ["all"]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ },
+ "default": [
+ "all",
+ "-ST1000",
+ "-ST1003",
+ "-ST1016",
+ "-ST1020",
+ "-ST1021",
+ "-ST1022"
+ ]
+ },
+ "dot-import-whitelist": {
+ "description": "By default, ST1001 forbids all uses of dot imports in non-test packages. This setting allows setting a whitelist of import paths that can be dot-imported anywhere.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "http-status-code-whitelist": {
+ "description": "ST1013 recommends using constants from the net/http package instead of hard-coding numeric HTTP status codes. This setting specifies a list of numeric status codes that this check does not complain about.",
+ "default": ["200", "400", "404", "500"],
+ "type": "array",
+ "items": {
+ "enum": [
+ "100",
+ "101",
+ "102",
+ "103",
+ "200",
+ "201",
+ "202",
+ "203",
+ "204",
+ "205",
+ "206",
+ "207",
+ "208",
+ "226",
+ "300",
+ "301",
+ "302",
+ "303",
+ "304",
+ "305",
+ "306",
+ "307",
+ "308",
+ "400",
+ "401",
+ "402",
+ "403",
+ "404",
+ "405",
+ "406",
+ "407",
+ "408",
+ "409",
+ "410",
+ "411",
+ "412",
+ "413",
+ "414",
+ "415",
+ "416",
+ "417",
+ "418",
+ "421",
+ "422",
+ "423",
+ "424",
+ "425",
+ "426",
+ "428",
+ "429",
+ "431",
+ "451",
+ "500",
+ "501",
+ "502",
+ "503",
+ "504",
+ "505",
+ "506",
+ "507",
+ "508",
+ "510",
+ "511"
+ ]
+ }
+ },
+ "initialisms": {
+ "description": "ST1003 check, among other things, for the correct capitalization of initialisms. The set of known initialisms can be configured with this option.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "default": [
+ "ACL",
+ "API",
+ "ASCII",
+ "CPU",
+ "CSS",
+ "DNS",
+ "EOF",
+ "GUID",
+ "HTML",
+ "HTTP",
+ "HTTPS",
+ "ID",
+ "IP",
+ "JSON",
+ "QPS",
+ "RAM",
+ "RPC",
+ "SLA",
+ "SMTP",
+ "SQL",
+ "SSH",
+ "TCP",
+ "TLS",
+ "TTL",
+ "UDP",
+ "UI",
+ "GID",
+ "UID",
+ "UUID",
+ "URI",
+ "URL",
+ "UTF8",
+ "VM",
+ "XML",
+ "XMPP",
+ "XSRF",
+ "XSS",
+ "SIP",
+ "RTP",
+ "AMQP",
+ "DB",
+ "TS"
+ ]
+ }
+ }
+ }
+ },
+ "tagalign": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "align": {
+ "description": "Align and sort can be used together or separately.",
+ "type": "boolean",
+ "default": true
+ },
+ "sort": {
+ "description": "Whether enable tags sort.",
+ "type": "boolean",
+ "default": true
+ },
+ "order": {
+ "description": "Specify the order of tags, the other tags will be sorted by name.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "default": [],
+ "examples": [
+ [
+ "json",
+ "yaml",
+ "yml",
+ "toml",
+ "mapstructure",
+ "binding",
+ "validate"
+ ]
+ ]
+ },
+ "strict": {
+ "description": "Whether enable strict style.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "tagliatelle": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "case": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "use-field-name": {
+ "description": "Use the struct field name to check the name of the struct tag.",
+ "type": "boolean",
+ "default": false
+ },
+ "rules": {
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "enum": [
+ "camel",
+ "pascal",
+ "kebab",
+ "snake",
+ "goCamel",
+ "goPascal",
+ "goKebab",
+ "goSnake",
+ "upper",
+ "upperSnake",
+ "lower",
+ "header"
+ ]
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "tenv": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "all": {
+ "description": "The option `all` will run against whole test files (`_test.go`) regardless of method/function signatures.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "testifylint": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "enable-all": {
+ "description": "Enable all checkers.",
+ "type": "boolean",
+ "default": false
+ },
+ "disable-all": {
+ "description": "Disable all checkers.",
+ "type": "boolean",
+ "default": false
+ },
+ "enable": {
+ "description": "Enable specific checkers.",
+ "type": "array",
+ "items": {
+ "enum": [
+ "blank-import",
+ "bool-compare",
+ "compares",
+ "contains",
+ "empty",
+ "encoded-compare",
+ "error-is-as",
+ "error-nil",
+ "expected-actual",
+ "float-compare",
+ "formatter",
+ "go-require",
+ "len",
+ "negative-positive",
+ "nil-compare",
+ "regexp",
+ "require-error",
+ "suite-broken-parallel",
+ "suite-dont-use-pkg",
+ "suite-extra-assert-call",
+ "suite-subtest-run",
+ "suite-thelper",
+ "useless-assert"
+ ]
+ },
+ "default": [
+ "blank-import",
+ "bool-compare",
+ "compares",
+ "contains",
+ "empty",
+ "encoded-compare",
+ "error-is-as",
+ "error-nil",
+ "expected-actual",
+ "float-compare",
+ "formatter",
+ "go-require",
+ "len",
+ "negative-positive",
+ "nil-compare",
+ "regexp",
+ "require-error",
+ "suite-broken-parallel",
+ "suite-dont-use-pkg",
+ "suite-extra-assert-call",
+ "suite-subtest-run",
+ "useless-assert"
+ ]
+ },
+ "disable": {
+ "description": "Disable specific checkers.",
+ "type": "array",
+ "items": {
+ "enum": [
+ "blank-import",
+ "bool-compare",
+ "compares",
+ "contains",
+ "empty",
+ "encoded-compare",
+ "error-is-as",
+ "error-nil",
+ "expected-actual",
+ "float-compare",
+ "formatter",
+ "go-require",
+ "len",
+ "negative-positive",
+ "nil-compare",
+ "regexp",
+ "require-error",
+ "suite-broken-parallel",
+ "suite-dont-use-pkg",
+ "suite-extra-assert-call",
+ "suite-subtest-run",
+ "suite-thelper",
+ "useless-assert"
+ ],
+ "default": [
+ "suite-thelper"
+ ]
+ }
+ },
+ "bool-compare": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignore-custom-types": {
+ "description": "To ignore user defined types (over builtin bool).",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "expected-actual": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "pattern": {
+ "description": "Regexp for expected variable name.",
+ "type": "string",
+ "default": "(^(exp(ected)?|want(ed)?)([A-Z]\\w*)?$)|(^(\\w*[a-z])?(Exp(ected)?|Want(ed)?)$)"
+ }
+ }
+ },
+ "formatter": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-format-string": {
+ "description": "To enable go vet's printf checks.",
+ "type": "boolean",
+ "default": true
+ },
+ "require-f-funcs": {
+ "description": "To require f-assertions (e.g. assert.Equalf) if format string is used, even if there are no variable-length variables.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "go-require": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignore-http-handlers": {
+ "description": "To ignore HTTP handlers (like http.HandlerFunc).",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "require-error": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "fn-pattern": {
+ "description": "Regexp for assertions to analyze. If defined, then only matched error assertions will be reported.",
+ "type": "string",
+ "default": ""
+ }
+ }
+ },
+ "suite-extra-assert-call": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "mode": {
+ "description": "To require or remove extra Assert() call?",
+ "type": "string",
+ "enum": ["remove", "require"],
+ "default": "remove"
+ }
+ }
+ }
+ }
+ },
+ "testpackage": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skip-regexp": {
+ "description": "Files with names matching this regular expression are skipped.",
+ "type": "string",
+ "examples": ["(export|internal)_test\\.go"]
+ },
+ "allow-packages": {
+ "description": "List of packages that don't end with _test that tests are allowed to be in.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["example"]
+ }
+ }
+ }
+ },
+ "thelper": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "test": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "begin": {
+ "description": "Check if `t.Helper()` begins helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "first": {
+ "description": "Check if *testing.T is first param of helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "name": {
+ "description": "Check if *testing.T param has t name.",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ },
+ "benchmark": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "begin": {
+ "description": "Check if `b.Helper()` begins helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "first": {
+ "description": "Check if *testing.B is first param of helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "name": {
+ "description": "Check if *testing.B param has b name.",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ },
+ "tb": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "begin": {
+ "description": "Check if `tb.Helper()` begins helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "first": {
+ "description": "Check if *testing.TB is first param of helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "name": {
+ "description": "Check if *testing.TB param has tb name.",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ },
+ "fuzz": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "begin": {
+ "description": "Check if `f.Helper()` begins helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "first": {
+ "description": "Check if *testing.F is first param of helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "name": {
+ "description": "Check if *testing.F param has f name.",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ }
+ }
+ },
+ "usestdlibvars": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "http-method": {
+ "description": "Suggest the use of http.MethodXX.",
+ "type": "boolean",
+ "default": true
+ },
+ "http-status-code": {
+ "description": "Suggest the use of http.StatusXX.",
+ "type": "boolean",
+ "default": true
+ },
+ "time-weekday": {
+ "description": "Suggest the use of time.Weekday.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "time-month": {
+ "description": "Suggest the use of time.Month.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "time-layout": {
+ "description": "Suggest the use of time.Layout.",
+ "type": "boolean",
+ "default": false
+ },
+ "crypto-hash": {
+ "description": "Suggest the use of crypto.Hash.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "default-rpc-path": {
+ "description": "Suggest the use of rpc.DefaultXXPath.",
+ "type": "boolean",
+ "default": false
+ },
+ "sql-isolation-level": {
+ "description": "Suggest the use of sql.LevelXX.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "tls-signature-scheme": {
+ "description": "Suggest the use of tls.SignatureScheme.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "constant-kind": {
+ "description": "Suggest the use of constant.Kind.String().",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "unconvert": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "fast-math": {
+ "type": "boolean",
+ "default": false
+ },
+ "safe": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "unparam": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-exported": {
+ "description": "Inspect exported functions. Set to true if no external program/library imports your code.\n\nWARNING: if you enable this setting, unparam will report a lot of false-positives in text editors:\nif it's called for subdir of a project it can't find external interfaces. All text editor integrations\nwith golangci-lint call it on a directory with the changed file.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "unused": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "field-writes-are-uses": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ },
+ "post-statements-are-reads": {
+ "description": "",
+ "type": "boolean",
+ "default": false
+ },
+ "exported-fields-are-used": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ },
+ "parameters-are-used": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ },
+ "local-variables-are-used": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ },
+ "generated-is-used": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "varnamelen": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-distance": {
+ "description": "Variables used in at most this N-many lines will be ignored.",
+ "type": "integer",
+ "default": 5
+ },
+ "min-name-length": {
+ "description": "The minimum length of a variable's name that is considered `long`.",
+ "type": "integer",
+ "default": 3
+ },
+ "check-receiver": {
+ "description": "Check method receiver names.",
+ "default": false,
+ "type": "boolean"
+ },
+ "check-return": {
+ "description": "Check named return values.",
+ "default": false,
+ "type": "boolean"
+ },
+ "check-type-param": {
+ "description": "Check type parameters.",
+ "default": false,
+ "type": "boolean"
+ },
+ "ignore-type-assert-ok": {
+ "description": "Ignore `ok` variables that hold the bool return value of a type assertion",
+ "default": false,
+ "type": "boolean"
+ },
+ "ignore-map-index-ok": {
+ "description": "Ignore `ok` variables that hold the bool return value of a map index.",
+ "default": false,
+ "type": "boolean"
+ },
+ "ignore-chan-recv-ok": {
+ "description": "Ignore `ok` variables that hold the bool return value of a channel receive.",
+ "default": false,
+ "type": "boolean"
+ },
+ "ignore-names": {
+ "description": "Optional list of variable names that should be ignored completely.",
+ "default": [[]],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignore-decls": {
+ "description": "Optional list of variable declarations that should be ignored completely.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "examples": [
+ ["c echo.Context", "t testing.T", "f *foo.Bar", "const C"]
+ ]
+ }
+ }
+ },
+ "whitespace": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "multi-if": {
+ "description": "Enforces newlines (or comments) after every multi-line if statement",
+ "type": "boolean",
+ "default": false
+ },
+ "multi-func": {
+ "description": "Enforces newlines (or comments) after every multi-line function signature",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "wrapcheck": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignoreSigs": {
+ "description": "An array of strings which specify substrings of signatures to ignore.",
+ "default": [
+ ".Errorf(",
+ "errors.New(",
+ "errors.Unwrap(",
+ ".Wrap(",
+ ".Wrapf(",
+ ".WithMessage(",
+ ".WithMessagef(",
+ ".WithStack("
+ ],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignoreSigRegexps": {
+ "description": "An array of strings which specify regular expressions of signatures to ignore.",
+ "default": [""],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignorePackageGlobs": {
+ "description": "An array of glob patterns which, if any match the package of the function returning the error, will skip wrapcheck analysis for this error.",
+ "default": [""],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignoreInterfaceRegexps": {
+ "description": "An array of glob patterns which, if matched to an underlying interface name, will ignore unwrapped errors returned from a function whose call is defined on the given interface.",
+ "default": [""],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "wsl": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "allow-assign-and-anything": {
+ "description": "Controls if you may cuddle assignments and anything without needing an empty line between them.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-assign-and-call": {
+ "description": "Allow calls and assignments to be cuddled as long as the lines have any matching variables, fields or types.",
+ "type": "boolean",
+ "default": true
+ },
+ "allow-cuddle-declarations": {
+ "description": "Allow declarations (var) to be cuddled.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-cuddle-with-calls": {
+ "description": "A list of call idents that everything can be cuddled with.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "allow-cuddle-with-rhs": {
+ "description": "AllowCuddleWithRHS is a list of right hand side variables that is allowed to be cuddled with anything.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "allow-multiline-assign": {
+ "description": "Allow multiline assignments to be cuddled.",
+ "type": "boolean",
+ "default": true
+ },
+ "allow-separated-leading-comment": {
+ "description": "Allow leading comments to be separated with empty lines.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-trailing-comment": {
+ "description": "Allow trailing comments in ending of blocks.",
+ "type": "boolean",
+ "default": false
+ },
+ "error-variable-names": {
+ "description": "When force-err-cuddling is enabled this is a list of names used for error variables to check for in the conditional.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "force-case-trailing-whitespace": {
+ "description": "Force newlines in end of case at this limit (0 = never).",
+ "type": "integer",
+ "minimum": 0,
+ "default": 0
+ },
+ "force-err-cuddling": {
+ "description": "Causes an error when an If statement that checks an error variable doesn't cuddle with the assignment of that variable.",
+ "type": "boolean",
+ "default": false
+ },
+ "force-short-decl-cuddling": {
+ "description": "Causes an error if a short declaration (:=) cuddles with anything other than another short declaration.",
+ "type": "boolean",
+ "default": false
+ },
+ "strict-append": {
+ "description": "If true, append is only allowed to be cuddled if appending value is matching variables, fields or types on line above.",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "copyloopvar": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-alias": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "custom": {
+ "description": "The custom section can be used to define linter plugins to be loaded at runtime. See README of golangci-lint for more information.\nEach custom linter should have a unique name.",
+ "type": "object",
+ "patternProperties": {
+ "^.*$": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "type": {
+ "description": "The plugin type.",
+ "enum": ["module", "goplugin"],
+ "default": "goplugin"
+ },
+ "path": {
+ "description": "The path to the plugin *.so. Can be absolute or local.",
+ "type": "string",
+ "examples": ["/path/to/example.so"]
+ },
+ "description": {
+ "description": "The description of the linter, for documentation purposes only.",
+ "type": "string"
+ },
+ "original-url": {
+ "description": "Intended to point to the repo location of the linter, for documentation purposes only.",
+ "type": "string"
+ },
+ "settings": {
+ "description": "Plugins settings/configuration. Only work with plugin based on `linterdb.PluginConstructor`.",
+ "type": "object"
+ }
+ },
+ "oneOf": [
+ {
+ "properties": {
+ "type": {"enum": ["module"] }
+ },
+ "required": ["type"]
+ },
+ {
+ "required": ["path"]
+ }
+ ]
+ }
+ }
+ }
+ }
+ },
+ "linters": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "enable": {
+ "description": "List of enabled linters.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linters"
+ }
+ },
+ "disable": {
+ "description": "List of disabled linters.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linters"
+ }
+ },
+ "enable-all": {
+ "description": "Whether to enable all linters. You can re-disable them with `disable` explicitly.",
+ "type": "boolean",
+ "default": false
+ },
+ "disable-all": {
+ "description": "Whether to disable all linters. You can re-enable them with `enable` explicitly.",
+ "type": "boolean",
+ "default": false
+ },
+ "presets": {
+ "description": "Allow to use different presets of linters",
+ "type": "array",
+ "items": {
+ "enum": [
+ "bugs",
+ "comment",
+ "complexity",
+ "error",
+ "format",
+ "import",
+ "metalinter",
+ "module",
+ "performance",
+ "sql",
+ "style",
+ "test",
+ "unused"
+ ]
+ }
+ },
+ "fast": {
+ "description": "Enable run of fast linters.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "issues": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "exclude": {
+ "description": "List of regular expressions of issue texts to exclude.\nBut independently from this option we use default exclude patterns. Their usage can be controlled through `exclude-use-default`.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "exclude-rules": {
+ "description": "Exclude configuration per-path, per-linter, per-text and per-source",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "path": {
+ "type": "string"
+ },
+ "path-except": {
+ "type": "string"
+ },
+ "linters": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linters"
+ }
+ },
+ "text": {
+ "type": "string"
+ },
+ "source": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "exclude-use-default": {
+ "description": "Independently from option `exclude` we use default exclude patterns. This behavior can be disabled by this option.",
+ "type": "boolean",
+ "default": true
+ },
+ "exclude-case-sensitive": {
+ "description": "If set to true, exclude and exclude-rules regular expressions become case sensitive.",
+ "type": "boolean",
+ "default": false
+ },
+ "exclude-generated": {
+ "description": "Mode of the generated files analysis.",
+ "enum": ["lax", "strict", "disable"],
+ "default": "lax"
+ },
+ "exclude-dirs": {
+ "description": "Which directories to exclude: issues from them won't be reported.",
+ "type": "array",
+ "items": {
+ "description": "You can use regexp here. The regexp is applied on the full path.\n\"/\" will be replaced by current OS file path separator to properly work on Windows.",
+ "type": "string",
+ "examples": ["generated.*"]
+ },
+ "default": [],
+ "examples": [["src/external_libs", "autogenerated_by_my_lib"]]
+ },
+ "exclude-dirs-use-default": {
+ "description": "Enable exclusion of directories \"vendor\", \"third_party\", \"testdata\", \"examples\", \"Godeps\", and \"builtin\".",
+ "type": "boolean",
+ "default": true
+ },
+ "exclude-files": {
+ "description": "Which files to exclude: they will be analyzed, but issues from them will not be reported.",
+ "type": "array",
+ "items": {
+ "description": "You can use regexp here. There is no need to include all autogenerated files, we confidently recognize them. If that is not the case, please let us know.\n\"/\" will be replaced by current OS file path separator to properly work on Windows.",
+ "type": "string",
+ "examples": [".*\\.my\\.go$"]
+ },
+ "default": [],
+ "examples": [[".*\\.my\\.go$", "lib/bad.go"]]
+ },
+ "include": {
+ "description": "The list of ids of default excludes to include or disable.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "default": []
+ },
+ "max-issues-per-linter": {
+ "description": "Maximum issues count per one linter. Set to 0 to disable.",
+ "type": "integer",
+ "default": 50,
+ "minimum": 0
+ },
+ "max-same-issues": {
+ "description": "Maximum count of issues with the same text. Set to 0 to disable.",
+ "type": "integer",
+ "default": 3,
+ "minimum": 0
+ },
+ "new": {
+ "description": "Show only new issues: if there are unstaged changes or untracked files, only those changes are analyzed, else only changes in HEAD~ are analyzed.",
+ "type": "boolean",
+ "default": false
+ },
+ "new-from-rev": {
+ "description": "Show only new issues created after this git revision.",
+ "type": "string"
+ },
+ "new-from-patch": {
+ "description": "Show only new issues created in git patch with this file path.",
+ "type": "string",
+ "examples": ["path/to/patch/file"]
+ },
+ "fix": {
+ "description": "Fix found issues (if it's supported by the linter).",
+ "type": "boolean",
+ "default": false
+ },
+ "whole-files": {
+ "description": "Show issues in any part of update files (requires new-from-rev or new-from-patch).",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "severity": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "default-severity": {
+ "description": "Set the default severity for issues. If severity rules are defined and the issues do not match or no severity is provided to the rule this will be the default severity applied. Severities should match the supported severity names of the selected out format.",
+ "type": "string",
+ "default": ""
+ },
+ "case-sensitive": {
+ "description": "If set to true, severity-rules regular expressions become case sensitive.",
+ "type": "boolean",
+ "default": false
+ },
+ "rules": {
+ "description": "When a list of severity rules are provided, severity information will be added to lint issues. Severity rules have the same filtering capability as exclude rules except you are allowed to specify one matcher per severity rule.\nOnly affects out formats that support setting severity information.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "severity": {
+ "type": "string"
+ },
+ "path": {
+ "type": "string"
+ },
+ "path-except": {
+ "type": "string"
+ },
+ "linters": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linters"
+ }
+ },
+ "text": {
+ "type": "string"
+ },
+ "source": {
+ "type": "string"
+ }
+ },
+ "required": ["severity"],
+ "anyOf": [
+ { "required": ["path"] },
+ { "required": ["path-except"] },
+ { "required": ["linters"] },
+ { "required": ["text"] },
+ { "required": ["source"] }
+ ]
+ },
+ "default": []
+ }
+ },
+ "required": ["default-severity"]
+ }
+ }
+}
diff --git a/vendor/github.com/golangci/golangci-lint/v2/jsonschema/golangci.v1.63.jsonschema.json b/vendor/github.com/golangci/golangci-lint/v2/jsonschema/golangci.v1.63.jsonschema.json
new file mode 100644
index 000000000..c54dd6904
--- /dev/null
+++ b/vendor/github.com/golangci/golangci-lint/v2/jsonschema/golangci.v1.63.jsonschema.json
@@ -0,0 +1,4082 @@
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "$id": "https://json.schemastore.org/golangci-lint.json",
+ "definitions": {
+ "gocritic-checks": {
+ "enum": [
+ "appendAssign",
+ "appendCombine",
+ "argOrder",
+ "assignOp",
+ "badCall",
+ "badCond",
+ "badLock",
+ "badRegexp",
+ "badSorting",
+ "badSyncOnceFunc",
+ "boolExprSimplify",
+ "builtinShadow",
+ "builtinShadowDecl",
+ "captLocal",
+ "caseOrder",
+ "codegenComment",
+ "commentFormatting",
+ "commentedOutCode",
+ "commentedOutImport",
+ "defaultCaseOrder",
+ "deferInLoop",
+ "deferUnlambda",
+ "deprecatedComment",
+ "docStub",
+ "dupArg",
+ "dupBranchBody",
+ "dupCase",
+ "dupImport",
+ "dupSubExpr",
+ "dynamicFmtString",
+ "elseif",
+ "emptyDecl",
+ "emptyFallthrough",
+ "emptyStringTest",
+ "equalFold",
+ "evalOrder",
+ "exitAfterDefer",
+ "exposedSyncMutex",
+ "externalErrorReassign",
+ "filepathJoin",
+ "flagDeref",
+ "flagName",
+ "hexLiteral",
+ "httpNoBody",
+ "hugeParam",
+ "ifElseChain",
+ "importShadow",
+ "indexAlloc",
+ "initClause",
+ "ioutilDeprecated",
+ "mapKey",
+ "methodExprCall",
+ "nestingReduce",
+ "newDeref",
+ "nilValReturn",
+ "octalLiteral",
+ "offBy1",
+ "paramTypeCombine",
+ "preferDecodeRune",
+ "preferFilepathJoin",
+ "preferFprint",
+ "preferStringWriter",
+ "preferWriteByte",
+ "ptrToRefParam",
+ "rangeAppendAll",
+ "rangeExprCopy",
+ "rangeValCopy",
+ "redundantSprint",
+ "regexpMust",
+ "regexpPattern",
+ "regexpSimplify",
+ "returnAfterHttpError",
+ "ruleguard",
+ "singleCaseSwitch",
+ "sliceClear",
+ "sloppyLen",
+ "sloppyReassign",
+ "sloppyTypeAssert",
+ "sortSlice",
+ "sprintfQuotedString",
+ "sqlQuery",
+ "stringConcatSimplify",
+ "stringXbytes",
+ "stringsCompare",
+ "switchTrue",
+ "syncMapLoadAndDelete",
+ "timeExprSimplify",
+ "todoCommentWithoutDetail",
+ "tooManyResultsChecker",
+ "truncateCmp",
+ "typeAssertChain",
+ "typeDefFirst",
+ "typeSwitchVar",
+ "typeUnparen",
+ "uncheckedInlineErr",
+ "underef",
+ "unlabelStmt",
+ "unlambda",
+ "unnamedResult",
+ "unnecessaryBlock",
+ "unnecessaryDefer",
+ "unslice",
+ "valSwap",
+ "weakCond",
+ "whyNoLint",
+ "wrapperFunc",
+ "yodaStyleExpr"
+ ]
+ },
+ "gocritic-tags": {
+ "enum": [
+ "diagnostic",
+ "style",
+ "performance",
+ "experimental",
+ "opinionated",
+ "security"
+ ]
+ },
+ "gosec-rules": {
+ "enum": [
+ "G101",
+ "G102",
+ "G103",
+ "G104",
+ "G106",
+ "G107",
+ "G108",
+ "G109",
+ "G110",
+ "G111",
+ "G112",
+ "G113",
+ "G114",
+ "G115",
+ "G201",
+ "G202",
+ "G203",
+ "G204",
+ "G301",
+ "G302",
+ "G303",
+ "G304",
+ "G305",
+ "G306",
+ "G307",
+ "G401",
+ "G402",
+ "G403",
+ "G404",
+ "G405",
+ "G406",
+ "G501",
+ "G502",
+ "G503",
+ "G504",
+ "G505",
+ "G506",
+ "G507",
+ "G601",
+ "G602"
+ ]
+ },
+ "govet-analyzers": {
+ "enum": [
+ "appends",
+ "asmdecl",
+ "assign",
+ "atomic",
+ "atomicalign",
+ "bools",
+ "buildtag",
+ "cgocall",
+ "composites",
+ "copylocks",
+ "deepequalerrors",
+ "defers",
+ "directive",
+ "errorsas",
+ "fieldalignment",
+ "findcall",
+ "framepointer",
+ "httpresponse",
+ "ifaceassert",
+ "loopclosure",
+ "lostcancel",
+ "nilfunc",
+ "nilness",
+ "printf",
+ "reflectvaluecompare",
+ "shadow",
+ "shift",
+ "sigchanyzer",
+ "slog",
+ "sortslice",
+ "stdmethods",
+ "stdversion",
+ "stringintconv",
+ "structtag",
+ "testinggoroutine",
+ "tests",
+ "timeformat",
+ "unmarshal",
+ "unreachable",
+ "unsafeptr",
+ "unusedresult",
+ "unusedwrite",
+ "waitgroup"
+ ]
+ },
+ "revive-rules": {
+ "enum": [
+ "add-constant",
+ "argument-limit",
+ "atomic",
+ "banned-characters",
+ "bare-return",
+ "blank-imports",
+ "bool-literal-in-expr",
+ "call-to-gc",
+ "cognitive-complexity",
+ "comment-spacings",
+ "comments-density",
+ "confusing-naming",
+ "confusing-results",
+ "constant-logical-expr",
+ "context-as-argument",
+ "context-keys-type",
+ "cyclomatic",
+ "datarace",
+ "deep-exit",
+ "defer",
+ "dot-imports",
+ "duplicated-imports",
+ "early-return",
+ "empty-block",
+ "empty-lines",
+ "enforce-map-style",
+ "enforce-repeated-arg-type-style",
+ "enforce-slice-style",
+ "error-naming",
+ "error-return",
+ "error-strings",
+ "errorf",
+ "exported",
+ "file-header",
+ "file-length-limit",
+ "filename-format",
+ "flag-parameter",
+ "function-length",
+ "function-result-limit",
+ "get-return",
+ "identical-branches",
+ "if-return",
+ "import-alias-naming",
+ "import-shadowing",
+ "imports-blocklist",
+ "increment-decrement",
+ "indent-error-flow",
+ "line-length-limit",
+ "max-control-nesting",
+ "max-public-structs",
+ "modifies-parameter",
+ "modifies-value-receiver",
+ "nested-structs",
+ "optimize-operands-order",
+ "package-comments",
+ "range",
+ "range-val-address",
+ "range-val-in-closure",
+ "receiver-naming",
+ "redefines-builtin-id",
+ "redundant-import-alias",
+ "string-format",
+ "string-of-int",
+ "struct-tag",
+ "superfluous-else",
+ "time-equal",
+ "time-naming",
+ "unchecked-type-assertion",
+ "unconditional-recursion",
+ "unexported-naming",
+ "unexported-return",
+ "unhandled-error",
+ "unnecessary-stmt",
+ "unreachable-code",
+ "unused-parameter",
+ "unused-receiver",
+ "use-any",
+ "useless-break",
+ "var-declaration",
+ "var-naming",
+ "waitgroup-by-value"
+ ]
+ },
+ "iface-analyzers": {
+ "enum": [
+ "identical",
+ "unused",
+ "opaque"
+ ]
+ },
+ "tagliatelle-cases": {
+ "enum": [
+ "camel",
+ "pascal",
+ "kebab",
+ "snake",
+ "goCamel",
+ "goPascal",
+ "goKebab",
+ "goSnake",
+ "upper",
+ "upperSnake",
+ "lower",
+ "header"
+ ]
+ },
+ "linters": {
+ "$comment": "anyOf with enum is used to allow auto completion of non-custom linters",
+ "description": "Linters usable.",
+ "anyOf": [
+ {
+ "enum": [
+ "asasalint",
+ "asciicheck",
+ "bidichk",
+ "bodyclose",
+ "canonicalheader",
+ "containedctx",
+ "contextcheck",
+ "copyloopvar",
+ "cyclop",
+ "decorder",
+ "depguard",
+ "dogsled",
+ "dupl",
+ "dupword",
+ "durationcheck",
+ "errcheck",
+ "errchkjson",
+ "errname",
+ "errorlint",
+ "exhaustive",
+ "exhaustruct",
+ "exportloopref",
+ "exptostd",
+ "fatcontext",
+ "forbidigo",
+ "forcetypeassert",
+ "funlen",
+ "gci",
+ "ginkgolinter",
+ "gocheckcompilerdirectives",
+ "gochecknoglobals",
+ "gochecknoinits",
+ "gochecksumtype",
+ "gocognit",
+ "goconst",
+ "gocritic",
+ "gocyclo",
+ "godot",
+ "godox",
+ "err113",
+ "gofmt",
+ "gofumpt",
+ "goheader",
+ "goimports",
+ "gomoddirectives",
+ "gomodguard",
+ "goprintffuncname",
+ "gosec",
+ "gosimple",
+ "gosmopolitan",
+ "govet",
+ "grouper",
+ "iface",
+ "importas",
+ "inamedparam",
+ "ineffassign",
+ "interfacebloat",
+ "intrange",
+ "ireturn",
+ "lll",
+ "loggercheck",
+ "maintidx",
+ "makezero",
+ "mirror",
+ "misspell",
+ "mnd",
+ "musttag",
+ "nakedret",
+ "nestif",
+ "nilerr",
+ "nilnesserr",
+ "nilnil",
+ "nlreturn",
+ "noctx",
+ "nolintlint",
+ "nonamedreturns",
+ "nosprintfhostport",
+ "paralleltest",
+ "perfsprint",
+ "prealloc",
+ "predeclared",
+ "promlinter",
+ "protogetter",
+ "reassign",
+ "recvcheck",
+ "revive",
+ "rowserrcheck",
+ "sloglint",
+ "sqlclosecheck",
+ "staticcheck",
+ "stylecheck",
+ "tagalign",
+ "tagliatelle",
+ "tenv",
+ "testableexamples",
+ "testifylint",
+ "testpackage",
+ "thelper",
+ "tparallel",
+ "unconvert",
+ "unparam",
+ "unused",
+ "usestdlibvars",
+ "usetesting",
+ "varnamelen",
+ "wastedassign",
+ "whitespace",
+ "wrapcheck",
+ "wsl",
+ "zerologlint"
+ ]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ }
+ },
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "run": {
+ "description": "Options for analysis running,",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "concurrency": {
+ "description": "Number of concurrent runners. Defaults to the number of available CPU cores.",
+ "type": "integer",
+ "minimum": 0,
+ "examples": [4]
+ },
+ "timeout": {
+ "description": "Timeout for the analysis.",
+ "type": "string",
+ "pattern": "^((\\d+h)?(\\d+m)?(\\d+(?:\\.\\d)?s)?|0)$",
+ "default": "1m",
+ "examples": ["30s", "5m", "5m30s"]
+ },
+ "issues-exit-code": {
+ "description": "Exit code when at least one issue was found.",
+ "type": "integer",
+ "default": 1
+ },
+ "tests": {
+ "description": "Enable inclusion of test files.",
+ "type": "boolean",
+ "default": true
+ },
+ "build-tags": {
+ "description": "List of build tags to pass to all linters.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "default": [],
+ "examples": [["mytag"]]
+ },
+ "modules-download-mode": {
+ "description": "Option to pass to \"go list -mod={option}\".\nSee \"go help modules\" for more information.",
+ "enum": ["mod", "readonly", "vendor"]
+ },
+ "allow-parallel-runners": {
+ "description": "Allow multiple parallel golangci-lint instances running. If disabled, golangci-lint acquires file lock on start.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-serial-runners": {
+ "description": "Allow multiple golangci-lint instances running, but serialize them around a lock.",
+ "type": "boolean",
+ "default": false
+ },
+ "go": {
+ "description": "Targeted Go version.",
+ "type": "string",
+ "default": "1.17"
+ }
+ }
+ },
+ "output": {
+ "description": "Output configuration options.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "formats": {
+ "description": "Output formats to use.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "path": {
+ "default": "stdout",
+ "anyOf": [
+ {
+ "enum": [ "stdout", "stderr" ]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ },
+ "format": {
+ "default": "colored-line-number",
+ "enum": [
+ "colored-line-number",
+ "line-number",
+ "json",
+ "colored-tab",
+ "tab",
+ "html",
+ "checkstyle",
+ "code-climate",
+ "junit-xml",
+ "junit-xml-extended",
+ "github-actions",
+ "teamcity",
+ "sarif"
+ ]
+ }
+ },
+ "required": ["format"]
+ }
+ },
+ "print-issued-lines": {
+ "description": "Print lines of code with issue.",
+ "type": "boolean",
+ "default": true
+ },
+ "print-linter-name": {
+ "description": "Print linter name in the end of issue text.",
+ "type": "boolean",
+ "default": true
+ },
+ "path-prefix": {
+ "description": "Add a prefix to the output file references.",
+ "type": "string",
+ "default": ""
+ },
+ "show-stats": {
+ "description": "Show statistics per linter.",
+ "type": "boolean",
+ "default": false
+ },
+ "sort-order": {
+ "type": "array",
+ "items": {
+ "enum": ["linter", "severity", "file"]
+ }
+ },
+ "sort-results": {
+ "description": "Sort results by: filepath, line and column.",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "linters-settings": {
+ "description": "All available settings of specific linters.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "dupword": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "keywords": {
+ "description": "Keywords for detecting duplicate words. If this list is not empty, only the words defined in this list will be detected.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["the", "and", "a"]
+ }
+ },
+ "ignore": {
+ "description": "Keywords used to ignore detection.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["0C0C"]
+ }
+ }
+ }
+ },
+ "asasalint": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "exclude": {
+ "description": "To specify a set of function names to exclude.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["\\.Wrapf"]
+ }
+ },
+ "use-builtin-exclusions": {
+ "description": "To enable/disable the asasalint builtin exclusions of function names.",
+ "type": "boolean",
+ "default": true
+ },
+ "ignore-test": {
+ "description": "Ignore *_test.go files.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "bidichk": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "left-to-right-embedding": {
+ "description": "Disallow: LEFT-TO-RIGHT-EMBEDDING",
+ "type": "boolean",
+ "default": false
+ },
+ "right-to-left-embedding": {
+ "description": "Disallow: RIGHT-TO-LEFT-EMBEDDING",
+ "type": "boolean",
+ "default": false
+ },
+ "pop-directional-formatting": {
+ "description": "Disallow: POP-DIRECTIONAL-FORMATTING",
+ "type": "boolean",
+ "default": false
+ },
+ "left-to-right-override": {
+ "description": "Disallow: LEFT-TO-RIGHT-OVERRIDE",
+ "type": "boolean",
+ "default": false
+ },
+ "right-to-left-override": {
+ "description": "Disallow: RIGHT-TO-LEFT-OVERRIDE",
+ "type": "boolean",
+ "default": false
+ },
+ "left-to-right-isolate": {
+ "description": "Disallow: LEFT-TO-RIGHT-ISOLATE",
+ "type": "boolean",
+ "default": false
+ },
+ "right-to-left-isolate": {
+ "description": "Disallow: RIGHT-TO-LEFT-ISOLATE",
+ "type": "boolean",
+ "default": false
+ },
+ "first-strong-isolate": {
+ "description": "Disallow: FIRST-STRONG-ISOLATE",
+ "type": "boolean",
+ "default": false
+ },
+ "pop-directional-isolate": {
+ "description": "Disallow: POP-DIRECTIONAL-ISOLATE",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "cyclop": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skip-tests": {
+ "description": "Should the linter execute on test files as well",
+ "type": "boolean",
+ "default": false
+ },
+ "max-complexity": {
+ "description": "Max complexity the function can have",
+ "type": "integer",
+ "default": 10,
+ "minimum": 0
+ },
+ "package-average": {
+ "description": "Max average complexity in package",
+ "type": "number",
+ "default": 0,
+ "minimum": 0
+ }
+ }
+ },
+ "decorder": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "dec-order": {
+ "type": "array",
+ "default": [["type", "const", "var", "func"]],
+ "items": {
+ "enum": ["type", "const", "var", "func"]
+ }
+ },
+ "ignore-underscore-vars": {
+ "description": "Underscore vars (vars with \"_\" as the name) will be ignored at all checks",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-dec-order-check": {
+ "description": "Order of declarations is not checked",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-init-func-first-check": {
+ "description": "Allow init func to be anywhere in file",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-dec-num-check": {
+ "description": "Multiple global type, const and var declarations are allowed",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-type-dec-num-check": {
+ "description": "Type declarations will be ignored for dec num check",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-const-dec-num-check": {
+ "description": "Const declarations will be ignored for dec num check",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-var-dec-num-check": {
+ "description": "Var declarations will be ignored for dec num check",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ },
+ "depguard": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "rules": {
+ "description": "Rules to apply.",
+ "type": "object",
+ "additionalProperties": false,
+ "patternProperties": {
+ "^[^.]+$": {
+ "description": "Name of a rule.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "list-mode": {
+ "description": "Used to determine the package matching priority.",
+ "enum": ["original", "strict", "lax"],
+ "default": "original"
+ },
+ "files": {
+ "description": "List of file globs that will match this list of settings to compare against.",
+ "additionalProperties": false,
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "allow": {
+ "description": "List of allowed packages.",
+ "additionalProperties": false,
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "deny": {
+ "description": "Packages that are not allowed where the value is a suggestion.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "desc": {
+ "description": "Description",
+ "type": "string"
+ },
+ "pkg": {
+ "description": "Package",
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "dogsled": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-blank-identifiers": {
+ "description": "Check assignments with too many blank identifiers.",
+ "type": "integer",
+ "default": 2,
+ "minimum": 0
+ }
+ }
+ },
+ "dupl": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "threshold": {
+ "description": "Tokens count to trigger issue.",
+ "type": "integer",
+ "default": 150,
+ "minimum": 0
+ }
+ }
+ },
+ "errcheck": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-type-assertions": {
+ "description": "Report about not checking errors in type assertions, i.e.: `a := b.(MyStruct)`",
+ "type": "boolean",
+ "default": false
+ },
+ "check-blank": {
+ "description": "Report about assignment of errors to blank identifier",
+ "type": "boolean",
+ "default": false
+ },
+ "exclude-functions": {
+ "description": "List of functions to exclude from checking, where each entry is a single function to exclude",
+ "type": "array",
+ "examples": ["io/ioutil.ReadFile", "io.Copy(*bytes.Buffer)"],
+ "items": {
+ "type": "string"
+ }
+ },
+ "disable-default-exclusions": {
+ "description": "To disable the errcheck built-in exclude list",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "errchkjson": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-error-free-encoding": {
+ "type": "boolean",
+ "default": false
+ },
+ "report-no-exported": {
+ "description": "Issue on struct that doesn't have exported fields.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "errorlint": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "errorf": {
+ "description": "Check whether fmt.Errorf uses the %w verb for formatting errors",
+ "type": "boolean",
+ "default": true
+ },
+ "errorf-multi": {
+ "description": "Permit more than 1 %w verb, valid per Go 1.20",
+ "type": "boolean",
+ "default": true
+ },
+ "asserts": {
+ "description": "Check for plain type assertions and type switches.",
+ "type": "boolean",
+ "default": true
+ },
+ "comparison": {
+ "description": "Check for plain error comparisons",
+ "type": "boolean",
+ "default": true
+ },
+ "allowed-errors": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "err": {
+ "type": "string"
+ },
+ "fun": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "allowed-errors-wildcard": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "err": {
+ "type": "string"
+ },
+ "fun": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "exhaustive": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check": {
+ "description": "Program elements to check for exhaustiveness.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["switch", "map"]
+ }
+ },
+ "check-generated": {
+ "description": "Check switch statements in generated files",
+ "type": "boolean",
+ "default": false
+ },
+ "explicit-exhaustive-switch": {
+ "description": "Only run exhaustive check on switches with \"//exhaustive:enforce\" comment.",
+ "type": "boolean",
+ "default": false
+ },
+ "explicit-exhaustive-map": {
+ "description": "Only run exhaustive check on map literals with \"//exhaustive:enforce\" comment.",
+ "type": "boolean",
+ "default": false
+ },
+ "default-case-required": {
+ "description": "Switch statement requires default case even if exhaustive.",
+ "type": "boolean",
+ "default": false
+ },
+ "default-signifies-exhaustive": {
+ "description": "Presence of `default` case in switch statements satisfies exhaustiveness, even if all enum members are not listed.",
+ "type": "boolean",
+ "default": false
+ },
+ "ignore-enum-members": {
+ "description": "Enum members matching `regex` do not have to be listed in switch statements to satisfy exhaustiveness",
+ "type": "string"
+ },
+ "ignore-enum-types": {
+ "description": "Enum types matching the supplied regex do not have to be listed in switch statements to satisfy exhaustiveness.",
+ "type": "string"
+ },
+ "package-scope-only": {
+ "description": "Consider enums only in package scopes, not in inner scopes.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "exhaustruct": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "include": {
+ "description": "List of regular expressions to match struct packages and names.",
+ "type": "array",
+ "examples": [".*\\.Test"],
+ "items": {
+ "type": "string"
+ }
+ },
+ "exclude": {
+ "description": "List of regular expressions to exclude struct packages and names from check.",
+ "type": "array",
+ "examples": ["cobra\\.Command$"],
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "forbidigo": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "exclude-godoc-examples": {
+ "description": "Exclude code in godoc examples.",
+ "type": "boolean",
+ "default": true
+ },
+ "analyze-types": {
+ "description": "Instead of matching the literal source code, use type information to replace expressions with strings that contain the package name and (for methods and fields) the type name.",
+ "type": "boolean",
+ "default": true
+ },
+ "forbid": {
+ "description": "List of identifiers to forbid (written using `regexp`)",
+ "type": "array",
+ "examples": ["^print(ln)?$"],
+ "items": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "p": {
+ "description": "Pattern",
+ "type": "string"
+ },
+ "pkg": {
+ "description": "Package",
+ "type": "string"
+ },
+ "msg": {
+ "description": "Message",
+ "type": "string"
+ }
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ "funlen": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "lines": {
+ "description": "Limit lines number per function.",
+ "type": "integer",
+ "default": 60
+ },
+ "statements": {
+ "description": "Limit statements number per function.",
+ "type": "integer",
+ "default": 40
+ },
+ "ignore-comments": {
+ "description": "Ignore comments when counting lines.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "gci": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "sections": {
+ "description": "Section configuration to compare against.",
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "enum": [
+ "standard",
+ "default",
+ "blank",
+ "dot",
+ "alias",
+ "localmodule"
+ ]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ },
+ "default": ["standard", "default"]
+ },
+ "skip-generated": {
+ "description": "Skip generated files.",
+ "type": "boolean",
+ "default": true
+ },
+ "no-inline-comments": {
+ "description": "Checks that no inline Comments are present.",
+ "type": "boolean",
+ "default": false
+ },
+ "no-prefix-comments": {
+ "description": "Checks that no prefix Comments(comment lines above an import) are present.",
+ "type": "boolean",
+ "default": false
+ },
+ "custom-order": {
+ "description": "Enable custom order of sections.",
+ "type": "boolean",
+ "default": false
+ },
+ "no-lex-order": {
+ "description": "Drops lexical ordering for custom sections.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "ginkgolinter": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "suppress-len-assertion": {
+ "description": "Suppress the wrong length assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-nil-assertion": {
+ "description": "Suppress the wrong nil assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-err-assertion": {
+ "description": "Suppress the wrong error assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-compare-assertion": {
+ "description": "Suppress the wrong comparison assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-async-assertion": {
+ "description": "Suppress the function all in async assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-type-compare-assertion": {
+ "description": "Suppress warning for comparing values from different types, like int32 and uint32.",
+ "type": "boolean",
+ "default": false
+ },
+ "forbid-focus-container": {
+ "description": "Trigger warning for ginkgo focus containers like FDescribe, FContext, FWhen or FIt.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-havelen-zero": {
+ "description": "Don't trigger warnings for HaveLen(0).",
+ "type": "boolean",
+ "default": false
+ },
+ "force-expect-to": {
+ "description": "Force using `Expect` with `To`, `ToNot` or `NotTo`",
+ "type": "boolean",
+ "default": false
+ },
+ "validate-async-intervals": {
+ "description": "Best effort validation of async intervals (timeout and polling).",
+ "type": "boolean",
+ "default": false
+ },
+ "forbid-spec-pollution": {
+ "description": "Trigger a warning for variable assignments in ginkgo containers like `Describe`, `Context` and `When`, instead of in `BeforeEach()`.",
+ "type": "boolean",
+ "default": false
+ },
+ "force-succeed": {
+ "description": "Force using the Succeed matcher for error functions, and the HaveOccurred matcher for non-function error values.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "gochecksumtype": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "default-signifies-exhaustive": {
+ "description": "Presence of `default` case in switch statements satisfies exhaustiveness, if all members are not listed.",
+ "type": "boolean",
+ "default": true
+ },
+ "include-shared-interfaces": {
+ "description": "Include shared interfaces in the exhaustiviness check.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "gocognit": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "min-complexity": {
+ "description": "Minimal code complexity to report (we recommend 10-20).",
+ "type": "integer",
+ "default": 30
+ }
+ }
+ },
+ "goconst": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "match-constant": {
+ "description": "Look for existing constants matching the values",
+ "type": "boolean",
+ "default": true
+ },
+ "min-len": {
+ "description": "Minimum length of string constant.",
+ "type": "integer",
+ "default": 3
+ },
+ "min-occurrences": {
+ "description": "Minimum occurrences count to trigger.",
+ "type": "integer",
+ "default": 3
+ },
+ "ignore-tests": {
+ "description": "Ignore test files.",
+ "type": "boolean",
+ "default": false
+ },
+ "ignore-calls": {
+ "description": "Ignore when constant is not used as function argument",
+ "type": "boolean",
+ "default": true
+ },
+ "ignore-strings": {
+ "description": "Exclude strings matching the given regular expression",
+ "type": "string"
+ },
+ "numbers": {
+ "description": "Search also for duplicated numbers.",
+ "type": "boolean",
+ "default": false
+ },
+ "min": {
+ "description": "Minimum value, only works with `numbers`",
+ "type": "integer",
+ "default": 3
+ },
+ "max": {
+ "description": "Maximum value, only works with `numbers`",
+ "type": "integer",
+ "default": 3
+ }
+ }
+ },
+ "gocritic": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "enabled-checks": {
+ "description": "Which checks should be enabled. By default, a list of stable checks is used. To see it, run `GL_DEBUG=gocritic golangci-lint run`.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/gocritic-checks"
+ }
+ },
+ "disabled-checks": {
+ "description": "Which checks should be disabled.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/gocritic-checks"
+ },
+ "default": []
+ },
+ "enabled-tags": {
+ "description": "Enable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/gocritic-tags"
+ }
+ },
+ "disabled-tags": {
+ "description": "Disable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/gocritic-tags"
+ }
+ },
+ "settings": {
+ "description": "Settings passed to gocritic. Properties must be valid and enabled check names.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "captLocal": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "paramsOnly" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "commentedOutCode": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "minLength" : {
+ "type": "number",
+ "default": 15
+ }
+ }
+ },
+ "elseif": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skipBalanced" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "hugeParam": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "sizeThreshold" : {
+ "type": "number",
+ "default": 80
+ }
+ }
+ },
+ "ifElseChain": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "minThreshold" : {
+ "type": "number",
+ "default": 2
+ }
+ }
+ },
+ "nestingReduce": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "bodyWidth" : {
+ "type": "number",
+ "default": 5
+ }
+ }
+ },
+ "rangeExprCopy": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "sizeThreshold" : {
+ "type": "number",
+ "default": 512
+ },
+ "skipTestFuncs" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "rangeValCopy": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "sizeThreshold" : {
+ "type": "number",
+ "default": 128
+ },
+ "skipTestFuncs" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "ruleguard": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "debug" : {
+ "type": "string"
+ },
+ "enable" : {
+ "type": "string"
+ },
+ "disable" : {
+ "type": "string"
+ },
+ "failOn" : {
+ "type": "string"
+ },
+ "rules" : {
+ "type": "string"
+ }
+ }
+ },
+ "tooManyResultsChecker": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "maxResults" : {
+ "type": "number",
+ "default": 5
+ }
+ }
+ },
+ "truncateCmp": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skipArchDependent" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "underef": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skipRecvDeref" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "unnamedResult": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "checkExported" : {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ }
+ }
+ },
+ "disable-all": {
+ "type": "boolean",
+ "default": false
+ },
+ "enable-all": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "gocyclo": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "min-complexity": {
+ "description": "Minimum code complexity to report (we recommend 10-20).",
+ "type": "integer",
+ "default": 30
+ }
+ }
+ },
+ "godot": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "scope": {
+ "description": "Comments to be checked.",
+ "enum": ["declarations", "toplevel", "all"],
+ "default": "declarations"
+ },
+ "exclude": {
+ "description": "List of regexps for excluding particular comment lines from check.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "period": {
+ "description": "Check that each sentence ends with a period.",
+ "type": "boolean",
+ "default": true
+ },
+ "capital": {
+ "description": "Check that each sentence starts with a capital letter.",
+ "type": "boolean",
+ "default": false
+ },
+ "check-all": {
+ "description": "DEPRECATED: Check all top-level comments, not only declarations.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "godox": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "keywords": {
+ "description": "Report any comments starting with one of these keywords. This is useful for TODO or FIXME comments that might be left in the code accidentally and should be resolved before merging.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "default": ["TODO", "BUG", "FIXME"]
+ }
+ }
+ },
+ "gofmt": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "simplify": {
+ "description": "Simplify code.",
+ "type": "boolean",
+ "default": true
+ },
+ "rewrite-rules": {
+ "description": "Apply the rewrite rules to the source before reformatting.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "pattern": {
+ "type": "string"
+ },
+ "replacement": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "interfacebloat": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max": {
+ "description": "The maximum number of methods allowed for an interface.",
+ "type": "integer"
+ }
+ }
+ },
+ "gofumpt": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "extra-rules": {
+ "description": "Choose whether or not to use the extra rules that are disabled by default.",
+ "type": "boolean",
+ "default": false
+ },
+ "module-path": {
+ "description": " Module path which contains the source code being formatted.",
+ "type": "string"
+ }
+ }
+ },
+ "goheader": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "values": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "const": {
+ "description": "Constants to use in the template.",
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "description": "Value for the constant.",
+ "type": "string"
+ }
+ },
+ "additionalProperties": false,
+ "examples": [
+ {
+ "YEAR": "2030",
+ "COMPANY": "MY FUTURISTIC COMPANY"
+ }
+ ]
+ },
+ "regexp": {
+ "description": "Regular expressions to use in your template.",
+ "type": "object",
+ "additionalProperties": false,
+ "patternProperties": {
+ "^.+$": {
+ "type": "string"
+ }
+ },
+ "examples": [
+ {
+ "AUTHOR": ".*@mycompany\\.com"
+ }
+ ]
+ }
+ }
+ },
+ "template": {
+ "description": "Template to put on top of every file.",
+ "type": "string",
+ "examples": [
+ "{{ MY COMPANY }}\nSPDX-License-Identifier: Apache-2.0\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at:\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License."
+ ]
+ },
+ "template-path": {
+ "description": "Path to the file containing the template source.",
+ "type": "string",
+ "examples": ["my_header_template.txt"]
+ }
+ },
+ "oneOf": [
+ { "required": ["template"] },
+ { "required": ["template-path"] }
+ ]
+ },
+ "goimports": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "local-prefixes": {
+ "description": "Put imports beginning with prefix after 3rd-party packages. It is a comma-separated list of prefixes.",
+ "type": "string",
+ "examples": ["github.com/org/project"]
+ }
+ }
+ },
+ "gomoddirectives": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "replace-local": {
+ "description": "Allow local `replace` directives.",
+ "type": "boolean",
+ "default": true
+ },
+ "replace-allow-list": {
+ "description": "List of allowed `replace` directives.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "retract-allow-no-explanation": {
+ "description": "Allow to not explain why the version has been retracted in the `retract` directives.",
+ "type": "boolean",
+ "default": false
+ },
+ "exclude-forbidden": {
+ "description": "Forbid the use of the `exclude` directives.",
+ "type": "boolean",
+ "default": false
+ },
+ "toolchain-forbidden": {
+ "description": "Forbid the use of the `toolchain` directive.",
+ "type": "boolean",
+ "default": false
+ },
+ "toolchain-pattern": {
+ "description": "Defines a pattern to validate `toolchain` directive.",
+ "type": "string"
+ },
+ "tool-forbidden": {
+ "description": "Forbid the use of the `tool` directives.",
+ "type": "boolean",
+ "default": false
+ },
+ "go-debug-forbidden": {
+ "description": "Forbid the use of the `godebug` directive.",
+ "type": "boolean",
+ "default": false
+ },
+ "go-version-pattern": {
+ "description": "Defines a pattern to validate `go` minimum version directive.",
+ "type": "string",
+ "default": ""
+ }
+ }
+ },
+ "gomodguard": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "allowed": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "modules": {
+ "description": "List of allowed modules.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["gopkg.in/yaml.v2"]
+ }
+ },
+ "domains": {
+ "description": "List of allowed module domains.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["golang.org"]
+ }
+ }
+ }
+ },
+ "blocked": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "modules": {
+ "description": "List of blocked modules.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "recommendations": {
+ "description": "Recommended modules that should be used instead.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "reason": {
+ "description": "Reason why the recommended module should be used.",
+ "type": "string"
+ }
+ }
+ }
+ },
+ "additionalProperties": false
+ }
+ },
+ "versions": {
+ "description": "List of blocked module version constraints.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "patternProperties": {
+ "^.*$": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "version": {
+ "description": "Version constraint.",
+ "type": "string"
+ },
+ "reason": {
+ "description": "Reason why the version constraint exists.",
+ "type": "string"
+ }
+ },
+ "required": ["reason"]
+ }
+ }
+ }
+ },
+ "local_replace_directives": {
+ "description": "Raise lint issues if loading local path with replace directive",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ }
+ }
+ },
+ "gosimple": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "checks": {
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "enum": ["all"]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ }
+ }
+ }
+ },
+ "gosec": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "includes": {
+ "type": "array",
+ "description": "To select a subset of rules to run",
+ "examples": [["G401"]],
+ "items": {
+ "$ref": "#/definitions/gosec-rules"
+ }
+ },
+ "excludes": {
+ "type": "array",
+ "description": "To specify a set of rules to explicitly exclude",
+ "examples": [["G401"]],
+ "items": {
+ "$ref": "#/definitions/gosec-rules"
+ }
+ },
+ "exclude-generated": {
+ "description": "Exclude generated files",
+ "type": "boolean",
+ "default": false
+ },
+ "severity": {
+ "description": "Filter out the issues with a lower severity than the given value",
+ "type": "string",
+ "enum": ["low", "medium", "high"],
+ "default": "low"
+ },
+ "confidence": {
+ "description": "Filter out the issues with a lower confidence than the given value",
+ "type": "string",
+ "enum": ["low", "medium", "high"],
+ "default": "low"
+ },
+ "config": {
+ "description": "To specify the configuration of rules",
+ "type": "object"
+ },
+ "concurrency": {
+ "description": "Concurrency value",
+ "type": "integer"
+ }
+ }
+ },
+ "gosmopolitan": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "allow-time-local": {
+ "description": "Allow and ignore `time.Local` usages.",
+ "type": "boolean",
+ "default": false
+ },
+ "escape-hatches": {
+ "description": "List of fully qualified names in the `full/pkg/path.name` form, to act as \"i18n escape hatches\".",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignore-tests": {
+ "description": "Ignore test files.",
+ "type": "boolean",
+ "default": false
+ },
+ "watch-for-scripts": {
+ "description": "List of Unicode scripts to watch for any usage in string literals.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "govet": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "settings": {
+ "description": "Settings per analyzer. Map of analyzer name to specific settings.\nRun `go tool vet help` to find out more.",
+ "type": "object",
+ "propertyNames": {
+ "$ref": "#/definitions/govet-analyzers"
+ },
+ "patternProperties": {
+ "^.*$": {
+ "description": "Run `go tool vet help ` to see all settings.",
+ "type": "object"
+ }
+ }
+ },
+ "enable": {
+ "description": "Enable analyzers by name.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/govet-analyzers"
+ }
+ },
+ "disable": {
+ "description": "Disable analyzers by name.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/govet-analyzers"
+ }
+ },
+ "enable-all": {
+ "description": "Enable all analyzers.",
+ "type": "boolean",
+ "default": false
+ },
+ "disable-all": {
+ "description": "Disable all analyzers.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "grouper": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "const-require-single-const": {
+ "type": "boolean",
+ "default": false
+ },
+ "const-require-grouping": {
+ "type": "boolean",
+ "default": false
+ },
+ "import-require-single-import": {
+ "type": "boolean",
+ "default": false
+ },
+ "import-require-grouping": {
+ "type": "boolean",
+ "default": false
+ },
+ "type-require-single-type": {
+ "type": "boolean",
+ "default": false
+ },
+ "type-require-grouping": {
+ "type": "boolean",
+ "default": false
+ },
+ "var-require-single-var": {
+ "type": "boolean",
+ "default": false
+ },
+ "var-require-grouping": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "iface": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "enable": {
+ "description": "Enable analyzers by name.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/iface-analyzers"
+ }
+ },
+ "settings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "unused": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "exclude": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "importas": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "no-unaliased": {
+ "description": "Do not allow unaliased imports of aliased packages.",
+ "type": "boolean",
+ "default": false
+ },
+ "no-extra-aliases": {
+ "description": "Do not allow non-required aliases.",
+ "type": "boolean",
+ "default": false
+ },
+ "alias": {
+ "description": "List of aliases",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "pkg": {
+ "description": "Package path e.g. knative.dev/serving/pkg/apis/autoscaling/v1alpha1",
+ "type": "string"
+ },
+ "alias": {
+ "description": "Package alias e.g. autoscalingv1alpha1",
+ "type": "string"
+ }
+ },
+ "required": ["pkg", "alias"]
+ }
+ }
+ }
+ },
+ "inamedparam": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skip-single-param": {
+ "description": "Skips check for interface methods with only a single parameter.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "ireturn": {
+ "type": "object",
+ "additionalProperties": false,
+ "description": "Use either `reject` or `allow` properties for interfaces matching.",
+ "properties": {
+ "allow": {
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "enum": ["anon", "error", "empty", "stdlib"]
+ }
+ ]
+ }
+ },
+ "reject": {
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "enum": ["anon", "error", "empty", "stdlib"]
+ }
+ ]
+ }
+ }
+ },
+ "anyOf": [
+ {
+ "not": {
+ "properties": {
+ "allow": {
+ "const": "reject"
+ }
+ }
+ },
+ "required": ["allow"]
+ },
+ {
+ "required": ["reject"]
+ }
+ ]
+ },
+ "lll": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "tab-width": {
+ "description": "Width of \"\\t\" in spaces.",
+ "type": "integer",
+ "minimum": 0,
+ "default": 1
+ },
+ "line-length": {
+ "description": "Maximum allowed line length, lines longer will be reported.",
+ "type": "integer",
+ "minimum": 1,
+ "default": 120
+ }
+ }
+ },
+ "maintidx": {
+ "description": "Maintainability index https://docs.microsoft.com/en-us/visualstudio/code-quality/code-metrics-maintainability-index-range-and-meaning?view=vs-2022",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "under": {
+ "description": "Minimum accatpable maintainability index level (see https://docs.microsoft.com/en-us/visualstudio/code-quality/code-metrics-maintainability-index-range-and-meaning?view=vs-2022)",
+ "type": "number",
+ "default": 20
+ }
+ }
+ },
+ "makezero": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "always": {
+ "description": "Allow only slices initialized with a length of zero.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "loggercheck": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "kitlog": {
+ "description": "Allow check for the github.com/go-kit/log library.",
+ "type": "boolean",
+ "default": true
+ },
+ "klog": {
+ "description": "Allow check for the k8s.io/klog/v2 library.",
+ "type": "boolean",
+ "default": true
+ },
+ "logr": {
+ "description": "Allow check for the github.com/go-logr/logr library.",
+ "type": "boolean",
+ "default": true
+ },
+ "slog": {
+ "description": "Allow check for the log/slog library.",
+ "type": "boolean",
+ "default": true
+ },
+ "zap": {
+ "description": "Allow check for the \"sugar logger\" from go.uber.org/zap library.",
+ "type": "boolean",
+ "default": true
+ },
+ "require-string-key": {
+ "description": "Require all logging keys to be inlined constant strings.",
+ "type": "boolean",
+ "default": false
+ },
+ "no-printf-like": {
+ "description": "Require printf-like format specifier (%s, %d for example) not present.",
+ "type": "boolean",
+ "default": false
+ },
+ "rules": {
+ "description": "List of custom rules to check against, where each rule is a single logger pattern, useful for wrapped loggers.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "misspell": {
+ "description": "Correct spellings using locale preferences for US or UK. Default is to use a neutral variety of English.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "locale": {
+ "enum": ["US", "UK"]
+ },
+ "ignore-words": {
+ "description": "List of words to ignore.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "mode": {
+ "description": "Mode of the analysis.",
+ "enum": ["restricted", "", "default"],
+ "default": ""
+ },
+ "extra-words": {
+ "description": "Extra word corrections.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "correction": {
+ "type": "string"
+ },
+ "typo": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "musttag": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "functions": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "tag": {
+ "type": "string"
+ },
+ "arg-pos": {
+ "type": "integer"
+ }
+ }
+ }
+ }
+ }
+ },
+ "nakedret": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-func-lines": {
+ "description": "Report if a function has more lines of code than this value and it has naked returns.",
+ "type": "integer",
+ "minimum": 0,
+ "default": 30
+ }
+ }
+ },
+ "nestif": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "min-complexity": {
+ "description": "Minimum complexity of \"if\" statements to report.",
+ "type": "integer",
+ "default": 5
+ }
+ }
+ },
+ "nilnil": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "detect-opposite": {
+ "type": "boolean",
+ "description": "In addition, detect opposite situation (simultaneous return of non-nil error and valid value).",
+ "default": false
+ },
+ "checked-types": {
+ "type": "array",
+ "description": "List of return types to check.",
+ "items": {
+ "enum": ["chan", "func", "iface", "map", "ptr", "uintptr", "unsafeptr"]
+ },
+ "default": ["chan", "func", "iface", "map", "ptr", "uintptr", "unsafeptr"]
+ }
+ }
+ },
+ "nlreturn": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "block-size": {
+ "description": "set block size that is still ok",
+ "type": "number",
+ "default": 0,
+ "minimum": 0
+ }
+ }
+ },
+ "mnd": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignored-files": {
+ "description": "List of file patterns to exclude from analysis.",
+ "examples": [["magic1_.*.go"]],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignored-functions": {
+ "description": "Comma-separated list of function patterns to exclude from the analysis.",
+ "examples": [["math.*", "http.StatusText", "make"]],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignored-numbers": {
+ "description": "List of numbers to exclude from analysis.",
+ "examples": [["1000", "1234_567_890", "3.14159264"]],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "checks": {
+ "description": "The list of enabled checks, see https://github.com/tommy-muehle/go-mnd/#checks for description.",
+ "type": "array",
+ "items": {
+ "enum": [
+ "argument",
+ "case",
+ "condition",
+ "operation",
+ "return",
+ "assign"
+ ]
+ }
+ }
+ }
+ },
+ "nolintlint": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "allow-unused": {
+ "description": "Enable to ensure that nolint directives are all used.",
+ "type": "boolean",
+ "default": true
+ },
+ "allow-no-explanation": {
+ "description": "Exclude these linters from requiring an explanation.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linters"
+ },
+ "default": []
+ },
+ "require-explanation": {
+ "description": "Enable to require an explanation of nonzero length after each nolint directive.",
+ "type": "boolean",
+ "default": false
+ },
+ "require-specific": {
+ "description": "Enable to require nolint directives to mention the specific linter being suppressed.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "reassign": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "patterns": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "recvcheck": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "disable-builtin": {
+ "description": "Disables the built-in method exclusions.",
+ "type": "boolean",
+ "default": true
+ },
+ "exclusions": {
+ "description": "User-defined method exclusions.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "nonamedreturns": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "report-error-in-defer": {
+ "description": "Report named error if it is assigned inside defer.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "paralleltest": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignore-missing": {
+ "description": "Ignore missing calls to `t.Parallel()` and only report incorrect uses of it.",
+ "type": "boolean",
+ "default": false
+ },
+ "ignore-missing-subtests": {
+ "description": "Ignore missing calls to `t.Parallel()` in subtests. Top-level tests are still required to have `t.Parallel`, but subtests are allowed to skip it.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "perfsprint": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "int-conversion": {
+ "description": "Optimizes even if it requires an int or uint type cast.",
+ "type": "boolean",
+ "default": true
+ },
+ "err-error": {
+ "description": "Optimizes into `err.Error()` even if it is only equivalent for non-nil errors.",
+ "type": "boolean",
+ "default": false
+ },
+ "errorf": {
+ "description": "Optimizes `fmt.Errorf`.",
+ "type": "boolean",
+ "default": true
+ },
+ "sprintf1": {
+ "description": "Optimizes `fmt.Sprintf` with only one argument.",
+ "type": "boolean",
+ "default": true
+ },
+ "strconcat": {
+ "description": "Optimizes into strings concatenation.",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "prealloc": {
+ "description": "We do not recommend using this linter before doing performance profiling.\nFor most programs usage of `prealloc` will be premature optimization.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "simple": {
+ "description": "Report preallocation suggestions only on simple loops that have no returns/breaks/continues/gotos in them.",
+ "type": "boolean",
+ "default": true
+ },
+ "range-loops": {
+ "description": "Report preallocation suggestions on range loops.",
+ "type": "boolean",
+ "default": true
+ },
+ "for-loops": {
+ "description": "Report preallocation suggestions on for loops.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "predeclared": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignore": {
+ "description": "Comma-separated list of predeclared identifiers to not report on.",
+ "type": "string"
+ },
+ "q": {
+ "description": "Include method names and field names (i.e., qualified names) in checks.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "promlinter": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "strict": {},
+ "disabled-linters": {
+ "type": "array",
+ "items": {
+ "enum": [
+ "Help",
+ "MetricUnits",
+ "Counter",
+ "HistogramSummaryReserved",
+ "MetricTypeInName",
+ "ReservedChars",
+ "CamelCase",
+ "UnitAbbreviations"
+ ]
+ }
+ }
+ }
+ },
+ "protogetter": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skip-generated-by": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["protoc-gen-go-my-own-generator"]
+ }
+ },
+ "skip-files": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["*.pb.go"]
+ }
+ },
+ "skip-any-generated": {
+ "description": "Skip any generated files from the checking.",
+ "type": "boolean",
+ "default": false
+ },
+ "replace-first-arg-in-append": {
+ "description": "Skip first argument of append function.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "revive": {
+ "type": "object",
+ "additionalProperties": false,
+ "examples": [
+ {
+ "ignore-generated-header": true,
+ "severity": "warning",
+ "rules": [
+ {
+ "name": "indent-error-flow",
+ "severity": "warning"
+ },
+ {
+ "name": "add-constant",
+ "severity": "warning",
+ "arguments": [
+ {
+ "maxLitCount": "3",
+ "allowStrs": "\"\"",
+ "allowInts": "0,1,2",
+ "allowFloats": "0.0,0.,1.0,1.,2.0,2."
+ }
+ ]
+ }
+ ]
+ }
+ ],
+ "properties": {
+ "max-open-files": {
+ "type": "integer"
+ },
+ "ignore-generated-header": {
+ "type": "boolean"
+ },
+ "confidence": {
+ "type": "number"
+ },
+ "severity": {
+ "type": "string",
+ "enum": ["warning", "error"]
+ },
+ "enable-all-rules": {
+ "type": "boolean",
+ "default": false
+ },
+ "directives": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "name": {
+ "type": "string",
+ "enum": ["specify-disable-reason"]
+ },
+ "severity": {
+ "type": "string",
+ "enum": ["warning", "error"]
+ },
+ "exclude": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "arguments": {
+ "type": "array"
+ }
+ }
+ }
+ },
+ "rules": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["name"],
+ "properties": {
+ "name": {
+ "$ref": "#/definitions/revive-rules",
+ "title": "The rule name"
+ },
+ "disabled": {
+ "type": "boolean"
+ },
+ "severity": {
+ "type": "string",
+ "enum": ["warning", "error"]
+ },
+ "exclude": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "arguments": {
+ "type": "array"
+ }
+ }
+ }
+ }
+ }
+ },
+ "rowserrcheck": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "packages": {
+ "type": "array",
+ "items": {
+ "description": "",
+ "type": "string",
+ "examples": ["github.com/jmoiron/sqlx"]
+ }
+ }
+ }
+ },
+ "sloglint": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "kv-only": {
+ "description": "Enforce using key-value pairs only (incompatible with attr-only).",
+ "type": "boolean",
+ "default": false
+ },
+ "no-global": {
+ "description": "Enforce not using global loggers.",
+ "enum": ["", "all", "default"],
+ "default": ""
+ },
+ "no-mixed-args": {
+ "description": "Enforce not mixing key-value pairs and attributes.",
+ "type": "boolean",
+ "default": true
+ },
+ "context": {
+ "description": "Enforce using methods that accept a context.",
+ "enum": ["", "all", "scope"],
+ "default": ""
+ },
+ "static-msg": {
+ "description": "Enforce using static values for log messages.",
+ "type": "boolean",
+ "default": false
+ },
+ "key-naming-case": {
+ "description": "Enforce a single key naming convention.",
+ "enum": ["snake", "kebab", "camel", "pascal"]
+ },
+ "attr-only": {
+ "description": "Enforce using attributes only (incompatible with kv-only).",
+ "type": "boolean",
+ "default": false
+ },
+ "no-raw-keys": {
+ "description": "Enforce using constants instead of raw keys.",
+ "type": "boolean",
+ "default": false
+ },
+ "forbidden-keys": {
+ "description": "Enforce not using specific keys.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "args-on-sep-lines": {
+ "description": "Enforce putting arguments on separate lines.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "spancheck": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "checks": {
+ "description": "Checks to enable.",
+ "type": "array",
+ "items": {
+ "enum": ["end", "record-error", "set-status"]
+ }
+ },
+ "ignore-check-signatures": {
+ "description": "A list of regexes for function signatures that silence `record-error` and `set-status` reports if found in the call path to a returned error.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "extra-start-span-signatures": {
+ "description": "A list of regexes for additional function signatures that create spans.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "staticcheck": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "checks": {
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "enum": ["all"]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ }
+ }
+ }
+ },
+ "stylecheck": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "checks": {
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "enum": ["all"]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ },
+ "default": [
+ "all",
+ "-ST1000",
+ "-ST1003",
+ "-ST1016",
+ "-ST1020",
+ "-ST1021",
+ "-ST1022"
+ ]
+ },
+ "dot-import-whitelist": {
+ "description": "By default, ST1001 forbids all uses of dot imports in non-test packages. This setting allows setting a whitelist of import paths that can be dot-imported anywhere.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "http-status-code-whitelist": {
+ "description": "ST1013 recommends using constants from the net/http package instead of hard-coding numeric HTTP status codes. This setting specifies a list of numeric status codes that this check does not complain about.",
+ "default": ["200", "400", "404", "500"],
+ "type": "array",
+ "items": {
+ "enum": [
+ "100",
+ "101",
+ "102",
+ "103",
+ "200",
+ "201",
+ "202",
+ "203",
+ "204",
+ "205",
+ "206",
+ "207",
+ "208",
+ "226",
+ "300",
+ "301",
+ "302",
+ "303",
+ "304",
+ "305",
+ "306",
+ "307",
+ "308",
+ "400",
+ "401",
+ "402",
+ "403",
+ "404",
+ "405",
+ "406",
+ "407",
+ "408",
+ "409",
+ "410",
+ "411",
+ "412",
+ "413",
+ "414",
+ "415",
+ "416",
+ "417",
+ "418",
+ "421",
+ "422",
+ "423",
+ "424",
+ "425",
+ "426",
+ "428",
+ "429",
+ "431",
+ "451",
+ "500",
+ "501",
+ "502",
+ "503",
+ "504",
+ "505",
+ "506",
+ "507",
+ "508",
+ "510",
+ "511"
+ ]
+ }
+ },
+ "initialisms": {
+ "description": "ST1003 check, among other things, for the correct capitalization of initialisms. The set of known initialisms can be configured with this option.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "default": [
+ "ACL",
+ "API",
+ "ASCII",
+ "CPU",
+ "CSS",
+ "DNS",
+ "EOF",
+ "GUID",
+ "HTML",
+ "HTTP",
+ "HTTPS",
+ "ID",
+ "IP",
+ "JSON",
+ "QPS",
+ "RAM",
+ "RPC",
+ "SLA",
+ "SMTP",
+ "SQL",
+ "SSH",
+ "TCP",
+ "TLS",
+ "TTL",
+ "UDP",
+ "UI",
+ "GID",
+ "UID",
+ "UUID",
+ "URI",
+ "URL",
+ "UTF8",
+ "VM",
+ "XML",
+ "XMPP",
+ "XSRF",
+ "XSS",
+ "SIP",
+ "RTP",
+ "AMQP",
+ "DB",
+ "TS"
+ ]
+ }
+ }
+ }
+ },
+ "tagalign": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "align": {
+ "description": "Align and sort can be used together or separately.",
+ "type": "boolean",
+ "default": true
+ },
+ "sort": {
+ "description": "Whether enable tags sort.",
+ "type": "boolean",
+ "default": true
+ },
+ "order": {
+ "description": "Specify the order of tags, the other tags will be sorted by name.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "default": [],
+ "examples": [
+ [
+ "json",
+ "yaml",
+ "yml",
+ "toml",
+ "mapstructure",
+ "binding",
+ "validate"
+ ]
+ ]
+ },
+ "strict": {
+ "description": "Whether enable strict style.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "tagliatelle": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "case": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "use-field-name": {
+ "description": "Use the struct field name to check the name of the struct tag.",
+ "type": "boolean",
+ "default": false
+ },
+ "ignored-fields": {
+ "description": "The field names to ignore.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["example"]
+ }
+ },
+ "rules": {
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "$ref": "#/definitions/tagliatelle-cases"
+ }
+ }
+ },
+ "extended-rules": {
+ "description": "Defines the association between tag name and case.",
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["case"],
+ "properties": {
+ "case": {
+ "$ref": "#/definitions/tagliatelle-cases"
+ },
+ "extra-initialisms": {
+ "type": "boolean",
+ "default": false
+ },
+ "initialism-overrides": {
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "overrides": {
+ "description": "Overrides the default/root configuration.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["pkg"],
+ "properties": {
+ "pkg": {
+ "description": "A package path.",
+ "type": "string"
+ },
+ "use-field-name": {
+ "description": "Use the struct field name to check the name of the struct tag.",
+ "type": "boolean",
+ "default": false
+ },
+ "ignored-fields": {
+ "description": "The field names to ignore.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["example"]
+ }
+ },
+ "ignore": {
+ "description": "Ignore the package (takes precedence over all other configurations).",
+ "type": "boolean",
+ "default": false
+ },
+ "rules": {
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "$ref": "#/definitions/tagliatelle-cases"
+ }
+ }
+ },
+ "extended-rules": {
+ "description": "Defines the association between tag name and case.",
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["case"],
+ "properties": {
+ "case": {
+ "$ref": "#/definitions/tagliatelle-cases"
+ },
+ "extra-initialisms": {
+ "type": "boolean",
+ "default": false
+ },
+ "initialism-overrides": {
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "tenv": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "all": {
+ "description": "The option `all` will run against whole test files (`_test.go`) regardless of method/function signatures.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "testifylint": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "enable-all": {
+ "description": "Enable all checkers.",
+ "type": "boolean",
+ "default": false
+ },
+ "disable-all": {
+ "description": "Disable all checkers.",
+ "type": "boolean",
+ "default": false
+ },
+ "enable": {
+ "description": "Enable specific checkers.",
+ "type": "array",
+ "items": {
+ "enum": [
+ "blank-import",
+ "bool-compare",
+ "compares",
+ "contains",
+ "empty",
+ "encoded-compare",
+ "error-is-as",
+ "error-nil",
+ "expected-actual",
+ "float-compare",
+ "formatter",
+ "go-require",
+ "len",
+ "negative-positive",
+ "nil-compare",
+ "regexp",
+ "require-error",
+ "suite-broken-parallel",
+ "suite-dont-use-pkg",
+ "suite-extra-assert-call",
+ "suite-subtest-run",
+ "suite-thelper",
+ "useless-assert"
+ ]
+ },
+ "default": [
+ "blank-import",
+ "bool-compare",
+ "compares",
+ "contains",
+ "empty",
+ "encoded-compare",
+ "error-is-as",
+ "error-nil",
+ "expected-actual",
+ "float-compare",
+ "formatter",
+ "go-require",
+ "len",
+ "negative-positive",
+ "nil-compare",
+ "regexp",
+ "require-error",
+ "suite-broken-parallel",
+ "suite-dont-use-pkg",
+ "suite-extra-assert-call",
+ "suite-subtest-run",
+ "useless-assert"
+ ]
+ },
+ "disable": {
+ "description": "Disable specific checkers.",
+ "type": "array",
+ "items": {
+ "enum": [
+ "blank-import",
+ "bool-compare",
+ "compares",
+ "contains",
+ "empty",
+ "encoded-compare",
+ "error-is-as",
+ "error-nil",
+ "expected-actual",
+ "float-compare",
+ "formatter",
+ "go-require",
+ "len",
+ "negative-positive",
+ "nil-compare",
+ "regexp",
+ "require-error",
+ "suite-broken-parallel",
+ "suite-dont-use-pkg",
+ "suite-extra-assert-call",
+ "suite-subtest-run",
+ "suite-thelper",
+ "useless-assert"
+ ],
+ "default": [
+ "suite-thelper"
+ ]
+ }
+ },
+ "bool-compare": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignore-custom-types": {
+ "description": "To ignore user defined types (over builtin bool).",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "expected-actual": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "pattern": {
+ "description": "Regexp for expected variable name.",
+ "type": "string",
+ "default": "(^(exp(ected)?|want(ed)?)([A-Z]\\w*)?$)|(^(\\w*[a-z])?(Exp(ected)?|Want(ed)?)$)"
+ }
+ }
+ },
+ "formatter": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-format-string": {
+ "description": "To enable go vet's printf checks.",
+ "type": "boolean",
+ "default": true
+ },
+ "require-f-funcs": {
+ "description": "To require f-assertions (e.g. assert.Equalf) if format string is used, even if there are no variable-length variables.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "go-require": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignore-http-handlers": {
+ "description": "To ignore HTTP handlers (like http.HandlerFunc).",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "require-error": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "fn-pattern": {
+ "description": "Regexp for assertions to analyze. If defined, then only matched error assertions will be reported.",
+ "type": "string",
+ "default": ""
+ }
+ }
+ },
+ "suite-extra-assert-call": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "mode": {
+ "description": "To require or remove extra Assert() call?",
+ "type": "string",
+ "enum": ["remove", "require"],
+ "default": "remove"
+ }
+ }
+ }
+ }
+ },
+ "testpackage": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skip-regexp": {
+ "description": "Files with names matching this regular expression are skipped.",
+ "type": "string",
+ "examples": ["(export|internal)_test\\.go"]
+ },
+ "allow-packages": {
+ "description": "List of packages that don't end with _test that tests are allowed to be in.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["example"]
+ }
+ }
+ }
+ },
+ "thelper": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "test": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "begin": {
+ "description": "Check if `t.Helper()` begins helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "first": {
+ "description": "Check if *testing.T is first param of helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "name": {
+ "description": "Check if *testing.T param has t name.",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ },
+ "benchmark": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "begin": {
+ "description": "Check if `b.Helper()` begins helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "first": {
+ "description": "Check if *testing.B is first param of helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "name": {
+ "description": "Check if *testing.B param has b name.",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ },
+ "tb": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "begin": {
+ "description": "Check if `tb.Helper()` begins helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "first": {
+ "description": "Check if *testing.TB is first param of helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "name": {
+ "description": "Check if *testing.TB param has tb name.",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ },
+ "fuzz": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "begin": {
+ "description": "Check if `f.Helper()` begins helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "first": {
+ "description": "Check if *testing.F is first param of helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "name": {
+ "description": "Check if *testing.F param has f name.",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ }
+ }
+ },
+ "usestdlibvars": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "http-method": {
+ "description": "Suggest the use of http.MethodXX.",
+ "type": "boolean",
+ "default": true
+ },
+ "http-status-code": {
+ "description": "Suggest the use of http.StatusXX.",
+ "type": "boolean",
+ "default": true
+ },
+ "time-weekday": {
+ "description": "Suggest the use of time.Weekday.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "time-month": {
+ "description": "Suggest the use of time.Month.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "time-layout": {
+ "description": "Suggest the use of time.Layout.",
+ "type": "boolean",
+ "default": false
+ },
+ "crypto-hash": {
+ "description": "Suggest the use of crypto.Hash.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "default-rpc-path": {
+ "description": "Suggest the use of rpc.DefaultXXPath.",
+ "type": "boolean",
+ "default": false
+ },
+ "sql-isolation-level": {
+ "description": "Suggest the use of sql.LevelXX.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "tls-signature-scheme": {
+ "description": "Suggest the use of tls.SignatureScheme.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "constant-kind": {
+ "description": "Suggest the use of constant.Kind.String().",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "usetesting": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "context-background": {
+ "type": "boolean",
+ "default": true
+ },
+ "context-todo": {
+ "type": "boolean",
+ "default": true
+ },
+ "os-chdir": {
+ "type": "boolean",
+ "default": true
+ },
+ "os-mkdir-temp": {
+ "type": "boolean",
+ "default": true
+ },
+ "os-setenv": {
+ "type": "boolean",
+ "default": false
+ },
+ "os-create-temp": {
+ "type": "boolean",
+ "default": true
+ },
+ "os-temp-dir": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "unconvert": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "fast-math": {
+ "type": "boolean",
+ "default": false
+ },
+ "safe": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "unparam": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-exported": {
+ "description": "Inspect exported functions. Set to true if no external program/library imports your code.\n\nWARNING: if you enable this setting, unparam will report a lot of false-positives in text editors:\nif it's called for subdir of a project it can't find external interfaces. All text editor integrations\nwith golangci-lint call it on a directory with the changed file.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "unused": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "field-writes-are-uses": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ },
+ "post-statements-are-reads": {
+ "description": "",
+ "type": "boolean",
+ "default": false
+ },
+ "exported-fields-are-used": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ },
+ "parameters-are-used": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ },
+ "local-variables-are-used": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ },
+ "generated-is-used": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "varnamelen": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-distance": {
+ "description": "Variables used in at most this N-many lines will be ignored.",
+ "type": "integer",
+ "default": 5
+ },
+ "min-name-length": {
+ "description": "The minimum length of a variable's name that is considered `long`.",
+ "type": "integer",
+ "default": 3
+ },
+ "check-receiver": {
+ "description": "Check method receiver names.",
+ "default": false,
+ "type": "boolean"
+ },
+ "check-return": {
+ "description": "Check named return values.",
+ "default": false,
+ "type": "boolean"
+ },
+ "check-type-param": {
+ "description": "Check type parameters.",
+ "default": false,
+ "type": "boolean"
+ },
+ "ignore-type-assert-ok": {
+ "description": "Ignore `ok` variables that hold the bool return value of a type assertion",
+ "default": false,
+ "type": "boolean"
+ },
+ "ignore-map-index-ok": {
+ "description": "Ignore `ok` variables that hold the bool return value of a map index.",
+ "default": false,
+ "type": "boolean"
+ },
+ "ignore-chan-recv-ok": {
+ "description": "Ignore `ok` variables that hold the bool return value of a channel receive.",
+ "default": false,
+ "type": "boolean"
+ },
+ "ignore-names": {
+ "description": "Optional list of variable names that should be ignored completely.",
+ "default": [[]],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignore-decls": {
+ "description": "Optional list of variable declarations that should be ignored completely.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "examples": [
+ ["c echo.Context", "t testing.T", "f *foo.Bar", "const C"]
+ ]
+ }
+ }
+ },
+ "whitespace": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "multi-if": {
+ "description": "Enforces newlines (or comments) after every multi-line if statement",
+ "type": "boolean",
+ "default": false
+ },
+ "multi-func": {
+ "description": "Enforces newlines (or comments) after every multi-line function signature",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "wrapcheck": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "extra-ignore-sigs": {
+ "description": "An array of strings specifying additional substrings of signatures to ignore.",
+ "default": [
+ ".CustomError(",
+ ".SpecificWrap("
+ ],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignoreSigs": {
+ "description": "An array of strings which specify substrings of signatures to ignore.",
+ "default": [
+ ".Errorf(",
+ "errors.New(",
+ "errors.Unwrap(",
+ ".Wrap(",
+ ".Wrapf(",
+ ".WithMessage(",
+ ".WithMessagef(",
+ ".WithStack("
+ ],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignoreSigRegexps": {
+ "description": "An array of strings which specify regular expressions of signatures to ignore.",
+ "default": [""],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignorePackageGlobs": {
+ "description": "An array of glob patterns which, if any match the package of the function returning the error, will skip wrapcheck analysis for this error.",
+ "default": [""],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignoreInterfaceRegexps": {
+ "description": "An array of glob patterns which, if matched to an underlying interface name, will ignore unwrapped errors returned from a function whose call is defined on the given interface.",
+ "default": [""],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "wsl": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "allow-assign-and-anything": {
+ "description": "Controls if you may cuddle assignments and anything without needing an empty line between them.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-assign-and-call": {
+ "description": "Allow calls and assignments to be cuddled as long as the lines have any matching variables, fields or types.",
+ "type": "boolean",
+ "default": true
+ },
+ "allow-cuddle-declarations": {
+ "description": "Allow declarations (var) to be cuddled.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-cuddle-with-calls": {
+ "description": "A list of call idents that everything can be cuddled with.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "allow-cuddle-with-rhs": {
+ "description": "AllowCuddleWithRHS is a list of right hand side variables that is allowed to be cuddled with anything.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "allow-multiline-assign": {
+ "description": "Allow multiline assignments to be cuddled.",
+ "type": "boolean",
+ "default": true
+ },
+ "allow-separated-leading-comment": {
+ "description": "Allow leading comments to be separated with empty lines.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-trailing-comment": {
+ "description": "Allow trailing comments in ending of blocks.",
+ "type": "boolean",
+ "default": false
+ },
+ "error-variable-names": {
+ "description": "When force-err-cuddling is enabled this is a list of names used for error variables to check for in the conditional.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "force-case-trailing-whitespace": {
+ "description": "Force newlines in end of case at this limit (0 = never).",
+ "type": "integer",
+ "minimum": 0,
+ "default": 0
+ },
+ "force-err-cuddling": {
+ "description": "Causes an error when an If statement that checks an error variable doesn't cuddle with the assignment of that variable.",
+ "type": "boolean",
+ "default": false
+ },
+ "force-short-decl-cuddling": {
+ "description": "Causes an error if a short declaration (:=) cuddles with anything other than another short declaration.",
+ "type": "boolean",
+ "default": false
+ },
+ "strict-append": {
+ "description": "If true, append is only allowed to be cuddled if appending value is matching variables, fields or types on line above.",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "copyloopvar": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-alias": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "custom": {
+ "description": "The custom section can be used to define linter plugins to be loaded at runtime. See README of golangci-lint for more information.\nEach custom linter should have a unique name.",
+ "type": "object",
+ "patternProperties": {
+ "^.*$": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "type": {
+ "description": "The plugin type.",
+ "enum": ["module", "goplugin"],
+ "default": "goplugin"
+ },
+ "path": {
+ "description": "The path to the plugin *.so. Can be absolute or local.",
+ "type": "string",
+ "examples": ["/path/to/example.so"]
+ },
+ "description": {
+ "description": "The description of the linter, for documentation purposes only.",
+ "type": "string"
+ },
+ "original-url": {
+ "description": "Intended to point to the repo location of the linter, for documentation purposes only.",
+ "type": "string"
+ },
+ "settings": {
+ "description": "Plugins settings/configuration. Only work with plugin based on `linterdb.PluginConstructor`.",
+ "type": "object"
+ }
+ },
+ "oneOf": [
+ {
+ "properties": {
+ "type": {"enum": ["module"] }
+ },
+ "required": ["type"]
+ },
+ {
+ "required": ["path"]
+ }
+ ]
+ }
+ }
+ }
+ }
+ },
+ "linters": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "enable": {
+ "description": "List of enabled linters.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linters"
+ }
+ },
+ "disable": {
+ "description": "List of disabled linters.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linters"
+ }
+ },
+ "enable-all": {
+ "description": "Whether to enable all linters. You can re-disable them with `disable` explicitly.",
+ "type": "boolean",
+ "default": false
+ },
+ "disable-all": {
+ "description": "Whether to disable all linters. You can re-enable them with `enable` explicitly.",
+ "type": "boolean",
+ "default": false
+ },
+ "presets": {
+ "description": "Allow to use different presets of linters",
+ "type": "array",
+ "items": {
+ "enum": [
+ "bugs",
+ "comment",
+ "complexity",
+ "error",
+ "format",
+ "import",
+ "metalinter",
+ "module",
+ "performance",
+ "sql",
+ "style",
+ "test",
+ "unused"
+ ]
+ }
+ },
+ "fast": {
+ "description": "Enable run of fast linters.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "issues": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "exclude": {
+ "description": "List of regular expressions of issue texts to exclude.\nBut independently from this option we use default exclude patterns. Their usage can be controlled through `exclude-use-default`.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "exclude-rules": {
+ "description": "Exclude configuration per-path, per-linter, per-text and per-source",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "path": {
+ "type": "string"
+ },
+ "path-except": {
+ "type": "string"
+ },
+ "linters": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linters"
+ }
+ },
+ "text": {
+ "type": "string"
+ },
+ "source": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "exclude-use-default": {
+ "description": "Independently from option `exclude` we use default exclude patterns. This behavior can be disabled by this option.",
+ "type": "boolean",
+ "default": true
+ },
+ "exclude-case-sensitive": {
+ "description": "If set to true, exclude and exclude-rules regular expressions become case sensitive.",
+ "type": "boolean",
+ "default": false
+ },
+ "exclude-generated": {
+ "description": "Mode of the generated files analysis.",
+ "enum": ["lax", "strict", "disable"],
+ "default": "lax"
+ },
+ "exclude-dirs": {
+ "description": "Which directories to exclude: issues from them won't be reported.",
+ "type": "array",
+ "items": {
+ "description": "You can use regexp here. The regexp is applied on the full path.\n\"/\" will be replaced by current OS file path separator to properly work on Windows.",
+ "type": "string",
+ "examples": ["generated.*"]
+ },
+ "default": [],
+ "examples": [["src/external_libs", "autogenerated_by_my_lib"]]
+ },
+ "exclude-dirs-use-default": {
+ "description": "Enable exclusion of directories \"vendor\", \"third_party\", \"testdata\", \"examples\", \"Godeps\", and \"builtin\".",
+ "type": "boolean",
+ "default": true
+ },
+ "exclude-files": {
+ "description": "Which files to exclude: they will be analyzed, but issues from them will not be reported.",
+ "type": "array",
+ "items": {
+ "description": "You can use regexp here. There is no need to include all autogenerated files, we confidently recognize them. If that is not the case, please let us know.\n\"/\" will be replaced by current OS file path separator to properly work on Windows.",
+ "type": "string",
+ "examples": [".*\\.my\\.go$"]
+ },
+ "default": [],
+ "examples": [[".*\\.my\\.go$", "lib/bad.go"]]
+ },
+ "include": {
+ "description": "The list of ids of default excludes to include or disable.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "default": []
+ },
+ "max-issues-per-linter": {
+ "description": "Maximum issues count per one linter. Set to 0 to disable.",
+ "type": "integer",
+ "default": 50,
+ "minimum": 0
+ },
+ "max-same-issues": {
+ "description": "Maximum count of issues with the same text. Set to 0 to disable.",
+ "type": "integer",
+ "default": 3,
+ "minimum": 0
+ },
+ "new": {
+ "description": "Show only new issues: if there are unstaged changes or untracked files, only those changes are analyzed, else only changes in HEAD~ are analyzed.",
+ "type": "boolean",
+ "default": false
+ },
+ "new-from-rev": {
+ "description": "Show only new issues created after this git revision.",
+ "type": "string"
+ },
+ "new-from-patch": {
+ "description": "Show only new issues created in git patch with this file path.",
+ "type": "string",
+ "examples": ["path/to/patch/file"]
+ },
+ "fix": {
+ "description": "Fix found issues (if it's supported by the linter).",
+ "type": "boolean",
+ "default": false
+ },
+ "uniq-by-line": {
+ "description": "Make issues output unique by line.",
+ "type": "boolean",
+ "default": true
+ },
+ "whole-files": {
+ "description": "Show issues in any part of update files (requires new-from-rev or new-from-patch).",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "severity": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "default-severity": {
+ "description": "Set the default severity for issues. If severity rules are defined and the issues do not match or no severity is provided to the rule this will be the default severity applied. Severities should match the supported severity names of the selected out format.",
+ "type": "string",
+ "default": ""
+ },
+ "case-sensitive": {
+ "description": "If set to true, severity-rules regular expressions become case sensitive.",
+ "type": "boolean",
+ "default": false
+ },
+ "rules": {
+ "description": "When a list of severity rules are provided, severity information will be added to lint issues. Severity rules have the same filtering capability as exclude rules except you are allowed to specify one matcher per severity rule.\nOnly affects out formats that support setting severity information.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "severity": {
+ "type": "string"
+ },
+ "path": {
+ "type": "string"
+ },
+ "path-except": {
+ "type": "string"
+ },
+ "linters": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linters"
+ }
+ },
+ "text": {
+ "type": "string"
+ },
+ "source": {
+ "type": "string"
+ }
+ },
+ "required": ["severity"],
+ "anyOf": [
+ { "required": ["path"] },
+ { "required": ["path-except"] },
+ { "required": ["linters"] },
+ { "required": ["text"] },
+ { "required": ["source"] }
+ ]
+ },
+ "default": []
+ }
+ },
+ "required": ["default-severity"]
+ }
+ }
+}
diff --git a/vendor/github.com/golangci/golangci-lint/v2/jsonschema/golangci.v1.64.jsonschema.json b/vendor/github.com/golangci/golangci-lint/v2/jsonschema/golangci.v1.64.jsonschema.json
new file mode 100644
index 000000000..b265c1a82
--- /dev/null
+++ b/vendor/github.com/golangci/golangci-lint/v2/jsonschema/golangci.v1.64.jsonschema.json
@@ -0,0 +1,4224 @@
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "$id": "https://json.schemastore.org/golangci-lint.json",
+ "definitions": {
+ "gocritic-checks": {
+ "enum": [
+ "appendAssign",
+ "appendCombine",
+ "argOrder",
+ "assignOp",
+ "badCall",
+ "badCond",
+ "badLock",
+ "badRegexp",
+ "badSorting",
+ "badSyncOnceFunc",
+ "boolExprSimplify",
+ "builtinShadow",
+ "builtinShadowDecl",
+ "captLocal",
+ "caseOrder",
+ "codegenComment",
+ "commentFormatting",
+ "commentedOutCode",
+ "commentedOutImport",
+ "defaultCaseOrder",
+ "deferInLoop",
+ "deferUnlambda",
+ "deprecatedComment",
+ "docStub",
+ "dupArg",
+ "dupBranchBody",
+ "dupCase",
+ "dupImport",
+ "dupSubExpr",
+ "dynamicFmtString",
+ "elseif",
+ "emptyDecl",
+ "emptyFallthrough",
+ "emptyStringTest",
+ "equalFold",
+ "evalOrder",
+ "exitAfterDefer",
+ "exposedSyncMutex",
+ "externalErrorReassign",
+ "filepathJoin",
+ "flagDeref",
+ "flagName",
+ "hexLiteral",
+ "httpNoBody",
+ "hugeParam",
+ "ifElseChain",
+ "importShadow",
+ "indexAlloc",
+ "initClause",
+ "ioutilDeprecated",
+ "mapKey",
+ "methodExprCall",
+ "nestingReduce",
+ "newDeref",
+ "nilValReturn",
+ "octalLiteral",
+ "offBy1",
+ "paramTypeCombine",
+ "preferDecodeRune",
+ "preferFilepathJoin",
+ "preferFprint",
+ "preferStringWriter",
+ "preferWriteByte",
+ "ptrToRefParam",
+ "rangeAppendAll",
+ "rangeExprCopy",
+ "rangeValCopy",
+ "redundantSprint",
+ "regexpMust",
+ "regexpPattern",
+ "regexpSimplify",
+ "returnAfterHttpError",
+ "ruleguard",
+ "singleCaseSwitch",
+ "sliceClear",
+ "sloppyLen",
+ "sloppyReassign",
+ "sloppyTypeAssert",
+ "sortSlice",
+ "sprintfQuotedString",
+ "sqlQuery",
+ "stringConcatSimplify",
+ "stringXbytes",
+ "stringsCompare",
+ "switchTrue",
+ "syncMapLoadAndDelete",
+ "timeExprSimplify",
+ "todoCommentWithoutDetail",
+ "tooManyResultsChecker",
+ "truncateCmp",
+ "typeAssertChain",
+ "typeDefFirst",
+ "typeSwitchVar",
+ "typeUnparen",
+ "uncheckedInlineErr",
+ "underef",
+ "unlabelStmt",
+ "unlambda",
+ "unnamedResult",
+ "unnecessaryBlock",
+ "unnecessaryDefer",
+ "unslice",
+ "valSwap",
+ "weakCond",
+ "whyNoLint",
+ "wrapperFunc",
+ "yodaStyleExpr"
+ ]
+ },
+ "gocritic-tags": {
+ "enum": [
+ "diagnostic",
+ "style",
+ "performance",
+ "experimental",
+ "opinionated",
+ "security"
+ ]
+ },
+ "gosec-rules": {
+ "enum": [
+ "G101",
+ "G102",
+ "G103",
+ "G104",
+ "G106",
+ "G107",
+ "G108",
+ "G109",
+ "G110",
+ "G111",
+ "G112",
+ "G113",
+ "G114",
+ "G115",
+ "G201",
+ "G202",
+ "G203",
+ "G204",
+ "G301",
+ "G302",
+ "G303",
+ "G304",
+ "G305",
+ "G306",
+ "G307",
+ "G401",
+ "G402",
+ "G403",
+ "G404",
+ "G405",
+ "G406",
+ "G501",
+ "G502",
+ "G503",
+ "G504",
+ "G505",
+ "G506",
+ "G507",
+ "G601",
+ "G602"
+ ]
+ },
+ "govet-analyzers": {
+ "enum": [
+ "appends",
+ "asmdecl",
+ "assign",
+ "atomic",
+ "atomicalign",
+ "bools",
+ "buildtag",
+ "cgocall",
+ "composites",
+ "copylocks",
+ "deepequalerrors",
+ "defers",
+ "directive",
+ "errorsas",
+ "fieldalignment",
+ "findcall",
+ "framepointer",
+ "httpresponse",
+ "ifaceassert",
+ "loopclosure",
+ "lostcancel",
+ "nilfunc",
+ "nilness",
+ "printf",
+ "reflectvaluecompare",
+ "shadow",
+ "shift",
+ "sigchanyzer",
+ "slog",
+ "sortslice",
+ "stdmethods",
+ "stdversion",
+ "stringintconv",
+ "structtag",
+ "testinggoroutine",
+ "tests",
+ "timeformat",
+ "unmarshal",
+ "unreachable",
+ "unsafeptr",
+ "unusedresult",
+ "unusedwrite",
+ "waitgroup"
+ ]
+ },
+ "revive-rules": {
+ "enum": [
+ "add-constant",
+ "argument-limit",
+ "atomic",
+ "banned-characters",
+ "bare-return",
+ "blank-imports",
+ "bool-literal-in-expr",
+ "call-to-gc",
+ "cognitive-complexity",
+ "comment-spacings",
+ "comments-density",
+ "confusing-naming",
+ "confusing-results",
+ "constant-logical-expr",
+ "context-as-argument",
+ "context-keys-type",
+ "cyclomatic",
+ "datarace",
+ "deep-exit",
+ "defer",
+ "dot-imports",
+ "duplicated-imports",
+ "early-return",
+ "empty-block",
+ "empty-lines",
+ "enforce-map-style",
+ "enforce-repeated-arg-type-style",
+ "enforce-slice-style",
+ "error-naming",
+ "error-return",
+ "error-strings",
+ "errorf",
+ "exported",
+ "file-header",
+ "file-length-limit",
+ "filename-format",
+ "flag-parameter",
+ "function-length",
+ "function-result-limit",
+ "get-return",
+ "identical-branches",
+ "if-return",
+ "import-alias-naming",
+ "import-shadowing",
+ "imports-blocklist",
+ "increment-decrement",
+ "indent-error-flow",
+ "line-length-limit",
+ "max-control-nesting",
+ "max-public-structs",
+ "modifies-parameter",
+ "modifies-value-receiver",
+ "nested-structs",
+ "optimize-operands-order",
+ "package-comments",
+ "range-val-address",
+ "range-val-in-closure",
+ "range",
+ "receiver-naming",
+ "redefines-builtin-id",
+ "redundant-build-tag",
+ "redundant-import-alias",
+ "string-format",
+ "string-of-int",
+ "struct-tag",
+ "superfluous-else",
+ "time-equal",
+ "time-naming",
+ "unchecked-type-assertion",
+ "unconditional-recursion",
+ "unexported-naming",
+ "unexported-return",
+ "unhandled-error",
+ "unnecessary-stmt",
+ "unreachable-code",
+ "unused-parameter",
+ "unused-receiver",
+ "use-any",
+ "use-errors-new",
+ "useless-break",
+ "var-declaration",
+ "var-naming",
+ "waitgroup-by-value"
+ ]
+ },
+ "iface-analyzers": {
+ "enum": [
+ "identical",
+ "unused",
+ "opaque"
+ ]
+ },
+ "tagliatelle-cases": {
+ "enum": [
+ "",
+ "camel",
+ "pascal",
+ "kebab",
+ "snake",
+ "goCamel",
+ "goPascal",
+ "goKebab",
+ "goSnake",
+ "upper",
+ "upperSnake",
+ "lower",
+ "header"
+ ]
+ },
+ "linters": {
+ "$comment": "anyOf with enum is used to allow auto completion of non-custom linters",
+ "description": "Linters usable.",
+ "anyOf": [
+ {
+ "enum": [
+ "asasalint",
+ "asciicheck",
+ "bidichk",
+ "bodyclose",
+ "canonicalheader",
+ "containedctx",
+ "contextcheck",
+ "copyloopvar",
+ "cyclop",
+ "decorder",
+ "depguard",
+ "dogsled",
+ "dupl",
+ "dupword",
+ "durationcheck",
+ "errcheck",
+ "errchkjson",
+ "errname",
+ "errorlint",
+ "exhaustive",
+ "exhaustruct",
+ "exptostd",
+ "fatcontext",
+ "forbidigo",
+ "forcetypeassert",
+ "funlen",
+ "gci",
+ "ginkgolinter",
+ "gocheckcompilerdirectives",
+ "gochecknoglobals",
+ "gochecknoinits",
+ "gochecksumtype",
+ "gocognit",
+ "goconst",
+ "gocritic",
+ "gocyclo",
+ "godot",
+ "godox",
+ "err113",
+ "gofmt",
+ "gofumpt",
+ "goheader",
+ "goimports",
+ "gomoddirectives",
+ "gomodguard",
+ "goprintffuncname",
+ "gosec",
+ "gosimple",
+ "gosmopolitan",
+ "govet",
+ "grouper",
+ "iface",
+ "importas",
+ "inamedparam",
+ "ineffassign",
+ "interfacebloat",
+ "intrange",
+ "ireturn",
+ "lll",
+ "loggercheck",
+ "maintidx",
+ "makezero",
+ "mirror",
+ "misspell",
+ "mnd",
+ "musttag",
+ "nakedret",
+ "nestif",
+ "nilerr",
+ "nilnesserr",
+ "nilnil",
+ "nlreturn",
+ "noctx",
+ "nolintlint",
+ "nonamedreturns",
+ "nosprintfhostport",
+ "paralleltest",
+ "perfsprint",
+ "prealloc",
+ "predeclared",
+ "promlinter",
+ "protogetter",
+ "reassign",
+ "recvcheck",
+ "revive",
+ "rowserrcheck",
+ "sloglint",
+ "sqlclosecheck",
+ "staticcheck",
+ "stylecheck",
+ "tagalign",
+ "tagliatelle",
+ "tenv",
+ "testableexamples",
+ "testifylint",
+ "testpackage",
+ "thelper",
+ "tparallel",
+ "unconvert",
+ "unparam",
+ "unused",
+ "usestdlibvars",
+ "usetesting",
+ "varnamelen",
+ "wastedassign",
+ "whitespace",
+ "wrapcheck",
+ "wsl",
+ "zerologlint"
+ ]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ },
+ "relative-path-modes": {
+ "enum": [
+ "gomod",
+ "gitroot",
+ "cfg",
+ "wd"
+ ]
+ }
+ },
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "run": {
+ "description": "Options for analysis running,",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "concurrency": {
+ "description": "Number of concurrent runners. Defaults to the number of available CPU cores.",
+ "type": "integer",
+ "minimum": 0,
+ "examples": [4]
+ },
+ "timeout": {
+ "description": "Timeout for the analysis.",
+ "type": "string",
+ "pattern": "^((\\d+h)?(\\d+m)?(\\d+(?:\\.\\d)?s)?|0)$",
+ "default": "1m",
+ "examples": ["30s", "5m", "5m30s"]
+ },
+ "issues-exit-code": {
+ "description": "Exit code when at least one issue was found.",
+ "type": "integer",
+ "default": 1
+ },
+ "tests": {
+ "description": "Enable inclusion of test files.",
+ "type": "boolean",
+ "default": true
+ },
+ "build-tags": {
+ "description": "List of build tags to pass to all linters.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "default": [],
+ "examples": [["mytag"]]
+ },
+ "modules-download-mode": {
+ "description": "Option to pass to \"go list -mod={option}\".\nSee \"go help modules\" for more information.",
+ "enum": ["mod", "readonly", "vendor"]
+ },
+ "allow-parallel-runners": {
+ "description": "Allow multiple parallel golangci-lint instances running. If disabled, golangci-lint acquires file lock on start.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-serial-runners": {
+ "description": "Allow multiple golangci-lint instances running, but serialize them around a lock.",
+ "type": "boolean",
+ "default": false
+ },
+ "go": {
+ "description": "Targeted Go version.",
+ "type": "string",
+ "default": "1.17"
+ },
+ "relative-path-mode": {
+ "description": "The mode used to evaluate relative paths.",
+ "type": "string",
+ "$ref": "#/definitions/relative-path-modes",
+ "default": "wd"
+ }
+ }
+ },
+ "output": {
+ "description": "Output configuration options.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "formats": {
+ "description": "Output formats to use.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "path": {
+ "default": "stdout",
+ "anyOf": [
+ {
+ "enum": [ "stdout", "stderr" ]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ },
+ "format": {
+ "default": "colored-line-number",
+ "enum": [
+ "colored-line-number",
+ "line-number",
+ "json",
+ "colored-tab",
+ "tab",
+ "html",
+ "checkstyle",
+ "code-climate",
+ "junit-xml",
+ "junit-xml-extended",
+ "github-actions",
+ "teamcity",
+ "sarif"
+ ]
+ }
+ },
+ "required": ["format"]
+ }
+ },
+ "print-issued-lines": {
+ "description": "Print lines of code with issue.",
+ "type": "boolean",
+ "default": true
+ },
+ "print-linter-name": {
+ "description": "Print linter name in the end of issue text.",
+ "type": "boolean",
+ "default": true
+ },
+ "path-prefix": {
+ "description": "Add a prefix to the output file references.",
+ "type": "string",
+ "default": ""
+ },
+ "show-stats": {
+ "description": "Show statistics per linter.",
+ "type": "boolean",
+ "default": false
+ },
+ "sort-order": {
+ "type": "array",
+ "items": {
+ "enum": ["linter", "severity", "file"]
+ }
+ },
+ "sort-results": {
+ "description": "Sort results by: filepath, line and column.",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "linters-settings": {
+ "description": "All available settings of specific linters.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "dupword": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "keywords": {
+ "description": "Keywords for detecting duplicate words. If this list is not empty, only the words defined in this list will be detected.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["the", "and", "a"]
+ }
+ },
+ "ignore": {
+ "description": "Keywords used to ignore detection.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["0C0C"]
+ }
+ }
+ }
+ },
+ "asasalint": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "exclude": {
+ "description": "To specify a set of function names to exclude.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["\\.Wrapf"]
+ }
+ },
+ "use-builtin-exclusions": {
+ "description": "To enable/disable the asasalint builtin exclusions of function names.",
+ "type": "boolean",
+ "default": true
+ },
+ "ignore-test": {
+ "description": "Ignore *_test.go files.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "bidichk": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "left-to-right-embedding": {
+ "description": "Disallow: LEFT-TO-RIGHT-EMBEDDING",
+ "type": "boolean",
+ "default": false
+ },
+ "right-to-left-embedding": {
+ "description": "Disallow: RIGHT-TO-LEFT-EMBEDDING",
+ "type": "boolean",
+ "default": false
+ },
+ "pop-directional-formatting": {
+ "description": "Disallow: POP-DIRECTIONAL-FORMATTING",
+ "type": "boolean",
+ "default": false
+ },
+ "left-to-right-override": {
+ "description": "Disallow: LEFT-TO-RIGHT-OVERRIDE",
+ "type": "boolean",
+ "default": false
+ },
+ "right-to-left-override": {
+ "description": "Disallow: RIGHT-TO-LEFT-OVERRIDE",
+ "type": "boolean",
+ "default": false
+ },
+ "left-to-right-isolate": {
+ "description": "Disallow: LEFT-TO-RIGHT-ISOLATE",
+ "type": "boolean",
+ "default": false
+ },
+ "right-to-left-isolate": {
+ "description": "Disallow: RIGHT-TO-LEFT-ISOLATE",
+ "type": "boolean",
+ "default": false
+ },
+ "first-strong-isolate": {
+ "description": "Disallow: FIRST-STRONG-ISOLATE",
+ "type": "boolean",
+ "default": false
+ },
+ "pop-directional-isolate": {
+ "description": "Disallow: POP-DIRECTIONAL-ISOLATE",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "cyclop": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skip-tests": {
+ "description": "Should the linter execute on test files as well",
+ "type": "boolean",
+ "default": false
+ },
+ "max-complexity": {
+ "description": "Max complexity the function can have",
+ "type": "integer",
+ "default": 10,
+ "minimum": 0
+ },
+ "package-average": {
+ "description": "Max average complexity in package",
+ "type": "number",
+ "default": 0,
+ "minimum": 0
+ }
+ }
+ },
+ "decorder": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "dec-order": {
+ "type": "array",
+ "default": [["type", "const", "var", "func"]],
+ "items": {
+ "enum": ["type", "const", "var", "func"]
+ }
+ },
+ "ignore-underscore-vars": {
+ "description": "Underscore vars (vars with \"_\" as the name) will be ignored at all checks",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-dec-order-check": {
+ "description": "Order of declarations is not checked",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-init-func-first-check": {
+ "description": "Allow init func to be anywhere in file",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-dec-num-check": {
+ "description": "Multiple global type, const and var declarations are allowed",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-type-dec-num-check": {
+ "description": "Type declarations will be ignored for dec num check",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-const-dec-num-check": {
+ "description": "Const declarations will be ignored for dec num check",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-var-dec-num-check": {
+ "description": "Var declarations will be ignored for dec num check",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ },
+ "depguard": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "rules": {
+ "description": "Rules to apply.",
+ "type": "object",
+ "additionalProperties": false,
+ "patternProperties": {
+ "^[^.]+$": {
+ "description": "Name of a rule.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "list-mode": {
+ "description": "Used to determine the package matching priority.",
+ "enum": ["original", "strict", "lax"],
+ "default": "original"
+ },
+ "files": {
+ "description": "List of file globs that will match this list of settings to compare against.",
+ "additionalProperties": false,
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "allow": {
+ "description": "List of allowed packages.",
+ "additionalProperties": false,
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "deny": {
+ "description": "Packages that are not allowed where the value is a suggestion.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "desc": {
+ "description": "Description",
+ "type": "string"
+ },
+ "pkg": {
+ "description": "Package",
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "dogsled": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-blank-identifiers": {
+ "description": "Check assignments with too many blank identifiers.",
+ "type": "integer",
+ "default": 2,
+ "minimum": 0
+ }
+ }
+ },
+ "dupl": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "threshold": {
+ "description": "Tokens count to trigger issue.",
+ "type": "integer",
+ "default": 150,
+ "minimum": 0
+ }
+ }
+ },
+ "errcheck": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-type-assertions": {
+ "description": "Report about not checking errors in type assertions, i.e.: `a := b.(MyStruct)`",
+ "type": "boolean",
+ "default": false
+ },
+ "check-blank": {
+ "description": "Report about assignment of errors to blank identifier",
+ "type": "boolean",
+ "default": false
+ },
+ "exclude-functions": {
+ "description": "List of functions to exclude from checking, where each entry is a single function to exclude",
+ "type": "array",
+ "examples": ["io/ioutil.ReadFile", "io.Copy(*bytes.Buffer)"],
+ "items": {
+ "type": "string"
+ }
+ },
+ "disable-default-exclusions": {
+ "description": "To disable the errcheck built-in exclude list",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "errchkjson": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-error-free-encoding": {
+ "type": "boolean",
+ "default": false
+ },
+ "report-no-exported": {
+ "description": "Issue on struct that doesn't have exported fields.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "errorlint": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "errorf": {
+ "description": "Check whether fmt.Errorf uses the %w verb for formatting errors",
+ "type": "boolean",
+ "default": true
+ },
+ "errorf-multi": {
+ "description": "Permit more than 1 %w verb, valid per Go 1.20",
+ "type": "boolean",
+ "default": true
+ },
+ "asserts": {
+ "description": "Check for plain type assertions and type switches.",
+ "type": "boolean",
+ "default": true
+ },
+ "comparison": {
+ "description": "Check for plain error comparisons",
+ "type": "boolean",
+ "default": true
+ },
+ "allowed-errors": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "err": {
+ "type": "string"
+ },
+ "fun": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "allowed-errors-wildcard": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "err": {
+ "type": "string"
+ },
+ "fun": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "exhaustive": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check": {
+ "description": "Program elements to check for exhaustiveness.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["switch", "map"]
+ }
+ },
+ "check-generated": {
+ "description": "Check switch statements in generated files",
+ "type": "boolean",
+ "default": false
+ },
+ "explicit-exhaustive-switch": {
+ "description": "Only run exhaustive check on switches with \"//exhaustive:enforce\" comment.",
+ "type": "boolean",
+ "default": false
+ },
+ "explicit-exhaustive-map": {
+ "description": "Only run exhaustive check on map literals with \"//exhaustive:enforce\" comment.",
+ "type": "boolean",
+ "default": false
+ },
+ "default-case-required": {
+ "description": "Switch statement requires default case even if exhaustive.",
+ "type": "boolean",
+ "default": false
+ },
+ "default-signifies-exhaustive": {
+ "description": "Presence of `default` case in switch statements satisfies exhaustiveness, even if all enum members are not listed.",
+ "type": "boolean",
+ "default": false
+ },
+ "ignore-enum-members": {
+ "description": "Enum members matching `regex` do not have to be listed in switch statements to satisfy exhaustiveness",
+ "type": "string"
+ },
+ "ignore-enum-types": {
+ "description": "Enum types matching the supplied regex do not have to be listed in switch statements to satisfy exhaustiveness.",
+ "type": "string"
+ },
+ "package-scope-only": {
+ "description": "Consider enums only in package scopes, not in inner scopes.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "exhaustruct": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "include": {
+ "description": "List of regular expressions to match struct packages and names.",
+ "type": "array",
+ "examples": [".*\\.Test"],
+ "items": {
+ "type": "string"
+ }
+ },
+ "exclude": {
+ "description": "List of regular expressions to exclude struct packages and names from check.",
+ "type": "array",
+ "examples": ["cobra\\.Command$"],
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "fatcontext": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-struct-pointers": {
+ "description": "Check for potential fat contexts in struct pointers.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "forbidigo": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "exclude-godoc-examples": {
+ "description": "Exclude code in godoc examples.",
+ "type": "boolean",
+ "default": true
+ },
+ "analyze-types": {
+ "description": "Instead of matching the literal source code, use type information to replace expressions with strings that contain the package name and (for methods and fields) the type name.",
+ "type": "boolean",
+ "default": true
+ },
+ "forbid": {
+ "description": "List of identifiers to forbid (written using `regexp`)",
+ "type": "array",
+ "examples": ["^print(ln)?$"],
+ "items": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "p": {
+ "description": "Pattern",
+ "type": "string"
+ },
+ "pkg": {
+ "description": "Package",
+ "type": "string"
+ },
+ "msg": {
+ "description": "Message",
+ "type": "string"
+ }
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ "funlen": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "lines": {
+ "description": "Limit lines number per function.",
+ "type": "integer",
+ "default": 60
+ },
+ "statements": {
+ "description": "Limit statements number per function.",
+ "type": "integer",
+ "default": 40
+ },
+ "ignore-comments": {
+ "description": "Ignore comments when counting lines.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "gci": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "sections": {
+ "description": "Section configuration to compare against.",
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "enum": [
+ "standard",
+ "default",
+ "blank",
+ "dot",
+ "alias",
+ "localmodule"
+ ]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ },
+ "default": ["standard", "default"]
+ },
+ "skip-generated": {
+ "description": "Skip generated files.",
+ "type": "boolean",
+ "default": true
+ },
+ "no-inline-comments": {
+ "description": "Checks that no inline Comments are present.",
+ "type": "boolean",
+ "default": false
+ },
+ "no-prefix-comments": {
+ "description": "Checks that no prefix Comments(comment lines above an import) are present.",
+ "type": "boolean",
+ "default": false
+ },
+ "custom-order": {
+ "description": "Enable custom order of sections.",
+ "type": "boolean",
+ "default": false
+ },
+ "no-lex-order": {
+ "description": "Drops lexical ordering for custom sections.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "ginkgolinter": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "suppress-len-assertion": {
+ "description": "Suppress the wrong length assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-nil-assertion": {
+ "description": "Suppress the wrong nil assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-err-assertion": {
+ "description": "Suppress the wrong error assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-compare-assertion": {
+ "description": "Suppress the wrong comparison assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-async-assertion": {
+ "description": "Suppress the function all in async assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-type-compare-assertion": {
+ "description": "Suppress warning for comparing values from different types, like int32 and uint32.",
+ "type": "boolean",
+ "default": false
+ },
+ "forbid-focus-container": {
+ "description": "Trigger warning for ginkgo focus containers like FDescribe, FContext, FWhen or FIt.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-havelen-zero": {
+ "description": "Don't trigger warnings for HaveLen(0).",
+ "type": "boolean",
+ "default": false
+ },
+ "force-expect-to": {
+ "description": "Force using `Expect` with `To`, `ToNot` or `NotTo`",
+ "type": "boolean",
+ "default": false
+ },
+ "validate-async-intervals": {
+ "description": "Best effort validation of async intervals (timeout and polling).",
+ "type": "boolean",
+ "default": false
+ },
+ "forbid-spec-pollution": {
+ "description": "Trigger a warning for variable assignments in ginkgo containers like `Describe`, `Context` and `When`, instead of in `BeforeEach()`.",
+ "type": "boolean",
+ "default": false
+ },
+ "force-succeed": {
+ "description": "Force using the Succeed matcher for error functions, and the HaveOccurred matcher for non-function error values.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "gochecksumtype": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "default-signifies-exhaustive": {
+ "description": "Presence of `default` case in switch statements satisfies exhaustiveness, if all members are not listed.",
+ "type": "boolean",
+ "default": true
+ },
+ "include-shared-interfaces": {
+ "description": "Include shared interfaces in the exhaustiviness check.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "gocognit": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "min-complexity": {
+ "description": "Minimal code complexity to report (we recommend 10-20).",
+ "type": "integer",
+ "default": 30
+ }
+ }
+ },
+ "goconst": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "match-constant": {
+ "description": "Look for existing constants matching the values",
+ "type": "boolean",
+ "default": true
+ },
+ "min-len": {
+ "description": "Minimum length of string constant.",
+ "type": "integer",
+ "default": 3
+ },
+ "min-occurrences": {
+ "description": "Minimum occurrences count to trigger.",
+ "type": "integer",
+ "default": 3
+ },
+ "ignore-tests": {
+ "description": "Ignore test files.",
+ "type": "boolean",
+ "default": false
+ },
+ "ignore-calls": {
+ "description": "Ignore when constant is not used as function argument",
+ "type": "boolean",
+ "default": true
+ },
+ "ignore-strings": {
+ "description": "Exclude strings matching the given regular expression",
+ "type": "string"
+ },
+ "numbers": {
+ "description": "Search also for duplicated numbers.",
+ "type": "boolean",
+ "default": false
+ },
+ "min": {
+ "description": "Minimum value, only works with `numbers`",
+ "type": "integer",
+ "default": 3
+ },
+ "max": {
+ "description": "Maximum value, only works with `numbers`",
+ "type": "integer",
+ "default": 3
+ }
+ }
+ },
+ "gocritic": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "enabled-checks": {
+ "description": "Which checks should be enabled. By default, a list of stable checks is used. To see it, run `GL_DEBUG=gocritic golangci-lint run`.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/gocritic-checks"
+ }
+ },
+ "disabled-checks": {
+ "description": "Which checks should be disabled.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/gocritic-checks"
+ },
+ "default": []
+ },
+ "enabled-tags": {
+ "description": "Enable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/gocritic-tags"
+ }
+ },
+ "disabled-tags": {
+ "description": "Disable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/gocritic-tags"
+ }
+ },
+ "settings": {
+ "description": "Settings passed to gocritic. Properties must be valid and enabled check names.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "captLocal": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "paramsOnly" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "commentedOutCode": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "minLength" : {
+ "type": "number",
+ "default": 15
+ }
+ }
+ },
+ "elseif": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skipBalanced" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "hugeParam": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "sizeThreshold" : {
+ "type": "number",
+ "default": 80
+ }
+ }
+ },
+ "ifElseChain": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "minThreshold" : {
+ "type": "number",
+ "default": 2
+ }
+ }
+ },
+ "nestingReduce": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "bodyWidth" : {
+ "type": "number",
+ "default": 5
+ }
+ }
+ },
+ "rangeExprCopy": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "sizeThreshold" : {
+ "type": "number",
+ "default": 512
+ },
+ "skipTestFuncs" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "rangeValCopy": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "sizeThreshold" : {
+ "type": "number",
+ "default": 128
+ },
+ "skipTestFuncs" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "ruleguard": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "debug" : {
+ "type": "string"
+ },
+ "enable" : {
+ "type": "string"
+ },
+ "disable" : {
+ "type": "string"
+ },
+ "failOn" : {
+ "type": "string"
+ },
+ "rules" : {
+ "type": "string"
+ }
+ }
+ },
+ "tooManyResultsChecker": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "maxResults" : {
+ "type": "number",
+ "default": 5
+ }
+ }
+ },
+ "truncateCmp": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skipArchDependent" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "underef": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skipRecvDeref" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "unnamedResult": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "checkExported" : {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ }
+ }
+ },
+ "disable-all": {
+ "type": "boolean",
+ "default": false
+ },
+ "enable-all": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "gocyclo": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "min-complexity": {
+ "description": "Minimum code complexity to report (we recommend 10-20).",
+ "type": "integer",
+ "default": 30
+ }
+ }
+ },
+ "godot": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "scope": {
+ "description": "Comments to be checked.",
+ "enum": ["declarations", "toplevel", "all"],
+ "default": "declarations"
+ },
+ "exclude": {
+ "description": "List of regexps for excluding particular comment lines from check.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "period": {
+ "description": "Check that each sentence ends with a period.",
+ "type": "boolean",
+ "default": true
+ },
+ "capital": {
+ "description": "Check that each sentence starts with a capital letter.",
+ "type": "boolean",
+ "default": false
+ },
+ "check-all": {
+ "description": "DEPRECATED: Check all top-level comments, not only declarations.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "godox": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "keywords": {
+ "description": "Report any comments starting with one of these keywords. This is useful for TODO or FIXME comments that might be left in the code accidentally and should be resolved before merging.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "default": ["TODO", "BUG", "FIXME"]
+ }
+ }
+ },
+ "gofmt": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "simplify": {
+ "description": "Simplify code.",
+ "type": "boolean",
+ "default": true
+ },
+ "rewrite-rules": {
+ "description": "Apply the rewrite rules to the source before reformatting.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "pattern": {
+ "type": "string"
+ },
+ "replacement": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "interfacebloat": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max": {
+ "description": "The maximum number of methods allowed for an interface.",
+ "type": "integer"
+ }
+ }
+ },
+ "gofumpt": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "extra-rules": {
+ "description": "Choose whether or not to use the extra rules that are disabled by default.",
+ "type": "boolean",
+ "default": false
+ },
+ "module-path": {
+ "description": " Module path which contains the source code being formatted.",
+ "type": "string"
+ }
+ }
+ },
+ "goheader": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "values": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "const": {
+ "description": "Constants to use in the template.",
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "description": "Value for the constant.",
+ "type": "string"
+ }
+ },
+ "additionalProperties": false,
+ "examples": [
+ {
+ "YEAR": "2030",
+ "COMPANY": "MY FUTURISTIC COMPANY"
+ }
+ ]
+ },
+ "regexp": {
+ "description": "Regular expressions to use in your template.",
+ "type": "object",
+ "additionalProperties": false,
+ "patternProperties": {
+ "^.+$": {
+ "type": "string"
+ }
+ },
+ "examples": [
+ {
+ "AUTHOR": ".*@mycompany\\.com"
+ }
+ ]
+ }
+ }
+ },
+ "template": {
+ "description": "Template to put on top of every file.",
+ "type": "string",
+ "examples": [
+ "{{ MY COMPANY }}\nSPDX-License-Identifier: Apache-2.0\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at:\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License."
+ ]
+ },
+ "template-path": {
+ "description": "Path to the file containing the template source.",
+ "type": "string",
+ "examples": ["my_header_template.txt"]
+ }
+ },
+ "oneOf": [
+ { "required": ["template"] },
+ { "required": ["template-path"] }
+ ]
+ },
+ "goimports": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "local-prefixes": {
+ "description": "Put imports beginning with prefix after 3rd-party packages. It is a comma-separated list of prefixes.",
+ "type": "string",
+ "examples": ["github.com/org/project"]
+ }
+ }
+ },
+ "gomoddirectives": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "replace-local": {
+ "description": "Allow local `replace` directives.",
+ "type": "boolean",
+ "default": true
+ },
+ "replace-allow-list": {
+ "description": "List of allowed `replace` directives.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "retract-allow-no-explanation": {
+ "description": "Allow to not explain why the version has been retracted in the `retract` directives.",
+ "type": "boolean",
+ "default": false
+ },
+ "exclude-forbidden": {
+ "description": "Forbid the use of the `exclude` directives.",
+ "type": "boolean",
+ "default": false
+ },
+ "toolchain-forbidden": {
+ "description": "Forbid the use of the `toolchain` directive.",
+ "type": "boolean",
+ "default": false
+ },
+ "toolchain-pattern": {
+ "description": "Defines a pattern to validate `toolchain` directive.",
+ "type": "string"
+ },
+ "tool-forbidden": {
+ "description": "Forbid the use of the `tool` directives.",
+ "type": "boolean",
+ "default": false
+ },
+ "go-debug-forbidden": {
+ "description": "Forbid the use of the `godebug` directive.",
+ "type": "boolean",
+ "default": false
+ },
+ "go-version-pattern": {
+ "description": "Defines a pattern to validate `go` minimum version directive.",
+ "type": "string",
+ "default": ""
+ }
+ }
+ },
+ "gomodguard": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "allowed": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "modules": {
+ "description": "List of allowed modules.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["gopkg.in/yaml.v2"]
+ }
+ },
+ "domains": {
+ "description": "List of allowed module domains.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["golang.org"]
+ }
+ }
+ }
+ },
+ "blocked": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "modules": {
+ "description": "List of blocked modules.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "recommendations": {
+ "description": "Recommended modules that should be used instead.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "reason": {
+ "description": "Reason why the recommended module should be used.",
+ "type": "string"
+ }
+ }
+ }
+ },
+ "additionalProperties": false
+ }
+ },
+ "versions": {
+ "description": "List of blocked module version constraints.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "patternProperties": {
+ "^.*$": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "version": {
+ "description": "Version constraint.",
+ "type": "string"
+ },
+ "reason": {
+ "description": "Reason why the version constraint exists.",
+ "type": "string"
+ }
+ },
+ "required": ["reason"]
+ }
+ }
+ }
+ },
+ "local_replace_directives": {
+ "description": "Raise lint issues if loading local path with replace directive",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ }
+ }
+ },
+ "gosimple": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "checks": {
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "enum": ["all"]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ }
+ }
+ }
+ },
+ "gosec": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "includes": {
+ "type": "array",
+ "description": "To select a subset of rules to run",
+ "examples": [["G401"]],
+ "items": {
+ "$ref": "#/definitions/gosec-rules"
+ }
+ },
+ "excludes": {
+ "type": "array",
+ "description": "To specify a set of rules to explicitly exclude",
+ "examples": [["G401"]],
+ "items": {
+ "$ref": "#/definitions/gosec-rules"
+ }
+ },
+ "exclude-generated": {
+ "description": "Exclude generated files",
+ "type": "boolean",
+ "default": false
+ },
+ "severity": {
+ "description": "Filter out the issues with a lower severity than the given value",
+ "type": "string",
+ "enum": ["low", "medium", "high"],
+ "default": "low"
+ },
+ "confidence": {
+ "description": "Filter out the issues with a lower confidence than the given value",
+ "type": "string",
+ "enum": ["low", "medium", "high"],
+ "default": "low"
+ },
+ "config": {
+ "description": "To specify the configuration of rules",
+ "type": "object"
+ },
+ "concurrency": {
+ "description": "Concurrency value",
+ "type": "integer"
+ }
+ }
+ },
+ "gosmopolitan": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "allow-time-local": {
+ "description": "Allow and ignore `time.Local` usages.",
+ "type": "boolean",
+ "default": false
+ },
+ "escape-hatches": {
+ "description": "List of fully qualified names in the `full/pkg/path.name` form, to act as \"i18n escape hatches\".",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignore-tests": {
+ "description": "Ignore test files.",
+ "type": "boolean",
+ "default": false
+ },
+ "watch-for-scripts": {
+ "description": "List of Unicode scripts to watch for any usage in string literals.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "govet": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "settings": {
+ "description": "Settings per analyzer. Map of analyzer name to specific settings.\nRun `go tool vet help` to find out more.",
+ "type": "object",
+ "propertyNames": {
+ "$ref": "#/definitions/govet-analyzers"
+ },
+ "patternProperties": {
+ "^.*$": {
+ "description": "Run `go tool vet help ` to see all settings.",
+ "type": "object"
+ }
+ }
+ },
+ "enable": {
+ "description": "Enable analyzers by name.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/govet-analyzers"
+ }
+ },
+ "disable": {
+ "description": "Disable analyzers by name.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/govet-analyzers"
+ }
+ },
+ "enable-all": {
+ "description": "Enable all analyzers.",
+ "type": "boolean",
+ "default": false
+ },
+ "disable-all": {
+ "description": "Disable all analyzers.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "grouper": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "const-require-single-const": {
+ "type": "boolean",
+ "default": false
+ },
+ "const-require-grouping": {
+ "type": "boolean",
+ "default": false
+ },
+ "import-require-single-import": {
+ "type": "boolean",
+ "default": false
+ },
+ "import-require-grouping": {
+ "type": "boolean",
+ "default": false
+ },
+ "type-require-single-type": {
+ "type": "boolean",
+ "default": false
+ },
+ "type-require-grouping": {
+ "type": "boolean",
+ "default": false
+ },
+ "var-require-single-var": {
+ "type": "boolean",
+ "default": false
+ },
+ "var-require-grouping": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "iface": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "enable": {
+ "description": "Enable analyzers by name.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/iface-analyzers"
+ }
+ },
+ "settings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "unused": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "exclude": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "importas": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "no-unaliased": {
+ "description": "Do not allow unaliased imports of aliased packages.",
+ "type": "boolean",
+ "default": false
+ },
+ "no-extra-aliases": {
+ "description": "Do not allow non-required aliases.",
+ "type": "boolean",
+ "default": false
+ },
+ "alias": {
+ "description": "List of aliases",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "pkg": {
+ "description": "Package path e.g. knative.dev/serving/pkg/apis/autoscaling/v1alpha1",
+ "type": "string"
+ },
+ "alias": {
+ "description": "Package alias e.g. autoscalingv1alpha1",
+ "type": "string"
+ }
+ },
+ "required": ["pkg", "alias"]
+ }
+ }
+ }
+ },
+ "inamedparam": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skip-single-param": {
+ "description": "Skips check for interface methods with only a single parameter.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "ireturn": {
+ "type": "object",
+ "additionalProperties": false,
+ "description": "Use either `reject` or `allow` properties for interfaces matching.",
+ "properties": {
+ "allow": {
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "enum": ["anon", "error", "empty", "stdlib"]
+ }
+ ]
+ }
+ },
+ "reject": {
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "enum": ["anon", "error", "empty", "stdlib"]
+ }
+ ]
+ }
+ }
+ },
+ "anyOf": [
+ {
+ "not": {
+ "properties": {
+ "allow": {
+ "const": "reject"
+ }
+ }
+ },
+ "required": ["allow"]
+ },
+ {
+ "required": ["reject"]
+ }
+ ]
+ },
+ "lll": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "tab-width": {
+ "description": "Width of \"\\t\" in spaces.",
+ "type": "integer",
+ "minimum": 0,
+ "default": 1
+ },
+ "line-length": {
+ "description": "Maximum allowed line length, lines longer will be reported.",
+ "type": "integer",
+ "minimum": 1,
+ "default": 120
+ }
+ }
+ },
+ "maintidx": {
+ "description": "Maintainability index https://docs.microsoft.com/en-us/visualstudio/code-quality/code-metrics-maintainability-index-range-and-meaning?view=vs-2022",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "under": {
+ "description": "Minimum accatpable maintainability index level (see https://docs.microsoft.com/en-us/visualstudio/code-quality/code-metrics-maintainability-index-range-and-meaning?view=vs-2022)",
+ "type": "number",
+ "default": 20
+ }
+ }
+ },
+ "makezero": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "always": {
+ "description": "Allow only slices initialized with a length of zero.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "loggercheck": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "kitlog": {
+ "description": "Allow check for the github.com/go-kit/log library.",
+ "type": "boolean",
+ "default": true
+ },
+ "klog": {
+ "description": "Allow check for the k8s.io/klog/v2 library.",
+ "type": "boolean",
+ "default": true
+ },
+ "logr": {
+ "description": "Allow check for the github.com/go-logr/logr library.",
+ "type": "boolean",
+ "default": true
+ },
+ "slog": {
+ "description": "Allow check for the log/slog library.",
+ "type": "boolean",
+ "default": true
+ },
+ "zap": {
+ "description": "Allow check for the \"sugar logger\" from go.uber.org/zap library.",
+ "type": "boolean",
+ "default": true
+ },
+ "require-string-key": {
+ "description": "Require all logging keys to be inlined constant strings.",
+ "type": "boolean",
+ "default": false
+ },
+ "no-printf-like": {
+ "description": "Require printf-like format specifier (%s, %d for example) not present.",
+ "type": "boolean",
+ "default": false
+ },
+ "rules": {
+ "description": "List of custom rules to check against, where each rule is a single logger pattern, useful for wrapped loggers.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "misspell": {
+ "description": "Correct spellings using locale preferences for US or UK. Default is to use a neutral variety of English.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "locale": {
+ "enum": ["US", "UK"]
+ },
+ "ignore-words": {
+ "description": "List of words to ignore.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "mode": {
+ "description": "Mode of the analysis.",
+ "enum": ["restricted", "", "default"],
+ "default": ""
+ },
+ "extra-words": {
+ "description": "Extra word corrections.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "correction": {
+ "type": "string"
+ },
+ "typo": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "musttag": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "functions": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "tag": {
+ "type": "string"
+ },
+ "arg-pos": {
+ "type": "integer"
+ }
+ }
+ }
+ }
+ }
+ },
+ "nakedret": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-func-lines": {
+ "description": "Report if a function has more lines of code than this value and it has naked returns.",
+ "type": "integer",
+ "minimum": 0,
+ "default": 30
+ }
+ }
+ },
+ "nestif": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "min-complexity": {
+ "description": "Minimum complexity of \"if\" statements to report.",
+ "type": "integer",
+ "default": 5
+ }
+ }
+ },
+ "nilnil": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "detect-opposite": {
+ "type": "boolean",
+ "description": "In addition, detect opposite situation (simultaneous return of non-nil error and valid value).",
+ "default": false
+ },
+ "checked-types": {
+ "type": "array",
+ "description": "List of return types to check.",
+ "items": {
+ "enum": ["chan", "func", "iface", "map", "ptr", "uintptr", "unsafeptr"]
+ },
+ "default": ["chan", "func", "iface", "map", "ptr", "uintptr", "unsafeptr"]
+ }
+ }
+ },
+ "nlreturn": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "block-size": {
+ "description": "set block size that is still ok",
+ "type": "number",
+ "default": 0,
+ "minimum": 0
+ }
+ }
+ },
+ "mnd": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignored-files": {
+ "description": "List of file patterns to exclude from analysis.",
+ "examples": [["magic1_.*.go"]],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignored-functions": {
+ "description": "Comma-separated list of function patterns to exclude from the analysis.",
+ "examples": [["math.*", "http.StatusText", "make"]],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignored-numbers": {
+ "description": "List of numbers to exclude from analysis.",
+ "examples": [["1000", "1234_567_890", "3.14159264"]],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "checks": {
+ "description": "The list of enabled checks, see https://github.com/tommy-muehle/go-mnd/#checks for description.",
+ "type": "array",
+ "items": {
+ "enum": [
+ "argument",
+ "case",
+ "condition",
+ "operation",
+ "return",
+ "assign"
+ ]
+ }
+ }
+ }
+ },
+ "nolintlint": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "allow-unused": {
+ "description": "Enable to ensure that nolint directives are all used.",
+ "type": "boolean",
+ "default": true
+ },
+ "allow-no-explanation": {
+ "description": "Exclude these linters from requiring an explanation.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linters"
+ },
+ "default": []
+ },
+ "require-explanation": {
+ "description": "Enable to require an explanation of nonzero length after each nolint directive.",
+ "type": "boolean",
+ "default": false
+ },
+ "require-specific": {
+ "description": "Enable to require nolint directives to mention the specific linter being suppressed.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "reassign": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "patterns": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "recvcheck": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "disable-builtin": {
+ "description": "Disables the built-in method exclusions.",
+ "type": "boolean",
+ "default": true
+ },
+ "exclusions": {
+ "description": "User-defined method exclusions.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "nonamedreturns": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "report-error-in-defer": {
+ "description": "Report named error if it is assigned inside defer.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "paralleltest": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignore-missing": {
+ "description": "Ignore missing calls to `t.Parallel()` and only report incorrect uses of it.",
+ "type": "boolean",
+ "default": false
+ },
+ "ignore-missing-subtests": {
+ "description": "Ignore missing calls to `t.Parallel()` in subtests. Top-level tests are still required to have `t.Parallel`, but subtests are allowed to skip it.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "perfsprint": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "integer-format": {
+ "description": "Enable/disable optimization of integer formatting.",
+ "type": "boolean",
+ "default": true
+ },
+ "int-conversion": {
+ "description": "Optimizes even if it requires an int or uint type cast.",
+ "type": "boolean",
+ "default": true
+ },
+ "error-format": {
+ "description": "Enable/disable optimization of error formatting.",
+ "type": "boolean",
+ "default": true
+ },
+ "err-error": {
+ "description": "Optimizes into `err.Error()` even if it is only equivalent for non-nil errors.",
+ "type": "boolean",
+ "default": false
+ },
+ "errorf": {
+ "description": "Optimizes `fmt.Errorf`.",
+ "type": "boolean",
+ "default": true
+ },
+ "string-format": {
+ "description": "Enable/disable optimization of string formatting.",
+ "type": "boolean",
+ "default": true
+ },
+ "sprintf1": {
+ "description": "Optimizes `fmt.Sprintf` with only one argument.",
+ "type": "boolean",
+ "default": true
+ },
+ "strconcat": {
+ "description": "Optimizes into strings concatenation.",
+ "type": "boolean",
+ "default": true
+ },
+ "bool-format": {
+ "description": "Enable/disable optimization of bool formatting.",
+ "type": "boolean",
+ "default": true
+ },
+ "hex-format": {
+ "description": "Enable/disable optimization of hex formatting.",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "prealloc": {
+ "description": "We do not recommend using this linter before doing performance profiling.\nFor most programs usage of `prealloc` will be premature optimization.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "simple": {
+ "description": "Report preallocation suggestions only on simple loops that have no returns/breaks/continues/gotos in them.",
+ "type": "boolean",
+ "default": true
+ },
+ "range-loops": {
+ "description": "Report preallocation suggestions on range loops.",
+ "type": "boolean",
+ "default": true
+ },
+ "for-loops": {
+ "description": "Report preallocation suggestions on for loops.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "predeclared": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignore": {
+ "description": "Comma-separated list of predeclared identifiers to not report on.",
+ "type": "string"
+ },
+ "q": {
+ "description": "Include method names and field names (i.e., qualified names) in checks.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "promlinter": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "strict": {},
+ "disabled-linters": {
+ "type": "array",
+ "items": {
+ "enum": [
+ "Help",
+ "MetricUnits",
+ "Counter",
+ "HistogramSummaryReserved",
+ "MetricTypeInName",
+ "ReservedChars",
+ "CamelCase",
+ "UnitAbbreviations"
+ ]
+ }
+ }
+ }
+ },
+ "protogetter": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skip-generated-by": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["protoc-gen-go-my-own-generator"]
+ }
+ },
+ "skip-files": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["*.pb.go"]
+ }
+ },
+ "skip-any-generated": {
+ "description": "Skip any generated files from the checking.",
+ "type": "boolean",
+ "default": false
+ },
+ "replace-first-arg-in-append": {
+ "description": "Skip first argument of append function.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "revive": {
+ "type": "object",
+ "additionalProperties": false,
+ "examples": [
+ {
+ "ignore-generated-header": true,
+ "severity": "warning",
+ "rules": [
+ {
+ "name": "indent-error-flow",
+ "severity": "warning"
+ },
+ {
+ "name": "add-constant",
+ "severity": "warning",
+ "arguments": [
+ {
+ "maxLitCount": "3",
+ "allowStrs": "\"\"",
+ "allowInts": "0,1,2",
+ "allowFloats": "0.0,0.,1.0,1.,2.0,2."
+ }
+ ]
+ }
+ ]
+ }
+ ],
+ "properties": {
+ "max-open-files": {
+ "type": "integer"
+ },
+ "ignore-generated-header": {
+ "type": "boolean"
+ },
+ "confidence": {
+ "type": "number"
+ },
+ "severity": {
+ "type": "string",
+ "enum": ["warning", "error"]
+ },
+ "enable-all-rules": {
+ "type": "boolean",
+ "default": false
+ },
+ "directives": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "name": {
+ "type": "string",
+ "enum": ["specify-disable-reason"]
+ },
+ "severity": {
+ "type": "string",
+ "enum": ["warning", "error"]
+ },
+ "exclude": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "arguments": {
+ "type": "array"
+ }
+ }
+ }
+ },
+ "rules": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["name"],
+ "properties": {
+ "name": {
+ "$ref": "#/definitions/revive-rules",
+ "title": "The rule name"
+ },
+ "disabled": {
+ "type": "boolean"
+ },
+ "severity": {
+ "type": "string",
+ "enum": ["warning", "error"]
+ },
+ "exclude": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "arguments": {
+ "type": "array"
+ }
+ }
+ }
+ }
+ }
+ },
+ "rowserrcheck": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "packages": {
+ "type": "array",
+ "items": {
+ "description": "",
+ "type": "string",
+ "examples": ["github.com/jmoiron/sqlx"]
+ }
+ }
+ }
+ },
+ "sloglint": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "kv-only": {
+ "description": "Enforce using key-value pairs only (incompatible with attr-only).",
+ "type": "boolean",
+ "default": false
+ },
+ "no-global": {
+ "description": "Enforce not using global loggers.",
+ "enum": ["", "all", "default"],
+ "default": ""
+ },
+ "no-mixed-args": {
+ "description": "Enforce not mixing key-value pairs and attributes.",
+ "type": "boolean",
+ "default": true
+ },
+ "context": {
+ "description": "Enforce using methods that accept a context.",
+ "enum": ["", "all", "scope"],
+ "default": ""
+ },
+ "static-msg": {
+ "description": "Enforce using static values for log messages.",
+ "type": "boolean",
+ "default": false
+ },
+ "key-naming-case": {
+ "description": "Enforce a single key naming convention.",
+ "enum": ["snake", "kebab", "camel", "pascal"]
+ },
+ "attr-only": {
+ "description": "Enforce using attributes only (incompatible with kv-only).",
+ "type": "boolean",
+ "default": false
+ },
+ "no-raw-keys": {
+ "description": "Enforce using constants instead of raw keys.",
+ "type": "boolean",
+ "default": false
+ },
+ "forbidden-keys": {
+ "description": "Enforce not using specific keys.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "args-on-sep-lines": {
+ "description": "Enforce putting arguments on separate lines.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "spancheck": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "checks": {
+ "description": "Checks to enable.",
+ "type": "array",
+ "items": {
+ "enum": ["end", "record-error", "set-status"]
+ }
+ },
+ "ignore-check-signatures": {
+ "description": "A list of regexes for function signatures that silence `record-error` and `set-status` reports if found in the call path to a returned error.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "extra-start-span-signatures": {
+ "description": "A list of regexes for additional function signatures that create spans.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "staticcheck": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "checks": {
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "enum": ["all"]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ }
+ }
+ }
+ },
+ "stylecheck": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "checks": {
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "enum": ["all"]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ },
+ "default": [
+ "all",
+ "-ST1000",
+ "-ST1003",
+ "-ST1016",
+ "-ST1020",
+ "-ST1021",
+ "-ST1022"
+ ]
+ },
+ "dot-import-whitelist": {
+ "description": "By default, ST1001 forbids all uses of dot imports in non-test packages. This setting allows setting a whitelist of import paths that can be dot-imported anywhere.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "http-status-code-whitelist": {
+ "description": "ST1013 recommends using constants from the net/http package instead of hard-coding numeric HTTP status codes. This setting specifies a list of numeric status codes that this check does not complain about.",
+ "default": ["200", "400", "404", "500"],
+ "type": "array",
+ "items": {
+ "enum": [
+ "100",
+ "101",
+ "102",
+ "103",
+ "200",
+ "201",
+ "202",
+ "203",
+ "204",
+ "205",
+ "206",
+ "207",
+ "208",
+ "226",
+ "300",
+ "301",
+ "302",
+ "303",
+ "304",
+ "305",
+ "306",
+ "307",
+ "308",
+ "400",
+ "401",
+ "402",
+ "403",
+ "404",
+ "405",
+ "406",
+ "407",
+ "408",
+ "409",
+ "410",
+ "411",
+ "412",
+ "413",
+ "414",
+ "415",
+ "416",
+ "417",
+ "418",
+ "421",
+ "422",
+ "423",
+ "424",
+ "425",
+ "426",
+ "428",
+ "429",
+ "431",
+ "451",
+ "500",
+ "501",
+ "502",
+ "503",
+ "504",
+ "505",
+ "506",
+ "507",
+ "508",
+ "510",
+ "511"
+ ]
+ }
+ },
+ "initialisms": {
+ "description": "ST1003 check, among other things, for the correct capitalization of initialisms. The set of known initialisms can be configured with this option.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "default": [
+ "ACL",
+ "API",
+ "ASCII",
+ "CPU",
+ "CSS",
+ "DNS",
+ "EOF",
+ "GUID",
+ "HTML",
+ "HTTP",
+ "HTTPS",
+ "ID",
+ "IP",
+ "JSON",
+ "QPS",
+ "RAM",
+ "RPC",
+ "SLA",
+ "SMTP",
+ "SQL",
+ "SSH",
+ "TCP",
+ "TLS",
+ "TTL",
+ "UDP",
+ "UI",
+ "GID",
+ "UID",
+ "UUID",
+ "URI",
+ "URL",
+ "UTF8",
+ "VM",
+ "XML",
+ "XMPP",
+ "XSRF",
+ "XSS",
+ "SIP",
+ "RTP",
+ "AMQP",
+ "DB",
+ "TS"
+ ]
+ }
+ }
+ }
+ },
+ "tagalign": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "align": {
+ "description": "Align and sort can be used together or separately.",
+ "type": "boolean",
+ "default": true
+ },
+ "sort": {
+ "description": "Whether enable tags sort.",
+ "type": "boolean",
+ "default": true
+ },
+ "order": {
+ "description": "Specify the order of tags, the other tags will be sorted by name.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "default": [],
+ "examples": [
+ [
+ "json",
+ "yaml",
+ "yml",
+ "toml",
+ "mapstructure",
+ "binding",
+ "validate"
+ ]
+ ]
+ },
+ "strict": {
+ "description": "Whether enable strict style.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "tagliatelle": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "case": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "use-field-name": {
+ "description": "Use the struct field name to check the name of the struct tag.",
+ "type": "boolean",
+ "default": false
+ },
+ "ignored-fields": {
+ "description": "The field names to ignore.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["example"]
+ }
+ },
+ "rules": {
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "$ref": "#/definitions/tagliatelle-cases"
+ }
+ }
+ },
+ "extended-rules": {
+ "description": "Defines the association between tag name and case.",
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["case"],
+ "properties": {
+ "case": {
+ "$ref": "#/definitions/tagliatelle-cases"
+ },
+ "extra-initialisms": {
+ "type": "boolean",
+ "default": false
+ },
+ "initialism-overrides": {
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "overrides": {
+ "description": "Overrides the default/root configuration.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["pkg"],
+ "properties": {
+ "pkg": {
+ "description": "A package path.",
+ "type": "string"
+ },
+ "use-field-name": {
+ "description": "Use the struct field name to check the name of the struct tag.",
+ "type": "boolean",
+ "default": false
+ },
+ "ignored-fields": {
+ "description": "The field names to ignore.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["example"]
+ }
+ },
+ "ignore": {
+ "description": "Ignore the package (takes precedence over all other configurations).",
+ "type": "boolean",
+ "default": false
+ },
+ "rules": {
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "$ref": "#/definitions/tagliatelle-cases"
+ }
+ }
+ },
+ "extended-rules": {
+ "description": "Defines the association between tag name and case.",
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["case"],
+ "properties": {
+ "case": {
+ "$ref": "#/definitions/tagliatelle-cases"
+ },
+ "extra-initialisms": {
+ "type": "boolean",
+ "default": false
+ },
+ "initialism-overrides": {
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "tenv": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "all": {
+ "description": "The option `all` will run against whole test files (`_test.go`) regardless of method/function signatures.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "testifylint": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "enable-all": {
+ "description": "Enable all checkers.",
+ "type": "boolean",
+ "default": false
+ },
+ "disable-all": {
+ "description": "Disable all checkers.",
+ "type": "boolean",
+ "default": false
+ },
+ "enable": {
+ "description": "Enable specific checkers.",
+ "type": "array",
+ "items": {
+ "enum": [
+ "blank-import",
+ "bool-compare",
+ "compares",
+ "contains",
+ "empty",
+ "encoded-compare",
+ "error-is-as",
+ "error-nil",
+ "expected-actual",
+ "float-compare",
+ "formatter",
+ "go-require",
+ "len",
+ "negative-positive",
+ "nil-compare",
+ "regexp",
+ "require-error",
+ "suite-broken-parallel",
+ "suite-dont-use-pkg",
+ "suite-extra-assert-call",
+ "suite-subtest-run",
+ "suite-thelper",
+ "useless-assert"
+ ]
+ },
+ "default": [
+ "blank-import",
+ "bool-compare",
+ "compares",
+ "contains",
+ "empty",
+ "encoded-compare",
+ "error-is-as",
+ "error-nil",
+ "expected-actual",
+ "float-compare",
+ "formatter",
+ "go-require",
+ "len",
+ "negative-positive",
+ "nil-compare",
+ "regexp",
+ "require-error",
+ "suite-broken-parallel",
+ "suite-dont-use-pkg",
+ "suite-extra-assert-call",
+ "suite-subtest-run",
+ "useless-assert"
+ ]
+ },
+ "disable": {
+ "description": "Disable specific checkers.",
+ "type": "array",
+ "items": {
+ "enum": [
+ "blank-import",
+ "bool-compare",
+ "compares",
+ "contains",
+ "empty",
+ "encoded-compare",
+ "error-is-as",
+ "error-nil",
+ "expected-actual",
+ "float-compare",
+ "formatter",
+ "go-require",
+ "len",
+ "negative-positive",
+ "nil-compare",
+ "regexp",
+ "require-error",
+ "suite-broken-parallel",
+ "suite-dont-use-pkg",
+ "suite-extra-assert-call",
+ "suite-subtest-run",
+ "suite-thelper",
+ "useless-assert"
+ ],
+ "default": [
+ "suite-thelper"
+ ]
+ }
+ },
+ "bool-compare": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignore-custom-types": {
+ "description": "To ignore user defined types (over builtin bool).",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "expected-actual": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "pattern": {
+ "description": "Regexp for expected variable name.",
+ "type": "string",
+ "default": "(^(exp(ected)?|want(ed)?)([A-Z]\\w*)?$)|(^(\\w*[a-z])?(Exp(ected)?|Want(ed)?)$)"
+ }
+ }
+ },
+ "formatter": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-format-string": {
+ "description": "To enable go vet's printf checks.",
+ "type": "boolean",
+ "default": true
+ },
+ "require-f-funcs": {
+ "description": "To require f-assertions (e.g. assert.Equalf) if format string is used, even if there are no variable-length variables.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "go-require": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignore-http-handlers": {
+ "description": "To ignore HTTP handlers (like http.HandlerFunc).",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "require-error": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "fn-pattern": {
+ "description": "Regexp for assertions to analyze. If defined, then only matched error assertions will be reported.",
+ "type": "string",
+ "default": ""
+ }
+ }
+ },
+ "suite-extra-assert-call": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "mode": {
+ "description": "To require or remove extra Assert() call?",
+ "type": "string",
+ "enum": ["remove", "require"],
+ "default": "remove"
+ }
+ }
+ }
+ }
+ },
+ "testpackage": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skip-regexp": {
+ "description": "Files with names matching this regular expression are skipped.",
+ "type": "string",
+ "examples": ["(export|internal)_test\\.go"]
+ },
+ "allow-packages": {
+ "description": "List of packages that don't end with _test that tests are allowed to be in.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["example"]
+ }
+ }
+ }
+ },
+ "thelper": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "test": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "begin": {
+ "description": "Check if `t.Helper()` begins helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "first": {
+ "description": "Check if *testing.T is first param of helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "name": {
+ "description": "Check if *testing.T param has t name.",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ },
+ "benchmark": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "begin": {
+ "description": "Check if `b.Helper()` begins helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "first": {
+ "description": "Check if *testing.B is first param of helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "name": {
+ "description": "Check if *testing.B param has b name.",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ },
+ "tb": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "begin": {
+ "description": "Check if `tb.Helper()` begins helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "first": {
+ "description": "Check if *testing.TB is first param of helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "name": {
+ "description": "Check if *testing.TB param has tb name.",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ },
+ "fuzz": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "begin": {
+ "description": "Check if `f.Helper()` begins helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "first": {
+ "description": "Check if *testing.F is first param of helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "name": {
+ "description": "Check if *testing.F param has f name.",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ }
+ }
+ },
+ "usestdlibvars": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "http-method": {
+ "description": "Suggest the use of http.MethodXX.",
+ "type": "boolean",
+ "default": true
+ },
+ "http-status-code": {
+ "description": "Suggest the use of http.StatusXX.",
+ "type": "boolean",
+ "default": true
+ },
+ "time-weekday": {
+ "description": "Suggest the use of time.Weekday.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "time-month": {
+ "description": "Suggest the use of time.Month.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "time-layout": {
+ "description": "Suggest the use of time.Layout.",
+ "type": "boolean",
+ "default": false
+ },
+ "crypto-hash": {
+ "description": "Suggest the use of crypto.Hash.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "default-rpc-path": {
+ "description": "Suggest the use of rpc.DefaultXXPath.",
+ "type": "boolean",
+ "default": false
+ },
+ "sql-isolation-level": {
+ "description": "Suggest the use of sql.LevelXX.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "tls-signature-scheme": {
+ "description": "Suggest the use of tls.SignatureScheme.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "constant-kind": {
+ "description": "Suggest the use of constant.Kind.String().",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "usetesting": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "context-background": {
+ "type": "boolean",
+ "default": true
+ },
+ "context-todo": {
+ "type": "boolean",
+ "default": true
+ },
+ "os-chdir": {
+ "type": "boolean",
+ "default": true
+ },
+ "os-mkdir-temp": {
+ "type": "boolean",
+ "default": true
+ },
+ "os-setenv": {
+ "type": "boolean",
+ "default": true
+ },
+ "os-create-temp": {
+ "type": "boolean",
+ "default": true
+ },
+ "os-temp-dir": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "unconvert": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "fast-math": {
+ "type": "boolean",
+ "default": false
+ },
+ "safe": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "unparam": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-exported": {
+ "description": "Inspect exported functions. Set to true if no external program/library imports your code.\n\nWARNING: if you enable this setting, unparam will report a lot of false-positives in text editors:\nif it's called for subdir of a project it can't find external interfaces. All text editor integrations\nwith golangci-lint call it on a directory with the changed file.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "unused": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "field-writes-are-uses": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ },
+ "post-statements-are-reads": {
+ "description": "",
+ "type": "boolean",
+ "default": false
+ },
+ "exported-fields-are-used": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ },
+ "parameters-are-used": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ },
+ "local-variables-are-used": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ },
+ "generated-is-used": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "varnamelen": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-distance": {
+ "description": "Variables used in at most this N-many lines will be ignored.",
+ "type": "integer",
+ "default": 5
+ },
+ "min-name-length": {
+ "description": "The minimum length of a variable's name that is considered `long`.",
+ "type": "integer",
+ "default": 3
+ },
+ "check-receiver": {
+ "description": "Check method receiver names.",
+ "default": false,
+ "type": "boolean"
+ },
+ "check-return": {
+ "description": "Check named return values.",
+ "default": false,
+ "type": "boolean"
+ },
+ "check-type-param": {
+ "description": "Check type parameters.",
+ "default": false,
+ "type": "boolean"
+ },
+ "ignore-type-assert-ok": {
+ "description": "Ignore `ok` variables that hold the bool return value of a type assertion",
+ "default": false,
+ "type": "boolean"
+ },
+ "ignore-map-index-ok": {
+ "description": "Ignore `ok` variables that hold the bool return value of a map index.",
+ "default": false,
+ "type": "boolean"
+ },
+ "ignore-chan-recv-ok": {
+ "description": "Ignore `ok` variables that hold the bool return value of a channel receive.",
+ "default": false,
+ "type": "boolean"
+ },
+ "ignore-names": {
+ "description": "Optional list of variable names that should be ignored completely.",
+ "default": [[]],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignore-decls": {
+ "description": "Optional list of variable declarations that should be ignored completely.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "examples": [
+ ["c echo.Context", "t testing.T", "f *foo.Bar", "const C"]
+ ]
+ }
+ }
+ },
+ "whitespace": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "multi-if": {
+ "description": "Enforces newlines (or comments) after every multi-line if statement",
+ "type": "boolean",
+ "default": false
+ },
+ "multi-func": {
+ "description": "Enforces newlines (or comments) after every multi-line function signature",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "wrapcheck": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "extra-ignore-sigs": {
+ "description": "An array of strings specifying additional substrings of signatures to ignore.",
+ "default": [
+ ".CustomError(",
+ ".SpecificWrap("
+ ],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignoreSigs": {
+ "description": "An array of strings which specify substrings of signatures to ignore.",
+ "default": [
+ ".Errorf(",
+ "errors.New(",
+ "errors.Unwrap(",
+ ".Wrap(",
+ ".Wrapf(",
+ ".WithMessage(",
+ ".WithMessagef(",
+ ".WithStack("
+ ],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignoreSigRegexps": {
+ "description": "An array of strings which specify regular expressions of signatures to ignore.",
+ "default": [""],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignorePackageGlobs": {
+ "description": "An array of glob patterns which, if any match the package of the function returning the error, will skip wrapcheck analysis for this error.",
+ "default": [""],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignoreInterfaceRegexps": {
+ "description": "An array of glob patterns which, if matched to an underlying interface name, will ignore unwrapped errors returned from a function whose call is defined on the given interface.",
+ "default": [""],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "wsl": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "allow-assign-and-anything": {
+ "description": "Controls if you may cuddle assignments and anything without needing an empty line between them.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-assign-and-call": {
+ "description": "Allow calls and assignments to be cuddled as long as the lines have any matching variables, fields or types.",
+ "type": "boolean",
+ "default": true
+ },
+ "allow-cuddle-declarations": {
+ "description": "Allow declarations (var) to be cuddled.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-cuddle-with-calls": {
+ "description": "A list of call idents that everything can be cuddled with.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "allow-cuddle-with-rhs": {
+ "description": "AllowCuddleWithRHS is a list of right hand side variables that is allowed to be cuddled with anything.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "allow-multiline-assign": {
+ "description": "Allow multiline assignments to be cuddled.",
+ "type": "boolean",
+ "default": true
+ },
+ "allow-separated-leading-comment": {
+ "description": "Allow leading comments to be separated with empty lines.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-trailing-comment": {
+ "description": "Allow trailing comments in ending of blocks.",
+ "type": "boolean",
+ "default": false
+ },
+ "error-variable-names": {
+ "description": "When force-err-cuddling is enabled this is a list of names used for error variables to check for in the conditional.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "force-case-trailing-whitespace": {
+ "description": "Force newlines in end of case at this limit (0 = never).",
+ "type": "integer",
+ "minimum": 0,
+ "default": 0
+ },
+ "force-err-cuddling": {
+ "description": "Causes an error when an If statement that checks an error variable doesn't cuddle with the assignment of that variable.",
+ "type": "boolean",
+ "default": false
+ },
+ "force-short-decl-cuddling": {
+ "description": "Causes an error if a short declaration (:=) cuddles with anything other than another short declaration.",
+ "type": "boolean",
+ "default": false
+ },
+ "strict-append": {
+ "description": "If true, append is only allowed to be cuddled if appending value is matching variables, fields or types on line above.",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "copyloopvar": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-alias": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "custom": {
+ "description": "The custom section can be used to define linter plugins to be loaded at runtime. See README of golangci-lint for more information.\nEach custom linter should have a unique name.",
+ "type": "object",
+ "patternProperties": {
+ "^.*$": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "type": {
+ "description": "The plugin type.",
+ "enum": ["module", "goplugin"],
+ "default": "goplugin"
+ },
+ "path": {
+ "description": "The path to the plugin *.so. Can be absolute or local.",
+ "type": "string",
+ "examples": ["/path/to/example.so"]
+ },
+ "description": {
+ "description": "The description of the linter, for documentation purposes only.",
+ "type": "string"
+ },
+ "original-url": {
+ "description": "Intended to point to the repo location of the linter, for documentation purposes only.",
+ "type": "string"
+ },
+ "settings": {
+ "description": "Plugins settings/configuration. Only work with plugin based on `linterdb.PluginConstructor`.",
+ "type": "object"
+ }
+ },
+ "oneOf": [
+ {
+ "properties": {
+ "type": {"enum": ["module"] }
+ },
+ "required": ["type"]
+ },
+ {
+ "required": ["path"]
+ }
+ ]
+ }
+ }
+ }
+ }
+ },
+ "linters": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "enable": {
+ "description": "List of enabled linters.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linters"
+ }
+ },
+ "disable": {
+ "description": "List of disabled linters.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linters"
+ }
+ },
+ "enable-all": {
+ "description": "Whether to enable all linters. You can re-disable them with `disable` explicitly.",
+ "type": "boolean",
+ "default": false
+ },
+ "disable-all": {
+ "description": "Whether to disable all linters. You can re-enable them with `enable` explicitly.",
+ "type": "boolean",
+ "default": false
+ },
+ "presets": {
+ "description": "Allow to use different presets of linters",
+ "type": "array",
+ "items": {
+ "enum": [
+ "bugs",
+ "comment",
+ "complexity",
+ "error",
+ "format",
+ "import",
+ "metalinter",
+ "module",
+ "performance",
+ "sql",
+ "style",
+ "test",
+ "unused"
+ ]
+ }
+ },
+ "fast": {
+ "description": "Enable run of fast linters.",
+ "type": "boolean",
+ "default": false
+ },
+ "exclusions":{
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "generated": {
+ "enum": ["strict", "lax", "disable"],
+ "default": "lax"
+ },
+ "warn-unused": {
+ "type": "boolean",
+ "default": false
+ },
+ "default": {
+ "type": "array",
+ "items": {
+ "enum": [
+ "comments",
+ "stdErrorHandling",
+ "commonFalsePositives",
+ "legacy"
+ ]
+ }
+ },
+ "rules": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "path": {
+ "type": "string"
+ },
+ "path-except": {
+ "type": "string"
+ },
+ "linters": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linters"
+ }
+ },
+ "text": {
+ "type": "string"
+ },
+ "source": {
+ "type": "string"
+ }
+ },
+ "anyOf": [
+ { "required": ["path"] },
+ { "required": ["path-except"] },
+ { "required": ["linters"] },
+ { "required": ["text"] },
+ { "required": ["source"] }
+ ]
+ }
+ },
+ "paths": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "paths-except": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "issues": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "exclude": {
+ "description": "List of regular expressions of issue texts to exclude.\nBut independently from this option we use default exclude patterns. Their usage can be controlled through `exclude-use-default`.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "exclude-rules": {
+ "description": "Exclude configuration per-path, per-linter, per-text and per-source",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "path": {
+ "type": "string"
+ },
+ "path-except": {
+ "type": "string"
+ },
+ "linters": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linters"
+ }
+ },
+ "text": {
+ "type": "string"
+ },
+ "source": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "exclude-use-default": {
+ "description": "Independently from option `exclude` we use default exclude patterns. This behavior can be disabled by this option.",
+ "type": "boolean",
+ "default": true
+ },
+ "exclude-case-sensitive": {
+ "description": "If set to true, exclude and exclude-rules regular expressions become case sensitive.",
+ "type": "boolean",
+ "default": false
+ },
+ "exclude-generated": {
+ "description": "Mode of the generated files analysis.",
+ "enum": ["lax", "strict", "disable"],
+ "default": "lax"
+ },
+ "exclude-dirs": {
+ "description": "Which directories to exclude: issues from them won't be reported.",
+ "type": "array",
+ "items": {
+ "description": "You can use regexp here. The regexp is applied on the full path.\n\"/\" will be replaced by current OS file path separator to properly work on Windows.",
+ "type": "string",
+ "examples": ["generated.*"]
+ },
+ "default": [],
+ "examples": [["src/external_libs", "autogenerated_by_my_lib"]]
+ },
+ "exclude-dirs-use-default": {
+ "description": "Enable exclusion of directories \"vendor\", \"third_party\", \"testdata\", \"examples\", \"Godeps\", and \"builtin\".",
+ "type": "boolean",
+ "default": true
+ },
+ "exclude-files": {
+ "description": "Which files to exclude: they will be analyzed, but issues from them will not be reported.",
+ "type": "array",
+ "items": {
+ "description": "You can use regexp here. There is no need to include all autogenerated files, we confidently recognize them. If that is not the case, please let us know.\n\"/\" will be replaced by current OS file path separator to properly work on Windows.",
+ "type": "string",
+ "examples": [".*\\.my\\.go$"]
+ },
+ "default": [],
+ "examples": [[".*\\.my\\.go$", "lib/bad.go"]]
+ },
+ "include": {
+ "description": "The list of ids of default excludes to include or disable.",
+ "type": "array",
+ "items": {
+ "enum": [
+ "EXC0001",
+ "EXC0002",
+ "EXC0003",
+ "EXC0004",
+ "EXC0005",
+ "EXC0006",
+ "EXC0007",
+ "EXC0008",
+ "EXC0009",
+ "EXC0010",
+ "EXC0011",
+ "EXC0012",
+ "EXC0013",
+ "EXC0014",
+ "EXC0015"
+ ]
+ },
+ "default": []
+ },
+ "max-issues-per-linter": {
+ "description": "Maximum issues count per one linter. Set to 0 to disable.",
+ "type": "integer",
+ "default": 50,
+ "minimum": 0
+ },
+ "max-same-issues": {
+ "description": "Maximum count of issues with the same text. Set to 0 to disable.",
+ "type": "integer",
+ "default": 3,
+ "minimum": 0
+ },
+ "new": {
+ "description": "Show only new issues: if there are unstaged changes or untracked files, only those changes are analyzed, else only changes in HEAD~ are analyzed.",
+ "type": "boolean",
+ "default": false
+ },
+ "new-from-merge-base": {
+ "description": "Show only new issues created after the best common ancestor (merge-base against HEAD).",
+ "type": "string"
+ },
+ "new-from-rev": {
+ "description": "Show only new issues created after this git revision.",
+ "type": "string"
+ },
+ "new-from-patch": {
+ "description": "Show only new issues created in git patch with this file path.",
+ "type": "string",
+ "examples": ["path/to/patch/file"]
+ },
+ "fix": {
+ "description": "Fix found issues (if it's supported by the linter).",
+ "type": "boolean",
+ "default": false
+ },
+ "uniq-by-line": {
+ "description": "Make issues output unique by line.",
+ "type": "boolean",
+ "default": true
+ },
+ "whole-files": {
+ "description": "Show issues in any part of update files (requires new-from-rev or new-from-patch).",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "severity": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "default-severity": {
+ "description": "Set the default severity for issues. If severity rules are defined and the issues do not match or no severity is provided to the rule this will be the default severity applied. Severities should match the supported severity names of the selected out format.",
+ "type": "string",
+ "default": ""
+ },
+ "case-sensitive": {
+ "description": "If set to true, severity-rules regular expressions become case sensitive.",
+ "type": "boolean",
+ "default": false
+ },
+ "rules": {
+ "description": "When a list of severity rules are provided, severity information will be added to lint issues. Severity rules have the same filtering capability as exclude rules except you are allowed to specify one matcher per severity rule.\nOnly affects out formats that support setting severity information.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "severity": {
+ "type": "string"
+ },
+ "path": {
+ "type": "string"
+ },
+ "path-except": {
+ "type": "string"
+ },
+ "linters": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linters"
+ }
+ },
+ "text": {
+ "type": "string"
+ },
+ "source": {
+ "type": "string"
+ }
+ },
+ "required": ["severity"],
+ "anyOf": [
+ { "required": ["path"] },
+ { "required": ["path-except"] },
+ { "required": ["linters"] },
+ { "required": ["text"] },
+ { "required": ["source"] }
+ ]
+ },
+ "default": []
+ }
+ },
+ "required": ["default-severity"]
+ }
+ }
+}
diff --git a/vendor/github.com/golangci/golangci-lint/v2/jsonschema/golangci.v1.jsonschema.json b/vendor/github.com/golangci/golangci-lint/v2/jsonschema/golangci.v1.jsonschema.json
new file mode 100644
index 000000000..b265c1a82
--- /dev/null
+++ b/vendor/github.com/golangci/golangci-lint/v2/jsonschema/golangci.v1.jsonschema.json
@@ -0,0 +1,4224 @@
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "$id": "https://json.schemastore.org/golangci-lint.json",
+ "definitions": {
+ "gocritic-checks": {
+ "enum": [
+ "appendAssign",
+ "appendCombine",
+ "argOrder",
+ "assignOp",
+ "badCall",
+ "badCond",
+ "badLock",
+ "badRegexp",
+ "badSorting",
+ "badSyncOnceFunc",
+ "boolExprSimplify",
+ "builtinShadow",
+ "builtinShadowDecl",
+ "captLocal",
+ "caseOrder",
+ "codegenComment",
+ "commentFormatting",
+ "commentedOutCode",
+ "commentedOutImport",
+ "defaultCaseOrder",
+ "deferInLoop",
+ "deferUnlambda",
+ "deprecatedComment",
+ "docStub",
+ "dupArg",
+ "dupBranchBody",
+ "dupCase",
+ "dupImport",
+ "dupSubExpr",
+ "dynamicFmtString",
+ "elseif",
+ "emptyDecl",
+ "emptyFallthrough",
+ "emptyStringTest",
+ "equalFold",
+ "evalOrder",
+ "exitAfterDefer",
+ "exposedSyncMutex",
+ "externalErrorReassign",
+ "filepathJoin",
+ "flagDeref",
+ "flagName",
+ "hexLiteral",
+ "httpNoBody",
+ "hugeParam",
+ "ifElseChain",
+ "importShadow",
+ "indexAlloc",
+ "initClause",
+ "ioutilDeprecated",
+ "mapKey",
+ "methodExprCall",
+ "nestingReduce",
+ "newDeref",
+ "nilValReturn",
+ "octalLiteral",
+ "offBy1",
+ "paramTypeCombine",
+ "preferDecodeRune",
+ "preferFilepathJoin",
+ "preferFprint",
+ "preferStringWriter",
+ "preferWriteByte",
+ "ptrToRefParam",
+ "rangeAppendAll",
+ "rangeExprCopy",
+ "rangeValCopy",
+ "redundantSprint",
+ "regexpMust",
+ "regexpPattern",
+ "regexpSimplify",
+ "returnAfterHttpError",
+ "ruleguard",
+ "singleCaseSwitch",
+ "sliceClear",
+ "sloppyLen",
+ "sloppyReassign",
+ "sloppyTypeAssert",
+ "sortSlice",
+ "sprintfQuotedString",
+ "sqlQuery",
+ "stringConcatSimplify",
+ "stringXbytes",
+ "stringsCompare",
+ "switchTrue",
+ "syncMapLoadAndDelete",
+ "timeExprSimplify",
+ "todoCommentWithoutDetail",
+ "tooManyResultsChecker",
+ "truncateCmp",
+ "typeAssertChain",
+ "typeDefFirst",
+ "typeSwitchVar",
+ "typeUnparen",
+ "uncheckedInlineErr",
+ "underef",
+ "unlabelStmt",
+ "unlambda",
+ "unnamedResult",
+ "unnecessaryBlock",
+ "unnecessaryDefer",
+ "unslice",
+ "valSwap",
+ "weakCond",
+ "whyNoLint",
+ "wrapperFunc",
+ "yodaStyleExpr"
+ ]
+ },
+ "gocritic-tags": {
+ "enum": [
+ "diagnostic",
+ "style",
+ "performance",
+ "experimental",
+ "opinionated",
+ "security"
+ ]
+ },
+ "gosec-rules": {
+ "enum": [
+ "G101",
+ "G102",
+ "G103",
+ "G104",
+ "G106",
+ "G107",
+ "G108",
+ "G109",
+ "G110",
+ "G111",
+ "G112",
+ "G113",
+ "G114",
+ "G115",
+ "G201",
+ "G202",
+ "G203",
+ "G204",
+ "G301",
+ "G302",
+ "G303",
+ "G304",
+ "G305",
+ "G306",
+ "G307",
+ "G401",
+ "G402",
+ "G403",
+ "G404",
+ "G405",
+ "G406",
+ "G501",
+ "G502",
+ "G503",
+ "G504",
+ "G505",
+ "G506",
+ "G507",
+ "G601",
+ "G602"
+ ]
+ },
+ "govet-analyzers": {
+ "enum": [
+ "appends",
+ "asmdecl",
+ "assign",
+ "atomic",
+ "atomicalign",
+ "bools",
+ "buildtag",
+ "cgocall",
+ "composites",
+ "copylocks",
+ "deepequalerrors",
+ "defers",
+ "directive",
+ "errorsas",
+ "fieldalignment",
+ "findcall",
+ "framepointer",
+ "httpresponse",
+ "ifaceassert",
+ "loopclosure",
+ "lostcancel",
+ "nilfunc",
+ "nilness",
+ "printf",
+ "reflectvaluecompare",
+ "shadow",
+ "shift",
+ "sigchanyzer",
+ "slog",
+ "sortslice",
+ "stdmethods",
+ "stdversion",
+ "stringintconv",
+ "structtag",
+ "testinggoroutine",
+ "tests",
+ "timeformat",
+ "unmarshal",
+ "unreachable",
+ "unsafeptr",
+ "unusedresult",
+ "unusedwrite",
+ "waitgroup"
+ ]
+ },
+ "revive-rules": {
+ "enum": [
+ "add-constant",
+ "argument-limit",
+ "atomic",
+ "banned-characters",
+ "bare-return",
+ "blank-imports",
+ "bool-literal-in-expr",
+ "call-to-gc",
+ "cognitive-complexity",
+ "comment-spacings",
+ "comments-density",
+ "confusing-naming",
+ "confusing-results",
+ "constant-logical-expr",
+ "context-as-argument",
+ "context-keys-type",
+ "cyclomatic",
+ "datarace",
+ "deep-exit",
+ "defer",
+ "dot-imports",
+ "duplicated-imports",
+ "early-return",
+ "empty-block",
+ "empty-lines",
+ "enforce-map-style",
+ "enforce-repeated-arg-type-style",
+ "enforce-slice-style",
+ "error-naming",
+ "error-return",
+ "error-strings",
+ "errorf",
+ "exported",
+ "file-header",
+ "file-length-limit",
+ "filename-format",
+ "flag-parameter",
+ "function-length",
+ "function-result-limit",
+ "get-return",
+ "identical-branches",
+ "if-return",
+ "import-alias-naming",
+ "import-shadowing",
+ "imports-blocklist",
+ "increment-decrement",
+ "indent-error-flow",
+ "line-length-limit",
+ "max-control-nesting",
+ "max-public-structs",
+ "modifies-parameter",
+ "modifies-value-receiver",
+ "nested-structs",
+ "optimize-operands-order",
+ "package-comments",
+ "range-val-address",
+ "range-val-in-closure",
+ "range",
+ "receiver-naming",
+ "redefines-builtin-id",
+ "redundant-build-tag",
+ "redundant-import-alias",
+ "string-format",
+ "string-of-int",
+ "struct-tag",
+ "superfluous-else",
+ "time-equal",
+ "time-naming",
+ "unchecked-type-assertion",
+ "unconditional-recursion",
+ "unexported-naming",
+ "unexported-return",
+ "unhandled-error",
+ "unnecessary-stmt",
+ "unreachable-code",
+ "unused-parameter",
+ "unused-receiver",
+ "use-any",
+ "use-errors-new",
+ "useless-break",
+ "var-declaration",
+ "var-naming",
+ "waitgroup-by-value"
+ ]
+ },
+ "iface-analyzers": {
+ "enum": [
+ "identical",
+ "unused",
+ "opaque"
+ ]
+ },
+ "tagliatelle-cases": {
+ "enum": [
+ "",
+ "camel",
+ "pascal",
+ "kebab",
+ "snake",
+ "goCamel",
+ "goPascal",
+ "goKebab",
+ "goSnake",
+ "upper",
+ "upperSnake",
+ "lower",
+ "header"
+ ]
+ },
+ "linters": {
+ "$comment": "anyOf with enum is used to allow auto completion of non-custom linters",
+ "description": "Linters usable.",
+ "anyOf": [
+ {
+ "enum": [
+ "asasalint",
+ "asciicheck",
+ "bidichk",
+ "bodyclose",
+ "canonicalheader",
+ "containedctx",
+ "contextcheck",
+ "copyloopvar",
+ "cyclop",
+ "decorder",
+ "depguard",
+ "dogsled",
+ "dupl",
+ "dupword",
+ "durationcheck",
+ "errcheck",
+ "errchkjson",
+ "errname",
+ "errorlint",
+ "exhaustive",
+ "exhaustruct",
+ "exptostd",
+ "fatcontext",
+ "forbidigo",
+ "forcetypeassert",
+ "funlen",
+ "gci",
+ "ginkgolinter",
+ "gocheckcompilerdirectives",
+ "gochecknoglobals",
+ "gochecknoinits",
+ "gochecksumtype",
+ "gocognit",
+ "goconst",
+ "gocritic",
+ "gocyclo",
+ "godot",
+ "godox",
+ "err113",
+ "gofmt",
+ "gofumpt",
+ "goheader",
+ "goimports",
+ "gomoddirectives",
+ "gomodguard",
+ "goprintffuncname",
+ "gosec",
+ "gosimple",
+ "gosmopolitan",
+ "govet",
+ "grouper",
+ "iface",
+ "importas",
+ "inamedparam",
+ "ineffassign",
+ "interfacebloat",
+ "intrange",
+ "ireturn",
+ "lll",
+ "loggercheck",
+ "maintidx",
+ "makezero",
+ "mirror",
+ "misspell",
+ "mnd",
+ "musttag",
+ "nakedret",
+ "nestif",
+ "nilerr",
+ "nilnesserr",
+ "nilnil",
+ "nlreturn",
+ "noctx",
+ "nolintlint",
+ "nonamedreturns",
+ "nosprintfhostport",
+ "paralleltest",
+ "perfsprint",
+ "prealloc",
+ "predeclared",
+ "promlinter",
+ "protogetter",
+ "reassign",
+ "recvcheck",
+ "revive",
+ "rowserrcheck",
+ "sloglint",
+ "sqlclosecheck",
+ "staticcheck",
+ "stylecheck",
+ "tagalign",
+ "tagliatelle",
+ "tenv",
+ "testableexamples",
+ "testifylint",
+ "testpackage",
+ "thelper",
+ "tparallel",
+ "unconvert",
+ "unparam",
+ "unused",
+ "usestdlibvars",
+ "usetesting",
+ "varnamelen",
+ "wastedassign",
+ "whitespace",
+ "wrapcheck",
+ "wsl",
+ "zerologlint"
+ ]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ },
+ "relative-path-modes": {
+ "enum": [
+ "gomod",
+ "gitroot",
+ "cfg",
+ "wd"
+ ]
+ }
+ },
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "run": {
+ "description": "Options for analysis running,",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "concurrency": {
+ "description": "Number of concurrent runners. Defaults to the number of available CPU cores.",
+ "type": "integer",
+ "minimum": 0,
+ "examples": [4]
+ },
+ "timeout": {
+ "description": "Timeout for the analysis.",
+ "type": "string",
+ "pattern": "^((\\d+h)?(\\d+m)?(\\d+(?:\\.\\d)?s)?|0)$",
+ "default": "1m",
+ "examples": ["30s", "5m", "5m30s"]
+ },
+ "issues-exit-code": {
+ "description": "Exit code when at least one issue was found.",
+ "type": "integer",
+ "default": 1
+ },
+ "tests": {
+ "description": "Enable inclusion of test files.",
+ "type": "boolean",
+ "default": true
+ },
+ "build-tags": {
+ "description": "List of build tags to pass to all linters.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "default": [],
+ "examples": [["mytag"]]
+ },
+ "modules-download-mode": {
+ "description": "Option to pass to \"go list -mod={option}\".\nSee \"go help modules\" for more information.",
+ "enum": ["mod", "readonly", "vendor"]
+ },
+ "allow-parallel-runners": {
+ "description": "Allow multiple parallel golangci-lint instances running. If disabled, golangci-lint acquires file lock on start.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-serial-runners": {
+ "description": "Allow multiple golangci-lint instances running, but serialize them around a lock.",
+ "type": "boolean",
+ "default": false
+ },
+ "go": {
+ "description": "Targeted Go version.",
+ "type": "string",
+ "default": "1.17"
+ },
+ "relative-path-mode": {
+ "description": "The mode used to evaluate relative paths.",
+ "type": "string",
+ "$ref": "#/definitions/relative-path-modes",
+ "default": "wd"
+ }
+ }
+ },
+ "output": {
+ "description": "Output configuration options.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "formats": {
+ "description": "Output formats to use.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "path": {
+ "default": "stdout",
+ "anyOf": [
+ {
+ "enum": [ "stdout", "stderr" ]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ },
+ "format": {
+ "default": "colored-line-number",
+ "enum": [
+ "colored-line-number",
+ "line-number",
+ "json",
+ "colored-tab",
+ "tab",
+ "html",
+ "checkstyle",
+ "code-climate",
+ "junit-xml",
+ "junit-xml-extended",
+ "github-actions",
+ "teamcity",
+ "sarif"
+ ]
+ }
+ },
+ "required": ["format"]
+ }
+ },
+ "print-issued-lines": {
+ "description": "Print lines of code with issue.",
+ "type": "boolean",
+ "default": true
+ },
+ "print-linter-name": {
+ "description": "Print linter name in the end of issue text.",
+ "type": "boolean",
+ "default": true
+ },
+ "path-prefix": {
+ "description": "Add a prefix to the output file references.",
+ "type": "string",
+ "default": ""
+ },
+ "show-stats": {
+ "description": "Show statistics per linter.",
+ "type": "boolean",
+ "default": false
+ },
+ "sort-order": {
+ "type": "array",
+ "items": {
+ "enum": ["linter", "severity", "file"]
+ }
+ },
+ "sort-results": {
+ "description": "Sort results by: filepath, line and column.",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "linters-settings": {
+ "description": "All available settings of specific linters.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "dupword": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "keywords": {
+ "description": "Keywords for detecting duplicate words. If this list is not empty, only the words defined in this list will be detected.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["the", "and", "a"]
+ }
+ },
+ "ignore": {
+ "description": "Keywords used to ignore detection.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["0C0C"]
+ }
+ }
+ }
+ },
+ "asasalint": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "exclude": {
+ "description": "To specify a set of function names to exclude.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["\\.Wrapf"]
+ }
+ },
+ "use-builtin-exclusions": {
+ "description": "To enable/disable the asasalint builtin exclusions of function names.",
+ "type": "boolean",
+ "default": true
+ },
+ "ignore-test": {
+ "description": "Ignore *_test.go files.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "bidichk": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "left-to-right-embedding": {
+ "description": "Disallow: LEFT-TO-RIGHT-EMBEDDING",
+ "type": "boolean",
+ "default": false
+ },
+ "right-to-left-embedding": {
+ "description": "Disallow: RIGHT-TO-LEFT-EMBEDDING",
+ "type": "boolean",
+ "default": false
+ },
+ "pop-directional-formatting": {
+ "description": "Disallow: POP-DIRECTIONAL-FORMATTING",
+ "type": "boolean",
+ "default": false
+ },
+ "left-to-right-override": {
+ "description": "Disallow: LEFT-TO-RIGHT-OVERRIDE",
+ "type": "boolean",
+ "default": false
+ },
+ "right-to-left-override": {
+ "description": "Disallow: RIGHT-TO-LEFT-OVERRIDE",
+ "type": "boolean",
+ "default": false
+ },
+ "left-to-right-isolate": {
+ "description": "Disallow: LEFT-TO-RIGHT-ISOLATE",
+ "type": "boolean",
+ "default": false
+ },
+ "right-to-left-isolate": {
+ "description": "Disallow: RIGHT-TO-LEFT-ISOLATE",
+ "type": "boolean",
+ "default": false
+ },
+ "first-strong-isolate": {
+ "description": "Disallow: FIRST-STRONG-ISOLATE",
+ "type": "boolean",
+ "default": false
+ },
+ "pop-directional-isolate": {
+ "description": "Disallow: POP-DIRECTIONAL-ISOLATE",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "cyclop": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skip-tests": {
+ "description": "Should the linter execute on test files as well",
+ "type": "boolean",
+ "default": false
+ },
+ "max-complexity": {
+ "description": "Max complexity the function can have",
+ "type": "integer",
+ "default": 10,
+ "minimum": 0
+ },
+ "package-average": {
+ "description": "Max average complexity in package",
+ "type": "number",
+ "default": 0,
+ "minimum": 0
+ }
+ }
+ },
+ "decorder": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "dec-order": {
+ "type": "array",
+ "default": [["type", "const", "var", "func"]],
+ "items": {
+ "enum": ["type", "const", "var", "func"]
+ }
+ },
+ "ignore-underscore-vars": {
+ "description": "Underscore vars (vars with \"_\" as the name) will be ignored at all checks",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-dec-order-check": {
+ "description": "Order of declarations is not checked",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-init-func-first-check": {
+ "description": "Allow init func to be anywhere in file",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-dec-num-check": {
+ "description": "Multiple global type, const and var declarations are allowed",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-type-dec-num-check": {
+ "description": "Type declarations will be ignored for dec num check",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-const-dec-num-check": {
+ "description": "Const declarations will be ignored for dec num check",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-var-dec-num-check": {
+ "description": "Var declarations will be ignored for dec num check",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ },
+ "depguard": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "rules": {
+ "description": "Rules to apply.",
+ "type": "object",
+ "additionalProperties": false,
+ "patternProperties": {
+ "^[^.]+$": {
+ "description": "Name of a rule.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "list-mode": {
+ "description": "Used to determine the package matching priority.",
+ "enum": ["original", "strict", "lax"],
+ "default": "original"
+ },
+ "files": {
+ "description": "List of file globs that will match this list of settings to compare against.",
+ "additionalProperties": false,
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "allow": {
+ "description": "List of allowed packages.",
+ "additionalProperties": false,
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "deny": {
+ "description": "Packages that are not allowed where the value is a suggestion.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "desc": {
+ "description": "Description",
+ "type": "string"
+ },
+ "pkg": {
+ "description": "Package",
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "dogsled": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-blank-identifiers": {
+ "description": "Check assignments with too many blank identifiers.",
+ "type": "integer",
+ "default": 2,
+ "minimum": 0
+ }
+ }
+ },
+ "dupl": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "threshold": {
+ "description": "Tokens count to trigger issue.",
+ "type": "integer",
+ "default": 150,
+ "minimum": 0
+ }
+ }
+ },
+ "errcheck": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-type-assertions": {
+ "description": "Report about not checking errors in type assertions, i.e.: `a := b.(MyStruct)`",
+ "type": "boolean",
+ "default": false
+ },
+ "check-blank": {
+ "description": "Report about assignment of errors to blank identifier",
+ "type": "boolean",
+ "default": false
+ },
+ "exclude-functions": {
+ "description": "List of functions to exclude from checking, where each entry is a single function to exclude",
+ "type": "array",
+ "examples": ["io/ioutil.ReadFile", "io.Copy(*bytes.Buffer)"],
+ "items": {
+ "type": "string"
+ }
+ },
+ "disable-default-exclusions": {
+ "description": "To disable the errcheck built-in exclude list",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "errchkjson": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-error-free-encoding": {
+ "type": "boolean",
+ "default": false
+ },
+ "report-no-exported": {
+ "description": "Issue on struct that doesn't have exported fields.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "errorlint": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "errorf": {
+ "description": "Check whether fmt.Errorf uses the %w verb for formatting errors",
+ "type": "boolean",
+ "default": true
+ },
+ "errorf-multi": {
+ "description": "Permit more than 1 %w verb, valid per Go 1.20",
+ "type": "boolean",
+ "default": true
+ },
+ "asserts": {
+ "description": "Check for plain type assertions and type switches.",
+ "type": "boolean",
+ "default": true
+ },
+ "comparison": {
+ "description": "Check for plain error comparisons",
+ "type": "boolean",
+ "default": true
+ },
+ "allowed-errors": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "err": {
+ "type": "string"
+ },
+ "fun": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "allowed-errors-wildcard": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "err": {
+ "type": "string"
+ },
+ "fun": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "exhaustive": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check": {
+ "description": "Program elements to check for exhaustiveness.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["switch", "map"]
+ }
+ },
+ "check-generated": {
+ "description": "Check switch statements in generated files",
+ "type": "boolean",
+ "default": false
+ },
+ "explicit-exhaustive-switch": {
+ "description": "Only run exhaustive check on switches with \"//exhaustive:enforce\" comment.",
+ "type": "boolean",
+ "default": false
+ },
+ "explicit-exhaustive-map": {
+ "description": "Only run exhaustive check on map literals with \"//exhaustive:enforce\" comment.",
+ "type": "boolean",
+ "default": false
+ },
+ "default-case-required": {
+ "description": "Switch statement requires default case even if exhaustive.",
+ "type": "boolean",
+ "default": false
+ },
+ "default-signifies-exhaustive": {
+ "description": "Presence of `default` case in switch statements satisfies exhaustiveness, even if all enum members are not listed.",
+ "type": "boolean",
+ "default": false
+ },
+ "ignore-enum-members": {
+ "description": "Enum members matching `regex` do not have to be listed in switch statements to satisfy exhaustiveness",
+ "type": "string"
+ },
+ "ignore-enum-types": {
+ "description": "Enum types matching the supplied regex do not have to be listed in switch statements to satisfy exhaustiveness.",
+ "type": "string"
+ },
+ "package-scope-only": {
+ "description": "Consider enums only in package scopes, not in inner scopes.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "exhaustruct": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "include": {
+ "description": "List of regular expressions to match struct packages and names.",
+ "type": "array",
+ "examples": [".*\\.Test"],
+ "items": {
+ "type": "string"
+ }
+ },
+ "exclude": {
+ "description": "List of regular expressions to exclude struct packages and names from check.",
+ "type": "array",
+ "examples": ["cobra\\.Command$"],
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "fatcontext": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-struct-pointers": {
+ "description": "Check for potential fat contexts in struct pointers.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "forbidigo": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "exclude-godoc-examples": {
+ "description": "Exclude code in godoc examples.",
+ "type": "boolean",
+ "default": true
+ },
+ "analyze-types": {
+ "description": "Instead of matching the literal source code, use type information to replace expressions with strings that contain the package name and (for methods and fields) the type name.",
+ "type": "boolean",
+ "default": true
+ },
+ "forbid": {
+ "description": "List of identifiers to forbid (written using `regexp`)",
+ "type": "array",
+ "examples": ["^print(ln)?$"],
+ "items": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "p": {
+ "description": "Pattern",
+ "type": "string"
+ },
+ "pkg": {
+ "description": "Package",
+ "type": "string"
+ },
+ "msg": {
+ "description": "Message",
+ "type": "string"
+ }
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ "funlen": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "lines": {
+ "description": "Limit lines number per function.",
+ "type": "integer",
+ "default": 60
+ },
+ "statements": {
+ "description": "Limit statements number per function.",
+ "type": "integer",
+ "default": 40
+ },
+ "ignore-comments": {
+ "description": "Ignore comments when counting lines.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "gci": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "sections": {
+ "description": "Section configuration to compare against.",
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "enum": [
+ "standard",
+ "default",
+ "blank",
+ "dot",
+ "alias",
+ "localmodule"
+ ]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ },
+ "default": ["standard", "default"]
+ },
+ "skip-generated": {
+ "description": "Skip generated files.",
+ "type": "boolean",
+ "default": true
+ },
+ "no-inline-comments": {
+ "description": "Checks that no inline Comments are present.",
+ "type": "boolean",
+ "default": false
+ },
+ "no-prefix-comments": {
+ "description": "Checks that no prefix Comments(comment lines above an import) are present.",
+ "type": "boolean",
+ "default": false
+ },
+ "custom-order": {
+ "description": "Enable custom order of sections.",
+ "type": "boolean",
+ "default": false
+ },
+ "no-lex-order": {
+ "description": "Drops lexical ordering for custom sections.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "ginkgolinter": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "suppress-len-assertion": {
+ "description": "Suppress the wrong length assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-nil-assertion": {
+ "description": "Suppress the wrong nil assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-err-assertion": {
+ "description": "Suppress the wrong error assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-compare-assertion": {
+ "description": "Suppress the wrong comparison assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-async-assertion": {
+ "description": "Suppress the function all in async assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-type-compare-assertion": {
+ "description": "Suppress warning for comparing values from different types, like int32 and uint32.",
+ "type": "boolean",
+ "default": false
+ },
+ "forbid-focus-container": {
+ "description": "Trigger warning for ginkgo focus containers like FDescribe, FContext, FWhen or FIt.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-havelen-zero": {
+ "description": "Don't trigger warnings for HaveLen(0).",
+ "type": "boolean",
+ "default": false
+ },
+ "force-expect-to": {
+ "description": "Force using `Expect` with `To`, `ToNot` or `NotTo`",
+ "type": "boolean",
+ "default": false
+ },
+ "validate-async-intervals": {
+ "description": "Best effort validation of async intervals (timeout and polling).",
+ "type": "boolean",
+ "default": false
+ },
+ "forbid-spec-pollution": {
+ "description": "Trigger a warning for variable assignments in ginkgo containers like `Describe`, `Context` and `When`, instead of in `BeforeEach()`.",
+ "type": "boolean",
+ "default": false
+ },
+ "force-succeed": {
+ "description": "Force using the Succeed matcher for error functions, and the HaveOccurred matcher for non-function error values.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "gochecksumtype": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "default-signifies-exhaustive": {
+ "description": "Presence of `default` case in switch statements satisfies exhaustiveness, if all members are not listed.",
+ "type": "boolean",
+ "default": true
+ },
+ "include-shared-interfaces": {
+ "description": "Include shared interfaces in the exhaustiviness check.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "gocognit": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "min-complexity": {
+ "description": "Minimal code complexity to report (we recommend 10-20).",
+ "type": "integer",
+ "default": 30
+ }
+ }
+ },
+ "goconst": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "match-constant": {
+ "description": "Look for existing constants matching the values",
+ "type": "boolean",
+ "default": true
+ },
+ "min-len": {
+ "description": "Minimum length of string constant.",
+ "type": "integer",
+ "default": 3
+ },
+ "min-occurrences": {
+ "description": "Minimum occurrences count to trigger.",
+ "type": "integer",
+ "default": 3
+ },
+ "ignore-tests": {
+ "description": "Ignore test files.",
+ "type": "boolean",
+ "default": false
+ },
+ "ignore-calls": {
+ "description": "Ignore when constant is not used as function argument",
+ "type": "boolean",
+ "default": true
+ },
+ "ignore-strings": {
+ "description": "Exclude strings matching the given regular expression",
+ "type": "string"
+ },
+ "numbers": {
+ "description": "Search also for duplicated numbers.",
+ "type": "boolean",
+ "default": false
+ },
+ "min": {
+ "description": "Minimum value, only works with `numbers`",
+ "type": "integer",
+ "default": 3
+ },
+ "max": {
+ "description": "Maximum value, only works with `numbers`",
+ "type": "integer",
+ "default": 3
+ }
+ }
+ },
+ "gocritic": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "enabled-checks": {
+ "description": "Which checks should be enabled. By default, a list of stable checks is used. To see it, run `GL_DEBUG=gocritic golangci-lint run`.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/gocritic-checks"
+ }
+ },
+ "disabled-checks": {
+ "description": "Which checks should be disabled.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/gocritic-checks"
+ },
+ "default": []
+ },
+ "enabled-tags": {
+ "description": "Enable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/gocritic-tags"
+ }
+ },
+ "disabled-tags": {
+ "description": "Disable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/gocritic-tags"
+ }
+ },
+ "settings": {
+ "description": "Settings passed to gocritic. Properties must be valid and enabled check names.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "captLocal": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "paramsOnly" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "commentedOutCode": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "minLength" : {
+ "type": "number",
+ "default": 15
+ }
+ }
+ },
+ "elseif": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skipBalanced" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "hugeParam": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "sizeThreshold" : {
+ "type": "number",
+ "default": 80
+ }
+ }
+ },
+ "ifElseChain": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "minThreshold" : {
+ "type": "number",
+ "default": 2
+ }
+ }
+ },
+ "nestingReduce": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "bodyWidth" : {
+ "type": "number",
+ "default": 5
+ }
+ }
+ },
+ "rangeExprCopy": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "sizeThreshold" : {
+ "type": "number",
+ "default": 512
+ },
+ "skipTestFuncs" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "rangeValCopy": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "sizeThreshold" : {
+ "type": "number",
+ "default": 128
+ },
+ "skipTestFuncs" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "ruleguard": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "debug" : {
+ "type": "string"
+ },
+ "enable" : {
+ "type": "string"
+ },
+ "disable" : {
+ "type": "string"
+ },
+ "failOn" : {
+ "type": "string"
+ },
+ "rules" : {
+ "type": "string"
+ }
+ }
+ },
+ "tooManyResultsChecker": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "maxResults" : {
+ "type": "number",
+ "default": 5
+ }
+ }
+ },
+ "truncateCmp": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skipArchDependent" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "underef": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skipRecvDeref" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "unnamedResult": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "checkExported" : {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ }
+ }
+ },
+ "disable-all": {
+ "type": "boolean",
+ "default": false
+ },
+ "enable-all": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "gocyclo": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "min-complexity": {
+ "description": "Minimum code complexity to report (we recommend 10-20).",
+ "type": "integer",
+ "default": 30
+ }
+ }
+ },
+ "godot": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "scope": {
+ "description": "Comments to be checked.",
+ "enum": ["declarations", "toplevel", "all"],
+ "default": "declarations"
+ },
+ "exclude": {
+ "description": "List of regexps for excluding particular comment lines from check.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "period": {
+ "description": "Check that each sentence ends with a period.",
+ "type": "boolean",
+ "default": true
+ },
+ "capital": {
+ "description": "Check that each sentence starts with a capital letter.",
+ "type": "boolean",
+ "default": false
+ },
+ "check-all": {
+ "description": "DEPRECATED: Check all top-level comments, not only declarations.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "godox": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "keywords": {
+ "description": "Report any comments starting with one of these keywords. This is useful for TODO or FIXME comments that might be left in the code accidentally and should be resolved before merging.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "default": ["TODO", "BUG", "FIXME"]
+ }
+ }
+ },
+ "gofmt": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "simplify": {
+ "description": "Simplify code.",
+ "type": "boolean",
+ "default": true
+ },
+ "rewrite-rules": {
+ "description": "Apply the rewrite rules to the source before reformatting.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "pattern": {
+ "type": "string"
+ },
+ "replacement": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "interfacebloat": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max": {
+ "description": "The maximum number of methods allowed for an interface.",
+ "type": "integer"
+ }
+ }
+ },
+ "gofumpt": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "extra-rules": {
+ "description": "Choose whether or not to use the extra rules that are disabled by default.",
+ "type": "boolean",
+ "default": false
+ },
+ "module-path": {
+ "description": " Module path which contains the source code being formatted.",
+ "type": "string"
+ }
+ }
+ },
+ "goheader": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "values": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "const": {
+ "description": "Constants to use in the template.",
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "description": "Value for the constant.",
+ "type": "string"
+ }
+ },
+ "additionalProperties": false,
+ "examples": [
+ {
+ "YEAR": "2030",
+ "COMPANY": "MY FUTURISTIC COMPANY"
+ }
+ ]
+ },
+ "regexp": {
+ "description": "Regular expressions to use in your template.",
+ "type": "object",
+ "additionalProperties": false,
+ "patternProperties": {
+ "^.+$": {
+ "type": "string"
+ }
+ },
+ "examples": [
+ {
+ "AUTHOR": ".*@mycompany\\.com"
+ }
+ ]
+ }
+ }
+ },
+ "template": {
+ "description": "Template to put on top of every file.",
+ "type": "string",
+ "examples": [
+ "{{ MY COMPANY }}\nSPDX-License-Identifier: Apache-2.0\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at:\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License."
+ ]
+ },
+ "template-path": {
+ "description": "Path to the file containing the template source.",
+ "type": "string",
+ "examples": ["my_header_template.txt"]
+ }
+ },
+ "oneOf": [
+ { "required": ["template"] },
+ { "required": ["template-path"] }
+ ]
+ },
+ "goimports": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "local-prefixes": {
+ "description": "Put imports beginning with prefix after 3rd-party packages. It is a comma-separated list of prefixes.",
+ "type": "string",
+ "examples": ["github.com/org/project"]
+ }
+ }
+ },
+ "gomoddirectives": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "replace-local": {
+ "description": "Allow local `replace` directives.",
+ "type": "boolean",
+ "default": true
+ },
+ "replace-allow-list": {
+ "description": "List of allowed `replace` directives.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "retract-allow-no-explanation": {
+ "description": "Allow to not explain why the version has been retracted in the `retract` directives.",
+ "type": "boolean",
+ "default": false
+ },
+ "exclude-forbidden": {
+ "description": "Forbid the use of the `exclude` directives.",
+ "type": "boolean",
+ "default": false
+ },
+ "toolchain-forbidden": {
+ "description": "Forbid the use of the `toolchain` directive.",
+ "type": "boolean",
+ "default": false
+ },
+ "toolchain-pattern": {
+ "description": "Defines a pattern to validate `toolchain` directive.",
+ "type": "string"
+ },
+ "tool-forbidden": {
+ "description": "Forbid the use of the `tool` directives.",
+ "type": "boolean",
+ "default": false
+ },
+ "go-debug-forbidden": {
+ "description": "Forbid the use of the `godebug` directive.",
+ "type": "boolean",
+ "default": false
+ },
+ "go-version-pattern": {
+ "description": "Defines a pattern to validate `go` minimum version directive.",
+ "type": "string",
+ "default": ""
+ }
+ }
+ },
+ "gomodguard": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "allowed": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "modules": {
+ "description": "List of allowed modules.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["gopkg.in/yaml.v2"]
+ }
+ },
+ "domains": {
+ "description": "List of allowed module domains.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["golang.org"]
+ }
+ }
+ }
+ },
+ "blocked": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "modules": {
+ "description": "List of blocked modules.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "recommendations": {
+ "description": "Recommended modules that should be used instead.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "reason": {
+ "description": "Reason why the recommended module should be used.",
+ "type": "string"
+ }
+ }
+ }
+ },
+ "additionalProperties": false
+ }
+ },
+ "versions": {
+ "description": "List of blocked module version constraints.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "patternProperties": {
+ "^.*$": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "version": {
+ "description": "Version constraint.",
+ "type": "string"
+ },
+ "reason": {
+ "description": "Reason why the version constraint exists.",
+ "type": "string"
+ }
+ },
+ "required": ["reason"]
+ }
+ }
+ }
+ },
+ "local_replace_directives": {
+ "description": "Raise lint issues if loading local path with replace directive",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ }
+ }
+ },
+ "gosimple": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "checks": {
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "enum": ["all"]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ }
+ }
+ }
+ },
+ "gosec": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "includes": {
+ "type": "array",
+ "description": "To select a subset of rules to run",
+ "examples": [["G401"]],
+ "items": {
+ "$ref": "#/definitions/gosec-rules"
+ }
+ },
+ "excludes": {
+ "type": "array",
+ "description": "To specify a set of rules to explicitly exclude",
+ "examples": [["G401"]],
+ "items": {
+ "$ref": "#/definitions/gosec-rules"
+ }
+ },
+ "exclude-generated": {
+ "description": "Exclude generated files",
+ "type": "boolean",
+ "default": false
+ },
+ "severity": {
+ "description": "Filter out the issues with a lower severity than the given value",
+ "type": "string",
+ "enum": ["low", "medium", "high"],
+ "default": "low"
+ },
+ "confidence": {
+ "description": "Filter out the issues with a lower confidence than the given value",
+ "type": "string",
+ "enum": ["low", "medium", "high"],
+ "default": "low"
+ },
+ "config": {
+ "description": "To specify the configuration of rules",
+ "type": "object"
+ },
+ "concurrency": {
+ "description": "Concurrency value",
+ "type": "integer"
+ }
+ }
+ },
+ "gosmopolitan": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "allow-time-local": {
+ "description": "Allow and ignore `time.Local` usages.",
+ "type": "boolean",
+ "default": false
+ },
+ "escape-hatches": {
+ "description": "List of fully qualified names in the `full/pkg/path.name` form, to act as \"i18n escape hatches\".",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignore-tests": {
+ "description": "Ignore test files.",
+ "type": "boolean",
+ "default": false
+ },
+ "watch-for-scripts": {
+ "description": "List of Unicode scripts to watch for any usage in string literals.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "govet": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "settings": {
+ "description": "Settings per analyzer. Map of analyzer name to specific settings.\nRun `go tool vet help` to find out more.",
+ "type": "object",
+ "propertyNames": {
+ "$ref": "#/definitions/govet-analyzers"
+ },
+ "patternProperties": {
+ "^.*$": {
+ "description": "Run `go tool vet help ` to see all settings.",
+ "type": "object"
+ }
+ }
+ },
+ "enable": {
+ "description": "Enable analyzers by name.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/govet-analyzers"
+ }
+ },
+ "disable": {
+ "description": "Disable analyzers by name.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/govet-analyzers"
+ }
+ },
+ "enable-all": {
+ "description": "Enable all analyzers.",
+ "type": "boolean",
+ "default": false
+ },
+ "disable-all": {
+ "description": "Disable all analyzers.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "grouper": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "const-require-single-const": {
+ "type": "boolean",
+ "default": false
+ },
+ "const-require-grouping": {
+ "type": "boolean",
+ "default": false
+ },
+ "import-require-single-import": {
+ "type": "boolean",
+ "default": false
+ },
+ "import-require-grouping": {
+ "type": "boolean",
+ "default": false
+ },
+ "type-require-single-type": {
+ "type": "boolean",
+ "default": false
+ },
+ "type-require-grouping": {
+ "type": "boolean",
+ "default": false
+ },
+ "var-require-single-var": {
+ "type": "boolean",
+ "default": false
+ },
+ "var-require-grouping": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "iface": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "enable": {
+ "description": "Enable analyzers by name.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/iface-analyzers"
+ }
+ },
+ "settings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "unused": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "exclude": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "importas": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "no-unaliased": {
+ "description": "Do not allow unaliased imports of aliased packages.",
+ "type": "boolean",
+ "default": false
+ },
+ "no-extra-aliases": {
+ "description": "Do not allow non-required aliases.",
+ "type": "boolean",
+ "default": false
+ },
+ "alias": {
+ "description": "List of aliases",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "pkg": {
+ "description": "Package path e.g. knative.dev/serving/pkg/apis/autoscaling/v1alpha1",
+ "type": "string"
+ },
+ "alias": {
+ "description": "Package alias e.g. autoscalingv1alpha1",
+ "type": "string"
+ }
+ },
+ "required": ["pkg", "alias"]
+ }
+ }
+ }
+ },
+ "inamedparam": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skip-single-param": {
+ "description": "Skips check for interface methods with only a single parameter.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "ireturn": {
+ "type": "object",
+ "additionalProperties": false,
+ "description": "Use either `reject` or `allow` properties for interfaces matching.",
+ "properties": {
+ "allow": {
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "enum": ["anon", "error", "empty", "stdlib"]
+ }
+ ]
+ }
+ },
+ "reject": {
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "enum": ["anon", "error", "empty", "stdlib"]
+ }
+ ]
+ }
+ }
+ },
+ "anyOf": [
+ {
+ "not": {
+ "properties": {
+ "allow": {
+ "const": "reject"
+ }
+ }
+ },
+ "required": ["allow"]
+ },
+ {
+ "required": ["reject"]
+ }
+ ]
+ },
+ "lll": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "tab-width": {
+ "description": "Width of \"\\t\" in spaces.",
+ "type": "integer",
+ "minimum": 0,
+ "default": 1
+ },
+ "line-length": {
+ "description": "Maximum allowed line length, lines longer will be reported.",
+ "type": "integer",
+ "minimum": 1,
+ "default": 120
+ }
+ }
+ },
+ "maintidx": {
+ "description": "Maintainability index https://docs.microsoft.com/en-us/visualstudio/code-quality/code-metrics-maintainability-index-range-and-meaning?view=vs-2022",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "under": {
+ "description": "Minimum accatpable maintainability index level (see https://docs.microsoft.com/en-us/visualstudio/code-quality/code-metrics-maintainability-index-range-and-meaning?view=vs-2022)",
+ "type": "number",
+ "default": 20
+ }
+ }
+ },
+ "makezero": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "always": {
+ "description": "Allow only slices initialized with a length of zero.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "loggercheck": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "kitlog": {
+ "description": "Allow check for the github.com/go-kit/log library.",
+ "type": "boolean",
+ "default": true
+ },
+ "klog": {
+ "description": "Allow check for the k8s.io/klog/v2 library.",
+ "type": "boolean",
+ "default": true
+ },
+ "logr": {
+ "description": "Allow check for the github.com/go-logr/logr library.",
+ "type": "boolean",
+ "default": true
+ },
+ "slog": {
+ "description": "Allow check for the log/slog library.",
+ "type": "boolean",
+ "default": true
+ },
+ "zap": {
+ "description": "Allow check for the \"sugar logger\" from go.uber.org/zap library.",
+ "type": "boolean",
+ "default": true
+ },
+ "require-string-key": {
+ "description": "Require all logging keys to be inlined constant strings.",
+ "type": "boolean",
+ "default": false
+ },
+ "no-printf-like": {
+ "description": "Require printf-like format specifier (%s, %d for example) not present.",
+ "type": "boolean",
+ "default": false
+ },
+ "rules": {
+ "description": "List of custom rules to check against, where each rule is a single logger pattern, useful for wrapped loggers.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "misspell": {
+ "description": "Correct spellings using locale preferences for US or UK. Default is to use a neutral variety of English.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "locale": {
+ "enum": ["US", "UK"]
+ },
+ "ignore-words": {
+ "description": "List of words to ignore.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "mode": {
+ "description": "Mode of the analysis.",
+ "enum": ["restricted", "", "default"],
+ "default": ""
+ },
+ "extra-words": {
+ "description": "Extra word corrections.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "correction": {
+ "type": "string"
+ },
+ "typo": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "musttag": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "functions": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "tag": {
+ "type": "string"
+ },
+ "arg-pos": {
+ "type": "integer"
+ }
+ }
+ }
+ }
+ }
+ },
+ "nakedret": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-func-lines": {
+ "description": "Report if a function has more lines of code than this value and it has naked returns.",
+ "type": "integer",
+ "minimum": 0,
+ "default": 30
+ }
+ }
+ },
+ "nestif": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "min-complexity": {
+ "description": "Minimum complexity of \"if\" statements to report.",
+ "type": "integer",
+ "default": 5
+ }
+ }
+ },
+ "nilnil": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "detect-opposite": {
+ "type": "boolean",
+ "description": "In addition, detect opposite situation (simultaneous return of non-nil error and valid value).",
+ "default": false
+ },
+ "checked-types": {
+ "type": "array",
+ "description": "List of return types to check.",
+ "items": {
+ "enum": ["chan", "func", "iface", "map", "ptr", "uintptr", "unsafeptr"]
+ },
+ "default": ["chan", "func", "iface", "map", "ptr", "uintptr", "unsafeptr"]
+ }
+ }
+ },
+ "nlreturn": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "block-size": {
+ "description": "set block size that is still ok",
+ "type": "number",
+ "default": 0,
+ "minimum": 0
+ }
+ }
+ },
+ "mnd": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignored-files": {
+ "description": "List of file patterns to exclude from analysis.",
+ "examples": [["magic1_.*.go"]],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignored-functions": {
+ "description": "Comma-separated list of function patterns to exclude from the analysis.",
+ "examples": [["math.*", "http.StatusText", "make"]],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignored-numbers": {
+ "description": "List of numbers to exclude from analysis.",
+ "examples": [["1000", "1234_567_890", "3.14159264"]],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "checks": {
+ "description": "The list of enabled checks, see https://github.com/tommy-muehle/go-mnd/#checks for description.",
+ "type": "array",
+ "items": {
+ "enum": [
+ "argument",
+ "case",
+ "condition",
+ "operation",
+ "return",
+ "assign"
+ ]
+ }
+ }
+ }
+ },
+ "nolintlint": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "allow-unused": {
+ "description": "Enable to ensure that nolint directives are all used.",
+ "type": "boolean",
+ "default": true
+ },
+ "allow-no-explanation": {
+ "description": "Exclude these linters from requiring an explanation.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linters"
+ },
+ "default": []
+ },
+ "require-explanation": {
+ "description": "Enable to require an explanation of nonzero length after each nolint directive.",
+ "type": "boolean",
+ "default": false
+ },
+ "require-specific": {
+ "description": "Enable to require nolint directives to mention the specific linter being suppressed.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "reassign": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "patterns": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "recvcheck": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "disable-builtin": {
+ "description": "Disables the built-in method exclusions.",
+ "type": "boolean",
+ "default": true
+ },
+ "exclusions": {
+ "description": "User-defined method exclusions.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "nonamedreturns": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "report-error-in-defer": {
+ "description": "Report named error if it is assigned inside defer.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "paralleltest": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignore-missing": {
+ "description": "Ignore missing calls to `t.Parallel()` and only report incorrect uses of it.",
+ "type": "boolean",
+ "default": false
+ },
+ "ignore-missing-subtests": {
+ "description": "Ignore missing calls to `t.Parallel()` in subtests. Top-level tests are still required to have `t.Parallel`, but subtests are allowed to skip it.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "perfsprint": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "integer-format": {
+ "description": "Enable/disable optimization of integer formatting.",
+ "type": "boolean",
+ "default": true
+ },
+ "int-conversion": {
+ "description": "Optimizes even if it requires an int or uint type cast.",
+ "type": "boolean",
+ "default": true
+ },
+ "error-format": {
+ "description": "Enable/disable optimization of error formatting.",
+ "type": "boolean",
+ "default": true
+ },
+ "err-error": {
+ "description": "Optimizes into `err.Error()` even if it is only equivalent for non-nil errors.",
+ "type": "boolean",
+ "default": false
+ },
+ "errorf": {
+ "description": "Optimizes `fmt.Errorf`.",
+ "type": "boolean",
+ "default": true
+ },
+ "string-format": {
+ "description": "Enable/disable optimization of string formatting.",
+ "type": "boolean",
+ "default": true
+ },
+ "sprintf1": {
+ "description": "Optimizes `fmt.Sprintf` with only one argument.",
+ "type": "boolean",
+ "default": true
+ },
+ "strconcat": {
+ "description": "Optimizes into strings concatenation.",
+ "type": "boolean",
+ "default": true
+ },
+ "bool-format": {
+ "description": "Enable/disable optimization of bool formatting.",
+ "type": "boolean",
+ "default": true
+ },
+ "hex-format": {
+ "description": "Enable/disable optimization of hex formatting.",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "prealloc": {
+ "description": "We do not recommend using this linter before doing performance profiling.\nFor most programs usage of `prealloc` will be premature optimization.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "simple": {
+ "description": "Report preallocation suggestions only on simple loops that have no returns/breaks/continues/gotos in them.",
+ "type": "boolean",
+ "default": true
+ },
+ "range-loops": {
+ "description": "Report preallocation suggestions on range loops.",
+ "type": "boolean",
+ "default": true
+ },
+ "for-loops": {
+ "description": "Report preallocation suggestions on for loops.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "predeclared": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignore": {
+ "description": "Comma-separated list of predeclared identifiers to not report on.",
+ "type": "string"
+ },
+ "q": {
+ "description": "Include method names and field names (i.e., qualified names) in checks.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "promlinter": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "strict": {},
+ "disabled-linters": {
+ "type": "array",
+ "items": {
+ "enum": [
+ "Help",
+ "MetricUnits",
+ "Counter",
+ "HistogramSummaryReserved",
+ "MetricTypeInName",
+ "ReservedChars",
+ "CamelCase",
+ "UnitAbbreviations"
+ ]
+ }
+ }
+ }
+ },
+ "protogetter": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skip-generated-by": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["protoc-gen-go-my-own-generator"]
+ }
+ },
+ "skip-files": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["*.pb.go"]
+ }
+ },
+ "skip-any-generated": {
+ "description": "Skip any generated files from the checking.",
+ "type": "boolean",
+ "default": false
+ },
+ "replace-first-arg-in-append": {
+ "description": "Skip first argument of append function.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "revive": {
+ "type": "object",
+ "additionalProperties": false,
+ "examples": [
+ {
+ "ignore-generated-header": true,
+ "severity": "warning",
+ "rules": [
+ {
+ "name": "indent-error-flow",
+ "severity": "warning"
+ },
+ {
+ "name": "add-constant",
+ "severity": "warning",
+ "arguments": [
+ {
+ "maxLitCount": "3",
+ "allowStrs": "\"\"",
+ "allowInts": "0,1,2",
+ "allowFloats": "0.0,0.,1.0,1.,2.0,2."
+ }
+ ]
+ }
+ ]
+ }
+ ],
+ "properties": {
+ "max-open-files": {
+ "type": "integer"
+ },
+ "ignore-generated-header": {
+ "type": "boolean"
+ },
+ "confidence": {
+ "type": "number"
+ },
+ "severity": {
+ "type": "string",
+ "enum": ["warning", "error"]
+ },
+ "enable-all-rules": {
+ "type": "boolean",
+ "default": false
+ },
+ "directives": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "name": {
+ "type": "string",
+ "enum": ["specify-disable-reason"]
+ },
+ "severity": {
+ "type": "string",
+ "enum": ["warning", "error"]
+ },
+ "exclude": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "arguments": {
+ "type": "array"
+ }
+ }
+ }
+ },
+ "rules": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["name"],
+ "properties": {
+ "name": {
+ "$ref": "#/definitions/revive-rules",
+ "title": "The rule name"
+ },
+ "disabled": {
+ "type": "boolean"
+ },
+ "severity": {
+ "type": "string",
+ "enum": ["warning", "error"]
+ },
+ "exclude": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "arguments": {
+ "type": "array"
+ }
+ }
+ }
+ }
+ }
+ },
+ "rowserrcheck": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "packages": {
+ "type": "array",
+ "items": {
+ "description": "",
+ "type": "string",
+ "examples": ["github.com/jmoiron/sqlx"]
+ }
+ }
+ }
+ },
+ "sloglint": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "kv-only": {
+ "description": "Enforce using key-value pairs only (incompatible with attr-only).",
+ "type": "boolean",
+ "default": false
+ },
+ "no-global": {
+ "description": "Enforce not using global loggers.",
+ "enum": ["", "all", "default"],
+ "default": ""
+ },
+ "no-mixed-args": {
+ "description": "Enforce not mixing key-value pairs and attributes.",
+ "type": "boolean",
+ "default": true
+ },
+ "context": {
+ "description": "Enforce using methods that accept a context.",
+ "enum": ["", "all", "scope"],
+ "default": ""
+ },
+ "static-msg": {
+ "description": "Enforce using static values for log messages.",
+ "type": "boolean",
+ "default": false
+ },
+ "key-naming-case": {
+ "description": "Enforce a single key naming convention.",
+ "enum": ["snake", "kebab", "camel", "pascal"]
+ },
+ "attr-only": {
+ "description": "Enforce using attributes only (incompatible with kv-only).",
+ "type": "boolean",
+ "default": false
+ },
+ "no-raw-keys": {
+ "description": "Enforce using constants instead of raw keys.",
+ "type": "boolean",
+ "default": false
+ },
+ "forbidden-keys": {
+ "description": "Enforce not using specific keys.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "args-on-sep-lines": {
+ "description": "Enforce putting arguments on separate lines.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "spancheck": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "checks": {
+ "description": "Checks to enable.",
+ "type": "array",
+ "items": {
+ "enum": ["end", "record-error", "set-status"]
+ }
+ },
+ "ignore-check-signatures": {
+ "description": "A list of regexes for function signatures that silence `record-error` and `set-status` reports if found in the call path to a returned error.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "extra-start-span-signatures": {
+ "description": "A list of regexes for additional function signatures that create spans.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "staticcheck": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "checks": {
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "enum": ["all"]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ }
+ }
+ }
+ },
+ "stylecheck": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "checks": {
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "enum": ["all"]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ },
+ "default": [
+ "all",
+ "-ST1000",
+ "-ST1003",
+ "-ST1016",
+ "-ST1020",
+ "-ST1021",
+ "-ST1022"
+ ]
+ },
+ "dot-import-whitelist": {
+ "description": "By default, ST1001 forbids all uses of dot imports in non-test packages. This setting allows setting a whitelist of import paths that can be dot-imported anywhere.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "http-status-code-whitelist": {
+ "description": "ST1013 recommends using constants from the net/http package instead of hard-coding numeric HTTP status codes. This setting specifies a list of numeric status codes that this check does not complain about.",
+ "default": ["200", "400", "404", "500"],
+ "type": "array",
+ "items": {
+ "enum": [
+ "100",
+ "101",
+ "102",
+ "103",
+ "200",
+ "201",
+ "202",
+ "203",
+ "204",
+ "205",
+ "206",
+ "207",
+ "208",
+ "226",
+ "300",
+ "301",
+ "302",
+ "303",
+ "304",
+ "305",
+ "306",
+ "307",
+ "308",
+ "400",
+ "401",
+ "402",
+ "403",
+ "404",
+ "405",
+ "406",
+ "407",
+ "408",
+ "409",
+ "410",
+ "411",
+ "412",
+ "413",
+ "414",
+ "415",
+ "416",
+ "417",
+ "418",
+ "421",
+ "422",
+ "423",
+ "424",
+ "425",
+ "426",
+ "428",
+ "429",
+ "431",
+ "451",
+ "500",
+ "501",
+ "502",
+ "503",
+ "504",
+ "505",
+ "506",
+ "507",
+ "508",
+ "510",
+ "511"
+ ]
+ }
+ },
+ "initialisms": {
+ "description": "ST1003 check, among other things, for the correct capitalization of initialisms. The set of known initialisms can be configured with this option.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "default": [
+ "ACL",
+ "API",
+ "ASCII",
+ "CPU",
+ "CSS",
+ "DNS",
+ "EOF",
+ "GUID",
+ "HTML",
+ "HTTP",
+ "HTTPS",
+ "ID",
+ "IP",
+ "JSON",
+ "QPS",
+ "RAM",
+ "RPC",
+ "SLA",
+ "SMTP",
+ "SQL",
+ "SSH",
+ "TCP",
+ "TLS",
+ "TTL",
+ "UDP",
+ "UI",
+ "GID",
+ "UID",
+ "UUID",
+ "URI",
+ "URL",
+ "UTF8",
+ "VM",
+ "XML",
+ "XMPP",
+ "XSRF",
+ "XSS",
+ "SIP",
+ "RTP",
+ "AMQP",
+ "DB",
+ "TS"
+ ]
+ }
+ }
+ }
+ },
+ "tagalign": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "align": {
+ "description": "Align and sort can be used together or separately.",
+ "type": "boolean",
+ "default": true
+ },
+ "sort": {
+ "description": "Whether enable tags sort.",
+ "type": "boolean",
+ "default": true
+ },
+ "order": {
+ "description": "Specify the order of tags, the other tags will be sorted by name.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "default": [],
+ "examples": [
+ [
+ "json",
+ "yaml",
+ "yml",
+ "toml",
+ "mapstructure",
+ "binding",
+ "validate"
+ ]
+ ]
+ },
+ "strict": {
+ "description": "Whether enable strict style.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "tagliatelle": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "case": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "use-field-name": {
+ "description": "Use the struct field name to check the name of the struct tag.",
+ "type": "boolean",
+ "default": false
+ },
+ "ignored-fields": {
+ "description": "The field names to ignore.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["example"]
+ }
+ },
+ "rules": {
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "$ref": "#/definitions/tagliatelle-cases"
+ }
+ }
+ },
+ "extended-rules": {
+ "description": "Defines the association between tag name and case.",
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["case"],
+ "properties": {
+ "case": {
+ "$ref": "#/definitions/tagliatelle-cases"
+ },
+ "extra-initialisms": {
+ "type": "boolean",
+ "default": false
+ },
+ "initialism-overrides": {
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "overrides": {
+ "description": "Overrides the default/root configuration.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["pkg"],
+ "properties": {
+ "pkg": {
+ "description": "A package path.",
+ "type": "string"
+ },
+ "use-field-name": {
+ "description": "Use the struct field name to check the name of the struct tag.",
+ "type": "boolean",
+ "default": false
+ },
+ "ignored-fields": {
+ "description": "The field names to ignore.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["example"]
+ }
+ },
+ "ignore": {
+ "description": "Ignore the package (takes precedence over all other configurations).",
+ "type": "boolean",
+ "default": false
+ },
+ "rules": {
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "$ref": "#/definitions/tagliatelle-cases"
+ }
+ }
+ },
+ "extended-rules": {
+ "description": "Defines the association between tag name and case.",
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["case"],
+ "properties": {
+ "case": {
+ "$ref": "#/definitions/tagliatelle-cases"
+ },
+ "extra-initialisms": {
+ "type": "boolean",
+ "default": false
+ },
+ "initialism-overrides": {
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "tenv": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "all": {
+ "description": "The option `all` will run against whole test files (`_test.go`) regardless of method/function signatures.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "testifylint": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "enable-all": {
+ "description": "Enable all checkers.",
+ "type": "boolean",
+ "default": false
+ },
+ "disable-all": {
+ "description": "Disable all checkers.",
+ "type": "boolean",
+ "default": false
+ },
+ "enable": {
+ "description": "Enable specific checkers.",
+ "type": "array",
+ "items": {
+ "enum": [
+ "blank-import",
+ "bool-compare",
+ "compares",
+ "contains",
+ "empty",
+ "encoded-compare",
+ "error-is-as",
+ "error-nil",
+ "expected-actual",
+ "float-compare",
+ "formatter",
+ "go-require",
+ "len",
+ "negative-positive",
+ "nil-compare",
+ "regexp",
+ "require-error",
+ "suite-broken-parallel",
+ "suite-dont-use-pkg",
+ "suite-extra-assert-call",
+ "suite-subtest-run",
+ "suite-thelper",
+ "useless-assert"
+ ]
+ },
+ "default": [
+ "blank-import",
+ "bool-compare",
+ "compares",
+ "contains",
+ "empty",
+ "encoded-compare",
+ "error-is-as",
+ "error-nil",
+ "expected-actual",
+ "float-compare",
+ "formatter",
+ "go-require",
+ "len",
+ "negative-positive",
+ "nil-compare",
+ "regexp",
+ "require-error",
+ "suite-broken-parallel",
+ "suite-dont-use-pkg",
+ "suite-extra-assert-call",
+ "suite-subtest-run",
+ "useless-assert"
+ ]
+ },
+ "disable": {
+ "description": "Disable specific checkers.",
+ "type": "array",
+ "items": {
+ "enum": [
+ "blank-import",
+ "bool-compare",
+ "compares",
+ "contains",
+ "empty",
+ "encoded-compare",
+ "error-is-as",
+ "error-nil",
+ "expected-actual",
+ "float-compare",
+ "formatter",
+ "go-require",
+ "len",
+ "negative-positive",
+ "nil-compare",
+ "regexp",
+ "require-error",
+ "suite-broken-parallel",
+ "suite-dont-use-pkg",
+ "suite-extra-assert-call",
+ "suite-subtest-run",
+ "suite-thelper",
+ "useless-assert"
+ ],
+ "default": [
+ "suite-thelper"
+ ]
+ }
+ },
+ "bool-compare": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignore-custom-types": {
+ "description": "To ignore user defined types (over builtin bool).",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "expected-actual": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "pattern": {
+ "description": "Regexp for expected variable name.",
+ "type": "string",
+ "default": "(^(exp(ected)?|want(ed)?)([A-Z]\\w*)?$)|(^(\\w*[a-z])?(Exp(ected)?|Want(ed)?)$)"
+ }
+ }
+ },
+ "formatter": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-format-string": {
+ "description": "To enable go vet's printf checks.",
+ "type": "boolean",
+ "default": true
+ },
+ "require-f-funcs": {
+ "description": "To require f-assertions (e.g. assert.Equalf) if format string is used, even if there are no variable-length variables.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "go-require": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignore-http-handlers": {
+ "description": "To ignore HTTP handlers (like http.HandlerFunc).",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "require-error": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "fn-pattern": {
+ "description": "Regexp for assertions to analyze. If defined, then only matched error assertions will be reported.",
+ "type": "string",
+ "default": ""
+ }
+ }
+ },
+ "suite-extra-assert-call": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "mode": {
+ "description": "To require or remove extra Assert() call?",
+ "type": "string",
+ "enum": ["remove", "require"],
+ "default": "remove"
+ }
+ }
+ }
+ }
+ },
+ "testpackage": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skip-regexp": {
+ "description": "Files with names matching this regular expression are skipped.",
+ "type": "string",
+ "examples": ["(export|internal)_test\\.go"]
+ },
+ "allow-packages": {
+ "description": "List of packages that don't end with _test that tests are allowed to be in.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["example"]
+ }
+ }
+ }
+ },
+ "thelper": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "test": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "begin": {
+ "description": "Check if `t.Helper()` begins helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "first": {
+ "description": "Check if *testing.T is first param of helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "name": {
+ "description": "Check if *testing.T param has t name.",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ },
+ "benchmark": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "begin": {
+ "description": "Check if `b.Helper()` begins helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "first": {
+ "description": "Check if *testing.B is first param of helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "name": {
+ "description": "Check if *testing.B param has b name.",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ },
+ "tb": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "begin": {
+ "description": "Check if `tb.Helper()` begins helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "first": {
+ "description": "Check if *testing.TB is first param of helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "name": {
+ "description": "Check if *testing.TB param has tb name.",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ },
+ "fuzz": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "begin": {
+ "description": "Check if `f.Helper()` begins helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "first": {
+ "description": "Check if *testing.F is first param of helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "name": {
+ "description": "Check if *testing.F param has f name.",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ }
+ }
+ },
+ "usestdlibvars": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "http-method": {
+ "description": "Suggest the use of http.MethodXX.",
+ "type": "boolean",
+ "default": true
+ },
+ "http-status-code": {
+ "description": "Suggest the use of http.StatusXX.",
+ "type": "boolean",
+ "default": true
+ },
+ "time-weekday": {
+ "description": "Suggest the use of time.Weekday.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "time-month": {
+ "description": "Suggest the use of time.Month.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "time-layout": {
+ "description": "Suggest the use of time.Layout.",
+ "type": "boolean",
+ "default": false
+ },
+ "crypto-hash": {
+ "description": "Suggest the use of crypto.Hash.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "default-rpc-path": {
+ "description": "Suggest the use of rpc.DefaultXXPath.",
+ "type": "boolean",
+ "default": false
+ },
+ "sql-isolation-level": {
+ "description": "Suggest the use of sql.LevelXX.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "tls-signature-scheme": {
+ "description": "Suggest the use of tls.SignatureScheme.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "constant-kind": {
+ "description": "Suggest the use of constant.Kind.String().",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "usetesting": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "context-background": {
+ "type": "boolean",
+ "default": true
+ },
+ "context-todo": {
+ "type": "boolean",
+ "default": true
+ },
+ "os-chdir": {
+ "type": "boolean",
+ "default": true
+ },
+ "os-mkdir-temp": {
+ "type": "boolean",
+ "default": true
+ },
+ "os-setenv": {
+ "type": "boolean",
+ "default": true
+ },
+ "os-create-temp": {
+ "type": "boolean",
+ "default": true
+ },
+ "os-temp-dir": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "unconvert": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "fast-math": {
+ "type": "boolean",
+ "default": false
+ },
+ "safe": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "unparam": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-exported": {
+ "description": "Inspect exported functions. Set to true if no external program/library imports your code.\n\nWARNING: if you enable this setting, unparam will report a lot of false-positives in text editors:\nif it's called for subdir of a project it can't find external interfaces. All text editor integrations\nwith golangci-lint call it on a directory with the changed file.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "unused": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "field-writes-are-uses": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ },
+ "post-statements-are-reads": {
+ "description": "",
+ "type": "boolean",
+ "default": false
+ },
+ "exported-fields-are-used": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ },
+ "parameters-are-used": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ },
+ "local-variables-are-used": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ },
+ "generated-is-used": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "varnamelen": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-distance": {
+ "description": "Variables used in at most this N-many lines will be ignored.",
+ "type": "integer",
+ "default": 5
+ },
+ "min-name-length": {
+ "description": "The minimum length of a variable's name that is considered `long`.",
+ "type": "integer",
+ "default": 3
+ },
+ "check-receiver": {
+ "description": "Check method receiver names.",
+ "default": false,
+ "type": "boolean"
+ },
+ "check-return": {
+ "description": "Check named return values.",
+ "default": false,
+ "type": "boolean"
+ },
+ "check-type-param": {
+ "description": "Check type parameters.",
+ "default": false,
+ "type": "boolean"
+ },
+ "ignore-type-assert-ok": {
+ "description": "Ignore `ok` variables that hold the bool return value of a type assertion",
+ "default": false,
+ "type": "boolean"
+ },
+ "ignore-map-index-ok": {
+ "description": "Ignore `ok` variables that hold the bool return value of a map index.",
+ "default": false,
+ "type": "boolean"
+ },
+ "ignore-chan-recv-ok": {
+ "description": "Ignore `ok` variables that hold the bool return value of a channel receive.",
+ "default": false,
+ "type": "boolean"
+ },
+ "ignore-names": {
+ "description": "Optional list of variable names that should be ignored completely.",
+ "default": [[]],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignore-decls": {
+ "description": "Optional list of variable declarations that should be ignored completely.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "examples": [
+ ["c echo.Context", "t testing.T", "f *foo.Bar", "const C"]
+ ]
+ }
+ }
+ },
+ "whitespace": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "multi-if": {
+ "description": "Enforces newlines (or comments) after every multi-line if statement",
+ "type": "boolean",
+ "default": false
+ },
+ "multi-func": {
+ "description": "Enforces newlines (or comments) after every multi-line function signature",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "wrapcheck": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "extra-ignore-sigs": {
+ "description": "An array of strings specifying additional substrings of signatures to ignore.",
+ "default": [
+ ".CustomError(",
+ ".SpecificWrap("
+ ],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignoreSigs": {
+ "description": "An array of strings which specify substrings of signatures to ignore.",
+ "default": [
+ ".Errorf(",
+ "errors.New(",
+ "errors.Unwrap(",
+ ".Wrap(",
+ ".Wrapf(",
+ ".WithMessage(",
+ ".WithMessagef(",
+ ".WithStack("
+ ],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignoreSigRegexps": {
+ "description": "An array of strings which specify regular expressions of signatures to ignore.",
+ "default": [""],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignorePackageGlobs": {
+ "description": "An array of glob patterns which, if any match the package of the function returning the error, will skip wrapcheck analysis for this error.",
+ "default": [""],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignoreInterfaceRegexps": {
+ "description": "An array of glob patterns which, if matched to an underlying interface name, will ignore unwrapped errors returned from a function whose call is defined on the given interface.",
+ "default": [""],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "wsl": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "allow-assign-and-anything": {
+ "description": "Controls if you may cuddle assignments and anything without needing an empty line between them.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-assign-and-call": {
+ "description": "Allow calls and assignments to be cuddled as long as the lines have any matching variables, fields or types.",
+ "type": "boolean",
+ "default": true
+ },
+ "allow-cuddle-declarations": {
+ "description": "Allow declarations (var) to be cuddled.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-cuddle-with-calls": {
+ "description": "A list of call idents that everything can be cuddled with.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "allow-cuddle-with-rhs": {
+ "description": "AllowCuddleWithRHS is a list of right hand side variables that is allowed to be cuddled with anything.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "allow-multiline-assign": {
+ "description": "Allow multiline assignments to be cuddled.",
+ "type": "boolean",
+ "default": true
+ },
+ "allow-separated-leading-comment": {
+ "description": "Allow leading comments to be separated with empty lines.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-trailing-comment": {
+ "description": "Allow trailing comments in ending of blocks.",
+ "type": "boolean",
+ "default": false
+ },
+ "error-variable-names": {
+ "description": "When force-err-cuddling is enabled this is a list of names used for error variables to check for in the conditional.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "force-case-trailing-whitespace": {
+ "description": "Force newlines in end of case at this limit (0 = never).",
+ "type": "integer",
+ "minimum": 0,
+ "default": 0
+ },
+ "force-err-cuddling": {
+ "description": "Causes an error when an If statement that checks an error variable doesn't cuddle with the assignment of that variable.",
+ "type": "boolean",
+ "default": false
+ },
+ "force-short-decl-cuddling": {
+ "description": "Causes an error if a short declaration (:=) cuddles with anything other than another short declaration.",
+ "type": "boolean",
+ "default": false
+ },
+ "strict-append": {
+ "description": "If true, append is only allowed to be cuddled if appending value is matching variables, fields or types on line above.",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "copyloopvar": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-alias": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "custom": {
+ "description": "The custom section can be used to define linter plugins to be loaded at runtime. See README of golangci-lint for more information.\nEach custom linter should have a unique name.",
+ "type": "object",
+ "patternProperties": {
+ "^.*$": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "type": {
+ "description": "The plugin type.",
+ "enum": ["module", "goplugin"],
+ "default": "goplugin"
+ },
+ "path": {
+ "description": "The path to the plugin *.so. Can be absolute or local.",
+ "type": "string",
+ "examples": ["/path/to/example.so"]
+ },
+ "description": {
+ "description": "The description of the linter, for documentation purposes only.",
+ "type": "string"
+ },
+ "original-url": {
+ "description": "Intended to point to the repo location of the linter, for documentation purposes only.",
+ "type": "string"
+ },
+ "settings": {
+ "description": "Plugins settings/configuration. Only work with plugin based on `linterdb.PluginConstructor`.",
+ "type": "object"
+ }
+ },
+ "oneOf": [
+ {
+ "properties": {
+ "type": {"enum": ["module"] }
+ },
+ "required": ["type"]
+ },
+ {
+ "required": ["path"]
+ }
+ ]
+ }
+ }
+ }
+ }
+ },
+ "linters": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "enable": {
+ "description": "List of enabled linters.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linters"
+ }
+ },
+ "disable": {
+ "description": "List of disabled linters.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linters"
+ }
+ },
+ "enable-all": {
+ "description": "Whether to enable all linters. You can re-disable them with `disable` explicitly.",
+ "type": "boolean",
+ "default": false
+ },
+ "disable-all": {
+ "description": "Whether to disable all linters. You can re-enable them with `enable` explicitly.",
+ "type": "boolean",
+ "default": false
+ },
+ "presets": {
+ "description": "Allow to use different presets of linters",
+ "type": "array",
+ "items": {
+ "enum": [
+ "bugs",
+ "comment",
+ "complexity",
+ "error",
+ "format",
+ "import",
+ "metalinter",
+ "module",
+ "performance",
+ "sql",
+ "style",
+ "test",
+ "unused"
+ ]
+ }
+ },
+ "fast": {
+ "description": "Enable run of fast linters.",
+ "type": "boolean",
+ "default": false
+ },
+ "exclusions":{
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "generated": {
+ "enum": ["strict", "lax", "disable"],
+ "default": "lax"
+ },
+ "warn-unused": {
+ "type": "boolean",
+ "default": false
+ },
+ "default": {
+ "type": "array",
+ "items": {
+ "enum": [
+ "comments",
+ "stdErrorHandling",
+ "commonFalsePositives",
+ "legacy"
+ ]
+ }
+ },
+ "rules": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "path": {
+ "type": "string"
+ },
+ "path-except": {
+ "type": "string"
+ },
+ "linters": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linters"
+ }
+ },
+ "text": {
+ "type": "string"
+ },
+ "source": {
+ "type": "string"
+ }
+ },
+ "anyOf": [
+ { "required": ["path"] },
+ { "required": ["path-except"] },
+ { "required": ["linters"] },
+ { "required": ["text"] },
+ { "required": ["source"] }
+ ]
+ }
+ },
+ "paths": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "paths-except": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "issues": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "exclude": {
+ "description": "List of regular expressions of issue texts to exclude.\nBut independently from this option we use default exclude patterns. Their usage can be controlled through `exclude-use-default`.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "exclude-rules": {
+ "description": "Exclude configuration per-path, per-linter, per-text and per-source",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "path": {
+ "type": "string"
+ },
+ "path-except": {
+ "type": "string"
+ },
+ "linters": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linters"
+ }
+ },
+ "text": {
+ "type": "string"
+ },
+ "source": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "exclude-use-default": {
+ "description": "Independently from option `exclude` we use default exclude patterns. This behavior can be disabled by this option.",
+ "type": "boolean",
+ "default": true
+ },
+ "exclude-case-sensitive": {
+ "description": "If set to true, exclude and exclude-rules regular expressions become case sensitive.",
+ "type": "boolean",
+ "default": false
+ },
+ "exclude-generated": {
+ "description": "Mode of the generated files analysis.",
+ "enum": ["lax", "strict", "disable"],
+ "default": "lax"
+ },
+ "exclude-dirs": {
+ "description": "Which directories to exclude: issues from them won't be reported.",
+ "type": "array",
+ "items": {
+ "description": "You can use regexp here. The regexp is applied on the full path.\n\"/\" will be replaced by current OS file path separator to properly work on Windows.",
+ "type": "string",
+ "examples": ["generated.*"]
+ },
+ "default": [],
+ "examples": [["src/external_libs", "autogenerated_by_my_lib"]]
+ },
+ "exclude-dirs-use-default": {
+ "description": "Enable exclusion of directories \"vendor\", \"third_party\", \"testdata\", \"examples\", \"Godeps\", and \"builtin\".",
+ "type": "boolean",
+ "default": true
+ },
+ "exclude-files": {
+ "description": "Which files to exclude: they will be analyzed, but issues from them will not be reported.",
+ "type": "array",
+ "items": {
+ "description": "You can use regexp here. There is no need to include all autogenerated files, we confidently recognize them. If that is not the case, please let us know.\n\"/\" will be replaced by current OS file path separator to properly work on Windows.",
+ "type": "string",
+ "examples": [".*\\.my\\.go$"]
+ },
+ "default": [],
+ "examples": [[".*\\.my\\.go$", "lib/bad.go"]]
+ },
+ "include": {
+ "description": "The list of ids of default excludes to include or disable.",
+ "type": "array",
+ "items": {
+ "enum": [
+ "EXC0001",
+ "EXC0002",
+ "EXC0003",
+ "EXC0004",
+ "EXC0005",
+ "EXC0006",
+ "EXC0007",
+ "EXC0008",
+ "EXC0009",
+ "EXC0010",
+ "EXC0011",
+ "EXC0012",
+ "EXC0013",
+ "EXC0014",
+ "EXC0015"
+ ]
+ },
+ "default": []
+ },
+ "max-issues-per-linter": {
+ "description": "Maximum issues count per one linter. Set to 0 to disable.",
+ "type": "integer",
+ "default": 50,
+ "minimum": 0
+ },
+ "max-same-issues": {
+ "description": "Maximum count of issues with the same text. Set to 0 to disable.",
+ "type": "integer",
+ "default": 3,
+ "minimum": 0
+ },
+ "new": {
+ "description": "Show only new issues: if there are unstaged changes or untracked files, only those changes are analyzed, else only changes in HEAD~ are analyzed.",
+ "type": "boolean",
+ "default": false
+ },
+ "new-from-merge-base": {
+ "description": "Show only new issues created after the best common ancestor (merge-base against HEAD).",
+ "type": "string"
+ },
+ "new-from-rev": {
+ "description": "Show only new issues created after this git revision.",
+ "type": "string"
+ },
+ "new-from-patch": {
+ "description": "Show only new issues created in git patch with this file path.",
+ "type": "string",
+ "examples": ["path/to/patch/file"]
+ },
+ "fix": {
+ "description": "Fix found issues (if it's supported by the linter).",
+ "type": "boolean",
+ "default": false
+ },
+ "uniq-by-line": {
+ "description": "Make issues output unique by line.",
+ "type": "boolean",
+ "default": true
+ },
+ "whole-files": {
+ "description": "Show issues in any part of update files (requires new-from-rev or new-from-patch).",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "severity": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "default-severity": {
+ "description": "Set the default severity for issues. If severity rules are defined and the issues do not match or no severity is provided to the rule this will be the default severity applied. Severities should match the supported severity names of the selected out format.",
+ "type": "string",
+ "default": ""
+ },
+ "case-sensitive": {
+ "description": "If set to true, severity-rules regular expressions become case sensitive.",
+ "type": "boolean",
+ "default": false
+ },
+ "rules": {
+ "description": "When a list of severity rules are provided, severity information will be added to lint issues. Severity rules have the same filtering capability as exclude rules except you are allowed to specify one matcher per severity rule.\nOnly affects out formats that support setting severity information.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "severity": {
+ "type": "string"
+ },
+ "path": {
+ "type": "string"
+ },
+ "path-except": {
+ "type": "string"
+ },
+ "linters": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linters"
+ }
+ },
+ "text": {
+ "type": "string"
+ },
+ "source": {
+ "type": "string"
+ }
+ },
+ "required": ["severity"],
+ "anyOf": [
+ { "required": ["path"] },
+ { "required": ["path-except"] },
+ { "required": ["linters"] },
+ { "required": ["text"] },
+ { "required": ["source"] }
+ ]
+ },
+ "default": []
+ }
+ },
+ "required": ["default-severity"]
+ }
+ }
+}
diff --git a/vendor/github.com/golangci/golangci-lint/v2/jsonschema/golangci.v2.0.jsonschema.json b/vendor/github.com/golangci/golangci-lint/v2/jsonschema/golangci.v2.0.jsonschema.json
new file mode 100644
index 000000000..437943b5f
--- /dev/null
+++ b/vendor/github.com/golangci/golangci-lint/v2/jsonschema/golangci.v2.0.jsonschema.json
@@ -0,0 +1,4738 @@
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "$id": "https://json.schemastore.org/golangci-lint.json",
+ "definitions": {
+ "gocritic-checks": {
+ "enum": [
+ "appendAssign",
+ "appendCombine",
+ "argOrder",
+ "assignOp",
+ "badCall",
+ "badCond",
+ "badLock",
+ "badRegexp",
+ "badSorting",
+ "badSyncOnceFunc",
+ "boolExprSimplify",
+ "builtinShadow",
+ "builtinShadowDecl",
+ "captLocal",
+ "caseOrder",
+ "codegenComment",
+ "commentFormatting",
+ "commentedOutCode",
+ "commentedOutImport",
+ "defaultCaseOrder",
+ "deferInLoop",
+ "deferUnlambda",
+ "deprecatedComment",
+ "docStub",
+ "dupArg",
+ "dupBranchBody",
+ "dupCase",
+ "dupImport",
+ "dupSubExpr",
+ "dynamicFmtString",
+ "elseif",
+ "emptyDecl",
+ "emptyFallthrough",
+ "emptyStringTest",
+ "equalFold",
+ "evalOrder",
+ "exitAfterDefer",
+ "exposedSyncMutex",
+ "externalErrorReassign",
+ "filepathJoin",
+ "flagDeref",
+ "flagName",
+ "hexLiteral",
+ "httpNoBody",
+ "hugeParam",
+ "ifElseChain",
+ "importShadow",
+ "indexAlloc",
+ "initClause",
+ "ioutilDeprecated",
+ "mapKey",
+ "methodExprCall",
+ "nestingReduce",
+ "newDeref",
+ "nilValReturn",
+ "octalLiteral",
+ "offBy1",
+ "paramTypeCombine",
+ "preferDecodeRune",
+ "preferFilepathJoin",
+ "preferFprint",
+ "preferStringWriter",
+ "preferWriteByte",
+ "ptrToRefParam",
+ "rangeAppendAll",
+ "rangeExprCopy",
+ "rangeValCopy",
+ "redundantSprint",
+ "regexpMust",
+ "regexpPattern",
+ "regexpSimplify",
+ "returnAfterHttpError",
+ "ruleguard",
+ "singleCaseSwitch",
+ "sliceClear",
+ "sloppyLen",
+ "sloppyReassign",
+ "sloppyTypeAssert",
+ "sortSlice",
+ "sprintfQuotedString",
+ "sqlQuery",
+ "stringConcatSimplify",
+ "stringXbytes",
+ "stringsCompare",
+ "switchTrue",
+ "syncMapLoadAndDelete",
+ "timeExprSimplify",
+ "todoCommentWithoutDetail",
+ "tooManyResultsChecker",
+ "truncateCmp",
+ "typeAssertChain",
+ "typeDefFirst",
+ "typeSwitchVar",
+ "typeUnparen",
+ "uncheckedInlineErr",
+ "underef",
+ "unlabelStmt",
+ "unlambda",
+ "unnamedResult",
+ "unnecessaryBlock",
+ "unnecessaryDefer",
+ "unslice",
+ "valSwap",
+ "weakCond",
+ "whyNoLint",
+ "wrapperFunc",
+ "yodaStyleExpr"
+ ]
+ },
+ "gocritic-tags": {
+ "enum": [
+ "diagnostic",
+ "style",
+ "performance",
+ "experimental",
+ "opinionated",
+ "security"
+ ]
+ },
+ "staticcheck-checks": {
+ "enum": [
+ "*",
+ "all",
+ "SA*",
+ "-SA*",
+ "SA1*",
+ "-SA1*",
+ "SA1000",
+ "-SA1000",
+ "SA1001",
+ "-SA1001",
+ "SA1002",
+ "-SA1002",
+ "SA1003",
+ "-SA1003",
+ "SA1004",
+ "-SA1004",
+ "SA1005",
+ "-SA1005",
+ "SA1006",
+ "-SA1006",
+ "SA1007",
+ "-SA1007",
+ "SA1008",
+ "-SA1008",
+ "SA1010",
+ "-SA1010",
+ "SA1011",
+ "-SA1011",
+ "SA1012",
+ "-SA1012",
+ "SA1013",
+ "-SA1013",
+ "SA1014",
+ "-SA1014",
+ "SA1015",
+ "-SA1015",
+ "SA1016",
+ "-SA1016",
+ "SA1017",
+ "-SA1017",
+ "SA1018",
+ "-SA1018",
+ "SA1019",
+ "-SA1019",
+ "SA1020",
+ "-SA1020",
+ "SA1021",
+ "-SA1021",
+ "SA1023",
+ "-SA1023",
+ "SA1024",
+ "-SA1024",
+ "SA1025",
+ "-SA1025",
+ "SA1026",
+ "-SA1026",
+ "SA1027",
+ "-SA1027",
+ "SA1028",
+ "-SA1028",
+ "SA1029",
+ "-SA1029",
+ "SA1030",
+ "-SA1030",
+ "SA1031",
+ "-SA1031",
+ "SA1032",
+ "-SA1032",
+ "SA2*",
+ "-SA2*",
+ "SA2000",
+ "-SA2000",
+ "SA2001",
+ "-SA2001",
+ "SA2002",
+ "-SA2002",
+ "SA2003",
+ "-SA2003",
+ "SA3*",
+ "-SA3*",
+ "SA3000",
+ "-SA3000",
+ "SA3001",
+ "-SA3001",
+ "SA4*",
+ "-SA4*",
+ "SA4000",
+ "-SA4000",
+ "SA4001",
+ "-SA4001",
+ "SA4003",
+ "-SA4003",
+ "SA4004",
+ "-SA4004",
+ "SA4005",
+ "-SA4005",
+ "SA4006",
+ "-SA4006",
+ "SA4008",
+ "-SA4008",
+ "SA4009",
+ "-SA4009",
+ "SA4010",
+ "-SA4010",
+ "SA4011",
+ "-SA4011",
+ "SA4012",
+ "-SA4012",
+ "SA4013",
+ "-SA4013",
+ "SA4014",
+ "-SA4014",
+ "SA4015",
+ "-SA4015",
+ "SA4016",
+ "-SA4016",
+ "SA4017",
+ "-SA4017",
+ "SA4018",
+ "-SA4018",
+ "SA4019",
+ "-SA4019",
+ "SA4020",
+ "-SA4020",
+ "SA4021",
+ "-SA4021",
+ "SA4022",
+ "-SA4022",
+ "SA4023",
+ "-SA4023",
+ "SA4024",
+ "-SA4024",
+ "SA4025",
+ "-SA4025",
+ "SA4026",
+ "-SA4026",
+ "SA4027",
+ "-SA4027",
+ "SA4028",
+ "-SA4028",
+ "SA4029",
+ "-SA4029",
+ "SA4030",
+ "-SA4030",
+ "SA4031",
+ "-SA4031",
+ "SA4032",
+ "-SA4032",
+ "SA5*",
+ "-SA5*",
+ "SA5000",
+ "-SA5000",
+ "SA5001",
+ "-SA5001",
+ "SA5002",
+ "-SA5002",
+ "SA5003",
+ "-SA5003",
+ "SA5004",
+ "-SA5004",
+ "SA5005",
+ "-SA5005",
+ "SA5007",
+ "-SA5007",
+ "SA5008",
+ "-SA5008",
+ "SA5009",
+ "-SA5009",
+ "SA5010",
+ "-SA5010",
+ "SA5011",
+ "-SA5011",
+ "SA5012",
+ "-SA5012",
+ "SA6*",
+ "-SA6*",
+ "SA6000",
+ "-SA6000",
+ "SA6001",
+ "-SA6001",
+ "SA6002",
+ "-SA6002",
+ "SA6003",
+ "-SA6003",
+ "SA6005",
+ "-SA6005",
+ "SA6006",
+ "-SA6006",
+ "SA9*",
+ "-SA9*",
+ "SA9001",
+ "-SA9001",
+ "SA9002",
+ "-SA9002",
+ "SA9003",
+ "-SA9003",
+ "SA9004",
+ "-SA9004",
+ "SA9005",
+ "-SA9005",
+ "SA9006",
+ "-SA9006",
+ "SA9007",
+ "-SA9007",
+ "SA9008",
+ "-SA9008",
+ "SA9009",
+ "-SA9009",
+ "ST*",
+ "-ST*",
+ "ST1*",
+ "-ST1*",
+ "ST1000",
+ "-ST1000",
+ "ST1001",
+ "-ST1001",
+ "ST1003",
+ "-ST1003",
+ "ST1005",
+ "-ST1005",
+ "ST1006",
+ "-ST1006",
+ "ST1008",
+ "-ST1008",
+ "ST1011",
+ "-ST1011",
+ "ST1012",
+ "-ST1012",
+ "ST1013",
+ "-ST1013",
+ "ST1015",
+ "-ST1015",
+ "ST1016",
+ "-ST1016",
+ "ST1017",
+ "-ST1017",
+ "ST1018",
+ "-ST1018",
+ "ST1019",
+ "-ST1019",
+ "ST1020",
+ "-ST1020",
+ "ST1021",
+ "-ST1021",
+ "ST1022",
+ "-ST1022",
+ "ST1023",
+ "-ST1023",
+ "S*",
+ "-S*",
+ "S1*",
+ "-S1*",
+ "S1000",
+ "-S1000",
+ "S1001",
+ "-S1001",
+ "S1002",
+ "-S1002",
+ "S1003",
+ "-S1003",
+ "S1004",
+ "-S1004",
+ "S1005",
+ "-S1005",
+ "S1006",
+ "-S1006",
+ "S1007",
+ "-S1007",
+ "S1008",
+ "-S1008",
+ "S1009",
+ "-S1009",
+ "S1010",
+ "-S1010",
+ "S1011",
+ "-S1011",
+ "S1012",
+ "-S1012",
+ "S1016",
+ "-S1016",
+ "S1017",
+ "-S1017",
+ "S1018",
+ "-S1018",
+ "S1019",
+ "-S1019",
+ "S1020",
+ "-S1020",
+ "S1021",
+ "-S1021",
+ "S1023",
+ "-S1023",
+ "S1024",
+ "-S1024",
+ "S1025",
+ "-S1025",
+ "S1028",
+ "-S1028",
+ "S1029",
+ "-S1029",
+ "S1030",
+ "-S1030",
+ "S1031",
+ "-S1031",
+ "S1032",
+ "-S1032",
+ "S1033",
+ "-S1033",
+ "S1034",
+ "-S1034",
+ "S1035",
+ "-S1035",
+ "S1036",
+ "-S1036",
+ "S1037",
+ "-S1037",
+ "S1038",
+ "-S1038",
+ "S1039",
+ "-S1039",
+ "S1040",
+ "-S1040",
+ "QF*",
+ "-QF*",
+ "QF1*",
+ "-QF1*",
+ "QF1001",
+ "-QF1001",
+ "QF1002",
+ "-QF1002",
+ "QF1003",
+ "-QF1003",
+ "QF1004",
+ "-QF1004",
+ "QF1005",
+ "-QF1005",
+ "QF1006",
+ "-QF1006",
+ "QF1007",
+ "-QF1007",
+ "QF1008",
+ "-QF1008",
+ "QF1009",
+ "-QF1009",
+ "QF1010",
+ "-QF1010",
+ "QF1011",
+ "-QF1011",
+ "QF1012",
+ "-QF1012"
+ ]
+ },
+ "gosec-rules": {
+ "enum": [
+ "G101",
+ "G102",
+ "G103",
+ "G104",
+ "G106",
+ "G107",
+ "G108",
+ "G109",
+ "G110",
+ "G111",
+ "G112",
+ "G113",
+ "G114",
+ "G115",
+ "G201",
+ "G202",
+ "G203",
+ "G204",
+ "G301",
+ "G302",
+ "G303",
+ "G304",
+ "G305",
+ "G306",
+ "G307",
+ "G401",
+ "G402",
+ "G403",
+ "G404",
+ "G405",
+ "G406",
+ "G501",
+ "G502",
+ "G503",
+ "G504",
+ "G505",
+ "G506",
+ "G507",
+ "G601",
+ "G602"
+ ]
+ },
+ "govet-analyzers": {
+ "enum": [
+ "appends",
+ "asmdecl",
+ "assign",
+ "atomic",
+ "atomicalign",
+ "bools",
+ "buildtag",
+ "cgocall",
+ "composites",
+ "copylocks",
+ "deepequalerrors",
+ "defers",
+ "directive",
+ "errorsas",
+ "fieldalignment",
+ "findcall",
+ "framepointer",
+ "httpresponse",
+ "ifaceassert",
+ "loopclosure",
+ "lostcancel",
+ "nilfunc",
+ "nilness",
+ "printf",
+ "reflectvaluecompare",
+ "shadow",
+ "shift",
+ "sigchanyzer",
+ "slog",
+ "sortslice",
+ "stdmethods",
+ "stdversion",
+ "stringintconv",
+ "structtag",
+ "testinggoroutine",
+ "tests",
+ "timeformat",
+ "unmarshal",
+ "unreachable",
+ "unsafeptr",
+ "unusedresult",
+ "unusedwrite",
+ "waitgroup"
+ ]
+ },
+ "revive-rules": {
+ "enum": [
+ "add-constant",
+ "argument-limit",
+ "atomic",
+ "banned-characters",
+ "bare-return",
+ "blank-imports",
+ "bool-literal-in-expr",
+ "call-to-gc",
+ "cognitive-complexity",
+ "comment-spacings",
+ "comments-density",
+ "confusing-naming",
+ "confusing-results",
+ "constant-logical-expr",
+ "context-as-argument",
+ "context-keys-type",
+ "cyclomatic",
+ "datarace",
+ "deep-exit",
+ "defer",
+ "dot-imports",
+ "duplicated-imports",
+ "early-return",
+ "empty-block",
+ "empty-lines",
+ "enforce-map-style",
+ "enforce-repeated-arg-type-style",
+ "enforce-slice-style",
+ "error-naming",
+ "error-return",
+ "error-strings",
+ "errorf",
+ "exported",
+ "file-header",
+ "file-length-limit",
+ "filename-format",
+ "flag-parameter",
+ "function-length",
+ "function-result-limit",
+ "get-return",
+ "identical-branches",
+ "if-return",
+ "import-alias-naming",
+ "import-shadowing",
+ "imports-blocklist",
+ "increment-decrement",
+ "indent-error-flow",
+ "line-length-limit",
+ "max-control-nesting",
+ "max-public-structs",
+ "modifies-parameter",
+ "modifies-value-receiver",
+ "nested-structs",
+ "optimize-operands-order",
+ "package-comments",
+ "range-val-address",
+ "range-val-in-closure",
+ "range",
+ "receiver-naming",
+ "redefines-builtin-id",
+ "redundant-build-tag",
+ "redundant-import-alias",
+ "redundant-test-main-exit",
+ "string-format",
+ "string-of-int",
+ "struct-tag",
+ "superfluous-else",
+ "time-equal",
+ "time-naming",
+ "unchecked-type-assertion",
+ "unconditional-recursion",
+ "unexported-naming",
+ "unexported-return",
+ "unhandled-error",
+ "unnecessary-stmt",
+ "unreachable-code",
+ "unused-parameter",
+ "unused-receiver",
+ "use-any",
+ "use-errors-new",
+ "useless-break",
+ "var-declaration",
+ "var-naming",
+ "waitgroup-by-value"
+ ]
+ },
+ "iface-analyzers": {
+ "enum": [
+ "identical",
+ "unused",
+ "opaque"
+ ]
+ },
+ "tagliatelle-cases": {
+ "enum": [
+ "",
+ "camel",
+ "pascal",
+ "kebab",
+ "snake",
+ "goCamel",
+ "goPascal",
+ "goKebab",
+ "goSnake",
+ "upper",
+ "upperSnake",
+ "lower",
+ "header"
+ ]
+ },
+ "relative-path-modes": {
+ "enum": [
+ "gomod",
+ "gitroot",
+ "cfg",
+ "wd"
+ ]
+ },
+ "simple-format": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "path": {
+ "$ref": "#/definitions/formats-path",
+ "default": "stdout"
+ }
+ }
+ },
+ "formats-path" : {
+ "anyOf": [
+ {
+ "enum": [
+ "stdout",
+ "stderr"
+ ]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ },
+ "linter-names": {
+ "$comment": "anyOf with enum is used to allow auto-completion of non-custom linters",
+ "description": "Usable linter names.",
+ "anyOf": [
+ {
+ "enum": [
+ "asasalint",
+ "asciicheck",
+ "bidichk",
+ "bodyclose",
+ "canonicalheader",
+ "containedctx",
+ "contextcheck",
+ "copyloopvar",
+ "cyclop",
+ "decorder",
+ "depguard",
+ "dogsled",
+ "dupl",
+ "dupword",
+ "durationcheck",
+ "errcheck",
+ "errchkjson",
+ "errname",
+ "errorlint",
+ "exhaustive",
+ "exhaustruct",
+ "exptostd",
+ "fatcontext",
+ "forbidigo",
+ "forcetypeassert",
+ "funlen",
+ "ginkgolinter",
+ "gocheckcompilerdirectives",
+ "gochecknoglobals",
+ "gochecknoinits",
+ "gochecksumtype",
+ "gocognit",
+ "goconst",
+ "gocritic",
+ "gocyclo",
+ "godot",
+ "godox",
+ "err113",
+ "goheader",
+ "gomoddirectives",
+ "gomodguard",
+ "goprintffuncname",
+ "gosec",
+ "gosimple",
+ "gosmopolitan",
+ "govet",
+ "grouper",
+ "iface",
+ "importas",
+ "inamedparam",
+ "ineffassign",
+ "interfacebloat",
+ "intrange",
+ "ireturn",
+ "lll",
+ "loggercheck",
+ "maintidx",
+ "makezero",
+ "mirror",
+ "misspell",
+ "mnd",
+ "musttag",
+ "nakedret",
+ "nestif",
+ "nilerr",
+ "nilnesserr",
+ "nilnil",
+ "nlreturn",
+ "noctx",
+ "nolintlint",
+ "nonamedreturns",
+ "nosprintfhostport",
+ "paralleltest",
+ "perfsprint",
+ "prealloc",
+ "predeclared",
+ "promlinter",
+ "protogetter",
+ "reassign",
+ "recvcheck",
+ "revive",
+ "rowserrcheck",
+ "sloglint",
+ "sqlclosecheck",
+ "staticcheck",
+ "stylecheck",
+ "tagalign",
+ "tagliatelle",
+ "testableexamples",
+ "testifylint",
+ "testpackage",
+ "thelper",
+ "tparallel",
+ "unconvert",
+ "unparam",
+ "unused",
+ "usestdlibvars",
+ "usetesting",
+ "varnamelen",
+ "wastedassign",
+ "whitespace",
+ "wrapcheck",
+ "wsl",
+ "zerologlint"
+ ]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ },
+ "formatter-names": {
+ "description": "Usable formatter names.",
+ "enum": [
+ "gci",
+ "gofmt",
+ "gofumpt",
+ "goimports",
+ "golines"
+ ]
+ },
+ "settings": {
+ "definitions": {
+ "dupwordSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "keywords": {
+ "description": "Keywords for detecting duplicate words. If this list is not empty, only the words defined in this list will be detected.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["the", "and", "a"]
+ }
+ },
+ "ignore": {
+ "description": "Keywords used to ignore detection.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["0C0C"]
+ }
+ }
+ }
+ },
+ "asasalintSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "exclude": {
+ "description": "To specify a set of function names to exclude.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["\\.Wrapf"]
+ }
+ },
+ "use-builtin-exclusions": {
+ "description": "To enable/disable the asasalint builtin exclusions of function names.",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "bidichkSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "left-to-right-embedding": {
+ "description": "Disallow: LEFT-TO-RIGHT-EMBEDDING",
+ "type": "boolean",
+ "default": false
+ },
+ "right-to-left-embedding": {
+ "description": "Disallow: RIGHT-TO-LEFT-EMBEDDING",
+ "type": "boolean",
+ "default": false
+ },
+ "pop-directional-formatting": {
+ "description": "Disallow: POP-DIRECTIONAL-FORMATTING",
+ "type": "boolean",
+ "default": false
+ },
+ "left-to-right-override": {
+ "description": "Disallow: LEFT-TO-RIGHT-OVERRIDE",
+ "type": "boolean",
+ "default": false
+ },
+ "right-to-left-override": {
+ "description": "Disallow: RIGHT-TO-LEFT-OVERRIDE",
+ "type": "boolean",
+ "default": false
+ },
+ "left-to-right-isolate": {
+ "description": "Disallow: LEFT-TO-RIGHT-ISOLATE",
+ "type": "boolean",
+ "default": false
+ },
+ "right-to-left-isolate": {
+ "description": "Disallow: RIGHT-TO-LEFT-ISOLATE",
+ "type": "boolean",
+ "default": false
+ },
+ "first-strong-isolate": {
+ "description": "Disallow: FIRST-STRONG-ISOLATE",
+ "type": "boolean",
+ "default": false
+ },
+ "pop-directional-isolate": {
+ "description": "Disallow: POP-DIRECTIONAL-ISOLATE",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "cyclopSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-complexity": {
+ "description": "Max complexity the function can have",
+ "type": "integer",
+ "default": 10,
+ "minimum": 0
+ },
+ "package-average": {
+ "description": "Max average complexity in package",
+ "type": "number",
+ "default": 0,
+ "minimum": 0
+ }
+ }
+ },
+ "decorderSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "dec-order": {
+ "type": "array",
+ "default": [["type", "const", "var", "func"]],
+ "items": {
+ "enum": ["type", "const", "var", "func"]
+ }
+ },
+ "ignore-underscore-vars": {
+ "description": "Underscore vars (vars with \"_\" as the name) will be ignored at all checks",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-dec-order-check": {
+ "description": "Order of declarations is not checked",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-init-func-first-check": {
+ "description": "Allow init func to be anywhere in file",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-dec-num-check": {
+ "description": "Multiple global type, const and var declarations are allowed",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-type-dec-num-check": {
+ "description": "Type declarations will be ignored for dec num check",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-const-dec-num-check": {
+ "description": "Const declarations will be ignored for dec num check",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-var-dec-num-check": {
+ "description": "Var declarations will be ignored for dec num check",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ },
+ "depguardSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "rules": {
+ "description": "Rules to apply.",
+ "type": "object",
+ "additionalProperties": false,
+ "patternProperties": {
+ "^[^.]+$": {
+ "description": "Name of a rule.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "list-mode": {
+ "description": "Used to determine the package matching priority.",
+ "enum": ["original", "strict", "lax"],
+ "default": "original"
+ },
+ "files": {
+ "description": "List of file globs that will match this list of settings to compare against.",
+ "additionalProperties": false,
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "allow": {
+ "description": "List of allowed packages.",
+ "additionalProperties": false,
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "deny": {
+ "description": "Packages that are not allowed where the value is a suggestion.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "desc": {
+ "description": "Description",
+ "type": "string"
+ },
+ "pkg": {
+ "description": "Package",
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "dogsledSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-blank-identifiers": {
+ "description": "Check assignments with too many blank identifiers.",
+ "type": "integer",
+ "default": 2,
+ "minimum": 0
+ }
+ }
+ },
+ "duplSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "threshold": {
+ "description": "Tokens count to trigger issue.",
+ "type": "integer",
+ "default": 150,
+ "minimum": 0
+ }
+ }
+ },
+ "errcheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-type-assertions": {
+ "description": "Report about not checking errors in type assertions, i.e.: `a := b.(MyStruct)`",
+ "type": "boolean",
+ "default": false
+ },
+ "check-blank": {
+ "description": "Report about assignment of errors to blank identifier",
+ "type": "boolean",
+ "default": false
+ },
+ "exclude-functions": {
+ "description": "List of functions to exclude from checking, where each entry is a single function to exclude",
+ "type": "array",
+ "examples": ["io/ioutil.ReadFile", "io.Copy(*bytes.Buffer)"],
+ "items": {
+ "type": "string"
+ }
+ },
+ "disable-default-exclusions": {
+ "description": "To disable the errcheck built-in exclude list",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "errchkjsonSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-error-free-encoding": {
+ "type": "boolean",
+ "default": false
+ },
+ "report-no-exported": {
+ "description": "Issue on struct that doesn't have exported fields.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "errorlintSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "errorf": {
+ "description": "Check whether fmt.Errorf uses the %w verb for formatting errors",
+ "type": "boolean",
+ "default": true
+ },
+ "errorf-multi": {
+ "description": "Permit more than 1 %w verb, valid per Go 1.20",
+ "type": "boolean",
+ "default": true
+ },
+ "asserts": {
+ "description": "Check for plain type assertions and type switches.",
+ "type": "boolean",
+ "default": true
+ },
+ "comparison": {
+ "description": "Check for plain error comparisons",
+ "type": "boolean",
+ "default": true
+ },
+ "allowed-errors": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "err": {
+ "type": "string"
+ },
+ "fun": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "allowed-errors-wildcard": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "err": {
+ "type": "string"
+ },
+ "fun": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "exhaustiveSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check": {
+ "description": "Program elements to check for exhaustiveness.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["switch", "map"]
+ }
+ },
+ "explicit-exhaustive-switch": {
+ "description": "Only run exhaustive check on switches with \"//exhaustive:enforce\" comment.",
+ "type": "boolean",
+ "default": false
+ },
+ "explicit-exhaustive-map": {
+ "description": "Only run exhaustive check on map literals with \"//exhaustive:enforce\" comment.",
+ "type": "boolean",
+ "default": false
+ },
+ "default-case-required": {
+ "description": "Switch statement requires default case even if exhaustive.",
+ "type": "boolean",
+ "default": false
+ },
+ "default-signifies-exhaustive": {
+ "description": "Presence of `default` case in switch statements satisfies exhaustiveness, even if all enum members are not listed.",
+ "type": "boolean",
+ "default": false
+ },
+ "ignore-enum-members": {
+ "description": "Enum members matching `regex` do not have to be listed in switch statements to satisfy exhaustiveness",
+ "type": "string"
+ },
+ "ignore-enum-types": {
+ "description": "Enum types matching the supplied regex do not have to be listed in switch statements to satisfy exhaustiveness.",
+ "type": "string"
+ },
+ "package-scope-only": {
+ "description": "Consider enums only in package scopes, not in inner scopes.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "exhaustructSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "include": {
+ "description": "List of regular expressions to match struct packages and names.",
+ "type": "array",
+ "examples": [".*\\.Test"],
+ "items": {
+ "type": "string"
+ }
+ },
+ "exclude": {
+ "description": "List of regular expressions to exclude struct packages and names from check.",
+ "type": "array",
+ "examples": ["cobra\\.Command$"],
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "fatcontextSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-struct-pointers": {
+ "description": "Check for potential fat contexts in struct pointers.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "forbidigoSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "exclude-godoc-examples": {
+ "description": "Exclude code in godoc examples.",
+ "type": "boolean",
+ "default": true
+ },
+ "analyze-types": {
+ "description": "Instead of matching the literal source code, use type information to replace expressions with strings that contain the package name and (for methods and fields) the type name.",
+ "type": "boolean",
+ "default": true
+ },
+ "forbid": {
+ "description": "List of identifiers to forbid (written using `regexp`)",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "pattern": {
+ "description": "Pattern",
+ "type": "string"
+ },
+ "pkg": {
+ "description": "Package",
+ "type": "string"
+ },
+ "msg": {
+ "description": "Message",
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "funlenSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "lines": {
+ "description": "Limit lines number per function.",
+ "type": "integer",
+ "default": 60
+ },
+ "statements": {
+ "description": "Limit statements number per function.",
+ "type": "integer",
+ "default": 40
+ },
+ "ignore-comments": {
+ "description": "Ignore comments when counting lines.",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "gciSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "sections": {
+ "description": "Section configuration to compare against.",
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "enum": [
+ "standard",
+ "default",
+ "blank",
+ "dot",
+ "alias",
+ "localmodule"
+ ]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ },
+ "default": ["standard", "default"]
+ },
+ "no-inline-comments": {
+ "description": "Checks that no inline Comments are present.",
+ "type": "boolean",
+ "default": false
+ },
+ "no-prefix-comments": {
+ "description": "Checks that no prefix Comments(comment lines above an import) are present.",
+ "type": "boolean",
+ "default": false
+ },
+ "custom-order": {
+ "description": "Enable custom order of sections.",
+ "type": "boolean",
+ "default": false
+ },
+ "no-lex-order": {
+ "description": "Drops lexical ordering for custom sections.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "ginkgolinterSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "suppress-len-assertion": {
+ "description": "Suppress the wrong length assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-nil-assertion": {
+ "description": "Suppress the wrong nil assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-err-assertion": {
+ "description": "Suppress the wrong error assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-compare-assertion": {
+ "description": "Suppress the wrong comparison assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-async-assertion": {
+ "description": "Suppress the function all in async assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-type-compare-assertion": {
+ "description": "Suppress warning for comparing values from different types, like int32 and uint32.",
+ "type": "boolean",
+ "default": false
+ },
+ "forbid-focus-container": {
+ "description": "Trigger warning for ginkgo focus containers like FDescribe, FContext, FWhen or FIt.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-havelen-zero": {
+ "description": "Don't trigger warnings for HaveLen(0).",
+ "type": "boolean",
+ "default": false
+ },
+ "force-expect-to": {
+ "description": "Force using `Expect` with `To`, `ToNot` or `NotTo`",
+ "type": "boolean",
+ "default": false
+ },
+ "validate-async-intervals": {
+ "description": "Best effort validation of async intervals (timeout and polling).",
+ "type": "boolean",
+ "default": false
+ },
+ "forbid-spec-pollution": {
+ "description": "Trigger a warning for variable assignments in ginkgo containers like `Describe`, `Context` and `When`, instead of in `BeforeEach()`.",
+ "type": "boolean",
+ "default": false
+ },
+ "force-succeed": {
+ "description": "Force using the Succeed matcher for error functions, and the HaveOccurred matcher for non-function error values.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "gochecksumtypeSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "default-signifies-exhaustive": {
+ "description": "Presence of `default` case in switch statements satisfies exhaustiveness, if all members are not listed.",
+ "type": "boolean",
+ "default": true
+ },
+ "include-shared-interfaces": {
+ "description": "Include shared interfaces in the exhaustiviness check.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "gocognitSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "min-complexity": {
+ "description": "Minimal code complexity to report (we recommend 10-20).",
+ "type": "integer",
+ "default": 30
+ }
+ }
+ },
+ "goconstSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "match-constant": {
+ "description": "Look for existing constants matching the values",
+ "type": "boolean",
+ "default": true
+ },
+ "min-len": {
+ "description": "Minimum length of string constant.",
+ "type": "integer",
+ "default": 3
+ },
+ "min-occurrences": {
+ "description": "Minimum occurrences count to trigger.",
+ "type": "integer",
+ "default": 3
+ },
+ "ignore-calls": {
+ "description": "Ignore when constant is not used as function argument",
+ "type": "boolean",
+ "default": true
+ },
+ "ignore-strings": {
+ "description": "Exclude strings matching the given regular expression",
+ "type": "string"
+ },
+ "numbers": {
+ "description": "Search also for duplicated numbers.",
+ "type": "boolean",
+ "default": false
+ },
+ "min": {
+ "description": "Minimum value, only works with `numbers`",
+ "type": "integer",
+ "default": 3
+ },
+ "max": {
+ "description": "Maximum value, only works with `numbers`",
+ "type": "integer",
+ "default": 3
+ }
+ }
+ },
+ "gocriticSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "enabled-checks": {
+ "description": "Which checks should be enabled. By default, a list of stable checks is used. To see it, run `GL_DEBUG=gocritic golangci-lint run`.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/gocritic-checks"
+ }
+ },
+ "disabled-checks": {
+ "description": "Which checks should be disabled.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/gocritic-checks"
+ },
+ "default": []
+ },
+ "enabled-tags": {
+ "description": "Enable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/gocritic-tags"
+ }
+ },
+ "disabled-tags": {
+ "description": "Disable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/gocritic-tags"
+ }
+ },
+ "settings": {
+ "description": "Settings passed to gocritic. Properties must be valid and enabled check names.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "captLocal": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "paramsOnly" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "commentedOutCode": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "minLength" : {
+ "type": "number",
+ "default": 15
+ }
+ }
+ },
+ "elseif": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skipBalanced" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "hugeParam": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "sizeThreshold" : {
+ "type": "number",
+ "default": 80
+ }
+ }
+ },
+ "ifElseChain": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "minThreshold" : {
+ "type": "number",
+ "default": 2
+ }
+ }
+ },
+ "nestingReduce": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "bodyWidth" : {
+ "type": "number",
+ "default": 5
+ }
+ }
+ },
+ "rangeExprCopy": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "sizeThreshold" : {
+ "type": "number",
+ "default": 512
+ },
+ "skipTestFuncs" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "rangeValCopy": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "sizeThreshold" : {
+ "type": "number",
+ "default": 128
+ },
+ "skipTestFuncs" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "ruleguard": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "debug" : {
+ "type": "string"
+ },
+ "enable" : {
+ "type": "string"
+ },
+ "disable" : {
+ "type": "string"
+ },
+ "failOn" : {
+ "type": "string"
+ },
+ "rules" : {
+ "type": "string"
+ }
+ }
+ },
+ "tooManyResultsChecker": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "maxResults" : {
+ "type": "number",
+ "default": 5
+ }
+ }
+ },
+ "truncateCmp": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skipArchDependent" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "underef": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skipRecvDeref" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "unnamedResult": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "checkExported" : {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ }
+ }
+ },
+ "disable-all": {
+ "type": "boolean",
+ "default": false
+ },
+ "enable-all": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "gocycloSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "min-complexity": {
+ "description": "Minimum code complexity to report (we recommend 10-20).",
+ "type": "integer",
+ "default": 30
+ }
+ }
+ },
+ "godotSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "scope": {
+ "description": "Comments to be checked.",
+ "enum": ["declarations", "toplevel", "all"],
+ "default": "declarations"
+ },
+ "exclude": {
+ "description": "List of regexps for excluding particular comment lines from check.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "period": {
+ "description": "Check that each sentence ends with a period.",
+ "type": "boolean",
+ "default": true
+ },
+ "capital": {
+ "description": "Check that each sentence starts with a capital letter.",
+ "type": "boolean",
+ "default": false
+ },
+ "check-all": {
+ "description": "DEPRECATED: Check all top-level comments, not only declarations.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "godoxSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "keywords": {
+ "description": "Report any comments starting with one of these keywords. This is useful for TODO or FIXME comments that might be left in the code accidentally and should be resolved before merging.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "default": ["TODO", "BUG", "FIXME"]
+ }
+ }
+ },
+ "gofmtSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "simplify": {
+ "description": "Simplify code.",
+ "type": "boolean",
+ "default": true
+ },
+ "rewrite-rules": {
+ "description": "Apply the rewrite rules to the source before reformatting.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "pattern": {
+ "type": "string"
+ },
+ "replacement": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "golinesSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-len": {
+ "type": "integer",
+ "default": 100
+ },
+ "tab-len": {
+ "type": "integer",
+ "default": 4
+ },
+ "shorten-comments": {
+ "type": "boolean",
+ "default": false
+ },
+ "reformat-tags": {
+ "type": "boolean",
+ "default": true
+ },
+ "chain-split-dots": {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "interfacebloatSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max": {
+ "description": "The maximum number of methods allowed for an interface.",
+ "type": "integer"
+ }
+ }
+ },
+ "gofumptSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "extra-rules": {
+ "description": "Choose whether or not to use the extra rules that are disabled by default.",
+ "type": "boolean",
+ "default": false
+ },
+ "module-path": {
+ "description": " Module path which contains the source code being formatted.",
+ "type": "string"
+ }
+ }
+ },
+ "goheaderSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "values": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "const": {
+ "description": "Constants to use in the template.",
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "description": "Value for the constant.",
+ "type": "string"
+ }
+ },
+ "additionalProperties": false,
+ "examples": [
+ {
+ "YEAR": "2030",
+ "COMPANY": "MY FUTURISTIC COMPANY"
+ }
+ ]
+ },
+ "regexp": {
+ "description": "Regular expressions to use in your template.",
+ "type": "object",
+ "additionalProperties": false,
+ "patternProperties": {
+ "^.+$": {
+ "type": "string"
+ }
+ },
+ "examples": [
+ {
+ "AUTHOR": ".*@mycompany\\.com"
+ }
+ ]
+ }
+ }
+ },
+ "template": {
+ "description": "Template to put on top of every file.",
+ "type": "string",
+ "examples": [
+ "{{ MY COMPANY }}\nSPDX-License-Identifier: Apache-2.0\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at:\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License."
+ ]
+ },
+ "template-path": {
+ "description": "Path to the file containing the template source.",
+ "type": "string",
+ "examples": ["my_header_template.txt"]
+ }
+ },
+ "oneOf": [
+ { "required": ["template"] },
+ { "required": ["template-path"] }
+ ]
+ },
+ "goimportsSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "local-prefixes": {
+ "description": "Put imports beginning with prefix after 3rd-party packages. It is a list of prefixes.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "gomoddirectivesSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "replace-local": {
+ "description": "Allow local `replace` directives.",
+ "type": "boolean",
+ "default": true
+ },
+ "replace-allow-list": {
+ "description": "List of allowed `replace` directives.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "retract-allow-no-explanation": {
+ "description": "Allow to not explain why the version has been retracted in the `retract` directives.",
+ "type": "boolean",
+ "default": false
+ },
+ "exclude-forbidden": {
+ "description": "Forbid the use of the `exclude` directives.",
+ "type": "boolean",
+ "default": false
+ },
+ "toolchain-forbidden": {
+ "description": "Forbid the use of the `toolchain` directive.",
+ "type": "boolean",
+ "default": false
+ },
+ "toolchain-pattern": {
+ "description": "Defines a pattern to validate `toolchain` directive.",
+ "type": "string"
+ },
+ "tool-forbidden": {
+ "description": "Forbid the use of the `tool` directives.",
+ "type": "boolean",
+ "default": false
+ },
+ "go-debug-forbidden": {
+ "description": "Forbid the use of the `godebug` directive.",
+ "type": "boolean",
+ "default": false
+ },
+ "go-version-pattern": {
+ "description": "Defines a pattern to validate `go` minimum version directive.",
+ "type": "string",
+ "default": ""
+ }
+ }
+ },
+ "gomodguardSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "allowed": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "modules": {
+ "description": "List of allowed modules.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["gopkg.in/yaml.v2"]
+ }
+ },
+ "domains": {
+ "description": "List of allowed module domains.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["golang.org"]
+ }
+ }
+ }
+ },
+ "blocked": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "modules": {
+ "description": "List of blocked modules.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "recommendations": {
+ "description": "Recommended modules that should be used instead.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "reason": {
+ "description": "Reason why the recommended module should be used.",
+ "type": "string"
+ }
+ }
+ }
+ },
+ "additionalProperties": false
+ }
+ },
+ "versions": {
+ "description": "List of blocked module version constraints.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "patternProperties": {
+ "^.*$": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "version": {
+ "description": "Version constraint.",
+ "type": "string"
+ },
+ "reason": {
+ "description": "Reason why the version constraint exists.",
+ "type": "string"
+ }
+ },
+ "required": ["reason"]
+ }
+ }
+ }
+ },
+ "local-replace-directives": {
+ "description": "Raise lint issues if loading local path with replace directive",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ }
+ }
+ },
+ "gosecSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "includes": {
+ "type": "array",
+ "description": "To select a subset of rules to run",
+ "examples": [["G401"]],
+ "items": {
+ "$ref": "#/definitions/gosec-rules"
+ }
+ },
+ "excludes": {
+ "type": "array",
+ "description": "To specify a set of rules to explicitly exclude",
+ "examples": [["G401"]],
+ "items": {
+ "$ref": "#/definitions/gosec-rules"
+ }
+ },
+ "severity": {
+ "description": "Filter out the issues with a lower severity than the given value",
+ "type": "string",
+ "enum": ["low", "medium", "high"],
+ "default": "low"
+ },
+ "confidence": {
+ "description": "Filter out the issues with a lower confidence than the given value",
+ "type": "string",
+ "enum": ["low", "medium", "high"],
+ "default": "low"
+ },
+ "config": {
+ "description": "To specify the configuration of rules",
+ "type": "object"
+ },
+ "concurrency": {
+ "description": "Concurrency value",
+ "type": "integer"
+ }
+ }
+ },
+ "gosmopolitanSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "allow-time-local": {
+ "description": "Allow and ignore `time.Local` usages.",
+ "type": "boolean",
+ "default": false
+ },
+ "escape-hatches": {
+ "description": "List of fully qualified names in the `full/pkg/path.name` form, to act as \"i18n escape hatches\".",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "watch-for-scripts": {
+ "description": "List of Unicode scripts to watch for any usage in string literals.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "govetSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "settings": {
+ "description": "Settings per analyzer. Map of analyzer name to specific settings.\nRun `go tool vet help` to find out more.",
+ "type": "object",
+ "propertyNames": {
+ "$ref": "#/definitions/govet-analyzers"
+ },
+ "patternProperties": {
+ "^.*$": {
+ "description": "Run `go tool vet help ` to see all settings.",
+ "type": "object"
+ }
+ }
+ },
+ "enable": {
+ "description": "Enable analyzers by name.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/govet-analyzers"
+ }
+ },
+ "disable": {
+ "description": "Disable analyzers by name.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/govet-analyzers"
+ }
+ },
+ "enable-all": {
+ "description": "Enable all analyzers.",
+ "type": "boolean",
+ "default": false
+ },
+ "disable-all": {
+ "description": "Disable all analyzers.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "grouperSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "const-require-single-const": {
+ "type": "boolean",
+ "default": false
+ },
+ "const-require-grouping": {
+ "type": "boolean",
+ "default": false
+ },
+ "import-require-single-import": {
+ "type": "boolean",
+ "default": false
+ },
+ "import-require-grouping": {
+ "type": "boolean",
+ "default": false
+ },
+ "type-require-single-type": {
+ "type": "boolean",
+ "default": false
+ },
+ "type-require-grouping": {
+ "type": "boolean",
+ "default": false
+ },
+ "var-require-single-var": {
+ "type": "boolean",
+ "default": false
+ },
+ "var-require-grouping": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "ifaceSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "enable": {
+ "description": "Enable analyzers by name.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/iface-analyzers"
+ }
+ },
+ "settings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "unused": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "exclude": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "importasSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "no-unaliased": {
+ "description": "Do not allow unaliased imports of aliased packages.",
+ "type": "boolean",
+ "default": false
+ },
+ "no-extra-aliases": {
+ "description": "Do not allow non-required aliases.",
+ "type": "boolean",
+ "default": false
+ },
+ "alias": {
+ "description": "List of aliases",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "pkg": {
+ "description": "Package path e.g. knative.dev/serving/pkg/apis/autoscaling/v1alpha1",
+ "type": "string"
+ },
+ "alias": {
+ "description": "Package alias e.g. autoscalingv1alpha1",
+ "type": "string"
+ }
+ },
+ "required": ["pkg", "alias"]
+ }
+ }
+ }
+ },
+ "inamedparamSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skip-single-param": {
+ "description": "Skips check for interface methods with only a single parameter.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "ireturnSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "description": "Use either `reject` or `allow` properties for interfaces matching.",
+ "properties": {
+ "allow": {
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "enum": ["anon", "error", "empty", "stdlib"]
+ }
+ ]
+ }
+ },
+ "reject": {
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "enum": ["anon", "error", "empty", "stdlib"]
+ }
+ ]
+ }
+ }
+ },
+ "anyOf": [
+ {
+ "not": {
+ "properties": {
+ "allow": {
+ "const": "reject"
+ }
+ }
+ },
+ "required": ["allow"]
+ },
+ {
+ "required": ["reject"]
+ }
+ ]
+ },
+ "lllSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "tab-width": {
+ "description": "Width of \"\\t\" in spaces.",
+ "type": "integer",
+ "minimum": 0,
+ "default": 1
+ },
+ "line-length": {
+ "description": "Maximum allowed line length, lines longer will be reported.",
+ "type": "integer",
+ "minimum": 1,
+ "default": 120
+ }
+ }
+ },
+ "maintidxSettings": {
+ "description": "Maintainability index https://docs.microsoft.com/en-us/visualstudio/code-quality/code-metrics-maintainability-index-range-and-meaning?view=vs-2022",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "under": {
+ "description": "Minimum accatpable maintainability index level (see https://docs.microsoft.com/en-us/visualstudio/code-quality/code-metrics-maintainability-index-range-and-meaning?view=vs-2022)",
+ "type": "number",
+ "default": 20
+ }
+ }
+ },
+ "makezeroSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "always": {
+ "description": "Allow only slices initialized with a length of zero.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "loggercheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "kitlog": {
+ "description": "Allow check for the github.com/go-kit/log library.",
+ "type": "boolean",
+ "default": true
+ },
+ "klog": {
+ "description": "Allow check for the k8s.io/klog/v2 library.",
+ "type": "boolean",
+ "default": true
+ },
+ "logr": {
+ "description": "Allow check for the github.com/go-logr/logr library.",
+ "type": "boolean",
+ "default": true
+ },
+ "slog": {
+ "description": "Allow check for the log/slog library.",
+ "type": "boolean",
+ "default": true
+ },
+ "zap": {
+ "description": "Allow check for the \"sugar logger\" from go.uber.org/zap library.",
+ "type": "boolean",
+ "default": true
+ },
+ "require-string-key": {
+ "description": "Require all logging keys to be inlined constant strings.",
+ "type": "boolean",
+ "default": false
+ },
+ "no-printf-like": {
+ "description": "Require printf-like format specifier (%s, %d for example) not present.",
+ "type": "boolean",
+ "default": false
+ },
+ "rules": {
+ "description": "List of custom rules to check against, where each rule is a single logger pattern, useful for wrapped loggers.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "misspellSettings": {
+ "description": "Correct spellings using locale preferences for US or UK. Default is to use a neutral variety of English.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "locale": {
+ "enum": ["US", "UK"]
+ },
+ "ignore-rules": {
+ "description": "List of rules to ignore.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "mode": {
+ "description": "Mode of the analysis.",
+ "enum": ["restricted", "", "default"],
+ "default": ""
+ },
+ "extra-words": {
+ "description": "Extra word corrections.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "correction": {
+ "type": "string"
+ },
+ "typo": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "musttagSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "functions": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "tag": {
+ "type": "string"
+ },
+ "arg-pos": {
+ "type": "integer"
+ }
+ }
+ }
+ }
+ }
+ },
+ "nakedretSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-func-lines": {
+ "description": "Report if a function has more lines of code than this value and it has naked returns.",
+ "type": "integer",
+ "minimum": 0,
+ "default": 30
+ }
+ }
+ },
+ "nestifSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "min-complexity": {
+ "description": "Minimum complexity of \"if\" statements to report.",
+ "type": "integer",
+ "default": 5
+ }
+ }
+ },
+ "nilnilSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "only-two": {
+ "type": "boolean",
+ "description": "To check functions with only two return values.",
+ "default": true
+ },
+ "detect-opposite": {
+ "type": "boolean",
+ "description": "In addition, detect opposite situation (simultaneous return of non-nil error and valid value).",
+ "default": false
+ },
+ "checked-types": {
+ "type": "array",
+ "description": "List of return types to check.",
+ "items": {
+ "enum": ["chan", "func", "iface", "map", "ptr", "uintptr", "unsafeptr"]
+ },
+ "default": ["chan", "func", "iface", "map", "ptr", "uintptr", "unsafeptr"]
+ }
+ }
+ },
+ "nlreturnSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "block-size": {
+ "description": "set block size that is still ok",
+ "type": "number",
+ "default": 0,
+ "minimum": 0
+ }
+ }
+ },
+ "mndSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignored-files": {
+ "description": "List of file patterns to exclude from analysis.",
+ "examples": [["magic1_.*.go"]],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignored-functions": {
+ "description": "Comma-separated list of function patterns to exclude from the analysis.",
+ "examples": [["math.*", "http.StatusText", "make"]],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignored-numbers": {
+ "description": "List of numbers to exclude from analysis.",
+ "examples": [["1000", "1234_567_890", "3.14159264"]],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "checks": {
+ "description": "The list of enabled checks, see https://github.com/tommy-muehle/go-mnd/#checks for description.",
+ "type": "array",
+ "items": {
+ "enum": [
+ "argument",
+ "case",
+ "condition",
+ "operation",
+ "return",
+ "assign"
+ ]
+ }
+ }
+ }
+ },
+ "nolintlintSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "allow-unused": {
+ "description": "Enable to ensure that nolint directives are all used.",
+ "type": "boolean",
+ "default": true
+ },
+ "allow-no-explanation": {
+ "description": "Exclude these linters from requiring an explanation.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linter-names"
+ },
+ "default": []
+ },
+ "require-explanation": {
+ "description": "Enable to require an explanation of nonzero length after each nolint directive.",
+ "type": "boolean",
+ "default": false
+ },
+ "require-specific": {
+ "description": "Enable to require nolint directives to mention the specific linter being suppressed.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "reassignSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "patterns": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "recvcheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "disable-builtin": {
+ "description": "Disables the built-in method exclusions.",
+ "type": "boolean",
+ "default": true
+ },
+ "exclusions": {
+ "description": "User-defined method exclusions.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "nonamedreturnsSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "report-error-in-defer": {
+ "description": "Report named error if it is assigned inside defer.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "paralleltestSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignore-missing": {
+ "description": "Ignore missing calls to `t.Parallel()` and only report incorrect uses of it.",
+ "type": "boolean",
+ "default": false
+ },
+ "ignore-missing-subtests": {
+ "description": "Ignore missing calls to `t.Parallel()` in subtests. Top-level tests are still required to have `t.Parallel`, but subtests are allowed to skip it.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "perfsprintSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "integer-format": {
+ "description": "Enable/disable optimization of integer formatting.",
+ "type": "boolean",
+ "default": true
+ },
+ "int-conversion": {
+ "description": "Optimizes even if it requires an int or uint type cast.",
+ "type": "boolean",
+ "default": true
+ },
+ "error-format": {
+ "description": "Enable/disable optimization of error formatting.",
+ "type": "boolean",
+ "default": true
+ },
+ "err-error": {
+ "description": "Optimizes into `err.Error()` even if it is only equivalent for non-nil errors.",
+ "type": "boolean",
+ "default": false
+ },
+ "errorf": {
+ "description": "Optimizes `fmt.Errorf`.",
+ "type": "boolean",
+ "default": true
+ },
+ "string-format": {
+ "description": "Enable/disable optimization of string formatting.",
+ "type": "boolean",
+ "default": true
+ },
+ "sprintf1": {
+ "description": "Optimizes `fmt.Sprintf` with only one argument.",
+ "type": "boolean",
+ "default": true
+ },
+ "strconcat": {
+ "description": "Optimizes into strings concatenation.",
+ "type": "boolean",
+ "default": true
+ },
+ "bool-format": {
+ "description": "Enable/disable optimization of bool formatting.",
+ "type": "boolean",
+ "default": true
+ },
+ "hex-format": {
+ "description": "Enable/disable optimization of hex formatting.",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "preallocSettings": {
+ "description": "We do not recommend using this linter before doing performance profiling.\nFor most programs usage of `prealloc` will be premature optimization.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "simple": {
+ "description": "Report preallocation suggestions only on simple loops that have no returns/breaks/continues/gotos in them.",
+ "type": "boolean",
+ "default": true
+ },
+ "range-loops": {
+ "description": "Report preallocation suggestions on range loops.",
+ "type": "boolean",
+ "default": true
+ },
+ "for-loops": {
+ "description": "Report preallocation suggestions on for loops.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "predeclaredSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignore": {
+ "description": "List of predeclared identifiers to not report on.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "qualified-name": {
+ "description": "Include method names and field names in checks.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "promlinterSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "strict": {},
+ "disabled-linters": {
+ "type": "array",
+ "items": {
+ "enum": [
+ "Help",
+ "MetricUnits",
+ "Counter",
+ "HistogramSummaryReserved",
+ "MetricTypeInName",
+ "ReservedChars",
+ "CamelCase",
+ "UnitAbbreviations"
+ ]
+ }
+ }
+ }
+ },
+ "protogetterSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skip-generated-by": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["protoc-gen-go-my-own-generator"]
+ }
+ },
+ "skip-files": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["*.pb.go"]
+ }
+ },
+ "skip-any-generated": {
+ "description": "Skip any generated files from the checking.",
+ "type": "boolean",
+ "default": false
+ },
+ "replace-first-arg-in-append": {
+ "description": "Skip first argument of append function.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "reviveSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "examples": [
+ {
+ "ignore-generated-header": true,
+ "severity": "warning",
+ "rules": [
+ {
+ "name": "indent-error-flow",
+ "severity": "warning"
+ },
+ {
+ "name": "add-constant",
+ "severity": "warning",
+ "arguments": [
+ {
+ "maxLitCount": "3",
+ "allowStrs": "\"\"",
+ "allowInts": "0,1,2",
+ "allowFloats": "0.0,0.,1.0,1.,2.0,2."
+ }
+ ]
+ }
+ ]
+ }
+ ],
+ "properties": {
+ "max-open-files": {
+ "type": "integer"
+ },
+ "confidence": {
+ "type": "number"
+ },
+ "severity": {
+ "type": "string",
+ "enum": ["warning", "error"]
+ },
+ "enable-all-rules": {
+ "type": "boolean",
+ "default": false
+ },
+ "directives": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "name": {
+ "type": "string",
+ "enum": ["specify-disable-reason"]
+ },
+ "severity": {
+ "type": "string",
+ "enum": ["warning", "error"]
+ },
+ "exclude": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "arguments": {
+ "type": "array"
+ }
+ }
+ }
+ },
+ "rules": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["name"],
+ "properties": {
+ "name": {
+ "$ref": "#/definitions/revive-rules",
+ "title": "The rule name"
+ },
+ "disabled": {
+ "type": "boolean"
+ },
+ "severity": {
+ "type": "string",
+ "enum": ["warning", "error"]
+ },
+ "exclude": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "arguments": {
+ "type": "array"
+ }
+ }
+ }
+ }
+ }
+ },
+ "rowserrcheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "packages": {
+ "type": "array",
+ "items": {
+ "description": "",
+ "type": "string",
+ "examples": ["github.com/jmoiron/sqlx"]
+ }
+ }
+ }
+ },
+ "sloglintSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "kv-only": {
+ "description": "Enforce using key-value pairs only (incompatible with attr-only).",
+ "type": "boolean",
+ "default": false
+ },
+ "no-global": {
+ "description": "Enforce not using global loggers.",
+ "enum": ["", "all", "default"],
+ "default": ""
+ },
+ "no-mixed-args": {
+ "description": "Enforce not mixing key-value pairs and attributes.",
+ "type": "boolean",
+ "default": true
+ },
+ "context": {
+ "description": "Enforce using methods that accept a context.",
+ "enum": ["", "all", "scope"],
+ "default": ""
+ },
+ "static-msg": {
+ "description": "Enforce using static values for log messages.",
+ "type": "boolean",
+ "default": false
+ },
+ "key-naming-case": {
+ "description": "Enforce a single key naming convention.",
+ "enum": ["snake", "kebab", "camel", "pascal"]
+ },
+ "attr-only": {
+ "description": "Enforce using attributes only (incompatible with kv-only).",
+ "type": "boolean",
+ "default": false
+ },
+ "no-raw-keys": {
+ "description": "Enforce using constants instead of raw keys.",
+ "type": "boolean",
+ "default": false
+ },
+ "forbidden-keys": {
+ "description": "Enforce not using specific keys.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "args-on-sep-lines": {
+ "description": "Enforce putting arguments on separate lines.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "spancheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "checks": {
+ "description": "Checks to enable.",
+ "type": "array",
+ "items": {
+ "enum": ["end", "record-error", "set-status"]
+ }
+ },
+ "ignore-check-signatures": {
+ "description": "A list of regexes for function signatures that silence `record-error` and `set-status` reports if found in the call path to a returned error.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "extra-start-span-signatures": {
+ "description": "A list of regexes for additional function signatures that create spans.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "staticcheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "checks": {
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "$ref": "#/definitions/staticcheck-checks"
+ },
+ {
+ "type": "string"
+ }
+ ]
+ }
+ },
+ "dot-import-whitelist": {
+ "description": "By default, ST1001 forbids all uses of dot imports in non-test packages. This setting allows setting a whitelist of import paths that can be dot-imported anywhere.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "http-status-code-whitelist": {
+ "description": "ST1013 recommends using constants from the net/http package instead of hard-coding numeric HTTP status codes. This setting specifies a list of numeric status codes that this check does not complain about.",
+ "default": ["200", "400", "404", "500"],
+ "type": "array",
+ "items": {
+ "enum": [
+ "100",
+ "101",
+ "102",
+ "103",
+ "200",
+ "201",
+ "202",
+ "203",
+ "204",
+ "205",
+ "206",
+ "207",
+ "208",
+ "226",
+ "300",
+ "301",
+ "302",
+ "303",
+ "304",
+ "305",
+ "306",
+ "307",
+ "308",
+ "400",
+ "401",
+ "402",
+ "403",
+ "404",
+ "405",
+ "406",
+ "407",
+ "408",
+ "409",
+ "410",
+ "411",
+ "412",
+ "413",
+ "414",
+ "415",
+ "416",
+ "417",
+ "418",
+ "421",
+ "422",
+ "423",
+ "424",
+ "425",
+ "426",
+ "428",
+ "429",
+ "431",
+ "451",
+ "500",
+ "501",
+ "502",
+ "503",
+ "504",
+ "505",
+ "506",
+ "507",
+ "508",
+ "510",
+ "511"
+ ]
+ }
+ },
+ "initialisms": {
+ "description": "ST1003 check, among other things, for the correct capitalization of initialisms. The set of known initialisms can be configured with this option.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "default": [
+ "ACL",
+ "API",
+ "ASCII",
+ "CPU",
+ "CSS",
+ "DNS",
+ "EOF",
+ "GUID",
+ "HTML",
+ "HTTP",
+ "HTTPS",
+ "ID",
+ "IP",
+ "JSON",
+ "QPS",
+ "RAM",
+ "RPC",
+ "SLA",
+ "SMTP",
+ "SQL",
+ "SSH",
+ "TCP",
+ "TLS",
+ "TTL",
+ "UDP",
+ "UI",
+ "GID",
+ "UID",
+ "UUID",
+ "URI",
+ "URL",
+ "UTF8",
+ "VM",
+ "XML",
+ "XMPP",
+ "XSRF",
+ "XSS",
+ "SIP",
+ "RTP",
+ "AMQP",
+ "DB",
+ "TS"
+ ]
+ }
+ }
+ }
+ },
+ "tagalignSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "align": {
+ "description": "Align and sort can be used together or separately.",
+ "type": "boolean",
+ "default": true
+ },
+ "sort": {
+ "description": "Whether enable tags sort.",
+ "type": "boolean",
+ "default": true
+ },
+ "order": {
+ "description": "Specify the order of tags, the other tags will be sorted by name.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "default": [],
+ "examples": [
+ [
+ "json",
+ "yaml",
+ "yml",
+ "toml",
+ "mapstructure",
+ "binding",
+ "validate"
+ ]
+ ]
+ },
+ "strict": {
+ "description": "Whether enable strict style.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "tagliatelleSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "case": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "use-field-name": {
+ "description": "Use the struct field name to check the name of the struct tag.",
+ "type": "boolean",
+ "default": false
+ },
+ "ignored-fields": {
+ "description": "The field names to ignore.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["example"]
+ }
+ },
+ "rules": {
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "$ref": "#/definitions/tagliatelle-cases"
+ }
+ }
+ },
+ "extended-rules": {
+ "description": "Defines the association between tag name and case.",
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["case"],
+ "properties": {
+ "case": {
+ "$ref": "#/definitions/tagliatelle-cases"
+ },
+ "extra-initialisms": {
+ "type": "boolean",
+ "default": false
+ },
+ "initialism-overrides": {
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "overrides": {
+ "description": "Overrides the default/root configuration.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["pkg"],
+ "properties": {
+ "pkg": {
+ "description": "A package path.",
+ "type": "string"
+ },
+ "use-field-name": {
+ "description": "Use the struct field name to check the name of the struct tag.",
+ "type": "boolean",
+ "default": false
+ },
+ "ignored-fields": {
+ "description": "The field names to ignore.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["example"]
+ }
+ },
+ "ignore": {
+ "description": "Ignore the package (takes precedence over all other configurations).",
+ "type": "boolean",
+ "default": false
+ },
+ "rules": {
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "$ref": "#/definitions/tagliatelle-cases"
+ }
+ }
+ },
+ "extended-rules": {
+ "description": "Defines the association between tag name and case.",
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["case"],
+ "properties": {
+ "case": {
+ "$ref": "#/definitions/tagliatelle-cases"
+ },
+ "extra-initialisms": {
+ "type": "boolean",
+ "default": false
+ },
+ "initialism-overrides": {
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "testifylintSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "enable-all": {
+ "description": "Enable all checkers.",
+ "type": "boolean",
+ "default": false
+ },
+ "disable-all": {
+ "description": "Disable all checkers.",
+ "type": "boolean",
+ "default": false
+ },
+ "enable": {
+ "description": "Enable specific checkers.",
+ "type": "array",
+ "items": {
+ "enum": [
+ "blank-import",
+ "bool-compare",
+ "compares",
+ "contains",
+ "empty",
+ "encoded-compare",
+ "equal-values",
+ "error-is-as",
+ "error-nil",
+ "expected-actual",
+ "float-compare",
+ "formatter",
+ "go-require",
+ "len",
+ "negative-positive",
+ "nil-compare",
+ "regexp",
+ "require-error",
+ "suite-broken-parallel",
+ "suite-dont-use-pkg",
+ "suite-extra-assert-call",
+ "suite-method-signature",
+ "suite-subtest-run",
+ "suite-thelper",
+ "useless-assert"
+ ]
+ },
+ "default": [
+ "blank-import",
+ "bool-compare",
+ "compares",
+ "contains",
+ "empty",
+ "encoded-compare",
+ "equal-values",
+ "error-is-as",
+ "error-nil",
+ "expected-actual",
+ "float-compare",
+ "formatter",
+ "go-require",
+ "len",
+ "negative-positive",
+ "nil-compare",
+ "regexp",
+ "require-error",
+ "suite-broken-parallel",
+ "suite-dont-use-pkg",
+ "suite-extra-assert-call",
+ "suite-method-signature",
+ "suite-subtest-run",
+ "useless-assert"
+ ]
+ },
+ "disable": {
+ "description": "Disable specific checkers.",
+ "type": "array",
+ "items": {
+ "enum": [
+ "blank-import",
+ "bool-compare",
+ "compares",
+ "contains",
+ "empty",
+ "encoded-compare",
+ "equal-values",
+ "error-is-as",
+ "error-nil",
+ "expected-actual",
+ "float-compare",
+ "formatter",
+ "go-require",
+ "len",
+ "negative-positive",
+ "nil-compare",
+ "regexp",
+ "require-error",
+ "suite-broken-parallel",
+ "suite-dont-use-pkg",
+ "suite-extra-assert-call",
+ "suite-method-signature",
+ "suite-subtest-run",
+ "suite-thelper",
+ "useless-assert"
+ ],
+ "default": [
+ "suite-thelper"
+ ]
+ }
+ },
+ "bool-compare": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignore-custom-types": {
+ "description": "To ignore user defined types (over builtin bool).",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "expected-actual": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "pattern": {
+ "description": "Regexp for expected variable name.",
+ "type": "string",
+ "default": "(^(exp(ected)?|want(ed)?)([A-Z]\\w*)?$)|(^(\\w*[a-z])?(Exp(ected)?|Want(ed)?)$)"
+ }
+ }
+ },
+ "formatter": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-format-string": {
+ "description": "To enable go vet's printf checks.",
+ "type": "boolean",
+ "default": true
+ },
+ "require-f-funcs": {
+ "description": "To require f-assertions (e.g. assert.Equalf) if format string is used, even if there are no variable-length variables.",
+ "type": "boolean",
+ "default": false
+ },
+ "require-string-msg": {
+ "description": "To require that the first element of msgAndArgs (msg) has a string type.",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "go-require": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignore-http-handlers": {
+ "description": "To ignore HTTP handlers (like http.HandlerFunc).",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "require-error": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "fn-pattern": {
+ "description": "Regexp for assertions to analyze. If defined, then only matched error assertions will be reported.",
+ "type": "string",
+ "default": ""
+ }
+ }
+ },
+ "suite-extra-assert-call": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "mode": {
+ "description": "To require or remove extra Assert() call?",
+ "type": "string",
+ "enum": ["remove", "require"],
+ "default": "remove"
+ }
+ }
+ }
+ }
+ },
+ "testpackageSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skip-regexp": {
+ "description": "Files with names matching this regular expression are skipped.",
+ "type": "string",
+ "examples": ["(export|internal)_test\\.go"]
+ },
+ "allow-packages": {
+ "description": "List of packages that don't end with _test that tests are allowed to be in.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["example"]
+ }
+ }
+ }
+ },
+ "thelperSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "test": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "begin": {
+ "description": "Check if `t.Helper()` begins helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "first": {
+ "description": "Check if *testing.T is first param of helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "name": {
+ "description": "Check if *testing.T param has t name.",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ },
+ "benchmark": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "begin": {
+ "description": "Check if `b.Helper()` begins helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "first": {
+ "description": "Check if *testing.B is first param of helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "name": {
+ "description": "Check if *testing.B param has b name.",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ },
+ "tb": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "begin": {
+ "description": "Check if `tb.Helper()` begins helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "first": {
+ "description": "Check if *testing.TB is first param of helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "name": {
+ "description": "Check if *testing.TB param has tb name.",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ },
+ "fuzz": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "begin": {
+ "description": "Check if `f.Helper()` begins helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "first": {
+ "description": "Check if *testing.F is first param of helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "name": {
+ "description": "Check if *testing.F param has f name.",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ }
+ }
+ },
+ "usestdlibvarsSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "http-method": {
+ "description": "Suggest the use of http.MethodXX.",
+ "type": "boolean",
+ "default": true
+ },
+ "http-status-code": {
+ "description": "Suggest the use of http.StatusXX.",
+ "type": "boolean",
+ "default": true
+ },
+ "time-weekday": {
+ "description": "Suggest the use of time.Weekday.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "time-month": {
+ "description": "Suggest the use of time.Month.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "time-layout": {
+ "description": "Suggest the use of time.Layout.",
+ "type": "boolean",
+ "default": false
+ },
+ "crypto-hash": {
+ "description": "Suggest the use of crypto.Hash.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "default-rpc-path": {
+ "description": "Suggest the use of rpc.DefaultXXPath.",
+ "type": "boolean",
+ "default": false
+ },
+ "sql-isolation-level": {
+ "description": "Suggest the use of sql.LevelXX.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "tls-signature-scheme": {
+ "description": "Suggest the use of tls.SignatureScheme.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "constant-kind": {
+ "description": "Suggest the use of constant.Kind.String().",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "usetestingSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "context-background": {
+ "type": "boolean",
+ "default": true
+ },
+ "context-todo": {
+ "type": "boolean",
+ "default": true
+ },
+ "os-chdir": {
+ "type": "boolean",
+ "default": true
+ },
+ "os-mkdir-temp": {
+ "type": "boolean",
+ "default": true
+ },
+ "os-setenv": {
+ "type": "boolean",
+ "default": true
+ },
+ "os-create-temp": {
+ "type": "boolean",
+ "default": true
+ },
+ "os-temp-dir": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "unconvertSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "fast-math": {
+ "type": "boolean",
+ "default": false
+ },
+ "safe": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "unparamSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-exported": {
+ "description": "Inspect exported functions. Set to true if no external program/library imports your code.\n\nWARNING: if you enable this setting, unparam will report a lot of false-positives in text editors:\nif it's called for subdir of a project it can't find external interfaces. All text editor integrations\nwith golangci-lint call it on a directory with the changed file.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "unusedSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "field-writes-are-uses": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ },
+ "post-statements-are-reads": {
+ "description": "",
+ "type": "boolean",
+ "default": false
+ },
+ "exported-fields-are-used": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ },
+ "parameters-are-used": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ },
+ "local-variables-are-used": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ },
+ "generated-is-used": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "varnamelenSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-distance": {
+ "description": "Variables used in at most this N-many lines will be ignored.",
+ "type": "integer",
+ "default": 5
+ },
+ "min-name-length": {
+ "description": "The minimum length of a variable's name that is considered `long`.",
+ "type": "integer",
+ "default": 3
+ },
+ "check-receiver": {
+ "description": "Check method receiver names.",
+ "default": false,
+ "type": "boolean"
+ },
+ "check-return": {
+ "description": "Check named return values.",
+ "default": false,
+ "type": "boolean"
+ },
+ "check-type-param": {
+ "description": "Check type parameters.",
+ "default": false,
+ "type": "boolean"
+ },
+ "ignore-type-assert-ok": {
+ "description": "Ignore `ok` variables that hold the bool return value of a type assertion",
+ "default": false,
+ "type": "boolean"
+ },
+ "ignore-map-index-ok": {
+ "description": "Ignore `ok` variables that hold the bool return value of a map index.",
+ "default": false,
+ "type": "boolean"
+ },
+ "ignore-chan-recv-ok": {
+ "description": "Ignore `ok` variables that hold the bool return value of a channel receive.",
+ "default": false,
+ "type": "boolean"
+ },
+ "ignore-names": {
+ "description": "Optional list of variable names that should be ignored completely.",
+ "default": [[]],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignore-decls": {
+ "description": "Optional list of variable declarations that should be ignored completely.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "examples": [
+ ["c echo.Context", "t testing.T", "f *foo.Bar", "const C"]
+ ]
+ }
+ }
+ },
+ "whitespaceSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "multi-if": {
+ "description": "Enforces newlines (or comments) after every multi-line if statement",
+ "type": "boolean",
+ "default": false
+ },
+ "multi-func": {
+ "description": "Enforces newlines (or comments) after every multi-line function signature",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "wrapcheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "extra-ignore-sigs": {
+ "description": "An array of strings specifying additional substrings of signatures to ignore.",
+ "default": [
+ ".CustomError(",
+ ".SpecificWrap("
+ ],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignore-sigs": {
+ "description": "An array of strings which specify substrings of signatures to ignore.",
+ "default": [
+ ".Errorf(",
+ "errors.New(",
+ "errors.Unwrap(",
+ ".Wrap(",
+ ".Wrapf(",
+ ".WithMessage(",
+ ".WithMessagef(",
+ ".WithStack("
+ ],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignore-sig-regexps": {
+ "description": "An array of strings which specify regular expressions of signatures to ignore.",
+ "default": [""],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignore-package-globs": {
+ "description": "An array of glob patterns which, if any match the package of the function returning the error, will skip wrapcheck analysis for this error.",
+ "default": [""],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignore-interface-regexps": {
+ "description": "An array of glob patterns which, if matched to an underlying interface name, will ignore unwrapped errors returned from a function whose call is defined on the given interface.",
+ "default": [""],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "wslSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "allow-assign-and-anything": {
+ "description": "Controls if you may cuddle assignments and anything without needing an empty line between them.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-assign-and-call": {
+ "description": "Allow calls and assignments to be cuddled as long as the lines have any matching variables, fields or types.",
+ "type": "boolean",
+ "default": true
+ },
+ "allow-cuddle-declarations": {
+ "description": "Allow declarations (var) to be cuddled.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-cuddle-with-calls": {
+ "description": "A list of call idents that everything can be cuddled with.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "allow-cuddle-with-rhs": {
+ "description": "AllowCuddleWithRHS is a list of right hand side variables that is allowed to be cuddled with anything.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "allow-cuddle-used-in-block": {
+ "description": "Allow cuddling with any block as long as the variable is used somewhere in the block",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-multiline-assign": {
+ "description": "Allow multiline assignments to be cuddled.",
+ "type": "boolean",
+ "default": true
+ },
+ "allow-separated-leading-comment": {
+ "description": "Allow leading comments to be separated with empty lines.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-trailing-comment": {
+ "description": "Allow trailing comments in ending of blocks.",
+ "type": "boolean",
+ "default": false
+ },
+ "error-variable-names": {
+ "description": "When force-err-cuddling is enabled this is a list of names used for error variables to check for in the conditional.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "force-case-trailing-whitespace": {
+ "description": "Force newlines in end of case at this limit (0 = never).",
+ "type": "integer",
+ "minimum": 0,
+ "default": 0
+ },
+ "force-err-cuddling": {
+ "description": "Causes an error when an If statement that checks an error variable doesn't cuddle with the assignment of that variable.",
+ "type": "boolean",
+ "default": false
+ },
+ "force-short-decl-cuddling": {
+ "description": "Causes an error if a short declaration (:=) cuddles with anything other than another short declaration.",
+ "type": "boolean",
+ "default": false
+ },
+ "strict-append": {
+ "description": "If true, append is only allowed to be cuddled if appending value is matching variables, fields or types on line above.",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "copyloopvarSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-alias": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "customSettings": {
+ "description": "The custom section can be used to define linter plugins to be loaded at runtime. See README of golangci-lint for more information.\nEach custom linter should have a unique name.",
+ "type": "object",
+ "patternProperties": {
+ "^.*$": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "type": {
+ "description": "The plugin type.",
+ "enum": ["module", "goplugin"],
+ "default": "goplugin"
+ },
+ "path": {
+ "description": "The path to the plugin *.so. Can be absolute or local.",
+ "type": "string",
+ "examples": ["/path/to/example.so"]
+ },
+ "description": {
+ "description": "The description of the linter, for documentation purposes only.",
+ "type": "string"
+ },
+ "original-url": {
+ "description": "Intended to point to the repo location of the linter, for documentation purposes only.",
+ "type": "string"
+ },
+ "settings": {
+ "description": "Plugins settings/configuration. Only work with plugin based on `linterdb.PluginConstructor`.",
+ "type": "object"
+ }
+ },
+ "oneOf": [
+ {
+ "properties": {
+ "type": {"enum": ["module"] }
+ },
+ "required": ["type"]
+ },
+ {
+ "required": ["path"]
+ }
+ ]
+ }
+ }
+ }
+ }
+ }
+ },
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["version"],
+ "properties": {
+ "version": {
+ "type": "string",
+ "default": "2"
+ },
+ "run": {
+ "description": "Options for analysis running,",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "concurrency": {
+ "description": "Number of concurrent runners. Defaults to the number of available CPU cores.",
+ "type": "integer",
+ "minimum": 0,
+ "examples": [4]
+ },
+ "timeout": {
+ "description": "Timeout for the analysis.",
+ "type": "string",
+ "pattern": "^((\\d+h)?(\\d+m)?(\\d+(?:\\.\\d)?s)?|0)$",
+ "default": "1m",
+ "examples": ["30s", "5m", "5m30s"]
+ },
+ "issues-exit-code": {
+ "description": "Exit code when at least one issue was found.",
+ "type": "integer",
+ "default": 1
+ },
+ "tests": {
+ "description": "Enable inclusion of test files.",
+ "type": "boolean",
+ "default": true
+ },
+ "build-tags": {
+ "description": "List of build tags to pass to all linters.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "default": [],
+ "examples": [["mytag"]]
+ },
+ "modules-download-mode": {
+ "description": "Option to pass to \"go list -mod={option}\".\nSee \"go help modules\" for more information.",
+ "enum": ["mod", "readonly", "vendor"]
+ },
+ "allow-parallel-runners": {
+ "description": "Allow multiple parallel golangci-lint instances running. If disabled, golangci-lint acquires file lock on start.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-serial-runners": {
+ "description": "Allow multiple golangci-lint instances running, but serialize them around a lock.",
+ "type": "boolean",
+ "default": false
+ },
+ "go": {
+ "description": "Targeted Go version.",
+ "type": "string",
+ "default": "1.17"
+ },
+ "relative-path-mode": {
+ "description": "The mode used to evaluate relative paths.",
+ "type": "string",
+ "$ref": "#/definitions/relative-path-modes",
+ "default": "wd"
+ }
+ }
+ },
+ "output": {
+ "description": "Output configuration options.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "formats": {
+ "description": "Output formats to use.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "text": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "path": {
+ "$ref": "#/definitions/formats-path",
+ "default": "stdout"
+ },
+ "print-linter-name": {
+ "type": "boolean",
+ "default": true
+ },
+ "print-issued-lines": {
+ "type": "boolean",
+ "default": true
+ },
+ "colors": {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "json": {
+ "$ref": "#/definitions/simple-format"
+ },
+ "tab": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "path": {
+ "$ref": "#/definitions/formats-path",
+ "default": "stdout"
+ },
+ "print-linter-name": {
+ "type": "boolean",
+ "default": true
+ },
+ "colors": {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "html": {
+ "$ref": "#/definitions/simple-format"
+ },
+ "checkstyle": {
+ "$ref": "#/definitions/simple-format"
+ },
+ "code-climate": {
+ "$ref": "#/definitions/simple-format"
+ },
+ "junit-xml": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "path": {
+ "$ref": "#/definitions/formats-path",
+ "default": "stdout"
+ },
+ "extended": {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "teamcity": {
+ "$ref": "#/definitions/simple-format"
+ },
+ "sarif": {
+ "$ref": "#/definitions/simple-format"
+ }
+ }
+ },
+ "path-prefix": {
+ "description": "Add a prefix to the output file references.",
+ "type": "string",
+ "default": ""
+ },
+ "show-stats": {
+ "description": "Show statistics per linter.",
+ "type": "boolean",
+ "default": true
+ },
+ "sort-order": {
+ "type": "array",
+ "items": {
+ "enum": ["linter", "severity", "file"]
+ }
+ }
+ }
+ },
+ "linters": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "default": {
+ "enum": [
+ "standard",
+ "all",
+ "none",
+ "fast"
+ ]
+ },
+ "enable": {
+ "description": "List of enabled linters.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linter-names"
+ }
+ },
+ "disable": {
+ "description": "List of disabled linters.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linter-names"
+ }
+ },
+ "settings": {
+ "description": "All available settings of specific linters.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "dupword": {
+ "$ref": "#/definitions/settings/definitions/dupwordSettings"
+ },
+ "asasalint": {
+ "$ref": "#/definitions/settings/definitions/asasalintSettings"
+ },
+ "bidichk": {
+ "$ref": "#/definitions/settings/definitions/bidichkSettings"
+ },
+ "cyclop": {
+ "$ref": "#/definitions/settings/definitions/cyclopSettings"
+ },
+ "decorder": {
+ "$ref": "#/definitions/settings/definitions/decorderSettings"
+ },
+ "depguard":{
+ "$ref": "#/definitions/settings/definitions/depguardSettings"
+ },
+ "dogsled": {
+ "$ref": "#/definitions/settings/definitions/dogsledSettings"
+ },
+ "dupl": {
+ "$ref": "#/definitions/settings/definitions/duplSettings"
+ },
+ "errcheck": {
+ "$ref": "#/definitions/settings/definitions/errcheckSettings"
+ },
+ "errchkjson": {
+ "$ref": "#/definitions/settings/definitions/errchkjsonSettings"
+ },
+ "errorlint": {
+ "$ref": "#/definitions/settings/definitions/errorlintSettings"
+ },
+ "exhaustive": {
+ "$ref": "#/definitions/settings/definitions/exhaustiveSettings"
+ },
+ "exhaustruct": {
+ "$ref": "#/definitions/settings/definitions/exhaustructSettings"
+ },
+ "fatcontext": {
+ "$ref": "#/definitions/settings/definitions/fatcontextSettings"
+ },
+ "forbidigo": {
+ "$ref": "#/definitions/settings/definitions/forbidigoSettings"
+ },
+ "funlen": {
+ "$ref": "#/definitions/settings/definitions/funlenSettings"
+ },
+ "ginkgolinter": {
+ "$ref": "#/definitions/settings/definitions/ginkgolinterSettings"
+ },
+ "gochecksumtype": {
+ "$ref": "#/definitions/settings/definitions/gochecksumtypeSettings"
+ },
+ "gocognit": {
+ "$ref": "#/definitions/settings/definitions/gocognitSettings"
+ },
+ "goconst": {
+ "$ref": "#/definitions/settings/definitions/goconstSettings"
+ },
+ "gocritic": {
+ "$ref": "#/definitions/settings/definitions/gocriticSettings"
+ },
+ "gocyclo": {
+ "$ref": "#/definitions/settings/definitions/gocycloSettings"
+ },
+ "godot": {
+ "$ref": "#/definitions/settings/definitions/godotSettings"
+ },
+ "godox": {
+ "$ref": "#/definitions/settings/definitions/godoxSettings"
+ },
+ "interfacebloat":{
+ "$ref": "#/definitions/settings/definitions/interfacebloatSettings"
+ },
+ "goheader": {
+ "$ref": "#/definitions/settings/definitions/goheaderSettings"
+ },
+ "gomoddirectives": {
+ "$ref": "#/definitions/settings/definitions/gomoddirectivesSettings"
+ },
+ "gomodguard": {
+ "$ref": "#/definitions/settings/definitions/gomodguardSettings"
+ },
+ "gosec": {
+ "$ref": "#/definitions/settings/definitions/gosecSettings"
+ },
+ "gosmopolitan": {
+ "$ref": "#/definitions/settings/definitions/gosmopolitanSettings"
+ },
+ "govet": {
+ "$ref": "#/definitions/settings/definitions/govetSettings"
+ },
+ "grouper": {
+ "$ref": "#/definitions/settings/definitions/grouperSettings"
+ },
+ "iface": {
+ "$ref": "#/definitions/settings/definitions/ifaceSettings"
+ },
+ "importas": {
+ "$ref": "#/definitions/settings/definitions/importasSettings"
+ },
+ "inamedparam": {
+ "$ref": "#/definitions/settings/definitions/inamedparamSettings"
+ },
+ "ireturn": {
+ "$ref": "#/definitions/settings/definitions/ireturnSettings"
+ },
+ "lll": {
+ "$ref": "#/definitions/settings/definitions/lllSettings"
+ },
+ "maintidx": {
+ "$ref": "#/definitions/settings/definitions/maintidxSettings"
+ },
+ "makezero":{
+ "$ref": "#/definitions/settings/definitions/makezeroSettings"
+ },
+ "loggercheck": {
+ "$ref": "#/definitions/settings/definitions/loggercheckSettings"
+ },
+ "misspell": {
+ "$ref": "#/definitions/settings/definitions/misspellSettings"
+ },
+ "musttag": {
+ "$ref": "#/definitions/settings/definitions/musttagSettings"
+ },
+ "nakedret": {
+ "$ref": "#/definitions/settings/definitions/nakedretSettings"
+ },
+ "nestif": {
+ "$ref": "#/definitions/settings/definitions/nestifSettings"
+ },
+ "nilnil": {
+ "$ref": "#/definitions/settings/definitions/nilnilSettings"
+ },
+ "nlreturn": {
+ "$ref": "#/definitions/settings/definitions/nlreturnSettings"
+ },
+ "mnd": {
+ "$ref": "#/definitions/settings/definitions/mndSettings"
+ },
+ "nolintlint":{
+ "$ref": "#/definitions/settings/definitions/nolintlintSettings"
+ },
+ "reassign": {
+ "$ref": "#/definitions/settings/definitions/reassignSettings"
+ },
+ "recvcheck": {
+ "$ref": "#/definitions/settings/definitions/recvcheckSettings"
+ },
+ "nonamedreturns": {
+ "$ref": "#/definitions/settings/definitions/nonamedreturnsSettings"
+ },
+ "paralleltest": {
+ "$ref": "#/definitions/settings/definitions/paralleltestSettings"
+ },
+ "perfsprint": {
+ "$ref": "#/definitions/settings/definitions/perfsprintSettings"
+ },
+ "prealloc": {
+ "$ref": "#/definitions/settings/definitions/preallocSettings"
+ },
+ "predeclared": {
+ "$ref": "#/definitions/settings/definitions/predeclaredSettings"
+ },
+ "promlinter": {
+ "$ref": "#/definitions/settings/definitions/promlinterSettings"
+ },
+ "protogetter": {
+ "$ref": "#/definitions/settings/definitions/protogetterSettings"
+ },
+ "revive": {
+ "$ref": "#/definitions/settings/definitions/reviveSettings"
+ },
+ "rowserrcheck": {
+ "$ref": "#/definitions/settings/definitions/rowserrcheckSettings"
+ },
+ "sloglint": {
+ "$ref": "#/definitions/settings/definitions/sloglintSettings"
+ },
+ "spancheck": {
+ "$ref": "#/definitions/settings/definitions/spancheckSettings"
+ },
+ "staticcheck":{
+ "$ref": "#/definitions/settings/definitions/staticcheckSettings"
+ },
+ "tagalign": {
+ "$ref": "#/definitions/settings/definitions/tagalignSettings"
+ },
+ "tagliatelle": {
+ "$ref": "#/definitions/settings/definitions/tagliatelleSettings"
+ },
+ "testifylint": {
+ "$ref": "#/definitions/settings/definitions/testifylintSettings"
+ },
+ "testpackage": {
+ "$ref": "#/definitions/settings/definitions/testpackageSettings"
+ },
+ "thelper": {
+ "$ref": "#/definitions/settings/definitions/thelperSettings"
+ },
+ "usestdlibvars": {
+ "$ref": "#/definitions/settings/definitions/usestdlibvarsSettings"
+ },
+ "usetesting": {
+ "$ref": "#/definitions/settings/definitions/usetestingSettings"
+ },
+ "unconvert": {
+ "$ref": "#/definitions/settings/definitions/unconvertSettings"
+ },
+ "unparam": {
+ "$ref": "#/definitions/settings/definitions/unparamSettings"
+ },
+ "unused": {
+ "$ref": "#/definitions/settings/definitions/unusedSettings"
+ },
+ "varnamelen": {
+ "$ref": "#/definitions/settings/definitions/varnamelenSettings"
+ },
+ "whitespace": {
+ "$ref": "#/definitions/settings/definitions/whitespaceSettings"
+ },
+ "wrapcheck": {
+ "$ref": "#/definitions/settings/definitions/wrapcheckSettings"
+ },
+ "wsl": {
+ "$ref": "#/definitions/settings/definitions/wslSettings"
+ },
+ "copyloopvar": {
+ "$ref": "#/definitions/settings/definitions/copyloopvarSettings"
+ },
+ "custom":{
+ "$ref": "#/definitions/settings/definitions/customSettings"
+ }
+ }
+ },
+ "exclusions":{
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "generated": {
+ "enum": ["strict", "lax", "disable"],
+ "default": "strict"
+ },
+ "warn-unused": {
+ "type": "boolean",
+ "default": false
+ },
+ "presets": {
+ "type": "array",
+ "items": {
+ "enum": [
+ "comments",
+ "std-error-handling",
+ "common-false-positives",
+ "legacy"
+ ]
+ }
+ },
+ "rules": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "path": {
+ "type": "string"
+ },
+ "path-except": {
+ "type": "string"
+ },
+ "linters": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linter-names"
+ }
+ },
+ "text": {
+ "type": "string"
+ },
+ "source": {
+ "type": "string"
+ }
+ },
+ "anyOf": [
+ { "required": ["path"] },
+ { "required": ["path-except"] },
+ { "required": ["linters"] },
+ { "required": ["text"] },
+ { "required": ["source"] }
+ ]
+ }
+ },
+ "paths": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "paths-except": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "formatters": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "enable": {
+ "description": "List of enabled formatters.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/formatter-names"
+ }
+ },
+ "settings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "gci": {
+ "$ref": "#/definitions/settings/definitions/gciSettings"
+ },
+ "gofmt": {
+ "$ref": "#/definitions/settings/definitions/gofmtSettings"
+ },
+ "gofumpt": {
+ "$ref": "#/definitions/settings/definitions/gofumptSettings"
+ },
+ "goimports": {
+ "$ref": "#/definitions/settings/definitions/goimportsSettings"
+ },
+ "golines": {
+ "$ref": "#/definitions/settings/definitions/golinesSettings"
+ }
+ }
+ },
+ "exclusions": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "generated": {
+ "enum": ["strict", "lax", "disable"],
+ "default": "strict"
+ },
+ "paths": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "issues": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-issues-per-linter": {
+ "description": "Maximum issues count per one linter. Set to 0 to disable.",
+ "type": "integer",
+ "default": 50,
+ "minimum": 0
+ },
+ "max-same-issues": {
+ "description": "Maximum count of issues with the same text. Set to 0 to disable.",
+ "type": "integer",
+ "default": 3,
+ "minimum": 0
+ },
+ "new": {
+ "description": "Show only new issues: if there are unstaged changes or untracked files, only those changes are analyzed, else only changes in HEAD~ are analyzed.",
+ "type": "boolean",
+ "default": false
+ },
+ "new-from-merge-base": {
+ "description": "Show only new issues created after the best common ancestor (merge-base against HEAD).",
+ "type": "string"
+ },
+ "new-from-rev": {
+ "description": "Show only new issues created after this git revision.",
+ "type": "string"
+ },
+ "new-from-patch": {
+ "description": "Show only new issues created in git patch with this file path.",
+ "type": "string",
+ "examples": ["path/to/patch/file"]
+ },
+ "fix": {
+ "description": "Fix found issues (if it's supported by the linter).",
+ "type": "boolean",
+ "default": false
+ },
+ "uniq-by-line": {
+ "description": "Make issues output unique by line.",
+ "type": "boolean",
+ "default": true
+ },
+ "whole-files": {
+ "description": "Show issues in any part of update files (requires new-from-rev or new-from-patch).",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "severity": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "default": {
+ "description": "Set the default severity for issues. If severity rules are defined and the issues do not match or no severity is provided to the rule this will be the default severity applied. Severities should match the supported severity names of the selected out format.",
+ "type": "string",
+ "default": ""
+ },
+ "rules": {
+ "description": "When a list of severity rules are provided, severity information will be added to lint issues. Severity rules have the same filtering capability as exclude rules except you are allowed to specify one matcher per severity rule.\nOnly affects out formats that support setting severity information.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "severity": {
+ "type": "string"
+ },
+ "path": {
+ "type": "string"
+ },
+ "path-except": {
+ "type": "string"
+ },
+ "linters": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linter-names"
+ }
+ },
+ "text": {
+ "type": "string"
+ },
+ "source": {
+ "type": "string"
+ }
+ },
+ "required": ["severity"],
+ "anyOf": [
+ { "required": ["path"] },
+ { "required": ["path-except"] },
+ { "required": ["linters"] },
+ { "required": ["text"] },
+ { "required": ["source"] }
+ ]
+ },
+ "default": []
+ }
+ },
+ "required": ["default"]
+ }
+ }
+}
diff --git a/vendor/github.com/golangci/golangci-lint/v2/jsonschema/golangci.v2.1.jsonschema.json b/vendor/github.com/golangci/golangci-lint/v2/jsonschema/golangci.v2.1.jsonschema.json
new file mode 100644
index 000000000..0f2ef5fcc
--- /dev/null
+++ b/vendor/github.com/golangci/golangci-lint/v2/jsonschema/golangci.v2.1.jsonschema.json
@@ -0,0 +1,4790 @@
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "$id": "https://json.schemastore.org/golangci-lint.json",
+ "definitions": {
+ "gocritic-checks": {
+ "enum": [
+ "appendAssign",
+ "appendCombine",
+ "argOrder",
+ "assignOp",
+ "badCall",
+ "badCond",
+ "badLock",
+ "badRegexp",
+ "badSorting",
+ "badSyncOnceFunc",
+ "boolExprSimplify",
+ "builtinShadow",
+ "builtinShadowDecl",
+ "captLocal",
+ "caseOrder",
+ "codegenComment",
+ "commentFormatting",
+ "commentedOutCode",
+ "commentedOutImport",
+ "defaultCaseOrder",
+ "deferInLoop",
+ "deferUnlambda",
+ "deprecatedComment",
+ "docStub",
+ "dupArg",
+ "dupBranchBody",
+ "dupCase",
+ "dupImport",
+ "dupSubExpr",
+ "dynamicFmtString",
+ "elseif",
+ "emptyDecl",
+ "emptyFallthrough",
+ "emptyStringTest",
+ "equalFold",
+ "evalOrder",
+ "exitAfterDefer",
+ "exposedSyncMutex",
+ "externalErrorReassign",
+ "filepathJoin",
+ "flagDeref",
+ "flagName",
+ "hexLiteral",
+ "httpNoBody",
+ "hugeParam",
+ "ifElseChain",
+ "importShadow",
+ "indexAlloc",
+ "initClause",
+ "ioutilDeprecated",
+ "mapKey",
+ "methodExprCall",
+ "nestingReduce",
+ "newDeref",
+ "nilValReturn",
+ "octalLiteral",
+ "offBy1",
+ "paramTypeCombine",
+ "preferDecodeRune",
+ "preferFilepathJoin",
+ "preferFprint",
+ "preferStringWriter",
+ "preferWriteByte",
+ "ptrToRefParam",
+ "rangeAppendAll",
+ "rangeExprCopy",
+ "rangeValCopy",
+ "redundantSprint",
+ "regexpMust",
+ "regexpPattern",
+ "regexpSimplify",
+ "returnAfterHttpError",
+ "ruleguard",
+ "singleCaseSwitch",
+ "sliceClear",
+ "sloppyLen",
+ "sloppyReassign",
+ "sloppyTypeAssert",
+ "sortSlice",
+ "sprintfQuotedString",
+ "sqlQuery",
+ "stringConcatSimplify",
+ "stringXbytes",
+ "stringsCompare",
+ "switchTrue",
+ "syncMapLoadAndDelete",
+ "timeExprSimplify",
+ "todoCommentWithoutDetail",
+ "tooManyResultsChecker",
+ "truncateCmp",
+ "typeAssertChain",
+ "typeDefFirst",
+ "typeSwitchVar",
+ "typeUnparen",
+ "uncheckedInlineErr",
+ "underef",
+ "unlabelStmt",
+ "unlambda",
+ "unnamedResult",
+ "unnecessaryBlock",
+ "unnecessaryDefer",
+ "unslice",
+ "valSwap",
+ "weakCond",
+ "whyNoLint",
+ "wrapperFunc",
+ "yodaStyleExpr"
+ ]
+ },
+ "gocritic-tags": {
+ "enum": [
+ "diagnostic",
+ "style",
+ "performance",
+ "experimental",
+ "opinionated",
+ "security"
+ ]
+ },
+ "staticcheck-checks": {
+ "enum": [
+ "*",
+ "all",
+ "SA*",
+ "-SA*",
+ "SA1*",
+ "-SA1*",
+ "SA1000",
+ "-SA1000",
+ "SA1001",
+ "-SA1001",
+ "SA1002",
+ "-SA1002",
+ "SA1003",
+ "-SA1003",
+ "SA1004",
+ "-SA1004",
+ "SA1005",
+ "-SA1005",
+ "SA1006",
+ "-SA1006",
+ "SA1007",
+ "-SA1007",
+ "SA1008",
+ "-SA1008",
+ "SA1010",
+ "-SA1010",
+ "SA1011",
+ "-SA1011",
+ "SA1012",
+ "-SA1012",
+ "SA1013",
+ "-SA1013",
+ "SA1014",
+ "-SA1014",
+ "SA1015",
+ "-SA1015",
+ "SA1016",
+ "-SA1016",
+ "SA1017",
+ "-SA1017",
+ "SA1018",
+ "-SA1018",
+ "SA1019",
+ "-SA1019",
+ "SA1020",
+ "-SA1020",
+ "SA1021",
+ "-SA1021",
+ "SA1023",
+ "-SA1023",
+ "SA1024",
+ "-SA1024",
+ "SA1025",
+ "-SA1025",
+ "SA1026",
+ "-SA1026",
+ "SA1027",
+ "-SA1027",
+ "SA1028",
+ "-SA1028",
+ "SA1029",
+ "-SA1029",
+ "SA1030",
+ "-SA1030",
+ "SA1031",
+ "-SA1031",
+ "SA1032",
+ "-SA1032",
+ "SA2*",
+ "-SA2*",
+ "SA2000",
+ "-SA2000",
+ "SA2001",
+ "-SA2001",
+ "SA2002",
+ "-SA2002",
+ "SA2003",
+ "-SA2003",
+ "SA3*",
+ "-SA3*",
+ "SA3000",
+ "-SA3000",
+ "SA3001",
+ "-SA3001",
+ "SA4*",
+ "-SA4*",
+ "SA4000",
+ "-SA4000",
+ "SA4001",
+ "-SA4001",
+ "SA4003",
+ "-SA4003",
+ "SA4004",
+ "-SA4004",
+ "SA4005",
+ "-SA4005",
+ "SA4006",
+ "-SA4006",
+ "SA4008",
+ "-SA4008",
+ "SA4009",
+ "-SA4009",
+ "SA4010",
+ "-SA4010",
+ "SA4011",
+ "-SA4011",
+ "SA4012",
+ "-SA4012",
+ "SA4013",
+ "-SA4013",
+ "SA4014",
+ "-SA4014",
+ "SA4015",
+ "-SA4015",
+ "SA4016",
+ "-SA4016",
+ "SA4017",
+ "-SA4017",
+ "SA4018",
+ "-SA4018",
+ "SA4019",
+ "-SA4019",
+ "SA4020",
+ "-SA4020",
+ "SA4021",
+ "-SA4021",
+ "SA4022",
+ "-SA4022",
+ "SA4023",
+ "-SA4023",
+ "SA4024",
+ "-SA4024",
+ "SA4025",
+ "-SA4025",
+ "SA4026",
+ "-SA4026",
+ "SA4027",
+ "-SA4027",
+ "SA4028",
+ "-SA4028",
+ "SA4029",
+ "-SA4029",
+ "SA4030",
+ "-SA4030",
+ "SA4031",
+ "-SA4031",
+ "SA4032",
+ "-SA4032",
+ "SA5*",
+ "-SA5*",
+ "SA5000",
+ "-SA5000",
+ "SA5001",
+ "-SA5001",
+ "SA5002",
+ "-SA5002",
+ "SA5003",
+ "-SA5003",
+ "SA5004",
+ "-SA5004",
+ "SA5005",
+ "-SA5005",
+ "SA5007",
+ "-SA5007",
+ "SA5008",
+ "-SA5008",
+ "SA5009",
+ "-SA5009",
+ "SA5010",
+ "-SA5010",
+ "SA5011",
+ "-SA5011",
+ "SA5012",
+ "-SA5012",
+ "SA6*",
+ "-SA6*",
+ "SA6000",
+ "-SA6000",
+ "SA6001",
+ "-SA6001",
+ "SA6002",
+ "-SA6002",
+ "SA6003",
+ "-SA6003",
+ "SA6005",
+ "-SA6005",
+ "SA6006",
+ "-SA6006",
+ "SA9*",
+ "-SA9*",
+ "SA9001",
+ "-SA9001",
+ "SA9002",
+ "-SA9002",
+ "SA9003",
+ "-SA9003",
+ "SA9004",
+ "-SA9004",
+ "SA9005",
+ "-SA9005",
+ "SA9006",
+ "-SA9006",
+ "SA9007",
+ "-SA9007",
+ "SA9008",
+ "-SA9008",
+ "SA9009",
+ "-SA9009",
+ "ST*",
+ "-ST*",
+ "ST1*",
+ "-ST1*",
+ "ST1000",
+ "-ST1000",
+ "ST1001",
+ "-ST1001",
+ "ST1003",
+ "-ST1003",
+ "ST1005",
+ "-ST1005",
+ "ST1006",
+ "-ST1006",
+ "ST1008",
+ "-ST1008",
+ "ST1011",
+ "-ST1011",
+ "ST1012",
+ "-ST1012",
+ "ST1013",
+ "-ST1013",
+ "ST1015",
+ "-ST1015",
+ "ST1016",
+ "-ST1016",
+ "ST1017",
+ "-ST1017",
+ "ST1018",
+ "-ST1018",
+ "ST1019",
+ "-ST1019",
+ "ST1020",
+ "-ST1020",
+ "ST1021",
+ "-ST1021",
+ "ST1022",
+ "-ST1022",
+ "ST1023",
+ "-ST1023",
+ "S*",
+ "-S*",
+ "S1*",
+ "-S1*",
+ "S1000",
+ "-S1000",
+ "S1001",
+ "-S1001",
+ "S1002",
+ "-S1002",
+ "S1003",
+ "-S1003",
+ "S1004",
+ "-S1004",
+ "S1005",
+ "-S1005",
+ "S1006",
+ "-S1006",
+ "S1007",
+ "-S1007",
+ "S1008",
+ "-S1008",
+ "S1009",
+ "-S1009",
+ "S1010",
+ "-S1010",
+ "S1011",
+ "-S1011",
+ "S1012",
+ "-S1012",
+ "S1016",
+ "-S1016",
+ "S1017",
+ "-S1017",
+ "S1018",
+ "-S1018",
+ "S1019",
+ "-S1019",
+ "S1020",
+ "-S1020",
+ "S1021",
+ "-S1021",
+ "S1023",
+ "-S1023",
+ "S1024",
+ "-S1024",
+ "S1025",
+ "-S1025",
+ "S1028",
+ "-S1028",
+ "S1029",
+ "-S1029",
+ "S1030",
+ "-S1030",
+ "S1031",
+ "-S1031",
+ "S1032",
+ "-S1032",
+ "S1033",
+ "-S1033",
+ "S1034",
+ "-S1034",
+ "S1035",
+ "-S1035",
+ "S1036",
+ "-S1036",
+ "S1037",
+ "-S1037",
+ "S1038",
+ "-S1038",
+ "S1039",
+ "-S1039",
+ "S1040",
+ "-S1040",
+ "QF*",
+ "-QF*",
+ "QF1*",
+ "-QF1*",
+ "QF1001",
+ "-QF1001",
+ "QF1002",
+ "-QF1002",
+ "QF1003",
+ "-QF1003",
+ "QF1004",
+ "-QF1004",
+ "QF1005",
+ "-QF1005",
+ "QF1006",
+ "-QF1006",
+ "QF1007",
+ "-QF1007",
+ "QF1008",
+ "-QF1008",
+ "QF1009",
+ "-QF1009",
+ "QF1010",
+ "-QF1010",
+ "QF1011",
+ "-QF1011",
+ "QF1012",
+ "-QF1012"
+ ]
+ },
+ "gosec-rules": {
+ "enum": [
+ "G101",
+ "G102",
+ "G103",
+ "G104",
+ "G106",
+ "G107",
+ "G108",
+ "G109",
+ "G110",
+ "G111",
+ "G112",
+ "G114",
+ "G115",
+ "G201",
+ "G202",
+ "G203",
+ "G204",
+ "G301",
+ "G302",
+ "G303",
+ "G304",
+ "G305",
+ "G306",
+ "G307",
+ "G401",
+ "G402",
+ "G403",
+ "G404",
+ "G405",
+ "G406",
+ "G501",
+ "G502",
+ "G503",
+ "G504",
+ "G505",
+ "G506",
+ "G507",
+ "G601",
+ "G602"
+ ]
+ },
+ "govet-analyzers": {
+ "enum": [
+ "appends",
+ "asmdecl",
+ "assign",
+ "atomic",
+ "atomicalign",
+ "bools",
+ "buildtag",
+ "cgocall",
+ "composites",
+ "copylocks",
+ "deepequalerrors",
+ "defers",
+ "directive",
+ "errorsas",
+ "fieldalignment",
+ "findcall",
+ "framepointer",
+ "httpmux",
+ "httpresponse",
+ "ifaceassert",
+ "loopclosure",
+ "lostcancel",
+ "nilfunc",
+ "nilness",
+ "printf",
+ "reflectvaluecompare",
+ "shadow",
+ "shift",
+ "sigchanyzer",
+ "slog",
+ "sortslice",
+ "stdmethods",
+ "stdversion",
+ "stringintconv",
+ "structtag",
+ "testinggoroutine",
+ "tests",
+ "timeformat",
+ "unmarshal",
+ "unreachable",
+ "unsafeptr",
+ "unusedresult",
+ "unusedwrite",
+ "waitgroup"
+ ]
+ },
+ "revive-rules": {
+ "enum": [
+ "add-constant",
+ "argument-limit",
+ "atomic",
+ "banned-characters",
+ "bare-return",
+ "blank-imports",
+ "bool-literal-in-expr",
+ "call-to-gc",
+ "cognitive-complexity",
+ "comment-spacings",
+ "comments-density",
+ "confusing-naming",
+ "confusing-results",
+ "constant-logical-expr",
+ "context-as-argument",
+ "context-keys-type",
+ "cyclomatic",
+ "datarace",
+ "deep-exit",
+ "defer",
+ "dot-imports",
+ "duplicated-imports",
+ "early-return",
+ "empty-block",
+ "empty-lines",
+ "enforce-map-style",
+ "enforce-repeated-arg-type-style",
+ "enforce-slice-style",
+ "error-naming",
+ "error-return",
+ "error-strings",
+ "errorf",
+ "exported",
+ "file-header",
+ "file-length-limit",
+ "filename-format",
+ "flag-parameter",
+ "function-length",
+ "function-result-limit",
+ "get-return",
+ "identical-branches",
+ "if-return",
+ "import-alias-naming",
+ "import-shadowing",
+ "imports-blocklist",
+ "increment-decrement",
+ "indent-error-flow",
+ "line-length-limit",
+ "max-control-nesting",
+ "max-public-structs",
+ "modifies-parameter",
+ "modifies-value-receiver",
+ "nested-structs",
+ "optimize-operands-order",
+ "package-comments",
+ "range-val-address",
+ "range-val-in-closure",
+ "range",
+ "receiver-naming",
+ "redefines-builtin-id",
+ "redundant-build-tag",
+ "redundant-import-alias",
+ "redundant-test-main-exit",
+ "string-format",
+ "string-of-int",
+ "struct-tag",
+ "superfluous-else",
+ "time-equal",
+ "time-naming",
+ "unchecked-type-assertion",
+ "unconditional-recursion",
+ "unexported-naming",
+ "unexported-return",
+ "unhandled-error",
+ "unnecessary-stmt",
+ "unreachable-code",
+ "unused-parameter",
+ "unused-receiver",
+ "use-any",
+ "use-errors-new",
+ "useless-break",
+ "var-declaration",
+ "var-naming",
+ "waitgroup-by-value"
+ ]
+ },
+ "iface-analyzers": {
+ "enum": [
+ "identical",
+ "unused",
+ "opaque"
+ ]
+ },
+ "tagliatelle-cases": {
+ "enum": [
+ "",
+ "camel",
+ "pascal",
+ "kebab",
+ "snake",
+ "goCamel",
+ "goPascal",
+ "goKebab",
+ "goSnake",
+ "upper",
+ "upperSnake",
+ "lower",
+ "header"
+ ]
+ },
+ "relative-path-modes": {
+ "enum": [
+ "gomod",
+ "gitroot",
+ "cfg",
+ "wd"
+ ]
+ },
+ "simple-format": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "path": {
+ "$ref": "#/definitions/formats-path",
+ "default": "stdout"
+ }
+ }
+ },
+ "formats-path" : {
+ "anyOf": [
+ {
+ "enum": [
+ "stdout",
+ "stderr"
+ ]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ },
+ "linter-names": {
+ "$comment": "anyOf with enum is used to allow auto-completion of non-custom linters",
+ "description": "Usable linter names.",
+ "anyOf": [
+ {
+ "enum": [
+ "asasalint",
+ "asciicheck",
+ "bidichk",
+ "bodyclose",
+ "canonicalheader",
+ "containedctx",
+ "contextcheck",
+ "copyloopvar",
+ "cyclop",
+ "decorder",
+ "depguard",
+ "dogsled",
+ "dupl",
+ "dupword",
+ "durationcheck",
+ "errcheck",
+ "errchkjson",
+ "errname",
+ "errorlint",
+ "exhaustive",
+ "exhaustruct",
+ "exptostd",
+ "fatcontext",
+ "forbidigo",
+ "forcetypeassert",
+ "funcorder",
+ "funlen",
+ "ginkgolinter",
+ "gocheckcompilerdirectives",
+ "gochecknoglobals",
+ "gochecknoinits",
+ "gochecksumtype",
+ "gocognit",
+ "goconst",
+ "gocritic",
+ "gocyclo",
+ "godot",
+ "godox",
+ "err113",
+ "goheader",
+ "gomoddirectives",
+ "gomodguard",
+ "goprintffuncname",
+ "gosec",
+ "gosimple",
+ "gosmopolitan",
+ "govet",
+ "grouper",
+ "iface",
+ "importas",
+ "inamedparam",
+ "ineffassign",
+ "interfacebloat",
+ "intrange",
+ "ireturn",
+ "lll",
+ "loggercheck",
+ "maintidx",
+ "makezero",
+ "mirror",
+ "misspell",
+ "mnd",
+ "musttag",
+ "nakedret",
+ "nestif",
+ "nilerr",
+ "nilnesserr",
+ "nilnil",
+ "nlreturn",
+ "noctx",
+ "nolintlint",
+ "nonamedreturns",
+ "nosprintfhostport",
+ "paralleltest",
+ "perfsprint",
+ "prealloc",
+ "predeclared",
+ "promlinter",
+ "protogetter",
+ "reassign",
+ "recvcheck",
+ "revive",
+ "rowserrcheck",
+ "sloglint",
+ "sqlclosecheck",
+ "staticcheck",
+ "stylecheck",
+ "tagalign",
+ "tagliatelle",
+ "testableexamples",
+ "testifylint",
+ "testpackage",
+ "thelper",
+ "tparallel",
+ "unconvert",
+ "unparam",
+ "unused",
+ "usestdlibvars",
+ "usetesting",
+ "varnamelen",
+ "wastedassign",
+ "whitespace",
+ "wrapcheck",
+ "wsl",
+ "zerologlint"
+ ]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ },
+ "formatter-names": {
+ "description": "Usable formatter names.",
+ "enum": [
+ "gci",
+ "gofmt",
+ "gofumpt",
+ "goimports",
+ "golines"
+ ]
+ },
+ "settings": {
+ "definitions": {
+ "dupwordSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "keywords": {
+ "description": "Keywords for detecting duplicate words. If this list is not empty, only the words defined in this list will be detected.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["the", "and", "a"]
+ }
+ },
+ "ignore": {
+ "description": "Keywords used to ignore detection.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["0C0C"]
+ }
+ }
+ }
+ },
+ "asasalintSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "exclude": {
+ "description": "To specify a set of function names to exclude.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["\\.Wrapf"]
+ }
+ },
+ "use-builtin-exclusions": {
+ "description": "To enable/disable the asasalint builtin exclusions of function names.",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "bidichkSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "left-to-right-embedding": {
+ "description": "Disallow: LEFT-TO-RIGHT-EMBEDDING",
+ "type": "boolean",
+ "default": false
+ },
+ "right-to-left-embedding": {
+ "description": "Disallow: RIGHT-TO-LEFT-EMBEDDING",
+ "type": "boolean",
+ "default": false
+ },
+ "pop-directional-formatting": {
+ "description": "Disallow: POP-DIRECTIONAL-FORMATTING",
+ "type": "boolean",
+ "default": false
+ },
+ "left-to-right-override": {
+ "description": "Disallow: LEFT-TO-RIGHT-OVERRIDE",
+ "type": "boolean",
+ "default": false
+ },
+ "right-to-left-override": {
+ "description": "Disallow: RIGHT-TO-LEFT-OVERRIDE",
+ "type": "boolean",
+ "default": false
+ },
+ "left-to-right-isolate": {
+ "description": "Disallow: LEFT-TO-RIGHT-ISOLATE",
+ "type": "boolean",
+ "default": false
+ },
+ "right-to-left-isolate": {
+ "description": "Disallow: RIGHT-TO-LEFT-ISOLATE",
+ "type": "boolean",
+ "default": false
+ },
+ "first-strong-isolate": {
+ "description": "Disallow: FIRST-STRONG-ISOLATE",
+ "type": "boolean",
+ "default": false
+ },
+ "pop-directional-isolate": {
+ "description": "Disallow: POP-DIRECTIONAL-ISOLATE",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "cyclopSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-complexity": {
+ "description": "Max complexity the function can have",
+ "type": "integer",
+ "default": 10,
+ "minimum": 0
+ },
+ "package-average": {
+ "description": "Max average complexity in package",
+ "type": "number",
+ "default": 0,
+ "minimum": 0
+ }
+ }
+ },
+ "decorderSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "dec-order": {
+ "type": "array",
+ "default": [["type", "const", "var", "func"]],
+ "items": {
+ "enum": ["type", "const", "var", "func"]
+ }
+ },
+ "ignore-underscore-vars": {
+ "description": "Underscore vars (vars with \"_\" as the name) will be ignored at all checks",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-dec-order-check": {
+ "description": "Order of declarations is not checked",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-init-func-first-check": {
+ "description": "Allow init func to be anywhere in file",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-dec-num-check": {
+ "description": "Multiple global type, const and var declarations are allowed",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-type-dec-num-check": {
+ "description": "Type declarations will be ignored for dec num check",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-const-dec-num-check": {
+ "description": "Const declarations will be ignored for dec num check",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-var-dec-num-check": {
+ "description": "Var declarations will be ignored for dec num check",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ },
+ "depguardSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "rules": {
+ "description": "Rules to apply.",
+ "type": "object",
+ "additionalProperties": false,
+ "patternProperties": {
+ "^[^.]+$": {
+ "description": "Name of a rule.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "list-mode": {
+ "description": "Used to determine the package matching priority.",
+ "enum": ["original", "strict", "lax"],
+ "default": "original"
+ },
+ "files": {
+ "description": "List of file globs that will match this list of settings to compare against.",
+ "additionalProperties": false,
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "allow": {
+ "description": "List of allowed packages.",
+ "additionalProperties": false,
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "deny": {
+ "description": "Packages that are not allowed where the value is a suggestion.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "desc": {
+ "description": "Description",
+ "type": "string"
+ },
+ "pkg": {
+ "description": "Package",
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "dogsledSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-blank-identifiers": {
+ "description": "Check assignments with too many blank identifiers.",
+ "type": "integer",
+ "default": 2,
+ "minimum": 0
+ }
+ }
+ },
+ "duplSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "threshold": {
+ "description": "Tokens count to trigger issue.",
+ "type": "integer",
+ "default": 150,
+ "minimum": 0
+ }
+ }
+ },
+ "errcheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-type-assertions": {
+ "description": "Report about not checking errors in type assertions, i.e.: `a := b.(MyStruct)`",
+ "type": "boolean",
+ "default": false
+ },
+ "check-blank": {
+ "description": "Report about assignment of errors to blank identifier",
+ "type": "boolean",
+ "default": false
+ },
+ "exclude-functions": {
+ "description": "List of functions to exclude from checking, where each entry is a single function to exclude",
+ "type": "array",
+ "examples": ["io/ioutil.ReadFile", "io.Copy(*bytes.Buffer)"],
+ "items": {
+ "type": "string"
+ }
+ },
+ "disable-default-exclusions": {
+ "description": "To disable the errcheck built-in exclude list",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "errchkjsonSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-error-free-encoding": {
+ "type": "boolean",
+ "default": false
+ },
+ "report-no-exported": {
+ "description": "Issue on struct that doesn't have exported fields.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "errorlintSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "errorf": {
+ "description": "Check whether fmt.Errorf uses the %w verb for formatting errors",
+ "type": "boolean",
+ "default": true
+ },
+ "errorf-multi": {
+ "description": "Permit more than 1 %w verb, valid per Go 1.20",
+ "type": "boolean",
+ "default": true
+ },
+ "asserts": {
+ "description": "Check for plain type assertions and type switches.",
+ "type": "boolean",
+ "default": true
+ },
+ "comparison": {
+ "description": "Check for plain error comparisons",
+ "type": "boolean",
+ "default": true
+ },
+ "allowed-errors": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "err": {
+ "type": "string"
+ },
+ "fun": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "allowed-errors-wildcard": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "err": {
+ "type": "string"
+ },
+ "fun": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "exhaustiveSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check": {
+ "description": "Program elements to check for exhaustiveness.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["switch", "map"]
+ }
+ },
+ "explicit-exhaustive-switch": {
+ "description": "Only run exhaustive check on switches with \"//exhaustive:enforce\" comment.",
+ "type": "boolean",
+ "default": false
+ },
+ "explicit-exhaustive-map": {
+ "description": "Only run exhaustive check on map literals with \"//exhaustive:enforce\" comment.",
+ "type": "boolean",
+ "default": false
+ },
+ "default-case-required": {
+ "description": "Switch statement requires default case even if exhaustive.",
+ "type": "boolean",
+ "default": false
+ },
+ "default-signifies-exhaustive": {
+ "description": "Presence of `default` case in switch statements satisfies exhaustiveness, even if all enum members are not listed.",
+ "type": "boolean",
+ "default": false
+ },
+ "ignore-enum-members": {
+ "description": "Enum members matching `regex` do not have to be listed in switch statements to satisfy exhaustiveness",
+ "type": "string"
+ },
+ "ignore-enum-types": {
+ "description": "Enum types matching the supplied regex do not have to be listed in switch statements to satisfy exhaustiveness.",
+ "type": "string"
+ },
+ "package-scope-only": {
+ "description": "Consider enums only in package scopes, not in inner scopes.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "exhaustructSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "include": {
+ "description": "List of regular expressions to match struct packages and names.",
+ "type": "array",
+ "examples": [".*\\.Test"],
+ "items": {
+ "type": "string"
+ }
+ },
+ "exclude": {
+ "description": "List of regular expressions to exclude struct packages and names from check.",
+ "type": "array",
+ "examples": ["cobra\\.Command$"],
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "fatcontextSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-struct-pointers": {
+ "description": "Check for potential fat contexts in struct pointers.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "forbidigoSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "exclude-godoc-examples": {
+ "description": "Exclude code in godoc examples.",
+ "type": "boolean",
+ "default": true
+ },
+ "analyze-types": {
+ "description": "Instead of matching the literal source code, use type information to replace expressions with strings that contain the package name and (for methods and fields) the type name.",
+ "type": "boolean",
+ "default": true
+ },
+ "forbid": {
+ "description": "List of identifiers to forbid (written using `regexp`)",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "pattern": {
+ "description": "Pattern",
+ "type": "string"
+ },
+ "pkg": {
+ "description": "Package",
+ "type": "string"
+ },
+ "msg": {
+ "description": "Message",
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "funcorderSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "constructor": {
+ "description": "Checks that constructors are placed after the structure declaration.",
+ "type": "boolean",
+ "default": true
+ },
+ "struct-method": {
+ "description": "Checks if the exported methods of a structure are placed before the non-exported ones.",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "funlenSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "lines": {
+ "description": "Limit lines number per function.",
+ "type": "integer",
+ "default": 60
+ },
+ "statements": {
+ "description": "Limit statements number per function.",
+ "type": "integer",
+ "default": 40
+ },
+ "ignore-comments": {
+ "description": "Ignore comments when counting lines.",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "gciSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "sections": {
+ "description": "Section configuration to compare against.",
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "enum": [
+ "standard",
+ "default",
+ "blank",
+ "dot",
+ "alias",
+ "localmodule"
+ ]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ },
+ "default": ["standard", "default"]
+ },
+ "no-inline-comments": {
+ "description": "Checks that no inline Comments are present.",
+ "type": "boolean",
+ "default": false
+ },
+ "no-prefix-comments": {
+ "description": "Checks that no prefix Comments(comment lines above an import) are present.",
+ "type": "boolean",
+ "default": false
+ },
+ "custom-order": {
+ "description": "Enable custom order of sections.",
+ "type": "boolean",
+ "default": false
+ },
+ "no-lex-order": {
+ "description": "Drops lexical ordering for custom sections.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "ginkgolinterSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "suppress-len-assertion": {
+ "description": "Suppress the wrong length assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-nil-assertion": {
+ "description": "Suppress the wrong nil assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-err-assertion": {
+ "description": "Suppress the wrong error assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-compare-assertion": {
+ "description": "Suppress the wrong comparison assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-async-assertion": {
+ "description": "Suppress the function all in async assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-type-compare-assertion": {
+ "description": "Suppress warning for comparing values from different types, like int32 and uint32.",
+ "type": "boolean",
+ "default": false
+ },
+ "forbid-focus-container": {
+ "description": "Trigger warning for ginkgo focus containers like FDescribe, FContext, FWhen or FIt.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-havelen-zero": {
+ "description": "Don't trigger warnings for HaveLen(0).",
+ "type": "boolean",
+ "default": false
+ },
+ "force-expect-to": {
+ "description": "Force using `Expect` with `To`, `ToNot` or `NotTo`",
+ "type": "boolean",
+ "default": false
+ },
+ "validate-async-intervals": {
+ "description": "Best effort validation of async intervals (timeout and polling).",
+ "type": "boolean",
+ "default": false
+ },
+ "forbid-spec-pollution": {
+ "description": "Trigger a warning for variable assignments in ginkgo containers like `Describe`, `Context` and `When`, instead of in `BeforeEach()`.",
+ "type": "boolean",
+ "default": false
+ },
+ "force-succeed": {
+ "description": "Force using the Succeed matcher for error functions, and the HaveOccurred matcher for non-function error values.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "gochecksumtypeSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "default-signifies-exhaustive": {
+ "description": "Presence of `default` case in switch statements satisfies exhaustiveness, if all members are not listed.",
+ "type": "boolean",
+ "default": true
+ },
+ "include-shared-interfaces": {
+ "description": "Include shared interfaces in the exhaustiviness check.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "gocognitSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "min-complexity": {
+ "description": "Minimal code complexity to report (we recommend 10-20).",
+ "type": "integer",
+ "default": 30
+ }
+ }
+ },
+ "goconstSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "match-constant": {
+ "description": "Look for existing constants matching the values",
+ "type": "boolean",
+ "default": true
+ },
+ "min-len": {
+ "description": "Minimum length of string constant.",
+ "type": "integer",
+ "default": 3
+ },
+ "min-occurrences": {
+ "description": "Minimum occurrences count to trigger.",
+ "type": "integer",
+ "default": 3
+ },
+ "ignore-calls": {
+ "description": "Ignore when constant is not used as function argument",
+ "type": "boolean",
+ "default": true
+ },
+ "ignore-string-values": {
+ "description": "Exclude strings matching the given regular expression",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "numbers": {
+ "description": "Search also for duplicated numbers.",
+ "type": "boolean",
+ "default": false
+ },
+ "min": {
+ "description": "Minimum value, only works with `numbers`",
+ "type": "integer",
+ "default": 3
+ },
+ "max": {
+ "description": "Maximum value, only works with `numbers`",
+ "type": "integer",
+ "default": 3
+ },
+ "find-duplicates": {
+ "description": "Detects constants with identical values",
+ "type": "boolean",
+ "default": false
+ },
+ "eval-const-expressions": {
+ "description": "Evaluates of constant expressions like Prefix + \"suffix\"",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "gocriticSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "enabled-checks": {
+ "description": "Which checks should be enabled. By default, a list of stable checks is used. To see it, run `GL_DEBUG=gocritic golangci-lint run`.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/gocritic-checks"
+ }
+ },
+ "disabled-checks": {
+ "description": "Which checks should be disabled.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/gocritic-checks"
+ },
+ "default": []
+ },
+ "enabled-tags": {
+ "description": "Enable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/gocritic-tags"
+ }
+ },
+ "disabled-tags": {
+ "description": "Disable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/gocritic-tags"
+ }
+ },
+ "settings": {
+ "description": "Settings passed to gocritic. Properties must be valid and enabled check names.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "captLocal": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "paramsOnly" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "commentedOutCode": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "minLength" : {
+ "type": "number",
+ "default": 15
+ }
+ }
+ },
+ "elseif": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skipBalanced" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "hugeParam": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "sizeThreshold" : {
+ "type": "number",
+ "default": 80
+ }
+ }
+ },
+ "ifElseChain": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "minThreshold" : {
+ "type": "number",
+ "default": 2
+ }
+ }
+ },
+ "nestingReduce": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "bodyWidth" : {
+ "type": "number",
+ "default": 5
+ }
+ }
+ },
+ "rangeExprCopy": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "sizeThreshold" : {
+ "type": "number",
+ "default": 512
+ },
+ "skipTestFuncs" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "rangeValCopy": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "sizeThreshold" : {
+ "type": "number",
+ "default": 128
+ },
+ "skipTestFuncs" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "ruleguard": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "debug" : {
+ "type": "string"
+ },
+ "enable" : {
+ "type": "string"
+ },
+ "disable" : {
+ "type": "string"
+ },
+ "failOn" : {
+ "type": "string"
+ },
+ "rules" : {
+ "type": "string"
+ }
+ }
+ },
+ "tooManyResultsChecker": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "maxResults" : {
+ "type": "number",
+ "default": 5
+ }
+ }
+ },
+ "truncateCmp": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skipArchDependent" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "underef": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skipRecvDeref" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "unnamedResult": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "checkExported" : {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ }
+ }
+ },
+ "disable-all": {
+ "type": "boolean",
+ "default": false
+ },
+ "enable-all": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "gocycloSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "min-complexity": {
+ "description": "Minimum code complexity to report (we recommend 10-20).",
+ "type": "integer",
+ "default": 30
+ }
+ }
+ },
+ "godotSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "scope": {
+ "description": "Comments to be checked.",
+ "enum": ["declarations", "toplevel", "all"],
+ "default": "declarations"
+ },
+ "exclude": {
+ "description": "List of regexps for excluding particular comment lines from check.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "period": {
+ "description": "Check that each sentence ends with a period.",
+ "type": "boolean",
+ "default": true
+ },
+ "capital": {
+ "description": "Check that each sentence starts with a capital letter.",
+ "type": "boolean",
+ "default": false
+ },
+ "check-all": {
+ "description": "DEPRECATED: Check all top-level comments, not only declarations.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "godoxSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "keywords": {
+ "description": "Report any comments starting with one of these keywords. This is useful for TODO or FIXME comments that might be left in the code accidentally and should be resolved before merging.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "default": ["TODO", "BUG", "FIXME"]
+ }
+ }
+ },
+ "gofmtSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "simplify": {
+ "description": "Simplify code.",
+ "type": "boolean",
+ "default": true
+ },
+ "rewrite-rules": {
+ "description": "Apply the rewrite rules to the source before reformatting.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "pattern": {
+ "type": "string"
+ },
+ "replacement": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "golinesSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-len": {
+ "type": "integer",
+ "default": 100
+ },
+ "tab-len": {
+ "type": "integer",
+ "default": 4
+ },
+ "shorten-comments": {
+ "type": "boolean",
+ "default": false
+ },
+ "reformat-tags": {
+ "type": "boolean",
+ "default": true
+ },
+ "chain-split-dots": {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "interfacebloatSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max": {
+ "description": "The maximum number of methods allowed for an interface.",
+ "type": "integer"
+ }
+ }
+ },
+ "gofumptSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "extra-rules": {
+ "description": "Choose whether or not to use the extra rules that are disabled by default.",
+ "type": "boolean",
+ "default": false
+ },
+ "module-path": {
+ "description": " Module path which contains the source code being formatted.",
+ "type": "string"
+ }
+ }
+ },
+ "goheaderSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "values": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "const": {
+ "description": "Constants to use in the template.",
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "description": "Value for the constant.",
+ "type": "string"
+ }
+ },
+ "additionalProperties": false,
+ "examples": [
+ {
+ "YEAR": "2030",
+ "COMPANY": "MY FUTURISTIC COMPANY"
+ }
+ ]
+ },
+ "regexp": {
+ "description": "Regular expressions to use in your template.",
+ "type": "object",
+ "additionalProperties": false,
+ "patternProperties": {
+ "^.+$": {
+ "type": "string"
+ }
+ },
+ "examples": [
+ {
+ "AUTHOR": ".*@mycompany\\.com"
+ }
+ ]
+ }
+ }
+ },
+ "template": {
+ "description": "Template to put on top of every file.",
+ "type": "string",
+ "examples": [
+ "{{ MY COMPANY }}\nSPDX-License-Identifier: Apache-2.0\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at:\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License."
+ ]
+ },
+ "template-path": {
+ "description": "Path to the file containing the template source.",
+ "type": "string",
+ "examples": ["my_header_template.txt"]
+ }
+ },
+ "oneOf": [
+ { "required": ["template"] },
+ { "required": ["template-path"] }
+ ]
+ },
+ "goimportsSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "local-prefixes": {
+ "description": "Put imports beginning with prefix after 3rd-party packages. It is a list of prefixes.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "gomoddirectivesSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "replace-local": {
+ "description": "Allow local `replace` directives.",
+ "type": "boolean",
+ "default": true
+ },
+ "replace-allow-list": {
+ "description": "List of allowed `replace` directives.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "retract-allow-no-explanation": {
+ "description": "Allow to not explain why the version has been retracted in the `retract` directives.",
+ "type": "boolean",
+ "default": false
+ },
+ "exclude-forbidden": {
+ "description": "Forbid the use of the `exclude` directives.",
+ "type": "boolean",
+ "default": false
+ },
+ "toolchain-forbidden": {
+ "description": "Forbid the use of the `toolchain` directive.",
+ "type": "boolean",
+ "default": false
+ },
+ "toolchain-pattern": {
+ "description": "Defines a pattern to validate `toolchain` directive.",
+ "type": "string"
+ },
+ "tool-forbidden": {
+ "description": "Forbid the use of the `tool` directives.",
+ "type": "boolean",
+ "default": false
+ },
+ "go-debug-forbidden": {
+ "description": "Forbid the use of the `godebug` directive.",
+ "type": "boolean",
+ "default": false
+ },
+ "go-version-pattern": {
+ "description": "Defines a pattern to validate `go` minimum version directive.",
+ "type": "string",
+ "default": ""
+ }
+ }
+ },
+ "gomodguardSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "allowed": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "modules": {
+ "description": "List of allowed modules.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["gopkg.in/yaml.v2"]
+ }
+ },
+ "domains": {
+ "description": "List of allowed module domains.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["golang.org"]
+ }
+ }
+ }
+ },
+ "blocked": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "modules": {
+ "description": "List of blocked modules.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "recommendations": {
+ "description": "Recommended modules that should be used instead.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "reason": {
+ "description": "Reason why the recommended module should be used.",
+ "type": "string"
+ }
+ }
+ }
+ },
+ "additionalProperties": false
+ }
+ },
+ "versions": {
+ "description": "List of blocked module version constraints.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "patternProperties": {
+ "^.*$": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "version": {
+ "description": "Version constraint.",
+ "type": "string"
+ },
+ "reason": {
+ "description": "Reason why the version constraint exists.",
+ "type": "string"
+ }
+ },
+ "required": ["reason"]
+ }
+ }
+ }
+ },
+ "local-replace-directives": {
+ "description": "Raise lint issues if loading local path with replace directive",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ }
+ }
+ },
+ "gosecSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "includes": {
+ "type": "array",
+ "description": "To select a subset of rules to run",
+ "examples": [["G401"]],
+ "items": {
+ "$ref": "#/definitions/gosec-rules"
+ }
+ },
+ "excludes": {
+ "type": "array",
+ "description": "To specify a set of rules to explicitly exclude",
+ "examples": [["G401"]],
+ "items": {
+ "$ref": "#/definitions/gosec-rules"
+ }
+ },
+ "severity": {
+ "description": "Filter out the issues with a lower severity than the given value",
+ "type": "string",
+ "enum": ["low", "medium", "high"],
+ "default": "low"
+ },
+ "confidence": {
+ "description": "Filter out the issues with a lower confidence than the given value",
+ "type": "string",
+ "enum": ["low", "medium", "high"],
+ "default": "low"
+ },
+ "config": {
+ "description": "To specify the configuration of rules",
+ "type": "object"
+ },
+ "concurrency": {
+ "description": "Concurrency value",
+ "type": "integer"
+ }
+ }
+ },
+ "gosmopolitanSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "allow-time-local": {
+ "description": "Allow and ignore `time.Local` usages.",
+ "type": "boolean",
+ "default": false
+ },
+ "escape-hatches": {
+ "description": "List of fully qualified names in the `full/pkg/path.name` form, to act as \"i18n escape hatches\".",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "watch-for-scripts": {
+ "description": "List of Unicode scripts to watch for any usage in string literals.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "govetSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "settings": {
+ "description": "Settings per analyzer. Map of analyzer name to specific settings.\nRun `go tool vet help` to find out more.",
+ "type": "object",
+ "propertyNames": {
+ "$ref": "#/definitions/govet-analyzers"
+ },
+ "patternProperties": {
+ "^.*$": {
+ "description": "Run `go tool vet help ` to see all settings.",
+ "type": "object"
+ }
+ }
+ },
+ "enable": {
+ "description": "Enable analyzers by name.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/govet-analyzers"
+ }
+ },
+ "disable": {
+ "description": "Disable analyzers by name.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/govet-analyzers"
+ }
+ },
+ "enable-all": {
+ "description": "Enable all analyzers.",
+ "type": "boolean",
+ "default": false
+ },
+ "disable-all": {
+ "description": "Disable all analyzers.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "grouperSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "const-require-single-const": {
+ "type": "boolean",
+ "default": false
+ },
+ "const-require-grouping": {
+ "type": "boolean",
+ "default": false
+ },
+ "import-require-single-import": {
+ "type": "boolean",
+ "default": false
+ },
+ "import-require-grouping": {
+ "type": "boolean",
+ "default": false
+ },
+ "type-require-single-type": {
+ "type": "boolean",
+ "default": false
+ },
+ "type-require-grouping": {
+ "type": "boolean",
+ "default": false
+ },
+ "var-require-single-var": {
+ "type": "boolean",
+ "default": false
+ },
+ "var-require-grouping": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "ifaceSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "enable": {
+ "description": "Enable analyzers by name.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/iface-analyzers"
+ }
+ },
+ "settings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "unused": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "exclude": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "importasSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "no-unaliased": {
+ "description": "Do not allow unaliased imports of aliased packages.",
+ "type": "boolean",
+ "default": false
+ },
+ "no-extra-aliases": {
+ "description": "Do not allow non-required aliases.",
+ "type": "boolean",
+ "default": false
+ },
+ "alias": {
+ "description": "List of aliases",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "pkg": {
+ "description": "Package path e.g. knative.dev/serving/pkg/apis/autoscaling/v1alpha1",
+ "type": "string"
+ },
+ "alias": {
+ "description": "Package alias e.g. autoscalingv1alpha1",
+ "type": "string"
+ }
+ },
+ "required": ["pkg", "alias"]
+ }
+ }
+ }
+ },
+ "inamedparamSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skip-single-param": {
+ "description": "Skips check for interface methods with only a single parameter.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "ireturnSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "description": "Use either `reject` or `allow` properties for interfaces matching.",
+ "properties": {
+ "allow": {
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "enum": ["anon", "error", "empty", "stdlib"]
+ }
+ ]
+ }
+ },
+ "reject": {
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "enum": ["anon", "error", "empty", "stdlib"]
+ }
+ ]
+ }
+ }
+ },
+ "anyOf": [
+ {
+ "not": {
+ "properties": {
+ "allow": {
+ "const": "reject"
+ }
+ }
+ },
+ "required": ["allow"]
+ },
+ {
+ "required": ["reject"]
+ }
+ ]
+ },
+ "lllSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "tab-width": {
+ "description": "Width of \"\\t\" in spaces.",
+ "type": "integer",
+ "minimum": 0,
+ "default": 1
+ },
+ "line-length": {
+ "description": "Maximum allowed line length, lines longer will be reported.",
+ "type": "integer",
+ "minimum": 1,
+ "default": 120
+ }
+ }
+ },
+ "maintidxSettings": {
+ "description": "Maintainability index https://docs.microsoft.com/en-us/visualstudio/code-quality/code-metrics-maintainability-index-range-and-meaning?view=vs-2022",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "under": {
+ "description": "Minimum accatpable maintainability index level (see https://docs.microsoft.com/en-us/visualstudio/code-quality/code-metrics-maintainability-index-range-and-meaning?view=vs-2022)",
+ "type": "number",
+ "default": 20
+ }
+ }
+ },
+ "makezeroSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "always": {
+ "description": "Allow only slices initialized with a length of zero.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "loggercheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "kitlog": {
+ "description": "Allow check for the github.com/go-kit/log library.",
+ "type": "boolean",
+ "default": true
+ },
+ "klog": {
+ "description": "Allow check for the k8s.io/klog/v2 library.",
+ "type": "boolean",
+ "default": true
+ },
+ "logr": {
+ "description": "Allow check for the github.com/go-logr/logr library.",
+ "type": "boolean",
+ "default": true
+ },
+ "slog": {
+ "description": "Allow check for the log/slog library.",
+ "type": "boolean",
+ "default": true
+ },
+ "zap": {
+ "description": "Allow check for the \"sugar logger\" from go.uber.org/zap library.",
+ "type": "boolean",
+ "default": true
+ },
+ "require-string-key": {
+ "description": "Require all logging keys to be inlined constant strings.",
+ "type": "boolean",
+ "default": false
+ },
+ "no-printf-like": {
+ "description": "Require printf-like format specifier (%s, %d for example) not present.",
+ "type": "boolean",
+ "default": false
+ },
+ "rules": {
+ "description": "List of custom rules to check against, where each rule is a single logger pattern, useful for wrapped loggers.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "misspellSettings": {
+ "description": "Correct spellings using locale preferences for US or UK. Default is to use a neutral variety of English.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "locale": {
+ "enum": ["US", "UK"]
+ },
+ "ignore-rules": {
+ "description": "List of rules to ignore.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "mode": {
+ "description": "Mode of the analysis.",
+ "enum": ["restricted", "", "default"],
+ "default": ""
+ },
+ "extra-words": {
+ "description": "Extra word corrections.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "correction": {
+ "type": "string"
+ },
+ "typo": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "musttagSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "functions": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "tag": {
+ "type": "string"
+ },
+ "arg-pos": {
+ "type": "integer"
+ }
+ }
+ }
+ }
+ }
+ },
+ "nakedretSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-func-lines": {
+ "description": "Report if a function has more lines of code than this value and it has naked returns.",
+ "type": "integer",
+ "minimum": 0,
+ "default": 30
+ }
+ }
+ },
+ "nestifSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "min-complexity": {
+ "description": "Minimum complexity of \"if\" statements to report.",
+ "type": "integer",
+ "default": 5
+ }
+ }
+ },
+ "nilnilSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "only-two": {
+ "type": "boolean",
+ "description": "To check functions with only two return values.",
+ "default": true
+ },
+ "detect-opposite": {
+ "type": "boolean",
+ "description": "In addition, detect opposite situation (simultaneous return of non-nil error and valid value).",
+ "default": false
+ },
+ "checked-types": {
+ "type": "array",
+ "description": "List of return types to check.",
+ "items": {
+ "enum": ["chan", "func", "iface", "map", "ptr", "uintptr", "unsafeptr"]
+ },
+ "default": ["chan", "func", "iface", "map", "ptr", "uintptr", "unsafeptr"]
+ }
+ }
+ },
+ "nlreturnSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "block-size": {
+ "description": "set block size that is still ok",
+ "type": "number",
+ "default": 0,
+ "minimum": 0
+ }
+ }
+ },
+ "mndSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignored-files": {
+ "description": "List of file patterns to exclude from analysis.",
+ "examples": [["magic1_.*.go"]],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignored-functions": {
+ "description": "Comma-separated list of function patterns to exclude from the analysis.",
+ "examples": [["math.*", "http.StatusText", "make"]],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignored-numbers": {
+ "description": "List of numbers to exclude from analysis.",
+ "examples": [["1000", "1234_567_890", "3.14159264"]],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "checks": {
+ "description": "The list of enabled checks, see https://github.com/tommy-muehle/go-mnd/#checks for description.",
+ "type": "array",
+ "items": {
+ "enum": [
+ "argument",
+ "case",
+ "condition",
+ "operation",
+ "return",
+ "assign"
+ ]
+ }
+ }
+ }
+ },
+ "nolintlintSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "allow-unused": {
+ "description": "Enable to ensure that nolint directives are all used.",
+ "type": "boolean",
+ "default": true
+ },
+ "allow-no-explanation": {
+ "description": "Exclude these linters from requiring an explanation.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linter-names"
+ },
+ "default": []
+ },
+ "require-explanation": {
+ "description": "Enable to require an explanation of nonzero length after each nolint directive.",
+ "type": "boolean",
+ "default": false
+ },
+ "require-specific": {
+ "description": "Enable to require nolint directives to mention the specific linter being suppressed.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "reassignSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "patterns": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "recvcheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "disable-builtin": {
+ "description": "Disables the built-in method exclusions.",
+ "type": "boolean",
+ "default": true
+ },
+ "exclusions": {
+ "description": "User-defined method exclusions.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "nonamedreturnsSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "report-error-in-defer": {
+ "description": "Report named error if it is assigned inside defer.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "paralleltestSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignore-missing": {
+ "description": "Ignore missing calls to `t.Parallel()` and only report incorrect uses of it.",
+ "type": "boolean",
+ "default": false
+ },
+ "ignore-missing-subtests": {
+ "description": "Ignore missing calls to `t.Parallel()` in subtests. Top-level tests are still required to have `t.Parallel`, but subtests are allowed to skip it.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "perfsprintSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "integer-format": {
+ "description": "Enable/disable optimization of integer formatting.",
+ "type": "boolean",
+ "default": true
+ },
+ "int-conversion": {
+ "description": "Optimizes even if it requires an int or uint type cast.",
+ "type": "boolean",
+ "default": true
+ },
+ "error-format": {
+ "description": "Enable/disable optimization of error formatting.",
+ "type": "boolean",
+ "default": true
+ },
+ "err-error": {
+ "description": "Optimizes into `err.Error()` even if it is only equivalent for non-nil errors.",
+ "type": "boolean",
+ "default": false
+ },
+ "errorf": {
+ "description": "Optimizes `fmt.Errorf`.",
+ "type": "boolean",
+ "default": true
+ },
+ "string-format": {
+ "description": "Enable/disable optimization of string formatting.",
+ "type": "boolean",
+ "default": true
+ },
+ "sprintf1": {
+ "description": "Optimizes `fmt.Sprintf` with only one argument.",
+ "type": "boolean",
+ "default": true
+ },
+ "strconcat": {
+ "description": "Optimizes into strings concatenation.",
+ "type": "boolean",
+ "default": true
+ },
+ "bool-format": {
+ "description": "Enable/disable optimization of bool formatting.",
+ "type": "boolean",
+ "default": true
+ },
+ "hex-format": {
+ "description": "Enable/disable optimization of hex formatting.",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "preallocSettings": {
+ "description": "We do not recommend using this linter before doing performance profiling.\nFor most programs usage of `prealloc` will be premature optimization.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "simple": {
+ "description": "Report preallocation suggestions only on simple loops that have no returns/breaks/continues/gotos in them.",
+ "type": "boolean",
+ "default": true
+ },
+ "range-loops": {
+ "description": "Report preallocation suggestions on range loops.",
+ "type": "boolean",
+ "default": true
+ },
+ "for-loops": {
+ "description": "Report preallocation suggestions on for loops.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "predeclaredSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignore": {
+ "description": "List of predeclared identifiers to not report on.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "qualified-name": {
+ "description": "Include method names and field names in checks.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "promlinterSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "strict": {},
+ "disabled-linters": {
+ "type": "array",
+ "items": {
+ "enum": [
+ "Help",
+ "MetricUnits",
+ "Counter",
+ "HistogramSummaryReserved",
+ "MetricTypeInName",
+ "ReservedChars",
+ "CamelCase",
+ "UnitAbbreviations"
+ ]
+ }
+ }
+ }
+ },
+ "protogetterSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skip-generated-by": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["protoc-gen-go-my-own-generator"]
+ }
+ },
+ "skip-files": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["*.pb.go"]
+ }
+ },
+ "skip-any-generated": {
+ "description": "Skip any generated files from the checking.",
+ "type": "boolean",
+ "default": false
+ },
+ "replace-first-arg-in-append": {
+ "description": "Skip first argument of append function.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "reviveSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "examples": [
+ {
+ "ignore-generated-header": true,
+ "severity": "warning",
+ "rules": [
+ {
+ "name": "indent-error-flow",
+ "severity": "warning"
+ },
+ {
+ "name": "add-constant",
+ "severity": "warning",
+ "arguments": [
+ {
+ "maxLitCount": "3",
+ "allowStrs": "\"\"",
+ "allowInts": "0,1,2",
+ "allowFloats": "0.0,0.,1.0,1.,2.0,2."
+ }
+ ]
+ }
+ ]
+ }
+ ],
+ "properties": {
+ "max-open-files": {
+ "type": "integer"
+ },
+ "confidence": {
+ "type": "number"
+ },
+ "severity": {
+ "type": "string",
+ "enum": ["warning", "error"]
+ },
+ "enable-all-rules": {
+ "type": "boolean",
+ "default": false
+ },
+ "directives": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "name": {
+ "type": "string",
+ "enum": ["specify-disable-reason"]
+ },
+ "severity": {
+ "type": "string",
+ "enum": ["warning", "error"]
+ },
+ "exclude": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "arguments": {
+ "type": "array"
+ }
+ }
+ }
+ },
+ "rules": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["name"],
+ "properties": {
+ "name": {
+ "$ref": "#/definitions/revive-rules",
+ "title": "The rule name"
+ },
+ "disabled": {
+ "type": "boolean"
+ },
+ "severity": {
+ "type": "string",
+ "enum": ["warning", "error"]
+ },
+ "exclude": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "arguments": {
+ "type": "array"
+ }
+ }
+ }
+ }
+ }
+ },
+ "rowserrcheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "packages": {
+ "type": "array",
+ "items": {
+ "description": "",
+ "type": "string",
+ "examples": ["github.com/jmoiron/sqlx"]
+ }
+ }
+ }
+ },
+ "sloglintSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "kv-only": {
+ "description": "Enforce using key-value pairs only (incompatible with attr-only).",
+ "type": "boolean",
+ "default": false
+ },
+ "no-global": {
+ "description": "Enforce not using global loggers.",
+ "enum": ["", "all", "default"],
+ "default": ""
+ },
+ "no-mixed-args": {
+ "description": "Enforce not mixing key-value pairs and attributes.",
+ "type": "boolean",
+ "default": true
+ },
+ "context": {
+ "description": "Enforce using methods that accept a context.",
+ "enum": ["", "all", "scope"],
+ "default": ""
+ },
+ "static-msg": {
+ "description": "Enforce using static values for log messages.",
+ "type": "boolean",
+ "default": false
+ },
+ "msg-style": {
+ "description": "Enforce message style.",
+ "enum": ["", "lowercased", "capitalized"],
+ "default": ""
+ },
+ "key-naming-case": {
+ "description": "Enforce a single key naming convention.",
+ "enum": ["snake", "kebab", "camel", "pascal"]
+ },
+ "attr-only": {
+ "description": "Enforce using attributes only (incompatible with kv-only).",
+ "type": "boolean",
+ "default": false
+ },
+ "no-raw-keys": {
+ "description": "Enforce using constants instead of raw keys.",
+ "type": "boolean",
+ "default": false
+ },
+ "forbidden-keys": {
+ "description": "Enforce not using specific keys.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "args-on-sep-lines": {
+ "description": "Enforce putting arguments on separate lines.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "spancheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "checks": {
+ "description": "Checks to enable.",
+ "type": "array",
+ "items": {
+ "enum": ["end", "record-error", "set-status"]
+ }
+ },
+ "ignore-check-signatures": {
+ "description": "A list of regexes for function signatures that silence `record-error` and `set-status` reports if found in the call path to a returned error.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "extra-start-span-signatures": {
+ "description": "A list of regexes for additional function signatures that create spans.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "staticcheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "checks": {
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "$ref": "#/definitions/staticcheck-checks"
+ },
+ {
+ "type": "string"
+ }
+ ]
+ }
+ },
+ "dot-import-whitelist": {
+ "description": "By default, ST1001 forbids all uses of dot imports in non-test packages. This setting allows setting a whitelist of import paths that can be dot-imported anywhere.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "http-status-code-whitelist": {
+ "description": "ST1013 recommends using constants from the net/http package instead of hard-coding numeric HTTP status codes. This setting specifies a list of numeric status codes that this check does not complain about.",
+ "default": ["200", "400", "404", "500"],
+ "type": "array",
+ "items": {
+ "enum": [
+ "100",
+ "101",
+ "102",
+ "103",
+ "200",
+ "201",
+ "202",
+ "203",
+ "204",
+ "205",
+ "206",
+ "207",
+ "208",
+ "226",
+ "300",
+ "301",
+ "302",
+ "303",
+ "304",
+ "305",
+ "306",
+ "307",
+ "308",
+ "400",
+ "401",
+ "402",
+ "403",
+ "404",
+ "405",
+ "406",
+ "407",
+ "408",
+ "409",
+ "410",
+ "411",
+ "412",
+ "413",
+ "414",
+ "415",
+ "416",
+ "417",
+ "418",
+ "421",
+ "422",
+ "423",
+ "424",
+ "425",
+ "426",
+ "428",
+ "429",
+ "431",
+ "451",
+ "500",
+ "501",
+ "502",
+ "503",
+ "504",
+ "505",
+ "506",
+ "507",
+ "508",
+ "510",
+ "511"
+ ]
+ }
+ },
+ "initialisms": {
+ "description": "ST1003 check, among other things, for the correct capitalization of initialisms. The set of known initialisms can be configured with this option.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "default": [
+ "ACL",
+ "API",
+ "ASCII",
+ "CPU",
+ "CSS",
+ "DNS",
+ "EOF",
+ "GUID",
+ "HTML",
+ "HTTP",
+ "HTTPS",
+ "ID",
+ "IP",
+ "JSON",
+ "QPS",
+ "RAM",
+ "RPC",
+ "SLA",
+ "SMTP",
+ "SQL",
+ "SSH",
+ "TCP",
+ "TLS",
+ "TTL",
+ "UDP",
+ "UI",
+ "GID",
+ "UID",
+ "UUID",
+ "URI",
+ "URL",
+ "UTF8",
+ "VM",
+ "XML",
+ "XMPP",
+ "XSRF",
+ "XSS",
+ "SIP",
+ "RTP",
+ "AMQP",
+ "DB",
+ "TS"
+ ]
+ }
+ }
+ }
+ },
+ "tagalignSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "align": {
+ "description": "Align and sort can be used together or separately.",
+ "type": "boolean",
+ "default": true
+ },
+ "sort": {
+ "description": "Whether enable tags sort.",
+ "type": "boolean",
+ "default": true
+ },
+ "order": {
+ "description": "Specify the order of tags, the other tags will be sorted by name.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "default": [],
+ "examples": [
+ [
+ "json",
+ "yaml",
+ "yml",
+ "toml",
+ "mapstructure",
+ "binding",
+ "validate"
+ ]
+ ]
+ },
+ "strict": {
+ "description": "Whether enable strict style.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "tagliatelleSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "case": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "use-field-name": {
+ "description": "Use the struct field name to check the name of the struct tag.",
+ "type": "boolean",
+ "default": false
+ },
+ "ignored-fields": {
+ "description": "The field names to ignore.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["example"]
+ }
+ },
+ "rules": {
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "$ref": "#/definitions/tagliatelle-cases"
+ }
+ }
+ },
+ "extended-rules": {
+ "description": "Defines the association between tag name and case.",
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["case"],
+ "properties": {
+ "case": {
+ "$ref": "#/definitions/tagliatelle-cases"
+ },
+ "extra-initialisms": {
+ "type": "boolean",
+ "default": false
+ },
+ "initialism-overrides": {
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "overrides": {
+ "description": "Overrides the default/root configuration.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["pkg"],
+ "properties": {
+ "pkg": {
+ "description": "A package path.",
+ "type": "string"
+ },
+ "use-field-name": {
+ "description": "Use the struct field name to check the name of the struct tag.",
+ "type": "boolean",
+ "default": false
+ },
+ "ignored-fields": {
+ "description": "The field names to ignore.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["example"]
+ }
+ },
+ "ignore": {
+ "description": "Ignore the package (takes precedence over all other configurations).",
+ "type": "boolean",
+ "default": false
+ },
+ "rules": {
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "$ref": "#/definitions/tagliatelle-cases"
+ }
+ }
+ },
+ "extended-rules": {
+ "description": "Defines the association between tag name and case.",
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["case"],
+ "properties": {
+ "case": {
+ "$ref": "#/definitions/tagliatelle-cases"
+ },
+ "extra-initialisms": {
+ "type": "boolean",
+ "default": false
+ },
+ "initialism-overrides": {
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "testifylintSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "enable-all": {
+ "description": "Enable all checkers.",
+ "type": "boolean",
+ "default": false
+ },
+ "disable-all": {
+ "description": "Disable all checkers.",
+ "type": "boolean",
+ "default": false
+ },
+ "enable": {
+ "description": "Enable specific checkers.",
+ "type": "array",
+ "items": {
+ "enum": [
+ "blank-import",
+ "bool-compare",
+ "compares",
+ "contains",
+ "empty",
+ "encoded-compare",
+ "equal-values",
+ "error-is-as",
+ "error-nil",
+ "expected-actual",
+ "float-compare",
+ "formatter",
+ "go-require",
+ "len",
+ "negative-positive",
+ "nil-compare",
+ "regexp",
+ "require-error",
+ "suite-broken-parallel",
+ "suite-dont-use-pkg",
+ "suite-extra-assert-call",
+ "suite-method-signature",
+ "suite-subtest-run",
+ "suite-thelper",
+ "useless-assert"
+ ]
+ },
+ "default": [
+ "blank-import",
+ "bool-compare",
+ "compares",
+ "contains",
+ "empty",
+ "encoded-compare",
+ "equal-values",
+ "error-is-as",
+ "error-nil",
+ "expected-actual",
+ "float-compare",
+ "formatter",
+ "go-require",
+ "len",
+ "negative-positive",
+ "nil-compare",
+ "regexp",
+ "require-error",
+ "suite-broken-parallel",
+ "suite-dont-use-pkg",
+ "suite-extra-assert-call",
+ "suite-method-signature",
+ "suite-subtest-run",
+ "useless-assert"
+ ]
+ },
+ "disable": {
+ "description": "Disable specific checkers.",
+ "type": "array",
+ "items": {
+ "enum": [
+ "blank-import",
+ "bool-compare",
+ "compares",
+ "contains",
+ "empty",
+ "encoded-compare",
+ "equal-values",
+ "error-is-as",
+ "error-nil",
+ "expected-actual",
+ "float-compare",
+ "formatter",
+ "go-require",
+ "len",
+ "negative-positive",
+ "nil-compare",
+ "regexp",
+ "require-error",
+ "suite-broken-parallel",
+ "suite-dont-use-pkg",
+ "suite-extra-assert-call",
+ "suite-method-signature",
+ "suite-subtest-run",
+ "suite-thelper",
+ "useless-assert"
+ ],
+ "default": [
+ "suite-thelper"
+ ]
+ }
+ },
+ "bool-compare": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignore-custom-types": {
+ "description": "To ignore user defined types (over builtin bool).",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "expected-actual": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "pattern": {
+ "description": "Regexp for expected variable name.",
+ "type": "string",
+ "default": "(^(exp(ected)?|want(ed)?)([A-Z]\\w*)?$)|(^(\\w*[a-z])?(Exp(ected)?|Want(ed)?)$)"
+ }
+ }
+ },
+ "formatter": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-format-string": {
+ "description": "To enable go vet's printf checks.",
+ "type": "boolean",
+ "default": true
+ },
+ "require-f-funcs": {
+ "description": "To require f-assertions (e.g. assert.Equalf) if format string is used, even if there are no variable-length variables.",
+ "type": "boolean",
+ "default": false
+ },
+ "require-string-msg": {
+ "description": "To require that the first element of msgAndArgs (msg) has a string type.",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "go-require": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignore-http-handlers": {
+ "description": "To ignore HTTP handlers (like http.HandlerFunc).",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "require-error": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "fn-pattern": {
+ "description": "Regexp for assertions to analyze. If defined, then only matched error assertions will be reported.",
+ "type": "string",
+ "default": ""
+ }
+ }
+ },
+ "suite-extra-assert-call": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "mode": {
+ "description": "To require or remove extra Assert() call?",
+ "type": "string",
+ "enum": ["remove", "require"],
+ "default": "remove"
+ }
+ }
+ }
+ }
+ },
+ "testpackageSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skip-regexp": {
+ "description": "Files with names matching this regular expression are skipped.",
+ "type": "string",
+ "examples": ["(export|internal)_test\\.go"]
+ },
+ "allow-packages": {
+ "description": "List of packages that don't end with _test that tests are allowed to be in.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["example"]
+ }
+ }
+ }
+ },
+ "thelperSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "test": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "begin": {
+ "description": "Check if `t.Helper()` begins helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "first": {
+ "description": "Check if *testing.T is first param of helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "name": {
+ "description": "Check if *testing.T param has t name.",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ },
+ "benchmark": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "begin": {
+ "description": "Check if `b.Helper()` begins helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "first": {
+ "description": "Check if *testing.B is first param of helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "name": {
+ "description": "Check if *testing.B param has b name.",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ },
+ "tb": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "begin": {
+ "description": "Check if `tb.Helper()` begins helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "first": {
+ "description": "Check if *testing.TB is first param of helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "name": {
+ "description": "Check if *testing.TB param has tb name.",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ },
+ "fuzz": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "begin": {
+ "description": "Check if `f.Helper()` begins helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "first": {
+ "description": "Check if *testing.F is first param of helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "name": {
+ "description": "Check if *testing.F param has f name.",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ }
+ }
+ },
+ "usestdlibvarsSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "http-method": {
+ "description": "Suggest the use of http.MethodXX.",
+ "type": "boolean",
+ "default": true
+ },
+ "http-status-code": {
+ "description": "Suggest the use of http.StatusXX.",
+ "type": "boolean",
+ "default": true
+ },
+ "time-weekday": {
+ "description": "Suggest the use of time.Weekday.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "time-month": {
+ "description": "Suggest the use of time.Month.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "time-layout": {
+ "description": "Suggest the use of time.Layout.",
+ "type": "boolean",
+ "default": false
+ },
+ "crypto-hash": {
+ "description": "Suggest the use of crypto.Hash.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "default-rpc-path": {
+ "description": "Suggest the use of rpc.DefaultXXPath.",
+ "type": "boolean",
+ "default": false
+ },
+ "sql-isolation-level": {
+ "description": "Suggest the use of sql.LevelXX.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "tls-signature-scheme": {
+ "description": "Suggest the use of tls.SignatureScheme.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "constant-kind": {
+ "description": "Suggest the use of constant.Kind.String().",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "usetestingSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "context-background": {
+ "type": "boolean",
+ "default": true
+ },
+ "context-todo": {
+ "type": "boolean",
+ "default": true
+ },
+ "os-chdir": {
+ "type": "boolean",
+ "default": true
+ },
+ "os-mkdir-temp": {
+ "type": "boolean",
+ "default": true
+ },
+ "os-setenv": {
+ "type": "boolean",
+ "default": true
+ },
+ "os-create-temp": {
+ "type": "boolean",
+ "default": true
+ },
+ "os-temp-dir": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "unconvertSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "fast-math": {
+ "type": "boolean",
+ "default": false
+ },
+ "safe": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "unparamSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-exported": {
+ "description": "Inspect exported functions. Set to true if no external program/library imports your code.\n\nWARNING: if you enable this setting, unparam will report a lot of false-positives in text editors:\nif it's called for subdir of a project it can't find external interfaces. All text editor integrations\nwith golangci-lint call it on a directory with the changed file.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "unusedSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "field-writes-are-uses": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ },
+ "post-statements-are-reads": {
+ "description": "",
+ "type": "boolean",
+ "default": false
+ },
+ "exported-fields-are-used": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ },
+ "parameters-are-used": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ },
+ "local-variables-are-used": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ },
+ "generated-is-used": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "varnamelenSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-distance": {
+ "description": "Variables used in at most this N-many lines will be ignored.",
+ "type": "integer",
+ "default": 5
+ },
+ "min-name-length": {
+ "description": "The minimum length of a variable's name that is considered `long`.",
+ "type": "integer",
+ "default": 3
+ },
+ "check-receiver": {
+ "description": "Check method receiver names.",
+ "default": false,
+ "type": "boolean"
+ },
+ "check-return": {
+ "description": "Check named return values.",
+ "default": false,
+ "type": "boolean"
+ },
+ "check-type-param": {
+ "description": "Check type parameters.",
+ "default": false,
+ "type": "boolean"
+ },
+ "ignore-type-assert-ok": {
+ "description": "Ignore `ok` variables that hold the bool return value of a type assertion",
+ "default": false,
+ "type": "boolean"
+ },
+ "ignore-map-index-ok": {
+ "description": "Ignore `ok` variables that hold the bool return value of a map index.",
+ "default": false,
+ "type": "boolean"
+ },
+ "ignore-chan-recv-ok": {
+ "description": "Ignore `ok` variables that hold the bool return value of a channel receive.",
+ "default": false,
+ "type": "boolean"
+ },
+ "ignore-names": {
+ "description": "Optional list of variable names that should be ignored completely.",
+ "default": [[]],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignore-decls": {
+ "description": "Optional list of variable declarations that should be ignored completely.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "examples": [
+ ["c echo.Context", "t testing.T", "f *foo.Bar", "const C"]
+ ]
+ }
+ }
+ },
+ "whitespaceSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "multi-if": {
+ "description": "Enforces newlines (or comments) after every multi-line if statement",
+ "type": "boolean",
+ "default": false
+ },
+ "multi-func": {
+ "description": "Enforces newlines (or comments) after every multi-line function signature",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "wrapcheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "extra-ignore-sigs": {
+ "description": "An array of strings specifying additional substrings of signatures to ignore.",
+ "default": [
+ ".CustomError(",
+ ".SpecificWrap("
+ ],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignore-sigs": {
+ "description": "An array of strings which specify substrings of signatures to ignore.",
+ "default": [
+ ".Errorf(",
+ "errors.New(",
+ "errors.Unwrap(",
+ ".Wrap(",
+ ".Wrapf(",
+ ".WithMessage(",
+ ".WithMessagef(",
+ ".WithStack("
+ ],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignore-sig-regexps": {
+ "description": "An array of strings which specify regular expressions of signatures to ignore.",
+ "default": [""],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignore-package-globs": {
+ "description": "An array of glob patterns which, if any match the package of the function returning the error, will skip wrapcheck analysis for this error.",
+ "default": [""],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignore-interface-regexps": {
+ "description": "An array of glob patterns which, if matched to an underlying interface name, will ignore unwrapped errors returned from a function whose call is defined on the given interface.",
+ "default": [""],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "report-internal-errors": {
+ "description": "Determines whether wrapcheck should report errors returned from inside the package.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "wslSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "allow-assign-and-anything": {
+ "description": "Controls if you may cuddle assignments and anything without needing an empty line between them.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-assign-and-call": {
+ "description": "Allow calls and assignments to be cuddled as long as the lines have any matching variables, fields or types.",
+ "type": "boolean",
+ "default": true
+ },
+ "allow-cuddle-declarations": {
+ "description": "Allow declarations (var) to be cuddled.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-cuddle-with-calls": {
+ "description": "A list of call idents that everything can be cuddled with.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "allow-cuddle-with-rhs": {
+ "description": "AllowCuddleWithRHS is a list of right hand side variables that is allowed to be cuddled with anything.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "allow-cuddle-used-in-block": {
+ "description": "Allow cuddling with any block as long as the variable is used somewhere in the block",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-multiline-assign": {
+ "description": "Allow multiline assignments to be cuddled.",
+ "type": "boolean",
+ "default": true
+ },
+ "allow-separated-leading-comment": {
+ "description": "Allow leading comments to be separated with empty lines.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-trailing-comment": {
+ "description": "Allow trailing comments in ending of blocks.",
+ "type": "boolean",
+ "default": false
+ },
+ "error-variable-names": {
+ "description": "When force-err-cuddling is enabled this is a list of names used for error variables to check for in the conditional.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "force-case-trailing-whitespace": {
+ "description": "Force newlines in end of case at this limit (0 = never).",
+ "type": "integer",
+ "minimum": 0,
+ "default": 0
+ },
+ "force-err-cuddling": {
+ "description": "Causes an error when an If statement that checks an error variable doesn't cuddle with the assignment of that variable.",
+ "type": "boolean",
+ "default": false
+ },
+ "force-short-decl-cuddling": {
+ "description": "Causes an error if a short declaration (:=) cuddles with anything other than another short declaration.",
+ "type": "boolean",
+ "default": false
+ },
+ "strict-append": {
+ "description": "If true, append is only allowed to be cuddled if appending value is matching variables, fields or types on line above.",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "copyloopvarSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-alias": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "customSettings": {
+ "description": "The custom section can be used to define linter plugins to be loaded at runtime. See README of golangci-lint for more information.\nEach custom linter should have a unique name.",
+ "type": "object",
+ "patternProperties": {
+ "^.*$": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "type": {
+ "description": "The plugin type.",
+ "enum": ["module", "goplugin"],
+ "default": "goplugin"
+ },
+ "path": {
+ "description": "The path to the plugin *.so. Can be absolute or local.",
+ "type": "string",
+ "examples": ["/path/to/example.so"]
+ },
+ "description": {
+ "description": "The description of the linter, for documentation purposes only.",
+ "type": "string"
+ },
+ "original-url": {
+ "description": "Intended to point to the repo location of the linter, for documentation purposes only.",
+ "type": "string"
+ },
+ "settings": {
+ "description": "Plugins settings/configuration. Only work with plugin based on `linterdb.PluginConstructor`.",
+ "type": "object"
+ }
+ },
+ "oneOf": [
+ {
+ "properties": {
+ "type": {"enum": ["module"] }
+ },
+ "required": ["type"]
+ },
+ {
+ "required": ["path"]
+ }
+ ]
+ }
+ }
+ }
+ }
+ }
+ },
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["version"],
+ "properties": {
+ "version": {
+ "type": "string",
+ "default": "2"
+ },
+ "run": {
+ "description": "Options for analysis running,",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "concurrency": {
+ "description": "Number of concurrent runners. Defaults to the number of available CPU cores.",
+ "type": "integer",
+ "minimum": 0,
+ "examples": [4]
+ },
+ "timeout": {
+ "description": "Timeout for the analysis.",
+ "type": "string",
+ "pattern": "^((\\d+h)?(\\d+m)?(\\d+(?:\\.\\d)?s)?|0)$",
+ "default": "1m",
+ "examples": ["30s", "5m", "5m30s"]
+ },
+ "issues-exit-code": {
+ "description": "Exit code when at least one issue was found.",
+ "type": "integer",
+ "default": 1
+ },
+ "tests": {
+ "description": "Enable inclusion of test files.",
+ "type": "boolean",
+ "default": true
+ },
+ "build-tags": {
+ "description": "List of build tags to pass to all linters.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "default": [],
+ "examples": [["mytag"]]
+ },
+ "modules-download-mode": {
+ "description": "Option to pass to \"go list -mod={option}\".\nSee \"go help modules\" for more information.",
+ "enum": ["mod", "readonly", "vendor"]
+ },
+ "allow-parallel-runners": {
+ "description": "Allow multiple parallel golangci-lint instances running. If disabled, golangci-lint acquires file lock on start.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-serial-runners": {
+ "description": "Allow multiple golangci-lint instances running, but serialize them around a lock.",
+ "type": "boolean",
+ "default": false
+ },
+ "go": {
+ "description": "Targeted Go version.",
+ "type": "string",
+ "default": "1.17"
+ },
+ "relative-path-mode": {
+ "description": "The mode used to evaluate relative paths.",
+ "type": "string",
+ "$ref": "#/definitions/relative-path-modes",
+ "default": "wd"
+ }
+ }
+ },
+ "output": {
+ "description": "Output configuration options.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "formats": {
+ "description": "Output formats to use.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "text": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "path": {
+ "$ref": "#/definitions/formats-path",
+ "default": "stdout"
+ },
+ "print-linter-name": {
+ "type": "boolean",
+ "default": true
+ },
+ "print-issued-lines": {
+ "type": "boolean",
+ "default": true
+ },
+ "colors": {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "json": {
+ "$ref": "#/definitions/simple-format"
+ },
+ "tab": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "path": {
+ "$ref": "#/definitions/formats-path",
+ "default": "stdout"
+ },
+ "print-linter-name": {
+ "type": "boolean",
+ "default": true
+ },
+ "colors": {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "html": {
+ "$ref": "#/definitions/simple-format"
+ },
+ "checkstyle": {
+ "$ref": "#/definitions/simple-format"
+ },
+ "code-climate": {
+ "$ref": "#/definitions/simple-format"
+ },
+ "junit-xml": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "path": {
+ "$ref": "#/definitions/formats-path",
+ "default": "stdout"
+ },
+ "extended": {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "teamcity": {
+ "$ref": "#/definitions/simple-format"
+ },
+ "sarif": {
+ "$ref": "#/definitions/simple-format"
+ }
+ }
+ },
+ "path-mode": {
+ "type": "string",
+ "default": "",
+ "examples": ["abs"]
+ },
+ "path-prefix": {
+ "description": "Add a prefix to the output file references.",
+ "type": "string",
+ "default": ""
+ },
+ "show-stats": {
+ "description": "Show statistics per linter.",
+ "type": "boolean",
+ "default": true
+ },
+ "sort-order": {
+ "type": "array",
+ "items": {
+ "enum": ["linter", "severity", "file"]
+ }
+ }
+ }
+ },
+ "linters": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "default": {
+ "enum": [
+ "standard",
+ "all",
+ "none",
+ "fast"
+ ]
+ },
+ "enable": {
+ "description": "List of enabled linters.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linter-names"
+ }
+ },
+ "disable": {
+ "description": "List of disabled linters.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linter-names"
+ }
+ },
+ "settings": {
+ "description": "All available settings of specific linters.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "dupword": {
+ "$ref": "#/definitions/settings/definitions/dupwordSettings"
+ },
+ "asasalint": {
+ "$ref": "#/definitions/settings/definitions/asasalintSettings"
+ },
+ "bidichk": {
+ "$ref": "#/definitions/settings/definitions/bidichkSettings"
+ },
+ "cyclop": {
+ "$ref": "#/definitions/settings/definitions/cyclopSettings"
+ },
+ "decorder": {
+ "$ref": "#/definitions/settings/definitions/decorderSettings"
+ },
+ "depguard":{
+ "$ref": "#/definitions/settings/definitions/depguardSettings"
+ },
+ "dogsled": {
+ "$ref": "#/definitions/settings/definitions/dogsledSettings"
+ },
+ "dupl": {
+ "$ref": "#/definitions/settings/definitions/duplSettings"
+ },
+ "errcheck": {
+ "$ref": "#/definitions/settings/definitions/errcheckSettings"
+ },
+ "errchkjson": {
+ "$ref": "#/definitions/settings/definitions/errchkjsonSettings"
+ },
+ "errorlint": {
+ "$ref": "#/definitions/settings/definitions/errorlintSettings"
+ },
+ "exhaustive": {
+ "$ref": "#/definitions/settings/definitions/exhaustiveSettings"
+ },
+ "exhaustruct": {
+ "$ref": "#/definitions/settings/definitions/exhaustructSettings"
+ },
+ "fatcontext": {
+ "$ref": "#/definitions/settings/definitions/fatcontextSettings"
+ },
+ "forbidigo": {
+ "$ref": "#/definitions/settings/definitions/forbidigoSettings"
+ },
+ "funcorder": {
+ "$ref": "#/definitions/settings/definitions/funcorderSettings"
+ },
+ "funlen": {
+ "$ref": "#/definitions/settings/definitions/funlenSettings"
+ },
+ "ginkgolinter": {
+ "$ref": "#/definitions/settings/definitions/ginkgolinterSettings"
+ },
+ "gochecksumtype": {
+ "$ref": "#/definitions/settings/definitions/gochecksumtypeSettings"
+ },
+ "gocognit": {
+ "$ref": "#/definitions/settings/definitions/gocognitSettings"
+ },
+ "goconst": {
+ "$ref": "#/definitions/settings/definitions/goconstSettings"
+ },
+ "gocritic": {
+ "$ref": "#/definitions/settings/definitions/gocriticSettings"
+ },
+ "gocyclo": {
+ "$ref": "#/definitions/settings/definitions/gocycloSettings"
+ },
+ "godot": {
+ "$ref": "#/definitions/settings/definitions/godotSettings"
+ },
+ "godox": {
+ "$ref": "#/definitions/settings/definitions/godoxSettings"
+ },
+ "interfacebloat":{
+ "$ref": "#/definitions/settings/definitions/interfacebloatSettings"
+ },
+ "goheader": {
+ "$ref": "#/definitions/settings/definitions/goheaderSettings"
+ },
+ "gomoddirectives": {
+ "$ref": "#/definitions/settings/definitions/gomoddirectivesSettings"
+ },
+ "gomodguard": {
+ "$ref": "#/definitions/settings/definitions/gomodguardSettings"
+ },
+ "gosec": {
+ "$ref": "#/definitions/settings/definitions/gosecSettings"
+ },
+ "gosmopolitan": {
+ "$ref": "#/definitions/settings/definitions/gosmopolitanSettings"
+ },
+ "govet": {
+ "$ref": "#/definitions/settings/definitions/govetSettings"
+ },
+ "grouper": {
+ "$ref": "#/definitions/settings/definitions/grouperSettings"
+ },
+ "iface": {
+ "$ref": "#/definitions/settings/definitions/ifaceSettings"
+ },
+ "importas": {
+ "$ref": "#/definitions/settings/definitions/importasSettings"
+ },
+ "inamedparam": {
+ "$ref": "#/definitions/settings/definitions/inamedparamSettings"
+ },
+ "ireturn": {
+ "$ref": "#/definitions/settings/definitions/ireturnSettings"
+ },
+ "lll": {
+ "$ref": "#/definitions/settings/definitions/lllSettings"
+ },
+ "maintidx": {
+ "$ref": "#/definitions/settings/definitions/maintidxSettings"
+ },
+ "makezero":{
+ "$ref": "#/definitions/settings/definitions/makezeroSettings"
+ },
+ "loggercheck": {
+ "$ref": "#/definitions/settings/definitions/loggercheckSettings"
+ },
+ "misspell": {
+ "$ref": "#/definitions/settings/definitions/misspellSettings"
+ },
+ "musttag": {
+ "$ref": "#/definitions/settings/definitions/musttagSettings"
+ },
+ "nakedret": {
+ "$ref": "#/definitions/settings/definitions/nakedretSettings"
+ },
+ "nestif": {
+ "$ref": "#/definitions/settings/definitions/nestifSettings"
+ },
+ "nilnil": {
+ "$ref": "#/definitions/settings/definitions/nilnilSettings"
+ },
+ "nlreturn": {
+ "$ref": "#/definitions/settings/definitions/nlreturnSettings"
+ },
+ "mnd": {
+ "$ref": "#/definitions/settings/definitions/mndSettings"
+ },
+ "nolintlint":{
+ "$ref": "#/definitions/settings/definitions/nolintlintSettings"
+ },
+ "reassign": {
+ "$ref": "#/definitions/settings/definitions/reassignSettings"
+ },
+ "recvcheck": {
+ "$ref": "#/definitions/settings/definitions/recvcheckSettings"
+ },
+ "nonamedreturns": {
+ "$ref": "#/definitions/settings/definitions/nonamedreturnsSettings"
+ },
+ "paralleltest": {
+ "$ref": "#/definitions/settings/definitions/paralleltestSettings"
+ },
+ "perfsprint": {
+ "$ref": "#/definitions/settings/definitions/perfsprintSettings"
+ },
+ "prealloc": {
+ "$ref": "#/definitions/settings/definitions/preallocSettings"
+ },
+ "predeclared": {
+ "$ref": "#/definitions/settings/definitions/predeclaredSettings"
+ },
+ "promlinter": {
+ "$ref": "#/definitions/settings/definitions/promlinterSettings"
+ },
+ "protogetter": {
+ "$ref": "#/definitions/settings/definitions/protogetterSettings"
+ },
+ "revive": {
+ "$ref": "#/definitions/settings/definitions/reviveSettings"
+ },
+ "rowserrcheck": {
+ "$ref": "#/definitions/settings/definitions/rowserrcheckSettings"
+ },
+ "sloglint": {
+ "$ref": "#/definitions/settings/definitions/sloglintSettings"
+ },
+ "spancheck": {
+ "$ref": "#/definitions/settings/definitions/spancheckSettings"
+ },
+ "staticcheck":{
+ "$ref": "#/definitions/settings/definitions/staticcheckSettings"
+ },
+ "tagalign": {
+ "$ref": "#/definitions/settings/definitions/tagalignSettings"
+ },
+ "tagliatelle": {
+ "$ref": "#/definitions/settings/definitions/tagliatelleSettings"
+ },
+ "testifylint": {
+ "$ref": "#/definitions/settings/definitions/testifylintSettings"
+ },
+ "testpackage": {
+ "$ref": "#/definitions/settings/definitions/testpackageSettings"
+ },
+ "thelper": {
+ "$ref": "#/definitions/settings/definitions/thelperSettings"
+ },
+ "usestdlibvars": {
+ "$ref": "#/definitions/settings/definitions/usestdlibvarsSettings"
+ },
+ "usetesting": {
+ "$ref": "#/definitions/settings/definitions/usetestingSettings"
+ },
+ "unconvert": {
+ "$ref": "#/definitions/settings/definitions/unconvertSettings"
+ },
+ "unparam": {
+ "$ref": "#/definitions/settings/definitions/unparamSettings"
+ },
+ "unused": {
+ "$ref": "#/definitions/settings/definitions/unusedSettings"
+ },
+ "varnamelen": {
+ "$ref": "#/definitions/settings/definitions/varnamelenSettings"
+ },
+ "whitespace": {
+ "$ref": "#/definitions/settings/definitions/whitespaceSettings"
+ },
+ "wrapcheck": {
+ "$ref": "#/definitions/settings/definitions/wrapcheckSettings"
+ },
+ "wsl": {
+ "$ref": "#/definitions/settings/definitions/wslSettings"
+ },
+ "copyloopvar": {
+ "$ref": "#/definitions/settings/definitions/copyloopvarSettings"
+ },
+ "custom":{
+ "$ref": "#/definitions/settings/definitions/customSettings"
+ }
+ }
+ },
+ "exclusions":{
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "generated": {
+ "enum": ["strict", "lax", "disable"],
+ "default": "strict"
+ },
+ "warn-unused": {
+ "type": "boolean",
+ "default": false
+ },
+ "presets": {
+ "type": "array",
+ "items": {
+ "enum": [
+ "comments",
+ "std-error-handling",
+ "common-false-positives",
+ "legacy"
+ ]
+ }
+ },
+ "rules": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "path": {
+ "type": "string"
+ },
+ "path-except": {
+ "type": "string"
+ },
+ "linters": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linter-names"
+ }
+ },
+ "text": {
+ "type": "string"
+ },
+ "source": {
+ "type": "string"
+ }
+ },
+ "anyOf": [
+ { "required": ["path"] },
+ { "required": ["path-except"] },
+ { "required": ["linters"] },
+ { "required": ["text"] },
+ { "required": ["source"] }
+ ]
+ }
+ },
+ "paths": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "paths-except": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "formatters": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "enable": {
+ "description": "List of enabled formatters.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/formatter-names"
+ }
+ },
+ "settings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "gci": {
+ "$ref": "#/definitions/settings/definitions/gciSettings"
+ },
+ "gofmt": {
+ "$ref": "#/definitions/settings/definitions/gofmtSettings"
+ },
+ "gofumpt": {
+ "$ref": "#/definitions/settings/definitions/gofumptSettings"
+ },
+ "goimports": {
+ "$ref": "#/definitions/settings/definitions/goimportsSettings"
+ },
+ "golines": {
+ "$ref": "#/definitions/settings/definitions/golinesSettings"
+ }
+ }
+ },
+ "exclusions": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "generated": {
+ "enum": ["strict", "lax", "disable"],
+ "default": "strict"
+ },
+ "paths": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "warn-unused": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ }
+ }
+ },
+ "issues": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-issues-per-linter": {
+ "description": "Maximum issues count per one linter. Set to 0 to disable.",
+ "type": "integer",
+ "default": 50,
+ "minimum": 0
+ },
+ "max-same-issues": {
+ "description": "Maximum count of issues with the same text. Set to 0 to disable.",
+ "type": "integer",
+ "default": 3,
+ "minimum": 0
+ },
+ "new": {
+ "description": "Show only new issues: if there are unstaged changes or untracked files, only those changes are analyzed, else only changes in HEAD~ are analyzed.",
+ "type": "boolean",
+ "default": false
+ },
+ "new-from-merge-base": {
+ "description": "Show only new issues created after the best common ancestor (merge-base against HEAD).",
+ "type": "string"
+ },
+ "new-from-rev": {
+ "description": "Show only new issues created after this git revision.",
+ "type": "string"
+ },
+ "new-from-patch": {
+ "description": "Show only new issues created in git patch with this file path.",
+ "type": "string",
+ "examples": ["path/to/patch/file"]
+ },
+ "fix": {
+ "description": "Fix found issues (if it's supported by the linter).",
+ "type": "boolean",
+ "default": false
+ },
+ "uniq-by-line": {
+ "description": "Make issues output unique by line.",
+ "type": "boolean",
+ "default": true
+ },
+ "whole-files": {
+ "description": "Show issues in any part of update files (requires new-from-rev or new-from-patch).",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "severity": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "default": {
+ "description": "Set the default severity for issues. If severity rules are defined and the issues do not match or no severity is provided to the rule this will be the default severity applied. Severities should match the supported severity names of the selected out format.",
+ "type": "string",
+ "default": ""
+ },
+ "rules": {
+ "description": "When a list of severity rules are provided, severity information will be added to lint issues. Severity rules have the same filtering capability as exclude rules except you are allowed to specify one matcher per severity rule.\nOnly affects out formats that support setting severity information.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "severity": {
+ "type": "string"
+ },
+ "path": {
+ "type": "string"
+ },
+ "path-except": {
+ "type": "string"
+ },
+ "linters": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linter-names"
+ }
+ },
+ "text": {
+ "type": "string"
+ },
+ "source": {
+ "type": "string"
+ }
+ },
+ "required": ["severity"],
+ "anyOf": [
+ { "required": ["path"] },
+ { "required": ["path-except"] },
+ { "required": ["linters"] },
+ { "required": ["text"] },
+ { "required": ["source"] }
+ ]
+ },
+ "default": []
+ }
+ },
+ "required": ["default"]
+ }
+ }
+}
diff --git a/vendor/github.com/golangci/golangci-lint/v2/jsonschema/golangci.v2.10.jsonschema.json b/vendor/github.com/golangci/golangci-lint/v2/jsonschema/golangci.v2.10.jsonschema.json
new file mode 100644
index 000000000..7fa4a12db
--- /dev/null
+++ b/vendor/github.com/golangci/golangci-lint/v2/jsonschema/golangci.v2.10.jsonschema.json
@@ -0,0 +1,5285 @@
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "$id": "https://json.schemastore.org/golangci-lint.json",
+ "definitions": {
+ "gocritic-checks": {
+ "enum": [
+ "appendAssign",
+ "appendCombine",
+ "argOrder",
+ "assignOp",
+ "badCall",
+ "badCond",
+ "badLock",
+ "badRegexp",
+ "badSorting",
+ "badSyncOnceFunc",
+ "boolExprSimplify",
+ "builtinShadow",
+ "builtinShadowDecl",
+ "captLocal",
+ "caseOrder",
+ "codegenComment",
+ "commentFormatting",
+ "commentedOutCode",
+ "commentedOutImport",
+ "defaultCaseOrder",
+ "deferInLoop",
+ "deferUnlambda",
+ "deprecatedComment",
+ "docStub",
+ "dupArg",
+ "dupBranchBody",
+ "dupCase",
+ "dupImport",
+ "dupOption",
+ "dupSubExpr",
+ "dynamicFmtString",
+ "elseif",
+ "emptyDecl",
+ "emptyFallthrough",
+ "emptyStringTest",
+ "equalFold",
+ "evalOrder",
+ "exitAfterDefer",
+ "exposedSyncMutex",
+ "externalErrorReassign",
+ "filepathJoin",
+ "flagDeref",
+ "flagName",
+ "hexLiteral",
+ "httpNoBody",
+ "hugeParam",
+ "ifElseChain",
+ "importShadow",
+ "indexAlloc",
+ "initClause",
+ "mapKey",
+ "methodExprCall",
+ "nestingReduce",
+ "newDeref",
+ "nilValReturn",
+ "octalLiteral",
+ "offBy1",
+ "paramTypeCombine",
+ "preferDecodeRune",
+ "preferFilepathJoin",
+ "preferFprint",
+ "preferStringWriter",
+ "preferWriteByte",
+ "ptrToRefParam",
+ "rangeAppendAll",
+ "rangeExprCopy",
+ "rangeValCopy",
+ "redundantSprint",
+ "regexpMust",
+ "regexpPattern",
+ "regexpSimplify",
+ "returnAfterHttpError",
+ "ruleguard",
+ "singleCaseSwitch",
+ "sliceClear",
+ "sloppyLen",
+ "sloppyReassign",
+ "sloppyTypeAssert",
+ "sortSlice",
+ "sprintfQuotedString",
+ "sqlQuery",
+ "stringConcatSimplify",
+ "stringXbytes",
+ "stringsCompare",
+ "switchTrue",
+ "syncMapLoadAndDelete",
+ "timeExprSimplify",
+ "todoCommentWithoutDetail",
+ "tooManyResultsChecker",
+ "truncateCmp",
+ "typeAssertChain",
+ "typeDefFirst",
+ "typeSwitchVar",
+ "typeUnparen",
+ "uncheckedInlineErr",
+ "underef",
+ "unlabelStmt",
+ "unlambda",
+ "unnamedResult",
+ "unnecessaryBlock",
+ "unnecessaryDefer",
+ "unslice",
+ "valSwap",
+ "weakCond",
+ "whyNoLint",
+ "wrapperFunc",
+ "yodaStyleExpr",
+ "zeroByteRepeat"
+ ]
+ },
+ "gocritic-tags": {
+ "enum": [
+ "diagnostic",
+ "style",
+ "performance",
+ "experimental",
+ "opinionated",
+ "security"
+ ]
+ },
+ "staticcheck-checks": {
+ "enum": [
+ "*",
+ "all",
+ "SA*",
+ "-SA*",
+ "SA1*",
+ "-SA1*",
+ "SA1000",
+ "-SA1000",
+ "SA1001",
+ "-SA1001",
+ "SA1002",
+ "-SA1002",
+ "SA1003",
+ "-SA1003",
+ "SA1004",
+ "-SA1004",
+ "SA1005",
+ "-SA1005",
+ "SA1006",
+ "-SA1006",
+ "SA1007",
+ "-SA1007",
+ "SA1008",
+ "-SA1008",
+ "SA1010",
+ "-SA1010",
+ "SA1011",
+ "-SA1011",
+ "SA1012",
+ "-SA1012",
+ "SA1013",
+ "-SA1013",
+ "SA1014",
+ "-SA1014",
+ "SA1015",
+ "-SA1015",
+ "SA1016",
+ "-SA1016",
+ "SA1017",
+ "-SA1017",
+ "SA1018",
+ "-SA1018",
+ "SA1019",
+ "-SA1019",
+ "SA1020",
+ "-SA1020",
+ "SA1021",
+ "-SA1021",
+ "SA1023",
+ "-SA1023",
+ "SA1024",
+ "-SA1024",
+ "SA1025",
+ "-SA1025",
+ "SA1026",
+ "-SA1026",
+ "SA1027",
+ "-SA1027",
+ "SA1028",
+ "-SA1028",
+ "SA1029",
+ "-SA1029",
+ "SA1030",
+ "-SA1030",
+ "SA1031",
+ "-SA1031",
+ "SA1032",
+ "-SA1032",
+ "SA2*",
+ "-SA2*",
+ "SA2000",
+ "-SA2000",
+ "SA2001",
+ "-SA2001",
+ "SA2002",
+ "-SA2002",
+ "SA2003",
+ "-SA2003",
+ "SA3*",
+ "-SA3*",
+ "SA3000",
+ "-SA3000",
+ "SA3001",
+ "-SA3001",
+ "SA4*",
+ "-SA4*",
+ "SA4000",
+ "-SA4000",
+ "SA4001",
+ "-SA4001",
+ "SA4003",
+ "-SA4003",
+ "SA4004",
+ "-SA4004",
+ "SA4005",
+ "-SA4005",
+ "SA4006",
+ "-SA4006",
+ "SA4008",
+ "-SA4008",
+ "SA4009",
+ "-SA4009",
+ "SA4010",
+ "-SA4010",
+ "SA4011",
+ "-SA4011",
+ "SA4012",
+ "-SA4012",
+ "SA4013",
+ "-SA4013",
+ "SA4014",
+ "-SA4014",
+ "SA4015",
+ "-SA4015",
+ "SA4016",
+ "-SA4016",
+ "SA4017",
+ "-SA4017",
+ "SA4018",
+ "-SA4018",
+ "SA4019",
+ "-SA4019",
+ "SA4020",
+ "-SA4020",
+ "SA4021",
+ "-SA4021",
+ "SA4022",
+ "-SA4022",
+ "SA4023",
+ "-SA4023",
+ "SA4024",
+ "-SA4024",
+ "SA4025",
+ "-SA4025",
+ "SA4026",
+ "-SA4026",
+ "SA4027",
+ "-SA4027",
+ "SA4028",
+ "-SA4028",
+ "SA4029",
+ "-SA4029",
+ "SA4030",
+ "-SA4030",
+ "SA4031",
+ "-SA4031",
+ "SA4032",
+ "-SA4032",
+ "SA5*",
+ "-SA5*",
+ "SA5000",
+ "-SA5000",
+ "SA5001",
+ "-SA5001",
+ "SA5002",
+ "-SA5002",
+ "SA5003",
+ "-SA5003",
+ "SA5004",
+ "-SA5004",
+ "SA5005",
+ "-SA5005",
+ "SA5007",
+ "-SA5007",
+ "SA5008",
+ "-SA5008",
+ "SA5009",
+ "-SA5009",
+ "SA5010",
+ "-SA5010",
+ "SA5011",
+ "-SA5011",
+ "SA5012",
+ "-SA5012",
+ "SA6*",
+ "-SA6*",
+ "SA6000",
+ "-SA6000",
+ "SA6001",
+ "-SA6001",
+ "SA6002",
+ "-SA6002",
+ "SA6003",
+ "-SA6003",
+ "SA6005",
+ "-SA6005",
+ "SA6006",
+ "-SA6006",
+ "SA9*",
+ "-SA9*",
+ "SA9001",
+ "-SA9001",
+ "SA9002",
+ "-SA9002",
+ "SA9003",
+ "-SA9003",
+ "SA9004",
+ "-SA9004",
+ "SA9005",
+ "-SA9005",
+ "SA9006",
+ "-SA9006",
+ "SA9007",
+ "-SA9007",
+ "SA9008",
+ "-SA9008",
+ "SA9009",
+ "-SA9009",
+ "ST*",
+ "-ST*",
+ "ST1*",
+ "-ST1*",
+ "ST1000",
+ "-ST1000",
+ "ST1001",
+ "-ST1001",
+ "ST1003",
+ "-ST1003",
+ "ST1005",
+ "-ST1005",
+ "ST1006",
+ "-ST1006",
+ "ST1008",
+ "-ST1008",
+ "ST1011",
+ "-ST1011",
+ "ST1012",
+ "-ST1012",
+ "ST1013",
+ "-ST1013",
+ "ST1015",
+ "-ST1015",
+ "ST1016",
+ "-ST1016",
+ "ST1017",
+ "-ST1017",
+ "ST1018",
+ "-ST1018",
+ "ST1019",
+ "-ST1019",
+ "ST1020",
+ "-ST1020",
+ "ST1021",
+ "-ST1021",
+ "ST1022",
+ "-ST1022",
+ "ST1023",
+ "-ST1023",
+ "S*",
+ "-S*",
+ "S1*",
+ "-S1*",
+ "S1000",
+ "-S1000",
+ "S1001",
+ "-S1001",
+ "S1002",
+ "-S1002",
+ "S1003",
+ "-S1003",
+ "S1004",
+ "-S1004",
+ "S1005",
+ "-S1005",
+ "S1006",
+ "-S1006",
+ "S1007",
+ "-S1007",
+ "S1008",
+ "-S1008",
+ "S1009",
+ "-S1009",
+ "S1010",
+ "-S1010",
+ "S1011",
+ "-S1011",
+ "S1012",
+ "-S1012",
+ "S1016",
+ "-S1016",
+ "S1017",
+ "-S1017",
+ "S1018",
+ "-S1018",
+ "S1019",
+ "-S1019",
+ "S1020",
+ "-S1020",
+ "S1021",
+ "-S1021",
+ "S1023",
+ "-S1023",
+ "S1024",
+ "-S1024",
+ "S1025",
+ "-S1025",
+ "S1028",
+ "-S1028",
+ "S1029",
+ "-S1029",
+ "S1030",
+ "-S1030",
+ "S1031",
+ "-S1031",
+ "S1032",
+ "-S1032",
+ "S1033",
+ "-S1033",
+ "S1034",
+ "-S1034",
+ "S1035",
+ "-S1035",
+ "S1036",
+ "-S1036",
+ "S1037",
+ "-S1037",
+ "S1038",
+ "-S1038",
+ "S1039",
+ "-S1039",
+ "S1040",
+ "-S1040",
+ "QF*",
+ "-QF*",
+ "QF1*",
+ "-QF1*",
+ "QF1001",
+ "-QF1001",
+ "QF1002",
+ "-QF1002",
+ "QF1003",
+ "-QF1003",
+ "QF1004",
+ "-QF1004",
+ "QF1005",
+ "-QF1005",
+ "QF1006",
+ "-QF1006",
+ "QF1007",
+ "-QF1007",
+ "QF1008",
+ "-QF1008",
+ "QF1009",
+ "-QF1009",
+ "QF1010",
+ "-QF1010",
+ "QF1011",
+ "-QF1011",
+ "QF1012",
+ "-QF1012"
+ ]
+ },
+ "godoclint-rules": {
+ "enum": [
+ "pkg-doc",
+ "single-pkg-doc",
+ "require-pkg-doc",
+ "start-with-name",
+ "require-doc",
+ "deprecated",
+ "max-len",
+ "no-unused-link",
+ "require-stdlib-doclink"
+ ]
+ },
+ "gosec-rules": {
+ "enum": [
+ "G101",
+ "G102",
+ "G103",
+ "G104",
+ "G106",
+ "G107",
+ "G108",
+ "G109",
+ "G110",
+ "G111",
+ "G112",
+ "G114",
+ "G115",
+ "G116",
+ "G117",
+ "G201",
+ "G202",
+ "G203",
+ "G204",
+ "G301",
+ "G302",
+ "G303",
+ "G304",
+ "G305",
+ "G306",
+ "G307",
+ "G401",
+ "G402",
+ "G403",
+ "G404",
+ "G405",
+ "G406",
+ "G501",
+ "G502",
+ "G503",
+ "G504",
+ "G505",
+ "G506",
+ "G507",
+ "G601",
+ "G602",
+ "G701",
+ "G702",
+ "G703",
+ "G704",
+ "G705",
+ "G706"
+ ]
+ },
+ "govet-analyzers": {
+ "enum": [
+ "appends",
+ "asmdecl",
+ "assign",
+ "atomic",
+ "atomicalign",
+ "bools",
+ "buildtag",
+ "cgocall",
+ "composites",
+ "copylocks",
+ "deepequalerrors",
+ "defers",
+ "directive",
+ "errorsas",
+ "fieldalignment",
+ "findcall",
+ "framepointer",
+ "hostport",
+ "httpmux",
+ "httpresponse",
+ "ifaceassert",
+ "loopclosure",
+ "lostcancel",
+ "nilfunc",
+ "nilness",
+ "printf",
+ "reflectvaluecompare",
+ "shadow",
+ "shift",
+ "sigchanyzer",
+ "slog",
+ "sortslice",
+ "stdmethods",
+ "stdversion",
+ "stringintconv",
+ "structtag",
+ "testinggoroutine",
+ "tests",
+ "timeformat",
+ "unmarshal",
+ "unreachable",
+ "unsafeptr",
+ "unusedresult",
+ "unusedwrite",
+ "waitgroup"
+ ]
+ },
+ "revive-rules": {
+ "enum": [
+ "add-constant",
+ "argument-limit",
+ "atomic",
+ "banned-characters",
+ "bare-return",
+ "blank-imports",
+ "bool-literal-in-expr",
+ "call-to-gc",
+ "cognitive-complexity",
+ "comment-spacings",
+ "comments-density",
+ "confusing-naming",
+ "confusing-results",
+ "constant-logical-expr",
+ "context-as-argument",
+ "context-keys-type",
+ "cyclomatic",
+ "datarace",
+ "deep-exit",
+ "defer",
+ "dot-imports",
+ "duplicated-imports",
+ "early-return",
+ "empty-block",
+ "empty-lines",
+ "enforce-map-style",
+ "enforce-repeated-arg-type-style",
+ "enforce-slice-style",
+ "enforce-switch-style",
+ "epoch-naming",
+ "error-naming",
+ "error-return",
+ "error-strings",
+ "errorf",
+ "exported",
+ "file-header",
+ "file-length-limit",
+ "filename-format",
+ "flag-parameter",
+ "forbidden-call-in-wg-go",
+ "function-length",
+ "function-result-limit",
+ "get-return",
+ "identical-branches",
+ "identical-ifelseif-branches",
+ "identical-ifelseif-conditions",
+ "identical-switch-branches",
+ "identical-switch-conditions",
+ "if-return",
+ "import-alias-naming",
+ "import-shadowing",
+ "imports-blocklist",
+ "increment-decrement",
+ "indent-error-flow",
+ "inefficient-map-lookup",
+ "line-length-limit",
+ "max-control-nesting",
+ "max-public-structs",
+ "modifies-parameter",
+ "modifies-value-receiver",
+ "nested-structs",
+ "optimize-operands-order",
+ "package-comments",
+ "package-directory-mismatch",
+ "range-val-address",
+ "range-val-in-closure",
+ "range",
+ "receiver-naming",
+ "redefines-builtin-id",
+ "redundant-build-tag",
+ "redundant-import-alias",
+ "redundant-test-main-exit",
+ "string-format",
+ "string-of-int",
+ "struct-tag",
+ "superfluous-else",
+ "time-date",
+ "time-equal",
+ "time-naming",
+ "unchecked-type-assertion",
+ "unconditional-recursion",
+ "unexported-naming",
+ "unexported-return",
+ "unhandled-error",
+ "unnecessary-format",
+ "unnecessary-if",
+ "unnecessary-stmt",
+ "unreachable-code",
+ "unsecure-url-scheme",
+ "unused-parameter",
+ "unused-receiver",
+ "use-any",
+ "use-errors-new",
+ "use-fmt-print",
+ "use-slices-sort",
+ "use-waitgroup-go",
+ "useless-break",
+ "useless-fallthrough",
+ "var-declaration",
+ "var-naming",
+ "waitgroup-by-value"
+ ]
+ },
+ "iface-analyzers": {
+ "enum": [
+ "identical",
+ "unused",
+ "opaque",
+ "unexported"
+ ]
+ },
+ "tagliatelle-cases": {
+ "enum": [
+ "",
+ "camel",
+ "pascal",
+ "kebab",
+ "snake",
+ "goCamel",
+ "goPascal",
+ "goKebab",
+ "goSnake",
+ "upper",
+ "upperSnake",
+ "lower",
+ "header"
+ ]
+ },
+ "modernize-analyzers": {
+ "enum": [
+ "any",
+ "fmtappendf",
+ "forvar",
+ "mapsloop",
+ "minmax",
+ "newexpr",
+ "omitzero",
+ "plusbuild",
+ "rangeint",
+ "reflecttypefor",
+ "slicescontains",
+ "slicessort",
+ "stditerators",
+ "stringscut",
+ "stringscutprefix",
+ "stringsseq",
+ "stringsbuilder",
+ "testingcontext",
+ "unsafefuncs",
+ "waitgroup"
+ ]
+ },
+ "wsl-checks": {
+ "enum": [
+ "assign",
+ "branch",
+ "decl",
+ "defer",
+ "expr",
+ "for",
+ "go",
+ "if",
+ "inc-dec",
+ "label",
+ "range",
+ "return",
+ "select",
+ "send",
+ "switch",
+ "type-switch",
+ "append",
+ "assign-exclusive",
+ "assign-expr",
+ "err",
+ "leading-whitespace",
+ "trailing-whitespace",
+ "after-block"
+ ]
+ },
+ "relative-path-modes": {
+ "enum": [
+ "gomod",
+ "gitroot",
+ "cfg",
+ "wd"
+ ]
+ },
+ "simple-format": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "path": {
+ "$ref": "#/definitions/formats-path",
+ "default": "stdout"
+ }
+ }
+ },
+ "formats-path" : {
+ "anyOf": [
+ {
+ "enum": [
+ "stdout",
+ "stderr"
+ ]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ },
+ "linter-names": {
+ "$comment": "anyOf with enum is used to allow auto-completion of non-custom linters",
+ "description": "Usable linter names.",
+ "anyOf": [
+ {
+ "enum": [
+ "arangolint",
+ "asasalint",
+ "asciicheck",
+ "bidichk",
+ "bodyclose",
+ "canonicalheader",
+ "containedctx",
+ "contextcheck",
+ "copyloopvar",
+ "cyclop",
+ "decorder",
+ "depguard",
+ "dogsled",
+ "dupl",
+ "dupword",
+ "durationcheck",
+ "embeddedstructfieldcheck",
+ "errcheck",
+ "errchkjson",
+ "errname",
+ "errorlint",
+ "exhaustive",
+ "exhaustruct",
+ "exptostd",
+ "fatcontext",
+ "forbidigo",
+ "forcetypeassert",
+ "funcorder",
+ "funlen",
+ "ginkgolinter",
+ "gocheckcompilerdirectives",
+ "gochecknoglobals",
+ "gochecknoinits",
+ "gochecksumtype",
+ "gocognit",
+ "goconst",
+ "gocritic",
+ "gocyclo",
+ "godoclint",
+ "godot",
+ "godox",
+ "err113",
+ "goheader",
+ "gomoddirectives",
+ "gomodguard",
+ "goprintffuncname",
+ "gosec",
+ "gosimple",
+ "gosmopolitan",
+ "govet",
+ "grouper",
+ "iface",
+ "importas",
+ "inamedparam",
+ "ineffassign",
+ "interfacebloat",
+ "intrange",
+ "iotamixing",
+ "ireturn",
+ "lll",
+ "loggercheck",
+ "maintidx",
+ "makezero",
+ "mirror",
+ "misspell",
+ "mnd",
+ "modernize",
+ "musttag",
+ "nakedret",
+ "nestif",
+ "nilerr",
+ "nilnesserr",
+ "nilnil",
+ "nlreturn",
+ "noctx",
+ "noinlineerr",
+ "nolintlint",
+ "nonamedreturns",
+ "nosprintfhostport",
+ "paralleltest",
+ "perfsprint",
+ "prealloc",
+ "predeclared",
+ "promlinter",
+ "protogetter",
+ "reassign",
+ "recvcheck",
+ "revive",
+ "rowserrcheck",
+ "sloglint",
+ "sqlclosecheck",
+ "staticcheck",
+ "stylecheck",
+ "tagalign",
+ "tagliatelle",
+ "testableexamples",
+ "testifylint",
+ "testpackage",
+ "thelper",
+ "tparallel",
+ "unconvert",
+ "unparam",
+ "unused",
+ "usestdlibvars",
+ "usetesting",
+ "varnamelen",
+ "wastedassign",
+ "whitespace",
+ "wrapcheck",
+ "wsl",
+ "wsl_v5",
+ "zerologlint"
+ ]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ },
+ "formatter-names": {
+ "description": "Usable formatter names.",
+ "enum": [
+ "gci",
+ "gofmt",
+ "gofumpt",
+ "goimports",
+ "golines",
+ "swaggo"
+ ]
+ },
+ "settings": {
+ "definitions": {
+ "dupwordSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "keywords": {
+ "description": "Keywords for detecting duplicate words. If this list is not empty, only the words defined in this list will be detected.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["the", "and", "a"]
+ }
+ },
+ "ignore": {
+ "description": "Keywords used to ignore detection.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["0C0C"]
+ }
+ },
+ "comments-only": {
+ "description": "Checks only comments, skip strings.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "asasalintSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "exclude": {
+ "description": "To specify a set of function names to exclude.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["\\.Wrapf"]
+ }
+ },
+ "use-builtin-exclusions": {
+ "description": "To enable/disable the asasalint builtin exclusions of function names.",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "bidichkSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "left-to-right-embedding": {
+ "description": "Disallow: LEFT-TO-RIGHT-EMBEDDING",
+ "type": "boolean",
+ "default": false
+ },
+ "right-to-left-embedding": {
+ "description": "Disallow: RIGHT-TO-LEFT-EMBEDDING",
+ "type": "boolean",
+ "default": false
+ },
+ "pop-directional-formatting": {
+ "description": "Disallow: POP-DIRECTIONAL-FORMATTING",
+ "type": "boolean",
+ "default": false
+ },
+ "left-to-right-override": {
+ "description": "Disallow: LEFT-TO-RIGHT-OVERRIDE",
+ "type": "boolean",
+ "default": false
+ },
+ "right-to-left-override": {
+ "description": "Disallow: RIGHT-TO-LEFT-OVERRIDE",
+ "type": "boolean",
+ "default": false
+ },
+ "left-to-right-isolate": {
+ "description": "Disallow: LEFT-TO-RIGHT-ISOLATE",
+ "type": "boolean",
+ "default": false
+ },
+ "right-to-left-isolate": {
+ "description": "Disallow: RIGHT-TO-LEFT-ISOLATE",
+ "type": "boolean",
+ "default": false
+ },
+ "first-strong-isolate": {
+ "description": "Disallow: FIRST-STRONG-ISOLATE",
+ "type": "boolean",
+ "default": false
+ },
+ "pop-directional-isolate": {
+ "description": "Disallow: POP-DIRECTIONAL-ISOLATE",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "cyclopSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-complexity": {
+ "description": "Max complexity the function can have",
+ "type": "integer",
+ "default": 10,
+ "minimum": 0
+ },
+ "package-average": {
+ "description": "Max average complexity in package",
+ "type": "number",
+ "default": 0,
+ "minimum": 0
+ }
+ }
+ },
+ "decorderSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "dec-order": {
+ "type": "array",
+ "default": [["type", "const", "var", "func"]],
+ "items": {
+ "enum": ["type", "const", "var", "func"]
+ }
+ },
+ "ignore-underscore-vars": {
+ "description": "Underscore vars (vars with \"_\" as the name) will be ignored at all checks",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-dec-order-check": {
+ "description": "Order of declarations is not checked",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-init-func-first-check": {
+ "description": "Allow init func to be anywhere in file",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-dec-num-check": {
+ "description": "Multiple global type, const and var declarations are allowed",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-type-dec-num-check": {
+ "description": "Type declarations will be ignored for dec num check",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-const-dec-num-check": {
+ "description": "Const declarations will be ignored for dec num check",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-var-dec-num-check": {
+ "description": "Var declarations will be ignored for dec num check",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ },
+ "depguardSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "rules": {
+ "description": "Rules to apply.",
+ "type": "object",
+ "additionalProperties": false,
+ "patternProperties": {
+ "^[^.]+$": {
+ "description": "Name of a rule.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "list-mode": {
+ "description": "Used to determine the package matching priority.",
+ "enum": ["original", "strict", "lax"],
+ "default": "original"
+ },
+ "files": {
+ "description": "List of file globs that will match this list of settings to compare against.",
+ "additionalProperties": false,
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "allow": {
+ "description": "List of allowed packages.",
+ "additionalProperties": false,
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "deny": {
+ "description": "Packages that are not allowed where the value is a suggestion.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "desc": {
+ "description": "Description",
+ "type": "string"
+ },
+ "pkg": {
+ "description": "Package",
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "dogsledSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-blank-identifiers": {
+ "description": "Check assignments with too many blank identifiers.",
+ "type": "integer",
+ "default": 2,
+ "minimum": 0
+ }
+ }
+ },
+ "duplSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "threshold": {
+ "description": "Tokens count to trigger issue.",
+ "type": "integer",
+ "default": 150,
+ "minimum": 0
+ }
+ }
+ },
+ "embeddedstructfieldcheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "empty-line": {
+ "description": "Checks that there is an empty space between the embedded fields and regular fields.",
+ "type": "boolean",
+ "default": false
+ },
+ "forbid-mutex": {
+ "description": "Checks that sync.Mutex and sync.RWMutex are not used as embedded fields.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "errcheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-type-assertions": {
+ "description": "Report about not checking errors in type assertions, i.e.: `a := b.(MyStruct)`",
+ "type": "boolean",
+ "default": false
+ },
+ "check-blank": {
+ "description": "Report about assignment of errors to blank identifier",
+ "type": "boolean",
+ "default": false
+ },
+ "exclude-functions": {
+ "description": "List of functions to exclude from checking, where each entry is a single function to exclude",
+ "type": "array",
+ "examples": ["io/ioutil.ReadFile", "io.Copy(*bytes.Buffer)"],
+ "items": {
+ "type": "string"
+ }
+ },
+ "disable-default-exclusions": {
+ "description": "To disable the errcheck built-in exclude list",
+ "type": "boolean",
+ "default": false
+ },
+ "verbose": {
+ "description": "Display function signature instead of selector",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "errchkjsonSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-error-free-encoding": {
+ "type": "boolean",
+ "default": false
+ },
+ "report-no-exported": {
+ "description": "Issue on struct that doesn't have exported fields.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "errorlintSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "errorf": {
+ "description": "Check whether fmt.Errorf uses the %w verb for formatting errors",
+ "type": "boolean",
+ "default": true
+ },
+ "errorf-multi": {
+ "description": "Permit more than 1 %w verb, valid per Go 1.20",
+ "type": "boolean",
+ "default": true
+ },
+ "asserts": {
+ "description": "Check for plain type assertions and type switches.",
+ "type": "boolean",
+ "default": true
+ },
+ "comparison": {
+ "description": "Check for plain error comparisons",
+ "type": "boolean",
+ "default": true
+ },
+ "allowed-errors": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "err": {
+ "type": "string"
+ },
+ "fun": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "allowed-errors-wildcard": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "err": {
+ "type": "string"
+ },
+ "fun": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "exhaustiveSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check": {
+ "description": "Program elements to check for exhaustiveness.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["switch", "map"]
+ }
+ },
+ "explicit-exhaustive-switch": {
+ "description": "Only run exhaustive check on switches with \"//exhaustive:enforce\" comment.",
+ "type": "boolean",
+ "default": false
+ },
+ "explicit-exhaustive-map": {
+ "description": "Only run exhaustive check on map literals with \"//exhaustive:enforce\" comment.",
+ "type": "boolean",
+ "default": false
+ },
+ "default-case-required": {
+ "description": "Switch statement requires default case even if exhaustive.",
+ "type": "boolean",
+ "default": false
+ },
+ "default-signifies-exhaustive": {
+ "description": "Presence of `default` case in switch statements satisfies exhaustiveness, even if all enum members are not listed.",
+ "type": "boolean",
+ "default": false
+ },
+ "ignore-enum-members": {
+ "description": "Enum members matching `regex` do not have to be listed in switch statements to satisfy exhaustiveness",
+ "type": "string"
+ },
+ "ignore-enum-types": {
+ "description": "Enum types matching the supplied regex do not have to be listed in switch statements to satisfy exhaustiveness.",
+ "type": "string"
+ },
+ "package-scope-only": {
+ "description": "Consider enums only in package scopes, not in inner scopes.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "exhaustructSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "include": {
+ "description": "List of regular expressions to match struct packages and names.",
+ "type": "array",
+ "examples": [".*\\.Test"],
+ "items": {
+ "type": "string"
+ }
+ },
+ "exclude": {
+ "description": "List of regular expressions to exclude struct packages and names from check.",
+ "type": "array",
+ "examples": ["cobra\\.Command$"],
+ "items": {
+ "type": "string"
+ }
+ },
+ "allow-empty": {
+ "description": "Allows empty structures, effectively excluding them from the check.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-empty-rx": {
+ "description": "List of regular expressions to match type names that should be allowed to be empty.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "allow-empty-returns": {
+ "description": "Allows empty structures in return statements.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-empty-declarations": {
+ "description": "Allows empty structures in variable declarations.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "fatcontextSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-struct-pointers": {
+ "description": "Check for potential fat contexts in struct pointers.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "forbidigoSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "exclude-godoc-examples": {
+ "description": "Exclude code in godoc examples.",
+ "type": "boolean",
+ "default": true
+ },
+ "analyze-types": {
+ "description": "Instead of matching the literal source code, use type information to replace expressions with strings that contain the package name and (for methods and fields) the type name.",
+ "type": "boolean",
+ "default": true
+ },
+ "forbid": {
+ "description": "List of identifiers to forbid (written using `regexp`)",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "pattern": {
+ "description": "Pattern",
+ "type": "string"
+ },
+ "pkg": {
+ "description": "Package",
+ "type": "string"
+ },
+ "msg": {
+ "description": "Message",
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "funcorderSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "constructor": {
+ "description": "Checks that constructors are placed after the structure declaration.",
+ "type": "boolean",
+ "default": true
+ },
+ "struct-method": {
+ "description": "Checks if the exported methods of a structure are placed before the non-exported ones.",
+ "type": "boolean",
+ "default": true
+ },
+ "alphabetical": {
+ "description": "Checks if the constructors and/or structure methods are sorted alphabetically.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "funlenSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "lines": {
+ "description": "Limit lines number per function.",
+ "type": "integer",
+ "default": 60
+ },
+ "statements": {
+ "description": "Limit statements number per function.",
+ "type": "integer",
+ "default": 40
+ },
+ "ignore-comments": {
+ "description": "Ignore comments when counting lines.",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "gciSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "sections": {
+ "description": "Section configuration to compare against.",
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "enum": [
+ "standard",
+ "default",
+ "blank",
+ "dot",
+ "alias",
+ "localmodule"
+ ]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ },
+ "default": ["standard", "default"]
+ },
+ "no-inline-comments": {
+ "description": "Checks that no inline Comments are present.",
+ "type": "boolean",
+ "default": false
+ },
+ "no-prefix-comments": {
+ "description": "Checks that no prefix Comments(comment lines above an import) are present.",
+ "type": "boolean",
+ "default": false
+ },
+ "custom-order": {
+ "description": "Enable custom order of sections.",
+ "type": "boolean",
+ "default": false
+ },
+ "no-lex-order": {
+ "description": "Drops lexical ordering for custom sections.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "ginkgolinterSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "suppress-len-assertion": {
+ "description": "Suppress the wrong length assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-nil-assertion": {
+ "description": "Suppress the wrong nil assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-err-assertion": {
+ "description": "Suppress the wrong error assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-compare-assertion": {
+ "description": "Suppress the wrong comparison assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-async-assertion": {
+ "description": "Suppress the function all in async assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-type-compare-assertion": {
+ "description": "Suppress warning for comparing values from different types, like int32 and uint32.",
+ "type": "boolean",
+ "default": false
+ },
+ "forbid-focus-container": {
+ "description": "Trigger warning for ginkgo focus containers like FDescribe, FContext, FWhen or FIt.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-havelen-zero": {
+ "description": "Don't trigger warnings for HaveLen(0).",
+ "type": "boolean",
+ "default": false
+ },
+ "force-expect-to": {
+ "description": "Force using `Expect` with `To`, `ToNot` or `NotTo`",
+ "type": "boolean",
+ "default": false
+ },
+ "validate-async-intervals": {
+ "description": "Best effort validation of async intervals (timeout and polling).",
+ "type": "boolean",
+ "default": false
+ },
+ "forbid-spec-pollution": {
+ "description": "Trigger a warning for variable assignments in ginkgo containers like `Describe`, `Context` and `When`, instead of in `BeforeEach()`.",
+ "type": "boolean",
+ "default": false
+ },
+ "force-succeed": {
+ "description": "Force using the Succeed matcher for error functions, and the HaveOccurred matcher for non-function error values.",
+ "type": "boolean",
+ "default": false
+ },
+ "force-assertion-description": {
+ "description": "Force adding assertion descriptions to gomega matchers.",
+ "type": "boolean",
+ "default": false
+ },
+ "force-tonot": {
+ "description": "Force using `ToNot`, `ShouldNot` instead of `To(Not())`.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "gochecksumtypeSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "default-signifies-exhaustive": {
+ "description": "Presence of `default` case in switch statements satisfies exhaustiveness, if all members are not listed.",
+ "type": "boolean",
+ "default": true
+ },
+ "include-shared-interfaces": {
+ "description": "Include shared interfaces in the exhaustiviness check.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "gocognitSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "min-complexity": {
+ "description": "Minimal code complexity to report (we recommend 10-20).",
+ "type": "integer",
+ "default": 30
+ }
+ }
+ },
+ "goconstSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "match-constant": {
+ "description": "Look for existing constants matching the values",
+ "type": "boolean",
+ "default": true
+ },
+ "min-len": {
+ "description": "Minimum length of string constant.",
+ "type": "integer",
+ "default": 3
+ },
+ "min-occurrences": {
+ "description": "Minimum occurrences count to trigger.",
+ "type": "integer",
+ "default": 3
+ },
+ "ignore-calls": {
+ "description": "Ignore when constant is not used as function argument",
+ "type": "boolean",
+ "default": true
+ },
+ "ignore-string-values": {
+ "description": "Exclude strings matching the given regular expression",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "numbers": {
+ "description": "Search also for duplicated numbers.",
+ "type": "boolean",
+ "default": false
+ },
+ "min": {
+ "description": "Minimum value, only works with `numbers`",
+ "type": "integer",
+ "default": 3
+ },
+ "max": {
+ "description": "Maximum value, only works with `numbers`",
+ "type": "integer",
+ "default": 3
+ },
+ "find-duplicates": {
+ "description": "Detects constants with identical values",
+ "type": "boolean",
+ "default": false
+ },
+ "eval-const-expressions": {
+ "description": "Evaluates of constant expressions like Prefix + \"suffix\"",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "gocriticSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "enabled-checks": {
+ "description": "Which checks should be enabled. By default, a list of stable checks is used. To see it, run `GL_DEBUG=gocritic golangci-lint run`.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/gocritic-checks"
+ }
+ },
+ "disabled-checks": {
+ "description": "Which checks should be disabled.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/gocritic-checks"
+ },
+ "default": []
+ },
+ "enabled-tags": {
+ "description": "Enable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/gocritic-tags"
+ }
+ },
+ "disabled-tags": {
+ "description": "Disable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/gocritic-tags"
+ }
+ },
+ "settings": {
+ "description": "Settings passed to gocritic. Properties must be valid and enabled check names.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "captLocal": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "paramsOnly" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "commentedOutCode": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "minLength" : {
+ "type": "number",
+ "default": 15
+ }
+ }
+ },
+ "elseif": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skipBalanced" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "hugeParam": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "sizeThreshold" : {
+ "type": "number",
+ "default": 80
+ }
+ }
+ },
+ "ifElseChain": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "minThreshold" : {
+ "type": "number",
+ "default": 2
+ }
+ }
+ },
+ "nestingReduce": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "bodyWidth" : {
+ "type": "number",
+ "default": 5
+ }
+ }
+ },
+ "rangeExprCopy": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "sizeThreshold" : {
+ "type": "number",
+ "default": 512
+ },
+ "skipTestFuncs" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "rangeValCopy": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "sizeThreshold" : {
+ "type": "number",
+ "default": 128
+ },
+ "skipTestFuncs" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "ruleguard": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "debug" : {
+ "type": "string"
+ },
+ "enable" : {
+ "type": "string"
+ },
+ "disable" : {
+ "type": "string"
+ },
+ "failOn" : {
+ "type": "string"
+ },
+ "rules" : {
+ "type": "string"
+ }
+ }
+ },
+ "tooManyResultsChecker": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "maxResults" : {
+ "type": "number",
+ "default": 5
+ }
+ }
+ },
+ "truncateCmp": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skipArchDependent" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "underef": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skipRecvDeref" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "unnamedResult": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "checkExported" : {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ }
+ }
+ },
+ "disable-all": {
+ "type": "boolean",
+ "default": false
+ },
+ "enable-all": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "gocycloSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "min-complexity": {
+ "description": "Minimum code complexity to report (we recommend 10-20).",
+ "type": "integer",
+ "default": 30
+ }
+ }
+ },
+ "godoclintSettings": {
+ "type": "object",
+ "properties": {
+ "default": {
+ "type": "string",
+ "enum": ["all", "basic", "none"],
+ "default": "basic",
+ "description": "Default set of rules to enable."
+ },
+ "enable": {
+ "description": "List of rules to enable in addition to the default set.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "$ref": "#/definitions/godoclint-rules"
+ }
+ },
+ "disable": {
+ "description": "List of rules to disable.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "$ref": "#/definitions/godoclint-rules"
+ }
+ },
+ "options": {
+ "type": "object",
+ "description": "A map for setting individual rule options.",
+ "properties": {
+ "max-len": {
+ "type": "object",
+ "properties": {
+ "length": {
+ "type": "integer",
+ "description": "Maximum line length for godocs, not including the `//`, `/*` or `*/` tokens.",
+ "default": 77
+ }
+ }
+ },
+ "require-doc": {
+ "type": "object",
+ "properties": {
+ "ignore-exported": {
+ "type": "boolean",
+ "description": "Ignore exported (public) symbols when applying the `require-doc` rule.",
+ "default": false
+ },
+ "ignore-unexported": {
+ "type": "boolean",
+ "description": "Ignore unexported (private) symbols when applying the `require-doc` rule.",
+ "default": true
+ }
+ }
+ },
+ "start-with-name": {
+ "type": "object",
+ "properties": {
+ "include-unexported": {
+ "type": "boolean",
+ "description": "Include unexported symbols when applying the `start-with-name` rule.",
+ "default": false
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "godotSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "scope": {
+ "description": "Comments to be checked.",
+ "enum": ["declarations", "toplevel", "all", "noinline"],
+ "default": "declarations"
+ },
+ "exclude": {
+ "description": "List of regexps for excluding particular comment lines from check.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "period": {
+ "description": "Check that each sentence ends with a period.",
+ "type": "boolean",
+ "default": true
+ },
+ "capital": {
+ "description": "Check that each sentence starts with a capital letter.",
+ "type": "boolean",
+ "default": false
+ },
+ "check-all": {
+ "description": "DEPRECATED: Check all top-level comments, not only declarations.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "godoxSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "keywords": {
+ "description": "Report any comments starting with one of these keywords. This is useful for TODO or FIXME comments that might be left in the code accidentally and should be resolved before merging.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "default": ["TODO", "BUG", "FIXME"]
+ }
+ }
+ },
+ "gofmtSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "simplify": {
+ "description": "Simplify code.",
+ "type": "boolean",
+ "default": true
+ },
+ "rewrite-rules": {
+ "description": "Apply the rewrite rules to the source before reformatting.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "pattern": {
+ "type": "string"
+ },
+ "replacement": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "golinesSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-len": {
+ "type": "integer",
+ "default": 100
+ },
+ "tab-len": {
+ "type": "integer",
+ "default": 4
+ },
+ "shorten-comments": {
+ "type": "boolean",
+ "default": false
+ },
+ "reformat-tags": {
+ "type": "boolean",
+ "default": true
+ },
+ "chain-split-dots": {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "interfacebloatSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max": {
+ "description": "The maximum number of methods allowed for an interface.",
+ "type": "integer"
+ }
+ }
+ },
+ "gofumptSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "extra-rules": {
+ "description": "Choose whether or not to use the extra rules that are disabled by default.",
+ "type": "boolean",
+ "default": false
+ },
+ "module-path": {
+ "description": " Module path which contains the source code being formatted.",
+ "type": "string"
+ }
+ }
+ },
+ "goheaderSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "values": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "const": {
+ "description": "Constants to use in the template.",
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "description": "Value for the constant.",
+ "type": "string"
+ }
+ },
+ "additionalProperties": false,
+ "examples": [
+ {
+ "YEAR": "2030",
+ "COMPANY": "MY FUTURISTIC COMPANY"
+ }
+ ]
+ },
+ "regexp": {
+ "description": "Regular expressions to use in your template.",
+ "type": "object",
+ "additionalProperties": false,
+ "patternProperties": {
+ "^.+$": {
+ "type": "string"
+ }
+ },
+ "examples": [
+ {
+ "AUTHOR": ".*@mycompany\\.com"
+ }
+ ]
+ }
+ }
+ },
+ "template": {
+ "description": "Template to put on top of every file.",
+ "type": "string",
+ "examples": [
+ "{{ MY COMPANY }}\nSPDX-License-Identifier: Apache-2.0\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at:\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License."
+ ]
+ },
+ "template-path": {
+ "description": "Path to the file containing the template source.",
+ "type": "string",
+ "examples": ["my_header_template.txt"]
+ }
+ },
+ "oneOf": [
+ { "required": ["template"] },
+ { "required": ["template-path"] }
+ ]
+ },
+ "goimportsSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "local-prefixes": {
+ "description": "Put imports beginning with prefix after 3rd-party packages. It is a list of prefixes.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "gomoddirectivesSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "replace-local": {
+ "description": "Allow local `replace` directives.",
+ "type": "boolean",
+ "default": true
+ },
+ "replace-allow-list": {
+ "description": "List of allowed `replace` directives.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "retract-allow-no-explanation": {
+ "description": "Allow to not explain why the version has been retracted in the `retract` directives.",
+ "type": "boolean",
+ "default": false
+ },
+ "exclude-forbidden": {
+ "description": "Forbid the use of the `exclude` directives.",
+ "type": "boolean",
+ "default": false
+ },
+ "ignore-forbidden": {
+ "description": "Forbid the use of the `ignore` directives. (>= go1.25)",
+ "type": "boolean",
+ "default": false
+ },
+ "toolchain-forbidden": {
+ "description": "Forbid the use of the `toolchain` directive.",
+ "type": "boolean",
+ "default": false
+ },
+ "toolchain-pattern": {
+ "description": "Defines a pattern to validate `toolchain` directive.",
+ "type": "string"
+ },
+ "tool-forbidden": {
+ "description": "Forbid the use of the `tool` directives.",
+ "type": "boolean",
+ "default": false
+ },
+ "go-debug-forbidden": {
+ "description": "Forbid the use of the `godebug` directive.",
+ "type": "boolean",
+ "default": false
+ },
+ "go-version-pattern": {
+ "description": "Defines a pattern to validate `go` minimum version directive.",
+ "type": "string",
+ "default": ""
+ },
+ "check-module-path": {
+ "description": "Check the validity of the module path.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "gomodguardSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "allowed": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "modules": {
+ "description": "List of allowed modules.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["gopkg.in/yaml.v2"]
+ }
+ },
+ "domains": {
+ "description": "List of allowed module domains.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["golang.org"]
+ }
+ }
+ }
+ },
+ "blocked": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "modules": {
+ "description": "List of blocked modules.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "recommendations": {
+ "description": "Recommended modules that should be used instead.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "reason": {
+ "description": "Reason why the recommended module should be used.",
+ "type": "string"
+ }
+ }
+ }
+ },
+ "additionalProperties": false
+ }
+ },
+ "versions": {
+ "description": "List of blocked module version constraints.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "patternProperties": {
+ "^.*$": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "version": {
+ "description": "Version constraint.",
+ "type": "string"
+ },
+ "reason": {
+ "description": "Reason why the version constraint exists.",
+ "type": "string"
+ }
+ },
+ "required": ["reason"]
+ }
+ }
+ }
+ },
+ "local-replace-directives": {
+ "description": "Raise lint issues if loading local path with replace directive",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ }
+ }
+ },
+ "gosecSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "includes": {
+ "type": "array",
+ "description": "To select a subset of rules to run",
+ "examples": [["G401"]],
+ "items": {
+ "$ref": "#/definitions/gosec-rules"
+ }
+ },
+ "excludes": {
+ "type": "array",
+ "description": "To specify a set of rules to explicitly exclude",
+ "examples": [["G401"]],
+ "items": {
+ "$ref": "#/definitions/gosec-rules"
+ }
+ },
+ "severity": {
+ "description": "Filter out the issues with a lower severity than the given value",
+ "type": "string",
+ "enum": ["low", "medium", "high"],
+ "default": "low"
+ },
+ "confidence": {
+ "description": "Filter out the issues with a lower confidence than the given value",
+ "type": "string",
+ "enum": ["low", "medium", "high"],
+ "default": "low"
+ },
+ "config": {
+ "description": "To specify the configuration of rules",
+ "type": "object"
+ },
+ "concurrency": {
+ "description": "Concurrency value",
+ "type": "integer"
+ }
+ }
+ },
+ "gosmopolitanSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "allow-time-local": {
+ "description": "Allow and ignore `time.Local` usages.",
+ "type": "boolean",
+ "default": false
+ },
+ "escape-hatches": {
+ "description": "List of fully qualified names in the `full/pkg/path.name` form, to act as \"i18n escape hatches\".",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "watch-for-scripts": {
+ "description": "List of Unicode scripts to watch for any usage in string literals.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "govetSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "settings": {
+ "description": "Settings per analyzer. Map of analyzer name to specific settings.\nRun `go tool vet help` to find out more.",
+ "type": "object",
+ "propertyNames": {
+ "$ref": "#/definitions/govet-analyzers"
+ },
+ "patternProperties": {
+ "^.*$": {
+ "description": "Run `go tool vet help ` to see all settings.",
+ "type": "object"
+ }
+ }
+ },
+ "enable": {
+ "description": "Enable analyzers by name.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/govet-analyzers"
+ }
+ },
+ "disable": {
+ "description": "Disable analyzers by name.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/govet-analyzers"
+ }
+ },
+ "enable-all": {
+ "description": "Enable all analyzers.",
+ "type": "boolean",
+ "default": false
+ },
+ "disable-all": {
+ "description": "Disable all analyzers.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "grouperSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "const-require-single-const": {
+ "type": "boolean",
+ "default": false
+ },
+ "const-require-grouping": {
+ "type": "boolean",
+ "default": false
+ },
+ "import-require-single-import": {
+ "type": "boolean",
+ "default": false
+ },
+ "import-require-grouping": {
+ "type": "boolean",
+ "default": false
+ },
+ "type-require-single-type": {
+ "type": "boolean",
+ "default": false
+ },
+ "type-require-grouping": {
+ "type": "boolean",
+ "default": false
+ },
+ "var-require-single-var": {
+ "type": "boolean",
+ "default": false
+ },
+ "var-require-grouping": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "ifaceSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "enable": {
+ "description": "Enable analyzers by name.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/iface-analyzers"
+ }
+ },
+ "settings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "unused": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "exclude": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "importasSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "no-unaliased": {
+ "description": "Do not allow unaliased imports of aliased packages.",
+ "type": "boolean",
+ "default": false
+ },
+ "no-extra-aliases": {
+ "description": "Do not allow non-required aliases.",
+ "type": "boolean",
+ "default": false
+ },
+ "alias": {
+ "description": "List of aliases",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "pkg": {
+ "description": "Package path e.g. knative.dev/serving/pkg/apis/autoscaling/v1alpha1",
+ "type": "string"
+ },
+ "alias": {
+ "description": "Package alias e.g. autoscalingv1alpha1",
+ "type": "string"
+ }
+ },
+ "required": ["pkg", "alias"]
+ }
+ }
+ }
+ },
+ "inamedparamSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skip-single-param": {
+ "description": "Skips check for interface methods with only a single parameter.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "ineffassignSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-escaping-errors": {
+ "description": "Check escaping variables of type error, may cause false positives.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "iotamixingSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "report-individual": {
+ "description": "Whether to report individual consts rather than just the const block.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "ireturnSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "description": "Use either `reject` or `allow` properties for interfaces matching.",
+ "properties": {
+ "allow": {
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "enum": ["anon", "error", "empty", "stdlib"]
+ }
+ ]
+ }
+ },
+ "reject": {
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "enum": ["anon", "error", "empty", "stdlib"]
+ }
+ ]
+ }
+ }
+ },
+ "anyOf": [
+ {
+ "not": {
+ "properties": {
+ "allow": {
+ "const": "reject"
+ }
+ }
+ },
+ "required": ["allow"]
+ },
+ {
+ "required": ["reject"]
+ }
+ ]
+ },
+ "lllSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "tab-width": {
+ "description": "Width of \"\\t\" in spaces.",
+ "type": "integer",
+ "minimum": 0,
+ "default": 1
+ },
+ "line-length": {
+ "description": "Maximum allowed line length, lines longer will be reported.",
+ "type": "integer",
+ "minimum": 1,
+ "default": 120
+ }
+ }
+ },
+ "maintidxSettings": {
+ "description": "Maintainability index https://docs.microsoft.com/en-us/visualstudio/code-quality/code-metrics-maintainability-index-range-and-meaning?view=vs-2022",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "under": {
+ "description": "Minimum accatpable maintainability index level (see https://docs.microsoft.com/en-us/visualstudio/code-quality/code-metrics-maintainability-index-range-and-meaning?view=vs-2022)",
+ "type": "number",
+ "default": 20
+ }
+ }
+ },
+ "makezeroSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "always": {
+ "description": "Allow only slices initialized with a length of zero.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "loggercheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "kitlog": {
+ "description": "Allow check for the github.com/go-kit/log library.",
+ "type": "boolean",
+ "default": true
+ },
+ "klog": {
+ "description": "Allow check for the k8s.io/klog/v2 library.",
+ "type": "boolean",
+ "default": true
+ },
+ "logr": {
+ "description": "Allow check for the github.com/go-logr/logr library.",
+ "type": "boolean",
+ "default": true
+ },
+ "slog": {
+ "description": "Allow check for the log/slog library.",
+ "type": "boolean",
+ "default": true
+ },
+ "zap": {
+ "description": "Allow check for the \"sugar logger\" from go.uber.org/zap library.",
+ "type": "boolean",
+ "default": true
+ },
+ "require-string-key": {
+ "description": "Require all logging keys to be inlined constant strings.",
+ "type": "boolean",
+ "default": false
+ },
+ "no-printf-like": {
+ "description": "Require printf-like format specifier (%s, %d for example) not present.",
+ "type": "boolean",
+ "default": false
+ },
+ "rules": {
+ "description": "List of custom rules to check against, where each rule is a single logger pattern, useful for wrapped loggers.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "misspellSettings": {
+ "description": "Correct spellings using locale preferences for US or UK. Default is to use a neutral variety of English.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "locale": {
+ "enum": ["US", "UK"]
+ },
+ "ignore-rules": {
+ "description": "List of rules to ignore.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "mode": {
+ "description": "Mode of the analysis.",
+ "enum": ["restricted", "", "default"],
+ "default": ""
+ },
+ "extra-words": {
+ "description": "Extra word corrections.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "correction": {
+ "type": "string"
+ },
+ "typo": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "musttagSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "functions": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "tag": {
+ "type": "string"
+ },
+ "arg-pos": {
+ "type": "integer"
+ }
+ }
+ }
+ }
+ }
+ },
+ "nakedretSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-func-lines": {
+ "description": "Report if a function has more lines of code than this value and it has naked returns.",
+ "type": "integer",
+ "minimum": 0,
+ "default": 30
+ }
+ }
+ },
+ "nestifSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "min-complexity": {
+ "description": "Minimum complexity of \"if\" statements to report.",
+ "type": "integer",
+ "default": 5
+ }
+ }
+ },
+ "nilnilSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "only-two": {
+ "type": "boolean",
+ "description": "To check functions with only two return values.",
+ "default": true
+ },
+ "detect-opposite": {
+ "type": "boolean",
+ "description": "In addition, detect opposite situation (simultaneous return of non-nil error and valid value).",
+ "default": false
+ },
+ "checked-types": {
+ "type": "array",
+ "description": "List of return types to check.",
+ "items": {
+ "enum": ["chan", "func", "iface", "map", "ptr", "uintptr", "unsafeptr"]
+ },
+ "default": ["chan", "func", "iface", "map", "ptr", "uintptr", "unsafeptr"]
+ }
+ }
+ },
+ "nlreturnSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "block-size": {
+ "description": "set block size that is still ok",
+ "type": "number",
+ "default": 0,
+ "minimum": 0
+ }
+ }
+ },
+ "mndSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignored-files": {
+ "description": "List of file patterns to exclude from analysis.",
+ "examples": [["magic1_.*.go"]],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignored-functions": {
+ "description": "Comma-separated list of function patterns to exclude from the analysis.",
+ "examples": [["math.*", "http.StatusText", "make"]],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignored-numbers": {
+ "description": "List of numbers to exclude from analysis.",
+ "examples": [["1000", "1234_567_890", "3.14159264"]],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "checks": {
+ "description": "The list of enabled checks, see https://github.com/tommy-muehle/go-mnd/#checks for description.",
+ "type": "array",
+ "items": {
+ "enum": [
+ "argument",
+ "case",
+ "condition",
+ "operation",
+ "return",
+ "assign"
+ ]
+ }
+ }
+ }
+ },
+ "modernizeSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "disable": {
+ "description": "List of analyzers to disable.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/modernize-analyzers"
+ }
+ }
+ }
+ },
+ "nolintlintSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "allow-unused": {
+ "description": "Enable to ensure that nolint directives are all used.",
+ "type": "boolean",
+ "default": true
+ },
+ "allow-no-explanation": {
+ "description": "Exclude these linters from requiring an explanation.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linter-names"
+ },
+ "default": []
+ },
+ "require-explanation": {
+ "description": "Enable to require an explanation of nonzero length after each nolint directive.",
+ "type": "boolean",
+ "default": false
+ },
+ "require-specific": {
+ "description": "Enable to require nolint directives to mention the specific linter being suppressed.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "reassignSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "patterns": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "recvcheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "disable-builtin": {
+ "description": "Disables the built-in method exclusions.",
+ "type": "boolean",
+ "default": true
+ },
+ "exclusions": {
+ "description": "User-defined method exclusions.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "nonamedreturnsSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "report-error-in-defer": {
+ "description": "Report named error if it is assigned inside defer.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "paralleltestSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignore-missing": {
+ "description": "Ignore missing calls to `t.Parallel()` and only report incorrect uses of it.",
+ "type": "boolean",
+ "default": false
+ },
+ "ignore-missing-subtests": {
+ "description": "Ignore missing calls to `t.Parallel()` in subtests. Top-level tests are still required to have `t.Parallel`, but subtests are allowed to skip it.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "perfsprintSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "integer-format": {
+ "description": "Enable/disable optimization of integer formatting.",
+ "type": "boolean",
+ "default": true
+ },
+ "int-conversion": {
+ "description": "Optimizes even if it requires an int or uint type cast.",
+ "type": "boolean",
+ "default": true
+ },
+ "error-format": {
+ "description": "Enable/disable optimization of error formatting.",
+ "type": "boolean",
+ "default": true
+ },
+ "err-error": {
+ "description": "Optimizes into `err.Error()` even if it is only equivalent for non-nil errors.",
+ "type": "boolean",
+ "default": false
+ },
+ "errorf": {
+ "description": "Optimizes `fmt.Errorf`.",
+ "type": "boolean",
+ "default": true
+ },
+ "string-format": {
+ "description": "Enable/disable optimization of string formatting.",
+ "type": "boolean",
+ "default": true
+ },
+ "sprintf1": {
+ "description": "Optimizes `fmt.Sprintf` with only one argument.",
+ "type": "boolean",
+ "default": true
+ },
+ "strconcat": {
+ "description": "Optimizes into strings concatenation.",
+ "type": "boolean",
+ "default": true
+ },
+ "bool-format": {
+ "description": "Enable/disable optimization of bool formatting.",
+ "type": "boolean",
+ "default": true
+ },
+ "hex-format": {
+ "description": "Enable/disable optimization of hex formatting.",
+ "type": "boolean",
+ "default": true
+ },
+ "concat-loop": {
+ "description": "Enable/disable optimization of concat loop.",
+ "type": "boolean",
+ "default": true
+ },
+ "loop-other-ops": {
+ "description": "Optimization of `concat-loop` even with other operations.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "preallocSettings": {
+ "description": "We do not recommend using this linter before doing performance profiling.\nFor most programs usage of `prealloc` will be premature optimization.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "simple": {
+ "description": "Report preallocation suggestions only on simple loops that have no returns/breaks/continues/gotos in them.",
+ "type": "boolean",
+ "default": true
+ },
+ "range-loops": {
+ "description": "Report preallocation suggestions on range loops.",
+ "type": "boolean",
+ "default": true
+ },
+ "for-loops": {
+ "description": "Report preallocation suggestions on for loops.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "predeclaredSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignore": {
+ "description": "List of predeclared identifiers to not report on.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "qualified-name": {
+ "description": "Include method names and field names in checks.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "promlinterSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "strict": {},
+ "disabled-linters": {
+ "type": "array",
+ "items": {
+ "enum": [
+ "Help",
+ "MetricUnits",
+ "Counter",
+ "HistogramSummaryReserved",
+ "MetricTypeInName",
+ "ReservedChars",
+ "CamelCase",
+ "UnitAbbreviations"
+ ]
+ }
+ }
+ }
+ },
+ "protogetterSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skip-generated-by": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["protoc-gen-go-my-own-generator"]
+ }
+ },
+ "skip-files": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["*.pb.go"]
+ }
+ },
+ "skip-any-generated": {
+ "description": "Skip any generated files from the checking.",
+ "type": "boolean",
+ "default": false
+ },
+ "replace-first-arg-in-append": {
+ "description": "Skip first argument of append function.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "reviveSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "examples": [
+ {
+ "ignore-generated-header": true,
+ "severity": "warning",
+ "rules": [
+ {
+ "name": "indent-error-flow",
+ "severity": "warning"
+ },
+ {
+ "name": "add-constant",
+ "severity": "warning",
+ "arguments": [
+ {
+ "maxLitCount": "3",
+ "allowStrs": "\"\"",
+ "allowInts": "0,1,2",
+ "allowFloats": "0.0,0.,1.0,1.,2.0,2."
+ }
+ ]
+ }
+ ]
+ }
+ ],
+ "properties": {
+ "max-open-files": {
+ "type": "integer"
+ },
+ "confidence": {
+ "type": "number"
+ },
+ "severity": {
+ "type": "string",
+ "enum": ["warning", "error"]
+ },
+ "enable-all-rules": {
+ "type": "boolean",
+ "default": false
+ },
+ "enable-default-rules": {
+ "type": "boolean",
+ "default": false
+ },
+ "directives": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "name": {
+ "type": "string",
+ "enum": ["specify-disable-reason"]
+ },
+ "severity": {
+ "type": "string",
+ "enum": ["warning", "error"]
+ },
+ "exclude": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "arguments": {
+ "type": "array"
+ }
+ }
+ }
+ },
+ "rules": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["name"],
+ "properties": {
+ "name": {
+ "$ref": "#/definitions/revive-rules",
+ "title": "The rule name"
+ },
+ "disabled": {
+ "type": "boolean"
+ },
+ "severity": {
+ "type": "string",
+ "enum": ["warning", "error"]
+ },
+ "exclude": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "arguments": {
+ "type": "array"
+ }
+ }
+ }
+ }
+ }
+ },
+ "rowserrcheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "packages": {
+ "type": "array",
+ "items": {
+ "description": "",
+ "type": "string",
+ "examples": ["github.com/jmoiron/sqlx"]
+ }
+ }
+ }
+ },
+ "sloglintSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "kv-only": {
+ "description": "Enforce using key-value pairs only (incompatible with attr-only).",
+ "type": "boolean",
+ "default": false
+ },
+ "no-global": {
+ "description": "Enforce not using global loggers.",
+ "enum": ["", "all", "default"],
+ "default": ""
+ },
+ "no-mixed-args": {
+ "description": "Enforce not mixing key-value pairs and attributes.",
+ "type": "boolean",
+ "default": true
+ },
+ "context": {
+ "description": "Enforce using methods that accept a context.",
+ "enum": ["", "all", "scope"],
+ "default": ""
+ },
+ "static-msg": {
+ "description": "Enforce using static values for log messages.",
+ "type": "boolean",
+ "default": false
+ },
+ "msg-style": {
+ "description": "Enforce message style.",
+ "enum": ["", "lowercased", "capitalized"],
+ "default": ""
+ },
+ "key-naming-case": {
+ "description": "Enforce a single key naming convention.",
+ "enum": ["snake", "kebab", "camel", "pascal"]
+ },
+ "attr-only": {
+ "description": "Enforce using attributes only (incompatible with kv-only).",
+ "type": "boolean",
+ "default": false
+ },
+ "no-raw-keys": {
+ "description": "Enforce using constants instead of raw keys.",
+ "type": "boolean",
+ "default": false
+ },
+ "forbidden-keys": {
+ "description": "Enforce not using specific keys.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "args-on-sep-lines": {
+ "description": "Enforce putting arguments on separate lines.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "spancheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "checks": {
+ "description": "Checks to enable.",
+ "type": "array",
+ "items": {
+ "enum": ["end", "record-error", "set-status"]
+ }
+ },
+ "ignore-check-signatures": {
+ "description": "A list of regexes for function signatures that silence `record-error` and `set-status` reports if found in the call path to a returned error.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "extra-start-span-signatures": {
+ "description": "A list of regexes for additional function signatures that create spans.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "staticcheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "checks": {
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "$ref": "#/definitions/staticcheck-checks"
+ },
+ {
+ "type": "string"
+ }
+ ]
+ }
+ },
+ "dot-import-whitelist": {
+ "description": "By default, ST1001 forbids all uses of dot imports in non-test packages. This setting allows setting a whitelist of import paths that can be dot-imported anywhere.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "http-status-code-whitelist": {
+ "description": "ST1013 recommends using constants from the net/http package instead of hard-coding numeric HTTP status codes. This setting specifies a list of numeric status codes that this check does not complain about.",
+ "default": ["200", "400", "404", "500"],
+ "type": "array",
+ "items": {
+ "enum": [
+ "100",
+ "101",
+ "102",
+ "103",
+ "200",
+ "201",
+ "202",
+ "203",
+ "204",
+ "205",
+ "206",
+ "207",
+ "208",
+ "226",
+ "300",
+ "301",
+ "302",
+ "303",
+ "304",
+ "305",
+ "306",
+ "307",
+ "308",
+ "400",
+ "401",
+ "402",
+ "403",
+ "404",
+ "405",
+ "406",
+ "407",
+ "408",
+ "409",
+ "410",
+ "411",
+ "412",
+ "413",
+ "414",
+ "415",
+ "416",
+ "417",
+ "418",
+ "421",
+ "422",
+ "423",
+ "424",
+ "425",
+ "426",
+ "428",
+ "429",
+ "431",
+ "451",
+ "500",
+ "501",
+ "502",
+ "503",
+ "504",
+ "505",
+ "506",
+ "507",
+ "508",
+ "510",
+ "511"
+ ]
+ }
+ },
+ "initialisms": {
+ "description": "ST1003 check, among other things, for the correct capitalization of initialisms. The set of known initialisms can be configured with this option.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "default": [
+ "ACL",
+ "API",
+ "ASCII",
+ "CPU",
+ "CSS",
+ "DNS",
+ "EOF",
+ "GUID",
+ "HTML",
+ "HTTP",
+ "HTTPS",
+ "ID",
+ "IP",
+ "JSON",
+ "QPS",
+ "RAM",
+ "RPC",
+ "SLA",
+ "SMTP",
+ "SQL",
+ "SSH",
+ "TCP",
+ "TLS",
+ "TTL",
+ "UDP",
+ "UI",
+ "GID",
+ "UID",
+ "UUID",
+ "URI",
+ "URL",
+ "UTF8",
+ "VM",
+ "XML",
+ "XMPP",
+ "XSRF",
+ "XSS",
+ "SIP",
+ "RTP",
+ "AMQP",
+ "DB",
+ "TS"
+ ]
+ }
+ }
+ }
+ },
+ "tagalignSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "align": {
+ "description": "Align and sort can be used together or separately.",
+ "type": "boolean",
+ "default": true
+ },
+ "sort": {
+ "description": "Whether enable tags sort.",
+ "type": "boolean",
+ "default": true
+ },
+ "order": {
+ "description": "Specify the order of tags, the other tags will be sorted by name.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "default": [],
+ "examples": [
+ [
+ "json",
+ "yaml",
+ "yml",
+ "toml",
+ "mapstructure",
+ "binding",
+ "validate"
+ ]
+ ]
+ },
+ "strict": {
+ "description": "Whether enable strict style.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "tagliatelleSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "case": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "use-field-name": {
+ "description": "Use the struct field name to check the name of the struct tag.",
+ "type": "boolean",
+ "default": false
+ },
+ "ignored-fields": {
+ "description": "The field names to ignore.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["example"]
+ }
+ },
+ "rules": {
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "$ref": "#/definitions/tagliatelle-cases"
+ }
+ }
+ },
+ "extended-rules": {
+ "description": "Defines the association between tag name and case.",
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["case"],
+ "properties": {
+ "case": {
+ "$ref": "#/definitions/tagliatelle-cases"
+ },
+ "extra-initialisms": {
+ "type": "boolean",
+ "default": false
+ },
+ "initialism-overrides": {
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "overrides": {
+ "description": "Overrides the default/root configuration.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["pkg"],
+ "properties": {
+ "pkg": {
+ "description": "A package path.",
+ "type": "string"
+ },
+ "use-field-name": {
+ "description": "Use the struct field name to check the name of the struct tag.",
+ "type": "boolean",
+ "default": false
+ },
+ "ignored-fields": {
+ "description": "The field names to ignore.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["example"]
+ }
+ },
+ "ignore": {
+ "description": "Ignore the package (takes precedence over all other configurations).",
+ "type": "boolean",
+ "default": false
+ },
+ "rules": {
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "$ref": "#/definitions/tagliatelle-cases"
+ }
+ }
+ },
+ "extended-rules": {
+ "description": "Defines the association between tag name and case.",
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["case"],
+ "properties": {
+ "case": {
+ "$ref": "#/definitions/tagliatelle-cases"
+ },
+ "extra-initialisms": {
+ "type": "boolean",
+ "default": false
+ },
+ "initialism-overrides": {
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "testifylintSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "enable-all": {
+ "description": "Enable all checkers.",
+ "type": "boolean",
+ "default": false
+ },
+ "disable-all": {
+ "description": "Disable all checkers.",
+ "type": "boolean",
+ "default": false
+ },
+ "enable": {
+ "description": "Enable specific checkers.",
+ "type": "array",
+ "items": {
+ "enum": [
+ "blank-import",
+ "bool-compare",
+ "compares",
+ "contains",
+ "empty",
+ "encoded-compare",
+ "equal-values",
+ "error-is-as",
+ "error-nil",
+ "expected-actual",
+ "float-compare",
+ "formatter",
+ "go-require",
+ "len",
+ "negative-positive",
+ "nil-compare",
+ "regexp",
+ "require-error",
+ "suite-broken-parallel",
+ "suite-dont-use-pkg",
+ "suite-extra-assert-call",
+ "suite-method-signature",
+ "suite-subtest-run",
+ "suite-thelper",
+ "useless-assert"
+ ]
+ },
+ "default": [
+ "blank-import",
+ "bool-compare",
+ "compares",
+ "contains",
+ "empty",
+ "encoded-compare",
+ "equal-values",
+ "error-is-as",
+ "error-nil",
+ "expected-actual",
+ "float-compare",
+ "formatter",
+ "go-require",
+ "len",
+ "negative-positive",
+ "nil-compare",
+ "regexp",
+ "require-error",
+ "suite-broken-parallel",
+ "suite-dont-use-pkg",
+ "suite-extra-assert-call",
+ "suite-method-signature",
+ "suite-subtest-run",
+ "useless-assert"
+ ]
+ },
+ "disable": {
+ "description": "Disable specific checkers.",
+ "type": "array",
+ "items": {
+ "enum": [
+ "blank-import",
+ "bool-compare",
+ "compares",
+ "contains",
+ "empty",
+ "encoded-compare",
+ "equal-values",
+ "error-is-as",
+ "error-nil",
+ "expected-actual",
+ "float-compare",
+ "formatter",
+ "go-require",
+ "len",
+ "negative-positive",
+ "nil-compare",
+ "regexp",
+ "require-error",
+ "suite-broken-parallel",
+ "suite-dont-use-pkg",
+ "suite-extra-assert-call",
+ "suite-method-signature",
+ "suite-subtest-run",
+ "suite-thelper",
+ "useless-assert"
+ ],
+ "default": [
+ "suite-thelper"
+ ]
+ }
+ },
+ "bool-compare": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignore-custom-types": {
+ "description": "To ignore user defined types (over builtin bool).",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "expected-actual": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "pattern": {
+ "description": "Regexp for expected variable name.",
+ "type": "string",
+ "default": "(^(exp(ected)?|want(ed)?)([A-Z]\\w*)?$)|(^(\\w*[a-z])?(Exp(ected)?|Want(ed)?)$)"
+ }
+ }
+ },
+ "formatter": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-format-string": {
+ "description": "To enable go vet's printf checks.",
+ "type": "boolean",
+ "default": true
+ },
+ "require-f-funcs": {
+ "description": "To require f-assertions (e.g. assert.Equalf) if format string is used, even if there are no variable-length variables.",
+ "type": "boolean",
+ "default": false
+ },
+ "require-string-msg": {
+ "description": "To require that the first element of msgAndArgs (msg) has a string type.",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "go-require": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignore-http-handlers": {
+ "description": "To ignore HTTP handlers (like http.HandlerFunc).",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "require-error": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "fn-pattern": {
+ "description": "Regexp for assertions to analyze. If defined, then only matched error assertions will be reported.",
+ "type": "string",
+ "default": ""
+ }
+ }
+ },
+ "suite-extra-assert-call": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "mode": {
+ "description": "To require or remove extra Assert() call?",
+ "type": "string",
+ "enum": ["remove", "require"],
+ "default": "remove"
+ }
+ }
+ }
+ }
+ },
+ "testpackageSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skip-regexp": {
+ "description": "Files with names matching this regular expression are skipped.",
+ "type": "string",
+ "examples": ["(export|internal)_test\\.go"]
+ },
+ "allow-packages": {
+ "description": "List of packages that don't end with _test that tests are allowed to be in.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["example"]
+ }
+ }
+ }
+ },
+ "thelperSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "test": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "begin": {
+ "description": "Check if `t.Helper()` begins helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "first": {
+ "description": "Check if *testing.T is first param of helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "name": {
+ "description": "Check if *testing.T param has t name.",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ },
+ "benchmark": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "begin": {
+ "description": "Check if `b.Helper()` begins helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "first": {
+ "description": "Check if *testing.B is first param of helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "name": {
+ "description": "Check if *testing.B param has b name.",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ },
+ "tb": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "begin": {
+ "description": "Check if `tb.Helper()` begins helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "first": {
+ "description": "Check if *testing.TB is first param of helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "name": {
+ "description": "Check if *testing.TB param has tb name.",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ },
+ "fuzz": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "begin": {
+ "description": "Check if `f.Helper()` begins helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "first": {
+ "description": "Check if *testing.F is first param of helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "name": {
+ "description": "Check if *testing.F param has f name.",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ }
+ }
+ },
+ "usestdlibvarsSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "http-method": {
+ "description": "Suggest the use of http.MethodXX.",
+ "type": "boolean",
+ "default": true
+ },
+ "http-status-code": {
+ "description": "Suggest the use of http.StatusXX.",
+ "type": "boolean",
+ "default": true
+ },
+ "time-weekday": {
+ "description": "Suggest the use of time.Weekday.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "time-month": {
+ "description": "Suggest the use of time.Month.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "time-layout": {
+ "description": "Suggest the use of time.Layout.",
+ "type": "boolean",
+ "default": false
+ },
+ "time-date-month": {
+ "description": "Suggest the use of time.Month in time.Date.",
+ "type": "boolean",
+ "default": false
+ },
+ "crypto-hash": {
+ "description": "Suggest the use of crypto.Hash.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "default-rpc-path": {
+ "description": "Suggest the use of rpc.DefaultXXPath.",
+ "type": "boolean",
+ "default": false
+ },
+ "sql-isolation-level": {
+ "description": "Suggest the use of sql.LevelXX.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "tls-signature-scheme": {
+ "description": "Suggest the use of tls.SignatureScheme.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "constant-kind": {
+ "description": "Suggest the use of constant.Kind.String().",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "usetestingSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "context-background": {
+ "type": "boolean",
+ "default": false
+ },
+ "context-todo": {
+ "type": "boolean",
+ "default": false
+ },
+ "os-chdir": {
+ "type": "boolean",
+ "default": true
+ },
+ "os-mkdir-temp": {
+ "type": "boolean",
+ "default": true
+ },
+ "os-setenv": {
+ "type": "boolean",
+ "default": true
+ },
+ "os-create-temp": {
+ "type": "boolean",
+ "default": true
+ },
+ "os-temp-dir": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "unconvertSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "fast-math": {
+ "type": "boolean",
+ "default": false
+ },
+ "safe": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "unparamSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-exported": {
+ "description": "Inspect exported functions. Set to true if no external program/library imports your code.\n\nWARNING: if you enable this setting, unparam will report a lot of false-positives in text editors:\nif it's called for subdir of a project it can't find external interfaces. All text editor integrations\nwith golangci-lint call it on a directory with the changed file.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "unqueryvetSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-sql-builders": {
+ "description": "Enable SQL builder checking.",
+ "type": "boolean",
+ "default": true
+ },
+ "check-aliased-wildcard": {
+ "description": "Enable aliased wildcard detection like SELECT t.*.",
+ "type": "boolean",
+ "default": true
+ },
+ "check-string-concat": {
+ "description": "Enable string concatenation analysis.",
+ "type": "boolean",
+ "default": true
+ },
+ "check-format-strings": {
+ "description": "Enable format string analysis like fmt.Sprintf.",
+ "type": "boolean",
+ "default": true
+ },
+ "check-string-builder": {
+ "description": "Enable strings.Builder analysis.",
+ "type": "boolean",
+ "default": true
+ },
+ "check-subqueries": {
+ "description": "Enable subquery analysis.",
+ "type": "boolean",
+ "default": true
+ },
+ "check-n1": {
+ "type": "boolean",
+ "default": false
+ },
+ "check-sql-injection": {
+ "type": "boolean",
+ "default": false
+ },
+ "check-tx-leaks": {
+ "type": "boolean",
+ "default": false
+ },
+ "allowed-patterns": {
+ "description": "Regex patterns for acceptable SELECT * usage.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "allow": {
+ "description": "Allow is a list of SQL patterns to allow (whitelist).",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignored-functions": {
+ "description": "Functions to ignore.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "sql-builders": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "squirrel": {
+ "type": "boolean",
+ "default": true
+ },
+ "gorm": {
+ "type": "boolean",
+ "default": true
+ },
+ "sqlx": {
+ "type": "boolean",
+ "default": true
+ },
+ "ent": {
+ "type": "boolean",
+ "default": true
+ },
+ "pgx": {
+ "type": "boolean",
+ "default": true
+ },
+ "bun": {
+ "type": "boolean",
+ "default": true
+ },
+ "sqlboiler": {
+ "type": "boolean",
+ "default": true
+ },
+ "jet": {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "custom-rules": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "id": {
+ "type": "string"
+ },
+ "pattern": {
+ "type": "string"
+ },
+ "patterns": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "when": {
+ "type": "string"
+ },
+ "message": {
+ "type": "string"
+ },
+ "action": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "unusedSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "field-writes-are-uses": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ },
+ "post-statements-are-reads": {
+ "description": "",
+ "type": "boolean",
+ "default": false
+ },
+ "exported-fields-are-used": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ },
+ "parameters-are-used": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ },
+ "local-variables-are-used": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ },
+ "generated-is-used": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "varnamelenSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-distance": {
+ "description": "Variables used in at most this N-many lines will be ignored.",
+ "type": "integer",
+ "default": 5
+ },
+ "min-name-length": {
+ "description": "The minimum length of a variable's name that is considered `long`.",
+ "type": "integer",
+ "default": 3
+ },
+ "check-receiver": {
+ "description": "Check method receiver names.",
+ "default": false,
+ "type": "boolean"
+ },
+ "check-return": {
+ "description": "Check named return values.",
+ "default": false,
+ "type": "boolean"
+ },
+ "check-type-param": {
+ "description": "Check type parameters.",
+ "default": false,
+ "type": "boolean"
+ },
+ "ignore-type-assert-ok": {
+ "description": "Ignore `ok` variables that hold the bool return value of a type assertion",
+ "default": false,
+ "type": "boolean"
+ },
+ "ignore-map-index-ok": {
+ "description": "Ignore `ok` variables that hold the bool return value of a map index.",
+ "default": false,
+ "type": "boolean"
+ },
+ "ignore-chan-recv-ok": {
+ "description": "Ignore `ok` variables that hold the bool return value of a channel receive.",
+ "default": false,
+ "type": "boolean"
+ },
+ "ignore-names": {
+ "description": "Optional list of variable names that should be ignored completely.",
+ "default": [[]],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignore-decls": {
+ "description": "Optional list of variable declarations that should be ignored completely.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "examples": [
+ ["c echo.Context", "t testing.T", "f *foo.Bar", "const C"]
+ ]
+ }
+ }
+ },
+ "whitespaceSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "multi-if": {
+ "description": "Enforces newlines (or comments) after every multi-line if statement",
+ "type": "boolean",
+ "default": false
+ },
+ "multi-func": {
+ "description": "Enforces newlines (or comments) after every multi-line function signature",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "wrapcheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "extra-ignore-sigs": {
+ "description": "An array of strings specifying additional substrings of signatures to ignore.",
+ "default": [
+ ".CustomError(",
+ ".SpecificWrap("
+ ],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignore-sigs": {
+ "description": "An array of strings which specify substrings of signatures to ignore.",
+ "default": [
+ ".Errorf(",
+ "errors.New(",
+ "errors.Unwrap(",
+ ".Wrap(",
+ ".Wrapf(",
+ ".WithMessage(",
+ ".WithMessagef(",
+ ".WithStack("
+ ],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignore-sig-regexps": {
+ "description": "An array of strings which specify regular expressions of signatures to ignore.",
+ "default": [""],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignore-package-globs": {
+ "description": "An array of glob patterns which, if any match the package of the function returning the error, will skip wrapcheck analysis for this error.",
+ "default": [""],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignore-interface-regexps": {
+ "description": "An array of glob patterns which, if matched to an underlying interface name, will ignore unwrapped errors returned from a function whose call is defined on the given interface.",
+ "default": [""],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "report-internal-errors": {
+ "description": "Determines whether wrapcheck should report errors returned from inside the package.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "wslSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "allow-assign-and-anything": {
+ "description": "Controls if you may cuddle assignments and anything without needing an empty line between them.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-assign-and-call": {
+ "description": "Allow calls and assignments to be cuddled as long as the lines have any matching variables, fields or types.",
+ "type": "boolean",
+ "default": true
+ },
+ "allow-cuddle-declarations": {
+ "description": "Allow declarations (var) to be cuddled.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-cuddle-with-calls": {
+ "description": "A list of call idents that everything can be cuddled with.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "allow-cuddle-with-rhs": {
+ "description": "AllowCuddleWithRHS is a list of right hand side variables that is allowed to be cuddled with anything.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "allow-cuddle-used-in-block": {
+ "description": "Allow cuddling with any block as long as the variable is used somewhere in the block",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-multiline-assign": {
+ "description": "Allow multiline assignments to be cuddled.",
+ "type": "boolean",
+ "default": true
+ },
+ "allow-separated-leading-comment": {
+ "description": "Allow leading comments to be separated with empty lines.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-trailing-comment": {
+ "description": "Allow trailing comments in ending of blocks.",
+ "type": "boolean",
+ "default": false
+ },
+ "error-variable-names": {
+ "description": "When force-err-cuddling is enabled this is a list of names used for error variables to check for in the conditional.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "force-case-trailing-whitespace": {
+ "description": "Force newlines in end of case at this limit (0 = never).",
+ "type": "integer",
+ "minimum": 0,
+ "default": 0
+ },
+ "force-err-cuddling": {
+ "description": "Causes an error when an If statement that checks an error variable doesn't cuddle with the assignment of that variable.",
+ "type": "boolean",
+ "default": false
+ },
+ "force-short-decl-cuddling": {
+ "description": "Causes an error if a short declaration (:=) cuddles with anything other than another short declaration.",
+ "type": "boolean",
+ "default": false
+ },
+ "strict-append": {
+ "description": "If true, append is only allowed to be cuddled if appending value is matching variables, fields or types on line above.",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "wslSettingsV5": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "allow-first-in-block": {
+ "type": "boolean",
+ "default": true
+ },
+ "allow-whole-block": {
+ "type": "boolean",
+ "default": false
+ },
+ "branch-max-lines": {
+ "type": "integer",
+ "default": 2
+ },
+ "case-max-lines": {
+ "type": "integer",
+ "default": 0
+ },
+ "default": {
+ "enum": ["all", "none", "default", ""],
+ "default": "default"
+ },
+ "enable": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/wsl-checks"
+ }
+ },
+ "disable": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/wsl-checks"
+ }
+ }
+ }
+ },
+ "copyloopvarSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-alias": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "customSettings": {
+ "description": "The custom section can be used to define linter plugins to be loaded at runtime. See README of golangci-lint for more information.\nEach custom linter should have a unique name.",
+ "type": "object",
+ "patternProperties": {
+ "^.*$": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "type": {
+ "description": "The plugin type.",
+ "enum": ["module", "goplugin"],
+ "default": "goplugin"
+ },
+ "path": {
+ "description": "The path to the plugin *.so. Can be absolute or local.",
+ "type": "string",
+ "examples": ["/path/to/example.so"]
+ },
+ "description": {
+ "description": "The description of the linter, for documentation purposes only.",
+ "type": "string"
+ },
+ "original-url": {
+ "description": "Intended to point to the repo location of the linter, for documentation purposes only.",
+ "type": "string"
+ },
+ "settings": {
+ "description": "Plugins settings/configuration. Only work with plugin based on `linterdb.PluginConstructor`.",
+ "type": "object"
+ }
+ },
+ "oneOf": [
+ {
+ "properties": {
+ "type": {"enum": ["module"] }
+ },
+ "required": ["type"]
+ },
+ {
+ "required": ["path"]
+ }
+ ]
+ }
+ }
+ }
+ }
+ }
+ },
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["version"],
+ "properties": {
+ "version": {
+ "type": "string",
+ "default": "2"
+ },
+ "run": {
+ "description": "Options for analysis running,",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "concurrency": {
+ "description": "Number of concurrent runners. Defaults to the number of available CPU cores.",
+ "type": "integer",
+ "minimum": 0,
+ "examples": [4]
+ },
+ "timeout": {
+ "description": "Timeout for the analysis.",
+ "type": "string",
+ "pattern": "^((\\d+h)?(\\d+m)?(\\d+(?:\\.\\d)?s)?|0)$",
+ "default": "1m",
+ "examples": ["30s", "5m", "5m30s"]
+ },
+ "issues-exit-code": {
+ "description": "Exit code when at least one issue was found.",
+ "type": "integer",
+ "default": 1
+ },
+ "tests": {
+ "description": "Enable inclusion of test files.",
+ "type": "boolean",
+ "default": true
+ },
+ "build-tags": {
+ "description": "List of build tags to pass to all linters.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "default": [],
+ "examples": [["mytag"]]
+ },
+ "modules-download-mode": {
+ "description": "Option to pass to \"go list -mod={option}\".\nSee \"go help modules\" for more information.",
+ "enum": ["mod", "readonly", "vendor"]
+ },
+ "enable-build-vcs": {
+ "type": "boolean",
+ "default": false
+ },
+ "allow-parallel-runners": {
+ "description": "Allow multiple parallel golangci-lint instances running. If disabled, golangci-lint acquires file lock on start.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-serial-runners": {
+ "description": "Allow multiple golangci-lint instances running, but serialize them around a lock.",
+ "type": "boolean",
+ "default": false
+ },
+ "go": {
+ "description": "Targeted Go version.",
+ "type": "string",
+ "default": "1.17"
+ },
+ "relative-path-mode": {
+ "description": "The mode used to evaluate relative paths.",
+ "type": "string",
+ "$ref": "#/definitions/relative-path-modes",
+ "default": "wd"
+ }
+ }
+ },
+ "output": {
+ "description": "Output configuration options.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "formats": {
+ "description": "Output formats to use.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "text": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "path": {
+ "$ref": "#/definitions/formats-path",
+ "default": "stdout"
+ },
+ "print-linter-name": {
+ "type": "boolean",
+ "default": true
+ },
+ "print-issued-lines": {
+ "type": "boolean",
+ "default": true
+ },
+ "colors": {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "json": {
+ "$ref": "#/definitions/simple-format"
+ },
+ "tab": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "path": {
+ "$ref": "#/definitions/formats-path",
+ "default": "stdout"
+ },
+ "print-linter-name": {
+ "type": "boolean",
+ "default": true
+ },
+ "colors": {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "html": {
+ "$ref": "#/definitions/simple-format"
+ },
+ "checkstyle": {
+ "$ref": "#/definitions/simple-format"
+ },
+ "code-climate": {
+ "$ref": "#/definitions/simple-format"
+ },
+ "junit-xml": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "path": {
+ "$ref": "#/definitions/formats-path",
+ "default": "stdout"
+ },
+ "extended": {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "teamcity": {
+ "$ref": "#/definitions/simple-format"
+ },
+ "sarif": {
+ "$ref": "#/definitions/simple-format"
+ }
+ }
+ },
+ "path-mode": {
+ "type": "string",
+ "default": "",
+ "examples": ["abs"]
+ },
+ "path-prefix": {
+ "description": "Add a prefix to the output file references.",
+ "type": "string",
+ "default": ""
+ },
+ "show-stats": {
+ "description": "Show statistics per linter.",
+ "type": "boolean",
+ "default": true
+ },
+ "sort-order": {
+ "type": "array",
+ "items": {
+ "enum": ["linter", "severity", "file"]
+ }
+ }
+ }
+ },
+ "linters": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "default": {
+ "enum": [
+ "standard",
+ "all",
+ "none",
+ "fast"
+ ]
+ },
+ "enable": {
+ "description": "List of enabled linters.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linter-names"
+ }
+ },
+ "disable": {
+ "description": "List of disabled linters.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linter-names"
+ }
+ },
+ "settings": {
+ "description": "All available settings of specific linters.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "dupword": {
+ "$ref": "#/definitions/settings/definitions/dupwordSettings"
+ },
+ "asasalint": {
+ "$ref": "#/definitions/settings/definitions/asasalintSettings"
+ },
+ "bidichk": {
+ "$ref": "#/definitions/settings/definitions/bidichkSettings"
+ },
+ "cyclop": {
+ "$ref": "#/definitions/settings/definitions/cyclopSettings"
+ },
+ "decorder": {
+ "$ref": "#/definitions/settings/definitions/decorderSettings"
+ },
+ "depguard":{
+ "$ref": "#/definitions/settings/definitions/depguardSettings"
+ },
+ "dogsled": {
+ "$ref": "#/definitions/settings/definitions/dogsledSettings"
+ },
+ "dupl": {
+ "$ref": "#/definitions/settings/definitions/duplSettings"
+ },
+ "embeddedstructfieldcheck": {
+ "$ref": "#/definitions/settings/definitions/embeddedstructfieldcheckSettings"
+ },
+ "errcheck": {
+ "$ref": "#/definitions/settings/definitions/errcheckSettings"
+ },
+ "errchkjson": {
+ "$ref": "#/definitions/settings/definitions/errchkjsonSettings"
+ },
+ "errorlint": {
+ "$ref": "#/definitions/settings/definitions/errorlintSettings"
+ },
+ "exhaustive": {
+ "$ref": "#/definitions/settings/definitions/exhaustiveSettings"
+ },
+ "exhaustruct": {
+ "$ref": "#/definitions/settings/definitions/exhaustructSettings"
+ },
+ "fatcontext": {
+ "$ref": "#/definitions/settings/definitions/fatcontextSettings"
+ },
+ "forbidigo": {
+ "$ref": "#/definitions/settings/definitions/forbidigoSettings"
+ },
+ "funcorder": {
+ "$ref": "#/definitions/settings/definitions/funcorderSettings"
+ },
+ "funlen": {
+ "$ref": "#/definitions/settings/definitions/funlenSettings"
+ },
+ "ginkgolinter": {
+ "$ref": "#/definitions/settings/definitions/ginkgolinterSettings"
+ },
+ "gochecksumtype": {
+ "$ref": "#/definitions/settings/definitions/gochecksumtypeSettings"
+ },
+ "gocognit": {
+ "$ref": "#/definitions/settings/definitions/gocognitSettings"
+ },
+ "goconst": {
+ "$ref": "#/definitions/settings/definitions/goconstSettings"
+ },
+ "gocritic": {
+ "$ref": "#/definitions/settings/definitions/gocriticSettings"
+ },
+ "gocyclo": {
+ "$ref": "#/definitions/settings/definitions/gocycloSettings"
+ },
+ "godoclint": {
+ "$ref": "#/definitions/settings/definitions/godoclintSettings"
+ },
+ "godot": {
+ "$ref": "#/definitions/settings/definitions/godotSettings"
+ },
+ "godox": {
+ "$ref": "#/definitions/settings/definitions/godoxSettings"
+ },
+ "interfacebloat":{
+ "$ref": "#/definitions/settings/definitions/interfacebloatSettings"
+ },
+ "goheader": {
+ "$ref": "#/definitions/settings/definitions/goheaderSettings"
+ },
+ "gomoddirectives": {
+ "$ref": "#/definitions/settings/definitions/gomoddirectivesSettings"
+ },
+ "gomodguard": {
+ "$ref": "#/definitions/settings/definitions/gomodguardSettings"
+ },
+ "gosec": {
+ "$ref": "#/definitions/settings/definitions/gosecSettings"
+ },
+ "gosmopolitan": {
+ "$ref": "#/definitions/settings/definitions/gosmopolitanSettings"
+ },
+ "govet": {
+ "$ref": "#/definitions/settings/definitions/govetSettings"
+ },
+ "grouper": {
+ "$ref": "#/definitions/settings/definitions/grouperSettings"
+ },
+ "iface": {
+ "$ref": "#/definitions/settings/definitions/ifaceSettings"
+ },
+ "importas": {
+ "$ref": "#/definitions/settings/definitions/importasSettings"
+ },
+ "inamedparam": {
+ "$ref": "#/definitions/settings/definitions/inamedparamSettings"
+ },
+ "ineffassign": {
+ "$ref": "#/definitions/settings/definitions/ineffassignSettings"
+ },
+ "iotamixing": {
+ "$ref": "#/definitions/settings/definitions/iotamixingSettings"
+ },
+ "ireturn": {
+ "$ref": "#/definitions/settings/definitions/ireturnSettings"
+ },
+ "lll": {
+ "$ref": "#/definitions/settings/definitions/lllSettings"
+ },
+ "maintidx": {
+ "$ref": "#/definitions/settings/definitions/maintidxSettings"
+ },
+ "makezero":{
+ "$ref": "#/definitions/settings/definitions/makezeroSettings"
+ },
+ "loggercheck": {
+ "$ref": "#/definitions/settings/definitions/loggercheckSettings"
+ },
+ "misspell": {
+ "$ref": "#/definitions/settings/definitions/misspellSettings"
+ },
+ "musttag": {
+ "$ref": "#/definitions/settings/definitions/musttagSettings"
+ },
+ "nakedret": {
+ "$ref": "#/definitions/settings/definitions/nakedretSettings"
+ },
+ "nestif": {
+ "$ref": "#/definitions/settings/definitions/nestifSettings"
+ },
+ "nilnil": {
+ "$ref": "#/definitions/settings/definitions/nilnilSettings"
+ },
+ "nlreturn": {
+ "$ref": "#/definitions/settings/definitions/nlreturnSettings"
+ },
+ "mnd": {
+ "$ref": "#/definitions/settings/definitions/mndSettings"
+ },
+ "modernize": {
+ "$ref": "#/definitions/settings/definitions/modernizeSettings"
+ },
+ "nolintlint":{
+ "$ref": "#/definitions/settings/definitions/nolintlintSettings"
+ },
+ "reassign": {
+ "$ref": "#/definitions/settings/definitions/reassignSettings"
+ },
+ "recvcheck": {
+ "$ref": "#/definitions/settings/definitions/recvcheckSettings"
+ },
+ "nonamedreturns": {
+ "$ref": "#/definitions/settings/definitions/nonamedreturnsSettings"
+ },
+ "paralleltest": {
+ "$ref": "#/definitions/settings/definitions/paralleltestSettings"
+ },
+ "perfsprint": {
+ "$ref": "#/definitions/settings/definitions/perfsprintSettings"
+ },
+ "prealloc": {
+ "$ref": "#/definitions/settings/definitions/preallocSettings"
+ },
+ "predeclared": {
+ "$ref": "#/definitions/settings/definitions/predeclaredSettings"
+ },
+ "promlinter": {
+ "$ref": "#/definitions/settings/definitions/promlinterSettings"
+ },
+ "protogetter": {
+ "$ref": "#/definitions/settings/definitions/protogetterSettings"
+ },
+ "revive": {
+ "$ref": "#/definitions/settings/definitions/reviveSettings"
+ },
+ "rowserrcheck": {
+ "$ref": "#/definitions/settings/definitions/rowserrcheckSettings"
+ },
+ "sloglint": {
+ "$ref": "#/definitions/settings/definitions/sloglintSettings"
+ },
+ "spancheck": {
+ "$ref": "#/definitions/settings/definitions/spancheckSettings"
+ },
+ "staticcheck":{
+ "$ref": "#/definitions/settings/definitions/staticcheckSettings"
+ },
+ "tagalign": {
+ "$ref": "#/definitions/settings/definitions/tagalignSettings"
+ },
+ "tagliatelle": {
+ "$ref": "#/definitions/settings/definitions/tagliatelleSettings"
+ },
+ "testifylint": {
+ "$ref": "#/definitions/settings/definitions/testifylintSettings"
+ },
+ "testpackage": {
+ "$ref": "#/definitions/settings/definitions/testpackageSettings"
+ },
+ "thelper": {
+ "$ref": "#/definitions/settings/definitions/thelperSettings"
+ },
+ "usestdlibvars": {
+ "$ref": "#/definitions/settings/definitions/usestdlibvarsSettings"
+ },
+ "usetesting": {
+ "$ref": "#/definitions/settings/definitions/usetestingSettings"
+ },
+ "unconvert": {
+ "$ref": "#/definitions/settings/definitions/unconvertSettings"
+ },
+ "unparam": {
+ "$ref": "#/definitions/settings/definitions/unparamSettings"
+ },
+ "unqueryvet": {
+ "$ref": "#/definitions/settings/definitions/unqueryvetSettings"
+ },
+ "unused": {
+ "$ref": "#/definitions/settings/definitions/unusedSettings"
+ },
+ "varnamelen": {
+ "$ref": "#/definitions/settings/definitions/varnamelenSettings"
+ },
+ "whitespace": {
+ "$ref": "#/definitions/settings/definitions/whitespaceSettings"
+ },
+ "wrapcheck": {
+ "$ref": "#/definitions/settings/definitions/wrapcheckSettings"
+ },
+ "wsl": {
+ "$ref": "#/definitions/settings/definitions/wslSettings"
+ },
+ "wsl_v5": {
+ "$ref": "#/definitions/settings/definitions/wslSettingsV5"
+ },
+ "copyloopvar": {
+ "$ref": "#/definitions/settings/definitions/copyloopvarSettings"
+ },
+ "custom":{
+ "$ref": "#/definitions/settings/definitions/customSettings"
+ }
+ }
+ },
+ "exclusions":{
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "generated": {
+ "enum": ["strict", "lax", "disable"],
+ "default": "strict"
+ },
+ "warn-unused": {
+ "type": "boolean",
+ "default": false
+ },
+ "presets": {
+ "type": "array",
+ "items": {
+ "enum": [
+ "comments",
+ "std-error-handling",
+ "common-false-positives",
+ "legacy"
+ ]
+ }
+ },
+ "rules": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "path": {
+ "type": "string"
+ },
+ "path-except": {
+ "type": "string"
+ },
+ "linters": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linter-names"
+ }
+ },
+ "text": {
+ "type": "string"
+ },
+ "source": {
+ "type": "string"
+ }
+ },
+ "anyOf": [
+ { "required": ["path"] },
+ { "required": ["path-except"] },
+ { "required": ["linters"] },
+ { "required": ["text"] },
+ { "required": ["source"] }
+ ]
+ }
+ },
+ "paths": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "paths-except": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "formatters": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "enable": {
+ "description": "List of enabled formatters.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/formatter-names"
+ }
+ },
+ "settings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "gci": {
+ "$ref": "#/definitions/settings/definitions/gciSettings"
+ },
+ "gofmt": {
+ "$ref": "#/definitions/settings/definitions/gofmtSettings"
+ },
+ "gofumpt": {
+ "$ref": "#/definitions/settings/definitions/gofumptSettings"
+ },
+ "goimports": {
+ "$ref": "#/definitions/settings/definitions/goimportsSettings"
+ },
+ "golines": {
+ "$ref": "#/definitions/settings/definitions/golinesSettings"
+ }
+ }
+ },
+ "exclusions": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "generated": {
+ "enum": ["strict", "lax", "disable"],
+ "default": "strict"
+ },
+ "paths": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "warn-unused": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ }
+ }
+ },
+ "issues": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-issues-per-linter": {
+ "description": "Maximum issues count per one linter. Set to 0 to disable.",
+ "type": "integer",
+ "default": 50,
+ "minimum": 0
+ },
+ "max-same-issues": {
+ "description": "Maximum count of issues with the same text. Set to 0 to disable.",
+ "type": "integer",
+ "default": 3,
+ "minimum": 0
+ },
+ "new": {
+ "description": "Show only new issues: if there are unstaged changes or untracked files, only those changes are analyzed, else only changes in HEAD~ are analyzed.",
+ "type": "boolean",
+ "default": false
+ },
+ "new-from-merge-base": {
+ "description": "Show only new issues created after the best common ancestor (merge-base against HEAD).",
+ "type": "string"
+ },
+ "new-from-rev": {
+ "description": "Show only new issues created after this git revision.",
+ "type": "string"
+ },
+ "new-from-patch": {
+ "description": "Show only new issues created in git patch with this file path.",
+ "type": "string",
+ "examples": ["path/to/patch/file"]
+ },
+ "fix": {
+ "description": "Apply the fixes detected by the linters and formatters (if it's supported by the linter).",
+ "type": "boolean",
+ "default": false
+ },
+ "uniq-by-line": {
+ "description": "Make issues output unique by line.",
+ "type": "boolean",
+ "default": true
+ },
+ "whole-files": {
+ "description": "Show issues in any part of update files (requires new-from-rev or new-from-patch).",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "severity": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "default": {
+ "description": "Set the default severity for issues. If severity rules are defined and the issues do not match or no severity is provided to the rule this will be the default severity applied. Severities should match the supported severity names of the selected out format.",
+ "type": "string",
+ "default": ""
+ },
+ "rules": {
+ "description": "When a list of severity rules are provided, severity information will be added to lint issues. Severity rules have the same filtering capability as exclude rules except you are allowed to specify one matcher per severity rule.\nOnly affects out formats that support setting severity information.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "severity": {
+ "type": "string"
+ },
+ "path": {
+ "type": "string"
+ },
+ "path-except": {
+ "type": "string"
+ },
+ "linters": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linter-names"
+ }
+ },
+ "text": {
+ "type": "string"
+ },
+ "source": {
+ "type": "string"
+ }
+ },
+ "required": ["severity"],
+ "anyOf": [
+ { "required": ["path"] },
+ { "required": ["path-except"] },
+ { "required": ["linters"] },
+ { "required": ["text"] },
+ { "required": ["source"] }
+ ]
+ },
+ "default": []
+ }
+ },
+ "required": ["default"]
+ }
+ }
+}
diff --git a/vendor/github.com/golangci/golangci-lint/v2/jsonschema/golangci.v2.11.jsonschema.json b/vendor/github.com/golangci/golangci-lint/v2/jsonschema/golangci.v2.11.jsonschema.json
new file mode 100644
index 000000000..38b3e77a5
--- /dev/null
+++ b/vendor/github.com/golangci/golangci-lint/v2/jsonschema/golangci.v2.11.jsonschema.json
@@ -0,0 +1,5295 @@
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "$id": "https://json.schemastore.org/golangci-lint.json",
+ "definitions": {
+ "gocritic-checks": {
+ "enum": [
+ "appendAssign",
+ "appendCombine",
+ "argOrder",
+ "assignOp",
+ "badCall",
+ "badCond",
+ "badLock",
+ "badRegexp",
+ "badSorting",
+ "badSyncOnceFunc",
+ "boolExprSimplify",
+ "builtinShadow",
+ "builtinShadowDecl",
+ "captLocal",
+ "caseOrder",
+ "codegenComment",
+ "commentFormatting",
+ "commentedOutCode",
+ "commentedOutImport",
+ "defaultCaseOrder",
+ "deferInLoop",
+ "deferUnlambda",
+ "deprecatedComment",
+ "docStub",
+ "dupArg",
+ "dupBranchBody",
+ "dupCase",
+ "dupImport",
+ "dupOption",
+ "dupSubExpr",
+ "dynamicFmtString",
+ "elseif",
+ "emptyDecl",
+ "emptyFallthrough",
+ "emptyStringTest",
+ "equalFold",
+ "evalOrder",
+ "exitAfterDefer",
+ "exposedSyncMutex",
+ "externalErrorReassign",
+ "filepathJoin",
+ "flagDeref",
+ "flagName",
+ "hexLiteral",
+ "httpNoBody",
+ "hugeParam",
+ "ifElseChain",
+ "importShadow",
+ "indexAlloc",
+ "initClause",
+ "mapKey",
+ "methodExprCall",
+ "nestingReduce",
+ "newDeref",
+ "nilValReturn",
+ "octalLiteral",
+ "offBy1",
+ "paramTypeCombine",
+ "preferDecodeRune",
+ "preferFilepathJoin",
+ "preferFprint",
+ "preferStringWriter",
+ "preferWriteByte",
+ "ptrToRefParam",
+ "rangeAppendAll",
+ "rangeExprCopy",
+ "rangeValCopy",
+ "redundantSprint",
+ "regexpMust",
+ "regexpPattern",
+ "regexpSimplify",
+ "returnAfterHttpError",
+ "ruleguard",
+ "singleCaseSwitch",
+ "sliceClear",
+ "sloppyLen",
+ "sloppyReassign",
+ "sloppyTypeAssert",
+ "sortSlice",
+ "sprintfQuotedString",
+ "sqlQuery",
+ "stringConcatSimplify",
+ "stringXbytes",
+ "stringsCompare",
+ "switchTrue",
+ "syncMapLoadAndDelete",
+ "timeExprSimplify",
+ "todoCommentWithoutDetail",
+ "tooManyResultsChecker",
+ "truncateCmp",
+ "typeAssertChain",
+ "typeDefFirst",
+ "typeSwitchVar",
+ "typeUnparen",
+ "uncheckedInlineErr",
+ "underef",
+ "unlabelStmt",
+ "unlambda",
+ "unnamedResult",
+ "unnecessaryBlock",
+ "unnecessaryDefer",
+ "unslice",
+ "valSwap",
+ "weakCond",
+ "whyNoLint",
+ "wrapperFunc",
+ "yodaStyleExpr",
+ "zeroByteRepeat"
+ ]
+ },
+ "gocritic-tags": {
+ "enum": [
+ "diagnostic",
+ "style",
+ "performance",
+ "experimental",
+ "opinionated",
+ "security"
+ ]
+ },
+ "staticcheck-checks": {
+ "enum": [
+ "*",
+ "all",
+ "SA*",
+ "-SA*",
+ "SA1*",
+ "-SA1*",
+ "SA1000",
+ "-SA1000",
+ "SA1001",
+ "-SA1001",
+ "SA1002",
+ "-SA1002",
+ "SA1003",
+ "-SA1003",
+ "SA1004",
+ "-SA1004",
+ "SA1005",
+ "-SA1005",
+ "SA1006",
+ "-SA1006",
+ "SA1007",
+ "-SA1007",
+ "SA1008",
+ "-SA1008",
+ "SA1010",
+ "-SA1010",
+ "SA1011",
+ "-SA1011",
+ "SA1012",
+ "-SA1012",
+ "SA1013",
+ "-SA1013",
+ "SA1014",
+ "-SA1014",
+ "SA1015",
+ "-SA1015",
+ "SA1016",
+ "-SA1016",
+ "SA1017",
+ "-SA1017",
+ "SA1018",
+ "-SA1018",
+ "SA1019",
+ "-SA1019",
+ "SA1020",
+ "-SA1020",
+ "SA1021",
+ "-SA1021",
+ "SA1023",
+ "-SA1023",
+ "SA1024",
+ "-SA1024",
+ "SA1025",
+ "-SA1025",
+ "SA1026",
+ "-SA1026",
+ "SA1027",
+ "-SA1027",
+ "SA1028",
+ "-SA1028",
+ "SA1029",
+ "-SA1029",
+ "SA1030",
+ "-SA1030",
+ "SA1031",
+ "-SA1031",
+ "SA1032",
+ "-SA1032",
+ "SA2*",
+ "-SA2*",
+ "SA2000",
+ "-SA2000",
+ "SA2001",
+ "-SA2001",
+ "SA2002",
+ "-SA2002",
+ "SA2003",
+ "-SA2003",
+ "SA3*",
+ "-SA3*",
+ "SA3000",
+ "-SA3000",
+ "SA3001",
+ "-SA3001",
+ "SA4*",
+ "-SA4*",
+ "SA4000",
+ "-SA4000",
+ "SA4001",
+ "-SA4001",
+ "SA4003",
+ "-SA4003",
+ "SA4004",
+ "-SA4004",
+ "SA4005",
+ "-SA4005",
+ "SA4006",
+ "-SA4006",
+ "SA4008",
+ "-SA4008",
+ "SA4009",
+ "-SA4009",
+ "SA4010",
+ "-SA4010",
+ "SA4011",
+ "-SA4011",
+ "SA4012",
+ "-SA4012",
+ "SA4013",
+ "-SA4013",
+ "SA4014",
+ "-SA4014",
+ "SA4015",
+ "-SA4015",
+ "SA4016",
+ "-SA4016",
+ "SA4017",
+ "-SA4017",
+ "SA4018",
+ "-SA4018",
+ "SA4019",
+ "-SA4019",
+ "SA4020",
+ "-SA4020",
+ "SA4021",
+ "-SA4021",
+ "SA4022",
+ "-SA4022",
+ "SA4023",
+ "-SA4023",
+ "SA4024",
+ "-SA4024",
+ "SA4025",
+ "-SA4025",
+ "SA4026",
+ "-SA4026",
+ "SA4027",
+ "-SA4027",
+ "SA4028",
+ "-SA4028",
+ "SA4029",
+ "-SA4029",
+ "SA4030",
+ "-SA4030",
+ "SA4031",
+ "-SA4031",
+ "SA4032",
+ "-SA4032",
+ "SA5*",
+ "-SA5*",
+ "SA5000",
+ "-SA5000",
+ "SA5001",
+ "-SA5001",
+ "SA5002",
+ "-SA5002",
+ "SA5003",
+ "-SA5003",
+ "SA5004",
+ "-SA5004",
+ "SA5005",
+ "-SA5005",
+ "SA5007",
+ "-SA5007",
+ "SA5008",
+ "-SA5008",
+ "SA5009",
+ "-SA5009",
+ "SA5010",
+ "-SA5010",
+ "SA5011",
+ "-SA5011",
+ "SA5012",
+ "-SA5012",
+ "SA6*",
+ "-SA6*",
+ "SA6000",
+ "-SA6000",
+ "SA6001",
+ "-SA6001",
+ "SA6002",
+ "-SA6002",
+ "SA6003",
+ "-SA6003",
+ "SA6005",
+ "-SA6005",
+ "SA6006",
+ "-SA6006",
+ "SA9*",
+ "-SA9*",
+ "SA9001",
+ "-SA9001",
+ "SA9002",
+ "-SA9002",
+ "SA9003",
+ "-SA9003",
+ "SA9004",
+ "-SA9004",
+ "SA9005",
+ "-SA9005",
+ "SA9006",
+ "-SA9006",
+ "SA9007",
+ "-SA9007",
+ "SA9008",
+ "-SA9008",
+ "SA9009",
+ "-SA9009",
+ "ST*",
+ "-ST*",
+ "ST1*",
+ "-ST1*",
+ "ST1000",
+ "-ST1000",
+ "ST1001",
+ "-ST1001",
+ "ST1003",
+ "-ST1003",
+ "ST1005",
+ "-ST1005",
+ "ST1006",
+ "-ST1006",
+ "ST1008",
+ "-ST1008",
+ "ST1011",
+ "-ST1011",
+ "ST1012",
+ "-ST1012",
+ "ST1013",
+ "-ST1013",
+ "ST1015",
+ "-ST1015",
+ "ST1016",
+ "-ST1016",
+ "ST1017",
+ "-ST1017",
+ "ST1018",
+ "-ST1018",
+ "ST1019",
+ "-ST1019",
+ "ST1020",
+ "-ST1020",
+ "ST1021",
+ "-ST1021",
+ "ST1022",
+ "-ST1022",
+ "ST1023",
+ "-ST1023",
+ "S*",
+ "-S*",
+ "S1*",
+ "-S1*",
+ "S1000",
+ "-S1000",
+ "S1001",
+ "-S1001",
+ "S1002",
+ "-S1002",
+ "S1003",
+ "-S1003",
+ "S1004",
+ "-S1004",
+ "S1005",
+ "-S1005",
+ "S1006",
+ "-S1006",
+ "S1007",
+ "-S1007",
+ "S1008",
+ "-S1008",
+ "S1009",
+ "-S1009",
+ "S1010",
+ "-S1010",
+ "S1011",
+ "-S1011",
+ "S1012",
+ "-S1012",
+ "S1016",
+ "-S1016",
+ "S1017",
+ "-S1017",
+ "S1018",
+ "-S1018",
+ "S1019",
+ "-S1019",
+ "S1020",
+ "-S1020",
+ "S1021",
+ "-S1021",
+ "S1023",
+ "-S1023",
+ "S1024",
+ "-S1024",
+ "S1025",
+ "-S1025",
+ "S1028",
+ "-S1028",
+ "S1029",
+ "-S1029",
+ "S1030",
+ "-S1030",
+ "S1031",
+ "-S1031",
+ "S1032",
+ "-S1032",
+ "S1033",
+ "-S1033",
+ "S1034",
+ "-S1034",
+ "S1035",
+ "-S1035",
+ "S1036",
+ "-S1036",
+ "S1037",
+ "-S1037",
+ "S1038",
+ "-S1038",
+ "S1039",
+ "-S1039",
+ "S1040",
+ "-S1040",
+ "QF*",
+ "-QF*",
+ "QF1*",
+ "-QF1*",
+ "QF1001",
+ "-QF1001",
+ "QF1002",
+ "-QF1002",
+ "QF1003",
+ "-QF1003",
+ "QF1004",
+ "-QF1004",
+ "QF1005",
+ "-QF1005",
+ "QF1006",
+ "-QF1006",
+ "QF1007",
+ "-QF1007",
+ "QF1008",
+ "-QF1008",
+ "QF1009",
+ "-QF1009",
+ "QF1010",
+ "-QF1010",
+ "QF1011",
+ "-QF1011",
+ "QF1012",
+ "-QF1012"
+ ]
+ },
+ "godoclint-rules": {
+ "enum": [
+ "pkg-doc",
+ "single-pkg-doc",
+ "require-pkg-doc",
+ "start-with-name",
+ "require-doc",
+ "deprecated",
+ "max-len",
+ "no-unused-link",
+ "require-stdlib-doclink"
+ ]
+ },
+ "gosec-rules": {
+ "enum": [
+ "G101",
+ "G102",
+ "G103",
+ "G104",
+ "G106",
+ "G107",
+ "G108",
+ "G109",
+ "G110",
+ "G111",
+ "G112",
+ "G113",
+ "G114",
+ "G115",
+ "G116",
+ "G117",
+ "G118",
+ "G119",
+ "G120",
+ "G121",
+ "G122",
+ "G123",
+ "G201",
+ "G202",
+ "G203",
+ "G204",
+ "G301",
+ "G302",
+ "G303",
+ "G304",
+ "G305",
+ "G306",
+ "G307",
+ "G401",
+ "G402",
+ "G403",
+ "G404",
+ "G405",
+ "G406",
+ "G408",
+ "G501",
+ "G502",
+ "G503",
+ "G504",
+ "G505",
+ "G506",
+ "G507",
+ "G601",
+ "G602",
+ "G701",
+ "G702",
+ "G703",
+ "G704",
+ "G705",
+ "G706",
+ "G707"
+ ]
+ },
+ "govet-analyzers": {
+ "enum": [
+ "appends",
+ "asmdecl",
+ "assign",
+ "atomic",
+ "atomicalign",
+ "bools",
+ "buildtag",
+ "cgocall",
+ "composites",
+ "copylocks",
+ "deepequalerrors",
+ "defers",
+ "directive",
+ "errorsas",
+ "fieldalignment",
+ "findcall",
+ "framepointer",
+ "hostport",
+ "httpmux",
+ "httpresponse",
+ "ifaceassert",
+ "loopclosure",
+ "lostcancel",
+ "nilfunc",
+ "nilness",
+ "printf",
+ "reflectvaluecompare",
+ "shadow",
+ "shift",
+ "sigchanyzer",
+ "slog",
+ "sortslice",
+ "stdmethods",
+ "stdversion",
+ "stringintconv",
+ "structtag",
+ "testinggoroutine",
+ "tests",
+ "timeformat",
+ "unmarshal",
+ "unreachable",
+ "unsafeptr",
+ "unusedresult",
+ "unusedwrite",
+ "waitgroup"
+ ]
+ },
+ "revive-rules": {
+ "enum": [
+ "add-constant",
+ "argument-limit",
+ "atomic",
+ "banned-characters",
+ "bare-return",
+ "blank-imports",
+ "bool-literal-in-expr",
+ "call-to-gc",
+ "cognitive-complexity",
+ "comment-spacings",
+ "comments-density",
+ "confusing-naming",
+ "confusing-results",
+ "constant-logical-expr",
+ "context-as-argument",
+ "context-keys-type",
+ "cyclomatic",
+ "datarace",
+ "deep-exit",
+ "defer",
+ "dot-imports",
+ "duplicated-imports",
+ "early-return",
+ "empty-block",
+ "empty-lines",
+ "enforce-map-style",
+ "enforce-repeated-arg-type-style",
+ "enforce-slice-style",
+ "enforce-switch-style",
+ "epoch-naming",
+ "error-naming",
+ "error-return",
+ "error-strings",
+ "errorf",
+ "exported",
+ "file-header",
+ "file-length-limit",
+ "filename-format",
+ "flag-parameter",
+ "forbidden-call-in-wg-go",
+ "function-length",
+ "function-result-limit",
+ "get-return",
+ "identical-branches",
+ "identical-ifelseif-branches",
+ "identical-ifelseif-conditions",
+ "identical-switch-branches",
+ "identical-switch-conditions",
+ "if-return",
+ "import-alias-naming",
+ "import-shadowing",
+ "imports-blocklist",
+ "increment-decrement",
+ "indent-error-flow",
+ "inefficient-map-lookup",
+ "line-length-limit",
+ "max-control-nesting",
+ "max-public-structs",
+ "modifies-parameter",
+ "modifies-value-receiver",
+ "nested-structs",
+ "optimize-operands-order",
+ "package-comments",
+ "package-naming",
+ "package-directory-mismatch",
+ "range-val-address",
+ "range-val-in-closure",
+ "range",
+ "receiver-naming",
+ "redefines-builtin-id",
+ "redundant-build-tag",
+ "redundant-import-alias",
+ "redundant-test-main-exit",
+ "string-format",
+ "string-of-int",
+ "struct-tag",
+ "superfluous-else",
+ "time-date",
+ "time-equal",
+ "time-naming",
+ "unchecked-type-assertion",
+ "unconditional-recursion",
+ "unexported-naming",
+ "unexported-return",
+ "unhandled-error",
+ "unnecessary-format",
+ "unnecessary-if",
+ "unnecessary-stmt",
+ "unreachable-code",
+ "unsecure-url-scheme",
+ "unused-parameter",
+ "unused-receiver",
+ "use-any",
+ "use-errors-new",
+ "use-fmt-print",
+ "use-slices-sort",
+ "use-waitgroup-go",
+ "useless-break",
+ "useless-fallthrough",
+ "var-declaration",
+ "var-naming",
+ "waitgroup-by-value"
+ ]
+ },
+ "iface-analyzers": {
+ "enum": [
+ "identical",
+ "unused",
+ "opaque",
+ "unexported"
+ ]
+ },
+ "tagliatelle-cases": {
+ "enum": [
+ "",
+ "camel",
+ "pascal",
+ "kebab",
+ "snake",
+ "goCamel",
+ "goPascal",
+ "goKebab",
+ "goSnake",
+ "upper",
+ "upperSnake",
+ "lower",
+ "header"
+ ]
+ },
+ "modernize-analyzers": {
+ "enum": [
+ "any",
+ "fmtappendf",
+ "forvar",
+ "mapsloop",
+ "minmax",
+ "newexpr",
+ "omitzero",
+ "plusbuild",
+ "rangeint",
+ "reflecttypefor",
+ "slicescontains",
+ "slicessort",
+ "stditerators",
+ "stringscut",
+ "stringscutprefix",
+ "stringsseq",
+ "stringsbuilder",
+ "testingcontext",
+ "unsafefuncs",
+ "waitgroup"
+ ]
+ },
+ "wsl-checks": {
+ "enum": [
+ "assign",
+ "branch",
+ "decl",
+ "defer",
+ "expr",
+ "for",
+ "go",
+ "if",
+ "inc-dec",
+ "label",
+ "range",
+ "return",
+ "select",
+ "send",
+ "switch",
+ "type-switch",
+ "append",
+ "assign-exclusive",
+ "assign-expr",
+ "err",
+ "leading-whitespace",
+ "trailing-whitespace",
+ "after-block"
+ ]
+ },
+ "relative-path-modes": {
+ "enum": [
+ "gomod",
+ "gitroot",
+ "cfg",
+ "wd"
+ ]
+ },
+ "simple-format": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "path": {
+ "$ref": "#/definitions/formats-path",
+ "default": "stdout"
+ }
+ }
+ },
+ "formats-path" : {
+ "anyOf": [
+ {
+ "enum": [
+ "stdout",
+ "stderr"
+ ]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ },
+ "linter-names": {
+ "$comment": "anyOf with enum is used to allow auto-completion of non-custom linters",
+ "description": "Usable linter names.",
+ "anyOf": [
+ {
+ "enum": [
+ "arangolint",
+ "asasalint",
+ "asciicheck",
+ "bidichk",
+ "bodyclose",
+ "canonicalheader",
+ "containedctx",
+ "contextcheck",
+ "copyloopvar",
+ "cyclop",
+ "decorder",
+ "depguard",
+ "dogsled",
+ "dupl",
+ "dupword",
+ "durationcheck",
+ "embeddedstructfieldcheck",
+ "errcheck",
+ "errchkjson",
+ "errname",
+ "errorlint",
+ "exhaustive",
+ "exhaustruct",
+ "exptostd",
+ "fatcontext",
+ "forbidigo",
+ "forcetypeassert",
+ "funcorder",
+ "funlen",
+ "ginkgolinter",
+ "gocheckcompilerdirectives",
+ "gochecknoglobals",
+ "gochecknoinits",
+ "gochecksumtype",
+ "gocognit",
+ "goconst",
+ "gocritic",
+ "gocyclo",
+ "godoclint",
+ "godot",
+ "godox",
+ "err113",
+ "goheader",
+ "gomoddirectives",
+ "gomodguard",
+ "goprintffuncname",
+ "gosec",
+ "gosimple",
+ "gosmopolitan",
+ "govet",
+ "grouper",
+ "iface",
+ "importas",
+ "inamedparam",
+ "ineffassign",
+ "interfacebloat",
+ "intrange",
+ "iotamixing",
+ "ireturn",
+ "lll",
+ "loggercheck",
+ "maintidx",
+ "makezero",
+ "mirror",
+ "misspell",
+ "mnd",
+ "modernize",
+ "musttag",
+ "nakedret",
+ "nestif",
+ "nilerr",
+ "nilnesserr",
+ "nilnil",
+ "nlreturn",
+ "noctx",
+ "noinlineerr",
+ "nolintlint",
+ "nonamedreturns",
+ "nosprintfhostport",
+ "paralleltest",
+ "perfsprint",
+ "prealloc",
+ "predeclared",
+ "promlinter",
+ "protogetter",
+ "reassign",
+ "recvcheck",
+ "revive",
+ "rowserrcheck",
+ "sloglint",
+ "sqlclosecheck",
+ "staticcheck",
+ "stylecheck",
+ "tagalign",
+ "tagliatelle",
+ "testableexamples",
+ "testifylint",
+ "testpackage",
+ "thelper",
+ "tparallel",
+ "unconvert",
+ "unparam",
+ "unused",
+ "usestdlibvars",
+ "usetesting",
+ "varnamelen",
+ "wastedassign",
+ "whitespace",
+ "wrapcheck",
+ "wsl",
+ "wsl_v5",
+ "zerologlint"
+ ]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ },
+ "formatter-names": {
+ "description": "Usable formatter names.",
+ "enum": [
+ "gci",
+ "gofmt",
+ "gofumpt",
+ "goimports",
+ "golines",
+ "swaggo"
+ ]
+ },
+ "settings": {
+ "definitions": {
+ "dupwordSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "keywords": {
+ "description": "Keywords for detecting duplicate words. If this list is not empty, only the words defined in this list will be detected.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["the", "and", "a"]
+ }
+ },
+ "ignore": {
+ "description": "Keywords used to ignore detection.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["0C0C"]
+ }
+ },
+ "comments-only": {
+ "description": "Checks only comments, skip strings.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "asasalintSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "exclude": {
+ "description": "To specify a set of function names to exclude.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["\\.Wrapf"]
+ }
+ },
+ "use-builtin-exclusions": {
+ "description": "To enable/disable the asasalint builtin exclusions of function names.",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "bidichkSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "left-to-right-embedding": {
+ "description": "Disallow: LEFT-TO-RIGHT-EMBEDDING",
+ "type": "boolean",
+ "default": false
+ },
+ "right-to-left-embedding": {
+ "description": "Disallow: RIGHT-TO-LEFT-EMBEDDING",
+ "type": "boolean",
+ "default": false
+ },
+ "pop-directional-formatting": {
+ "description": "Disallow: POP-DIRECTIONAL-FORMATTING",
+ "type": "boolean",
+ "default": false
+ },
+ "left-to-right-override": {
+ "description": "Disallow: LEFT-TO-RIGHT-OVERRIDE",
+ "type": "boolean",
+ "default": false
+ },
+ "right-to-left-override": {
+ "description": "Disallow: RIGHT-TO-LEFT-OVERRIDE",
+ "type": "boolean",
+ "default": false
+ },
+ "left-to-right-isolate": {
+ "description": "Disallow: LEFT-TO-RIGHT-ISOLATE",
+ "type": "boolean",
+ "default": false
+ },
+ "right-to-left-isolate": {
+ "description": "Disallow: RIGHT-TO-LEFT-ISOLATE",
+ "type": "boolean",
+ "default": false
+ },
+ "first-strong-isolate": {
+ "description": "Disallow: FIRST-STRONG-ISOLATE",
+ "type": "boolean",
+ "default": false
+ },
+ "pop-directional-isolate": {
+ "description": "Disallow: POP-DIRECTIONAL-ISOLATE",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "cyclopSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-complexity": {
+ "description": "Max complexity the function can have",
+ "type": "integer",
+ "default": 10,
+ "minimum": 0
+ },
+ "package-average": {
+ "description": "Max average complexity in package",
+ "type": "number",
+ "default": 0,
+ "minimum": 0
+ }
+ }
+ },
+ "decorderSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "dec-order": {
+ "type": "array",
+ "default": [["type", "const", "var", "func"]],
+ "items": {
+ "enum": ["type", "const", "var", "func"]
+ }
+ },
+ "ignore-underscore-vars": {
+ "description": "Underscore vars (vars with \"_\" as the name) will be ignored at all checks",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-dec-order-check": {
+ "description": "Order of declarations is not checked",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-init-func-first-check": {
+ "description": "Allow init func to be anywhere in file",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-dec-num-check": {
+ "description": "Multiple global type, const and var declarations are allowed",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-type-dec-num-check": {
+ "description": "Type declarations will be ignored for dec num check",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-const-dec-num-check": {
+ "description": "Const declarations will be ignored for dec num check",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-var-dec-num-check": {
+ "description": "Var declarations will be ignored for dec num check",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ },
+ "depguardSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "rules": {
+ "description": "Rules to apply.",
+ "type": "object",
+ "additionalProperties": false,
+ "patternProperties": {
+ "^[^.]+$": {
+ "description": "Name of a rule.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "list-mode": {
+ "description": "Used to determine the package matching priority.",
+ "enum": ["original", "strict", "lax"],
+ "default": "original"
+ },
+ "files": {
+ "description": "List of file globs that will match this list of settings to compare against.",
+ "additionalProperties": false,
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "allow": {
+ "description": "List of allowed packages.",
+ "additionalProperties": false,
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "deny": {
+ "description": "Packages that are not allowed where the value is a suggestion.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "desc": {
+ "description": "Description",
+ "type": "string"
+ },
+ "pkg": {
+ "description": "Package",
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "dogsledSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-blank-identifiers": {
+ "description": "Check assignments with too many blank identifiers.",
+ "type": "integer",
+ "default": 2,
+ "minimum": 0
+ }
+ }
+ },
+ "duplSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "threshold": {
+ "description": "Tokens count to trigger issue.",
+ "type": "integer",
+ "default": 150,
+ "minimum": 0
+ }
+ }
+ },
+ "embeddedstructfieldcheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "empty-line": {
+ "description": "Checks that there is an empty space between the embedded fields and regular fields.",
+ "type": "boolean",
+ "default": false
+ },
+ "forbid-mutex": {
+ "description": "Checks that sync.Mutex and sync.RWMutex are not used as embedded fields.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "errcheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-type-assertions": {
+ "description": "Report about not checking errors in type assertions, i.e.: `a := b.(MyStruct)`",
+ "type": "boolean",
+ "default": false
+ },
+ "check-blank": {
+ "description": "Report about assignment of errors to blank identifier",
+ "type": "boolean",
+ "default": false
+ },
+ "exclude-functions": {
+ "description": "List of functions to exclude from checking, where each entry is a single function to exclude",
+ "type": "array",
+ "examples": ["io/ioutil.ReadFile", "io.Copy(*bytes.Buffer)"],
+ "items": {
+ "type": "string"
+ }
+ },
+ "disable-default-exclusions": {
+ "description": "To disable the errcheck built-in exclude list",
+ "type": "boolean",
+ "default": false
+ },
+ "verbose": {
+ "description": "Display function signature instead of selector",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "errchkjsonSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-error-free-encoding": {
+ "type": "boolean",
+ "default": false
+ },
+ "report-no-exported": {
+ "description": "Issue on struct that doesn't have exported fields.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "errorlintSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "errorf": {
+ "description": "Check whether fmt.Errorf uses the %w verb for formatting errors",
+ "type": "boolean",
+ "default": true
+ },
+ "errorf-multi": {
+ "description": "Permit more than 1 %w verb, valid per Go 1.20",
+ "type": "boolean",
+ "default": true
+ },
+ "asserts": {
+ "description": "Check for plain type assertions and type switches.",
+ "type": "boolean",
+ "default": true
+ },
+ "comparison": {
+ "description": "Check for plain error comparisons",
+ "type": "boolean",
+ "default": true
+ },
+ "allowed-errors": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "err": {
+ "type": "string"
+ },
+ "fun": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "allowed-errors-wildcard": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "err": {
+ "type": "string"
+ },
+ "fun": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "exhaustiveSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check": {
+ "description": "Program elements to check for exhaustiveness.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["switch", "map"]
+ }
+ },
+ "explicit-exhaustive-switch": {
+ "description": "Only run exhaustive check on switches with \"//exhaustive:enforce\" comment.",
+ "type": "boolean",
+ "default": false
+ },
+ "explicit-exhaustive-map": {
+ "description": "Only run exhaustive check on map literals with \"//exhaustive:enforce\" comment.",
+ "type": "boolean",
+ "default": false
+ },
+ "default-case-required": {
+ "description": "Switch statement requires default case even if exhaustive.",
+ "type": "boolean",
+ "default": false
+ },
+ "default-signifies-exhaustive": {
+ "description": "Presence of `default` case in switch statements satisfies exhaustiveness, even if all enum members are not listed.",
+ "type": "boolean",
+ "default": false
+ },
+ "ignore-enum-members": {
+ "description": "Enum members matching `regex` do not have to be listed in switch statements to satisfy exhaustiveness",
+ "type": "string"
+ },
+ "ignore-enum-types": {
+ "description": "Enum types matching the supplied regex do not have to be listed in switch statements to satisfy exhaustiveness.",
+ "type": "string"
+ },
+ "package-scope-only": {
+ "description": "Consider enums only in package scopes, not in inner scopes.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "exhaustructSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "include": {
+ "description": "List of regular expressions to match struct packages and names.",
+ "type": "array",
+ "examples": [".*\\.Test"],
+ "items": {
+ "type": "string"
+ }
+ },
+ "exclude": {
+ "description": "List of regular expressions to exclude struct packages and names from check.",
+ "type": "array",
+ "examples": ["cobra\\.Command$"],
+ "items": {
+ "type": "string"
+ }
+ },
+ "allow-empty": {
+ "description": "Allows empty structures, effectively excluding them from the check.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-empty-rx": {
+ "description": "List of regular expressions to match type names that should be allowed to be empty.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "allow-empty-returns": {
+ "description": "Allows empty structures in return statements.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-empty-declarations": {
+ "description": "Allows empty structures in variable declarations.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "fatcontextSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-struct-pointers": {
+ "description": "Check for potential fat contexts in struct pointers.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "forbidigoSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "exclude-godoc-examples": {
+ "description": "Exclude code in godoc examples.",
+ "type": "boolean",
+ "default": true
+ },
+ "analyze-types": {
+ "description": "Instead of matching the literal source code, use type information to replace expressions with strings that contain the package name and (for methods and fields) the type name.",
+ "type": "boolean",
+ "default": true
+ },
+ "forbid": {
+ "description": "List of identifiers to forbid (written using `regexp`)",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "pattern": {
+ "description": "Pattern",
+ "type": "string"
+ },
+ "pkg": {
+ "description": "Package",
+ "type": "string"
+ },
+ "msg": {
+ "description": "Message",
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "funcorderSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "constructor": {
+ "description": "Checks that constructors are placed after the structure declaration.",
+ "type": "boolean",
+ "default": true
+ },
+ "struct-method": {
+ "description": "Checks if the exported methods of a structure are placed before the non-exported ones.",
+ "type": "boolean",
+ "default": true
+ },
+ "alphabetical": {
+ "description": "Checks if the constructors and/or structure methods are sorted alphabetically.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "funlenSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "lines": {
+ "description": "Limit lines number per function.",
+ "type": "integer",
+ "default": 60
+ },
+ "statements": {
+ "description": "Limit statements number per function.",
+ "type": "integer",
+ "default": 40
+ },
+ "ignore-comments": {
+ "description": "Ignore comments when counting lines.",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "gciSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "sections": {
+ "description": "Section configuration to compare against.",
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "enum": [
+ "standard",
+ "default",
+ "blank",
+ "dot",
+ "alias",
+ "localmodule"
+ ]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ },
+ "default": ["standard", "default"]
+ },
+ "no-inline-comments": {
+ "description": "Checks that no inline Comments are present.",
+ "type": "boolean",
+ "default": false
+ },
+ "no-prefix-comments": {
+ "description": "Checks that no prefix Comments(comment lines above an import) are present.",
+ "type": "boolean",
+ "default": false
+ },
+ "custom-order": {
+ "description": "Enable custom order of sections.",
+ "type": "boolean",
+ "default": false
+ },
+ "no-lex-order": {
+ "description": "Drops lexical ordering for custom sections.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "ginkgolinterSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "suppress-len-assertion": {
+ "description": "Suppress the wrong length assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-nil-assertion": {
+ "description": "Suppress the wrong nil assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-err-assertion": {
+ "description": "Suppress the wrong error assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-compare-assertion": {
+ "description": "Suppress the wrong comparison assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-async-assertion": {
+ "description": "Suppress the function all in async assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-type-compare-assertion": {
+ "description": "Suppress warning for comparing values from different types, like int32 and uint32.",
+ "type": "boolean",
+ "default": false
+ },
+ "forbid-focus-container": {
+ "description": "Trigger warning for ginkgo focus containers like FDescribe, FContext, FWhen or FIt.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-havelen-zero": {
+ "description": "Don't trigger warnings for HaveLen(0).",
+ "type": "boolean",
+ "default": false
+ },
+ "force-expect-to": {
+ "description": "Force using `Expect` with `To`, `ToNot` or `NotTo`",
+ "type": "boolean",
+ "default": false
+ },
+ "validate-async-intervals": {
+ "description": "Best effort validation of async intervals (timeout and polling).",
+ "type": "boolean",
+ "default": false
+ },
+ "forbid-spec-pollution": {
+ "description": "Trigger a warning for variable assignments in ginkgo containers like `Describe`, `Context` and `When`, instead of in `BeforeEach()`.",
+ "type": "boolean",
+ "default": false
+ },
+ "force-succeed": {
+ "description": "Force using the Succeed matcher for error functions, and the HaveOccurred matcher for non-function error values.",
+ "type": "boolean",
+ "default": false
+ },
+ "force-assertion-description": {
+ "description": "Force adding assertion descriptions to gomega matchers.",
+ "type": "boolean",
+ "default": false
+ },
+ "force-tonot": {
+ "description": "Force using `ToNot`, `ShouldNot` instead of `To(Not())`.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "gochecksumtypeSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "default-signifies-exhaustive": {
+ "description": "Presence of `default` case in switch statements satisfies exhaustiveness, if all members are not listed.",
+ "type": "boolean",
+ "default": true
+ },
+ "include-shared-interfaces": {
+ "description": "Include shared interfaces in the exhaustiviness check.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "gocognitSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "min-complexity": {
+ "description": "Minimal code complexity to report (we recommend 10-20).",
+ "type": "integer",
+ "default": 30
+ }
+ }
+ },
+ "goconstSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "match-constant": {
+ "description": "Look for existing constants matching the values",
+ "type": "boolean",
+ "default": true
+ },
+ "min-len": {
+ "description": "Minimum length of string constant.",
+ "type": "integer",
+ "default": 3
+ },
+ "min-occurrences": {
+ "description": "Minimum occurrences count to trigger.",
+ "type": "integer",
+ "default": 3
+ },
+ "ignore-calls": {
+ "description": "Ignore when constant is not used as function argument",
+ "type": "boolean",
+ "default": true
+ },
+ "ignore-string-values": {
+ "description": "Exclude strings matching the given regular expression",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "numbers": {
+ "description": "Search also for duplicated numbers.",
+ "type": "boolean",
+ "default": false
+ },
+ "min": {
+ "description": "Minimum value, only works with `numbers`",
+ "type": "integer",
+ "default": 3
+ },
+ "max": {
+ "description": "Maximum value, only works with `numbers`",
+ "type": "integer",
+ "default": 3
+ },
+ "find-duplicates": {
+ "description": "Detects constants with identical values",
+ "type": "boolean",
+ "default": false
+ },
+ "eval-const-expressions": {
+ "description": "Evaluates of constant expressions like Prefix + \"suffix\"",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "gocriticSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "enabled-checks": {
+ "description": "Which checks should be enabled. By default, a list of stable checks is used. To see it, run `GL_DEBUG=gocritic golangci-lint run`.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/gocritic-checks"
+ }
+ },
+ "disabled-checks": {
+ "description": "Which checks should be disabled.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/gocritic-checks"
+ },
+ "default": []
+ },
+ "enabled-tags": {
+ "description": "Enable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/gocritic-tags"
+ }
+ },
+ "disabled-tags": {
+ "description": "Disable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/gocritic-tags"
+ }
+ },
+ "settings": {
+ "description": "Settings passed to gocritic. Properties must be valid and enabled check names.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "captLocal": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "paramsOnly" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "commentedOutCode": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "minLength" : {
+ "type": "number",
+ "default": 15
+ }
+ }
+ },
+ "elseif": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skipBalanced" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "hugeParam": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "sizeThreshold" : {
+ "type": "number",
+ "default": 80
+ }
+ }
+ },
+ "ifElseChain": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "minThreshold" : {
+ "type": "number",
+ "default": 2
+ }
+ }
+ },
+ "nestingReduce": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "bodyWidth" : {
+ "type": "number",
+ "default": 5
+ }
+ }
+ },
+ "rangeExprCopy": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "sizeThreshold" : {
+ "type": "number",
+ "default": 512
+ },
+ "skipTestFuncs" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "rangeValCopy": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "sizeThreshold" : {
+ "type": "number",
+ "default": 128
+ },
+ "skipTestFuncs" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "ruleguard": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "debug" : {
+ "type": "string"
+ },
+ "enable" : {
+ "type": "string"
+ },
+ "disable" : {
+ "type": "string"
+ },
+ "failOn" : {
+ "type": "string"
+ },
+ "rules" : {
+ "type": "string"
+ }
+ }
+ },
+ "tooManyResultsChecker": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "maxResults" : {
+ "type": "number",
+ "default": 5
+ }
+ }
+ },
+ "truncateCmp": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skipArchDependent" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "underef": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skipRecvDeref" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "unnamedResult": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "checkExported" : {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ }
+ }
+ },
+ "disable-all": {
+ "type": "boolean",
+ "default": false
+ },
+ "enable-all": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "gocycloSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "min-complexity": {
+ "description": "Minimum code complexity to report (we recommend 10-20).",
+ "type": "integer",
+ "default": 30
+ }
+ }
+ },
+ "godoclintSettings": {
+ "type": "object",
+ "properties": {
+ "default": {
+ "type": "string",
+ "enum": ["all", "basic", "none"],
+ "default": "basic",
+ "description": "Default set of rules to enable."
+ },
+ "enable": {
+ "description": "List of rules to enable in addition to the default set.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "$ref": "#/definitions/godoclint-rules"
+ }
+ },
+ "disable": {
+ "description": "List of rules to disable.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "$ref": "#/definitions/godoclint-rules"
+ }
+ },
+ "options": {
+ "type": "object",
+ "description": "A map for setting individual rule options.",
+ "properties": {
+ "max-len": {
+ "type": "object",
+ "properties": {
+ "length": {
+ "type": "integer",
+ "description": "Maximum line length for godocs, not including the `//`, `/*` or `*/` tokens.",
+ "default": 77
+ }
+ }
+ },
+ "require-doc": {
+ "type": "object",
+ "properties": {
+ "ignore-exported": {
+ "type": "boolean",
+ "description": "Ignore exported (public) symbols when applying the `require-doc` rule.",
+ "default": false
+ },
+ "ignore-unexported": {
+ "type": "boolean",
+ "description": "Ignore unexported (private) symbols when applying the `require-doc` rule.",
+ "default": true
+ }
+ }
+ },
+ "start-with-name": {
+ "type": "object",
+ "properties": {
+ "include-unexported": {
+ "type": "boolean",
+ "description": "Include unexported symbols when applying the `start-with-name` rule.",
+ "default": false
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "godotSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "scope": {
+ "description": "Comments to be checked.",
+ "enum": ["declarations", "toplevel", "all", "noinline"],
+ "default": "declarations"
+ },
+ "exclude": {
+ "description": "List of regexps for excluding particular comment lines from check.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "period": {
+ "description": "Check that each sentence ends with a period.",
+ "type": "boolean",
+ "default": true
+ },
+ "capital": {
+ "description": "Check that each sentence starts with a capital letter.",
+ "type": "boolean",
+ "default": false
+ },
+ "check-all": {
+ "description": "DEPRECATED: Check all top-level comments, not only declarations.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "godoxSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "keywords": {
+ "description": "Report any comments starting with one of these keywords. This is useful for TODO or FIXME comments that might be left in the code accidentally and should be resolved before merging.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "default": ["TODO", "BUG", "FIXME"]
+ }
+ }
+ },
+ "gofmtSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "simplify": {
+ "description": "Simplify code.",
+ "type": "boolean",
+ "default": true
+ },
+ "rewrite-rules": {
+ "description": "Apply the rewrite rules to the source before reformatting.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "pattern": {
+ "type": "string"
+ },
+ "replacement": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "golinesSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-len": {
+ "type": "integer",
+ "default": 100
+ },
+ "tab-len": {
+ "type": "integer",
+ "default": 4
+ },
+ "shorten-comments": {
+ "type": "boolean",
+ "default": false
+ },
+ "reformat-tags": {
+ "type": "boolean",
+ "default": true
+ },
+ "chain-split-dots": {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "interfacebloatSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max": {
+ "description": "The maximum number of methods allowed for an interface.",
+ "type": "integer"
+ }
+ }
+ },
+ "gofumptSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "extra-rules": {
+ "description": "Choose whether or not to use the extra rules that are disabled by default.",
+ "type": "boolean",
+ "default": false
+ },
+ "module-path": {
+ "description": " Module path which contains the source code being formatted.",
+ "type": "string"
+ }
+ }
+ },
+ "goheaderSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "values": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "const": {
+ "description": "Constants to use in the template.",
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "description": "Value for the constant.",
+ "type": "string"
+ }
+ },
+ "additionalProperties": false,
+ "examples": [
+ {
+ "YEAR": "2030",
+ "COMPANY": "MY FUTURISTIC COMPANY"
+ }
+ ]
+ },
+ "regexp": {
+ "description": "Regular expressions to use in your template.",
+ "type": "object",
+ "additionalProperties": false,
+ "patternProperties": {
+ "^.+$": {
+ "type": "string"
+ }
+ },
+ "examples": [
+ {
+ "AUTHOR": ".*@mycompany\\.com"
+ }
+ ]
+ }
+ }
+ },
+ "template": {
+ "description": "Template to put on top of every file.",
+ "type": "string",
+ "examples": [
+ "{{ MY COMPANY }}\nSPDX-License-Identifier: Apache-2.0\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at:\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License."
+ ]
+ },
+ "template-path": {
+ "description": "Path to the file containing the template source.",
+ "type": "string",
+ "examples": ["my_header_template.txt"]
+ }
+ },
+ "oneOf": [
+ { "required": ["template"] },
+ { "required": ["template-path"] }
+ ]
+ },
+ "goimportsSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "local-prefixes": {
+ "description": "Put imports beginning with prefix after 3rd-party packages. It is a list of prefixes.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "gomoddirectivesSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "replace-local": {
+ "description": "Allow local `replace` directives.",
+ "type": "boolean",
+ "default": true
+ },
+ "replace-allow-list": {
+ "description": "List of allowed `replace` directives.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "retract-allow-no-explanation": {
+ "description": "Allow to not explain why the version has been retracted in the `retract` directives.",
+ "type": "boolean",
+ "default": false
+ },
+ "exclude-forbidden": {
+ "description": "Forbid the use of the `exclude` directives.",
+ "type": "boolean",
+ "default": false
+ },
+ "ignore-forbidden": {
+ "description": "Forbid the use of the `ignore` directives. (>= go1.25)",
+ "type": "boolean",
+ "default": false
+ },
+ "toolchain-forbidden": {
+ "description": "Forbid the use of the `toolchain` directive.",
+ "type": "boolean",
+ "default": false
+ },
+ "toolchain-pattern": {
+ "description": "Defines a pattern to validate `toolchain` directive.",
+ "type": "string"
+ },
+ "tool-forbidden": {
+ "description": "Forbid the use of the `tool` directives.",
+ "type": "boolean",
+ "default": false
+ },
+ "go-debug-forbidden": {
+ "description": "Forbid the use of the `godebug` directive.",
+ "type": "boolean",
+ "default": false
+ },
+ "go-version-pattern": {
+ "description": "Defines a pattern to validate `go` minimum version directive.",
+ "type": "string",
+ "default": ""
+ },
+ "check-module-path": {
+ "description": "Check the validity of the module path.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "gomodguardSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "allowed": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "modules": {
+ "description": "List of allowed modules.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["gopkg.in/yaml.v2"]
+ }
+ },
+ "domains": {
+ "description": "List of allowed module domains.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["golang.org"]
+ }
+ }
+ }
+ },
+ "blocked": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "modules": {
+ "description": "List of blocked modules.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "recommendations": {
+ "description": "Recommended modules that should be used instead.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "reason": {
+ "description": "Reason why the recommended module should be used.",
+ "type": "string"
+ }
+ }
+ }
+ },
+ "additionalProperties": false
+ }
+ },
+ "versions": {
+ "description": "List of blocked module version constraints.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "patternProperties": {
+ "^.*$": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "version": {
+ "description": "Version constraint.",
+ "type": "string"
+ },
+ "reason": {
+ "description": "Reason why the version constraint exists.",
+ "type": "string"
+ }
+ },
+ "required": ["reason"]
+ }
+ }
+ }
+ },
+ "local-replace-directives": {
+ "description": "Raise lint issues if loading local path with replace directive",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ }
+ }
+ },
+ "gosecSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "includes": {
+ "type": "array",
+ "description": "To select a subset of rules to run",
+ "examples": [["G401"]],
+ "items": {
+ "$ref": "#/definitions/gosec-rules"
+ }
+ },
+ "excludes": {
+ "type": "array",
+ "description": "To specify a set of rules to explicitly exclude",
+ "examples": [["G401"]],
+ "items": {
+ "$ref": "#/definitions/gosec-rules"
+ }
+ },
+ "severity": {
+ "description": "Filter out the issues with a lower severity than the given value",
+ "type": "string",
+ "enum": ["low", "medium", "high"],
+ "default": "low"
+ },
+ "confidence": {
+ "description": "Filter out the issues with a lower confidence than the given value",
+ "type": "string",
+ "enum": ["low", "medium", "high"],
+ "default": "low"
+ },
+ "config": {
+ "description": "To specify the configuration of rules",
+ "type": "object"
+ },
+ "concurrency": {
+ "description": "Concurrency value",
+ "type": "integer"
+ }
+ }
+ },
+ "gosmopolitanSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "allow-time-local": {
+ "description": "Allow and ignore `time.Local` usages.",
+ "type": "boolean",
+ "default": false
+ },
+ "escape-hatches": {
+ "description": "List of fully qualified names in the `full/pkg/path.name` form, to act as \"i18n escape hatches\".",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "watch-for-scripts": {
+ "description": "List of Unicode scripts to watch for any usage in string literals.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "govetSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "settings": {
+ "description": "Settings per analyzer. Map of analyzer name to specific settings.\nRun `go tool vet help` to find out more.",
+ "type": "object",
+ "propertyNames": {
+ "$ref": "#/definitions/govet-analyzers"
+ },
+ "patternProperties": {
+ "^.*$": {
+ "description": "Run `go tool vet help ` to see all settings.",
+ "type": "object"
+ }
+ }
+ },
+ "enable": {
+ "description": "Enable analyzers by name.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/govet-analyzers"
+ }
+ },
+ "disable": {
+ "description": "Disable analyzers by name.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/govet-analyzers"
+ }
+ },
+ "enable-all": {
+ "description": "Enable all analyzers.",
+ "type": "boolean",
+ "default": false
+ },
+ "disable-all": {
+ "description": "Disable all analyzers.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "grouperSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "const-require-single-const": {
+ "type": "boolean",
+ "default": false
+ },
+ "const-require-grouping": {
+ "type": "boolean",
+ "default": false
+ },
+ "import-require-single-import": {
+ "type": "boolean",
+ "default": false
+ },
+ "import-require-grouping": {
+ "type": "boolean",
+ "default": false
+ },
+ "type-require-single-type": {
+ "type": "boolean",
+ "default": false
+ },
+ "type-require-grouping": {
+ "type": "boolean",
+ "default": false
+ },
+ "var-require-single-var": {
+ "type": "boolean",
+ "default": false
+ },
+ "var-require-grouping": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "ifaceSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "enable": {
+ "description": "Enable analyzers by name.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/iface-analyzers"
+ }
+ },
+ "settings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "unused": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "exclude": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "importasSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "no-unaliased": {
+ "description": "Do not allow unaliased imports of aliased packages.",
+ "type": "boolean",
+ "default": false
+ },
+ "no-extra-aliases": {
+ "description": "Do not allow non-required aliases.",
+ "type": "boolean",
+ "default": false
+ },
+ "alias": {
+ "description": "List of aliases",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "pkg": {
+ "description": "Package path e.g. knative.dev/serving/pkg/apis/autoscaling/v1alpha1",
+ "type": "string"
+ },
+ "alias": {
+ "description": "Package alias e.g. autoscalingv1alpha1",
+ "type": "string"
+ }
+ },
+ "required": ["pkg", "alias"]
+ }
+ }
+ }
+ },
+ "inamedparamSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skip-single-param": {
+ "description": "Skips check for interface methods with only a single parameter.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "ineffassignSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-escaping-errors": {
+ "description": "Check escaping variables of type error, may cause false positives.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "iotamixingSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "report-individual": {
+ "description": "Whether to report individual consts rather than just the const block.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "ireturnSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "description": "Use either `reject` or `allow` properties for interfaces matching.",
+ "properties": {
+ "allow": {
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "enum": ["anon", "error", "empty", "stdlib"]
+ }
+ ]
+ }
+ },
+ "reject": {
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "enum": ["anon", "error", "empty", "stdlib"]
+ }
+ ]
+ }
+ }
+ },
+ "anyOf": [
+ {
+ "not": {
+ "properties": {
+ "allow": {
+ "const": "reject"
+ }
+ }
+ },
+ "required": ["allow"]
+ },
+ {
+ "required": ["reject"]
+ }
+ ]
+ },
+ "lllSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "tab-width": {
+ "description": "Width of \"\\t\" in spaces.",
+ "type": "integer",
+ "minimum": 0,
+ "default": 1
+ },
+ "line-length": {
+ "description": "Maximum allowed line length, lines longer will be reported.",
+ "type": "integer",
+ "minimum": 1,
+ "default": 120
+ }
+ }
+ },
+ "maintidxSettings": {
+ "description": "Maintainability index https://docs.microsoft.com/en-us/visualstudio/code-quality/code-metrics-maintainability-index-range-and-meaning?view=vs-2022",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "under": {
+ "description": "Minimum accatpable maintainability index level (see https://docs.microsoft.com/en-us/visualstudio/code-quality/code-metrics-maintainability-index-range-and-meaning?view=vs-2022)",
+ "type": "number",
+ "default": 20
+ }
+ }
+ },
+ "makezeroSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "always": {
+ "description": "Allow only slices initialized with a length of zero.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "loggercheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "kitlog": {
+ "description": "Allow check for the github.com/go-kit/log library.",
+ "type": "boolean",
+ "default": true
+ },
+ "klog": {
+ "description": "Allow check for the k8s.io/klog/v2 library.",
+ "type": "boolean",
+ "default": true
+ },
+ "logr": {
+ "description": "Allow check for the github.com/go-logr/logr library.",
+ "type": "boolean",
+ "default": true
+ },
+ "slog": {
+ "description": "Allow check for the log/slog library.",
+ "type": "boolean",
+ "default": true
+ },
+ "zap": {
+ "description": "Allow check for the \"sugar logger\" from go.uber.org/zap library.",
+ "type": "boolean",
+ "default": true
+ },
+ "require-string-key": {
+ "description": "Require all logging keys to be inlined constant strings.",
+ "type": "boolean",
+ "default": false
+ },
+ "no-printf-like": {
+ "description": "Require printf-like format specifier (%s, %d for example) not present.",
+ "type": "boolean",
+ "default": false
+ },
+ "rules": {
+ "description": "List of custom rules to check against, where each rule is a single logger pattern, useful for wrapped loggers.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "misspellSettings": {
+ "description": "Correct spellings using locale preferences for US or UK. Default is to use a neutral variety of English.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "locale": {
+ "enum": ["US", "UK"]
+ },
+ "ignore-rules": {
+ "description": "List of rules to ignore.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "mode": {
+ "description": "Mode of the analysis.",
+ "enum": ["restricted", "", "default"],
+ "default": ""
+ },
+ "extra-words": {
+ "description": "Extra word corrections.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "correction": {
+ "type": "string"
+ },
+ "typo": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "musttagSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "functions": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "tag": {
+ "type": "string"
+ },
+ "arg-pos": {
+ "type": "integer"
+ }
+ }
+ }
+ }
+ }
+ },
+ "nakedretSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-func-lines": {
+ "description": "Report if a function has more lines of code than this value and it has naked returns.",
+ "type": "integer",
+ "minimum": 0,
+ "default": 30
+ }
+ }
+ },
+ "nestifSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "min-complexity": {
+ "description": "Minimum complexity of \"if\" statements to report.",
+ "type": "integer",
+ "default": 5
+ }
+ }
+ },
+ "nilnilSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "only-two": {
+ "type": "boolean",
+ "description": "To check functions with only two return values.",
+ "default": true
+ },
+ "detect-opposite": {
+ "type": "boolean",
+ "description": "In addition, detect opposite situation (simultaneous return of non-nil error and valid value).",
+ "default": false
+ },
+ "checked-types": {
+ "type": "array",
+ "description": "List of return types to check.",
+ "items": {
+ "enum": ["chan", "func", "iface", "map", "ptr", "uintptr", "unsafeptr"]
+ },
+ "default": ["chan", "func", "iface", "map", "ptr", "uintptr", "unsafeptr"]
+ }
+ }
+ },
+ "nlreturnSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "block-size": {
+ "description": "set block size that is still ok",
+ "type": "number",
+ "default": 0,
+ "minimum": 0
+ }
+ }
+ },
+ "mndSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignored-files": {
+ "description": "List of file patterns to exclude from analysis.",
+ "examples": [["magic1_.*.go"]],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignored-functions": {
+ "description": "Comma-separated list of function patterns to exclude from the analysis.",
+ "examples": [["math.*", "http.StatusText", "make"]],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignored-numbers": {
+ "description": "List of numbers to exclude from analysis.",
+ "examples": [["1000", "1234_567_890", "3.14159264"]],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "checks": {
+ "description": "The list of enabled checks, see https://github.com/tommy-muehle/go-mnd/#checks for description.",
+ "type": "array",
+ "items": {
+ "enum": [
+ "argument",
+ "case",
+ "condition",
+ "operation",
+ "return",
+ "assign"
+ ]
+ }
+ }
+ }
+ },
+ "modernizeSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "disable": {
+ "description": "List of analyzers to disable.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/modernize-analyzers"
+ }
+ }
+ }
+ },
+ "nolintlintSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "allow-unused": {
+ "description": "Enable to ensure that nolint directives are all used.",
+ "type": "boolean",
+ "default": true
+ },
+ "allow-no-explanation": {
+ "description": "Exclude these linters from requiring an explanation.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linter-names"
+ },
+ "default": []
+ },
+ "require-explanation": {
+ "description": "Enable to require an explanation of nonzero length after each nolint directive.",
+ "type": "boolean",
+ "default": false
+ },
+ "require-specific": {
+ "description": "Enable to require nolint directives to mention the specific linter being suppressed.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "reassignSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "patterns": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "recvcheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "disable-builtin": {
+ "description": "Disables the built-in method exclusions.",
+ "type": "boolean",
+ "default": true
+ },
+ "exclusions": {
+ "description": "User-defined method exclusions.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "nonamedreturnsSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "report-error-in-defer": {
+ "description": "Report named error if it is assigned inside defer.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "paralleltestSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignore-missing": {
+ "description": "Ignore missing calls to `t.Parallel()` and only report incorrect uses of it.",
+ "type": "boolean",
+ "default": false
+ },
+ "ignore-missing-subtests": {
+ "description": "Ignore missing calls to `t.Parallel()` in subtests. Top-level tests are still required to have `t.Parallel`, but subtests are allowed to skip it.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "perfsprintSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "integer-format": {
+ "description": "Enable/disable optimization of integer formatting.",
+ "type": "boolean",
+ "default": true
+ },
+ "int-conversion": {
+ "description": "Optimizes even if it requires an int or uint type cast.",
+ "type": "boolean",
+ "default": true
+ },
+ "error-format": {
+ "description": "Enable/disable optimization of error formatting.",
+ "type": "boolean",
+ "default": true
+ },
+ "err-error": {
+ "description": "Optimizes into `err.Error()` even if it is only equivalent for non-nil errors.",
+ "type": "boolean",
+ "default": false
+ },
+ "errorf": {
+ "description": "Optimizes `fmt.Errorf`.",
+ "type": "boolean",
+ "default": true
+ },
+ "string-format": {
+ "description": "Enable/disable optimization of string formatting.",
+ "type": "boolean",
+ "default": true
+ },
+ "sprintf1": {
+ "description": "Optimizes `fmt.Sprintf` with only one argument.",
+ "type": "boolean",
+ "default": true
+ },
+ "strconcat": {
+ "description": "Optimizes into strings concatenation.",
+ "type": "boolean",
+ "default": true
+ },
+ "bool-format": {
+ "description": "Enable/disable optimization of bool formatting.",
+ "type": "boolean",
+ "default": true
+ },
+ "hex-format": {
+ "description": "Enable/disable optimization of hex formatting.",
+ "type": "boolean",
+ "default": true
+ },
+ "concat-loop": {
+ "description": "Enable/disable optimization of concat loop.",
+ "type": "boolean",
+ "default": true
+ },
+ "loop-other-ops": {
+ "description": "Optimization of `concat-loop` even with other operations.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "preallocSettings": {
+ "description": "We do not recommend using this linter before doing performance profiling.\nFor most programs usage of `prealloc` will be premature optimization.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "simple": {
+ "description": "Report preallocation suggestions only on simple loops that have no returns/breaks/continues/gotos in them.",
+ "type": "boolean",
+ "default": true
+ },
+ "range-loops": {
+ "description": "Report preallocation suggestions on range loops.",
+ "type": "boolean",
+ "default": true
+ },
+ "for-loops": {
+ "description": "Report preallocation suggestions on for loops.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "predeclaredSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignore": {
+ "description": "List of predeclared identifiers to not report on.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "qualified-name": {
+ "description": "Include method names and field names in checks.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "promlinterSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "strict": {},
+ "disabled-linters": {
+ "type": "array",
+ "items": {
+ "enum": [
+ "Help",
+ "MetricUnits",
+ "Counter",
+ "HistogramSummaryReserved",
+ "MetricTypeInName",
+ "ReservedChars",
+ "CamelCase",
+ "UnitAbbreviations"
+ ]
+ }
+ }
+ }
+ },
+ "protogetterSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skip-generated-by": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["protoc-gen-go-my-own-generator"]
+ }
+ },
+ "skip-files": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["*.pb.go"]
+ }
+ },
+ "skip-any-generated": {
+ "description": "Skip any generated files from the checking.",
+ "type": "boolean",
+ "default": false
+ },
+ "replace-first-arg-in-append": {
+ "description": "Skip first argument of append function.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "reviveSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "examples": [
+ {
+ "ignore-generated-header": true,
+ "severity": "warning",
+ "rules": [
+ {
+ "name": "indent-error-flow",
+ "severity": "warning"
+ },
+ {
+ "name": "add-constant",
+ "severity": "warning",
+ "arguments": [
+ {
+ "maxLitCount": "3",
+ "allowStrs": "\"\"",
+ "allowInts": "0,1,2",
+ "allowFloats": "0.0,0.,1.0,1.,2.0,2."
+ }
+ ]
+ }
+ ]
+ }
+ ],
+ "properties": {
+ "max-open-files": {
+ "type": "integer"
+ },
+ "confidence": {
+ "type": "number"
+ },
+ "severity": {
+ "type": "string",
+ "enum": ["warning", "error"]
+ },
+ "enable-all-rules": {
+ "type": "boolean",
+ "default": false
+ },
+ "enable-default-rules": {
+ "type": "boolean",
+ "default": false
+ },
+ "directives": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "name": {
+ "type": "string",
+ "enum": ["specify-disable-reason"]
+ },
+ "severity": {
+ "type": "string",
+ "enum": ["warning", "error"]
+ },
+ "exclude": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "arguments": {
+ "type": "array"
+ }
+ }
+ }
+ },
+ "rules": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["name"],
+ "properties": {
+ "name": {
+ "$ref": "#/definitions/revive-rules",
+ "title": "The rule name"
+ },
+ "disabled": {
+ "type": "boolean"
+ },
+ "severity": {
+ "type": "string",
+ "enum": ["warning", "error"]
+ },
+ "exclude": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "arguments": {
+ "type": "array"
+ }
+ }
+ }
+ }
+ }
+ },
+ "rowserrcheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "packages": {
+ "type": "array",
+ "items": {
+ "description": "",
+ "type": "string",
+ "examples": ["github.com/jmoiron/sqlx"]
+ }
+ }
+ }
+ },
+ "sloglintSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "kv-only": {
+ "description": "Enforce using key-value pairs only (incompatible with attr-only).",
+ "type": "boolean",
+ "default": false
+ },
+ "no-global": {
+ "description": "Enforce not using global loggers.",
+ "enum": ["", "all", "default"],
+ "default": ""
+ },
+ "no-mixed-args": {
+ "description": "Enforce not mixing key-value pairs and attributes.",
+ "type": "boolean",
+ "default": true
+ },
+ "context": {
+ "description": "Enforce using methods that accept a context.",
+ "enum": ["", "all", "scope"],
+ "default": ""
+ },
+ "static-msg": {
+ "description": "Enforce using static values for log messages.",
+ "type": "boolean",
+ "default": false
+ },
+ "msg-style": {
+ "description": "Enforce message style.",
+ "enum": ["", "lowercased", "capitalized"],
+ "default": ""
+ },
+ "key-naming-case": {
+ "description": "Enforce a single key naming convention.",
+ "enum": ["snake", "kebab", "camel", "pascal"]
+ },
+ "attr-only": {
+ "description": "Enforce using attributes only (incompatible with kv-only).",
+ "type": "boolean",
+ "default": false
+ },
+ "no-raw-keys": {
+ "description": "Enforce using constants instead of raw keys.",
+ "type": "boolean",
+ "default": false
+ },
+ "forbidden-keys": {
+ "description": "Enforce not using specific keys.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "args-on-sep-lines": {
+ "description": "Enforce putting arguments on separate lines.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "spancheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "checks": {
+ "description": "Checks to enable.",
+ "type": "array",
+ "items": {
+ "enum": ["end", "record-error", "set-status"]
+ }
+ },
+ "ignore-check-signatures": {
+ "description": "A list of regexes for function signatures that silence `record-error` and `set-status` reports if found in the call path to a returned error.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "extra-start-span-signatures": {
+ "description": "A list of regexes for additional function signatures that create spans.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "staticcheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "checks": {
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "$ref": "#/definitions/staticcheck-checks"
+ },
+ {
+ "type": "string"
+ }
+ ]
+ }
+ },
+ "dot-import-whitelist": {
+ "description": "By default, ST1001 forbids all uses of dot imports in non-test packages. This setting allows setting a whitelist of import paths that can be dot-imported anywhere.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "http-status-code-whitelist": {
+ "description": "ST1013 recommends using constants from the net/http package instead of hard-coding numeric HTTP status codes. This setting specifies a list of numeric status codes that this check does not complain about.",
+ "default": ["200", "400", "404", "500"],
+ "type": "array",
+ "items": {
+ "enum": [
+ "100",
+ "101",
+ "102",
+ "103",
+ "200",
+ "201",
+ "202",
+ "203",
+ "204",
+ "205",
+ "206",
+ "207",
+ "208",
+ "226",
+ "300",
+ "301",
+ "302",
+ "303",
+ "304",
+ "305",
+ "306",
+ "307",
+ "308",
+ "400",
+ "401",
+ "402",
+ "403",
+ "404",
+ "405",
+ "406",
+ "407",
+ "408",
+ "409",
+ "410",
+ "411",
+ "412",
+ "413",
+ "414",
+ "415",
+ "416",
+ "417",
+ "418",
+ "421",
+ "422",
+ "423",
+ "424",
+ "425",
+ "426",
+ "428",
+ "429",
+ "431",
+ "451",
+ "500",
+ "501",
+ "502",
+ "503",
+ "504",
+ "505",
+ "506",
+ "507",
+ "508",
+ "510",
+ "511"
+ ]
+ }
+ },
+ "initialisms": {
+ "description": "ST1003 check, among other things, for the correct capitalization of initialisms. The set of known initialisms can be configured with this option.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "default": [
+ "ACL",
+ "API",
+ "ASCII",
+ "CPU",
+ "CSS",
+ "DNS",
+ "EOF",
+ "GUID",
+ "HTML",
+ "HTTP",
+ "HTTPS",
+ "ID",
+ "IP",
+ "JSON",
+ "QPS",
+ "RAM",
+ "RPC",
+ "SLA",
+ "SMTP",
+ "SQL",
+ "SSH",
+ "TCP",
+ "TLS",
+ "TTL",
+ "UDP",
+ "UI",
+ "GID",
+ "UID",
+ "UUID",
+ "URI",
+ "URL",
+ "UTF8",
+ "VM",
+ "XML",
+ "XMPP",
+ "XSRF",
+ "XSS",
+ "SIP",
+ "RTP",
+ "AMQP",
+ "DB",
+ "TS"
+ ]
+ }
+ }
+ }
+ },
+ "tagalignSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "align": {
+ "description": "Align and sort can be used together or separately.",
+ "type": "boolean",
+ "default": true
+ },
+ "sort": {
+ "description": "Whether enable tags sort.",
+ "type": "boolean",
+ "default": true
+ },
+ "order": {
+ "description": "Specify the order of tags, the other tags will be sorted by name.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "default": [],
+ "examples": [
+ [
+ "json",
+ "yaml",
+ "yml",
+ "toml",
+ "mapstructure",
+ "binding",
+ "validate"
+ ]
+ ]
+ },
+ "strict": {
+ "description": "Whether enable strict style.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "tagliatelleSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "case": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "use-field-name": {
+ "description": "Use the struct field name to check the name of the struct tag.",
+ "type": "boolean",
+ "default": false
+ },
+ "ignored-fields": {
+ "description": "The field names to ignore.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["example"]
+ }
+ },
+ "rules": {
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "$ref": "#/definitions/tagliatelle-cases"
+ }
+ }
+ },
+ "extended-rules": {
+ "description": "Defines the association between tag name and case.",
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["case"],
+ "properties": {
+ "case": {
+ "$ref": "#/definitions/tagliatelle-cases"
+ },
+ "extra-initialisms": {
+ "type": "boolean",
+ "default": false
+ },
+ "initialism-overrides": {
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "overrides": {
+ "description": "Overrides the default/root configuration.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["pkg"],
+ "properties": {
+ "pkg": {
+ "description": "A package path.",
+ "type": "string"
+ },
+ "use-field-name": {
+ "description": "Use the struct field name to check the name of the struct tag.",
+ "type": "boolean",
+ "default": false
+ },
+ "ignored-fields": {
+ "description": "The field names to ignore.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["example"]
+ }
+ },
+ "ignore": {
+ "description": "Ignore the package (takes precedence over all other configurations).",
+ "type": "boolean",
+ "default": false
+ },
+ "rules": {
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "$ref": "#/definitions/tagliatelle-cases"
+ }
+ }
+ },
+ "extended-rules": {
+ "description": "Defines the association between tag name and case.",
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["case"],
+ "properties": {
+ "case": {
+ "$ref": "#/definitions/tagliatelle-cases"
+ },
+ "extra-initialisms": {
+ "type": "boolean",
+ "default": false
+ },
+ "initialism-overrides": {
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "testifylintSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "enable-all": {
+ "description": "Enable all checkers.",
+ "type": "boolean",
+ "default": false
+ },
+ "disable-all": {
+ "description": "Disable all checkers.",
+ "type": "boolean",
+ "default": false
+ },
+ "enable": {
+ "description": "Enable specific checkers.",
+ "type": "array",
+ "items": {
+ "enum": [
+ "blank-import",
+ "bool-compare",
+ "compares",
+ "contains",
+ "empty",
+ "encoded-compare",
+ "equal-values",
+ "error-is-as",
+ "error-nil",
+ "expected-actual",
+ "float-compare",
+ "formatter",
+ "go-require",
+ "len",
+ "negative-positive",
+ "nil-compare",
+ "regexp",
+ "require-error",
+ "suite-broken-parallel",
+ "suite-dont-use-pkg",
+ "suite-extra-assert-call",
+ "suite-method-signature",
+ "suite-subtest-run",
+ "suite-thelper",
+ "useless-assert"
+ ]
+ },
+ "default": [
+ "blank-import",
+ "bool-compare",
+ "compares",
+ "contains",
+ "empty",
+ "encoded-compare",
+ "equal-values",
+ "error-is-as",
+ "error-nil",
+ "expected-actual",
+ "float-compare",
+ "formatter",
+ "go-require",
+ "len",
+ "negative-positive",
+ "nil-compare",
+ "regexp",
+ "require-error",
+ "suite-broken-parallel",
+ "suite-dont-use-pkg",
+ "suite-extra-assert-call",
+ "suite-method-signature",
+ "suite-subtest-run",
+ "useless-assert"
+ ]
+ },
+ "disable": {
+ "description": "Disable specific checkers.",
+ "type": "array",
+ "items": {
+ "enum": [
+ "blank-import",
+ "bool-compare",
+ "compares",
+ "contains",
+ "empty",
+ "encoded-compare",
+ "equal-values",
+ "error-is-as",
+ "error-nil",
+ "expected-actual",
+ "float-compare",
+ "formatter",
+ "go-require",
+ "len",
+ "negative-positive",
+ "nil-compare",
+ "regexp",
+ "require-error",
+ "suite-broken-parallel",
+ "suite-dont-use-pkg",
+ "suite-extra-assert-call",
+ "suite-method-signature",
+ "suite-subtest-run",
+ "suite-thelper",
+ "useless-assert"
+ ],
+ "default": [
+ "suite-thelper"
+ ]
+ }
+ },
+ "bool-compare": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignore-custom-types": {
+ "description": "To ignore user defined types (over builtin bool).",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "expected-actual": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "pattern": {
+ "description": "Regexp for expected variable name.",
+ "type": "string",
+ "default": "(^(exp(ected)?|want(ed)?)([A-Z]\\w*)?$)|(^(\\w*[a-z])?(Exp(ected)?|Want(ed)?)$)"
+ }
+ }
+ },
+ "formatter": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-format-string": {
+ "description": "To enable go vet's printf checks.",
+ "type": "boolean",
+ "default": true
+ },
+ "require-f-funcs": {
+ "description": "To require f-assertions (e.g. assert.Equalf) if format string is used, even if there are no variable-length variables.",
+ "type": "boolean",
+ "default": false
+ },
+ "require-string-msg": {
+ "description": "To require that the first element of msgAndArgs (msg) has a string type.",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "go-require": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignore-http-handlers": {
+ "description": "To ignore HTTP handlers (like http.HandlerFunc).",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "require-error": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "fn-pattern": {
+ "description": "Regexp for assertions to analyze. If defined, then only matched error assertions will be reported.",
+ "type": "string",
+ "default": ""
+ }
+ }
+ },
+ "suite-extra-assert-call": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "mode": {
+ "description": "To require or remove extra Assert() call?",
+ "type": "string",
+ "enum": ["remove", "require"],
+ "default": "remove"
+ }
+ }
+ }
+ }
+ },
+ "testpackageSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skip-regexp": {
+ "description": "Files with names matching this regular expression are skipped.",
+ "type": "string",
+ "examples": ["(export|internal)_test\\.go"]
+ },
+ "allow-packages": {
+ "description": "List of packages that don't end with _test that tests are allowed to be in.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["example"]
+ }
+ }
+ }
+ },
+ "thelperSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "test": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "begin": {
+ "description": "Check if `t.Helper()` begins helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "first": {
+ "description": "Check if *testing.T is first param of helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "name": {
+ "description": "Check if *testing.T param has t name.",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ },
+ "benchmark": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "begin": {
+ "description": "Check if `b.Helper()` begins helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "first": {
+ "description": "Check if *testing.B is first param of helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "name": {
+ "description": "Check if *testing.B param has b name.",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ },
+ "tb": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "begin": {
+ "description": "Check if `tb.Helper()` begins helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "first": {
+ "description": "Check if *testing.TB is first param of helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "name": {
+ "description": "Check if *testing.TB param has tb name.",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ },
+ "fuzz": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "begin": {
+ "description": "Check if `f.Helper()` begins helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "first": {
+ "description": "Check if *testing.F is first param of helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "name": {
+ "description": "Check if *testing.F param has f name.",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ }
+ }
+ },
+ "usestdlibvarsSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "http-method": {
+ "description": "Suggest the use of http.MethodXX.",
+ "type": "boolean",
+ "default": true
+ },
+ "http-status-code": {
+ "description": "Suggest the use of http.StatusXX.",
+ "type": "boolean",
+ "default": true
+ },
+ "time-weekday": {
+ "description": "Suggest the use of time.Weekday.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "time-month": {
+ "description": "Suggest the use of time.Month.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "time-layout": {
+ "description": "Suggest the use of time.Layout.",
+ "type": "boolean",
+ "default": false
+ },
+ "time-date-month": {
+ "description": "Suggest the use of time.Month in time.Date.",
+ "type": "boolean",
+ "default": false
+ },
+ "crypto-hash": {
+ "description": "Suggest the use of crypto.Hash.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "default-rpc-path": {
+ "description": "Suggest the use of rpc.DefaultXXPath.",
+ "type": "boolean",
+ "default": false
+ },
+ "sql-isolation-level": {
+ "description": "Suggest the use of sql.LevelXX.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "tls-signature-scheme": {
+ "description": "Suggest the use of tls.SignatureScheme.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "constant-kind": {
+ "description": "Suggest the use of constant.Kind.String().",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "usetestingSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "context-background": {
+ "type": "boolean",
+ "default": false
+ },
+ "context-todo": {
+ "type": "boolean",
+ "default": false
+ },
+ "os-chdir": {
+ "type": "boolean",
+ "default": true
+ },
+ "os-mkdir-temp": {
+ "type": "boolean",
+ "default": true
+ },
+ "os-setenv": {
+ "type": "boolean",
+ "default": true
+ },
+ "os-create-temp": {
+ "type": "boolean",
+ "default": true
+ },
+ "os-temp-dir": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "unconvertSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "fast-math": {
+ "type": "boolean",
+ "default": false
+ },
+ "safe": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "unparamSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-exported": {
+ "description": "Inspect exported functions. Set to true if no external program/library imports your code.\n\nWARNING: if you enable this setting, unparam will report a lot of false-positives in text editors:\nif it's called for subdir of a project it can't find external interfaces. All text editor integrations\nwith golangci-lint call it on a directory with the changed file.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "unqueryvetSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-sql-builders": {
+ "description": "Enable SQL builder checking.",
+ "type": "boolean",
+ "default": true
+ },
+ "check-aliased-wildcard": {
+ "description": "Enable aliased wildcard detection like SELECT t.*.",
+ "type": "boolean",
+ "default": true
+ },
+ "check-string-concat": {
+ "description": "Enable string concatenation analysis.",
+ "type": "boolean",
+ "default": true
+ },
+ "check-format-strings": {
+ "description": "Enable format string analysis like fmt.Sprintf.",
+ "type": "boolean",
+ "default": true
+ },
+ "check-string-builder": {
+ "description": "Enable strings.Builder analysis.",
+ "type": "boolean",
+ "default": true
+ },
+ "check-subqueries": {
+ "description": "Enable subquery analysis.",
+ "type": "boolean",
+ "default": true
+ },
+ "check-n1": {
+ "type": "boolean",
+ "default": false
+ },
+ "check-sql-injection": {
+ "type": "boolean",
+ "default": false
+ },
+ "check-tx-leaks": {
+ "type": "boolean",
+ "default": false
+ },
+ "allowed-patterns": {
+ "description": "Regex patterns for acceptable SELECT * usage.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "allow": {
+ "description": "Allow is a list of SQL patterns to allow (whitelist).",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignored-functions": {
+ "description": "Functions to ignore.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "sql-builders": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "squirrel": {
+ "type": "boolean",
+ "default": true
+ },
+ "gorm": {
+ "type": "boolean",
+ "default": true
+ },
+ "sqlx": {
+ "type": "boolean",
+ "default": true
+ },
+ "ent": {
+ "type": "boolean",
+ "default": true
+ },
+ "pgx": {
+ "type": "boolean",
+ "default": true
+ },
+ "bun": {
+ "type": "boolean",
+ "default": true
+ },
+ "sqlboiler": {
+ "type": "boolean",
+ "default": true
+ },
+ "jet": {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "custom-rules": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "id": {
+ "type": "string"
+ },
+ "pattern": {
+ "type": "string"
+ },
+ "patterns": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "when": {
+ "type": "string"
+ },
+ "message": {
+ "type": "string"
+ },
+ "action": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "unusedSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "field-writes-are-uses": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ },
+ "post-statements-are-reads": {
+ "description": "",
+ "type": "boolean",
+ "default": false
+ },
+ "exported-fields-are-used": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ },
+ "parameters-are-used": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ },
+ "local-variables-are-used": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ },
+ "generated-is-used": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "varnamelenSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-distance": {
+ "description": "Variables used in at most this N-many lines will be ignored.",
+ "type": "integer",
+ "default": 5
+ },
+ "min-name-length": {
+ "description": "The minimum length of a variable's name that is considered `long`.",
+ "type": "integer",
+ "default": 3
+ },
+ "check-receiver": {
+ "description": "Check method receiver names.",
+ "default": false,
+ "type": "boolean"
+ },
+ "check-return": {
+ "description": "Check named return values.",
+ "default": false,
+ "type": "boolean"
+ },
+ "check-type-param": {
+ "description": "Check type parameters.",
+ "default": false,
+ "type": "boolean"
+ },
+ "ignore-type-assert-ok": {
+ "description": "Ignore `ok` variables that hold the bool return value of a type assertion",
+ "default": false,
+ "type": "boolean"
+ },
+ "ignore-map-index-ok": {
+ "description": "Ignore `ok` variables that hold the bool return value of a map index.",
+ "default": false,
+ "type": "boolean"
+ },
+ "ignore-chan-recv-ok": {
+ "description": "Ignore `ok` variables that hold the bool return value of a channel receive.",
+ "default": false,
+ "type": "boolean"
+ },
+ "ignore-names": {
+ "description": "Optional list of variable names that should be ignored completely.",
+ "default": [[]],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignore-decls": {
+ "description": "Optional list of variable declarations that should be ignored completely.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "examples": [
+ ["c echo.Context", "t testing.T", "f *foo.Bar", "const C"]
+ ]
+ }
+ }
+ },
+ "whitespaceSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "multi-if": {
+ "description": "Enforces newlines (or comments) after every multi-line if statement",
+ "type": "boolean",
+ "default": false
+ },
+ "multi-func": {
+ "description": "Enforces newlines (or comments) after every multi-line function signature",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "wrapcheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "extra-ignore-sigs": {
+ "description": "An array of strings specifying additional substrings of signatures to ignore.",
+ "default": [
+ ".CustomError(",
+ ".SpecificWrap("
+ ],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignore-sigs": {
+ "description": "An array of strings which specify substrings of signatures to ignore.",
+ "default": [
+ ".Errorf(",
+ "errors.New(",
+ "errors.Unwrap(",
+ ".Wrap(",
+ ".Wrapf(",
+ ".WithMessage(",
+ ".WithMessagef(",
+ ".WithStack("
+ ],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignore-sig-regexps": {
+ "description": "An array of strings which specify regular expressions of signatures to ignore.",
+ "default": [""],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignore-package-globs": {
+ "description": "An array of glob patterns which, if any match the package of the function returning the error, will skip wrapcheck analysis for this error.",
+ "default": [""],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignore-interface-regexps": {
+ "description": "An array of glob patterns which, if matched to an underlying interface name, will ignore unwrapped errors returned from a function whose call is defined on the given interface.",
+ "default": [""],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "report-internal-errors": {
+ "description": "Determines whether wrapcheck should report errors returned from inside the package.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "wslSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "allow-assign-and-anything": {
+ "description": "Controls if you may cuddle assignments and anything without needing an empty line between them.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-assign-and-call": {
+ "description": "Allow calls and assignments to be cuddled as long as the lines have any matching variables, fields or types.",
+ "type": "boolean",
+ "default": true
+ },
+ "allow-cuddle-declarations": {
+ "description": "Allow declarations (var) to be cuddled.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-cuddle-with-calls": {
+ "description": "A list of call idents that everything can be cuddled with.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "allow-cuddle-with-rhs": {
+ "description": "AllowCuddleWithRHS is a list of right hand side variables that is allowed to be cuddled with anything.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "allow-cuddle-used-in-block": {
+ "description": "Allow cuddling with any block as long as the variable is used somewhere in the block",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-multiline-assign": {
+ "description": "Allow multiline assignments to be cuddled.",
+ "type": "boolean",
+ "default": true
+ },
+ "allow-separated-leading-comment": {
+ "description": "Allow leading comments to be separated with empty lines.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-trailing-comment": {
+ "description": "Allow trailing comments in ending of blocks.",
+ "type": "boolean",
+ "default": false
+ },
+ "error-variable-names": {
+ "description": "When force-err-cuddling is enabled this is a list of names used for error variables to check for in the conditional.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "force-case-trailing-whitespace": {
+ "description": "Force newlines in end of case at this limit (0 = never).",
+ "type": "integer",
+ "minimum": 0,
+ "default": 0
+ },
+ "force-err-cuddling": {
+ "description": "Causes an error when an If statement that checks an error variable doesn't cuddle with the assignment of that variable.",
+ "type": "boolean",
+ "default": false
+ },
+ "force-short-decl-cuddling": {
+ "description": "Causes an error if a short declaration (:=) cuddles with anything other than another short declaration.",
+ "type": "boolean",
+ "default": false
+ },
+ "strict-append": {
+ "description": "If true, append is only allowed to be cuddled if appending value is matching variables, fields or types on line above.",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "wslSettingsV5": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "allow-first-in-block": {
+ "type": "boolean",
+ "default": true
+ },
+ "allow-whole-block": {
+ "type": "boolean",
+ "default": false
+ },
+ "branch-max-lines": {
+ "type": "integer",
+ "default": 2
+ },
+ "case-max-lines": {
+ "type": "integer",
+ "default": 0
+ },
+ "default": {
+ "enum": ["all", "none", "default", ""],
+ "default": "default"
+ },
+ "enable": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/wsl-checks"
+ }
+ },
+ "disable": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/wsl-checks"
+ }
+ }
+ }
+ },
+ "copyloopvarSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-alias": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "customSettings": {
+ "description": "The custom section can be used to define linter plugins to be loaded at runtime. See README of golangci-lint for more information.\nEach custom linter should have a unique name.",
+ "type": "object",
+ "patternProperties": {
+ "^.*$": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "type": {
+ "description": "The plugin type.",
+ "enum": ["module", "goplugin"],
+ "default": "goplugin"
+ },
+ "path": {
+ "description": "The path to the plugin *.so. Can be absolute or local.",
+ "type": "string",
+ "examples": ["/path/to/example.so"]
+ },
+ "description": {
+ "description": "The description of the linter, for documentation purposes only.",
+ "type": "string"
+ },
+ "original-url": {
+ "description": "Intended to point to the repo location of the linter, for documentation purposes only.",
+ "type": "string"
+ },
+ "settings": {
+ "description": "Plugins settings/configuration. Only work with plugin based on `linterdb.PluginConstructor`.",
+ "type": "object"
+ }
+ },
+ "oneOf": [
+ {
+ "properties": {
+ "type": {"enum": ["module"] }
+ },
+ "required": ["type"]
+ },
+ {
+ "required": ["path"]
+ }
+ ]
+ }
+ }
+ }
+ }
+ }
+ },
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["version"],
+ "properties": {
+ "version": {
+ "type": "string",
+ "default": "2"
+ },
+ "run": {
+ "description": "Options for analysis running,",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "concurrency": {
+ "description": "Number of concurrent runners. Defaults to the number of available CPU cores.",
+ "type": "integer",
+ "minimum": 0,
+ "examples": [4]
+ },
+ "timeout": {
+ "description": "Timeout for the analysis.",
+ "type": "string",
+ "pattern": "^((\\d+h)?(\\d+m)?(\\d+(?:\\.\\d)?s)?|0)$",
+ "default": "1m",
+ "examples": ["30s", "5m", "5m30s"]
+ },
+ "issues-exit-code": {
+ "description": "Exit code when at least one issue was found.",
+ "type": "integer",
+ "default": 1
+ },
+ "tests": {
+ "description": "Enable inclusion of test files.",
+ "type": "boolean",
+ "default": true
+ },
+ "build-tags": {
+ "description": "List of build tags to pass to all linters.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "default": [],
+ "examples": [["mytag"]]
+ },
+ "modules-download-mode": {
+ "description": "Option to pass to \"go list -mod={option}\".\nSee \"go help modules\" for more information.",
+ "enum": ["mod", "readonly", "vendor"]
+ },
+ "enable-build-vcs": {
+ "type": "boolean",
+ "default": false
+ },
+ "allow-parallel-runners": {
+ "description": "Allow multiple parallel golangci-lint instances running. If disabled, golangci-lint acquires file lock on start.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-serial-runners": {
+ "description": "Allow multiple golangci-lint instances running, but serialize them around a lock.",
+ "type": "boolean",
+ "default": false
+ },
+ "go": {
+ "description": "Targeted Go version.",
+ "type": "string",
+ "default": "1.17"
+ },
+ "relative-path-mode": {
+ "description": "The mode used to evaluate relative paths.",
+ "type": "string",
+ "$ref": "#/definitions/relative-path-modes",
+ "default": "wd"
+ }
+ }
+ },
+ "output": {
+ "description": "Output configuration options.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "formats": {
+ "description": "Output formats to use.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "text": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "path": {
+ "$ref": "#/definitions/formats-path",
+ "default": "stdout"
+ },
+ "print-linter-name": {
+ "type": "boolean",
+ "default": true
+ },
+ "print-issued-lines": {
+ "type": "boolean",
+ "default": true
+ },
+ "colors": {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "json": {
+ "$ref": "#/definitions/simple-format"
+ },
+ "tab": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "path": {
+ "$ref": "#/definitions/formats-path",
+ "default": "stdout"
+ },
+ "print-linter-name": {
+ "type": "boolean",
+ "default": true
+ },
+ "colors": {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "html": {
+ "$ref": "#/definitions/simple-format"
+ },
+ "checkstyle": {
+ "$ref": "#/definitions/simple-format"
+ },
+ "code-climate": {
+ "$ref": "#/definitions/simple-format"
+ },
+ "junit-xml": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "path": {
+ "$ref": "#/definitions/formats-path",
+ "default": "stdout"
+ },
+ "extended": {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "teamcity": {
+ "$ref": "#/definitions/simple-format"
+ },
+ "sarif": {
+ "$ref": "#/definitions/simple-format"
+ }
+ }
+ },
+ "path-mode": {
+ "type": "string",
+ "default": "",
+ "examples": ["abs"]
+ },
+ "path-prefix": {
+ "description": "Add a prefix to the output file references.",
+ "type": "string",
+ "default": ""
+ },
+ "show-stats": {
+ "description": "Show statistics per linter.",
+ "type": "boolean",
+ "default": true
+ },
+ "sort-order": {
+ "type": "array",
+ "items": {
+ "enum": ["linter", "severity", "file"]
+ }
+ }
+ }
+ },
+ "linters": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "default": {
+ "enum": [
+ "standard",
+ "all",
+ "none",
+ "fast"
+ ]
+ },
+ "enable": {
+ "description": "List of enabled linters.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linter-names"
+ }
+ },
+ "disable": {
+ "description": "List of disabled linters.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linter-names"
+ }
+ },
+ "settings": {
+ "description": "All available settings of specific linters.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "dupword": {
+ "$ref": "#/definitions/settings/definitions/dupwordSettings"
+ },
+ "asasalint": {
+ "$ref": "#/definitions/settings/definitions/asasalintSettings"
+ },
+ "bidichk": {
+ "$ref": "#/definitions/settings/definitions/bidichkSettings"
+ },
+ "cyclop": {
+ "$ref": "#/definitions/settings/definitions/cyclopSettings"
+ },
+ "decorder": {
+ "$ref": "#/definitions/settings/definitions/decorderSettings"
+ },
+ "depguard":{
+ "$ref": "#/definitions/settings/definitions/depguardSettings"
+ },
+ "dogsled": {
+ "$ref": "#/definitions/settings/definitions/dogsledSettings"
+ },
+ "dupl": {
+ "$ref": "#/definitions/settings/definitions/duplSettings"
+ },
+ "embeddedstructfieldcheck": {
+ "$ref": "#/definitions/settings/definitions/embeddedstructfieldcheckSettings"
+ },
+ "errcheck": {
+ "$ref": "#/definitions/settings/definitions/errcheckSettings"
+ },
+ "errchkjson": {
+ "$ref": "#/definitions/settings/definitions/errchkjsonSettings"
+ },
+ "errorlint": {
+ "$ref": "#/definitions/settings/definitions/errorlintSettings"
+ },
+ "exhaustive": {
+ "$ref": "#/definitions/settings/definitions/exhaustiveSettings"
+ },
+ "exhaustruct": {
+ "$ref": "#/definitions/settings/definitions/exhaustructSettings"
+ },
+ "fatcontext": {
+ "$ref": "#/definitions/settings/definitions/fatcontextSettings"
+ },
+ "forbidigo": {
+ "$ref": "#/definitions/settings/definitions/forbidigoSettings"
+ },
+ "funcorder": {
+ "$ref": "#/definitions/settings/definitions/funcorderSettings"
+ },
+ "funlen": {
+ "$ref": "#/definitions/settings/definitions/funlenSettings"
+ },
+ "ginkgolinter": {
+ "$ref": "#/definitions/settings/definitions/ginkgolinterSettings"
+ },
+ "gochecksumtype": {
+ "$ref": "#/definitions/settings/definitions/gochecksumtypeSettings"
+ },
+ "gocognit": {
+ "$ref": "#/definitions/settings/definitions/gocognitSettings"
+ },
+ "goconst": {
+ "$ref": "#/definitions/settings/definitions/goconstSettings"
+ },
+ "gocritic": {
+ "$ref": "#/definitions/settings/definitions/gocriticSettings"
+ },
+ "gocyclo": {
+ "$ref": "#/definitions/settings/definitions/gocycloSettings"
+ },
+ "godoclint": {
+ "$ref": "#/definitions/settings/definitions/godoclintSettings"
+ },
+ "godot": {
+ "$ref": "#/definitions/settings/definitions/godotSettings"
+ },
+ "godox": {
+ "$ref": "#/definitions/settings/definitions/godoxSettings"
+ },
+ "interfacebloat":{
+ "$ref": "#/definitions/settings/definitions/interfacebloatSettings"
+ },
+ "goheader": {
+ "$ref": "#/definitions/settings/definitions/goheaderSettings"
+ },
+ "gomoddirectives": {
+ "$ref": "#/definitions/settings/definitions/gomoddirectivesSettings"
+ },
+ "gomodguard": {
+ "$ref": "#/definitions/settings/definitions/gomodguardSettings"
+ },
+ "gosec": {
+ "$ref": "#/definitions/settings/definitions/gosecSettings"
+ },
+ "gosmopolitan": {
+ "$ref": "#/definitions/settings/definitions/gosmopolitanSettings"
+ },
+ "govet": {
+ "$ref": "#/definitions/settings/definitions/govetSettings"
+ },
+ "grouper": {
+ "$ref": "#/definitions/settings/definitions/grouperSettings"
+ },
+ "iface": {
+ "$ref": "#/definitions/settings/definitions/ifaceSettings"
+ },
+ "importas": {
+ "$ref": "#/definitions/settings/definitions/importasSettings"
+ },
+ "inamedparam": {
+ "$ref": "#/definitions/settings/definitions/inamedparamSettings"
+ },
+ "ineffassign": {
+ "$ref": "#/definitions/settings/definitions/ineffassignSettings"
+ },
+ "iotamixing": {
+ "$ref": "#/definitions/settings/definitions/iotamixingSettings"
+ },
+ "ireturn": {
+ "$ref": "#/definitions/settings/definitions/ireturnSettings"
+ },
+ "lll": {
+ "$ref": "#/definitions/settings/definitions/lllSettings"
+ },
+ "maintidx": {
+ "$ref": "#/definitions/settings/definitions/maintidxSettings"
+ },
+ "makezero":{
+ "$ref": "#/definitions/settings/definitions/makezeroSettings"
+ },
+ "loggercheck": {
+ "$ref": "#/definitions/settings/definitions/loggercheckSettings"
+ },
+ "misspell": {
+ "$ref": "#/definitions/settings/definitions/misspellSettings"
+ },
+ "musttag": {
+ "$ref": "#/definitions/settings/definitions/musttagSettings"
+ },
+ "nakedret": {
+ "$ref": "#/definitions/settings/definitions/nakedretSettings"
+ },
+ "nestif": {
+ "$ref": "#/definitions/settings/definitions/nestifSettings"
+ },
+ "nilnil": {
+ "$ref": "#/definitions/settings/definitions/nilnilSettings"
+ },
+ "nlreturn": {
+ "$ref": "#/definitions/settings/definitions/nlreturnSettings"
+ },
+ "mnd": {
+ "$ref": "#/definitions/settings/definitions/mndSettings"
+ },
+ "modernize": {
+ "$ref": "#/definitions/settings/definitions/modernizeSettings"
+ },
+ "nolintlint":{
+ "$ref": "#/definitions/settings/definitions/nolintlintSettings"
+ },
+ "reassign": {
+ "$ref": "#/definitions/settings/definitions/reassignSettings"
+ },
+ "recvcheck": {
+ "$ref": "#/definitions/settings/definitions/recvcheckSettings"
+ },
+ "nonamedreturns": {
+ "$ref": "#/definitions/settings/definitions/nonamedreturnsSettings"
+ },
+ "paralleltest": {
+ "$ref": "#/definitions/settings/definitions/paralleltestSettings"
+ },
+ "perfsprint": {
+ "$ref": "#/definitions/settings/definitions/perfsprintSettings"
+ },
+ "prealloc": {
+ "$ref": "#/definitions/settings/definitions/preallocSettings"
+ },
+ "predeclared": {
+ "$ref": "#/definitions/settings/definitions/predeclaredSettings"
+ },
+ "promlinter": {
+ "$ref": "#/definitions/settings/definitions/promlinterSettings"
+ },
+ "protogetter": {
+ "$ref": "#/definitions/settings/definitions/protogetterSettings"
+ },
+ "revive": {
+ "$ref": "#/definitions/settings/definitions/reviveSettings"
+ },
+ "rowserrcheck": {
+ "$ref": "#/definitions/settings/definitions/rowserrcheckSettings"
+ },
+ "sloglint": {
+ "$ref": "#/definitions/settings/definitions/sloglintSettings"
+ },
+ "spancheck": {
+ "$ref": "#/definitions/settings/definitions/spancheckSettings"
+ },
+ "staticcheck":{
+ "$ref": "#/definitions/settings/definitions/staticcheckSettings"
+ },
+ "tagalign": {
+ "$ref": "#/definitions/settings/definitions/tagalignSettings"
+ },
+ "tagliatelle": {
+ "$ref": "#/definitions/settings/definitions/tagliatelleSettings"
+ },
+ "testifylint": {
+ "$ref": "#/definitions/settings/definitions/testifylintSettings"
+ },
+ "testpackage": {
+ "$ref": "#/definitions/settings/definitions/testpackageSettings"
+ },
+ "thelper": {
+ "$ref": "#/definitions/settings/definitions/thelperSettings"
+ },
+ "usestdlibvars": {
+ "$ref": "#/definitions/settings/definitions/usestdlibvarsSettings"
+ },
+ "usetesting": {
+ "$ref": "#/definitions/settings/definitions/usetestingSettings"
+ },
+ "unconvert": {
+ "$ref": "#/definitions/settings/definitions/unconvertSettings"
+ },
+ "unparam": {
+ "$ref": "#/definitions/settings/definitions/unparamSettings"
+ },
+ "unqueryvet": {
+ "$ref": "#/definitions/settings/definitions/unqueryvetSettings"
+ },
+ "unused": {
+ "$ref": "#/definitions/settings/definitions/unusedSettings"
+ },
+ "varnamelen": {
+ "$ref": "#/definitions/settings/definitions/varnamelenSettings"
+ },
+ "whitespace": {
+ "$ref": "#/definitions/settings/definitions/whitespaceSettings"
+ },
+ "wrapcheck": {
+ "$ref": "#/definitions/settings/definitions/wrapcheckSettings"
+ },
+ "wsl": {
+ "$ref": "#/definitions/settings/definitions/wslSettings"
+ },
+ "wsl_v5": {
+ "$ref": "#/definitions/settings/definitions/wslSettingsV5"
+ },
+ "copyloopvar": {
+ "$ref": "#/definitions/settings/definitions/copyloopvarSettings"
+ },
+ "custom":{
+ "$ref": "#/definitions/settings/definitions/customSettings"
+ }
+ }
+ },
+ "exclusions":{
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "generated": {
+ "enum": ["strict", "lax", "disable"],
+ "default": "strict"
+ },
+ "warn-unused": {
+ "type": "boolean",
+ "default": false
+ },
+ "presets": {
+ "type": "array",
+ "items": {
+ "enum": [
+ "comments",
+ "std-error-handling",
+ "common-false-positives",
+ "legacy"
+ ]
+ }
+ },
+ "rules": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "path": {
+ "type": "string"
+ },
+ "path-except": {
+ "type": "string"
+ },
+ "linters": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linter-names"
+ }
+ },
+ "text": {
+ "type": "string"
+ },
+ "source": {
+ "type": "string"
+ }
+ },
+ "anyOf": [
+ { "required": ["path"] },
+ { "required": ["path-except"] },
+ { "required": ["linters"] },
+ { "required": ["text"] },
+ { "required": ["source"] }
+ ]
+ }
+ },
+ "paths": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "paths-except": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "formatters": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "enable": {
+ "description": "List of enabled formatters.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/formatter-names"
+ }
+ },
+ "settings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "gci": {
+ "$ref": "#/definitions/settings/definitions/gciSettings"
+ },
+ "gofmt": {
+ "$ref": "#/definitions/settings/definitions/gofmtSettings"
+ },
+ "gofumpt": {
+ "$ref": "#/definitions/settings/definitions/gofumptSettings"
+ },
+ "goimports": {
+ "$ref": "#/definitions/settings/definitions/goimportsSettings"
+ },
+ "golines": {
+ "$ref": "#/definitions/settings/definitions/golinesSettings"
+ }
+ }
+ },
+ "exclusions": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "generated": {
+ "enum": ["strict", "lax", "disable"],
+ "default": "strict"
+ },
+ "paths": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "warn-unused": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ }
+ }
+ },
+ "issues": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-issues-per-linter": {
+ "description": "Maximum issues count per one linter. Set to 0 to disable.",
+ "type": "integer",
+ "default": 50,
+ "minimum": 0
+ },
+ "max-same-issues": {
+ "description": "Maximum count of issues with the same text. Set to 0 to disable.",
+ "type": "integer",
+ "default": 3,
+ "minimum": 0
+ },
+ "new": {
+ "description": "Show only new issues: if there are unstaged changes or untracked files, only those changes are analyzed, else only changes in HEAD~ are analyzed.",
+ "type": "boolean",
+ "default": false
+ },
+ "new-from-merge-base": {
+ "description": "Show only new issues created after the best common ancestor (merge-base against HEAD).",
+ "type": "string"
+ },
+ "new-from-rev": {
+ "description": "Show only new issues created after this git revision.",
+ "type": "string"
+ },
+ "new-from-patch": {
+ "description": "Show only new issues created in git patch with this file path.",
+ "type": "string",
+ "examples": ["path/to/patch/file"]
+ },
+ "fix": {
+ "description": "Apply the fixes detected by the linters and formatters (if it's supported by the linter).",
+ "type": "boolean",
+ "default": false
+ },
+ "uniq-by-line": {
+ "description": "Make issues output unique by line.",
+ "type": "boolean",
+ "default": true
+ },
+ "whole-files": {
+ "description": "Show issues in any part of update files (requires new-from-rev or new-from-patch).",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "severity": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "default": {
+ "description": "Set the default severity for issues. If severity rules are defined and the issues do not match or no severity is provided to the rule this will be the default severity applied. Severities should match the supported severity names of the selected out format.",
+ "type": "string",
+ "default": ""
+ },
+ "rules": {
+ "description": "When a list of severity rules are provided, severity information will be added to lint issues. Severity rules have the same filtering capability as exclude rules except you are allowed to specify one matcher per severity rule.\nOnly affects out formats that support setting severity information.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "severity": {
+ "type": "string"
+ },
+ "path": {
+ "type": "string"
+ },
+ "path-except": {
+ "type": "string"
+ },
+ "linters": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linter-names"
+ }
+ },
+ "text": {
+ "type": "string"
+ },
+ "source": {
+ "type": "string"
+ }
+ },
+ "required": ["severity"],
+ "anyOf": [
+ { "required": ["path"] },
+ { "required": ["path-except"] },
+ { "required": ["linters"] },
+ { "required": ["text"] },
+ { "required": ["source"] }
+ ]
+ },
+ "default": []
+ }
+ },
+ "required": ["default"]
+ }
+ }
+}
diff --git a/vendor/github.com/golangci/golangci-lint/v2/jsonschema/golangci.v2.2.jsonschema.json b/vendor/github.com/golangci/golangci-lint/v2/jsonschema/golangci.v2.2.jsonschema.json
new file mode 100644
index 000000000..3e51264fe
--- /dev/null
+++ b/vendor/github.com/golangci/golangci-lint/v2/jsonschema/golangci.v2.2.jsonschema.json
@@ -0,0 +1,4901 @@
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "$id": "https://json.schemastore.org/golangci-lint.json",
+ "definitions": {
+ "gocritic-checks": {
+ "enum": [
+ "appendAssign",
+ "appendCombine",
+ "argOrder",
+ "assignOp",
+ "badCall",
+ "badCond",
+ "badLock",
+ "badRegexp",
+ "badSorting",
+ "badSyncOnceFunc",
+ "boolExprSimplify",
+ "builtinShadow",
+ "builtinShadowDecl",
+ "captLocal",
+ "caseOrder",
+ "codegenComment",
+ "commentFormatting",
+ "commentedOutCode",
+ "commentedOutImport",
+ "defaultCaseOrder",
+ "deferInLoop",
+ "deferUnlambda",
+ "deprecatedComment",
+ "docStub",
+ "dupArg",
+ "dupBranchBody",
+ "dupCase",
+ "dupImport",
+ "dupSubExpr",
+ "dynamicFmtString",
+ "elseif",
+ "emptyDecl",
+ "emptyFallthrough",
+ "emptyStringTest",
+ "equalFold",
+ "evalOrder",
+ "exitAfterDefer",
+ "exposedSyncMutex",
+ "externalErrorReassign",
+ "filepathJoin",
+ "flagDeref",
+ "flagName",
+ "hexLiteral",
+ "httpNoBody",
+ "hugeParam",
+ "ifElseChain",
+ "importShadow",
+ "indexAlloc",
+ "initClause",
+ "ioutilDeprecated",
+ "mapKey",
+ "methodExprCall",
+ "nestingReduce",
+ "newDeref",
+ "nilValReturn",
+ "octalLiteral",
+ "offBy1",
+ "paramTypeCombine",
+ "preferDecodeRune",
+ "preferFilepathJoin",
+ "preferFprint",
+ "preferStringWriter",
+ "preferWriteByte",
+ "ptrToRefParam",
+ "rangeAppendAll",
+ "rangeExprCopy",
+ "rangeValCopy",
+ "redundantSprint",
+ "regexpMust",
+ "regexpPattern",
+ "regexpSimplify",
+ "returnAfterHttpError",
+ "ruleguard",
+ "singleCaseSwitch",
+ "sliceClear",
+ "sloppyLen",
+ "sloppyReassign",
+ "sloppyTypeAssert",
+ "sortSlice",
+ "sprintfQuotedString",
+ "sqlQuery",
+ "stringConcatSimplify",
+ "stringXbytes",
+ "stringsCompare",
+ "switchTrue",
+ "syncMapLoadAndDelete",
+ "timeExprSimplify",
+ "todoCommentWithoutDetail",
+ "tooManyResultsChecker",
+ "truncateCmp",
+ "typeAssertChain",
+ "typeDefFirst",
+ "typeSwitchVar",
+ "typeUnparen",
+ "uncheckedInlineErr",
+ "underef",
+ "unlabelStmt",
+ "unlambda",
+ "unnamedResult",
+ "unnecessaryBlock",
+ "unnecessaryDefer",
+ "unslice",
+ "valSwap",
+ "weakCond",
+ "whyNoLint",
+ "wrapperFunc",
+ "yodaStyleExpr"
+ ]
+ },
+ "gocritic-tags": {
+ "enum": [
+ "diagnostic",
+ "style",
+ "performance",
+ "experimental",
+ "opinionated",
+ "security"
+ ]
+ },
+ "staticcheck-checks": {
+ "enum": [
+ "*",
+ "all",
+ "SA*",
+ "-SA*",
+ "SA1*",
+ "-SA1*",
+ "SA1000",
+ "-SA1000",
+ "SA1001",
+ "-SA1001",
+ "SA1002",
+ "-SA1002",
+ "SA1003",
+ "-SA1003",
+ "SA1004",
+ "-SA1004",
+ "SA1005",
+ "-SA1005",
+ "SA1006",
+ "-SA1006",
+ "SA1007",
+ "-SA1007",
+ "SA1008",
+ "-SA1008",
+ "SA1010",
+ "-SA1010",
+ "SA1011",
+ "-SA1011",
+ "SA1012",
+ "-SA1012",
+ "SA1013",
+ "-SA1013",
+ "SA1014",
+ "-SA1014",
+ "SA1015",
+ "-SA1015",
+ "SA1016",
+ "-SA1016",
+ "SA1017",
+ "-SA1017",
+ "SA1018",
+ "-SA1018",
+ "SA1019",
+ "-SA1019",
+ "SA1020",
+ "-SA1020",
+ "SA1021",
+ "-SA1021",
+ "SA1023",
+ "-SA1023",
+ "SA1024",
+ "-SA1024",
+ "SA1025",
+ "-SA1025",
+ "SA1026",
+ "-SA1026",
+ "SA1027",
+ "-SA1027",
+ "SA1028",
+ "-SA1028",
+ "SA1029",
+ "-SA1029",
+ "SA1030",
+ "-SA1030",
+ "SA1031",
+ "-SA1031",
+ "SA1032",
+ "-SA1032",
+ "SA2*",
+ "-SA2*",
+ "SA2000",
+ "-SA2000",
+ "SA2001",
+ "-SA2001",
+ "SA2002",
+ "-SA2002",
+ "SA2003",
+ "-SA2003",
+ "SA3*",
+ "-SA3*",
+ "SA3000",
+ "-SA3000",
+ "SA3001",
+ "-SA3001",
+ "SA4*",
+ "-SA4*",
+ "SA4000",
+ "-SA4000",
+ "SA4001",
+ "-SA4001",
+ "SA4003",
+ "-SA4003",
+ "SA4004",
+ "-SA4004",
+ "SA4005",
+ "-SA4005",
+ "SA4006",
+ "-SA4006",
+ "SA4008",
+ "-SA4008",
+ "SA4009",
+ "-SA4009",
+ "SA4010",
+ "-SA4010",
+ "SA4011",
+ "-SA4011",
+ "SA4012",
+ "-SA4012",
+ "SA4013",
+ "-SA4013",
+ "SA4014",
+ "-SA4014",
+ "SA4015",
+ "-SA4015",
+ "SA4016",
+ "-SA4016",
+ "SA4017",
+ "-SA4017",
+ "SA4018",
+ "-SA4018",
+ "SA4019",
+ "-SA4019",
+ "SA4020",
+ "-SA4020",
+ "SA4021",
+ "-SA4021",
+ "SA4022",
+ "-SA4022",
+ "SA4023",
+ "-SA4023",
+ "SA4024",
+ "-SA4024",
+ "SA4025",
+ "-SA4025",
+ "SA4026",
+ "-SA4026",
+ "SA4027",
+ "-SA4027",
+ "SA4028",
+ "-SA4028",
+ "SA4029",
+ "-SA4029",
+ "SA4030",
+ "-SA4030",
+ "SA4031",
+ "-SA4031",
+ "SA4032",
+ "-SA4032",
+ "SA5*",
+ "-SA5*",
+ "SA5000",
+ "-SA5000",
+ "SA5001",
+ "-SA5001",
+ "SA5002",
+ "-SA5002",
+ "SA5003",
+ "-SA5003",
+ "SA5004",
+ "-SA5004",
+ "SA5005",
+ "-SA5005",
+ "SA5007",
+ "-SA5007",
+ "SA5008",
+ "-SA5008",
+ "SA5009",
+ "-SA5009",
+ "SA5010",
+ "-SA5010",
+ "SA5011",
+ "-SA5011",
+ "SA5012",
+ "-SA5012",
+ "SA6*",
+ "-SA6*",
+ "SA6000",
+ "-SA6000",
+ "SA6001",
+ "-SA6001",
+ "SA6002",
+ "-SA6002",
+ "SA6003",
+ "-SA6003",
+ "SA6005",
+ "-SA6005",
+ "SA6006",
+ "-SA6006",
+ "SA9*",
+ "-SA9*",
+ "SA9001",
+ "-SA9001",
+ "SA9002",
+ "-SA9002",
+ "SA9003",
+ "-SA9003",
+ "SA9004",
+ "-SA9004",
+ "SA9005",
+ "-SA9005",
+ "SA9006",
+ "-SA9006",
+ "SA9007",
+ "-SA9007",
+ "SA9008",
+ "-SA9008",
+ "SA9009",
+ "-SA9009",
+ "ST*",
+ "-ST*",
+ "ST1*",
+ "-ST1*",
+ "ST1000",
+ "-ST1000",
+ "ST1001",
+ "-ST1001",
+ "ST1003",
+ "-ST1003",
+ "ST1005",
+ "-ST1005",
+ "ST1006",
+ "-ST1006",
+ "ST1008",
+ "-ST1008",
+ "ST1011",
+ "-ST1011",
+ "ST1012",
+ "-ST1012",
+ "ST1013",
+ "-ST1013",
+ "ST1015",
+ "-ST1015",
+ "ST1016",
+ "-ST1016",
+ "ST1017",
+ "-ST1017",
+ "ST1018",
+ "-ST1018",
+ "ST1019",
+ "-ST1019",
+ "ST1020",
+ "-ST1020",
+ "ST1021",
+ "-ST1021",
+ "ST1022",
+ "-ST1022",
+ "ST1023",
+ "-ST1023",
+ "S*",
+ "-S*",
+ "S1*",
+ "-S1*",
+ "S1000",
+ "-S1000",
+ "S1001",
+ "-S1001",
+ "S1002",
+ "-S1002",
+ "S1003",
+ "-S1003",
+ "S1004",
+ "-S1004",
+ "S1005",
+ "-S1005",
+ "S1006",
+ "-S1006",
+ "S1007",
+ "-S1007",
+ "S1008",
+ "-S1008",
+ "S1009",
+ "-S1009",
+ "S1010",
+ "-S1010",
+ "S1011",
+ "-S1011",
+ "S1012",
+ "-S1012",
+ "S1016",
+ "-S1016",
+ "S1017",
+ "-S1017",
+ "S1018",
+ "-S1018",
+ "S1019",
+ "-S1019",
+ "S1020",
+ "-S1020",
+ "S1021",
+ "-S1021",
+ "S1023",
+ "-S1023",
+ "S1024",
+ "-S1024",
+ "S1025",
+ "-S1025",
+ "S1028",
+ "-S1028",
+ "S1029",
+ "-S1029",
+ "S1030",
+ "-S1030",
+ "S1031",
+ "-S1031",
+ "S1032",
+ "-S1032",
+ "S1033",
+ "-S1033",
+ "S1034",
+ "-S1034",
+ "S1035",
+ "-S1035",
+ "S1036",
+ "-S1036",
+ "S1037",
+ "-S1037",
+ "S1038",
+ "-S1038",
+ "S1039",
+ "-S1039",
+ "S1040",
+ "-S1040",
+ "QF*",
+ "-QF*",
+ "QF1*",
+ "-QF1*",
+ "QF1001",
+ "-QF1001",
+ "QF1002",
+ "-QF1002",
+ "QF1003",
+ "-QF1003",
+ "QF1004",
+ "-QF1004",
+ "QF1005",
+ "-QF1005",
+ "QF1006",
+ "-QF1006",
+ "QF1007",
+ "-QF1007",
+ "QF1008",
+ "-QF1008",
+ "QF1009",
+ "-QF1009",
+ "QF1010",
+ "-QF1010",
+ "QF1011",
+ "-QF1011",
+ "QF1012",
+ "-QF1012"
+ ]
+ },
+ "gosec-rules": {
+ "enum": [
+ "G101",
+ "G102",
+ "G103",
+ "G104",
+ "G106",
+ "G107",
+ "G108",
+ "G109",
+ "G110",
+ "G111",
+ "G112",
+ "G114",
+ "G115",
+ "G201",
+ "G202",
+ "G203",
+ "G204",
+ "G301",
+ "G302",
+ "G303",
+ "G304",
+ "G305",
+ "G306",
+ "G307",
+ "G401",
+ "G402",
+ "G403",
+ "G404",
+ "G405",
+ "G406",
+ "G501",
+ "G502",
+ "G503",
+ "G504",
+ "G505",
+ "G506",
+ "G507",
+ "G601",
+ "G602"
+ ]
+ },
+ "govet-analyzers": {
+ "enum": [
+ "appends",
+ "asmdecl",
+ "assign",
+ "atomic",
+ "atomicalign",
+ "bools",
+ "buildtag",
+ "cgocall",
+ "composites",
+ "copylocks",
+ "deepequalerrors",
+ "defers",
+ "directive",
+ "errorsas",
+ "fieldalignment",
+ "findcall",
+ "framepointer",
+ "hostport",
+ "httpmux",
+ "httpresponse",
+ "ifaceassert",
+ "loopclosure",
+ "lostcancel",
+ "nilfunc",
+ "nilness",
+ "printf",
+ "reflectvaluecompare",
+ "shadow",
+ "shift",
+ "sigchanyzer",
+ "slog",
+ "sortslice",
+ "stdmethods",
+ "stdversion",
+ "stringintconv",
+ "structtag",
+ "testinggoroutine",
+ "tests",
+ "timeformat",
+ "unmarshal",
+ "unreachable",
+ "unsafeptr",
+ "unusedresult",
+ "unusedwrite",
+ "waitgroup"
+ ]
+ },
+ "revive-rules": {
+ "enum": [
+ "add-constant",
+ "argument-limit",
+ "atomic",
+ "banned-characters",
+ "bare-return",
+ "blank-imports",
+ "bool-literal-in-expr",
+ "call-to-gc",
+ "cognitive-complexity",
+ "comment-spacings",
+ "comments-density",
+ "confusing-naming",
+ "confusing-results",
+ "constant-logical-expr",
+ "context-as-argument",
+ "context-keys-type",
+ "cyclomatic",
+ "datarace",
+ "deep-exit",
+ "defer",
+ "dot-imports",
+ "duplicated-imports",
+ "early-return",
+ "empty-block",
+ "empty-lines",
+ "enforce-map-style",
+ "enforce-repeated-arg-type-style",
+ "enforce-slice-style",
+ "error-naming",
+ "error-return",
+ "error-strings",
+ "errorf",
+ "exported",
+ "file-header",
+ "file-length-limit",
+ "filename-format",
+ "flag-parameter",
+ "function-length",
+ "function-result-limit",
+ "get-return",
+ "identical-branches",
+ "if-return",
+ "import-alias-naming",
+ "import-shadowing",
+ "imports-blocklist",
+ "increment-decrement",
+ "indent-error-flow",
+ "line-length-limit",
+ "max-control-nesting",
+ "max-public-structs",
+ "modifies-parameter",
+ "modifies-value-receiver",
+ "nested-structs",
+ "optimize-operands-order",
+ "package-comments",
+ "range-val-address",
+ "range-val-in-closure",
+ "range",
+ "receiver-naming",
+ "redefines-builtin-id",
+ "redundant-build-tag",
+ "redundant-import-alias",
+ "redundant-test-main-exit",
+ "string-format",
+ "string-of-int",
+ "struct-tag",
+ "superfluous-else",
+ "time-date",
+ "time-equal",
+ "time-naming",
+ "unchecked-type-assertion",
+ "unconditional-recursion",
+ "unexported-naming",
+ "unexported-return",
+ "unhandled-error",
+ "unnecessary-format",
+ "unnecessary-stmt",
+ "unreachable-code",
+ "unused-parameter",
+ "unused-receiver",
+ "use-any",
+ "use-errors-new",
+ "use-fmt-print",
+ "useless-break",
+ "var-declaration",
+ "var-naming",
+ "waitgroup-by-value"
+ ]
+ },
+ "iface-analyzers": {
+ "enum": [
+ "identical",
+ "unused",
+ "opaque",
+ "unexported"
+ ]
+ },
+ "tagliatelle-cases": {
+ "enum": [
+ "",
+ "camel",
+ "pascal",
+ "kebab",
+ "snake",
+ "goCamel",
+ "goPascal",
+ "goKebab",
+ "goSnake",
+ "upper",
+ "upperSnake",
+ "lower",
+ "header"
+ ]
+ },
+ "wsl-checks": {
+ "enum": [
+ "assign",
+ "branch",
+ "decl",
+ "defer",
+ "expr",
+ "for",
+ "go",
+ "if",
+ "inc-dec",
+ "label",
+ "range",
+ "return",
+ "select",
+ "send",
+ "switch",
+ "type-switch",
+ "append",
+ "assign-exclusive",
+ "assign-expr",
+ "err",
+ "leading-whitespace",
+ "trailing-whitespace"
+ ]
+ },
+ "relative-path-modes": {
+ "enum": [
+ "gomod",
+ "gitroot",
+ "cfg",
+ "wd"
+ ]
+ },
+ "simple-format": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "path": {
+ "$ref": "#/definitions/formats-path",
+ "default": "stdout"
+ }
+ }
+ },
+ "formats-path" : {
+ "anyOf": [
+ {
+ "enum": [
+ "stdout",
+ "stderr"
+ ]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ },
+ "linter-names": {
+ "$comment": "anyOf with enum is used to allow auto-completion of non-custom linters",
+ "description": "Usable linter names.",
+ "anyOf": [
+ {
+ "enum": [
+ "arangolint",
+ "asasalint",
+ "asciicheck",
+ "bidichk",
+ "bodyclose",
+ "canonicalheader",
+ "containedctx",
+ "contextcheck",
+ "copyloopvar",
+ "cyclop",
+ "decorder",
+ "depguard",
+ "dogsled",
+ "dupl",
+ "dupword",
+ "durationcheck",
+ "embeddedstructfieldcheck",
+ "errcheck",
+ "errchkjson",
+ "errname",
+ "errorlint",
+ "exhaustive",
+ "exhaustruct",
+ "exptostd",
+ "fatcontext",
+ "forbidigo",
+ "forcetypeassert",
+ "funcorder",
+ "funlen",
+ "ginkgolinter",
+ "gocheckcompilerdirectives",
+ "gochecknoglobals",
+ "gochecknoinits",
+ "gochecksumtype",
+ "gocognit",
+ "goconst",
+ "gocritic",
+ "gocyclo",
+ "godot",
+ "godox",
+ "err113",
+ "goheader",
+ "gomoddirectives",
+ "gomodguard",
+ "goprintffuncname",
+ "gosec",
+ "gosimple",
+ "gosmopolitan",
+ "govet",
+ "grouper",
+ "iface",
+ "importas",
+ "inamedparam",
+ "ineffassign",
+ "interfacebloat",
+ "intrange",
+ "ireturn",
+ "lll",
+ "loggercheck",
+ "maintidx",
+ "makezero",
+ "mirror",
+ "misspell",
+ "mnd",
+ "musttag",
+ "nakedret",
+ "nestif",
+ "nilerr",
+ "nilnesserr",
+ "nilnil",
+ "nlreturn",
+ "noctx",
+ "noinlineerr",
+ "nolintlint",
+ "nonamedreturns",
+ "nosprintfhostport",
+ "paralleltest",
+ "perfsprint",
+ "prealloc",
+ "predeclared",
+ "promlinter",
+ "protogetter",
+ "reassign",
+ "recvcheck",
+ "revive",
+ "rowserrcheck",
+ "sloglint",
+ "sqlclosecheck",
+ "staticcheck",
+ "stylecheck",
+ "tagalign",
+ "tagliatelle",
+ "testableexamples",
+ "testifylint",
+ "testpackage",
+ "thelper",
+ "tparallel",
+ "unconvert",
+ "unparam",
+ "unused",
+ "usestdlibvars",
+ "usetesting",
+ "varnamelen",
+ "wastedassign",
+ "whitespace",
+ "wrapcheck",
+ "wsl",
+ "wsl_v5",
+ "zerologlint"
+ ]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ },
+ "formatter-names": {
+ "description": "Usable formatter names.",
+ "enum": [
+ "gci",
+ "gofmt",
+ "gofumpt",
+ "goimports",
+ "golines",
+ "swaggo"
+ ]
+ },
+ "settings": {
+ "definitions": {
+ "dupwordSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "keywords": {
+ "description": "Keywords for detecting duplicate words. If this list is not empty, only the words defined in this list will be detected.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["the", "and", "a"]
+ }
+ },
+ "ignore": {
+ "description": "Keywords used to ignore detection.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["0C0C"]
+ }
+ }
+ }
+ },
+ "asasalintSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "exclude": {
+ "description": "To specify a set of function names to exclude.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["\\.Wrapf"]
+ }
+ },
+ "use-builtin-exclusions": {
+ "description": "To enable/disable the asasalint builtin exclusions of function names.",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "bidichkSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "left-to-right-embedding": {
+ "description": "Disallow: LEFT-TO-RIGHT-EMBEDDING",
+ "type": "boolean",
+ "default": false
+ },
+ "right-to-left-embedding": {
+ "description": "Disallow: RIGHT-TO-LEFT-EMBEDDING",
+ "type": "boolean",
+ "default": false
+ },
+ "pop-directional-formatting": {
+ "description": "Disallow: POP-DIRECTIONAL-FORMATTING",
+ "type": "boolean",
+ "default": false
+ },
+ "left-to-right-override": {
+ "description": "Disallow: LEFT-TO-RIGHT-OVERRIDE",
+ "type": "boolean",
+ "default": false
+ },
+ "right-to-left-override": {
+ "description": "Disallow: RIGHT-TO-LEFT-OVERRIDE",
+ "type": "boolean",
+ "default": false
+ },
+ "left-to-right-isolate": {
+ "description": "Disallow: LEFT-TO-RIGHT-ISOLATE",
+ "type": "boolean",
+ "default": false
+ },
+ "right-to-left-isolate": {
+ "description": "Disallow: RIGHT-TO-LEFT-ISOLATE",
+ "type": "boolean",
+ "default": false
+ },
+ "first-strong-isolate": {
+ "description": "Disallow: FIRST-STRONG-ISOLATE",
+ "type": "boolean",
+ "default": false
+ },
+ "pop-directional-isolate": {
+ "description": "Disallow: POP-DIRECTIONAL-ISOLATE",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "cyclopSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-complexity": {
+ "description": "Max complexity the function can have",
+ "type": "integer",
+ "default": 10,
+ "minimum": 0
+ },
+ "package-average": {
+ "description": "Max average complexity in package",
+ "type": "number",
+ "default": 0,
+ "minimum": 0
+ }
+ }
+ },
+ "decorderSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "dec-order": {
+ "type": "array",
+ "default": [["type", "const", "var", "func"]],
+ "items": {
+ "enum": ["type", "const", "var", "func"]
+ }
+ },
+ "ignore-underscore-vars": {
+ "description": "Underscore vars (vars with \"_\" as the name) will be ignored at all checks",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-dec-order-check": {
+ "description": "Order of declarations is not checked",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-init-func-first-check": {
+ "description": "Allow init func to be anywhere in file",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-dec-num-check": {
+ "description": "Multiple global type, const and var declarations are allowed",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-type-dec-num-check": {
+ "description": "Type declarations will be ignored for dec num check",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-const-dec-num-check": {
+ "description": "Const declarations will be ignored for dec num check",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-var-dec-num-check": {
+ "description": "Var declarations will be ignored for dec num check",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ },
+ "depguardSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "rules": {
+ "description": "Rules to apply.",
+ "type": "object",
+ "additionalProperties": false,
+ "patternProperties": {
+ "^[^.]+$": {
+ "description": "Name of a rule.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "list-mode": {
+ "description": "Used to determine the package matching priority.",
+ "enum": ["original", "strict", "lax"],
+ "default": "original"
+ },
+ "files": {
+ "description": "List of file globs that will match this list of settings to compare against.",
+ "additionalProperties": false,
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "allow": {
+ "description": "List of allowed packages.",
+ "additionalProperties": false,
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "deny": {
+ "description": "Packages that are not allowed where the value is a suggestion.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "desc": {
+ "description": "Description",
+ "type": "string"
+ },
+ "pkg": {
+ "description": "Package",
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "dogsledSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-blank-identifiers": {
+ "description": "Check assignments with too many blank identifiers.",
+ "type": "integer",
+ "default": 2,
+ "minimum": 0
+ }
+ }
+ },
+ "duplSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "threshold": {
+ "description": "Tokens count to trigger issue.",
+ "type": "integer",
+ "default": 150,
+ "minimum": 0
+ }
+ }
+ },
+ "embeddedstructfieldcheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "forbid-mutex": {
+ "description": "Checks that sync.Mutex and sync.RWMutex are not used as embedded fields.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "errcheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-type-assertions": {
+ "description": "Report about not checking errors in type assertions, i.e.: `a := b.(MyStruct)`",
+ "type": "boolean",
+ "default": false
+ },
+ "check-blank": {
+ "description": "Report about assignment of errors to blank identifier",
+ "type": "boolean",
+ "default": false
+ },
+ "exclude-functions": {
+ "description": "List of functions to exclude from checking, where each entry is a single function to exclude",
+ "type": "array",
+ "examples": ["io/ioutil.ReadFile", "io.Copy(*bytes.Buffer)"],
+ "items": {
+ "type": "string"
+ }
+ },
+ "disable-default-exclusions": {
+ "description": "To disable the errcheck built-in exclude list",
+ "type": "boolean",
+ "default": false
+ },
+ "verbose": {
+ "description": "Display function signature instead of selector",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "errchkjsonSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-error-free-encoding": {
+ "type": "boolean",
+ "default": false
+ },
+ "report-no-exported": {
+ "description": "Issue on struct that doesn't have exported fields.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "errorlintSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "errorf": {
+ "description": "Check whether fmt.Errorf uses the %w verb for formatting errors",
+ "type": "boolean",
+ "default": true
+ },
+ "errorf-multi": {
+ "description": "Permit more than 1 %w verb, valid per Go 1.20",
+ "type": "boolean",
+ "default": true
+ },
+ "asserts": {
+ "description": "Check for plain type assertions and type switches.",
+ "type": "boolean",
+ "default": true
+ },
+ "comparison": {
+ "description": "Check for plain error comparisons",
+ "type": "boolean",
+ "default": true
+ },
+ "allowed-errors": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "err": {
+ "type": "string"
+ },
+ "fun": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "allowed-errors-wildcard": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "err": {
+ "type": "string"
+ },
+ "fun": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "exhaustiveSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check": {
+ "description": "Program elements to check for exhaustiveness.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["switch", "map"]
+ }
+ },
+ "explicit-exhaustive-switch": {
+ "description": "Only run exhaustive check on switches with \"//exhaustive:enforce\" comment.",
+ "type": "boolean",
+ "default": false
+ },
+ "explicit-exhaustive-map": {
+ "description": "Only run exhaustive check on map literals with \"//exhaustive:enforce\" comment.",
+ "type": "boolean",
+ "default": false
+ },
+ "default-case-required": {
+ "description": "Switch statement requires default case even if exhaustive.",
+ "type": "boolean",
+ "default": false
+ },
+ "default-signifies-exhaustive": {
+ "description": "Presence of `default` case in switch statements satisfies exhaustiveness, even if all enum members are not listed.",
+ "type": "boolean",
+ "default": false
+ },
+ "ignore-enum-members": {
+ "description": "Enum members matching `regex` do not have to be listed in switch statements to satisfy exhaustiveness",
+ "type": "string"
+ },
+ "ignore-enum-types": {
+ "description": "Enum types matching the supplied regex do not have to be listed in switch statements to satisfy exhaustiveness.",
+ "type": "string"
+ },
+ "package-scope-only": {
+ "description": "Consider enums only in package scopes, not in inner scopes.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "exhaustructSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "include": {
+ "description": "List of regular expressions to match struct packages and names.",
+ "type": "array",
+ "examples": [".*\\.Test"],
+ "items": {
+ "type": "string"
+ }
+ },
+ "exclude": {
+ "description": "List of regular expressions to exclude struct packages and names from check.",
+ "type": "array",
+ "examples": ["cobra\\.Command$"],
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "fatcontextSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-struct-pointers": {
+ "description": "Check for potential fat contexts in struct pointers.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "forbidigoSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "exclude-godoc-examples": {
+ "description": "Exclude code in godoc examples.",
+ "type": "boolean",
+ "default": true
+ },
+ "analyze-types": {
+ "description": "Instead of matching the literal source code, use type information to replace expressions with strings that contain the package name and (for methods and fields) the type name.",
+ "type": "boolean",
+ "default": true
+ },
+ "forbid": {
+ "description": "List of identifiers to forbid (written using `regexp`)",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "pattern": {
+ "description": "Pattern",
+ "type": "string"
+ },
+ "pkg": {
+ "description": "Package",
+ "type": "string"
+ },
+ "msg": {
+ "description": "Message",
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "funcorderSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "constructor": {
+ "description": "Checks that constructors are placed after the structure declaration.",
+ "type": "boolean",
+ "default": true
+ },
+ "struct-method": {
+ "description": "Checks if the exported methods of a structure are placed before the non-exported ones.",
+ "type": "boolean",
+ "default": true
+ },
+ "alphabetical": {
+ "description": "Checks if the constructors and/or structure methods are sorted alphabetically.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "funlenSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "lines": {
+ "description": "Limit lines number per function.",
+ "type": "integer",
+ "default": 60
+ },
+ "statements": {
+ "description": "Limit statements number per function.",
+ "type": "integer",
+ "default": 40
+ },
+ "ignore-comments": {
+ "description": "Ignore comments when counting lines.",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "gciSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "sections": {
+ "description": "Section configuration to compare against.",
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "enum": [
+ "standard",
+ "default",
+ "blank",
+ "dot",
+ "alias",
+ "localmodule"
+ ]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ },
+ "default": ["standard", "default"]
+ },
+ "no-inline-comments": {
+ "description": "Checks that no inline Comments are present.",
+ "type": "boolean",
+ "default": false
+ },
+ "no-prefix-comments": {
+ "description": "Checks that no prefix Comments(comment lines above an import) are present.",
+ "type": "boolean",
+ "default": false
+ },
+ "custom-order": {
+ "description": "Enable custom order of sections.",
+ "type": "boolean",
+ "default": false
+ },
+ "no-lex-order": {
+ "description": "Drops lexical ordering for custom sections.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "ginkgolinterSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "suppress-len-assertion": {
+ "description": "Suppress the wrong length assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-nil-assertion": {
+ "description": "Suppress the wrong nil assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-err-assertion": {
+ "description": "Suppress the wrong error assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-compare-assertion": {
+ "description": "Suppress the wrong comparison assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-async-assertion": {
+ "description": "Suppress the function all in async assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-type-compare-assertion": {
+ "description": "Suppress warning for comparing values from different types, like int32 and uint32.",
+ "type": "boolean",
+ "default": false
+ },
+ "forbid-focus-container": {
+ "description": "Trigger warning for ginkgo focus containers like FDescribe, FContext, FWhen or FIt.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-havelen-zero": {
+ "description": "Don't trigger warnings for HaveLen(0).",
+ "type": "boolean",
+ "default": false
+ },
+ "force-expect-to": {
+ "description": "Force using `Expect` with `To`, `ToNot` or `NotTo`",
+ "type": "boolean",
+ "default": false
+ },
+ "validate-async-intervals": {
+ "description": "Best effort validation of async intervals (timeout and polling).",
+ "type": "boolean",
+ "default": false
+ },
+ "forbid-spec-pollution": {
+ "description": "Trigger a warning for variable assignments in ginkgo containers like `Describe`, `Context` and `When`, instead of in `BeforeEach()`.",
+ "type": "boolean",
+ "default": false
+ },
+ "force-succeed": {
+ "description": "Force using the Succeed matcher for error functions, and the HaveOccurred matcher for non-function error values.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "gochecksumtypeSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "default-signifies-exhaustive": {
+ "description": "Presence of `default` case in switch statements satisfies exhaustiveness, if all members are not listed.",
+ "type": "boolean",
+ "default": true
+ },
+ "include-shared-interfaces": {
+ "description": "Include shared interfaces in the exhaustiviness check.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "gocognitSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "min-complexity": {
+ "description": "Minimal code complexity to report (we recommend 10-20).",
+ "type": "integer",
+ "default": 30
+ }
+ }
+ },
+ "goconstSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "match-constant": {
+ "description": "Look for existing constants matching the values",
+ "type": "boolean",
+ "default": true
+ },
+ "min-len": {
+ "description": "Minimum length of string constant.",
+ "type": "integer",
+ "default": 3
+ },
+ "min-occurrences": {
+ "description": "Minimum occurrences count to trigger.",
+ "type": "integer",
+ "default": 3
+ },
+ "ignore-calls": {
+ "description": "Ignore when constant is not used as function argument",
+ "type": "boolean",
+ "default": true
+ },
+ "ignore-string-values": {
+ "description": "Exclude strings matching the given regular expression",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "numbers": {
+ "description": "Search also for duplicated numbers.",
+ "type": "boolean",
+ "default": false
+ },
+ "min": {
+ "description": "Minimum value, only works with `numbers`",
+ "type": "integer",
+ "default": 3
+ },
+ "max": {
+ "description": "Maximum value, only works with `numbers`",
+ "type": "integer",
+ "default": 3
+ },
+ "find-duplicates": {
+ "description": "Detects constants with identical values",
+ "type": "boolean",
+ "default": false
+ },
+ "eval-const-expressions": {
+ "description": "Evaluates of constant expressions like Prefix + \"suffix\"",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "gocriticSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "enabled-checks": {
+ "description": "Which checks should be enabled. By default, a list of stable checks is used. To see it, run `GL_DEBUG=gocritic golangci-lint run`.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/gocritic-checks"
+ }
+ },
+ "disabled-checks": {
+ "description": "Which checks should be disabled.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/gocritic-checks"
+ },
+ "default": []
+ },
+ "enabled-tags": {
+ "description": "Enable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/gocritic-tags"
+ }
+ },
+ "disabled-tags": {
+ "description": "Disable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/gocritic-tags"
+ }
+ },
+ "settings": {
+ "description": "Settings passed to gocritic. Properties must be valid and enabled check names.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "captLocal": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "paramsOnly" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "commentedOutCode": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "minLength" : {
+ "type": "number",
+ "default": 15
+ }
+ }
+ },
+ "elseif": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skipBalanced" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "hugeParam": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "sizeThreshold" : {
+ "type": "number",
+ "default": 80
+ }
+ }
+ },
+ "ifElseChain": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "minThreshold" : {
+ "type": "number",
+ "default": 2
+ }
+ }
+ },
+ "nestingReduce": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "bodyWidth" : {
+ "type": "number",
+ "default": 5
+ }
+ }
+ },
+ "rangeExprCopy": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "sizeThreshold" : {
+ "type": "number",
+ "default": 512
+ },
+ "skipTestFuncs" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "rangeValCopy": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "sizeThreshold" : {
+ "type": "number",
+ "default": 128
+ },
+ "skipTestFuncs" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "ruleguard": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "debug" : {
+ "type": "string"
+ },
+ "enable" : {
+ "type": "string"
+ },
+ "disable" : {
+ "type": "string"
+ },
+ "failOn" : {
+ "type": "string"
+ },
+ "rules" : {
+ "type": "string"
+ }
+ }
+ },
+ "tooManyResultsChecker": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "maxResults" : {
+ "type": "number",
+ "default": 5
+ }
+ }
+ },
+ "truncateCmp": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skipArchDependent" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "underef": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skipRecvDeref" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "unnamedResult": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "checkExported" : {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ }
+ }
+ },
+ "disable-all": {
+ "type": "boolean",
+ "default": false
+ },
+ "enable-all": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "gocycloSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "min-complexity": {
+ "description": "Minimum code complexity to report (we recommend 10-20).",
+ "type": "integer",
+ "default": 30
+ }
+ }
+ },
+ "godotSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "scope": {
+ "description": "Comments to be checked.",
+ "enum": ["declarations", "toplevel", "all", "noinline"],
+ "default": "declarations"
+ },
+ "exclude": {
+ "description": "List of regexps for excluding particular comment lines from check.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "period": {
+ "description": "Check that each sentence ends with a period.",
+ "type": "boolean",
+ "default": true
+ },
+ "capital": {
+ "description": "Check that each sentence starts with a capital letter.",
+ "type": "boolean",
+ "default": false
+ },
+ "check-all": {
+ "description": "DEPRECATED: Check all top-level comments, not only declarations.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "godoxSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "keywords": {
+ "description": "Report any comments starting with one of these keywords. This is useful for TODO or FIXME comments that might be left in the code accidentally and should be resolved before merging.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "default": ["TODO", "BUG", "FIXME"]
+ }
+ }
+ },
+ "gofmtSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "simplify": {
+ "description": "Simplify code.",
+ "type": "boolean",
+ "default": true
+ },
+ "rewrite-rules": {
+ "description": "Apply the rewrite rules to the source before reformatting.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "pattern": {
+ "type": "string"
+ },
+ "replacement": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "golinesSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-len": {
+ "type": "integer",
+ "default": 100
+ },
+ "tab-len": {
+ "type": "integer",
+ "default": 4
+ },
+ "shorten-comments": {
+ "type": "boolean",
+ "default": false
+ },
+ "reformat-tags": {
+ "type": "boolean",
+ "default": true
+ },
+ "chain-split-dots": {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "interfacebloatSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max": {
+ "description": "The maximum number of methods allowed for an interface.",
+ "type": "integer"
+ }
+ }
+ },
+ "gofumptSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "extra-rules": {
+ "description": "Choose whether or not to use the extra rules that are disabled by default.",
+ "type": "boolean",
+ "default": false
+ },
+ "module-path": {
+ "description": " Module path which contains the source code being formatted.",
+ "type": "string"
+ }
+ }
+ },
+ "goheaderSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "values": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "const": {
+ "description": "Constants to use in the template.",
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "description": "Value for the constant.",
+ "type": "string"
+ }
+ },
+ "additionalProperties": false,
+ "examples": [
+ {
+ "YEAR": "2030",
+ "COMPANY": "MY FUTURISTIC COMPANY"
+ }
+ ]
+ },
+ "regexp": {
+ "description": "Regular expressions to use in your template.",
+ "type": "object",
+ "additionalProperties": false,
+ "patternProperties": {
+ "^.+$": {
+ "type": "string"
+ }
+ },
+ "examples": [
+ {
+ "AUTHOR": ".*@mycompany\\.com"
+ }
+ ]
+ }
+ }
+ },
+ "template": {
+ "description": "Template to put on top of every file.",
+ "type": "string",
+ "examples": [
+ "{{ MY COMPANY }}\nSPDX-License-Identifier: Apache-2.0\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at:\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License."
+ ]
+ },
+ "template-path": {
+ "description": "Path to the file containing the template source.",
+ "type": "string",
+ "examples": ["my_header_template.txt"]
+ }
+ },
+ "oneOf": [
+ { "required": ["template"] },
+ { "required": ["template-path"] }
+ ]
+ },
+ "goimportsSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "local-prefixes": {
+ "description": "Put imports beginning with prefix after 3rd-party packages. It is a list of prefixes.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "gomoddirectivesSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "replace-local": {
+ "description": "Allow local `replace` directives.",
+ "type": "boolean",
+ "default": true
+ },
+ "replace-allow-list": {
+ "description": "List of allowed `replace` directives.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "retract-allow-no-explanation": {
+ "description": "Allow to not explain why the version has been retracted in the `retract` directives.",
+ "type": "boolean",
+ "default": false
+ },
+ "exclude-forbidden": {
+ "description": "Forbid the use of the `exclude` directives.",
+ "type": "boolean",
+ "default": false
+ },
+ "ignore-forbidden": {
+ "description": "Forbid the use of the `ignore` directives. (>= go1.25)",
+ "type": "boolean",
+ "default": false
+ },
+ "toolchain-forbidden": {
+ "description": "Forbid the use of the `toolchain` directive.",
+ "type": "boolean",
+ "default": false
+ },
+ "toolchain-pattern": {
+ "description": "Defines a pattern to validate `toolchain` directive.",
+ "type": "string"
+ },
+ "tool-forbidden": {
+ "description": "Forbid the use of the `tool` directives.",
+ "type": "boolean",
+ "default": false
+ },
+ "go-debug-forbidden": {
+ "description": "Forbid the use of the `godebug` directive.",
+ "type": "boolean",
+ "default": false
+ },
+ "go-version-pattern": {
+ "description": "Defines a pattern to validate `go` minimum version directive.",
+ "type": "string",
+ "default": ""
+ }
+ }
+ },
+ "gomodguardSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "allowed": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "modules": {
+ "description": "List of allowed modules.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["gopkg.in/yaml.v2"]
+ }
+ },
+ "domains": {
+ "description": "List of allowed module domains.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["golang.org"]
+ }
+ }
+ }
+ },
+ "blocked": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "modules": {
+ "description": "List of blocked modules.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "recommendations": {
+ "description": "Recommended modules that should be used instead.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "reason": {
+ "description": "Reason why the recommended module should be used.",
+ "type": "string"
+ }
+ }
+ }
+ },
+ "additionalProperties": false
+ }
+ },
+ "versions": {
+ "description": "List of blocked module version constraints.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "patternProperties": {
+ "^.*$": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "version": {
+ "description": "Version constraint.",
+ "type": "string"
+ },
+ "reason": {
+ "description": "Reason why the version constraint exists.",
+ "type": "string"
+ }
+ },
+ "required": ["reason"]
+ }
+ }
+ }
+ },
+ "local-replace-directives": {
+ "description": "Raise lint issues if loading local path with replace directive",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ }
+ }
+ },
+ "gosecSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "includes": {
+ "type": "array",
+ "description": "To select a subset of rules to run",
+ "examples": [["G401"]],
+ "items": {
+ "$ref": "#/definitions/gosec-rules"
+ }
+ },
+ "excludes": {
+ "type": "array",
+ "description": "To specify a set of rules to explicitly exclude",
+ "examples": [["G401"]],
+ "items": {
+ "$ref": "#/definitions/gosec-rules"
+ }
+ },
+ "severity": {
+ "description": "Filter out the issues with a lower severity than the given value",
+ "type": "string",
+ "enum": ["low", "medium", "high"],
+ "default": "low"
+ },
+ "confidence": {
+ "description": "Filter out the issues with a lower confidence than the given value",
+ "type": "string",
+ "enum": ["low", "medium", "high"],
+ "default": "low"
+ },
+ "config": {
+ "description": "To specify the configuration of rules",
+ "type": "object"
+ },
+ "concurrency": {
+ "description": "Concurrency value",
+ "type": "integer"
+ }
+ }
+ },
+ "gosmopolitanSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "allow-time-local": {
+ "description": "Allow and ignore `time.Local` usages.",
+ "type": "boolean",
+ "default": false
+ },
+ "escape-hatches": {
+ "description": "List of fully qualified names in the `full/pkg/path.name` form, to act as \"i18n escape hatches\".",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "watch-for-scripts": {
+ "description": "List of Unicode scripts to watch for any usage in string literals.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "govetSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "settings": {
+ "description": "Settings per analyzer. Map of analyzer name to specific settings.\nRun `go tool vet help` to find out more.",
+ "type": "object",
+ "propertyNames": {
+ "$ref": "#/definitions/govet-analyzers"
+ },
+ "patternProperties": {
+ "^.*$": {
+ "description": "Run `go tool vet help ` to see all settings.",
+ "type": "object"
+ }
+ }
+ },
+ "enable": {
+ "description": "Enable analyzers by name.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/govet-analyzers"
+ }
+ },
+ "disable": {
+ "description": "Disable analyzers by name.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/govet-analyzers"
+ }
+ },
+ "enable-all": {
+ "description": "Enable all analyzers.",
+ "type": "boolean",
+ "default": false
+ },
+ "disable-all": {
+ "description": "Disable all analyzers.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "grouperSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "const-require-single-const": {
+ "type": "boolean",
+ "default": false
+ },
+ "const-require-grouping": {
+ "type": "boolean",
+ "default": false
+ },
+ "import-require-single-import": {
+ "type": "boolean",
+ "default": false
+ },
+ "import-require-grouping": {
+ "type": "boolean",
+ "default": false
+ },
+ "type-require-single-type": {
+ "type": "boolean",
+ "default": false
+ },
+ "type-require-grouping": {
+ "type": "boolean",
+ "default": false
+ },
+ "var-require-single-var": {
+ "type": "boolean",
+ "default": false
+ },
+ "var-require-grouping": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "ifaceSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "enable": {
+ "description": "Enable analyzers by name.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/iface-analyzers"
+ }
+ },
+ "settings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "unused": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "exclude": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "importasSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "no-unaliased": {
+ "description": "Do not allow unaliased imports of aliased packages.",
+ "type": "boolean",
+ "default": false
+ },
+ "no-extra-aliases": {
+ "description": "Do not allow non-required aliases.",
+ "type": "boolean",
+ "default": false
+ },
+ "alias": {
+ "description": "List of aliases",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "pkg": {
+ "description": "Package path e.g. knative.dev/serving/pkg/apis/autoscaling/v1alpha1",
+ "type": "string"
+ },
+ "alias": {
+ "description": "Package alias e.g. autoscalingv1alpha1",
+ "type": "string"
+ }
+ },
+ "required": ["pkg", "alias"]
+ }
+ }
+ }
+ },
+ "inamedparamSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skip-single-param": {
+ "description": "Skips check for interface methods with only a single parameter.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "ireturnSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "description": "Use either `reject` or `allow` properties for interfaces matching.",
+ "properties": {
+ "allow": {
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "enum": ["anon", "error", "empty", "stdlib"]
+ }
+ ]
+ }
+ },
+ "reject": {
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "enum": ["anon", "error", "empty", "stdlib"]
+ }
+ ]
+ }
+ }
+ },
+ "anyOf": [
+ {
+ "not": {
+ "properties": {
+ "allow": {
+ "const": "reject"
+ }
+ }
+ },
+ "required": ["allow"]
+ },
+ {
+ "required": ["reject"]
+ }
+ ]
+ },
+ "lllSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "tab-width": {
+ "description": "Width of \"\\t\" in spaces.",
+ "type": "integer",
+ "minimum": 0,
+ "default": 1
+ },
+ "line-length": {
+ "description": "Maximum allowed line length, lines longer will be reported.",
+ "type": "integer",
+ "minimum": 1,
+ "default": 120
+ }
+ }
+ },
+ "maintidxSettings": {
+ "description": "Maintainability index https://docs.microsoft.com/en-us/visualstudio/code-quality/code-metrics-maintainability-index-range-and-meaning?view=vs-2022",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "under": {
+ "description": "Minimum accatpable maintainability index level (see https://docs.microsoft.com/en-us/visualstudio/code-quality/code-metrics-maintainability-index-range-and-meaning?view=vs-2022)",
+ "type": "number",
+ "default": 20
+ }
+ }
+ },
+ "makezeroSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "always": {
+ "description": "Allow only slices initialized with a length of zero.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "loggercheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "kitlog": {
+ "description": "Allow check for the github.com/go-kit/log library.",
+ "type": "boolean",
+ "default": true
+ },
+ "klog": {
+ "description": "Allow check for the k8s.io/klog/v2 library.",
+ "type": "boolean",
+ "default": true
+ },
+ "logr": {
+ "description": "Allow check for the github.com/go-logr/logr library.",
+ "type": "boolean",
+ "default": true
+ },
+ "slog": {
+ "description": "Allow check for the log/slog library.",
+ "type": "boolean",
+ "default": true
+ },
+ "zap": {
+ "description": "Allow check for the \"sugar logger\" from go.uber.org/zap library.",
+ "type": "boolean",
+ "default": true
+ },
+ "require-string-key": {
+ "description": "Require all logging keys to be inlined constant strings.",
+ "type": "boolean",
+ "default": false
+ },
+ "no-printf-like": {
+ "description": "Require printf-like format specifier (%s, %d for example) not present.",
+ "type": "boolean",
+ "default": false
+ },
+ "rules": {
+ "description": "List of custom rules to check against, where each rule is a single logger pattern, useful for wrapped loggers.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "misspellSettings": {
+ "description": "Correct spellings using locale preferences for US or UK. Default is to use a neutral variety of English.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "locale": {
+ "enum": ["US", "UK"]
+ },
+ "ignore-rules": {
+ "description": "List of rules to ignore.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "mode": {
+ "description": "Mode of the analysis.",
+ "enum": ["restricted", "", "default"],
+ "default": ""
+ },
+ "extra-words": {
+ "description": "Extra word corrections.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "correction": {
+ "type": "string"
+ },
+ "typo": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "musttagSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "functions": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "tag": {
+ "type": "string"
+ },
+ "arg-pos": {
+ "type": "integer"
+ }
+ }
+ }
+ }
+ }
+ },
+ "nakedretSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-func-lines": {
+ "description": "Report if a function has more lines of code than this value and it has naked returns.",
+ "type": "integer",
+ "minimum": 0,
+ "default": 30
+ }
+ }
+ },
+ "nestifSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "min-complexity": {
+ "description": "Minimum complexity of \"if\" statements to report.",
+ "type": "integer",
+ "default": 5
+ }
+ }
+ },
+ "nilnilSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "only-two": {
+ "type": "boolean",
+ "description": "To check functions with only two return values.",
+ "default": true
+ },
+ "detect-opposite": {
+ "type": "boolean",
+ "description": "In addition, detect opposite situation (simultaneous return of non-nil error and valid value).",
+ "default": false
+ },
+ "checked-types": {
+ "type": "array",
+ "description": "List of return types to check.",
+ "items": {
+ "enum": ["chan", "func", "iface", "map", "ptr", "uintptr", "unsafeptr"]
+ },
+ "default": ["chan", "func", "iface", "map", "ptr", "uintptr", "unsafeptr"]
+ }
+ }
+ },
+ "nlreturnSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "block-size": {
+ "description": "set block size that is still ok",
+ "type": "number",
+ "default": 0,
+ "minimum": 0
+ }
+ }
+ },
+ "mndSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignored-files": {
+ "description": "List of file patterns to exclude from analysis.",
+ "examples": [["magic1_.*.go"]],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignored-functions": {
+ "description": "Comma-separated list of function patterns to exclude from the analysis.",
+ "examples": [["math.*", "http.StatusText", "make"]],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignored-numbers": {
+ "description": "List of numbers to exclude from analysis.",
+ "examples": [["1000", "1234_567_890", "3.14159264"]],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "checks": {
+ "description": "The list of enabled checks, see https://github.com/tommy-muehle/go-mnd/#checks for description.",
+ "type": "array",
+ "items": {
+ "enum": [
+ "argument",
+ "case",
+ "condition",
+ "operation",
+ "return",
+ "assign"
+ ]
+ }
+ }
+ }
+ },
+ "nolintlintSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "allow-unused": {
+ "description": "Enable to ensure that nolint directives are all used.",
+ "type": "boolean",
+ "default": true
+ },
+ "allow-no-explanation": {
+ "description": "Exclude these linters from requiring an explanation.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linter-names"
+ },
+ "default": []
+ },
+ "require-explanation": {
+ "description": "Enable to require an explanation of nonzero length after each nolint directive.",
+ "type": "boolean",
+ "default": false
+ },
+ "require-specific": {
+ "description": "Enable to require nolint directives to mention the specific linter being suppressed.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "reassignSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "patterns": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "recvcheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "disable-builtin": {
+ "description": "Disables the built-in method exclusions.",
+ "type": "boolean",
+ "default": true
+ },
+ "exclusions": {
+ "description": "User-defined method exclusions.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "nonamedreturnsSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "report-error-in-defer": {
+ "description": "Report named error if it is assigned inside defer.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "paralleltestSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignore-missing": {
+ "description": "Ignore missing calls to `t.Parallel()` and only report incorrect uses of it.",
+ "type": "boolean",
+ "default": false
+ },
+ "ignore-missing-subtests": {
+ "description": "Ignore missing calls to `t.Parallel()` in subtests. Top-level tests are still required to have `t.Parallel`, but subtests are allowed to skip it.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "perfsprintSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "integer-format": {
+ "description": "Enable/disable optimization of integer formatting.",
+ "type": "boolean",
+ "default": true
+ },
+ "int-conversion": {
+ "description": "Optimizes even if it requires an int or uint type cast.",
+ "type": "boolean",
+ "default": true
+ },
+ "error-format": {
+ "description": "Enable/disable optimization of error formatting.",
+ "type": "boolean",
+ "default": true
+ },
+ "err-error": {
+ "description": "Optimizes into `err.Error()` even if it is only equivalent for non-nil errors.",
+ "type": "boolean",
+ "default": false
+ },
+ "errorf": {
+ "description": "Optimizes `fmt.Errorf`.",
+ "type": "boolean",
+ "default": true
+ },
+ "string-format": {
+ "description": "Enable/disable optimization of string formatting.",
+ "type": "boolean",
+ "default": true
+ },
+ "sprintf1": {
+ "description": "Optimizes `fmt.Sprintf` with only one argument.",
+ "type": "boolean",
+ "default": true
+ },
+ "strconcat": {
+ "description": "Optimizes into strings concatenation.",
+ "type": "boolean",
+ "default": true
+ },
+ "bool-format": {
+ "description": "Enable/disable optimization of bool formatting.",
+ "type": "boolean",
+ "default": true
+ },
+ "hex-format": {
+ "description": "Enable/disable optimization of hex formatting.",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "preallocSettings": {
+ "description": "We do not recommend using this linter before doing performance profiling.\nFor most programs usage of `prealloc` will be premature optimization.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "simple": {
+ "description": "Report preallocation suggestions only on simple loops that have no returns/breaks/continues/gotos in them.",
+ "type": "boolean",
+ "default": true
+ },
+ "range-loops": {
+ "description": "Report preallocation suggestions on range loops.",
+ "type": "boolean",
+ "default": true
+ },
+ "for-loops": {
+ "description": "Report preallocation suggestions on for loops.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "predeclaredSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignore": {
+ "description": "List of predeclared identifiers to not report on.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "qualified-name": {
+ "description": "Include method names and field names in checks.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "promlinterSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "strict": {},
+ "disabled-linters": {
+ "type": "array",
+ "items": {
+ "enum": [
+ "Help",
+ "MetricUnits",
+ "Counter",
+ "HistogramSummaryReserved",
+ "MetricTypeInName",
+ "ReservedChars",
+ "CamelCase",
+ "UnitAbbreviations"
+ ]
+ }
+ }
+ }
+ },
+ "protogetterSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skip-generated-by": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["protoc-gen-go-my-own-generator"]
+ }
+ },
+ "skip-files": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["*.pb.go"]
+ }
+ },
+ "skip-any-generated": {
+ "description": "Skip any generated files from the checking.",
+ "type": "boolean",
+ "default": false
+ },
+ "replace-first-arg-in-append": {
+ "description": "Skip first argument of append function.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "reviveSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "examples": [
+ {
+ "ignore-generated-header": true,
+ "severity": "warning",
+ "rules": [
+ {
+ "name": "indent-error-flow",
+ "severity": "warning"
+ },
+ {
+ "name": "add-constant",
+ "severity": "warning",
+ "arguments": [
+ {
+ "maxLitCount": "3",
+ "allowStrs": "\"\"",
+ "allowInts": "0,1,2",
+ "allowFloats": "0.0,0.,1.0,1.,2.0,2."
+ }
+ ]
+ }
+ ]
+ }
+ ],
+ "properties": {
+ "max-open-files": {
+ "type": "integer"
+ },
+ "confidence": {
+ "type": "number"
+ },
+ "severity": {
+ "type": "string",
+ "enum": ["warning", "error"]
+ },
+ "enable-all-rules": {
+ "type": "boolean",
+ "default": false
+ },
+ "directives": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "name": {
+ "type": "string",
+ "enum": ["specify-disable-reason"]
+ },
+ "severity": {
+ "type": "string",
+ "enum": ["warning", "error"]
+ },
+ "exclude": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "arguments": {
+ "type": "array"
+ }
+ }
+ }
+ },
+ "rules": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["name"],
+ "properties": {
+ "name": {
+ "$ref": "#/definitions/revive-rules",
+ "title": "The rule name"
+ },
+ "disabled": {
+ "type": "boolean"
+ },
+ "severity": {
+ "type": "string",
+ "enum": ["warning", "error"]
+ },
+ "exclude": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "arguments": {
+ "type": "array"
+ }
+ }
+ }
+ }
+ }
+ },
+ "rowserrcheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "packages": {
+ "type": "array",
+ "items": {
+ "description": "",
+ "type": "string",
+ "examples": ["github.com/jmoiron/sqlx"]
+ }
+ }
+ }
+ },
+ "sloglintSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "kv-only": {
+ "description": "Enforce using key-value pairs only (incompatible with attr-only).",
+ "type": "boolean",
+ "default": false
+ },
+ "no-global": {
+ "description": "Enforce not using global loggers.",
+ "enum": ["", "all", "default"],
+ "default": ""
+ },
+ "no-mixed-args": {
+ "description": "Enforce not mixing key-value pairs and attributes.",
+ "type": "boolean",
+ "default": true
+ },
+ "context": {
+ "description": "Enforce using methods that accept a context.",
+ "enum": ["", "all", "scope"],
+ "default": ""
+ },
+ "static-msg": {
+ "description": "Enforce using static values for log messages.",
+ "type": "boolean",
+ "default": false
+ },
+ "msg-style": {
+ "description": "Enforce message style.",
+ "enum": ["", "lowercased", "capitalized"],
+ "default": ""
+ },
+ "key-naming-case": {
+ "description": "Enforce a single key naming convention.",
+ "enum": ["snake", "kebab", "camel", "pascal"]
+ },
+ "attr-only": {
+ "description": "Enforce using attributes only (incompatible with kv-only).",
+ "type": "boolean",
+ "default": false
+ },
+ "no-raw-keys": {
+ "description": "Enforce using constants instead of raw keys.",
+ "type": "boolean",
+ "default": false
+ },
+ "forbidden-keys": {
+ "description": "Enforce not using specific keys.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "args-on-sep-lines": {
+ "description": "Enforce putting arguments on separate lines.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "spancheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "checks": {
+ "description": "Checks to enable.",
+ "type": "array",
+ "items": {
+ "enum": ["end", "record-error", "set-status"]
+ }
+ },
+ "ignore-check-signatures": {
+ "description": "A list of regexes for function signatures that silence `record-error` and `set-status` reports if found in the call path to a returned error.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "extra-start-span-signatures": {
+ "description": "A list of regexes for additional function signatures that create spans.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "staticcheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "checks": {
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "$ref": "#/definitions/staticcheck-checks"
+ },
+ {
+ "type": "string"
+ }
+ ]
+ }
+ },
+ "dot-import-whitelist": {
+ "description": "By default, ST1001 forbids all uses of dot imports in non-test packages. This setting allows setting a whitelist of import paths that can be dot-imported anywhere.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "http-status-code-whitelist": {
+ "description": "ST1013 recommends using constants from the net/http package instead of hard-coding numeric HTTP status codes. This setting specifies a list of numeric status codes that this check does not complain about.",
+ "default": ["200", "400", "404", "500"],
+ "type": "array",
+ "items": {
+ "enum": [
+ "100",
+ "101",
+ "102",
+ "103",
+ "200",
+ "201",
+ "202",
+ "203",
+ "204",
+ "205",
+ "206",
+ "207",
+ "208",
+ "226",
+ "300",
+ "301",
+ "302",
+ "303",
+ "304",
+ "305",
+ "306",
+ "307",
+ "308",
+ "400",
+ "401",
+ "402",
+ "403",
+ "404",
+ "405",
+ "406",
+ "407",
+ "408",
+ "409",
+ "410",
+ "411",
+ "412",
+ "413",
+ "414",
+ "415",
+ "416",
+ "417",
+ "418",
+ "421",
+ "422",
+ "423",
+ "424",
+ "425",
+ "426",
+ "428",
+ "429",
+ "431",
+ "451",
+ "500",
+ "501",
+ "502",
+ "503",
+ "504",
+ "505",
+ "506",
+ "507",
+ "508",
+ "510",
+ "511"
+ ]
+ }
+ },
+ "initialisms": {
+ "description": "ST1003 check, among other things, for the correct capitalization of initialisms. The set of known initialisms can be configured with this option.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "default": [
+ "ACL",
+ "API",
+ "ASCII",
+ "CPU",
+ "CSS",
+ "DNS",
+ "EOF",
+ "GUID",
+ "HTML",
+ "HTTP",
+ "HTTPS",
+ "ID",
+ "IP",
+ "JSON",
+ "QPS",
+ "RAM",
+ "RPC",
+ "SLA",
+ "SMTP",
+ "SQL",
+ "SSH",
+ "TCP",
+ "TLS",
+ "TTL",
+ "UDP",
+ "UI",
+ "GID",
+ "UID",
+ "UUID",
+ "URI",
+ "URL",
+ "UTF8",
+ "VM",
+ "XML",
+ "XMPP",
+ "XSRF",
+ "XSS",
+ "SIP",
+ "RTP",
+ "AMQP",
+ "DB",
+ "TS"
+ ]
+ }
+ }
+ }
+ },
+ "tagalignSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "align": {
+ "description": "Align and sort can be used together or separately.",
+ "type": "boolean",
+ "default": true
+ },
+ "sort": {
+ "description": "Whether enable tags sort.",
+ "type": "boolean",
+ "default": true
+ },
+ "order": {
+ "description": "Specify the order of tags, the other tags will be sorted by name.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "default": [],
+ "examples": [
+ [
+ "json",
+ "yaml",
+ "yml",
+ "toml",
+ "mapstructure",
+ "binding",
+ "validate"
+ ]
+ ]
+ },
+ "strict": {
+ "description": "Whether enable strict style.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "tagliatelleSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "case": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "use-field-name": {
+ "description": "Use the struct field name to check the name of the struct tag.",
+ "type": "boolean",
+ "default": false
+ },
+ "ignored-fields": {
+ "description": "The field names to ignore.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["example"]
+ }
+ },
+ "rules": {
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "$ref": "#/definitions/tagliatelle-cases"
+ }
+ }
+ },
+ "extended-rules": {
+ "description": "Defines the association between tag name and case.",
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["case"],
+ "properties": {
+ "case": {
+ "$ref": "#/definitions/tagliatelle-cases"
+ },
+ "extra-initialisms": {
+ "type": "boolean",
+ "default": false
+ },
+ "initialism-overrides": {
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "overrides": {
+ "description": "Overrides the default/root configuration.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["pkg"],
+ "properties": {
+ "pkg": {
+ "description": "A package path.",
+ "type": "string"
+ },
+ "use-field-name": {
+ "description": "Use the struct field name to check the name of the struct tag.",
+ "type": "boolean",
+ "default": false
+ },
+ "ignored-fields": {
+ "description": "The field names to ignore.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["example"]
+ }
+ },
+ "ignore": {
+ "description": "Ignore the package (takes precedence over all other configurations).",
+ "type": "boolean",
+ "default": false
+ },
+ "rules": {
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "$ref": "#/definitions/tagliatelle-cases"
+ }
+ }
+ },
+ "extended-rules": {
+ "description": "Defines the association between tag name and case.",
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["case"],
+ "properties": {
+ "case": {
+ "$ref": "#/definitions/tagliatelle-cases"
+ },
+ "extra-initialisms": {
+ "type": "boolean",
+ "default": false
+ },
+ "initialism-overrides": {
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "testifylintSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "enable-all": {
+ "description": "Enable all checkers.",
+ "type": "boolean",
+ "default": false
+ },
+ "disable-all": {
+ "description": "Disable all checkers.",
+ "type": "boolean",
+ "default": false
+ },
+ "enable": {
+ "description": "Enable specific checkers.",
+ "type": "array",
+ "items": {
+ "enum": [
+ "blank-import",
+ "bool-compare",
+ "compares",
+ "contains",
+ "empty",
+ "encoded-compare",
+ "equal-values",
+ "error-is-as",
+ "error-nil",
+ "expected-actual",
+ "float-compare",
+ "formatter",
+ "go-require",
+ "len",
+ "negative-positive",
+ "nil-compare",
+ "regexp",
+ "require-error",
+ "suite-broken-parallel",
+ "suite-dont-use-pkg",
+ "suite-extra-assert-call",
+ "suite-method-signature",
+ "suite-subtest-run",
+ "suite-thelper",
+ "useless-assert"
+ ]
+ },
+ "default": [
+ "blank-import",
+ "bool-compare",
+ "compares",
+ "contains",
+ "empty",
+ "encoded-compare",
+ "equal-values",
+ "error-is-as",
+ "error-nil",
+ "expected-actual",
+ "float-compare",
+ "formatter",
+ "go-require",
+ "len",
+ "negative-positive",
+ "nil-compare",
+ "regexp",
+ "require-error",
+ "suite-broken-parallel",
+ "suite-dont-use-pkg",
+ "suite-extra-assert-call",
+ "suite-method-signature",
+ "suite-subtest-run",
+ "useless-assert"
+ ]
+ },
+ "disable": {
+ "description": "Disable specific checkers.",
+ "type": "array",
+ "items": {
+ "enum": [
+ "blank-import",
+ "bool-compare",
+ "compares",
+ "contains",
+ "empty",
+ "encoded-compare",
+ "equal-values",
+ "error-is-as",
+ "error-nil",
+ "expected-actual",
+ "float-compare",
+ "formatter",
+ "go-require",
+ "len",
+ "negative-positive",
+ "nil-compare",
+ "regexp",
+ "require-error",
+ "suite-broken-parallel",
+ "suite-dont-use-pkg",
+ "suite-extra-assert-call",
+ "suite-method-signature",
+ "suite-subtest-run",
+ "suite-thelper",
+ "useless-assert"
+ ],
+ "default": [
+ "suite-thelper"
+ ]
+ }
+ },
+ "bool-compare": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignore-custom-types": {
+ "description": "To ignore user defined types (over builtin bool).",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "expected-actual": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "pattern": {
+ "description": "Regexp for expected variable name.",
+ "type": "string",
+ "default": "(^(exp(ected)?|want(ed)?)([A-Z]\\w*)?$)|(^(\\w*[a-z])?(Exp(ected)?|Want(ed)?)$)"
+ }
+ }
+ },
+ "formatter": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-format-string": {
+ "description": "To enable go vet's printf checks.",
+ "type": "boolean",
+ "default": true
+ },
+ "require-f-funcs": {
+ "description": "To require f-assertions (e.g. assert.Equalf) if format string is used, even if there are no variable-length variables.",
+ "type": "boolean",
+ "default": false
+ },
+ "require-string-msg": {
+ "description": "To require that the first element of msgAndArgs (msg) has a string type.",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "go-require": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignore-http-handlers": {
+ "description": "To ignore HTTP handlers (like http.HandlerFunc).",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "require-error": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "fn-pattern": {
+ "description": "Regexp for assertions to analyze. If defined, then only matched error assertions will be reported.",
+ "type": "string",
+ "default": ""
+ }
+ }
+ },
+ "suite-extra-assert-call": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "mode": {
+ "description": "To require or remove extra Assert() call?",
+ "type": "string",
+ "enum": ["remove", "require"],
+ "default": "remove"
+ }
+ }
+ }
+ }
+ },
+ "testpackageSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skip-regexp": {
+ "description": "Files with names matching this regular expression are skipped.",
+ "type": "string",
+ "examples": ["(export|internal)_test\\.go"]
+ },
+ "allow-packages": {
+ "description": "List of packages that don't end with _test that tests are allowed to be in.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["example"]
+ }
+ }
+ }
+ },
+ "thelperSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "test": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "begin": {
+ "description": "Check if `t.Helper()` begins helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "first": {
+ "description": "Check if *testing.T is first param of helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "name": {
+ "description": "Check if *testing.T param has t name.",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ },
+ "benchmark": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "begin": {
+ "description": "Check if `b.Helper()` begins helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "first": {
+ "description": "Check if *testing.B is first param of helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "name": {
+ "description": "Check if *testing.B param has b name.",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ },
+ "tb": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "begin": {
+ "description": "Check if `tb.Helper()` begins helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "first": {
+ "description": "Check if *testing.TB is first param of helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "name": {
+ "description": "Check if *testing.TB param has tb name.",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ },
+ "fuzz": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "begin": {
+ "description": "Check if `f.Helper()` begins helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "first": {
+ "description": "Check if *testing.F is first param of helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "name": {
+ "description": "Check if *testing.F param has f name.",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ }
+ }
+ },
+ "usestdlibvarsSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "http-method": {
+ "description": "Suggest the use of http.MethodXX.",
+ "type": "boolean",
+ "default": true
+ },
+ "http-status-code": {
+ "description": "Suggest the use of http.StatusXX.",
+ "type": "boolean",
+ "default": true
+ },
+ "time-weekday": {
+ "description": "Suggest the use of time.Weekday.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "time-month": {
+ "description": "Suggest the use of time.Month.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "time-layout": {
+ "description": "Suggest the use of time.Layout.",
+ "type": "boolean",
+ "default": false
+ },
+ "time-date-month": {
+ "description": "Suggest the use of time.Month in time.Date.",
+ "type": "boolean",
+ "default": false
+ },
+ "crypto-hash": {
+ "description": "Suggest the use of crypto.Hash.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "default-rpc-path": {
+ "description": "Suggest the use of rpc.DefaultXXPath.",
+ "type": "boolean",
+ "default": false
+ },
+ "sql-isolation-level": {
+ "description": "Suggest the use of sql.LevelXX.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "tls-signature-scheme": {
+ "description": "Suggest the use of tls.SignatureScheme.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "constant-kind": {
+ "description": "Suggest the use of constant.Kind.String().",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "usetestingSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "context-background": {
+ "type": "boolean",
+ "default": false
+ },
+ "context-todo": {
+ "type": "boolean",
+ "default": false
+ },
+ "os-chdir": {
+ "type": "boolean",
+ "default": true
+ },
+ "os-mkdir-temp": {
+ "type": "boolean",
+ "default": true
+ },
+ "os-setenv": {
+ "type": "boolean",
+ "default": true
+ },
+ "os-create-temp": {
+ "type": "boolean",
+ "default": true
+ },
+ "os-temp-dir": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "unconvertSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "fast-math": {
+ "type": "boolean",
+ "default": false
+ },
+ "safe": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "unparamSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-exported": {
+ "description": "Inspect exported functions. Set to true if no external program/library imports your code.\n\nWARNING: if you enable this setting, unparam will report a lot of false-positives in text editors:\nif it's called for subdir of a project it can't find external interfaces. All text editor integrations\nwith golangci-lint call it on a directory with the changed file.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "unusedSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "field-writes-are-uses": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ },
+ "post-statements-are-reads": {
+ "description": "",
+ "type": "boolean",
+ "default": false
+ },
+ "exported-fields-are-used": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ },
+ "parameters-are-used": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ },
+ "local-variables-are-used": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ },
+ "generated-is-used": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "varnamelenSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-distance": {
+ "description": "Variables used in at most this N-many lines will be ignored.",
+ "type": "integer",
+ "default": 5
+ },
+ "min-name-length": {
+ "description": "The minimum length of a variable's name that is considered `long`.",
+ "type": "integer",
+ "default": 3
+ },
+ "check-receiver": {
+ "description": "Check method receiver names.",
+ "default": false,
+ "type": "boolean"
+ },
+ "check-return": {
+ "description": "Check named return values.",
+ "default": false,
+ "type": "boolean"
+ },
+ "check-type-param": {
+ "description": "Check type parameters.",
+ "default": false,
+ "type": "boolean"
+ },
+ "ignore-type-assert-ok": {
+ "description": "Ignore `ok` variables that hold the bool return value of a type assertion",
+ "default": false,
+ "type": "boolean"
+ },
+ "ignore-map-index-ok": {
+ "description": "Ignore `ok` variables that hold the bool return value of a map index.",
+ "default": false,
+ "type": "boolean"
+ },
+ "ignore-chan-recv-ok": {
+ "description": "Ignore `ok` variables that hold the bool return value of a channel receive.",
+ "default": false,
+ "type": "boolean"
+ },
+ "ignore-names": {
+ "description": "Optional list of variable names that should be ignored completely.",
+ "default": [[]],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignore-decls": {
+ "description": "Optional list of variable declarations that should be ignored completely.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "examples": [
+ ["c echo.Context", "t testing.T", "f *foo.Bar", "const C"]
+ ]
+ }
+ }
+ },
+ "whitespaceSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "multi-if": {
+ "description": "Enforces newlines (or comments) after every multi-line if statement",
+ "type": "boolean",
+ "default": false
+ },
+ "multi-func": {
+ "description": "Enforces newlines (or comments) after every multi-line function signature",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "wrapcheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "extra-ignore-sigs": {
+ "description": "An array of strings specifying additional substrings of signatures to ignore.",
+ "default": [
+ ".CustomError(",
+ ".SpecificWrap("
+ ],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignore-sigs": {
+ "description": "An array of strings which specify substrings of signatures to ignore.",
+ "default": [
+ ".Errorf(",
+ "errors.New(",
+ "errors.Unwrap(",
+ ".Wrap(",
+ ".Wrapf(",
+ ".WithMessage(",
+ ".WithMessagef(",
+ ".WithStack("
+ ],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignore-sig-regexps": {
+ "description": "An array of strings which specify regular expressions of signatures to ignore.",
+ "default": [""],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignore-package-globs": {
+ "description": "An array of glob patterns which, if any match the package of the function returning the error, will skip wrapcheck analysis for this error.",
+ "default": [""],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignore-interface-regexps": {
+ "description": "An array of glob patterns which, if matched to an underlying interface name, will ignore unwrapped errors returned from a function whose call is defined on the given interface.",
+ "default": [""],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "report-internal-errors": {
+ "description": "Determines whether wrapcheck should report errors returned from inside the package.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "wslSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "allow-assign-and-anything": {
+ "description": "Controls if you may cuddle assignments and anything without needing an empty line between them.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-assign-and-call": {
+ "description": "Allow calls and assignments to be cuddled as long as the lines have any matching variables, fields or types.",
+ "type": "boolean",
+ "default": true
+ },
+ "allow-cuddle-declarations": {
+ "description": "Allow declarations (var) to be cuddled.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-cuddle-with-calls": {
+ "description": "A list of call idents that everything can be cuddled with.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "allow-cuddle-with-rhs": {
+ "description": "AllowCuddleWithRHS is a list of right hand side variables that is allowed to be cuddled with anything.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "allow-cuddle-used-in-block": {
+ "description": "Allow cuddling with any block as long as the variable is used somewhere in the block",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-multiline-assign": {
+ "description": "Allow multiline assignments to be cuddled.",
+ "type": "boolean",
+ "default": true
+ },
+ "allow-separated-leading-comment": {
+ "description": "Allow leading comments to be separated with empty lines.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-trailing-comment": {
+ "description": "Allow trailing comments in ending of blocks.",
+ "type": "boolean",
+ "default": false
+ },
+ "error-variable-names": {
+ "description": "When force-err-cuddling is enabled this is a list of names used for error variables to check for in the conditional.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "force-case-trailing-whitespace": {
+ "description": "Force newlines in end of case at this limit (0 = never).",
+ "type": "integer",
+ "minimum": 0,
+ "default": 0
+ },
+ "force-err-cuddling": {
+ "description": "Causes an error when an If statement that checks an error variable doesn't cuddle with the assignment of that variable.",
+ "type": "boolean",
+ "default": false
+ },
+ "force-short-decl-cuddling": {
+ "description": "Causes an error if a short declaration (:=) cuddles with anything other than another short declaration.",
+ "type": "boolean",
+ "default": false
+ },
+ "strict-append": {
+ "description": "If true, append is only allowed to be cuddled if appending value is matching variables, fields or types on line above.",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "wslSettingsV5": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "allow-first-in-block": {
+ "type": "boolean",
+ "default": true
+ },
+ "allow-whole-block": {
+ "type": "boolean",
+ "default": false
+ },
+ "branch-max-lines": {
+ "type": "integer",
+ "default": 2
+ },
+ "case-max-lines": {
+ "type": "integer",
+ "default": 0
+ },
+ "default": {
+ "enum": ["all", "none", "default", ""],
+ "default": "default"
+ },
+ "enable": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/wsl-checks"
+ }
+ },
+ "disable": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/wsl-checks"
+ }
+ }
+ }
+ },
+ "copyloopvarSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-alias": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "customSettings": {
+ "description": "The custom section can be used to define linter plugins to be loaded at runtime. See README of golangci-lint for more information.\nEach custom linter should have a unique name.",
+ "type": "object",
+ "patternProperties": {
+ "^.*$": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "type": {
+ "description": "The plugin type.",
+ "enum": ["module", "goplugin"],
+ "default": "goplugin"
+ },
+ "path": {
+ "description": "The path to the plugin *.so. Can be absolute or local.",
+ "type": "string",
+ "examples": ["/path/to/example.so"]
+ },
+ "description": {
+ "description": "The description of the linter, for documentation purposes only.",
+ "type": "string"
+ },
+ "original-url": {
+ "description": "Intended to point to the repo location of the linter, for documentation purposes only.",
+ "type": "string"
+ },
+ "settings": {
+ "description": "Plugins settings/configuration. Only work with plugin based on `linterdb.PluginConstructor`.",
+ "type": "object"
+ }
+ },
+ "oneOf": [
+ {
+ "properties": {
+ "type": {"enum": ["module"] }
+ },
+ "required": ["type"]
+ },
+ {
+ "required": ["path"]
+ }
+ ]
+ }
+ }
+ }
+ }
+ }
+ },
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["version"],
+ "properties": {
+ "version": {
+ "type": "string",
+ "default": "2"
+ },
+ "run": {
+ "description": "Options for analysis running,",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "concurrency": {
+ "description": "Number of concurrent runners. Defaults to the number of available CPU cores.",
+ "type": "integer",
+ "minimum": 0,
+ "examples": [4]
+ },
+ "timeout": {
+ "description": "Timeout for the analysis.",
+ "type": "string",
+ "pattern": "^((\\d+h)?(\\d+m)?(\\d+(?:\\.\\d)?s)?|0)$",
+ "default": "1m",
+ "examples": ["30s", "5m", "5m30s"]
+ },
+ "issues-exit-code": {
+ "description": "Exit code when at least one issue was found.",
+ "type": "integer",
+ "default": 1
+ },
+ "tests": {
+ "description": "Enable inclusion of test files.",
+ "type": "boolean",
+ "default": true
+ },
+ "build-tags": {
+ "description": "List of build tags to pass to all linters.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "default": [],
+ "examples": [["mytag"]]
+ },
+ "modules-download-mode": {
+ "description": "Option to pass to \"go list -mod={option}\".\nSee \"go help modules\" for more information.",
+ "enum": ["mod", "readonly", "vendor"]
+ },
+ "allow-parallel-runners": {
+ "description": "Allow multiple parallel golangci-lint instances running. If disabled, golangci-lint acquires file lock on start.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-serial-runners": {
+ "description": "Allow multiple golangci-lint instances running, but serialize them around a lock.",
+ "type": "boolean",
+ "default": false
+ },
+ "go": {
+ "description": "Targeted Go version.",
+ "type": "string",
+ "default": "1.17"
+ },
+ "relative-path-mode": {
+ "description": "The mode used to evaluate relative paths.",
+ "type": "string",
+ "$ref": "#/definitions/relative-path-modes",
+ "default": "wd"
+ }
+ }
+ },
+ "output": {
+ "description": "Output configuration options.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "formats": {
+ "description": "Output formats to use.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "text": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "path": {
+ "$ref": "#/definitions/formats-path",
+ "default": "stdout"
+ },
+ "print-linter-name": {
+ "type": "boolean",
+ "default": true
+ },
+ "print-issued-lines": {
+ "type": "boolean",
+ "default": true
+ },
+ "colors": {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "json": {
+ "$ref": "#/definitions/simple-format"
+ },
+ "tab": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "path": {
+ "$ref": "#/definitions/formats-path",
+ "default": "stdout"
+ },
+ "print-linter-name": {
+ "type": "boolean",
+ "default": true
+ },
+ "colors": {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "html": {
+ "$ref": "#/definitions/simple-format"
+ },
+ "checkstyle": {
+ "$ref": "#/definitions/simple-format"
+ },
+ "code-climate": {
+ "$ref": "#/definitions/simple-format"
+ },
+ "junit-xml": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "path": {
+ "$ref": "#/definitions/formats-path",
+ "default": "stdout"
+ },
+ "extended": {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "teamcity": {
+ "$ref": "#/definitions/simple-format"
+ },
+ "sarif": {
+ "$ref": "#/definitions/simple-format"
+ }
+ }
+ },
+ "path-mode": {
+ "type": "string",
+ "default": "",
+ "examples": ["abs"]
+ },
+ "path-prefix": {
+ "description": "Add a prefix to the output file references.",
+ "type": "string",
+ "default": ""
+ },
+ "show-stats": {
+ "description": "Show statistics per linter.",
+ "type": "boolean",
+ "default": true
+ },
+ "sort-order": {
+ "type": "array",
+ "items": {
+ "enum": ["linter", "severity", "file"]
+ }
+ }
+ }
+ },
+ "linters": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "default": {
+ "enum": [
+ "standard",
+ "all",
+ "none",
+ "fast"
+ ]
+ },
+ "enable": {
+ "description": "List of enabled linters.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linter-names"
+ }
+ },
+ "disable": {
+ "description": "List of disabled linters.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linter-names"
+ }
+ },
+ "settings": {
+ "description": "All available settings of specific linters.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "dupword": {
+ "$ref": "#/definitions/settings/definitions/dupwordSettings"
+ },
+ "asasalint": {
+ "$ref": "#/definitions/settings/definitions/asasalintSettings"
+ },
+ "bidichk": {
+ "$ref": "#/definitions/settings/definitions/bidichkSettings"
+ },
+ "cyclop": {
+ "$ref": "#/definitions/settings/definitions/cyclopSettings"
+ },
+ "decorder": {
+ "$ref": "#/definitions/settings/definitions/decorderSettings"
+ },
+ "depguard":{
+ "$ref": "#/definitions/settings/definitions/depguardSettings"
+ },
+ "dogsled": {
+ "$ref": "#/definitions/settings/definitions/dogsledSettings"
+ },
+ "dupl": {
+ "$ref": "#/definitions/settings/definitions/duplSettings"
+ },
+ "embeddedstructfieldcheck": {
+ "$ref": "#/definitions/settings/definitions/embeddedstructfieldcheckSettings"
+ },
+ "errcheck": {
+ "$ref": "#/definitions/settings/definitions/errcheckSettings"
+ },
+ "errchkjson": {
+ "$ref": "#/definitions/settings/definitions/errchkjsonSettings"
+ },
+ "errorlint": {
+ "$ref": "#/definitions/settings/definitions/errorlintSettings"
+ },
+ "exhaustive": {
+ "$ref": "#/definitions/settings/definitions/exhaustiveSettings"
+ },
+ "exhaustruct": {
+ "$ref": "#/definitions/settings/definitions/exhaustructSettings"
+ },
+ "fatcontext": {
+ "$ref": "#/definitions/settings/definitions/fatcontextSettings"
+ },
+ "forbidigo": {
+ "$ref": "#/definitions/settings/definitions/forbidigoSettings"
+ },
+ "funcorder": {
+ "$ref": "#/definitions/settings/definitions/funcorderSettings"
+ },
+ "funlen": {
+ "$ref": "#/definitions/settings/definitions/funlenSettings"
+ },
+ "ginkgolinter": {
+ "$ref": "#/definitions/settings/definitions/ginkgolinterSettings"
+ },
+ "gochecksumtype": {
+ "$ref": "#/definitions/settings/definitions/gochecksumtypeSettings"
+ },
+ "gocognit": {
+ "$ref": "#/definitions/settings/definitions/gocognitSettings"
+ },
+ "goconst": {
+ "$ref": "#/definitions/settings/definitions/goconstSettings"
+ },
+ "gocritic": {
+ "$ref": "#/definitions/settings/definitions/gocriticSettings"
+ },
+ "gocyclo": {
+ "$ref": "#/definitions/settings/definitions/gocycloSettings"
+ },
+ "godot": {
+ "$ref": "#/definitions/settings/definitions/godotSettings"
+ },
+ "godox": {
+ "$ref": "#/definitions/settings/definitions/godoxSettings"
+ },
+ "interfacebloat":{
+ "$ref": "#/definitions/settings/definitions/interfacebloatSettings"
+ },
+ "goheader": {
+ "$ref": "#/definitions/settings/definitions/goheaderSettings"
+ },
+ "gomoddirectives": {
+ "$ref": "#/definitions/settings/definitions/gomoddirectivesSettings"
+ },
+ "gomodguard": {
+ "$ref": "#/definitions/settings/definitions/gomodguardSettings"
+ },
+ "gosec": {
+ "$ref": "#/definitions/settings/definitions/gosecSettings"
+ },
+ "gosmopolitan": {
+ "$ref": "#/definitions/settings/definitions/gosmopolitanSettings"
+ },
+ "govet": {
+ "$ref": "#/definitions/settings/definitions/govetSettings"
+ },
+ "grouper": {
+ "$ref": "#/definitions/settings/definitions/grouperSettings"
+ },
+ "iface": {
+ "$ref": "#/definitions/settings/definitions/ifaceSettings"
+ },
+ "importas": {
+ "$ref": "#/definitions/settings/definitions/importasSettings"
+ },
+ "inamedparam": {
+ "$ref": "#/definitions/settings/definitions/inamedparamSettings"
+ },
+ "ireturn": {
+ "$ref": "#/definitions/settings/definitions/ireturnSettings"
+ },
+ "lll": {
+ "$ref": "#/definitions/settings/definitions/lllSettings"
+ },
+ "maintidx": {
+ "$ref": "#/definitions/settings/definitions/maintidxSettings"
+ },
+ "makezero":{
+ "$ref": "#/definitions/settings/definitions/makezeroSettings"
+ },
+ "loggercheck": {
+ "$ref": "#/definitions/settings/definitions/loggercheckSettings"
+ },
+ "misspell": {
+ "$ref": "#/definitions/settings/definitions/misspellSettings"
+ },
+ "musttag": {
+ "$ref": "#/definitions/settings/definitions/musttagSettings"
+ },
+ "nakedret": {
+ "$ref": "#/definitions/settings/definitions/nakedretSettings"
+ },
+ "nestif": {
+ "$ref": "#/definitions/settings/definitions/nestifSettings"
+ },
+ "nilnil": {
+ "$ref": "#/definitions/settings/definitions/nilnilSettings"
+ },
+ "nlreturn": {
+ "$ref": "#/definitions/settings/definitions/nlreturnSettings"
+ },
+ "mnd": {
+ "$ref": "#/definitions/settings/definitions/mndSettings"
+ },
+ "nolintlint":{
+ "$ref": "#/definitions/settings/definitions/nolintlintSettings"
+ },
+ "reassign": {
+ "$ref": "#/definitions/settings/definitions/reassignSettings"
+ },
+ "recvcheck": {
+ "$ref": "#/definitions/settings/definitions/recvcheckSettings"
+ },
+ "nonamedreturns": {
+ "$ref": "#/definitions/settings/definitions/nonamedreturnsSettings"
+ },
+ "paralleltest": {
+ "$ref": "#/definitions/settings/definitions/paralleltestSettings"
+ },
+ "perfsprint": {
+ "$ref": "#/definitions/settings/definitions/perfsprintSettings"
+ },
+ "prealloc": {
+ "$ref": "#/definitions/settings/definitions/preallocSettings"
+ },
+ "predeclared": {
+ "$ref": "#/definitions/settings/definitions/predeclaredSettings"
+ },
+ "promlinter": {
+ "$ref": "#/definitions/settings/definitions/promlinterSettings"
+ },
+ "protogetter": {
+ "$ref": "#/definitions/settings/definitions/protogetterSettings"
+ },
+ "revive": {
+ "$ref": "#/definitions/settings/definitions/reviveSettings"
+ },
+ "rowserrcheck": {
+ "$ref": "#/definitions/settings/definitions/rowserrcheckSettings"
+ },
+ "sloglint": {
+ "$ref": "#/definitions/settings/definitions/sloglintSettings"
+ },
+ "spancheck": {
+ "$ref": "#/definitions/settings/definitions/spancheckSettings"
+ },
+ "staticcheck":{
+ "$ref": "#/definitions/settings/definitions/staticcheckSettings"
+ },
+ "tagalign": {
+ "$ref": "#/definitions/settings/definitions/tagalignSettings"
+ },
+ "tagliatelle": {
+ "$ref": "#/definitions/settings/definitions/tagliatelleSettings"
+ },
+ "testifylint": {
+ "$ref": "#/definitions/settings/definitions/testifylintSettings"
+ },
+ "testpackage": {
+ "$ref": "#/definitions/settings/definitions/testpackageSettings"
+ },
+ "thelper": {
+ "$ref": "#/definitions/settings/definitions/thelperSettings"
+ },
+ "usestdlibvars": {
+ "$ref": "#/definitions/settings/definitions/usestdlibvarsSettings"
+ },
+ "usetesting": {
+ "$ref": "#/definitions/settings/definitions/usetestingSettings"
+ },
+ "unconvert": {
+ "$ref": "#/definitions/settings/definitions/unconvertSettings"
+ },
+ "unparam": {
+ "$ref": "#/definitions/settings/definitions/unparamSettings"
+ },
+ "unused": {
+ "$ref": "#/definitions/settings/definitions/unusedSettings"
+ },
+ "varnamelen": {
+ "$ref": "#/definitions/settings/definitions/varnamelenSettings"
+ },
+ "whitespace": {
+ "$ref": "#/definitions/settings/definitions/whitespaceSettings"
+ },
+ "wrapcheck": {
+ "$ref": "#/definitions/settings/definitions/wrapcheckSettings"
+ },
+ "wsl": {
+ "$ref": "#/definitions/settings/definitions/wslSettings"
+ },
+ "wsl_v5": {
+ "$ref": "#/definitions/settings/definitions/wslSettingsV5"
+ },
+ "copyloopvar": {
+ "$ref": "#/definitions/settings/definitions/copyloopvarSettings"
+ },
+ "custom":{
+ "$ref": "#/definitions/settings/definitions/customSettings"
+ }
+ }
+ },
+ "exclusions":{
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "generated": {
+ "enum": ["strict", "lax", "disable"],
+ "default": "strict"
+ },
+ "warn-unused": {
+ "type": "boolean",
+ "default": false
+ },
+ "presets": {
+ "type": "array",
+ "items": {
+ "enum": [
+ "comments",
+ "std-error-handling",
+ "common-false-positives",
+ "legacy"
+ ]
+ }
+ },
+ "rules": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "path": {
+ "type": "string"
+ },
+ "path-except": {
+ "type": "string"
+ },
+ "linters": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linter-names"
+ }
+ },
+ "text": {
+ "type": "string"
+ },
+ "source": {
+ "type": "string"
+ }
+ },
+ "anyOf": [
+ { "required": ["path"] },
+ { "required": ["path-except"] },
+ { "required": ["linters"] },
+ { "required": ["text"] },
+ { "required": ["source"] }
+ ]
+ }
+ },
+ "paths": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "paths-except": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "formatters": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "enable": {
+ "description": "List of enabled formatters.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/formatter-names"
+ }
+ },
+ "settings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "gci": {
+ "$ref": "#/definitions/settings/definitions/gciSettings"
+ },
+ "gofmt": {
+ "$ref": "#/definitions/settings/definitions/gofmtSettings"
+ },
+ "gofumpt": {
+ "$ref": "#/definitions/settings/definitions/gofumptSettings"
+ },
+ "goimports": {
+ "$ref": "#/definitions/settings/definitions/goimportsSettings"
+ },
+ "golines": {
+ "$ref": "#/definitions/settings/definitions/golinesSettings"
+ }
+ }
+ },
+ "exclusions": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "generated": {
+ "enum": ["strict", "lax", "disable"],
+ "default": "strict"
+ },
+ "paths": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "warn-unused": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ }
+ }
+ },
+ "issues": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-issues-per-linter": {
+ "description": "Maximum issues count per one linter. Set to 0 to disable.",
+ "type": "integer",
+ "default": 50,
+ "minimum": 0
+ },
+ "max-same-issues": {
+ "description": "Maximum count of issues with the same text. Set to 0 to disable.",
+ "type": "integer",
+ "default": 3,
+ "minimum": 0
+ },
+ "new": {
+ "description": "Show only new issues: if there are unstaged changes or untracked files, only those changes are analyzed, else only changes in HEAD~ are analyzed.",
+ "type": "boolean",
+ "default": false
+ },
+ "new-from-merge-base": {
+ "description": "Show only new issues created after the best common ancestor (merge-base against HEAD).",
+ "type": "string"
+ },
+ "new-from-rev": {
+ "description": "Show only new issues created after this git revision.",
+ "type": "string"
+ },
+ "new-from-patch": {
+ "description": "Show only new issues created in git patch with this file path.",
+ "type": "string",
+ "examples": ["path/to/patch/file"]
+ },
+ "fix": {
+ "description": "Fix found issues (if it's supported by the linter).",
+ "type": "boolean",
+ "default": false
+ },
+ "uniq-by-line": {
+ "description": "Make issues output unique by line.",
+ "type": "boolean",
+ "default": true
+ },
+ "whole-files": {
+ "description": "Show issues in any part of update files (requires new-from-rev or new-from-patch).",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "severity": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "default": {
+ "description": "Set the default severity for issues. If severity rules are defined and the issues do not match or no severity is provided to the rule this will be the default severity applied. Severities should match the supported severity names of the selected out format.",
+ "type": "string",
+ "default": ""
+ },
+ "rules": {
+ "description": "When a list of severity rules are provided, severity information will be added to lint issues. Severity rules have the same filtering capability as exclude rules except you are allowed to specify one matcher per severity rule.\nOnly affects out formats that support setting severity information.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "severity": {
+ "type": "string"
+ },
+ "path": {
+ "type": "string"
+ },
+ "path-except": {
+ "type": "string"
+ },
+ "linters": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linter-names"
+ }
+ },
+ "text": {
+ "type": "string"
+ },
+ "source": {
+ "type": "string"
+ }
+ },
+ "required": ["severity"],
+ "anyOf": [
+ { "required": ["path"] },
+ { "required": ["path-except"] },
+ { "required": ["linters"] },
+ { "required": ["text"] },
+ { "required": ["source"] }
+ ]
+ },
+ "default": []
+ }
+ },
+ "required": ["default"]
+ }
+ }
+}
diff --git a/vendor/github.com/golangci/golangci-lint/v2/jsonschema/golangci.v2.3.jsonschema.json b/vendor/github.com/golangci/golangci-lint/v2/jsonschema/golangci.v2.3.jsonschema.json
new file mode 100644
index 000000000..7c4840521
--- /dev/null
+++ b/vendor/github.com/golangci/golangci-lint/v2/jsonschema/golangci.v2.3.jsonschema.json
@@ -0,0 +1,4907 @@
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "$id": "https://json.schemastore.org/golangci-lint.json",
+ "definitions": {
+ "gocritic-checks": {
+ "enum": [
+ "appendAssign",
+ "appendCombine",
+ "argOrder",
+ "assignOp",
+ "badCall",
+ "badCond",
+ "badLock",
+ "badRegexp",
+ "badSorting",
+ "badSyncOnceFunc",
+ "boolExprSimplify",
+ "builtinShadow",
+ "builtinShadowDecl",
+ "captLocal",
+ "caseOrder",
+ "codegenComment",
+ "commentFormatting",
+ "commentedOutCode",
+ "commentedOutImport",
+ "defaultCaseOrder",
+ "deferInLoop",
+ "deferUnlambda",
+ "deprecatedComment",
+ "docStub",
+ "dupArg",
+ "dupBranchBody",
+ "dupCase",
+ "dupImport",
+ "dupSubExpr",
+ "dynamicFmtString",
+ "elseif",
+ "emptyDecl",
+ "emptyFallthrough",
+ "emptyStringTest",
+ "equalFold",
+ "evalOrder",
+ "exitAfterDefer",
+ "exposedSyncMutex",
+ "externalErrorReassign",
+ "filepathJoin",
+ "flagDeref",
+ "flagName",
+ "hexLiteral",
+ "httpNoBody",
+ "hugeParam",
+ "ifElseChain",
+ "importShadow",
+ "indexAlloc",
+ "initClause",
+ "ioutilDeprecated",
+ "mapKey",
+ "methodExprCall",
+ "nestingReduce",
+ "newDeref",
+ "nilValReturn",
+ "octalLiteral",
+ "offBy1",
+ "paramTypeCombine",
+ "preferDecodeRune",
+ "preferFilepathJoin",
+ "preferFprint",
+ "preferStringWriter",
+ "preferWriteByte",
+ "ptrToRefParam",
+ "rangeAppendAll",
+ "rangeExprCopy",
+ "rangeValCopy",
+ "redundantSprint",
+ "regexpMust",
+ "regexpPattern",
+ "regexpSimplify",
+ "returnAfterHttpError",
+ "ruleguard",
+ "singleCaseSwitch",
+ "sliceClear",
+ "sloppyLen",
+ "sloppyReassign",
+ "sloppyTypeAssert",
+ "sortSlice",
+ "sprintfQuotedString",
+ "sqlQuery",
+ "stringConcatSimplify",
+ "stringXbytes",
+ "stringsCompare",
+ "switchTrue",
+ "syncMapLoadAndDelete",
+ "timeExprSimplify",
+ "todoCommentWithoutDetail",
+ "tooManyResultsChecker",
+ "truncateCmp",
+ "typeAssertChain",
+ "typeDefFirst",
+ "typeSwitchVar",
+ "typeUnparen",
+ "uncheckedInlineErr",
+ "underef",
+ "unlabelStmt",
+ "unlambda",
+ "unnamedResult",
+ "unnecessaryBlock",
+ "unnecessaryDefer",
+ "unslice",
+ "valSwap",
+ "weakCond",
+ "whyNoLint",
+ "wrapperFunc",
+ "yodaStyleExpr"
+ ]
+ },
+ "gocritic-tags": {
+ "enum": [
+ "diagnostic",
+ "style",
+ "performance",
+ "experimental",
+ "opinionated",
+ "security"
+ ]
+ },
+ "staticcheck-checks": {
+ "enum": [
+ "*",
+ "all",
+ "SA*",
+ "-SA*",
+ "SA1*",
+ "-SA1*",
+ "SA1000",
+ "-SA1000",
+ "SA1001",
+ "-SA1001",
+ "SA1002",
+ "-SA1002",
+ "SA1003",
+ "-SA1003",
+ "SA1004",
+ "-SA1004",
+ "SA1005",
+ "-SA1005",
+ "SA1006",
+ "-SA1006",
+ "SA1007",
+ "-SA1007",
+ "SA1008",
+ "-SA1008",
+ "SA1010",
+ "-SA1010",
+ "SA1011",
+ "-SA1011",
+ "SA1012",
+ "-SA1012",
+ "SA1013",
+ "-SA1013",
+ "SA1014",
+ "-SA1014",
+ "SA1015",
+ "-SA1015",
+ "SA1016",
+ "-SA1016",
+ "SA1017",
+ "-SA1017",
+ "SA1018",
+ "-SA1018",
+ "SA1019",
+ "-SA1019",
+ "SA1020",
+ "-SA1020",
+ "SA1021",
+ "-SA1021",
+ "SA1023",
+ "-SA1023",
+ "SA1024",
+ "-SA1024",
+ "SA1025",
+ "-SA1025",
+ "SA1026",
+ "-SA1026",
+ "SA1027",
+ "-SA1027",
+ "SA1028",
+ "-SA1028",
+ "SA1029",
+ "-SA1029",
+ "SA1030",
+ "-SA1030",
+ "SA1031",
+ "-SA1031",
+ "SA1032",
+ "-SA1032",
+ "SA2*",
+ "-SA2*",
+ "SA2000",
+ "-SA2000",
+ "SA2001",
+ "-SA2001",
+ "SA2002",
+ "-SA2002",
+ "SA2003",
+ "-SA2003",
+ "SA3*",
+ "-SA3*",
+ "SA3000",
+ "-SA3000",
+ "SA3001",
+ "-SA3001",
+ "SA4*",
+ "-SA4*",
+ "SA4000",
+ "-SA4000",
+ "SA4001",
+ "-SA4001",
+ "SA4003",
+ "-SA4003",
+ "SA4004",
+ "-SA4004",
+ "SA4005",
+ "-SA4005",
+ "SA4006",
+ "-SA4006",
+ "SA4008",
+ "-SA4008",
+ "SA4009",
+ "-SA4009",
+ "SA4010",
+ "-SA4010",
+ "SA4011",
+ "-SA4011",
+ "SA4012",
+ "-SA4012",
+ "SA4013",
+ "-SA4013",
+ "SA4014",
+ "-SA4014",
+ "SA4015",
+ "-SA4015",
+ "SA4016",
+ "-SA4016",
+ "SA4017",
+ "-SA4017",
+ "SA4018",
+ "-SA4018",
+ "SA4019",
+ "-SA4019",
+ "SA4020",
+ "-SA4020",
+ "SA4021",
+ "-SA4021",
+ "SA4022",
+ "-SA4022",
+ "SA4023",
+ "-SA4023",
+ "SA4024",
+ "-SA4024",
+ "SA4025",
+ "-SA4025",
+ "SA4026",
+ "-SA4026",
+ "SA4027",
+ "-SA4027",
+ "SA4028",
+ "-SA4028",
+ "SA4029",
+ "-SA4029",
+ "SA4030",
+ "-SA4030",
+ "SA4031",
+ "-SA4031",
+ "SA4032",
+ "-SA4032",
+ "SA5*",
+ "-SA5*",
+ "SA5000",
+ "-SA5000",
+ "SA5001",
+ "-SA5001",
+ "SA5002",
+ "-SA5002",
+ "SA5003",
+ "-SA5003",
+ "SA5004",
+ "-SA5004",
+ "SA5005",
+ "-SA5005",
+ "SA5007",
+ "-SA5007",
+ "SA5008",
+ "-SA5008",
+ "SA5009",
+ "-SA5009",
+ "SA5010",
+ "-SA5010",
+ "SA5011",
+ "-SA5011",
+ "SA5012",
+ "-SA5012",
+ "SA6*",
+ "-SA6*",
+ "SA6000",
+ "-SA6000",
+ "SA6001",
+ "-SA6001",
+ "SA6002",
+ "-SA6002",
+ "SA6003",
+ "-SA6003",
+ "SA6005",
+ "-SA6005",
+ "SA6006",
+ "-SA6006",
+ "SA9*",
+ "-SA9*",
+ "SA9001",
+ "-SA9001",
+ "SA9002",
+ "-SA9002",
+ "SA9003",
+ "-SA9003",
+ "SA9004",
+ "-SA9004",
+ "SA9005",
+ "-SA9005",
+ "SA9006",
+ "-SA9006",
+ "SA9007",
+ "-SA9007",
+ "SA9008",
+ "-SA9008",
+ "SA9009",
+ "-SA9009",
+ "ST*",
+ "-ST*",
+ "ST1*",
+ "-ST1*",
+ "ST1000",
+ "-ST1000",
+ "ST1001",
+ "-ST1001",
+ "ST1003",
+ "-ST1003",
+ "ST1005",
+ "-ST1005",
+ "ST1006",
+ "-ST1006",
+ "ST1008",
+ "-ST1008",
+ "ST1011",
+ "-ST1011",
+ "ST1012",
+ "-ST1012",
+ "ST1013",
+ "-ST1013",
+ "ST1015",
+ "-ST1015",
+ "ST1016",
+ "-ST1016",
+ "ST1017",
+ "-ST1017",
+ "ST1018",
+ "-ST1018",
+ "ST1019",
+ "-ST1019",
+ "ST1020",
+ "-ST1020",
+ "ST1021",
+ "-ST1021",
+ "ST1022",
+ "-ST1022",
+ "ST1023",
+ "-ST1023",
+ "S*",
+ "-S*",
+ "S1*",
+ "-S1*",
+ "S1000",
+ "-S1000",
+ "S1001",
+ "-S1001",
+ "S1002",
+ "-S1002",
+ "S1003",
+ "-S1003",
+ "S1004",
+ "-S1004",
+ "S1005",
+ "-S1005",
+ "S1006",
+ "-S1006",
+ "S1007",
+ "-S1007",
+ "S1008",
+ "-S1008",
+ "S1009",
+ "-S1009",
+ "S1010",
+ "-S1010",
+ "S1011",
+ "-S1011",
+ "S1012",
+ "-S1012",
+ "S1016",
+ "-S1016",
+ "S1017",
+ "-S1017",
+ "S1018",
+ "-S1018",
+ "S1019",
+ "-S1019",
+ "S1020",
+ "-S1020",
+ "S1021",
+ "-S1021",
+ "S1023",
+ "-S1023",
+ "S1024",
+ "-S1024",
+ "S1025",
+ "-S1025",
+ "S1028",
+ "-S1028",
+ "S1029",
+ "-S1029",
+ "S1030",
+ "-S1030",
+ "S1031",
+ "-S1031",
+ "S1032",
+ "-S1032",
+ "S1033",
+ "-S1033",
+ "S1034",
+ "-S1034",
+ "S1035",
+ "-S1035",
+ "S1036",
+ "-S1036",
+ "S1037",
+ "-S1037",
+ "S1038",
+ "-S1038",
+ "S1039",
+ "-S1039",
+ "S1040",
+ "-S1040",
+ "QF*",
+ "-QF*",
+ "QF1*",
+ "-QF1*",
+ "QF1001",
+ "-QF1001",
+ "QF1002",
+ "-QF1002",
+ "QF1003",
+ "-QF1003",
+ "QF1004",
+ "-QF1004",
+ "QF1005",
+ "-QF1005",
+ "QF1006",
+ "-QF1006",
+ "QF1007",
+ "-QF1007",
+ "QF1008",
+ "-QF1008",
+ "QF1009",
+ "-QF1009",
+ "QF1010",
+ "-QF1010",
+ "QF1011",
+ "-QF1011",
+ "QF1012",
+ "-QF1012"
+ ]
+ },
+ "gosec-rules": {
+ "enum": [
+ "G101",
+ "G102",
+ "G103",
+ "G104",
+ "G106",
+ "G107",
+ "G108",
+ "G109",
+ "G110",
+ "G111",
+ "G112",
+ "G114",
+ "G115",
+ "G201",
+ "G202",
+ "G203",
+ "G204",
+ "G301",
+ "G302",
+ "G303",
+ "G304",
+ "G305",
+ "G306",
+ "G307",
+ "G401",
+ "G402",
+ "G403",
+ "G404",
+ "G405",
+ "G406",
+ "G501",
+ "G502",
+ "G503",
+ "G504",
+ "G505",
+ "G506",
+ "G507",
+ "G601",
+ "G602"
+ ]
+ },
+ "govet-analyzers": {
+ "enum": [
+ "appends",
+ "asmdecl",
+ "assign",
+ "atomic",
+ "atomicalign",
+ "bools",
+ "buildtag",
+ "cgocall",
+ "composites",
+ "copylocks",
+ "deepequalerrors",
+ "defers",
+ "directive",
+ "errorsas",
+ "fieldalignment",
+ "findcall",
+ "framepointer",
+ "hostport",
+ "httpmux",
+ "httpresponse",
+ "ifaceassert",
+ "loopclosure",
+ "lostcancel",
+ "nilfunc",
+ "nilness",
+ "printf",
+ "reflectvaluecompare",
+ "shadow",
+ "shift",
+ "sigchanyzer",
+ "slog",
+ "sortslice",
+ "stdmethods",
+ "stdversion",
+ "stringintconv",
+ "structtag",
+ "testinggoroutine",
+ "tests",
+ "timeformat",
+ "unmarshal",
+ "unreachable",
+ "unsafeptr",
+ "unusedresult",
+ "unusedwrite",
+ "waitgroup"
+ ]
+ },
+ "revive-rules": {
+ "enum": [
+ "add-constant",
+ "argument-limit",
+ "atomic",
+ "banned-characters",
+ "bare-return",
+ "blank-imports",
+ "bool-literal-in-expr",
+ "call-to-gc",
+ "cognitive-complexity",
+ "comment-spacings",
+ "comments-density",
+ "confusing-naming",
+ "confusing-results",
+ "constant-logical-expr",
+ "context-as-argument",
+ "context-keys-type",
+ "cyclomatic",
+ "datarace",
+ "deep-exit",
+ "defer",
+ "dot-imports",
+ "duplicated-imports",
+ "early-return",
+ "empty-block",
+ "empty-lines",
+ "enforce-map-style",
+ "enforce-repeated-arg-type-style",
+ "enforce-slice-style",
+ "enforce-switch-style",
+ "error-naming",
+ "error-return",
+ "error-strings",
+ "errorf",
+ "exported",
+ "file-header",
+ "file-length-limit",
+ "filename-format",
+ "flag-parameter",
+ "function-length",
+ "function-result-limit",
+ "get-return",
+ "identical-branches",
+ "if-return",
+ "import-alias-naming",
+ "import-shadowing",
+ "imports-blocklist",
+ "increment-decrement",
+ "indent-error-flow",
+ "line-length-limit",
+ "max-control-nesting",
+ "max-public-structs",
+ "modifies-parameter",
+ "modifies-value-receiver",
+ "nested-structs",
+ "optimize-operands-order",
+ "package-comments",
+ "range-val-address",
+ "range-val-in-closure",
+ "range",
+ "receiver-naming",
+ "redefines-builtin-id",
+ "redundant-build-tag",
+ "redundant-import-alias",
+ "redundant-test-main-exit",
+ "string-format",
+ "string-of-int",
+ "struct-tag",
+ "superfluous-else",
+ "time-date",
+ "time-equal",
+ "time-naming",
+ "unchecked-type-assertion",
+ "unconditional-recursion",
+ "unexported-naming",
+ "unexported-return",
+ "unhandled-error",
+ "unnecessary-format",
+ "unnecessary-stmt",
+ "unreachable-code",
+ "unused-parameter",
+ "unused-receiver",
+ "use-any",
+ "use-errors-new",
+ "use-fmt-print",
+ "useless-break",
+ "var-declaration",
+ "var-naming",
+ "waitgroup-by-value"
+ ]
+ },
+ "iface-analyzers": {
+ "enum": [
+ "identical",
+ "unused",
+ "opaque",
+ "unexported"
+ ]
+ },
+ "tagliatelle-cases": {
+ "enum": [
+ "",
+ "camel",
+ "pascal",
+ "kebab",
+ "snake",
+ "goCamel",
+ "goPascal",
+ "goKebab",
+ "goSnake",
+ "upper",
+ "upperSnake",
+ "lower",
+ "header"
+ ]
+ },
+ "wsl-checks": {
+ "enum": [
+ "assign",
+ "branch",
+ "decl",
+ "defer",
+ "expr",
+ "for",
+ "go",
+ "if",
+ "inc-dec",
+ "label",
+ "range",
+ "return",
+ "select",
+ "send",
+ "switch",
+ "type-switch",
+ "append",
+ "assign-exclusive",
+ "assign-expr",
+ "err",
+ "leading-whitespace",
+ "trailing-whitespace"
+ ]
+ },
+ "relative-path-modes": {
+ "enum": [
+ "gomod",
+ "gitroot",
+ "cfg",
+ "wd"
+ ]
+ },
+ "simple-format": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "path": {
+ "$ref": "#/definitions/formats-path",
+ "default": "stdout"
+ }
+ }
+ },
+ "formats-path" : {
+ "anyOf": [
+ {
+ "enum": [
+ "stdout",
+ "stderr"
+ ]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ },
+ "linter-names": {
+ "$comment": "anyOf with enum is used to allow auto-completion of non-custom linters",
+ "description": "Usable linter names.",
+ "anyOf": [
+ {
+ "enum": [
+ "arangolint",
+ "asasalint",
+ "asciicheck",
+ "bidichk",
+ "bodyclose",
+ "canonicalheader",
+ "containedctx",
+ "contextcheck",
+ "copyloopvar",
+ "cyclop",
+ "decorder",
+ "depguard",
+ "dogsled",
+ "dupl",
+ "dupword",
+ "durationcheck",
+ "embeddedstructfieldcheck",
+ "errcheck",
+ "errchkjson",
+ "errname",
+ "errorlint",
+ "exhaustive",
+ "exhaustruct",
+ "exptostd",
+ "fatcontext",
+ "forbidigo",
+ "forcetypeassert",
+ "funcorder",
+ "funlen",
+ "ginkgolinter",
+ "gocheckcompilerdirectives",
+ "gochecknoglobals",
+ "gochecknoinits",
+ "gochecksumtype",
+ "gocognit",
+ "goconst",
+ "gocritic",
+ "gocyclo",
+ "godot",
+ "godox",
+ "err113",
+ "goheader",
+ "gomoddirectives",
+ "gomodguard",
+ "goprintffuncname",
+ "gosec",
+ "gosimple",
+ "gosmopolitan",
+ "govet",
+ "grouper",
+ "iface",
+ "importas",
+ "inamedparam",
+ "ineffassign",
+ "interfacebloat",
+ "intrange",
+ "ireturn",
+ "lll",
+ "loggercheck",
+ "maintidx",
+ "makezero",
+ "mirror",
+ "misspell",
+ "mnd",
+ "musttag",
+ "nakedret",
+ "nestif",
+ "nilerr",
+ "nilnesserr",
+ "nilnil",
+ "nlreturn",
+ "noctx",
+ "noinlineerr",
+ "nolintlint",
+ "nonamedreturns",
+ "nosprintfhostport",
+ "paralleltest",
+ "perfsprint",
+ "prealloc",
+ "predeclared",
+ "promlinter",
+ "protogetter",
+ "reassign",
+ "recvcheck",
+ "revive",
+ "rowserrcheck",
+ "sloglint",
+ "sqlclosecheck",
+ "staticcheck",
+ "stylecheck",
+ "tagalign",
+ "tagliatelle",
+ "testableexamples",
+ "testifylint",
+ "testpackage",
+ "thelper",
+ "tparallel",
+ "unconvert",
+ "unparam",
+ "unused",
+ "usestdlibvars",
+ "usetesting",
+ "varnamelen",
+ "wastedassign",
+ "whitespace",
+ "wrapcheck",
+ "wsl",
+ "wsl_v5",
+ "zerologlint"
+ ]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ },
+ "formatter-names": {
+ "description": "Usable formatter names.",
+ "enum": [
+ "gci",
+ "gofmt",
+ "gofumpt",
+ "goimports",
+ "golines",
+ "swaggo"
+ ]
+ },
+ "settings": {
+ "definitions": {
+ "dupwordSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "keywords": {
+ "description": "Keywords for detecting duplicate words. If this list is not empty, only the words defined in this list will be detected.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["the", "and", "a"]
+ }
+ },
+ "ignore": {
+ "description": "Keywords used to ignore detection.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["0C0C"]
+ }
+ }
+ }
+ },
+ "asasalintSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "exclude": {
+ "description": "To specify a set of function names to exclude.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["\\.Wrapf"]
+ }
+ },
+ "use-builtin-exclusions": {
+ "description": "To enable/disable the asasalint builtin exclusions of function names.",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "bidichkSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "left-to-right-embedding": {
+ "description": "Disallow: LEFT-TO-RIGHT-EMBEDDING",
+ "type": "boolean",
+ "default": false
+ },
+ "right-to-left-embedding": {
+ "description": "Disallow: RIGHT-TO-LEFT-EMBEDDING",
+ "type": "boolean",
+ "default": false
+ },
+ "pop-directional-formatting": {
+ "description": "Disallow: POP-DIRECTIONAL-FORMATTING",
+ "type": "boolean",
+ "default": false
+ },
+ "left-to-right-override": {
+ "description": "Disallow: LEFT-TO-RIGHT-OVERRIDE",
+ "type": "boolean",
+ "default": false
+ },
+ "right-to-left-override": {
+ "description": "Disallow: RIGHT-TO-LEFT-OVERRIDE",
+ "type": "boolean",
+ "default": false
+ },
+ "left-to-right-isolate": {
+ "description": "Disallow: LEFT-TO-RIGHT-ISOLATE",
+ "type": "boolean",
+ "default": false
+ },
+ "right-to-left-isolate": {
+ "description": "Disallow: RIGHT-TO-LEFT-ISOLATE",
+ "type": "boolean",
+ "default": false
+ },
+ "first-strong-isolate": {
+ "description": "Disallow: FIRST-STRONG-ISOLATE",
+ "type": "boolean",
+ "default": false
+ },
+ "pop-directional-isolate": {
+ "description": "Disallow: POP-DIRECTIONAL-ISOLATE",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "cyclopSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-complexity": {
+ "description": "Max complexity the function can have",
+ "type": "integer",
+ "default": 10,
+ "minimum": 0
+ },
+ "package-average": {
+ "description": "Max average complexity in package",
+ "type": "number",
+ "default": 0,
+ "minimum": 0
+ }
+ }
+ },
+ "decorderSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "dec-order": {
+ "type": "array",
+ "default": [["type", "const", "var", "func"]],
+ "items": {
+ "enum": ["type", "const", "var", "func"]
+ }
+ },
+ "ignore-underscore-vars": {
+ "description": "Underscore vars (vars with \"_\" as the name) will be ignored at all checks",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-dec-order-check": {
+ "description": "Order of declarations is not checked",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-init-func-first-check": {
+ "description": "Allow init func to be anywhere in file",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-dec-num-check": {
+ "description": "Multiple global type, const and var declarations are allowed",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-type-dec-num-check": {
+ "description": "Type declarations will be ignored for dec num check",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-const-dec-num-check": {
+ "description": "Const declarations will be ignored for dec num check",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-var-dec-num-check": {
+ "description": "Var declarations will be ignored for dec num check",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ },
+ "depguardSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "rules": {
+ "description": "Rules to apply.",
+ "type": "object",
+ "additionalProperties": false,
+ "patternProperties": {
+ "^[^.]+$": {
+ "description": "Name of a rule.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "list-mode": {
+ "description": "Used to determine the package matching priority.",
+ "enum": ["original", "strict", "lax"],
+ "default": "original"
+ },
+ "files": {
+ "description": "List of file globs that will match this list of settings to compare against.",
+ "additionalProperties": false,
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "allow": {
+ "description": "List of allowed packages.",
+ "additionalProperties": false,
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "deny": {
+ "description": "Packages that are not allowed where the value is a suggestion.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "desc": {
+ "description": "Description",
+ "type": "string"
+ },
+ "pkg": {
+ "description": "Package",
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "dogsledSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-blank-identifiers": {
+ "description": "Check assignments with too many blank identifiers.",
+ "type": "integer",
+ "default": 2,
+ "minimum": 0
+ }
+ }
+ },
+ "duplSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "threshold": {
+ "description": "Tokens count to trigger issue.",
+ "type": "integer",
+ "default": 150,
+ "minimum": 0
+ }
+ }
+ },
+ "embeddedstructfieldcheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "forbid-mutex": {
+ "description": "Checks that sync.Mutex and sync.RWMutex are not used as embedded fields.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "errcheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-type-assertions": {
+ "description": "Report about not checking errors in type assertions, i.e.: `a := b.(MyStruct)`",
+ "type": "boolean",
+ "default": false
+ },
+ "check-blank": {
+ "description": "Report about assignment of errors to blank identifier",
+ "type": "boolean",
+ "default": false
+ },
+ "exclude-functions": {
+ "description": "List of functions to exclude from checking, where each entry is a single function to exclude",
+ "type": "array",
+ "examples": ["io/ioutil.ReadFile", "io.Copy(*bytes.Buffer)"],
+ "items": {
+ "type": "string"
+ }
+ },
+ "disable-default-exclusions": {
+ "description": "To disable the errcheck built-in exclude list",
+ "type": "boolean",
+ "default": false
+ },
+ "verbose": {
+ "description": "Display function signature instead of selector",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "errchkjsonSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-error-free-encoding": {
+ "type": "boolean",
+ "default": false
+ },
+ "report-no-exported": {
+ "description": "Issue on struct that doesn't have exported fields.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "errorlintSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "errorf": {
+ "description": "Check whether fmt.Errorf uses the %w verb for formatting errors",
+ "type": "boolean",
+ "default": true
+ },
+ "errorf-multi": {
+ "description": "Permit more than 1 %w verb, valid per Go 1.20",
+ "type": "boolean",
+ "default": true
+ },
+ "asserts": {
+ "description": "Check for plain type assertions and type switches.",
+ "type": "boolean",
+ "default": true
+ },
+ "comparison": {
+ "description": "Check for plain error comparisons",
+ "type": "boolean",
+ "default": true
+ },
+ "allowed-errors": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "err": {
+ "type": "string"
+ },
+ "fun": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "allowed-errors-wildcard": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "err": {
+ "type": "string"
+ },
+ "fun": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "exhaustiveSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check": {
+ "description": "Program elements to check for exhaustiveness.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["switch", "map"]
+ }
+ },
+ "explicit-exhaustive-switch": {
+ "description": "Only run exhaustive check on switches with \"//exhaustive:enforce\" comment.",
+ "type": "boolean",
+ "default": false
+ },
+ "explicit-exhaustive-map": {
+ "description": "Only run exhaustive check on map literals with \"//exhaustive:enforce\" comment.",
+ "type": "boolean",
+ "default": false
+ },
+ "default-case-required": {
+ "description": "Switch statement requires default case even if exhaustive.",
+ "type": "boolean",
+ "default": false
+ },
+ "default-signifies-exhaustive": {
+ "description": "Presence of `default` case in switch statements satisfies exhaustiveness, even if all enum members are not listed.",
+ "type": "boolean",
+ "default": false
+ },
+ "ignore-enum-members": {
+ "description": "Enum members matching `regex` do not have to be listed in switch statements to satisfy exhaustiveness",
+ "type": "string"
+ },
+ "ignore-enum-types": {
+ "description": "Enum types matching the supplied regex do not have to be listed in switch statements to satisfy exhaustiveness.",
+ "type": "string"
+ },
+ "package-scope-only": {
+ "description": "Consider enums only in package scopes, not in inner scopes.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "exhaustructSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "include": {
+ "description": "List of regular expressions to match struct packages and names.",
+ "type": "array",
+ "examples": [".*\\.Test"],
+ "items": {
+ "type": "string"
+ }
+ },
+ "exclude": {
+ "description": "List of regular expressions to exclude struct packages and names from check.",
+ "type": "array",
+ "examples": ["cobra\\.Command$"],
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "fatcontextSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-struct-pointers": {
+ "description": "Check for potential fat contexts in struct pointers.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "forbidigoSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "exclude-godoc-examples": {
+ "description": "Exclude code in godoc examples.",
+ "type": "boolean",
+ "default": true
+ },
+ "analyze-types": {
+ "description": "Instead of matching the literal source code, use type information to replace expressions with strings that contain the package name and (for methods and fields) the type name.",
+ "type": "boolean",
+ "default": true
+ },
+ "forbid": {
+ "description": "List of identifiers to forbid (written using `regexp`)",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "pattern": {
+ "description": "Pattern",
+ "type": "string"
+ },
+ "pkg": {
+ "description": "Package",
+ "type": "string"
+ },
+ "msg": {
+ "description": "Message",
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "funcorderSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "constructor": {
+ "description": "Checks that constructors are placed after the structure declaration.",
+ "type": "boolean",
+ "default": true
+ },
+ "struct-method": {
+ "description": "Checks if the exported methods of a structure are placed before the non-exported ones.",
+ "type": "boolean",
+ "default": true
+ },
+ "alphabetical": {
+ "description": "Checks if the constructors and/or structure methods are sorted alphabetically.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "funlenSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "lines": {
+ "description": "Limit lines number per function.",
+ "type": "integer",
+ "default": 60
+ },
+ "statements": {
+ "description": "Limit statements number per function.",
+ "type": "integer",
+ "default": 40
+ },
+ "ignore-comments": {
+ "description": "Ignore comments when counting lines.",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "gciSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "sections": {
+ "description": "Section configuration to compare against.",
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "enum": [
+ "standard",
+ "default",
+ "blank",
+ "dot",
+ "alias",
+ "localmodule"
+ ]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ },
+ "default": ["standard", "default"]
+ },
+ "no-inline-comments": {
+ "description": "Checks that no inline Comments are present.",
+ "type": "boolean",
+ "default": false
+ },
+ "no-prefix-comments": {
+ "description": "Checks that no prefix Comments(comment lines above an import) are present.",
+ "type": "boolean",
+ "default": false
+ },
+ "custom-order": {
+ "description": "Enable custom order of sections.",
+ "type": "boolean",
+ "default": false
+ },
+ "no-lex-order": {
+ "description": "Drops lexical ordering for custom sections.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "ginkgolinterSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "suppress-len-assertion": {
+ "description": "Suppress the wrong length assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-nil-assertion": {
+ "description": "Suppress the wrong nil assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-err-assertion": {
+ "description": "Suppress the wrong error assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-compare-assertion": {
+ "description": "Suppress the wrong comparison assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-async-assertion": {
+ "description": "Suppress the function all in async assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-type-compare-assertion": {
+ "description": "Suppress warning for comparing values from different types, like int32 and uint32.",
+ "type": "boolean",
+ "default": false
+ },
+ "forbid-focus-container": {
+ "description": "Trigger warning for ginkgo focus containers like FDescribe, FContext, FWhen or FIt.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-havelen-zero": {
+ "description": "Don't trigger warnings for HaveLen(0).",
+ "type": "boolean",
+ "default": false
+ },
+ "force-expect-to": {
+ "description": "Force using `Expect` with `To`, `ToNot` or `NotTo`",
+ "type": "boolean",
+ "default": false
+ },
+ "validate-async-intervals": {
+ "description": "Best effort validation of async intervals (timeout and polling).",
+ "type": "boolean",
+ "default": false
+ },
+ "forbid-spec-pollution": {
+ "description": "Trigger a warning for variable assignments in ginkgo containers like `Describe`, `Context` and `When`, instead of in `BeforeEach()`.",
+ "type": "boolean",
+ "default": false
+ },
+ "force-succeed": {
+ "description": "Force using the Succeed matcher for error functions, and the HaveOccurred matcher for non-function error values.",
+ "type": "boolean",
+ "default": false
+ },
+ "force-assertion-description": {
+ "description": "Force adding assertion descriptions to gomega matchers.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "gochecksumtypeSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "default-signifies-exhaustive": {
+ "description": "Presence of `default` case in switch statements satisfies exhaustiveness, if all members are not listed.",
+ "type": "boolean",
+ "default": true
+ },
+ "include-shared-interfaces": {
+ "description": "Include shared interfaces in the exhaustiviness check.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "gocognitSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "min-complexity": {
+ "description": "Minimal code complexity to report (we recommend 10-20).",
+ "type": "integer",
+ "default": 30
+ }
+ }
+ },
+ "goconstSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "match-constant": {
+ "description": "Look for existing constants matching the values",
+ "type": "boolean",
+ "default": true
+ },
+ "min-len": {
+ "description": "Minimum length of string constant.",
+ "type": "integer",
+ "default": 3
+ },
+ "min-occurrences": {
+ "description": "Minimum occurrences count to trigger.",
+ "type": "integer",
+ "default": 3
+ },
+ "ignore-calls": {
+ "description": "Ignore when constant is not used as function argument",
+ "type": "boolean",
+ "default": true
+ },
+ "ignore-string-values": {
+ "description": "Exclude strings matching the given regular expression",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "numbers": {
+ "description": "Search also for duplicated numbers.",
+ "type": "boolean",
+ "default": false
+ },
+ "min": {
+ "description": "Minimum value, only works with `numbers`",
+ "type": "integer",
+ "default": 3
+ },
+ "max": {
+ "description": "Maximum value, only works with `numbers`",
+ "type": "integer",
+ "default": 3
+ },
+ "find-duplicates": {
+ "description": "Detects constants with identical values",
+ "type": "boolean",
+ "default": false
+ },
+ "eval-const-expressions": {
+ "description": "Evaluates of constant expressions like Prefix + \"suffix\"",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "gocriticSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "enabled-checks": {
+ "description": "Which checks should be enabled. By default, a list of stable checks is used. To see it, run `GL_DEBUG=gocritic golangci-lint run`.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/gocritic-checks"
+ }
+ },
+ "disabled-checks": {
+ "description": "Which checks should be disabled.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/gocritic-checks"
+ },
+ "default": []
+ },
+ "enabled-tags": {
+ "description": "Enable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/gocritic-tags"
+ }
+ },
+ "disabled-tags": {
+ "description": "Disable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/gocritic-tags"
+ }
+ },
+ "settings": {
+ "description": "Settings passed to gocritic. Properties must be valid and enabled check names.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "captLocal": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "paramsOnly" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "commentedOutCode": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "minLength" : {
+ "type": "number",
+ "default": 15
+ }
+ }
+ },
+ "elseif": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skipBalanced" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "hugeParam": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "sizeThreshold" : {
+ "type": "number",
+ "default": 80
+ }
+ }
+ },
+ "ifElseChain": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "minThreshold" : {
+ "type": "number",
+ "default": 2
+ }
+ }
+ },
+ "nestingReduce": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "bodyWidth" : {
+ "type": "number",
+ "default": 5
+ }
+ }
+ },
+ "rangeExprCopy": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "sizeThreshold" : {
+ "type": "number",
+ "default": 512
+ },
+ "skipTestFuncs" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "rangeValCopy": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "sizeThreshold" : {
+ "type": "number",
+ "default": 128
+ },
+ "skipTestFuncs" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "ruleguard": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "debug" : {
+ "type": "string"
+ },
+ "enable" : {
+ "type": "string"
+ },
+ "disable" : {
+ "type": "string"
+ },
+ "failOn" : {
+ "type": "string"
+ },
+ "rules" : {
+ "type": "string"
+ }
+ }
+ },
+ "tooManyResultsChecker": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "maxResults" : {
+ "type": "number",
+ "default": 5
+ }
+ }
+ },
+ "truncateCmp": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skipArchDependent" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "underef": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skipRecvDeref" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "unnamedResult": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "checkExported" : {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ }
+ }
+ },
+ "disable-all": {
+ "type": "boolean",
+ "default": false
+ },
+ "enable-all": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "gocycloSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "min-complexity": {
+ "description": "Minimum code complexity to report (we recommend 10-20).",
+ "type": "integer",
+ "default": 30
+ }
+ }
+ },
+ "godotSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "scope": {
+ "description": "Comments to be checked.",
+ "enum": ["declarations", "toplevel", "all", "noinline"],
+ "default": "declarations"
+ },
+ "exclude": {
+ "description": "List of regexps for excluding particular comment lines from check.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "period": {
+ "description": "Check that each sentence ends with a period.",
+ "type": "boolean",
+ "default": true
+ },
+ "capital": {
+ "description": "Check that each sentence starts with a capital letter.",
+ "type": "boolean",
+ "default": false
+ },
+ "check-all": {
+ "description": "DEPRECATED: Check all top-level comments, not only declarations.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "godoxSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "keywords": {
+ "description": "Report any comments starting with one of these keywords. This is useful for TODO or FIXME comments that might be left in the code accidentally and should be resolved before merging.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "default": ["TODO", "BUG", "FIXME"]
+ }
+ }
+ },
+ "gofmtSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "simplify": {
+ "description": "Simplify code.",
+ "type": "boolean",
+ "default": true
+ },
+ "rewrite-rules": {
+ "description": "Apply the rewrite rules to the source before reformatting.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "pattern": {
+ "type": "string"
+ },
+ "replacement": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "golinesSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-len": {
+ "type": "integer",
+ "default": 100
+ },
+ "tab-len": {
+ "type": "integer",
+ "default": 4
+ },
+ "shorten-comments": {
+ "type": "boolean",
+ "default": false
+ },
+ "reformat-tags": {
+ "type": "boolean",
+ "default": true
+ },
+ "chain-split-dots": {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "interfacebloatSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max": {
+ "description": "The maximum number of methods allowed for an interface.",
+ "type": "integer"
+ }
+ }
+ },
+ "gofumptSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "extra-rules": {
+ "description": "Choose whether or not to use the extra rules that are disabled by default.",
+ "type": "boolean",
+ "default": false
+ },
+ "module-path": {
+ "description": " Module path which contains the source code being formatted.",
+ "type": "string"
+ }
+ }
+ },
+ "goheaderSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "values": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "const": {
+ "description": "Constants to use in the template.",
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "description": "Value for the constant.",
+ "type": "string"
+ }
+ },
+ "additionalProperties": false,
+ "examples": [
+ {
+ "YEAR": "2030",
+ "COMPANY": "MY FUTURISTIC COMPANY"
+ }
+ ]
+ },
+ "regexp": {
+ "description": "Regular expressions to use in your template.",
+ "type": "object",
+ "additionalProperties": false,
+ "patternProperties": {
+ "^.+$": {
+ "type": "string"
+ }
+ },
+ "examples": [
+ {
+ "AUTHOR": ".*@mycompany\\.com"
+ }
+ ]
+ }
+ }
+ },
+ "template": {
+ "description": "Template to put on top of every file.",
+ "type": "string",
+ "examples": [
+ "{{ MY COMPANY }}\nSPDX-License-Identifier: Apache-2.0\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at:\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License."
+ ]
+ },
+ "template-path": {
+ "description": "Path to the file containing the template source.",
+ "type": "string",
+ "examples": ["my_header_template.txt"]
+ }
+ },
+ "oneOf": [
+ { "required": ["template"] },
+ { "required": ["template-path"] }
+ ]
+ },
+ "goimportsSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "local-prefixes": {
+ "description": "Put imports beginning with prefix after 3rd-party packages. It is a list of prefixes.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "gomoddirectivesSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "replace-local": {
+ "description": "Allow local `replace` directives.",
+ "type": "boolean",
+ "default": true
+ },
+ "replace-allow-list": {
+ "description": "List of allowed `replace` directives.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "retract-allow-no-explanation": {
+ "description": "Allow to not explain why the version has been retracted in the `retract` directives.",
+ "type": "boolean",
+ "default": false
+ },
+ "exclude-forbidden": {
+ "description": "Forbid the use of the `exclude` directives.",
+ "type": "boolean",
+ "default": false
+ },
+ "ignore-forbidden": {
+ "description": "Forbid the use of the `ignore` directives. (>= go1.25)",
+ "type": "boolean",
+ "default": false
+ },
+ "toolchain-forbidden": {
+ "description": "Forbid the use of the `toolchain` directive.",
+ "type": "boolean",
+ "default": false
+ },
+ "toolchain-pattern": {
+ "description": "Defines a pattern to validate `toolchain` directive.",
+ "type": "string"
+ },
+ "tool-forbidden": {
+ "description": "Forbid the use of the `tool` directives.",
+ "type": "boolean",
+ "default": false
+ },
+ "go-debug-forbidden": {
+ "description": "Forbid the use of the `godebug` directive.",
+ "type": "boolean",
+ "default": false
+ },
+ "go-version-pattern": {
+ "description": "Defines a pattern to validate `go` minimum version directive.",
+ "type": "string",
+ "default": ""
+ }
+ }
+ },
+ "gomodguardSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "allowed": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "modules": {
+ "description": "List of allowed modules.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["gopkg.in/yaml.v2"]
+ }
+ },
+ "domains": {
+ "description": "List of allowed module domains.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["golang.org"]
+ }
+ }
+ }
+ },
+ "blocked": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "modules": {
+ "description": "List of blocked modules.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "recommendations": {
+ "description": "Recommended modules that should be used instead.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "reason": {
+ "description": "Reason why the recommended module should be used.",
+ "type": "string"
+ }
+ }
+ }
+ },
+ "additionalProperties": false
+ }
+ },
+ "versions": {
+ "description": "List of blocked module version constraints.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "patternProperties": {
+ "^.*$": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "version": {
+ "description": "Version constraint.",
+ "type": "string"
+ },
+ "reason": {
+ "description": "Reason why the version constraint exists.",
+ "type": "string"
+ }
+ },
+ "required": ["reason"]
+ }
+ }
+ }
+ },
+ "local-replace-directives": {
+ "description": "Raise lint issues if loading local path with replace directive",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ }
+ }
+ },
+ "gosecSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "includes": {
+ "type": "array",
+ "description": "To select a subset of rules to run",
+ "examples": [["G401"]],
+ "items": {
+ "$ref": "#/definitions/gosec-rules"
+ }
+ },
+ "excludes": {
+ "type": "array",
+ "description": "To specify a set of rules to explicitly exclude",
+ "examples": [["G401"]],
+ "items": {
+ "$ref": "#/definitions/gosec-rules"
+ }
+ },
+ "severity": {
+ "description": "Filter out the issues with a lower severity than the given value",
+ "type": "string",
+ "enum": ["low", "medium", "high"],
+ "default": "low"
+ },
+ "confidence": {
+ "description": "Filter out the issues with a lower confidence than the given value",
+ "type": "string",
+ "enum": ["low", "medium", "high"],
+ "default": "low"
+ },
+ "config": {
+ "description": "To specify the configuration of rules",
+ "type": "object"
+ },
+ "concurrency": {
+ "description": "Concurrency value",
+ "type": "integer"
+ }
+ }
+ },
+ "gosmopolitanSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "allow-time-local": {
+ "description": "Allow and ignore `time.Local` usages.",
+ "type": "boolean",
+ "default": false
+ },
+ "escape-hatches": {
+ "description": "List of fully qualified names in the `full/pkg/path.name` form, to act as \"i18n escape hatches\".",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "watch-for-scripts": {
+ "description": "List of Unicode scripts to watch for any usage in string literals.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "govetSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "settings": {
+ "description": "Settings per analyzer. Map of analyzer name to specific settings.\nRun `go tool vet help` to find out more.",
+ "type": "object",
+ "propertyNames": {
+ "$ref": "#/definitions/govet-analyzers"
+ },
+ "patternProperties": {
+ "^.*$": {
+ "description": "Run `go tool vet help ` to see all settings.",
+ "type": "object"
+ }
+ }
+ },
+ "enable": {
+ "description": "Enable analyzers by name.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/govet-analyzers"
+ }
+ },
+ "disable": {
+ "description": "Disable analyzers by name.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/govet-analyzers"
+ }
+ },
+ "enable-all": {
+ "description": "Enable all analyzers.",
+ "type": "boolean",
+ "default": false
+ },
+ "disable-all": {
+ "description": "Disable all analyzers.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "grouperSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "const-require-single-const": {
+ "type": "boolean",
+ "default": false
+ },
+ "const-require-grouping": {
+ "type": "boolean",
+ "default": false
+ },
+ "import-require-single-import": {
+ "type": "boolean",
+ "default": false
+ },
+ "import-require-grouping": {
+ "type": "boolean",
+ "default": false
+ },
+ "type-require-single-type": {
+ "type": "boolean",
+ "default": false
+ },
+ "type-require-grouping": {
+ "type": "boolean",
+ "default": false
+ },
+ "var-require-single-var": {
+ "type": "boolean",
+ "default": false
+ },
+ "var-require-grouping": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "ifaceSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "enable": {
+ "description": "Enable analyzers by name.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/iface-analyzers"
+ }
+ },
+ "settings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "unused": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "exclude": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "importasSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "no-unaliased": {
+ "description": "Do not allow unaliased imports of aliased packages.",
+ "type": "boolean",
+ "default": false
+ },
+ "no-extra-aliases": {
+ "description": "Do not allow non-required aliases.",
+ "type": "boolean",
+ "default": false
+ },
+ "alias": {
+ "description": "List of aliases",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "pkg": {
+ "description": "Package path e.g. knative.dev/serving/pkg/apis/autoscaling/v1alpha1",
+ "type": "string"
+ },
+ "alias": {
+ "description": "Package alias e.g. autoscalingv1alpha1",
+ "type": "string"
+ }
+ },
+ "required": ["pkg", "alias"]
+ }
+ }
+ }
+ },
+ "inamedparamSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skip-single-param": {
+ "description": "Skips check for interface methods with only a single parameter.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "ireturnSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "description": "Use either `reject` or `allow` properties for interfaces matching.",
+ "properties": {
+ "allow": {
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "enum": ["anon", "error", "empty", "stdlib"]
+ }
+ ]
+ }
+ },
+ "reject": {
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "enum": ["anon", "error", "empty", "stdlib"]
+ }
+ ]
+ }
+ }
+ },
+ "anyOf": [
+ {
+ "not": {
+ "properties": {
+ "allow": {
+ "const": "reject"
+ }
+ }
+ },
+ "required": ["allow"]
+ },
+ {
+ "required": ["reject"]
+ }
+ ]
+ },
+ "lllSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "tab-width": {
+ "description": "Width of \"\\t\" in spaces.",
+ "type": "integer",
+ "minimum": 0,
+ "default": 1
+ },
+ "line-length": {
+ "description": "Maximum allowed line length, lines longer will be reported.",
+ "type": "integer",
+ "minimum": 1,
+ "default": 120
+ }
+ }
+ },
+ "maintidxSettings": {
+ "description": "Maintainability index https://docs.microsoft.com/en-us/visualstudio/code-quality/code-metrics-maintainability-index-range-and-meaning?view=vs-2022",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "under": {
+ "description": "Minimum accatpable maintainability index level (see https://docs.microsoft.com/en-us/visualstudio/code-quality/code-metrics-maintainability-index-range-and-meaning?view=vs-2022)",
+ "type": "number",
+ "default": 20
+ }
+ }
+ },
+ "makezeroSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "always": {
+ "description": "Allow only slices initialized with a length of zero.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "loggercheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "kitlog": {
+ "description": "Allow check for the github.com/go-kit/log library.",
+ "type": "boolean",
+ "default": true
+ },
+ "klog": {
+ "description": "Allow check for the k8s.io/klog/v2 library.",
+ "type": "boolean",
+ "default": true
+ },
+ "logr": {
+ "description": "Allow check for the github.com/go-logr/logr library.",
+ "type": "boolean",
+ "default": true
+ },
+ "slog": {
+ "description": "Allow check for the log/slog library.",
+ "type": "boolean",
+ "default": true
+ },
+ "zap": {
+ "description": "Allow check for the \"sugar logger\" from go.uber.org/zap library.",
+ "type": "boolean",
+ "default": true
+ },
+ "require-string-key": {
+ "description": "Require all logging keys to be inlined constant strings.",
+ "type": "boolean",
+ "default": false
+ },
+ "no-printf-like": {
+ "description": "Require printf-like format specifier (%s, %d for example) not present.",
+ "type": "boolean",
+ "default": false
+ },
+ "rules": {
+ "description": "List of custom rules to check against, where each rule is a single logger pattern, useful for wrapped loggers.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "misspellSettings": {
+ "description": "Correct spellings using locale preferences for US or UK. Default is to use a neutral variety of English.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "locale": {
+ "enum": ["US", "UK"]
+ },
+ "ignore-rules": {
+ "description": "List of rules to ignore.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "mode": {
+ "description": "Mode of the analysis.",
+ "enum": ["restricted", "", "default"],
+ "default": ""
+ },
+ "extra-words": {
+ "description": "Extra word corrections.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "correction": {
+ "type": "string"
+ },
+ "typo": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "musttagSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "functions": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "tag": {
+ "type": "string"
+ },
+ "arg-pos": {
+ "type": "integer"
+ }
+ }
+ }
+ }
+ }
+ },
+ "nakedretSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-func-lines": {
+ "description": "Report if a function has more lines of code than this value and it has naked returns.",
+ "type": "integer",
+ "minimum": 0,
+ "default": 30
+ }
+ }
+ },
+ "nestifSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "min-complexity": {
+ "description": "Minimum complexity of \"if\" statements to report.",
+ "type": "integer",
+ "default": 5
+ }
+ }
+ },
+ "nilnilSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "only-two": {
+ "type": "boolean",
+ "description": "To check functions with only two return values.",
+ "default": true
+ },
+ "detect-opposite": {
+ "type": "boolean",
+ "description": "In addition, detect opposite situation (simultaneous return of non-nil error and valid value).",
+ "default": false
+ },
+ "checked-types": {
+ "type": "array",
+ "description": "List of return types to check.",
+ "items": {
+ "enum": ["chan", "func", "iface", "map", "ptr", "uintptr", "unsafeptr"]
+ },
+ "default": ["chan", "func", "iface", "map", "ptr", "uintptr", "unsafeptr"]
+ }
+ }
+ },
+ "nlreturnSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "block-size": {
+ "description": "set block size that is still ok",
+ "type": "number",
+ "default": 0,
+ "minimum": 0
+ }
+ }
+ },
+ "mndSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignored-files": {
+ "description": "List of file patterns to exclude from analysis.",
+ "examples": [["magic1_.*.go"]],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignored-functions": {
+ "description": "Comma-separated list of function patterns to exclude from the analysis.",
+ "examples": [["math.*", "http.StatusText", "make"]],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignored-numbers": {
+ "description": "List of numbers to exclude from analysis.",
+ "examples": [["1000", "1234_567_890", "3.14159264"]],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "checks": {
+ "description": "The list of enabled checks, see https://github.com/tommy-muehle/go-mnd/#checks for description.",
+ "type": "array",
+ "items": {
+ "enum": [
+ "argument",
+ "case",
+ "condition",
+ "operation",
+ "return",
+ "assign"
+ ]
+ }
+ }
+ }
+ },
+ "nolintlintSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "allow-unused": {
+ "description": "Enable to ensure that nolint directives are all used.",
+ "type": "boolean",
+ "default": true
+ },
+ "allow-no-explanation": {
+ "description": "Exclude these linters from requiring an explanation.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linter-names"
+ },
+ "default": []
+ },
+ "require-explanation": {
+ "description": "Enable to require an explanation of nonzero length after each nolint directive.",
+ "type": "boolean",
+ "default": false
+ },
+ "require-specific": {
+ "description": "Enable to require nolint directives to mention the specific linter being suppressed.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "reassignSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "patterns": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "recvcheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "disable-builtin": {
+ "description": "Disables the built-in method exclusions.",
+ "type": "boolean",
+ "default": true
+ },
+ "exclusions": {
+ "description": "User-defined method exclusions.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "nonamedreturnsSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "report-error-in-defer": {
+ "description": "Report named error if it is assigned inside defer.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "paralleltestSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignore-missing": {
+ "description": "Ignore missing calls to `t.Parallel()` and only report incorrect uses of it.",
+ "type": "boolean",
+ "default": false
+ },
+ "ignore-missing-subtests": {
+ "description": "Ignore missing calls to `t.Parallel()` in subtests. Top-level tests are still required to have `t.Parallel`, but subtests are allowed to skip it.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "perfsprintSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "integer-format": {
+ "description": "Enable/disable optimization of integer formatting.",
+ "type": "boolean",
+ "default": true
+ },
+ "int-conversion": {
+ "description": "Optimizes even if it requires an int or uint type cast.",
+ "type": "boolean",
+ "default": true
+ },
+ "error-format": {
+ "description": "Enable/disable optimization of error formatting.",
+ "type": "boolean",
+ "default": true
+ },
+ "err-error": {
+ "description": "Optimizes into `err.Error()` even if it is only equivalent for non-nil errors.",
+ "type": "boolean",
+ "default": false
+ },
+ "errorf": {
+ "description": "Optimizes `fmt.Errorf`.",
+ "type": "boolean",
+ "default": true
+ },
+ "string-format": {
+ "description": "Enable/disable optimization of string formatting.",
+ "type": "boolean",
+ "default": true
+ },
+ "sprintf1": {
+ "description": "Optimizes `fmt.Sprintf` with only one argument.",
+ "type": "boolean",
+ "default": true
+ },
+ "strconcat": {
+ "description": "Optimizes into strings concatenation.",
+ "type": "boolean",
+ "default": true
+ },
+ "bool-format": {
+ "description": "Enable/disable optimization of bool formatting.",
+ "type": "boolean",
+ "default": true
+ },
+ "hex-format": {
+ "description": "Enable/disable optimization of hex formatting.",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "preallocSettings": {
+ "description": "We do not recommend using this linter before doing performance profiling.\nFor most programs usage of `prealloc` will be premature optimization.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "simple": {
+ "description": "Report preallocation suggestions only on simple loops that have no returns/breaks/continues/gotos in them.",
+ "type": "boolean",
+ "default": true
+ },
+ "range-loops": {
+ "description": "Report preallocation suggestions on range loops.",
+ "type": "boolean",
+ "default": true
+ },
+ "for-loops": {
+ "description": "Report preallocation suggestions on for loops.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "predeclaredSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignore": {
+ "description": "List of predeclared identifiers to not report on.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "qualified-name": {
+ "description": "Include method names and field names in checks.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "promlinterSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "strict": {},
+ "disabled-linters": {
+ "type": "array",
+ "items": {
+ "enum": [
+ "Help",
+ "MetricUnits",
+ "Counter",
+ "HistogramSummaryReserved",
+ "MetricTypeInName",
+ "ReservedChars",
+ "CamelCase",
+ "UnitAbbreviations"
+ ]
+ }
+ }
+ }
+ },
+ "protogetterSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skip-generated-by": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["protoc-gen-go-my-own-generator"]
+ }
+ },
+ "skip-files": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["*.pb.go"]
+ }
+ },
+ "skip-any-generated": {
+ "description": "Skip any generated files from the checking.",
+ "type": "boolean",
+ "default": false
+ },
+ "replace-first-arg-in-append": {
+ "description": "Skip first argument of append function.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "reviveSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "examples": [
+ {
+ "ignore-generated-header": true,
+ "severity": "warning",
+ "rules": [
+ {
+ "name": "indent-error-flow",
+ "severity": "warning"
+ },
+ {
+ "name": "add-constant",
+ "severity": "warning",
+ "arguments": [
+ {
+ "maxLitCount": "3",
+ "allowStrs": "\"\"",
+ "allowInts": "0,1,2",
+ "allowFloats": "0.0,0.,1.0,1.,2.0,2."
+ }
+ ]
+ }
+ ]
+ }
+ ],
+ "properties": {
+ "max-open-files": {
+ "type": "integer"
+ },
+ "confidence": {
+ "type": "number"
+ },
+ "severity": {
+ "type": "string",
+ "enum": ["warning", "error"]
+ },
+ "enable-all-rules": {
+ "type": "boolean",
+ "default": false
+ },
+ "directives": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "name": {
+ "type": "string",
+ "enum": ["specify-disable-reason"]
+ },
+ "severity": {
+ "type": "string",
+ "enum": ["warning", "error"]
+ },
+ "exclude": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "arguments": {
+ "type": "array"
+ }
+ }
+ }
+ },
+ "rules": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["name"],
+ "properties": {
+ "name": {
+ "$ref": "#/definitions/revive-rules",
+ "title": "The rule name"
+ },
+ "disabled": {
+ "type": "boolean"
+ },
+ "severity": {
+ "type": "string",
+ "enum": ["warning", "error"]
+ },
+ "exclude": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "arguments": {
+ "type": "array"
+ }
+ }
+ }
+ }
+ }
+ },
+ "rowserrcheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "packages": {
+ "type": "array",
+ "items": {
+ "description": "",
+ "type": "string",
+ "examples": ["github.com/jmoiron/sqlx"]
+ }
+ }
+ }
+ },
+ "sloglintSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "kv-only": {
+ "description": "Enforce using key-value pairs only (incompatible with attr-only).",
+ "type": "boolean",
+ "default": false
+ },
+ "no-global": {
+ "description": "Enforce not using global loggers.",
+ "enum": ["", "all", "default"],
+ "default": ""
+ },
+ "no-mixed-args": {
+ "description": "Enforce not mixing key-value pairs and attributes.",
+ "type": "boolean",
+ "default": true
+ },
+ "context": {
+ "description": "Enforce using methods that accept a context.",
+ "enum": ["", "all", "scope"],
+ "default": ""
+ },
+ "static-msg": {
+ "description": "Enforce using static values for log messages.",
+ "type": "boolean",
+ "default": false
+ },
+ "msg-style": {
+ "description": "Enforce message style.",
+ "enum": ["", "lowercased", "capitalized"],
+ "default": ""
+ },
+ "key-naming-case": {
+ "description": "Enforce a single key naming convention.",
+ "enum": ["snake", "kebab", "camel", "pascal"]
+ },
+ "attr-only": {
+ "description": "Enforce using attributes only (incompatible with kv-only).",
+ "type": "boolean",
+ "default": false
+ },
+ "no-raw-keys": {
+ "description": "Enforce using constants instead of raw keys.",
+ "type": "boolean",
+ "default": false
+ },
+ "forbidden-keys": {
+ "description": "Enforce not using specific keys.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "args-on-sep-lines": {
+ "description": "Enforce putting arguments on separate lines.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "spancheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "checks": {
+ "description": "Checks to enable.",
+ "type": "array",
+ "items": {
+ "enum": ["end", "record-error", "set-status"]
+ }
+ },
+ "ignore-check-signatures": {
+ "description": "A list of regexes for function signatures that silence `record-error` and `set-status` reports if found in the call path to a returned error.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "extra-start-span-signatures": {
+ "description": "A list of regexes for additional function signatures that create spans.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "staticcheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "checks": {
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "$ref": "#/definitions/staticcheck-checks"
+ },
+ {
+ "type": "string"
+ }
+ ]
+ }
+ },
+ "dot-import-whitelist": {
+ "description": "By default, ST1001 forbids all uses of dot imports in non-test packages. This setting allows setting a whitelist of import paths that can be dot-imported anywhere.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "http-status-code-whitelist": {
+ "description": "ST1013 recommends using constants from the net/http package instead of hard-coding numeric HTTP status codes. This setting specifies a list of numeric status codes that this check does not complain about.",
+ "default": ["200", "400", "404", "500"],
+ "type": "array",
+ "items": {
+ "enum": [
+ "100",
+ "101",
+ "102",
+ "103",
+ "200",
+ "201",
+ "202",
+ "203",
+ "204",
+ "205",
+ "206",
+ "207",
+ "208",
+ "226",
+ "300",
+ "301",
+ "302",
+ "303",
+ "304",
+ "305",
+ "306",
+ "307",
+ "308",
+ "400",
+ "401",
+ "402",
+ "403",
+ "404",
+ "405",
+ "406",
+ "407",
+ "408",
+ "409",
+ "410",
+ "411",
+ "412",
+ "413",
+ "414",
+ "415",
+ "416",
+ "417",
+ "418",
+ "421",
+ "422",
+ "423",
+ "424",
+ "425",
+ "426",
+ "428",
+ "429",
+ "431",
+ "451",
+ "500",
+ "501",
+ "502",
+ "503",
+ "504",
+ "505",
+ "506",
+ "507",
+ "508",
+ "510",
+ "511"
+ ]
+ }
+ },
+ "initialisms": {
+ "description": "ST1003 check, among other things, for the correct capitalization of initialisms. The set of known initialisms can be configured with this option.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "default": [
+ "ACL",
+ "API",
+ "ASCII",
+ "CPU",
+ "CSS",
+ "DNS",
+ "EOF",
+ "GUID",
+ "HTML",
+ "HTTP",
+ "HTTPS",
+ "ID",
+ "IP",
+ "JSON",
+ "QPS",
+ "RAM",
+ "RPC",
+ "SLA",
+ "SMTP",
+ "SQL",
+ "SSH",
+ "TCP",
+ "TLS",
+ "TTL",
+ "UDP",
+ "UI",
+ "GID",
+ "UID",
+ "UUID",
+ "URI",
+ "URL",
+ "UTF8",
+ "VM",
+ "XML",
+ "XMPP",
+ "XSRF",
+ "XSS",
+ "SIP",
+ "RTP",
+ "AMQP",
+ "DB",
+ "TS"
+ ]
+ }
+ }
+ }
+ },
+ "tagalignSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "align": {
+ "description": "Align and sort can be used together or separately.",
+ "type": "boolean",
+ "default": true
+ },
+ "sort": {
+ "description": "Whether enable tags sort.",
+ "type": "boolean",
+ "default": true
+ },
+ "order": {
+ "description": "Specify the order of tags, the other tags will be sorted by name.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "default": [],
+ "examples": [
+ [
+ "json",
+ "yaml",
+ "yml",
+ "toml",
+ "mapstructure",
+ "binding",
+ "validate"
+ ]
+ ]
+ },
+ "strict": {
+ "description": "Whether enable strict style.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "tagliatelleSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "case": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "use-field-name": {
+ "description": "Use the struct field name to check the name of the struct tag.",
+ "type": "boolean",
+ "default": false
+ },
+ "ignored-fields": {
+ "description": "The field names to ignore.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["example"]
+ }
+ },
+ "rules": {
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "$ref": "#/definitions/tagliatelle-cases"
+ }
+ }
+ },
+ "extended-rules": {
+ "description": "Defines the association between tag name and case.",
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["case"],
+ "properties": {
+ "case": {
+ "$ref": "#/definitions/tagliatelle-cases"
+ },
+ "extra-initialisms": {
+ "type": "boolean",
+ "default": false
+ },
+ "initialism-overrides": {
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "overrides": {
+ "description": "Overrides the default/root configuration.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["pkg"],
+ "properties": {
+ "pkg": {
+ "description": "A package path.",
+ "type": "string"
+ },
+ "use-field-name": {
+ "description": "Use the struct field name to check the name of the struct tag.",
+ "type": "boolean",
+ "default": false
+ },
+ "ignored-fields": {
+ "description": "The field names to ignore.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["example"]
+ }
+ },
+ "ignore": {
+ "description": "Ignore the package (takes precedence over all other configurations).",
+ "type": "boolean",
+ "default": false
+ },
+ "rules": {
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "$ref": "#/definitions/tagliatelle-cases"
+ }
+ }
+ },
+ "extended-rules": {
+ "description": "Defines the association between tag name and case.",
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["case"],
+ "properties": {
+ "case": {
+ "$ref": "#/definitions/tagliatelle-cases"
+ },
+ "extra-initialisms": {
+ "type": "boolean",
+ "default": false
+ },
+ "initialism-overrides": {
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "testifylintSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "enable-all": {
+ "description": "Enable all checkers.",
+ "type": "boolean",
+ "default": false
+ },
+ "disable-all": {
+ "description": "Disable all checkers.",
+ "type": "boolean",
+ "default": false
+ },
+ "enable": {
+ "description": "Enable specific checkers.",
+ "type": "array",
+ "items": {
+ "enum": [
+ "blank-import",
+ "bool-compare",
+ "compares",
+ "contains",
+ "empty",
+ "encoded-compare",
+ "equal-values",
+ "error-is-as",
+ "error-nil",
+ "expected-actual",
+ "float-compare",
+ "formatter",
+ "go-require",
+ "len",
+ "negative-positive",
+ "nil-compare",
+ "regexp",
+ "require-error",
+ "suite-broken-parallel",
+ "suite-dont-use-pkg",
+ "suite-extra-assert-call",
+ "suite-method-signature",
+ "suite-subtest-run",
+ "suite-thelper",
+ "useless-assert"
+ ]
+ },
+ "default": [
+ "blank-import",
+ "bool-compare",
+ "compares",
+ "contains",
+ "empty",
+ "encoded-compare",
+ "equal-values",
+ "error-is-as",
+ "error-nil",
+ "expected-actual",
+ "float-compare",
+ "formatter",
+ "go-require",
+ "len",
+ "negative-positive",
+ "nil-compare",
+ "regexp",
+ "require-error",
+ "suite-broken-parallel",
+ "suite-dont-use-pkg",
+ "suite-extra-assert-call",
+ "suite-method-signature",
+ "suite-subtest-run",
+ "useless-assert"
+ ]
+ },
+ "disable": {
+ "description": "Disable specific checkers.",
+ "type": "array",
+ "items": {
+ "enum": [
+ "blank-import",
+ "bool-compare",
+ "compares",
+ "contains",
+ "empty",
+ "encoded-compare",
+ "equal-values",
+ "error-is-as",
+ "error-nil",
+ "expected-actual",
+ "float-compare",
+ "formatter",
+ "go-require",
+ "len",
+ "negative-positive",
+ "nil-compare",
+ "regexp",
+ "require-error",
+ "suite-broken-parallel",
+ "suite-dont-use-pkg",
+ "suite-extra-assert-call",
+ "suite-method-signature",
+ "suite-subtest-run",
+ "suite-thelper",
+ "useless-assert"
+ ],
+ "default": [
+ "suite-thelper"
+ ]
+ }
+ },
+ "bool-compare": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignore-custom-types": {
+ "description": "To ignore user defined types (over builtin bool).",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "expected-actual": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "pattern": {
+ "description": "Regexp for expected variable name.",
+ "type": "string",
+ "default": "(^(exp(ected)?|want(ed)?)([A-Z]\\w*)?$)|(^(\\w*[a-z])?(Exp(ected)?|Want(ed)?)$)"
+ }
+ }
+ },
+ "formatter": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-format-string": {
+ "description": "To enable go vet's printf checks.",
+ "type": "boolean",
+ "default": true
+ },
+ "require-f-funcs": {
+ "description": "To require f-assertions (e.g. assert.Equalf) if format string is used, even if there are no variable-length variables.",
+ "type": "boolean",
+ "default": false
+ },
+ "require-string-msg": {
+ "description": "To require that the first element of msgAndArgs (msg) has a string type.",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "go-require": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignore-http-handlers": {
+ "description": "To ignore HTTP handlers (like http.HandlerFunc).",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "require-error": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "fn-pattern": {
+ "description": "Regexp for assertions to analyze. If defined, then only matched error assertions will be reported.",
+ "type": "string",
+ "default": ""
+ }
+ }
+ },
+ "suite-extra-assert-call": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "mode": {
+ "description": "To require or remove extra Assert() call?",
+ "type": "string",
+ "enum": ["remove", "require"],
+ "default": "remove"
+ }
+ }
+ }
+ }
+ },
+ "testpackageSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skip-regexp": {
+ "description": "Files with names matching this regular expression are skipped.",
+ "type": "string",
+ "examples": ["(export|internal)_test\\.go"]
+ },
+ "allow-packages": {
+ "description": "List of packages that don't end with _test that tests are allowed to be in.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["example"]
+ }
+ }
+ }
+ },
+ "thelperSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "test": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "begin": {
+ "description": "Check if `t.Helper()` begins helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "first": {
+ "description": "Check if *testing.T is first param of helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "name": {
+ "description": "Check if *testing.T param has t name.",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ },
+ "benchmark": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "begin": {
+ "description": "Check if `b.Helper()` begins helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "first": {
+ "description": "Check if *testing.B is first param of helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "name": {
+ "description": "Check if *testing.B param has b name.",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ },
+ "tb": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "begin": {
+ "description": "Check if `tb.Helper()` begins helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "first": {
+ "description": "Check if *testing.TB is first param of helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "name": {
+ "description": "Check if *testing.TB param has tb name.",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ },
+ "fuzz": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "begin": {
+ "description": "Check if `f.Helper()` begins helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "first": {
+ "description": "Check if *testing.F is first param of helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "name": {
+ "description": "Check if *testing.F param has f name.",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ }
+ }
+ },
+ "usestdlibvarsSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "http-method": {
+ "description": "Suggest the use of http.MethodXX.",
+ "type": "boolean",
+ "default": true
+ },
+ "http-status-code": {
+ "description": "Suggest the use of http.StatusXX.",
+ "type": "boolean",
+ "default": true
+ },
+ "time-weekday": {
+ "description": "Suggest the use of time.Weekday.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "time-month": {
+ "description": "Suggest the use of time.Month.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "time-layout": {
+ "description": "Suggest the use of time.Layout.",
+ "type": "boolean",
+ "default": false
+ },
+ "time-date-month": {
+ "description": "Suggest the use of time.Month in time.Date.",
+ "type": "boolean",
+ "default": false
+ },
+ "crypto-hash": {
+ "description": "Suggest the use of crypto.Hash.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "default-rpc-path": {
+ "description": "Suggest the use of rpc.DefaultXXPath.",
+ "type": "boolean",
+ "default": false
+ },
+ "sql-isolation-level": {
+ "description": "Suggest the use of sql.LevelXX.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "tls-signature-scheme": {
+ "description": "Suggest the use of tls.SignatureScheme.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "constant-kind": {
+ "description": "Suggest the use of constant.Kind.String().",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "usetestingSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "context-background": {
+ "type": "boolean",
+ "default": false
+ },
+ "context-todo": {
+ "type": "boolean",
+ "default": false
+ },
+ "os-chdir": {
+ "type": "boolean",
+ "default": true
+ },
+ "os-mkdir-temp": {
+ "type": "boolean",
+ "default": true
+ },
+ "os-setenv": {
+ "type": "boolean",
+ "default": true
+ },
+ "os-create-temp": {
+ "type": "boolean",
+ "default": true
+ },
+ "os-temp-dir": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "unconvertSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "fast-math": {
+ "type": "boolean",
+ "default": false
+ },
+ "safe": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "unparamSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-exported": {
+ "description": "Inspect exported functions. Set to true if no external program/library imports your code.\n\nWARNING: if you enable this setting, unparam will report a lot of false-positives in text editors:\nif it's called for subdir of a project it can't find external interfaces. All text editor integrations\nwith golangci-lint call it on a directory with the changed file.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "unusedSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "field-writes-are-uses": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ },
+ "post-statements-are-reads": {
+ "description": "",
+ "type": "boolean",
+ "default": false
+ },
+ "exported-fields-are-used": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ },
+ "parameters-are-used": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ },
+ "local-variables-are-used": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ },
+ "generated-is-used": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "varnamelenSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-distance": {
+ "description": "Variables used in at most this N-many lines will be ignored.",
+ "type": "integer",
+ "default": 5
+ },
+ "min-name-length": {
+ "description": "The minimum length of a variable's name that is considered `long`.",
+ "type": "integer",
+ "default": 3
+ },
+ "check-receiver": {
+ "description": "Check method receiver names.",
+ "default": false,
+ "type": "boolean"
+ },
+ "check-return": {
+ "description": "Check named return values.",
+ "default": false,
+ "type": "boolean"
+ },
+ "check-type-param": {
+ "description": "Check type parameters.",
+ "default": false,
+ "type": "boolean"
+ },
+ "ignore-type-assert-ok": {
+ "description": "Ignore `ok` variables that hold the bool return value of a type assertion",
+ "default": false,
+ "type": "boolean"
+ },
+ "ignore-map-index-ok": {
+ "description": "Ignore `ok` variables that hold the bool return value of a map index.",
+ "default": false,
+ "type": "boolean"
+ },
+ "ignore-chan-recv-ok": {
+ "description": "Ignore `ok` variables that hold the bool return value of a channel receive.",
+ "default": false,
+ "type": "boolean"
+ },
+ "ignore-names": {
+ "description": "Optional list of variable names that should be ignored completely.",
+ "default": [[]],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignore-decls": {
+ "description": "Optional list of variable declarations that should be ignored completely.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "examples": [
+ ["c echo.Context", "t testing.T", "f *foo.Bar", "const C"]
+ ]
+ }
+ }
+ },
+ "whitespaceSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "multi-if": {
+ "description": "Enforces newlines (or comments) after every multi-line if statement",
+ "type": "boolean",
+ "default": false
+ },
+ "multi-func": {
+ "description": "Enforces newlines (or comments) after every multi-line function signature",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "wrapcheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "extra-ignore-sigs": {
+ "description": "An array of strings specifying additional substrings of signatures to ignore.",
+ "default": [
+ ".CustomError(",
+ ".SpecificWrap("
+ ],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignore-sigs": {
+ "description": "An array of strings which specify substrings of signatures to ignore.",
+ "default": [
+ ".Errorf(",
+ "errors.New(",
+ "errors.Unwrap(",
+ ".Wrap(",
+ ".Wrapf(",
+ ".WithMessage(",
+ ".WithMessagef(",
+ ".WithStack("
+ ],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignore-sig-regexps": {
+ "description": "An array of strings which specify regular expressions of signatures to ignore.",
+ "default": [""],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignore-package-globs": {
+ "description": "An array of glob patterns which, if any match the package of the function returning the error, will skip wrapcheck analysis for this error.",
+ "default": [""],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignore-interface-regexps": {
+ "description": "An array of glob patterns which, if matched to an underlying interface name, will ignore unwrapped errors returned from a function whose call is defined on the given interface.",
+ "default": [""],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "report-internal-errors": {
+ "description": "Determines whether wrapcheck should report errors returned from inside the package.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "wslSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "allow-assign-and-anything": {
+ "description": "Controls if you may cuddle assignments and anything without needing an empty line between them.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-assign-and-call": {
+ "description": "Allow calls and assignments to be cuddled as long as the lines have any matching variables, fields or types.",
+ "type": "boolean",
+ "default": true
+ },
+ "allow-cuddle-declarations": {
+ "description": "Allow declarations (var) to be cuddled.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-cuddle-with-calls": {
+ "description": "A list of call idents that everything can be cuddled with.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "allow-cuddle-with-rhs": {
+ "description": "AllowCuddleWithRHS is a list of right hand side variables that is allowed to be cuddled with anything.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "allow-cuddle-used-in-block": {
+ "description": "Allow cuddling with any block as long as the variable is used somewhere in the block",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-multiline-assign": {
+ "description": "Allow multiline assignments to be cuddled.",
+ "type": "boolean",
+ "default": true
+ },
+ "allow-separated-leading-comment": {
+ "description": "Allow leading comments to be separated with empty lines.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-trailing-comment": {
+ "description": "Allow trailing comments in ending of blocks.",
+ "type": "boolean",
+ "default": false
+ },
+ "error-variable-names": {
+ "description": "When force-err-cuddling is enabled this is a list of names used for error variables to check for in the conditional.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "force-case-trailing-whitespace": {
+ "description": "Force newlines in end of case at this limit (0 = never).",
+ "type": "integer",
+ "minimum": 0,
+ "default": 0
+ },
+ "force-err-cuddling": {
+ "description": "Causes an error when an If statement that checks an error variable doesn't cuddle with the assignment of that variable.",
+ "type": "boolean",
+ "default": false
+ },
+ "force-short-decl-cuddling": {
+ "description": "Causes an error if a short declaration (:=) cuddles with anything other than another short declaration.",
+ "type": "boolean",
+ "default": false
+ },
+ "strict-append": {
+ "description": "If true, append is only allowed to be cuddled if appending value is matching variables, fields or types on line above.",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "wslSettingsV5": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "allow-first-in-block": {
+ "type": "boolean",
+ "default": true
+ },
+ "allow-whole-block": {
+ "type": "boolean",
+ "default": false
+ },
+ "branch-max-lines": {
+ "type": "integer",
+ "default": 2
+ },
+ "case-max-lines": {
+ "type": "integer",
+ "default": 0
+ },
+ "default": {
+ "enum": ["all", "none", "default", ""],
+ "default": "default"
+ },
+ "enable": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/wsl-checks"
+ }
+ },
+ "disable": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/wsl-checks"
+ }
+ }
+ }
+ },
+ "copyloopvarSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-alias": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "customSettings": {
+ "description": "The custom section can be used to define linter plugins to be loaded at runtime. See README of golangci-lint for more information.\nEach custom linter should have a unique name.",
+ "type": "object",
+ "patternProperties": {
+ "^.*$": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "type": {
+ "description": "The plugin type.",
+ "enum": ["module", "goplugin"],
+ "default": "goplugin"
+ },
+ "path": {
+ "description": "The path to the plugin *.so. Can be absolute or local.",
+ "type": "string",
+ "examples": ["/path/to/example.so"]
+ },
+ "description": {
+ "description": "The description of the linter, for documentation purposes only.",
+ "type": "string"
+ },
+ "original-url": {
+ "description": "Intended to point to the repo location of the linter, for documentation purposes only.",
+ "type": "string"
+ },
+ "settings": {
+ "description": "Plugins settings/configuration. Only work with plugin based on `linterdb.PluginConstructor`.",
+ "type": "object"
+ }
+ },
+ "oneOf": [
+ {
+ "properties": {
+ "type": {"enum": ["module"] }
+ },
+ "required": ["type"]
+ },
+ {
+ "required": ["path"]
+ }
+ ]
+ }
+ }
+ }
+ }
+ }
+ },
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["version"],
+ "properties": {
+ "version": {
+ "type": "string",
+ "default": "2"
+ },
+ "run": {
+ "description": "Options for analysis running,",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "concurrency": {
+ "description": "Number of concurrent runners. Defaults to the number of available CPU cores.",
+ "type": "integer",
+ "minimum": 0,
+ "examples": [4]
+ },
+ "timeout": {
+ "description": "Timeout for the analysis.",
+ "type": "string",
+ "pattern": "^((\\d+h)?(\\d+m)?(\\d+(?:\\.\\d)?s)?|0)$",
+ "default": "1m",
+ "examples": ["30s", "5m", "5m30s"]
+ },
+ "issues-exit-code": {
+ "description": "Exit code when at least one issue was found.",
+ "type": "integer",
+ "default": 1
+ },
+ "tests": {
+ "description": "Enable inclusion of test files.",
+ "type": "boolean",
+ "default": true
+ },
+ "build-tags": {
+ "description": "List of build tags to pass to all linters.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "default": [],
+ "examples": [["mytag"]]
+ },
+ "modules-download-mode": {
+ "description": "Option to pass to \"go list -mod={option}\".\nSee \"go help modules\" for more information.",
+ "enum": ["mod", "readonly", "vendor"]
+ },
+ "allow-parallel-runners": {
+ "description": "Allow multiple parallel golangci-lint instances running. If disabled, golangci-lint acquires file lock on start.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-serial-runners": {
+ "description": "Allow multiple golangci-lint instances running, but serialize them around a lock.",
+ "type": "boolean",
+ "default": false
+ },
+ "go": {
+ "description": "Targeted Go version.",
+ "type": "string",
+ "default": "1.17"
+ },
+ "relative-path-mode": {
+ "description": "The mode used to evaluate relative paths.",
+ "type": "string",
+ "$ref": "#/definitions/relative-path-modes",
+ "default": "wd"
+ }
+ }
+ },
+ "output": {
+ "description": "Output configuration options.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "formats": {
+ "description": "Output formats to use.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "text": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "path": {
+ "$ref": "#/definitions/formats-path",
+ "default": "stdout"
+ },
+ "print-linter-name": {
+ "type": "boolean",
+ "default": true
+ },
+ "print-issued-lines": {
+ "type": "boolean",
+ "default": true
+ },
+ "colors": {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "json": {
+ "$ref": "#/definitions/simple-format"
+ },
+ "tab": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "path": {
+ "$ref": "#/definitions/formats-path",
+ "default": "stdout"
+ },
+ "print-linter-name": {
+ "type": "boolean",
+ "default": true
+ },
+ "colors": {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "html": {
+ "$ref": "#/definitions/simple-format"
+ },
+ "checkstyle": {
+ "$ref": "#/definitions/simple-format"
+ },
+ "code-climate": {
+ "$ref": "#/definitions/simple-format"
+ },
+ "junit-xml": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "path": {
+ "$ref": "#/definitions/formats-path",
+ "default": "stdout"
+ },
+ "extended": {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "teamcity": {
+ "$ref": "#/definitions/simple-format"
+ },
+ "sarif": {
+ "$ref": "#/definitions/simple-format"
+ }
+ }
+ },
+ "path-mode": {
+ "type": "string",
+ "default": "",
+ "examples": ["abs"]
+ },
+ "path-prefix": {
+ "description": "Add a prefix to the output file references.",
+ "type": "string",
+ "default": ""
+ },
+ "show-stats": {
+ "description": "Show statistics per linter.",
+ "type": "boolean",
+ "default": true
+ },
+ "sort-order": {
+ "type": "array",
+ "items": {
+ "enum": ["linter", "severity", "file"]
+ }
+ }
+ }
+ },
+ "linters": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "default": {
+ "enum": [
+ "standard",
+ "all",
+ "none",
+ "fast"
+ ]
+ },
+ "enable": {
+ "description": "List of enabled linters.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linter-names"
+ }
+ },
+ "disable": {
+ "description": "List of disabled linters.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linter-names"
+ }
+ },
+ "settings": {
+ "description": "All available settings of specific linters.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "dupword": {
+ "$ref": "#/definitions/settings/definitions/dupwordSettings"
+ },
+ "asasalint": {
+ "$ref": "#/definitions/settings/definitions/asasalintSettings"
+ },
+ "bidichk": {
+ "$ref": "#/definitions/settings/definitions/bidichkSettings"
+ },
+ "cyclop": {
+ "$ref": "#/definitions/settings/definitions/cyclopSettings"
+ },
+ "decorder": {
+ "$ref": "#/definitions/settings/definitions/decorderSettings"
+ },
+ "depguard":{
+ "$ref": "#/definitions/settings/definitions/depguardSettings"
+ },
+ "dogsled": {
+ "$ref": "#/definitions/settings/definitions/dogsledSettings"
+ },
+ "dupl": {
+ "$ref": "#/definitions/settings/definitions/duplSettings"
+ },
+ "embeddedstructfieldcheck": {
+ "$ref": "#/definitions/settings/definitions/embeddedstructfieldcheckSettings"
+ },
+ "errcheck": {
+ "$ref": "#/definitions/settings/definitions/errcheckSettings"
+ },
+ "errchkjson": {
+ "$ref": "#/definitions/settings/definitions/errchkjsonSettings"
+ },
+ "errorlint": {
+ "$ref": "#/definitions/settings/definitions/errorlintSettings"
+ },
+ "exhaustive": {
+ "$ref": "#/definitions/settings/definitions/exhaustiveSettings"
+ },
+ "exhaustruct": {
+ "$ref": "#/definitions/settings/definitions/exhaustructSettings"
+ },
+ "fatcontext": {
+ "$ref": "#/definitions/settings/definitions/fatcontextSettings"
+ },
+ "forbidigo": {
+ "$ref": "#/definitions/settings/definitions/forbidigoSettings"
+ },
+ "funcorder": {
+ "$ref": "#/definitions/settings/definitions/funcorderSettings"
+ },
+ "funlen": {
+ "$ref": "#/definitions/settings/definitions/funlenSettings"
+ },
+ "ginkgolinter": {
+ "$ref": "#/definitions/settings/definitions/ginkgolinterSettings"
+ },
+ "gochecksumtype": {
+ "$ref": "#/definitions/settings/definitions/gochecksumtypeSettings"
+ },
+ "gocognit": {
+ "$ref": "#/definitions/settings/definitions/gocognitSettings"
+ },
+ "goconst": {
+ "$ref": "#/definitions/settings/definitions/goconstSettings"
+ },
+ "gocritic": {
+ "$ref": "#/definitions/settings/definitions/gocriticSettings"
+ },
+ "gocyclo": {
+ "$ref": "#/definitions/settings/definitions/gocycloSettings"
+ },
+ "godot": {
+ "$ref": "#/definitions/settings/definitions/godotSettings"
+ },
+ "godox": {
+ "$ref": "#/definitions/settings/definitions/godoxSettings"
+ },
+ "interfacebloat":{
+ "$ref": "#/definitions/settings/definitions/interfacebloatSettings"
+ },
+ "goheader": {
+ "$ref": "#/definitions/settings/definitions/goheaderSettings"
+ },
+ "gomoddirectives": {
+ "$ref": "#/definitions/settings/definitions/gomoddirectivesSettings"
+ },
+ "gomodguard": {
+ "$ref": "#/definitions/settings/definitions/gomodguardSettings"
+ },
+ "gosec": {
+ "$ref": "#/definitions/settings/definitions/gosecSettings"
+ },
+ "gosmopolitan": {
+ "$ref": "#/definitions/settings/definitions/gosmopolitanSettings"
+ },
+ "govet": {
+ "$ref": "#/definitions/settings/definitions/govetSettings"
+ },
+ "grouper": {
+ "$ref": "#/definitions/settings/definitions/grouperSettings"
+ },
+ "iface": {
+ "$ref": "#/definitions/settings/definitions/ifaceSettings"
+ },
+ "importas": {
+ "$ref": "#/definitions/settings/definitions/importasSettings"
+ },
+ "inamedparam": {
+ "$ref": "#/definitions/settings/definitions/inamedparamSettings"
+ },
+ "ireturn": {
+ "$ref": "#/definitions/settings/definitions/ireturnSettings"
+ },
+ "lll": {
+ "$ref": "#/definitions/settings/definitions/lllSettings"
+ },
+ "maintidx": {
+ "$ref": "#/definitions/settings/definitions/maintidxSettings"
+ },
+ "makezero":{
+ "$ref": "#/definitions/settings/definitions/makezeroSettings"
+ },
+ "loggercheck": {
+ "$ref": "#/definitions/settings/definitions/loggercheckSettings"
+ },
+ "misspell": {
+ "$ref": "#/definitions/settings/definitions/misspellSettings"
+ },
+ "musttag": {
+ "$ref": "#/definitions/settings/definitions/musttagSettings"
+ },
+ "nakedret": {
+ "$ref": "#/definitions/settings/definitions/nakedretSettings"
+ },
+ "nestif": {
+ "$ref": "#/definitions/settings/definitions/nestifSettings"
+ },
+ "nilnil": {
+ "$ref": "#/definitions/settings/definitions/nilnilSettings"
+ },
+ "nlreturn": {
+ "$ref": "#/definitions/settings/definitions/nlreturnSettings"
+ },
+ "mnd": {
+ "$ref": "#/definitions/settings/definitions/mndSettings"
+ },
+ "nolintlint":{
+ "$ref": "#/definitions/settings/definitions/nolintlintSettings"
+ },
+ "reassign": {
+ "$ref": "#/definitions/settings/definitions/reassignSettings"
+ },
+ "recvcheck": {
+ "$ref": "#/definitions/settings/definitions/recvcheckSettings"
+ },
+ "nonamedreturns": {
+ "$ref": "#/definitions/settings/definitions/nonamedreturnsSettings"
+ },
+ "paralleltest": {
+ "$ref": "#/definitions/settings/definitions/paralleltestSettings"
+ },
+ "perfsprint": {
+ "$ref": "#/definitions/settings/definitions/perfsprintSettings"
+ },
+ "prealloc": {
+ "$ref": "#/definitions/settings/definitions/preallocSettings"
+ },
+ "predeclared": {
+ "$ref": "#/definitions/settings/definitions/predeclaredSettings"
+ },
+ "promlinter": {
+ "$ref": "#/definitions/settings/definitions/promlinterSettings"
+ },
+ "protogetter": {
+ "$ref": "#/definitions/settings/definitions/protogetterSettings"
+ },
+ "revive": {
+ "$ref": "#/definitions/settings/definitions/reviveSettings"
+ },
+ "rowserrcheck": {
+ "$ref": "#/definitions/settings/definitions/rowserrcheckSettings"
+ },
+ "sloglint": {
+ "$ref": "#/definitions/settings/definitions/sloglintSettings"
+ },
+ "spancheck": {
+ "$ref": "#/definitions/settings/definitions/spancheckSettings"
+ },
+ "staticcheck":{
+ "$ref": "#/definitions/settings/definitions/staticcheckSettings"
+ },
+ "tagalign": {
+ "$ref": "#/definitions/settings/definitions/tagalignSettings"
+ },
+ "tagliatelle": {
+ "$ref": "#/definitions/settings/definitions/tagliatelleSettings"
+ },
+ "testifylint": {
+ "$ref": "#/definitions/settings/definitions/testifylintSettings"
+ },
+ "testpackage": {
+ "$ref": "#/definitions/settings/definitions/testpackageSettings"
+ },
+ "thelper": {
+ "$ref": "#/definitions/settings/definitions/thelperSettings"
+ },
+ "usestdlibvars": {
+ "$ref": "#/definitions/settings/definitions/usestdlibvarsSettings"
+ },
+ "usetesting": {
+ "$ref": "#/definitions/settings/definitions/usetestingSettings"
+ },
+ "unconvert": {
+ "$ref": "#/definitions/settings/definitions/unconvertSettings"
+ },
+ "unparam": {
+ "$ref": "#/definitions/settings/definitions/unparamSettings"
+ },
+ "unused": {
+ "$ref": "#/definitions/settings/definitions/unusedSettings"
+ },
+ "varnamelen": {
+ "$ref": "#/definitions/settings/definitions/varnamelenSettings"
+ },
+ "whitespace": {
+ "$ref": "#/definitions/settings/definitions/whitespaceSettings"
+ },
+ "wrapcheck": {
+ "$ref": "#/definitions/settings/definitions/wrapcheckSettings"
+ },
+ "wsl": {
+ "$ref": "#/definitions/settings/definitions/wslSettings"
+ },
+ "wsl_v5": {
+ "$ref": "#/definitions/settings/definitions/wslSettingsV5"
+ },
+ "copyloopvar": {
+ "$ref": "#/definitions/settings/definitions/copyloopvarSettings"
+ },
+ "custom":{
+ "$ref": "#/definitions/settings/definitions/customSettings"
+ }
+ }
+ },
+ "exclusions":{
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "generated": {
+ "enum": ["strict", "lax", "disable"],
+ "default": "strict"
+ },
+ "warn-unused": {
+ "type": "boolean",
+ "default": false
+ },
+ "presets": {
+ "type": "array",
+ "items": {
+ "enum": [
+ "comments",
+ "std-error-handling",
+ "common-false-positives",
+ "legacy"
+ ]
+ }
+ },
+ "rules": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "path": {
+ "type": "string"
+ },
+ "path-except": {
+ "type": "string"
+ },
+ "linters": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linter-names"
+ }
+ },
+ "text": {
+ "type": "string"
+ },
+ "source": {
+ "type": "string"
+ }
+ },
+ "anyOf": [
+ { "required": ["path"] },
+ { "required": ["path-except"] },
+ { "required": ["linters"] },
+ { "required": ["text"] },
+ { "required": ["source"] }
+ ]
+ }
+ },
+ "paths": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "paths-except": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "formatters": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "enable": {
+ "description": "List of enabled formatters.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/formatter-names"
+ }
+ },
+ "settings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "gci": {
+ "$ref": "#/definitions/settings/definitions/gciSettings"
+ },
+ "gofmt": {
+ "$ref": "#/definitions/settings/definitions/gofmtSettings"
+ },
+ "gofumpt": {
+ "$ref": "#/definitions/settings/definitions/gofumptSettings"
+ },
+ "goimports": {
+ "$ref": "#/definitions/settings/definitions/goimportsSettings"
+ },
+ "golines": {
+ "$ref": "#/definitions/settings/definitions/golinesSettings"
+ }
+ }
+ },
+ "exclusions": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "generated": {
+ "enum": ["strict", "lax", "disable"],
+ "default": "strict"
+ },
+ "paths": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "warn-unused": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ }
+ }
+ },
+ "issues": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-issues-per-linter": {
+ "description": "Maximum issues count per one linter. Set to 0 to disable.",
+ "type": "integer",
+ "default": 50,
+ "minimum": 0
+ },
+ "max-same-issues": {
+ "description": "Maximum count of issues with the same text. Set to 0 to disable.",
+ "type": "integer",
+ "default": 3,
+ "minimum": 0
+ },
+ "new": {
+ "description": "Show only new issues: if there are unstaged changes or untracked files, only those changes are analyzed, else only changes in HEAD~ are analyzed.",
+ "type": "boolean",
+ "default": false
+ },
+ "new-from-merge-base": {
+ "description": "Show only new issues created after the best common ancestor (merge-base against HEAD).",
+ "type": "string"
+ },
+ "new-from-rev": {
+ "description": "Show only new issues created after this git revision.",
+ "type": "string"
+ },
+ "new-from-patch": {
+ "description": "Show only new issues created in git patch with this file path.",
+ "type": "string",
+ "examples": ["path/to/patch/file"]
+ },
+ "fix": {
+ "description": "Fix found issues (if it's supported by the linter).",
+ "type": "boolean",
+ "default": false
+ },
+ "uniq-by-line": {
+ "description": "Make issues output unique by line.",
+ "type": "boolean",
+ "default": true
+ },
+ "whole-files": {
+ "description": "Show issues in any part of update files (requires new-from-rev or new-from-patch).",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "severity": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "default": {
+ "description": "Set the default severity for issues. If severity rules are defined and the issues do not match or no severity is provided to the rule this will be the default severity applied. Severities should match the supported severity names of the selected out format.",
+ "type": "string",
+ "default": ""
+ },
+ "rules": {
+ "description": "When a list of severity rules are provided, severity information will be added to lint issues. Severity rules have the same filtering capability as exclude rules except you are allowed to specify one matcher per severity rule.\nOnly affects out formats that support setting severity information.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "severity": {
+ "type": "string"
+ },
+ "path": {
+ "type": "string"
+ },
+ "path-except": {
+ "type": "string"
+ },
+ "linters": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linter-names"
+ }
+ },
+ "text": {
+ "type": "string"
+ },
+ "source": {
+ "type": "string"
+ }
+ },
+ "required": ["severity"],
+ "anyOf": [
+ { "required": ["path"] },
+ { "required": ["path-except"] },
+ { "required": ["linters"] },
+ { "required": ["text"] },
+ { "required": ["source"] }
+ ]
+ },
+ "default": []
+ }
+ },
+ "required": ["default"]
+ }
+ }
+}
diff --git a/vendor/github.com/golangci/golangci-lint/v2/jsonschema/golangci.v2.4.jsonschema.json b/vendor/github.com/golangci/golangci-lint/v2/jsonschema/golangci.v2.4.jsonschema.json
new file mode 100644
index 000000000..67cd80a55
--- /dev/null
+++ b/vendor/github.com/golangci/golangci-lint/v2/jsonschema/golangci.v2.4.jsonschema.json
@@ -0,0 +1,4929 @@
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "$id": "https://json.schemastore.org/golangci-lint.json",
+ "definitions": {
+ "gocritic-checks": {
+ "enum": [
+ "appendAssign",
+ "appendCombine",
+ "argOrder",
+ "assignOp",
+ "badCall",
+ "badCond",
+ "badLock",
+ "badRegexp",
+ "badSorting",
+ "badSyncOnceFunc",
+ "boolExprSimplify",
+ "builtinShadow",
+ "builtinShadowDecl",
+ "captLocal",
+ "caseOrder",
+ "codegenComment",
+ "commentFormatting",
+ "commentedOutCode",
+ "commentedOutImport",
+ "defaultCaseOrder",
+ "deferInLoop",
+ "deferUnlambda",
+ "deprecatedComment",
+ "docStub",
+ "dupArg",
+ "dupBranchBody",
+ "dupCase",
+ "dupImport",
+ "dupSubExpr",
+ "dynamicFmtString",
+ "elseif",
+ "emptyDecl",
+ "emptyFallthrough",
+ "emptyStringTest",
+ "equalFold",
+ "evalOrder",
+ "exitAfterDefer",
+ "exposedSyncMutex",
+ "externalErrorReassign",
+ "filepathJoin",
+ "flagDeref",
+ "flagName",
+ "hexLiteral",
+ "httpNoBody",
+ "hugeParam",
+ "ifElseChain",
+ "importShadow",
+ "indexAlloc",
+ "initClause",
+ "ioutilDeprecated",
+ "mapKey",
+ "methodExprCall",
+ "nestingReduce",
+ "newDeref",
+ "nilValReturn",
+ "octalLiteral",
+ "offBy1",
+ "paramTypeCombine",
+ "preferDecodeRune",
+ "preferFilepathJoin",
+ "preferFprint",
+ "preferStringWriter",
+ "preferWriteByte",
+ "ptrToRefParam",
+ "rangeAppendAll",
+ "rangeExprCopy",
+ "rangeValCopy",
+ "redundantSprint",
+ "regexpMust",
+ "regexpPattern",
+ "regexpSimplify",
+ "returnAfterHttpError",
+ "ruleguard",
+ "singleCaseSwitch",
+ "sliceClear",
+ "sloppyLen",
+ "sloppyReassign",
+ "sloppyTypeAssert",
+ "sortSlice",
+ "sprintfQuotedString",
+ "sqlQuery",
+ "stringConcatSimplify",
+ "stringXbytes",
+ "stringsCompare",
+ "switchTrue",
+ "syncMapLoadAndDelete",
+ "timeExprSimplify",
+ "todoCommentWithoutDetail",
+ "tooManyResultsChecker",
+ "truncateCmp",
+ "typeAssertChain",
+ "typeDefFirst",
+ "typeSwitchVar",
+ "typeUnparen",
+ "uncheckedInlineErr",
+ "underef",
+ "unlabelStmt",
+ "unlambda",
+ "unnamedResult",
+ "unnecessaryBlock",
+ "unnecessaryDefer",
+ "unslice",
+ "valSwap",
+ "weakCond",
+ "whyNoLint",
+ "wrapperFunc",
+ "yodaStyleExpr"
+ ]
+ },
+ "gocritic-tags": {
+ "enum": [
+ "diagnostic",
+ "style",
+ "performance",
+ "experimental",
+ "opinionated",
+ "security"
+ ]
+ },
+ "staticcheck-checks": {
+ "enum": [
+ "*",
+ "all",
+ "SA*",
+ "-SA*",
+ "SA1*",
+ "-SA1*",
+ "SA1000",
+ "-SA1000",
+ "SA1001",
+ "-SA1001",
+ "SA1002",
+ "-SA1002",
+ "SA1003",
+ "-SA1003",
+ "SA1004",
+ "-SA1004",
+ "SA1005",
+ "-SA1005",
+ "SA1006",
+ "-SA1006",
+ "SA1007",
+ "-SA1007",
+ "SA1008",
+ "-SA1008",
+ "SA1010",
+ "-SA1010",
+ "SA1011",
+ "-SA1011",
+ "SA1012",
+ "-SA1012",
+ "SA1013",
+ "-SA1013",
+ "SA1014",
+ "-SA1014",
+ "SA1015",
+ "-SA1015",
+ "SA1016",
+ "-SA1016",
+ "SA1017",
+ "-SA1017",
+ "SA1018",
+ "-SA1018",
+ "SA1019",
+ "-SA1019",
+ "SA1020",
+ "-SA1020",
+ "SA1021",
+ "-SA1021",
+ "SA1023",
+ "-SA1023",
+ "SA1024",
+ "-SA1024",
+ "SA1025",
+ "-SA1025",
+ "SA1026",
+ "-SA1026",
+ "SA1027",
+ "-SA1027",
+ "SA1028",
+ "-SA1028",
+ "SA1029",
+ "-SA1029",
+ "SA1030",
+ "-SA1030",
+ "SA1031",
+ "-SA1031",
+ "SA1032",
+ "-SA1032",
+ "SA2*",
+ "-SA2*",
+ "SA2000",
+ "-SA2000",
+ "SA2001",
+ "-SA2001",
+ "SA2002",
+ "-SA2002",
+ "SA2003",
+ "-SA2003",
+ "SA3*",
+ "-SA3*",
+ "SA3000",
+ "-SA3000",
+ "SA3001",
+ "-SA3001",
+ "SA4*",
+ "-SA4*",
+ "SA4000",
+ "-SA4000",
+ "SA4001",
+ "-SA4001",
+ "SA4003",
+ "-SA4003",
+ "SA4004",
+ "-SA4004",
+ "SA4005",
+ "-SA4005",
+ "SA4006",
+ "-SA4006",
+ "SA4008",
+ "-SA4008",
+ "SA4009",
+ "-SA4009",
+ "SA4010",
+ "-SA4010",
+ "SA4011",
+ "-SA4011",
+ "SA4012",
+ "-SA4012",
+ "SA4013",
+ "-SA4013",
+ "SA4014",
+ "-SA4014",
+ "SA4015",
+ "-SA4015",
+ "SA4016",
+ "-SA4016",
+ "SA4017",
+ "-SA4017",
+ "SA4018",
+ "-SA4018",
+ "SA4019",
+ "-SA4019",
+ "SA4020",
+ "-SA4020",
+ "SA4021",
+ "-SA4021",
+ "SA4022",
+ "-SA4022",
+ "SA4023",
+ "-SA4023",
+ "SA4024",
+ "-SA4024",
+ "SA4025",
+ "-SA4025",
+ "SA4026",
+ "-SA4026",
+ "SA4027",
+ "-SA4027",
+ "SA4028",
+ "-SA4028",
+ "SA4029",
+ "-SA4029",
+ "SA4030",
+ "-SA4030",
+ "SA4031",
+ "-SA4031",
+ "SA4032",
+ "-SA4032",
+ "SA5*",
+ "-SA5*",
+ "SA5000",
+ "-SA5000",
+ "SA5001",
+ "-SA5001",
+ "SA5002",
+ "-SA5002",
+ "SA5003",
+ "-SA5003",
+ "SA5004",
+ "-SA5004",
+ "SA5005",
+ "-SA5005",
+ "SA5007",
+ "-SA5007",
+ "SA5008",
+ "-SA5008",
+ "SA5009",
+ "-SA5009",
+ "SA5010",
+ "-SA5010",
+ "SA5011",
+ "-SA5011",
+ "SA5012",
+ "-SA5012",
+ "SA6*",
+ "-SA6*",
+ "SA6000",
+ "-SA6000",
+ "SA6001",
+ "-SA6001",
+ "SA6002",
+ "-SA6002",
+ "SA6003",
+ "-SA6003",
+ "SA6005",
+ "-SA6005",
+ "SA6006",
+ "-SA6006",
+ "SA9*",
+ "-SA9*",
+ "SA9001",
+ "-SA9001",
+ "SA9002",
+ "-SA9002",
+ "SA9003",
+ "-SA9003",
+ "SA9004",
+ "-SA9004",
+ "SA9005",
+ "-SA9005",
+ "SA9006",
+ "-SA9006",
+ "SA9007",
+ "-SA9007",
+ "SA9008",
+ "-SA9008",
+ "SA9009",
+ "-SA9009",
+ "ST*",
+ "-ST*",
+ "ST1*",
+ "-ST1*",
+ "ST1000",
+ "-ST1000",
+ "ST1001",
+ "-ST1001",
+ "ST1003",
+ "-ST1003",
+ "ST1005",
+ "-ST1005",
+ "ST1006",
+ "-ST1006",
+ "ST1008",
+ "-ST1008",
+ "ST1011",
+ "-ST1011",
+ "ST1012",
+ "-ST1012",
+ "ST1013",
+ "-ST1013",
+ "ST1015",
+ "-ST1015",
+ "ST1016",
+ "-ST1016",
+ "ST1017",
+ "-ST1017",
+ "ST1018",
+ "-ST1018",
+ "ST1019",
+ "-ST1019",
+ "ST1020",
+ "-ST1020",
+ "ST1021",
+ "-ST1021",
+ "ST1022",
+ "-ST1022",
+ "ST1023",
+ "-ST1023",
+ "S*",
+ "-S*",
+ "S1*",
+ "-S1*",
+ "S1000",
+ "-S1000",
+ "S1001",
+ "-S1001",
+ "S1002",
+ "-S1002",
+ "S1003",
+ "-S1003",
+ "S1004",
+ "-S1004",
+ "S1005",
+ "-S1005",
+ "S1006",
+ "-S1006",
+ "S1007",
+ "-S1007",
+ "S1008",
+ "-S1008",
+ "S1009",
+ "-S1009",
+ "S1010",
+ "-S1010",
+ "S1011",
+ "-S1011",
+ "S1012",
+ "-S1012",
+ "S1016",
+ "-S1016",
+ "S1017",
+ "-S1017",
+ "S1018",
+ "-S1018",
+ "S1019",
+ "-S1019",
+ "S1020",
+ "-S1020",
+ "S1021",
+ "-S1021",
+ "S1023",
+ "-S1023",
+ "S1024",
+ "-S1024",
+ "S1025",
+ "-S1025",
+ "S1028",
+ "-S1028",
+ "S1029",
+ "-S1029",
+ "S1030",
+ "-S1030",
+ "S1031",
+ "-S1031",
+ "S1032",
+ "-S1032",
+ "S1033",
+ "-S1033",
+ "S1034",
+ "-S1034",
+ "S1035",
+ "-S1035",
+ "S1036",
+ "-S1036",
+ "S1037",
+ "-S1037",
+ "S1038",
+ "-S1038",
+ "S1039",
+ "-S1039",
+ "S1040",
+ "-S1040",
+ "QF*",
+ "-QF*",
+ "QF1*",
+ "-QF1*",
+ "QF1001",
+ "-QF1001",
+ "QF1002",
+ "-QF1002",
+ "QF1003",
+ "-QF1003",
+ "QF1004",
+ "-QF1004",
+ "QF1005",
+ "-QF1005",
+ "QF1006",
+ "-QF1006",
+ "QF1007",
+ "-QF1007",
+ "QF1008",
+ "-QF1008",
+ "QF1009",
+ "-QF1009",
+ "QF1010",
+ "-QF1010",
+ "QF1011",
+ "-QF1011",
+ "QF1012",
+ "-QF1012"
+ ]
+ },
+ "gosec-rules": {
+ "enum": [
+ "G101",
+ "G102",
+ "G103",
+ "G104",
+ "G106",
+ "G107",
+ "G108",
+ "G109",
+ "G110",
+ "G111",
+ "G112",
+ "G114",
+ "G115",
+ "G201",
+ "G202",
+ "G203",
+ "G204",
+ "G301",
+ "G302",
+ "G303",
+ "G304",
+ "G305",
+ "G306",
+ "G307",
+ "G401",
+ "G402",
+ "G403",
+ "G404",
+ "G405",
+ "G406",
+ "G501",
+ "G502",
+ "G503",
+ "G504",
+ "G505",
+ "G506",
+ "G507",
+ "G601",
+ "G602"
+ ]
+ },
+ "govet-analyzers": {
+ "enum": [
+ "appends",
+ "asmdecl",
+ "assign",
+ "atomic",
+ "atomicalign",
+ "bools",
+ "buildtag",
+ "cgocall",
+ "composites",
+ "copylocks",
+ "deepequalerrors",
+ "defers",
+ "directive",
+ "errorsas",
+ "fieldalignment",
+ "findcall",
+ "framepointer",
+ "hostport",
+ "httpmux",
+ "httpresponse",
+ "ifaceassert",
+ "loopclosure",
+ "lostcancel",
+ "nilfunc",
+ "nilness",
+ "printf",
+ "reflectvaluecompare",
+ "shadow",
+ "shift",
+ "sigchanyzer",
+ "slog",
+ "sortslice",
+ "stdmethods",
+ "stdversion",
+ "stringintconv",
+ "structtag",
+ "testinggoroutine",
+ "tests",
+ "timeformat",
+ "unmarshal",
+ "unreachable",
+ "unsafeptr",
+ "unusedresult",
+ "unusedwrite",
+ "waitgroup"
+ ]
+ },
+ "revive-rules": {
+ "enum": [
+ "add-constant",
+ "argument-limit",
+ "atomic",
+ "banned-characters",
+ "bare-return",
+ "blank-imports",
+ "bool-literal-in-expr",
+ "call-to-gc",
+ "cognitive-complexity",
+ "comment-spacings",
+ "comments-density",
+ "confusing-naming",
+ "confusing-results",
+ "constant-logical-expr",
+ "context-as-argument",
+ "context-keys-type",
+ "cyclomatic",
+ "datarace",
+ "deep-exit",
+ "defer",
+ "dot-imports",
+ "duplicated-imports",
+ "early-return",
+ "empty-block",
+ "empty-lines",
+ "enforce-map-style",
+ "enforce-repeated-arg-type-style",
+ "enforce-slice-style",
+ "enforce-switch-style",
+ "error-naming",
+ "error-return",
+ "error-strings",
+ "errorf",
+ "exported",
+ "file-header",
+ "file-length-limit",
+ "filename-format",
+ "flag-parameter",
+ "function-length",
+ "function-result-limit",
+ "get-return",
+ "identical-branches",
+ "if-return",
+ "import-alias-naming",
+ "import-shadowing",
+ "imports-blocklist",
+ "increment-decrement",
+ "indent-error-flow",
+ "line-length-limit",
+ "max-control-nesting",
+ "max-public-structs",
+ "modifies-parameter",
+ "modifies-value-receiver",
+ "nested-structs",
+ "optimize-operands-order",
+ "package-comments",
+ "range-val-address",
+ "range-val-in-closure",
+ "range",
+ "receiver-naming",
+ "redefines-builtin-id",
+ "redundant-build-tag",
+ "redundant-import-alias",
+ "redundant-test-main-exit",
+ "string-format",
+ "string-of-int",
+ "struct-tag",
+ "superfluous-else",
+ "time-date",
+ "time-equal",
+ "time-naming",
+ "unchecked-type-assertion",
+ "unconditional-recursion",
+ "unexported-naming",
+ "unexported-return",
+ "unhandled-error",
+ "unnecessary-format",
+ "unnecessary-stmt",
+ "unreachable-code",
+ "unused-parameter",
+ "unused-receiver",
+ "use-any",
+ "use-errors-new",
+ "use-fmt-print",
+ "useless-break",
+ "var-declaration",
+ "var-naming",
+ "waitgroup-by-value"
+ ]
+ },
+ "iface-analyzers": {
+ "enum": [
+ "identical",
+ "unused",
+ "opaque",
+ "unexported"
+ ]
+ },
+ "tagliatelle-cases": {
+ "enum": [
+ "",
+ "camel",
+ "pascal",
+ "kebab",
+ "snake",
+ "goCamel",
+ "goPascal",
+ "goKebab",
+ "goSnake",
+ "upper",
+ "upperSnake",
+ "lower",
+ "header"
+ ]
+ },
+ "wsl-checks": {
+ "enum": [
+ "assign",
+ "branch",
+ "decl",
+ "defer",
+ "expr",
+ "for",
+ "go",
+ "if",
+ "inc-dec",
+ "label",
+ "range",
+ "return",
+ "select",
+ "send",
+ "switch",
+ "type-switch",
+ "append",
+ "assign-exclusive",
+ "assign-expr",
+ "err",
+ "leading-whitespace",
+ "trailing-whitespace"
+ ]
+ },
+ "relative-path-modes": {
+ "enum": [
+ "gomod",
+ "gitroot",
+ "cfg",
+ "wd"
+ ]
+ },
+ "simple-format": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "path": {
+ "$ref": "#/definitions/formats-path",
+ "default": "stdout"
+ }
+ }
+ },
+ "formats-path" : {
+ "anyOf": [
+ {
+ "enum": [
+ "stdout",
+ "stderr"
+ ]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ },
+ "linter-names": {
+ "$comment": "anyOf with enum is used to allow auto-completion of non-custom linters",
+ "description": "Usable linter names.",
+ "anyOf": [
+ {
+ "enum": [
+ "arangolint",
+ "asasalint",
+ "asciicheck",
+ "bidichk",
+ "bodyclose",
+ "canonicalheader",
+ "containedctx",
+ "contextcheck",
+ "copyloopvar",
+ "cyclop",
+ "decorder",
+ "depguard",
+ "dogsled",
+ "dupl",
+ "dupword",
+ "durationcheck",
+ "embeddedstructfieldcheck",
+ "errcheck",
+ "errchkjson",
+ "errname",
+ "errorlint",
+ "exhaustive",
+ "exhaustruct",
+ "exptostd",
+ "fatcontext",
+ "forbidigo",
+ "forcetypeassert",
+ "funcorder",
+ "funlen",
+ "ginkgolinter",
+ "gocheckcompilerdirectives",
+ "gochecknoglobals",
+ "gochecknoinits",
+ "gochecksumtype",
+ "gocognit",
+ "goconst",
+ "gocritic",
+ "gocyclo",
+ "godot",
+ "godox",
+ "err113",
+ "goheader",
+ "gomoddirectives",
+ "gomodguard",
+ "goprintffuncname",
+ "gosec",
+ "gosimple",
+ "gosmopolitan",
+ "govet",
+ "grouper",
+ "iface",
+ "importas",
+ "inamedparam",
+ "ineffassign",
+ "interfacebloat",
+ "intrange",
+ "ireturn",
+ "lll",
+ "loggercheck",
+ "maintidx",
+ "makezero",
+ "mirror",
+ "misspell",
+ "mnd",
+ "musttag",
+ "nakedret",
+ "nestif",
+ "nilerr",
+ "nilnesserr",
+ "nilnil",
+ "nlreturn",
+ "noctx",
+ "noinlineerr",
+ "nolintlint",
+ "nonamedreturns",
+ "nosprintfhostport",
+ "paralleltest",
+ "perfsprint",
+ "prealloc",
+ "predeclared",
+ "promlinter",
+ "protogetter",
+ "reassign",
+ "recvcheck",
+ "revive",
+ "rowserrcheck",
+ "sloglint",
+ "sqlclosecheck",
+ "staticcheck",
+ "stylecheck",
+ "tagalign",
+ "tagliatelle",
+ "testableexamples",
+ "testifylint",
+ "testpackage",
+ "thelper",
+ "tparallel",
+ "unconvert",
+ "unparam",
+ "unused",
+ "usestdlibvars",
+ "usetesting",
+ "varnamelen",
+ "wastedassign",
+ "whitespace",
+ "wrapcheck",
+ "wsl",
+ "wsl_v5",
+ "zerologlint"
+ ]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ },
+ "formatter-names": {
+ "description": "Usable formatter names.",
+ "enum": [
+ "gci",
+ "gofmt",
+ "gofumpt",
+ "goimports",
+ "golines",
+ "swaggo"
+ ]
+ },
+ "settings": {
+ "definitions": {
+ "dupwordSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "keywords": {
+ "description": "Keywords for detecting duplicate words. If this list is not empty, only the words defined in this list will be detected.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["the", "and", "a"]
+ }
+ },
+ "ignore": {
+ "description": "Keywords used to ignore detection.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["0C0C"]
+ }
+ }
+ }
+ },
+ "asasalintSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "exclude": {
+ "description": "To specify a set of function names to exclude.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["\\.Wrapf"]
+ }
+ },
+ "use-builtin-exclusions": {
+ "description": "To enable/disable the asasalint builtin exclusions of function names.",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "bidichkSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "left-to-right-embedding": {
+ "description": "Disallow: LEFT-TO-RIGHT-EMBEDDING",
+ "type": "boolean",
+ "default": false
+ },
+ "right-to-left-embedding": {
+ "description": "Disallow: RIGHT-TO-LEFT-EMBEDDING",
+ "type": "boolean",
+ "default": false
+ },
+ "pop-directional-formatting": {
+ "description": "Disallow: POP-DIRECTIONAL-FORMATTING",
+ "type": "boolean",
+ "default": false
+ },
+ "left-to-right-override": {
+ "description": "Disallow: LEFT-TO-RIGHT-OVERRIDE",
+ "type": "boolean",
+ "default": false
+ },
+ "right-to-left-override": {
+ "description": "Disallow: RIGHT-TO-LEFT-OVERRIDE",
+ "type": "boolean",
+ "default": false
+ },
+ "left-to-right-isolate": {
+ "description": "Disallow: LEFT-TO-RIGHT-ISOLATE",
+ "type": "boolean",
+ "default": false
+ },
+ "right-to-left-isolate": {
+ "description": "Disallow: RIGHT-TO-LEFT-ISOLATE",
+ "type": "boolean",
+ "default": false
+ },
+ "first-strong-isolate": {
+ "description": "Disallow: FIRST-STRONG-ISOLATE",
+ "type": "boolean",
+ "default": false
+ },
+ "pop-directional-isolate": {
+ "description": "Disallow: POP-DIRECTIONAL-ISOLATE",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "cyclopSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-complexity": {
+ "description": "Max complexity the function can have",
+ "type": "integer",
+ "default": 10,
+ "minimum": 0
+ },
+ "package-average": {
+ "description": "Max average complexity in package",
+ "type": "number",
+ "default": 0,
+ "minimum": 0
+ }
+ }
+ },
+ "decorderSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "dec-order": {
+ "type": "array",
+ "default": [["type", "const", "var", "func"]],
+ "items": {
+ "enum": ["type", "const", "var", "func"]
+ }
+ },
+ "ignore-underscore-vars": {
+ "description": "Underscore vars (vars with \"_\" as the name) will be ignored at all checks",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-dec-order-check": {
+ "description": "Order of declarations is not checked",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-init-func-first-check": {
+ "description": "Allow init func to be anywhere in file",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-dec-num-check": {
+ "description": "Multiple global type, const and var declarations are allowed",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-type-dec-num-check": {
+ "description": "Type declarations will be ignored for dec num check",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-const-dec-num-check": {
+ "description": "Const declarations will be ignored for dec num check",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-var-dec-num-check": {
+ "description": "Var declarations will be ignored for dec num check",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ },
+ "depguardSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "rules": {
+ "description": "Rules to apply.",
+ "type": "object",
+ "additionalProperties": false,
+ "patternProperties": {
+ "^[^.]+$": {
+ "description": "Name of a rule.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "list-mode": {
+ "description": "Used to determine the package matching priority.",
+ "enum": ["original", "strict", "lax"],
+ "default": "original"
+ },
+ "files": {
+ "description": "List of file globs that will match this list of settings to compare against.",
+ "additionalProperties": false,
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "allow": {
+ "description": "List of allowed packages.",
+ "additionalProperties": false,
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "deny": {
+ "description": "Packages that are not allowed where the value is a suggestion.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "desc": {
+ "description": "Description",
+ "type": "string"
+ },
+ "pkg": {
+ "description": "Package",
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "dogsledSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-blank-identifiers": {
+ "description": "Check assignments with too many blank identifiers.",
+ "type": "integer",
+ "default": 2,
+ "minimum": 0
+ }
+ }
+ },
+ "duplSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "threshold": {
+ "description": "Tokens count to trigger issue.",
+ "type": "integer",
+ "default": 150,
+ "minimum": 0
+ }
+ }
+ },
+ "embeddedstructfieldcheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "forbid-mutex": {
+ "description": "Checks that sync.Mutex and sync.RWMutex are not used as embedded fields.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "errcheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-type-assertions": {
+ "description": "Report about not checking errors in type assertions, i.e.: `a := b.(MyStruct)`",
+ "type": "boolean",
+ "default": false
+ },
+ "check-blank": {
+ "description": "Report about assignment of errors to blank identifier",
+ "type": "boolean",
+ "default": false
+ },
+ "exclude-functions": {
+ "description": "List of functions to exclude from checking, where each entry is a single function to exclude",
+ "type": "array",
+ "examples": ["io/ioutil.ReadFile", "io.Copy(*bytes.Buffer)"],
+ "items": {
+ "type": "string"
+ }
+ },
+ "disable-default-exclusions": {
+ "description": "To disable the errcheck built-in exclude list",
+ "type": "boolean",
+ "default": false
+ },
+ "verbose": {
+ "description": "Display function signature instead of selector",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "errchkjsonSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-error-free-encoding": {
+ "type": "boolean",
+ "default": false
+ },
+ "report-no-exported": {
+ "description": "Issue on struct that doesn't have exported fields.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "errorlintSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "errorf": {
+ "description": "Check whether fmt.Errorf uses the %w verb for formatting errors",
+ "type": "boolean",
+ "default": true
+ },
+ "errorf-multi": {
+ "description": "Permit more than 1 %w verb, valid per Go 1.20",
+ "type": "boolean",
+ "default": true
+ },
+ "asserts": {
+ "description": "Check for plain type assertions and type switches.",
+ "type": "boolean",
+ "default": true
+ },
+ "comparison": {
+ "description": "Check for plain error comparisons",
+ "type": "boolean",
+ "default": true
+ },
+ "allowed-errors": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "err": {
+ "type": "string"
+ },
+ "fun": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "allowed-errors-wildcard": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "err": {
+ "type": "string"
+ },
+ "fun": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "exhaustiveSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check": {
+ "description": "Program elements to check for exhaustiveness.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["switch", "map"]
+ }
+ },
+ "explicit-exhaustive-switch": {
+ "description": "Only run exhaustive check on switches with \"//exhaustive:enforce\" comment.",
+ "type": "boolean",
+ "default": false
+ },
+ "explicit-exhaustive-map": {
+ "description": "Only run exhaustive check on map literals with \"//exhaustive:enforce\" comment.",
+ "type": "boolean",
+ "default": false
+ },
+ "default-case-required": {
+ "description": "Switch statement requires default case even if exhaustive.",
+ "type": "boolean",
+ "default": false
+ },
+ "default-signifies-exhaustive": {
+ "description": "Presence of `default` case in switch statements satisfies exhaustiveness, even if all enum members are not listed.",
+ "type": "boolean",
+ "default": false
+ },
+ "ignore-enum-members": {
+ "description": "Enum members matching `regex` do not have to be listed in switch statements to satisfy exhaustiveness",
+ "type": "string"
+ },
+ "ignore-enum-types": {
+ "description": "Enum types matching the supplied regex do not have to be listed in switch statements to satisfy exhaustiveness.",
+ "type": "string"
+ },
+ "package-scope-only": {
+ "description": "Consider enums only in package scopes, not in inner scopes.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "exhaustructSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "include": {
+ "description": "List of regular expressions to match struct packages and names.",
+ "type": "array",
+ "examples": [".*\\.Test"],
+ "items": {
+ "type": "string"
+ }
+ },
+ "exclude": {
+ "description": "List of regular expressions to exclude struct packages and names from check.",
+ "type": "array",
+ "examples": ["cobra\\.Command$"],
+ "items": {
+ "type": "string"
+ }
+ },
+ "allow-empty": {
+ "description": "Allows empty structures, effectively excluding them from the check.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-empty-rx": {
+ "description": "List of regular expressions to match type names that should be allowed to be empty.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "allow-empty-returns": {
+ "description": "Allows empty structures in return statements.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-empty-declarations": {
+ "description": "Allows empty structures in variable declarations.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "fatcontextSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-struct-pointers": {
+ "description": "Check for potential fat contexts in struct pointers.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "forbidigoSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "exclude-godoc-examples": {
+ "description": "Exclude code in godoc examples.",
+ "type": "boolean",
+ "default": true
+ },
+ "analyze-types": {
+ "description": "Instead of matching the literal source code, use type information to replace expressions with strings that contain the package name and (for methods and fields) the type name.",
+ "type": "boolean",
+ "default": true
+ },
+ "forbid": {
+ "description": "List of identifiers to forbid (written using `regexp`)",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "pattern": {
+ "description": "Pattern",
+ "type": "string"
+ },
+ "pkg": {
+ "description": "Package",
+ "type": "string"
+ },
+ "msg": {
+ "description": "Message",
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "funcorderSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "constructor": {
+ "description": "Checks that constructors are placed after the structure declaration.",
+ "type": "boolean",
+ "default": true
+ },
+ "struct-method": {
+ "description": "Checks if the exported methods of a structure are placed before the non-exported ones.",
+ "type": "boolean",
+ "default": true
+ },
+ "alphabetical": {
+ "description": "Checks if the constructors and/or structure methods are sorted alphabetically.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "funlenSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "lines": {
+ "description": "Limit lines number per function.",
+ "type": "integer",
+ "default": 60
+ },
+ "statements": {
+ "description": "Limit statements number per function.",
+ "type": "integer",
+ "default": 40
+ },
+ "ignore-comments": {
+ "description": "Ignore comments when counting lines.",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "gciSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "sections": {
+ "description": "Section configuration to compare against.",
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "enum": [
+ "standard",
+ "default",
+ "blank",
+ "dot",
+ "alias",
+ "localmodule"
+ ]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ },
+ "default": ["standard", "default"]
+ },
+ "no-inline-comments": {
+ "description": "Checks that no inline Comments are present.",
+ "type": "boolean",
+ "default": false
+ },
+ "no-prefix-comments": {
+ "description": "Checks that no prefix Comments(comment lines above an import) are present.",
+ "type": "boolean",
+ "default": false
+ },
+ "custom-order": {
+ "description": "Enable custom order of sections.",
+ "type": "boolean",
+ "default": false
+ },
+ "no-lex-order": {
+ "description": "Drops lexical ordering for custom sections.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "ginkgolinterSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "suppress-len-assertion": {
+ "description": "Suppress the wrong length assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-nil-assertion": {
+ "description": "Suppress the wrong nil assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-err-assertion": {
+ "description": "Suppress the wrong error assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-compare-assertion": {
+ "description": "Suppress the wrong comparison assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-async-assertion": {
+ "description": "Suppress the function all in async assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-type-compare-assertion": {
+ "description": "Suppress warning for comparing values from different types, like int32 and uint32.",
+ "type": "boolean",
+ "default": false
+ },
+ "forbid-focus-container": {
+ "description": "Trigger warning for ginkgo focus containers like FDescribe, FContext, FWhen or FIt.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-havelen-zero": {
+ "description": "Don't trigger warnings for HaveLen(0).",
+ "type": "boolean",
+ "default": false
+ },
+ "force-expect-to": {
+ "description": "Force using `Expect` with `To`, `ToNot` or `NotTo`",
+ "type": "boolean",
+ "default": false
+ },
+ "validate-async-intervals": {
+ "description": "Best effort validation of async intervals (timeout and polling).",
+ "type": "boolean",
+ "default": false
+ },
+ "forbid-spec-pollution": {
+ "description": "Trigger a warning for variable assignments in ginkgo containers like `Describe`, `Context` and `When`, instead of in `BeforeEach()`.",
+ "type": "boolean",
+ "default": false
+ },
+ "force-succeed": {
+ "description": "Force using the Succeed matcher for error functions, and the HaveOccurred matcher for non-function error values.",
+ "type": "boolean",
+ "default": false
+ },
+ "force-assertion-description": {
+ "description": "Force adding assertion descriptions to gomega matchers.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "gochecksumtypeSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "default-signifies-exhaustive": {
+ "description": "Presence of `default` case in switch statements satisfies exhaustiveness, if all members are not listed.",
+ "type": "boolean",
+ "default": true
+ },
+ "include-shared-interfaces": {
+ "description": "Include shared interfaces in the exhaustiviness check.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "gocognitSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "min-complexity": {
+ "description": "Minimal code complexity to report (we recommend 10-20).",
+ "type": "integer",
+ "default": 30
+ }
+ }
+ },
+ "goconstSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "match-constant": {
+ "description": "Look for existing constants matching the values",
+ "type": "boolean",
+ "default": true
+ },
+ "min-len": {
+ "description": "Minimum length of string constant.",
+ "type": "integer",
+ "default": 3
+ },
+ "min-occurrences": {
+ "description": "Minimum occurrences count to trigger.",
+ "type": "integer",
+ "default": 3
+ },
+ "ignore-calls": {
+ "description": "Ignore when constant is not used as function argument",
+ "type": "boolean",
+ "default": true
+ },
+ "ignore-string-values": {
+ "description": "Exclude strings matching the given regular expression",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "numbers": {
+ "description": "Search also for duplicated numbers.",
+ "type": "boolean",
+ "default": false
+ },
+ "min": {
+ "description": "Minimum value, only works with `numbers`",
+ "type": "integer",
+ "default": 3
+ },
+ "max": {
+ "description": "Maximum value, only works with `numbers`",
+ "type": "integer",
+ "default": 3
+ },
+ "find-duplicates": {
+ "description": "Detects constants with identical values",
+ "type": "boolean",
+ "default": false
+ },
+ "eval-const-expressions": {
+ "description": "Evaluates of constant expressions like Prefix + \"suffix\"",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "gocriticSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "enabled-checks": {
+ "description": "Which checks should be enabled. By default, a list of stable checks is used. To see it, run `GL_DEBUG=gocritic golangci-lint run`.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/gocritic-checks"
+ }
+ },
+ "disabled-checks": {
+ "description": "Which checks should be disabled.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/gocritic-checks"
+ },
+ "default": []
+ },
+ "enabled-tags": {
+ "description": "Enable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/gocritic-tags"
+ }
+ },
+ "disabled-tags": {
+ "description": "Disable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/gocritic-tags"
+ }
+ },
+ "settings": {
+ "description": "Settings passed to gocritic. Properties must be valid and enabled check names.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "captLocal": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "paramsOnly" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "commentedOutCode": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "minLength" : {
+ "type": "number",
+ "default": 15
+ }
+ }
+ },
+ "elseif": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skipBalanced" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "hugeParam": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "sizeThreshold" : {
+ "type": "number",
+ "default": 80
+ }
+ }
+ },
+ "ifElseChain": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "minThreshold" : {
+ "type": "number",
+ "default": 2
+ }
+ }
+ },
+ "nestingReduce": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "bodyWidth" : {
+ "type": "number",
+ "default": 5
+ }
+ }
+ },
+ "rangeExprCopy": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "sizeThreshold" : {
+ "type": "number",
+ "default": 512
+ },
+ "skipTestFuncs" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "rangeValCopy": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "sizeThreshold" : {
+ "type": "number",
+ "default": 128
+ },
+ "skipTestFuncs" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "ruleguard": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "debug" : {
+ "type": "string"
+ },
+ "enable" : {
+ "type": "string"
+ },
+ "disable" : {
+ "type": "string"
+ },
+ "failOn" : {
+ "type": "string"
+ },
+ "rules" : {
+ "type": "string"
+ }
+ }
+ },
+ "tooManyResultsChecker": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "maxResults" : {
+ "type": "number",
+ "default": 5
+ }
+ }
+ },
+ "truncateCmp": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skipArchDependent" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "underef": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skipRecvDeref" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "unnamedResult": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "checkExported" : {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ }
+ }
+ },
+ "disable-all": {
+ "type": "boolean",
+ "default": false
+ },
+ "enable-all": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "gocycloSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "min-complexity": {
+ "description": "Minimum code complexity to report (we recommend 10-20).",
+ "type": "integer",
+ "default": 30
+ }
+ }
+ },
+ "godotSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "scope": {
+ "description": "Comments to be checked.",
+ "enum": ["declarations", "toplevel", "all", "noinline"],
+ "default": "declarations"
+ },
+ "exclude": {
+ "description": "List of regexps for excluding particular comment lines from check.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "period": {
+ "description": "Check that each sentence ends with a period.",
+ "type": "boolean",
+ "default": true
+ },
+ "capital": {
+ "description": "Check that each sentence starts with a capital letter.",
+ "type": "boolean",
+ "default": false
+ },
+ "check-all": {
+ "description": "DEPRECATED: Check all top-level comments, not only declarations.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "godoxSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "keywords": {
+ "description": "Report any comments starting with one of these keywords. This is useful for TODO or FIXME comments that might be left in the code accidentally and should be resolved before merging.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "default": ["TODO", "BUG", "FIXME"]
+ }
+ }
+ },
+ "gofmtSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "simplify": {
+ "description": "Simplify code.",
+ "type": "boolean",
+ "default": true
+ },
+ "rewrite-rules": {
+ "description": "Apply the rewrite rules to the source before reformatting.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "pattern": {
+ "type": "string"
+ },
+ "replacement": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "golinesSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-len": {
+ "type": "integer",
+ "default": 100
+ },
+ "tab-len": {
+ "type": "integer",
+ "default": 4
+ },
+ "shorten-comments": {
+ "type": "boolean",
+ "default": false
+ },
+ "reformat-tags": {
+ "type": "boolean",
+ "default": true
+ },
+ "chain-split-dots": {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "interfacebloatSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max": {
+ "description": "The maximum number of methods allowed for an interface.",
+ "type": "integer"
+ }
+ }
+ },
+ "gofumptSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "extra-rules": {
+ "description": "Choose whether or not to use the extra rules that are disabled by default.",
+ "type": "boolean",
+ "default": false
+ },
+ "module-path": {
+ "description": " Module path which contains the source code being formatted.",
+ "type": "string"
+ }
+ }
+ },
+ "goheaderSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "values": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "const": {
+ "description": "Constants to use in the template.",
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "description": "Value for the constant.",
+ "type": "string"
+ }
+ },
+ "additionalProperties": false,
+ "examples": [
+ {
+ "YEAR": "2030",
+ "COMPANY": "MY FUTURISTIC COMPANY"
+ }
+ ]
+ },
+ "regexp": {
+ "description": "Regular expressions to use in your template.",
+ "type": "object",
+ "additionalProperties": false,
+ "patternProperties": {
+ "^.+$": {
+ "type": "string"
+ }
+ },
+ "examples": [
+ {
+ "AUTHOR": ".*@mycompany\\.com"
+ }
+ ]
+ }
+ }
+ },
+ "template": {
+ "description": "Template to put on top of every file.",
+ "type": "string",
+ "examples": [
+ "{{ MY COMPANY }}\nSPDX-License-Identifier: Apache-2.0\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at:\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License."
+ ]
+ },
+ "template-path": {
+ "description": "Path to the file containing the template source.",
+ "type": "string",
+ "examples": ["my_header_template.txt"]
+ }
+ },
+ "oneOf": [
+ { "required": ["template"] },
+ { "required": ["template-path"] }
+ ]
+ },
+ "goimportsSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "local-prefixes": {
+ "description": "Put imports beginning with prefix after 3rd-party packages. It is a list of prefixes.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "gomoddirectivesSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "replace-local": {
+ "description": "Allow local `replace` directives.",
+ "type": "boolean",
+ "default": true
+ },
+ "replace-allow-list": {
+ "description": "List of allowed `replace` directives.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "retract-allow-no-explanation": {
+ "description": "Allow to not explain why the version has been retracted in the `retract` directives.",
+ "type": "boolean",
+ "default": false
+ },
+ "exclude-forbidden": {
+ "description": "Forbid the use of the `exclude` directives.",
+ "type": "boolean",
+ "default": false
+ },
+ "ignore-forbidden": {
+ "description": "Forbid the use of the `ignore` directives. (>= go1.25)",
+ "type": "boolean",
+ "default": false
+ },
+ "toolchain-forbidden": {
+ "description": "Forbid the use of the `toolchain` directive.",
+ "type": "boolean",
+ "default": false
+ },
+ "toolchain-pattern": {
+ "description": "Defines a pattern to validate `toolchain` directive.",
+ "type": "string"
+ },
+ "tool-forbidden": {
+ "description": "Forbid the use of the `tool` directives.",
+ "type": "boolean",
+ "default": false
+ },
+ "go-debug-forbidden": {
+ "description": "Forbid the use of the `godebug` directive.",
+ "type": "boolean",
+ "default": false
+ },
+ "go-version-pattern": {
+ "description": "Defines a pattern to validate `go` minimum version directive.",
+ "type": "string",
+ "default": ""
+ }
+ }
+ },
+ "gomodguardSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "allowed": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "modules": {
+ "description": "List of allowed modules.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["gopkg.in/yaml.v2"]
+ }
+ },
+ "domains": {
+ "description": "List of allowed module domains.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["golang.org"]
+ }
+ }
+ }
+ },
+ "blocked": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "modules": {
+ "description": "List of blocked modules.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "recommendations": {
+ "description": "Recommended modules that should be used instead.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "reason": {
+ "description": "Reason why the recommended module should be used.",
+ "type": "string"
+ }
+ }
+ }
+ },
+ "additionalProperties": false
+ }
+ },
+ "versions": {
+ "description": "List of blocked module version constraints.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "patternProperties": {
+ "^.*$": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "version": {
+ "description": "Version constraint.",
+ "type": "string"
+ },
+ "reason": {
+ "description": "Reason why the version constraint exists.",
+ "type": "string"
+ }
+ },
+ "required": ["reason"]
+ }
+ }
+ }
+ },
+ "local-replace-directives": {
+ "description": "Raise lint issues if loading local path with replace directive",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ }
+ }
+ },
+ "gosecSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "includes": {
+ "type": "array",
+ "description": "To select a subset of rules to run",
+ "examples": [["G401"]],
+ "items": {
+ "$ref": "#/definitions/gosec-rules"
+ }
+ },
+ "excludes": {
+ "type": "array",
+ "description": "To specify a set of rules to explicitly exclude",
+ "examples": [["G401"]],
+ "items": {
+ "$ref": "#/definitions/gosec-rules"
+ }
+ },
+ "severity": {
+ "description": "Filter out the issues with a lower severity than the given value",
+ "type": "string",
+ "enum": ["low", "medium", "high"],
+ "default": "low"
+ },
+ "confidence": {
+ "description": "Filter out the issues with a lower confidence than the given value",
+ "type": "string",
+ "enum": ["low", "medium", "high"],
+ "default": "low"
+ },
+ "config": {
+ "description": "To specify the configuration of rules",
+ "type": "object"
+ },
+ "concurrency": {
+ "description": "Concurrency value",
+ "type": "integer"
+ }
+ }
+ },
+ "gosmopolitanSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "allow-time-local": {
+ "description": "Allow and ignore `time.Local` usages.",
+ "type": "boolean",
+ "default": false
+ },
+ "escape-hatches": {
+ "description": "List of fully qualified names in the `full/pkg/path.name` form, to act as \"i18n escape hatches\".",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "watch-for-scripts": {
+ "description": "List of Unicode scripts to watch for any usage in string literals.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "govetSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "settings": {
+ "description": "Settings per analyzer. Map of analyzer name to specific settings.\nRun `go tool vet help` to find out more.",
+ "type": "object",
+ "propertyNames": {
+ "$ref": "#/definitions/govet-analyzers"
+ },
+ "patternProperties": {
+ "^.*$": {
+ "description": "Run `go tool vet help ` to see all settings.",
+ "type": "object"
+ }
+ }
+ },
+ "enable": {
+ "description": "Enable analyzers by name.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/govet-analyzers"
+ }
+ },
+ "disable": {
+ "description": "Disable analyzers by name.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/govet-analyzers"
+ }
+ },
+ "enable-all": {
+ "description": "Enable all analyzers.",
+ "type": "boolean",
+ "default": false
+ },
+ "disable-all": {
+ "description": "Disable all analyzers.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "grouperSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "const-require-single-const": {
+ "type": "boolean",
+ "default": false
+ },
+ "const-require-grouping": {
+ "type": "boolean",
+ "default": false
+ },
+ "import-require-single-import": {
+ "type": "boolean",
+ "default": false
+ },
+ "import-require-grouping": {
+ "type": "boolean",
+ "default": false
+ },
+ "type-require-single-type": {
+ "type": "boolean",
+ "default": false
+ },
+ "type-require-grouping": {
+ "type": "boolean",
+ "default": false
+ },
+ "var-require-single-var": {
+ "type": "boolean",
+ "default": false
+ },
+ "var-require-grouping": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "ifaceSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "enable": {
+ "description": "Enable analyzers by name.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/iface-analyzers"
+ }
+ },
+ "settings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "unused": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "exclude": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "importasSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "no-unaliased": {
+ "description": "Do not allow unaliased imports of aliased packages.",
+ "type": "boolean",
+ "default": false
+ },
+ "no-extra-aliases": {
+ "description": "Do not allow non-required aliases.",
+ "type": "boolean",
+ "default": false
+ },
+ "alias": {
+ "description": "List of aliases",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "pkg": {
+ "description": "Package path e.g. knative.dev/serving/pkg/apis/autoscaling/v1alpha1",
+ "type": "string"
+ },
+ "alias": {
+ "description": "Package alias e.g. autoscalingv1alpha1",
+ "type": "string"
+ }
+ },
+ "required": ["pkg", "alias"]
+ }
+ }
+ }
+ },
+ "inamedparamSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skip-single-param": {
+ "description": "Skips check for interface methods with only a single parameter.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "ireturnSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "description": "Use either `reject` or `allow` properties for interfaces matching.",
+ "properties": {
+ "allow": {
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "enum": ["anon", "error", "empty", "stdlib"]
+ }
+ ]
+ }
+ },
+ "reject": {
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "enum": ["anon", "error", "empty", "stdlib"]
+ }
+ ]
+ }
+ }
+ },
+ "anyOf": [
+ {
+ "not": {
+ "properties": {
+ "allow": {
+ "const": "reject"
+ }
+ }
+ },
+ "required": ["allow"]
+ },
+ {
+ "required": ["reject"]
+ }
+ ]
+ },
+ "lllSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "tab-width": {
+ "description": "Width of \"\\t\" in spaces.",
+ "type": "integer",
+ "minimum": 0,
+ "default": 1
+ },
+ "line-length": {
+ "description": "Maximum allowed line length, lines longer will be reported.",
+ "type": "integer",
+ "minimum": 1,
+ "default": 120
+ }
+ }
+ },
+ "maintidxSettings": {
+ "description": "Maintainability index https://docs.microsoft.com/en-us/visualstudio/code-quality/code-metrics-maintainability-index-range-and-meaning?view=vs-2022",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "under": {
+ "description": "Minimum accatpable maintainability index level (see https://docs.microsoft.com/en-us/visualstudio/code-quality/code-metrics-maintainability-index-range-and-meaning?view=vs-2022)",
+ "type": "number",
+ "default": 20
+ }
+ }
+ },
+ "makezeroSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "always": {
+ "description": "Allow only slices initialized with a length of zero.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "loggercheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "kitlog": {
+ "description": "Allow check for the github.com/go-kit/log library.",
+ "type": "boolean",
+ "default": true
+ },
+ "klog": {
+ "description": "Allow check for the k8s.io/klog/v2 library.",
+ "type": "boolean",
+ "default": true
+ },
+ "logr": {
+ "description": "Allow check for the github.com/go-logr/logr library.",
+ "type": "boolean",
+ "default": true
+ },
+ "slog": {
+ "description": "Allow check for the log/slog library.",
+ "type": "boolean",
+ "default": true
+ },
+ "zap": {
+ "description": "Allow check for the \"sugar logger\" from go.uber.org/zap library.",
+ "type": "boolean",
+ "default": true
+ },
+ "require-string-key": {
+ "description": "Require all logging keys to be inlined constant strings.",
+ "type": "boolean",
+ "default": false
+ },
+ "no-printf-like": {
+ "description": "Require printf-like format specifier (%s, %d for example) not present.",
+ "type": "boolean",
+ "default": false
+ },
+ "rules": {
+ "description": "List of custom rules to check against, where each rule is a single logger pattern, useful for wrapped loggers.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "misspellSettings": {
+ "description": "Correct spellings using locale preferences for US or UK. Default is to use a neutral variety of English.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "locale": {
+ "enum": ["US", "UK"]
+ },
+ "ignore-rules": {
+ "description": "List of rules to ignore.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "mode": {
+ "description": "Mode of the analysis.",
+ "enum": ["restricted", "", "default"],
+ "default": ""
+ },
+ "extra-words": {
+ "description": "Extra word corrections.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "correction": {
+ "type": "string"
+ },
+ "typo": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "musttagSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "functions": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "tag": {
+ "type": "string"
+ },
+ "arg-pos": {
+ "type": "integer"
+ }
+ }
+ }
+ }
+ }
+ },
+ "nakedretSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-func-lines": {
+ "description": "Report if a function has more lines of code than this value and it has naked returns.",
+ "type": "integer",
+ "minimum": 0,
+ "default": 30
+ }
+ }
+ },
+ "nestifSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "min-complexity": {
+ "description": "Minimum complexity of \"if\" statements to report.",
+ "type": "integer",
+ "default": 5
+ }
+ }
+ },
+ "nilnilSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "only-two": {
+ "type": "boolean",
+ "description": "To check functions with only two return values.",
+ "default": true
+ },
+ "detect-opposite": {
+ "type": "boolean",
+ "description": "In addition, detect opposite situation (simultaneous return of non-nil error and valid value).",
+ "default": false
+ },
+ "checked-types": {
+ "type": "array",
+ "description": "List of return types to check.",
+ "items": {
+ "enum": ["chan", "func", "iface", "map", "ptr", "uintptr", "unsafeptr"]
+ },
+ "default": ["chan", "func", "iface", "map", "ptr", "uintptr", "unsafeptr"]
+ }
+ }
+ },
+ "nlreturnSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "block-size": {
+ "description": "set block size that is still ok",
+ "type": "number",
+ "default": 0,
+ "minimum": 0
+ }
+ }
+ },
+ "mndSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignored-files": {
+ "description": "List of file patterns to exclude from analysis.",
+ "examples": [["magic1_.*.go"]],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignored-functions": {
+ "description": "Comma-separated list of function patterns to exclude from the analysis.",
+ "examples": [["math.*", "http.StatusText", "make"]],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignored-numbers": {
+ "description": "List of numbers to exclude from analysis.",
+ "examples": [["1000", "1234_567_890", "3.14159264"]],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "checks": {
+ "description": "The list of enabled checks, see https://github.com/tommy-muehle/go-mnd/#checks for description.",
+ "type": "array",
+ "items": {
+ "enum": [
+ "argument",
+ "case",
+ "condition",
+ "operation",
+ "return",
+ "assign"
+ ]
+ }
+ }
+ }
+ },
+ "nolintlintSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "allow-unused": {
+ "description": "Enable to ensure that nolint directives are all used.",
+ "type": "boolean",
+ "default": true
+ },
+ "allow-no-explanation": {
+ "description": "Exclude these linters from requiring an explanation.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linter-names"
+ },
+ "default": []
+ },
+ "require-explanation": {
+ "description": "Enable to require an explanation of nonzero length after each nolint directive.",
+ "type": "boolean",
+ "default": false
+ },
+ "require-specific": {
+ "description": "Enable to require nolint directives to mention the specific linter being suppressed.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "reassignSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "patterns": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "recvcheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "disable-builtin": {
+ "description": "Disables the built-in method exclusions.",
+ "type": "boolean",
+ "default": true
+ },
+ "exclusions": {
+ "description": "User-defined method exclusions.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "nonamedreturnsSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "report-error-in-defer": {
+ "description": "Report named error if it is assigned inside defer.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "paralleltestSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignore-missing": {
+ "description": "Ignore missing calls to `t.Parallel()` and only report incorrect uses of it.",
+ "type": "boolean",
+ "default": false
+ },
+ "ignore-missing-subtests": {
+ "description": "Ignore missing calls to `t.Parallel()` in subtests. Top-level tests are still required to have `t.Parallel`, but subtests are allowed to skip it.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "perfsprintSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "integer-format": {
+ "description": "Enable/disable optimization of integer formatting.",
+ "type": "boolean",
+ "default": true
+ },
+ "int-conversion": {
+ "description": "Optimizes even if it requires an int or uint type cast.",
+ "type": "boolean",
+ "default": true
+ },
+ "error-format": {
+ "description": "Enable/disable optimization of error formatting.",
+ "type": "boolean",
+ "default": true
+ },
+ "err-error": {
+ "description": "Optimizes into `err.Error()` even if it is only equivalent for non-nil errors.",
+ "type": "boolean",
+ "default": false
+ },
+ "errorf": {
+ "description": "Optimizes `fmt.Errorf`.",
+ "type": "boolean",
+ "default": true
+ },
+ "string-format": {
+ "description": "Enable/disable optimization of string formatting.",
+ "type": "boolean",
+ "default": true
+ },
+ "sprintf1": {
+ "description": "Optimizes `fmt.Sprintf` with only one argument.",
+ "type": "boolean",
+ "default": true
+ },
+ "strconcat": {
+ "description": "Optimizes into strings concatenation.",
+ "type": "boolean",
+ "default": true
+ },
+ "bool-format": {
+ "description": "Enable/disable optimization of bool formatting.",
+ "type": "boolean",
+ "default": true
+ },
+ "hex-format": {
+ "description": "Enable/disable optimization of hex formatting.",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "preallocSettings": {
+ "description": "We do not recommend using this linter before doing performance profiling.\nFor most programs usage of `prealloc` will be premature optimization.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "simple": {
+ "description": "Report preallocation suggestions only on simple loops that have no returns/breaks/continues/gotos in them.",
+ "type": "boolean",
+ "default": true
+ },
+ "range-loops": {
+ "description": "Report preallocation suggestions on range loops.",
+ "type": "boolean",
+ "default": true
+ },
+ "for-loops": {
+ "description": "Report preallocation suggestions on for loops.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "predeclaredSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignore": {
+ "description": "List of predeclared identifiers to not report on.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "qualified-name": {
+ "description": "Include method names and field names in checks.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "promlinterSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "strict": {},
+ "disabled-linters": {
+ "type": "array",
+ "items": {
+ "enum": [
+ "Help",
+ "MetricUnits",
+ "Counter",
+ "HistogramSummaryReserved",
+ "MetricTypeInName",
+ "ReservedChars",
+ "CamelCase",
+ "UnitAbbreviations"
+ ]
+ }
+ }
+ }
+ },
+ "protogetterSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skip-generated-by": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["protoc-gen-go-my-own-generator"]
+ }
+ },
+ "skip-files": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["*.pb.go"]
+ }
+ },
+ "skip-any-generated": {
+ "description": "Skip any generated files from the checking.",
+ "type": "boolean",
+ "default": false
+ },
+ "replace-first-arg-in-append": {
+ "description": "Skip first argument of append function.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "reviveSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "examples": [
+ {
+ "ignore-generated-header": true,
+ "severity": "warning",
+ "rules": [
+ {
+ "name": "indent-error-flow",
+ "severity": "warning"
+ },
+ {
+ "name": "add-constant",
+ "severity": "warning",
+ "arguments": [
+ {
+ "maxLitCount": "3",
+ "allowStrs": "\"\"",
+ "allowInts": "0,1,2",
+ "allowFloats": "0.0,0.,1.0,1.,2.0,2."
+ }
+ ]
+ }
+ ]
+ }
+ ],
+ "properties": {
+ "max-open-files": {
+ "type": "integer"
+ },
+ "confidence": {
+ "type": "number"
+ },
+ "severity": {
+ "type": "string",
+ "enum": ["warning", "error"]
+ },
+ "enable-all-rules": {
+ "type": "boolean",
+ "default": false
+ },
+ "directives": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "name": {
+ "type": "string",
+ "enum": ["specify-disable-reason"]
+ },
+ "severity": {
+ "type": "string",
+ "enum": ["warning", "error"]
+ },
+ "exclude": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "arguments": {
+ "type": "array"
+ }
+ }
+ }
+ },
+ "rules": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["name"],
+ "properties": {
+ "name": {
+ "$ref": "#/definitions/revive-rules",
+ "title": "The rule name"
+ },
+ "disabled": {
+ "type": "boolean"
+ },
+ "severity": {
+ "type": "string",
+ "enum": ["warning", "error"]
+ },
+ "exclude": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "arguments": {
+ "type": "array"
+ }
+ }
+ }
+ }
+ }
+ },
+ "rowserrcheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "packages": {
+ "type": "array",
+ "items": {
+ "description": "",
+ "type": "string",
+ "examples": ["github.com/jmoiron/sqlx"]
+ }
+ }
+ }
+ },
+ "sloglintSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "kv-only": {
+ "description": "Enforce using key-value pairs only (incompatible with attr-only).",
+ "type": "boolean",
+ "default": false
+ },
+ "no-global": {
+ "description": "Enforce not using global loggers.",
+ "enum": ["", "all", "default"],
+ "default": ""
+ },
+ "no-mixed-args": {
+ "description": "Enforce not mixing key-value pairs and attributes.",
+ "type": "boolean",
+ "default": true
+ },
+ "context": {
+ "description": "Enforce using methods that accept a context.",
+ "enum": ["", "all", "scope"],
+ "default": ""
+ },
+ "static-msg": {
+ "description": "Enforce using static values for log messages.",
+ "type": "boolean",
+ "default": false
+ },
+ "msg-style": {
+ "description": "Enforce message style.",
+ "enum": ["", "lowercased", "capitalized"],
+ "default": ""
+ },
+ "key-naming-case": {
+ "description": "Enforce a single key naming convention.",
+ "enum": ["snake", "kebab", "camel", "pascal"]
+ },
+ "attr-only": {
+ "description": "Enforce using attributes only (incompatible with kv-only).",
+ "type": "boolean",
+ "default": false
+ },
+ "no-raw-keys": {
+ "description": "Enforce using constants instead of raw keys.",
+ "type": "boolean",
+ "default": false
+ },
+ "forbidden-keys": {
+ "description": "Enforce not using specific keys.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "args-on-sep-lines": {
+ "description": "Enforce putting arguments on separate lines.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "spancheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "checks": {
+ "description": "Checks to enable.",
+ "type": "array",
+ "items": {
+ "enum": ["end", "record-error", "set-status"]
+ }
+ },
+ "ignore-check-signatures": {
+ "description": "A list of regexes for function signatures that silence `record-error` and `set-status` reports if found in the call path to a returned error.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "extra-start-span-signatures": {
+ "description": "A list of regexes for additional function signatures that create spans.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "staticcheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "checks": {
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "$ref": "#/definitions/staticcheck-checks"
+ },
+ {
+ "type": "string"
+ }
+ ]
+ }
+ },
+ "dot-import-whitelist": {
+ "description": "By default, ST1001 forbids all uses of dot imports in non-test packages. This setting allows setting a whitelist of import paths that can be dot-imported anywhere.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "http-status-code-whitelist": {
+ "description": "ST1013 recommends using constants from the net/http package instead of hard-coding numeric HTTP status codes. This setting specifies a list of numeric status codes that this check does not complain about.",
+ "default": ["200", "400", "404", "500"],
+ "type": "array",
+ "items": {
+ "enum": [
+ "100",
+ "101",
+ "102",
+ "103",
+ "200",
+ "201",
+ "202",
+ "203",
+ "204",
+ "205",
+ "206",
+ "207",
+ "208",
+ "226",
+ "300",
+ "301",
+ "302",
+ "303",
+ "304",
+ "305",
+ "306",
+ "307",
+ "308",
+ "400",
+ "401",
+ "402",
+ "403",
+ "404",
+ "405",
+ "406",
+ "407",
+ "408",
+ "409",
+ "410",
+ "411",
+ "412",
+ "413",
+ "414",
+ "415",
+ "416",
+ "417",
+ "418",
+ "421",
+ "422",
+ "423",
+ "424",
+ "425",
+ "426",
+ "428",
+ "429",
+ "431",
+ "451",
+ "500",
+ "501",
+ "502",
+ "503",
+ "504",
+ "505",
+ "506",
+ "507",
+ "508",
+ "510",
+ "511"
+ ]
+ }
+ },
+ "initialisms": {
+ "description": "ST1003 check, among other things, for the correct capitalization of initialisms. The set of known initialisms can be configured with this option.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "default": [
+ "ACL",
+ "API",
+ "ASCII",
+ "CPU",
+ "CSS",
+ "DNS",
+ "EOF",
+ "GUID",
+ "HTML",
+ "HTTP",
+ "HTTPS",
+ "ID",
+ "IP",
+ "JSON",
+ "QPS",
+ "RAM",
+ "RPC",
+ "SLA",
+ "SMTP",
+ "SQL",
+ "SSH",
+ "TCP",
+ "TLS",
+ "TTL",
+ "UDP",
+ "UI",
+ "GID",
+ "UID",
+ "UUID",
+ "URI",
+ "URL",
+ "UTF8",
+ "VM",
+ "XML",
+ "XMPP",
+ "XSRF",
+ "XSS",
+ "SIP",
+ "RTP",
+ "AMQP",
+ "DB",
+ "TS"
+ ]
+ }
+ }
+ }
+ },
+ "tagalignSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "align": {
+ "description": "Align and sort can be used together or separately.",
+ "type": "boolean",
+ "default": true
+ },
+ "sort": {
+ "description": "Whether enable tags sort.",
+ "type": "boolean",
+ "default": true
+ },
+ "order": {
+ "description": "Specify the order of tags, the other tags will be sorted by name.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "default": [],
+ "examples": [
+ [
+ "json",
+ "yaml",
+ "yml",
+ "toml",
+ "mapstructure",
+ "binding",
+ "validate"
+ ]
+ ]
+ },
+ "strict": {
+ "description": "Whether enable strict style.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "tagliatelleSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "case": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "use-field-name": {
+ "description": "Use the struct field name to check the name of the struct tag.",
+ "type": "boolean",
+ "default": false
+ },
+ "ignored-fields": {
+ "description": "The field names to ignore.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["example"]
+ }
+ },
+ "rules": {
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "$ref": "#/definitions/tagliatelle-cases"
+ }
+ }
+ },
+ "extended-rules": {
+ "description": "Defines the association between tag name and case.",
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["case"],
+ "properties": {
+ "case": {
+ "$ref": "#/definitions/tagliatelle-cases"
+ },
+ "extra-initialisms": {
+ "type": "boolean",
+ "default": false
+ },
+ "initialism-overrides": {
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "overrides": {
+ "description": "Overrides the default/root configuration.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["pkg"],
+ "properties": {
+ "pkg": {
+ "description": "A package path.",
+ "type": "string"
+ },
+ "use-field-name": {
+ "description": "Use the struct field name to check the name of the struct tag.",
+ "type": "boolean",
+ "default": false
+ },
+ "ignored-fields": {
+ "description": "The field names to ignore.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["example"]
+ }
+ },
+ "ignore": {
+ "description": "Ignore the package (takes precedence over all other configurations).",
+ "type": "boolean",
+ "default": false
+ },
+ "rules": {
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "$ref": "#/definitions/tagliatelle-cases"
+ }
+ }
+ },
+ "extended-rules": {
+ "description": "Defines the association between tag name and case.",
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["case"],
+ "properties": {
+ "case": {
+ "$ref": "#/definitions/tagliatelle-cases"
+ },
+ "extra-initialisms": {
+ "type": "boolean",
+ "default": false
+ },
+ "initialism-overrides": {
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "testifylintSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "enable-all": {
+ "description": "Enable all checkers.",
+ "type": "boolean",
+ "default": false
+ },
+ "disable-all": {
+ "description": "Disable all checkers.",
+ "type": "boolean",
+ "default": false
+ },
+ "enable": {
+ "description": "Enable specific checkers.",
+ "type": "array",
+ "items": {
+ "enum": [
+ "blank-import",
+ "bool-compare",
+ "compares",
+ "contains",
+ "empty",
+ "encoded-compare",
+ "equal-values",
+ "error-is-as",
+ "error-nil",
+ "expected-actual",
+ "float-compare",
+ "formatter",
+ "go-require",
+ "len",
+ "negative-positive",
+ "nil-compare",
+ "regexp",
+ "require-error",
+ "suite-broken-parallel",
+ "suite-dont-use-pkg",
+ "suite-extra-assert-call",
+ "suite-method-signature",
+ "suite-subtest-run",
+ "suite-thelper",
+ "useless-assert"
+ ]
+ },
+ "default": [
+ "blank-import",
+ "bool-compare",
+ "compares",
+ "contains",
+ "empty",
+ "encoded-compare",
+ "equal-values",
+ "error-is-as",
+ "error-nil",
+ "expected-actual",
+ "float-compare",
+ "formatter",
+ "go-require",
+ "len",
+ "negative-positive",
+ "nil-compare",
+ "regexp",
+ "require-error",
+ "suite-broken-parallel",
+ "suite-dont-use-pkg",
+ "suite-extra-assert-call",
+ "suite-method-signature",
+ "suite-subtest-run",
+ "useless-assert"
+ ]
+ },
+ "disable": {
+ "description": "Disable specific checkers.",
+ "type": "array",
+ "items": {
+ "enum": [
+ "blank-import",
+ "bool-compare",
+ "compares",
+ "contains",
+ "empty",
+ "encoded-compare",
+ "equal-values",
+ "error-is-as",
+ "error-nil",
+ "expected-actual",
+ "float-compare",
+ "formatter",
+ "go-require",
+ "len",
+ "negative-positive",
+ "nil-compare",
+ "regexp",
+ "require-error",
+ "suite-broken-parallel",
+ "suite-dont-use-pkg",
+ "suite-extra-assert-call",
+ "suite-method-signature",
+ "suite-subtest-run",
+ "suite-thelper",
+ "useless-assert"
+ ],
+ "default": [
+ "suite-thelper"
+ ]
+ }
+ },
+ "bool-compare": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignore-custom-types": {
+ "description": "To ignore user defined types (over builtin bool).",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "expected-actual": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "pattern": {
+ "description": "Regexp for expected variable name.",
+ "type": "string",
+ "default": "(^(exp(ected)?|want(ed)?)([A-Z]\\w*)?$)|(^(\\w*[a-z])?(Exp(ected)?|Want(ed)?)$)"
+ }
+ }
+ },
+ "formatter": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-format-string": {
+ "description": "To enable go vet's printf checks.",
+ "type": "boolean",
+ "default": true
+ },
+ "require-f-funcs": {
+ "description": "To require f-assertions (e.g. assert.Equalf) if format string is used, even if there are no variable-length variables.",
+ "type": "boolean",
+ "default": false
+ },
+ "require-string-msg": {
+ "description": "To require that the first element of msgAndArgs (msg) has a string type.",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "go-require": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignore-http-handlers": {
+ "description": "To ignore HTTP handlers (like http.HandlerFunc).",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "require-error": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "fn-pattern": {
+ "description": "Regexp for assertions to analyze. If defined, then only matched error assertions will be reported.",
+ "type": "string",
+ "default": ""
+ }
+ }
+ },
+ "suite-extra-assert-call": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "mode": {
+ "description": "To require or remove extra Assert() call?",
+ "type": "string",
+ "enum": ["remove", "require"],
+ "default": "remove"
+ }
+ }
+ }
+ }
+ },
+ "testpackageSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skip-regexp": {
+ "description": "Files with names matching this regular expression are skipped.",
+ "type": "string",
+ "examples": ["(export|internal)_test\\.go"]
+ },
+ "allow-packages": {
+ "description": "List of packages that don't end with _test that tests are allowed to be in.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["example"]
+ }
+ }
+ }
+ },
+ "thelperSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "test": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "begin": {
+ "description": "Check if `t.Helper()` begins helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "first": {
+ "description": "Check if *testing.T is first param of helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "name": {
+ "description": "Check if *testing.T param has t name.",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ },
+ "benchmark": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "begin": {
+ "description": "Check if `b.Helper()` begins helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "first": {
+ "description": "Check if *testing.B is first param of helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "name": {
+ "description": "Check if *testing.B param has b name.",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ },
+ "tb": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "begin": {
+ "description": "Check if `tb.Helper()` begins helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "first": {
+ "description": "Check if *testing.TB is first param of helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "name": {
+ "description": "Check if *testing.TB param has tb name.",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ },
+ "fuzz": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "begin": {
+ "description": "Check if `f.Helper()` begins helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "first": {
+ "description": "Check if *testing.F is first param of helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "name": {
+ "description": "Check if *testing.F param has f name.",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ }
+ }
+ },
+ "usestdlibvarsSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "http-method": {
+ "description": "Suggest the use of http.MethodXX.",
+ "type": "boolean",
+ "default": true
+ },
+ "http-status-code": {
+ "description": "Suggest the use of http.StatusXX.",
+ "type": "boolean",
+ "default": true
+ },
+ "time-weekday": {
+ "description": "Suggest the use of time.Weekday.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "time-month": {
+ "description": "Suggest the use of time.Month.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "time-layout": {
+ "description": "Suggest the use of time.Layout.",
+ "type": "boolean",
+ "default": false
+ },
+ "time-date-month": {
+ "description": "Suggest the use of time.Month in time.Date.",
+ "type": "boolean",
+ "default": false
+ },
+ "crypto-hash": {
+ "description": "Suggest the use of crypto.Hash.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "default-rpc-path": {
+ "description": "Suggest the use of rpc.DefaultXXPath.",
+ "type": "boolean",
+ "default": false
+ },
+ "sql-isolation-level": {
+ "description": "Suggest the use of sql.LevelXX.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "tls-signature-scheme": {
+ "description": "Suggest the use of tls.SignatureScheme.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "constant-kind": {
+ "description": "Suggest the use of constant.Kind.String().",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "usetestingSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "context-background": {
+ "type": "boolean",
+ "default": false
+ },
+ "context-todo": {
+ "type": "boolean",
+ "default": false
+ },
+ "os-chdir": {
+ "type": "boolean",
+ "default": true
+ },
+ "os-mkdir-temp": {
+ "type": "boolean",
+ "default": true
+ },
+ "os-setenv": {
+ "type": "boolean",
+ "default": true
+ },
+ "os-create-temp": {
+ "type": "boolean",
+ "default": true
+ },
+ "os-temp-dir": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "unconvertSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "fast-math": {
+ "type": "boolean",
+ "default": false
+ },
+ "safe": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "unparamSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-exported": {
+ "description": "Inspect exported functions. Set to true if no external program/library imports your code.\n\nWARNING: if you enable this setting, unparam will report a lot of false-positives in text editors:\nif it's called for subdir of a project it can't find external interfaces. All text editor integrations\nwith golangci-lint call it on a directory with the changed file.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "unusedSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "field-writes-are-uses": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ },
+ "post-statements-are-reads": {
+ "description": "",
+ "type": "boolean",
+ "default": false
+ },
+ "exported-fields-are-used": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ },
+ "parameters-are-used": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ },
+ "local-variables-are-used": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ },
+ "generated-is-used": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "varnamelenSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-distance": {
+ "description": "Variables used in at most this N-many lines will be ignored.",
+ "type": "integer",
+ "default": 5
+ },
+ "min-name-length": {
+ "description": "The minimum length of a variable's name that is considered `long`.",
+ "type": "integer",
+ "default": 3
+ },
+ "check-receiver": {
+ "description": "Check method receiver names.",
+ "default": false,
+ "type": "boolean"
+ },
+ "check-return": {
+ "description": "Check named return values.",
+ "default": false,
+ "type": "boolean"
+ },
+ "check-type-param": {
+ "description": "Check type parameters.",
+ "default": false,
+ "type": "boolean"
+ },
+ "ignore-type-assert-ok": {
+ "description": "Ignore `ok` variables that hold the bool return value of a type assertion",
+ "default": false,
+ "type": "boolean"
+ },
+ "ignore-map-index-ok": {
+ "description": "Ignore `ok` variables that hold the bool return value of a map index.",
+ "default": false,
+ "type": "boolean"
+ },
+ "ignore-chan-recv-ok": {
+ "description": "Ignore `ok` variables that hold the bool return value of a channel receive.",
+ "default": false,
+ "type": "boolean"
+ },
+ "ignore-names": {
+ "description": "Optional list of variable names that should be ignored completely.",
+ "default": [[]],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignore-decls": {
+ "description": "Optional list of variable declarations that should be ignored completely.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "examples": [
+ ["c echo.Context", "t testing.T", "f *foo.Bar", "const C"]
+ ]
+ }
+ }
+ },
+ "whitespaceSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "multi-if": {
+ "description": "Enforces newlines (or comments) after every multi-line if statement",
+ "type": "boolean",
+ "default": false
+ },
+ "multi-func": {
+ "description": "Enforces newlines (or comments) after every multi-line function signature",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "wrapcheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "extra-ignore-sigs": {
+ "description": "An array of strings specifying additional substrings of signatures to ignore.",
+ "default": [
+ ".CustomError(",
+ ".SpecificWrap("
+ ],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignore-sigs": {
+ "description": "An array of strings which specify substrings of signatures to ignore.",
+ "default": [
+ ".Errorf(",
+ "errors.New(",
+ "errors.Unwrap(",
+ ".Wrap(",
+ ".Wrapf(",
+ ".WithMessage(",
+ ".WithMessagef(",
+ ".WithStack("
+ ],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignore-sig-regexps": {
+ "description": "An array of strings which specify regular expressions of signatures to ignore.",
+ "default": [""],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignore-package-globs": {
+ "description": "An array of glob patterns which, if any match the package of the function returning the error, will skip wrapcheck analysis for this error.",
+ "default": [""],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignore-interface-regexps": {
+ "description": "An array of glob patterns which, if matched to an underlying interface name, will ignore unwrapped errors returned from a function whose call is defined on the given interface.",
+ "default": [""],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "report-internal-errors": {
+ "description": "Determines whether wrapcheck should report errors returned from inside the package.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "wslSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "allow-assign-and-anything": {
+ "description": "Controls if you may cuddle assignments and anything without needing an empty line between them.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-assign-and-call": {
+ "description": "Allow calls and assignments to be cuddled as long as the lines have any matching variables, fields or types.",
+ "type": "boolean",
+ "default": true
+ },
+ "allow-cuddle-declarations": {
+ "description": "Allow declarations (var) to be cuddled.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-cuddle-with-calls": {
+ "description": "A list of call idents that everything can be cuddled with.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "allow-cuddle-with-rhs": {
+ "description": "AllowCuddleWithRHS is a list of right hand side variables that is allowed to be cuddled with anything.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "allow-cuddle-used-in-block": {
+ "description": "Allow cuddling with any block as long as the variable is used somewhere in the block",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-multiline-assign": {
+ "description": "Allow multiline assignments to be cuddled.",
+ "type": "boolean",
+ "default": true
+ },
+ "allow-separated-leading-comment": {
+ "description": "Allow leading comments to be separated with empty lines.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-trailing-comment": {
+ "description": "Allow trailing comments in ending of blocks.",
+ "type": "boolean",
+ "default": false
+ },
+ "error-variable-names": {
+ "description": "When force-err-cuddling is enabled this is a list of names used for error variables to check for in the conditional.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "force-case-trailing-whitespace": {
+ "description": "Force newlines in end of case at this limit (0 = never).",
+ "type": "integer",
+ "minimum": 0,
+ "default": 0
+ },
+ "force-err-cuddling": {
+ "description": "Causes an error when an If statement that checks an error variable doesn't cuddle with the assignment of that variable.",
+ "type": "boolean",
+ "default": false
+ },
+ "force-short-decl-cuddling": {
+ "description": "Causes an error if a short declaration (:=) cuddles with anything other than another short declaration.",
+ "type": "boolean",
+ "default": false
+ },
+ "strict-append": {
+ "description": "If true, append is only allowed to be cuddled if appending value is matching variables, fields or types on line above.",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "wslSettingsV5": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "allow-first-in-block": {
+ "type": "boolean",
+ "default": true
+ },
+ "allow-whole-block": {
+ "type": "boolean",
+ "default": false
+ },
+ "branch-max-lines": {
+ "type": "integer",
+ "default": 2
+ },
+ "case-max-lines": {
+ "type": "integer",
+ "default": 0
+ },
+ "default": {
+ "enum": ["all", "none", "default", ""],
+ "default": "default"
+ },
+ "enable": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/wsl-checks"
+ }
+ },
+ "disable": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/wsl-checks"
+ }
+ }
+ }
+ },
+ "copyloopvarSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-alias": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "customSettings": {
+ "description": "The custom section can be used to define linter plugins to be loaded at runtime. See README of golangci-lint for more information.\nEach custom linter should have a unique name.",
+ "type": "object",
+ "patternProperties": {
+ "^.*$": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "type": {
+ "description": "The plugin type.",
+ "enum": ["module", "goplugin"],
+ "default": "goplugin"
+ },
+ "path": {
+ "description": "The path to the plugin *.so. Can be absolute or local.",
+ "type": "string",
+ "examples": ["/path/to/example.so"]
+ },
+ "description": {
+ "description": "The description of the linter, for documentation purposes only.",
+ "type": "string"
+ },
+ "original-url": {
+ "description": "Intended to point to the repo location of the linter, for documentation purposes only.",
+ "type": "string"
+ },
+ "settings": {
+ "description": "Plugins settings/configuration. Only work with plugin based on `linterdb.PluginConstructor`.",
+ "type": "object"
+ }
+ },
+ "oneOf": [
+ {
+ "properties": {
+ "type": {"enum": ["module"] }
+ },
+ "required": ["type"]
+ },
+ {
+ "required": ["path"]
+ }
+ ]
+ }
+ }
+ }
+ }
+ }
+ },
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["version"],
+ "properties": {
+ "version": {
+ "type": "string",
+ "default": "2"
+ },
+ "run": {
+ "description": "Options for analysis running,",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "concurrency": {
+ "description": "Number of concurrent runners. Defaults to the number of available CPU cores.",
+ "type": "integer",
+ "minimum": 0,
+ "examples": [4]
+ },
+ "timeout": {
+ "description": "Timeout for the analysis.",
+ "type": "string",
+ "pattern": "^((\\d+h)?(\\d+m)?(\\d+(?:\\.\\d)?s)?|0)$",
+ "default": "1m",
+ "examples": ["30s", "5m", "5m30s"]
+ },
+ "issues-exit-code": {
+ "description": "Exit code when at least one issue was found.",
+ "type": "integer",
+ "default": 1
+ },
+ "tests": {
+ "description": "Enable inclusion of test files.",
+ "type": "boolean",
+ "default": true
+ },
+ "build-tags": {
+ "description": "List of build tags to pass to all linters.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "default": [],
+ "examples": [["mytag"]]
+ },
+ "modules-download-mode": {
+ "description": "Option to pass to \"go list -mod={option}\".\nSee \"go help modules\" for more information.",
+ "enum": ["mod", "readonly", "vendor"]
+ },
+ "allow-parallel-runners": {
+ "description": "Allow multiple parallel golangci-lint instances running. If disabled, golangci-lint acquires file lock on start.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-serial-runners": {
+ "description": "Allow multiple golangci-lint instances running, but serialize them around a lock.",
+ "type": "boolean",
+ "default": false
+ },
+ "go": {
+ "description": "Targeted Go version.",
+ "type": "string",
+ "default": "1.17"
+ },
+ "relative-path-mode": {
+ "description": "The mode used to evaluate relative paths.",
+ "type": "string",
+ "$ref": "#/definitions/relative-path-modes",
+ "default": "wd"
+ }
+ }
+ },
+ "output": {
+ "description": "Output configuration options.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "formats": {
+ "description": "Output formats to use.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "text": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "path": {
+ "$ref": "#/definitions/formats-path",
+ "default": "stdout"
+ },
+ "print-linter-name": {
+ "type": "boolean",
+ "default": true
+ },
+ "print-issued-lines": {
+ "type": "boolean",
+ "default": true
+ },
+ "colors": {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "json": {
+ "$ref": "#/definitions/simple-format"
+ },
+ "tab": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "path": {
+ "$ref": "#/definitions/formats-path",
+ "default": "stdout"
+ },
+ "print-linter-name": {
+ "type": "boolean",
+ "default": true
+ },
+ "colors": {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "html": {
+ "$ref": "#/definitions/simple-format"
+ },
+ "checkstyle": {
+ "$ref": "#/definitions/simple-format"
+ },
+ "code-climate": {
+ "$ref": "#/definitions/simple-format"
+ },
+ "junit-xml": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "path": {
+ "$ref": "#/definitions/formats-path",
+ "default": "stdout"
+ },
+ "extended": {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "teamcity": {
+ "$ref": "#/definitions/simple-format"
+ },
+ "sarif": {
+ "$ref": "#/definitions/simple-format"
+ }
+ }
+ },
+ "path-mode": {
+ "type": "string",
+ "default": "",
+ "examples": ["abs"]
+ },
+ "path-prefix": {
+ "description": "Add a prefix to the output file references.",
+ "type": "string",
+ "default": ""
+ },
+ "show-stats": {
+ "description": "Show statistics per linter.",
+ "type": "boolean",
+ "default": true
+ },
+ "sort-order": {
+ "type": "array",
+ "items": {
+ "enum": ["linter", "severity", "file"]
+ }
+ }
+ }
+ },
+ "linters": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "default": {
+ "enum": [
+ "standard",
+ "all",
+ "none",
+ "fast"
+ ]
+ },
+ "enable": {
+ "description": "List of enabled linters.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linter-names"
+ }
+ },
+ "disable": {
+ "description": "List of disabled linters.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linter-names"
+ }
+ },
+ "settings": {
+ "description": "All available settings of specific linters.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "dupword": {
+ "$ref": "#/definitions/settings/definitions/dupwordSettings"
+ },
+ "asasalint": {
+ "$ref": "#/definitions/settings/definitions/asasalintSettings"
+ },
+ "bidichk": {
+ "$ref": "#/definitions/settings/definitions/bidichkSettings"
+ },
+ "cyclop": {
+ "$ref": "#/definitions/settings/definitions/cyclopSettings"
+ },
+ "decorder": {
+ "$ref": "#/definitions/settings/definitions/decorderSettings"
+ },
+ "depguard":{
+ "$ref": "#/definitions/settings/definitions/depguardSettings"
+ },
+ "dogsled": {
+ "$ref": "#/definitions/settings/definitions/dogsledSettings"
+ },
+ "dupl": {
+ "$ref": "#/definitions/settings/definitions/duplSettings"
+ },
+ "embeddedstructfieldcheck": {
+ "$ref": "#/definitions/settings/definitions/embeddedstructfieldcheckSettings"
+ },
+ "errcheck": {
+ "$ref": "#/definitions/settings/definitions/errcheckSettings"
+ },
+ "errchkjson": {
+ "$ref": "#/definitions/settings/definitions/errchkjsonSettings"
+ },
+ "errorlint": {
+ "$ref": "#/definitions/settings/definitions/errorlintSettings"
+ },
+ "exhaustive": {
+ "$ref": "#/definitions/settings/definitions/exhaustiveSettings"
+ },
+ "exhaustruct": {
+ "$ref": "#/definitions/settings/definitions/exhaustructSettings"
+ },
+ "fatcontext": {
+ "$ref": "#/definitions/settings/definitions/fatcontextSettings"
+ },
+ "forbidigo": {
+ "$ref": "#/definitions/settings/definitions/forbidigoSettings"
+ },
+ "funcorder": {
+ "$ref": "#/definitions/settings/definitions/funcorderSettings"
+ },
+ "funlen": {
+ "$ref": "#/definitions/settings/definitions/funlenSettings"
+ },
+ "ginkgolinter": {
+ "$ref": "#/definitions/settings/definitions/ginkgolinterSettings"
+ },
+ "gochecksumtype": {
+ "$ref": "#/definitions/settings/definitions/gochecksumtypeSettings"
+ },
+ "gocognit": {
+ "$ref": "#/definitions/settings/definitions/gocognitSettings"
+ },
+ "goconst": {
+ "$ref": "#/definitions/settings/definitions/goconstSettings"
+ },
+ "gocritic": {
+ "$ref": "#/definitions/settings/definitions/gocriticSettings"
+ },
+ "gocyclo": {
+ "$ref": "#/definitions/settings/definitions/gocycloSettings"
+ },
+ "godot": {
+ "$ref": "#/definitions/settings/definitions/godotSettings"
+ },
+ "godox": {
+ "$ref": "#/definitions/settings/definitions/godoxSettings"
+ },
+ "interfacebloat":{
+ "$ref": "#/definitions/settings/definitions/interfacebloatSettings"
+ },
+ "goheader": {
+ "$ref": "#/definitions/settings/definitions/goheaderSettings"
+ },
+ "gomoddirectives": {
+ "$ref": "#/definitions/settings/definitions/gomoddirectivesSettings"
+ },
+ "gomodguard": {
+ "$ref": "#/definitions/settings/definitions/gomodguardSettings"
+ },
+ "gosec": {
+ "$ref": "#/definitions/settings/definitions/gosecSettings"
+ },
+ "gosmopolitan": {
+ "$ref": "#/definitions/settings/definitions/gosmopolitanSettings"
+ },
+ "govet": {
+ "$ref": "#/definitions/settings/definitions/govetSettings"
+ },
+ "grouper": {
+ "$ref": "#/definitions/settings/definitions/grouperSettings"
+ },
+ "iface": {
+ "$ref": "#/definitions/settings/definitions/ifaceSettings"
+ },
+ "importas": {
+ "$ref": "#/definitions/settings/definitions/importasSettings"
+ },
+ "inamedparam": {
+ "$ref": "#/definitions/settings/definitions/inamedparamSettings"
+ },
+ "ireturn": {
+ "$ref": "#/definitions/settings/definitions/ireturnSettings"
+ },
+ "lll": {
+ "$ref": "#/definitions/settings/definitions/lllSettings"
+ },
+ "maintidx": {
+ "$ref": "#/definitions/settings/definitions/maintidxSettings"
+ },
+ "makezero":{
+ "$ref": "#/definitions/settings/definitions/makezeroSettings"
+ },
+ "loggercheck": {
+ "$ref": "#/definitions/settings/definitions/loggercheckSettings"
+ },
+ "misspell": {
+ "$ref": "#/definitions/settings/definitions/misspellSettings"
+ },
+ "musttag": {
+ "$ref": "#/definitions/settings/definitions/musttagSettings"
+ },
+ "nakedret": {
+ "$ref": "#/definitions/settings/definitions/nakedretSettings"
+ },
+ "nestif": {
+ "$ref": "#/definitions/settings/definitions/nestifSettings"
+ },
+ "nilnil": {
+ "$ref": "#/definitions/settings/definitions/nilnilSettings"
+ },
+ "nlreturn": {
+ "$ref": "#/definitions/settings/definitions/nlreturnSettings"
+ },
+ "mnd": {
+ "$ref": "#/definitions/settings/definitions/mndSettings"
+ },
+ "nolintlint":{
+ "$ref": "#/definitions/settings/definitions/nolintlintSettings"
+ },
+ "reassign": {
+ "$ref": "#/definitions/settings/definitions/reassignSettings"
+ },
+ "recvcheck": {
+ "$ref": "#/definitions/settings/definitions/recvcheckSettings"
+ },
+ "nonamedreturns": {
+ "$ref": "#/definitions/settings/definitions/nonamedreturnsSettings"
+ },
+ "paralleltest": {
+ "$ref": "#/definitions/settings/definitions/paralleltestSettings"
+ },
+ "perfsprint": {
+ "$ref": "#/definitions/settings/definitions/perfsprintSettings"
+ },
+ "prealloc": {
+ "$ref": "#/definitions/settings/definitions/preallocSettings"
+ },
+ "predeclared": {
+ "$ref": "#/definitions/settings/definitions/predeclaredSettings"
+ },
+ "promlinter": {
+ "$ref": "#/definitions/settings/definitions/promlinterSettings"
+ },
+ "protogetter": {
+ "$ref": "#/definitions/settings/definitions/protogetterSettings"
+ },
+ "revive": {
+ "$ref": "#/definitions/settings/definitions/reviveSettings"
+ },
+ "rowserrcheck": {
+ "$ref": "#/definitions/settings/definitions/rowserrcheckSettings"
+ },
+ "sloglint": {
+ "$ref": "#/definitions/settings/definitions/sloglintSettings"
+ },
+ "spancheck": {
+ "$ref": "#/definitions/settings/definitions/spancheckSettings"
+ },
+ "staticcheck":{
+ "$ref": "#/definitions/settings/definitions/staticcheckSettings"
+ },
+ "tagalign": {
+ "$ref": "#/definitions/settings/definitions/tagalignSettings"
+ },
+ "tagliatelle": {
+ "$ref": "#/definitions/settings/definitions/tagliatelleSettings"
+ },
+ "testifylint": {
+ "$ref": "#/definitions/settings/definitions/testifylintSettings"
+ },
+ "testpackage": {
+ "$ref": "#/definitions/settings/definitions/testpackageSettings"
+ },
+ "thelper": {
+ "$ref": "#/definitions/settings/definitions/thelperSettings"
+ },
+ "usestdlibvars": {
+ "$ref": "#/definitions/settings/definitions/usestdlibvarsSettings"
+ },
+ "usetesting": {
+ "$ref": "#/definitions/settings/definitions/usetestingSettings"
+ },
+ "unconvert": {
+ "$ref": "#/definitions/settings/definitions/unconvertSettings"
+ },
+ "unparam": {
+ "$ref": "#/definitions/settings/definitions/unparamSettings"
+ },
+ "unused": {
+ "$ref": "#/definitions/settings/definitions/unusedSettings"
+ },
+ "varnamelen": {
+ "$ref": "#/definitions/settings/definitions/varnamelenSettings"
+ },
+ "whitespace": {
+ "$ref": "#/definitions/settings/definitions/whitespaceSettings"
+ },
+ "wrapcheck": {
+ "$ref": "#/definitions/settings/definitions/wrapcheckSettings"
+ },
+ "wsl": {
+ "$ref": "#/definitions/settings/definitions/wslSettings"
+ },
+ "wsl_v5": {
+ "$ref": "#/definitions/settings/definitions/wslSettingsV5"
+ },
+ "copyloopvar": {
+ "$ref": "#/definitions/settings/definitions/copyloopvarSettings"
+ },
+ "custom":{
+ "$ref": "#/definitions/settings/definitions/customSettings"
+ }
+ }
+ },
+ "exclusions":{
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "generated": {
+ "enum": ["strict", "lax", "disable"],
+ "default": "strict"
+ },
+ "warn-unused": {
+ "type": "boolean",
+ "default": false
+ },
+ "presets": {
+ "type": "array",
+ "items": {
+ "enum": [
+ "comments",
+ "std-error-handling",
+ "common-false-positives",
+ "legacy"
+ ]
+ }
+ },
+ "rules": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "path": {
+ "type": "string"
+ },
+ "path-except": {
+ "type": "string"
+ },
+ "linters": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linter-names"
+ }
+ },
+ "text": {
+ "type": "string"
+ },
+ "source": {
+ "type": "string"
+ }
+ },
+ "anyOf": [
+ { "required": ["path"] },
+ { "required": ["path-except"] },
+ { "required": ["linters"] },
+ { "required": ["text"] },
+ { "required": ["source"] }
+ ]
+ }
+ },
+ "paths": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "paths-except": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "formatters": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "enable": {
+ "description": "List of enabled formatters.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/formatter-names"
+ }
+ },
+ "settings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "gci": {
+ "$ref": "#/definitions/settings/definitions/gciSettings"
+ },
+ "gofmt": {
+ "$ref": "#/definitions/settings/definitions/gofmtSettings"
+ },
+ "gofumpt": {
+ "$ref": "#/definitions/settings/definitions/gofumptSettings"
+ },
+ "goimports": {
+ "$ref": "#/definitions/settings/definitions/goimportsSettings"
+ },
+ "golines": {
+ "$ref": "#/definitions/settings/definitions/golinesSettings"
+ }
+ }
+ },
+ "exclusions": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "generated": {
+ "enum": ["strict", "lax", "disable"],
+ "default": "strict"
+ },
+ "paths": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "warn-unused": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ }
+ }
+ },
+ "issues": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-issues-per-linter": {
+ "description": "Maximum issues count per one linter. Set to 0 to disable.",
+ "type": "integer",
+ "default": 50,
+ "minimum": 0
+ },
+ "max-same-issues": {
+ "description": "Maximum count of issues with the same text. Set to 0 to disable.",
+ "type": "integer",
+ "default": 3,
+ "minimum": 0
+ },
+ "new": {
+ "description": "Show only new issues: if there are unstaged changes or untracked files, only those changes are analyzed, else only changes in HEAD~ are analyzed.",
+ "type": "boolean",
+ "default": false
+ },
+ "new-from-merge-base": {
+ "description": "Show only new issues created after the best common ancestor (merge-base against HEAD).",
+ "type": "string"
+ },
+ "new-from-rev": {
+ "description": "Show only new issues created after this git revision.",
+ "type": "string"
+ },
+ "new-from-patch": {
+ "description": "Show only new issues created in git patch with this file path.",
+ "type": "string",
+ "examples": ["path/to/patch/file"]
+ },
+ "fix": {
+ "description": "Fix found issues (if it's supported by the linter).",
+ "type": "boolean",
+ "default": false
+ },
+ "uniq-by-line": {
+ "description": "Make issues output unique by line.",
+ "type": "boolean",
+ "default": true
+ },
+ "whole-files": {
+ "description": "Show issues in any part of update files (requires new-from-rev or new-from-patch).",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "severity": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "default": {
+ "description": "Set the default severity for issues. If severity rules are defined and the issues do not match or no severity is provided to the rule this will be the default severity applied. Severities should match the supported severity names of the selected out format.",
+ "type": "string",
+ "default": ""
+ },
+ "rules": {
+ "description": "When a list of severity rules are provided, severity information will be added to lint issues. Severity rules have the same filtering capability as exclude rules except you are allowed to specify one matcher per severity rule.\nOnly affects out formats that support setting severity information.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "severity": {
+ "type": "string"
+ },
+ "path": {
+ "type": "string"
+ },
+ "path-except": {
+ "type": "string"
+ },
+ "linters": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linter-names"
+ }
+ },
+ "text": {
+ "type": "string"
+ },
+ "source": {
+ "type": "string"
+ }
+ },
+ "required": ["severity"],
+ "anyOf": [
+ { "required": ["path"] },
+ { "required": ["path-except"] },
+ { "required": ["linters"] },
+ { "required": ["text"] },
+ { "required": ["source"] }
+ ]
+ },
+ "default": []
+ }
+ },
+ "required": ["default"]
+ }
+ }
+}
diff --git a/vendor/github.com/golangci/golangci-lint/v2/jsonschema/golangci.v2.5.jsonschema.json b/vendor/github.com/golangci/golangci-lint/v2/jsonschema/golangci.v2.5.jsonschema.json
new file mode 100644
index 000000000..f471fd3da
--- /dev/null
+++ b/vendor/github.com/golangci/golangci-lint/v2/jsonschema/golangci.v2.5.jsonschema.json
@@ -0,0 +1,5081 @@
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "$id": "https://json.schemastore.org/golangci-lint.json",
+ "definitions": {
+ "gocritic-checks": {
+ "enum": [
+ "appendAssign",
+ "appendCombine",
+ "argOrder",
+ "assignOp",
+ "badCall",
+ "badCond",
+ "badLock",
+ "badRegexp",
+ "badSorting",
+ "badSyncOnceFunc",
+ "boolExprSimplify",
+ "builtinShadow",
+ "builtinShadowDecl",
+ "captLocal",
+ "caseOrder",
+ "codegenComment",
+ "commentFormatting",
+ "commentedOutCode",
+ "commentedOutImport",
+ "defaultCaseOrder",
+ "deferInLoop",
+ "deferUnlambda",
+ "deprecatedComment",
+ "docStub",
+ "dupArg",
+ "dupBranchBody",
+ "dupCase",
+ "dupImport",
+ "dupSubExpr",
+ "dynamicFmtString",
+ "elseif",
+ "emptyDecl",
+ "emptyFallthrough",
+ "emptyStringTest",
+ "equalFold",
+ "evalOrder",
+ "exitAfterDefer",
+ "exposedSyncMutex",
+ "externalErrorReassign",
+ "filepathJoin",
+ "flagDeref",
+ "flagName",
+ "hexLiteral",
+ "httpNoBody",
+ "hugeParam",
+ "ifElseChain",
+ "importShadow",
+ "indexAlloc",
+ "initClause",
+ "ioutilDeprecated",
+ "mapKey",
+ "methodExprCall",
+ "nestingReduce",
+ "newDeref",
+ "nilValReturn",
+ "octalLiteral",
+ "offBy1",
+ "paramTypeCombine",
+ "preferDecodeRune",
+ "preferFilepathJoin",
+ "preferFprint",
+ "preferStringWriter",
+ "preferWriteByte",
+ "ptrToRefParam",
+ "rangeAppendAll",
+ "rangeExprCopy",
+ "rangeValCopy",
+ "redundantSprint",
+ "regexpMust",
+ "regexpPattern",
+ "regexpSimplify",
+ "returnAfterHttpError",
+ "ruleguard",
+ "singleCaseSwitch",
+ "sliceClear",
+ "sloppyLen",
+ "sloppyReassign",
+ "sloppyTypeAssert",
+ "sortSlice",
+ "sprintfQuotedString",
+ "sqlQuery",
+ "stringConcatSimplify",
+ "stringXbytes",
+ "stringsCompare",
+ "switchTrue",
+ "syncMapLoadAndDelete",
+ "timeExprSimplify",
+ "todoCommentWithoutDetail",
+ "tooManyResultsChecker",
+ "truncateCmp",
+ "typeAssertChain",
+ "typeDefFirst",
+ "typeSwitchVar",
+ "typeUnparen",
+ "uncheckedInlineErr",
+ "underef",
+ "unlabelStmt",
+ "unlambda",
+ "unnamedResult",
+ "unnecessaryBlock",
+ "unnecessaryDefer",
+ "unslice",
+ "valSwap",
+ "weakCond",
+ "whyNoLint",
+ "wrapperFunc",
+ "yodaStyleExpr"
+ ]
+ },
+ "gocritic-tags": {
+ "enum": [
+ "diagnostic",
+ "style",
+ "performance",
+ "experimental",
+ "opinionated",
+ "security"
+ ]
+ },
+ "staticcheck-checks": {
+ "enum": [
+ "*",
+ "all",
+ "SA*",
+ "-SA*",
+ "SA1*",
+ "-SA1*",
+ "SA1000",
+ "-SA1000",
+ "SA1001",
+ "-SA1001",
+ "SA1002",
+ "-SA1002",
+ "SA1003",
+ "-SA1003",
+ "SA1004",
+ "-SA1004",
+ "SA1005",
+ "-SA1005",
+ "SA1006",
+ "-SA1006",
+ "SA1007",
+ "-SA1007",
+ "SA1008",
+ "-SA1008",
+ "SA1010",
+ "-SA1010",
+ "SA1011",
+ "-SA1011",
+ "SA1012",
+ "-SA1012",
+ "SA1013",
+ "-SA1013",
+ "SA1014",
+ "-SA1014",
+ "SA1015",
+ "-SA1015",
+ "SA1016",
+ "-SA1016",
+ "SA1017",
+ "-SA1017",
+ "SA1018",
+ "-SA1018",
+ "SA1019",
+ "-SA1019",
+ "SA1020",
+ "-SA1020",
+ "SA1021",
+ "-SA1021",
+ "SA1023",
+ "-SA1023",
+ "SA1024",
+ "-SA1024",
+ "SA1025",
+ "-SA1025",
+ "SA1026",
+ "-SA1026",
+ "SA1027",
+ "-SA1027",
+ "SA1028",
+ "-SA1028",
+ "SA1029",
+ "-SA1029",
+ "SA1030",
+ "-SA1030",
+ "SA1031",
+ "-SA1031",
+ "SA1032",
+ "-SA1032",
+ "SA2*",
+ "-SA2*",
+ "SA2000",
+ "-SA2000",
+ "SA2001",
+ "-SA2001",
+ "SA2002",
+ "-SA2002",
+ "SA2003",
+ "-SA2003",
+ "SA3*",
+ "-SA3*",
+ "SA3000",
+ "-SA3000",
+ "SA3001",
+ "-SA3001",
+ "SA4*",
+ "-SA4*",
+ "SA4000",
+ "-SA4000",
+ "SA4001",
+ "-SA4001",
+ "SA4003",
+ "-SA4003",
+ "SA4004",
+ "-SA4004",
+ "SA4005",
+ "-SA4005",
+ "SA4006",
+ "-SA4006",
+ "SA4008",
+ "-SA4008",
+ "SA4009",
+ "-SA4009",
+ "SA4010",
+ "-SA4010",
+ "SA4011",
+ "-SA4011",
+ "SA4012",
+ "-SA4012",
+ "SA4013",
+ "-SA4013",
+ "SA4014",
+ "-SA4014",
+ "SA4015",
+ "-SA4015",
+ "SA4016",
+ "-SA4016",
+ "SA4017",
+ "-SA4017",
+ "SA4018",
+ "-SA4018",
+ "SA4019",
+ "-SA4019",
+ "SA4020",
+ "-SA4020",
+ "SA4021",
+ "-SA4021",
+ "SA4022",
+ "-SA4022",
+ "SA4023",
+ "-SA4023",
+ "SA4024",
+ "-SA4024",
+ "SA4025",
+ "-SA4025",
+ "SA4026",
+ "-SA4026",
+ "SA4027",
+ "-SA4027",
+ "SA4028",
+ "-SA4028",
+ "SA4029",
+ "-SA4029",
+ "SA4030",
+ "-SA4030",
+ "SA4031",
+ "-SA4031",
+ "SA4032",
+ "-SA4032",
+ "SA5*",
+ "-SA5*",
+ "SA5000",
+ "-SA5000",
+ "SA5001",
+ "-SA5001",
+ "SA5002",
+ "-SA5002",
+ "SA5003",
+ "-SA5003",
+ "SA5004",
+ "-SA5004",
+ "SA5005",
+ "-SA5005",
+ "SA5007",
+ "-SA5007",
+ "SA5008",
+ "-SA5008",
+ "SA5009",
+ "-SA5009",
+ "SA5010",
+ "-SA5010",
+ "SA5011",
+ "-SA5011",
+ "SA5012",
+ "-SA5012",
+ "SA6*",
+ "-SA6*",
+ "SA6000",
+ "-SA6000",
+ "SA6001",
+ "-SA6001",
+ "SA6002",
+ "-SA6002",
+ "SA6003",
+ "-SA6003",
+ "SA6005",
+ "-SA6005",
+ "SA6006",
+ "-SA6006",
+ "SA9*",
+ "-SA9*",
+ "SA9001",
+ "-SA9001",
+ "SA9002",
+ "-SA9002",
+ "SA9003",
+ "-SA9003",
+ "SA9004",
+ "-SA9004",
+ "SA9005",
+ "-SA9005",
+ "SA9006",
+ "-SA9006",
+ "SA9007",
+ "-SA9007",
+ "SA9008",
+ "-SA9008",
+ "SA9009",
+ "-SA9009",
+ "ST*",
+ "-ST*",
+ "ST1*",
+ "-ST1*",
+ "ST1000",
+ "-ST1000",
+ "ST1001",
+ "-ST1001",
+ "ST1003",
+ "-ST1003",
+ "ST1005",
+ "-ST1005",
+ "ST1006",
+ "-ST1006",
+ "ST1008",
+ "-ST1008",
+ "ST1011",
+ "-ST1011",
+ "ST1012",
+ "-ST1012",
+ "ST1013",
+ "-ST1013",
+ "ST1015",
+ "-ST1015",
+ "ST1016",
+ "-ST1016",
+ "ST1017",
+ "-ST1017",
+ "ST1018",
+ "-ST1018",
+ "ST1019",
+ "-ST1019",
+ "ST1020",
+ "-ST1020",
+ "ST1021",
+ "-ST1021",
+ "ST1022",
+ "-ST1022",
+ "ST1023",
+ "-ST1023",
+ "S*",
+ "-S*",
+ "S1*",
+ "-S1*",
+ "S1000",
+ "-S1000",
+ "S1001",
+ "-S1001",
+ "S1002",
+ "-S1002",
+ "S1003",
+ "-S1003",
+ "S1004",
+ "-S1004",
+ "S1005",
+ "-S1005",
+ "S1006",
+ "-S1006",
+ "S1007",
+ "-S1007",
+ "S1008",
+ "-S1008",
+ "S1009",
+ "-S1009",
+ "S1010",
+ "-S1010",
+ "S1011",
+ "-S1011",
+ "S1012",
+ "-S1012",
+ "S1016",
+ "-S1016",
+ "S1017",
+ "-S1017",
+ "S1018",
+ "-S1018",
+ "S1019",
+ "-S1019",
+ "S1020",
+ "-S1020",
+ "S1021",
+ "-S1021",
+ "S1023",
+ "-S1023",
+ "S1024",
+ "-S1024",
+ "S1025",
+ "-S1025",
+ "S1028",
+ "-S1028",
+ "S1029",
+ "-S1029",
+ "S1030",
+ "-S1030",
+ "S1031",
+ "-S1031",
+ "S1032",
+ "-S1032",
+ "S1033",
+ "-S1033",
+ "S1034",
+ "-S1034",
+ "S1035",
+ "-S1035",
+ "S1036",
+ "-S1036",
+ "S1037",
+ "-S1037",
+ "S1038",
+ "-S1038",
+ "S1039",
+ "-S1039",
+ "S1040",
+ "-S1040",
+ "QF*",
+ "-QF*",
+ "QF1*",
+ "-QF1*",
+ "QF1001",
+ "-QF1001",
+ "QF1002",
+ "-QF1002",
+ "QF1003",
+ "-QF1003",
+ "QF1004",
+ "-QF1004",
+ "QF1005",
+ "-QF1005",
+ "QF1006",
+ "-QF1006",
+ "QF1007",
+ "-QF1007",
+ "QF1008",
+ "-QF1008",
+ "QF1009",
+ "-QF1009",
+ "QF1010",
+ "-QF1010",
+ "QF1011",
+ "-QF1011",
+ "QF1012",
+ "-QF1012"
+ ]
+ },
+ "godoclint-rules": {
+ "enum": [
+ "pkg-doc",
+ "single-pkg-doc",
+ "require-pkg-doc",
+ "start-with-name",
+ "require-doc",
+ "deprecated",
+ "max-len",
+ "no-unused-link"
+ ]
+ },
+ "gosec-rules": {
+ "enum": [
+ "G101",
+ "G102",
+ "G103",
+ "G104",
+ "G106",
+ "G107",
+ "G108",
+ "G109",
+ "G110",
+ "G111",
+ "G112",
+ "G114",
+ "G115",
+ "G201",
+ "G202",
+ "G203",
+ "G204",
+ "G301",
+ "G302",
+ "G303",
+ "G304",
+ "G305",
+ "G306",
+ "G307",
+ "G401",
+ "G402",
+ "G403",
+ "G404",
+ "G405",
+ "G406",
+ "G501",
+ "G502",
+ "G503",
+ "G504",
+ "G505",
+ "G506",
+ "G507",
+ "G601",
+ "G602"
+ ]
+ },
+ "govet-analyzers": {
+ "enum": [
+ "appends",
+ "asmdecl",
+ "assign",
+ "atomic",
+ "atomicalign",
+ "bools",
+ "buildtag",
+ "cgocall",
+ "composites",
+ "copylocks",
+ "deepequalerrors",
+ "defers",
+ "directive",
+ "errorsas",
+ "fieldalignment",
+ "findcall",
+ "framepointer",
+ "hostport",
+ "httpmux",
+ "httpresponse",
+ "ifaceassert",
+ "loopclosure",
+ "lostcancel",
+ "nilfunc",
+ "nilness",
+ "printf",
+ "reflectvaluecompare",
+ "shadow",
+ "shift",
+ "sigchanyzer",
+ "slog",
+ "sortslice",
+ "stdmethods",
+ "stdversion",
+ "stringintconv",
+ "structtag",
+ "testinggoroutine",
+ "tests",
+ "timeformat",
+ "unmarshal",
+ "unreachable",
+ "unsafeptr",
+ "unusedresult",
+ "unusedwrite",
+ "waitgroup"
+ ]
+ },
+ "revive-rules": {
+ "enum": [
+ "add-constant",
+ "argument-limit",
+ "atomic",
+ "banned-characters",
+ "bare-return",
+ "blank-imports",
+ "bool-literal-in-expr",
+ "call-to-gc",
+ "cognitive-complexity",
+ "comment-spacings",
+ "comments-density",
+ "confusing-naming",
+ "confusing-results",
+ "constant-logical-expr",
+ "context-as-argument",
+ "context-keys-type",
+ "cyclomatic",
+ "datarace",
+ "deep-exit",
+ "defer",
+ "dot-imports",
+ "duplicated-imports",
+ "early-return",
+ "empty-block",
+ "empty-lines",
+ "enforce-map-style",
+ "enforce-repeated-arg-type-style",
+ "enforce-slice-style",
+ "enforce-switch-style",
+ "error-naming",
+ "error-return",
+ "error-strings",
+ "errorf",
+ "exported",
+ "file-header",
+ "file-length-limit",
+ "filename-format",
+ "flag-parameter",
+ "function-length",
+ "function-result-limit",
+ "get-return",
+ "identical-branches",
+ "identical-ifelseif-branches",
+ "identical-ifelseif-conditions",
+ "identical-switch-branches",
+ "identical-switch-conditions",
+ "if-return",
+ "import-alias-naming",
+ "import-shadowing",
+ "imports-blocklist",
+ "increment-decrement",
+ "indent-error-flow",
+ "line-length-limit",
+ "max-control-nesting",
+ "max-public-structs",
+ "modifies-parameter",
+ "modifies-value-receiver",
+ "nested-structs",
+ "optimize-operands-order",
+ "package-comments",
+ "package-directory-mismatch",
+ "range-val-address",
+ "range-val-in-closure",
+ "range",
+ "receiver-naming",
+ "redefines-builtin-id",
+ "redundant-build-tag",
+ "redundant-import-alias",
+ "redundant-test-main-exit",
+ "string-format",
+ "string-of-int",
+ "struct-tag",
+ "superfluous-else",
+ "time-date",
+ "time-equal",
+ "time-naming",
+ "unchecked-type-assertion",
+ "unconditional-recursion",
+ "unexported-naming",
+ "unexported-return",
+ "unhandled-error",
+ "unnecessary-format",
+ "unnecessary-stmt",
+ "unreachable-code",
+ "unsecure-url-scheme",
+ "unused-parameter",
+ "unused-receiver",
+ "use-any",
+ "use-errors-new",
+ "use-fmt-print",
+ "use-waitgroup-go",
+ "useless-break",
+ "useless-fallthrough",
+ "var-declaration",
+ "var-naming",
+ "waitgroup-by-value"
+ ]
+ },
+ "iface-analyzers": {
+ "enum": [
+ "identical",
+ "unused",
+ "opaque",
+ "unexported"
+ ]
+ },
+ "tagliatelle-cases": {
+ "enum": [
+ "",
+ "camel",
+ "pascal",
+ "kebab",
+ "snake",
+ "goCamel",
+ "goPascal",
+ "goKebab",
+ "goSnake",
+ "upper",
+ "upperSnake",
+ "lower",
+ "header"
+ ]
+ },
+ "wsl-checks": {
+ "enum": [
+ "assign",
+ "branch",
+ "decl",
+ "defer",
+ "expr",
+ "for",
+ "go",
+ "if",
+ "inc-dec",
+ "label",
+ "range",
+ "return",
+ "select",
+ "send",
+ "switch",
+ "type-switch",
+ "append",
+ "assign-exclusive",
+ "assign-expr",
+ "err",
+ "leading-whitespace",
+ "trailing-whitespace"
+ ]
+ },
+ "relative-path-modes": {
+ "enum": [
+ "gomod",
+ "gitroot",
+ "cfg",
+ "wd"
+ ]
+ },
+ "simple-format": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "path": {
+ "$ref": "#/definitions/formats-path",
+ "default": "stdout"
+ }
+ }
+ },
+ "formats-path" : {
+ "anyOf": [
+ {
+ "enum": [
+ "stdout",
+ "stderr"
+ ]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ },
+ "linter-names": {
+ "$comment": "anyOf with enum is used to allow auto-completion of non-custom linters",
+ "description": "Usable linter names.",
+ "anyOf": [
+ {
+ "enum": [
+ "arangolint",
+ "asasalint",
+ "asciicheck",
+ "bidichk",
+ "bodyclose",
+ "canonicalheader",
+ "containedctx",
+ "contextcheck",
+ "copyloopvar",
+ "cyclop",
+ "decorder",
+ "depguard",
+ "dogsled",
+ "dupl",
+ "dupword",
+ "durationcheck",
+ "embeddedstructfieldcheck",
+ "errcheck",
+ "errchkjson",
+ "errname",
+ "errorlint",
+ "exhaustive",
+ "exhaustruct",
+ "exptostd",
+ "fatcontext",
+ "forbidigo",
+ "forcetypeassert",
+ "funcorder",
+ "funlen",
+ "ginkgolinter",
+ "gocheckcompilerdirectives",
+ "gochecknoglobals",
+ "gochecknoinits",
+ "gochecksumtype",
+ "gocognit",
+ "goconst",
+ "gocritic",
+ "gocyclo",
+ "godoclint",
+ "godot",
+ "godox",
+ "err113",
+ "goheader",
+ "gomoddirectives",
+ "gomodguard",
+ "goprintffuncname",
+ "gosec",
+ "gosimple",
+ "gosmopolitan",
+ "govet",
+ "grouper",
+ "iface",
+ "importas",
+ "inamedparam",
+ "ineffassign",
+ "interfacebloat",
+ "intrange",
+ "iotamixing",
+ "ireturn",
+ "lll",
+ "loggercheck",
+ "maintidx",
+ "makezero",
+ "mirror",
+ "misspell",
+ "mnd",
+ "musttag",
+ "nakedret",
+ "nestif",
+ "nilerr",
+ "nilnesserr",
+ "nilnil",
+ "nlreturn",
+ "noctx",
+ "noinlineerr",
+ "nolintlint",
+ "nonamedreturns",
+ "nosprintfhostport",
+ "paralleltest",
+ "perfsprint",
+ "prealloc",
+ "predeclared",
+ "promlinter",
+ "protogetter",
+ "reassign",
+ "recvcheck",
+ "revive",
+ "rowserrcheck",
+ "sloglint",
+ "sqlclosecheck",
+ "staticcheck",
+ "stylecheck",
+ "tagalign",
+ "tagliatelle",
+ "testableexamples",
+ "testifylint",
+ "testpackage",
+ "thelper",
+ "tparallel",
+ "unconvert",
+ "unparam",
+ "unused",
+ "usestdlibvars",
+ "usetesting",
+ "varnamelen",
+ "wastedassign",
+ "whitespace",
+ "wrapcheck",
+ "wsl",
+ "wsl_v5",
+ "zerologlint"
+ ]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ },
+ "formatter-names": {
+ "description": "Usable formatter names.",
+ "enum": [
+ "gci",
+ "gofmt",
+ "gofumpt",
+ "goimports",
+ "golines",
+ "swaggo"
+ ]
+ },
+ "settings": {
+ "definitions": {
+ "dupwordSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "keywords": {
+ "description": "Keywords for detecting duplicate words. If this list is not empty, only the words defined in this list will be detected.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["the", "and", "a"]
+ }
+ },
+ "ignore": {
+ "description": "Keywords used to ignore detection.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["0C0C"]
+ }
+ }
+ }
+ },
+ "asasalintSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "exclude": {
+ "description": "To specify a set of function names to exclude.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["\\.Wrapf"]
+ }
+ },
+ "use-builtin-exclusions": {
+ "description": "To enable/disable the asasalint builtin exclusions of function names.",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "bidichkSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "left-to-right-embedding": {
+ "description": "Disallow: LEFT-TO-RIGHT-EMBEDDING",
+ "type": "boolean",
+ "default": false
+ },
+ "right-to-left-embedding": {
+ "description": "Disallow: RIGHT-TO-LEFT-EMBEDDING",
+ "type": "boolean",
+ "default": false
+ },
+ "pop-directional-formatting": {
+ "description": "Disallow: POP-DIRECTIONAL-FORMATTING",
+ "type": "boolean",
+ "default": false
+ },
+ "left-to-right-override": {
+ "description": "Disallow: LEFT-TO-RIGHT-OVERRIDE",
+ "type": "boolean",
+ "default": false
+ },
+ "right-to-left-override": {
+ "description": "Disallow: RIGHT-TO-LEFT-OVERRIDE",
+ "type": "boolean",
+ "default": false
+ },
+ "left-to-right-isolate": {
+ "description": "Disallow: LEFT-TO-RIGHT-ISOLATE",
+ "type": "boolean",
+ "default": false
+ },
+ "right-to-left-isolate": {
+ "description": "Disallow: RIGHT-TO-LEFT-ISOLATE",
+ "type": "boolean",
+ "default": false
+ },
+ "first-strong-isolate": {
+ "description": "Disallow: FIRST-STRONG-ISOLATE",
+ "type": "boolean",
+ "default": false
+ },
+ "pop-directional-isolate": {
+ "description": "Disallow: POP-DIRECTIONAL-ISOLATE",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "cyclopSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-complexity": {
+ "description": "Max complexity the function can have",
+ "type": "integer",
+ "default": 10,
+ "minimum": 0
+ },
+ "package-average": {
+ "description": "Max average complexity in package",
+ "type": "number",
+ "default": 0,
+ "minimum": 0
+ }
+ }
+ },
+ "decorderSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "dec-order": {
+ "type": "array",
+ "default": [["type", "const", "var", "func"]],
+ "items": {
+ "enum": ["type", "const", "var", "func"]
+ }
+ },
+ "ignore-underscore-vars": {
+ "description": "Underscore vars (vars with \"_\" as the name) will be ignored at all checks",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-dec-order-check": {
+ "description": "Order of declarations is not checked",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-init-func-first-check": {
+ "description": "Allow init func to be anywhere in file",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-dec-num-check": {
+ "description": "Multiple global type, const and var declarations are allowed",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-type-dec-num-check": {
+ "description": "Type declarations will be ignored for dec num check",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-const-dec-num-check": {
+ "description": "Const declarations will be ignored for dec num check",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-var-dec-num-check": {
+ "description": "Var declarations will be ignored for dec num check",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ },
+ "depguardSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "rules": {
+ "description": "Rules to apply.",
+ "type": "object",
+ "additionalProperties": false,
+ "patternProperties": {
+ "^[^.]+$": {
+ "description": "Name of a rule.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "list-mode": {
+ "description": "Used to determine the package matching priority.",
+ "enum": ["original", "strict", "lax"],
+ "default": "original"
+ },
+ "files": {
+ "description": "List of file globs that will match this list of settings to compare against.",
+ "additionalProperties": false,
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "allow": {
+ "description": "List of allowed packages.",
+ "additionalProperties": false,
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "deny": {
+ "description": "Packages that are not allowed where the value is a suggestion.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "desc": {
+ "description": "Description",
+ "type": "string"
+ },
+ "pkg": {
+ "description": "Package",
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "dogsledSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-blank-identifiers": {
+ "description": "Check assignments with too many blank identifiers.",
+ "type": "integer",
+ "default": 2,
+ "minimum": 0
+ }
+ }
+ },
+ "duplSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "threshold": {
+ "description": "Tokens count to trigger issue.",
+ "type": "integer",
+ "default": 150,
+ "minimum": 0
+ }
+ }
+ },
+ "embeddedstructfieldcheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "empty-line": {
+ "description": "Checks that there is an empty space between the embedded fields and regular fields.",
+ "type": "boolean",
+ "default": false
+ },
+ "forbid-mutex": {
+ "description": "Checks that sync.Mutex and sync.RWMutex are not used as embedded fields.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "errcheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-type-assertions": {
+ "description": "Report about not checking errors in type assertions, i.e.: `a := b.(MyStruct)`",
+ "type": "boolean",
+ "default": false
+ },
+ "check-blank": {
+ "description": "Report about assignment of errors to blank identifier",
+ "type": "boolean",
+ "default": false
+ },
+ "exclude-functions": {
+ "description": "List of functions to exclude from checking, where each entry is a single function to exclude",
+ "type": "array",
+ "examples": ["io/ioutil.ReadFile", "io.Copy(*bytes.Buffer)"],
+ "items": {
+ "type": "string"
+ }
+ },
+ "disable-default-exclusions": {
+ "description": "To disable the errcheck built-in exclude list",
+ "type": "boolean",
+ "default": false
+ },
+ "verbose": {
+ "description": "Display function signature instead of selector",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "errchkjsonSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-error-free-encoding": {
+ "type": "boolean",
+ "default": false
+ },
+ "report-no-exported": {
+ "description": "Issue on struct that doesn't have exported fields.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "errorlintSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "errorf": {
+ "description": "Check whether fmt.Errorf uses the %w verb for formatting errors",
+ "type": "boolean",
+ "default": true
+ },
+ "errorf-multi": {
+ "description": "Permit more than 1 %w verb, valid per Go 1.20",
+ "type": "boolean",
+ "default": true
+ },
+ "asserts": {
+ "description": "Check for plain type assertions and type switches.",
+ "type": "boolean",
+ "default": true
+ },
+ "comparison": {
+ "description": "Check for plain error comparisons",
+ "type": "boolean",
+ "default": true
+ },
+ "allowed-errors": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "err": {
+ "type": "string"
+ },
+ "fun": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "allowed-errors-wildcard": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "err": {
+ "type": "string"
+ },
+ "fun": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "exhaustiveSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check": {
+ "description": "Program elements to check for exhaustiveness.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["switch", "map"]
+ }
+ },
+ "explicit-exhaustive-switch": {
+ "description": "Only run exhaustive check on switches with \"//exhaustive:enforce\" comment.",
+ "type": "boolean",
+ "default": false
+ },
+ "explicit-exhaustive-map": {
+ "description": "Only run exhaustive check on map literals with \"//exhaustive:enforce\" comment.",
+ "type": "boolean",
+ "default": false
+ },
+ "default-case-required": {
+ "description": "Switch statement requires default case even if exhaustive.",
+ "type": "boolean",
+ "default": false
+ },
+ "default-signifies-exhaustive": {
+ "description": "Presence of `default` case in switch statements satisfies exhaustiveness, even if all enum members are not listed.",
+ "type": "boolean",
+ "default": false
+ },
+ "ignore-enum-members": {
+ "description": "Enum members matching `regex` do not have to be listed in switch statements to satisfy exhaustiveness",
+ "type": "string"
+ },
+ "ignore-enum-types": {
+ "description": "Enum types matching the supplied regex do not have to be listed in switch statements to satisfy exhaustiveness.",
+ "type": "string"
+ },
+ "package-scope-only": {
+ "description": "Consider enums only in package scopes, not in inner scopes.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "exhaustructSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "include": {
+ "description": "List of regular expressions to match struct packages and names.",
+ "type": "array",
+ "examples": [".*\\.Test"],
+ "items": {
+ "type": "string"
+ }
+ },
+ "exclude": {
+ "description": "List of regular expressions to exclude struct packages and names from check.",
+ "type": "array",
+ "examples": ["cobra\\.Command$"],
+ "items": {
+ "type": "string"
+ }
+ },
+ "allow-empty": {
+ "description": "Allows empty structures, effectively excluding them from the check.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-empty-rx": {
+ "description": "List of regular expressions to match type names that should be allowed to be empty.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "allow-empty-returns": {
+ "description": "Allows empty structures in return statements.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-empty-declarations": {
+ "description": "Allows empty structures in variable declarations.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "fatcontextSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-struct-pointers": {
+ "description": "Check for potential fat contexts in struct pointers.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "forbidigoSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "exclude-godoc-examples": {
+ "description": "Exclude code in godoc examples.",
+ "type": "boolean",
+ "default": true
+ },
+ "analyze-types": {
+ "description": "Instead of matching the literal source code, use type information to replace expressions with strings that contain the package name and (for methods and fields) the type name.",
+ "type": "boolean",
+ "default": true
+ },
+ "forbid": {
+ "description": "List of identifiers to forbid (written using `regexp`)",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "pattern": {
+ "description": "Pattern",
+ "type": "string"
+ },
+ "pkg": {
+ "description": "Package",
+ "type": "string"
+ },
+ "msg": {
+ "description": "Message",
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "funcorderSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "constructor": {
+ "description": "Checks that constructors are placed after the structure declaration.",
+ "type": "boolean",
+ "default": true
+ },
+ "struct-method": {
+ "description": "Checks if the exported methods of a structure are placed before the non-exported ones.",
+ "type": "boolean",
+ "default": true
+ },
+ "alphabetical": {
+ "description": "Checks if the constructors and/or structure methods are sorted alphabetically.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "funlenSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "lines": {
+ "description": "Limit lines number per function.",
+ "type": "integer",
+ "default": 60
+ },
+ "statements": {
+ "description": "Limit statements number per function.",
+ "type": "integer",
+ "default": 40
+ },
+ "ignore-comments": {
+ "description": "Ignore comments when counting lines.",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "gciSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "sections": {
+ "description": "Section configuration to compare against.",
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "enum": [
+ "standard",
+ "default",
+ "blank",
+ "dot",
+ "alias",
+ "localmodule"
+ ]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ },
+ "default": ["standard", "default"]
+ },
+ "no-inline-comments": {
+ "description": "Checks that no inline Comments are present.",
+ "type": "boolean",
+ "default": false
+ },
+ "no-prefix-comments": {
+ "description": "Checks that no prefix Comments(comment lines above an import) are present.",
+ "type": "boolean",
+ "default": false
+ },
+ "custom-order": {
+ "description": "Enable custom order of sections.",
+ "type": "boolean",
+ "default": false
+ },
+ "no-lex-order": {
+ "description": "Drops lexical ordering for custom sections.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "ginkgolinterSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "suppress-len-assertion": {
+ "description": "Suppress the wrong length assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-nil-assertion": {
+ "description": "Suppress the wrong nil assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-err-assertion": {
+ "description": "Suppress the wrong error assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-compare-assertion": {
+ "description": "Suppress the wrong comparison assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-async-assertion": {
+ "description": "Suppress the function all in async assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-type-compare-assertion": {
+ "description": "Suppress warning for comparing values from different types, like int32 and uint32.",
+ "type": "boolean",
+ "default": false
+ },
+ "forbid-focus-container": {
+ "description": "Trigger warning for ginkgo focus containers like FDescribe, FContext, FWhen or FIt.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-havelen-zero": {
+ "description": "Don't trigger warnings for HaveLen(0).",
+ "type": "boolean",
+ "default": false
+ },
+ "force-expect-to": {
+ "description": "Force using `Expect` with `To`, `ToNot` or `NotTo`",
+ "type": "boolean",
+ "default": false
+ },
+ "validate-async-intervals": {
+ "description": "Best effort validation of async intervals (timeout and polling).",
+ "type": "boolean",
+ "default": false
+ },
+ "forbid-spec-pollution": {
+ "description": "Trigger a warning for variable assignments in ginkgo containers like `Describe`, `Context` and `When`, instead of in `BeforeEach()`.",
+ "type": "boolean",
+ "default": false
+ },
+ "force-succeed": {
+ "description": "Force using the Succeed matcher for error functions, and the HaveOccurred matcher for non-function error values.",
+ "type": "boolean",
+ "default": false
+ },
+ "force-assertion-description": {
+ "description": "Force adding assertion descriptions to gomega matchers.",
+ "type": "boolean",
+ "default": false
+ },
+ "force-tonot": {
+ "description": "Force using `ToNot`, `ShouldNot` instead of `To(Not())`.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "gochecksumtypeSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "default-signifies-exhaustive": {
+ "description": "Presence of `default` case in switch statements satisfies exhaustiveness, if all members are not listed.",
+ "type": "boolean",
+ "default": true
+ },
+ "include-shared-interfaces": {
+ "description": "Include shared interfaces in the exhaustiviness check.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "gocognitSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "min-complexity": {
+ "description": "Minimal code complexity to report (we recommend 10-20).",
+ "type": "integer",
+ "default": 30
+ }
+ }
+ },
+ "goconstSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "match-constant": {
+ "description": "Look for existing constants matching the values",
+ "type": "boolean",
+ "default": true
+ },
+ "min-len": {
+ "description": "Minimum length of string constant.",
+ "type": "integer",
+ "default": 3
+ },
+ "min-occurrences": {
+ "description": "Minimum occurrences count to trigger.",
+ "type": "integer",
+ "default": 3
+ },
+ "ignore-calls": {
+ "description": "Ignore when constant is not used as function argument",
+ "type": "boolean",
+ "default": true
+ },
+ "ignore-string-values": {
+ "description": "Exclude strings matching the given regular expression",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "numbers": {
+ "description": "Search also for duplicated numbers.",
+ "type": "boolean",
+ "default": false
+ },
+ "min": {
+ "description": "Minimum value, only works with `numbers`",
+ "type": "integer",
+ "default": 3
+ },
+ "max": {
+ "description": "Maximum value, only works with `numbers`",
+ "type": "integer",
+ "default": 3
+ },
+ "find-duplicates": {
+ "description": "Detects constants with identical values",
+ "type": "boolean",
+ "default": false
+ },
+ "eval-const-expressions": {
+ "description": "Evaluates of constant expressions like Prefix + \"suffix\"",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "gocriticSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "enabled-checks": {
+ "description": "Which checks should be enabled. By default, a list of stable checks is used. To see it, run `GL_DEBUG=gocritic golangci-lint run`.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/gocritic-checks"
+ }
+ },
+ "disabled-checks": {
+ "description": "Which checks should be disabled.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/gocritic-checks"
+ },
+ "default": []
+ },
+ "enabled-tags": {
+ "description": "Enable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/gocritic-tags"
+ }
+ },
+ "disabled-tags": {
+ "description": "Disable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/gocritic-tags"
+ }
+ },
+ "settings": {
+ "description": "Settings passed to gocritic. Properties must be valid and enabled check names.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "captLocal": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "paramsOnly" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "commentedOutCode": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "minLength" : {
+ "type": "number",
+ "default": 15
+ }
+ }
+ },
+ "elseif": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skipBalanced" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "hugeParam": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "sizeThreshold" : {
+ "type": "number",
+ "default": 80
+ }
+ }
+ },
+ "ifElseChain": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "minThreshold" : {
+ "type": "number",
+ "default": 2
+ }
+ }
+ },
+ "nestingReduce": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "bodyWidth" : {
+ "type": "number",
+ "default": 5
+ }
+ }
+ },
+ "rangeExprCopy": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "sizeThreshold" : {
+ "type": "number",
+ "default": 512
+ },
+ "skipTestFuncs" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "rangeValCopy": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "sizeThreshold" : {
+ "type": "number",
+ "default": 128
+ },
+ "skipTestFuncs" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "ruleguard": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "debug" : {
+ "type": "string"
+ },
+ "enable" : {
+ "type": "string"
+ },
+ "disable" : {
+ "type": "string"
+ },
+ "failOn" : {
+ "type": "string"
+ },
+ "rules" : {
+ "type": "string"
+ }
+ }
+ },
+ "tooManyResultsChecker": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "maxResults" : {
+ "type": "number",
+ "default": 5
+ }
+ }
+ },
+ "truncateCmp": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skipArchDependent" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "underef": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skipRecvDeref" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "unnamedResult": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "checkExported" : {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ }
+ }
+ },
+ "disable-all": {
+ "type": "boolean",
+ "default": false
+ },
+ "enable-all": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "gocycloSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "min-complexity": {
+ "description": "Minimum code complexity to report (we recommend 10-20).",
+ "type": "integer",
+ "default": 30
+ }
+ }
+ },
+ "godoclintSettings": {
+ "type": "object",
+ "properties": {
+ "default": {
+ "type": "string",
+ "enum": ["all", "basic", "none"],
+ "default": "basic",
+ "description": "Default set of rules to enable."
+ },
+ "enable": {
+ "description": "List of rules to enable in addition to the default set.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "$ref": "#/definitions/godoclint-rules"
+ }
+ },
+ "disable": {
+ "description": "List of rules to disable.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "$ref": "#/definitions/godoclint-rules"
+ }
+ },
+ "options": {
+ "type": "object",
+ "description": "A map for setting individual rule options.",
+ "properties": {
+ "max-len": {
+ "type": "object",
+ "properties": {
+ "length": {
+ "type": "integer",
+ "description": "Maximum line length for godocs, not including the `// `, or `/*` or `*/` tokens.",
+ "default": 77
+ }
+ }
+ },
+ "require-doc": {
+ "type": "object",
+ "properties": {
+ "ignore-exported": {
+ "type": "boolean",
+ "description": "Ignore exported (public) symbols when applying the `require-doc` rule.",
+ "default": false
+ },
+ "ignore-unexported": {
+ "type": "boolean",
+ "description": "Ignore unexported (private) symbols when applying the `require-doc` rule.",
+ "default": true
+ }
+ }
+ },
+ "start-with-name": {
+ "type": "object",
+ "properties": {
+ "include-unexported": {
+ "type": "boolean",
+ "description": "Include unexported symbols when applying the `start-with-name` rule.",
+ "default": false
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "godotSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "scope": {
+ "description": "Comments to be checked.",
+ "enum": ["declarations", "toplevel", "all", "noinline"],
+ "default": "declarations"
+ },
+ "exclude": {
+ "description": "List of regexps for excluding particular comment lines from check.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "period": {
+ "description": "Check that each sentence ends with a period.",
+ "type": "boolean",
+ "default": true
+ },
+ "capital": {
+ "description": "Check that each sentence starts with a capital letter.",
+ "type": "boolean",
+ "default": false
+ },
+ "check-all": {
+ "description": "DEPRECATED: Check all top-level comments, not only declarations.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "godoxSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "keywords": {
+ "description": "Report any comments starting with one of these keywords. This is useful for TODO or FIXME comments that might be left in the code accidentally and should be resolved before merging.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "default": ["TODO", "BUG", "FIXME"]
+ }
+ }
+ },
+ "gofmtSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "simplify": {
+ "description": "Simplify code.",
+ "type": "boolean",
+ "default": true
+ },
+ "rewrite-rules": {
+ "description": "Apply the rewrite rules to the source before reformatting.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "pattern": {
+ "type": "string"
+ },
+ "replacement": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "golinesSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-len": {
+ "type": "integer",
+ "default": 100
+ },
+ "tab-len": {
+ "type": "integer",
+ "default": 4
+ },
+ "shorten-comments": {
+ "type": "boolean",
+ "default": false
+ },
+ "reformat-tags": {
+ "type": "boolean",
+ "default": true
+ },
+ "chain-split-dots": {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "interfacebloatSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max": {
+ "description": "The maximum number of methods allowed for an interface.",
+ "type": "integer"
+ }
+ }
+ },
+ "gofumptSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "extra-rules": {
+ "description": "Choose whether or not to use the extra rules that are disabled by default.",
+ "type": "boolean",
+ "default": false
+ },
+ "module-path": {
+ "description": " Module path which contains the source code being formatted.",
+ "type": "string"
+ }
+ }
+ },
+ "goheaderSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "values": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "const": {
+ "description": "Constants to use in the template.",
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "description": "Value for the constant.",
+ "type": "string"
+ }
+ },
+ "additionalProperties": false,
+ "examples": [
+ {
+ "YEAR": "2030",
+ "COMPANY": "MY FUTURISTIC COMPANY"
+ }
+ ]
+ },
+ "regexp": {
+ "description": "Regular expressions to use in your template.",
+ "type": "object",
+ "additionalProperties": false,
+ "patternProperties": {
+ "^.+$": {
+ "type": "string"
+ }
+ },
+ "examples": [
+ {
+ "AUTHOR": ".*@mycompany\\.com"
+ }
+ ]
+ }
+ }
+ },
+ "template": {
+ "description": "Template to put on top of every file.",
+ "type": "string",
+ "examples": [
+ "{{ MY COMPANY }}\nSPDX-License-Identifier: Apache-2.0\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at:\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License."
+ ]
+ },
+ "template-path": {
+ "description": "Path to the file containing the template source.",
+ "type": "string",
+ "examples": ["my_header_template.txt"]
+ }
+ },
+ "oneOf": [
+ { "required": ["template"] },
+ { "required": ["template-path"] }
+ ]
+ },
+ "goimportsSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "local-prefixes": {
+ "description": "Put imports beginning with prefix after 3rd-party packages. It is a list of prefixes.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "gomoddirectivesSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "replace-local": {
+ "description": "Allow local `replace` directives.",
+ "type": "boolean",
+ "default": true
+ },
+ "replace-allow-list": {
+ "description": "List of allowed `replace` directives.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "retract-allow-no-explanation": {
+ "description": "Allow to not explain why the version has been retracted in the `retract` directives.",
+ "type": "boolean",
+ "default": false
+ },
+ "exclude-forbidden": {
+ "description": "Forbid the use of the `exclude` directives.",
+ "type": "boolean",
+ "default": false
+ },
+ "ignore-forbidden": {
+ "description": "Forbid the use of the `ignore` directives. (>= go1.25)",
+ "type": "boolean",
+ "default": false
+ },
+ "toolchain-forbidden": {
+ "description": "Forbid the use of the `toolchain` directive.",
+ "type": "boolean",
+ "default": false
+ },
+ "toolchain-pattern": {
+ "description": "Defines a pattern to validate `toolchain` directive.",
+ "type": "string"
+ },
+ "tool-forbidden": {
+ "description": "Forbid the use of the `tool` directives.",
+ "type": "boolean",
+ "default": false
+ },
+ "go-debug-forbidden": {
+ "description": "Forbid the use of the `godebug` directive.",
+ "type": "boolean",
+ "default": false
+ },
+ "go-version-pattern": {
+ "description": "Defines a pattern to validate `go` minimum version directive.",
+ "type": "string",
+ "default": ""
+ }
+ }
+ },
+ "gomodguardSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "allowed": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "modules": {
+ "description": "List of allowed modules.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["gopkg.in/yaml.v2"]
+ }
+ },
+ "domains": {
+ "description": "List of allowed module domains.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["golang.org"]
+ }
+ }
+ }
+ },
+ "blocked": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "modules": {
+ "description": "List of blocked modules.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "recommendations": {
+ "description": "Recommended modules that should be used instead.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "reason": {
+ "description": "Reason why the recommended module should be used.",
+ "type": "string"
+ }
+ }
+ }
+ },
+ "additionalProperties": false
+ }
+ },
+ "versions": {
+ "description": "List of blocked module version constraints.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "patternProperties": {
+ "^.*$": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "version": {
+ "description": "Version constraint.",
+ "type": "string"
+ },
+ "reason": {
+ "description": "Reason why the version constraint exists.",
+ "type": "string"
+ }
+ },
+ "required": ["reason"]
+ }
+ }
+ }
+ },
+ "local-replace-directives": {
+ "description": "Raise lint issues if loading local path with replace directive",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ }
+ }
+ },
+ "gosecSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "includes": {
+ "type": "array",
+ "description": "To select a subset of rules to run",
+ "examples": [["G401"]],
+ "items": {
+ "$ref": "#/definitions/gosec-rules"
+ }
+ },
+ "excludes": {
+ "type": "array",
+ "description": "To specify a set of rules to explicitly exclude",
+ "examples": [["G401"]],
+ "items": {
+ "$ref": "#/definitions/gosec-rules"
+ }
+ },
+ "severity": {
+ "description": "Filter out the issues with a lower severity than the given value",
+ "type": "string",
+ "enum": ["low", "medium", "high"],
+ "default": "low"
+ },
+ "confidence": {
+ "description": "Filter out the issues with a lower confidence than the given value",
+ "type": "string",
+ "enum": ["low", "medium", "high"],
+ "default": "low"
+ },
+ "config": {
+ "description": "To specify the configuration of rules",
+ "type": "object"
+ },
+ "concurrency": {
+ "description": "Concurrency value",
+ "type": "integer"
+ }
+ }
+ },
+ "gosmopolitanSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "allow-time-local": {
+ "description": "Allow and ignore `time.Local` usages.",
+ "type": "boolean",
+ "default": false
+ },
+ "escape-hatches": {
+ "description": "List of fully qualified names in the `full/pkg/path.name` form, to act as \"i18n escape hatches\".",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "watch-for-scripts": {
+ "description": "List of Unicode scripts to watch for any usage in string literals.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "govetSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "settings": {
+ "description": "Settings per analyzer. Map of analyzer name to specific settings.\nRun `go tool vet help` to find out more.",
+ "type": "object",
+ "propertyNames": {
+ "$ref": "#/definitions/govet-analyzers"
+ },
+ "patternProperties": {
+ "^.*$": {
+ "description": "Run `go tool vet help ` to see all settings.",
+ "type": "object"
+ }
+ }
+ },
+ "enable": {
+ "description": "Enable analyzers by name.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/govet-analyzers"
+ }
+ },
+ "disable": {
+ "description": "Disable analyzers by name.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/govet-analyzers"
+ }
+ },
+ "enable-all": {
+ "description": "Enable all analyzers.",
+ "type": "boolean",
+ "default": false
+ },
+ "disable-all": {
+ "description": "Disable all analyzers.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "grouperSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "const-require-single-const": {
+ "type": "boolean",
+ "default": false
+ },
+ "const-require-grouping": {
+ "type": "boolean",
+ "default": false
+ },
+ "import-require-single-import": {
+ "type": "boolean",
+ "default": false
+ },
+ "import-require-grouping": {
+ "type": "boolean",
+ "default": false
+ },
+ "type-require-single-type": {
+ "type": "boolean",
+ "default": false
+ },
+ "type-require-grouping": {
+ "type": "boolean",
+ "default": false
+ },
+ "var-require-single-var": {
+ "type": "boolean",
+ "default": false
+ },
+ "var-require-grouping": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "ifaceSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "enable": {
+ "description": "Enable analyzers by name.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/iface-analyzers"
+ }
+ },
+ "settings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "unused": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "exclude": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "importasSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "no-unaliased": {
+ "description": "Do not allow unaliased imports of aliased packages.",
+ "type": "boolean",
+ "default": false
+ },
+ "no-extra-aliases": {
+ "description": "Do not allow non-required aliases.",
+ "type": "boolean",
+ "default": false
+ },
+ "alias": {
+ "description": "List of aliases",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "pkg": {
+ "description": "Package path e.g. knative.dev/serving/pkg/apis/autoscaling/v1alpha1",
+ "type": "string"
+ },
+ "alias": {
+ "description": "Package alias e.g. autoscalingv1alpha1",
+ "type": "string"
+ }
+ },
+ "required": ["pkg", "alias"]
+ }
+ }
+ }
+ },
+ "inamedparamSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skip-single-param": {
+ "description": "Skips check for interface methods with only a single parameter.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "ineffassignSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-escaping-errors": {
+ "description": "Check escaping variables of type error, may cause false positives.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "iotamixingSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "report-individual": {
+ "description": "Whether to report individual consts rather than just the const block.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "ireturnSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "description": "Use either `reject` or `allow` properties for interfaces matching.",
+ "properties": {
+ "allow": {
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "enum": ["anon", "error", "empty", "stdlib"]
+ }
+ ]
+ }
+ },
+ "reject": {
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "enum": ["anon", "error", "empty", "stdlib"]
+ }
+ ]
+ }
+ }
+ },
+ "anyOf": [
+ {
+ "not": {
+ "properties": {
+ "allow": {
+ "const": "reject"
+ }
+ }
+ },
+ "required": ["allow"]
+ },
+ {
+ "required": ["reject"]
+ }
+ ]
+ },
+ "lllSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "tab-width": {
+ "description": "Width of \"\\t\" in spaces.",
+ "type": "integer",
+ "minimum": 0,
+ "default": 1
+ },
+ "line-length": {
+ "description": "Maximum allowed line length, lines longer will be reported.",
+ "type": "integer",
+ "minimum": 1,
+ "default": 120
+ }
+ }
+ },
+ "maintidxSettings": {
+ "description": "Maintainability index https://docs.microsoft.com/en-us/visualstudio/code-quality/code-metrics-maintainability-index-range-and-meaning?view=vs-2022",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "under": {
+ "description": "Minimum accatpable maintainability index level (see https://docs.microsoft.com/en-us/visualstudio/code-quality/code-metrics-maintainability-index-range-and-meaning?view=vs-2022)",
+ "type": "number",
+ "default": 20
+ }
+ }
+ },
+ "makezeroSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "always": {
+ "description": "Allow only slices initialized with a length of zero.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "loggercheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "kitlog": {
+ "description": "Allow check for the github.com/go-kit/log library.",
+ "type": "boolean",
+ "default": true
+ },
+ "klog": {
+ "description": "Allow check for the k8s.io/klog/v2 library.",
+ "type": "boolean",
+ "default": true
+ },
+ "logr": {
+ "description": "Allow check for the github.com/go-logr/logr library.",
+ "type": "boolean",
+ "default": true
+ },
+ "slog": {
+ "description": "Allow check for the log/slog library.",
+ "type": "boolean",
+ "default": true
+ },
+ "zap": {
+ "description": "Allow check for the \"sugar logger\" from go.uber.org/zap library.",
+ "type": "boolean",
+ "default": true
+ },
+ "require-string-key": {
+ "description": "Require all logging keys to be inlined constant strings.",
+ "type": "boolean",
+ "default": false
+ },
+ "no-printf-like": {
+ "description": "Require printf-like format specifier (%s, %d for example) not present.",
+ "type": "boolean",
+ "default": false
+ },
+ "rules": {
+ "description": "List of custom rules to check against, where each rule is a single logger pattern, useful for wrapped loggers.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "misspellSettings": {
+ "description": "Correct spellings using locale preferences for US or UK. Default is to use a neutral variety of English.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "locale": {
+ "enum": ["US", "UK"]
+ },
+ "ignore-rules": {
+ "description": "List of rules to ignore.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "mode": {
+ "description": "Mode of the analysis.",
+ "enum": ["restricted", "", "default"],
+ "default": ""
+ },
+ "extra-words": {
+ "description": "Extra word corrections.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "correction": {
+ "type": "string"
+ },
+ "typo": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "musttagSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "functions": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "tag": {
+ "type": "string"
+ },
+ "arg-pos": {
+ "type": "integer"
+ }
+ }
+ }
+ }
+ }
+ },
+ "nakedretSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-func-lines": {
+ "description": "Report if a function has more lines of code than this value and it has naked returns.",
+ "type": "integer",
+ "minimum": 0,
+ "default": 30
+ }
+ }
+ },
+ "nestifSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "min-complexity": {
+ "description": "Minimum complexity of \"if\" statements to report.",
+ "type": "integer",
+ "default": 5
+ }
+ }
+ },
+ "nilnilSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "only-two": {
+ "type": "boolean",
+ "description": "To check functions with only two return values.",
+ "default": true
+ },
+ "detect-opposite": {
+ "type": "boolean",
+ "description": "In addition, detect opposite situation (simultaneous return of non-nil error and valid value).",
+ "default": false
+ },
+ "checked-types": {
+ "type": "array",
+ "description": "List of return types to check.",
+ "items": {
+ "enum": ["chan", "func", "iface", "map", "ptr", "uintptr", "unsafeptr"]
+ },
+ "default": ["chan", "func", "iface", "map", "ptr", "uintptr", "unsafeptr"]
+ }
+ }
+ },
+ "nlreturnSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "block-size": {
+ "description": "set block size that is still ok",
+ "type": "number",
+ "default": 0,
+ "minimum": 0
+ }
+ }
+ },
+ "mndSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignored-files": {
+ "description": "List of file patterns to exclude from analysis.",
+ "examples": [["magic1_.*.go"]],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignored-functions": {
+ "description": "Comma-separated list of function patterns to exclude from the analysis.",
+ "examples": [["math.*", "http.StatusText", "make"]],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignored-numbers": {
+ "description": "List of numbers to exclude from analysis.",
+ "examples": [["1000", "1234_567_890", "3.14159264"]],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "checks": {
+ "description": "The list of enabled checks, see https://github.com/tommy-muehle/go-mnd/#checks for description.",
+ "type": "array",
+ "items": {
+ "enum": [
+ "argument",
+ "case",
+ "condition",
+ "operation",
+ "return",
+ "assign"
+ ]
+ }
+ }
+ }
+ },
+ "nolintlintSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "allow-unused": {
+ "description": "Enable to ensure that nolint directives are all used.",
+ "type": "boolean",
+ "default": true
+ },
+ "allow-no-explanation": {
+ "description": "Exclude these linters from requiring an explanation.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linter-names"
+ },
+ "default": []
+ },
+ "require-explanation": {
+ "description": "Enable to require an explanation of nonzero length after each nolint directive.",
+ "type": "boolean",
+ "default": false
+ },
+ "require-specific": {
+ "description": "Enable to require nolint directives to mention the specific linter being suppressed.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "reassignSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "patterns": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "recvcheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "disable-builtin": {
+ "description": "Disables the built-in method exclusions.",
+ "type": "boolean",
+ "default": true
+ },
+ "exclusions": {
+ "description": "User-defined method exclusions.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "nonamedreturnsSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "report-error-in-defer": {
+ "description": "Report named error if it is assigned inside defer.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "paralleltestSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignore-missing": {
+ "description": "Ignore missing calls to `t.Parallel()` and only report incorrect uses of it.",
+ "type": "boolean",
+ "default": false
+ },
+ "ignore-missing-subtests": {
+ "description": "Ignore missing calls to `t.Parallel()` in subtests. Top-level tests are still required to have `t.Parallel`, but subtests are allowed to skip it.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "perfsprintSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "integer-format": {
+ "description": "Enable/disable optimization of integer formatting.",
+ "type": "boolean",
+ "default": true
+ },
+ "int-conversion": {
+ "description": "Optimizes even if it requires an int or uint type cast.",
+ "type": "boolean",
+ "default": true
+ },
+ "error-format": {
+ "description": "Enable/disable optimization of error formatting.",
+ "type": "boolean",
+ "default": true
+ },
+ "err-error": {
+ "description": "Optimizes into `err.Error()` even if it is only equivalent for non-nil errors.",
+ "type": "boolean",
+ "default": false
+ },
+ "errorf": {
+ "description": "Optimizes `fmt.Errorf`.",
+ "type": "boolean",
+ "default": true
+ },
+ "string-format": {
+ "description": "Enable/disable optimization of string formatting.",
+ "type": "boolean",
+ "default": true
+ },
+ "sprintf1": {
+ "description": "Optimizes `fmt.Sprintf` with only one argument.",
+ "type": "boolean",
+ "default": true
+ },
+ "strconcat": {
+ "description": "Optimizes into strings concatenation.",
+ "type": "boolean",
+ "default": true
+ },
+ "bool-format": {
+ "description": "Enable/disable optimization of bool formatting.",
+ "type": "boolean",
+ "default": true
+ },
+ "hex-format": {
+ "description": "Enable/disable optimization of hex formatting.",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "preallocSettings": {
+ "description": "We do not recommend using this linter before doing performance profiling.\nFor most programs usage of `prealloc` will be premature optimization.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "simple": {
+ "description": "Report preallocation suggestions only on simple loops that have no returns/breaks/continues/gotos in them.",
+ "type": "boolean",
+ "default": true
+ },
+ "range-loops": {
+ "description": "Report preallocation suggestions on range loops.",
+ "type": "boolean",
+ "default": true
+ },
+ "for-loops": {
+ "description": "Report preallocation suggestions on for loops.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "predeclaredSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignore": {
+ "description": "List of predeclared identifiers to not report on.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "qualified-name": {
+ "description": "Include method names and field names in checks.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "promlinterSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "strict": {},
+ "disabled-linters": {
+ "type": "array",
+ "items": {
+ "enum": [
+ "Help",
+ "MetricUnits",
+ "Counter",
+ "HistogramSummaryReserved",
+ "MetricTypeInName",
+ "ReservedChars",
+ "CamelCase",
+ "UnitAbbreviations"
+ ]
+ }
+ }
+ }
+ },
+ "protogetterSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skip-generated-by": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["protoc-gen-go-my-own-generator"]
+ }
+ },
+ "skip-files": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["*.pb.go"]
+ }
+ },
+ "skip-any-generated": {
+ "description": "Skip any generated files from the checking.",
+ "type": "boolean",
+ "default": false
+ },
+ "replace-first-arg-in-append": {
+ "description": "Skip first argument of append function.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "reviveSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "examples": [
+ {
+ "ignore-generated-header": true,
+ "severity": "warning",
+ "rules": [
+ {
+ "name": "indent-error-flow",
+ "severity": "warning"
+ },
+ {
+ "name": "add-constant",
+ "severity": "warning",
+ "arguments": [
+ {
+ "maxLitCount": "3",
+ "allowStrs": "\"\"",
+ "allowInts": "0,1,2",
+ "allowFloats": "0.0,0.,1.0,1.,2.0,2."
+ }
+ ]
+ }
+ ]
+ }
+ ],
+ "properties": {
+ "max-open-files": {
+ "type": "integer"
+ },
+ "confidence": {
+ "type": "number"
+ },
+ "severity": {
+ "type": "string",
+ "enum": ["warning", "error"]
+ },
+ "enable-all-rules": {
+ "type": "boolean",
+ "default": false
+ },
+ "directives": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "name": {
+ "type": "string",
+ "enum": ["specify-disable-reason"]
+ },
+ "severity": {
+ "type": "string",
+ "enum": ["warning", "error"]
+ },
+ "exclude": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "arguments": {
+ "type": "array"
+ }
+ }
+ }
+ },
+ "rules": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["name"],
+ "properties": {
+ "name": {
+ "$ref": "#/definitions/revive-rules",
+ "title": "The rule name"
+ },
+ "disabled": {
+ "type": "boolean"
+ },
+ "severity": {
+ "type": "string",
+ "enum": ["warning", "error"]
+ },
+ "exclude": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "arguments": {
+ "type": "array"
+ }
+ }
+ }
+ }
+ }
+ },
+ "rowserrcheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "packages": {
+ "type": "array",
+ "items": {
+ "description": "",
+ "type": "string",
+ "examples": ["github.com/jmoiron/sqlx"]
+ }
+ }
+ }
+ },
+ "sloglintSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "kv-only": {
+ "description": "Enforce using key-value pairs only (incompatible with attr-only).",
+ "type": "boolean",
+ "default": false
+ },
+ "no-global": {
+ "description": "Enforce not using global loggers.",
+ "enum": ["", "all", "default"],
+ "default": ""
+ },
+ "no-mixed-args": {
+ "description": "Enforce not mixing key-value pairs and attributes.",
+ "type": "boolean",
+ "default": true
+ },
+ "context": {
+ "description": "Enforce using methods that accept a context.",
+ "enum": ["", "all", "scope"],
+ "default": ""
+ },
+ "static-msg": {
+ "description": "Enforce using static values for log messages.",
+ "type": "boolean",
+ "default": false
+ },
+ "msg-style": {
+ "description": "Enforce message style.",
+ "enum": ["", "lowercased", "capitalized"],
+ "default": ""
+ },
+ "key-naming-case": {
+ "description": "Enforce a single key naming convention.",
+ "enum": ["snake", "kebab", "camel", "pascal"]
+ },
+ "attr-only": {
+ "description": "Enforce using attributes only (incompatible with kv-only).",
+ "type": "boolean",
+ "default": false
+ },
+ "no-raw-keys": {
+ "description": "Enforce using constants instead of raw keys.",
+ "type": "boolean",
+ "default": false
+ },
+ "forbidden-keys": {
+ "description": "Enforce not using specific keys.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "args-on-sep-lines": {
+ "description": "Enforce putting arguments on separate lines.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "spancheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "checks": {
+ "description": "Checks to enable.",
+ "type": "array",
+ "items": {
+ "enum": ["end", "record-error", "set-status"]
+ }
+ },
+ "ignore-check-signatures": {
+ "description": "A list of regexes for function signatures that silence `record-error` and `set-status` reports if found in the call path to a returned error.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "extra-start-span-signatures": {
+ "description": "A list of regexes for additional function signatures that create spans.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "staticcheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "checks": {
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "$ref": "#/definitions/staticcheck-checks"
+ },
+ {
+ "type": "string"
+ }
+ ]
+ }
+ },
+ "dot-import-whitelist": {
+ "description": "By default, ST1001 forbids all uses of dot imports in non-test packages. This setting allows setting a whitelist of import paths that can be dot-imported anywhere.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "http-status-code-whitelist": {
+ "description": "ST1013 recommends using constants from the net/http package instead of hard-coding numeric HTTP status codes. This setting specifies a list of numeric status codes that this check does not complain about.",
+ "default": ["200", "400", "404", "500"],
+ "type": "array",
+ "items": {
+ "enum": [
+ "100",
+ "101",
+ "102",
+ "103",
+ "200",
+ "201",
+ "202",
+ "203",
+ "204",
+ "205",
+ "206",
+ "207",
+ "208",
+ "226",
+ "300",
+ "301",
+ "302",
+ "303",
+ "304",
+ "305",
+ "306",
+ "307",
+ "308",
+ "400",
+ "401",
+ "402",
+ "403",
+ "404",
+ "405",
+ "406",
+ "407",
+ "408",
+ "409",
+ "410",
+ "411",
+ "412",
+ "413",
+ "414",
+ "415",
+ "416",
+ "417",
+ "418",
+ "421",
+ "422",
+ "423",
+ "424",
+ "425",
+ "426",
+ "428",
+ "429",
+ "431",
+ "451",
+ "500",
+ "501",
+ "502",
+ "503",
+ "504",
+ "505",
+ "506",
+ "507",
+ "508",
+ "510",
+ "511"
+ ]
+ }
+ },
+ "initialisms": {
+ "description": "ST1003 check, among other things, for the correct capitalization of initialisms. The set of known initialisms can be configured with this option.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "default": [
+ "ACL",
+ "API",
+ "ASCII",
+ "CPU",
+ "CSS",
+ "DNS",
+ "EOF",
+ "GUID",
+ "HTML",
+ "HTTP",
+ "HTTPS",
+ "ID",
+ "IP",
+ "JSON",
+ "QPS",
+ "RAM",
+ "RPC",
+ "SLA",
+ "SMTP",
+ "SQL",
+ "SSH",
+ "TCP",
+ "TLS",
+ "TTL",
+ "UDP",
+ "UI",
+ "GID",
+ "UID",
+ "UUID",
+ "URI",
+ "URL",
+ "UTF8",
+ "VM",
+ "XML",
+ "XMPP",
+ "XSRF",
+ "XSS",
+ "SIP",
+ "RTP",
+ "AMQP",
+ "DB",
+ "TS"
+ ]
+ }
+ }
+ }
+ },
+ "tagalignSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "align": {
+ "description": "Align and sort can be used together or separately.",
+ "type": "boolean",
+ "default": true
+ },
+ "sort": {
+ "description": "Whether enable tags sort.",
+ "type": "boolean",
+ "default": true
+ },
+ "order": {
+ "description": "Specify the order of tags, the other tags will be sorted by name.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "default": [],
+ "examples": [
+ [
+ "json",
+ "yaml",
+ "yml",
+ "toml",
+ "mapstructure",
+ "binding",
+ "validate"
+ ]
+ ]
+ },
+ "strict": {
+ "description": "Whether enable strict style.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "tagliatelleSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "case": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "use-field-name": {
+ "description": "Use the struct field name to check the name of the struct tag.",
+ "type": "boolean",
+ "default": false
+ },
+ "ignored-fields": {
+ "description": "The field names to ignore.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["example"]
+ }
+ },
+ "rules": {
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "$ref": "#/definitions/tagliatelle-cases"
+ }
+ }
+ },
+ "extended-rules": {
+ "description": "Defines the association between tag name and case.",
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["case"],
+ "properties": {
+ "case": {
+ "$ref": "#/definitions/tagliatelle-cases"
+ },
+ "extra-initialisms": {
+ "type": "boolean",
+ "default": false
+ },
+ "initialism-overrides": {
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "overrides": {
+ "description": "Overrides the default/root configuration.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["pkg"],
+ "properties": {
+ "pkg": {
+ "description": "A package path.",
+ "type": "string"
+ },
+ "use-field-name": {
+ "description": "Use the struct field name to check the name of the struct tag.",
+ "type": "boolean",
+ "default": false
+ },
+ "ignored-fields": {
+ "description": "The field names to ignore.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["example"]
+ }
+ },
+ "ignore": {
+ "description": "Ignore the package (takes precedence over all other configurations).",
+ "type": "boolean",
+ "default": false
+ },
+ "rules": {
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "$ref": "#/definitions/tagliatelle-cases"
+ }
+ }
+ },
+ "extended-rules": {
+ "description": "Defines the association between tag name and case.",
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["case"],
+ "properties": {
+ "case": {
+ "$ref": "#/definitions/tagliatelle-cases"
+ },
+ "extra-initialisms": {
+ "type": "boolean",
+ "default": false
+ },
+ "initialism-overrides": {
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "testifylintSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "enable-all": {
+ "description": "Enable all checkers.",
+ "type": "boolean",
+ "default": false
+ },
+ "disable-all": {
+ "description": "Disable all checkers.",
+ "type": "boolean",
+ "default": false
+ },
+ "enable": {
+ "description": "Enable specific checkers.",
+ "type": "array",
+ "items": {
+ "enum": [
+ "blank-import",
+ "bool-compare",
+ "compares",
+ "contains",
+ "empty",
+ "encoded-compare",
+ "equal-values",
+ "error-is-as",
+ "error-nil",
+ "expected-actual",
+ "float-compare",
+ "formatter",
+ "go-require",
+ "len",
+ "negative-positive",
+ "nil-compare",
+ "regexp",
+ "require-error",
+ "suite-broken-parallel",
+ "suite-dont-use-pkg",
+ "suite-extra-assert-call",
+ "suite-method-signature",
+ "suite-subtest-run",
+ "suite-thelper",
+ "useless-assert"
+ ]
+ },
+ "default": [
+ "blank-import",
+ "bool-compare",
+ "compares",
+ "contains",
+ "empty",
+ "encoded-compare",
+ "equal-values",
+ "error-is-as",
+ "error-nil",
+ "expected-actual",
+ "float-compare",
+ "formatter",
+ "go-require",
+ "len",
+ "negative-positive",
+ "nil-compare",
+ "regexp",
+ "require-error",
+ "suite-broken-parallel",
+ "suite-dont-use-pkg",
+ "suite-extra-assert-call",
+ "suite-method-signature",
+ "suite-subtest-run",
+ "useless-assert"
+ ]
+ },
+ "disable": {
+ "description": "Disable specific checkers.",
+ "type": "array",
+ "items": {
+ "enum": [
+ "blank-import",
+ "bool-compare",
+ "compares",
+ "contains",
+ "empty",
+ "encoded-compare",
+ "equal-values",
+ "error-is-as",
+ "error-nil",
+ "expected-actual",
+ "float-compare",
+ "formatter",
+ "go-require",
+ "len",
+ "negative-positive",
+ "nil-compare",
+ "regexp",
+ "require-error",
+ "suite-broken-parallel",
+ "suite-dont-use-pkg",
+ "suite-extra-assert-call",
+ "suite-method-signature",
+ "suite-subtest-run",
+ "suite-thelper",
+ "useless-assert"
+ ],
+ "default": [
+ "suite-thelper"
+ ]
+ }
+ },
+ "bool-compare": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignore-custom-types": {
+ "description": "To ignore user defined types (over builtin bool).",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "expected-actual": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "pattern": {
+ "description": "Regexp for expected variable name.",
+ "type": "string",
+ "default": "(^(exp(ected)?|want(ed)?)([A-Z]\\w*)?$)|(^(\\w*[a-z])?(Exp(ected)?|Want(ed)?)$)"
+ }
+ }
+ },
+ "formatter": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-format-string": {
+ "description": "To enable go vet's printf checks.",
+ "type": "boolean",
+ "default": true
+ },
+ "require-f-funcs": {
+ "description": "To require f-assertions (e.g. assert.Equalf) if format string is used, even if there are no variable-length variables.",
+ "type": "boolean",
+ "default": false
+ },
+ "require-string-msg": {
+ "description": "To require that the first element of msgAndArgs (msg) has a string type.",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "go-require": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignore-http-handlers": {
+ "description": "To ignore HTTP handlers (like http.HandlerFunc).",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "require-error": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "fn-pattern": {
+ "description": "Regexp for assertions to analyze. If defined, then only matched error assertions will be reported.",
+ "type": "string",
+ "default": ""
+ }
+ }
+ },
+ "suite-extra-assert-call": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "mode": {
+ "description": "To require or remove extra Assert() call?",
+ "type": "string",
+ "enum": ["remove", "require"],
+ "default": "remove"
+ }
+ }
+ }
+ }
+ },
+ "testpackageSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skip-regexp": {
+ "description": "Files with names matching this regular expression are skipped.",
+ "type": "string",
+ "examples": ["(export|internal)_test\\.go"]
+ },
+ "allow-packages": {
+ "description": "List of packages that don't end with _test that tests are allowed to be in.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["example"]
+ }
+ }
+ }
+ },
+ "thelperSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "test": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "begin": {
+ "description": "Check if `t.Helper()` begins helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "first": {
+ "description": "Check if *testing.T is first param of helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "name": {
+ "description": "Check if *testing.T param has t name.",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ },
+ "benchmark": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "begin": {
+ "description": "Check if `b.Helper()` begins helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "first": {
+ "description": "Check if *testing.B is first param of helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "name": {
+ "description": "Check if *testing.B param has b name.",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ },
+ "tb": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "begin": {
+ "description": "Check if `tb.Helper()` begins helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "first": {
+ "description": "Check if *testing.TB is first param of helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "name": {
+ "description": "Check if *testing.TB param has tb name.",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ },
+ "fuzz": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "begin": {
+ "description": "Check if `f.Helper()` begins helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "first": {
+ "description": "Check if *testing.F is first param of helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "name": {
+ "description": "Check if *testing.F param has f name.",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ }
+ }
+ },
+ "usestdlibvarsSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "http-method": {
+ "description": "Suggest the use of http.MethodXX.",
+ "type": "boolean",
+ "default": true
+ },
+ "http-status-code": {
+ "description": "Suggest the use of http.StatusXX.",
+ "type": "boolean",
+ "default": true
+ },
+ "time-weekday": {
+ "description": "Suggest the use of time.Weekday.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "time-month": {
+ "description": "Suggest the use of time.Month.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "time-layout": {
+ "description": "Suggest the use of time.Layout.",
+ "type": "boolean",
+ "default": false
+ },
+ "time-date-month": {
+ "description": "Suggest the use of time.Month in time.Date.",
+ "type": "boolean",
+ "default": false
+ },
+ "crypto-hash": {
+ "description": "Suggest the use of crypto.Hash.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "default-rpc-path": {
+ "description": "Suggest the use of rpc.DefaultXXPath.",
+ "type": "boolean",
+ "default": false
+ },
+ "sql-isolation-level": {
+ "description": "Suggest the use of sql.LevelXX.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "tls-signature-scheme": {
+ "description": "Suggest the use of tls.SignatureScheme.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "constant-kind": {
+ "description": "Suggest the use of constant.Kind.String().",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "usetestingSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "context-background": {
+ "type": "boolean",
+ "default": false
+ },
+ "context-todo": {
+ "type": "boolean",
+ "default": false
+ },
+ "os-chdir": {
+ "type": "boolean",
+ "default": true
+ },
+ "os-mkdir-temp": {
+ "type": "boolean",
+ "default": true
+ },
+ "os-setenv": {
+ "type": "boolean",
+ "default": true
+ },
+ "os-create-temp": {
+ "type": "boolean",
+ "default": true
+ },
+ "os-temp-dir": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "unconvertSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "fast-math": {
+ "type": "boolean",
+ "default": false
+ },
+ "safe": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "unparamSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-exported": {
+ "description": "Inspect exported functions. Set to true if no external program/library imports your code.\n\nWARNING: if you enable this setting, unparam will report a lot of false-positives in text editors:\nif it's called for subdir of a project it can't find external interfaces. All text editor integrations\nwith golangci-lint call it on a directory with the changed file.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "unqueryvetSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-sql-builders": {
+ "description": "Enable SQL builder checking.",
+ "type": "boolean",
+ "default": true
+ },
+ "allowed-patterns": {
+ "description": "Regex patterns for acceptable SELECT * usage.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "unusedSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "field-writes-are-uses": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ },
+ "post-statements-are-reads": {
+ "description": "",
+ "type": "boolean",
+ "default": false
+ },
+ "exported-fields-are-used": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ },
+ "parameters-are-used": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ },
+ "local-variables-are-used": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ },
+ "generated-is-used": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "varnamelenSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-distance": {
+ "description": "Variables used in at most this N-many lines will be ignored.",
+ "type": "integer",
+ "default": 5
+ },
+ "min-name-length": {
+ "description": "The minimum length of a variable's name that is considered `long`.",
+ "type": "integer",
+ "default": 3
+ },
+ "check-receiver": {
+ "description": "Check method receiver names.",
+ "default": false,
+ "type": "boolean"
+ },
+ "check-return": {
+ "description": "Check named return values.",
+ "default": false,
+ "type": "boolean"
+ },
+ "check-type-param": {
+ "description": "Check type parameters.",
+ "default": false,
+ "type": "boolean"
+ },
+ "ignore-type-assert-ok": {
+ "description": "Ignore `ok` variables that hold the bool return value of a type assertion",
+ "default": false,
+ "type": "boolean"
+ },
+ "ignore-map-index-ok": {
+ "description": "Ignore `ok` variables that hold the bool return value of a map index.",
+ "default": false,
+ "type": "boolean"
+ },
+ "ignore-chan-recv-ok": {
+ "description": "Ignore `ok` variables that hold the bool return value of a channel receive.",
+ "default": false,
+ "type": "boolean"
+ },
+ "ignore-names": {
+ "description": "Optional list of variable names that should be ignored completely.",
+ "default": [[]],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignore-decls": {
+ "description": "Optional list of variable declarations that should be ignored completely.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "examples": [
+ ["c echo.Context", "t testing.T", "f *foo.Bar", "const C"]
+ ]
+ }
+ }
+ },
+ "whitespaceSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "multi-if": {
+ "description": "Enforces newlines (or comments) after every multi-line if statement",
+ "type": "boolean",
+ "default": false
+ },
+ "multi-func": {
+ "description": "Enforces newlines (or comments) after every multi-line function signature",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "wrapcheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "extra-ignore-sigs": {
+ "description": "An array of strings specifying additional substrings of signatures to ignore.",
+ "default": [
+ ".CustomError(",
+ ".SpecificWrap("
+ ],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignore-sigs": {
+ "description": "An array of strings which specify substrings of signatures to ignore.",
+ "default": [
+ ".Errorf(",
+ "errors.New(",
+ "errors.Unwrap(",
+ ".Wrap(",
+ ".Wrapf(",
+ ".WithMessage(",
+ ".WithMessagef(",
+ ".WithStack("
+ ],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignore-sig-regexps": {
+ "description": "An array of strings which specify regular expressions of signatures to ignore.",
+ "default": [""],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignore-package-globs": {
+ "description": "An array of glob patterns which, if any match the package of the function returning the error, will skip wrapcheck analysis for this error.",
+ "default": [""],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignore-interface-regexps": {
+ "description": "An array of glob patterns which, if matched to an underlying interface name, will ignore unwrapped errors returned from a function whose call is defined on the given interface.",
+ "default": [""],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "report-internal-errors": {
+ "description": "Determines whether wrapcheck should report errors returned from inside the package.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "wslSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "allow-assign-and-anything": {
+ "description": "Controls if you may cuddle assignments and anything without needing an empty line between them.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-assign-and-call": {
+ "description": "Allow calls and assignments to be cuddled as long as the lines have any matching variables, fields or types.",
+ "type": "boolean",
+ "default": true
+ },
+ "allow-cuddle-declarations": {
+ "description": "Allow declarations (var) to be cuddled.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-cuddle-with-calls": {
+ "description": "A list of call idents that everything can be cuddled with.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "allow-cuddle-with-rhs": {
+ "description": "AllowCuddleWithRHS is a list of right hand side variables that is allowed to be cuddled with anything.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "allow-cuddle-used-in-block": {
+ "description": "Allow cuddling with any block as long as the variable is used somewhere in the block",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-multiline-assign": {
+ "description": "Allow multiline assignments to be cuddled.",
+ "type": "boolean",
+ "default": true
+ },
+ "allow-separated-leading-comment": {
+ "description": "Allow leading comments to be separated with empty lines.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-trailing-comment": {
+ "description": "Allow trailing comments in ending of blocks.",
+ "type": "boolean",
+ "default": false
+ },
+ "error-variable-names": {
+ "description": "When force-err-cuddling is enabled this is a list of names used for error variables to check for in the conditional.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "force-case-trailing-whitespace": {
+ "description": "Force newlines in end of case at this limit (0 = never).",
+ "type": "integer",
+ "minimum": 0,
+ "default": 0
+ },
+ "force-err-cuddling": {
+ "description": "Causes an error when an If statement that checks an error variable doesn't cuddle with the assignment of that variable.",
+ "type": "boolean",
+ "default": false
+ },
+ "force-short-decl-cuddling": {
+ "description": "Causes an error if a short declaration (:=) cuddles with anything other than another short declaration.",
+ "type": "boolean",
+ "default": false
+ },
+ "strict-append": {
+ "description": "If true, append is only allowed to be cuddled if appending value is matching variables, fields or types on line above.",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "wslSettingsV5": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "allow-first-in-block": {
+ "type": "boolean",
+ "default": true
+ },
+ "allow-whole-block": {
+ "type": "boolean",
+ "default": false
+ },
+ "branch-max-lines": {
+ "type": "integer",
+ "default": 2
+ },
+ "case-max-lines": {
+ "type": "integer",
+ "default": 0
+ },
+ "default": {
+ "enum": ["all", "none", "default", ""],
+ "default": "default"
+ },
+ "enable": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/wsl-checks"
+ }
+ },
+ "disable": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/wsl-checks"
+ }
+ }
+ }
+ },
+ "copyloopvarSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-alias": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "customSettings": {
+ "description": "The custom section can be used to define linter plugins to be loaded at runtime. See README of golangci-lint for more information.\nEach custom linter should have a unique name.",
+ "type": "object",
+ "patternProperties": {
+ "^.*$": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "type": {
+ "description": "The plugin type.",
+ "enum": ["module", "goplugin"],
+ "default": "goplugin"
+ },
+ "path": {
+ "description": "The path to the plugin *.so. Can be absolute or local.",
+ "type": "string",
+ "examples": ["/path/to/example.so"]
+ },
+ "description": {
+ "description": "The description of the linter, for documentation purposes only.",
+ "type": "string"
+ },
+ "original-url": {
+ "description": "Intended to point to the repo location of the linter, for documentation purposes only.",
+ "type": "string"
+ },
+ "settings": {
+ "description": "Plugins settings/configuration. Only work with plugin based on `linterdb.PluginConstructor`.",
+ "type": "object"
+ }
+ },
+ "oneOf": [
+ {
+ "properties": {
+ "type": {"enum": ["module"] }
+ },
+ "required": ["type"]
+ },
+ {
+ "required": ["path"]
+ }
+ ]
+ }
+ }
+ }
+ }
+ }
+ },
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["version"],
+ "properties": {
+ "version": {
+ "type": "string",
+ "default": "2"
+ },
+ "run": {
+ "description": "Options for analysis running,",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "concurrency": {
+ "description": "Number of concurrent runners. Defaults to the number of available CPU cores.",
+ "type": "integer",
+ "minimum": 0,
+ "examples": [4]
+ },
+ "timeout": {
+ "description": "Timeout for the analysis.",
+ "type": "string",
+ "pattern": "^((\\d+h)?(\\d+m)?(\\d+(?:\\.\\d)?s)?|0)$",
+ "default": "1m",
+ "examples": ["30s", "5m", "5m30s"]
+ },
+ "issues-exit-code": {
+ "description": "Exit code when at least one issue was found.",
+ "type": "integer",
+ "default": 1
+ },
+ "tests": {
+ "description": "Enable inclusion of test files.",
+ "type": "boolean",
+ "default": true
+ },
+ "build-tags": {
+ "description": "List of build tags to pass to all linters.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "default": [],
+ "examples": [["mytag"]]
+ },
+ "modules-download-mode": {
+ "description": "Option to pass to \"go list -mod={option}\".\nSee \"go help modules\" for more information.",
+ "enum": ["mod", "readonly", "vendor"]
+ },
+ "allow-parallel-runners": {
+ "description": "Allow multiple parallel golangci-lint instances running. If disabled, golangci-lint acquires file lock on start.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-serial-runners": {
+ "description": "Allow multiple golangci-lint instances running, but serialize them around a lock.",
+ "type": "boolean",
+ "default": false
+ },
+ "go": {
+ "description": "Targeted Go version.",
+ "type": "string",
+ "default": "1.17"
+ },
+ "relative-path-mode": {
+ "description": "The mode used to evaluate relative paths.",
+ "type": "string",
+ "$ref": "#/definitions/relative-path-modes",
+ "default": "wd"
+ }
+ }
+ },
+ "output": {
+ "description": "Output configuration options.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "formats": {
+ "description": "Output formats to use.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "text": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "path": {
+ "$ref": "#/definitions/formats-path",
+ "default": "stdout"
+ },
+ "print-linter-name": {
+ "type": "boolean",
+ "default": true
+ },
+ "print-issued-lines": {
+ "type": "boolean",
+ "default": true
+ },
+ "colors": {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "json": {
+ "$ref": "#/definitions/simple-format"
+ },
+ "tab": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "path": {
+ "$ref": "#/definitions/formats-path",
+ "default": "stdout"
+ },
+ "print-linter-name": {
+ "type": "boolean",
+ "default": true
+ },
+ "colors": {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "html": {
+ "$ref": "#/definitions/simple-format"
+ },
+ "checkstyle": {
+ "$ref": "#/definitions/simple-format"
+ },
+ "code-climate": {
+ "$ref": "#/definitions/simple-format"
+ },
+ "junit-xml": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "path": {
+ "$ref": "#/definitions/formats-path",
+ "default": "stdout"
+ },
+ "extended": {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "teamcity": {
+ "$ref": "#/definitions/simple-format"
+ },
+ "sarif": {
+ "$ref": "#/definitions/simple-format"
+ }
+ }
+ },
+ "path-mode": {
+ "type": "string",
+ "default": "",
+ "examples": ["abs"]
+ },
+ "path-prefix": {
+ "description": "Add a prefix to the output file references.",
+ "type": "string",
+ "default": ""
+ },
+ "show-stats": {
+ "description": "Show statistics per linter.",
+ "type": "boolean",
+ "default": true
+ },
+ "sort-order": {
+ "type": "array",
+ "items": {
+ "enum": ["linter", "severity", "file"]
+ }
+ }
+ }
+ },
+ "linters": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "default": {
+ "enum": [
+ "standard",
+ "all",
+ "none",
+ "fast"
+ ]
+ },
+ "enable": {
+ "description": "List of enabled linters.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linter-names"
+ }
+ },
+ "disable": {
+ "description": "List of disabled linters.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linter-names"
+ }
+ },
+ "settings": {
+ "description": "All available settings of specific linters.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "dupword": {
+ "$ref": "#/definitions/settings/definitions/dupwordSettings"
+ },
+ "asasalint": {
+ "$ref": "#/definitions/settings/definitions/asasalintSettings"
+ },
+ "bidichk": {
+ "$ref": "#/definitions/settings/definitions/bidichkSettings"
+ },
+ "cyclop": {
+ "$ref": "#/definitions/settings/definitions/cyclopSettings"
+ },
+ "decorder": {
+ "$ref": "#/definitions/settings/definitions/decorderSettings"
+ },
+ "depguard":{
+ "$ref": "#/definitions/settings/definitions/depguardSettings"
+ },
+ "dogsled": {
+ "$ref": "#/definitions/settings/definitions/dogsledSettings"
+ },
+ "dupl": {
+ "$ref": "#/definitions/settings/definitions/duplSettings"
+ },
+ "embeddedstructfieldcheck": {
+ "$ref": "#/definitions/settings/definitions/embeddedstructfieldcheckSettings"
+ },
+ "errcheck": {
+ "$ref": "#/definitions/settings/definitions/errcheckSettings"
+ },
+ "errchkjson": {
+ "$ref": "#/definitions/settings/definitions/errchkjsonSettings"
+ },
+ "errorlint": {
+ "$ref": "#/definitions/settings/definitions/errorlintSettings"
+ },
+ "exhaustive": {
+ "$ref": "#/definitions/settings/definitions/exhaustiveSettings"
+ },
+ "exhaustruct": {
+ "$ref": "#/definitions/settings/definitions/exhaustructSettings"
+ },
+ "fatcontext": {
+ "$ref": "#/definitions/settings/definitions/fatcontextSettings"
+ },
+ "forbidigo": {
+ "$ref": "#/definitions/settings/definitions/forbidigoSettings"
+ },
+ "funcorder": {
+ "$ref": "#/definitions/settings/definitions/funcorderSettings"
+ },
+ "funlen": {
+ "$ref": "#/definitions/settings/definitions/funlenSettings"
+ },
+ "ginkgolinter": {
+ "$ref": "#/definitions/settings/definitions/ginkgolinterSettings"
+ },
+ "gochecksumtype": {
+ "$ref": "#/definitions/settings/definitions/gochecksumtypeSettings"
+ },
+ "gocognit": {
+ "$ref": "#/definitions/settings/definitions/gocognitSettings"
+ },
+ "goconst": {
+ "$ref": "#/definitions/settings/definitions/goconstSettings"
+ },
+ "gocritic": {
+ "$ref": "#/definitions/settings/definitions/gocriticSettings"
+ },
+ "gocyclo": {
+ "$ref": "#/definitions/settings/definitions/gocycloSettings"
+ },
+ "godoclint": {
+ "$ref": "#/definitions/settings/definitions/godoclintSettings"
+ },
+ "godot": {
+ "$ref": "#/definitions/settings/definitions/godotSettings"
+ },
+ "godox": {
+ "$ref": "#/definitions/settings/definitions/godoxSettings"
+ },
+ "interfacebloat":{
+ "$ref": "#/definitions/settings/definitions/interfacebloatSettings"
+ },
+ "goheader": {
+ "$ref": "#/definitions/settings/definitions/goheaderSettings"
+ },
+ "gomoddirectives": {
+ "$ref": "#/definitions/settings/definitions/gomoddirectivesSettings"
+ },
+ "gomodguard": {
+ "$ref": "#/definitions/settings/definitions/gomodguardSettings"
+ },
+ "gosec": {
+ "$ref": "#/definitions/settings/definitions/gosecSettings"
+ },
+ "gosmopolitan": {
+ "$ref": "#/definitions/settings/definitions/gosmopolitanSettings"
+ },
+ "govet": {
+ "$ref": "#/definitions/settings/definitions/govetSettings"
+ },
+ "grouper": {
+ "$ref": "#/definitions/settings/definitions/grouperSettings"
+ },
+ "iface": {
+ "$ref": "#/definitions/settings/definitions/ifaceSettings"
+ },
+ "importas": {
+ "$ref": "#/definitions/settings/definitions/importasSettings"
+ },
+ "inamedparam": {
+ "$ref": "#/definitions/settings/definitions/inamedparamSettings"
+ },
+ "ineffassign": {
+ "$ref": "#/definitions/settings/definitions/ineffassignSettings"
+ },
+ "iotamixing": {
+ "$ref": "#/definitions/settings/definitions/iotamixingSettings"
+ },
+ "ireturn": {
+ "$ref": "#/definitions/settings/definitions/ireturnSettings"
+ },
+ "lll": {
+ "$ref": "#/definitions/settings/definitions/lllSettings"
+ },
+ "maintidx": {
+ "$ref": "#/definitions/settings/definitions/maintidxSettings"
+ },
+ "makezero":{
+ "$ref": "#/definitions/settings/definitions/makezeroSettings"
+ },
+ "loggercheck": {
+ "$ref": "#/definitions/settings/definitions/loggercheckSettings"
+ },
+ "misspell": {
+ "$ref": "#/definitions/settings/definitions/misspellSettings"
+ },
+ "musttag": {
+ "$ref": "#/definitions/settings/definitions/musttagSettings"
+ },
+ "nakedret": {
+ "$ref": "#/definitions/settings/definitions/nakedretSettings"
+ },
+ "nestif": {
+ "$ref": "#/definitions/settings/definitions/nestifSettings"
+ },
+ "nilnil": {
+ "$ref": "#/definitions/settings/definitions/nilnilSettings"
+ },
+ "nlreturn": {
+ "$ref": "#/definitions/settings/definitions/nlreturnSettings"
+ },
+ "mnd": {
+ "$ref": "#/definitions/settings/definitions/mndSettings"
+ },
+ "nolintlint":{
+ "$ref": "#/definitions/settings/definitions/nolintlintSettings"
+ },
+ "reassign": {
+ "$ref": "#/definitions/settings/definitions/reassignSettings"
+ },
+ "recvcheck": {
+ "$ref": "#/definitions/settings/definitions/recvcheckSettings"
+ },
+ "nonamedreturns": {
+ "$ref": "#/definitions/settings/definitions/nonamedreturnsSettings"
+ },
+ "paralleltest": {
+ "$ref": "#/definitions/settings/definitions/paralleltestSettings"
+ },
+ "perfsprint": {
+ "$ref": "#/definitions/settings/definitions/perfsprintSettings"
+ },
+ "prealloc": {
+ "$ref": "#/definitions/settings/definitions/preallocSettings"
+ },
+ "predeclared": {
+ "$ref": "#/definitions/settings/definitions/predeclaredSettings"
+ },
+ "promlinter": {
+ "$ref": "#/definitions/settings/definitions/promlinterSettings"
+ },
+ "protogetter": {
+ "$ref": "#/definitions/settings/definitions/protogetterSettings"
+ },
+ "revive": {
+ "$ref": "#/definitions/settings/definitions/reviveSettings"
+ },
+ "rowserrcheck": {
+ "$ref": "#/definitions/settings/definitions/rowserrcheckSettings"
+ },
+ "sloglint": {
+ "$ref": "#/definitions/settings/definitions/sloglintSettings"
+ },
+ "spancheck": {
+ "$ref": "#/definitions/settings/definitions/spancheckSettings"
+ },
+ "staticcheck":{
+ "$ref": "#/definitions/settings/definitions/staticcheckSettings"
+ },
+ "tagalign": {
+ "$ref": "#/definitions/settings/definitions/tagalignSettings"
+ },
+ "tagliatelle": {
+ "$ref": "#/definitions/settings/definitions/tagliatelleSettings"
+ },
+ "testifylint": {
+ "$ref": "#/definitions/settings/definitions/testifylintSettings"
+ },
+ "testpackage": {
+ "$ref": "#/definitions/settings/definitions/testpackageSettings"
+ },
+ "thelper": {
+ "$ref": "#/definitions/settings/definitions/thelperSettings"
+ },
+ "usestdlibvars": {
+ "$ref": "#/definitions/settings/definitions/usestdlibvarsSettings"
+ },
+ "usetesting": {
+ "$ref": "#/definitions/settings/definitions/usetestingSettings"
+ },
+ "unconvert": {
+ "$ref": "#/definitions/settings/definitions/unconvertSettings"
+ },
+ "unparam": {
+ "$ref": "#/definitions/settings/definitions/unparamSettings"
+ },
+ "unqueryvet": {
+ "$ref": "#/definitions/settings/definitions/unqueryvetSettings"
+ },
+ "unused": {
+ "$ref": "#/definitions/settings/definitions/unusedSettings"
+ },
+ "varnamelen": {
+ "$ref": "#/definitions/settings/definitions/varnamelenSettings"
+ },
+ "whitespace": {
+ "$ref": "#/definitions/settings/definitions/whitespaceSettings"
+ },
+ "wrapcheck": {
+ "$ref": "#/definitions/settings/definitions/wrapcheckSettings"
+ },
+ "wsl": {
+ "$ref": "#/definitions/settings/definitions/wslSettings"
+ },
+ "wsl_v5": {
+ "$ref": "#/definitions/settings/definitions/wslSettingsV5"
+ },
+ "copyloopvar": {
+ "$ref": "#/definitions/settings/definitions/copyloopvarSettings"
+ },
+ "custom":{
+ "$ref": "#/definitions/settings/definitions/customSettings"
+ }
+ }
+ },
+ "exclusions":{
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "generated": {
+ "enum": ["strict", "lax", "disable"],
+ "default": "strict"
+ },
+ "warn-unused": {
+ "type": "boolean",
+ "default": false
+ },
+ "presets": {
+ "type": "array",
+ "items": {
+ "enum": [
+ "comments",
+ "std-error-handling",
+ "common-false-positives",
+ "legacy"
+ ]
+ }
+ },
+ "rules": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "path": {
+ "type": "string"
+ },
+ "path-except": {
+ "type": "string"
+ },
+ "linters": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linter-names"
+ }
+ },
+ "text": {
+ "type": "string"
+ },
+ "source": {
+ "type": "string"
+ }
+ },
+ "anyOf": [
+ { "required": ["path"] },
+ { "required": ["path-except"] },
+ { "required": ["linters"] },
+ { "required": ["text"] },
+ { "required": ["source"] }
+ ]
+ }
+ },
+ "paths": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "paths-except": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "formatters": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "enable": {
+ "description": "List of enabled formatters.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/formatter-names"
+ }
+ },
+ "settings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "gci": {
+ "$ref": "#/definitions/settings/definitions/gciSettings"
+ },
+ "gofmt": {
+ "$ref": "#/definitions/settings/definitions/gofmtSettings"
+ },
+ "gofumpt": {
+ "$ref": "#/definitions/settings/definitions/gofumptSettings"
+ },
+ "goimports": {
+ "$ref": "#/definitions/settings/definitions/goimportsSettings"
+ },
+ "golines": {
+ "$ref": "#/definitions/settings/definitions/golinesSettings"
+ }
+ }
+ },
+ "exclusions": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "generated": {
+ "enum": ["strict", "lax", "disable"],
+ "default": "strict"
+ },
+ "paths": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "warn-unused": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ }
+ }
+ },
+ "issues": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-issues-per-linter": {
+ "description": "Maximum issues count per one linter. Set to 0 to disable.",
+ "type": "integer",
+ "default": 50,
+ "minimum": 0
+ },
+ "max-same-issues": {
+ "description": "Maximum count of issues with the same text. Set to 0 to disable.",
+ "type": "integer",
+ "default": 3,
+ "minimum": 0
+ },
+ "new": {
+ "description": "Show only new issues: if there are unstaged changes or untracked files, only those changes are analyzed, else only changes in HEAD~ are analyzed.",
+ "type": "boolean",
+ "default": false
+ },
+ "new-from-merge-base": {
+ "description": "Show only new issues created after the best common ancestor (merge-base against HEAD).",
+ "type": "string"
+ },
+ "new-from-rev": {
+ "description": "Show only new issues created after this git revision.",
+ "type": "string"
+ },
+ "new-from-patch": {
+ "description": "Show only new issues created in git patch with this file path.",
+ "type": "string",
+ "examples": ["path/to/patch/file"]
+ },
+ "fix": {
+ "description": "Fix found issues (if it's supported by the linter).",
+ "type": "boolean",
+ "default": false
+ },
+ "uniq-by-line": {
+ "description": "Make issues output unique by line.",
+ "type": "boolean",
+ "default": true
+ },
+ "whole-files": {
+ "description": "Show issues in any part of update files (requires new-from-rev or new-from-patch).",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "severity": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "default": {
+ "description": "Set the default severity for issues. If severity rules are defined and the issues do not match or no severity is provided to the rule this will be the default severity applied. Severities should match the supported severity names of the selected out format.",
+ "type": "string",
+ "default": ""
+ },
+ "rules": {
+ "description": "When a list of severity rules are provided, severity information will be added to lint issues. Severity rules have the same filtering capability as exclude rules except you are allowed to specify one matcher per severity rule.\nOnly affects out formats that support setting severity information.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "severity": {
+ "type": "string"
+ },
+ "path": {
+ "type": "string"
+ },
+ "path-except": {
+ "type": "string"
+ },
+ "linters": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linter-names"
+ }
+ },
+ "text": {
+ "type": "string"
+ },
+ "source": {
+ "type": "string"
+ }
+ },
+ "required": ["severity"],
+ "anyOf": [
+ { "required": ["path"] },
+ { "required": ["path-except"] },
+ { "required": ["linters"] },
+ { "required": ["text"] },
+ { "required": ["source"] }
+ ]
+ },
+ "default": []
+ }
+ },
+ "required": ["default"]
+ }
+ }
+}
diff --git a/vendor/github.com/golangci/golangci-lint/v2/jsonschema/golangci.v2.6.jsonschema.json b/vendor/github.com/golangci/golangci-lint/v2/jsonschema/golangci.v2.6.jsonschema.json
new file mode 100644
index 000000000..e2f59663e
--- /dev/null
+++ b/vendor/github.com/golangci/golangci-lint/v2/jsonschema/golangci.v2.6.jsonschema.json
@@ -0,0 +1,5136 @@
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "$id": "https://json.schemastore.org/golangci-lint.json",
+ "definitions": {
+ "gocritic-checks": {
+ "enum": [
+ "appendAssign",
+ "appendCombine",
+ "argOrder",
+ "assignOp",
+ "badCall",
+ "badCond",
+ "badLock",
+ "badRegexp",
+ "badSorting",
+ "badSyncOnceFunc",
+ "boolExprSimplify",
+ "builtinShadow",
+ "builtinShadowDecl",
+ "captLocal",
+ "caseOrder",
+ "codegenComment",
+ "commentFormatting",
+ "commentedOutCode",
+ "commentedOutImport",
+ "defaultCaseOrder",
+ "deferInLoop",
+ "deferUnlambda",
+ "deprecatedComment",
+ "docStub",
+ "dupArg",
+ "dupBranchBody",
+ "dupCase",
+ "dupImport",
+ "dupOption",
+ "dupSubExpr",
+ "dynamicFmtString",
+ "elseif",
+ "emptyDecl",
+ "emptyFallthrough",
+ "emptyStringTest",
+ "equalFold",
+ "evalOrder",
+ "exitAfterDefer",
+ "exposedSyncMutex",
+ "externalErrorReassign",
+ "filepathJoin",
+ "flagDeref",
+ "flagName",
+ "hexLiteral",
+ "httpNoBody",
+ "hugeParam",
+ "ifElseChain",
+ "importShadow",
+ "indexAlloc",
+ "initClause",
+ "mapKey",
+ "methodExprCall",
+ "nestingReduce",
+ "newDeref",
+ "nilValReturn",
+ "octalLiteral",
+ "offBy1",
+ "paramTypeCombine",
+ "preferDecodeRune",
+ "preferFilepathJoin",
+ "preferFprint",
+ "preferStringWriter",
+ "preferWriteByte",
+ "ptrToRefParam",
+ "rangeAppendAll",
+ "rangeExprCopy",
+ "rangeValCopy",
+ "redundantSprint",
+ "regexpMust",
+ "regexpPattern",
+ "regexpSimplify",
+ "returnAfterHttpError",
+ "ruleguard",
+ "singleCaseSwitch",
+ "sliceClear",
+ "sloppyLen",
+ "sloppyReassign",
+ "sloppyTypeAssert",
+ "sortSlice",
+ "sprintfQuotedString",
+ "sqlQuery",
+ "stringConcatSimplify",
+ "stringXbytes",
+ "stringsCompare",
+ "switchTrue",
+ "syncMapLoadAndDelete",
+ "timeExprSimplify",
+ "todoCommentWithoutDetail",
+ "tooManyResultsChecker",
+ "truncateCmp",
+ "typeAssertChain",
+ "typeDefFirst",
+ "typeSwitchVar",
+ "typeUnparen",
+ "uncheckedInlineErr",
+ "underef",
+ "unlabelStmt",
+ "unlambda",
+ "unnamedResult",
+ "unnecessaryBlock",
+ "unnecessaryDefer",
+ "unslice",
+ "valSwap",
+ "weakCond",
+ "whyNoLint",
+ "wrapperFunc",
+ "yodaStyleExpr",
+ "zeroByteRepeat"
+ ]
+ },
+ "gocritic-tags": {
+ "enum": [
+ "diagnostic",
+ "style",
+ "performance",
+ "experimental",
+ "opinionated",
+ "security"
+ ]
+ },
+ "staticcheck-checks": {
+ "enum": [
+ "*",
+ "all",
+ "SA*",
+ "-SA*",
+ "SA1*",
+ "-SA1*",
+ "SA1000",
+ "-SA1000",
+ "SA1001",
+ "-SA1001",
+ "SA1002",
+ "-SA1002",
+ "SA1003",
+ "-SA1003",
+ "SA1004",
+ "-SA1004",
+ "SA1005",
+ "-SA1005",
+ "SA1006",
+ "-SA1006",
+ "SA1007",
+ "-SA1007",
+ "SA1008",
+ "-SA1008",
+ "SA1010",
+ "-SA1010",
+ "SA1011",
+ "-SA1011",
+ "SA1012",
+ "-SA1012",
+ "SA1013",
+ "-SA1013",
+ "SA1014",
+ "-SA1014",
+ "SA1015",
+ "-SA1015",
+ "SA1016",
+ "-SA1016",
+ "SA1017",
+ "-SA1017",
+ "SA1018",
+ "-SA1018",
+ "SA1019",
+ "-SA1019",
+ "SA1020",
+ "-SA1020",
+ "SA1021",
+ "-SA1021",
+ "SA1023",
+ "-SA1023",
+ "SA1024",
+ "-SA1024",
+ "SA1025",
+ "-SA1025",
+ "SA1026",
+ "-SA1026",
+ "SA1027",
+ "-SA1027",
+ "SA1028",
+ "-SA1028",
+ "SA1029",
+ "-SA1029",
+ "SA1030",
+ "-SA1030",
+ "SA1031",
+ "-SA1031",
+ "SA1032",
+ "-SA1032",
+ "SA2*",
+ "-SA2*",
+ "SA2000",
+ "-SA2000",
+ "SA2001",
+ "-SA2001",
+ "SA2002",
+ "-SA2002",
+ "SA2003",
+ "-SA2003",
+ "SA3*",
+ "-SA3*",
+ "SA3000",
+ "-SA3000",
+ "SA3001",
+ "-SA3001",
+ "SA4*",
+ "-SA4*",
+ "SA4000",
+ "-SA4000",
+ "SA4001",
+ "-SA4001",
+ "SA4003",
+ "-SA4003",
+ "SA4004",
+ "-SA4004",
+ "SA4005",
+ "-SA4005",
+ "SA4006",
+ "-SA4006",
+ "SA4008",
+ "-SA4008",
+ "SA4009",
+ "-SA4009",
+ "SA4010",
+ "-SA4010",
+ "SA4011",
+ "-SA4011",
+ "SA4012",
+ "-SA4012",
+ "SA4013",
+ "-SA4013",
+ "SA4014",
+ "-SA4014",
+ "SA4015",
+ "-SA4015",
+ "SA4016",
+ "-SA4016",
+ "SA4017",
+ "-SA4017",
+ "SA4018",
+ "-SA4018",
+ "SA4019",
+ "-SA4019",
+ "SA4020",
+ "-SA4020",
+ "SA4021",
+ "-SA4021",
+ "SA4022",
+ "-SA4022",
+ "SA4023",
+ "-SA4023",
+ "SA4024",
+ "-SA4024",
+ "SA4025",
+ "-SA4025",
+ "SA4026",
+ "-SA4026",
+ "SA4027",
+ "-SA4027",
+ "SA4028",
+ "-SA4028",
+ "SA4029",
+ "-SA4029",
+ "SA4030",
+ "-SA4030",
+ "SA4031",
+ "-SA4031",
+ "SA4032",
+ "-SA4032",
+ "SA5*",
+ "-SA5*",
+ "SA5000",
+ "-SA5000",
+ "SA5001",
+ "-SA5001",
+ "SA5002",
+ "-SA5002",
+ "SA5003",
+ "-SA5003",
+ "SA5004",
+ "-SA5004",
+ "SA5005",
+ "-SA5005",
+ "SA5007",
+ "-SA5007",
+ "SA5008",
+ "-SA5008",
+ "SA5009",
+ "-SA5009",
+ "SA5010",
+ "-SA5010",
+ "SA5011",
+ "-SA5011",
+ "SA5012",
+ "-SA5012",
+ "SA6*",
+ "-SA6*",
+ "SA6000",
+ "-SA6000",
+ "SA6001",
+ "-SA6001",
+ "SA6002",
+ "-SA6002",
+ "SA6003",
+ "-SA6003",
+ "SA6005",
+ "-SA6005",
+ "SA6006",
+ "-SA6006",
+ "SA9*",
+ "-SA9*",
+ "SA9001",
+ "-SA9001",
+ "SA9002",
+ "-SA9002",
+ "SA9003",
+ "-SA9003",
+ "SA9004",
+ "-SA9004",
+ "SA9005",
+ "-SA9005",
+ "SA9006",
+ "-SA9006",
+ "SA9007",
+ "-SA9007",
+ "SA9008",
+ "-SA9008",
+ "SA9009",
+ "-SA9009",
+ "ST*",
+ "-ST*",
+ "ST1*",
+ "-ST1*",
+ "ST1000",
+ "-ST1000",
+ "ST1001",
+ "-ST1001",
+ "ST1003",
+ "-ST1003",
+ "ST1005",
+ "-ST1005",
+ "ST1006",
+ "-ST1006",
+ "ST1008",
+ "-ST1008",
+ "ST1011",
+ "-ST1011",
+ "ST1012",
+ "-ST1012",
+ "ST1013",
+ "-ST1013",
+ "ST1015",
+ "-ST1015",
+ "ST1016",
+ "-ST1016",
+ "ST1017",
+ "-ST1017",
+ "ST1018",
+ "-ST1018",
+ "ST1019",
+ "-ST1019",
+ "ST1020",
+ "-ST1020",
+ "ST1021",
+ "-ST1021",
+ "ST1022",
+ "-ST1022",
+ "ST1023",
+ "-ST1023",
+ "S*",
+ "-S*",
+ "S1*",
+ "-S1*",
+ "S1000",
+ "-S1000",
+ "S1001",
+ "-S1001",
+ "S1002",
+ "-S1002",
+ "S1003",
+ "-S1003",
+ "S1004",
+ "-S1004",
+ "S1005",
+ "-S1005",
+ "S1006",
+ "-S1006",
+ "S1007",
+ "-S1007",
+ "S1008",
+ "-S1008",
+ "S1009",
+ "-S1009",
+ "S1010",
+ "-S1010",
+ "S1011",
+ "-S1011",
+ "S1012",
+ "-S1012",
+ "S1016",
+ "-S1016",
+ "S1017",
+ "-S1017",
+ "S1018",
+ "-S1018",
+ "S1019",
+ "-S1019",
+ "S1020",
+ "-S1020",
+ "S1021",
+ "-S1021",
+ "S1023",
+ "-S1023",
+ "S1024",
+ "-S1024",
+ "S1025",
+ "-S1025",
+ "S1028",
+ "-S1028",
+ "S1029",
+ "-S1029",
+ "S1030",
+ "-S1030",
+ "S1031",
+ "-S1031",
+ "S1032",
+ "-S1032",
+ "S1033",
+ "-S1033",
+ "S1034",
+ "-S1034",
+ "S1035",
+ "-S1035",
+ "S1036",
+ "-S1036",
+ "S1037",
+ "-S1037",
+ "S1038",
+ "-S1038",
+ "S1039",
+ "-S1039",
+ "S1040",
+ "-S1040",
+ "QF*",
+ "-QF*",
+ "QF1*",
+ "-QF1*",
+ "QF1001",
+ "-QF1001",
+ "QF1002",
+ "-QF1002",
+ "QF1003",
+ "-QF1003",
+ "QF1004",
+ "-QF1004",
+ "QF1005",
+ "-QF1005",
+ "QF1006",
+ "-QF1006",
+ "QF1007",
+ "-QF1007",
+ "QF1008",
+ "-QF1008",
+ "QF1009",
+ "-QF1009",
+ "QF1010",
+ "-QF1010",
+ "QF1011",
+ "-QF1011",
+ "QF1012",
+ "-QF1012"
+ ]
+ },
+ "godoclint-rules": {
+ "enum": [
+ "pkg-doc",
+ "single-pkg-doc",
+ "require-pkg-doc",
+ "start-with-name",
+ "require-doc",
+ "deprecated",
+ "max-len",
+ "no-unused-link"
+ ]
+ },
+ "gosec-rules": {
+ "enum": [
+ "G101",
+ "G102",
+ "G103",
+ "G104",
+ "G106",
+ "G107",
+ "G108",
+ "G109",
+ "G110",
+ "G111",
+ "G112",
+ "G114",
+ "G115",
+ "G201",
+ "G202",
+ "G203",
+ "G204",
+ "G301",
+ "G302",
+ "G303",
+ "G304",
+ "G305",
+ "G306",
+ "G307",
+ "G401",
+ "G402",
+ "G403",
+ "G404",
+ "G405",
+ "G406",
+ "G501",
+ "G502",
+ "G503",
+ "G504",
+ "G505",
+ "G506",
+ "G507",
+ "G601",
+ "G602"
+ ]
+ },
+ "govet-analyzers": {
+ "enum": [
+ "appends",
+ "asmdecl",
+ "assign",
+ "atomic",
+ "atomicalign",
+ "bools",
+ "buildtag",
+ "cgocall",
+ "composites",
+ "copylocks",
+ "deepequalerrors",
+ "defers",
+ "directive",
+ "errorsas",
+ "fieldalignment",
+ "findcall",
+ "framepointer",
+ "hostport",
+ "httpmux",
+ "httpresponse",
+ "ifaceassert",
+ "loopclosure",
+ "lostcancel",
+ "nilfunc",
+ "nilness",
+ "printf",
+ "reflectvaluecompare",
+ "shadow",
+ "shift",
+ "sigchanyzer",
+ "slog",
+ "sortslice",
+ "stdmethods",
+ "stdversion",
+ "stringintconv",
+ "structtag",
+ "testinggoroutine",
+ "tests",
+ "timeformat",
+ "unmarshal",
+ "unreachable",
+ "unsafeptr",
+ "unusedresult",
+ "unusedwrite",
+ "waitgroup"
+ ]
+ },
+ "revive-rules": {
+ "enum": [
+ "add-constant",
+ "argument-limit",
+ "atomic",
+ "banned-characters",
+ "bare-return",
+ "blank-imports",
+ "bool-literal-in-expr",
+ "call-to-gc",
+ "cognitive-complexity",
+ "comment-spacings",
+ "comments-density",
+ "confusing-naming",
+ "confusing-results",
+ "constant-logical-expr",
+ "context-as-argument",
+ "context-keys-type",
+ "cyclomatic",
+ "datarace",
+ "deep-exit",
+ "defer",
+ "dot-imports",
+ "duplicated-imports",
+ "early-return",
+ "empty-block",
+ "empty-lines",
+ "enforce-map-style",
+ "enforce-repeated-arg-type-style",
+ "enforce-slice-style",
+ "enforce-switch-style",
+ "error-naming",
+ "error-return",
+ "error-strings",
+ "errorf",
+ "exported",
+ "file-header",
+ "file-length-limit",
+ "filename-format",
+ "flag-parameter",
+ "function-length",
+ "function-result-limit",
+ "get-return",
+ "identical-branches",
+ "identical-ifelseif-branches",
+ "identical-ifelseif-conditions",
+ "identical-switch-branches",
+ "identical-switch-conditions",
+ "if-return",
+ "import-alias-naming",
+ "import-shadowing",
+ "imports-blocklist",
+ "increment-decrement",
+ "indent-error-flow",
+ "line-length-limit",
+ "max-control-nesting",
+ "max-public-structs",
+ "modifies-parameter",
+ "modifies-value-receiver",
+ "nested-structs",
+ "optimize-operands-order",
+ "package-comments",
+ "package-directory-mismatch",
+ "range-val-address",
+ "range-val-in-closure",
+ "range",
+ "receiver-naming",
+ "redefines-builtin-id",
+ "redundant-build-tag",
+ "redundant-import-alias",
+ "redundant-test-main-exit",
+ "string-format",
+ "string-of-int",
+ "struct-tag",
+ "superfluous-else",
+ "time-date",
+ "time-equal",
+ "time-naming",
+ "unchecked-type-assertion",
+ "unconditional-recursion",
+ "unexported-naming",
+ "unexported-return",
+ "unhandled-error",
+ "unnecessary-format",
+ "unnecessary-stmt",
+ "unreachable-code",
+ "unsecure-url-scheme",
+ "unused-parameter",
+ "unused-receiver",
+ "use-any",
+ "use-errors-new",
+ "use-fmt-print",
+ "use-waitgroup-go",
+ "useless-break",
+ "useless-fallthrough",
+ "var-declaration",
+ "var-naming",
+ "waitgroup-by-value"
+ ]
+ },
+ "iface-analyzers": {
+ "enum": [
+ "identical",
+ "unused",
+ "opaque",
+ "unexported"
+ ]
+ },
+ "tagliatelle-cases": {
+ "enum": [
+ "",
+ "camel",
+ "pascal",
+ "kebab",
+ "snake",
+ "goCamel",
+ "goPascal",
+ "goKebab",
+ "goSnake",
+ "upper",
+ "upperSnake",
+ "lower",
+ "header"
+ ]
+ },
+ "modernize-analyzers": {
+ "enum": [
+ "any",
+ "bloop",
+ "fmtappendf",
+ "forvar",
+ "mapsloop",
+ "minmax",
+ "newexpr",
+ "omitzero",
+ "rangeint",
+ "reflecttypefor",
+ "slicescontains",
+ "slicessort",
+ "stditerators",
+ "stringscutprefix",
+ "stringsseq",
+ "stringsbuilder",
+ "testingcontext",
+ "waitgroup"
+ ]
+ },
+ "wsl-checks": {
+ "enum": [
+ "assign",
+ "branch",
+ "decl",
+ "defer",
+ "expr",
+ "for",
+ "go",
+ "if",
+ "inc-dec",
+ "label",
+ "range",
+ "return",
+ "select",
+ "send",
+ "switch",
+ "type-switch",
+ "append",
+ "assign-exclusive",
+ "assign-expr",
+ "err",
+ "leading-whitespace",
+ "trailing-whitespace"
+ ]
+ },
+ "relative-path-modes": {
+ "enum": [
+ "gomod",
+ "gitroot",
+ "cfg",
+ "wd"
+ ]
+ },
+ "simple-format": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "path": {
+ "$ref": "#/definitions/formats-path",
+ "default": "stdout"
+ }
+ }
+ },
+ "formats-path" : {
+ "anyOf": [
+ {
+ "enum": [
+ "stdout",
+ "stderr"
+ ]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ },
+ "linter-names": {
+ "$comment": "anyOf with enum is used to allow auto-completion of non-custom linters",
+ "description": "Usable linter names.",
+ "anyOf": [
+ {
+ "enum": [
+ "arangolint",
+ "asasalint",
+ "asciicheck",
+ "bidichk",
+ "bodyclose",
+ "canonicalheader",
+ "containedctx",
+ "contextcheck",
+ "copyloopvar",
+ "cyclop",
+ "decorder",
+ "depguard",
+ "dogsled",
+ "dupl",
+ "dupword",
+ "durationcheck",
+ "embeddedstructfieldcheck",
+ "errcheck",
+ "errchkjson",
+ "errname",
+ "errorlint",
+ "exhaustive",
+ "exhaustruct",
+ "exptostd",
+ "fatcontext",
+ "forbidigo",
+ "forcetypeassert",
+ "funcorder",
+ "funlen",
+ "ginkgolinter",
+ "gocheckcompilerdirectives",
+ "gochecknoglobals",
+ "gochecknoinits",
+ "gochecksumtype",
+ "gocognit",
+ "goconst",
+ "gocritic",
+ "gocyclo",
+ "godoclint",
+ "godot",
+ "godox",
+ "err113",
+ "goheader",
+ "gomoddirectives",
+ "gomodguard",
+ "goprintffuncname",
+ "gosec",
+ "gosimple",
+ "gosmopolitan",
+ "govet",
+ "grouper",
+ "iface",
+ "importas",
+ "inamedparam",
+ "ineffassign",
+ "interfacebloat",
+ "intrange",
+ "iotamixing",
+ "ireturn",
+ "lll",
+ "loggercheck",
+ "maintidx",
+ "makezero",
+ "mirror",
+ "misspell",
+ "mnd",
+ "modernize",
+ "musttag",
+ "nakedret",
+ "nestif",
+ "nilerr",
+ "nilnesserr",
+ "nilnil",
+ "nlreturn",
+ "noctx",
+ "noinlineerr",
+ "nolintlint",
+ "nonamedreturns",
+ "nosprintfhostport",
+ "paralleltest",
+ "perfsprint",
+ "prealloc",
+ "predeclared",
+ "promlinter",
+ "protogetter",
+ "reassign",
+ "recvcheck",
+ "revive",
+ "rowserrcheck",
+ "sloglint",
+ "sqlclosecheck",
+ "staticcheck",
+ "stylecheck",
+ "tagalign",
+ "tagliatelle",
+ "testableexamples",
+ "testifylint",
+ "testpackage",
+ "thelper",
+ "tparallel",
+ "unconvert",
+ "unparam",
+ "unused",
+ "usestdlibvars",
+ "usetesting",
+ "varnamelen",
+ "wastedassign",
+ "whitespace",
+ "wrapcheck",
+ "wsl",
+ "wsl_v5",
+ "zerologlint"
+ ]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ },
+ "formatter-names": {
+ "description": "Usable formatter names.",
+ "enum": [
+ "gci",
+ "gofmt",
+ "gofumpt",
+ "goimports",
+ "golines",
+ "swaggo"
+ ]
+ },
+ "settings": {
+ "definitions": {
+ "dupwordSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "keywords": {
+ "description": "Keywords for detecting duplicate words. If this list is not empty, only the words defined in this list will be detected.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["the", "and", "a"]
+ }
+ },
+ "ignore": {
+ "description": "Keywords used to ignore detection.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["0C0C"]
+ }
+ },
+ "comments-only": {
+ "description": "Checks only comments, skip strings.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "asasalintSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "exclude": {
+ "description": "To specify a set of function names to exclude.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["\\.Wrapf"]
+ }
+ },
+ "use-builtin-exclusions": {
+ "description": "To enable/disable the asasalint builtin exclusions of function names.",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "bidichkSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "left-to-right-embedding": {
+ "description": "Disallow: LEFT-TO-RIGHT-EMBEDDING",
+ "type": "boolean",
+ "default": false
+ },
+ "right-to-left-embedding": {
+ "description": "Disallow: RIGHT-TO-LEFT-EMBEDDING",
+ "type": "boolean",
+ "default": false
+ },
+ "pop-directional-formatting": {
+ "description": "Disallow: POP-DIRECTIONAL-FORMATTING",
+ "type": "boolean",
+ "default": false
+ },
+ "left-to-right-override": {
+ "description": "Disallow: LEFT-TO-RIGHT-OVERRIDE",
+ "type": "boolean",
+ "default": false
+ },
+ "right-to-left-override": {
+ "description": "Disallow: RIGHT-TO-LEFT-OVERRIDE",
+ "type": "boolean",
+ "default": false
+ },
+ "left-to-right-isolate": {
+ "description": "Disallow: LEFT-TO-RIGHT-ISOLATE",
+ "type": "boolean",
+ "default": false
+ },
+ "right-to-left-isolate": {
+ "description": "Disallow: RIGHT-TO-LEFT-ISOLATE",
+ "type": "boolean",
+ "default": false
+ },
+ "first-strong-isolate": {
+ "description": "Disallow: FIRST-STRONG-ISOLATE",
+ "type": "boolean",
+ "default": false
+ },
+ "pop-directional-isolate": {
+ "description": "Disallow: POP-DIRECTIONAL-ISOLATE",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "cyclopSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-complexity": {
+ "description": "Max complexity the function can have",
+ "type": "integer",
+ "default": 10,
+ "minimum": 0
+ },
+ "package-average": {
+ "description": "Max average complexity in package",
+ "type": "number",
+ "default": 0,
+ "minimum": 0
+ }
+ }
+ },
+ "decorderSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "dec-order": {
+ "type": "array",
+ "default": [["type", "const", "var", "func"]],
+ "items": {
+ "enum": ["type", "const", "var", "func"]
+ }
+ },
+ "ignore-underscore-vars": {
+ "description": "Underscore vars (vars with \"_\" as the name) will be ignored at all checks",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-dec-order-check": {
+ "description": "Order of declarations is not checked",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-init-func-first-check": {
+ "description": "Allow init func to be anywhere in file",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-dec-num-check": {
+ "description": "Multiple global type, const and var declarations are allowed",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-type-dec-num-check": {
+ "description": "Type declarations will be ignored for dec num check",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-const-dec-num-check": {
+ "description": "Const declarations will be ignored for dec num check",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-var-dec-num-check": {
+ "description": "Var declarations will be ignored for dec num check",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ },
+ "depguardSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "rules": {
+ "description": "Rules to apply.",
+ "type": "object",
+ "additionalProperties": false,
+ "patternProperties": {
+ "^[^.]+$": {
+ "description": "Name of a rule.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "list-mode": {
+ "description": "Used to determine the package matching priority.",
+ "enum": ["original", "strict", "lax"],
+ "default": "original"
+ },
+ "files": {
+ "description": "List of file globs that will match this list of settings to compare against.",
+ "additionalProperties": false,
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "allow": {
+ "description": "List of allowed packages.",
+ "additionalProperties": false,
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "deny": {
+ "description": "Packages that are not allowed where the value is a suggestion.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "desc": {
+ "description": "Description",
+ "type": "string"
+ },
+ "pkg": {
+ "description": "Package",
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "dogsledSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-blank-identifiers": {
+ "description": "Check assignments with too many blank identifiers.",
+ "type": "integer",
+ "default": 2,
+ "minimum": 0
+ }
+ }
+ },
+ "duplSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "threshold": {
+ "description": "Tokens count to trigger issue.",
+ "type": "integer",
+ "default": 150,
+ "minimum": 0
+ }
+ }
+ },
+ "embeddedstructfieldcheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "empty-line": {
+ "description": "Checks that there is an empty space between the embedded fields and regular fields.",
+ "type": "boolean",
+ "default": false
+ },
+ "forbid-mutex": {
+ "description": "Checks that sync.Mutex and sync.RWMutex are not used as embedded fields.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "errcheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-type-assertions": {
+ "description": "Report about not checking errors in type assertions, i.e.: `a := b.(MyStruct)`",
+ "type": "boolean",
+ "default": false
+ },
+ "check-blank": {
+ "description": "Report about assignment of errors to blank identifier",
+ "type": "boolean",
+ "default": false
+ },
+ "exclude-functions": {
+ "description": "List of functions to exclude from checking, where each entry is a single function to exclude",
+ "type": "array",
+ "examples": ["io/ioutil.ReadFile", "io.Copy(*bytes.Buffer)"],
+ "items": {
+ "type": "string"
+ }
+ },
+ "disable-default-exclusions": {
+ "description": "To disable the errcheck built-in exclude list",
+ "type": "boolean",
+ "default": false
+ },
+ "verbose": {
+ "description": "Display function signature instead of selector",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "errchkjsonSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-error-free-encoding": {
+ "type": "boolean",
+ "default": false
+ },
+ "report-no-exported": {
+ "description": "Issue on struct that doesn't have exported fields.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "errorlintSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "errorf": {
+ "description": "Check whether fmt.Errorf uses the %w verb for formatting errors",
+ "type": "boolean",
+ "default": true
+ },
+ "errorf-multi": {
+ "description": "Permit more than 1 %w verb, valid per Go 1.20",
+ "type": "boolean",
+ "default": true
+ },
+ "asserts": {
+ "description": "Check for plain type assertions and type switches.",
+ "type": "boolean",
+ "default": true
+ },
+ "comparison": {
+ "description": "Check for plain error comparisons",
+ "type": "boolean",
+ "default": true
+ },
+ "allowed-errors": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "err": {
+ "type": "string"
+ },
+ "fun": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "allowed-errors-wildcard": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "err": {
+ "type": "string"
+ },
+ "fun": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "exhaustiveSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check": {
+ "description": "Program elements to check for exhaustiveness.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["switch", "map"]
+ }
+ },
+ "explicit-exhaustive-switch": {
+ "description": "Only run exhaustive check on switches with \"//exhaustive:enforce\" comment.",
+ "type": "boolean",
+ "default": false
+ },
+ "explicit-exhaustive-map": {
+ "description": "Only run exhaustive check on map literals with \"//exhaustive:enforce\" comment.",
+ "type": "boolean",
+ "default": false
+ },
+ "default-case-required": {
+ "description": "Switch statement requires default case even if exhaustive.",
+ "type": "boolean",
+ "default": false
+ },
+ "default-signifies-exhaustive": {
+ "description": "Presence of `default` case in switch statements satisfies exhaustiveness, even if all enum members are not listed.",
+ "type": "boolean",
+ "default": false
+ },
+ "ignore-enum-members": {
+ "description": "Enum members matching `regex` do not have to be listed in switch statements to satisfy exhaustiveness",
+ "type": "string"
+ },
+ "ignore-enum-types": {
+ "description": "Enum types matching the supplied regex do not have to be listed in switch statements to satisfy exhaustiveness.",
+ "type": "string"
+ },
+ "package-scope-only": {
+ "description": "Consider enums only in package scopes, not in inner scopes.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "exhaustructSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "include": {
+ "description": "List of regular expressions to match struct packages and names.",
+ "type": "array",
+ "examples": [".*\\.Test"],
+ "items": {
+ "type": "string"
+ }
+ },
+ "exclude": {
+ "description": "List of regular expressions to exclude struct packages and names from check.",
+ "type": "array",
+ "examples": ["cobra\\.Command$"],
+ "items": {
+ "type": "string"
+ }
+ },
+ "allow-empty": {
+ "description": "Allows empty structures, effectively excluding them from the check.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-empty-rx": {
+ "description": "List of regular expressions to match type names that should be allowed to be empty.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "allow-empty-returns": {
+ "description": "Allows empty structures in return statements.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-empty-declarations": {
+ "description": "Allows empty structures in variable declarations.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "fatcontextSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-struct-pointers": {
+ "description": "Check for potential fat contexts in struct pointers.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "forbidigoSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "exclude-godoc-examples": {
+ "description": "Exclude code in godoc examples.",
+ "type": "boolean",
+ "default": true
+ },
+ "analyze-types": {
+ "description": "Instead of matching the literal source code, use type information to replace expressions with strings that contain the package name and (for methods and fields) the type name.",
+ "type": "boolean",
+ "default": true
+ },
+ "forbid": {
+ "description": "List of identifiers to forbid (written using `regexp`)",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "pattern": {
+ "description": "Pattern",
+ "type": "string"
+ },
+ "pkg": {
+ "description": "Package",
+ "type": "string"
+ },
+ "msg": {
+ "description": "Message",
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "funcorderSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "constructor": {
+ "description": "Checks that constructors are placed after the structure declaration.",
+ "type": "boolean",
+ "default": true
+ },
+ "struct-method": {
+ "description": "Checks if the exported methods of a structure are placed before the non-exported ones.",
+ "type": "boolean",
+ "default": true
+ },
+ "alphabetical": {
+ "description": "Checks if the constructors and/or structure methods are sorted alphabetically.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "funlenSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "lines": {
+ "description": "Limit lines number per function.",
+ "type": "integer",
+ "default": 60
+ },
+ "statements": {
+ "description": "Limit statements number per function.",
+ "type": "integer",
+ "default": 40
+ },
+ "ignore-comments": {
+ "description": "Ignore comments when counting lines.",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "gciSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "sections": {
+ "description": "Section configuration to compare against.",
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "enum": [
+ "standard",
+ "default",
+ "blank",
+ "dot",
+ "alias",
+ "localmodule"
+ ]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ },
+ "default": ["standard", "default"]
+ },
+ "no-inline-comments": {
+ "description": "Checks that no inline Comments are present.",
+ "type": "boolean",
+ "default": false
+ },
+ "no-prefix-comments": {
+ "description": "Checks that no prefix Comments(comment lines above an import) are present.",
+ "type": "boolean",
+ "default": false
+ },
+ "custom-order": {
+ "description": "Enable custom order of sections.",
+ "type": "boolean",
+ "default": false
+ },
+ "no-lex-order": {
+ "description": "Drops lexical ordering for custom sections.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "ginkgolinterSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "suppress-len-assertion": {
+ "description": "Suppress the wrong length assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-nil-assertion": {
+ "description": "Suppress the wrong nil assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-err-assertion": {
+ "description": "Suppress the wrong error assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-compare-assertion": {
+ "description": "Suppress the wrong comparison assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-async-assertion": {
+ "description": "Suppress the function all in async assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-type-compare-assertion": {
+ "description": "Suppress warning for comparing values from different types, like int32 and uint32.",
+ "type": "boolean",
+ "default": false
+ },
+ "forbid-focus-container": {
+ "description": "Trigger warning for ginkgo focus containers like FDescribe, FContext, FWhen or FIt.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-havelen-zero": {
+ "description": "Don't trigger warnings for HaveLen(0).",
+ "type": "boolean",
+ "default": false
+ },
+ "force-expect-to": {
+ "description": "Force using `Expect` with `To`, `ToNot` or `NotTo`",
+ "type": "boolean",
+ "default": false
+ },
+ "validate-async-intervals": {
+ "description": "Best effort validation of async intervals (timeout and polling).",
+ "type": "boolean",
+ "default": false
+ },
+ "forbid-spec-pollution": {
+ "description": "Trigger a warning for variable assignments in ginkgo containers like `Describe`, `Context` and `When`, instead of in `BeforeEach()`.",
+ "type": "boolean",
+ "default": false
+ },
+ "force-succeed": {
+ "description": "Force using the Succeed matcher for error functions, and the HaveOccurred matcher for non-function error values.",
+ "type": "boolean",
+ "default": false
+ },
+ "force-assertion-description": {
+ "description": "Force adding assertion descriptions to gomega matchers.",
+ "type": "boolean",
+ "default": false
+ },
+ "force-tonot": {
+ "description": "Force using `ToNot`, `ShouldNot` instead of `To(Not())`.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "gochecksumtypeSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "default-signifies-exhaustive": {
+ "description": "Presence of `default` case in switch statements satisfies exhaustiveness, if all members are not listed.",
+ "type": "boolean",
+ "default": true
+ },
+ "include-shared-interfaces": {
+ "description": "Include shared interfaces in the exhaustiviness check.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "gocognitSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "min-complexity": {
+ "description": "Minimal code complexity to report (we recommend 10-20).",
+ "type": "integer",
+ "default": 30
+ }
+ }
+ },
+ "goconstSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "match-constant": {
+ "description": "Look for existing constants matching the values",
+ "type": "boolean",
+ "default": true
+ },
+ "min-len": {
+ "description": "Minimum length of string constant.",
+ "type": "integer",
+ "default": 3
+ },
+ "min-occurrences": {
+ "description": "Minimum occurrences count to trigger.",
+ "type": "integer",
+ "default": 3
+ },
+ "ignore-calls": {
+ "description": "Ignore when constant is not used as function argument",
+ "type": "boolean",
+ "default": true
+ },
+ "ignore-string-values": {
+ "description": "Exclude strings matching the given regular expression",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "numbers": {
+ "description": "Search also for duplicated numbers.",
+ "type": "boolean",
+ "default": false
+ },
+ "min": {
+ "description": "Minimum value, only works with `numbers`",
+ "type": "integer",
+ "default": 3
+ },
+ "max": {
+ "description": "Maximum value, only works with `numbers`",
+ "type": "integer",
+ "default": 3
+ },
+ "find-duplicates": {
+ "description": "Detects constants with identical values",
+ "type": "boolean",
+ "default": false
+ },
+ "eval-const-expressions": {
+ "description": "Evaluates of constant expressions like Prefix + \"suffix\"",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "gocriticSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "enabled-checks": {
+ "description": "Which checks should be enabled. By default, a list of stable checks is used. To see it, run `GL_DEBUG=gocritic golangci-lint run`.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/gocritic-checks"
+ }
+ },
+ "disabled-checks": {
+ "description": "Which checks should be disabled.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/gocritic-checks"
+ },
+ "default": []
+ },
+ "enabled-tags": {
+ "description": "Enable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/gocritic-tags"
+ }
+ },
+ "disabled-tags": {
+ "description": "Disable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/gocritic-tags"
+ }
+ },
+ "settings": {
+ "description": "Settings passed to gocritic. Properties must be valid and enabled check names.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "captLocal": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "paramsOnly" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "commentedOutCode": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "minLength" : {
+ "type": "number",
+ "default": 15
+ }
+ }
+ },
+ "elseif": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skipBalanced" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "hugeParam": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "sizeThreshold" : {
+ "type": "number",
+ "default": 80
+ }
+ }
+ },
+ "ifElseChain": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "minThreshold" : {
+ "type": "number",
+ "default": 2
+ }
+ }
+ },
+ "nestingReduce": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "bodyWidth" : {
+ "type": "number",
+ "default": 5
+ }
+ }
+ },
+ "rangeExprCopy": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "sizeThreshold" : {
+ "type": "number",
+ "default": 512
+ },
+ "skipTestFuncs" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "rangeValCopy": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "sizeThreshold" : {
+ "type": "number",
+ "default": 128
+ },
+ "skipTestFuncs" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "ruleguard": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "debug" : {
+ "type": "string"
+ },
+ "enable" : {
+ "type": "string"
+ },
+ "disable" : {
+ "type": "string"
+ },
+ "failOn" : {
+ "type": "string"
+ },
+ "rules" : {
+ "type": "string"
+ }
+ }
+ },
+ "tooManyResultsChecker": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "maxResults" : {
+ "type": "number",
+ "default": 5
+ }
+ }
+ },
+ "truncateCmp": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skipArchDependent" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "underef": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skipRecvDeref" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "unnamedResult": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "checkExported" : {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ }
+ }
+ },
+ "disable-all": {
+ "type": "boolean",
+ "default": false
+ },
+ "enable-all": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "gocycloSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "min-complexity": {
+ "description": "Minimum code complexity to report (we recommend 10-20).",
+ "type": "integer",
+ "default": 30
+ }
+ }
+ },
+ "godoclintSettings": {
+ "type": "object",
+ "properties": {
+ "default": {
+ "type": "string",
+ "enum": ["all", "basic", "none"],
+ "default": "basic",
+ "description": "Default set of rules to enable."
+ },
+ "enable": {
+ "description": "List of rules to enable in addition to the default set.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "$ref": "#/definitions/godoclint-rules"
+ }
+ },
+ "disable": {
+ "description": "List of rules to disable.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "$ref": "#/definitions/godoclint-rules"
+ }
+ },
+ "options": {
+ "type": "object",
+ "description": "A map for setting individual rule options.",
+ "properties": {
+ "max-len": {
+ "type": "object",
+ "properties": {
+ "length": {
+ "type": "integer",
+ "description": "Maximum line length for godocs, not including the `// `, or `/*` or `*/` tokens.",
+ "default": 77
+ }
+ }
+ },
+ "require-doc": {
+ "type": "object",
+ "properties": {
+ "ignore-exported": {
+ "type": "boolean",
+ "description": "Ignore exported (public) symbols when applying the `require-doc` rule.",
+ "default": false
+ },
+ "ignore-unexported": {
+ "type": "boolean",
+ "description": "Ignore unexported (private) symbols when applying the `require-doc` rule.",
+ "default": true
+ }
+ }
+ },
+ "start-with-name": {
+ "type": "object",
+ "properties": {
+ "include-unexported": {
+ "type": "boolean",
+ "description": "Include unexported symbols when applying the `start-with-name` rule.",
+ "default": false
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "godotSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "scope": {
+ "description": "Comments to be checked.",
+ "enum": ["declarations", "toplevel", "all", "noinline"],
+ "default": "declarations"
+ },
+ "exclude": {
+ "description": "List of regexps for excluding particular comment lines from check.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "period": {
+ "description": "Check that each sentence ends with a period.",
+ "type": "boolean",
+ "default": true
+ },
+ "capital": {
+ "description": "Check that each sentence starts with a capital letter.",
+ "type": "boolean",
+ "default": false
+ },
+ "check-all": {
+ "description": "DEPRECATED: Check all top-level comments, not only declarations.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "godoxSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "keywords": {
+ "description": "Report any comments starting with one of these keywords. This is useful for TODO or FIXME comments that might be left in the code accidentally and should be resolved before merging.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "default": ["TODO", "BUG", "FIXME"]
+ }
+ }
+ },
+ "gofmtSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "simplify": {
+ "description": "Simplify code.",
+ "type": "boolean",
+ "default": true
+ },
+ "rewrite-rules": {
+ "description": "Apply the rewrite rules to the source before reformatting.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "pattern": {
+ "type": "string"
+ },
+ "replacement": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "golinesSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-len": {
+ "type": "integer",
+ "default": 100
+ },
+ "tab-len": {
+ "type": "integer",
+ "default": 4
+ },
+ "shorten-comments": {
+ "type": "boolean",
+ "default": false
+ },
+ "reformat-tags": {
+ "type": "boolean",
+ "default": true
+ },
+ "chain-split-dots": {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "interfacebloatSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max": {
+ "description": "The maximum number of methods allowed for an interface.",
+ "type": "integer"
+ }
+ }
+ },
+ "gofumptSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "extra-rules": {
+ "description": "Choose whether or not to use the extra rules that are disabled by default.",
+ "type": "boolean",
+ "default": false
+ },
+ "module-path": {
+ "description": " Module path which contains the source code being formatted.",
+ "type": "string"
+ }
+ }
+ },
+ "goheaderSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "values": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "const": {
+ "description": "Constants to use in the template.",
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "description": "Value for the constant.",
+ "type": "string"
+ }
+ },
+ "additionalProperties": false,
+ "examples": [
+ {
+ "YEAR": "2030",
+ "COMPANY": "MY FUTURISTIC COMPANY"
+ }
+ ]
+ },
+ "regexp": {
+ "description": "Regular expressions to use in your template.",
+ "type": "object",
+ "additionalProperties": false,
+ "patternProperties": {
+ "^.+$": {
+ "type": "string"
+ }
+ },
+ "examples": [
+ {
+ "AUTHOR": ".*@mycompany\\.com"
+ }
+ ]
+ }
+ }
+ },
+ "template": {
+ "description": "Template to put on top of every file.",
+ "type": "string",
+ "examples": [
+ "{{ MY COMPANY }}\nSPDX-License-Identifier: Apache-2.0\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at:\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License."
+ ]
+ },
+ "template-path": {
+ "description": "Path to the file containing the template source.",
+ "type": "string",
+ "examples": ["my_header_template.txt"]
+ }
+ },
+ "oneOf": [
+ { "required": ["template"] },
+ { "required": ["template-path"] }
+ ]
+ },
+ "goimportsSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "local-prefixes": {
+ "description": "Put imports beginning with prefix after 3rd-party packages. It is a list of prefixes.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "gomoddirectivesSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "replace-local": {
+ "description": "Allow local `replace` directives.",
+ "type": "boolean",
+ "default": true
+ },
+ "replace-allow-list": {
+ "description": "List of allowed `replace` directives.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "retract-allow-no-explanation": {
+ "description": "Allow to not explain why the version has been retracted in the `retract` directives.",
+ "type": "boolean",
+ "default": false
+ },
+ "exclude-forbidden": {
+ "description": "Forbid the use of the `exclude` directives.",
+ "type": "boolean",
+ "default": false
+ },
+ "ignore-forbidden": {
+ "description": "Forbid the use of the `ignore` directives. (>= go1.25)",
+ "type": "boolean",
+ "default": false
+ },
+ "toolchain-forbidden": {
+ "description": "Forbid the use of the `toolchain` directive.",
+ "type": "boolean",
+ "default": false
+ },
+ "toolchain-pattern": {
+ "description": "Defines a pattern to validate `toolchain` directive.",
+ "type": "string"
+ },
+ "tool-forbidden": {
+ "description": "Forbid the use of the `tool` directives.",
+ "type": "boolean",
+ "default": false
+ },
+ "go-debug-forbidden": {
+ "description": "Forbid the use of the `godebug` directive.",
+ "type": "boolean",
+ "default": false
+ },
+ "go-version-pattern": {
+ "description": "Defines a pattern to validate `go` minimum version directive.",
+ "type": "string",
+ "default": ""
+ }
+ }
+ },
+ "gomodguardSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "allowed": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "modules": {
+ "description": "List of allowed modules.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["gopkg.in/yaml.v2"]
+ }
+ },
+ "domains": {
+ "description": "List of allowed module domains.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["golang.org"]
+ }
+ }
+ }
+ },
+ "blocked": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "modules": {
+ "description": "List of blocked modules.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "recommendations": {
+ "description": "Recommended modules that should be used instead.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "reason": {
+ "description": "Reason why the recommended module should be used.",
+ "type": "string"
+ }
+ }
+ }
+ },
+ "additionalProperties": false
+ }
+ },
+ "versions": {
+ "description": "List of blocked module version constraints.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "patternProperties": {
+ "^.*$": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "version": {
+ "description": "Version constraint.",
+ "type": "string"
+ },
+ "reason": {
+ "description": "Reason why the version constraint exists.",
+ "type": "string"
+ }
+ },
+ "required": ["reason"]
+ }
+ }
+ }
+ },
+ "local-replace-directives": {
+ "description": "Raise lint issues if loading local path with replace directive",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ }
+ }
+ },
+ "gosecSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "includes": {
+ "type": "array",
+ "description": "To select a subset of rules to run",
+ "examples": [["G401"]],
+ "items": {
+ "$ref": "#/definitions/gosec-rules"
+ }
+ },
+ "excludes": {
+ "type": "array",
+ "description": "To specify a set of rules to explicitly exclude",
+ "examples": [["G401"]],
+ "items": {
+ "$ref": "#/definitions/gosec-rules"
+ }
+ },
+ "severity": {
+ "description": "Filter out the issues with a lower severity than the given value",
+ "type": "string",
+ "enum": ["low", "medium", "high"],
+ "default": "low"
+ },
+ "confidence": {
+ "description": "Filter out the issues with a lower confidence than the given value",
+ "type": "string",
+ "enum": ["low", "medium", "high"],
+ "default": "low"
+ },
+ "config": {
+ "description": "To specify the configuration of rules",
+ "type": "object"
+ },
+ "concurrency": {
+ "description": "Concurrency value",
+ "type": "integer"
+ }
+ }
+ },
+ "gosmopolitanSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "allow-time-local": {
+ "description": "Allow and ignore `time.Local` usages.",
+ "type": "boolean",
+ "default": false
+ },
+ "escape-hatches": {
+ "description": "List of fully qualified names in the `full/pkg/path.name` form, to act as \"i18n escape hatches\".",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "watch-for-scripts": {
+ "description": "List of Unicode scripts to watch for any usage in string literals.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "govetSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "settings": {
+ "description": "Settings per analyzer. Map of analyzer name to specific settings.\nRun `go tool vet help` to find out more.",
+ "type": "object",
+ "propertyNames": {
+ "$ref": "#/definitions/govet-analyzers"
+ },
+ "patternProperties": {
+ "^.*$": {
+ "description": "Run `go tool vet help ` to see all settings.",
+ "type": "object"
+ }
+ }
+ },
+ "enable": {
+ "description": "Enable analyzers by name.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/govet-analyzers"
+ }
+ },
+ "disable": {
+ "description": "Disable analyzers by name.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/govet-analyzers"
+ }
+ },
+ "enable-all": {
+ "description": "Enable all analyzers.",
+ "type": "boolean",
+ "default": false
+ },
+ "disable-all": {
+ "description": "Disable all analyzers.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "grouperSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "const-require-single-const": {
+ "type": "boolean",
+ "default": false
+ },
+ "const-require-grouping": {
+ "type": "boolean",
+ "default": false
+ },
+ "import-require-single-import": {
+ "type": "boolean",
+ "default": false
+ },
+ "import-require-grouping": {
+ "type": "boolean",
+ "default": false
+ },
+ "type-require-single-type": {
+ "type": "boolean",
+ "default": false
+ },
+ "type-require-grouping": {
+ "type": "boolean",
+ "default": false
+ },
+ "var-require-single-var": {
+ "type": "boolean",
+ "default": false
+ },
+ "var-require-grouping": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "ifaceSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "enable": {
+ "description": "Enable analyzers by name.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/iface-analyzers"
+ }
+ },
+ "settings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "unused": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "exclude": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "importasSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "no-unaliased": {
+ "description": "Do not allow unaliased imports of aliased packages.",
+ "type": "boolean",
+ "default": false
+ },
+ "no-extra-aliases": {
+ "description": "Do not allow non-required aliases.",
+ "type": "boolean",
+ "default": false
+ },
+ "alias": {
+ "description": "List of aliases",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "pkg": {
+ "description": "Package path e.g. knative.dev/serving/pkg/apis/autoscaling/v1alpha1",
+ "type": "string"
+ },
+ "alias": {
+ "description": "Package alias e.g. autoscalingv1alpha1",
+ "type": "string"
+ }
+ },
+ "required": ["pkg", "alias"]
+ }
+ }
+ }
+ },
+ "inamedparamSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skip-single-param": {
+ "description": "Skips check for interface methods with only a single parameter.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "ineffassignSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-escaping-errors": {
+ "description": "Check escaping variables of type error, may cause false positives.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "iotamixingSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "report-individual": {
+ "description": "Whether to report individual consts rather than just the const block.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "ireturnSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "description": "Use either `reject` or `allow` properties for interfaces matching.",
+ "properties": {
+ "allow": {
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "enum": ["anon", "error", "empty", "stdlib"]
+ }
+ ]
+ }
+ },
+ "reject": {
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "enum": ["anon", "error", "empty", "stdlib"]
+ }
+ ]
+ }
+ }
+ },
+ "anyOf": [
+ {
+ "not": {
+ "properties": {
+ "allow": {
+ "const": "reject"
+ }
+ }
+ },
+ "required": ["allow"]
+ },
+ {
+ "required": ["reject"]
+ }
+ ]
+ },
+ "lllSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "tab-width": {
+ "description": "Width of \"\\t\" in spaces.",
+ "type": "integer",
+ "minimum": 0,
+ "default": 1
+ },
+ "line-length": {
+ "description": "Maximum allowed line length, lines longer will be reported.",
+ "type": "integer",
+ "minimum": 1,
+ "default": 120
+ }
+ }
+ },
+ "maintidxSettings": {
+ "description": "Maintainability index https://docs.microsoft.com/en-us/visualstudio/code-quality/code-metrics-maintainability-index-range-and-meaning?view=vs-2022",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "under": {
+ "description": "Minimum accatpable maintainability index level (see https://docs.microsoft.com/en-us/visualstudio/code-quality/code-metrics-maintainability-index-range-and-meaning?view=vs-2022)",
+ "type": "number",
+ "default": 20
+ }
+ }
+ },
+ "makezeroSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "always": {
+ "description": "Allow only slices initialized with a length of zero.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "loggercheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "kitlog": {
+ "description": "Allow check for the github.com/go-kit/log library.",
+ "type": "boolean",
+ "default": true
+ },
+ "klog": {
+ "description": "Allow check for the k8s.io/klog/v2 library.",
+ "type": "boolean",
+ "default": true
+ },
+ "logr": {
+ "description": "Allow check for the github.com/go-logr/logr library.",
+ "type": "boolean",
+ "default": true
+ },
+ "slog": {
+ "description": "Allow check for the log/slog library.",
+ "type": "boolean",
+ "default": true
+ },
+ "zap": {
+ "description": "Allow check for the \"sugar logger\" from go.uber.org/zap library.",
+ "type": "boolean",
+ "default": true
+ },
+ "require-string-key": {
+ "description": "Require all logging keys to be inlined constant strings.",
+ "type": "boolean",
+ "default": false
+ },
+ "no-printf-like": {
+ "description": "Require printf-like format specifier (%s, %d for example) not present.",
+ "type": "boolean",
+ "default": false
+ },
+ "rules": {
+ "description": "List of custom rules to check against, where each rule is a single logger pattern, useful for wrapped loggers.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "misspellSettings": {
+ "description": "Correct spellings using locale preferences for US or UK. Default is to use a neutral variety of English.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "locale": {
+ "enum": ["US", "UK"]
+ },
+ "ignore-rules": {
+ "description": "List of rules to ignore.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "mode": {
+ "description": "Mode of the analysis.",
+ "enum": ["restricted", "", "default"],
+ "default": ""
+ },
+ "extra-words": {
+ "description": "Extra word corrections.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "correction": {
+ "type": "string"
+ },
+ "typo": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "musttagSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "functions": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "tag": {
+ "type": "string"
+ },
+ "arg-pos": {
+ "type": "integer"
+ }
+ }
+ }
+ }
+ }
+ },
+ "nakedretSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-func-lines": {
+ "description": "Report if a function has more lines of code than this value and it has naked returns.",
+ "type": "integer",
+ "minimum": 0,
+ "default": 30
+ }
+ }
+ },
+ "nestifSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "min-complexity": {
+ "description": "Minimum complexity of \"if\" statements to report.",
+ "type": "integer",
+ "default": 5
+ }
+ }
+ },
+ "nilnilSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "only-two": {
+ "type": "boolean",
+ "description": "To check functions with only two return values.",
+ "default": true
+ },
+ "detect-opposite": {
+ "type": "boolean",
+ "description": "In addition, detect opposite situation (simultaneous return of non-nil error and valid value).",
+ "default": false
+ },
+ "checked-types": {
+ "type": "array",
+ "description": "List of return types to check.",
+ "items": {
+ "enum": ["chan", "func", "iface", "map", "ptr", "uintptr", "unsafeptr"]
+ },
+ "default": ["chan", "func", "iface", "map", "ptr", "uintptr", "unsafeptr"]
+ }
+ }
+ },
+ "nlreturnSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "block-size": {
+ "description": "set block size that is still ok",
+ "type": "number",
+ "default": 0,
+ "minimum": 0
+ }
+ }
+ },
+ "mndSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignored-files": {
+ "description": "List of file patterns to exclude from analysis.",
+ "examples": [["magic1_.*.go"]],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignored-functions": {
+ "description": "Comma-separated list of function patterns to exclude from the analysis.",
+ "examples": [["math.*", "http.StatusText", "make"]],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignored-numbers": {
+ "description": "List of numbers to exclude from analysis.",
+ "examples": [["1000", "1234_567_890", "3.14159264"]],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "checks": {
+ "description": "The list of enabled checks, see https://github.com/tommy-muehle/go-mnd/#checks for description.",
+ "type": "array",
+ "items": {
+ "enum": [
+ "argument",
+ "case",
+ "condition",
+ "operation",
+ "return",
+ "assign"
+ ]
+ }
+ }
+ }
+ },
+ "modernizeSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "disable": {
+ "description": "List of analyzers to disable.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/modernize-analyzers"
+ }
+ }
+ }
+ },
+ "nolintlintSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "allow-unused": {
+ "description": "Enable to ensure that nolint directives are all used.",
+ "type": "boolean",
+ "default": true
+ },
+ "allow-no-explanation": {
+ "description": "Exclude these linters from requiring an explanation.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linter-names"
+ },
+ "default": []
+ },
+ "require-explanation": {
+ "description": "Enable to require an explanation of nonzero length after each nolint directive.",
+ "type": "boolean",
+ "default": false
+ },
+ "require-specific": {
+ "description": "Enable to require nolint directives to mention the specific linter being suppressed.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "reassignSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "patterns": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "recvcheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "disable-builtin": {
+ "description": "Disables the built-in method exclusions.",
+ "type": "boolean",
+ "default": true
+ },
+ "exclusions": {
+ "description": "User-defined method exclusions.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "nonamedreturnsSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "report-error-in-defer": {
+ "description": "Report named error if it is assigned inside defer.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "paralleltestSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignore-missing": {
+ "description": "Ignore missing calls to `t.Parallel()` and only report incorrect uses of it.",
+ "type": "boolean",
+ "default": false
+ },
+ "ignore-missing-subtests": {
+ "description": "Ignore missing calls to `t.Parallel()` in subtests. Top-level tests are still required to have `t.Parallel`, but subtests are allowed to skip it.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "perfsprintSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "integer-format": {
+ "description": "Enable/disable optimization of integer formatting.",
+ "type": "boolean",
+ "default": true
+ },
+ "int-conversion": {
+ "description": "Optimizes even if it requires an int or uint type cast.",
+ "type": "boolean",
+ "default": true
+ },
+ "error-format": {
+ "description": "Enable/disable optimization of error formatting.",
+ "type": "boolean",
+ "default": true
+ },
+ "err-error": {
+ "description": "Optimizes into `err.Error()` even if it is only equivalent for non-nil errors.",
+ "type": "boolean",
+ "default": false
+ },
+ "errorf": {
+ "description": "Optimizes `fmt.Errorf`.",
+ "type": "boolean",
+ "default": true
+ },
+ "string-format": {
+ "description": "Enable/disable optimization of string formatting.",
+ "type": "boolean",
+ "default": true
+ },
+ "sprintf1": {
+ "description": "Optimizes `fmt.Sprintf` with only one argument.",
+ "type": "boolean",
+ "default": true
+ },
+ "strconcat": {
+ "description": "Optimizes into strings concatenation.",
+ "type": "boolean",
+ "default": true
+ },
+ "bool-format": {
+ "description": "Enable/disable optimization of bool formatting.",
+ "type": "boolean",
+ "default": true
+ },
+ "hex-format": {
+ "description": "Enable/disable optimization of hex formatting.",
+ "type": "boolean",
+ "default": true
+ },
+ "concat-loop": {
+ "description": "Enable/disable optimization of concat loop.",
+ "type": "boolean",
+ "default": true
+ },
+ "loop-other-ops": {
+ "description": "Optimization of `concat-loop` even with other operations.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "preallocSettings": {
+ "description": "We do not recommend using this linter before doing performance profiling.\nFor most programs usage of `prealloc` will be premature optimization.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "simple": {
+ "description": "Report preallocation suggestions only on simple loops that have no returns/breaks/continues/gotos in them.",
+ "type": "boolean",
+ "default": true
+ },
+ "range-loops": {
+ "description": "Report preallocation suggestions on range loops.",
+ "type": "boolean",
+ "default": true
+ },
+ "for-loops": {
+ "description": "Report preallocation suggestions on for loops.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "predeclaredSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignore": {
+ "description": "List of predeclared identifiers to not report on.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "qualified-name": {
+ "description": "Include method names and field names in checks.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "promlinterSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "strict": {},
+ "disabled-linters": {
+ "type": "array",
+ "items": {
+ "enum": [
+ "Help",
+ "MetricUnits",
+ "Counter",
+ "HistogramSummaryReserved",
+ "MetricTypeInName",
+ "ReservedChars",
+ "CamelCase",
+ "UnitAbbreviations"
+ ]
+ }
+ }
+ }
+ },
+ "protogetterSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skip-generated-by": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["protoc-gen-go-my-own-generator"]
+ }
+ },
+ "skip-files": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["*.pb.go"]
+ }
+ },
+ "skip-any-generated": {
+ "description": "Skip any generated files from the checking.",
+ "type": "boolean",
+ "default": false
+ },
+ "replace-first-arg-in-append": {
+ "description": "Skip first argument of append function.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "reviveSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "examples": [
+ {
+ "ignore-generated-header": true,
+ "severity": "warning",
+ "rules": [
+ {
+ "name": "indent-error-flow",
+ "severity": "warning"
+ },
+ {
+ "name": "add-constant",
+ "severity": "warning",
+ "arguments": [
+ {
+ "maxLitCount": "3",
+ "allowStrs": "\"\"",
+ "allowInts": "0,1,2",
+ "allowFloats": "0.0,0.,1.0,1.,2.0,2."
+ }
+ ]
+ }
+ ]
+ }
+ ],
+ "properties": {
+ "max-open-files": {
+ "type": "integer"
+ },
+ "confidence": {
+ "type": "number"
+ },
+ "severity": {
+ "type": "string",
+ "enum": ["warning", "error"]
+ },
+ "enable-all-rules": {
+ "type": "boolean",
+ "default": false
+ },
+ "directives": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "name": {
+ "type": "string",
+ "enum": ["specify-disable-reason"]
+ },
+ "severity": {
+ "type": "string",
+ "enum": ["warning", "error"]
+ },
+ "exclude": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "arguments": {
+ "type": "array"
+ }
+ }
+ }
+ },
+ "rules": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["name"],
+ "properties": {
+ "name": {
+ "$ref": "#/definitions/revive-rules",
+ "title": "The rule name"
+ },
+ "disabled": {
+ "type": "boolean"
+ },
+ "severity": {
+ "type": "string",
+ "enum": ["warning", "error"]
+ },
+ "exclude": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "arguments": {
+ "type": "array"
+ }
+ }
+ }
+ }
+ }
+ },
+ "rowserrcheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "packages": {
+ "type": "array",
+ "items": {
+ "description": "",
+ "type": "string",
+ "examples": ["github.com/jmoiron/sqlx"]
+ }
+ }
+ }
+ },
+ "sloglintSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "kv-only": {
+ "description": "Enforce using key-value pairs only (incompatible with attr-only).",
+ "type": "boolean",
+ "default": false
+ },
+ "no-global": {
+ "description": "Enforce not using global loggers.",
+ "enum": ["", "all", "default"],
+ "default": ""
+ },
+ "no-mixed-args": {
+ "description": "Enforce not mixing key-value pairs and attributes.",
+ "type": "boolean",
+ "default": true
+ },
+ "context": {
+ "description": "Enforce using methods that accept a context.",
+ "enum": ["", "all", "scope"],
+ "default": ""
+ },
+ "static-msg": {
+ "description": "Enforce using static values for log messages.",
+ "type": "boolean",
+ "default": false
+ },
+ "msg-style": {
+ "description": "Enforce message style.",
+ "enum": ["", "lowercased", "capitalized"],
+ "default": ""
+ },
+ "key-naming-case": {
+ "description": "Enforce a single key naming convention.",
+ "enum": ["snake", "kebab", "camel", "pascal"]
+ },
+ "attr-only": {
+ "description": "Enforce using attributes only (incompatible with kv-only).",
+ "type": "boolean",
+ "default": false
+ },
+ "no-raw-keys": {
+ "description": "Enforce using constants instead of raw keys.",
+ "type": "boolean",
+ "default": false
+ },
+ "forbidden-keys": {
+ "description": "Enforce not using specific keys.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "args-on-sep-lines": {
+ "description": "Enforce putting arguments on separate lines.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "spancheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "checks": {
+ "description": "Checks to enable.",
+ "type": "array",
+ "items": {
+ "enum": ["end", "record-error", "set-status"]
+ }
+ },
+ "ignore-check-signatures": {
+ "description": "A list of regexes for function signatures that silence `record-error` and `set-status` reports if found in the call path to a returned error.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "extra-start-span-signatures": {
+ "description": "A list of regexes for additional function signatures that create spans.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "staticcheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "checks": {
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "$ref": "#/definitions/staticcheck-checks"
+ },
+ {
+ "type": "string"
+ }
+ ]
+ }
+ },
+ "dot-import-whitelist": {
+ "description": "By default, ST1001 forbids all uses of dot imports in non-test packages. This setting allows setting a whitelist of import paths that can be dot-imported anywhere.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "http-status-code-whitelist": {
+ "description": "ST1013 recommends using constants from the net/http package instead of hard-coding numeric HTTP status codes. This setting specifies a list of numeric status codes that this check does not complain about.",
+ "default": ["200", "400", "404", "500"],
+ "type": "array",
+ "items": {
+ "enum": [
+ "100",
+ "101",
+ "102",
+ "103",
+ "200",
+ "201",
+ "202",
+ "203",
+ "204",
+ "205",
+ "206",
+ "207",
+ "208",
+ "226",
+ "300",
+ "301",
+ "302",
+ "303",
+ "304",
+ "305",
+ "306",
+ "307",
+ "308",
+ "400",
+ "401",
+ "402",
+ "403",
+ "404",
+ "405",
+ "406",
+ "407",
+ "408",
+ "409",
+ "410",
+ "411",
+ "412",
+ "413",
+ "414",
+ "415",
+ "416",
+ "417",
+ "418",
+ "421",
+ "422",
+ "423",
+ "424",
+ "425",
+ "426",
+ "428",
+ "429",
+ "431",
+ "451",
+ "500",
+ "501",
+ "502",
+ "503",
+ "504",
+ "505",
+ "506",
+ "507",
+ "508",
+ "510",
+ "511"
+ ]
+ }
+ },
+ "initialisms": {
+ "description": "ST1003 check, among other things, for the correct capitalization of initialisms. The set of known initialisms can be configured with this option.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "default": [
+ "ACL",
+ "API",
+ "ASCII",
+ "CPU",
+ "CSS",
+ "DNS",
+ "EOF",
+ "GUID",
+ "HTML",
+ "HTTP",
+ "HTTPS",
+ "ID",
+ "IP",
+ "JSON",
+ "QPS",
+ "RAM",
+ "RPC",
+ "SLA",
+ "SMTP",
+ "SQL",
+ "SSH",
+ "TCP",
+ "TLS",
+ "TTL",
+ "UDP",
+ "UI",
+ "GID",
+ "UID",
+ "UUID",
+ "URI",
+ "URL",
+ "UTF8",
+ "VM",
+ "XML",
+ "XMPP",
+ "XSRF",
+ "XSS",
+ "SIP",
+ "RTP",
+ "AMQP",
+ "DB",
+ "TS"
+ ]
+ }
+ }
+ }
+ },
+ "tagalignSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "align": {
+ "description": "Align and sort can be used together or separately.",
+ "type": "boolean",
+ "default": true
+ },
+ "sort": {
+ "description": "Whether enable tags sort.",
+ "type": "boolean",
+ "default": true
+ },
+ "order": {
+ "description": "Specify the order of tags, the other tags will be sorted by name.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "default": [],
+ "examples": [
+ [
+ "json",
+ "yaml",
+ "yml",
+ "toml",
+ "mapstructure",
+ "binding",
+ "validate"
+ ]
+ ]
+ },
+ "strict": {
+ "description": "Whether enable strict style.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "tagliatelleSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "case": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "use-field-name": {
+ "description": "Use the struct field name to check the name of the struct tag.",
+ "type": "boolean",
+ "default": false
+ },
+ "ignored-fields": {
+ "description": "The field names to ignore.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["example"]
+ }
+ },
+ "rules": {
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "$ref": "#/definitions/tagliatelle-cases"
+ }
+ }
+ },
+ "extended-rules": {
+ "description": "Defines the association between tag name and case.",
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["case"],
+ "properties": {
+ "case": {
+ "$ref": "#/definitions/tagliatelle-cases"
+ },
+ "extra-initialisms": {
+ "type": "boolean",
+ "default": false
+ },
+ "initialism-overrides": {
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "overrides": {
+ "description": "Overrides the default/root configuration.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["pkg"],
+ "properties": {
+ "pkg": {
+ "description": "A package path.",
+ "type": "string"
+ },
+ "use-field-name": {
+ "description": "Use the struct field name to check the name of the struct tag.",
+ "type": "boolean",
+ "default": false
+ },
+ "ignored-fields": {
+ "description": "The field names to ignore.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["example"]
+ }
+ },
+ "ignore": {
+ "description": "Ignore the package (takes precedence over all other configurations).",
+ "type": "boolean",
+ "default": false
+ },
+ "rules": {
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "$ref": "#/definitions/tagliatelle-cases"
+ }
+ }
+ },
+ "extended-rules": {
+ "description": "Defines the association between tag name and case.",
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["case"],
+ "properties": {
+ "case": {
+ "$ref": "#/definitions/tagliatelle-cases"
+ },
+ "extra-initialisms": {
+ "type": "boolean",
+ "default": false
+ },
+ "initialism-overrides": {
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "testifylintSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "enable-all": {
+ "description": "Enable all checkers.",
+ "type": "boolean",
+ "default": false
+ },
+ "disable-all": {
+ "description": "Disable all checkers.",
+ "type": "boolean",
+ "default": false
+ },
+ "enable": {
+ "description": "Enable specific checkers.",
+ "type": "array",
+ "items": {
+ "enum": [
+ "blank-import",
+ "bool-compare",
+ "compares",
+ "contains",
+ "empty",
+ "encoded-compare",
+ "equal-values",
+ "error-is-as",
+ "error-nil",
+ "expected-actual",
+ "float-compare",
+ "formatter",
+ "go-require",
+ "len",
+ "negative-positive",
+ "nil-compare",
+ "regexp",
+ "require-error",
+ "suite-broken-parallel",
+ "suite-dont-use-pkg",
+ "suite-extra-assert-call",
+ "suite-method-signature",
+ "suite-subtest-run",
+ "suite-thelper",
+ "useless-assert"
+ ]
+ },
+ "default": [
+ "blank-import",
+ "bool-compare",
+ "compares",
+ "contains",
+ "empty",
+ "encoded-compare",
+ "equal-values",
+ "error-is-as",
+ "error-nil",
+ "expected-actual",
+ "float-compare",
+ "formatter",
+ "go-require",
+ "len",
+ "negative-positive",
+ "nil-compare",
+ "regexp",
+ "require-error",
+ "suite-broken-parallel",
+ "suite-dont-use-pkg",
+ "suite-extra-assert-call",
+ "suite-method-signature",
+ "suite-subtest-run",
+ "useless-assert"
+ ]
+ },
+ "disable": {
+ "description": "Disable specific checkers.",
+ "type": "array",
+ "items": {
+ "enum": [
+ "blank-import",
+ "bool-compare",
+ "compares",
+ "contains",
+ "empty",
+ "encoded-compare",
+ "equal-values",
+ "error-is-as",
+ "error-nil",
+ "expected-actual",
+ "float-compare",
+ "formatter",
+ "go-require",
+ "len",
+ "negative-positive",
+ "nil-compare",
+ "regexp",
+ "require-error",
+ "suite-broken-parallel",
+ "suite-dont-use-pkg",
+ "suite-extra-assert-call",
+ "suite-method-signature",
+ "suite-subtest-run",
+ "suite-thelper",
+ "useless-assert"
+ ],
+ "default": [
+ "suite-thelper"
+ ]
+ }
+ },
+ "bool-compare": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignore-custom-types": {
+ "description": "To ignore user defined types (over builtin bool).",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "expected-actual": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "pattern": {
+ "description": "Regexp for expected variable name.",
+ "type": "string",
+ "default": "(^(exp(ected)?|want(ed)?)([A-Z]\\w*)?$)|(^(\\w*[a-z])?(Exp(ected)?|Want(ed)?)$)"
+ }
+ }
+ },
+ "formatter": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-format-string": {
+ "description": "To enable go vet's printf checks.",
+ "type": "boolean",
+ "default": true
+ },
+ "require-f-funcs": {
+ "description": "To require f-assertions (e.g. assert.Equalf) if format string is used, even if there are no variable-length variables.",
+ "type": "boolean",
+ "default": false
+ },
+ "require-string-msg": {
+ "description": "To require that the first element of msgAndArgs (msg) has a string type.",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "go-require": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignore-http-handlers": {
+ "description": "To ignore HTTP handlers (like http.HandlerFunc).",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "require-error": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "fn-pattern": {
+ "description": "Regexp for assertions to analyze. If defined, then only matched error assertions will be reported.",
+ "type": "string",
+ "default": ""
+ }
+ }
+ },
+ "suite-extra-assert-call": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "mode": {
+ "description": "To require or remove extra Assert() call?",
+ "type": "string",
+ "enum": ["remove", "require"],
+ "default": "remove"
+ }
+ }
+ }
+ }
+ },
+ "testpackageSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skip-regexp": {
+ "description": "Files with names matching this regular expression are skipped.",
+ "type": "string",
+ "examples": ["(export|internal)_test\\.go"]
+ },
+ "allow-packages": {
+ "description": "List of packages that don't end with _test that tests are allowed to be in.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["example"]
+ }
+ }
+ }
+ },
+ "thelperSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "test": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "begin": {
+ "description": "Check if `t.Helper()` begins helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "first": {
+ "description": "Check if *testing.T is first param of helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "name": {
+ "description": "Check if *testing.T param has t name.",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ },
+ "benchmark": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "begin": {
+ "description": "Check if `b.Helper()` begins helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "first": {
+ "description": "Check if *testing.B is first param of helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "name": {
+ "description": "Check if *testing.B param has b name.",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ },
+ "tb": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "begin": {
+ "description": "Check if `tb.Helper()` begins helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "first": {
+ "description": "Check if *testing.TB is first param of helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "name": {
+ "description": "Check if *testing.TB param has tb name.",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ },
+ "fuzz": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "begin": {
+ "description": "Check if `f.Helper()` begins helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "first": {
+ "description": "Check if *testing.F is first param of helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "name": {
+ "description": "Check if *testing.F param has f name.",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ }
+ }
+ },
+ "usestdlibvarsSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "http-method": {
+ "description": "Suggest the use of http.MethodXX.",
+ "type": "boolean",
+ "default": true
+ },
+ "http-status-code": {
+ "description": "Suggest the use of http.StatusXX.",
+ "type": "boolean",
+ "default": true
+ },
+ "time-weekday": {
+ "description": "Suggest the use of time.Weekday.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "time-month": {
+ "description": "Suggest the use of time.Month.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "time-layout": {
+ "description": "Suggest the use of time.Layout.",
+ "type": "boolean",
+ "default": false
+ },
+ "time-date-month": {
+ "description": "Suggest the use of time.Month in time.Date.",
+ "type": "boolean",
+ "default": false
+ },
+ "crypto-hash": {
+ "description": "Suggest the use of crypto.Hash.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "default-rpc-path": {
+ "description": "Suggest the use of rpc.DefaultXXPath.",
+ "type": "boolean",
+ "default": false
+ },
+ "sql-isolation-level": {
+ "description": "Suggest the use of sql.LevelXX.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "tls-signature-scheme": {
+ "description": "Suggest the use of tls.SignatureScheme.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "constant-kind": {
+ "description": "Suggest the use of constant.Kind.String().",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "usetestingSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "context-background": {
+ "type": "boolean",
+ "default": false
+ },
+ "context-todo": {
+ "type": "boolean",
+ "default": false
+ },
+ "os-chdir": {
+ "type": "boolean",
+ "default": true
+ },
+ "os-mkdir-temp": {
+ "type": "boolean",
+ "default": true
+ },
+ "os-setenv": {
+ "type": "boolean",
+ "default": true
+ },
+ "os-create-temp": {
+ "type": "boolean",
+ "default": true
+ },
+ "os-temp-dir": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "unconvertSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "fast-math": {
+ "type": "boolean",
+ "default": false
+ },
+ "safe": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "unparamSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-exported": {
+ "description": "Inspect exported functions. Set to true if no external program/library imports your code.\n\nWARNING: if you enable this setting, unparam will report a lot of false-positives in text editors:\nif it's called for subdir of a project it can't find external interfaces. All text editor integrations\nwith golangci-lint call it on a directory with the changed file.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "unqueryvetSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-sql-builders": {
+ "description": "Enable SQL builder checking.",
+ "type": "boolean",
+ "default": true
+ },
+ "allowed-patterns": {
+ "description": "Regex patterns for acceptable SELECT * usage.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "unusedSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "field-writes-are-uses": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ },
+ "post-statements-are-reads": {
+ "description": "",
+ "type": "boolean",
+ "default": false
+ },
+ "exported-fields-are-used": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ },
+ "parameters-are-used": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ },
+ "local-variables-are-used": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ },
+ "generated-is-used": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "varnamelenSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-distance": {
+ "description": "Variables used in at most this N-many lines will be ignored.",
+ "type": "integer",
+ "default": 5
+ },
+ "min-name-length": {
+ "description": "The minimum length of a variable's name that is considered `long`.",
+ "type": "integer",
+ "default": 3
+ },
+ "check-receiver": {
+ "description": "Check method receiver names.",
+ "default": false,
+ "type": "boolean"
+ },
+ "check-return": {
+ "description": "Check named return values.",
+ "default": false,
+ "type": "boolean"
+ },
+ "check-type-param": {
+ "description": "Check type parameters.",
+ "default": false,
+ "type": "boolean"
+ },
+ "ignore-type-assert-ok": {
+ "description": "Ignore `ok` variables that hold the bool return value of a type assertion",
+ "default": false,
+ "type": "boolean"
+ },
+ "ignore-map-index-ok": {
+ "description": "Ignore `ok` variables that hold the bool return value of a map index.",
+ "default": false,
+ "type": "boolean"
+ },
+ "ignore-chan-recv-ok": {
+ "description": "Ignore `ok` variables that hold the bool return value of a channel receive.",
+ "default": false,
+ "type": "boolean"
+ },
+ "ignore-names": {
+ "description": "Optional list of variable names that should be ignored completely.",
+ "default": [[]],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignore-decls": {
+ "description": "Optional list of variable declarations that should be ignored completely.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "examples": [
+ ["c echo.Context", "t testing.T", "f *foo.Bar", "const C"]
+ ]
+ }
+ }
+ },
+ "whitespaceSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "multi-if": {
+ "description": "Enforces newlines (or comments) after every multi-line if statement",
+ "type": "boolean",
+ "default": false
+ },
+ "multi-func": {
+ "description": "Enforces newlines (or comments) after every multi-line function signature",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "wrapcheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "extra-ignore-sigs": {
+ "description": "An array of strings specifying additional substrings of signatures to ignore.",
+ "default": [
+ ".CustomError(",
+ ".SpecificWrap("
+ ],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignore-sigs": {
+ "description": "An array of strings which specify substrings of signatures to ignore.",
+ "default": [
+ ".Errorf(",
+ "errors.New(",
+ "errors.Unwrap(",
+ ".Wrap(",
+ ".Wrapf(",
+ ".WithMessage(",
+ ".WithMessagef(",
+ ".WithStack("
+ ],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignore-sig-regexps": {
+ "description": "An array of strings which specify regular expressions of signatures to ignore.",
+ "default": [""],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignore-package-globs": {
+ "description": "An array of glob patterns which, if any match the package of the function returning the error, will skip wrapcheck analysis for this error.",
+ "default": [""],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignore-interface-regexps": {
+ "description": "An array of glob patterns which, if matched to an underlying interface name, will ignore unwrapped errors returned from a function whose call is defined on the given interface.",
+ "default": [""],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "report-internal-errors": {
+ "description": "Determines whether wrapcheck should report errors returned from inside the package.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "wslSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "allow-assign-and-anything": {
+ "description": "Controls if you may cuddle assignments and anything without needing an empty line between them.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-assign-and-call": {
+ "description": "Allow calls and assignments to be cuddled as long as the lines have any matching variables, fields or types.",
+ "type": "boolean",
+ "default": true
+ },
+ "allow-cuddle-declarations": {
+ "description": "Allow declarations (var) to be cuddled.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-cuddle-with-calls": {
+ "description": "A list of call idents that everything can be cuddled with.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "allow-cuddle-with-rhs": {
+ "description": "AllowCuddleWithRHS is a list of right hand side variables that is allowed to be cuddled with anything.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "allow-cuddle-used-in-block": {
+ "description": "Allow cuddling with any block as long as the variable is used somewhere in the block",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-multiline-assign": {
+ "description": "Allow multiline assignments to be cuddled.",
+ "type": "boolean",
+ "default": true
+ },
+ "allow-separated-leading-comment": {
+ "description": "Allow leading comments to be separated with empty lines.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-trailing-comment": {
+ "description": "Allow trailing comments in ending of blocks.",
+ "type": "boolean",
+ "default": false
+ },
+ "error-variable-names": {
+ "description": "When force-err-cuddling is enabled this is a list of names used for error variables to check for in the conditional.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "force-case-trailing-whitespace": {
+ "description": "Force newlines in end of case at this limit (0 = never).",
+ "type": "integer",
+ "minimum": 0,
+ "default": 0
+ },
+ "force-err-cuddling": {
+ "description": "Causes an error when an If statement that checks an error variable doesn't cuddle with the assignment of that variable.",
+ "type": "boolean",
+ "default": false
+ },
+ "force-short-decl-cuddling": {
+ "description": "Causes an error if a short declaration (:=) cuddles with anything other than another short declaration.",
+ "type": "boolean",
+ "default": false
+ },
+ "strict-append": {
+ "description": "If true, append is only allowed to be cuddled if appending value is matching variables, fields or types on line above.",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "wslSettingsV5": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "allow-first-in-block": {
+ "type": "boolean",
+ "default": true
+ },
+ "allow-whole-block": {
+ "type": "boolean",
+ "default": false
+ },
+ "branch-max-lines": {
+ "type": "integer",
+ "default": 2
+ },
+ "case-max-lines": {
+ "type": "integer",
+ "default": 0
+ },
+ "default": {
+ "enum": ["all", "none", "default", ""],
+ "default": "default"
+ },
+ "enable": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/wsl-checks"
+ }
+ },
+ "disable": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/wsl-checks"
+ }
+ }
+ }
+ },
+ "copyloopvarSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-alias": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "customSettings": {
+ "description": "The custom section can be used to define linter plugins to be loaded at runtime. See README of golangci-lint for more information.\nEach custom linter should have a unique name.",
+ "type": "object",
+ "patternProperties": {
+ "^.*$": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "type": {
+ "description": "The plugin type.",
+ "enum": ["module", "goplugin"],
+ "default": "goplugin"
+ },
+ "path": {
+ "description": "The path to the plugin *.so. Can be absolute or local.",
+ "type": "string",
+ "examples": ["/path/to/example.so"]
+ },
+ "description": {
+ "description": "The description of the linter, for documentation purposes only.",
+ "type": "string"
+ },
+ "original-url": {
+ "description": "Intended to point to the repo location of the linter, for documentation purposes only.",
+ "type": "string"
+ },
+ "settings": {
+ "description": "Plugins settings/configuration. Only work with plugin based on `linterdb.PluginConstructor`.",
+ "type": "object"
+ }
+ },
+ "oneOf": [
+ {
+ "properties": {
+ "type": {"enum": ["module"] }
+ },
+ "required": ["type"]
+ },
+ {
+ "required": ["path"]
+ }
+ ]
+ }
+ }
+ }
+ }
+ }
+ },
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["version"],
+ "properties": {
+ "version": {
+ "type": "string",
+ "default": "2"
+ },
+ "run": {
+ "description": "Options for analysis running,",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "concurrency": {
+ "description": "Number of concurrent runners. Defaults to the number of available CPU cores.",
+ "type": "integer",
+ "minimum": 0,
+ "examples": [4]
+ },
+ "timeout": {
+ "description": "Timeout for the analysis.",
+ "type": "string",
+ "pattern": "^((\\d+h)?(\\d+m)?(\\d+(?:\\.\\d)?s)?|0)$",
+ "default": "1m",
+ "examples": ["30s", "5m", "5m30s"]
+ },
+ "issues-exit-code": {
+ "description": "Exit code when at least one issue was found.",
+ "type": "integer",
+ "default": 1
+ },
+ "tests": {
+ "description": "Enable inclusion of test files.",
+ "type": "boolean",
+ "default": true
+ },
+ "build-tags": {
+ "description": "List of build tags to pass to all linters.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "default": [],
+ "examples": [["mytag"]]
+ },
+ "modules-download-mode": {
+ "description": "Option to pass to \"go list -mod={option}\".\nSee \"go help modules\" for more information.",
+ "enum": ["mod", "readonly", "vendor"]
+ },
+ "allow-parallel-runners": {
+ "description": "Allow multiple parallel golangci-lint instances running. If disabled, golangci-lint acquires file lock on start.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-serial-runners": {
+ "description": "Allow multiple golangci-lint instances running, but serialize them around a lock.",
+ "type": "boolean",
+ "default": false
+ },
+ "go": {
+ "description": "Targeted Go version.",
+ "type": "string",
+ "default": "1.17"
+ },
+ "relative-path-mode": {
+ "description": "The mode used to evaluate relative paths.",
+ "type": "string",
+ "$ref": "#/definitions/relative-path-modes",
+ "default": "wd"
+ }
+ }
+ },
+ "output": {
+ "description": "Output configuration options.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "formats": {
+ "description": "Output formats to use.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "text": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "path": {
+ "$ref": "#/definitions/formats-path",
+ "default": "stdout"
+ },
+ "print-linter-name": {
+ "type": "boolean",
+ "default": true
+ },
+ "print-issued-lines": {
+ "type": "boolean",
+ "default": true
+ },
+ "colors": {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "json": {
+ "$ref": "#/definitions/simple-format"
+ },
+ "tab": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "path": {
+ "$ref": "#/definitions/formats-path",
+ "default": "stdout"
+ },
+ "print-linter-name": {
+ "type": "boolean",
+ "default": true
+ },
+ "colors": {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "html": {
+ "$ref": "#/definitions/simple-format"
+ },
+ "checkstyle": {
+ "$ref": "#/definitions/simple-format"
+ },
+ "code-climate": {
+ "$ref": "#/definitions/simple-format"
+ },
+ "junit-xml": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "path": {
+ "$ref": "#/definitions/formats-path",
+ "default": "stdout"
+ },
+ "extended": {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "teamcity": {
+ "$ref": "#/definitions/simple-format"
+ },
+ "sarif": {
+ "$ref": "#/definitions/simple-format"
+ }
+ }
+ },
+ "path-mode": {
+ "type": "string",
+ "default": "",
+ "examples": ["abs"]
+ },
+ "path-prefix": {
+ "description": "Add a prefix to the output file references.",
+ "type": "string",
+ "default": ""
+ },
+ "show-stats": {
+ "description": "Show statistics per linter.",
+ "type": "boolean",
+ "default": true
+ },
+ "sort-order": {
+ "type": "array",
+ "items": {
+ "enum": ["linter", "severity", "file"]
+ }
+ }
+ }
+ },
+ "linters": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "default": {
+ "enum": [
+ "standard",
+ "all",
+ "none",
+ "fast"
+ ]
+ },
+ "enable": {
+ "description": "List of enabled linters.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linter-names"
+ }
+ },
+ "disable": {
+ "description": "List of disabled linters.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linter-names"
+ }
+ },
+ "settings": {
+ "description": "All available settings of specific linters.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "dupword": {
+ "$ref": "#/definitions/settings/definitions/dupwordSettings"
+ },
+ "asasalint": {
+ "$ref": "#/definitions/settings/definitions/asasalintSettings"
+ },
+ "bidichk": {
+ "$ref": "#/definitions/settings/definitions/bidichkSettings"
+ },
+ "cyclop": {
+ "$ref": "#/definitions/settings/definitions/cyclopSettings"
+ },
+ "decorder": {
+ "$ref": "#/definitions/settings/definitions/decorderSettings"
+ },
+ "depguard":{
+ "$ref": "#/definitions/settings/definitions/depguardSettings"
+ },
+ "dogsled": {
+ "$ref": "#/definitions/settings/definitions/dogsledSettings"
+ },
+ "dupl": {
+ "$ref": "#/definitions/settings/definitions/duplSettings"
+ },
+ "embeddedstructfieldcheck": {
+ "$ref": "#/definitions/settings/definitions/embeddedstructfieldcheckSettings"
+ },
+ "errcheck": {
+ "$ref": "#/definitions/settings/definitions/errcheckSettings"
+ },
+ "errchkjson": {
+ "$ref": "#/definitions/settings/definitions/errchkjsonSettings"
+ },
+ "errorlint": {
+ "$ref": "#/definitions/settings/definitions/errorlintSettings"
+ },
+ "exhaustive": {
+ "$ref": "#/definitions/settings/definitions/exhaustiveSettings"
+ },
+ "exhaustruct": {
+ "$ref": "#/definitions/settings/definitions/exhaustructSettings"
+ },
+ "fatcontext": {
+ "$ref": "#/definitions/settings/definitions/fatcontextSettings"
+ },
+ "forbidigo": {
+ "$ref": "#/definitions/settings/definitions/forbidigoSettings"
+ },
+ "funcorder": {
+ "$ref": "#/definitions/settings/definitions/funcorderSettings"
+ },
+ "funlen": {
+ "$ref": "#/definitions/settings/definitions/funlenSettings"
+ },
+ "ginkgolinter": {
+ "$ref": "#/definitions/settings/definitions/ginkgolinterSettings"
+ },
+ "gochecksumtype": {
+ "$ref": "#/definitions/settings/definitions/gochecksumtypeSettings"
+ },
+ "gocognit": {
+ "$ref": "#/definitions/settings/definitions/gocognitSettings"
+ },
+ "goconst": {
+ "$ref": "#/definitions/settings/definitions/goconstSettings"
+ },
+ "gocritic": {
+ "$ref": "#/definitions/settings/definitions/gocriticSettings"
+ },
+ "gocyclo": {
+ "$ref": "#/definitions/settings/definitions/gocycloSettings"
+ },
+ "godoclint": {
+ "$ref": "#/definitions/settings/definitions/godoclintSettings"
+ },
+ "godot": {
+ "$ref": "#/definitions/settings/definitions/godotSettings"
+ },
+ "godox": {
+ "$ref": "#/definitions/settings/definitions/godoxSettings"
+ },
+ "interfacebloat":{
+ "$ref": "#/definitions/settings/definitions/interfacebloatSettings"
+ },
+ "goheader": {
+ "$ref": "#/definitions/settings/definitions/goheaderSettings"
+ },
+ "gomoddirectives": {
+ "$ref": "#/definitions/settings/definitions/gomoddirectivesSettings"
+ },
+ "gomodguard": {
+ "$ref": "#/definitions/settings/definitions/gomodguardSettings"
+ },
+ "gosec": {
+ "$ref": "#/definitions/settings/definitions/gosecSettings"
+ },
+ "gosmopolitan": {
+ "$ref": "#/definitions/settings/definitions/gosmopolitanSettings"
+ },
+ "govet": {
+ "$ref": "#/definitions/settings/definitions/govetSettings"
+ },
+ "grouper": {
+ "$ref": "#/definitions/settings/definitions/grouperSettings"
+ },
+ "iface": {
+ "$ref": "#/definitions/settings/definitions/ifaceSettings"
+ },
+ "importas": {
+ "$ref": "#/definitions/settings/definitions/importasSettings"
+ },
+ "inamedparam": {
+ "$ref": "#/definitions/settings/definitions/inamedparamSettings"
+ },
+ "ineffassign": {
+ "$ref": "#/definitions/settings/definitions/ineffassignSettings"
+ },
+ "iotamixing": {
+ "$ref": "#/definitions/settings/definitions/iotamixingSettings"
+ },
+ "ireturn": {
+ "$ref": "#/definitions/settings/definitions/ireturnSettings"
+ },
+ "lll": {
+ "$ref": "#/definitions/settings/definitions/lllSettings"
+ },
+ "maintidx": {
+ "$ref": "#/definitions/settings/definitions/maintidxSettings"
+ },
+ "makezero":{
+ "$ref": "#/definitions/settings/definitions/makezeroSettings"
+ },
+ "loggercheck": {
+ "$ref": "#/definitions/settings/definitions/loggercheckSettings"
+ },
+ "misspell": {
+ "$ref": "#/definitions/settings/definitions/misspellSettings"
+ },
+ "musttag": {
+ "$ref": "#/definitions/settings/definitions/musttagSettings"
+ },
+ "nakedret": {
+ "$ref": "#/definitions/settings/definitions/nakedretSettings"
+ },
+ "nestif": {
+ "$ref": "#/definitions/settings/definitions/nestifSettings"
+ },
+ "nilnil": {
+ "$ref": "#/definitions/settings/definitions/nilnilSettings"
+ },
+ "nlreturn": {
+ "$ref": "#/definitions/settings/definitions/nlreturnSettings"
+ },
+ "mnd": {
+ "$ref": "#/definitions/settings/definitions/mndSettings"
+ },
+ "modernize": {
+ "$ref": "#/definitions/settings/definitions/modernizeSettings"
+ },
+ "nolintlint":{
+ "$ref": "#/definitions/settings/definitions/nolintlintSettings"
+ },
+ "reassign": {
+ "$ref": "#/definitions/settings/definitions/reassignSettings"
+ },
+ "recvcheck": {
+ "$ref": "#/definitions/settings/definitions/recvcheckSettings"
+ },
+ "nonamedreturns": {
+ "$ref": "#/definitions/settings/definitions/nonamedreturnsSettings"
+ },
+ "paralleltest": {
+ "$ref": "#/definitions/settings/definitions/paralleltestSettings"
+ },
+ "perfsprint": {
+ "$ref": "#/definitions/settings/definitions/perfsprintSettings"
+ },
+ "prealloc": {
+ "$ref": "#/definitions/settings/definitions/preallocSettings"
+ },
+ "predeclared": {
+ "$ref": "#/definitions/settings/definitions/predeclaredSettings"
+ },
+ "promlinter": {
+ "$ref": "#/definitions/settings/definitions/promlinterSettings"
+ },
+ "protogetter": {
+ "$ref": "#/definitions/settings/definitions/protogetterSettings"
+ },
+ "revive": {
+ "$ref": "#/definitions/settings/definitions/reviveSettings"
+ },
+ "rowserrcheck": {
+ "$ref": "#/definitions/settings/definitions/rowserrcheckSettings"
+ },
+ "sloglint": {
+ "$ref": "#/definitions/settings/definitions/sloglintSettings"
+ },
+ "spancheck": {
+ "$ref": "#/definitions/settings/definitions/spancheckSettings"
+ },
+ "staticcheck":{
+ "$ref": "#/definitions/settings/definitions/staticcheckSettings"
+ },
+ "tagalign": {
+ "$ref": "#/definitions/settings/definitions/tagalignSettings"
+ },
+ "tagliatelle": {
+ "$ref": "#/definitions/settings/definitions/tagliatelleSettings"
+ },
+ "testifylint": {
+ "$ref": "#/definitions/settings/definitions/testifylintSettings"
+ },
+ "testpackage": {
+ "$ref": "#/definitions/settings/definitions/testpackageSettings"
+ },
+ "thelper": {
+ "$ref": "#/definitions/settings/definitions/thelperSettings"
+ },
+ "usestdlibvars": {
+ "$ref": "#/definitions/settings/definitions/usestdlibvarsSettings"
+ },
+ "usetesting": {
+ "$ref": "#/definitions/settings/definitions/usetestingSettings"
+ },
+ "unconvert": {
+ "$ref": "#/definitions/settings/definitions/unconvertSettings"
+ },
+ "unparam": {
+ "$ref": "#/definitions/settings/definitions/unparamSettings"
+ },
+ "unqueryvet": {
+ "$ref": "#/definitions/settings/definitions/unqueryvetSettings"
+ },
+ "unused": {
+ "$ref": "#/definitions/settings/definitions/unusedSettings"
+ },
+ "varnamelen": {
+ "$ref": "#/definitions/settings/definitions/varnamelenSettings"
+ },
+ "whitespace": {
+ "$ref": "#/definitions/settings/definitions/whitespaceSettings"
+ },
+ "wrapcheck": {
+ "$ref": "#/definitions/settings/definitions/wrapcheckSettings"
+ },
+ "wsl": {
+ "$ref": "#/definitions/settings/definitions/wslSettings"
+ },
+ "wsl_v5": {
+ "$ref": "#/definitions/settings/definitions/wslSettingsV5"
+ },
+ "copyloopvar": {
+ "$ref": "#/definitions/settings/definitions/copyloopvarSettings"
+ },
+ "custom":{
+ "$ref": "#/definitions/settings/definitions/customSettings"
+ }
+ }
+ },
+ "exclusions":{
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "generated": {
+ "enum": ["strict", "lax", "disable"],
+ "default": "strict"
+ },
+ "warn-unused": {
+ "type": "boolean",
+ "default": false
+ },
+ "presets": {
+ "type": "array",
+ "items": {
+ "enum": [
+ "comments",
+ "std-error-handling",
+ "common-false-positives",
+ "legacy"
+ ]
+ }
+ },
+ "rules": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "path": {
+ "type": "string"
+ },
+ "path-except": {
+ "type": "string"
+ },
+ "linters": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linter-names"
+ }
+ },
+ "text": {
+ "type": "string"
+ },
+ "source": {
+ "type": "string"
+ }
+ },
+ "anyOf": [
+ { "required": ["path"] },
+ { "required": ["path-except"] },
+ { "required": ["linters"] },
+ { "required": ["text"] },
+ { "required": ["source"] }
+ ]
+ }
+ },
+ "paths": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "paths-except": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "formatters": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "enable": {
+ "description": "List of enabled formatters.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/formatter-names"
+ }
+ },
+ "settings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "gci": {
+ "$ref": "#/definitions/settings/definitions/gciSettings"
+ },
+ "gofmt": {
+ "$ref": "#/definitions/settings/definitions/gofmtSettings"
+ },
+ "gofumpt": {
+ "$ref": "#/definitions/settings/definitions/gofumptSettings"
+ },
+ "goimports": {
+ "$ref": "#/definitions/settings/definitions/goimportsSettings"
+ },
+ "golines": {
+ "$ref": "#/definitions/settings/definitions/golinesSettings"
+ }
+ }
+ },
+ "exclusions": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "generated": {
+ "enum": ["strict", "lax", "disable"],
+ "default": "strict"
+ },
+ "paths": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "warn-unused": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ }
+ }
+ },
+ "issues": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-issues-per-linter": {
+ "description": "Maximum issues count per one linter. Set to 0 to disable.",
+ "type": "integer",
+ "default": 50,
+ "minimum": 0
+ },
+ "max-same-issues": {
+ "description": "Maximum count of issues with the same text. Set to 0 to disable.",
+ "type": "integer",
+ "default": 3,
+ "minimum": 0
+ },
+ "new": {
+ "description": "Show only new issues: if there are unstaged changes or untracked files, only those changes are analyzed, else only changes in HEAD~ are analyzed.",
+ "type": "boolean",
+ "default": false
+ },
+ "new-from-merge-base": {
+ "description": "Show only new issues created after the best common ancestor (merge-base against HEAD).",
+ "type": "string"
+ },
+ "new-from-rev": {
+ "description": "Show only new issues created after this git revision.",
+ "type": "string"
+ },
+ "new-from-patch": {
+ "description": "Show only new issues created in git patch with this file path.",
+ "type": "string",
+ "examples": ["path/to/patch/file"]
+ },
+ "fix": {
+ "description": "Apply the fixes detected by the linters and formatters (if it's supported by the linter).",
+ "type": "boolean",
+ "default": false
+ },
+ "uniq-by-line": {
+ "description": "Make issues output unique by line.",
+ "type": "boolean",
+ "default": true
+ },
+ "whole-files": {
+ "description": "Show issues in any part of update files (requires new-from-rev or new-from-patch).",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "severity": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "default": {
+ "description": "Set the default severity for issues. If severity rules are defined and the issues do not match or no severity is provided to the rule this will be the default severity applied. Severities should match the supported severity names of the selected out format.",
+ "type": "string",
+ "default": ""
+ },
+ "rules": {
+ "description": "When a list of severity rules are provided, severity information will be added to lint issues. Severity rules have the same filtering capability as exclude rules except you are allowed to specify one matcher per severity rule.\nOnly affects out formats that support setting severity information.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "severity": {
+ "type": "string"
+ },
+ "path": {
+ "type": "string"
+ },
+ "path-except": {
+ "type": "string"
+ },
+ "linters": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linter-names"
+ }
+ },
+ "text": {
+ "type": "string"
+ },
+ "source": {
+ "type": "string"
+ }
+ },
+ "required": ["severity"],
+ "anyOf": [
+ { "required": ["path"] },
+ { "required": ["path-except"] },
+ { "required": ["linters"] },
+ { "required": ["text"] },
+ { "required": ["source"] }
+ ]
+ },
+ "default": []
+ }
+ },
+ "required": ["default"]
+ }
+ }
+}
diff --git a/vendor/github.com/golangci/golangci-lint/v2/jsonschema/golangci.v2.7.jsonschema.json b/vendor/github.com/golangci/golangci-lint/v2/jsonschema/golangci.v2.7.jsonschema.json
new file mode 100644
index 000000000..accf61f97
--- /dev/null
+++ b/vendor/github.com/golangci/golangci-lint/v2/jsonschema/golangci.v2.7.jsonschema.json
@@ -0,0 +1,5144 @@
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "$id": "https://json.schemastore.org/golangci-lint.json",
+ "definitions": {
+ "gocritic-checks": {
+ "enum": [
+ "appendAssign",
+ "appendCombine",
+ "argOrder",
+ "assignOp",
+ "badCall",
+ "badCond",
+ "badLock",
+ "badRegexp",
+ "badSorting",
+ "badSyncOnceFunc",
+ "boolExprSimplify",
+ "builtinShadow",
+ "builtinShadowDecl",
+ "captLocal",
+ "caseOrder",
+ "codegenComment",
+ "commentFormatting",
+ "commentedOutCode",
+ "commentedOutImport",
+ "defaultCaseOrder",
+ "deferInLoop",
+ "deferUnlambda",
+ "deprecatedComment",
+ "docStub",
+ "dupArg",
+ "dupBranchBody",
+ "dupCase",
+ "dupImport",
+ "dupOption",
+ "dupSubExpr",
+ "dynamicFmtString",
+ "elseif",
+ "emptyDecl",
+ "emptyFallthrough",
+ "emptyStringTest",
+ "equalFold",
+ "evalOrder",
+ "exitAfterDefer",
+ "exposedSyncMutex",
+ "externalErrorReassign",
+ "filepathJoin",
+ "flagDeref",
+ "flagName",
+ "hexLiteral",
+ "httpNoBody",
+ "hugeParam",
+ "ifElseChain",
+ "importShadow",
+ "indexAlloc",
+ "initClause",
+ "mapKey",
+ "methodExprCall",
+ "nestingReduce",
+ "newDeref",
+ "nilValReturn",
+ "octalLiteral",
+ "offBy1",
+ "paramTypeCombine",
+ "preferDecodeRune",
+ "preferFilepathJoin",
+ "preferFprint",
+ "preferStringWriter",
+ "preferWriteByte",
+ "ptrToRefParam",
+ "rangeAppendAll",
+ "rangeExprCopy",
+ "rangeValCopy",
+ "redundantSprint",
+ "regexpMust",
+ "regexpPattern",
+ "regexpSimplify",
+ "returnAfterHttpError",
+ "ruleguard",
+ "singleCaseSwitch",
+ "sliceClear",
+ "sloppyLen",
+ "sloppyReassign",
+ "sloppyTypeAssert",
+ "sortSlice",
+ "sprintfQuotedString",
+ "sqlQuery",
+ "stringConcatSimplify",
+ "stringXbytes",
+ "stringsCompare",
+ "switchTrue",
+ "syncMapLoadAndDelete",
+ "timeExprSimplify",
+ "todoCommentWithoutDetail",
+ "tooManyResultsChecker",
+ "truncateCmp",
+ "typeAssertChain",
+ "typeDefFirst",
+ "typeSwitchVar",
+ "typeUnparen",
+ "uncheckedInlineErr",
+ "underef",
+ "unlabelStmt",
+ "unlambda",
+ "unnamedResult",
+ "unnecessaryBlock",
+ "unnecessaryDefer",
+ "unslice",
+ "valSwap",
+ "weakCond",
+ "whyNoLint",
+ "wrapperFunc",
+ "yodaStyleExpr",
+ "zeroByteRepeat"
+ ]
+ },
+ "gocritic-tags": {
+ "enum": [
+ "diagnostic",
+ "style",
+ "performance",
+ "experimental",
+ "opinionated",
+ "security"
+ ]
+ },
+ "staticcheck-checks": {
+ "enum": [
+ "*",
+ "all",
+ "SA*",
+ "-SA*",
+ "SA1*",
+ "-SA1*",
+ "SA1000",
+ "-SA1000",
+ "SA1001",
+ "-SA1001",
+ "SA1002",
+ "-SA1002",
+ "SA1003",
+ "-SA1003",
+ "SA1004",
+ "-SA1004",
+ "SA1005",
+ "-SA1005",
+ "SA1006",
+ "-SA1006",
+ "SA1007",
+ "-SA1007",
+ "SA1008",
+ "-SA1008",
+ "SA1010",
+ "-SA1010",
+ "SA1011",
+ "-SA1011",
+ "SA1012",
+ "-SA1012",
+ "SA1013",
+ "-SA1013",
+ "SA1014",
+ "-SA1014",
+ "SA1015",
+ "-SA1015",
+ "SA1016",
+ "-SA1016",
+ "SA1017",
+ "-SA1017",
+ "SA1018",
+ "-SA1018",
+ "SA1019",
+ "-SA1019",
+ "SA1020",
+ "-SA1020",
+ "SA1021",
+ "-SA1021",
+ "SA1023",
+ "-SA1023",
+ "SA1024",
+ "-SA1024",
+ "SA1025",
+ "-SA1025",
+ "SA1026",
+ "-SA1026",
+ "SA1027",
+ "-SA1027",
+ "SA1028",
+ "-SA1028",
+ "SA1029",
+ "-SA1029",
+ "SA1030",
+ "-SA1030",
+ "SA1031",
+ "-SA1031",
+ "SA1032",
+ "-SA1032",
+ "SA2*",
+ "-SA2*",
+ "SA2000",
+ "-SA2000",
+ "SA2001",
+ "-SA2001",
+ "SA2002",
+ "-SA2002",
+ "SA2003",
+ "-SA2003",
+ "SA3*",
+ "-SA3*",
+ "SA3000",
+ "-SA3000",
+ "SA3001",
+ "-SA3001",
+ "SA4*",
+ "-SA4*",
+ "SA4000",
+ "-SA4000",
+ "SA4001",
+ "-SA4001",
+ "SA4003",
+ "-SA4003",
+ "SA4004",
+ "-SA4004",
+ "SA4005",
+ "-SA4005",
+ "SA4006",
+ "-SA4006",
+ "SA4008",
+ "-SA4008",
+ "SA4009",
+ "-SA4009",
+ "SA4010",
+ "-SA4010",
+ "SA4011",
+ "-SA4011",
+ "SA4012",
+ "-SA4012",
+ "SA4013",
+ "-SA4013",
+ "SA4014",
+ "-SA4014",
+ "SA4015",
+ "-SA4015",
+ "SA4016",
+ "-SA4016",
+ "SA4017",
+ "-SA4017",
+ "SA4018",
+ "-SA4018",
+ "SA4019",
+ "-SA4019",
+ "SA4020",
+ "-SA4020",
+ "SA4021",
+ "-SA4021",
+ "SA4022",
+ "-SA4022",
+ "SA4023",
+ "-SA4023",
+ "SA4024",
+ "-SA4024",
+ "SA4025",
+ "-SA4025",
+ "SA4026",
+ "-SA4026",
+ "SA4027",
+ "-SA4027",
+ "SA4028",
+ "-SA4028",
+ "SA4029",
+ "-SA4029",
+ "SA4030",
+ "-SA4030",
+ "SA4031",
+ "-SA4031",
+ "SA4032",
+ "-SA4032",
+ "SA5*",
+ "-SA5*",
+ "SA5000",
+ "-SA5000",
+ "SA5001",
+ "-SA5001",
+ "SA5002",
+ "-SA5002",
+ "SA5003",
+ "-SA5003",
+ "SA5004",
+ "-SA5004",
+ "SA5005",
+ "-SA5005",
+ "SA5007",
+ "-SA5007",
+ "SA5008",
+ "-SA5008",
+ "SA5009",
+ "-SA5009",
+ "SA5010",
+ "-SA5010",
+ "SA5011",
+ "-SA5011",
+ "SA5012",
+ "-SA5012",
+ "SA6*",
+ "-SA6*",
+ "SA6000",
+ "-SA6000",
+ "SA6001",
+ "-SA6001",
+ "SA6002",
+ "-SA6002",
+ "SA6003",
+ "-SA6003",
+ "SA6005",
+ "-SA6005",
+ "SA6006",
+ "-SA6006",
+ "SA9*",
+ "-SA9*",
+ "SA9001",
+ "-SA9001",
+ "SA9002",
+ "-SA9002",
+ "SA9003",
+ "-SA9003",
+ "SA9004",
+ "-SA9004",
+ "SA9005",
+ "-SA9005",
+ "SA9006",
+ "-SA9006",
+ "SA9007",
+ "-SA9007",
+ "SA9008",
+ "-SA9008",
+ "SA9009",
+ "-SA9009",
+ "ST*",
+ "-ST*",
+ "ST1*",
+ "-ST1*",
+ "ST1000",
+ "-ST1000",
+ "ST1001",
+ "-ST1001",
+ "ST1003",
+ "-ST1003",
+ "ST1005",
+ "-ST1005",
+ "ST1006",
+ "-ST1006",
+ "ST1008",
+ "-ST1008",
+ "ST1011",
+ "-ST1011",
+ "ST1012",
+ "-ST1012",
+ "ST1013",
+ "-ST1013",
+ "ST1015",
+ "-ST1015",
+ "ST1016",
+ "-ST1016",
+ "ST1017",
+ "-ST1017",
+ "ST1018",
+ "-ST1018",
+ "ST1019",
+ "-ST1019",
+ "ST1020",
+ "-ST1020",
+ "ST1021",
+ "-ST1021",
+ "ST1022",
+ "-ST1022",
+ "ST1023",
+ "-ST1023",
+ "S*",
+ "-S*",
+ "S1*",
+ "-S1*",
+ "S1000",
+ "-S1000",
+ "S1001",
+ "-S1001",
+ "S1002",
+ "-S1002",
+ "S1003",
+ "-S1003",
+ "S1004",
+ "-S1004",
+ "S1005",
+ "-S1005",
+ "S1006",
+ "-S1006",
+ "S1007",
+ "-S1007",
+ "S1008",
+ "-S1008",
+ "S1009",
+ "-S1009",
+ "S1010",
+ "-S1010",
+ "S1011",
+ "-S1011",
+ "S1012",
+ "-S1012",
+ "S1016",
+ "-S1016",
+ "S1017",
+ "-S1017",
+ "S1018",
+ "-S1018",
+ "S1019",
+ "-S1019",
+ "S1020",
+ "-S1020",
+ "S1021",
+ "-S1021",
+ "S1023",
+ "-S1023",
+ "S1024",
+ "-S1024",
+ "S1025",
+ "-S1025",
+ "S1028",
+ "-S1028",
+ "S1029",
+ "-S1029",
+ "S1030",
+ "-S1030",
+ "S1031",
+ "-S1031",
+ "S1032",
+ "-S1032",
+ "S1033",
+ "-S1033",
+ "S1034",
+ "-S1034",
+ "S1035",
+ "-S1035",
+ "S1036",
+ "-S1036",
+ "S1037",
+ "-S1037",
+ "S1038",
+ "-S1038",
+ "S1039",
+ "-S1039",
+ "S1040",
+ "-S1040",
+ "QF*",
+ "-QF*",
+ "QF1*",
+ "-QF1*",
+ "QF1001",
+ "-QF1001",
+ "QF1002",
+ "-QF1002",
+ "QF1003",
+ "-QF1003",
+ "QF1004",
+ "-QF1004",
+ "QF1005",
+ "-QF1005",
+ "QF1006",
+ "-QF1006",
+ "QF1007",
+ "-QF1007",
+ "QF1008",
+ "-QF1008",
+ "QF1009",
+ "-QF1009",
+ "QF1010",
+ "-QF1010",
+ "QF1011",
+ "-QF1011",
+ "QF1012",
+ "-QF1012"
+ ]
+ },
+ "godoclint-rules": {
+ "enum": [
+ "pkg-doc",
+ "single-pkg-doc",
+ "require-pkg-doc",
+ "start-with-name",
+ "require-doc",
+ "deprecated",
+ "max-len",
+ "no-unused-link"
+ ]
+ },
+ "gosec-rules": {
+ "enum": [
+ "G101",
+ "G102",
+ "G103",
+ "G104",
+ "G106",
+ "G107",
+ "G108",
+ "G109",
+ "G110",
+ "G111",
+ "G112",
+ "G114",
+ "G115",
+ "G201",
+ "G202",
+ "G203",
+ "G204",
+ "G301",
+ "G302",
+ "G303",
+ "G304",
+ "G305",
+ "G306",
+ "G307",
+ "G401",
+ "G402",
+ "G403",
+ "G404",
+ "G405",
+ "G406",
+ "G501",
+ "G502",
+ "G503",
+ "G504",
+ "G505",
+ "G506",
+ "G507",
+ "G601",
+ "G602"
+ ]
+ },
+ "govet-analyzers": {
+ "enum": [
+ "appends",
+ "asmdecl",
+ "assign",
+ "atomic",
+ "atomicalign",
+ "bools",
+ "buildtag",
+ "cgocall",
+ "composites",
+ "copylocks",
+ "deepequalerrors",
+ "defers",
+ "directive",
+ "errorsas",
+ "fieldalignment",
+ "findcall",
+ "framepointer",
+ "hostport",
+ "httpmux",
+ "httpresponse",
+ "ifaceassert",
+ "loopclosure",
+ "lostcancel",
+ "nilfunc",
+ "nilness",
+ "printf",
+ "reflectvaluecompare",
+ "shadow",
+ "shift",
+ "sigchanyzer",
+ "slog",
+ "sortslice",
+ "stdmethods",
+ "stdversion",
+ "stringintconv",
+ "structtag",
+ "testinggoroutine",
+ "tests",
+ "timeformat",
+ "unmarshal",
+ "unreachable",
+ "unsafeptr",
+ "unusedresult",
+ "unusedwrite",
+ "waitgroup"
+ ]
+ },
+ "revive-rules": {
+ "enum": [
+ "add-constant",
+ "argument-limit",
+ "atomic",
+ "banned-characters",
+ "bare-return",
+ "blank-imports",
+ "bool-literal-in-expr",
+ "call-to-gc",
+ "cognitive-complexity",
+ "comment-spacings",
+ "comments-density",
+ "confusing-naming",
+ "confusing-results",
+ "constant-logical-expr",
+ "context-as-argument",
+ "context-keys-type",
+ "cyclomatic",
+ "datarace",
+ "deep-exit",
+ "defer",
+ "dot-imports",
+ "duplicated-imports",
+ "early-return",
+ "empty-block",
+ "empty-lines",
+ "enforce-map-style",
+ "enforce-repeated-arg-type-style",
+ "enforce-slice-style",
+ "enforce-switch-style",
+ "error-naming",
+ "error-return",
+ "error-strings",
+ "errorf",
+ "exported",
+ "file-header",
+ "file-length-limit",
+ "filename-format",
+ "flag-parameter",
+ "forbidden-call-in-wg-go",
+ "function-length",
+ "function-result-limit",
+ "get-return",
+ "identical-branches",
+ "identical-ifelseif-branches",
+ "identical-ifelseif-conditions",
+ "identical-switch-branches",
+ "identical-switch-conditions",
+ "if-return",
+ "import-alias-naming",
+ "import-shadowing",
+ "imports-blocklist",
+ "increment-decrement",
+ "indent-error-flow",
+ "inefficient-map-lookup",
+ "line-length-limit",
+ "max-control-nesting",
+ "max-public-structs",
+ "modifies-parameter",
+ "modifies-value-receiver",
+ "nested-structs",
+ "optimize-operands-order",
+ "package-comments",
+ "package-directory-mismatch",
+ "range-val-address",
+ "range-val-in-closure",
+ "range",
+ "receiver-naming",
+ "redefines-builtin-id",
+ "redundant-build-tag",
+ "redundant-import-alias",
+ "redundant-test-main-exit",
+ "string-format",
+ "string-of-int",
+ "struct-tag",
+ "superfluous-else",
+ "time-date",
+ "time-equal",
+ "time-naming",
+ "unchecked-type-assertion",
+ "unconditional-recursion",
+ "unexported-naming",
+ "unexported-return",
+ "unhandled-error",
+ "unnecessary-format",
+ "unnecessary-if",
+ "unnecessary-stmt",
+ "unreachable-code",
+ "unsecure-url-scheme",
+ "unused-parameter",
+ "unused-receiver",
+ "use-any",
+ "use-errors-new",
+ "use-fmt-print",
+ "use-waitgroup-go",
+ "useless-break",
+ "useless-fallthrough",
+ "var-declaration",
+ "var-naming",
+ "waitgroup-by-value"
+ ]
+ },
+ "iface-analyzers": {
+ "enum": [
+ "identical",
+ "unused",
+ "opaque",
+ "unexported"
+ ]
+ },
+ "tagliatelle-cases": {
+ "enum": [
+ "",
+ "camel",
+ "pascal",
+ "kebab",
+ "snake",
+ "goCamel",
+ "goPascal",
+ "goKebab",
+ "goSnake",
+ "upper",
+ "upperSnake",
+ "lower",
+ "header"
+ ]
+ },
+ "modernize-analyzers": {
+ "enum": [
+ "any",
+ "bloop",
+ "fmtappendf",
+ "forvar",
+ "mapsloop",
+ "minmax",
+ "newexpr",
+ "omitzero",
+ "plusbuild",
+ "rangeint",
+ "reflecttypefor",
+ "slicescontains",
+ "slicessort",
+ "stditerators",
+ "stringscutprefix",
+ "stringsseq",
+ "stringsbuilder",
+ "testingcontext",
+ "waitgroup"
+ ]
+ },
+ "wsl-checks": {
+ "enum": [
+ "assign",
+ "branch",
+ "decl",
+ "defer",
+ "expr",
+ "for",
+ "go",
+ "if",
+ "inc-dec",
+ "label",
+ "range",
+ "return",
+ "select",
+ "send",
+ "switch",
+ "type-switch",
+ "append",
+ "assign-exclusive",
+ "assign-expr",
+ "err",
+ "leading-whitespace",
+ "trailing-whitespace"
+ ]
+ },
+ "relative-path-modes": {
+ "enum": [
+ "gomod",
+ "gitroot",
+ "cfg",
+ "wd"
+ ]
+ },
+ "simple-format": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "path": {
+ "$ref": "#/definitions/formats-path",
+ "default": "stdout"
+ }
+ }
+ },
+ "formats-path" : {
+ "anyOf": [
+ {
+ "enum": [
+ "stdout",
+ "stderr"
+ ]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ },
+ "linter-names": {
+ "$comment": "anyOf with enum is used to allow auto-completion of non-custom linters",
+ "description": "Usable linter names.",
+ "anyOf": [
+ {
+ "enum": [
+ "arangolint",
+ "asasalint",
+ "asciicheck",
+ "bidichk",
+ "bodyclose",
+ "canonicalheader",
+ "containedctx",
+ "contextcheck",
+ "copyloopvar",
+ "cyclop",
+ "decorder",
+ "depguard",
+ "dogsled",
+ "dupl",
+ "dupword",
+ "durationcheck",
+ "embeddedstructfieldcheck",
+ "errcheck",
+ "errchkjson",
+ "errname",
+ "errorlint",
+ "exhaustive",
+ "exhaustruct",
+ "exptostd",
+ "fatcontext",
+ "forbidigo",
+ "forcetypeassert",
+ "funcorder",
+ "funlen",
+ "ginkgolinter",
+ "gocheckcompilerdirectives",
+ "gochecknoglobals",
+ "gochecknoinits",
+ "gochecksumtype",
+ "gocognit",
+ "goconst",
+ "gocritic",
+ "gocyclo",
+ "godoclint",
+ "godot",
+ "godox",
+ "err113",
+ "goheader",
+ "gomoddirectives",
+ "gomodguard",
+ "goprintffuncname",
+ "gosec",
+ "gosimple",
+ "gosmopolitan",
+ "govet",
+ "grouper",
+ "iface",
+ "importas",
+ "inamedparam",
+ "ineffassign",
+ "interfacebloat",
+ "intrange",
+ "iotamixing",
+ "ireturn",
+ "lll",
+ "loggercheck",
+ "maintidx",
+ "makezero",
+ "mirror",
+ "misspell",
+ "mnd",
+ "modernize",
+ "musttag",
+ "nakedret",
+ "nestif",
+ "nilerr",
+ "nilnesserr",
+ "nilnil",
+ "nlreturn",
+ "noctx",
+ "noinlineerr",
+ "nolintlint",
+ "nonamedreturns",
+ "nosprintfhostport",
+ "paralleltest",
+ "perfsprint",
+ "prealloc",
+ "predeclared",
+ "promlinter",
+ "protogetter",
+ "reassign",
+ "recvcheck",
+ "revive",
+ "rowserrcheck",
+ "sloglint",
+ "sqlclosecheck",
+ "staticcheck",
+ "stylecheck",
+ "tagalign",
+ "tagliatelle",
+ "testableexamples",
+ "testifylint",
+ "testpackage",
+ "thelper",
+ "tparallel",
+ "unconvert",
+ "unparam",
+ "unused",
+ "usestdlibvars",
+ "usetesting",
+ "varnamelen",
+ "wastedassign",
+ "whitespace",
+ "wrapcheck",
+ "wsl",
+ "wsl_v5",
+ "zerologlint"
+ ]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ },
+ "formatter-names": {
+ "description": "Usable formatter names.",
+ "enum": [
+ "gci",
+ "gofmt",
+ "gofumpt",
+ "goimports",
+ "golines",
+ "swaggo"
+ ]
+ },
+ "settings": {
+ "definitions": {
+ "dupwordSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "keywords": {
+ "description": "Keywords for detecting duplicate words. If this list is not empty, only the words defined in this list will be detected.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["the", "and", "a"]
+ }
+ },
+ "ignore": {
+ "description": "Keywords used to ignore detection.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["0C0C"]
+ }
+ },
+ "comments-only": {
+ "description": "Checks only comments, skip strings.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "asasalintSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "exclude": {
+ "description": "To specify a set of function names to exclude.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["\\.Wrapf"]
+ }
+ },
+ "use-builtin-exclusions": {
+ "description": "To enable/disable the asasalint builtin exclusions of function names.",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "bidichkSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "left-to-right-embedding": {
+ "description": "Disallow: LEFT-TO-RIGHT-EMBEDDING",
+ "type": "boolean",
+ "default": false
+ },
+ "right-to-left-embedding": {
+ "description": "Disallow: RIGHT-TO-LEFT-EMBEDDING",
+ "type": "boolean",
+ "default": false
+ },
+ "pop-directional-formatting": {
+ "description": "Disallow: POP-DIRECTIONAL-FORMATTING",
+ "type": "boolean",
+ "default": false
+ },
+ "left-to-right-override": {
+ "description": "Disallow: LEFT-TO-RIGHT-OVERRIDE",
+ "type": "boolean",
+ "default": false
+ },
+ "right-to-left-override": {
+ "description": "Disallow: RIGHT-TO-LEFT-OVERRIDE",
+ "type": "boolean",
+ "default": false
+ },
+ "left-to-right-isolate": {
+ "description": "Disallow: LEFT-TO-RIGHT-ISOLATE",
+ "type": "boolean",
+ "default": false
+ },
+ "right-to-left-isolate": {
+ "description": "Disallow: RIGHT-TO-LEFT-ISOLATE",
+ "type": "boolean",
+ "default": false
+ },
+ "first-strong-isolate": {
+ "description": "Disallow: FIRST-STRONG-ISOLATE",
+ "type": "boolean",
+ "default": false
+ },
+ "pop-directional-isolate": {
+ "description": "Disallow: POP-DIRECTIONAL-ISOLATE",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "cyclopSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-complexity": {
+ "description": "Max complexity the function can have",
+ "type": "integer",
+ "default": 10,
+ "minimum": 0
+ },
+ "package-average": {
+ "description": "Max average complexity in package",
+ "type": "number",
+ "default": 0,
+ "minimum": 0
+ }
+ }
+ },
+ "decorderSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "dec-order": {
+ "type": "array",
+ "default": [["type", "const", "var", "func"]],
+ "items": {
+ "enum": ["type", "const", "var", "func"]
+ }
+ },
+ "ignore-underscore-vars": {
+ "description": "Underscore vars (vars with \"_\" as the name) will be ignored at all checks",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-dec-order-check": {
+ "description": "Order of declarations is not checked",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-init-func-first-check": {
+ "description": "Allow init func to be anywhere in file",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-dec-num-check": {
+ "description": "Multiple global type, const and var declarations are allowed",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-type-dec-num-check": {
+ "description": "Type declarations will be ignored for dec num check",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-const-dec-num-check": {
+ "description": "Const declarations will be ignored for dec num check",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-var-dec-num-check": {
+ "description": "Var declarations will be ignored for dec num check",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ },
+ "depguardSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "rules": {
+ "description": "Rules to apply.",
+ "type": "object",
+ "additionalProperties": false,
+ "patternProperties": {
+ "^[^.]+$": {
+ "description": "Name of a rule.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "list-mode": {
+ "description": "Used to determine the package matching priority.",
+ "enum": ["original", "strict", "lax"],
+ "default": "original"
+ },
+ "files": {
+ "description": "List of file globs that will match this list of settings to compare against.",
+ "additionalProperties": false,
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "allow": {
+ "description": "List of allowed packages.",
+ "additionalProperties": false,
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "deny": {
+ "description": "Packages that are not allowed where the value is a suggestion.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "desc": {
+ "description": "Description",
+ "type": "string"
+ },
+ "pkg": {
+ "description": "Package",
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "dogsledSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-blank-identifiers": {
+ "description": "Check assignments with too many blank identifiers.",
+ "type": "integer",
+ "default": 2,
+ "minimum": 0
+ }
+ }
+ },
+ "duplSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "threshold": {
+ "description": "Tokens count to trigger issue.",
+ "type": "integer",
+ "default": 150,
+ "minimum": 0
+ }
+ }
+ },
+ "embeddedstructfieldcheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "empty-line": {
+ "description": "Checks that there is an empty space between the embedded fields and regular fields.",
+ "type": "boolean",
+ "default": false
+ },
+ "forbid-mutex": {
+ "description": "Checks that sync.Mutex and sync.RWMutex are not used as embedded fields.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "errcheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-type-assertions": {
+ "description": "Report about not checking errors in type assertions, i.e.: `a := b.(MyStruct)`",
+ "type": "boolean",
+ "default": false
+ },
+ "check-blank": {
+ "description": "Report about assignment of errors to blank identifier",
+ "type": "boolean",
+ "default": false
+ },
+ "exclude-functions": {
+ "description": "List of functions to exclude from checking, where each entry is a single function to exclude",
+ "type": "array",
+ "examples": ["io/ioutil.ReadFile", "io.Copy(*bytes.Buffer)"],
+ "items": {
+ "type": "string"
+ }
+ },
+ "disable-default-exclusions": {
+ "description": "To disable the errcheck built-in exclude list",
+ "type": "boolean",
+ "default": false
+ },
+ "verbose": {
+ "description": "Display function signature instead of selector",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "errchkjsonSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-error-free-encoding": {
+ "type": "boolean",
+ "default": false
+ },
+ "report-no-exported": {
+ "description": "Issue on struct that doesn't have exported fields.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "errorlintSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "errorf": {
+ "description": "Check whether fmt.Errorf uses the %w verb for formatting errors",
+ "type": "boolean",
+ "default": true
+ },
+ "errorf-multi": {
+ "description": "Permit more than 1 %w verb, valid per Go 1.20",
+ "type": "boolean",
+ "default": true
+ },
+ "asserts": {
+ "description": "Check for plain type assertions and type switches.",
+ "type": "boolean",
+ "default": true
+ },
+ "comparison": {
+ "description": "Check for plain error comparisons",
+ "type": "boolean",
+ "default": true
+ },
+ "allowed-errors": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "err": {
+ "type": "string"
+ },
+ "fun": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "allowed-errors-wildcard": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "err": {
+ "type": "string"
+ },
+ "fun": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "exhaustiveSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check": {
+ "description": "Program elements to check for exhaustiveness.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["switch", "map"]
+ }
+ },
+ "explicit-exhaustive-switch": {
+ "description": "Only run exhaustive check on switches with \"//exhaustive:enforce\" comment.",
+ "type": "boolean",
+ "default": false
+ },
+ "explicit-exhaustive-map": {
+ "description": "Only run exhaustive check on map literals with \"//exhaustive:enforce\" comment.",
+ "type": "boolean",
+ "default": false
+ },
+ "default-case-required": {
+ "description": "Switch statement requires default case even if exhaustive.",
+ "type": "boolean",
+ "default": false
+ },
+ "default-signifies-exhaustive": {
+ "description": "Presence of `default` case in switch statements satisfies exhaustiveness, even if all enum members are not listed.",
+ "type": "boolean",
+ "default": false
+ },
+ "ignore-enum-members": {
+ "description": "Enum members matching `regex` do not have to be listed in switch statements to satisfy exhaustiveness",
+ "type": "string"
+ },
+ "ignore-enum-types": {
+ "description": "Enum types matching the supplied regex do not have to be listed in switch statements to satisfy exhaustiveness.",
+ "type": "string"
+ },
+ "package-scope-only": {
+ "description": "Consider enums only in package scopes, not in inner scopes.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "exhaustructSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "include": {
+ "description": "List of regular expressions to match struct packages and names.",
+ "type": "array",
+ "examples": [".*\\.Test"],
+ "items": {
+ "type": "string"
+ }
+ },
+ "exclude": {
+ "description": "List of regular expressions to exclude struct packages and names from check.",
+ "type": "array",
+ "examples": ["cobra\\.Command$"],
+ "items": {
+ "type": "string"
+ }
+ },
+ "allow-empty": {
+ "description": "Allows empty structures, effectively excluding them from the check.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-empty-rx": {
+ "description": "List of regular expressions to match type names that should be allowed to be empty.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "allow-empty-returns": {
+ "description": "Allows empty structures in return statements.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-empty-declarations": {
+ "description": "Allows empty structures in variable declarations.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "fatcontextSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-struct-pointers": {
+ "description": "Check for potential fat contexts in struct pointers.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "forbidigoSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "exclude-godoc-examples": {
+ "description": "Exclude code in godoc examples.",
+ "type": "boolean",
+ "default": true
+ },
+ "analyze-types": {
+ "description": "Instead of matching the literal source code, use type information to replace expressions with strings that contain the package name and (for methods and fields) the type name.",
+ "type": "boolean",
+ "default": true
+ },
+ "forbid": {
+ "description": "List of identifiers to forbid (written using `regexp`)",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "pattern": {
+ "description": "Pattern",
+ "type": "string"
+ },
+ "pkg": {
+ "description": "Package",
+ "type": "string"
+ },
+ "msg": {
+ "description": "Message",
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "funcorderSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "constructor": {
+ "description": "Checks that constructors are placed after the structure declaration.",
+ "type": "boolean",
+ "default": true
+ },
+ "struct-method": {
+ "description": "Checks if the exported methods of a structure are placed before the non-exported ones.",
+ "type": "boolean",
+ "default": true
+ },
+ "alphabetical": {
+ "description": "Checks if the constructors and/or structure methods are sorted alphabetically.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "funlenSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "lines": {
+ "description": "Limit lines number per function.",
+ "type": "integer",
+ "default": 60
+ },
+ "statements": {
+ "description": "Limit statements number per function.",
+ "type": "integer",
+ "default": 40
+ },
+ "ignore-comments": {
+ "description": "Ignore comments when counting lines.",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "gciSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "sections": {
+ "description": "Section configuration to compare against.",
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "enum": [
+ "standard",
+ "default",
+ "blank",
+ "dot",
+ "alias",
+ "localmodule"
+ ]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ },
+ "default": ["standard", "default"]
+ },
+ "no-inline-comments": {
+ "description": "Checks that no inline Comments are present.",
+ "type": "boolean",
+ "default": false
+ },
+ "no-prefix-comments": {
+ "description": "Checks that no prefix Comments(comment lines above an import) are present.",
+ "type": "boolean",
+ "default": false
+ },
+ "custom-order": {
+ "description": "Enable custom order of sections.",
+ "type": "boolean",
+ "default": false
+ },
+ "no-lex-order": {
+ "description": "Drops lexical ordering for custom sections.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "ginkgolinterSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "suppress-len-assertion": {
+ "description": "Suppress the wrong length assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-nil-assertion": {
+ "description": "Suppress the wrong nil assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-err-assertion": {
+ "description": "Suppress the wrong error assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-compare-assertion": {
+ "description": "Suppress the wrong comparison assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-async-assertion": {
+ "description": "Suppress the function all in async assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-type-compare-assertion": {
+ "description": "Suppress warning for comparing values from different types, like int32 and uint32.",
+ "type": "boolean",
+ "default": false
+ },
+ "forbid-focus-container": {
+ "description": "Trigger warning for ginkgo focus containers like FDescribe, FContext, FWhen or FIt.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-havelen-zero": {
+ "description": "Don't trigger warnings for HaveLen(0).",
+ "type": "boolean",
+ "default": false
+ },
+ "force-expect-to": {
+ "description": "Force using `Expect` with `To`, `ToNot` or `NotTo`",
+ "type": "boolean",
+ "default": false
+ },
+ "validate-async-intervals": {
+ "description": "Best effort validation of async intervals (timeout and polling).",
+ "type": "boolean",
+ "default": false
+ },
+ "forbid-spec-pollution": {
+ "description": "Trigger a warning for variable assignments in ginkgo containers like `Describe`, `Context` and `When`, instead of in `BeforeEach()`.",
+ "type": "boolean",
+ "default": false
+ },
+ "force-succeed": {
+ "description": "Force using the Succeed matcher for error functions, and the HaveOccurred matcher for non-function error values.",
+ "type": "boolean",
+ "default": false
+ },
+ "force-assertion-description": {
+ "description": "Force adding assertion descriptions to gomega matchers.",
+ "type": "boolean",
+ "default": false
+ },
+ "force-tonot": {
+ "description": "Force using `ToNot`, `ShouldNot` instead of `To(Not())`.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "gochecksumtypeSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "default-signifies-exhaustive": {
+ "description": "Presence of `default` case in switch statements satisfies exhaustiveness, if all members are not listed.",
+ "type": "boolean",
+ "default": true
+ },
+ "include-shared-interfaces": {
+ "description": "Include shared interfaces in the exhaustiviness check.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "gocognitSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "min-complexity": {
+ "description": "Minimal code complexity to report (we recommend 10-20).",
+ "type": "integer",
+ "default": 30
+ }
+ }
+ },
+ "goconstSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "match-constant": {
+ "description": "Look for existing constants matching the values",
+ "type": "boolean",
+ "default": true
+ },
+ "min-len": {
+ "description": "Minimum length of string constant.",
+ "type": "integer",
+ "default": 3
+ },
+ "min-occurrences": {
+ "description": "Minimum occurrences count to trigger.",
+ "type": "integer",
+ "default": 3
+ },
+ "ignore-calls": {
+ "description": "Ignore when constant is not used as function argument",
+ "type": "boolean",
+ "default": true
+ },
+ "ignore-string-values": {
+ "description": "Exclude strings matching the given regular expression",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "numbers": {
+ "description": "Search also for duplicated numbers.",
+ "type": "boolean",
+ "default": false
+ },
+ "min": {
+ "description": "Minimum value, only works with `numbers`",
+ "type": "integer",
+ "default": 3
+ },
+ "max": {
+ "description": "Maximum value, only works with `numbers`",
+ "type": "integer",
+ "default": 3
+ },
+ "find-duplicates": {
+ "description": "Detects constants with identical values",
+ "type": "boolean",
+ "default": false
+ },
+ "eval-const-expressions": {
+ "description": "Evaluates of constant expressions like Prefix + \"suffix\"",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "gocriticSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "enabled-checks": {
+ "description": "Which checks should be enabled. By default, a list of stable checks is used. To see it, run `GL_DEBUG=gocritic golangci-lint run`.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/gocritic-checks"
+ }
+ },
+ "disabled-checks": {
+ "description": "Which checks should be disabled.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/gocritic-checks"
+ },
+ "default": []
+ },
+ "enabled-tags": {
+ "description": "Enable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/gocritic-tags"
+ }
+ },
+ "disabled-tags": {
+ "description": "Disable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/gocritic-tags"
+ }
+ },
+ "settings": {
+ "description": "Settings passed to gocritic. Properties must be valid and enabled check names.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "captLocal": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "paramsOnly" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "commentedOutCode": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "minLength" : {
+ "type": "number",
+ "default": 15
+ }
+ }
+ },
+ "elseif": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skipBalanced" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "hugeParam": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "sizeThreshold" : {
+ "type": "number",
+ "default": 80
+ }
+ }
+ },
+ "ifElseChain": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "minThreshold" : {
+ "type": "number",
+ "default": 2
+ }
+ }
+ },
+ "nestingReduce": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "bodyWidth" : {
+ "type": "number",
+ "default": 5
+ }
+ }
+ },
+ "rangeExprCopy": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "sizeThreshold" : {
+ "type": "number",
+ "default": 512
+ },
+ "skipTestFuncs" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "rangeValCopy": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "sizeThreshold" : {
+ "type": "number",
+ "default": 128
+ },
+ "skipTestFuncs" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "ruleguard": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "debug" : {
+ "type": "string"
+ },
+ "enable" : {
+ "type": "string"
+ },
+ "disable" : {
+ "type": "string"
+ },
+ "failOn" : {
+ "type": "string"
+ },
+ "rules" : {
+ "type": "string"
+ }
+ }
+ },
+ "tooManyResultsChecker": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "maxResults" : {
+ "type": "number",
+ "default": 5
+ }
+ }
+ },
+ "truncateCmp": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skipArchDependent" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "underef": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skipRecvDeref" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "unnamedResult": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "checkExported" : {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ }
+ }
+ },
+ "disable-all": {
+ "type": "boolean",
+ "default": false
+ },
+ "enable-all": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "gocycloSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "min-complexity": {
+ "description": "Minimum code complexity to report (we recommend 10-20).",
+ "type": "integer",
+ "default": 30
+ }
+ }
+ },
+ "godoclintSettings": {
+ "type": "object",
+ "properties": {
+ "default": {
+ "type": "string",
+ "enum": ["all", "basic", "none"],
+ "default": "basic",
+ "description": "Default set of rules to enable."
+ },
+ "enable": {
+ "description": "List of rules to enable in addition to the default set.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "$ref": "#/definitions/godoclint-rules"
+ }
+ },
+ "disable": {
+ "description": "List of rules to disable.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "$ref": "#/definitions/godoclint-rules"
+ }
+ },
+ "options": {
+ "type": "object",
+ "description": "A map for setting individual rule options.",
+ "properties": {
+ "max-len": {
+ "type": "object",
+ "properties": {
+ "length": {
+ "type": "integer",
+ "description": "Maximum line length for godocs, not including the `// `, or `/*` or `*/` tokens.",
+ "default": 77
+ }
+ }
+ },
+ "require-doc": {
+ "type": "object",
+ "properties": {
+ "ignore-exported": {
+ "type": "boolean",
+ "description": "Ignore exported (public) symbols when applying the `require-doc` rule.",
+ "default": false
+ },
+ "ignore-unexported": {
+ "type": "boolean",
+ "description": "Ignore unexported (private) symbols when applying the `require-doc` rule.",
+ "default": true
+ }
+ }
+ },
+ "start-with-name": {
+ "type": "object",
+ "properties": {
+ "include-unexported": {
+ "type": "boolean",
+ "description": "Include unexported symbols when applying the `start-with-name` rule.",
+ "default": false
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "godotSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "scope": {
+ "description": "Comments to be checked.",
+ "enum": ["declarations", "toplevel", "all", "noinline"],
+ "default": "declarations"
+ },
+ "exclude": {
+ "description": "List of regexps for excluding particular comment lines from check.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "period": {
+ "description": "Check that each sentence ends with a period.",
+ "type": "boolean",
+ "default": true
+ },
+ "capital": {
+ "description": "Check that each sentence starts with a capital letter.",
+ "type": "boolean",
+ "default": false
+ },
+ "check-all": {
+ "description": "DEPRECATED: Check all top-level comments, not only declarations.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "godoxSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "keywords": {
+ "description": "Report any comments starting with one of these keywords. This is useful for TODO or FIXME comments that might be left in the code accidentally and should be resolved before merging.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "default": ["TODO", "BUG", "FIXME"]
+ }
+ }
+ },
+ "gofmtSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "simplify": {
+ "description": "Simplify code.",
+ "type": "boolean",
+ "default": true
+ },
+ "rewrite-rules": {
+ "description": "Apply the rewrite rules to the source before reformatting.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "pattern": {
+ "type": "string"
+ },
+ "replacement": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "golinesSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-len": {
+ "type": "integer",
+ "default": 100
+ },
+ "tab-len": {
+ "type": "integer",
+ "default": 4
+ },
+ "shorten-comments": {
+ "type": "boolean",
+ "default": false
+ },
+ "reformat-tags": {
+ "type": "boolean",
+ "default": true
+ },
+ "chain-split-dots": {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "interfacebloatSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max": {
+ "description": "The maximum number of methods allowed for an interface.",
+ "type": "integer"
+ }
+ }
+ },
+ "gofumptSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "extra-rules": {
+ "description": "Choose whether or not to use the extra rules that are disabled by default.",
+ "type": "boolean",
+ "default": false
+ },
+ "module-path": {
+ "description": " Module path which contains the source code being formatted.",
+ "type": "string"
+ }
+ }
+ },
+ "goheaderSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "values": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "const": {
+ "description": "Constants to use in the template.",
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "description": "Value for the constant.",
+ "type": "string"
+ }
+ },
+ "additionalProperties": false,
+ "examples": [
+ {
+ "YEAR": "2030",
+ "COMPANY": "MY FUTURISTIC COMPANY"
+ }
+ ]
+ },
+ "regexp": {
+ "description": "Regular expressions to use in your template.",
+ "type": "object",
+ "additionalProperties": false,
+ "patternProperties": {
+ "^.+$": {
+ "type": "string"
+ }
+ },
+ "examples": [
+ {
+ "AUTHOR": ".*@mycompany\\.com"
+ }
+ ]
+ }
+ }
+ },
+ "template": {
+ "description": "Template to put on top of every file.",
+ "type": "string",
+ "examples": [
+ "{{ MY COMPANY }}\nSPDX-License-Identifier: Apache-2.0\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at:\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License."
+ ]
+ },
+ "template-path": {
+ "description": "Path to the file containing the template source.",
+ "type": "string",
+ "examples": ["my_header_template.txt"]
+ }
+ },
+ "oneOf": [
+ { "required": ["template"] },
+ { "required": ["template-path"] }
+ ]
+ },
+ "goimportsSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "local-prefixes": {
+ "description": "Put imports beginning with prefix after 3rd-party packages. It is a list of prefixes.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "gomoddirectivesSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "replace-local": {
+ "description": "Allow local `replace` directives.",
+ "type": "boolean",
+ "default": true
+ },
+ "replace-allow-list": {
+ "description": "List of allowed `replace` directives.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "retract-allow-no-explanation": {
+ "description": "Allow to not explain why the version has been retracted in the `retract` directives.",
+ "type": "boolean",
+ "default": false
+ },
+ "exclude-forbidden": {
+ "description": "Forbid the use of the `exclude` directives.",
+ "type": "boolean",
+ "default": false
+ },
+ "ignore-forbidden": {
+ "description": "Forbid the use of the `ignore` directives. (>= go1.25)",
+ "type": "boolean",
+ "default": false
+ },
+ "toolchain-forbidden": {
+ "description": "Forbid the use of the `toolchain` directive.",
+ "type": "boolean",
+ "default": false
+ },
+ "toolchain-pattern": {
+ "description": "Defines a pattern to validate `toolchain` directive.",
+ "type": "string"
+ },
+ "tool-forbidden": {
+ "description": "Forbid the use of the `tool` directives.",
+ "type": "boolean",
+ "default": false
+ },
+ "go-debug-forbidden": {
+ "description": "Forbid the use of the `godebug` directive.",
+ "type": "boolean",
+ "default": false
+ },
+ "go-version-pattern": {
+ "description": "Defines a pattern to validate `go` minimum version directive.",
+ "type": "string",
+ "default": ""
+ }
+ }
+ },
+ "gomodguardSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "allowed": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "modules": {
+ "description": "List of allowed modules.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["gopkg.in/yaml.v2"]
+ }
+ },
+ "domains": {
+ "description": "List of allowed module domains.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["golang.org"]
+ }
+ }
+ }
+ },
+ "blocked": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "modules": {
+ "description": "List of blocked modules.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "recommendations": {
+ "description": "Recommended modules that should be used instead.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "reason": {
+ "description": "Reason why the recommended module should be used.",
+ "type": "string"
+ }
+ }
+ }
+ },
+ "additionalProperties": false
+ }
+ },
+ "versions": {
+ "description": "List of blocked module version constraints.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "patternProperties": {
+ "^.*$": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "version": {
+ "description": "Version constraint.",
+ "type": "string"
+ },
+ "reason": {
+ "description": "Reason why the version constraint exists.",
+ "type": "string"
+ }
+ },
+ "required": ["reason"]
+ }
+ }
+ }
+ },
+ "local-replace-directives": {
+ "description": "Raise lint issues if loading local path with replace directive",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ }
+ }
+ },
+ "gosecSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "includes": {
+ "type": "array",
+ "description": "To select a subset of rules to run",
+ "examples": [["G401"]],
+ "items": {
+ "$ref": "#/definitions/gosec-rules"
+ }
+ },
+ "excludes": {
+ "type": "array",
+ "description": "To specify a set of rules to explicitly exclude",
+ "examples": [["G401"]],
+ "items": {
+ "$ref": "#/definitions/gosec-rules"
+ }
+ },
+ "severity": {
+ "description": "Filter out the issues with a lower severity than the given value",
+ "type": "string",
+ "enum": ["low", "medium", "high"],
+ "default": "low"
+ },
+ "confidence": {
+ "description": "Filter out the issues with a lower confidence than the given value",
+ "type": "string",
+ "enum": ["low", "medium", "high"],
+ "default": "low"
+ },
+ "config": {
+ "description": "To specify the configuration of rules",
+ "type": "object"
+ },
+ "concurrency": {
+ "description": "Concurrency value",
+ "type": "integer"
+ }
+ }
+ },
+ "gosmopolitanSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "allow-time-local": {
+ "description": "Allow and ignore `time.Local` usages.",
+ "type": "boolean",
+ "default": false
+ },
+ "escape-hatches": {
+ "description": "List of fully qualified names in the `full/pkg/path.name` form, to act as \"i18n escape hatches\".",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "watch-for-scripts": {
+ "description": "List of Unicode scripts to watch for any usage in string literals.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "govetSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "settings": {
+ "description": "Settings per analyzer. Map of analyzer name to specific settings.\nRun `go tool vet help` to find out more.",
+ "type": "object",
+ "propertyNames": {
+ "$ref": "#/definitions/govet-analyzers"
+ },
+ "patternProperties": {
+ "^.*$": {
+ "description": "Run `go tool vet help ` to see all settings.",
+ "type": "object"
+ }
+ }
+ },
+ "enable": {
+ "description": "Enable analyzers by name.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/govet-analyzers"
+ }
+ },
+ "disable": {
+ "description": "Disable analyzers by name.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/govet-analyzers"
+ }
+ },
+ "enable-all": {
+ "description": "Enable all analyzers.",
+ "type": "boolean",
+ "default": false
+ },
+ "disable-all": {
+ "description": "Disable all analyzers.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "grouperSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "const-require-single-const": {
+ "type": "boolean",
+ "default": false
+ },
+ "const-require-grouping": {
+ "type": "boolean",
+ "default": false
+ },
+ "import-require-single-import": {
+ "type": "boolean",
+ "default": false
+ },
+ "import-require-grouping": {
+ "type": "boolean",
+ "default": false
+ },
+ "type-require-single-type": {
+ "type": "boolean",
+ "default": false
+ },
+ "type-require-grouping": {
+ "type": "boolean",
+ "default": false
+ },
+ "var-require-single-var": {
+ "type": "boolean",
+ "default": false
+ },
+ "var-require-grouping": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "ifaceSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "enable": {
+ "description": "Enable analyzers by name.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/iface-analyzers"
+ }
+ },
+ "settings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "unused": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "exclude": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "importasSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "no-unaliased": {
+ "description": "Do not allow unaliased imports of aliased packages.",
+ "type": "boolean",
+ "default": false
+ },
+ "no-extra-aliases": {
+ "description": "Do not allow non-required aliases.",
+ "type": "boolean",
+ "default": false
+ },
+ "alias": {
+ "description": "List of aliases",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "pkg": {
+ "description": "Package path e.g. knative.dev/serving/pkg/apis/autoscaling/v1alpha1",
+ "type": "string"
+ },
+ "alias": {
+ "description": "Package alias e.g. autoscalingv1alpha1",
+ "type": "string"
+ }
+ },
+ "required": ["pkg", "alias"]
+ }
+ }
+ }
+ },
+ "inamedparamSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skip-single-param": {
+ "description": "Skips check for interface methods with only a single parameter.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "ineffassignSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-escaping-errors": {
+ "description": "Check escaping variables of type error, may cause false positives.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "iotamixingSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "report-individual": {
+ "description": "Whether to report individual consts rather than just the const block.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "ireturnSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "description": "Use either `reject` or `allow` properties for interfaces matching.",
+ "properties": {
+ "allow": {
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "enum": ["anon", "error", "empty", "stdlib"]
+ }
+ ]
+ }
+ },
+ "reject": {
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "enum": ["anon", "error", "empty", "stdlib"]
+ }
+ ]
+ }
+ }
+ },
+ "anyOf": [
+ {
+ "not": {
+ "properties": {
+ "allow": {
+ "const": "reject"
+ }
+ }
+ },
+ "required": ["allow"]
+ },
+ {
+ "required": ["reject"]
+ }
+ ]
+ },
+ "lllSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "tab-width": {
+ "description": "Width of \"\\t\" in spaces.",
+ "type": "integer",
+ "minimum": 0,
+ "default": 1
+ },
+ "line-length": {
+ "description": "Maximum allowed line length, lines longer will be reported.",
+ "type": "integer",
+ "minimum": 1,
+ "default": 120
+ }
+ }
+ },
+ "maintidxSettings": {
+ "description": "Maintainability index https://docs.microsoft.com/en-us/visualstudio/code-quality/code-metrics-maintainability-index-range-and-meaning?view=vs-2022",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "under": {
+ "description": "Minimum accatpable maintainability index level (see https://docs.microsoft.com/en-us/visualstudio/code-quality/code-metrics-maintainability-index-range-and-meaning?view=vs-2022)",
+ "type": "number",
+ "default": 20
+ }
+ }
+ },
+ "makezeroSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "always": {
+ "description": "Allow only slices initialized with a length of zero.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "loggercheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "kitlog": {
+ "description": "Allow check for the github.com/go-kit/log library.",
+ "type": "boolean",
+ "default": true
+ },
+ "klog": {
+ "description": "Allow check for the k8s.io/klog/v2 library.",
+ "type": "boolean",
+ "default": true
+ },
+ "logr": {
+ "description": "Allow check for the github.com/go-logr/logr library.",
+ "type": "boolean",
+ "default": true
+ },
+ "slog": {
+ "description": "Allow check for the log/slog library.",
+ "type": "boolean",
+ "default": true
+ },
+ "zap": {
+ "description": "Allow check for the \"sugar logger\" from go.uber.org/zap library.",
+ "type": "boolean",
+ "default": true
+ },
+ "require-string-key": {
+ "description": "Require all logging keys to be inlined constant strings.",
+ "type": "boolean",
+ "default": false
+ },
+ "no-printf-like": {
+ "description": "Require printf-like format specifier (%s, %d for example) not present.",
+ "type": "boolean",
+ "default": false
+ },
+ "rules": {
+ "description": "List of custom rules to check against, where each rule is a single logger pattern, useful for wrapped loggers.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "misspellSettings": {
+ "description": "Correct spellings using locale preferences for US or UK. Default is to use a neutral variety of English.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "locale": {
+ "enum": ["US", "UK"]
+ },
+ "ignore-rules": {
+ "description": "List of rules to ignore.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "mode": {
+ "description": "Mode of the analysis.",
+ "enum": ["restricted", "", "default"],
+ "default": ""
+ },
+ "extra-words": {
+ "description": "Extra word corrections.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "correction": {
+ "type": "string"
+ },
+ "typo": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "musttagSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "functions": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "tag": {
+ "type": "string"
+ },
+ "arg-pos": {
+ "type": "integer"
+ }
+ }
+ }
+ }
+ }
+ },
+ "nakedretSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-func-lines": {
+ "description": "Report if a function has more lines of code than this value and it has naked returns.",
+ "type": "integer",
+ "minimum": 0,
+ "default": 30
+ }
+ }
+ },
+ "nestifSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "min-complexity": {
+ "description": "Minimum complexity of \"if\" statements to report.",
+ "type": "integer",
+ "default": 5
+ }
+ }
+ },
+ "nilnilSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "only-two": {
+ "type": "boolean",
+ "description": "To check functions with only two return values.",
+ "default": true
+ },
+ "detect-opposite": {
+ "type": "boolean",
+ "description": "In addition, detect opposite situation (simultaneous return of non-nil error and valid value).",
+ "default": false
+ },
+ "checked-types": {
+ "type": "array",
+ "description": "List of return types to check.",
+ "items": {
+ "enum": ["chan", "func", "iface", "map", "ptr", "uintptr", "unsafeptr"]
+ },
+ "default": ["chan", "func", "iface", "map", "ptr", "uintptr", "unsafeptr"]
+ }
+ }
+ },
+ "nlreturnSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "block-size": {
+ "description": "set block size that is still ok",
+ "type": "number",
+ "default": 0,
+ "minimum": 0
+ }
+ }
+ },
+ "mndSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignored-files": {
+ "description": "List of file patterns to exclude from analysis.",
+ "examples": [["magic1_.*.go"]],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignored-functions": {
+ "description": "Comma-separated list of function patterns to exclude from the analysis.",
+ "examples": [["math.*", "http.StatusText", "make"]],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignored-numbers": {
+ "description": "List of numbers to exclude from analysis.",
+ "examples": [["1000", "1234_567_890", "3.14159264"]],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "checks": {
+ "description": "The list of enabled checks, see https://github.com/tommy-muehle/go-mnd/#checks for description.",
+ "type": "array",
+ "items": {
+ "enum": [
+ "argument",
+ "case",
+ "condition",
+ "operation",
+ "return",
+ "assign"
+ ]
+ }
+ }
+ }
+ },
+ "modernizeSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "disable": {
+ "description": "List of analyzers to disable.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/modernize-analyzers"
+ }
+ }
+ }
+ },
+ "nolintlintSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "allow-unused": {
+ "description": "Enable to ensure that nolint directives are all used.",
+ "type": "boolean",
+ "default": true
+ },
+ "allow-no-explanation": {
+ "description": "Exclude these linters from requiring an explanation.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linter-names"
+ },
+ "default": []
+ },
+ "require-explanation": {
+ "description": "Enable to require an explanation of nonzero length after each nolint directive.",
+ "type": "boolean",
+ "default": false
+ },
+ "require-specific": {
+ "description": "Enable to require nolint directives to mention the specific linter being suppressed.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "reassignSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "patterns": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "recvcheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "disable-builtin": {
+ "description": "Disables the built-in method exclusions.",
+ "type": "boolean",
+ "default": true
+ },
+ "exclusions": {
+ "description": "User-defined method exclusions.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "nonamedreturnsSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "report-error-in-defer": {
+ "description": "Report named error if it is assigned inside defer.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "paralleltestSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignore-missing": {
+ "description": "Ignore missing calls to `t.Parallel()` and only report incorrect uses of it.",
+ "type": "boolean",
+ "default": false
+ },
+ "ignore-missing-subtests": {
+ "description": "Ignore missing calls to `t.Parallel()` in subtests. Top-level tests are still required to have `t.Parallel`, but subtests are allowed to skip it.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "perfsprintSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "integer-format": {
+ "description": "Enable/disable optimization of integer formatting.",
+ "type": "boolean",
+ "default": true
+ },
+ "int-conversion": {
+ "description": "Optimizes even if it requires an int or uint type cast.",
+ "type": "boolean",
+ "default": true
+ },
+ "error-format": {
+ "description": "Enable/disable optimization of error formatting.",
+ "type": "boolean",
+ "default": true
+ },
+ "err-error": {
+ "description": "Optimizes into `err.Error()` even if it is only equivalent for non-nil errors.",
+ "type": "boolean",
+ "default": false
+ },
+ "errorf": {
+ "description": "Optimizes `fmt.Errorf`.",
+ "type": "boolean",
+ "default": true
+ },
+ "string-format": {
+ "description": "Enable/disable optimization of string formatting.",
+ "type": "boolean",
+ "default": true
+ },
+ "sprintf1": {
+ "description": "Optimizes `fmt.Sprintf` with only one argument.",
+ "type": "boolean",
+ "default": true
+ },
+ "strconcat": {
+ "description": "Optimizes into strings concatenation.",
+ "type": "boolean",
+ "default": true
+ },
+ "bool-format": {
+ "description": "Enable/disable optimization of bool formatting.",
+ "type": "boolean",
+ "default": true
+ },
+ "hex-format": {
+ "description": "Enable/disable optimization of hex formatting.",
+ "type": "boolean",
+ "default": true
+ },
+ "concat-loop": {
+ "description": "Enable/disable optimization of concat loop.",
+ "type": "boolean",
+ "default": true
+ },
+ "loop-other-ops": {
+ "description": "Optimization of `concat-loop` even with other operations.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "preallocSettings": {
+ "description": "We do not recommend using this linter before doing performance profiling.\nFor most programs usage of `prealloc` will be premature optimization.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "simple": {
+ "description": "Report preallocation suggestions only on simple loops that have no returns/breaks/continues/gotos in them.",
+ "type": "boolean",
+ "default": true
+ },
+ "range-loops": {
+ "description": "Report preallocation suggestions on range loops.",
+ "type": "boolean",
+ "default": true
+ },
+ "for-loops": {
+ "description": "Report preallocation suggestions on for loops.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "predeclaredSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignore": {
+ "description": "List of predeclared identifiers to not report on.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "qualified-name": {
+ "description": "Include method names and field names in checks.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "promlinterSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "strict": {},
+ "disabled-linters": {
+ "type": "array",
+ "items": {
+ "enum": [
+ "Help",
+ "MetricUnits",
+ "Counter",
+ "HistogramSummaryReserved",
+ "MetricTypeInName",
+ "ReservedChars",
+ "CamelCase",
+ "UnitAbbreviations"
+ ]
+ }
+ }
+ }
+ },
+ "protogetterSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skip-generated-by": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["protoc-gen-go-my-own-generator"]
+ }
+ },
+ "skip-files": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["*.pb.go"]
+ }
+ },
+ "skip-any-generated": {
+ "description": "Skip any generated files from the checking.",
+ "type": "boolean",
+ "default": false
+ },
+ "replace-first-arg-in-append": {
+ "description": "Skip first argument of append function.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "reviveSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "examples": [
+ {
+ "ignore-generated-header": true,
+ "severity": "warning",
+ "rules": [
+ {
+ "name": "indent-error-flow",
+ "severity": "warning"
+ },
+ {
+ "name": "add-constant",
+ "severity": "warning",
+ "arguments": [
+ {
+ "maxLitCount": "3",
+ "allowStrs": "\"\"",
+ "allowInts": "0,1,2",
+ "allowFloats": "0.0,0.,1.0,1.,2.0,2."
+ }
+ ]
+ }
+ ]
+ }
+ ],
+ "properties": {
+ "max-open-files": {
+ "type": "integer"
+ },
+ "confidence": {
+ "type": "number"
+ },
+ "severity": {
+ "type": "string",
+ "enum": ["warning", "error"]
+ },
+ "enable-all-rules": {
+ "type": "boolean",
+ "default": false
+ },
+ "enable-default-rules": {
+ "type": "boolean",
+ "default": false
+ },
+ "directives": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "name": {
+ "type": "string",
+ "enum": ["specify-disable-reason"]
+ },
+ "severity": {
+ "type": "string",
+ "enum": ["warning", "error"]
+ },
+ "exclude": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "arguments": {
+ "type": "array"
+ }
+ }
+ }
+ },
+ "rules": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["name"],
+ "properties": {
+ "name": {
+ "$ref": "#/definitions/revive-rules",
+ "title": "The rule name"
+ },
+ "disabled": {
+ "type": "boolean"
+ },
+ "severity": {
+ "type": "string",
+ "enum": ["warning", "error"]
+ },
+ "exclude": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "arguments": {
+ "type": "array"
+ }
+ }
+ }
+ }
+ }
+ },
+ "rowserrcheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "packages": {
+ "type": "array",
+ "items": {
+ "description": "",
+ "type": "string",
+ "examples": ["github.com/jmoiron/sqlx"]
+ }
+ }
+ }
+ },
+ "sloglintSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "kv-only": {
+ "description": "Enforce using key-value pairs only (incompatible with attr-only).",
+ "type": "boolean",
+ "default": false
+ },
+ "no-global": {
+ "description": "Enforce not using global loggers.",
+ "enum": ["", "all", "default"],
+ "default": ""
+ },
+ "no-mixed-args": {
+ "description": "Enforce not mixing key-value pairs and attributes.",
+ "type": "boolean",
+ "default": true
+ },
+ "context": {
+ "description": "Enforce using methods that accept a context.",
+ "enum": ["", "all", "scope"],
+ "default": ""
+ },
+ "static-msg": {
+ "description": "Enforce using static values for log messages.",
+ "type": "boolean",
+ "default": false
+ },
+ "msg-style": {
+ "description": "Enforce message style.",
+ "enum": ["", "lowercased", "capitalized"],
+ "default": ""
+ },
+ "key-naming-case": {
+ "description": "Enforce a single key naming convention.",
+ "enum": ["snake", "kebab", "camel", "pascal"]
+ },
+ "attr-only": {
+ "description": "Enforce using attributes only (incompatible with kv-only).",
+ "type": "boolean",
+ "default": false
+ },
+ "no-raw-keys": {
+ "description": "Enforce using constants instead of raw keys.",
+ "type": "boolean",
+ "default": false
+ },
+ "forbidden-keys": {
+ "description": "Enforce not using specific keys.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "args-on-sep-lines": {
+ "description": "Enforce putting arguments on separate lines.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "spancheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "checks": {
+ "description": "Checks to enable.",
+ "type": "array",
+ "items": {
+ "enum": ["end", "record-error", "set-status"]
+ }
+ },
+ "ignore-check-signatures": {
+ "description": "A list of regexes for function signatures that silence `record-error` and `set-status` reports if found in the call path to a returned error.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "extra-start-span-signatures": {
+ "description": "A list of regexes for additional function signatures that create spans.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "staticcheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "checks": {
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "$ref": "#/definitions/staticcheck-checks"
+ },
+ {
+ "type": "string"
+ }
+ ]
+ }
+ },
+ "dot-import-whitelist": {
+ "description": "By default, ST1001 forbids all uses of dot imports in non-test packages. This setting allows setting a whitelist of import paths that can be dot-imported anywhere.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "http-status-code-whitelist": {
+ "description": "ST1013 recommends using constants from the net/http package instead of hard-coding numeric HTTP status codes. This setting specifies a list of numeric status codes that this check does not complain about.",
+ "default": ["200", "400", "404", "500"],
+ "type": "array",
+ "items": {
+ "enum": [
+ "100",
+ "101",
+ "102",
+ "103",
+ "200",
+ "201",
+ "202",
+ "203",
+ "204",
+ "205",
+ "206",
+ "207",
+ "208",
+ "226",
+ "300",
+ "301",
+ "302",
+ "303",
+ "304",
+ "305",
+ "306",
+ "307",
+ "308",
+ "400",
+ "401",
+ "402",
+ "403",
+ "404",
+ "405",
+ "406",
+ "407",
+ "408",
+ "409",
+ "410",
+ "411",
+ "412",
+ "413",
+ "414",
+ "415",
+ "416",
+ "417",
+ "418",
+ "421",
+ "422",
+ "423",
+ "424",
+ "425",
+ "426",
+ "428",
+ "429",
+ "431",
+ "451",
+ "500",
+ "501",
+ "502",
+ "503",
+ "504",
+ "505",
+ "506",
+ "507",
+ "508",
+ "510",
+ "511"
+ ]
+ }
+ },
+ "initialisms": {
+ "description": "ST1003 check, among other things, for the correct capitalization of initialisms. The set of known initialisms can be configured with this option.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "default": [
+ "ACL",
+ "API",
+ "ASCII",
+ "CPU",
+ "CSS",
+ "DNS",
+ "EOF",
+ "GUID",
+ "HTML",
+ "HTTP",
+ "HTTPS",
+ "ID",
+ "IP",
+ "JSON",
+ "QPS",
+ "RAM",
+ "RPC",
+ "SLA",
+ "SMTP",
+ "SQL",
+ "SSH",
+ "TCP",
+ "TLS",
+ "TTL",
+ "UDP",
+ "UI",
+ "GID",
+ "UID",
+ "UUID",
+ "URI",
+ "URL",
+ "UTF8",
+ "VM",
+ "XML",
+ "XMPP",
+ "XSRF",
+ "XSS",
+ "SIP",
+ "RTP",
+ "AMQP",
+ "DB",
+ "TS"
+ ]
+ }
+ }
+ }
+ },
+ "tagalignSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "align": {
+ "description": "Align and sort can be used together or separately.",
+ "type": "boolean",
+ "default": true
+ },
+ "sort": {
+ "description": "Whether enable tags sort.",
+ "type": "boolean",
+ "default": true
+ },
+ "order": {
+ "description": "Specify the order of tags, the other tags will be sorted by name.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "default": [],
+ "examples": [
+ [
+ "json",
+ "yaml",
+ "yml",
+ "toml",
+ "mapstructure",
+ "binding",
+ "validate"
+ ]
+ ]
+ },
+ "strict": {
+ "description": "Whether enable strict style.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "tagliatelleSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "case": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "use-field-name": {
+ "description": "Use the struct field name to check the name of the struct tag.",
+ "type": "boolean",
+ "default": false
+ },
+ "ignored-fields": {
+ "description": "The field names to ignore.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["example"]
+ }
+ },
+ "rules": {
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "$ref": "#/definitions/tagliatelle-cases"
+ }
+ }
+ },
+ "extended-rules": {
+ "description": "Defines the association between tag name and case.",
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["case"],
+ "properties": {
+ "case": {
+ "$ref": "#/definitions/tagliatelle-cases"
+ },
+ "extra-initialisms": {
+ "type": "boolean",
+ "default": false
+ },
+ "initialism-overrides": {
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "overrides": {
+ "description": "Overrides the default/root configuration.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["pkg"],
+ "properties": {
+ "pkg": {
+ "description": "A package path.",
+ "type": "string"
+ },
+ "use-field-name": {
+ "description": "Use the struct field name to check the name of the struct tag.",
+ "type": "boolean",
+ "default": false
+ },
+ "ignored-fields": {
+ "description": "The field names to ignore.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["example"]
+ }
+ },
+ "ignore": {
+ "description": "Ignore the package (takes precedence over all other configurations).",
+ "type": "boolean",
+ "default": false
+ },
+ "rules": {
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "$ref": "#/definitions/tagliatelle-cases"
+ }
+ }
+ },
+ "extended-rules": {
+ "description": "Defines the association between tag name and case.",
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["case"],
+ "properties": {
+ "case": {
+ "$ref": "#/definitions/tagliatelle-cases"
+ },
+ "extra-initialisms": {
+ "type": "boolean",
+ "default": false
+ },
+ "initialism-overrides": {
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "testifylintSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "enable-all": {
+ "description": "Enable all checkers.",
+ "type": "boolean",
+ "default": false
+ },
+ "disable-all": {
+ "description": "Disable all checkers.",
+ "type": "boolean",
+ "default": false
+ },
+ "enable": {
+ "description": "Enable specific checkers.",
+ "type": "array",
+ "items": {
+ "enum": [
+ "blank-import",
+ "bool-compare",
+ "compares",
+ "contains",
+ "empty",
+ "encoded-compare",
+ "equal-values",
+ "error-is-as",
+ "error-nil",
+ "expected-actual",
+ "float-compare",
+ "formatter",
+ "go-require",
+ "len",
+ "negative-positive",
+ "nil-compare",
+ "regexp",
+ "require-error",
+ "suite-broken-parallel",
+ "suite-dont-use-pkg",
+ "suite-extra-assert-call",
+ "suite-method-signature",
+ "suite-subtest-run",
+ "suite-thelper",
+ "useless-assert"
+ ]
+ },
+ "default": [
+ "blank-import",
+ "bool-compare",
+ "compares",
+ "contains",
+ "empty",
+ "encoded-compare",
+ "equal-values",
+ "error-is-as",
+ "error-nil",
+ "expected-actual",
+ "float-compare",
+ "formatter",
+ "go-require",
+ "len",
+ "negative-positive",
+ "nil-compare",
+ "regexp",
+ "require-error",
+ "suite-broken-parallel",
+ "suite-dont-use-pkg",
+ "suite-extra-assert-call",
+ "suite-method-signature",
+ "suite-subtest-run",
+ "useless-assert"
+ ]
+ },
+ "disable": {
+ "description": "Disable specific checkers.",
+ "type": "array",
+ "items": {
+ "enum": [
+ "blank-import",
+ "bool-compare",
+ "compares",
+ "contains",
+ "empty",
+ "encoded-compare",
+ "equal-values",
+ "error-is-as",
+ "error-nil",
+ "expected-actual",
+ "float-compare",
+ "formatter",
+ "go-require",
+ "len",
+ "negative-positive",
+ "nil-compare",
+ "regexp",
+ "require-error",
+ "suite-broken-parallel",
+ "suite-dont-use-pkg",
+ "suite-extra-assert-call",
+ "suite-method-signature",
+ "suite-subtest-run",
+ "suite-thelper",
+ "useless-assert"
+ ],
+ "default": [
+ "suite-thelper"
+ ]
+ }
+ },
+ "bool-compare": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignore-custom-types": {
+ "description": "To ignore user defined types (over builtin bool).",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "expected-actual": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "pattern": {
+ "description": "Regexp for expected variable name.",
+ "type": "string",
+ "default": "(^(exp(ected)?|want(ed)?)([A-Z]\\w*)?$)|(^(\\w*[a-z])?(Exp(ected)?|Want(ed)?)$)"
+ }
+ }
+ },
+ "formatter": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-format-string": {
+ "description": "To enable go vet's printf checks.",
+ "type": "boolean",
+ "default": true
+ },
+ "require-f-funcs": {
+ "description": "To require f-assertions (e.g. assert.Equalf) if format string is used, even if there are no variable-length variables.",
+ "type": "boolean",
+ "default": false
+ },
+ "require-string-msg": {
+ "description": "To require that the first element of msgAndArgs (msg) has a string type.",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "go-require": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignore-http-handlers": {
+ "description": "To ignore HTTP handlers (like http.HandlerFunc).",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "require-error": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "fn-pattern": {
+ "description": "Regexp for assertions to analyze. If defined, then only matched error assertions will be reported.",
+ "type": "string",
+ "default": ""
+ }
+ }
+ },
+ "suite-extra-assert-call": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "mode": {
+ "description": "To require or remove extra Assert() call?",
+ "type": "string",
+ "enum": ["remove", "require"],
+ "default": "remove"
+ }
+ }
+ }
+ }
+ },
+ "testpackageSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skip-regexp": {
+ "description": "Files with names matching this regular expression are skipped.",
+ "type": "string",
+ "examples": ["(export|internal)_test\\.go"]
+ },
+ "allow-packages": {
+ "description": "List of packages that don't end with _test that tests are allowed to be in.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["example"]
+ }
+ }
+ }
+ },
+ "thelperSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "test": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "begin": {
+ "description": "Check if `t.Helper()` begins helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "first": {
+ "description": "Check if *testing.T is first param of helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "name": {
+ "description": "Check if *testing.T param has t name.",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ },
+ "benchmark": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "begin": {
+ "description": "Check if `b.Helper()` begins helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "first": {
+ "description": "Check if *testing.B is first param of helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "name": {
+ "description": "Check if *testing.B param has b name.",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ },
+ "tb": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "begin": {
+ "description": "Check if `tb.Helper()` begins helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "first": {
+ "description": "Check if *testing.TB is first param of helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "name": {
+ "description": "Check if *testing.TB param has tb name.",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ },
+ "fuzz": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "begin": {
+ "description": "Check if `f.Helper()` begins helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "first": {
+ "description": "Check if *testing.F is first param of helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "name": {
+ "description": "Check if *testing.F param has f name.",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ }
+ }
+ },
+ "usestdlibvarsSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "http-method": {
+ "description": "Suggest the use of http.MethodXX.",
+ "type": "boolean",
+ "default": true
+ },
+ "http-status-code": {
+ "description": "Suggest the use of http.StatusXX.",
+ "type": "boolean",
+ "default": true
+ },
+ "time-weekday": {
+ "description": "Suggest the use of time.Weekday.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "time-month": {
+ "description": "Suggest the use of time.Month.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "time-layout": {
+ "description": "Suggest the use of time.Layout.",
+ "type": "boolean",
+ "default": false
+ },
+ "time-date-month": {
+ "description": "Suggest the use of time.Month in time.Date.",
+ "type": "boolean",
+ "default": false
+ },
+ "crypto-hash": {
+ "description": "Suggest the use of crypto.Hash.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "default-rpc-path": {
+ "description": "Suggest the use of rpc.DefaultXXPath.",
+ "type": "boolean",
+ "default": false
+ },
+ "sql-isolation-level": {
+ "description": "Suggest the use of sql.LevelXX.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "tls-signature-scheme": {
+ "description": "Suggest the use of tls.SignatureScheme.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "constant-kind": {
+ "description": "Suggest the use of constant.Kind.String().",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "usetestingSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "context-background": {
+ "type": "boolean",
+ "default": false
+ },
+ "context-todo": {
+ "type": "boolean",
+ "default": false
+ },
+ "os-chdir": {
+ "type": "boolean",
+ "default": true
+ },
+ "os-mkdir-temp": {
+ "type": "boolean",
+ "default": true
+ },
+ "os-setenv": {
+ "type": "boolean",
+ "default": true
+ },
+ "os-create-temp": {
+ "type": "boolean",
+ "default": true
+ },
+ "os-temp-dir": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "unconvertSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "fast-math": {
+ "type": "boolean",
+ "default": false
+ },
+ "safe": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "unparamSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-exported": {
+ "description": "Inspect exported functions. Set to true if no external program/library imports your code.\n\nWARNING: if you enable this setting, unparam will report a lot of false-positives in text editors:\nif it's called for subdir of a project it can't find external interfaces. All text editor integrations\nwith golangci-lint call it on a directory with the changed file.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "unqueryvetSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-sql-builders": {
+ "description": "Enable SQL builder checking.",
+ "type": "boolean",
+ "default": true
+ },
+ "allowed-patterns": {
+ "description": "Regex patterns for acceptable SELECT * usage.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "unusedSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "field-writes-are-uses": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ },
+ "post-statements-are-reads": {
+ "description": "",
+ "type": "boolean",
+ "default": false
+ },
+ "exported-fields-are-used": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ },
+ "parameters-are-used": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ },
+ "local-variables-are-used": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ },
+ "generated-is-used": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "varnamelenSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-distance": {
+ "description": "Variables used in at most this N-many lines will be ignored.",
+ "type": "integer",
+ "default": 5
+ },
+ "min-name-length": {
+ "description": "The minimum length of a variable's name that is considered `long`.",
+ "type": "integer",
+ "default": 3
+ },
+ "check-receiver": {
+ "description": "Check method receiver names.",
+ "default": false,
+ "type": "boolean"
+ },
+ "check-return": {
+ "description": "Check named return values.",
+ "default": false,
+ "type": "boolean"
+ },
+ "check-type-param": {
+ "description": "Check type parameters.",
+ "default": false,
+ "type": "boolean"
+ },
+ "ignore-type-assert-ok": {
+ "description": "Ignore `ok` variables that hold the bool return value of a type assertion",
+ "default": false,
+ "type": "boolean"
+ },
+ "ignore-map-index-ok": {
+ "description": "Ignore `ok` variables that hold the bool return value of a map index.",
+ "default": false,
+ "type": "boolean"
+ },
+ "ignore-chan-recv-ok": {
+ "description": "Ignore `ok` variables that hold the bool return value of a channel receive.",
+ "default": false,
+ "type": "boolean"
+ },
+ "ignore-names": {
+ "description": "Optional list of variable names that should be ignored completely.",
+ "default": [[]],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignore-decls": {
+ "description": "Optional list of variable declarations that should be ignored completely.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "examples": [
+ ["c echo.Context", "t testing.T", "f *foo.Bar", "const C"]
+ ]
+ }
+ }
+ },
+ "whitespaceSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "multi-if": {
+ "description": "Enforces newlines (or comments) after every multi-line if statement",
+ "type": "boolean",
+ "default": false
+ },
+ "multi-func": {
+ "description": "Enforces newlines (or comments) after every multi-line function signature",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "wrapcheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "extra-ignore-sigs": {
+ "description": "An array of strings specifying additional substrings of signatures to ignore.",
+ "default": [
+ ".CustomError(",
+ ".SpecificWrap("
+ ],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignore-sigs": {
+ "description": "An array of strings which specify substrings of signatures to ignore.",
+ "default": [
+ ".Errorf(",
+ "errors.New(",
+ "errors.Unwrap(",
+ ".Wrap(",
+ ".Wrapf(",
+ ".WithMessage(",
+ ".WithMessagef(",
+ ".WithStack("
+ ],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignore-sig-regexps": {
+ "description": "An array of strings which specify regular expressions of signatures to ignore.",
+ "default": [""],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignore-package-globs": {
+ "description": "An array of glob patterns which, if any match the package of the function returning the error, will skip wrapcheck analysis for this error.",
+ "default": [""],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignore-interface-regexps": {
+ "description": "An array of glob patterns which, if matched to an underlying interface name, will ignore unwrapped errors returned from a function whose call is defined on the given interface.",
+ "default": [""],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "report-internal-errors": {
+ "description": "Determines whether wrapcheck should report errors returned from inside the package.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "wslSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "allow-assign-and-anything": {
+ "description": "Controls if you may cuddle assignments and anything without needing an empty line between them.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-assign-and-call": {
+ "description": "Allow calls and assignments to be cuddled as long as the lines have any matching variables, fields or types.",
+ "type": "boolean",
+ "default": true
+ },
+ "allow-cuddle-declarations": {
+ "description": "Allow declarations (var) to be cuddled.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-cuddle-with-calls": {
+ "description": "A list of call idents that everything can be cuddled with.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "allow-cuddle-with-rhs": {
+ "description": "AllowCuddleWithRHS is a list of right hand side variables that is allowed to be cuddled with anything.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "allow-cuddle-used-in-block": {
+ "description": "Allow cuddling with any block as long as the variable is used somewhere in the block",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-multiline-assign": {
+ "description": "Allow multiline assignments to be cuddled.",
+ "type": "boolean",
+ "default": true
+ },
+ "allow-separated-leading-comment": {
+ "description": "Allow leading comments to be separated with empty lines.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-trailing-comment": {
+ "description": "Allow trailing comments in ending of blocks.",
+ "type": "boolean",
+ "default": false
+ },
+ "error-variable-names": {
+ "description": "When force-err-cuddling is enabled this is a list of names used for error variables to check for in the conditional.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "force-case-trailing-whitespace": {
+ "description": "Force newlines in end of case at this limit (0 = never).",
+ "type": "integer",
+ "minimum": 0,
+ "default": 0
+ },
+ "force-err-cuddling": {
+ "description": "Causes an error when an If statement that checks an error variable doesn't cuddle with the assignment of that variable.",
+ "type": "boolean",
+ "default": false
+ },
+ "force-short-decl-cuddling": {
+ "description": "Causes an error if a short declaration (:=) cuddles with anything other than another short declaration.",
+ "type": "boolean",
+ "default": false
+ },
+ "strict-append": {
+ "description": "If true, append is only allowed to be cuddled if appending value is matching variables, fields or types on line above.",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "wslSettingsV5": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "allow-first-in-block": {
+ "type": "boolean",
+ "default": true
+ },
+ "allow-whole-block": {
+ "type": "boolean",
+ "default": false
+ },
+ "branch-max-lines": {
+ "type": "integer",
+ "default": 2
+ },
+ "case-max-lines": {
+ "type": "integer",
+ "default": 0
+ },
+ "default": {
+ "enum": ["all", "none", "default", ""],
+ "default": "default"
+ },
+ "enable": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/wsl-checks"
+ }
+ },
+ "disable": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/wsl-checks"
+ }
+ }
+ }
+ },
+ "copyloopvarSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-alias": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "customSettings": {
+ "description": "The custom section can be used to define linter plugins to be loaded at runtime. See README of golangci-lint for more information.\nEach custom linter should have a unique name.",
+ "type": "object",
+ "patternProperties": {
+ "^.*$": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "type": {
+ "description": "The plugin type.",
+ "enum": ["module", "goplugin"],
+ "default": "goplugin"
+ },
+ "path": {
+ "description": "The path to the plugin *.so. Can be absolute or local.",
+ "type": "string",
+ "examples": ["/path/to/example.so"]
+ },
+ "description": {
+ "description": "The description of the linter, for documentation purposes only.",
+ "type": "string"
+ },
+ "original-url": {
+ "description": "Intended to point to the repo location of the linter, for documentation purposes only.",
+ "type": "string"
+ },
+ "settings": {
+ "description": "Plugins settings/configuration. Only work with plugin based on `linterdb.PluginConstructor`.",
+ "type": "object"
+ }
+ },
+ "oneOf": [
+ {
+ "properties": {
+ "type": {"enum": ["module"] }
+ },
+ "required": ["type"]
+ },
+ {
+ "required": ["path"]
+ }
+ ]
+ }
+ }
+ }
+ }
+ }
+ },
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["version"],
+ "properties": {
+ "version": {
+ "type": "string",
+ "default": "2"
+ },
+ "run": {
+ "description": "Options for analysis running,",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "concurrency": {
+ "description": "Number of concurrent runners. Defaults to the number of available CPU cores.",
+ "type": "integer",
+ "minimum": 0,
+ "examples": [4]
+ },
+ "timeout": {
+ "description": "Timeout for the analysis.",
+ "type": "string",
+ "pattern": "^((\\d+h)?(\\d+m)?(\\d+(?:\\.\\d)?s)?|0)$",
+ "default": "1m",
+ "examples": ["30s", "5m", "5m30s"]
+ },
+ "issues-exit-code": {
+ "description": "Exit code when at least one issue was found.",
+ "type": "integer",
+ "default": 1
+ },
+ "tests": {
+ "description": "Enable inclusion of test files.",
+ "type": "boolean",
+ "default": true
+ },
+ "build-tags": {
+ "description": "List of build tags to pass to all linters.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "default": [],
+ "examples": [["mytag"]]
+ },
+ "modules-download-mode": {
+ "description": "Option to pass to \"go list -mod={option}\".\nSee \"go help modules\" for more information.",
+ "enum": ["mod", "readonly", "vendor"]
+ },
+ "allow-parallel-runners": {
+ "description": "Allow multiple parallel golangci-lint instances running. If disabled, golangci-lint acquires file lock on start.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-serial-runners": {
+ "description": "Allow multiple golangci-lint instances running, but serialize them around a lock.",
+ "type": "boolean",
+ "default": false
+ },
+ "go": {
+ "description": "Targeted Go version.",
+ "type": "string",
+ "default": "1.17"
+ },
+ "relative-path-mode": {
+ "description": "The mode used to evaluate relative paths.",
+ "type": "string",
+ "$ref": "#/definitions/relative-path-modes",
+ "default": "wd"
+ }
+ }
+ },
+ "output": {
+ "description": "Output configuration options.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "formats": {
+ "description": "Output formats to use.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "text": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "path": {
+ "$ref": "#/definitions/formats-path",
+ "default": "stdout"
+ },
+ "print-linter-name": {
+ "type": "boolean",
+ "default": true
+ },
+ "print-issued-lines": {
+ "type": "boolean",
+ "default": true
+ },
+ "colors": {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "json": {
+ "$ref": "#/definitions/simple-format"
+ },
+ "tab": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "path": {
+ "$ref": "#/definitions/formats-path",
+ "default": "stdout"
+ },
+ "print-linter-name": {
+ "type": "boolean",
+ "default": true
+ },
+ "colors": {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "html": {
+ "$ref": "#/definitions/simple-format"
+ },
+ "checkstyle": {
+ "$ref": "#/definitions/simple-format"
+ },
+ "code-climate": {
+ "$ref": "#/definitions/simple-format"
+ },
+ "junit-xml": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "path": {
+ "$ref": "#/definitions/formats-path",
+ "default": "stdout"
+ },
+ "extended": {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "teamcity": {
+ "$ref": "#/definitions/simple-format"
+ },
+ "sarif": {
+ "$ref": "#/definitions/simple-format"
+ }
+ }
+ },
+ "path-mode": {
+ "type": "string",
+ "default": "",
+ "examples": ["abs"]
+ },
+ "path-prefix": {
+ "description": "Add a prefix to the output file references.",
+ "type": "string",
+ "default": ""
+ },
+ "show-stats": {
+ "description": "Show statistics per linter.",
+ "type": "boolean",
+ "default": true
+ },
+ "sort-order": {
+ "type": "array",
+ "items": {
+ "enum": ["linter", "severity", "file"]
+ }
+ }
+ }
+ },
+ "linters": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "default": {
+ "enum": [
+ "standard",
+ "all",
+ "none",
+ "fast"
+ ]
+ },
+ "enable": {
+ "description": "List of enabled linters.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linter-names"
+ }
+ },
+ "disable": {
+ "description": "List of disabled linters.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linter-names"
+ }
+ },
+ "settings": {
+ "description": "All available settings of specific linters.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "dupword": {
+ "$ref": "#/definitions/settings/definitions/dupwordSettings"
+ },
+ "asasalint": {
+ "$ref": "#/definitions/settings/definitions/asasalintSettings"
+ },
+ "bidichk": {
+ "$ref": "#/definitions/settings/definitions/bidichkSettings"
+ },
+ "cyclop": {
+ "$ref": "#/definitions/settings/definitions/cyclopSettings"
+ },
+ "decorder": {
+ "$ref": "#/definitions/settings/definitions/decorderSettings"
+ },
+ "depguard":{
+ "$ref": "#/definitions/settings/definitions/depguardSettings"
+ },
+ "dogsled": {
+ "$ref": "#/definitions/settings/definitions/dogsledSettings"
+ },
+ "dupl": {
+ "$ref": "#/definitions/settings/definitions/duplSettings"
+ },
+ "embeddedstructfieldcheck": {
+ "$ref": "#/definitions/settings/definitions/embeddedstructfieldcheckSettings"
+ },
+ "errcheck": {
+ "$ref": "#/definitions/settings/definitions/errcheckSettings"
+ },
+ "errchkjson": {
+ "$ref": "#/definitions/settings/definitions/errchkjsonSettings"
+ },
+ "errorlint": {
+ "$ref": "#/definitions/settings/definitions/errorlintSettings"
+ },
+ "exhaustive": {
+ "$ref": "#/definitions/settings/definitions/exhaustiveSettings"
+ },
+ "exhaustruct": {
+ "$ref": "#/definitions/settings/definitions/exhaustructSettings"
+ },
+ "fatcontext": {
+ "$ref": "#/definitions/settings/definitions/fatcontextSettings"
+ },
+ "forbidigo": {
+ "$ref": "#/definitions/settings/definitions/forbidigoSettings"
+ },
+ "funcorder": {
+ "$ref": "#/definitions/settings/definitions/funcorderSettings"
+ },
+ "funlen": {
+ "$ref": "#/definitions/settings/definitions/funlenSettings"
+ },
+ "ginkgolinter": {
+ "$ref": "#/definitions/settings/definitions/ginkgolinterSettings"
+ },
+ "gochecksumtype": {
+ "$ref": "#/definitions/settings/definitions/gochecksumtypeSettings"
+ },
+ "gocognit": {
+ "$ref": "#/definitions/settings/definitions/gocognitSettings"
+ },
+ "goconst": {
+ "$ref": "#/definitions/settings/definitions/goconstSettings"
+ },
+ "gocritic": {
+ "$ref": "#/definitions/settings/definitions/gocriticSettings"
+ },
+ "gocyclo": {
+ "$ref": "#/definitions/settings/definitions/gocycloSettings"
+ },
+ "godoclint": {
+ "$ref": "#/definitions/settings/definitions/godoclintSettings"
+ },
+ "godot": {
+ "$ref": "#/definitions/settings/definitions/godotSettings"
+ },
+ "godox": {
+ "$ref": "#/definitions/settings/definitions/godoxSettings"
+ },
+ "interfacebloat":{
+ "$ref": "#/definitions/settings/definitions/interfacebloatSettings"
+ },
+ "goheader": {
+ "$ref": "#/definitions/settings/definitions/goheaderSettings"
+ },
+ "gomoddirectives": {
+ "$ref": "#/definitions/settings/definitions/gomoddirectivesSettings"
+ },
+ "gomodguard": {
+ "$ref": "#/definitions/settings/definitions/gomodguardSettings"
+ },
+ "gosec": {
+ "$ref": "#/definitions/settings/definitions/gosecSettings"
+ },
+ "gosmopolitan": {
+ "$ref": "#/definitions/settings/definitions/gosmopolitanSettings"
+ },
+ "govet": {
+ "$ref": "#/definitions/settings/definitions/govetSettings"
+ },
+ "grouper": {
+ "$ref": "#/definitions/settings/definitions/grouperSettings"
+ },
+ "iface": {
+ "$ref": "#/definitions/settings/definitions/ifaceSettings"
+ },
+ "importas": {
+ "$ref": "#/definitions/settings/definitions/importasSettings"
+ },
+ "inamedparam": {
+ "$ref": "#/definitions/settings/definitions/inamedparamSettings"
+ },
+ "ineffassign": {
+ "$ref": "#/definitions/settings/definitions/ineffassignSettings"
+ },
+ "iotamixing": {
+ "$ref": "#/definitions/settings/definitions/iotamixingSettings"
+ },
+ "ireturn": {
+ "$ref": "#/definitions/settings/definitions/ireturnSettings"
+ },
+ "lll": {
+ "$ref": "#/definitions/settings/definitions/lllSettings"
+ },
+ "maintidx": {
+ "$ref": "#/definitions/settings/definitions/maintidxSettings"
+ },
+ "makezero":{
+ "$ref": "#/definitions/settings/definitions/makezeroSettings"
+ },
+ "loggercheck": {
+ "$ref": "#/definitions/settings/definitions/loggercheckSettings"
+ },
+ "misspell": {
+ "$ref": "#/definitions/settings/definitions/misspellSettings"
+ },
+ "musttag": {
+ "$ref": "#/definitions/settings/definitions/musttagSettings"
+ },
+ "nakedret": {
+ "$ref": "#/definitions/settings/definitions/nakedretSettings"
+ },
+ "nestif": {
+ "$ref": "#/definitions/settings/definitions/nestifSettings"
+ },
+ "nilnil": {
+ "$ref": "#/definitions/settings/definitions/nilnilSettings"
+ },
+ "nlreturn": {
+ "$ref": "#/definitions/settings/definitions/nlreturnSettings"
+ },
+ "mnd": {
+ "$ref": "#/definitions/settings/definitions/mndSettings"
+ },
+ "modernize": {
+ "$ref": "#/definitions/settings/definitions/modernizeSettings"
+ },
+ "nolintlint":{
+ "$ref": "#/definitions/settings/definitions/nolintlintSettings"
+ },
+ "reassign": {
+ "$ref": "#/definitions/settings/definitions/reassignSettings"
+ },
+ "recvcheck": {
+ "$ref": "#/definitions/settings/definitions/recvcheckSettings"
+ },
+ "nonamedreturns": {
+ "$ref": "#/definitions/settings/definitions/nonamedreturnsSettings"
+ },
+ "paralleltest": {
+ "$ref": "#/definitions/settings/definitions/paralleltestSettings"
+ },
+ "perfsprint": {
+ "$ref": "#/definitions/settings/definitions/perfsprintSettings"
+ },
+ "prealloc": {
+ "$ref": "#/definitions/settings/definitions/preallocSettings"
+ },
+ "predeclared": {
+ "$ref": "#/definitions/settings/definitions/predeclaredSettings"
+ },
+ "promlinter": {
+ "$ref": "#/definitions/settings/definitions/promlinterSettings"
+ },
+ "protogetter": {
+ "$ref": "#/definitions/settings/definitions/protogetterSettings"
+ },
+ "revive": {
+ "$ref": "#/definitions/settings/definitions/reviveSettings"
+ },
+ "rowserrcheck": {
+ "$ref": "#/definitions/settings/definitions/rowserrcheckSettings"
+ },
+ "sloglint": {
+ "$ref": "#/definitions/settings/definitions/sloglintSettings"
+ },
+ "spancheck": {
+ "$ref": "#/definitions/settings/definitions/spancheckSettings"
+ },
+ "staticcheck":{
+ "$ref": "#/definitions/settings/definitions/staticcheckSettings"
+ },
+ "tagalign": {
+ "$ref": "#/definitions/settings/definitions/tagalignSettings"
+ },
+ "tagliatelle": {
+ "$ref": "#/definitions/settings/definitions/tagliatelleSettings"
+ },
+ "testifylint": {
+ "$ref": "#/definitions/settings/definitions/testifylintSettings"
+ },
+ "testpackage": {
+ "$ref": "#/definitions/settings/definitions/testpackageSettings"
+ },
+ "thelper": {
+ "$ref": "#/definitions/settings/definitions/thelperSettings"
+ },
+ "usestdlibvars": {
+ "$ref": "#/definitions/settings/definitions/usestdlibvarsSettings"
+ },
+ "usetesting": {
+ "$ref": "#/definitions/settings/definitions/usetestingSettings"
+ },
+ "unconvert": {
+ "$ref": "#/definitions/settings/definitions/unconvertSettings"
+ },
+ "unparam": {
+ "$ref": "#/definitions/settings/definitions/unparamSettings"
+ },
+ "unqueryvet": {
+ "$ref": "#/definitions/settings/definitions/unqueryvetSettings"
+ },
+ "unused": {
+ "$ref": "#/definitions/settings/definitions/unusedSettings"
+ },
+ "varnamelen": {
+ "$ref": "#/definitions/settings/definitions/varnamelenSettings"
+ },
+ "whitespace": {
+ "$ref": "#/definitions/settings/definitions/whitespaceSettings"
+ },
+ "wrapcheck": {
+ "$ref": "#/definitions/settings/definitions/wrapcheckSettings"
+ },
+ "wsl": {
+ "$ref": "#/definitions/settings/definitions/wslSettings"
+ },
+ "wsl_v5": {
+ "$ref": "#/definitions/settings/definitions/wslSettingsV5"
+ },
+ "copyloopvar": {
+ "$ref": "#/definitions/settings/definitions/copyloopvarSettings"
+ },
+ "custom":{
+ "$ref": "#/definitions/settings/definitions/customSettings"
+ }
+ }
+ },
+ "exclusions":{
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "generated": {
+ "enum": ["strict", "lax", "disable"],
+ "default": "strict"
+ },
+ "warn-unused": {
+ "type": "boolean",
+ "default": false
+ },
+ "presets": {
+ "type": "array",
+ "items": {
+ "enum": [
+ "comments",
+ "std-error-handling",
+ "common-false-positives",
+ "legacy"
+ ]
+ }
+ },
+ "rules": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "path": {
+ "type": "string"
+ },
+ "path-except": {
+ "type": "string"
+ },
+ "linters": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linter-names"
+ }
+ },
+ "text": {
+ "type": "string"
+ },
+ "source": {
+ "type": "string"
+ }
+ },
+ "anyOf": [
+ { "required": ["path"] },
+ { "required": ["path-except"] },
+ { "required": ["linters"] },
+ { "required": ["text"] },
+ { "required": ["source"] }
+ ]
+ }
+ },
+ "paths": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "paths-except": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "formatters": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "enable": {
+ "description": "List of enabled formatters.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/formatter-names"
+ }
+ },
+ "settings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "gci": {
+ "$ref": "#/definitions/settings/definitions/gciSettings"
+ },
+ "gofmt": {
+ "$ref": "#/definitions/settings/definitions/gofmtSettings"
+ },
+ "gofumpt": {
+ "$ref": "#/definitions/settings/definitions/gofumptSettings"
+ },
+ "goimports": {
+ "$ref": "#/definitions/settings/definitions/goimportsSettings"
+ },
+ "golines": {
+ "$ref": "#/definitions/settings/definitions/golinesSettings"
+ }
+ }
+ },
+ "exclusions": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "generated": {
+ "enum": ["strict", "lax", "disable"],
+ "default": "strict"
+ },
+ "paths": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "warn-unused": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ }
+ }
+ },
+ "issues": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-issues-per-linter": {
+ "description": "Maximum issues count per one linter. Set to 0 to disable.",
+ "type": "integer",
+ "default": 50,
+ "minimum": 0
+ },
+ "max-same-issues": {
+ "description": "Maximum count of issues with the same text. Set to 0 to disable.",
+ "type": "integer",
+ "default": 3,
+ "minimum": 0
+ },
+ "new": {
+ "description": "Show only new issues: if there are unstaged changes or untracked files, only those changes are analyzed, else only changes in HEAD~ are analyzed.",
+ "type": "boolean",
+ "default": false
+ },
+ "new-from-merge-base": {
+ "description": "Show only new issues created after the best common ancestor (merge-base against HEAD).",
+ "type": "string"
+ },
+ "new-from-rev": {
+ "description": "Show only new issues created after this git revision.",
+ "type": "string"
+ },
+ "new-from-patch": {
+ "description": "Show only new issues created in git patch with this file path.",
+ "type": "string",
+ "examples": ["path/to/patch/file"]
+ },
+ "fix": {
+ "description": "Apply the fixes detected by the linters and formatters (if it's supported by the linter).",
+ "type": "boolean",
+ "default": false
+ },
+ "uniq-by-line": {
+ "description": "Make issues output unique by line.",
+ "type": "boolean",
+ "default": true
+ },
+ "whole-files": {
+ "description": "Show issues in any part of update files (requires new-from-rev or new-from-patch).",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "severity": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "default": {
+ "description": "Set the default severity for issues. If severity rules are defined and the issues do not match or no severity is provided to the rule this will be the default severity applied. Severities should match the supported severity names of the selected out format.",
+ "type": "string",
+ "default": ""
+ },
+ "rules": {
+ "description": "When a list of severity rules are provided, severity information will be added to lint issues. Severity rules have the same filtering capability as exclude rules except you are allowed to specify one matcher per severity rule.\nOnly affects out formats that support setting severity information.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "severity": {
+ "type": "string"
+ },
+ "path": {
+ "type": "string"
+ },
+ "path-except": {
+ "type": "string"
+ },
+ "linters": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linter-names"
+ }
+ },
+ "text": {
+ "type": "string"
+ },
+ "source": {
+ "type": "string"
+ }
+ },
+ "required": ["severity"],
+ "anyOf": [
+ { "required": ["path"] },
+ { "required": ["path-except"] },
+ { "required": ["linters"] },
+ { "required": ["text"] },
+ { "required": ["source"] }
+ ]
+ },
+ "default": []
+ }
+ },
+ "required": ["default"]
+ }
+ }
+}
diff --git a/vendor/github.com/golangci/golangci-lint/v2/jsonschema/golangci.v2.8.jsonschema.json b/vendor/github.com/golangci/golangci-lint/v2/jsonschema/golangci.v2.8.jsonschema.json
new file mode 100644
index 000000000..675beedd0
--- /dev/null
+++ b/vendor/github.com/golangci/golangci-lint/v2/jsonschema/golangci.v2.8.jsonschema.json
@@ -0,0 +1,5223 @@
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "$id": "https://json.schemastore.org/golangci-lint.json",
+ "definitions": {
+ "gocritic-checks": {
+ "enum": [
+ "appendAssign",
+ "appendCombine",
+ "argOrder",
+ "assignOp",
+ "badCall",
+ "badCond",
+ "badLock",
+ "badRegexp",
+ "badSorting",
+ "badSyncOnceFunc",
+ "boolExprSimplify",
+ "builtinShadow",
+ "builtinShadowDecl",
+ "captLocal",
+ "caseOrder",
+ "codegenComment",
+ "commentFormatting",
+ "commentedOutCode",
+ "commentedOutImport",
+ "defaultCaseOrder",
+ "deferInLoop",
+ "deferUnlambda",
+ "deprecatedComment",
+ "docStub",
+ "dupArg",
+ "dupBranchBody",
+ "dupCase",
+ "dupImport",
+ "dupOption",
+ "dupSubExpr",
+ "dynamicFmtString",
+ "elseif",
+ "emptyDecl",
+ "emptyFallthrough",
+ "emptyStringTest",
+ "equalFold",
+ "evalOrder",
+ "exitAfterDefer",
+ "exposedSyncMutex",
+ "externalErrorReassign",
+ "filepathJoin",
+ "flagDeref",
+ "flagName",
+ "hexLiteral",
+ "httpNoBody",
+ "hugeParam",
+ "ifElseChain",
+ "importShadow",
+ "indexAlloc",
+ "initClause",
+ "mapKey",
+ "methodExprCall",
+ "nestingReduce",
+ "newDeref",
+ "nilValReturn",
+ "octalLiteral",
+ "offBy1",
+ "paramTypeCombine",
+ "preferDecodeRune",
+ "preferFilepathJoin",
+ "preferFprint",
+ "preferStringWriter",
+ "preferWriteByte",
+ "ptrToRefParam",
+ "rangeAppendAll",
+ "rangeExprCopy",
+ "rangeValCopy",
+ "redundantSprint",
+ "regexpMust",
+ "regexpPattern",
+ "regexpSimplify",
+ "returnAfterHttpError",
+ "ruleguard",
+ "singleCaseSwitch",
+ "sliceClear",
+ "sloppyLen",
+ "sloppyReassign",
+ "sloppyTypeAssert",
+ "sortSlice",
+ "sprintfQuotedString",
+ "sqlQuery",
+ "stringConcatSimplify",
+ "stringXbytes",
+ "stringsCompare",
+ "switchTrue",
+ "syncMapLoadAndDelete",
+ "timeExprSimplify",
+ "todoCommentWithoutDetail",
+ "tooManyResultsChecker",
+ "truncateCmp",
+ "typeAssertChain",
+ "typeDefFirst",
+ "typeSwitchVar",
+ "typeUnparen",
+ "uncheckedInlineErr",
+ "underef",
+ "unlabelStmt",
+ "unlambda",
+ "unnamedResult",
+ "unnecessaryBlock",
+ "unnecessaryDefer",
+ "unslice",
+ "valSwap",
+ "weakCond",
+ "whyNoLint",
+ "wrapperFunc",
+ "yodaStyleExpr",
+ "zeroByteRepeat"
+ ]
+ },
+ "gocritic-tags": {
+ "enum": [
+ "diagnostic",
+ "style",
+ "performance",
+ "experimental",
+ "opinionated",
+ "security"
+ ]
+ },
+ "staticcheck-checks": {
+ "enum": [
+ "*",
+ "all",
+ "SA*",
+ "-SA*",
+ "SA1*",
+ "-SA1*",
+ "SA1000",
+ "-SA1000",
+ "SA1001",
+ "-SA1001",
+ "SA1002",
+ "-SA1002",
+ "SA1003",
+ "-SA1003",
+ "SA1004",
+ "-SA1004",
+ "SA1005",
+ "-SA1005",
+ "SA1006",
+ "-SA1006",
+ "SA1007",
+ "-SA1007",
+ "SA1008",
+ "-SA1008",
+ "SA1010",
+ "-SA1010",
+ "SA1011",
+ "-SA1011",
+ "SA1012",
+ "-SA1012",
+ "SA1013",
+ "-SA1013",
+ "SA1014",
+ "-SA1014",
+ "SA1015",
+ "-SA1015",
+ "SA1016",
+ "-SA1016",
+ "SA1017",
+ "-SA1017",
+ "SA1018",
+ "-SA1018",
+ "SA1019",
+ "-SA1019",
+ "SA1020",
+ "-SA1020",
+ "SA1021",
+ "-SA1021",
+ "SA1023",
+ "-SA1023",
+ "SA1024",
+ "-SA1024",
+ "SA1025",
+ "-SA1025",
+ "SA1026",
+ "-SA1026",
+ "SA1027",
+ "-SA1027",
+ "SA1028",
+ "-SA1028",
+ "SA1029",
+ "-SA1029",
+ "SA1030",
+ "-SA1030",
+ "SA1031",
+ "-SA1031",
+ "SA1032",
+ "-SA1032",
+ "SA2*",
+ "-SA2*",
+ "SA2000",
+ "-SA2000",
+ "SA2001",
+ "-SA2001",
+ "SA2002",
+ "-SA2002",
+ "SA2003",
+ "-SA2003",
+ "SA3*",
+ "-SA3*",
+ "SA3000",
+ "-SA3000",
+ "SA3001",
+ "-SA3001",
+ "SA4*",
+ "-SA4*",
+ "SA4000",
+ "-SA4000",
+ "SA4001",
+ "-SA4001",
+ "SA4003",
+ "-SA4003",
+ "SA4004",
+ "-SA4004",
+ "SA4005",
+ "-SA4005",
+ "SA4006",
+ "-SA4006",
+ "SA4008",
+ "-SA4008",
+ "SA4009",
+ "-SA4009",
+ "SA4010",
+ "-SA4010",
+ "SA4011",
+ "-SA4011",
+ "SA4012",
+ "-SA4012",
+ "SA4013",
+ "-SA4013",
+ "SA4014",
+ "-SA4014",
+ "SA4015",
+ "-SA4015",
+ "SA4016",
+ "-SA4016",
+ "SA4017",
+ "-SA4017",
+ "SA4018",
+ "-SA4018",
+ "SA4019",
+ "-SA4019",
+ "SA4020",
+ "-SA4020",
+ "SA4021",
+ "-SA4021",
+ "SA4022",
+ "-SA4022",
+ "SA4023",
+ "-SA4023",
+ "SA4024",
+ "-SA4024",
+ "SA4025",
+ "-SA4025",
+ "SA4026",
+ "-SA4026",
+ "SA4027",
+ "-SA4027",
+ "SA4028",
+ "-SA4028",
+ "SA4029",
+ "-SA4029",
+ "SA4030",
+ "-SA4030",
+ "SA4031",
+ "-SA4031",
+ "SA4032",
+ "-SA4032",
+ "SA5*",
+ "-SA5*",
+ "SA5000",
+ "-SA5000",
+ "SA5001",
+ "-SA5001",
+ "SA5002",
+ "-SA5002",
+ "SA5003",
+ "-SA5003",
+ "SA5004",
+ "-SA5004",
+ "SA5005",
+ "-SA5005",
+ "SA5007",
+ "-SA5007",
+ "SA5008",
+ "-SA5008",
+ "SA5009",
+ "-SA5009",
+ "SA5010",
+ "-SA5010",
+ "SA5011",
+ "-SA5011",
+ "SA5012",
+ "-SA5012",
+ "SA6*",
+ "-SA6*",
+ "SA6000",
+ "-SA6000",
+ "SA6001",
+ "-SA6001",
+ "SA6002",
+ "-SA6002",
+ "SA6003",
+ "-SA6003",
+ "SA6005",
+ "-SA6005",
+ "SA6006",
+ "-SA6006",
+ "SA9*",
+ "-SA9*",
+ "SA9001",
+ "-SA9001",
+ "SA9002",
+ "-SA9002",
+ "SA9003",
+ "-SA9003",
+ "SA9004",
+ "-SA9004",
+ "SA9005",
+ "-SA9005",
+ "SA9006",
+ "-SA9006",
+ "SA9007",
+ "-SA9007",
+ "SA9008",
+ "-SA9008",
+ "SA9009",
+ "-SA9009",
+ "ST*",
+ "-ST*",
+ "ST1*",
+ "-ST1*",
+ "ST1000",
+ "-ST1000",
+ "ST1001",
+ "-ST1001",
+ "ST1003",
+ "-ST1003",
+ "ST1005",
+ "-ST1005",
+ "ST1006",
+ "-ST1006",
+ "ST1008",
+ "-ST1008",
+ "ST1011",
+ "-ST1011",
+ "ST1012",
+ "-ST1012",
+ "ST1013",
+ "-ST1013",
+ "ST1015",
+ "-ST1015",
+ "ST1016",
+ "-ST1016",
+ "ST1017",
+ "-ST1017",
+ "ST1018",
+ "-ST1018",
+ "ST1019",
+ "-ST1019",
+ "ST1020",
+ "-ST1020",
+ "ST1021",
+ "-ST1021",
+ "ST1022",
+ "-ST1022",
+ "ST1023",
+ "-ST1023",
+ "S*",
+ "-S*",
+ "S1*",
+ "-S1*",
+ "S1000",
+ "-S1000",
+ "S1001",
+ "-S1001",
+ "S1002",
+ "-S1002",
+ "S1003",
+ "-S1003",
+ "S1004",
+ "-S1004",
+ "S1005",
+ "-S1005",
+ "S1006",
+ "-S1006",
+ "S1007",
+ "-S1007",
+ "S1008",
+ "-S1008",
+ "S1009",
+ "-S1009",
+ "S1010",
+ "-S1010",
+ "S1011",
+ "-S1011",
+ "S1012",
+ "-S1012",
+ "S1016",
+ "-S1016",
+ "S1017",
+ "-S1017",
+ "S1018",
+ "-S1018",
+ "S1019",
+ "-S1019",
+ "S1020",
+ "-S1020",
+ "S1021",
+ "-S1021",
+ "S1023",
+ "-S1023",
+ "S1024",
+ "-S1024",
+ "S1025",
+ "-S1025",
+ "S1028",
+ "-S1028",
+ "S1029",
+ "-S1029",
+ "S1030",
+ "-S1030",
+ "S1031",
+ "-S1031",
+ "S1032",
+ "-S1032",
+ "S1033",
+ "-S1033",
+ "S1034",
+ "-S1034",
+ "S1035",
+ "-S1035",
+ "S1036",
+ "-S1036",
+ "S1037",
+ "-S1037",
+ "S1038",
+ "-S1038",
+ "S1039",
+ "-S1039",
+ "S1040",
+ "-S1040",
+ "QF*",
+ "-QF*",
+ "QF1*",
+ "-QF1*",
+ "QF1001",
+ "-QF1001",
+ "QF1002",
+ "-QF1002",
+ "QF1003",
+ "-QF1003",
+ "QF1004",
+ "-QF1004",
+ "QF1005",
+ "-QF1005",
+ "QF1006",
+ "-QF1006",
+ "QF1007",
+ "-QF1007",
+ "QF1008",
+ "-QF1008",
+ "QF1009",
+ "-QF1009",
+ "QF1010",
+ "-QF1010",
+ "QF1011",
+ "-QF1011",
+ "QF1012",
+ "-QF1012"
+ ]
+ },
+ "godoclint-rules": {
+ "enum": [
+ "pkg-doc",
+ "single-pkg-doc",
+ "require-pkg-doc",
+ "start-with-name",
+ "require-doc",
+ "deprecated",
+ "max-len",
+ "no-unused-link",
+ "require-stdlib-doclink"
+ ]
+ },
+ "gosec-rules": {
+ "enum": [
+ "G101",
+ "G102",
+ "G103",
+ "G104",
+ "G106",
+ "G107",
+ "G108",
+ "G109",
+ "G110",
+ "G111",
+ "G112",
+ "G114",
+ "G115",
+ "G116",
+ "G201",
+ "G202",
+ "G203",
+ "G204",
+ "G301",
+ "G302",
+ "G303",
+ "G304",
+ "G305",
+ "G306",
+ "G307",
+ "G401",
+ "G402",
+ "G403",
+ "G404",
+ "G405",
+ "G406",
+ "G501",
+ "G502",
+ "G503",
+ "G504",
+ "G505",
+ "G506",
+ "G507",
+ "G601",
+ "G602"
+ ]
+ },
+ "govet-analyzers": {
+ "enum": [
+ "appends",
+ "asmdecl",
+ "assign",
+ "atomic",
+ "atomicalign",
+ "bools",
+ "buildtag",
+ "cgocall",
+ "composites",
+ "copylocks",
+ "deepequalerrors",
+ "defers",
+ "directive",
+ "errorsas",
+ "fieldalignment",
+ "findcall",
+ "framepointer",
+ "hostport",
+ "httpmux",
+ "httpresponse",
+ "ifaceassert",
+ "loopclosure",
+ "lostcancel",
+ "nilfunc",
+ "nilness",
+ "printf",
+ "reflectvaluecompare",
+ "shadow",
+ "shift",
+ "sigchanyzer",
+ "slog",
+ "sortslice",
+ "stdmethods",
+ "stdversion",
+ "stringintconv",
+ "structtag",
+ "testinggoroutine",
+ "tests",
+ "timeformat",
+ "unmarshal",
+ "unreachable",
+ "unsafeptr",
+ "unusedresult",
+ "unusedwrite",
+ "waitgroup"
+ ]
+ },
+ "revive-rules": {
+ "enum": [
+ "add-constant",
+ "argument-limit",
+ "atomic",
+ "banned-characters",
+ "bare-return",
+ "blank-imports",
+ "bool-literal-in-expr",
+ "call-to-gc",
+ "cognitive-complexity",
+ "comment-spacings",
+ "comments-density",
+ "confusing-naming",
+ "confusing-results",
+ "constant-logical-expr",
+ "context-as-argument",
+ "context-keys-type",
+ "cyclomatic",
+ "datarace",
+ "deep-exit",
+ "defer",
+ "dot-imports",
+ "duplicated-imports",
+ "early-return",
+ "empty-block",
+ "empty-lines",
+ "enforce-map-style",
+ "enforce-repeated-arg-type-style",
+ "enforce-slice-style",
+ "enforce-switch-style",
+ "error-naming",
+ "error-return",
+ "error-strings",
+ "errorf",
+ "exported",
+ "file-header",
+ "file-length-limit",
+ "filename-format",
+ "flag-parameter",
+ "forbidden-call-in-wg-go",
+ "function-length",
+ "function-result-limit",
+ "get-return",
+ "identical-branches",
+ "identical-ifelseif-branches",
+ "identical-ifelseif-conditions",
+ "identical-switch-branches",
+ "identical-switch-conditions",
+ "if-return",
+ "import-alias-naming",
+ "import-shadowing",
+ "imports-blocklist",
+ "increment-decrement",
+ "indent-error-flow",
+ "inefficient-map-lookup",
+ "line-length-limit",
+ "max-control-nesting",
+ "max-public-structs",
+ "modifies-parameter",
+ "modifies-value-receiver",
+ "nested-structs",
+ "optimize-operands-order",
+ "package-comments",
+ "package-directory-mismatch",
+ "range-val-address",
+ "range-val-in-closure",
+ "range",
+ "receiver-naming",
+ "redefines-builtin-id",
+ "redundant-build-tag",
+ "redundant-import-alias",
+ "redundant-test-main-exit",
+ "string-format",
+ "string-of-int",
+ "struct-tag",
+ "superfluous-else",
+ "time-date",
+ "time-equal",
+ "time-naming",
+ "unchecked-type-assertion",
+ "unconditional-recursion",
+ "unexported-naming",
+ "unexported-return",
+ "unhandled-error",
+ "unnecessary-format",
+ "unnecessary-if",
+ "unnecessary-stmt",
+ "unreachable-code",
+ "unsecure-url-scheme",
+ "unused-parameter",
+ "unused-receiver",
+ "use-any",
+ "use-errors-new",
+ "use-fmt-print",
+ "use-waitgroup-go",
+ "useless-break",
+ "useless-fallthrough",
+ "var-declaration",
+ "var-naming",
+ "waitgroup-by-value"
+ ]
+ },
+ "iface-analyzers": {
+ "enum": [
+ "identical",
+ "unused",
+ "opaque",
+ "unexported"
+ ]
+ },
+ "tagliatelle-cases": {
+ "enum": [
+ "",
+ "camel",
+ "pascal",
+ "kebab",
+ "snake",
+ "goCamel",
+ "goPascal",
+ "goKebab",
+ "goSnake",
+ "upper",
+ "upperSnake",
+ "lower",
+ "header"
+ ]
+ },
+ "modernize-analyzers": {
+ "enum": [
+ "any",
+ "bloop",
+ "fmtappendf",
+ "forvar",
+ "mapsloop",
+ "minmax",
+ "newexpr",
+ "omitzero",
+ "plusbuild",
+ "rangeint",
+ "reflecttypefor",
+ "slicescontains",
+ "slicessort",
+ "stditerators",
+ "stringscut",
+ "stringscutprefix",
+ "stringsseq",
+ "stringsbuilder",
+ "testingcontext",
+ "unsafefuncs",
+ "waitgroup"
+ ]
+ },
+ "wsl-checks": {
+ "enum": [
+ "assign",
+ "branch",
+ "decl",
+ "defer",
+ "expr",
+ "for",
+ "go",
+ "if",
+ "inc-dec",
+ "label",
+ "range",
+ "return",
+ "select",
+ "send",
+ "switch",
+ "type-switch",
+ "append",
+ "assign-exclusive",
+ "assign-expr",
+ "err",
+ "leading-whitespace",
+ "trailing-whitespace"
+ ]
+ },
+ "relative-path-modes": {
+ "enum": [
+ "gomod",
+ "gitroot",
+ "cfg",
+ "wd"
+ ]
+ },
+ "simple-format": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "path": {
+ "$ref": "#/definitions/formats-path",
+ "default": "stdout"
+ }
+ }
+ },
+ "formats-path" : {
+ "anyOf": [
+ {
+ "enum": [
+ "stdout",
+ "stderr"
+ ]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ },
+ "linter-names": {
+ "$comment": "anyOf with enum is used to allow auto-completion of non-custom linters",
+ "description": "Usable linter names.",
+ "anyOf": [
+ {
+ "enum": [
+ "arangolint",
+ "asasalint",
+ "asciicheck",
+ "bidichk",
+ "bodyclose",
+ "canonicalheader",
+ "containedctx",
+ "contextcheck",
+ "copyloopvar",
+ "cyclop",
+ "decorder",
+ "depguard",
+ "dogsled",
+ "dupl",
+ "dupword",
+ "durationcheck",
+ "embeddedstructfieldcheck",
+ "errcheck",
+ "errchkjson",
+ "errname",
+ "errorlint",
+ "exhaustive",
+ "exhaustruct",
+ "exptostd",
+ "fatcontext",
+ "forbidigo",
+ "forcetypeassert",
+ "funcorder",
+ "funlen",
+ "ginkgolinter",
+ "gocheckcompilerdirectives",
+ "gochecknoglobals",
+ "gochecknoinits",
+ "gochecksumtype",
+ "gocognit",
+ "goconst",
+ "gocritic",
+ "gocyclo",
+ "godoclint",
+ "godot",
+ "godox",
+ "err113",
+ "goheader",
+ "gomoddirectives",
+ "gomodguard",
+ "goprintffuncname",
+ "gosec",
+ "gosimple",
+ "gosmopolitan",
+ "govet",
+ "grouper",
+ "iface",
+ "importas",
+ "inamedparam",
+ "ineffassign",
+ "interfacebloat",
+ "intrange",
+ "iotamixing",
+ "ireturn",
+ "lll",
+ "loggercheck",
+ "maintidx",
+ "makezero",
+ "mirror",
+ "misspell",
+ "mnd",
+ "modernize",
+ "musttag",
+ "nakedret",
+ "nestif",
+ "nilerr",
+ "nilnesserr",
+ "nilnil",
+ "nlreturn",
+ "noctx",
+ "noinlineerr",
+ "nolintlint",
+ "nonamedreturns",
+ "nosprintfhostport",
+ "paralleltest",
+ "perfsprint",
+ "prealloc",
+ "predeclared",
+ "promlinter",
+ "protogetter",
+ "reassign",
+ "recvcheck",
+ "revive",
+ "rowserrcheck",
+ "sloglint",
+ "sqlclosecheck",
+ "staticcheck",
+ "stylecheck",
+ "tagalign",
+ "tagliatelle",
+ "testableexamples",
+ "testifylint",
+ "testpackage",
+ "thelper",
+ "tparallel",
+ "unconvert",
+ "unparam",
+ "unused",
+ "usestdlibvars",
+ "usetesting",
+ "varnamelen",
+ "wastedassign",
+ "whitespace",
+ "wrapcheck",
+ "wsl",
+ "wsl_v5",
+ "zerologlint"
+ ]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ },
+ "formatter-names": {
+ "description": "Usable formatter names.",
+ "enum": [
+ "gci",
+ "gofmt",
+ "gofumpt",
+ "goimports",
+ "golines",
+ "swaggo"
+ ]
+ },
+ "settings": {
+ "definitions": {
+ "dupwordSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "keywords": {
+ "description": "Keywords for detecting duplicate words. If this list is not empty, only the words defined in this list will be detected.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["the", "and", "a"]
+ }
+ },
+ "ignore": {
+ "description": "Keywords used to ignore detection.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["0C0C"]
+ }
+ },
+ "comments-only": {
+ "description": "Checks only comments, skip strings.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "asasalintSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "exclude": {
+ "description": "To specify a set of function names to exclude.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["\\.Wrapf"]
+ }
+ },
+ "use-builtin-exclusions": {
+ "description": "To enable/disable the asasalint builtin exclusions of function names.",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "bidichkSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "left-to-right-embedding": {
+ "description": "Disallow: LEFT-TO-RIGHT-EMBEDDING",
+ "type": "boolean",
+ "default": false
+ },
+ "right-to-left-embedding": {
+ "description": "Disallow: RIGHT-TO-LEFT-EMBEDDING",
+ "type": "boolean",
+ "default": false
+ },
+ "pop-directional-formatting": {
+ "description": "Disallow: POP-DIRECTIONAL-FORMATTING",
+ "type": "boolean",
+ "default": false
+ },
+ "left-to-right-override": {
+ "description": "Disallow: LEFT-TO-RIGHT-OVERRIDE",
+ "type": "boolean",
+ "default": false
+ },
+ "right-to-left-override": {
+ "description": "Disallow: RIGHT-TO-LEFT-OVERRIDE",
+ "type": "boolean",
+ "default": false
+ },
+ "left-to-right-isolate": {
+ "description": "Disallow: LEFT-TO-RIGHT-ISOLATE",
+ "type": "boolean",
+ "default": false
+ },
+ "right-to-left-isolate": {
+ "description": "Disallow: RIGHT-TO-LEFT-ISOLATE",
+ "type": "boolean",
+ "default": false
+ },
+ "first-strong-isolate": {
+ "description": "Disallow: FIRST-STRONG-ISOLATE",
+ "type": "boolean",
+ "default": false
+ },
+ "pop-directional-isolate": {
+ "description": "Disallow: POP-DIRECTIONAL-ISOLATE",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "cyclopSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-complexity": {
+ "description": "Max complexity the function can have",
+ "type": "integer",
+ "default": 10,
+ "minimum": 0
+ },
+ "package-average": {
+ "description": "Max average complexity in package",
+ "type": "number",
+ "default": 0,
+ "minimum": 0
+ }
+ }
+ },
+ "decorderSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "dec-order": {
+ "type": "array",
+ "default": [["type", "const", "var", "func"]],
+ "items": {
+ "enum": ["type", "const", "var", "func"]
+ }
+ },
+ "ignore-underscore-vars": {
+ "description": "Underscore vars (vars with \"_\" as the name) will be ignored at all checks",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-dec-order-check": {
+ "description": "Order of declarations is not checked",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-init-func-first-check": {
+ "description": "Allow init func to be anywhere in file",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-dec-num-check": {
+ "description": "Multiple global type, const and var declarations are allowed",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-type-dec-num-check": {
+ "description": "Type declarations will be ignored for dec num check",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-const-dec-num-check": {
+ "description": "Const declarations will be ignored for dec num check",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-var-dec-num-check": {
+ "description": "Var declarations will be ignored for dec num check",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ },
+ "depguardSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "rules": {
+ "description": "Rules to apply.",
+ "type": "object",
+ "additionalProperties": false,
+ "patternProperties": {
+ "^[^.]+$": {
+ "description": "Name of a rule.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "list-mode": {
+ "description": "Used to determine the package matching priority.",
+ "enum": ["original", "strict", "lax"],
+ "default": "original"
+ },
+ "files": {
+ "description": "List of file globs that will match this list of settings to compare against.",
+ "additionalProperties": false,
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "allow": {
+ "description": "List of allowed packages.",
+ "additionalProperties": false,
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "deny": {
+ "description": "Packages that are not allowed where the value is a suggestion.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "desc": {
+ "description": "Description",
+ "type": "string"
+ },
+ "pkg": {
+ "description": "Package",
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "dogsledSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-blank-identifiers": {
+ "description": "Check assignments with too many blank identifiers.",
+ "type": "integer",
+ "default": 2,
+ "minimum": 0
+ }
+ }
+ },
+ "duplSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "threshold": {
+ "description": "Tokens count to trigger issue.",
+ "type": "integer",
+ "default": 150,
+ "minimum": 0
+ }
+ }
+ },
+ "embeddedstructfieldcheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "empty-line": {
+ "description": "Checks that there is an empty space between the embedded fields and regular fields.",
+ "type": "boolean",
+ "default": false
+ },
+ "forbid-mutex": {
+ "description": "Checks that sync.Mutex and sync.RWMutex are not used as embedded fields.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "errcheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-type-assertions": {
+ "description": "Report about not checking errors in type assertions, i.e.: `a := b.(MyStruct)`",
+ "type": "boolean",
+ "default": false
+ },
+ "check-blank": {
+ "description": "Report about assignment of errors to blank identifier",
+ "type": "boolean",
+ "default": false
+ },
+ "exclude-functions": {
+ "description": "List of functions to exclude from checking, where each entry is a single function to exclude",
+ "type": "array",
+ "examples": ["io/ioutil.ReadFile", "io.Copy(*bytes.Buffer)"],
+ "items": {
+ "type": "string"
+ }
+ },
+ "disable-default-exclusions": {
+ "description": "To disable the errcheck built-in exclude list",
+ "type": "boolean",
+ "default": false
+ },
+ "verbose": {
+ "description": "Display function signature instead of selector",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "errchkjsonSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-error-free-encoding": {
+ "type": "boolean",
+ "default": false
+ },
+ "report-no-exported": {
+ "description": "Issue on struct that doesn't have exported fields.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "errorlintSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "errorf": {
+ "description": "Check whether fmt.Errorf uses the %w verb for formatting errors",
+ "type": "boolean",
+ "default": true
+ },
+ "errorf-multi": {
+ "description": "Permit more than 1 %w verb, valid per Go 1.20",
+ "type": "boolean",
+ "default": true
+ },
+ "asserts": {
+ "description": "Check for plain type assertions and type switches.",
+ "type": "boolean",
+ "default": true
+ },
+ "comparison": {
+ "description": "Check for plain error comparisons",
+ "type": "boolean",
+ "default": true
+ },
+ "allowed-errors": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "err": {
+ "type": "string"
+ },
+ "fun": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "allowed-errors-wildcard": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "err": {
+ "type": "string"
+ },
+ "fun": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "exhaustiveSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check": {
+ "description": "Program elements to check for exhaustiveness.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["switch", "map"]
+ }
+ },
+ "explicit-exhaustive-switch": {
+ "description": "Only run exhaustive check on switches with \"//exhaustive:enforce\" comment.",
+ "type": "boolean",
+ "default": false
+ },
+ "explicit-exhaustive-map": {
+ "description": "Only run exhaustive check on map literals with \"//exhaustive:enforce\" comment.",
+ "type": "boolean",
+ "default": false
+ },
+ "default-case-required": {
+ "description": "Switch statement requires default case even if exhaustive.",
+ "type": "boolean",
+ "default": false
+ },
+ "default-signifies-exhaustive": {
+ "description": "Presence of `default` case in switch statements satisfies exhaustiveness, even if all enum members are not listed.",
+ "type": "boolean",
+ "default": false
+ },
+ "ignore-enum-members": {
+ "description": "Enum members matching `regex` do not have to be listed in switch statements to satisfy exhaustiveness",
+ "type": "string"
+ },
+ "ignore-enum-types": {
+ "description": "Enum types matching the supplied regex do not have to be listed in switch statements to satisfy exhaustiveness.",
+ "type": "string"
+ },
+ "package-scope-only": {
+ "description": "Consider enums only in package scopes, not in inner scopes.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "exhaustructSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "include": {
+ "description": "List of regular expressions to match struct packages and names.",
+ "type": "array",
+ "examples": [".*\\.Test"],
+ "items": {
+ "type": "string"
+ }
+ },
+ "exclude": {
+ "description": "List of regular expressions to exclude struct packages and names from check.",
+ "type": "array",
+ "examples": ["cobra\\.Command$"],
+ "items": {
+ "type": "string"
+ }
+ },
+ "allow-empty": {
+ "description": "Allows empty structures, effectively excluding them from the check.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-empty-rx": {
+ "description": "List of regular expressions to match type names that should be allowed to be empty.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "allow-empty-returns": {
+ "description": "Allows empty structures in return statements.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-empty-declarations": {
+ "description": "Allows empty structures in variable declarations.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "fatcontextSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-struct-pointers": {
+ "description": "Check for potential fat contexts in struct pointers.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "forbidigoSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "exclude-godoc-examples": {
+ "description": "Exclude code in godoc examples.",
+ "type": "boolean",
+ "default": true
+ },
+ "analyze-types": {
+ "description": "Instead of matching the literal source code, use type information to replace expressions with strings that contain the package name and (for methods and fields) the type name.",
+ "type": "boolean",
+ "default": true
+ },
+ "forbid": {
+ "description": "List of identifiers to forbid (written using `regexp`)",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "pattern": {
+ "description": "Pattern",
+ "type": "string"
+ },
+ "pkg": {
+ "description": "Package",
+ "type": "string"
+ },
+ "msg": {
+ "description": "Message",
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "funcorderSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "constructor": {
+ "description": "Checks that constructors are placed after the structure declaration.",
+ "type": "boolean",
+ "default": true
+ },
+ "struct-method": {
+ "description": "Checks if the exported methods of a structure are placed before the non-exported ones.",
+ "type": "boolean",
+ "default": true
+ },
+ "alphabetical": {
+ "description": "Checks if the constructors and/or structure methods are sorted alphabetically.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "funlenSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "lines": {
+ "description": "Limit lines number per function.",
+ "type": "integer",
+ "default": 60
+ },
+ "statements": {
+ "description": "Limit statements number per function.",
+ "type": "integer",
+ "default": 40
+ },
+ "ignore-comments": {
+ "description": "Ignore comments when counting lines.",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "gciSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "sections": {
+ "description": "Section configuration to compare against.",
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "enum": [
+ "standard",
+ "default",
+ "blank",
+ "dot",
+ "alias",
+ "localmodule"
+ ]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ },
+ "default": ["standard", "default"]
+ },
+ "no-inline-comments": {
+ "description": "Checks that no inline Comments are present.",
+ "type": "boolean",
+ "default": false
+ },
+ "no-prefix-comments": {
+ "description": "Checks that no prefix Comments(comment lines above an import) are present.",
+ "type": "boolean",
+ "default": false
+ },
+ "custom-order": {
+ "description": "Enable custom order of sections.",
+ "type": "boolean",
+ "default": false
+ },
+ "no-lex-order": {
+ "description": "Drops lexical ordering for custom sections.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "ginkgolinterSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "suppress-len-assertion": {
+ "description": "Suppress the wrong length assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-nil-assertion": {
+ "description": "Suppress the wrong nil assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-err-assertion": {
+ "description": "Suppress the wrong error assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-compare-assertion": {
+ "description": "Suppress the wrong comparison assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-async-assertion": {
+ "description": "Suppress the function all in async assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-type-compare-assertion": {
+ "description": "Suppress warning for comparing values from different types, like int32 and uint32.",
+ "type": "boolean",
+ "default": false
+ },
+ "forbid-focus-container": {
+ "description": "Trigger warning for ginkgo focus containers like FDescribe, FContext, FWhen or FIt.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-havelen-zero": {
+ "description": "Don't trigger warnings for HaveLen(0).",
+ "type": "boolean",
+ "default": false
+ },
+ "force-expect-to": {
+ "description": "Force using `Expect` with `To`, `ToNot` or `NotTo`",
+ "type": "boolean",
+ "default": false
+ },
+ "validate-async-intervals": {
+ "description": "Best effort validation of async intervals (timeout and polling).",
+ "type": "boolean",
+ "default": false
+ },
+ "forbid-spec-pollution": {
+ "description": "Trigger a warning for variable assignments in ginkgo containers like `Describe`, `Context` and `When`, instead of in `BeforeEach()`.",
+ "type": "boolean",
+ "default": false
+ },
+ "force-succeed": {
+ "description": "Force using the Succeed matcher for error functions, and the HaveOccurred matcher for non-function error values.",
+ "type": "boolean",
+ "default": false
+ },
+ "force-assertion-description": {
+ "description": "Force adding assertion descriptions to gomega matchers.",
+ "type": "boolean",
+ "default": false
+ },
+ "force-tonot": {
+ "description": "Force using `ToNot`, `ShouldNot` instead of `To(Not())`.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "gochecksumtypeSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "default-signifies-exhaustive": {
+ "description": "Presence of `default` case in switch statements satisfies exhaustiveness, if all members are not listed.",
+ "type": "boolean",
+ "default": true
+ },
+ "include-shared-interfaces": {
+ "description": "Include shared interfaces in the exhaustiviness check.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "gocognitSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "min-complexity": {
+ "description": "Minimal code complexity to report (we recommend 10-20).",
+ "type": "integer",
+ "default": 30
+ }
+ }
+ },
+ "goconstSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "match-constant": {
+ "description": "Look for existing constants matching the values",
+ "type": "boolean",
+ "default": true
+ },
+ "min-len": {
+ "description": "Minimum length of string constant.",
+ "type": "integer",
+ "default": 3
+ },
+ "min-occurrences": {
+ "description": "Minimum occurrences count to trigger.",
+ "type": "integer",
+ "default": 3
+ },
+ "ignore-calls": {
+ "description": "Ignore when constant is not used as function argument",
+ "type": "boolean",
+ "default": true
+ },
+ "ignore-string-values": {
+ "description": "Exclude strings matching the given regular expression",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "numbers": {
+ "description": "Search also for duplicated numbers.",
+ "type": "boolean",
+ "default": false
+ },
+ "min": {
+ "description": "Minimum value, only works with `numbers`",
+ "type": "integer",
+ "default": 3
+ },
+ "max": {
+ "description": "Maximum value, only works with `numbers`",
+ "type": "integer",
+ "default": 3
+ },
+ "find-duplicates": {
+ "description": "Detects constants with identical values",
+ "type": "boolean",
+ "default": false
+ },
+ "eval-const-expressions": {
+ "description": "Evaluates of constant expressions like Prefix + \"suffix\"",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "gocriticSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "enabled-checks": {
+ "description": "Which checks should be enabled. By default, a list of stable checks is used. To see it, run `GL_DEBUG=gocritic golangci-lint run`.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/gocritic-checks"
+ }
+ },
+ "disabled-checks": {
+ "description": "Which checks should be disabled.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/gocritic-checks"
+ },
+ "default": []
+ },
+ "enabled-tags": {
+ "description": "Enable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/gocritic-tags"
+ }
+ },
+ "disabled-tags": {
+ "description": "Disable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/gocritic-tags"
+ }
+ },
+ "settings": {
+ "description": "Settings passed to gocritic. Properties must be valid and enabled check names.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "captLocal": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "paramsOnly" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "commentedOutCode": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "minLength" : {
+ "type": "number",
+ "default": 15
+ }
+ }
+ },
+ "elseif": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skipBalanced" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "hugeParam": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "sizeThreshold" : {
+ "type": "number",
+ "default": 80
+ }
+ }
+ },
+ "ifElseChain": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "minThreshold" : {
+ "type": "number",
+ "default": 2
+ }
+ }
+ },
+ "nestingReduce": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "bodyWidth" : {
+ "type": "number",
+ "default": 5
+ }
+ }
+ },
+ "rangeExprCopy": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "sizeThreshold" : {
+ "type": "number",
+ "default": 512
+ },
+ "skipTestFuncs" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "rangeValCopy": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "sizeThreshold" : {
+ "type": "number",
+ "default": 128
+ },
+ "skipTestFuncs" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "ruleguard": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "debug" : {
+ "type": "string"
+ },
+ "enable" : {
+ "type": "string"
+ },
+ "disable" : {
+ "type": "string"
+ },
+ "failOn" : {
+ "type": "string"
+ },
+ "rules" : {
+ "type": "string"
+ }
+ }
+ },
+ "tooManyResultsChecker": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "maxResults" : {
+ "type": "number",
+ "default": 5
+ }
+ }
+ },
+ "truncateCmp": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skipArchDependent" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "underef": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skipRecvDeref" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "unnamedResult": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "checkExported" : {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ }
+ }
+ },
+ "disable-all": {
+ "type": "boolean",
+ "default": false
+ },
+ "enable-all": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "gocycloSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "min-complexity": {
+ "description": "Minimum code complexity to report (we recommend 10-20).",
+ "type": "integer",
+ "default": 30
+ }
+ }
+ },
+ "godoclintSettings": {
+ "type": "object",
+ "properties": {
+ "default": {
+ "type": "string",
+ "enum": ["all", "basic", "none"],
+ "default": "basic",
+ "description": "Default set of rules to enable."
+ },
+ "enable": {
+ "description": "List of rules to enable in addition to the default set.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "$ref": "#/definitions/godoclint-rules"
+ }
+ },
+ "disable": {
+ "description": "List of rules to disable.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "$ref": "#/definitions/godoclint-rules"
+ }
+ },
+ "options": {
+ "type": "object",
+ "description": "A map for setting individual rule options.",
+ "properties": {
+ "max-len": {
+ "type": "object",
+ "properties": {
+ "length": {
+ "type": "integer",
+ "description": "Maximum line length for godocs, not including the `//`, `/*` or `*/` tokens.",
+ "default": 77
+ }
+ }
+ },
+ "require-doc": {
+ "type": "object",
+ "properties": {
+ "ignore-exported": {
+ "type": "boolean",
+ "description": "Ignore exported (public) symbols when applying the `require-doc` rule.",
+ "default": false
+ },
+ "ignore-unexported": {
+ "type": "boolean",
+ "description": "Ignore unexported (private) symbols when applying the `require-doc` rule.",
+ "default": true
+ }
+ }
+ },
+ "start-with-name": {
+ "type": "object",
+ "properties": {
+ "include-unexported": {
+ "type": "boolean",
+ "description": "Include unexported symbols when applying the `start-with-name` rule.",
+ "default": false
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "godotSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "scope": {
+ "description": "Comments to be checked.",
+ "enum": ["declarations", "toplevel", "all", "noinline"],
+ "default": "declarations"
+ },
+ "exclude": {
+ "description": "List of regexps for excluding particular comment lines from check.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "period": {
+ "description": "Check that each sentence ends with a period.",
+ "type": "boolean",
+ "default": true
+ },
+ "capital": {
+ "description": "Check that each sentence starts with a capital letter.",
+ "type": "boolean",
+ "default": false
+ },
+ "check-all": {
+ "description": "DEPRECATED: Check all top-level comments, not only declarations.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "godoxSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "keywords": {
+ "description": "Report any comments starting with one of these keywords. This is useful for TODO or FIXME comments that might be left in the code accidentally and should be resolved before merging.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "default": ["TODO", "BUG", "FIXME"]
+ }
+ }
+ },
+ "gofmtSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "simplify": {
+ "description": "Simplify code.",
+ "type": "boolean",
+ "default": true
+ },
+ "rewrite-rules": {
+ "description": "Apply the rewrite rules to the source before reformatting.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "pattern": {
+ "type": "string"
+ },
+ "replacement": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "golinesSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-len": {
+ "type": "integer",
+ "default": 100
+ },
+ "tab-len": {
+ "type": "integer",
+ "default": 4
+ },
+ "shorten-comments": {
+ "type": "boolean",
+ "default": false
+ },
+ "reformat-tags": {
+ "type": "boolean",
+ "default": true
+ },
+ "chain-split-dots": {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "interfacebloatSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max": {
+ "description": "The maximum number of methods allowed for an interface.",
+ "type": "integer"
+ }
+ }
+ },
+ "gofumptSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "extra-rules": {
+ "description": "Choose whether or not to use the extra rules that are disabled by default.",
+ "type": "boolean",
+ "default": false
+ },
+ "module-path": {
+ "description": " Module path which contains the source code being formatted.",
+ "type": "string"
+ }
+ }
+ },
+ "goheaderSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "values": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "const": {
+ "description": "Constants to use in the template.",
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "description": "Value for the constant.",
+ "type": "string"
+ }
+ },
+ "additionalProperties": false,
+ "examples": [
+ {
+ "YEAR": "2030",
+ "COMPANY": "MY FUTURISTIC COMPANY"
+ }
+ ]
+ },
+ "regexp": {
+ "description": "Regular expressions to use in your template.",
+ "type": "object",
+ "additionalProperties": false,
+ "patternProperties": {
+ "^.+$": {
+ "type": "string"
+ }
+ },
+ "examples": [
+ {
+ "AUTHOR": ".*@mycompany\\.com"
+ }
+ ]
+ }
+ }
+ },
+ "template": {
+ "description": "Template to put on top of every file.",
+ "type": "string",
+ "examples": [
+ "{{ MY COMPANY }}\nSPDX-License-Identifier: Apache-2.0\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at:\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License."
+ ]
+ },
+ "template-path": {
+ "description": "Path to the file containing the template source.",
+ "type": "string",
+ "examples": ["my_header_template.txt"]
+ }
+ },
+ "oneOf": [
+ { "required": ["template"] },
+ { "required": ["template-path"] }
+ ]
+ },
+ "goimportsSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "local-prefixes": {
+ "description": "Put imports beginning with prefix after 3rd-party packages. It is a list of prefixes.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "gomoddirectivesSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "replace-local": {
+ "description": "Allow local `replace` directives.",
+ "type": "boolean",
+ "default": true
+ },
+ "replace-allow-list": {
+ "description": "List of allowed `replace` directives.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "retract-allow-no-explanation": {
+ "description": "Allow to not explain why the version has been retracted in the `retract` directives.",
+ "type": "boolean",
+ "default": false
+ },
+ "exclude-forbidden": {
+ "description": "Forbid the use of the `exclude` directives.",
+ "type": "boolean",
+ "default": false
+ },
+ "ignore-forbidden": {
+ "description": "Forbid the use of the `ignore` directives. (>= go1.25)",
+ "type": "boolean",
+ "default": false
+ },
+ "toolchain-forbidden": {
+ "description": "Forbid the use of the `toolchain` directive.",
+ "type": "boolean",
+ "default": false
+ },
+ "toolchain-pattern": {
+ "description": "Defines a pattern to validate `toolchain` directive.",
+ "type": "string"
+ },
+ "tool-forbidden": {
+ "description": "Forbid the use of the `tool` directives.",
+ "type": "boolean",
+ "default": false
+ },
+ "go-debug-forbidden": {
+ "description": "Forbid the use of the `godebug` directive.",
+ "type": "boolean",
+ "default": false
+ },
+ "go-version-pattern": {
+ "description": "Defines a pattern to validate `go` minimum version directive.",
+ "type": "string",
+ "default": ""
+ },
+ "check-module-path": {
+ "description": "Check the validity of the module path.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "gomodguardSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "allowed": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "modules": {
+ "description": "List of allowed modules.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["gopkg.in/yaml.v2"]
+ }
+ },
+ "domains": {
+ "description": "List of allowed module domains.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["golang.org"]
+ }
+ }
+ }
+ },
+ "blocked": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "modules": {
+ "description": "List of blocked modules.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "recommendations": {
+ "description": "Recommended modules that should be used instead.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "reason": {
+ "description": "Reason why the recommended module should be used.",
+ "type": "string"
+ }
+ }
+ }
+ },
+ "additionalProperties": false
+ }
+ },
+ "versions": {
+ "description": "List of blocked module version constraints.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "patternProperties": {
+ "^.*$": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "version": {
+ "description": "Version constraint.",
+ "type": "string"
+ },
+ "reason": {
+ "description": "Reason why the version constraint exists.",
+ "type": "string"
+ }
+ },
+ "required": ["reason"]
+ }
+ }
+ }
+ },
+ "local-replace-directives": {
+ "description": "Raise lint issues if loading local path with replace directive",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ }
+ }
+ },
+ "gosecSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "includes": {
+ "type": "array",
+ "description": "To select a subset of rules to run",
+ "examples": [["G401"]],
+ "items": {
+ "$ref": "#/definitions/gosec-rules"
+ }
+ },
+ "excludes": {
+ "type": "array",
+ "description": "To specify a set of rules to explicitly exclude",
+ "examples": [["G401"]],
+ "items": {
+ "$ref": "#/definitions/gosec-rules"
+ }
+ },
+ "severity": {
+ "description": "Filter out the issues with a lower severity than the given value",
+ "type": "string",
+ "enum": ["low", "medium", "high"],
+ "default": "low"
+ },
+ "confidence": {
+ "description": "Filter out the issues with a lower confidence than the given value",
+ "type": "string",
+ "enum": ["low", "medium", "high"],
+ "default": "low"
+ },
+ "config": {
+ "description": "To specify the configuration of rules",
+ "type": "object"
+ },
+ "concurrency": {
+ "description": "Concurrency value",
+ "type": "integer"
+ }
+ }
+ },
+ "gosmopolitanSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "allow-time-local": {
+ "description": "Allow and ignore `time.Local` usages.",
+ "type": "boolean",
+ "default": false
+ },
+ "escape-hatches": {
+ "description": "List of fully qualified names in the `full/pkg/path.name` form, to act as \"i18n escape hatches\".",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "watch-for-scripts": {
+ "description": "List of Unicode scripts to watch for any usage in string literals.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "govetSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "settings": {
+ "description": "Settings per analyzer. Map of analyzer name to specific settings.\nRun `go tool vet help` to find out more.",
+ "type": "object",
+ "propertyNames": {
+ "$ref": "#/definitions/govet-analyzers"
+ },
+ "patternProperties": {
+ "^.*$": {
+ "description": "Run `go tool vet help ` to see all settings.",
+ "type": "object"
+ }
+ }
+ },
+ "enable": {
+ "description": "Enable analyzers by name.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/govet-analyzers"
+ }
+ },
+ "disable": {
+ "description": "Disable analyzers by name.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/govet-analyzers"
+ }
+ },
+ "enable-all": {
+ "description": "Enable all analyzers.",
+ "type": "boolean",
+ "default": false
+ },
+ "disable-all": {
+ "description": "Disable all analyzers.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "grouperSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "const-require-single-const": {
+ "type": "boolean",
+ "default": false
+ },
+ "const-require-grouping": {
+ "type": "boolean",
+ "default": false
+ },
+ "import-require-single-import": {
+ "type": "boolean",
+ "default": false
+ },
+ "import-require-grouping": {
+ "type": "boolean",
+ "default": false
+ },
+ "type-require-single-type": {
+ "type": "boolean",
+ "default": false
+ },
+ "type-require-grouping": {
+ "type": "boolean",
+ "default": false
+ },
+ "var-require-single-var": {
+ "type": "boolean",
+ "default": false
+ },
+ "var-require-grouping": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "ifaceSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "enable": {
+ "description": "Enable analyzers by name.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/iface-analyzers"
+ }
+ },
+ "settings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "unused": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "exclude": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "importasSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "no-unaliased": {
+ "description": "Do not allow unaliased imports of aliased packages.",
+ "type": "boolean",
+ "default": false
+ },
+ "no-extra-aliases": {
+ "description": "Do not allow non-required aliases.",
+ "type": "boolean",
+ "default": false
+ },
+ "alias": {
+ "description": "List of aliases",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "pkg": {
+ "description": "Package path e.g. knative.dev/serving/pkg/apis/autoscaling/v1alpha1",
+ "type": "string"
+ },
+ "alias": {
+ "description": "Package alias e.g. autoscalingv1alpha1",
+ "type": "string"
+ }
+ },
+ "required": ["pkg", "alias"]
+ }
+ }
+ }
+ },
+ "inamedparamSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skip-single-param": {
+ "description": "Skips check for interface methods with only a single parameter.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "ineffassignSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-escaping-errors": {
+ "description": "Check escaping variables of type error, may cause false positives.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "iotamixingSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "report-individual": {
+ "description": "Whether to report individual consts rather than just the const block.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "ireturnSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "description": "Use either `reject` or `allow` properties for interfaces matching.",
+ "properties": {
+ "allow": {
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "enum": ["anon", "error", "empty", "stdlib"]
+ }
+ ]
+ }
+ },
+ "reject": {
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "enum": ["anon", "error", "empty", "stdlib"]
+ }
+ ]
+ }
+ }
+ },
+ "anyOf": [
+ {
+ "not": {
+ "properties": {
+ "allow": {
+ "const": "reject"
+ }
+ }
+ },
+ "required": ["allow"]
+ },
+ {
+ "required": ["reject"]
+ }
+ ]
+ },
+ "lllSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "tab-width": {
+ "description": "Width of \"\\t\" in spaces.",
+ "type": "integer",
+ "minimum": 0,
+ "default": 1
+ },
+ "line-length": {
+ "description": "Maximum allowed line length, lines longer will be reported.",
+ "type": "integer",
+ "minimum": 1,
+ "default": 120
+ }
+ }
+ },
+ "maintidxSettings": {
+ "description": "Maintainability index https://docs.microsoft.com/en-us/visualstudio/code-quality/code-metrics-maintainability-index-range-and-meaning?view=vs-2022",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "under": {
+ "description": "Minimum accatpable maintainability index level (see https://docs.microsoft.com/en-us/visualstudio/code-quality/code-metrics-maintainability-index-range-and-meaning?view=vs-2022)",
+ "type": "number",
+ "default": 20
+ }
+ }
+ },
+ "makezeroSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "always": {
+ "description": "Allow only slices initialized with a length of zero.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "loggercheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "kitlog": {
+ "description": "Allow check for the github.com/go-kit/log library.",
+ "type": "boolean",
+ "default": true
+ },
+ "klog": {
+ "description": "Allow check for the k8s.io/klog/v2 library.",
+ "type": "boolean",
+ "default": true
+ },
+ "logr": {
+ "description": "Allow check for the github.com/go-logr/logr library.",
+ "type": "boolean",
+ "default": true
+ },
+ "slog": {
+ "description": "Allow check for the log/slog library.",
+ "type": "boolean",
+ "default": true
+ },
+ "zap": {
+ "description": "Allow check for the \"sugar logger\" from go.uber.org/zap library.",
+ "type": "boolean",
+ "default": true
+ },
+ "require-string-key": {
+ "description": "Require all logging keys to be inlined constant strings.",
+ "type": "boolean",
+ "default": false
+ },
+ "no-printf-like": {
+ "description": "Require printf-like format specifier (%s, %d for example) not present.",
+ "type": "boolean",
+ "default": false
+ },
+ "rules": {
+ "description": "List of custom rules to check against, where each rule is a single logger pattern, useful for wrapped loggers.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "misspellSettings": {
+ "description": "Correct spellings using locale preferences for US or UK. Default is to use a neutral variety of English.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "locale": {
+ "enum": ["US", "UK"]
+ },
+ "ignore-rules": {
+ "description": "List of rules to ignore.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "mode": {
+ "description": "Mode of the analysis.",
+ "enum": ["restricted", "", "default"],
+ "default": ""
+ },
+ "extra-words": {
+ "description": "Extra word corrections.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "correction": {
+ "type": "string"
+ },
+ "typo": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "musttagSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "functions": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "tag": {
+ "type": "string"
+ },
+ "arg-pos": {
+ "type": "integer"
+ }
+ }
+ }
+ }
+ }
+ },
+ "nakedretSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-func-lines": {
+ "description": "Report if a function has more lines of code than this value and it has naked returns.",
+ "type": "integer",
+ "minimum": 0,
+ "default": 30
+ }
+ }
+ },
+ "nestifSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "min-complexity": {
+ "description": "Minimum complexity of \"if\" statements to report.",
+ "type": "integer",
+ "default": 5
+ }
+ }
+ },
+ "nilnilSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "only-two": {
+ "type": "boolean",
+ "description": "To check functions with only two return values.",
+ "default": true
+ },
+ "detect-opposite": {
+ "type": "boolean",
+ "description": "In addition, detect opposite situation (simultaneous return of non-nil error and valid value).",
+ "default": false
+ },
+ "checked-types": {
+ "type": "array",
+ "description": "List of return types to check.",
+ "items": {
+ "enum": ["chan", "func", "iface", "map", "ptr", "uintptr", "unsafeptr"]
+ },
+ "default": ["chan", "func", "iface", "map", "ptr", "uintptr", "unsafeptr"]
+ }
+ }
+ },
+ "nlreturnSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "block-size": {
+ "description": "set block size that is still ok",
+ "type": "number",
+ "default": 0,
+ "minimum": 0
+ }
+ }
+ },
+ "mndSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignored-files": {
+ "description": "List of file patterns to exclude from analysis.",
+ "examples": [["magic1_.*.go"]],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignored-functions": {
+ "description": "Comma-separated list of function patterns to exclude from the analysis.",
+ "examples": [["math.*", "http.StatusText", "make"]],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignored-numbers": {
+ "description": "List of numbers to exclude from analysis.",
+ "examples": [["1000", "1234_567_890", "3.14159264"]],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "checks": {
+ "description": "The list of enabled checks, see https://github.com/tommy-muehle/go-mnd/#checks for description.",
+ "type": "array",
+ "items": {
+ "enum": [
+ "argument",
+ "case",
+ "condition",
+ "operation",
+ "return",
+ "assign"
+ ]
+ }
+ }
+ }
+ },
+ "modernizeSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "disable": {
+ "description": "List of analyzers to disable.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/modernize-analyzers"
+ }
+ }
+ }
+ },
+ "nolintlintSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "allow-unused": {
+ "description": "Enable to ensure that nolint directives are all used.",
+ "type": "boolean",
+ "default": true
+ },
+ "allow-no-explanation": {
+ "description": "Exclude these linters from requiring an explanation.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linter-names"
+ },
+ "default": []
+ },
+ "require-explanation": {
+ "description": "Enable to require an explanation of nonzero length after each nolint directive.",
+ "type": "boolean",
+ "default": false
+ },
+ "require-specific": {
+ "description": "Enable to require nolint directives to mention the specific linter being suppressed.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "reassignSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "patterns": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "recvcheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "disable-builtin": {
+ "description": "Disables the built-in method exclusions.",
+ "type": "boolean",
+ "default": true
+ },
+ "exclusions": {
+ "description": "User-defined method exclusions.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "nonamedreturnsSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "report-error-in-defer": {
+ "description": "Report named error if it is assigned inside defer.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "paralleltestSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignore-missing": {
+ "description": "Ignore missing calls to `t.Parallel()` and only report incorrect uses of it.",
+ "type": "boolean",
+ "default": false
+ },
+ "ignore-missing-subtests": {
+ "description": "Ignore missing calls to `t.Parallel()` in subtests. Top-level tests are still required to have `t.Parallel`, but subtests are allowed to skip it.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "perfsprintSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "integer-format": {
+ "description": "Enable/disable optimization of integer formatting.",
+ "type": "boolean",
+ "default": true
+ },
+ "int-conversion": {
+ "description": "Optimizes even if it requires an int or uint type cast.",
+ "type": "boolean",
+ "default": true
+ },
+ "error-format": {
+ "description": "Enable/disable optimization of error formatting.",
+ "type": "boolean",
+ "default": true
+ },
+ "err-error": {
+ "description": "Optimizes into `err.Error()` even if it is only equivalent for non-nil errors.",
+ "type": "boolean",
+ "default": false
+ },
+ "errorf": {
+ "description": "Optimizes `fmt.Errorf`.",
+ "type": "boolean",
+ "default": true
+ },
+ "string-format": {
+ "description": "Enable/disable optimization of string formatting.",
+ "type": "boolean",
+ "default": true
+ },
+ "sprintf1": {
+ "description": "Optimizes `fmt.Sprintf` with only one argument.",
+ "type": "boolean",
+ "default": true
+ },
+ "strconcat": {
+ "description": "Optimizes into strings concatenation.",
+ "type": "boolean",
+ "default": true
+ },
+ "bool-format": {
+ "description": "Enable/disable optimization of bool formatting.",
+ "type": "boolean",
+ "default": true
+ },
+ "hex-format": {
+ "description": "Enable/disable optimization of hex formatting.",
+ "type": "boolean",
+ "default": true
+ },
+ "concat-loop": {
+ "description": "Enable/disable optimization of concat loop.",
+ "type": "boolean",
+ "default": true
+ },
+ "loop-other-ops": {
+ "description": "Optimization of `concat-loop` even with other operations.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "preallocSettings": {
+ "description": "We do not recommend using this linter before doing performance profiling.\nFor most programs usage of `prealloc` will be premature optimization.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "simple": {
+ "description": "Report preallocation suggestions only on simple loops that have no returns/breaks/continues/gotos in them.",
+ "type": "boolean",
+ "default": true
+ },
+ "range-loops": {
+ "description": "Report preallocation suggestions on range loops.",
+ "type": "boolean",
+ "default": true
+ },
+ "for-loops": {
+ "description": "Report preallocation suggestions on for loops.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "predeclaredSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignore": {
+ "description": "List of predeclared identifiers to not report on.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "qualified-name": {
+ "description": "Include method names and field names in checks.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "promlinterSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "strict": {},
+ "disabled-linters": {
+ "type": "array",
+ "items": {
+ "enum": [
+ "Help",
+ "MetricUnits",
+ "Counter",
+ "HistogramSummaryReserved",
+ "MetricTypeInName",
+ "ReservedChars",
+ "CamelCase",
+ "UnitAbbreviations"
+ ]
+ }
+ }
+ }
+ },
+ "protogetterSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skip-generated-by": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["protoc-gen-go-my-own-generator"]
+ }
+ },
+ "skip-files": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["*.pb.go"]
+ }
+ },
+ "skip-any-generated": {
+ "description": "Skip any generated files from the checking.",
+ "type": "boolean",
+ "default": false
+ },
+ "replace-first-arg-in-append": {
+ "description": "Skip first argument of append function.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "reviveSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "examples": [
+ {
+ "ignore-generated-header": true,
+ "severity": "warning",
+ "rules": [
+ {
+ "name": "indent-error-flow",
+ "severity": "warning"
+ },
+ {
+ "name": "add-constant",
+ "severity": "warning",
+ "arguments": [
+ {
+ "maxLitCount": "3",
+ "allowStrs": "\"\"",
+ "allowInts": "0,1,2",
+ "allowFloats": "0.0,0.,1.0,1.,2.0,2."
+ }
+ ]
+ }
+ ]
+ }
+ ],
+ "properties": {
+ "max-open-files": {
+ "type": "integer"
+ },
+ "confidence": {
+ "type": "number"
+ },
+ "severity": {
+ "type": "string",
+ "enum": ["warning", "error"]
+ },
+ "enable-all-rules": {
+ "type": "boolean",
+ "default": false
+ },
+ "enable-default-rules": {
+ "type": "boolean",
+ "default": false
+ },
+ "directives": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "name": {
+ "type": "string",
+ "enum": ["specify-disable-reason"]
+ },
+ "severity": {
+ "type": "string",
+ "enum": ["warning", "error"]
+ },
+ "exclude": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "arguments": {
+ "type": "array"
+ }
+ }
+ }
+ },
+ "rules": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["name"],
+ "properties": {
+ "name": {
+ "$ref": "#/definitions/revive-rules",
+ "title": "The rule name"
+ },
+ "disabled": {
+ "type": "boolean"
+ },
+ "severity": {
+ "type": "string",
+ "enum": ["warning", "error"]
+ },
+ "exclude": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "arguments": {
+ "type": "array"
+ }
+ }
+ }
+ }
+ }
+ },
+ "rowserrcheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "packages": {
+ "type": "array",
+ "items": {
+ "description": "",
+ "type": "string",
+ "examples": ["github.com/jmoiron/sqlx"]
+ }
+ }
+ }
+ },
+ "sloglintSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "kv-only": {
+ "description": "Enforce using key-value pairs only (incompatible with attr-only).",
+ "type": "boolean",
+ "default": false
+ },
+ "no-global": {
+ "description": "Enforce not using global loggers.",
+ "enum": ["", "all", "default"],
+ "default": ""
+ },
+ "no-mixed-args": {
+ "description": "Enforce not mixing key-value pairs and attributes.",
+ "type": "boolean",
+ "default": true
+ },
+ "context": {
+ "description": "Enforce using methods that accept a context.",
+ "enum": ["", "all", "scope"],
+ "default": ""
+ },
+ "static-msg": {
+ "description": "Enforce using static values for log messages.",
+ "type": "boolean",
+ "default": false
+ },
+ "msg-style": {
+ "description": "Enforce message style.",
+ "enum": ["", "lowercased", "capitalized"],
+ "default": ""
+ },
+ "key-naming-case": {
+ "description": "Enforce a single key naming convention.",
+ "enum": ["snake", "kebab", "camel", "pascal"]
+ },
+ "attr-only": {
+ "description": "Enforce using attributes only (incompatible with kv-only).",
+ "type": "boolean",
+ "default": false
+ },
+ "no-raw-keys": {
+ "description": "Enforce using constants instead of raw keys.",
+ "type": "boolean",
+ "default": false
+ },
+ "forbidden-keys": {
+ "description": "Enforce not using specific keys.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "args-on-sep-lines": {
+ "description": "Enforce putting arguments on separate lines.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "spancheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "checks": {
+ "description": "Checks to enable.",
+ "type": "array",
+ "items": {
+ "enum": ["end", "record-error", "set-status"]
+ }
+ },
+ "ignore-check-signatures": {
+ "description": "A list of regexes for function signatures that silence `record-error` and `set-status` reports if found in the call path to a returned error.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "extra-start-span-signatures": {
+ "description": "A list of regexes for additional function signatures that create spans.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "staticcheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "checks": {
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "$ref": "#/definitions/staticcheck-checks"
+ },
+ {
+ "type": "string"
+ }
+ ]
+ }
+ },
+ "dot-import-whitelist": {
+ "description": "By default, ST1001 forbids all uses of dot imports in non-test packages. This setting allows setting a whitelist of import paths that can be dot-imported anywhere.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "http-status-code-whitelist": {
+ "description": "ST1013 recommends using constants from the net/http package instead of hard-coding numeric HTTP status codes. This setting specifies a list of numeric status codes that this check does not complain about.",
+ "default": ["200", "400", "404", "500"],
+ "type": "array",
+ "items": {
+ "enum": [
+ "100",
+ "101",
+ "102",
+ "103",
+ "200",
+ "201",
+ "202",
+ "203",
+ "204",
+ "205",
+ "206",
+ "207",
+ "208",
+ "226",
+ "300",
+ "301",
+ "302",
+ "303",
+ "304",
+ "305",
+ "306",
+ "307",
+ "308",
+ "400",
+ "401",
+ "402",
+ "403",
+ "404",
+ "405",
+ "406",
+ "407",
+ "408",
+ "409",
+ "410",
+ "411",
+ "412",
+ "413",
+ "414",
+ "415",
+ "416",
+ "417",
+ "418",
+ "421",
+ "422",
+ "423",
+ "424",
+ "425",
+ "426",
+ "428",
+ "429",
+ "431",
+ "451",
+ "500",
+ "501",
+ "502",
+ "503",
+ "504",
+ "505",
+ "506",
+ "507",
+ "508",
+ "510",
+ "511"
+ ]
+ }
+ },
+ "initialisms": {
+ "description": "ST1003 check, among other things, for the correct capitalization of initialisms. The set of known initialisms can be configured with this option.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "default": [
+ "ACL",
+ "API",
+ "ASCII",
+ "CPU",
+ "CSS",
+ "DNS",
+ "EOF",
+ "GUID",
+ "HTML",
+ "HTTP",
+ "HTTPS",
+ "ID",
+ "IP",
+ "JSON",
+ "QPS",
+ "RAM",
+ "RPC",
+ "SLA",
+ "SMTP",
+ "SQL",
+ "SSH",
+ "TCP",
+ "TLS",
+ "TTL",
+ "UDP",
+ "UI",
+ "GID",
+ "UID",
+ "UUID",
+ "URI",
+ "URL",
+ "UTF8",
+ "VM",
+ "XML",
+ "XMPP",
+ "XSRF",
+ "XSS",
+ "SIP",
+ "RTP",
+ "AMQP",
+ "DB",
+ "TS"
+ ]
+ }
+ }
+ }
+ },
+ "tagalignSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "align": {
+ "description": "Align and sort can be used together or separately.",
+ "type": "boolean",
+ "default": true
+ },
+ "sort": {
+ "description": "Whether enable tags sort.",
+ "type": "boolean",
+ "default": true
+ },
+ "order": {
+ "description": "Specify the order of tags, the other tags will be sorted by name.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "default": [],
+ "examples": [
+ [
+ "json",
+ "yaml",
+ "yml",
+ "toml",
+ "mapstructure",
+ "binding",
+ "validate"
+ ]
+ ]
+ },
+ "strict": {
+ "description": "Whether enable strict style.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "tagliatelleSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "case": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "use-field-name": {
+ "description": "Use the struct field name to check the name of the struct tag.",
+ "type": "boolean",
+ "default": false
+ },
+ "ignored-fields": {
+ "description": "The field names to ignore.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["example"]
+ }
+ },
+ "rules": {
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "$ref": "#/definitions/tagliatelle-cases"
+ }
+ }
+ },
+ "extended-rules": {
+ "description": "Defines the association between tag name and case.",
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["case"],
+ "properties": {
+ "case": {
+ "$ref": "#/definitions/tagliatelle-cases"
+ },
+ "extra-initialisms": {
+ "type": "boolean",
+ "default": false
+ },
+ "initialism-overrides": {
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "overrides": {
+ "description": "Overrides the default/root configuration.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["pkg"],
+ "properties": {
+ "pkg": {
+ "description": "A package path.",
+ "type": "string"
+ },
+ "use-field-name": {
+ "description": "Use the struct field name to check the name of the struct tag.",
+ "type": "boolean",
+ "default": false
+ },
+ "ignored-fields": {
+ "description": "The field names to ignore.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["example"]
+ }
+ },
+ "ignore": {
+ "description": "Ignore the package (takes precedence over all other configurations).",
+ "type": "boolean",
+ "default": false
+ },
+ "rules": {
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "$ref": "#/definitions/tagliatelle-cases"
+ }
+ }
+ },
+ "extended-rules": {
+ "description": "Defines the association between tag name and case.",
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["case"],
+ "properties": {
+ "case": {
+ "$ref": "#/definitions/tagliatelle-cases"
+ },
+ "extra-initialisms": {
+ "type": "boolean",
+ "default": false
+ },
+ "initialism-overrides": {
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "testifylintSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "enable-all": {
+ "description": "Enable all checkers.",
+ "type": "boolean",
+ "default": false
+ },
+ "disable-all": {
+ "description": "Disable all checkers.",
+ "type": "boolean",
+ "default": false
+ },
+ "enable": {
+ "description": "Enable specific checkers.",
+ "type": "array",
+ "items": {
+ "enum": [
+ "blank-import",
+ "bool-compare",
+ "compares",
+ "contains",
+ "empty",
+ "encoded-compare",
+ "equal-values",
+ "error-is-as",
+ "error-nil",
+ "expected-actual",
+ "float-compare",
+ "formatter",
+ "go-require",
+ "len",
+ "negative-positive",
+ "nil-compare",
+ "regexp",
+ "require-error",
+ "suite-broken-parallel",
+ "suite-dont-use-pkg",
+ "suite-extra-assert-call",
+ "suite-method-signature",
+ "suite-subtest-run",
+ "suite-thelper",
+ "useless-assert"
+ ]
+ },
+ "default": [
+ "blank-import",
+ "bool-compare",
+ "compares",
+ "contains",
+ "empty",
+ "encoded-compare",
+ "equal-values",
+ "error-is-as",
+ "error-nil",
+ "expected-actual",
+ "float-compare",
+ "formatter",
+ "go-require",
+ "len",
+ "negative-positive",
+ "nil-compare",
+ "regexp",
+ "require-error",
+ "suite-broken-parallel",
+ "suite-dont-use-pkg",
+ "suite-extra-assert-call",
+ "suite-method-signature",
+ "suite-subtest-run",
+ "useless-assert"
+ ]
+ },
+ "disable": {
+ "description": "Disable specific checkers.",
+ "type": "array",
+ "items": {
+ "enum": [
+ "blank-import",
+ "bool-compare",
+ "compares",
+ "contains",
+ "empty",
+ "encoded-compare",
+ "equal-values",
+ "error-is-as",
+ "error-nil",
+ "expected-actual",
+ "float-compare",
+ "formatter",
+ "go-require",
+ "len",
+ "negative-positive",
+ "nil-compare",
+ "regexp",
+ "require-error",
+ "suite-broken-parallel",
+ "suite-dont-use-pkg",
+ "suite-extra-assert-call",
+ "suite-method-signature",
+ "suite-subtest-run",
+ "suite-thelper",
+ "useless-assert"
+ ],
+ "default": [
+ "suite-thelper"
+ ]
+ }
+ },
+ "bool-compare": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignore-custom-types": {
+ "description": "To ignore user defined types (over builtin bool).",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "expected-actual": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "pattern": {
+ "description": "Regexp for expected variable name.",
+ "type": "string",
+ "default": "(^(exp(ected)?|want(ed)?)([A-Z]\\w*)?$)|(^(\\w*[a-z])?(Exp(ected)?|Want(ed)?)$)"
+ }
+ }
+ },
+ "formatter": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-format-string": {
+ "description": "To enable go vet's printf checks.",
+ "type": "boolean",
+ "default": true
+ },
+ "require-f-funcs": {
+ "description": "To require f-assertions (e.g. assert.Equalf) if format string is used, even if there are no variable-length variables.",
+ "type": "boolean",
+ "default": false
+ },
+ "require-string-msg": {
+ "description": "To require that the first element of msgAndArgs (msg) has a string type.",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "go-require": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignore-http-handlers": {
+ "description": "To ignore HTTP handlers (like http.HandlerFunc).",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "require-error": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "fn-pattern": {
+ "description": "Regexp for assertions to analyze. If defined, then only matched error assertions will be reported.",
+ "type": "string",
+ "default": ""
+ }
+ }
+ },
+ "suite-extra-assert-call": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "mode": {
+ "description": "To require or remove extra Assert() call?",
+ "type": "string",
+ "enum": ["remove", "require"],
+ "default": "remove"
+ }
+ }
+ }
+ }
+ },
+ "testpackageSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skip-regexp": {
+ "description": "Files with names matching this regular expression are skipped.",
+ "type": "string",
+ "examples": ["(export|internal)_test\\.go"]
+ },
+ "allow-packages": {
+ "description": "List of packages that don't end with _test that tests are allowed to be in.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["example"]
+ }
+ }
+ }
+ },
+ "thelperSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "test": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "begin": {
+ "description": "Check if `t.Helper()` begins helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "first": {
+ "description": "Check if *testing.T is first param of helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "name": {
+ "description": "Check if *testing.T param has t name.",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ },
+ "benchmark": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "begin": {
+ "description": "Check if `b.Helper()` begins helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "first": {
+ "description": "Check if *testing.B is first param of helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "name": {
+ "description": "Check if *testing.B param has b name.",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ },
+ "tb": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "begin": {
+ "description": "Check if `tb.Helper()` begins helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "first": {
+ "description": "Check if *testing.TB is first param of helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "name": {
+ "description": "Check if *testing.TB param has tb name.",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ },
+ "fuzz": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "begin": {
+ "description": "Check if `f.Helper()` begins helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "first": {
+ "description": "Check if *testing.F is first param of helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "name": {
+ "description": "Check if *testing.F param has f name.",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ }
+ }
+ },
+ "usestdlibvarsSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "http-method": {
+ "description": "Suggest the use of http.MethodXX.",
+ "type": "boolean",
+ "default": true
+ },
+ "http-status-code": {
+ "description": "Suggest the use of http.StatusXX.",
+ "type": "boolean",
+ "default": true
+ },
+ "time-weekday": {
+ "description": "Suggest the use of time.Weekday.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "time-month": {
+ "description": "Suggest the use of time.Month.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "time-layout": {
+ "description": "Suggest the use of time.Layout.",
+ "type": "boolean",
+ "default": false
+ },
+ "time-date-month": {
+ "description": "Suggest the use of time.Month in time.Date.",
+ "type": "boolean",
+ "default": false
+ },
+ "crypto-hash": {
+ "description": "Suggest the use of crypto.Hash.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "default-rpc-path": {
+ "description": "Suggest the use of rpc.DefaultXXPath.",
+ "type": "boolean",
+ "default": false
+ },
+ "sql-isolation-level": {
+ "description": "Suggest the use of sql.LevelXX.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "tls-signature-scheme": {
+ "description": "Suggest the use of tls.SignatureScheme.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "constant-kind": {
+ "description": "Suggest the use of constant.Kind.String().",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "usetestingSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "context-background": {
+ "type": "boolean",
+ "default": false
+ },
+ "context-todo": {
+ "type": "boolean",
+ "default": false
+ },
+ "os-chdir": {
+ "type": "boolean",
+ "default": true
+ },
+ "os-mkdir-temp": {
+ "type": "boolean",
+ "default": true
+ },
+ "os-setenv": {
+ "type": "boolean",
+ "default": true
+ },
+ "os-create-temp": {
+ "type": "boolean",
+ "default": true
+ },
+ "os-temp-dir": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "unconvertSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "fast-math": {
+ "type": "boolean",
+ "default": false
+ },
+ "safe": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "unparamSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-exported": {
+ "description": "Inspect exported functions. Set to true if no external program/library imports your code.\n\nWARNING: if you enable this setting, unparam will report a lot of false-positives in text editors:\nif it's called for subdir of a project it can't find external interfaces. All text editor integrations\nwith golangci-lint call it on a directory with the changed file.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "unqueryvetSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-sql-builders": {
+ "description": "Enable SQL builder checking.",
+ "type": "boolean",
+ "default": true
+ },
+ "check-aliased-wildcard": {
+ "description": "Enable aliased wildcard detection like SELECT t.*.",
+ "type": "boolean",
+ "default": true
+ },
+ "check-string-concat": {
+ "description": "Enable string concatenation analysis.",
+ "type": "boolean",
+ "default": true
+ },
+ "check-format-strings": {
+ "description": "Enable format string analysis like fmt.Sprintf.",
+ "type": "boolean",
+ "default": true
+ },
+ "check-string-builder": {
+ "description": "Enable strings.Builder analysis.",
+ "type": "boolean",
+ "default": true
+ },
+ "check-subqueries": {
+ "description": "Enable subquery analysis.",
+ "type": "boolean",
+ "default": true
+ },
+ "allowed-patterns": {
+ "description": "Regex patterns for acceptable SELECT * usage.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignored-functions": {
+ "description": "Functions to ignore.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "sql-builders": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "squirrel": {
+ "type": "boolean",
+ "default": true
+ },
+ "gorm": {
+ "type": "boolean",
+ "default": true
+ },
+ "sqlx": {
+ "type": "boolean",
+ "default": true
+ },
+ "ent": {
+ "type": "boolean",
+ "default": true
+ },
+ "pgx": {
+ "type": "boolean",
+ "default": true
+ },
+ "bun": {
+ "type": "boolean",
+ "default": true
+ },
+ "sqlboiler": {
+ "type": "boolean",
+ "default": true
+ },
+ "jet": {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ }
+ }
+ },
+ "unusedSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "field-writes-are-uses": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ },
+ "post-statements-are-reads": {
+ "description": "",
+ "type": "boolean",
+ "default": false
+ },
+ "exported-fields-are-used": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ },
+ "parameters-are-used": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ },
+ "local-variables-are-used": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ },
+ "generated-is-used": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "varnamelenSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-distance": {
+ "description": "Variables used in at most this N-many lines will be ignored.",
+ "type": "integer",
+ "default": 5
+ },
+ "min-name-length": {
+ "description": "The minimum length of a variable's name that is considered `long`.",
+ "type": "integer",
+ "default": 3
+ },
+ "check-receiver": {
+ "description": "Check method receiver names.",
+ "default": false,
+ "type": "boolean"
+ },
+ "check-return": {
+ "description": "Check named return values.",
+ "default": false,
+ "type": "boolean"
+ },
+ "check-type-param": {
+ "description": "Check type parameters.",
+ "default": false,
+ "type": "boolean"
+ },
+ "ignore-type-assert-ok": {
+ "description": "Ignore `ok` variables that hold the bool return value of a type assertion",
+ "default": false,
+ "type": "boolean"
+ },
+ "ignore-map-index-ok": {
+ "description": "Ignore `ok` variables that hold the bool return value of a map index.",
+ "default": false,
+ "type": "boolean"
+ },
+ "ignore-chan-recv-ok": {
+ "description": "Ignore `ok` variables that hold the bool return value of a channel receive.",
+ "default": false,
+ "type": "boolean"
+ },
+ "ignore-names": {
+ "description": "Optional list of variable names that should be ignored completely.",
+ "default": [[]],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignore-decls": {
+ "description": "Optional list of variable declarations that should be ignored completely.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "examples": [
+ ["c echo.Context", "t testing.T", "f *foo.Bar", "const C"]
+ ]
+ }
+ }
+ },
+ "whitespaceSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "multi-if": {
+ "description": "Enforces newlines (or comments) after every multi-line if statement",
+ "type": "boolean",
+ "default": false
+ },
+ "multi-func": {
+ "description": "Enforces newlines (or comments) after every multi-line function signature",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "wrapcheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "extra-ignore-sigs": {
+ "description": "An array of strings specifying additional substrings of signatures to ignore.",
+ "default": [
+ ".CustomError(",
+ ".SpecificWrap("
+ ],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignore-sigs": {
+ "description": "An array of strings which specify substrings of signatures to ignore.",
+ "default": [
+ ".Errorf(",
+ "errors.New(",
+ "errors.Unwrap(",
+ ".Wrap(",
+ ".Wrapf(",
+ ".WithMessage(",
+ ".WithMessagef(",
+ ".WithStack("
+ ],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignore-sig-regexps": {
+ "description": "An array of strings which specify regular expressions of signatures to ignore.",
+ "default": [""],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignore-package-globs": {
+ "description": "An array of glob patterns which, if any match the package of the function returning the error, will skip wrapcheck analysis for this error.",
+ "default": [""],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignore-interface-regexps": {
+ "description": "An array of glob patterns which, if matched to an underlying interface name, will ignore unwrapped errors returned from a function whose call is defined on the given interface.",
+ "default": [""],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "report-internal-errors": {
+ "description": "Determines whether wrapcheck should report errors returned from inside the package.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "wslSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "allow-assign-and-anything": {
+ "description": "Controls if you may cuddle assignments and anything without needing an empty line between them.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-assign-and-call": {
+ "description": "Allow calls and assignments to be cuddled as long as the lines have any matching variables, fields or types.",
+ "type": "boolean",
+ "default": true
+ },
+ "allow-cuddle-declarations": {
+ "description": "Allow declarations (var) to be cuddled.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-cuddle-with-calls": {
+ "description": "A list of call idents that everything can be cuddled with.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "allow-cuddle-with-rhs": {
+ "description": "AllowCuddleWithRHS is a list of right hand side variables that is allowed to be cuddled with anything.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "allow-cuddle-used-in-block": {
+ "description": "Allow cuddling with any block as long as the variable is used somewhere in the block",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-multiline-assign": {
+ "description": "Allow multiline assignments to be cuddled.",
+ "type": "boolean",
+ "default": true
+ },
+ "allow-separated-leading-comment": {
+ "description": "Allow leading comments to be separated with empty lines.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-trailing-comment": {
+ "description": "Allow trailing comments in ending of blocks.",
+ "type": "boolean",
+ "default": false
+ },
+ "error-variable-names": {
+ "description": "When force-err-cuddling is enabled this is a list of names used for error variables to check for in the conditional.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "force-case-trailing-whitespace": {
+ "description": "Force newlines in end of case at this limit (0 = never).",
+ "type": "integer",
+ "minimum": 0,
+ "default": 0
+ },
+ "force-err-cuddling": {
+ "description": "Causes an error when an If statement that checks an error variable doesn't cuddle with the assignment of that variable.",
+ "type": "boolean",
+ "default": false
+ },
+ "force-short-decl-cuddling": {
+ "description": "Causes an error if a short declaration (:=) cuddles with anything other than another short declaration.",
+ "type": "boolean",
+ "default": false
+ },
+ "strict-append": {
+ "description": "If true, append is only allowed to be cuddled if appending value is matching variables, fields or types on line above.",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "wslSettingsV5": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "allow-first-in-block": {
+ "type": "boolean",
+ "default": true
+ },
+ "allow-whole-block": {
+ "type": "boolean",
+ "default": false
+ },
+ "branch-max-lines": {
+ "type": "integer",
+ "default": 2
+ },
+ "case-max-lines": {
+ "type": "integer",
+ "default": 0
+ },
+ "default": {
+ "enum": ["all", "none", "default", ""],
+ "default": "default"
+ },
+ "enable": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/wsl-checks"
+ }
+ },
+ "disable": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/wsl-checks"
+ }
+ }
+ }
+ },
+ "copyloopvarSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-alias": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "customSettings": {
+ "description": "The custom section can be used to define linter plugins to be loaded at runtime. See README of golangci-lint for more information.\nEach custom linter should have a unique name.",
+ "type": "object",
+ "patternProperties": {
+ "^.*$": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "type": {
+ "description": "The plugin type.",
+ "enum": ["module", "goplugin"],
+ "default": "goplugin"
+ },
+ "path": {
+ "description": "The path to the plugin *.so. Can be absolute or local.",
+ "type": "string",
+ "examples": ["/path/to/example.so"]
+ },
+ "description": {
+ "description": "The description of the linter, for documentation purposes only.",
+ "type": "string"
+ },
+ "original-url": {
+ "description": "Intended to point to the repo location of the linter, for documentation purposes only.",
+ "type": "string"
+ },
+ "settings": {
+ "description": "Plugins settings/configuration. Only work with plugin based on `linterdb.PluginConstructor`.",
+ "type": "object"
+ }
+ },
+ "oneOf": [
+ {
+ "properties": {
+ "type": {"enum": ["module"] }
+ },
+ "required": ["type"]
+ },
+ {
+ "required": ["path"]
+ }
+ ]
+ }
+ }
+ }
+ }
+ }
+ },
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["version"],
+ "properties": {
+ "version": {
+ "type": "string",
+ "default": "2"
+ },
+ "run": {
+ "description": "Options for analysis running,",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "concurrency": {
+ "description": "Number of concurrent runners. Defaults to the number of available CPU cores.",
+ "type": "integer",
+ "minimum": 0,
+ "examples": [4]
+ },
+ "timeout": {
+ "description": "Timeout for the analysis.",
+ "type": "string",
+ "pattern": "^((\\d+h)?(\\d+m)?(\\d+(?:\\.\\d)?s)?|0)$",
+ "default": "1m",
+ "examples": ["30s", "5m", "5m30s"]
+ },
+ "issues-exit-code": {
+ "description": "Exit code when at least one issue was found.",
+ "type": "integer",
+ "default": 1
+ },
+ "tests": {
+ "description": "Enable inclusion of test files.",
+ "type": "boolean",
+ "default": true
+ },
+ "build-tags": {
+ "description": "List of build tags to pass to all linters.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "default": [],
+ "examples": [["mytag"]]
+ },
+ "modules-download-mode": {
+ "description": "Option to pass to \"go list -mod={option}\".\nSee \"go help modules\" for more information.",
+ "enum": ["mod", "readonly", "vendor"]
+ },
+ "allow-parallel-runners": {
+ "description": "Allow multiple parallel golangci-lint instances running. If disabled, golangci-lint acquires file lock on start.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-serial-runners": {
+ "description": "Allow multiple golangci-lint instances running, but serialize them around a lock.",
+ "type": "boolean",
+ "default": false
+ },
+ "go": {
+ "description": "Targeted Go version.",
+ "type": "string",
+ "default": "1.17"
+ },
+ "relative-path-mode": {
+ "description": "The mode used to evaluate relative paths.",
+ "type": "string",
+ "$ref": "#/definitions/relative-path-modes",
+ "default": "wd"
+ }
+ }
+ },
+ "output": {
+ "description": "Output configuration options.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "formats": {
+ "description": "Output formats to use.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "text": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "path": {
+ "$ref": "#/definitions/formats-path",
+ "default": "stdout"
+ },
+ "print-linter-name": {
+ "type": "boolean",
+ "default": true
+ },
+ "print-issued-lines": {
+ "type": "boolean",
+ "default": true
+ },
+ "colors": {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "json": {
+ "$ref": "#/definitions/simple-format"
+ },
+ "tab": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "path": {
+ "$ref": "#/definitions/formats-path",
+ "default": "stdout"
+ },
+ "print-linter-name": {
+ "type": "boolean",
+ "default": true
+ },
+ "colors": {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "html": {
+ "$ref": "#/definitions/simple-format"
+ },
+ "checkstyle": {
+ "$ref": "#/definitions/simple-format"
+ },
+ "code-climate": {
+ "$ref": "#/definitions/simple-format"
+ },
+ "junit-xml": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "path": {
+ "$ref": "#/definitions/formats-path",
+ "default": "stdout"
+ },
+ "extended": {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "teamcity": {
+ "$ref": "#/definitions/simple-format"
+ },
+ "sarif": {
+ "$ref": "#/definitions/simple-format"
+ }
+ }
+ },
+ "path-mode": {
+ "type": "string",
+ "default": "",
+ "examples": ["abs"]
+ },
+ "path-prefix": {
+ "description": "Add a prefix to the output file references.",
+ "type": "string",
+ "default": ""
+ },
+ "show-stats": {
+ "description": "Show statistics per linter.",
+ "type": "boolean",
+ "default": true
+ },
+ "sort-order": {
+ "type": "array",
+ "items": {
+ "enum": ["linter", "severity", "file"]
+ }
+ }
+ }
+ },
+ "linters": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "default": {
+ "enum": [
+ "standard",
+ "all",
+ "none",
+ "fast"
+ ]
+ },
+ "enable": {
+ "description": "List of enabled linters.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linter-names"
+ }
+ },
+ "disable": {
+ "description": "List of disabled linters.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linter-names"
+ }
+ },
+ "settings": {
+ "description": "All available settings of specific linters.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "dupword": {
+ "$ref": "#/definitions/settings/definitions/dupwordSettings"
+ },
+ "asasalint": {
+ "$ref": "#/definitions/settings/definitions/asasalintSettings"
+ },
+ "bidichk": {
+ "$ref": "#/definitions/settings/definitions/bidichkSettings"
+ },
+ "cyclop": {
+ "$ref": "#/definitions/settings/definitions/cyclopSettings"
+ },
+ "decorder": {
+ "$ref": "#/definitions/settings/definitions/decorderSettings"
+ },
+ "depguard":{
+ "$ref": "#/definitions/settings/definitions/depguardSettings"
+ },
+ "dogsled": {
+ "$ref": "#/definitions/settings/definitions/dogsledSettings"
+ },
+ "dupl": {
+ "$ref": "#/definitions/settings/definitions/duplSettings"
+ },
+ "embeddedstructfieldcheck": {
+ "$ref": "#/definitions/settings/definitions/embeddedstructfieldcheckSettings"
+ },
+ "errcheck": {
+ "$ref": "#/definitions/settings/definitions/errcheckSettings"
+ },
+ "errchkjson": {
+ "$ref": "#/definitions/settings/definitions/errchkjsonSettings"
+ },
+ "errorlint": {
+ "$ref": "#/definitions/settings/definitions/errorlintSettings"
+ },
+ "exhaustive": {
+ "$ref": "#/definitions/settings/definitions/exhaustiveSettings"
+ },
+ "exhaustruct": {
+ "$ref": "#/definitions/settings/definitions/exhaustructSettings"
+ },
+ "fatcontext": {
+ "$ref": "#/definitions/settings/definitions/fatcontextSettings"
+ },
+ "forbidigo": {
+ "$ref": "#/definitions/settings/definitions/forbidigoSettings"
+ },
+ "funcorder": {
+ "$ref": "#/definitions/settings/definitions/funcorderSettings"
+ },
+ "funlen": {
+ "$ref": "#/definitions/settings/definitions/funlenSettings"
+ },
+ "ginkgolinter": {
+ "$ref": "#/definitions/settings/definitions/ginkgolinterSettings"
+ },
+ "gochecksumtype": {
+ "$ref": "#/definitions/settings/definitions/gochecksumtypeSettings"
+ },
+ "gocognit": {
+ "$ref": "#/definitions/settings/definitions/gocognitSettings"
+ },
+ "goconst": {
+ "$ref": "#/definitions/settings/definitions/goconstSettings"
+ },
+ "gocritic": {
+ "$ref": "#/definitions/settings/definitions/gocriticSettings"
+ },
+ "gocyclo": {
+ "$ref": "#/definitions/settings/definitions/gocycloSettings"
+ },
+ "godoclint": {
+ "$ref": "#/definitions/settings/definitions/godoclintSettings"
+ },
+ "godot": {
+ "$ref": "#/definitions/settings/definitions/godotSettings"
+ },
+ "godox": {
+ "$ref": "#/definitions/settings/definitions/godoxSettings"
+ },
+ "interfacebloat":{
+ "$ref": "#/definitions/settings/definitions/interfacebloatSettings"
+ },
+ "goheader": {
+ "$ref": "#/definitions/settings/definitions/goheaderSettings"
+ },
+ "gomoddirectives": {
+ "$ref": "#/definitions/settings/definitions/gomoddirectivesSettings"
+ },
+ "gomodguard": {
+ "$ref": "#/definitions/settings/definitions/gomodguardSettings"
+ },
+ "gosec": {
+ "$ref": "#/definitions/settings/definitions/gosecSettings"
+ },
+ "gosmopolitan": {
+ "$ref": "#/definitions/settings/definitions/gosmopolitanSettings"
+ },
+ "govet": {
+ "$ref": "#/definitions/settings/definitions/govetSettings"
+ },
+ "grouper": {
+ "$ref": "#/definitions/settings/definitions/grouperSettings"
+ },
+ "iface": {
+ "$ref": "#/definitions/settings/definitions/ifaceSettings"
+ },
+ "importas": {
+ "$ref": "#/definitions/settings/definitions/importasSettings"
+ },
+ "inamedparam": {
+ "$ref": "#/definitions/settings/definitions/inamedparamSettings"
+ },
+ "ineffassign": {
+ "$ref": "#/definitions/settings/definitions/ineffassignSettings"
+ },
+ "iotamixing": {
+ "$ref": "#/definitions/settings/definitions/iotamixingSettings"
+ },
+ "ireturn": {
+ "$ref": "#/definitions/settings/definitions/ireturnSettings"
+ },
+ "lll": {
+ "$ref": "#/definitions/settings/definitions/lllSettings"
+ },
+ "maintidx": {
+ "$ref": "#/definitions/settings/definitions/maintidxSettings"
+ },
+ "makezero":{
+ "$ref": "#/definitions/settings/definitions/makezeroSettings"
+ },
+ "loggercheck": {
+ "$ref": "#/definitions/settings/definitions/loggercheckSettings"
+ },
+ "misspell": {
+ "$ref": "#/definitions/settings/definitions/misspellSettings"
+ },
+ "musttag": {
+ "$ref": "#/definitions/settings/definitions/musttagSettings"
+ },
+ "nakedret": {
+ "$ref": "#/definitions/settings/definitions/nakedretSettings"
+ },
+ "nestif": {
+ "$ref": "#/definitions/settings/definitions/nestifSettings"
+ },
+ "nilnil": {
+ "$ref": "#/definitions/settings/definitions/nilnilSettings"
+ },
+ "nlreturn": {
+ "$ref": "#/definitions/settings/definitions/nlreturnSettings"
+ },
+ "mnd": {
+ "$ref": "#/definitions/settings/definitions/mndSettings"
+ },
+ "modernize": {
+ "$ref": "#/definitions/settings/definitions/modernizeSettings"
+ },
+ "nolintlint":{
+ "$ref": "#/definitions/settings/definitions/nolintlintSettings"
+ },
+ "reassign": {
+ "$ref": "#/definitions/settings/definitions/reassignSettings"
+ },
+ "recvcheck": {
+ "$ref": "#/definitions/settings/definitions/recvcheckSettings"
+ },
+ "nonamedreturns": {
+ "$ref": "#/definitions/settings/definitions/nonamedreturnsSettings"
+ },
+ "paralleltest": {
+ "$ref": "#/definitions/settings/definitions/paralleltestSettings"
+ },
+ "perfsprint": {
+ "$ref": "#/definitions/settings/definitions/perfsprintSettings"
+ },
+ "prealloc": {
+ "$ref": "#/definitions/settings/definitions/preallocSettings"
+ },
+ "predeclared": {
+ "$ref": "#/definitions/settings/definitions/predeclaredSettings"
+ },
+ "promlinter": {
+ "$ref": "#/definitions/settings/definitions/promlinterSettings"
+ },
+ "protogetter": {
+ "$ref": "#/definitions/settings/definitions/protogetterSettings"
+ },
+ "revive": {
+ "$ref": "#/definitions/settings/definitions/reviveSettings"
+ },
+ "rowserrcheck": {
+ "$ref": "#/definitions/settings/definitions/rowserrcheckSettings"
+ },
+ "sloglint": {
+ "$ref": "#/definitions/settings/definitions/sloglintSettings"
+ },
+ "spancheck": {
+ "$ref": "#/definitions/settings/definitions/spancheckSettings"
+ },
+ "staticcheck":{
+ "$ref": "#/definitions/settings/definitions/staticcheckSettings"
+ },
+ "tagalign": {
+ "$ref": "#/definitions/settings/definitions/tagalignSettings"
+ },
+ "tagliatelle": {
+ "$ref": "#/definitions/settings/definitions/tagliatelleSettings"
+ },
+ "testifylint": {
+ "$ref": "#/definitions/settings/definitions/testifylintSettings"
+ },
+ "testpackage": {
+ "$ref": "#/definitions/settings/definitions/testpackageSettings"
+ },
+ "thelper": {
+ "$ref": "#/definitions/settings/definitions/thelperSettings"
+ },
+ "usestdlibvars": {
+ "$ref": "#/definitions/settings/definitions/usestdlibvarsSettings"
+ },
+ "usetesting": {
+ "$ref": "#/definitions/settings/definitions/usetestingSettings"
+ },
+ "unconvert": {
+ "$ref": "#/definitions/settings/definitions/unconvertSettings"
+ },
+ "unparam": {
+ "$ref": "#/definitions/settings/definitions/unparamSettings"
+ },
+ "unqueryvet": {
+ "$ref": "#/definitions/settings/definitions/unqueryvetSettings"
+ },
+ "unused": {
+ "$ref": "#/definitions/settings/definitions/unusedSettings"
+ },
+ "varnamelen": {
+ "$ref": "#/definitions/settings/definitions/varnamelenSettings"
+ },
+ "whitespace": {
+ "$ref": "#/definitions/settings/definitions/whitespaceSettings"
+ },
+ "wrapcheck": {
+ "$ref": "#/definitions/settings/definitions/wrapcheckSettings"
+ },
+ "wsl": {
+ "$ref": "#/definitions/settings/definitions/wslSettings"
+ },
+ "wsl_v5": {
+ "$ref": "#/definitions/settings/definitions/wslSettingsV5"
+ },
+ "copyloopvar": {
+ "$ref": "#/definitions/settings/definitions/copyloopvarSettings"
+ },
+ "custom":{
+ "$ref": "#/definitions/settings/definitions/customSettings"
+ }
+ }
+ },
+ "exclusions":{
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "generated": {
+ "enum": ["strict", "lax", "disable"],
+ "default": "strict"
+ },
+ "warn-unused": {
+ "type": "boolean",
+ "default": false
+ },
+ "presets": {
+ "type": "array",
+ "items": {
+ "enum": [
+ "comments",
+ "std-error-handling",
+ "common-false-positives",
+ "legacy"
+ ]
+ }
+ },
+ "rules": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "path": {
+ "type": "string"
+ },
+ "path-except": {
+ "type": "string"
+ },
+ "linters": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linter-names"
+ }
+ },
+ "text": {
+ "type": "string"
+ },
+ "source": {
+ "type": "string"
+ }
+ },
+ "anyOf": [
+ { "required": ["path"] },
+ { "required": ["path-except"] },
+ { "required": ["linters"] },
+ { "required": ["text"] },
+ { "required": ["source"] }
+ ]
+ }
+ },
+ "paths": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "paths-except": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "formatters": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "enable": {
+ "description": "List of enabled formatters.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/formatter-names"
+ }
+ },
+ "settings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "gci": {
+ "$ref": "#/definitions/settings/definitions/gciSettings"
+ },
+ "gofmt": {
+ "$ref": "#/definitions/settings/definitions/gofmtSettings"
+ },
+ "gofumpt": {
+ "$ref": "#/definitions/settings/definitions/gofumptSettings"
+ },
+ "goimports": {
+ "$ref": "#/definitions/settings/definitions/goimportsSettings"
+ },
+ "golines": {
+ "$ref": "#/definitions/settings/definitions/golinesSettings"
+ }
+ }
+ },
+ "exclusions": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "generated": {
+ "enum": ["strict", "lax", "disable"],
+ "default": "strict"
+ },
+ "paths": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "warn-unused": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ }
+ }
+ },
+ "issues": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-issues-per-linter": {
+ "description": "Maximum issues count per one linter. Set to 0 to disable.",
+ "type": "integer",
+ "default": 50,
+ "minimum": 0
+ },
+ "max-same-issues": {
+ "description": "Maximum count of issues with the same text. Set to 0 to disable.",
+ "type": "integer",
+ "default": 3,
+ "minimum": 0
+ },
+ "new": {
+ "description": "Show only new issues: if there are unstaged changes or untracked files, only those changes are analyzed, else only changes in HEAD~ are analyzed.",
+ "type": "boolean",
+ "default": false
+ },
+ "new-from-merge-base": {
+ "description": "Show only new issues created after the best common ancestor (merge-base against HEAD).",
+ "type": "string"
+ },
+ "new-from-rev": {
+ "description": "Show only new issues created after this git revision.",
+ "type": "string"
+ },
+ "new-from-patch": {
+ "description": "Show only new issues created in git patch with this file path.",
+ "type": "string",
+ "examples": ["path/to/patch/file"]
+ },
+ "fix": {
+ "description": "Apply the fixes detected by the linters and formatters (if it's supported by the linter).",
+ "type": "boolean",
+ "default": false
+ },
+ "uniq-by-line": {
+ "description": "Make issues output unique by line.",
+ "type": "boolean",
+ "default": true
+ },
+ "whole-files": {
+ "description": "Show issues in any part of update files (requires new-from-rev or new-from-patch).",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "severity": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "default": {
+ "description": "Set the default severity for issues. If severity rules are defined and the issues do not match or no severity is provided to the rule this will be the default severity applied. Severities should match the supported severity names of the selected out format.",
+ "type": "string",
+ "default": ""
+ },
+ "rules": {
+ "description": "When a list of severity rules are provided, severity information will be added to lint issues. Severity rules have the same filtering capability as exclude rules except you are allowed to specify one matcher per severity rule.\nOnly affects out formats that support setting severity information.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "severity": {
+ "type": "string"
+ },
+ "path": {
+ "type": "string"
+ },
+ "path-except": {
+ "type": "string"
+ },
+ "linters": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linter-names"
+ }
+ },
+ "text": {
+ "type": "string"
+ },
+ "source": {
+ "type": "string"
+ }
+ },
+ "required": ["severity"],
+ "anyOf": [
+ { "required": ["path"] },
+ { "required": ["path-except"] },
+ { "required": ["linters"] },
+ { "required": ["text"] },
+ { "required": ["source"] }
+ ]
+ },
+ "default": []
+ }
+ },
+ "required": ["default"]
+ }
+ }
+}
diff --git a/vendor/github.com/golangci/golangci-lint/v2/jsonschema/golangci.v2.9.jsonschema.json b/vendor/github.com/golangci/golangci-lint/v2/jsonschema/golangci.v2.9.jsonschema.json
new file mode 100644
index 000000000..38b3590c6
--- /dev/null
+++ b/vendor/github.com/golangci/golangci-lint/v2/jsonschema/golangci.v2.9.jsonschema.json
@@ -0,0 +1,5278 @@
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "$id": "https://json.schemastore.org/golangci-lint.json",
+ "definitions": {
+ "gocritic-checks": {
+ "enum": [
+ "appendAssign",
+ "appendCombine",
+ "argOrder",
+ "assignOp",
+ "badCall",
+ "badCond",
+ "badLock",
+ "badRegexp",
+ "badSorting",
+ "badSyncOnceFunc",
+ "boolExprSimplify",
+ "builtinShadow",
+ "builtinShadowDecl",
+ "captLocal",
+ "caseOrder",
+ "codegenComment",
+ "commentFormatting",
+ "commentedOutCode",
+ "commentedOutImport",
+ "defaultCaseOrder",
+ "deferInLoop",
+ "deferUnlambda",
+ "deprecatedComment",
+ "docStub",
+ "dupArg",
+ "dupBranchBody",
+ "dupCase",
+ "dupImport",
+ "dupOption",
+ "dupSubExpr",
+ "dynamicFmtString",
+ "elseif",
+ "emptyDecl",
+ "emptyFallthrough",
+ "emptyStringTest",
+ "equalFold",
+ "evalOrder",
+ "exitAfterDefer",
+ "exposedSyncMutex",
+ "externalErrorReassign",
+ "filepathJoin",
+ "flagDeref",
+ "flagName",
+ "hexLiteral",
+ "httpNoBody",
+ "hugeParam",
+ "ifElseChain",
+ "importShadow",
+ "indexAlloc",
+ "initClause",
+ "mapKey",
+ "methodExprCall",
+ "nestingReduce",
+ "newDeref",
+ "nilValReturn",
+ "octalLiteral",
+ "offBy1",
+ "paramTypeCombine",
+ "preferDecodeRune",
+ "preferFilepathJoin",
+ "preferFprint",
+ "preferStringWriter",
+ "preferWriteByte",
+ "ptrToRefParam",
+ "rangeAppendAll",
+ "rangeExprCopy",
+ "rangeValCopy",
+ "redundantSprint",
+ "regexpMust",
+ "regexpPattern",
+ "regexpSimplify",
+ "returnAfterHttpError",
+ "ruleguard",
+ "singleCaseSwitch",
+ "sliceClear",
+ "sloppyLen",
+ "sloppyReassign",
+ "sloppyTypeAssert",
+ "sortSlice",
+ "sprintfQuotedString",
+ "sqlQuery",
+ "stringConcatSimplify",
+ "stringXbytes",
+ "stringsCompare",
+ "switchTrue",
+ "syncMapLoadAndDelete",
+ "timeExprSimplify",
+ "todoCommentWithoutDetail",
+ "tooManyResultsChecker",
+ "truncateCmp",
+ "typeAssertChain",
+ "typeDefFirst",
+ "typeSwitchVar",
+ "typeUnparen",
+ "uncheckedInlineErr",
+ "underef",
+ "unlabelStmt",
+ "unlambda",
+ "unnamedResult",
+ "unnecessaryBlock",
+ "unnecessaryDefer",
+ "unslice",
+ "valSwap",
+ "weakCond",
+ "whyNoLint",
+ "wrapperFunc",
+ "yodaStyleExpr",
+ "zeroByteRepeat"
+ ]
+ },
+ "gocritic-tags": {
+ "enum": [
+ "diagnostic",
+ "style",
+ "performance",
+ "experimental",
+ "opinionated",
+ "security"
+ ]
+ },
+ "staticcheck-checks": {
+ "enum": [
+ "*",
+ "all",
+ "SA*",
+ "-SA*",
+ "SA1*",
+ "-SA1*",
+ "SA1000",
+ "-SA1000",
+ "SA1001",
+ "-SA1001",
+ "SA1002",
+ "-SA1002",
+ "SA1003",
+ "-SA1003",
+ "SA1004",
+ "-SA1004",
+ "SA1005",
+ "-SA1005",
+ "SA1006",
+ "-SA1006",
+ "SA1007",
+ "-SA1007",
+ "SA1008",
+ "-SA1008",
+ "SA1010",
+ "-SA1010",
+ "SA1011",
+ "-SA1011",
+ "SA1012",
+ "-SA1012",
+ "SA1013",
+ "-SA1013",
+ "SA1014",
+ "-SA1014",
+ "SA1015",
+ "-SA1015",
+ "SA1016",
+ "-SA1016",
+ "SA1017",
+ "-SA1017",
+ "SA1018",
+ "-SA1018",
+ "SA1019",
+ "-SA1019",
+ "SA1020",
+ "-SA1020",
+ "SA1021",
+ "-SA1021",
+ "SA1023",
+ "-SA1023",
+ "SA1024",
+ "-SA1024",
+ "SA1025",
+ "-SA1025",
+ "SA1026",
+ "-SA1026",
+ "SA1027",
+ "-SA1027",
+ "SA1028",
+ "-SA1028",
+ "SA1029",
+ "-SA1029",
+ "SA1030",
+ "-SA1030",
+ "SA1031",
+ "-SA1031",
+ "SA1032",
+ "-SA1032",
+ "SA2*",
+ "-SA2*",
+ "SA2000",
+ "-SA2000",
+ "SA2001",
+ "-SA2001",
+ "SA2002",
+ "-SA2002",
+ "SA2003",
+ "-SA2003",
+ "SA3*",
+ "-SA3*",
+ "SA3000",
+ "-SA3000",
+ "SA3001",
+ "-SA3001",
+ "SA4*",
+ "-SA4*",
+ "SA4000",
+ "-SA4000",
+ "SA4001",
+ "-SA4001",
+ "SA4003",
+ "-SA4003",
+ "SA4004",
+ "-SA4004",
+ "SA4005",
+ "-SA4005",
+ "SA4006",
+ "-SA4006",
+ "SA4008",
+ "-SA4008",
+ "SA4009",
+ "-SA4009",
+ "SA4010",
+ "-SA4010",
+ "SA4011",
+ "-SA4011",
+ "SA4012",
+ "-SA4012",
+ "SA4013",
+ "-SA4013",
+ "SA4014",
+ "-SA4014",
+ "SA4015",
+ "-SA4015",
+ "SA4016",
+ "-SA4016",
+ "SA4017",
+ "-SA4017",
+ "SA4018",
+ "-SA4018",
+ "SA4019",
+ "-SA4019",
+ "SA4020",
+ "-SA4020",
+ "SA4021",
+ "-SA4021",
+ "SA4022",
+ "-SA4022",
+ "SA4023",
+ "-SA4023",
+ "SA4024",
+ "-SA4024",
+ "SA4025",
+ "-SA4025",
+ "SA4026",
+ "-SA4026",
+ "SA4027",
+ "-SA4027",
+ "SA4028",
+ "-SA4028",
+ "SA4029",
+ "-SA4029",
+ "SA4030",
+ "-SA4030",
+ "SA4031",
+ "-SA4031",
+ "SA4032",
+ "-SA4032",
+ "SA5*",
+ "-SA5*",
+ "SA5000",
+ "-SA5000",
+ "SA5001",
+ "-SA5001",
+ "SA5002",
+ "-SA5002",
+ "SA5003",
+ "-SA5003",
+ "SA5004",
+ "-SA5004",
+ "SA5005",
+ "-SA5005",
+ "SA5007",
+ "-SA5007",
+ "SA5008",
+ "-SA5008",
+ "SA5009",
+ "-SA5009",
+ "SA5010",
+ "-SA5010",
+ "SA5011",
+ "-SA5011",
+ "SA5012",
+ "-SA5012",
+ "SA6*",
+ "-SA6*",
+ "SA6000",
+ "-SA6000",
+ "SA6001",
+ "-SA6001",
+ "SA6002",
+ "-SA6002",
+ "SA6003",
+ "-SA6003",
+ "SA6005",
+ "-SA6005",
+ "SA6006",
+ "-SA6006",
+ "SA9*",
+ "-SA9*",
+ "SA9001",
+ "-SA9001",
+ "SA9002",
+ "-SA9002",
+ "SA9003",
+ "-SA9003",
+ "SA9004",
+ "-SA9004",
+ "SA9005",
+ "-SA9005",
+ "SA9006",
+ "-SA9006",
+ "SA9007",
+ "-SA9007",
+ "SA9008",
+ "-SA9008",
+ "SA9009",
+ "-SA9009",
+ "ST*",
+ "-ST*",
+ "ST1*",
+ "-ST1*",
+ "ST1000",
+ "-ST1000",
+ "ST1001",
+ "-ST1001",
+ "ST1003",
+ "-ST1003",
+ "ST1005",
+ "-ST1005",
+ "ST1006",
+ "-ST1006",
+ "ST1008",
+ "-ST1008",
+ "ST1011",
+ "-ST1011",
+ "ST1012",
+ "-ST1012",
+ "ST1013",
+ "-ST1013",
+ "ST1015",
+ "-ST1015",
+ "ST1016",
+ "-ST1016",
+ "ST1017",
+ "-ST1017",
+ "ST1018",
+ "-ST1018",
+ "ST1019",
+ "-ST1019",
+ "ST1020",
+ "-ST1020",
+ "ST1021",
+ "-ST1021",
+ "ST1022",
+ "-ST1022",
+ "ST1023",
+ "-ST1023",
+ "S*",
+ "-S*",
+ "S1*",
+ "-S1*",
+ "S1000",
+ "-S1000",
+ "S1001",
+ "-S1001",
+ "S1002",
+ "-S1002",
+ "S1003",
+ "-S1003",
+ "S1004",
+ "-S1004",
+ "S1005",
+ "-S1005",
+ "S1006",
+ "-S1006",
+ "S1007",
+ "-S1007",
+ "S1008",
+ "-S1008",
+ "S1009",
+ "-S1009",
+ "S1010",
+ "-S1010",
+ "S1011",
+ "-S1011",
+ "S1012",
+ "-S1012",
+ "S1016",
+ "-S1016",
+ "S1017",
+ "-S1017",
+ "S1018",
+ "-S1018",
+ "S1019",
+ "-S1019",
+ "S1020",
+ "-S1020",
+ "S1021",
+ "-S1021",
+ "S1023",
+ "-S1023",
+ "S1024",
+ "-S1024",
+ "S1025",
+ "-S1025",
+ "S1028",
+ "-S1028",
+ "S1029",
+ "-S1029",
+ "S1030",
+ "-S1030",
+ "S1031",
+ "-S1031",
+ "S1032",
+ "-S1032",
+ "S1033",
+ "-S1033",
+ "S1034",
+ "-S1034",
+ "S1035",
+ "-S1035",
+ "S1036",
+ "-S1036",
+ "S1037",
+ "-S1037",
+ "S1038",
+ "-S1038",
+ "S1039",
+ "-S1039",
+ "S1040",
+ "-S1040",
+ "QF*",
+ "-QF*",
+ "QF1*",
+ "-QF1*",
+ "QF1001",
+ "-QF1001",
+ "QF1002",
+ "-QF1002",
+ "QF1003",
+ "-QF1003",
+ "QF1004",
+ "-QF1004",
+ "QF1005",
+ "-QF1005",
+ "QF1006",
+ "-QF1006",
+ "QF1007",
+ "-QF1007",
+ "QF1008",
+ "-QF1008",
+ "QF1009",
+ "-QF1009",
+ "QF1010",
+ "-QF1010",
+ "QF1011",
+ "-QF1011",
+ "QF1012",
+ "-QF1012"
+ ]
+ },
+ "godoclint-rules": {
+ "enum": [
+ "pkg-doc",
+ "single-pkg-doc",
+ "require-pkg-doc",
+ "start-with-name",
+ "require-doc",
+ "deprecated",
+ "max-len",
+ "no-unused-link",
+ "require-stdlib-doclink"
+ ]
+ },
+ "gosec-rules": {
+ "enum": [
+ "G101",
+ "G102",
+ "G103",
+ "G104",
+ "G106",
+ "G107",
+ "G108",
+ "G109",
+ "G110",
+ "G111",
+ "G112",
+ "G114",
+ "G115",
+ "G116",
+ "G201",
+ "G202",
+ "G203",
+ "G204",
+ "G301",
+ "G302",
+ "G303",
+ "G304",
+ "G305",
+ "G306",
+ "G307",
+ "G401",
+ "G402",
+ "G403",
+ "G404",
+ "G405",
+ "G406",
+ "G501",
+ "G502",
+ "G503",
+ "G504",
+ "G505",
+ "G506",
+ "G507",
+ "G601",
+ "G602"
+ ]
+ },
+ "govet-analyzers": {
+ "enum": [
+ "appends",
+ "asmdecl",
+ "assign",
+ "atomic",
+ "atomicalign",
+ "bools",
+ "buildtag",
+ "cgocall",
+ "composites",
+ "copylocks",
+ "deepequalerrors",
+ "defers",
+ "directive",
+ "errorsas",
+ "fieldalignment",
+ "findcall",
+ "framepointer",
+ "hostport",
+ "httpmux",
+ "httpresponse",
+ "ifaceassert",
+ "loopclosure",
+ "lostcancel",
+ "nilfunc",
+ "nilness",
+ "printf",
+ "reflectvaluecompare",
+ "shadow",
+ "shift",
+ "sigchanyzer",
+ "slog",
+ "sortslice",
+ "stdmethods",
+ "stdversion",
+ "stringintconv",
+ "structtag",
+ "testinggoroutine",
+ "tests",
+ "timeformat",
+ "unmarshal",
+ "unreachable",
+ "unsafeptr",
+ "unusedresult",
+ "unusedwrite",
+ "waitgroup"
+ ]
+ },
+ "revive-rules": {
+ "enum": [
+ "add-constant",
+ "argument-limit",
+ "atomic",
+ "banned-characters",
+ "bare-return",
+ "blank-imports",
+ "bool-literal-in-expr",
+ "call-to-gc",
+ "cognitive-complexity",
+ "comment-spacings",
+ "comments-density",
+ "confusing-naming",
+ "confusing-results",
+ "constant-logical-expr",
+ "context-as-argument",
+ "context-keys-type",
+ "cyclomatic",
+ "datarace",
+ "deep-exit",
+ "defer",
+ "dot-imports",
+ "duplicated-imports",
+ "early-return",
+ "empty-block",
+ "empty-lines",
+ "enforce-map-style",
+ "enforce-repeated-arg-type-style",
+ "enforce-slice-style",
+ "enforce-switch-style",
+ "epoch-naming",
+ "error-naming",
+ "error-return",
+ "error-strings",
+ "errorf",
+ "exported",
+ "file-header",
+ "file-length-limit",
+ "filename-format",
+ "flag-parameter",
+ "forbidden-call-in-wg-go",
+ "function-length",
+ "function-result-limit",
+ "get-return",
+ "identical-branches",
+ "identical-ifelseif-branches",
+ "identical-ifelseif-conditions",
+ "identical-switch-branches",
+ "identical-switch-conditions",
+ "if-return",
+ "import-alias-naming",
+ "import-shadowing",
+ "imports-blocklist",
+ "increment-decrement",
+ "indent-error-flow",
+ "inefficient-map-lookup",
+ "line-length-limit",
+ "max-control-nesting",
+ "max-public-structs",
+ "modifies-parameter",
+ "modifies-value-receiver",
+ "nested-structs",
+ "optimize-operands-order",
+ "package-comments",
+ "package-directory-mismatch",
+ "range-val-address",
+ "range-val-in-closure",
+ "range",
+ "receiver-naming",
+ "redefines-builtin-id",
+ "redundant-build-tag",
+ "redundant-import-alias",
+ "redundant-test-main-exit",
+ "string-format",
+ "string-of-int",
+ "struct-tag",
+ "superfluous-else",
+ "time-date",
+ "time-equal",
+ "time-naming",
+ "unchecked-type-assertion",
+ "unconditional-recursion",
+ "unexported-naming",
+ "unexported-return",
+ "unhandled-error",
+ "unnecessary-format",
+ "unnecessary-if",
+ "unnecessary-stmt",
+ "unreachable-code",
+ "unsecure-url-scheme",
+ "unused-parameter",
+ "unused-receiver",
+ "use-any",
+ "use-errors-new",
+ "use-fmt-print",
+ "use-slices-sort",
+ "use-waitgroup-go",
+ "useless-break",
+ "useless-fallthrough",
+ "var-declaration",
+ "var-naming",
+ "waitgroup-by-value"
+ ]
+ },
+ "iface-analyzers": {
+ "enum": [
+ "identical",
+ "unused",
+ "opaque",
+ "unexported"
+ ]
+ },
+ "tagliatelle-cases": {
+ "enum": [
+ "",
+ "camel",
+ "pascal",
+ "kebab",
+ "snake",
+ "goCamel",
+ "goPascal",
+ "goKebab",
+ "goSnake",
+ "upper",
+ "upperSnake",
+ "lower",
+ "header"
+ ]
+ },
+ "modernize-analyzers": {
+ "enum": [
+ "any",
+ "fmtappendf",
+ "forvar",
+ "mapsloop",
+ "minmax",
+ "newexpr",
+ "omitzero",
+ "plusbuild",
+ "rangeint",
+ "reflecttypefor",
+ "slicescontains",
+ "slicessort",
+ "stditerators",
+ "stringscut",
+ "stringscutprefix",
+ "stringsseq",
+ "stringsbuilder",
+ "testingcontext",
+ "unsafefuncs",
+ "waitgroup"
+ ]
+ },
+ "wsl-checks": {
+ "enum": [
+ "assign",
+ "branch",
+ "decl",
+ "defer",
+ "expr",
+ "for",
+ "go",
+ "if",
+ "inc-dec",
+ "label",
+ "range",
+ "return",
+ "select",
+ "send",
+ "switch",
+ "type-switch",
+ "append",
+ "assign-exclusive",
+ "assign-expr",
+ "err",
+ "leading-whitespace",
+ "trailing-whitespace",
+ "after-block"
+ ]
+ },
+ "relative-path-modes": {
+ "enum": [
+ "gomod",
+ "gitroot",
+ "cfg",
+ "wd"
+ ]
+ },
+ "simple-format": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "path": {
+ "$ref": "#/definitions/formats-path",
+ "default": "stdout"
+ }
+ }
+ },
+ "formats-path" : {
+ "anyOf": [
+ {
+ "enum": [
+ "stdout",
+ "stderr"
+ ]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ },
+ "linter-names": {
+ "$comment": "anyOf with enum is used to allow auto-completion of non-custom linters",
+ "description": "Usable linter names.",
+ "anyOf": [
+ {
+ "enum": [
+ "arangolint",
+ "asasalint",
+ "asciicheck",
+ "bidichk",
+ "bodyclose",
+ "canonicalheader",
+ "containedctx",
+ "contextcheck",
+ "copyloopvar",
+ "cyclop",
+ "decorder",
+ "depguard",
+ "dogsled",
+ "dupl",
+ "dupword",
+ "durationcheck",
+ "embeddedstructfieldcheck",
+ "errcheck",
+ "errchkjson",
+ "errname",
+ "errorlint",
+ "exhaustive",
+ "exhaustruct",
+ "exptostd",
+ "fatcontext",
+ "forbidigo",
+ "forcetypeassert",
+ "funcorder",
+ "funlen",
+ "ginkgolinter",
+ "gocheckcompilerdirectives",
+ "gochecknoglobals",
+ "gochecknoinits",
+ "gochecksumtype",
+ "gocognit",
+ "goconst",
+ "gocritic",
+ "gocyclo",
+ "godoclint",
+ "godot",
+ "godox",
+ "err113",
+ "goheader",
+ "gomoddirectives",
+ "gomodguard",
+ "goprintffuncname",
+ "gosec",
+ "gosimple",
+ "gosmopolitan",
+ "govet",
+ "grouper",
+ "iface",
+ "importas",
+ "inamedparam",
+ "ineffassign",
+ "interfacebloat",
+ "intrange",
+ "iotamixing",
+ "ireturn",
+ "lll",
+ "loggercheck",
+ "maintidx",
+ "makezero",
+ "mirror",
+ "misspell",
+ "mnd",
+ "modernize",
+ "musttag",
+ "nakedret",
+ "nestif",
+ "nilerr",
+ "nilnesserr",
+ "nilnil",
+ "nlreturn",
+ "noctx",
+ "noinlineerr",
+ "nolintlint",
+ "nonamedreturns",
+ "nosprintfhostport",
+ "paralleltest",
+ "perfsprint",
+ "prealloc",
+ "predeclared",
+ "promlinter",
+ "protogetter",
+ "reassign",
+ "recvcheck",
+ "revive",
+ "rowserrcheck",
+ "sloglint",
+ "sqlclosecheck",
+ "staticcheck",
+ "stylecheck",
+ "tagalign",
+ "tagliatelle",
+ "testableexamples",
+ "testifylint",
+ "testpackage",
+ "thelper",
+ "tparallel",
+ "unconvert",
+ "unparam",
+ "unused",
+ "usestdlibvars",
+ "usetesting",
+ "varnamelen",
+ "wastedassign",
+ "whitespace",
+ "wrapcheck",
+ "wsl",
+ "wsl_v5",
+ "zerologlint"
+ ]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ },
+ "formatter-names": {
+ "description": "Usable formatter names.",
+ "enum": [
+ "gci",
+ "gofmt",
+ "gofumpt",
+ "goimports",
+ "golines",
+ "swaggo"
+ ]
+ },
+ "settings": {
+ "definitions": {
+ "dupwordSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "keywords": {
+ "description": "Keywords for detecting duplicate words. If this list is not empty, only the words defined in this list will be detected.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["the", "and", "a"]
+ }
+ },
+ "ignore": {
+ "description": "Keywords used to ignore detection.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["0C0C"]
+ }
+ },
+ "comments-only": {
+ "description": "Checks only comments, skip strings.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "asasalintSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "exclude": {
+ "description": "To specify a set of function names to exclude.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["\\.Wrapf"]
+ }
+ },
+ "use-builtin-exclusions": {
+ "description": "To enable/disable the asasalint builtin exclusions of function names.",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "bidichkSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "left-to-right-embedding": {
+ "description": "Disallow: LEFT-TO-RIGHT-EMBEDDING",
+ "type": "boolean",
+ "default": false
+ },
+ "right-to-left-embedding": {
+ "description": "Disallow: RIGHT-TO-LEFT-EMBEDDING",
+ "type": "boolean",
+ "default": false
+ },
+ "pop-directional-formatting": {
+ "description": "Disallow: POP-DIRECTIONAL-FORMATTING",
+ "type": "boolean",
+ "default": false
+ },
+ "left-to-right-override": {
+ "description": "Disallow: LEFT-TO-RIGHT-OVERRIDE",
+ "type": "boolean",
+ "default": false
+ },
+ "right-to-left-override": {
+ "description": "Disallow: RIGHT-TO-LEFT-OVERRIDE",
+ "type": "boolean",
+ "default": false
+ },
+ "left-to-right-isolate": {
+ "description": "Disallow: LEFT-TO-RIGHT-ISOLATE",
+ "type": "boolean",
+ "default": false
+ },
+ "right-to-left-isolate": {
+ "description": "Disallow: RIGHT-TO-LEFT-ISOLATE",
+ "type": "boolean",
+ "default": false
+ },
+ "first-strong-isolate": {
+ "description": "Disallow: FIRST-STRONG-ISOLATE",
+ "type": "boolean",
+ "default": false
+ },
+ "pop-directional-isolate": {
+ "description": "Disallow: POP-DIRECTIONAL-ISOLATE",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "cyclopSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-complexity": {
+ "description": "Max complexity the function can have",
+ "type": "integer",
+ "default": 10,
+ "minimum": 0
+ },
+ "package-average": {
+ "description": "Max average complexity in package",
+ "type": "number",
+ "default": 0,
+ "minimum": 0
+ }
+ }
+ },
+ "decorderSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "dec-order": {
+ "type": "array",
+ "default": [["type", "const", "var", "func"]],
+ "items": {
+ "enum": ["type", "const", "var", "func"]
+ }
+ },
+ "ignore-underscore-vars": {
+ "description": "Underscore vars (vars with \"_\" as the name) will be ignored at all checks",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-dec-order-check": {
+ "description": "Order of declarations is not checked",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-init-func-first-check": {
+ "description": "Allow init func to be anywhere in file",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-dec-num-check": {
+ "description": "Multiple global type, const and var declarations are allowed",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-type-dec-num-check": {
+ "description": "Type declarations will be ignored for dec num check",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-const-dec-num-check": {
+ "description": "Const declarations will be ignored for dec num check",
+ "default": true,
+ "type": "boolean"
+ },
+ "disable-var-dec-num-check": {
+ "description": "Var declarations will be ignored for dec num check",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ },
+ "depguardSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "rules": {
+ "description": "Rules to apply.",
+ "type": "object",
+ "additionalProperties": false,
+ "patternProperties": {
+ "^[^.]+$": {
+ "description": "Name of a rule.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "list-mode": {
+ "description": "Used to determine the package matching priority.",
+ "enum": ["original", "strict", "lax"],
+ "default": "original"
+ },
+ "files": {
+ "description": "List of file globs that will match this list of settings to compare against.",
+ "additionalProperties": false,
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "allow": {
+ "description": "List of allowed packages.",
+ "additionalProperties": false,
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "deny": {
+ "description": "Packages that are not allowed where the value is a suggestion.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "desc": {
+ "description": "Description",
+ "type": "string"
+ },
+ "pkg": {
+ "description": "Package",
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "dogsledSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-blank-identifiers": {
+ "description": "Check assignments with too many blank identifiers.",
+ "type": "integer",
+ "default": 2,
+ "minimum": 0
+ }
+ }
+ },
+ "duplSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "threshold": {
+ "description": "Tokens count to trigger issue.",
+ "type": "integer",
+ "default": 150,
+ "minimum": 0
+ }
+ }
+ },
+ "embeddedstructfieldcheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "empty-line": {
+ "description": "Checks that there is an empty space between the embedded fields and regular fields.",
+ "type": "boolean",
+ "default": false
+ },
+ "forbid-mutex": {
+ "description": "Checks that sync.Mutex and sync.RWMutex are not used as embedded fields.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "errcheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-type-assertions": {
+ "description": "Report about not checking errors in type assertions, i.e.: `a := b.(MyStruct)`",
+ "type": "boolean",
+ "default": false
+ },
+ "check-blank": {
+ "description": "Report about assignment of errors to blank identifier",
+ "type": "boolean",
+ "default": false
+ },
+ "exclude-functions": {
+ "description": "List of functions to exclude from checking, where each entry is a single function to exclude",
+ "type": "array",
+ "examples": ["io/ioutil.ReadFile", "io.Copy(*bytes.Buffer)"],
+ "items": {
+ "type": "string"
+ }
+ },
+ "disable-default-exclusions": {
+ "description": "To disable the errcheck built-in exclude list",
+ "type": "boolean",
+ "default": false
+ },
+ "verbose": {
+ "description": "Display function signature instead of selector",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "errchkjsonSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-error-free-encoding": {
+ "type": "boolean",
+ "default": false
+ },
+ "report-no-exported": {
+ "description": "Issue on struct that doesn't have exported fields.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "errorlintSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "errorf": {
+ "description": "Check whether fmt.Errorf uses the %w verb for formatting errors",
+ "type": "boolean",
+ "default": true
+ },
+ "errorf-multi": {
+ "description": "Permit more than 1 %w verb, valid per Go 1.20",
+ "type": "boolean",
+ "default": true
+ },
+ "asserts": {
+ "description": "Check for plain type assertions and type switches.",
+ "type": "boolean",
+ "default": true
+ },
+ "comparison": {
+ "description": "Check for plain error comparisons",
+ "type": "boolean",
+ "default": true
+ },
+ "allowed-errors": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "err": {
+ "type": "string"
+ },
+ "fun": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "allowed-errors-wildcard": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "err": {
+ "type": "string"
+ },
+ "fun": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "exhaustiveSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check": {
+ "description": "Program elements to check for exhaustiveness.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["switch", "map"]
+ }
+ },
+ "explicit-exhaustive-switch": {
+ "description": "Only run exhaustive check on switches with \"//exhaustive:enforce\" comment.",
+ "type": "boolean",
+ "default": false
+ },
+ "explicit-exhaustive-map": {
+ "description": "Only run exhaustive check on map literals with \"//exhaustive:enforce\" comment.",
+ "type": "boolean",
+ "default": false
+ },
+ "default-case-required": {
+ "description": "Switch statement requires default case even if exhaustive.",
+ "type": "boolean",
+ "default": false
+ },
+ "default-signifies-exhaustive": {
+ "description": "Presence of `default` case in switch statements satisfies exhaustiveness, even if all enum members are not listed.",
+ "type": "boolean",
+ "default": false
+ },
+ "ignore-enum-members": {
+ "description": "Enum members matching `regex` do not have to be listed in switch statements to satisfy exhaustiveness",
+ "type": "string"
+ },
+ "ignore-enum-types": {
+ "description": "Enum types matching the supplied regex do not have to be listed in switch statements to satisfy exhaustiveness.",
+ "type": "string"
+ },
+ "package-scope-only": {
+ "description": "Consider enums only in package scopes, not in inner scopes.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "exhaustructSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "include": {
+ "description": "List of regular expressions to match struct packages and names.",
+ "type": "array",
+ "examples": [".*\\.Test"],
+ "items": {
+ "type": "string"
+ }
+ },
+ "exclude": {
+ "description": "List of regular expressions to exclude struct packages and names from check.",
+ "type": "array",
+ "examples": ["cobra\\.Command$"],
+ "items": {
+ "type": "string"
+ }
+ },
+ "allow-empty": {
+ "description": "Allows empty structures, effectively excluding them from the check.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-empty-rx": {
+ "description": "List of regular expressions to match type names that should be allowed to be empty.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "allow-empty-returns": {
+ "description": "Allows empty structures in return statements.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-empty-declarations": {
+ "description": "Allows empty structures in variable declarations.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "fatcontextSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-struct-pointers": {
+ "description": "Check for potential fat contexts in struct pointers.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "forbidigoSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "exclude-godoc-examples": {
+ "description": "Exclude code in godoc examples.",
+ "type": "boolean",
+ "default": true
+ },
+ "analyze-types": {
+ "description": "Instead of matching the literal source code, use type information to replace expressions with strings that contain the package name and (for methods and fields) the type name.",
+ "type": "boolean",
+ "default": true
+ },
+ "forbid": {
+ "description": "List of identifiers to forbid (written using `regexp`)",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "pattern": {
+ "description": "Pattern",
+ "type": "string"
+ },
+ "pkg": {
+ "description": "Package",
+ "type": "string"
+ },
+ "msg": {
+ "description": "Message",
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "funcorderSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "constructor": {
+ "description": "Checks that constructors are placed after the structure declaration.",
+ "type": "boolean",
+ "default": true
+ },
+ "struct-method": {
+ "description": "Checks if the exported methods of a structure are placed before the non-exported ones.",
+ "type": "boolean",
+ "default": true
+ },
+ "alphabetical": {
+ "description": "Checks if the constructors and/or structure methods are sorted alphabetically.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "funlenSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "lines": {
+ "description": "Limit lines number per function.",
+ "type": "integer",
+ "default": 60
+ },
+ "statements": {
+ "description": "Limit statements number per function.",
+ "type": "integer",
+ "default": 40
+ },
+ "ignore-comments": {
+ "description": "Ignore comments when counting lines.",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "gciSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "sections": {
+ "description": "Section configuration to compare against.",
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "enum": [
+ "standard",
+ "default",
+ "blank",
+ "dot",
+ "alias",
+ "localmodule"
+ ]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ },
+ "default": ["standard", "default"]
+ },
+ "no-inline-comments": {
+ "description": "Checks that no inline Comments are present.",
+ "type": "boolean",
+ "default": false
+ },
+ "no-prefix-comments": {
+ "description": "Checks that no prefix Comments(comment lines above an import) are present.",
+ "type": "boolean",
+ "default": false
+ },
+ "custom-order": {
+ "description": "Enable custom order of sections.",
+ "type": "boolean",
+ "default": false
+ },
+ "no-lex-order": {
+ "description": "Drops lexical ordering for custom sections.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "ginkgolinterSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "suppress-len-assertion": {
+ "description": "Suppress the wrong length assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-nil-assertion": {
+ "description": "Suppress the wrong nil assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-err-assertion": {
+ "description": "Suppress the wrong error assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-compare-assertion": {
+ "description": "Suppress the wrong comparison assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-async-assertion": {
+ "description": "Suppress the function all in async assertion warning.",
+ "type": "boolean",
+ "default": false
+ },
+ "suppress-type-compare-assertion": {
+ "description": "Suppress warning for comparing values from different types, like int32 and uint32.",
+ "type": "boolean",
+ "default": false
+ },
+ "forbid-focus-container": {
+ "description": "Trigger warning for ginkgo focus containers like FDescribe, FContext, FWhen or FIt.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-havelen-zero": {
+ "description": "Don't trigger warnings for HaveLen(0).",
+ "type": "boolean",
+ "default": false
+ },
+ "force-expect-to": {
+ "description": "Force using `Expect` with `To`, `ToNot` or `NotTo`",
+ "type": "boolean",
+ "default": false
+ },
+ "validate-async-intervals": {
+ "description": "Best effort validation of async intervals (timeout and polling).",
+ "type": "boolean",
+ "default": false
+ },
+ "forbid-spec-pollution": {
+ "description": "Trigger a warning for variable assignments in ginkgo containers like `Describe`, `Context` and `When`, instead of in `BeforeEach()`.",
+ "type": "boolean",
+ "default": false
+ },
+ "force-succeed": {
+ "description": "Force using the Succeed matcher for error functions, and the HaveOccurred matcher for non-function error values.",
+ "type": "boolean",
+ "default": false
+ },
+ "force-assertion-description": {
+ "description": "Force adding assertion descriptions to gomega matchers.",
+ "type": "boolean",
+ "default": false
+ },
+ "force-tonot": {
+ "description": "Force using `ToNot`, `ShouldNot` instead of `To(Not())`.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "gochecksumtypeSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "default-signifies-exhaustive": {
+ "description": "Presence of `default` case in switch statements satisfies exhaustiveness, if all members are not listed.",
+ "type": "boolean",
+ "default": true
+ },
+ "include-shared-interfaces": {
+ "description": "Include shared interfaces in the exhaustiviness check.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "gocognitSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "min-complexity": {
+ "description": "Minimal code complexity to report (we recommend 10-20).",
+ "type": "integer",
+ "default": 30
+ }
+ }
+ },
+ "goconstSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "match-constant": {
+ "description": "Look for existing constants matching the values",
+ "type": "boolean",
+ "default": true
+ },
+ "min-len": {
+ "description": "Minimum length of string constant.",
+ "type": "integer",
+ "default": 3
+ },
+ "min-occurrences": {
+ "description": "Minimum occurrences count to trigger.",
+ "type": "integer",
+ "default": 3
+ },
+ "ignore-calls": {
+ "description": "Ignore when constant is not used as function argument",
+ "type": "boolean",
+ "default": true
+ },
+ "ignore-string-values": {
+ "description": "Exclude strings matching the given regular expression",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "numbers": {
+ "description": "Search also for duplicated numbers.",
+ "type": "boolean",
+ "default": false
+ },
+ "min": {
+ "description": "Minimum value, only works with `numbers`",
+ "type": "integer",
+ "default": 3
+ },
+ "max": {
+ "description": "Maximum value, only works with `numbers`",
+ "type": "integer",
+ "default": 3
+ },
+ "find-duplicates": {
+ "description": "Detects constants with identical values",
+ "type": "boolean",
+ "default": false
+ },
+ "eval-const-expressions": {
+ "description": "Evaluates of constant expressions like Prefix + \"suffix\"",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "gocriticSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "enabled-checks": {
+ "description": "Which checks should be enabled. By default, a list of stable checks is used. To see it, run `GL_DEBUG=gocritic golangci-lint run`.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/gocritic-checks"
+ }
+ },
+ "disabled-checks": {
+ "description": "Which checks should be disabled.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/gocritic-checks"
+ },
+ "default": []
+ },
+ "enabled-tags": {
+ "description": "Enable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/gocritic-tags"
+ }
+ },
+ "disabled-tags": {
+ "description": "Disable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/gocritic-tags"
+ }
+ },
+ "settings": {
+ "description": "Settings passed to gocritic. Properties must be valid and enabled check names.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "captLocal": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "paramsOnly" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "commentedOutCode": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "minLength" : {
+ "type": "number",
+ "default": 15
+ }
+ }
+ },
+ "elseif": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skipBalanced" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "hugeParam": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "sizeThreshold" : {
+ "type": "number",
+ "default": 80
+ }
+ }
+ },
+ "ifElseChain": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "minThreshold" : {
+ "type": "number",
+ "default": 2
+ }
+ }
+ },
+ "nestingReduce": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "bodyWidth" : {
+ "type": "number",
+ "default": 5
+ }
+ }
+ },
+ "rangeExprCopy": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "sizeThreshold" : {
+ "type": "number",
+ "default": 512
+ },
+ "skipTestFuncs" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "rangeValCopy": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "sizeThreshold" : {
+ "type": "number",
+ "default": 128
+ },
+ "skipTestFuncs" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "ruleguard": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "debug" : {
+ "type": "string"
+ },
+ "enable" : {
+ "type": "string"
+ },
+ "disable" : {
+ "type": "string"
+ },
+ "failOn" : {
+ "type": "string"
+ },
+ "rules" : {
+ "type": "string"
+ }
+ }
+ },
+ "tooManyResultsChecker": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "maxResults" : {
+ "type": "number",
+ "default": 5
+ }
+ }
+ },
+ "truncateCmp": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skipArchDependent" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "underef": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skipRecvDeref" : {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "unnamedResult": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "checkExported" : {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ }
+ }
+ },
+ "disable-all": {
+ "type": "boolean",
+ "default": false
+ },
+ "enable-all": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "gocycloSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "min-complexity": {
+ "description": "Minimum code complexity to report (we recommend 10-20).",
+ "type": "integer",
+ "default": 30
+ }
+ }
+ },
+ "godoclintSettings": {
+ "type": "object",
+ "properties": {
+ "default": {
+ "type": "string",
+ "enum": ["all", "basic", "none"],
+ "default": "basic",
+ "description": "Default set of rules to enable."
+ },
+ "enable": {
+ "description": "List of rules to enable in addition to the default set.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "$ref": "#/definitions/godoclint-rules"
+ }
+ },
+ "disable": {
+ "description": "List of rules to disable.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "$ref": "#/definitions/godoclint-rules"
+ }
+ },
+ "options": {
+ "type": "object",
+ "description": "A map for setting individual rule options.",
+ "properties": {
+ "max-len": {
+ "type": "object",
+ "properties": {
+ "length": {
+ "type": "integer",
+ "description": "Maximum line length for godocs, not including the `//`, `/*` or `*/` tokens.",
+ "default": 77
+ }
+ }
+ },
+ "require-doc": {
+ "type": "object",
+ "properties": {
+ "ignore-exported": {
+ "type": "boolean",
+ "description": "Ignore exported (public) symbols when applying the `require-doc` rule.",
+ "default": false
+ },
+ "ignore-unexported": {
+ "type": "boolean",
+ "description": "Ignore unexported (private) symbols when applying the `require-doc` rule.",
+ "default": true
+ }
+ }
+ },
+ "start-with-name": {
+ "type": "object",
+ "properties": {
+ "include-unexported": {
+ "type": "boolean",
+ "description": "Include unexported symbols when applying the `start-with-name` rule.",
+ "default": false
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "godotSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "scope": {
+ "description": "Comments to be checked.",
+ "enum": ["declarations", "toplevel", "all", "noinline"],
+ "default": "declarations"
+ },
+ "exclude": {
+ "description": "List of regexps for excluding particular comment lines from check.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "period": {
+ "description": "Check that each sentence ends with a period.",
+ "type": "boolean",
+ "default": true
+ },
+ "capital": {
+ "description": "Check that each sentence starts with a capital letter.",
+ "type": "boolean",
+ "default": false
+ },
+ "check-all": {
+ "description": "DEPRECATED: Check all top-level comments, not only declarations.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "godoxSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "keywords": {
+ "description": "Report any comments starting with one of these keywords. This is useful for TODO or FIXME comments that might be left in the code accidentally and should be resolved before merging.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "default": ["TODO", "BUG", "FIXME"]
+ }
+ }
+ },
+ "gofmtSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "simplify": {
+ "description": "Simplify code.",
+ "type": "boolean",
+ "default": true
+ },
+ "rewrite-rules": {
+ "description": "Apply the rewrite rules to the source before reformatting.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "pattern": {
+ "type": "string"
+ },
+ "replacement": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "golinesSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-len": {
+ "type": "integer",
+ "default": 100
+ },
+ "tab-len": {
+ "type": "integer",
+ "default": 4
+ },
+ "shorten-comments": {
+ "type": "boolean",
+ "default": false
+ },
+ "reformat-tags": {
+ "type": "boolean",
+ "default": true
+ },
+ "chain-split-dots": {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "interfacebloatSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max": {
+ "description": "The maximum number of methods allowed for an interface.",
+ "type": "integer"
+ }
+ }
+ },
+ "gofumptSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "extra-rules": {
+ "description": "Choose whether or not to use the extra rules that are disabled by default.",
+ "type": "boolean",
+ "default": false
+ },
+ "module-path": {
+ "description": " Module path which contains the source code being formatted.",
+ "type": "string"
+ }
+ }
+ },
+ "goheaderSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "values": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "const": {
+ "description": "Constants to use in the template.",
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "description": "Value for the constant.",
+ "type": "string"
+ }
+ },
+ "additionalProperties": false,
+ "examples": [
+ {
+ "YEAR": "2030",
+ "COMPANY": "MY FUTURISTIC COMPANY"
+ }
+ ]
+ },
+ "regexp": {
+ "description": "Regular expressions to use in your template.",
+ "type": "object",
+ "additionalProperties": false,
+ "patternProperties": {
+ "^.+$": {
+ "type": "string"
+ }
+ },
+ "examples": [
+ {
+ "AUTHOR": ".*@mycompany\\.com"
+ }
+ ]
+ }
+ }
+ },
+ "template": {
+ "description": "Template to put on top of every file.",
+ "type": "string",
+ "examples": [
+ "{{ MY COMPANY }}\nSPDX-License-Identifier: Apache-2.0\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at:\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License."
+ ]
+ },
+ "template-path": {
+ "description": "Path to the file containing the template source.",
+ "type": "string",
+ "examples": ["my_header_template.txt"]
+ }
+ },
+ "oneOf": [
+ { "required": ["template"] },
+ { "required": ["template-path"] }
+ ]
+ },
+ "goimportsSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "local-prefixes": {
+ "description": "Put imports beginning with prefix after 3rd-party packages. It is a list of prefixes.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "gomoddirectivesSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "replace-local": {
+ "description": "Allow local `replace` directives.",
+ "type": "boolean",
+ "default": true
+ },
+ "replace-allow-list": {
+ "description": "List of allowed `replace` directives.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "retract-allow-no-explanation": {
+ "description": "Allow to not explain why the version has been retracted in the `retract` directives.",
+ "type": "boolean",
+ "default": false
+ },
+ "exclude-forbidden": {
+ "description": "Forbid the use of the `exclude` directives.",
+ "type": "boolean",
+ "default": false
+ },
+ "ignore-forbidden": {
+ "description": "Forbid the use of the `ignore` directives. (>= go1.25)",
+ "type": "boolean",
+ "default": false
+ },
+ "toolchain-forbidden": {
+ "description": "Forbid the use of the `toolchain` directive.",
+ "type": "boolean",
+ "default": false
+ },
+ "toolchain-pattern": {
+ "description": "Defines a pattern to validate `toolchain` directive.",
+ "type": "string"
+ },
+ "tool-forbidden": {
+ "description": "Forbid the use of the `tool` directives.",
+ "type": "boolean",
+ "default": false
+ },
+ "go-debug-forbidden": {
+ "description": "Forbid the use of the `godebug` directive.",
+ "type": "boolean",
+ "default": false
+ },
+ "go-version-pattern": {
+ "description": "Defines a pattern to validate `go` minimum version directive.",
+ "type": "string",
+ "default": ""
+ },
+ "check-module-path": {
+ "description": "Check the validity of the module path.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "gomodguardSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "allowed": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "modules": {
+ "description": "List of allowed modules.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["gopkg.in/yaml.v2"]
+ }
+ },
+ "domains": {
+ "description": "List of allowed module domains.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["golang.org"]
+ }
+ }
+ }
+ },
+ "blocked": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "modules": {
+ "description": "List of blocked modules.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "recommendations": {
+ "description": "Recommended modules that should be used instead.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "reason": {
+ "description": "Reason why the recommended module should be used.",
+ "type": "string"
+ }
+ }
+ }
+ },
+ "additionalProperties": false
+ }
+ },
+ "versions": {
+ "description": "List of blocked module version constraints.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "patternProperties": {
+ "^.*$": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "version": {
+ "description": "Version constraint.",
+ "type": "string"
+ },
+ "reason": {
+ "description": "Reason why the version constraint exists.",
+ "type": "string"
+ }
+ },
+ "required": ["reason"]
+ }
+ }
+ }
+ },
+ "local-replace-directives": {
+ "description": "Raise lint issues if loading local path with replace directive",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ }
+ }
+ },
+ "gosecSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "includes": {
+ "type": "array",
+ "description": "To select a subset of rules to run",
+ "examples": [["G401"]],
+ "items": {
+ "$ref": "#/definitions/gosec-rules"
+ }
+ },
+ "excludes": {
+ "type": "array",
+ "description": "To specify a set of rules to explicitly exclude",
+ "examples": [["G401"]],
+ "items": {
+ "$ref": "#/definitions/gosec-rules"
+ }
+ },
+ "severity": {
+ "description": "Filter out the issues with a lower severity than the given value",
+ "type": "string",
+ "enum": ["low", "medium", "high"],
+ "default": "low"
+ },
+ "confidence": {
+ "description": "Filter out the issues with a lower confidence than the given value",
+ "type": "string",
+ "enum": ["low", "medium", "high"],
+ "default": "low"
+ },
+ "config": {
+ "description": "To specify the configuration of rules",
+ "type": "object"
+ },
+ "concurrency": {
+ "description": "Concurrency value",
+ "type": "integer"
+ }
+ }
+ },
+ "gosmopolitanSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "allow-time-local": {
+ "description": "Allow and ignore `time.Local` usages.",
+ "type": "boolean",
+ "default": false
+ },
+ "escape-hatches": {
+ "description": "List of fully qualified names in the `full/pkg/path.name` form, to act as \"i18n escape hatches\".",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "watch-for-scripts": {
+ "description": "List of Unicode scripts to watch for any usage in string literals.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "govetSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "settings": {
+ "description": "Settings per analyzer. Map of analyzer name to specific settings.\nRun `go tool vet help` to find out more.",
+ "type": "object",
+ "propertyNames": {
+ "$ref": "#/definitions/govet-analyzers"
+ },
+ "patternProperties": {
+ "^.*$": {
+ "description": "Run `go tool vet help ` to see all settings.",
+ "type": "object"
+ }
+ }
+ },
+ "enable": {
+ "description": "Enable analyzers by name.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/govet-analyzers"
+ }
+ },
+ "disable": {
+ "description": "Disable analyzers by name.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/govet-analyzers"
+ }
+ },
+ "enable-all": {
+ "description": "Enable all analyzers.",
+ "type": "boolean",
+ "default": false
+ },
+ "disable-all": {
+ "description": "Disable all analyzers.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "grouperSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "const-require-single-const": {
+ "type": "boolean",
+ "default": false
+ },
+ "const-require-grouping": {
+ "type": "boolean",
+ "default": false
+ },
+ "import-require-single-import": {
+ "type": "boolean",
+ "default": false
+ },
+ "import-require-grouping": {
+ "type": "boolean",
+ "default": false
+ },
+ "type-require-single-type": {
+ "type": "boolean",
+ "default": false
+ },
+ "type-require-grouping": {
+ "type": "boolean",
+ "default": false
+ },
+ "var-require-single-var": {
+ "type": "boolean",
+ "default": false
+ },
+ "var-require-grouping": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "ifaceSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "enable": {
+ "description": "Enable analyzers by name.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/iface-analyzers"
+ }
+ },
+ "settings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "unused": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "exclude": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "importasSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "no-unaliased": {
+ "description": "Do not allow unaliased imports of aliased packages.",
+ "type": "boolean",
+ "default": false
+ },
+ "no-extra-aliases": {
+ "description": "Do not allow non-required aliases.",
+ "type": "boolean",
+ "default": false
+ },
+ "alias": {
+ "description": "List of aliases",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "pkg": {
+ "description": "Package path e.g. knative.dev/serving/pkg/apis/autoscaling/v1alpha1",
+ "type": "string"
+ },
+ "alias": {
+ "description": "Package alias e.g. autoscalingv1alpha1",
+ "type": "string"
+ }
+ },
+ "required": ["pkg", "alias"]
+ }
+ }
+ }
+ },
+ "inamedparamSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skip-single-param": {
+ "description": "Skips check for interface methods with only a single parameter.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "ineffassignSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-escaping-errors": {
+ "description": "Check escaping variables of type error, may cause false positives.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "iotamixingSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "report-individual": {
+ "description": "Whether to report individual consts rather than just the const block.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "ireturnSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "description": "Use either `reject` or `allow` properties for interfaces matching.",
+ "properties": {
+ "allow": {
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "enum": ["anon", "error", "empty", "stdlib"]
+ }
+ ]
+ }
+ },
+ "reject": {
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "enum": ["anon", "error", "empty", "stdlib"]
+ }
+ ]
+ }
+ }
+ },
+ "anyOf": [
+ {
+ "not": {
+ "properties": {
+ "allow": {
+ "const": "reject"
+ }
+ }
+ },
+ "required": ["allow"]
+ },
+ {
+ "required": ["reject"]
+ }
+ ]
+ },
+ "lllSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "tab-width": {
+ "description": "Width of \"\\t\" in spaces.",
+ "type": "integer",
+ "minimum": 0,
+ "default": 1
+ },
+ "line-length": {
+ "description": "Maximum allowed line length, lines longer will be reported.",
+ "type": "integer",
+ "minimum": 1,
+ "default": 120
+ }
+ }
+ },
+ "maintidxSettings": {
+ "description": "Maintainability index https://docs.microsoft.com/en-us/visualstudio/code-quality/code-metrics-maintainability-index-range-and-meaning?view=vs-2022",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "under": {
+ "description": "Minimum accatpable maintainability index level (see https://docs.microsoft.com/en-us/visualstudio/code-quality/code-metrics-maintainability-index-range-and-meaning?view=vs-2022)",
+ "type": "number",
+ "default": 20
+ }
+ }
+ },
+ "makezeroSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "always": {
+ "description": "Allow only slices initialized with a length of zero.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "loggercheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "kitlog": {
+ "description": "Allow check for the github.com/go-kit/log library.",
+ "type": "boolean",
+ "default": true
+ },
+ "klog": {
+ "description": "Allow check for the k8s.io/klog/v2 library.",
+ "type": "boolean",
+ "default": true
+ },
+ "logr": {
+ "description": "Allow check for the github.com/go-logr/logr library.",
+ "type": "boolean",
+ "default": true
+ },
+ "slog": {
+ "description": "Allow check for the log/slog library.",
+ "type": "boolean",
+ "default": true
+ },
+ "zap": {
+ "description": "Allow check for the \"sugar logger\" from go.uber.org/zap library.",
+ "type": "boolean",
+ "default": true
+ },
+ "require-string-key": {
+ "description": "Require all logging keys to be inlined constant strings.",
+ "type": "boolean",
+ "default": false
+ },
+ "no-printf-like": {
+ "description": "Require printf-like format specifier (%s, %d for example) not present.",
+ "type": "boolean",
+ "default": false
+ },
+ "rules": {
+ "description": "List of custom rules to check against, where each rule is a single logger pattern, useful for wrapped loggers.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "misspellSettings": {
+ "description": "Correct spellings using locale preferences for US or UK. Default is to use a neutral variety of English.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "locale": {
+ "enum": ["US", "UK"]
+ },
+ "ignore-rules": {
+ "description": "List of rules to ignore.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "mode": {
+ "description": "Mode of the analysis.",
+ "enum": ["restricted", "", "default"],
+ "default": ""
+ },
+ "extra-words": {
+ "description": "Extra word corrections.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "correction": {
+ "type": "string"
+ },
+ "typo": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "musttagSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "functions": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "tag": {
+ "type": "string"
+ },
+ "arg-pos": {
+ "type": "integer"
+ }
+ }
+ }
+ }
+ }
+ },
+ "nakedretSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-func-lines": {
+ "description": "Report if a function has more lines of code than this value and it has naked returns.",
+ "type": "integer",
+ "minimum": 0,
+ "default": 30
+ }
+ }
+ },
+ "nestifSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "min-complexity": {
+ "description": "Minimum complexity of \"if\" statements to report.",
+ "type": "integer",
+ "default": 5
+ }
+ }
+ },
+ "nilnilSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "only-two": {
+ "type": "boolean",
+ "description": "To check functions with only two return values.",
+ "default": true
+ },
+ "detect-opposite": {
+ "type": "boolean",
+ "description": "In addition, detect opposite situation (simultaneous return of non-nil error and valid value).",
+ "default": false
+ },
+ "checked-types": {
+ "type": "array",
+ "description": "List of return types to check.",
+ "items": {
+ "enum": ["chan", "func", "iface", "map", "ptr", "uintptr", "unsafeptr"]
+ },
+ "default": ["chan", "func", "iface", "map", "ptr", "uintptr", "unsafeptr"]
+ }
+ }
+ },
+ "nlreturnSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "block-size": {
+ "description": "set block size that is still ok",
+ "type": "number",
+ "default": 0,
+ "minimum": 0
+ }
+ }
+ },
+ "mndSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignored-files": {
+ "description": "List of file patterns to exclude from analysis.",
+ "examples": [["magic1_.*.go"]],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignored-functions": {
+ "description": "Comma-separated list of function patterns to exclude from the analysis.",
+ "examples": [["math.*", "http.StatusText", "make"]],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignored-numbers": {
+ "description": "List of numbers to exclude from analysis.",
+ "examples": [["1000", "1234_567_890", "3.14159264"]],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "checks": {
+ "description": "The list of enabled checks, see https://github.com/tommy-muehle/go-mnd/#checks for description.",
+ "type": "array",
+ "items": {
+ "enum": [
+ "argument",
+ "case",
+ "condition",
+ "operation",
+ "return",
+ "assign"
+ ]
+ }
+ }
+ }
+ },
+ "modernizeSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "disable": {
+ "description": "List of analyzers to disable.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/modernize-analyzers"
+ }
+ }
+ }
+ },
+ "nolintlintSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "allow-unused": {
+ "description": "Enable to ensure that nolint directives are all used.",
+ "type": "boolean",
+ "default": true
+ },
+ "allow-no-explanation": {
+ "description": "Exclude these linters from requiring an explanation.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linter-names"
+ },
+ "default": []
+ },
+ "require-explanation": {
+ "description": "Enable to require an explanation of nonzero length after each nolint directive.",
+ "type": "boolean",
+ "default": false
+ },
+ "require-specific": {
+ "description": "Enable to require nolint directives to mention the specific linter being suppressed.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "reassignSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "patterns": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "recvcheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "disable-builtin": {
+ "description": "Disables the built-in method exclusions.",
+ "type": "boolean",
+ "default": true
+ },
+ "exclusions": {
+ "description": "User-defined method exclusions.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "nonamedreturnsSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "report-error-in-defer": {
+ "description": "Report named error if it is assigned inside defer.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "paralleltestSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignore-missing": {
+ "description": "Ignore missing calls to `t.Parallel()` and only report incorrect uses of it.",
+ "type": "boolean",
+ "default": false
+ },
+ "ignore-missing-subtests": {
+ "description": "Ignore missing calls to `t.Parallel()` in subtests. Top-level tests are still required to have `t.Parallel`, but subtests are allowed to skip it.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "perfsprintSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "integer-format": {
+ "description": "Enable/disable optimization of integer formatting.",
+ "type": "boolean",
+ "default": true
+ },
+ "int-conversion": {
+ "description": "Optimizes even if it requires an int or uint type cast.",
+ "type": "boolean",
+ "default": true
+ },
+ "error-format": {
+ "description": "Enable/disable optimization of error formatting.",
+ "type": "boolean",
+ "default": true
+ },
+ "err-error": {
+ "description": "Optimizes into `err.Error()` even if it is only equivalent for non-nil errors.",
+ "type": "boolean",
+ "default": false
+ },
+ "errorf": {
+ "description": "Optimizes `fmt.Errorf`.",
+ "type": "boolean",
+ "default": true
+ },
+ "string-format": {
+ "description": "Enable/disable optimization of string formatting.",
+ "type": "boolean",
+ "default": true
+ },
+ "sprintf1": {
+ "description": "Optimizes `fmt.Sprintf` with only one argument.",
+ "type": "boolean",
+ "default": true
+ },
+ "strconcat": {
+ "description": "Optimizes into strings concatenation.",
+ "type": "boolean",
+ "default": true
+ },
+ "bool-format": {
+ "description": "Enable/disable optimization of bool formatting.",
+ "type": "boolean",
+ "default": true
+ },
+ "hex-format": {
+ "description": "Enable/disable optimization of hex formatting.",
+ "type": "boolean",
+ "default": true
+ },
+ "concat-loop": {
+ "description": "Enable/disable optimization of concat loop.",
+ "type": "boolean",
+ "default": true
+ },
+ "loop-other-ops": {
+ "description": "Optimization of `concat-loop` even with other operations.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "preallocSettings": {
+ "description": "We do not recommend using this linter before doing performance profiling.\nFor most programs usage of `prealloc` will be premature optimization.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "simple": {
+ "description": "Report preallocation suggestions only on simple loops that have no returns/breaks/continues/gotos in them.",
+ "type": "boolean",
+ "default": true
+ },
+ "range-loops": {
+ "description": "Report preallocation suggestions on range loops.",
+ "type": "boolean",
+ "default": true
+ },
+ "for-loops": {
+ "description": "Report preallocation suggestions on for loops.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "predeclaredSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignore": {
+ "description": "List of predeclared identifiers to not report on.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "qualified-name": {
+ "description": "Include method names and field names in checks.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "promlinterSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "strict": {},
+ "disabled-linters": {
+ "type": "array",
+ "items": {
+ "enum": [
+ "Help",
+ "MetricUnits",
+ "Counter",
+ "HistogramSummaryReserved",
+ "MetricTypeInName",
+ "ReservedChars",
+ "CamelCase",
+ "UnitAbbreviations"
+ ]
+ }
+ }
+ }
+ },
+ "protogetterSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skip-generated-by": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["protoc-gen-go-my-own-generator"]
+ }
+ },
+ "skip-files": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["*.pb.go"]
+ }
+ },
+ "skip-any-generated": {
+ "description": "Skip any generated files from the checking.",
+ "type": "boolean",
+ "default": false
+ },
+ "replace-first-arg-in-append": {
+ "description": "Skip first argument of append function.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "reviveSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "examples": [
+ {
+ "ignore-generated-header": true,
+ "severity": "warning",
+ "rules": [
+ {
+ "name": "indent-error-flow",
+ "severity": "warning"
+ },
+ {
+ "name": "add-constant",
+ "severity": "warning",
+ "arguments": [
+ {
+ "maxLitCount": "3",
+ "allowStrs": "\"\"",
+ "allowInts": "0,1,2",
+ "allowFloats": "0.0,0.,1.0,1.,2.0,2."
+ }
+ ]
+ }
+ ]
+ }
+ ],
+ "properties": {
+ "max-open-files": {
+ "type": "integer"
+ },
+ "confidence": {
+ "type": "number"
+ },
+ "severity": {
+ "type": "string",
+ "enum": ["warning", "error"]
+ },
+ "enable-all-rules": {
+ "type": "boolean",
+ "default": false
+ },
+ "enable-default-rules": {
+ "type": "boolean",
+ "default": false
+ },
+ "directives": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "name": {
+ "type": "string",
+ "enum": ["specify-disable-reason"]
+ },
+ "severity": {
+ "type": "string",
+ "enum": ["warning", "error"]
+ },
+ "exclude": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "arguments": {
+ "type": "array"
+ }
+ }
+ }
+ },
+ "rules": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["name"],
+ "properties": {
+ "name": {
+ "$ref": "#/definitions/revive-rules",
+ "title": "The rule name"
+ },
+ "disabled": {
+ "type": "boolean"
+ },
+ "severity": {
+ "type": "string",
+ "enum": ["warning", "error"]
+ },
+ "exclude": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "arguments": {
+ "type": "array"
+ }
+ }
+ }
+ }
+ }
+ },
+ "rowserrcheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "packages": {
+ "type": "array",
+ "items": {
+ "description": "",
+ "type": "string",
+ "examples": ["github.com/jmoiron/sqlx"]
+ }
+ }
+ }
+ },
+ "sloglintSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "kv-only": {
+ "description": "Enforce using key-value pairs only (incompatible with attr-only).",
+ "type": "boolean",
+ "default": false
+ },
+ "no-global": {
+ "description": "Enforce not using global loggers.",
+ "enum": ["", "all", "default"],
+ "default": ""
+ },
+ "no-mixed-args": {
+ "description": "Enforce not mixing key-value pairs and attributes.",
+ "type": "boolean",
+ "default": true
+ },
+ "context": {
+ "description": "Enforce using methods that accept a context.",
+ "enum": ["", "all", "scope"],
+ "default": ""
+ },
+ "static-msg": {
+ "description": "Enforce using static values for log messages.",
+ "type": "boolean",
+ "default": false
+ },
+ "msg-style": {
+ "description": "Enforce message style.",
+ "enum": ["", "lowercased", "capitalized"],
+ "default": ""
+ },
+ "key-naming-case": {
+ "description": "Enforce a single key naming convention.",
+ "enum": ["snake", "kebab", "camel", "pascal"]
+ },
+ "attr-only": {
+ "description": "Enforce using attributes only (incompatible with kv-only).",
+ "type": "boolean",
+ "default": false
+ },
+ "no-raw-keys": {
+ "description": "Enforce using constants instead of raw keys.",
+ "type": "boolean",
+ "default": false
+ },
+ "forbidden-keys": {
+ "description": "Enforce not using specific keys.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "args-on-sep-lines": {
+ "description": "Enforce putting arguments on separate lines.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "spancheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "checks": {
+ "description": "Checks to enable.",
+ "type": "array",
+ "items": {
+ "enum": ["end", "record-error", "set-status"]
+ }
+ },
+ "ignore-check-signatures": {
+ "description": "A list of regexes for function signatures that silence `record-error` and `set-status` reports if found in the call path to a returned error.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "extra-start-span-signatures": {
+ "description": "A list of regexes for additional function signatures that create spans.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "staticcheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "checks": {
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "$ref": "#/definitions/staticcheck-checks"
+ },
+ {
+ "type": "string"
+ }
+ ]
+ }
+ },
+ "dot-import-whitelist": {
+ "description": "By default, ST1001 forbids all uses of dot imports in non-test packages. This setting allows setting a whitelist of import paths that can be dot-imported anywhere.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "http-status-code-whitelist": {
+ "description": "ST1013 recommends using constants from the net/http package instead of hard-coding numeric HTTP status codes. This setting specifies a list of numeric status codes that this check does not complain about.",
+ "default": ["200", "400", "404", "500"],
+ "type": "array",
+ "items": {
+ "enum": [
+ "100",
+ "101",
+ "102",
+ "103",
+ "200",
+ "201",
+ "202",
+ "203",
+ "204",
+ "205",
+ "206",
+ "207",
+ "208",
+ "226",
+ "300",
+ "301",
+ "302",
+ "303",
+ "304",
+ "305",
+ "306",
+ "307",
+ "308",
+ "400",
+ "401",
+ "402",
+ "403",
+ "404",
+ "405",
+ "406",
+ "407",
+ "408",
+ "409",
+ "410",
+ "411",
+ "412",
+ "413",
+ "414",
+ "415",
+ "416",
+ "417",
+ "418",
+ "421",
+ "422",
+ "423",
+ "424",
+ "425",
+ "426",
+ "428",
+ "429",
+ "431",
+ "451",
+ "500",
+ "501",
+ "502",
+ "503",
+ "504",
+ "505",
+ "506",
+ "507",
+ "508",
+ "510",
+ "511"
+ ]
+ }
+ },
+ "initialisms": {
+ "description": "ST1003 check, among other things, for the correct capitalization of initialisms. The set of known initialisms can be configured with this option.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "default": [
+ "ACL",
+ "API",
+ "ASCII",
+ "CPU",
+ "CSS",
+ "DNS",
+ "EOF",
+ "GUID",
+ "HTML",
+ "HTTP",
+ "HTTPS",
+ "ID",
+ "IP",
+ "JSON",
+ "QPS",
+ "RAM",
+ "RPC",
+ "SLA",
+ "SMTP",
+ "SQL",
+ "SSH",
+ "TCP",
+ "TLS",
+ "TTL",
+ "UDP",
+ "UI",
+ "GID",
+ "UID",
+ "UUID",
+ "URI",
+ "URL",
+ "UTF8",
+ "VM",
+ "XML",
+ "XMPP",
+ "XSRF",
+ "XSS",
+ "SIP",
+ "RTP",
+ "AMQP",
+ "DB",
+ "TS"
+ ]
+ }
+ }
+ }
+ },
+ "tagalignSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "align": {
+ "description": "Align and sort can be used together or separately.",
+ "type": "boolean",
+ "default": true
+ },
+ "sort": {
+ "description": "Whether enable tags sort.",
+ "type": "boolean",
+ "default": true
+ },
+ "order": {
+ "description": "Specify the order of tags, the other tags will be sorted by name.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "default": [],
+ "examples": [
+ [
+ "json",
+ "yaml",
+ "yml",
+ "toml",
+ "mapstructure",
+ "binding",
+ "validate"
+ ]
+ ]
+ },
+ "strict": {
+ "description": "Whether enable strict style.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "tagliatelleSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "case": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "use-field-name": {
+ "description": "Use the struct field name to check the name of the struct tag.",
+ "type": "boolean",
+ "default": false
+ },
+ "ignored-fields": {
+ "description": "The field names to ignore.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["example"]
+ }
+ },
+ "rules": {
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "$ref": "#/definitions/tagliatelle-cases"
+ }
+ }
+ },
+ "extended-rules": {
+ "description": "Defines the association between tag name and case.",
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["case"],
+ "properties": {
+ "case": {
+ "$ref": "#/definitions/tagliatelle-cases"
+ },
+ "extra-initialisms": {
+ "type": "boolean",
+ "default": false
+ },
+ "initialism-overrides": {
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "overrides": {
+ "description": "Overrides the default/root configuration.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["pkg"],
+ "properties": {
+ "pkg": {
+ "description": "A package path.",
+ "type": "string"
+ },
+ "use-field-name": {
+ "description": "Use the struct field name to check the name of the struct tag.",
+ "type": "boolean",
+ "default": false
+ },
+ "ignored-fields": {
+ "description": "The field names to ignore.",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": ["example"]
+ }
+ },
+ "ignore": {
+ "description": "Ignore the package (takes precedence over all other configurations).",
+ "type": "boolean",
+ "default": false
+ },
+ "rules": {
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "$ref": "#/definitions/tagliatelle-cases"
+ }
+ }
+ },
+ "extended-rules": {
+ "description": "Defines the association between tag name and case.",
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["case"],
+ "properties": {
+ "case": {
+ "$ref": "#/definitions/tagliatelle-cases"
+ },
+ "extra-initialisms": {
+ "type": "boolean",
+ "default": false
+ },
+ "initialism-overrides": {
+ "type": "object",
+ "patternProperties": {
+ "^.+$": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "testifylintSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "enable-all": {
+ "description": "Enable all checkers.",
+ "type": "boolean",
+ "default": false
+ },
+ "disable-all": {
+ "description": "Disable all checkers.",
+ "type": "boolean",
+ "default": false
+ },
+ "enable": {
+ "description": "Enable specific checkers.",
+ "type": "array",
+ "items": {
+ "enum": [
+ "blank-import",
+ "bool-compare",
+ "compares",
+ "contains",
+ "empty",
+ "encoded-compare",
+ "equal-values",
+ "error-is-as",
+ "error-nil",
+ "expected-actual",
+ "float-compare",
+ "formatter",
+ "go-require",
+ "len",
+ "negative-positive",
+ "nil-compare",
+ "regexp",
+ "require-error",
+ "suite-broken-parallel",
+ "suite-dont-use-pkg",
+ "suite-extra-assert-call",
+ "suite-method-signature",
+ "suite-subtest-run",
+ "suite-thelper",
+ "useless-assert"
+ ]
+ },
+ "default": [
+ "blank-import",
+ "bool-compare",
+ "compares",
+ "contains",
+ "empty",
+ "encoded-compare",
+ "equal-values",
+ "error-is-as",
+ "error-nil",
+ "expected-actual",
+ "float-compare",
+ "formatter",
+ "go-require",
+ "len",
+ "negative-positive",
+ "nil-compare",
+ "regexp",
+ "require-error",
+ "suite-broken-parallel",
+ "suite-dont-use-pkg",
+ "suite-extra-assert-call",
+ "suite-method-signature",
+ "suite-subtest-run",
+ "useless-assert"
+ ]
+ },
+ "disable": {
+ "description": "Disable specific checkers.",
+ "type": "array",
+ "items": {
+ "enum": [
+ "blank-import",
+ "bool-compare",
+ "compares",
+ "contains",
+ "empty",
+ "encoded-compare",
+ "equal-values",
+ "error-is-as",
+ "error-nil",
+ "expected-actual",
+ "float-compare",
+ "formatter",
+ "go-require",
+ "len",
+ "negative-positive",
+ "nil-compare",
+ "regexp",
+ "require-error",
+ "suite-broken-parallel",
+ "suite-dont-use-pkg",
+ "suite-extra-assert-call",
+ "suite-method-signature",
+ "suite-subtest-run",
+ "suite-thelper",
+ "useless-assert"
+ ],
+ "default": [
+ "suite-thelper"
+ ]
+ }
+ },
+ "bool-compare": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignore-custom-types": {
+ "description": "To ignore user defined types (over builtin bool).",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "expected-actual": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "pattern": {
+ "description": "Regexp for expected variable name.",
+ "type": "string",
+ "default": "(^(exp(ected)?|want(ed)?)([A-Z]\\w*)?$)|(^(\\w*[a-z])?(Exp(ected)?|Want(ed)?)$)"
+ }
+ }
+ },
+ "formatter": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-format-string": {
+ "description": "To enable go vet's printf checks.",
+ "type": "boolean",
+ "default": true
+ },
+ "require-f-funcs": {
+ "description": "To require f-assertions (e.g. assert.Equalf) if format string is used, even if there are no variable-length variables.",
+ "type": "boolean",
+ "default": false
+ },
+ "require-string-msg": {
+ "description": "To require that the first element of msgAndArgs (msg) has a string type.",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "go-require": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ignore-http-handlers": {
+ "description": "To ignore HTTP handlers (like http.HandlerFunc).",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "require-error": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "fn-pattern": {
+ "description": "Regexp for assertions to analyze. If defined, then only matched error assertions will be reported.",
+ "type": "string",
+ "default": ""
+ }
+ }
+ },
+ "suite-extra-assert-call": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "mode": {
+ "description": "To require or remove extra Assert() call?",
+ "type": "string",
+ "enum": ["remove", "require"],
+ "default": "remove"
+ }
+ }
+ }
+ }
+ },
+ "testpackageSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "skip-regexp": {
+ "description": "Files with names matching this regular expression are skipped.",
+ "type": "string",
+ "examples": ["(export|internal)_test\\.go"]
+ },
+ "allow-packages": {
+ "description": "List of packages that don't end with _test that tests are allowed to be in.",
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "string",
+ "examples": ["example"]
+ }
+ }
+ }
+ },
+ "thelperSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "test": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "begin": {
+ "description": "Check if `t.Helper()` begins helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "first": {
+ "description": "Check if *testing.T is first param of helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "name": {
+ "description": "Check if *testing.T param has t name.",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ },
+ "benchmark": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "begin": {
+ "description": "Check if `b.Helper()` begins helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "first": {
+ "description": "Check if *testing.B is first param of helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "name": {
+ "description": "Check if *testing.B param has b name.",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ },
+ "tb": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "begin": {
+ "description": "Check if `tb.Helper()` begins helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "first": {
+ "description": "Check if *testing.TB is first param of helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "name": {
+ "description": "Check if *testing.TB param has tb name.",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ },
+ "fuzz": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "begin": {
+ "description": "Check if `f.Helper()` begins helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "first": {
+ "description": "Check if *testing.F is first param of helper function.",
+ "default": true,
+ "type": "boolean"
+ },
+ "name": {
+ "description": "Check if *testing.F param has f name.",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ }
+ }
+ },
+ "usestdlibvarsSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "http-method": {
+ "description": "Suggest the use of http.MethodXX.",
+ "type": "boolean",
+ "default": true
+ },
+ "http-status-code": {
+ "description": "Suggest the use of http.StatusXX.",
+ "type": "boolean",
+ "default": true
+ },
+ "time-weekday": {
+ "description": "Suggest the use of time.Weekday.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "time-month": {
+ "description": "Suggest the use of time.Month.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "time-layout": {
+ "description": "Suggest the use of time.Layout.",
+ "type": "boolean",
+ "default": false
+ },
+ "time-date-month": {
+ "description": "Suggest the use of time.Month in time.Date.",
+ "type": "boolean",
+ "default": false
+ },
+ "crypto-hash": {
+ "description": "Suggest the use of crypto.Hash.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "default-rpc-path": {
+ "description": "Suggest the use of rpc.DefaultXXPath.",
+ "type": "boolean",
+ "default": false
+ },
+ "sql-isolation-level": {
+ "description": "Suggest the use of sql.LevelXX.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "tls-signature-scheme": {
+ "description": "Suggest the use of tls.SignatureScheme.String().",
+ "type": "boolean",
+ "default": false
+ },
+ "constant-kind": {
+ "description": "Suggest the use of constant.Kind.String().",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "usetestingSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "context-background": {
+ "type": "boolean",
+ "default": false
+ },
+ "context-todo": {
+ "type": "boolean",
+ "default": false
+ },
+ "os-chdir": {
+ "type": "boolean",
+ "default": true
+ },
+ "os-mkdir-temp": {
+ "type": "boolean",
+ "default": true
+ },
+ "os-setenv": {
+ "type": "boolean",
+ "default": true
+ },
+ "os-create-temp": {
+ "type": "boolean",
+ "default": true
+ },
+ "os-temp-dir": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "unconvertSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "fast-math": {
+ "type": "boolean",
+ "default": false
+ },
+ "safe": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "unparamSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-exported": {
+ "description": "Inspect exported functions. Set to true if no external program/library imports your code.\n\nWARNING: if you enable this setting, unparam will report a lot of false-positives in text editors:\nif it's called for subdir of a project it can't find external interfaces. All text editor integrations\nwith golangci-lint call it on a directory with the changed file.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "unqueryvetSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-sql-builders": {
+ "description": "Enable SQL builder checking.",
+ "type": "boolean",
+ "default": true
+ },
+ "check-aliased-wildcard": {
+ "description": "Enable aliased wildcard detection like SELECT t.*.",
+ "type": "boolean",
+ "default": true
+ },
+ "check-string-concat": {
+ "description": "Enable string concatenation analysis.",
+ "type": "boolean",
+ "default": true
+ },
+ "check-format-strings": {
+ "description": "Enable format string analysis like fmt.Sprintf.",
+ "type": "boolean",
+ "default": true
+ },
+ "check-string-builder": {
+ "description": "Enable strings.Builder analysis.",
+ "type": "boolean",
+ "default": true
+ },
+ "check-subqueries": {
+ "description": "Enable subquery analysis.",
+ "type": "boolean",
+ "default": true
+ },
+ "check-n1": {
+ "type": "boolean",
+ "default": false
+ },
+ "check-sql-injection": {
+ "type": "boolean",
+ "default": false
+ },
+ "check-tx-leaks": {
+ "type": "boolean",
+ "default": false
+ },
+ "allowed-patterns": {
+ "description": "Regex patterns for acceptable SELECT * usage.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "allow": {
+ "description": "Allow is a list of SQL patterns to allow (whitelist).",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignored-functions": {
+ "description": "Functions to ignore.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "sql-builders": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "squirrel": {
+ "type": "boolean",
+ "default": true
+ },
+ "gorm": {
+ "type": "boolean",
+ "default": true
+ },
+ "sqlx": {
+ "type": "boolean",
+ "default": true
+ },
+ "ent": {
+ "type": "boolean",
+ "default": true
+ },
+ "pgx": {
+ "type": "boolean",
+ "default": true
+ },
+ "bun": {
+ "type": "boolean",
+ "default": true
+ },
+ "sqlboiler": {
+ "type": "boolean",
+ "default": true
+ },
+ "jet": {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "custom-rules": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "id": {
+ "type": "string"
+ },
+ "pattern": {
+ "type": "string"
+ },
+ "patterns": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "when": {
+ "type": "string"
+ },
+ "message": {
+ "type": "string"
+ },
+ "action": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "unusedSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "field-writes-are-uses": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ },
+ "post-statements-are-reads": {
+ "description": "",
+ "type": "boolean",
+ "default": false
+ },
+ "exported-fields-are-used": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ },
+ "parameters-are-used": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ },
+ "local-variables-are-used": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ },
+ "generated-is-used": {
+ "description": "",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "varnamelenSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-distance": {
+ "description": "Variables used in at most this N-many lines will be ignored.",
+ "type": "integer",
+ "default": 5
+ },
+ "min-name-length": {
+ "description": "The minimum length of a variable's name that is considered `long`.",
+ "type": "integer",
+ "default": 3
+ },
+ "check-receiver": {
+ "description": "Check method receiver names.",
+ "default": false,
+ "type": "boolean"
+ },
+ "check-return": {
+ "description": "Check named return values.",
+ "default": false,
+ "type": "boolean"
+ },
+ "check-type-param": {
+ "description": "Check type parameters.",
+ "default": false,
+ "type": "boolean"
+ },
+ "ignore-type-assert-ok": {
+ "description": "Ignore `ok` variables that hold the bool return value of a type assertion",
+ "default": false,
+ "type": "boolean"
+ },
+ "ignore-map-index-ok": {
+ "description": "Ignore `ok` variables that hold the bool return value of a map index.",
+ "default": false,
+ "type": "boolean"
+ },
+ "ignore-chan-recv-ok": {
+ "description": "Ignore `ok` variables that hold the bool return value of a channel receive.",
+ "default": false,
+ "type": "boolean"
+ },
+ "ignore-names": {
+ "description": "Optional list of variable names that should be ignored completely.",
+ "default": [[]],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignore-decls": {
+ "description": "Optional list of variable declarations that should be ignored completely.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "examples": [
+ ["c echo.Context", "t testing.T", "f *foo.Bar", "const C"]
+ ]
+ }
+ }
+ },
+ "whitespaceSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "multi-if": {
+ "description": "Enforces newlines (or comments) after every multi-line if statement",
+ "type": "boolean",
+ "default": false
+ },
+ "multi-func": {
+ "description": "Enforces newlines (or comments) after every multi-line function signature",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "wrapcheckSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "extra-ignore-sigs": {
+ "description": "An array of strings specifying additional substrings of signatures to ignore.",
+ "default": [
+ ".CustomError(",
+ ".SpecificWrap("
+ ],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignore-sigs": {
+ "description": "An array of strings which specify substrings of signatures to ignore.",
+ "default": [
+ ".Errorf(",
+ "errors.New(",
+ "errors.Unwrap(",
+ ".Wrap(",
+ ".Wrapf(",
+ ".WithMessage(",
+ ".WithMessagef(",
+ ".WithStack("
+ ],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignore-sig-regexps": {
+ "description": "An array of strings which specify regular expressions of signatures to ignore.",
+ "default": [""],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignore-package-globs": {
+ "description": "An array of glob patterns which, if any match the package of the function returning the error, will skip wrapcheck analysis for this error.",
+ "default": [""],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "ignore-interface-regexps": {
+ "description": "An array of glob patterns which, if matched to an underlying interface name, will ignore unwrapped errors returned from a function whose call is defined on the given interface.",
+ "default": [""],
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "report-internal-errors": {
+ "description": "Determines whether wrapcheck should report errors returned from inside the package.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "wslSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "allow-assign-and-anything": {
+ "description": "Controls if you may cuddle assignments and anything without needing an empty line between them.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-assign-and-call": {
+ "description": "Allow calls and assignments to be cuddled as long as the lines have any matching variables, fields or types.",
+ "type": "boolean",
+ "default": true
+ },
+ "allow-cuddle-declarations": {
+ "description": "Allow declarations (var) to be cuddled.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-cuddle-with-calls": {
+ "description": "A list of call idents that everything can be cuddled with.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "allow-cuddle-with-rhs": {
+ "description": "AllowCuddleWithRHS is a list of right hand side variables that is allowed to be cuddled with anything.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "allow-cuddle-used-in-block": {
+ "description": "Allow cuddling with any block as long as the variable is used somewhere in the block",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-multiline-assign": {
+ "description": "Allow multiline assignments to be cuddled.",
+ "type": "boolean",
+ "default": true
+ },
+ "allow-separated-leading-comment": {
+ "description": "Allow leading comments to be separated with empty lines.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-trailing-comment": {
+ "description": "Allow trailing comments in ending of blocks.",
+ "type": "boolean",
+ "default": false
+ },
+ "error-variable-names": {
+ "description": "When force-err-cuddling is enabled this is a list of names used for error variables to check for in the conditional.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "force-case-trailing-whitespace": {
+ "description": "Force newlines in end of case at this limit (0 = never).",
+ "type": "integer",
+ "minimum": 0,
+ "default": 0
+ },
+ "force-err-cuddling": {
+ "description": "Causes an error when an If statement that checks an error variable doesn't cuddle with the assignment of that variable.",
+ "type": "boolean",
+ "default": false
+ },
+ "force-short-decl-cuddling": {
+ "description": "Causes an error if a short declaration (:=) cuddles with anything other than another short declaration.",
+ "type": "boolean",
+ "default": false
+ },
+ "strict-append": {
+ "description": "If true, append is only allowed to be cuddled if appending value is matching variables, fields or types on line above.",
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "wslSettingsV5": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "allow-first-in-block": {
+ "type": "boolean",
+ "default": true
+ },
+ "allow-whole-block": {
+ "type": "boolean",
+ "default": false
+ },
+ "branch-max-lines": {
+ "type": "integer",
+ "default": 2
+ },
+ "case-max-lines": {
+ "type": "integer",
+ "default": 0
+ },
+ "default": {
+ "enum": ["all", "none", "default", ""],
+ "default": "default"
+ },
+ "enable": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/wsl-checks"
+ }
+ },
+ "disable": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/wsl-checks"
+ }
+ }
+ }
+ },
+ "copyloopvarSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "check-alias": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "customSettings": {
+ "description": "The custom section can be used to define linter plugins to be loaded at runtime. See README of golangci-lint for more information.\nEach custom linter should have a unique name.",
+ "type": "object",
+ "patternProperties": {
+ "^.*$": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "type": {
+ "description": "The plugin type.",
+ "enum": ["module", "goplugin"],
+ "default": "goplugin"
+ },
+ "path": {
+ "description": "The path to the plugin *.so. Can be absolute or local.",
+ "type": "string",
+ "examples": ["/path/to/example.so"]
+ },
+ "description": {
+ "description": "The description of the linter, for documentation purposes only.",
+ "type": "string"
+ },
+ "original-url": {
+ "description": "Intended to point to the repo location of the linter, for documentation purposes only.",
+ "type": "string"
+ },
+ "settings": {
+ "description": "Plugins settings/configuration. Only work with plugin based on `linterdb.PluginConstructor`.",
+ "type": "object"
+ }
+ },
+ "oneOf": [
+ {
+ "properties": {
+ "type": {"enum": ["module"] }
+ },
+ "required": ["type"]
+ },
+ {
+ "required": ["path"]
+ }
+ ]
+ }
+ }
+ }
+ }
+ }
+ },
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["version"],
+ "properties": {
+ "version": {
+ "type": "string",
+ "default": "2"
+ },
+ "run": {
+ "description": "Options for analysis running,",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "concurrency": {
+ "description": "Number of concurrent runners. Defaults to the number of available CPU cores.",
+ "type": "integer",
+ "minimum": 0,
+ "examples": [4]
+ },
+ "timeout": {
+ "description": "Timeout for the analysis.",
+ "type": "string",
+ "pattern": "^((\\d+h)?(\\d+m)?(\\d+(?:\\.\\d)?s)?|0)$",
+ "default": "1m",
+ "examples": ["30s", "5m", "5m30s"]
+ },
+ "issues-exit-code": {
+ "description": "Exit code when at least one issue was found.",
+ "type": "integer",
+ "default": 1
+ },
+ "tests": {
+ "description": "Enable inclusion of test files.",
+ "type": "boolean",
+ "default": true
+ },
+ "build-tags": {
+ "description": "List of build tags to pass to all linters.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "default": [],
+ "examples": [["mytag"]]
+ },
+ "modules-download-mode": {
+ "description": "Option to pass to \"go list -mod={option}\".\nSee \"go help modules\" for more information.",
+ "enum": ["mod", "readonly", "vendor"]
+ },
+ "enable-build-vcs": {
+ "type": "boolean",
+ "default": false
+ },
+ "allow-parallel-runners": {
+ "description": "Allow multiple parallel golangci-lint instances running. If disabled, golangci-lint acquires file lock on start.",
+ "type": "boolean",
+ "default": false
+ },
+ "allow-serial-runners": {
+ "description": "Allow multiple golangci-lint instances running, but serialize them around a lock.",
+ "type": "boolean",
+ "default": false
+ },
+ "go": {
+ "description": "Targeted Go version.",
+ "type": "string",
+ "default": "1.17"
+ },
+ "relative-path-mode": {
+ "description": "The mode used to evaluate relative paths.",
+ "type": "string",
+ "$ref": "#/definitions/relative-path-modes",
+ "default": "wd"
+ }
+ }
+ },
+ "output": {
+ "description": "Output configuration options.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "formats": {
+ "description": "Output formats to use.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "text": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "path": {
+ "$ref": "#/definitions/formats-path",
+ "default": "stdout"
+ },
+ "print-linter-name": {
+ "type": "boolean",
+ "default": true
+ },
+ "print-issued-lines": {
+ "type": "boolean",
+ "default": true
+ },
+ "colors": {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "json": {
+ "$ref": "#/definitions/simple-format"
+ },
+ "tab": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "path": {
+ "$ref": "#/definitions/formats-path",
+ "default": "stdout"
+ },
+ "print-linter-name": {
+ "type": "boolean",
+ "default": true
+ },
+ "colors": {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "html": {
+ "$ref": "#/definitions/simple-format"
+ },
+ "checkstyle": {
+ "$ref": "#/definitions/simple-format"
+ },
+ "code-climate": {
+ "$ref": "#/definitions/simple-format"
+ },
+ "junit-xml": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "path": {
+ "$ref": "#/definitions/formats-path",
+ "default": "stdout"
+ },
+ "extended": {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ },
+ "teamcity": {
+ "$ref": "#/definitions/simple-format"
+ },
+ "sarif": {
+ "$ref": "#/definitions/simple-format"
+ }
+ }
+ },
+ "path-mode": {
+ "type": "string",
+ "default": "",
+ "examples": ["abs"]
+ },
+ "path-prefix": {
+ "description": "Add a prefix to the output file references.",
+ "type": "string",
+ "default": ""
+ },
+ "show-stats": {
+ "description": "Show statistics per linter.",
+ "type": "boolean",
+ "default": true
+ },
+ "sort-order": {
+ "type": "array",
+ "items": {
+ "enum": ["linter", "severity", "file"]
+ }
+ }
+ }
+ },
+ "linters": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "default": {
+ "enum": [
+ "standard",
+ "all",
+ "none",
+ "fast"
+ ]
+ },
+ "enable": {
+ "description": "List of enabled linters.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linter-names"
+ }
+ },
+ "disable": {
+ "description": "List of disabled linters.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linter-names"
+ }
+ },
+ "settings": {
+ "description": "All available settings of specific linters.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "dupword": {
+ "$ref": "#/definitions/settings/definitions/dupwordSettings"
+ },
+ "asasalint": {
+ "$ref": "#/definitions/settings/definitions/asasalintSettings"
+ },
+ "bidichk": {
+ "$ref": "#/definitions/settings/definitions/bidichkSettings"
+ },
+ "cyclop": {
+ "$ref": "#/definitions/settings/definitions/cyclopSettings"
+ },
+ "decorder": {
+ "$ref": "#/definitions/settings/definitions/decorderSettings"
+ },
+ "depguard":{
+ "$ref": "#/definitions/settings/definitions/depguardSettings"
+ },
+ "dogsled": {
+ "$ref": "#/definitions/settings/definitions/dogsledSettings"
+ },
+ "dupl": {
+ "$ref": "#/definitions/settings/definitions/duplSettings"
+ },
+ "embeddedstructfieldcheck": {
+ "$ref": "#/definitions/settings/definitions/embeddedstructfieldcheckSettings"
+ },
+ "errcheck": {
+ "$ref": "#/definitions/settings/definitions/errcheckSettings"
+ },
+ "errchkjson": {
+ "$ref": "#/definitions/settings/definitions/errchkjsonSettings"
+ },
+ "errorlint": {
+ "$ref": "#/definitions/settings/definitions/errorlintSettings"
+ },
+ "exhaustive": {
+ "$ref": "#/definitions/settings/definitions/exhaustiveSettings"
+ },
+ "exhaustruct": {
+ "$ref": "#/definitions/settings/definitions/exhaustructSettings"
+ },
+ "fatcontext": {
+ "$ref": "#/definitions/settings/definitions/fatcontextSettings"
+ },
+ "forbidigo": {
+ "$ref": "#/definitions/settings/definitions/forbidigoSettings"
+ },
+ "funcorder": {
+ "$ref": "#/definitions/settings/definitions/funcorderSettings"
+ },
+ "funlen": {
+ "$ref": "#/definitions/settings/definitions/funlenSettings"
+ },
+ "ginkgolinter": {
+ "$ref": "#/definitions/settings/definitions/ginkgolinterSettings"
+ },
+ "gochecksumtype": {
+ "$ref": "#/definitions/settings/definitions/gochecksumtypeSettings"
+ },
+ "gocognit": {
+ "$ref": "#/definitions/settings/definitions/gocognitSettings"
+ },
+ "goconst": {
+ "$ref": "#/definitions/settings/definitions/goconstSettings"
+ },
+ "gocritic": {
+ "$ref": "#/definitions/settings/definitions/gocriticSettings"
+ },
+ "gocyclo": {
+ "$ref": "#/definitions/settings/definitions/gocycloSettings"
+ },
+ "godoclint": {
+ "$ref": "#/definitions/settings/definitions/godoclintSettings"
+ },
+ "godot": {
+ "$ref": "#/definitions/settings/definitions/godotSettings"
+ },
+ "godox": {
+ "$ref": "#/definitions/settings/definitions/godoxSettings"
+ },
+ "interfacebloat":{
+ "$ref": "#/definitions/settings/definitions/interfacebloatSettings"
+ },
+ "goheader": {
+ "$ref": "#/definitions/settings/definitions/goheaderSettings"
+ },
+ "gomoddirectives": {
+ "$ref": "#/definitions/settings/definitions/gomoddirectivesSettings"
+ },
+ "gomodguard": {
+ "$ref": "#/definitions/settings/definitions/gomodguardSettings"
+ },
+ "gosec": {
+ "$ref": "#/definitions/settings/definitions/gosecSettings"
+ },
+ "gosmopolitan": {
+ "$ref": "#/definitions/settings/definitions/gosmopolitanSettings"
+ },
+ "govet": {
+ "$ref": "#/definitions/settings/definitions/govetSettings"
+ },
+ "grouper": {
+ "$ref": "#/definitions/settings/definitions/grouperSettings"
+ },
+ "iface": {
+ "$ref": "#/definitions/settings/definitions/ifaceSettings"
+ },
+ "importas": {
+ "$ref": "#/definitions/settings/definitions/importasSettings"
+ },
+ "inamedparam": {
+ "$ref": "#/definitions/settings/definitions/inamedparamSettings"
+ },
+ "ineffassign": {
+ "$ref": "#/definitions/settings/definitions/ineffassignSettings"
+ },
+ "iotamixing": {
+ "$ref": "#/definitions/settings/definitions/iotamixingSettings"
+ },
+ "ireturn": {
+ "$ref": "#/definitions/settings/definitions/ireturnSettings"
+ },
+ "lll": {
+ "$ref": "#/definitions/settings/definitions/lllSettings"
+ },
+ "maintidx": {
+ "$ref": "#/definitions/settings/definitions/maintidxSettings"
+ },
+ "makezero":{
+ "$ref": "#/definitions/settings/definitions/makezeroSettings"
+ },
+ "loggercheck": {
+ "$ref": "#/definitions/settings/definitions/loggercheckSettings"
+ },
+ "misspell": {
+ "$ref": "#/definitions/settings/definitions/misspellSettings"
+ },
+ "musttag": {
+ "$ref": "#/definitions/settings/definitions/musttagSettings"
+ },
+ "nakedret": {
+ "$ref": "#/definitions/settings/definitions/nakedretSettings"
+ },
+ "nestif": {
+ "$ref": "#/definitions/settings/definitions/nestifSettings"
+ },
+ "nilnil": {
+ "$ref": "#/definitions/settings/definitions/nilnilSettings"
+ },
+ "nlreturn": {
+ "$ref": "#/definitions/settings/definitions/nlreturnSettings"
+ },
+ "mnd": {
+ "$ref": "#/definitions/settings/definitions/mndSettings"
+ },
+ "modernize": {
+ "$ref": "#/definitions/settings/definitions/modernizeSettings"
+ },
+ "nolintlint":{
+ "$ref": "#/definitions/settings/definitions/nolintlintSettings"
+ },
+ "reassign": {
+ "$ref": "#/definitions/settings/definitions/reassignSettings"
+ },
+ "recvcheck": {
+ "$ref": "#/definitions/settings/definitions/recvcheckSettings"
+ },
+ "nonamedreturns": {
+ "$ref": "#/definitions/settings/definitions/nonamedreturnsSettings"
+ },
+ "paralleltest": {
+ "$ref": "#/definitions/settings/definitions/paralleltestSettings"
+ },
+ "perfsprint": {
+ "$ref": "#/definitions/settings/definitions/perfsprintSettings"
+ },
+ "prealloc": {
+ "$ref": "#/definitions/settings/definitions/preallocSettings"
+ },
+ "predeclared": {
+ "$ref": "#/definitions/settings/definitions/predeclaredSettings"
+ },
+ "promlinter": {
+ "$ref": "#/definitions/settings/definitions/promlinterSettings"
+ },
+ "protogetter": {
+ "$ref": "#/definitions/settings/definitions/protogetterSettings"
+ },
+ "revive": {
+ "$ref": "#/definitions/settings/definitions/reviveSettings"
+ },
+ "rowserrcheck": {
+ "$ref": "#/definitions/settings/definitions/rowserrcheckSettings"
+ },
+ "sloglint": {
+ "$ref": "#/definitions/settings/definitions/sloglintSettings"
+ },
+ "spancheck": {
+ "$ref": "#/definitions/settings/definitions/spancheckSettings"
+ },
+ "staticcheck":{
+ "$ref": "#/definitions/settings/definitions/staticcheckSettings"
+ },
+ "tagalign": {
+ "$ref": "#/definitions/settings/definitions/tagalignSettings"
+ },
+ "tagliatelle": {
+ "$ref": "#/definitions/settings/definitions/tagliatelleSettings"
+ },
+ "testifylint": {
+ "$ref": "#/definitions/settings/definitions/testifylintSettings"
+ },
+ "testpackage": {
+ "$ref": "#/definitions/settings/definitions/testpackageSettings"
+ },
+ "thelper": {
+ "$ref": "#/definitions/settings/definitions/thelperSettings"
+ },
+ "usestdlibvars": {
+ "$ref": "#/definitions/settings/definitions/usestdlibvarsSettings"
+ },
+ "usetesting": {
+ "$ref": "#/definitions/settings/definitions/usetestingSettings"
+ },
+ "unconvert": {
+ "$ref": "#/definitions/settings/definitions/unconvertSettings"
+ },
+ "unparam": {
+ "$ref": "#/definitions/settings/definitions/unparamSettings"
+ },
+ "unqueryvet": {
+ "$ref": "#/definitions/settings/definitions/unqueryvetSettings"
+ },
+ "unused": {
+ "$ref": "#/definitions/settings/definitions/unusedSettings"
+ },
+ "varnamelen": {
+ "$ref": "#/definitions/settings/definitions/varnamelenSettings"
+ },
+ "whitespace": {
+ "$ref": "#/definitions/settings/definitions/whitespaceSettings"
+ },
+ "wrapcheck": {
+ "$ref": "#/definitions/settings/definitions/wrapcheckSettings"
+ },
+ "wsl": {
+ "$ref": "#/definitions/settings/definitions/wslSettings"
+ },
+ "wsl_v5": {
+ "$ref": "#/definitions/settings/definitions/wslSettingsV5"
+ },
+ "copyloopvar": {
+ "$ref": "#/definitions/settings/definitions/copyloopvarSettings"
+ },
+ "custom":{
+ "$ref": "#/definitions/settings/definitions/customSettings"
+ }
+ }
+ },
+ "exclusions":{
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "generated": {
+ "enum": ["strict", "lax", "disable"],
+ "default": "strict"
+ },
+ "warn-unused": {
+ "type": "boolean",
+ "default": false
+ },
+ "presets": {
+ "type": "array",
+ "items": {
+ "enum": [
+ "comments",
+ "std-error-handling",
+ "common-false-positives",
+ "legacy"
+ ]
+ }
+ },
+ "rules": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "path": {
+ "type": "string"
+ },
+ "path-except": {
+ "type": "string"
+ },
+ "linters": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linter-names"
+ }
+ },
+ "text": {
+ "type": "string"
+ },
+ "source": {
+ "type": "string"
+ }
+ },
+ "anyOf": [
+ { "required": ["path"] },
+ { "required": ["path-except"] },
+ { "required": ["linters"] },
+ { "required": ["text"] },
+ { "required": ["source"] }
+ ]
+ }
+ },
+ "paths": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "paths-except": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "formatters": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "enable": {
+ "description": "List of enabled formatters.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/formatter-names"
+ }
+ },
+ "settings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "gci": {
+ "$ref": "#/definitions/settings/definitions/gciSettings"
+ },
+ "gofmt": {
+ "$ref": "#/definitions/settings/definitions/gofmtSettings"
+ },
+ "gofumpt": {
+ "$ref": "#/definitions/settings/definitions/gofumptSettings"
+ },
+ "goimports": {
+ "$ref": "#/definitions/settings/definitions/goimportsSettings"
+ },
+ "golines": {
+ "$ref": "#/definitions/settings/definitions/golinesSettings"
+ }
+ }
+ },
+ "exclusions": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "generated": {
+ "enum": ["strict", "lax", "disable"],
+ "default": "strict"
+ },
+ "paths": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "warn-unused": {
+ "type": "boolean",
+ "default": false
+ }
+ }
+ }
+ }
+ },
+ "issues": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max-issues-per-linter": {
+ "description": "Maximum issues count per one linter. Set to 0 to disable.",
+ "type": "integer",
+ "default": 50,
+ "minimum": 0
+ },
+ "max-same-issues": {
+ "description": "Maximum count of issues with the same text. Set to 0 to disable.",
+ "type": "integer",
+ "default": 3,
+ "minimum": 0
+ },
+ "new": {
+ "description": "Show only new issues: if there are unstaged changes or untracked files, only those changes are analyzed, else only changes in HEAD~ are analyzed.",
+ "type": "boolean",
+ "default": false
+ },
+ "new-from-merge-base": {
+ "description": "Show only new issues created after the best common ancestor (merge-base against HEAD).",
+ "type": "string"
+ },
+ "new-from-rev": {
+ "description": "Show only new issues created after this git revision.",
+ "type": "string"
+ },
+ "new-from-patch": {
+ "description": "Show only new issues created in git patch with this file path.",
+ "type": "string",
+ "examples": ["path/to/patch/file"]
+ },
+ "fix": {
+ "description": "Apply the fixes detected by the linters and formatters (if it's supported by the linter).",
+ "type": "boolean",
+ "default": false
+ },
+ "uniq-by-line": {
+ "description": "Make issues output unique by line.",
+ "type": "boolean",
+ "default": true
+ },
+ "whole-files": {
+ "description": "Show issues in any part of update files (requires new-from-rev or new-from-patch).",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "severity": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "default": {
+ "description": "Set the default severity for issues. If severity rules are defined and the issues do not match or no severity is provided to the rule this will be the default severity applied. Severities should match the supported severity names of the selected out format.",
+ "type": "string",
+ "default": ""
+ },
+ "rules": {
+ "description": "When a list of severity rules are provided, severity information will be added to lint issues. Severity rules have the same filtering capability as exclude rules except you are allowed to specify one matcher per severity rule.\nOnly affects out formats that support setting severity information.",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "severity": {
+ "type": "string"
+ },
+ "path": {
+ "type": "string"
+ },
+ "path-except": {
+ "type": "string"
+ },
+ "linters": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/linter-names"
+ }
+ },
+ "text": {
+ "type": "string"
+ },
+ "source": {
+ "type": "string"
+ }
+ },
+ "required": ["severity"],
+ "anyOf": [
+ { "required": ["path"] },
+ { "required": ["path-except"] },
+ { "required": ["linters"] },
+ { "required": ["text"] },
+ { "required": ["source"] }
+ ]
+ },
+ "default": []
+ }
+ },
+ "required": ["default"]
+ }
+ }
+}
diff --git a/vendor/github.com/golangci/golangci-lint/v2/jsonschema/jsonschema.go b/vendor/github.com/golangci/golangci-lint/v2/jsonschema/jsonschema.go
new file mode 100644
index 000000000..b380e4430
--- /dev/null
+++ b/vendor/github.com/golangci/golangci-lint/v2/jsonschema/jsonschema.go
@@ -0,0 +1,40 @@
+package jsonschema
+
+import (
+ "embed"
+ "path/filepath"
+
+ "github.com/santhosh-tekuri/jsonschema/v6"
+)
+
+const (
+ V1Schema = "/golangci.v1.jsonschema.json"
+ NextSchema = "/golangci.next.jsonschema.json"
+)
+
+//go:embed golangci.next.jsonschema.json golangci.v1.jsonschema.json
+var content embed.FS
+
+type EmbedLoader struct {
+ jsonschema.FileLoader
+}
+
+func NewEmbedLoader() *EmbedLoader {
+ return &EmbedLoader{}
+}
+
+func (f *EmbedLoader) Load(uri string) (any, error) {
+ p, err := f.ToFile(uri)
+ if err != nil {
+ return nil, err
+ }
+
+ file, err := content.Open(filepath.Base(p))
+ if err != nil {
+ return nil, err
+ }
+
+ defer func() { _ = file.Close() }()
+
+ return jsonschema.UnmarshalJSON(file)
+}
diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/config.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/config.go
index b1889fa42..79945eb0c 100644
--- a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/config.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/config.go
@@ -24,9 +24,8 @@ type configCommand struct {
viper *viper.Viper
cmd *cobra.Command
- opts config.LoaderOptions
- verifyOpts verifyOptions
- pathOpts pathOptions
+ opts config.LoaderOptions
+ pathOpts pathOptions
buildInfo BuildInfo
@@ -78,11 +77,6 @@ func newConfigCommand(log logutils.Log, info BuildInfo) *configCommand {
setupConfigFileFlagSet(flagSet, &c.opts)
- // ex: --schema jsonschema/golangci.next.jsonschema.json
- verifyFlagSet := verifyCommand.Flags()
- verifyFlagSet.StringVar(&c.verifyOpts.schemaURL, "schema", "", color.GreenString("JSON schema URL"))
- _ = verifyFlagSet.MarkHidden("schema")
-
pathFlagSet := pathCommand.Flags()
pathFlagSet.BoolVar(&c.pathOpts.JSON, "json", false, color.GreenString("Display as JSON"))
diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/config_verify.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/config_verify.go
index 1bbc47d8d..8e99c7ee6 100644
--- a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/config_verify.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/config_verify.go
@@ -1,31 +1,23 @@
package commands
import (
- "context"
"encoding/json"
"errors"
"fmt"
- "net/http"
"os"
"path/filepath"
"strconv"
"strings"
- "time"
- hcversion "github.com/hashicorp/go-version"
"github.com/pelletier/go-toml/v2"
"github.com/santhosh-tekuri/jsonschema/v6"
"github.com/spf13/cobra"
- "github.com/spf13/pflag"
"go.yaml.in/yaml/v3"
+ jsonsch "github.com/golangci/golangci-lint/v2/jsonschema"
"github.com/golangci/golangci-lint/v2/pkg/exitcodes"
)
-type verifyOptions struct {
- schemaURL string // For debugging purpose only (Flag only).
-}
-
func (c *configCommand) executeVerify(cmd *cobra.Command, _ []string) error {
usedConfigFile := c.getUsedConfig()
if usedConfigFile == "" {
@@ -33,12 +25,9 @@ func (c *configCommand) executeVerify(cmd *cobra.Command, _ []string) error {
os.Exit(exitcodes.NoConfigFileDetected)
}
- schemaURL, err := createSchemaURL(cmd.Flags(), c.buildInfo)
- if err != nil {
- return fmt.Errorf("get JSON schema: %w", err)
- }
+ c.log.Infof("Verifying the configuration file %q with the JSON Schema", usedConfigFile)
- err = validateConfiguration(schemaURL, usedConfigFile)
+ err := validateConfiguration(jsonsch.NextSchema, usedConfigFile)
if err != nil {
var v *jsonschema.ValidationError
if !errors.As(err, &v) {
@@ -53,85 +42,12 @@ func (c *configCommand) executeVerify(cmd *cobra.Command, _ []string) error {
return nil
}
-func createSchemaURL(flags *pflag.FlagSet, buildInfo BuildInfo) (string, error) {
- schemaURL, err := flags.GetString("schema")
- if err != nil {
- return "", fmt.Errorf("get schema flag: %w", err)
- }
-
- if schemaURL != "" {
- return schemaURL, nil
- }
-
- switch {
- case buildInfo.Version != "" && buildInfo.Version != "(devel)":
- version, err := hcversion.NewVersion(buildInfo.Version)
- if err != nil {
- return "", fmt.Errorf("parse version: %w", err)
- }
-
- if version.Core().Equal(hcversion.Must(hcversion.NewVersion("v0.0.0"))) {
- commit, err := extractCommitHash(buildInfo)
- if err != nil {
- return "", err
- }
-
- return fmt.Sprintf("https://raw.githubusercontent.com/golangci/golangci-lint/%s/jsonschema/golangci.next.jsonschema.json",
- commit), nil
- }
-
- return fmt.Sprintf("https://golangci-lint.run/jsonschema/golangci.v%d.%d.jsonschema.json",
- version.Segments()[0], version.Segments()[1]), nil
-
- case buildInfo.Commit != "" && buildInfo.Commit != "?":
- commit, err := extractCommitHash(buildInfo)
- if err != nil {
- return "", err
- }
-
- return fmt.Sprintf("https://raw.githubusercontent.com/golangci/golangci-lint/%s/jsonschema/golangci.next.jsonschema.json",
- commit), nil
-
- default:
- return "", errors.New("version not found")
- }
-}
-
-func extractCommitHash(buildInfo BuildInfo) (string, error) {
- if buildInfo.Commit == "" || buildInfo.Commit == "?" {
- return "", errors.New("empty commit information")
- }
-
- if buildInfo.Commit == "unknown" {
- return "", errors.New("unknown commit information")
- }
-
- commit := buildInfo.Commit
-
- if strings.HasPrefix(commit, "(") {
- c, _, ok := strings.Cut(strings.TrimPrefix(commit, "("), ",")
- if !ok {
- return "", errors.New("commit information not found")
- }
-
- commit = c
- }
-
- if commit == "unknown" {
- return "", errors.New("unknown commit information")
- }
-
- return commit, nil
-}
-
func validateConfiguration(schemaPath, targetFile string) error {
compiler := jsonschema.NewCompiler()
- compiler.UseLoader(jsonschema.SchemeURLLoader{
- "file": jsonschema.FileLoader{},
- "https": newJSONSchemaHTTPLoader(),
- })
+ compiler.UseLoader(jsonsch.NewEmbedLoader())
compiler.DefaultDraft(jsonschema.Draft7)
+ // The name is not us
schema, err := compiler.Compile(schemaPath)
if err != nil {
return fmt.Errorf("compile schema: %w", err)
@@ -207,33 +123,3 @@ func decodeTomlFile(filename string) (any, error) {
return m, nil
}
-
-type jsonschemaHTTPLoader struct {
- *http.Client
-}
-
-func newJSONSchemaHTTPLoader() *jsonschemaHTTPLoader {
- return &jsonschemaHTTPLoader{Client: &http.Client{
- Timeout: 2 * time.Second,
- }}
-}
-
-func (l jsonschemaHTTPLoader) Load(url string) (any, error) {
- req, err := http.NewRequestWithContext(context.Background(), http.MethodGet, url, http.NoBody)
- if err != nil {
- return nil, err
- }
-
- resp, err := l.Do(req)
- if err != nil {
- return nil, err
- }
-
- defer resp.Body.Close()
-
- if resp.StatusCode != http.StatusOK {
- return nil, fmt.Errorf("%s returned status code %d", url, resp.StatusCode)
- }
-
- return jsonschema.UnmarshalJSON(resp.Body)
-}
diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/builder.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/builder.go
index 63f6f2f18..df2a134a4 100644
--- a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/builder.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/builder.go
@@ -96,6 +96,7 @@ func (b Builder) clone(ctx context.Context) error {
"https://github.com/golangci/golangci-lint.git",
)
cmd.Dir = b.root
+ cmd.Env = filterGitEnviron(os.Environ())
output, err := cmd.CombinedOutput()
if err != nil {
@@ -280,3 +281,33 @@ func sanitizeVersion(v string) string {
return strings.Join(strings.FieldsFunc(v, fn), "")
}
+
+// Inspired by https://github.com/pre-commit/pre-commit/blob/f5678bf4ac35cffc0ff7174ad85f7fdc2a5c977e/pre_commit/git.py#L27
+func filterGitEnviron(envs []string) []string {
+ var filtered []string
+
+ for _, env := range envs {
+ if !strings.HasPrefix(env, "GIT_") {
+ filtered = append(filtered, env)
+ continue
+ }
+
+ if strings.HasPrefix(env, "GIT_CONFIG_KEY_") || strings.HasPrefix(env, "GIT_CONFIG_VALUE_") {
+ filtered = append(filtered, env)
+ continue
+ }
+
+ key, _, _ := strings.Cut(env, "=")
+
+ switch key {
+ case "GIT_EXEC_PATH", "GIT_SSH", "GIT_SSH_COMMAND", "GIT_SSL_CAINFO",
+ "GIT_SSL_NO_VERIFY", "GIT_CONFIG_COUNT",
+ "GIT_HTTP_PROXY_AUTHMETHOD",
+ "GIT_ALLOW_PROTOCOL",
+ "GIT_ASKPASS":
+ filtered = append(filtered, env)
+ }
+ }
+
+ return filtered
+}
diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/migrate.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/migrate.go
index 7012e9226..cfc5eb015 100644
--- a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/migrate.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/migrate.go
@@ -7,12 +7,13 @@ import (
"path/filepath"
"strings"
- "github.com/charmbracelet/lipgloss"
+ "charm.land/lipgloss/v2"
"github.com/fatih/color"
"github.com/santhosh-tekuri/jsonschema/v6"
"github.com/spf13/cobra"
"github.com/spf13/viper"
+ jsonsch "github.com/golangci/golangci-lint/v2/jsonschema"
"github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate"
"github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/fakeloader"
"github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/parser"
@@ -153,7 +154,7 @@ func (c *migrateCommand) preRunE(cmd *cobra.Command, _ []string) error {
c.log.Infof("Validating v1 configuration file: %s", usedConfigFile)
- err := validateConfiguration("https://golangci-lint.run/jsonschema/golangci.v1.jsonschema.json", usedConfigFile)
+ err := validateConfiguration(jsonsch.V1Schema, usedConfigFile)
if err != nil {
var v *jsonschema.ValidationError
if !errors.As(err, &v) {
diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/run.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/run.go
index 93efa6d9c..84c470152 100644
--- a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/run.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/run.go
@@ -25,7 +25,6 @@ import (
"github.com/spf13/cobra"
"github.com/spf13/pflag"
"github.com/spf13/viper"
- "go.uber.org/automaxprocs/maxprocs"
"go.yaml.in/yaml/v3"
"golang.org/x/mod/sumdb/dirhash"
@@ -160,16 +159,8 @@ func (c *runCommand) persistentPreRunE(cmd *cobra.Command, args []string) error
return fmt.Errorf("can't load config: %w", err)
}
- if c.cfg.Run.Concurrency == 0 {
- // `runtime.GOMAXPROCS` defaults to the value of `runtime.NumCPU`.
- backup := runtime.GOMAXPROCS(0)
-
- // Automatically set GOMAXPROCS to match Linux container CPU quota.
- _, err := maxprocs.Set(maxprocs.Logger(c.log.Infof))
- if err != nil {
- runtime.GOMAXPROCS(backup)
- }
- } else {
+ // https://go.dev/doc/go1.25#container-aware-gomaxprocs
+ if c.cfg.Run.Concurrency != 0 {
runtime.GOMAXPROCS(c.cfg.Run.Concurrency)
}
@@ -722,7 +713,8 @@ func computeGoModSalt() (string, error) {
return "", fmt.Errorf("failed to read go.mod: %w", err)
}
- sum, err := dirhash.Hash1([]string{goModPath}, func(string) (io.ReadCloser, error) {
+ // NOTE: the variable `goModPath` is not used here to ensure getting the same hash, independently of the location, for the same content.
+ sum, err := dirhash.Hash1([]string{"go.mod"}, func(string) (io.ReadCloser, error) {
return io.NopCloser(bytes.NewReader(data)), nil
})
if err != nil {
diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/config/linters_settings.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/config/linters_settings.go
index 6c8554d99..7f001da34 100644
--- a/vendor/github.com/golangci/golangci-lint/v2/pkg/config/linters_settings.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/config/linters_settings.go
@@ -141,17 +141,20 @@ var defaultLintersSettings = LintersSettings{
Predeclared: PredeclaredSettings{
Qualified: false,
},
- SlogLint: SlogLintSettings{
- NoMixedArgs: true,
- KVOnly: false,
- AttrOnly: false,
+ Sloglint: SloglintSettings{
NoGlobal: "",
Context: "",
StaticMsg: false,
+ MsgStyle: "",
+ NoMixedArgs: true,
+ KVOnly: false,
+ AttrOnly: false,
+ ArgsOnSepLines: false,
NoRawKeys: false,
+ AllowedKeys: []string{},
+ ForbiddenKeys: []string{},
KeyNamingCase: "",
- ForbiddenKeys: nil,
- ArgsOnSepLines: false,
+ CustomFuncs: []SloglintCustomFunc{},
},
TagAlign: TagAlignSettings{
Align: true,
@@ -180,6 +183,9 @@ var defaultLintersSettings = LintersSettings{
SQLBoiler: true,
Jet: true,
},
+ CheckN1: false,
+ CheckSQLInjection: false,
+ CheckTxLeak: false,
},
Unused: UnusedSettings{
FieldWritesAreUses: true,
@@ -223,13 +229,14 @@ var defaultLintersSettings = LintersSettings{
ForceExclusiveShortDeclarations: false,
},
WSLv5: WSLv5Settings{
- AllowFirstInBlock: true,
- AllowWholeBlock: false,
- BranchMaxLines: 2,
- CaseMaxLines: 0,
- Default: "default",
- Enable: nil,
- Disable: nil,
+ AllowFirstInBlock: true,
+ AllowWholeBlock: false,
+ BranchMaxLines: 2,
+ CaseMaxLines: 0,
+ CuddleMaxStatements: 1,
+ Default: "default",
+ Enable: nil,
+ Disable: nil,
},
}
@@ -238,6 +245,7 @@ type LintersSettings struct {
Asasalint AsasalintSettings `mapstructure:"asasalint"`
BiDiChk BiDiChkSettings `mapstructure:"bidichk"`
+ BodyClose BodyCloseSettings `mapstructure:"bodyclose"`
CopyLoopVar CopyLoopVarSettings `mapstructure:"copyloopvar"`
Cyclop CyclopSettings `mapstructure:"cyclop"`
Decorder DecorderSettings `mapstructure:"decorder"`
@@ -267,6 +275,7 @@ type LintersSettings struct {
Goheader GoHeaderSettings `mapstructure:"goheader"`
GoModDirectives GoModDirectivesSettings `mapstructure:"gomoddirectives"`
Gomodguard GoModGuardSettings `mapstructure:"gomodguard"`
+ Gomodguardv2 GoModGuardv2Settings `mapstructure:"gomodguard_v2"`
Gosec GoSecSettings `mapstructure:"gosec"`
Gosmopolitan GosmopolitanSettings `mapstructure:"gosmopolitan"`
Unqueryvet UnqueryvetSettings `mapstructure:"unqueryvet"`
@@ -303,7 +312,7 @@ type LintersSettings struct {
Recvcheck RecvcheckSettings `mapstructure:"recvcheck"`
Revive ReviveSettings `mapstructure:"revive"`
RowsErrCheck RowsErrCheckSettings `mapstructure:"rowserrcheck"`
- SlogLint SlogLintSettings `mapstructure:"sloglint"`
+ Sloglint SloglintSettings `mapstructure:"sloglint"`
Spancheck SpancheckSettings `mapstructure:"spancheck"`
Staticcheck StaticCheckSettings `mapstructure:"staticcheck"`
TagAlign TagAlignSettings `mapstructure:"tagalign"`
@@ -356,6 +365,10 @@ type BiDiChkSettings struct {
PopDirectionalIsolate bool `mapstructure:"pop-directional-isolate"`
}
+type BodyCloseSettings struct {
+ CheckConsumption bool `mapstructure:"check-consumption"`
+}
+
type CopyLoopVarSettings struct {
CheckAlias bool `mapstructure:"check-alias"`
}
@@ -523,6 +536,11 @@ type GoConstSettings struct {
IgnoreCalls bool `mapstructure:"ignore-calls"`
FindDuplicates bool `mapstructure:"find-duplicates"`
EvalConstExpressions bool `mapstructure:"eval-const-expressions"`
+ IgnoreFunctions []string `mapstructure:"ignore-functions"`
+
+ // This option cannot be managed with `linters.exclusions.rules`.
+ // Because the linter counts occurrences across all files in the package.
+ IgnoreTests bool `mapstructure:"ignore-tests"`
// Deprecated: use IgnoreStringValues instead.
IgnoreStrings string `mapstructure:"ignore-strings"`
@@ -593,6 +611,26 @@ type GoModDirectivesSettings struct {
CheckModulePath bool `mapstructure:"check-module-path"`
}
+type GoModGuardv2Settings struct {
+ Allowed []GoModGuardv2Base `mapstructure:"allowed"`
+ Blocked []GoModGuardv2Blocked `mapstructure:"blocked"`
+ LocalReplaceDirectives bool `mapstructure:"local-replace-directives"`
+}
+
+type GoModGuardv2Base struct {
+ Module string `mapstructure:"module"`
+ Version string `mapstructure:"version"`
+ MatchType string `mapstructure:"match-type"`
+}
+
+type GoModGuardv2Blocked struct {
+ GoModGuardv2Base `mapstructure:",squash"`
+
+ Recommendations []string `mapstructure:"recommendations"`
+ Reason string `mapstructure:"reason"`
+}
+
+// Deprecated: use GoModGuardv2Settings instead.
type GoModGuardSettings struct {
Allowed GoModGuardAllowed `mapstructure:"allowed"`
Blocked GoModGuardBlocked `mapstructure:"blocked"`
@@ -796,6 +834,7 @@ type ParallelTestSettings struct {
Go string `mapstructure:"-"`
IgnoreMissing bool `mapstructure:"ignore-missing"`
IgnoreMissingSubtests bool `mapstructure:"ignore-missing-subtests"`
+ CheckCleanup bool `mapstructure:"check-cleanup"`
}
type PerfSprintSettings struct {
@@ -879,18 +918,26 @@ type RowsErrCheckSettings struct {
Packages []string `mapstructure:"packages"`
}
-type SlogLintSettings struct {
- NoMixedArgs bool `mapstructure:"no-mixed-args"`
- KVOnly bool `mapstructure:"kv-only"`
- AttrOnly bool `mapstructure:"attr-only"`
- NoGlobal string `mapstructure:"no-global"`
- Context string `mapstructure:"context"`
- StaticMsg bool `mapstructure:"static-msg"`
- MsgStyle string `mapstructure:"msg-style"`
- NoRawKeys bool `mapstructure:"no-raw-keys"`
- KeyNamingCase string `mapstructure:"key-naming-case"`
- ForbiddenKeys []string `mapstructure:"forbidden-keys"`
- ArgsOnSepLines bool `mapstructure:"args-on-sep-lines"`
+type SloglintSettings struct {
+ NoGlobal string `mapstructure:"no-global"`
+ Context string `mapstructure:"context"`
+ StaticMsg bool `mapstructure:"static-msg"`
+ MsgStyle string `mapstructure:"msg-style"`
+ NoMixedArgs bool `mapstructure:"no-mixed-args"`
+ KVOnly bool `mapstructure:"kv-only"`
+ AttrOnly bool `mapstructure:"attr-only"`
+ ArgsOnSepLines bool `mapstructure:"args-on-sep-lines"`
+ NoRawKeys bool `mapstructure:"no-raw-keys"`
+ AllowedKeys []string `mapstructure:"allowed-keys"`
+ ForbiddenKeys []string `mapstructure:"forbidden-keys"`
+ KeyNamingCase string `mapstructure:"key-naming-case"`
+ CustomFuncs []SloglintCustomFunc `mapstructure:"custom-funcs"`
+}
+
+type SloglintCustomFunc struct {
+ Name string `mapstructure:"name"`
+ MsgPos int `mapstructure:"msg-pos"`
+ ArgsPos int `mapstructure:"args-pos"`
}
type SpancheckSettings struct {
@@ -1045,7 +1092,12 @@ type UnqueryvetSettings struct {
CheckFormatStrings bool `mapstructure:"check-format-strings"`
CheckStringBuilder bool `mapstructure:"check-string-builder"`
CheckSubqueries bool `mapstructure:"check-subqueries"`
+ CheckN1 bool `mapstructure:"check-n1"`
+ CheckSQLInjection bool `mapstructure:"check-sql-injection"`
+ CheckTxLeak bool `mapstructure:"check-tx-leaks"`
SQLBuilders UnqueryvetSQLBuildersSettings `mapstructure:"sql-builders"`
+ Allow []string `mapstructure:"allow"`
+ CustomRules []UnqueryvetCustomRule `mapstructure:"custom-rules"`
}
type UnqueryvetSQLBuildersSettings struct {
@@ -1059,6 +1111,15 @@ type UnqueryvetSQLBuildersSettings struct {
Jet bool `mapstructure:"jet"`
}
+type UnqueryvetCustomRule struct {
+ ID string `mapstructure:"id"`
+ Pattern string `mapstructure:"pattern"`
+ Patterns []string `mapstructure:"patterns"`
+ When string `mapstructure:"when"`
+ Message string `mapstructure:"message"`
+ Action string `mapstructure:"action"`
+}
+
type UnusedSettings struct {
FieldWritesAreUses bool `mapstructure:"field-writes-are-uses"`
PostStatementsAreReads bool `mapstructure:"post-statements-are-reads"`
@@ -1114,13 +1175,14 @@ type WSLv4Settings struct {
}
type WSLv5Settings struct {
- AllowFirstInBlock bool `mapstructure:"allow-first-in-block"`
- AllowWholeBlock bool `mapstructure:"allow-whole-block"`
- BranchMaxLines int `mapstructure:"branch-max-lines"`
- CaseMaxLines int `mapstructure:"case-max-lines"`
- Default string `mapstructure:"default"`
- Enable []string `mapstructure:"enable"`
- Disable []string `mapstructure:"disable"`
+ AllowFirstInBlock bool `mapstructure:"allow-first-in-block"`
+ AllowWholeBlock bool `mapstructure:"allow-whole-block"`
+ BranchMaxLines int `mapstructure:"branch-max-lines"`
+ CaseMaxLines int `mapstructure:"case-max-lines"`
+ CuddleMaxStatements int `mapstructure:"cuddle-max-statements"`
+ Default string `mapstructure:"default"`
+ Enable []string `mapstructure:"enable"`
+ Disable []string `mapstructure:"disable"`
}
// CustomLinterSettings encapsulates the meta-data of a private linter.
diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/config/run.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/config/run.go
index dcddf0cb6..358557c06 100644
--- a/vendor/github.com/golangci/golangci-lint/v2/pkg/config/run.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/config/run.go
@@ -21,6 +21,7 @@ type Run struct {
BuildTags []string `mapstructure:"build-tags"`
ModulesDownloadMode string `mapstructure:"modules-download-mode"`
+ EnableBuildVCS bool `mapstructure:"enable-build-vcs"`
ExitCodeIfIssuesFound int `mapstructure:"issues-exit-code"`
AnalyzeTests bool `mapstructure:"tests"`
diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/runner.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/runner.go
index ba9c0bd06..2e7d30c76 100644
--- a/vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/runner.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/runner.go
@@ -270,13 +270,9 @@ func (r *runner) analyze(pkgs []*packages.Package, analyzers []*analysis.Analyze
for _, lp := range loadingPackages {
if lp.isInitial {
- wg.Add(1)
-
- go func(lp *loadingPackage) {
+ wg.Go(func() {
lp.analyzeRecursive(ctx, cancel, r.loadMode, loadSem)
-
- wg.Done()
- }(lp)
+ })
}
}
diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/runner_action.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/runner_action.go
index eafc2e4d8..1ee3c4435 100644
--- a/vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/runner_action.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/runner_action.go
@@ -63,9 +63,10 @@ func (act *action) markDepsForAnalyzingSource() {
// Horizontal deps (analyzer.Requires) must be loaded from source and analyzed before analyzing
// this action.
for _, dep := range act.Deps {
- if dep.Package == act.Package {
+ if dep.Package == act.Package && !dep.needAnalyzeSource {
// Analyze source only for horizontal dependencies, e.g. from "buildssa".
dep.needAnalyzeSource = true // can't be set in parallel
+ dep.markDepsForAnalyzingSource()
}
}
}
diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/runner_action_cache.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/runner_action_cache.go
index 2cf4dcfca..1fafbca57 100644
--- a/vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/runner_action_cache.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/runner_action_cache.go
@@ -96,23 +96,22 @@ func (act *action) loadPersistedFacts() bool {
for _, f := range facts {
if f.Path == "" { // this is a package fact
- key := packageFactKey{act.Package.Types, act.factType(f.Fact)}
+ key := packageFactKey{pkg: act.Package.Types, typ: act.factType(f.Fact)}
act.packageFacts[key] = f.Fact
continue
}
obj, err := objectpath.Object(act.Package.Types, objectpath.Path(f.Path))
if err != nil {
- // Be lenient about these errors. For example, when
- // analyzing io/ioutil from source, we may get a fact
- // for methods on the devNull type, and objectpath
- // will happily create a path for them. However, when
- // we later load io/ioutil from export data, the path
- // no longer resolves.
+ // Be lenient about these errors.
+ // For example, when analyzing io/ioutil from source,
+ // we may get a fact for methods on the devNull type,
+ // and objectpath will happily create a path for them.
+ // However,
+ // when we later load io/ioutil from export data,
+ // the path no longer resolves.
//
// If an exported type embeds the unexported type,
- // then (part of) the unexported type will become part
- // of the type information and our path will resolve
- // again.
+ // then (part of) the unexported type will become part of the type information and our path will resolve again.
continue
}
factKey := objectFactKey{obj, act.factType(f.Fact)}
diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/runner_checker.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/runner_checker.go
index e8fda9947..284aed2e6 100644
--- a/vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/runner_checker.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/runner_checker.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//
-// Altered copy of https://github.com/golang/tools/blob/v0.28.0/go/analysis/internal/checker/checker.go
+// Altered copy of https://github.com/golang/tools/blob/v0.43.0/go/analysis/checker/checker.go
package goanalysis
@@ -19,8 +19,7 @@ import (
"golang.org/x/tools/go/analysis"
"golang.org/x/tools/go/packages"
- "github.com/golangci/golangci-lint/v2/internal/x/tools/analysisflags"
- "github.com/golangci/golangci-lint/v2/internal/x/tools/analysisinternal"
+ "github.com/golangci/golangci-lint/v2/internal/x/tools/driverutil"
"github.com/golangci/golangci-lint/v2/pkg/goanalysis/pkgerrors"
)
@@ -134,9 +133,7 @@ func (act *action) analyze() {
module := &analysis.Module{} // possibly empty (non nil) in go/analysis drivers.
if mod := act.Package.Module; mod != nil {
- module.Path = mod.Path
- module.Version = mod.Version
- module.GoVersion = mod.GoVersion
+ module = analysisModuleFromPackagesModule(mod)
}
// Run the analysis.
@@ -161,7 +158,7 @@ func (act *action) analyze() {
AllObjectFacts: act.AllObjectFacts,
AllPackageFacts: act.AllPackageFacts,
}
- pass.ReadFile = analysisinternal.CheckedReadFile(pass, os.ReadFile)
+ pass.ReadFile = driverutil.CheckedReadFile(pass, os.ReadFile)
act.pass = pass
act.runner.passToPkgGuard.Lock()
@@ -199,7 +196,7 @@ func (act *action) analyze() {
// resolve diagnostic URLs
for i := range act.Diagnostics {
- url, err := analysisflags.ResolveURL(act.Analyzer, act.Diagnostics[i])
+ url, err := driverutil.ResolveURL(act.Analyzer, act.Diagnostics[i])
if err != nil {
return nil, err
}
@@ -324,7 +321,7 @@ func exportedFrom(obj types.Object, pkg *types.Package) bool {
switch obj := obj.(type) {
case *types.Func:
return obj.Exported() && obj.Pkg() == pkg ||
- obj.Type().(*types.Signature).Recv() != nil
+ obj.Signature().Recv() != nil
case *types.Var:
if obj.IsField() {
return true
@@ -387,8 +384,8 @@ func (act *action) exportObjectFact(obj types.Object, fact analysis.Fact) {
// See documentation at AllObjectFacts field of [analysis.Pass].
func (act *action) AllObjectFacts() []analysis.ObjectFact {
facts := make([]analysis.ObjectFact, 0, len(act.objectFacts))
- for k := range act.objectFacts {
- facts = append(facts, analysis.ObjectFact{Object: k.obj, Fact: act.objectFacts[k]})
+ for k, fact := range act.objectFacts {
+ facts = append(facts, analysis.ObjectFact{Object: k.obj, Fact: fact})
}
return facts
}
@@ -427,7 +424,7 @@ func (act *action) exportPackageFact(fact analysis.Fact) {
// NOTE(ldez) altered: add receiver to handle logs.
func (act *action) factType(fact analysis.Fact) reflect.Type {
t := reflect.TypeOf(fact)
- if t.Kind() != reflect.Ptr {
+ if t.Kind() != reflect.Pointer {
act.runner.log.Fatalf("invalid Fact type: got %T, want pointer", fact)
}
return t
@@ -445,3 +442,30 @@ func (act *action) AllPackageFacts() []analysis.PackageFact {
}
return facts
}
+
+// NOTE(ldez) no alteration.
+func analysisModuleFromPackagesModule(mod *packages.Module) *analysis.Module {
+ if mod == nil {
+ return nil
+ }
+
+ var modErr *analysis.ModuleError
+ if mod.Error != nil {
+ modErr = &analysis.ModuleError{
+ Err: mod.Error.Err,
+ }
+ }
+
+ return &analysis.Module{
+ Path: mod.Path,
+ Version: mod.Version,
+ Replace: analysisModuleFromPackagesModule(mod.Replace),
+ Time: mod.Time,
+ Main: mod.Main,
+ Indirect: mod.Indirect,
+ Dir: mod.Dir,
+ GoMod: mod.GoMod,
+ GoVersion: mod.GoVersion,
+ Error: modErr,
+ }
+}
diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/runner_loadingpackage.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/runner_loadingpackage.go
index 217803bba..e01d3eaa2 100644
--- a/vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/runner_loadingpackage.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/runner_loadingpackage.go
@@ -46,14 +46,10 @@ func (lp *loadingPackage) analyzeRecursive(ctx context.Context, cancel context.C
// Load the direct dependencies, in parallel.
var wg sync.WaitGroup
- wg.Add(len(lp.imports))
-
for _, imp := range lp.imports {
- go func(imp *loadingPackage) {
+ wg.Go(func() {
imp.analyzeRecursive(ctx, cancel, loadMode, loadSem)
-
- wg.Done()
- }(imp)
+ })
}
wg.Wait()
@@ -517,7 +513,7 @@ func sizeOfValueTreeBytes(v any) int {
func sizeOfReflectValueTreeBytes(rv reflect.Value, visitedPtrs map[uintptr]struct{}) int {
switch rv.Kind() {
- case reflect.Ptr:
+ case reflect.Pointer:
ptrSize := int(rv.Type().Size())
if rv.IsNil() {
return ptrSize
diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/runners_cache.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/runners_cache.go
index 5cd8a6b1c..b74d4f94f 100644
--- a/vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/runners_cache.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/runners_cache.go
@@ -25,17 +25,15 @@ func saveIssuesToCache(allPkgs []*packages.Package, pkgsFromCache map[*packages.
perPkgIssues[issue.Pkg] = append(perPkgIssues[issue.Pkg], issue)
}
- var savedIssuesCount int64 = 0
+ var savedIssuesCount int64
lintResKey := getIssuesCacheKey(analyzers)
workerCount := runtime.GOMAXPROCS(-1)
var wg sync.WaitGroup
- wg.Add(workerCount)
pkgCh := make(chan *packages.Package, len(allPkgs))
for range workerCount {
- go func() {
- defer wg.Done()
+ wg.Go(func() {
for pkg := range pkgCh {
pkgIssues := perPkgIssues[pkg]
encodedIssues := make([]EncodingIssue, 0, len(pkgIssues))
@@ -59,7 +57,7 @@ func saveIssuesToCache(allPkgs []*packages.Package, pkgsFromCache map[*packages.
issuesCacheDebugf("Saved package %s issues (%d) to cache", pkg, len(pkgIssues))
}
}
- }()
+ })
}
for _, pkg := range allPkgs {
@@ -94,12 +92,10 @@ func loadIssuesFromCache(pkgs []*packages.Package, lintCtx *linter.Context,
workerCount := runtime.GOMAXPROCS(-1)
var wg sync.WaitGroup
- wg.Add(workerCount)
pkgCh := make(chan *packages.Package, len(pkgs))
for range workerCount {
- go func() {
- defer wg.Done()
+ wg.Go(func() {
for pkg := range pkgCh {
var pkgIssues []*EncodingIssue
err := lintCtx.PkgCache.Get(pkg, cache.HashModeNeedAllDeps, lintResKey, &pkgIssues)
@@ -128,7 +124,7 @@ func loadIssuesFromCache(pkgs []*packages.Package, lintCtx *linter.Context,
}
cacheRes.issues = issues
}
- }()
+ })
}
for _, pkg := range pkgs {
diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/goformat/runner.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/goformat/runner.go
index 650fb8f5e..ac70dc70a 100644
--- a/vendor/github.com/golangci/golangci-lint/v2/pkg/goformat/runner.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/goformat/runner.go
@@ -97,6 +97,9 @@ func (c *Runner) walk(root string, stdout *os.File) error {
return err
}
+ //nolint:gosec // See explanation below.
+ // `path` contains the `root` but when using `r, err := os.OpenRoot(root)`, this part is not inside the file tree of `r`.
+ // `filepath.Rel()` can be used but it seems overkill in the context and doesn't work well with a file.
in, err := os.Open(path)
if err != nil {
return err
diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/goformatters/gci/internal/section/standard_list.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/goformatters/gci/internal/section/standard_list.go
index f84eb0f33..a7787409e 100644
--- a/vendor/github.com/golangci/golangci-lint/v2/pkg/goformatters/gci/internal/section/standard_list.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/goformatters/gci/internal/section/standard_list.go
@@ -1,6 +1,6 @@
package section
-// Code generated based on go1.25.0 X:boringcrypto,arenas,synctest,jsonv2. DO NOT EDIT.
+// Code generated based on go1.26.0 X:boringcrypto,arenas,jsonv2,runtimesecret. DO NOT EDIT.
var standardPackages = map[string]struct{}{
"archive/tar": {},
@@ -31,8 +31,10 @@ var standardPackages = map[string]struct{}{
"crypto/fips140": {},
"crypto/hkdf": {},
"crypto/hmac": {},
+ "crypto/hpke": {},
"crypto/md5": {},
"crypto/mlkem": {},
+ "crypto/mlkem/mlkemtest": {},
"crypto/pbkdf2": {},
"crypto/rand": {},
"crypto/rc4": {},
@@ -154,6 +156,7 @@ var standardPackages = map[string]struct{}{
"runtime/metrics": {},
"runtime/pprof": {},
"runtime/race": {},
+ "runtime/secret": {},
"runtime/trace": {},
"slices": {},
"sort": {},
@@ -165,6 +168,7 @@ var standardPackages = map[string]struct{}{
"syscall": {},
"syscall/js": {},
"testing": {},
+ "testing/cryptotest": {},
"testing/fstest": {},
"testing/iotest": {},
"testing/quick": {},
diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/bodyclose/bodyclose.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/bodyclose/bodyclose.go
index f68c4d0a9..95cf790bc 100644
--- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/bodyclose/bodyclose.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/bodyclose/bodyclose.go
@@ -3,11 +3,21 @@ package bodyclose
import (
"github.com/timakin/bodyclose/passes/bodyclose"
+ "github.com/golangci/golangci-lint/v2/pkg/config"
"github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
-func New() *goanalysis.Linter {
+func New(settings *config.BodyCloseSettings) *goanalysis.Linter {
+ var cfg map[string]any
+
+ if settings != nil {
+ cfg = map[string]any{
+ "check-consumption": settings.CheckConsumption,
+ }
+ }
+
return goanalysis.
NewLinterFromAnalyzer(bodyclose.Analyzer).
+ WithConfig(cfg).
WithLoadMode(goanalysis.LoadModeTypesInfo)
}
diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/clickhouselint/clickhouselint.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/clickhouselint/clickhouselint.go
new file mode 100644
index 000000000..0459864bc
--- /dev/null
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/clickhouselint/clickhouselint.go
@@ -0,0 +1,18 @@
+package clickhouselint
+
+import (
+ "github.com/ClickHouse/clickhouse-go-linter/passes/chbatchclose"
+ "github.com/ClickHouse/clickhouse-go-linter/passes/chrowserr"
+ "golang.org/x/tools/go/analysis"
+
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
+)
+
+func New() *goanalysis.Linter {
+ return goanalysis.NewLinter(
+ "clickhouselint",
+ "Detects common mistakes with the ClickHouse native Go driver API.",
+ []*analysis.Analyzer{chrowserr.NewAnalyzer(), chbatchclose.NewAnalyzer()},
+ nil,
+ ).WithLoadMode(goanalysis.LoadModeTypesInfo)
+}
diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/goconst/goconst.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/goconst/goconst.go
index b58d860c6..be2312247 100644
--- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/goconst/goconst.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/goconst/goconst.go
@@ -50,6 +50,7 @@ func New(settings *config.GoConstSettings) *goanalysis.Linter {
func runGoconst(pass *analysis.Pass, settings *config.GoConstSettings) ([]*goanalysis.Issue, error) {
cfg := goconstAPI.Config{
IgnoreStrings: settings.IgnoreStringValues,
+ IgnoreTests: settings.IgnoreTests,
MatchWithConstants: settings.MatchWithConstants,
MinStringLength: settings.MinStringLen,
MinOccurrences: settings.MinOccurrencesCount,
@@ -59,9 +60,7 @@ func runGoconst(pass *analysis.Pass, settings *config.GoConstSettings) ([]*goana
ExcludeTypes: map[goconstAPI.Type]bool{},
FindDuplicates: settings.FindDuplicates,
EvalConstExpressions: settings.EvalConstExpressions,
-
- // Should be managed with `linters.exclusions.rules`.
- IgnoreTests: false,
+ IgnoreFunctions: settings.IgnoreFunctions,
}
if settings.IgnoreCalls {
diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/gomodguard/gomodguard.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/gomodguard/gomodguard.go
index 7d16f57b3..b8bdd0965 100644
--- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/gomodguard/gomodguard.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/gomodguard/gomodguard.go
@@ -87,3 +87,66 @@ func New(settings *config.GoModGuardSettings) *goanalysis.Linter {
}).
WithLoadMode(goanalysis.LoadModeSyntax)
}
+
+// Only used the set YAML struct tags.
+type v2YAML struct {
+ Allowed []goModGuardv2Base `yaml:"allowed,omitempty"`
+ Blocked []goModGuardv2Blocked `yaml:"blocked,omitempty"`
+ LocalReplaceDirectives bool `yaml:"local-replace-directives,omitempty"`
+}
+
+// Only used the set YAML struct tags.
+type goModGuardv2Base struct {
+ Module string `yaml:"module,omitempty"`
+ Version string `yaml:"version,omitempty"`
+ MatchType string `yaml:"match-type,omitempty"`
+}
+
+// Only used the set YAML struct tags.
+type goModGuardv2Blocked struct {
+ goModGuardv2Base `yaml:",inline"`
+
+ Recommendations []string `yaml:"recommendations,omitempty"`
+ Reason string `yaml:"reason,omitempty"`
+}
+
+func Migration(old *config.GoModGuardSettings) any {
+ if old == nil {
+ return nil
+ }
+
+ if len(old.Allowed.Modules) == 0 && len(old.Allowed.Domains) == 0 && len(old.Blocked.Modules) == 0 && !old.Blocked.LocalReplaceDirectives {
+ return nil
+ }
+
+ cfg := &v2YAML{
+ LocalReplaceDirectives: old.Blocked.LocalReplaceDirectives,
+ }
+
+ for _, module := range old.Allowed.Modules {
+ cfg.Allowed = append(cfg.Allowed, goModGuardv2Base{
+ Module: module,
+ })
+ }
+
+ for _, domain := range old.Allowed.Domains {
+ cfg.Allowed = append(cfg.Allowed, goModGuardv2Base{
+ Module: domain + "/.*",
+ MatchType: "regex",
+ })
+ }
+
+ for _, blocked := range old.Blocked.Modules {
+ for name, module := range blocked {
+ cfg.Blocked = append(cfg.Blocked, goModGuardv2Blocked{
+ goModGuardv2Base: goModGuardv2Base{
+ Module: name,
+ },
+ Recommendations: module.Recommendations,
+ Reason: module.Reason,
+ })
+ }
+ }
+
+ return cfg
+}
diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/gomodguard/gomodguard_v2.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/gomodguard/gomodguard_v2.go
new file mode 100644
index 000000000..d25e72060
--- /dev/null
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/gomodguard/gomodguard_v2.go
@@ -0,0 +1,106 @@
+package gomodguard
+
+import (
+ "sync"
+
+ "github.com/Masterminds/semver/v3"
+ "github.com/ryancurrah/gomodguard/v2"
+ "golang.org/x/tools/go/analysis"
+
+ "github.com/golangci/golangci-lint/v2/pkg/config"
+ "github.com/golangci/golangci-lint/v2/pkg/goanalysis"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/internal"
+ "github.com/golangci/golangci-lint/v2/pkg/lint/linter"
+ "github.com/golangci/golangci-lint/v2/pkg/result"
+)
+
+const linterNameV2 = "gomodguard_v2"
+
+func NewV2(settings *config.GoModGuardv2Settings) *goanalysis.Linter {
+ var issues []*goanalysis.Issue
+ var mu sync.Mutex
+
+ processorCfg := &gomodguard.Configuration{}
+ if settings != nil {
+ processorCfg.LocalReplaceDirectives = settings.LocalReplaceDirectives
+
+ for _, allowed := range settings.Allowed {
+ rule := gomodguard.AllowedModule{
+ Module: allowed.Module,
+ MatchType: gomodguard.MatchType(allowed.MatchType),
+ Version: nil,
+ Matcher: nil,
+ }
+
+ if allowed.Version != "" {
+ var err error
+
+ rule.Version, err = semver.NewConstraint(allowed.Version)
+ if err != nil {
+ internal.LinterLogger.Fatalf("gomodguard: invalid constraint: %v", err)
+ }
+ }
+
+ processorCfg.Allowed = append(processorCfg.Allowed, rule)
+ }
+
+ for _, blocked := range settings.Blocked {
+ rule := gomodguard.BlockedModule{
+ Module: blocked.Module,
+ MatchType: gomodguard.MatchType(blocked.MatchType),
+ Recommendations: blocked.Recommendations,
+ Reason: blocked.Reason,
+ }
+
+ if blocked.Version != "" {
+ var err error
+
+ rule.Version, err = semver.NewConstraint(blocked.Version)
+ if err != nil {
+ internal.LinterLogger.Fatalf("gomodguard: invalid constraint: %v", err)
+ }
+ }
+
+ processorCfg.Blocked = append(processorCfg.Blocked, rule)
+ }
+ }
+
+ analyzer := &analysis.Analyzer{
+ Name: linterNameV2,
+ Doc: "Allow and blocklist linter for direct Go module dependencies. " +
+ "This is different from depguard where there are different block " +
+ "types for example version constraints and module recommendations.",
+ Run: goanalysis.DummyRun,
+ }
+
+ return goanalysis.NewLinterFromAnalyzer(analyzer).
+ WithContextSetter(func(lintCtx *linter.Context) {
+ processor, err := gomodguard.NewProcessor(processorCfg)
+ if err != nil {
+ lintCtx.Log.Warnf("running gomodguard failed: %s: if you are not using go modules "+
+ "it is suggested to disable this linter", err)
+ return
+ }
+
+ analyzer.Run = func(pass *analysis.Pass) (any, error) {
+ gomodguardIssues := processor.ProcessFiles(internal.GetGoFileNames(pass))
+
+ mu.Lock()
+ defer mu.Unlock()
+
+ for _, gomodguardIssue := range gomodguardIssues {
+ issues = append(issues, goanalysis.NewIssue(&result.Issue{
+ FromLinter: linterNameV2,
+ Pos: gomodguardIssue.Position,
+ Text: gomodguardIssue.Reason,
+ }, pass))
+ }
+
+ return nil, nil
+ }
+ }).
+ WithIssuesReporter(func(*linter.Context) []*goanalysis.Issue {
+ return issues
+ }).
+ WithLoadMode(goanalysis.LoadModeSyntax)
+}
diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/govet/govet.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/govet/govet.go
index 7755e4ec2..9f98f4054 100644
--- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/govet/govet.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/govet/govet.go
@@ -28,6 +28,7 @@ import (
"golang.org/x/tools/go/analysis/passes/httpmux"
"golang.org/x/tools/go/analysis/passes/httpresponse"
"golang.org/x/tools/go/analysis/passes/ifaceassert"
+ "golang.org/x/tools/go/analysis/passes/inline"
_ "golang.org/x/tools/go/analysis/passes/inspect" // unused internal analyzer
"golang.org/x/tools/go/analysis/passes/loopclosure"
"golang.org/x/tools/go/analysis/passes/lostcancel"
@@ -83,6 +84,7 @@ var (
httpmux.Analyzer,
httpresponse.Analyzer,
ifaceassert.Analyzer,
+ inline.Analyzer,
loopclosure.Analyzer,
lostcancel.Analyzer,
nilfunc.Analyzer,
@@ -109,7 +111,8 @@ var (
waitgroup.Analyzer,
}
- // https://github.com/golang/go/blob/go1.25.2/src/cmd/vet/main.go#L57-L91
+ // https://github.com/golang/go/blob/go1.26.1/src/cmd/vet/main.go#L63-L99
+ // https://github.com/golang/go/blob/go1.26.1/src/cmd/fix/main.go#L47-L51
defaultAnalyzers = []*analysis.Analyzer{
appends.Analyzer,
asmdecl.Analyzer,
@@ -127,6 +130,7 @@ var (
hostport.Analyzer,
httpresponse.Analyzer,
ifaceassert.Analyzer,
+ inline.Analyzer,
loopclosure.Analyzer,
lostcancel.Analyzer,
nilfunc.Analyzer,
diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/paralleltest/paralleltest.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/paralleltest/paralleltest.go
index f3eac2e05..be052628b 100644
--- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/paralleltest/paralleltest.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/paralleltest/paralleltest.go
@@ -14,6 +14,7 @@ func New(settings *config.ParallelTestSettings) *goanalysis.Linter {
cfg = map[string]any{
"i": settings.IgnoreMissing,
"ignoremissingsubtests": settings.IgnoreMissingSubtests,
+ "checkcleanup": settings.CheckCleanup,
}
if config.IsGoGreaterThanOrEqual(settings.Go, "1.22") {
diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/prealloc/prealloc.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/prealloc/prealloc.go
index 3dbe3822a..cc209feff 100644
--- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/prealloc/prealloc.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/prealloc/prealloc.go
@@ -14,18 +14,10 @@ func New(settings *config.PreallocSettings) *goanalysis.Linter {
Name: "prealloc",
Doc: "Find slice declarations that could potentially be pre-allocated",
Run: func(pass *analysis.Pass) (any, error) {
- runPreAlloc(pass, settings)
+ pkg.Check(pass, settings.Simple, settings.RangeLoops, settings.ForLoops)
return nil, nil
},
}).
- WithLoadMode(goanalysis.LoadModeSyntax)
-}
-
-func runPreAlloc(pass *analysis.Pass, settings *config.PreallocSettings) {
- hints := pkg.Check(pass.Files, settings.Simple, settings.RangeLoops, settings.ForLoops)
-
- for _, hint := range hints {
- pass.Report(hint)
- }
+ WithLoadMode(goanalysis.LoadModeTypesInfo)
}
diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/revive/revive.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/revive/revive.go
index 63d710d32..7fe736f20 100644
--- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/revive/revive.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/revive/revive.go
@@ -209,9 +209,11 @@ func getConfig(cfg *config.ReviveSettings) (*lint.Config, error) {
}
func createConfigMap(cfg *config.ReviveSettings) map[string]any {
+ const severity = "severity"
+
rawRoot := map[string]any{
"confidence": cfg.Confidence,
- "severity": cfg.Severity,
+ severity: cfg.Severity,
"errorCode": cfg.ErrorCode,
"warningCode": cfg.WarningCode,
"enableAllRules": cfg.EnableAllRules,
@@ -224,7 +226,7 @@ func createConfigMap(cfg *config.ReviveSettings) map[string]any {
rawDirectives := map[string]map[string]any{}
for _, directive := range cfg.Directives {
rawDirectives[directive.Name] = map[string]any{
- "severity": directive.Severity,
+ severity: directive.Severity,
}
}
@@ -235,7 +237,7 @@ func createConfigMap(cfg *config.ReviveSettings) map[string]any {
rawRules := map[string]map[string]any{}
for _, s := range cfg.Rules {
rawRules[s.Name] = map[string]any{
- "severity": s.Severity,
+ severity: s.Severity,
"arguments": safeTomlSlice(s.Arguments),
"disabled": s.Disabled,
"exclude": s.Exclude,
@@ -272,7 +274,7 @@ func safeTomlSlice(r []any) []any {
}
// This element is not exported by revive, so we need copy the code.
-// Extracted from https://github.com/mgechev/revive/blob/v1.13.0/config/config.go#L16
+// Extracted from https://github.com/mgechev/revive/blob/v1.15.0/config/config.go#L16
var defaultRules = []lint.Rule{
&rule.VarDeclarationsRule{},
&rule.PackageCommentsRule{},
@@ -324,6 +326,7 @@ var allRules = append([]lint.Rule{
&rule.EnforceRepeatedArgTypeStyleRule{},
&rule.EnforceSliceStyleRule{},
&rule.EnforceSwitchStyleRule{},
+ &rule.EpochNamingRule{},
&rule.FileHeaderRule{},
&rule.FileLengthLimitRule{},
&rule.FilenameFormatRule{},
@@ -350,6 +353,7 @@ var allRules = append([]lint.Rule{
&rule.NestedStructs{},
&rule.OptimizeOperandsOrderRule{},
&rule.PackageDirectoryMismatchRule{},
+ &rule.PackageNamingRule{},
&rule.RangeValAddress{},
&rule.RangeValInClosureRule{},
&rule.RedundantBuildTagRule{},
@@ -374,6 +378,7 @@ var allRules = append([]lint.Rule{
&rule.UseFmtPrintRule{},
&rule.UselessBreak{},
&rule.UselessFallthroughRule{},
+ &rule.UseSlicesSort{},
&rule.UseWaitGroupGoRule{},
&rule.WaitGroupByValueRule{},
}, defaultRules...)
diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/rowserrcheck/rowserrcheck.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/rowserrcheck/rowserrcheck.go
index de0fe4da9..572990390 100644
--- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/rowserrcheck/rowserrcheck.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/rowserrcheck/rowserrcheck.go
@@ -1,7 +1,7 @@
package rowserrcheck
import (
- "github.com/jingyugao/rowserrcheck/passes/rowserr"
+ "github.com/golangci/rowserrcheck/passes/rowserr"
"github.com/golangci/golangci-lint/v2/pkg/config"
"github.com/golangci/golangci-lint/v2/pkg/goanalysis"
diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/sloglint/sloglint.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/sloglint/sloglint.go
index 891f1fcfd..2db696e51 100644
--- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/sloglint/sloglint.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/sloglint/sloglint.go
@@ -7,22 +7,31 @@ import (
"github.com/golangci/golangci-lint/v2/pkg/goanalysis"
)
-func New(settings *config.SlogLintSettings) *goanalysis.Linter {
+func New(settings *config.SloglintSettings) *goanalysis.Linter {
var opts *sloglint.Options
if settings != nil {
opts = &sloglint.Options{
- NoMixedArgs: settings.NoMixedArgs,
- KVOnly: settings.KVOnly,
- AttrOnly: settings.AttrOnly,
- NoGlobal: settings.NoGlobal,
- ContextOnly: settings.Context,
- StaticMsg: settings.StaticMsg,
- MsgStyle: settings.MsgStyle,
- NoRawKeys: settings.NoRawKeys,
- KeyNamingCase: settings.KeyNamingCase,
- ForbiddenKeys: settings.ForbiddenKeys,
- ArgsOnSepLines: settings.ArgsOnSepLines,
+ NoGlobalLogger: settings.NoGlobal,
+ ContextOnly: settings.Context,
+ StaticMessage: settings.StaticMsg,
+ MessageStyle: settings.MsgStyle,
+ NoMixedArguments: settings.NoMixedArgs,
+ KeyValuePairsOnly: settings.KVOnly,
+ AttributesOnly: settings.AttrOnly,
+ ArgumentsOnSeparateLines: settings.ArgsOnSepLines,
+ ConstantKeys: settings.NoRawKeys,
+ AllowedKeys: settings.AllowedKeys,
+ ForbiddenKeys: settings.ForbiddenKeys,
+ KeyNamingCase: settings.KeyNamingCase,
+ }
+
+ for _, fn := range settings.CustomFuncs {
+ opts.CustomFuncs = append(opts.CustomFuncs, sloglint.Func{
+ FullName: fn.Name,
+ MessagePos: fn.MsgPos,
+ ArgumentsPos: fn.ArgsPos,
+ })
}
}
diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/sqlclosecheck/sqlclosecheck.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/sqlclosecheck/sqlclosecheck.go
index 4c970cc52..69872733e 100644
--- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/sqlclosecheck/sqlclosecheck.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/sqlclosecheck/sqlclosecheck.go
@@ -8,6 +8,6 @@ import (
func New() *goanalysis.Linter {
return goanalysis.
- NewLinterFromAnalyzer(analyzer.NewAnalyzer()).
+ NewLinterFromAnalyzer(analyzer.NewDeferOnlyAnalyzer()).
WithLoadMode(goanalysis.LoadModeTypesInfo)
}
diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/unqueryvet/unqueryvet.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/unqueryvet/unqueryvet.go
index c6aad8860..e2c185869 100644
--- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/unqueryvet/unqueryvet.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/unqueryvet/unqueryvet.go
@@ -12,15 +12,35 @@ func New(settings *config.UnqueryvetSettings) *goanalysis.Linter {
cfg := pkgconfig.DefaultSettings()
if settings != nil {
- // IgnoredFiles, and Severity are explicitly ignored.
+ // IgnoredFiles, Ignore, Severity, and Rules are explicitly ignored.
cfg.CheckSQLBuilders = settings.CheckSQLBuilders
cfg.CheckAliasedWildcard = settings.CheckAliasedWildcard
cfg.CheckStringConcat = settings.CheckStringConcat
cfg.CheckFormatStrings = settings.CheckFormatStrings
cfg.CheckStringBuilder = settings.CheckStringBuilder
cfg.CheckSubqueries = settings.CheckSubqueries
+ cfg.N1DetectionEnabled = settings.CheckN1
+ cfg.SQLInjectionDetectionEnabled = settings.CheckSQLInjection
+ cfg.TxLeakDetectionEnabled = settings.CheckTxLeak
cfg.IgnoredFunctions = settings.IgnoredFunctions
+ for _, rule := range settings.CustomRules {
+ // The field Fix is explicitly ignored.
+ cfg.CustomRules = append(cfg.CustomRules, pkgconfig.CustomRule{
+ ID: rule.ID,
+ Pattern: rule.Pattern,
+ Patterns: rule.Patterns,
+ When: rule.When,
+ Message: rule.Message,
+ Severity: "error",
+ Action: rule.Action,
+ })
+ }
+
+ if len(settings.Allow) > 0 {
+ cfg.Allow = settings.Allow
+ }
+
if len(settings.AllowedPatterns) > 0 {
cfg.AllowedPatterns = settings.AllowedPatterns
}
diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/wsl/wsl_v5.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/wsl/wsl_v5.go
index cb7b25628..8b8eef3f2 100644
--- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/wsl/wsl_v5.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/wsl/wsl_v5.go
@@ -18,12 +18,13 @@ func NewV5(settings *config.WSLv5Settings) *goanalysis.Linter {
}
conf = &wsl.Configuration{
- IncludeGenerated: true, // force to true because golangci-lint already has a way to filter generated files.
- AllowFirstInBlock: settings.AllowFirstInBlock,
- AllowWholeBlock: settings.AllowWholeBlock,
- BranchMaxLines: settings.BranchMaxLines,
- CaseMaxLines: settings.CaseMaxLines,
- Checks: checkSet,
+ IncludeGenerated: true, // force to true because golangci-lint already has a way to filter generated files.
+ AllowFirstInBlock: settings.AllowFirstInBlock,
+ AllowWholeBlock: settings.AllowWholeBlock,
+ BranchMaxLines: settings.BranchMaxLines,
+ CaseMaxLines: settings.CaseMaxLines,
+ CuddleMaxStatements: settings.CuddleMaxStatements,
+ Checks: checkSet,
}
}
diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/lint/linter/config.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/lint/linter/config.go
index a5b98413d..2386220db 100644
--- a/vendor/github.com/golangci/golangci-lint/v2/pkg/lint/linter/config.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/lint/linter/config.go
@@ -185,15 +185,18 @@ func Replacement[T any](replacement string, mgr func(T) any, data T) func(*Depre
encoder := yaml.NewEncoder(buf)
encoder.SetIndent(2)
+ linters := map[string]any{
+ "enable": []string{d.Replacement},
+ }
+
+ replacementSettings := mgr(data)
+
+ if replacementSettings != nil {
+ linters["settings"] = map[string]any{d.Replacement: replacementSettings}
+ }
+
suggestion := map[string]any{
- "linters": map[string]any{
- "enable": []string{
- d.Replacement,
- },
- "settings": map[string]any{
- d.Replacement: mgr(data),
- },
- },
+ "linters": linters,
}
err := encoder.Encode(suggestion)
diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/lint/lintersdb/builder_linter.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/lint/lintersdb/builder_linter.go
index b1abb6db9..2e9515b27 100644
--- a/vendor/github.com/golangci/golangci-lint/v2/pkg/lint/lintersdb/builder_linter.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/lint/lintersdb/builder_linter.go
@@ -9,6 +9,7 @@ import (
"github.com/golangci/golangci-lint/v2/pkg/golinters/bidichk"
"github.com/golangci/golangci-lint/v2/pkg/golinters/bodyclose"
"github.com/golangci/golangci-lint/v2/pkg/golinters/canonicalheader"
+ "github.com/golangci/golangci-lint/v2/pkg/golinters/clickhouselint"
"github.com/golangci/golangci-lint/v2/pkg/golinters/containedctx"
"github.com/golangci/golangci-lint/v2/pkg/golinters/contextcheck"
"github.com/golangci/golangci-lint/v2/pkg/golinters/copyloopvar"
@@ -132,7 +133,7 @@ func NewLinterBuilder() *LinterBuilder {
}
// Build loads all the "internal" linters.
-// The configuration is use for the linter settings.
+// The configuration is used for the linter settings.
func (LinterBuilder) Build(cfg *config.Config) ([]*linter.Config, error) {
if cfg == nil {
return nil, nil
@@ -161,7 +162,7 @@ func (LinterBuilder) Build(cfg *config.Config) ([]*linter.Config, error) {
WithSince("v1.43.0").
WithURL("https://github.com/breml/bidichk"),
- linter.NewConfig(bodyclose.New()).
+ linter.NewConfig(bodyclose.New(&cfg.Linters.Settings.BodyClose)).
WithSince("v1.18.0").
WithLoadForGoAnalysis().
WithURL("https://github.com/timakin/bodyclose"),
@@ -172,6 +173,11 @@ func (LinterBuilder) Build(cfg *config.Config) ([]*linter.Config, error) {
WithAutoFix().
WithURL("https://github.com/lasiar/canonicalheader"),
+ linter.NewConfig(clickhouselint.New()).
+ WithSince("v2.12.0").
+ WithLoadForGoAnalysis().
+ WithURL("https://github.com/ClickHouse/clickhouse-go-linter"),
+
linter.NewConfig(containedctx.New()).
WithSince("v1.44.0").
WithLoadForGoAnalysis().
@@ -394,6 +400,12 @@ func (LinterBuilder) Build(cfg *config.Config) ([]*linter.Config, error) {
linter.NewConfig(gomodguard.New(&cfg.Linters.Settings.Gomodguard)).
WithSince("v1.25.0").
+ DeprecatedWarning("new major version.", "v2.12.0",
+ linter.Replacement("gomodguard_v2", gomodguard.Migration, &cfg.Linters.Settings.Gomodguard)).
+ WithURL("https://github.com/ryancurrah/gomodguard"),
+
+ linter.NewConfig(gomodguard.NewV2(&cfg.Linters.Settings.Gomodguardv2)).
+ WithSince("v2.12.0").
WithURL("https://github.com/ryancurrah/gomodguard"),
linter.NewConfig(goprintffuncname.New()).
@@ -532,6 +544,7 @@ func (LinterBuilder) Build(cfg *config.Config) ([]*linter.Config, error) {
linter.NewConfig(noinlineerr.New()).
WithSince("v2.2.0").
WithLoadForGoAnalysis().
+ WithAutoFix().
WithURL("https://github.com/AlwxSin/noinlineerr"),
linter.NewConfig(nonamedreturns.New(&cfg.Linters.Settings.NoNamedReturns)).
@@ -556,6 +569,7 @@ func (LinterBuilder) Build(cfg *config.Config) ([]*linter.Config, error) {
linter.NewConfig(prealloc.New(&cfg.Linters.Settings.Prealloc)).
WithSince("v1.19.0").
+ WithLoadForGoAnalysis().
WithURL("https://github.com/alexkohler/prealloc"),
linter.NewConfig(predeclared.New(&cfg.Linters.Settings.Predeclared)).
@@ -591,9 +605,9 @@ func (LinterBuilder) Build(cfg *config.Config) ([]*linter.Config, error) {
linter.NewConfig(rowserrcheck.New(&cfg.Linters.Settings.RowsErrCheck)).
WithSince("v1.23.0").
WithLoadForGoAnalysis().
- WithURL("https://github.com/jingyugao/rowserrcheck"),
+ WithURL("https://github.com/golangci/rowserrcheck"),
- linter.NewConfig(sloglint.New(&cfg.Linters.Settings.SlogLint)).
+ linter.NewConfig(sloglint.New(&cfg.Linters.Settings.Sloglint)).
WithSince("v1.55.0").
WithLoadForGoAnalysis().
WithAutoFix().
@@ -619,7 +633,7 @@ func (LinterBuilder) Build(cfg *config.Config) ([]*linter.Config, error) {
linter.NewConfig(swaggo.New()).
WithSince("v2.2.0").
WithAutoFix().
- WithURL("https://github.com/swaggo/swaggo"),
+ WithURL("https://github.com/swaggo/swag"),
linter.NewConfig(tagalign.New(&cfg.Linters.Settings.TagAlign)).
WithSince("v1.53.0").
diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/lint/package.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/lint/package.go
index 3127a24b8..1d68efb68 100644
--- a/vendor/github.com/golangci/golangci-lint/v2/pkg/lint/package.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/lint/package.go
@@ -230,6 +230,11 @@ func (l *PackageLoader) makeBuildFlags() []string {
buildFlags = append(buildFlags, fmt.Sprintf("-mod=%s", l.cfg.Run.ModulesDownloadMode))
}
+ if !l.cfg.Run.EnableBuildVCS {
+ // disable collecting VCS information
+ buildFlags = append(buildFlags, "-buildvcs=false")
+ }
+
return buildFlags
}
diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/lint/runner.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/lint/runner.go
index ba7750f28..99182ffe3 100644
--- a/vendor/github.com/golangci/golangci-lint/v2/pkg/lint/runner.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/lint/runner.go
@@ -59,6 +59,15 @@ func NewRunner(log logutils.Log, cfg *config.Config, goenv *goutil.Env,
}
}
+ switch len(enabledLinters) {
+ case 0:
+ return nil, errors.New("no linters enabled")
+ case 1:
+ if _, ok := enabledLinters["typecheck"]; ok {
+ return nil, errors.New("no linters enabled")
+ }
+ }
+
formattersCfg := &config.Formatters{
Enable: enabledFormatters,
Settings: cfg.Linters.Settings.FormatterSettings,
diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/exclusion_rules.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/exclusion_rules.go
index 2b5221a89..2e29600f5 100644
--- a/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/exclusion_rules.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/exclusion_rules.go
@@ -32,7 +32,7 @@ func NewExclusionRules(log logutils.Log, lines *fsutils.LineCache, cfg *config.L
skippedCounter: map[string]int{},
}
- excludeRules := slices.Concat(slices.Clone(cfg.Rules), getLinterExclusionPresets(cfg.Presets))
+ excludeRules := slices.Concat(cfg.Rules, getLinterExclusionPresets(cfg.Presets))
p.rules = parseRules(excludeRules, "", newExcludeRule)
diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/filename_unadjuster.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/filename_unadjuster.go
index e39601d5a..9a8f35ab0 100644
--- a/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/filename_unadjuster.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/filename_unadjuster.go
@@ -3,6 +3,7 @@ package processors
import (
"go/parser"
"go/token"
+ "slices"
"strings"
"sync"
"time"
@@ -41,14 +42,14 @@ func NewFilenameUnadjuster(pkgs []*packages.Package, log logutils.Log) *Filename
startedAt := time.Now()
var wg sync.WaitGroup
- wg.Add(len(pkgs))
-
- for _, pkg := range pkgs {
- go func(pkg *packages.Package) {
- // It's important to call func here to run GC
- processUnadjusterPkg(&m, pkg, log)
- wg.Done()
- }(pkg)
+
+ for chunk := range slices.Chunk(pkgs, len(pkgs)/2000+1) {
+ wg.Go(func() {
+ for _, pkg := range chunk {
+ // It's important to call func here to run GC
+ processUnadjusterPkg(&m, pkg, log)
+ }
+ })
}
wg.Wait()
diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/nolint_filter.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/nolint_filter.go
index b1ba3be1e..1f45f044e 100644
--- a/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/nolint_filter.go
+++ b/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/nolint_filter.go
@@ -37,11 +37,8 @@ func (i *ignoredRange) doesMatch(issue *result.Issue) bool {
// only allow selective nolinting of nolintlint
nolintFoundForLinter := len(i.linters) == 0 && issue.FromLinter != nolintlint.LinterName
- for _, linterName := range i.linters {
- if linterName == issue.FromLinter {
- nolintFoundForLinter = true
- break
- }
+ if slices.Contains(i.linters, issue.FromLinter) {
+ nolintFoundForLinter = true
}
if nolintFoundForLinter {
diff --git a/vendor/github.com/golangci/golines/LICENSE b/vendor/github.com/golangci/golines/LICENSE
index 1fbffdf72..b417faf7e 100644
--- a/vendor/github.com/golangci/golines/LICENSE
+++ b/vendor/github.com/golangci/golines/LICENSE
@@ -1,5 +1,6 @@
MIT License
+Copyright (c) 2025 Golangci Team
Copyright (c) 2019 Segment.io, Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
diff --git a/vendor/github.com/golangci/golines/shorten/format.go b/vendor/github.com/golangci/golines/shorten/format.go
index 6c3abb67a..c177ee573 100644
--- a/vendor/github.com/golangci/golines/shorten/format.go
+++ b/vendor/github.com/golangci/golines/shorten/format.go
@@ -75,6 +75,8 @@ func (s *Shortener) formatDecl(decl dst.Decl) {
// formatStmt formats an AST statement node.
// Among other examples, these include assignments, case clauses,
// for statements, if statements, and select statements.
+//
+//nolint:funlen // the number of statements is expected.
func (s *Shortener) formatStmt(stmt dst.Stmt, force bool) {
stmtType := reflect.TypeOf(stmt)
@@ -145,6 +147,12 @@ func (s *Shortener) formatStmt(stmt dst.Stmt, force bool) {
case *dst.SwitchStmt:
s.formatStmt(st.Body, false)
+ // Ignored: st.Init
+
+ if st.Tag != nil {
+ s.formatExpr(st.Tag, shouldShorten, false)
+ }
+
case *dst.TypeSwitchStmt:
s.formatStmt(st.Body, false)
@@ -212,7 +220,7 @@ func (s *Shortener) formatExpr(expr dst.Expr, force, isChain bool) {
}
case *dst.CompositeLit:
- if shouldShorten {
+ if shouldShorten || annotation.HasRecursive(e) {
for i, element := range e.Elts {
if i == 0 {
element.Decorations().Before = dst.NewLine
diff --git a/vendor/github.com/golangci/golines/shorten/internal/annotation/annotation.go b/vendor/github.com/golangci/golines/shorten/internal/annotation/annotation.go
index 8491b4e46..0a9c1f0c8 100644
--- a/vendor/github.com/golangci/golines/shorten/internal/annotation/annotation.go
+++ b/vendor/github.com/golangci/golines/shorten/internal/annotation/annotation.go
@@ -62,6 +62,9 @@ func HasRecursive[T dst.Node](node T) bool {
case *dst.FieldList:
return slices.ContainsFunc(n.List, HasRecursive)
+
+ case *dst.CompositeLit:
+ return slices.ContainsFunc(n.Elts, HasRecursive)
}
return false
diff --git a/vendor/github.com/golangci/misspell/.golangci.yml b/vendor/github.com/golangci/misspell/.golangci.yml
index 1811db3a0..9e4446f99 100644
--- a/vendor/github.com/golangci/misspell/.golangci.yml
+++ b/vendor/github.com/golangci/misspell/.golangci.yml
@@ -37,7 +37,7 @@ linters:
- tparallel
- varnamelen
- wrapcheck
- - wsl # FIXME(ldez) must be fixed
+ - wsl # deprecated
settings:
depguard:
diff --git a/vendor/github.com/golangci/misspell/ascii.go b/vendor/github.com/golangci/misspell/ascii.go
index 74abe5141..acf5f5334 100644
--- a/vendor/github.com/golangci/misspell/ascii.go
+++ b/vendor/github.com/golangci/misspell/ascii.go
@@ -7,6 +7,7 @@ func ByteToUpper(x byte) byte {
c := b - byte(0x61)
d := ^(b - byte(0x7b))
e := (c & d) & (^x & 0x7f)
+
return x - (e >> 2)
}
@@ -16,6 +17,7 @@ func ByteToLower(eax byte) byte {
ebx := eax&byte(0x7f) + byte(0x25)
ebx = ebx&byte(0x7f) + byte(0x1a)
ebx = ((ebx & ^eax) >> 2) & byte(0x20)
+
return eax + ebx
}
@@ -32,18 +34,21 @@ func StringEqualFold(s1, s2 string) bool {
if len(s1) != len(s2) {
return false
}
+
for i := range len(s1) {
c1 := s1[i]
c2 := s2[i]
// c1 & c2
if c1 != c2 {
c1 |= 'a' - 'A'
+
c2 |= 'a' - 'A'
if c1 != c2 || c1 < 'a' || c1 > 'z' {
return false
}
}
}
+
return true
}
@@ -53,8 +58,10 @@ func StringHasPrefixFold(s1, s2 string) bool {
if len(s1) < len(s2) {
return false
}
+
if len(s1) == len(s2) {
return StringEqualFold(s1, s2)
}
+
return StringEqualFold(s1[:len(s2)], s2)
}
diff --git a/vendor/github.com/golangci/misspell/case.go b/vendor/github.com/golangci/misspell/case.go
index 533ce4db3..20e33a212 100644
--- a/vendor/github.com/golangci/misspell/case.go
+++ b/vendor/github.com/golangci/misspell/case.go
@@ -39,6 +39,7 @@ func CaseStyle(word string) WordCase {
case upperCount == 1 && lowerCount > 0 && word[0] >= 'A' && word[0] <= 'Z':
return CaseTitle
}
+
return CaseUnknown
}
diff --git a/vendor/github.com/golangci/misspell/mime.go b/vendor/github.com/golangci/misspell/mime.go
index 19d49e085..a74a355cb 100644
--- a/vendor/github.com/golangci/misspell/mime.go
+++ b/vendor/github.com/golangci/misspell/mime.go
@@ -126,6 +126,7 @@ func isTextFile(raw []byte) bool {
// allow any text/ type with utf-8 encoding.
// DetectContentType sometimes returns charset=utf-16 for XML stuff in which case ignore.
mime := http.DetectContentType(raw)
+
return strings.HasPrefix(mime, "text/") && strings.HasSuffix(mime, "charset=utf-8")
}
@@ -173,18 +174,23 @@ func ReadTextFile(filename string) (string, error) {
// if input is large, read the first 512 bytes to sniff type
// if not-text, then exit
isText := false
+
if fstat.Size() > 50000 {
var fin *os.File
+
fin, err = os.Open(filename)
if err != nil {
return "", fmt.Errorf("unable to open large file %q: %w", filename, err)
}
defer fin.Close()
+
buf := make([]byte, 512)
+
_, err = io.ReadFull(fin, buf)
if err != nil {
return "", fmt.Errorf("unable to read 512 bytes from %q: %w", filename, err)
}
+
if !isTextFile(buf) {
return "", nil
}
@@ -202,5 +208,6 @@ func ReadTextFile(filename string) (string, error) {
if !isText && !isTextFile(raw) {
return "", nil
}
+
return string(raw), nil
}
diff --git a/vendor/github.com/golangci/misspell/notwords.go b/vendor/github.com/golangci/misspell/notwords.go
index f694f46dc..4697dcf72 100644
--- a/vendor/github.com/golangci/misspell/notwords.go
+++ b/vendor/github.com/golangci/misspell/notwords.go
@@ -24,6 +24,7 @@ var (
// TODO: windows style.
func RemovePath(s string) string {
out := bytes.Buffer{}
+
var idx int
for s != "" {
if idx = strings.IndexByte(s, '/'); idx == -1 {
@@ -36,6 +37,7 @@ func RemovePath(s string) string {
}
var chclass string
+
switch s[idx] {
case '/', ' ', '\n', '\t', '\r':
chclass = " \n\r\t"
@@ -46,6 +48,7 @@ func RemovePath(s string) string {
default:
out.WriteString(s[:idx+2])
s = s[idx+2:]
+
continue
}
@@ -59,6 +62,7 @@ func RemovePath(s string) string {
break
}
}
+
return out.String()
}
diff --git a/vendor/github.com/golangci/misspell/replace.go b/vendor/github.com/golangci/misspell/replace.go
index f51ac3b3b..6d88c5336 100644
--- a/vendor/github.com/golangci/misspell/replace.go
+++ b/vendor/github.com/golangci/misspell/replace.go
@@ -42,6 +42,7 @@ func New() *Replacer {
Replacements: DictMain,
}
r.Compile()
+
return &r
}
@@ -54,8 +55,10 @@ func (r *Replacer) RemoveRule(ignore []string) {
if inArray(ignore, r.Replacements[i]) {
continue
}
+
newWords = append(newWords, r.Replacements[i:i+2]...)
}
+
r.engine = nil
r.Replacements = newWords
}
@@ -75,6 +78,7 @@ func (r *Replacer) Compile() {
for i := 0; i < len(r.Replacements); i += 2 {
r.corrected[r.Replacements[i]] = r.Replacements[i+1]
}
+
r.engine = NewStringReplacer(r.Replacements...)
}
@@ -86,7 +90,9 @@ func (r *Replacer) ReplaceGo(input string) (string, []Diff) {
s.Mode = scanner.ScanIdents | scanner.ScanFloats | scanner.ScanChars | scanner.ScanStrings | scanner.ScanRawStrings | scanner.ScanComments
lastPos := 0
output := ""
+
Loop:
+
for {
switch s.Scan() {
case scanner.Comment:
@@ -109,19 +115,23 @@ Loop:
// no changes, no copies
return input, nil
}
+
if lastPos < len(input) {
output += input[lastPos:]
}
+
diffs := make([]Diff, 0, 8)
buf := bytes.NewBuffer(make([]byte, 0, max(len(input), len(output))+100))
// faster that making a bytes.Buffer and bufio.ReadString
outlines := strings.SplitAfter(output, "\n")
+
inlines := strings.SplitAfter(input, "\n")
for i := range inlines {
if inlines[i] == outlines[i] {
buf.WriteString(outlines[i])
continue
}
+
r.recheckLine(inlines[i], i+1, buf, func(d Diff) {
diffs = append(diffs, d)
})
@@ -136,16 +146,19 @@ func (r *Replacer) Replace(input string) (string, []Diff) {
if input == output {
return input, nil
}
+
diffs := make([]Diff, 0, 8)
buf := bytes.NewBuffer(make([]byte, 0, max(len(input), len(output))+100))
// faster that making a bytes.Buffer and bufio.ReadString
outlines := strings.SplitAfter(output, "\n")
+
inlines := strings.SplitAfter(input, "\n")
for i := range inlines {
if inlines[i] == outlines[i] {
buf.WriteString(outlines[i])
continue
}
+
r.recheckLine(inlines[i], i+1, buf, func(d Diff) {
diffs = append(diffs, d)
})
@@ -162,7 +175,9 @@ func (r *Replacer) ReplaceReader(raw io.Reader, w io.Writer, next func(Diff)) er
line string
lineNum int
)
+
reader := bufio.NewReader(raw)
+
for err == nil {
lineNum++
line, err = reader.ReadString('\n')
@@ -181,6 +196,7 @@ func (r *Replacer) ReplaceReader(raw io.Reader, w io.Writer, next func(Diff)) er
// but it can be inaccurate, so we need to double-check
r.recheckLine(line, lineNum, w, next)
}
+
return nil
}
@@ -206,6 +222,7 @@ func (r *Replacer) recheckLine(s string, lineNum int, buf io.Writer, next func(D
idx := wordRegexp.FindAllStringIndex(redacted, -1)
for _, ab := range idx {
word := s[ab[0]:ab[1]]
+
newword := r.engine.Replace(word)
if newword == word {
// no replacement done
@@ -222,6 +239,7 @@ func (r *Replacer) recheckLine(s string, lineNum int, buf io.Writer, next func(D
// word got corrected into something we know
io.WriteString(buf, s[first:ab[0]])
io.WriteString(buf, newword)
+
first = ab[1]
next(Diff{
FullLine: s,
@@ -230,9 +248,11 @@ func (r *Replacer) recheckLine(s string, lineNum int, buf io.Writer, next func(D
Corrected: newword,
Column: ab[0],
})
+
continue
}
// Word got corrected into something unknown. Ignore it
}
+
io.WriteString(buf, s[first:])
}
diff --git a/vendor/github.com/golangci/misspell/stringreplacer.go b/vendor/github.com/golangci/misspell/stringreplacer.go
index a03716849..b36fe6576 100644
--- a/vendor/github.com/golangci/misspell/stringreplacer.go
+++ b/vendor/github.com/golangci/misspell/stringreplacer.go
@@ -99,6 +99,7 @@ func (t *trieNode) add(key, val string, priority int, r *genericReplacer) {
t.value = val
t.priority = priority
}
+
return
}
@@ -110,6 +111,7 @@ func (t *trieNode) add(key, val string, priority int, r *genericReplacer) {
break
}
}
+
switch n {
case len(t.prefix):
t.next.add(key[n:], val, priority, r)
@@ -126,12 +128,14 @@ func (t *trieNode) add(key, val string, priority int, r *genericReplacer) {
next: t.next,
}
}
+
keyNode := new(trieNode)
t.table = make([]*trieNode, r.tableSize)
t.table[r.mapping[t.prefix[0]]] = prefixNode
t.table[r.mapping[key[0]]] = keyNode
t.prefix = ""
t.next = nil
+
keyNode.add(key[1:], val, priority, r)
default:
// Insert new node after the common section of the prefix.
@@ -143,6 +147,7 @@ func (t *trieNode) add(key, val string, priority int, r *genericReplacer) {
t.next = next
next.add(key[n:], val, priority, r)
}
+
return
}
@@ -152,7 +157,9 @@ func (t *trieNode) add(key, val string, priority int, r *genericReplacer) {
if t.table[m] == nil {
t.table[m] = new(trieNode)
}
+
t.table[m].add(key[1:], val, priority, r)
+
return
}
@@ -187,6 +194,7 @@ func makeGenericReplacer(oldnew []string) *genericReplacer {
}
var index byte
+
for i, b := range r.mapping {
if b == 0 {
r.mapping[i] = byte(r.tableSize)
@@ -201,19 +209,25 @@ func makeGenericReplacer(oldnew []string) *genericReplacer {
for i := 0; i < len(oldnew); i += 2 {
r.root.add(strings.ToLower(oldnew[i]), oldnew[i+1], len(oldnew)-i, r)
}
+
return r
}
func (r *genericReplacer) Replace(s string) string {
buf := make(appendSliceWriter, 0, len(s))
r.WriteString(&buf, s)
+
return string(buf)
}
func (r *genericReplacer) WriteString(w io.Writer, s string) (n int, err error) {
sw := getStringWriter(w)
- var last, wn int
- var prevMatchEmpty bool
+
+ var (
+ last, wn int
+ prevMatchEmpty bool
+ )
+
for i := 0; i <= len(s); {
// Fast path: s[i] is not a prefix of any pattern.
if i != len(s) && r.root.priority == 0 {
@@ -226,6 +240,7 @@ func (r *genericReplacer) WriteString(w io.Writer, s string) (n int, err error)
// Ignore the empty match iff the previous loop found the empty match.
val, keylen, match := r.lookup(s[i:], prevMatchEmpty)
+
prevMatchEmpty = match && keylen == 0
if match {
orig := s[i : i+keylen]
@@ -245,28 +260,37 @@ func (r *genericReplacer) WriteString(w io.Writer, s string) (n int, err error)
val = strings.ToUpper(val[:1]) + strings.ToLower(val[1:])
}
}
+
wn, err = sw.WriteString(s[last:i])
n += wn
+
if err != nil {
- return
+ return n, err
}
+
// debug helper: log.Printf("%d: Going to correct %q with %q", i, s[i:i+keylen], val)
wn, err = sw.WriteString(val)
n += wn
+
if err != nil {
- return
+ return n, err
}
+
i += keylen
last = i
+
continue
}
+
i++
}
+
if last != len(s) {
wn, err = sw.WriteString(s[last:])
n += wn
}
- return
+
+ return n, err
}
func (r *genericReplacer) lookup(s string, ignoreRoot bool) (val string, keylen int, found bool) {
@@ -275,6 +299,7 @@ func (r *genericReplacer) lookup(s string, ignoreRoot bool) (val string, keylen
bestPriority := 0
node := &r.root
n := 0
+
for node != nil {
if node.priority > bestPriority && (!ignoreRoot || node != &r.root) {
bestPriority = node.priority
@@ -286,11 +311,13 @@ func (r *genericReplacer) lookup(s string, ignoreRoot bool) (val string, keylen
if s == "" {
break
}
+
if node.table != nil {
index := r.mapping[ByteToLower(s[0])]
if int(index) == r.tableSize {
break
}
+
node = node.table[index]
s = s[1:]
n++
@@ -302,7 +329,8 @@ func (r *genericReplacer) lookup(s string, ignoreRoot bool) (val string, keylen
break
}
}
- return
+
+ return val, keylen, found
}
type appendSliceWriter []byte
@@ -332,5 +360,6 @@ func getStringWriter(w io.Writer) io.StringWriter {
if !ok {
sw = stringWriter{w}
}
+
return sw
}
diff --git a/vendor/github.com/golangci/misspell/words.go b/vendor/github.com/golangci/misspell/words.go
index 64bfd88e5..788682957 100644
--- a/vendor/github.com/golangci/misspell/words.go
+++ b/vendor/github.com/golangci/misspell/words.go
@@ -19642,6 +19642,7 @@ var DictMain = []string{
"repulican", "republican",
"repulisve", "repulsive",
"repuslive", "repulsive",
+ "requiered", "required",
"resaurant", "restaurant",
"researchs", "researchers",
"resembels", "resembles",
@@ -26750,6 +26751,7 @@ var DictMain = []string{
"requeim", "requiem",
"requime", "requiem",
"requred", "required",
+ "requrie", "require",
"resapwn", "respawn",
"rescuse", "rescues",
"resembe", "resemble",
diff --git a/vendor/github.com/jingyugao/rowserrcheck/LICENSE b/vendor/github.com/golangci/rowserrcheck/LICENSE
similarity index 100%
rename from vendor/github.com/jingyugao/rowserrcheck/LICENSE
rename to vendor/github.com/golangci/rowserrcheck/LICENSE
diff --git a/vendor/github.com/jingyugao/rowserrcheck/passes/rowserr/rowserr.go b/vendor/github.com/golangci/rowserrcheck/passes/rowserr/rowserr.go
similarity index 82%
rename from vendor/github.com/jingyugao/rowserrcheck/passes/rowserr/rowserr.go
rename to vendor/github.com/golangci/rowserrcheck/passes/rowserr/rowserr.go
index a142a6744..a05382c69 100644
--- a/vendor/github.com/jingyugao/rowserrcheck/passes/rowserr/rowserr.go
+++ b/vendor/github.com/golangci/rowserrcheck/passes/rowserr/rowserr.go
@@ -3,6 +3,7 @@ package rowserr
import (
"go/ast"
"go/types"
+ "slices"
"golang.org/x/tools/go/analysis"
"golang.org/x/tools/go/analysis/passes/buildssa"
@@ -35,21 +36,22 @@ type runner struct {
sqlPkgs []string
}
-func NewRun(pkgs ...string) func(pass *analysis.Pass) (interface{}, error) {
- return func(pass *analysis.Pass) (interface{}, error) {
- sqlPkgs := append(pkgs, "database/sql")
+func NewRun(pkgs ...string) func(pass *analysis.Pass) (any, error) {
+ return func(pass *analysis.Pass) (any, error) {
+ sqlPkgs := slices.Concat(pkgs, []string{"database/sql"})
for _, pkg := range sqlPkgs {
r := new(runner)
r.sqlPkgs = sqlPkgs
r.run(pass, pkg)
}
+
return nil, nil
}
}
// run executes an analysis for the pass. The receiver is passed
// by value because this func is called in parallel for different passes.
-func (r runner) run(pass *analysis.Pass, pkgPath string) {
+func (r *runner) run(pass *analysis.Pass, pkgPath string) {
r.pass = pass
pssa := pass.ResultOf[buildssa.Analyzer].(*buildssa.SSA)
funcs := pssa.SrcFuncs
@@ -65,6 +67,7 @@ func (r runner) run(pass *analysis.Pass, pkgPath string) {
// skip checking
return
}
+
r.rowsObj = rowsType.Object()
if r.rowsObj == nil {
// skip checking
@@ -88,8 +91,8 @@ func (r runner) run(pass *analysis.Pass, pkgPath string) {
// skip if the function is just referenced
var isRefFunc bool
- for i := 0; i < f.Signature.Results().Len(); i++ {
- if types.Identical(f.Signature.Results().At(i).Type(), r.rowsTyp) {
+ for v := range f.Signature.Results().Variables() {
+ if types.Identical(v.Type(), r.rowsTyp) {
isRefFunc = true
}
}
@@ -114,38 +117,59 @@ func (r *runner) errCallMissing(b *ssa.BasicBlock, i int) (ret bool) {
return false
}
+ if call.Referrers() == nil {
+ return false
+ }
+
for _, cRef := range *call.Referrers() {
val, ok := r.getRowsVal(cRef)
if !ok {
continue
}
- if len(*val.Referrers()) == 0 {
- continue
+
+ if val.Referrers() == nil {
+ return false
}
+
resRefs := *val.Referrers()
+
+ if len(resRefs) == 0 {
+ continue
+ }
+
var errCalled func(resRef ssa.Instruction) bool
+
errCalled = func(resRef ssa.Instruction) bool {
switch resRef := resRef.(type) {
case *ssa.Phi:
- for _, rf := range *resRef.Referrers() {
- if errCalled(rf) {
- return true
- }
+ if resRef.Referrers() == nil {
+ return false
+ }
+
+ if slices.ContainsFunc(*resRef.Referrers(), errCalled) {
+ return true
}
case *ssa.Store: // Call in Closure function
+ if resRef.Addr.Referrers() == nil {
+ return false
+ }
+
for _, aref := range *resRef.Addr.Referrers() {
switch c := aref.(type) {
case *ssa.MakeClosure:
f := c.Fn.(*ssa.Function)
+
called := r.isClosureCalled(c)
if r.calledInFunc(f, called) {
return true
}
case *ssa.UnOp:
- for _, rf := range *c.Referrers() {
- if errCalled(rf) {
- return true
- }
+ if c.Referrers() == nil {
+ continue
+ }
+
+ if slices.ContainsFunc(*c.Referrers(), errCalled) {
+ return true
}
}
}
@@ -153,6 +177,7 @@ func (r *runner) errCallMissing(b *ssa.BasicBlock, i int) (ret bool) {
if r.isErrCall(resRef) {
return true
}
+
if f, ok := resRef.Call.Value.(*ssa.Function); ok {
for _, b := range f.Blocks {
for i := range b.Instrs {
@@ -163,16 +188,22 @@ func (r *runner) errCallMissing(b *ssa.BasicBlock, i int) (ret bool) {
}
}
case *ssa.FieldAddr:
+ if resRef.Referrers() == nil {
+ return false
+ }
+
for _, bRef := range *resRef.Referrers() {
bOp, ok := r.getBodyOp(bRef)
if !ok {
continue
}
- for _, ccall := range *bOp.Referrers() {
- if r.isErrCall(ccall) {
- return true
- }
+ if bOp.Referrers() == nil {
+ continue
+ }
+
+ if slices.ContainsFunc(*bOp.Referrers(), r.isErrCall) {
+ return true
}
}
}
@@ -180,10 +211,8 @@ func (r *runner) errCallMissing(b *ssa.BasicBlock, i int) (ret bool) {
return false
}
- for _, resRef := range resRefs {
- if errCalled(resRef) {
- return false
- }
+ if slices.ContainsFunc(resRefs, errCalled) {
+ return false
}
}
@@ -198,11 +227,12 @@ func (r *runner) getCallReturnsRow(instr ssa.Instruction) (*ssa.Call, bool) {
res := call.Call.Signature().Results()
- for i := 0; i < res.Len(); i++ {
- typeToCheck := res.At(i).Type()
+ for v := range res.Variables() {
+ typeToCheck := v.Type()
if types.Identical(typeToCheck, r.rowsTyp) {
return call, true
}
+
if r.rowsInterface != nil && types.Implements(typeToCheck, r.rowsInterface) {
return call, true
}
@@ -217,6 +247,7 @@ func (r *runner) getRowsVal(instr ssa.Instruction) (ssa.Value, bool) {
if len(instr.Call.Args) == 1 && types.Identical(instr.Call.Args[0].Type(), r.rowsTyp) {
return instr.Call.Args[0], true
}
+
if len(instr.Call.Args) == 1 && r.rowsInterface != nil && types.Implements(instr.Call.Args[0].Type(), r.rowsInterface) {
return instr.Call.Args[0], true
}
@@ -224,6 +255,7 @@ func (r *runner) getRowsVal(instr ssa.Instruction) (ssa.Value, bool) {
if types.Identical(instr.Type(), r.rowsTyp) {
return instr, true
}
+
if r.rowsInterface != nil && types.Implements(instr.Type(), r.rowsInterface) {
return instr, true
}
@@ -251,6 +283,7 @@ func (r *runner) isErrCall(ccall ssa.Instruction) bool {
if ccall.Call.Value != nil && ccall.Call.Value.Name() == errMethod {
return true
}
+
if ccall.Call.Method != nil && ccall.Call.Method.Name() == errMethod {
return true
}
@@ -258,6 +291,7 @@ func (r *runner) isErrCall(ccall ssa.Instruction) bool {
if ccall.Call.Value != nil && ccall.Call.Value.Name() == errMethod {
return true
}
+
if ccall.Call.Method != nil && ccall.Call.Method.Name() == errMethod {
return true
}
@@ -267,6 +301,10 @@ func (r *runner) isErrCall(ccall ssa.Instruction) bool {
}
func (r *runner) isClosureCalled(c *ssa.MakeClosure) bool {
+ if c.Referrers() == nil {
+ return false
+ }
+
for _, ref := range *c.Referrers() {
switch ref.(type) {
case *ssa.Call, *ssa.Defer:
@@ -282,7 +320,12 @@ func (r *runner) calledInFunc(f *ssa.Function, called bool) bool {
for i, instr := range b.Instrs {
switch instr := instr.(type) {
case *ssa.UnOp:
+ if instr.Referrers() == nil {
+ continue
+ }
+
for _, ref := range *instr.Referrers() {
+ //nolint:nestif // need to be reviewed.
if v, ok := ref.(ssa.Value); ok {
if vCall, ok := v.(*ssa.Call); ok {
if vCall.Call.Value != nil && vCall.Call.Value.Name() == errMethod {
@@ -300,5 +343,6 @@ func (r *runner) calledInFunc(f *ssa.Function, called bool) bool {
}
}
}
+
return false
}
diff --git a/vendor/github.com/google/btree/README.md b/vendor/github.com/google/btree/README.md
deleted file mode 100644
index eab5dbf7b..000000000
--- a/vendor/github.com/google/btree/README.md
+++ /dev/null
@@ -1,10 +0,0 @@
-# BTree implementation for Go
-
-This package provides an in-memory B-Tree implementation for Go, useful as
-an ordered, mutable data structure.
-
-The API is based off of the wonderful
-http://godoc.org/github.com/petar/GoLLRB/llrb, and is meant to allow btree to
-act as a drop-in replacement for gollrb trees.
-
-See http://godoc.org/github.com/google/btree for documentation.
diff --git a/vendor/github.com/google/btree/btree.go b/vendor/github.com/google/btree/btree.go
deleted file mode 100644
index 6f5184fef..000000000
--- a/vendor/github.com/google/btree/btree.go
+++ /dev/null
@@ -1,893 +0,0 @@
-// 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.
-
-//go:build !go1.18
-// +build !go1.18
-
-// Package btree implements in-memory B-Trees of arbitrary degree.
-//
-// btree implements an in-memory B-Tree for use as an ordered data structure.
-// It is not meant for persistent storage solutions.
-//
-// It has a flatter structure than an equivalent red-black or other binary tree,
-// which in some cases yields better memory usage and/or performance.
-// See some discussion on the matter here:
-// http://google-opensource.blogspot.com/2013/01/c-containers-that-save-memory-and-time.html
-// Note, though, that this project is in no way related to the C++ B-Tree
-// implementation written about there.
-//
-// Within this tree, each node contains a slice of items and a (possibly nil)
-// slice of children. For basic numeric values or raw structs, this can cause
-// efficiency differences when compared to equivalent C++ template code that
-// stores values in arrays within the node:
-// * Due to the overhead of storing values as interfaces (each
-// value needs to be stored as the value itself, then 2 words for the
-// interface pointing to that value and its type), resulting in higher
-// memory use.
-// * Since interfaces can point to values anywhere in memory, values are
-// most likely not stored in contiguous blocks, resulting in a higher
-// number of cache misses.
-// These issues don't tend to matter, though, when working with strings or other
-// heap-allocated structures, since C++-equivalent structures also must store
-// pointers and also distribute their values across the heap.
-//
-// This implementation is designed to be a drop-in replacement to gollrb.LLRB
-// trees, (http://github.com/petar/gollrb), an excellent and probably the most
-// widely used ordered tree implementation in the Go ecosystem currently.
-// Its functions, therefore, exactly mirror those of
-// llrb.LLRB where possible. Unlike gollrb, though, we currently don't
-// support storing multiple equivalent values.
-package btree
-
-import (
- "fmt"
- "io"
- "sort"
- "strings"
- "sync"
-)
-
-// Item represents a single object in the tree.
-type Item interface {
- // Less tests whether the current item is less than the given argument.
- //
- // This must provide a strict weak ordering.
- // If !a.Less(b) && !b.Less(a), we treat this to mean a == b (i.e. we can only
- // hold one of either a or b in the tree).
- Less(than Item) bool
-}
-
-const (
- DefaultFreeListSize = 32
-)
-
-var (
- nilItems = make(items, 16)
- nilChildren = make(children, 16)
-)
-
-// FreeList represents a free list of btree nodes. By default each
-// BTree has its own FreeList, but multiple BTrees can share the same
-// FreeList.
-// Two Btrees using the same freelist are safe for concurrent write access.
-type FreeList struct {
- mu sync.Mutex
- freelist []*node
-}
-
-// NewFreeList creates a new free list.
-// size is the maximum size of the returned free list.
-func NewFreeList(size int) *FreeList {
- return &FreeList{freelist: make([]*node, 0, size)}
-}
-
-func (f *FreeList) newNode() (n *node) {
- f.mu.Lock()
- index := len(f.freelist) - 1
- if index < 0 {
- f.mu.Unlock()
- return new(node)
- }
- n = f.freelist[index]
- f.freelist[index] = nil
- f.freelist = f.freelist[:index]
- f.mu.Unlock()
- return
-}
-
-// freeNode adds the given node to the list, returning true if it was added
-// and false if it was discarded.
-func (f *FreeList) freeNode(n *node) (out bool) {
- f.mu.Lock()
- if len(f.freelist) < cap(f.freelist) {
- f.freelist = append(f.freelist, n)
- out = true
- }
- f.mu.Unlock()
- return
-}
-
-// ItemIterator allows callers of Ascend* to iterate in-order over portions of
-// the tree. When this function returns false, iteration will stop and the
-// associated Ascend* function will immediately return.
-type ItemIterator func(i Item) bool
-
-// New creates a new B-Tree with the given degree.
-//
-// New(2), for example, will create a 2-3-4 tree (each node contains 1-3 items
-// and 2-4 children).
-func New(degree int) *BTree {
- return NewWithFreeList(degree, NewFreeList(DefaultFreeListSize))
-}
-
-// NewWithFreeList creates a new B-Tree that uses the given node free list.
-func NewWithFreeList(degree int, f *FreeList) *BTree {
- if degree <= 1 {
- panic("bad degree")
- }
- return &BTree{
- degree: degree,
- cow: ©OnWriteContext{freelist: f},
- }
-}
-
-// items stores items in a node.
-type items []Item
-
-// insertAt inserts a value into the given index, pushing all subsequent values
-// forward.
-func (s *items) insertAt(index int, item Item) {
- *s = append(*s, nil)
- if index < len(*s) {
- copy((*s)[index+1:], (*s)[index:])
- }
- (*s)[index] = item
-}
-
-// removeAt removes a value at a given index, pulling all subsequent values
-// back.
-func (s *items) removeAt(index int) Item {
- item := (*s)[index]
- copy((*s)[index:], (*s)[index+1:])
- (*s)[len(*s)-1] = nil
- *s = (*s)[:len(*s)-1]
- return item
-}
-
-// pop removes and returns the last element in the list.
-func (s *items) pop() (out Item) {
- index := len(*s) - 1
- out = (*s)[index]
- (*s)[index] = nil
- *s = (*s)[:index]
- return
-}
-
-// truncate truncates this instance at index so that it contains only the
-// first index items. index must be less than or equal to length.
-func (s *items) truncate(index int) {
- var toClear items
- *s, toClear = (*s)[:index], (*s)[index:]
- for len(toClear) > 0 {
- toClear = toClear[copy(toClear, nilItems):]
- }
-}
-
-// find returns the index where the given item should be inserted into this
-// list. 'found' is true if the item already exists in the list at the given
-// index.
-func (s items) find(item Item) (index int, found bool) {
- i := sort.Search(len(s), func(i int) bool {
- return item.Less(s[i])
- })
- if i > 0 && !s[i-1].Less(item) {
- return i - 1, true
- }
- return i, false
-}
-
-// children stores child nodes in a node.
-type children []*node
-
-// insertAt inserts a value into the given index, pushing all subsequent values
-// forward.
-func (s *children) insertAt(index int, n *node) {
- *s = append(*s, nil)
- if index < len(*s) {
- copy((*s)[index+1:], (*s)[index:])
- }
- (*s)[index] = n
-}
-
-// removeAt removes a value at a given index, pulling all subsequent values
-// back.
-func (s *children) removeAt(index int) *node {
- n := (*s)[index]
- copy((*s)[index:], (*s)[index+1:])
- (*s)[len(*s)-1] = nil
- *s = (*s)[:len(*s)-1]
- return n
-}
-
-// pop removes and returns the last element in the list.
-func (s *children) pop() (out *node) {
- index := len(*s) - 1
- out = (*s)[index]
- (*s)[index] = nil
- *s = (*s)[:index]
- return
-}
-
-// truncate truncates this instance at index so that it contains only the
-// first index children. index must be less than or equal to length.
-func (s *children) truncate(index int) {
- var toClear children
- *s, toClear = (*s)[:index], (*s)[index:]
- for len(toClear) > 0 {
- toClear = toClear[copy(toClear, nilChildren):]
- }
-}
-
-// node is an internal node in a tree.
-//
-// It must at all times maintain the invariant that either
-// * len(children) == 0, len(items) unconstrained
-// * len(children) == len(items) + 1
-type node struct {
- items items
- children children
- cow *copyOnWriteContext
-}
-
-func (n *node) mutableFor(cow *copyOnWriteContext) *node {
- if n.cow == cow {
- return n
- }
- out := cow.newNode()
- if cap(out.items) >= len(n.items) {
- out.items = out.items[:len(n.items)]
- } else {
- out.items = make(items, len(n.items), cap(n.items))
- }
- copy(out.items, n.items)
- // Copy children
- if cap(out.children) >= len(n.children) {
- out.children = out.children[:len(n.children)]
- } else {
- out.children = make(children, len(n.children), cap(n.children))
- }
- copy(out.children, n.children)
- return out
-}
-
-func (n *node) mutableChild(i int) *node {
- c := n.children[i].mutableFor(n.cow)
- n.children[i] = c
- return c
-}
-
-// split splits the given node at the given index. The current node shrinks,
-// and this function returns the item that existed at that index and a new node
-// containing all items/children after it.
-func (n *node) split(i int) (Item, *node) {
- item := n.items[i]
- next := n.cow.newNode()
- next.items = append(next.items, n.items[i+1:]...)
- n.items.truncate(i)
- if len(n.children) > 0 {
- next.children = append(next.children, n.children[i+1:]...)
- n.children.truncate(i + 1)
- }
- return item, next
-}
-
-// maybeSplitChild checks if a child should be split, and if so splits it.
-// Returns whether or not a split occurred.
-func (n *node) maybeSplitChild(i, maxItems int) bool {
- if len(n.children[i].items) < maxItems {
- return false
- }
- first := n.mutableChild(i)
- item, second := first.split(maxItems / 2)
- n.items.insertAt(i, item)
- n.children.insertAt(i+1, second)
- return true
-}
-
-// insert inserts an item into the subtree rooted at this node, making sure
-// no nodes in the subtree exceed maxItems items. Should an equivalent item be
-// be found/replaced by insert, it will be returned.
-func (n *node) insert(item Item, maxItems int) Item {
- i, found := n.items.find(item)
- if found {
- out := n.items[i]
- n.items[i] = item
- return out
- }
- if len(n.children) == 0 {
- n.items.insertAt(i, item)
- return nil
- }
- if n.maybeSplitChild(i, maxItems) {
- inTree := n.items[i]
- switch {
- case item.Less(inTree):
- // no change, we want first split node
- case inTree.Less(item):
- i++ // we want second split node
- default:
- out := n.items[i]
- n.items[i] = item
- return out
- }
- }
- return n.mutableChild(i).insert(item, maxItems)
-}
-
-// get finds the given key in the subtree and returns it.
-func (n *node) get(key Item) Item {
- i, found := n.items.find(key)
- if found {
- return n.items[i]
- } else if len(n.children) > 0 {
- return n.children[i].get(key)
- }
- return nil
-}
-
-// min returns the first item in the subtree.
-func min(n *node) Item {
- if n == nil {
- return nil
- }
- for len(n.children) > 0 {
- n = n.children[0]
- }
- if len(n.items) == 0 {
- return nil
- }
- return n.items[0]
-}
-
-// max returns the last item in the subtree.
-func max(n *node) Item {
- if n == nil {
- return nil
- }
- for len(n.children) > 0 {
- n = n.children[len(n.children)-1]
- }
- if len(n.items) == 0 {
- return nil
- }
- return n.items[len(n.items)-1]
-}
-
-// toRemove details what item to remove in a node.remove call.
-type toRemove int
-
-const (
- removeItem toRemove = iota // removes the given item
- removeMin // removes smallest item in the subtree
- removeMax // removes largest item in the subtree
-)
-
-// remove removes an item from the subtree rooted at this node.
-func (n *node) remove(item Item, minItems int, typ toRemove) Item {
- var i int
- var found bool
- switch typ {
- case removeMax:
- if len(n.children) == 0 {
- return n.items.pop()
- }
- i = len(n.items)
- case removeMin:
- if len(n.children) == 0 {
- return n.items.removeAt(0)
- }
- i = 0
- case removeItem:
- i, found = n.items.find(item)
- if len(n.children) == 0 {
- if found {
- return n.items.removeAt(i)
- }
- return nil
- }
- default:
- panic("invalid type")
- }
- // If we get to here, we have children.
- if len(n.children[i].items) <= minItems {
- return n.growChildAndRemove(i, item, minItems, typ)
- }
- child := n.mutableChild(i)
- // Either we had enough items to begin with, or we've done some
- // merging/stealing, because we've got enough now and we're ready to return
- // stuff.
- if found {
- // The item exists at index 'i', and the child we've selected can give us a
- // predecessor, since if we've gotten here it's got > minItems items in it.
- out := n.items[i]
- // We use our special-case 'remove' call with typ=maxItem to pull the
- // predecessor of item i (the rightmost leaf of our immediate left child)
- // and set it into where we pulled the item from.
- n.items[i] = child.remove(nil, minItems, removeMax)
- return out
- }
- // Final recursive call. Once we're here, we know that the item isn't in this
- // node and that the child is big enough to remove from.
- return child.remove(item, minItems, typ)
-}
-
-// growChildAndRemove grows child 'i' to make sure it's possible to remove an
-// item from it while keeping it at minItems, then calls remove to actually
-// remove it.
-//
-// Most documentation says we have to do two sets of special casing:
-// 1) item is in this node
-// 2) item is in child
-// In both cases, we need to handle the two subcases:
-// A) node has enough values that it can spare one
-// B) node doesn't have enough values
-// For the latter, we have to check:
-// a) left sibling has node to spare
-// b) right sibling has node to spare
-// c) we must merge
-// To simplify our code here, we handle cases #1 and #2 the same:
-// If a node doesn't have enough items, we make sure it does (using a,b,c).
-// We then simply redo our remove call, and the second time (regardless of
-// whether we're in case 1 or 2), we'll have enough items and can guarantee
-// that we hit case A.
-func (n *node) growChildAndRemove(i int, item Item, minItems int, typ toRemove) Item {
- if i > 0 && len(n.children[i-1].items) > minItems {
- // Steal from left child
- child := n.mutableChild(i)
- stealFrom := n.mutableChild(i - 1)
- stolenItem := stealFrom.items.pop()
- child.items.insertAt(0, n.items[i-1])
- n.items[i-1] = stolenItem
- if len(stealFrom.children) > 0 {
- child.children.insertAt(0, stealFrom.children.pop())
- }
- } else if i < len(n.items) && len(n.children[i+1].items) > minItems {
- // steal from right child
- child := n.mutableChild(i)
- stealFrom := n.mutableChild(i + 1)
- stolenItem := stealFrom.items.removeAt(0)
- child.items = append(child.items, n.items[i])
- n.items[i] = stolenItem
- if len(stealFrom.children) > 0 {
- child.children = append(child.children, stealFrom.children.removeAt(0))
- }
- } else {
- if i >= len(n.items) {
- i--
- }
- child := n.mutableChild(i)
- // merge with right child
- mergeItem := n.items.removeAt(i)
- mergeChild := n.children.removeAt(i + 1).mutableFor(n.cow)
- child.items = append(child.items, mergeItem)
- child.items = append(child.items, mergeChild.items...)
- child.children = append(child.children, mergeChild.children...)
- n.cow.freeNode(mergeChild)
- }
- return n.remove(item, minItems, typ)
-}
-
-type direction int
-
-const (
- descend = direction(-1)
- ascend = direction(+1)
-)
-
-// iterate provides a simple method for iterating over elements in the tree.
-//
-// When ascending, the 'start' should be less than 'stop' and when descending,
-// the 'start' should be greater than 'stop'. Setting 'includeStart' to true
-// will force the iterator to include the first item when it equals 'start',
-// thus creating a "greaterOrEqual" or "lessThanEqual" rather than just a
-// "greaterThan" or "lessThan" queries.
-func (n *node) iterate(dir direction, start, stop Item, includeStart bool, hit bool, iter ItemIterator) (bool, bool) {
- var ok, found bool
- var index int
- switch dir {
- case ascend:
- if start != nil {
- index, _ = n.items.find(start)
- }
- for i := index; i < len(n.items); i++ {
- if len(n.children) > 0 {
- if hit, ok = n.children[i].iterate(dir, start, stop, includeStart, hit, iter); !ok {
- return hit, false
- }
- }
- if !includeStart && !hit && start != nil && !start.Less(n.items[i]) {
- hit = true
- continue
- }
- hit = true
- if stop != nil && !n.items[i].Less(stop) {
- return hit, false
- }
- if !iter(n.items[i]) {
- return hit, false
- }
- }
- if len(n.children) > 0 {
- if hit, ok = n.children[len(n.children)-1].iterate(dir, start, stop, includeStart, hit, iter); !ok {
- return hit, false
- }
- }
- case descend:
- if start != nil {
- index, found = n.items.find(start)
- if !found {
- index = index - 1
- }
- } else {
- index = len(n.items) - 1
- }
- for i := index; i >= 0; i-- {
- if start != nil && !n.items[i].Less(start) {
- if !includeStart || hit || start.Less(n.items[i]) {
- continue
- }
- }
- if len(n.children) > 0 {
- if hit, ok = n.children[i+1].iterate(dir, start, stop, includeStart, hit, iter); !ok {
- return hit, false
- }
- }
- if stop != nil && !stop.Less(n.items[i]) {
- return hit, false // continue
- }
- hit = true
- if !iter(n.items[i]) {
- return hit, false
- }
- }
- if len(n.children) > 0 {
- if hit, ok = n.children[0].iterate(dir, start, stop, includeStart, hit, iter); !ok {
- return hit, false
- }
- }
- }
- return hit, true
-}
-
-// Used for testing/debugging purposes.
-func (n *node) print(w io.Writer, level int) {
- fmt.Fprintf(w, "%sNODE:%v\n", strings.Repeat(" ", level), n.items)
- for _, c := range n.children {
- c.print(w, level+1)
- }
-}
-
-// BTree is an implementation of a B-Tree.
-//
-// BTree stores Item instances in an ordered structure, allowing easy insertion,
-// removal, and iteration.
-//
-// Write operations are not safe for concurrent mutation by multiple
-// goroutines, but Read operations are.
-type BTree struct {
- degree int
- length int
- root *node
- cow *copyOnWriteContext
-}
-
-// copyOnWriteContext pointers determine node ownership... a tree with a write
-// context equivalent to a node's write context is allowed to modify that node.
-// A tree whose write context does not match a node's is not allowed to modify
-// it, and must create a new, writable copy (IE: it's a Clone).
-//
-// When doing any write operation, we maintain the invariant that the current
-// node's context is equal to the context of the tree that requested the write.
-// We do this by, before we descend into any node, creating a copy with the
-// correct context if the contexts don't match.
-//
-// Since the node we're currently visiting on any write has the requesting
-// tree's context, that node is modifiable in place. Children of that node may
-// not share context, but before we descend into them, we'll make a mutable
-// copy.
-type copyOnWriteContext struct {
- freelist *FreeList
-}
-
-// Clone clones the btree, lazily. Clone should not be called concurrently,
-// but the original tree (t) and the new tree (t2) can be used concurrently
-// once the Clone call completes.
-//
-// The internal tree structure of b is marked read-only and shared between t and
-// t2. Writes to both t and t2 use copy-on-write logic, creating new nodes
-// whenever one of b's original nodes would have been modified. Read operations
-// should have no performance degredation. Write operations for both t and t2
-// will initially experience minor slow-downs caused by additional allocs and
-// copies due to the aforementioned copy-on-write logic, but should converge to
-// the original performance characteristics of the original tree.
-func (t *BTree) Clone() (t2 *BTree) {
- // Create two entirely new copy-on-write contexts.
- // This operation effectively creates three trees:
- // the original, shared nodes (old b.cow)
- // the new b.cow nodes
- // the new out.cow nodes
- cow1, cow2 := *t.cow, *t.cow
- out := *t
- t.cow = &cow1
- out.cow = &cow2
- return &out
-}
-
-// maxItems returns the max number of items to allow per node.
-func (t *BTree) maxItems() int {
- return t.degree*2 - 1
-}
-
-// minItems returns the min number of items to allow per node (ignored for the
-// root node).
-func (t *BTree) minItems() int {
- return t.degree - 1
-}
-
-func (c *copyOnWriteContext) newNode() (n *node) {
- n = c.freelist.newNode()
- n.cow = c
- return
-}
-
-type freeType int
-
-const (
- ftFreelistFull freeType = iota // node was freed (available for GC, not stored in freelist)
- ftStored // node was stored in the freelist for later use
- ftNotOwned // node was ignored by COW, since it's owned by another one
-)
-
-// freeNode frees a node within a given COW context, if it's owned by that
-// context. It returns what happened to the node (see freeType const
-// documentation).
-func (c *copyOnWriteContext) freeNode(n *node) freeType {
- if n.cow == c {
- // clear to allow GC
- n.items.truncate(0)
- n.children.truncate(0)
- n.cow = nil
- if c.freelist.freeNode(n) {
- return ftStored
- } else {
- return ftFreelistFull
- }
- } else {
- return ftNotOwned
- }
-}
-
-// ReplaceOrInsert adds the given item to the tree. If an item in the tree
-// already equals the given one, it is removed from the tree and returned.
-// Otherwise, nil is returned.
-//
-// nil cannot be added to the tree (will panic).
-func (t *BTree) ReplaceOrInsert(item Item) Item {
- if item == nil {
- panic("nil item being added to BTree")
- }
- if t.root == nil {
- t.root = t.cow.newNode()
- t.root.items = append(t.root.items, item)
- t.length++
- return nil
- } else {
- t.root = t.root.mutableFor(t.cow)
- if len(t.root.items) >= t.maxItems() {
- item2, second := t.root.split(t.maxItems() / 2)
- oldroot := t.root
- t.root = t.cow.newNode()
- t.root.items = append(t.root.items, item2)
- t.root.children = append(t.root.children, oldroot, second)
- }
- }
- out := t.root.insert(item, t.maxItems())
- if out == nil {
- t.length++
- }
- return out
-}
-
-// Delete removes an item equal to the passed in item from the tree, returning
-// it. If no such item exists, returns nil.
-func (t *BTree) Delete(item Item) Item {
- return t.deleteItem(item, removeItem)
-}
-
-// DeleteMin removes the smallest item in the tree and returns it.
-// If no such item exists, returns nil.
-func (t *BTree) DeleteMin() Item {
- return t.deleteItem(nil, removeMin)
-}
-
-// DeleteMax removes the largest item in the tree and returns it.
-// If no such item exists, returns nil.
-func (t *BTree) DeleteMax() Item {
- return t.deleteItem(nil, removeMax)
-}
-
-func (t *BTree) deleteItem(item Item, typ toRemove) Item {
- if t.root == nil || len(t.root.items) == 0 {
- return nil
- }
- t.root = t.root.mutableFor(t.cow)
- out := t.root.remove(item, t.minItems(), typ)
- if len(t.root.items) == 0 && len(t.root.children) > 0 {
- oldroot := t.root
- t.root = t.root.children[0]
- t.cow.freeNode(oldroot)
- }
- if out != nil {
- t.length--
- }
- return out
-}
-
-// AscendRange calls the iterator for every value in the tree within the range
-// [greaterOrEqual, lessThan), until iterator returns false.
-func (t *BTree) AscendRange(greaterOrEqual, lessThan Item, iterator ItemIterator) {
- if t.root == nil {
- return
- }
- t.root.iterate(ascend, greaterOrEqual, lessThan, true, false, iterator)
-}
-
-// AscendLessThan calls the iterator for every value in the tree within the range
-// [first, pivot), until iterator returns false.
-func (t *BTree) AscendLessThan(pivot Item, iterator ItemIterator) {
- if t.root == nil {
- return
- }
- t.root.iterate(ascend, nil, pivot, false, false, iterator)
-}
-
-// AscendGreaterOrEqual calls the iterator for every value in the tree within
-// the range [pivot, last], until iterator returns false.
-func (t *BTree) AscendGreaterOrEqual(pivot Item, iterator ItemIterator) {
- if t.root == nil {
- return
- }
- t.root.iterate(ascend, pivot, nil, true, false, iterator)
-}
-
-// Ascend calls the iterator for every value in the tree within the range
-// [first, last], until iterator returns false.
-func (t *BTree) Ascend(iterator ItemIterator) {
- if t.root == nil {
- return
- }
- t.root.iterate(ascend, nil, nil, false, false, iterator)
-}
-
-// DescendRange calls the iterator for every value in the tree within the range
-// [lessOrEqual, greaterThan), until iterator returns false.
-func (t *BTree) DescendRange(lessOrEqual, greaterThan Item, iterator ItemIterator) {
- if t.root == nil {
- return
- }
- t.root.iterate(descend, lessOrEqual, greaterThan, true, false, iterator)
-}
-
-// DescendLessOrEqual calls the iterator for every value in the tree within the range
-// [pivot, first], until iterator returns false.
-func (t *BTree) DescendLessOrEqual(pivot Item, iterator ItemIterator) {
- if t.root == nil {
- return
- }
- t.root.iterate(descend, pivot, nil, true, false, iterator)
-}
-
-// DescendGreaterThan calls the iterator for every value in the tree within
-// the range [last, pivot), until iterator returns false.
-func (t *BTree) DescendGreaterThan(pivot Item, iterator ItemIterator) {
- if t.root == nil {
- return
- }
- t.root.iterate(descend, nil, pivot, false, false, iterator)
-}
-
-// Descend calls the iterator for every value in the tree within the range
-// [last, first], until iterator returns false.
-func (t *BTree) Descend(iterator ItemIterator) {
- if t.root == nil {
- return
- }
- t.root.iterate(descend, nil, nil, false, false, iterator)
-}
-
-// Get looks for the key item in the tree, returning it. It returns nil if
-// unable to find that item.
-func (t *BTree) Get(key Item) Item {
- if t.root == nil {
- return nil
- }
- return t.root.get(key)
-}
-
-// Min returns the smallest item in the tree, or nil if the tree is empty.
-func (t *BTree) Min() Item {
- return min(t.root)
-}
-
-// Max returns the largest item in the tree, or nil if the tree is empty.
-func (t *BTree) Max() Item {
- return max(t.root)
-}
-
-// Has returns true if the given key is in the tree.
-func (t *BTree) Has(key Item) bool {
- return t.Get(key) != nil
-}
-
-// Len returns the number of items currently in the tree.
-func (t *BTree) Len() int {
- return t.length
-}
-
-// Clear removes all items from the btree. If addNodesToFreelist is true,
-// t's nodes are added to its freelist as part of this call, until the freelist
-// is full. Otherwise, the root node is simply dereferenced and the subtree
-// left to Go's normal GC processes.
-//
-// This can be much faster
-// than calling Delete on all elements, because that requires finding/removing
-// each element in the tree and updating the tree accordingly. It also is
-// somewhat faster than creating a new tree to replace the old one, because
-// nodes from the old tree are reclaimed into the freelist for use by the new
-// one, instead of being lost to the garbage collector.
-//
-// This call takes:
-// O(1): when addNodesToFreelist is false, this is a single operation.
-// O(1): when the freelist is already full, it breaks out immediately
-// O(freelist size): when the freelist is empty and the nodes are all owned
-// by this tree, nodes are added to the freelist until full.
-// O(tree size): when all nodes are owned by another tree, all nodes are
-// iterated over looking for nodes to add to the freelist, and due to
-// ownership, none are.
-func (t *BTree) Clear(addNodesToFreelist bool) {
- if t.root != nil && addNodesToFreelist {
- t.root.reset(t.cow)
- }
- t.root, t.length = nil, 0
-}
-
-// reset returns a subtree to the freelist. It breaks out immediately if the
-// freelist is full, since the only benefit of iterating is to fill that
-// freelist up. Returns true if parent reset call should continue.
-func (n *node) reset(c *copyOnWriteContext) bool {
- for _, child := range n.children {
- if !child.reset(c) {
- return false
- }
- }
- return c.freeNode(n) != ftFreelistFull
-}
-
-// Int implements the Item interface for integers.
-type Int int
-
-// Less returns true if int(a) < int(b).
-func (a Int) Less(b Item) bool {
- return a < b.(Int)
-}
diff --git a/vendor/github.com/google/btree/btree_generic.go b/vendor/github.com/google/btree/btree_generic.go
deleted file mode 100644
index e44a0f488..000000000
--- a/vendor/github.com/google/btree/btree_generic.go
+++ /dev/null
@@ -1,1083 +0,0 @@
-// Copyright 2014-2022 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.
-
-//go:build go1.18
-// +build go1.18
-
-// In Go 1.18 and beyond, a BTreeG generic is created, and BTree is a specific
-// instantiation of that generic for the Item interface, with a backwards-
-// compatible API. Before go1.18, generics are not supported,
-// and BTree is just an implementation based around the Item interface.
-
-// Package btree implements in-memory B-Trees of arbitrary degree.
-//
-// btree implements an in-memory B-Tree for use as an ordered data structure.
-// It is not meant for persistent storage solutions.
-//
-// It has a flatter structure than an equivalent red-black or other binary tree,
-// which in some cases yields better memory usage and/or performance.
-// See some discussion on the matter here:
-// http://google-opensource.blogspot.com/2013/01/c-containers-that-save-memory-and-time.html
-// Note, though, that this project is in no way related to the C++ B-Tree
-// implementation written about there.
-//
-// Within this tree, each node contains a slice of items and a (possibly nil)
-// slice of children. For basic numeric values or raw structs, this can cause
-// efficiency differences when compared to equivalent C++ template code that
-// stores values in arrays within the node:
-// * Due to the overhead of storing values as interfaces (each
-// value needs to be stored as the value itself, then 2 words for the
-// interface pointing to that value and its type), resulting in higher
-// memory use.
-// * Since interfaces can point to values anywhere in memory, values are
-// most likely not stored in contiguous blocks, resulting in a higher
-// number of cache misses.
-// These issues don't tend to matter, though, when working with strings or other
-// heap-allocated structures, since C++-equivalent structures also must store
-// pointers and also distribute their values across the heap.
-//
-// This implementation is designed to be a drop-in replacement to gollrb.LLRB
-// trees, (http://github.com/petar/gollrb), an excellent and probably the most
-// widely used ordered tree implementation in the Go ecosystem currently.
-// Its functions, therefore, exactly mirror those of
-// llrb.LLRB where possible. Unlike gollrb, though, we currently don't
-// support storing multiple equivalent values.
-//
-// There are two implementations; those suffixed with 'G' are generics, usable
-// for any type, and require a passed-in "less" function to define their ordering.
-// Those without this prefix are specific to the 'Item' interface, and use
-// its 'Less' function for ordering.
-package btree
-
-import (
- "fmt"
- "io"
- "sort"
- "strings"
- "sync"
-)
-
-// Item represents a single object in the tree.
-type Item interface {
- // Less tests whether the current item is less than the given argument.
- //
- // This must provide a strict weak ordering.
- // If !a.Less(b) && !b.Less(a), we treat this to mean a == b (i.e. we can only
- // hold one of either a or b in the tree).
- Less(than Item) bool
-}
-
-const (
- DefaultFreeListSize = 32
-)
-
-// FreeListG represents a free list of btree nodes. By default each
-// BTree has its own FreeList, but multiple BTrees can share the same
-// FreeList, in particular when they're created with Clone.
-// Two Btrees using the same freelist are safe for concurrent write access.
-type FreeListG[T any] struct {
- mu sync.Mutex
- freelist []*node[T]
-}
-
-// NewFreeListG creates a new free list.
-// size is the maximum size of the returned free list.
-func NewFreeListG[T any](size int) *FreeListG[T] {
- return &FreeListG[T]{freelist: make([]*node[T], 0, size)}
-}
-
-func (f *FreeListG[T]) newNode() (n *node[T]) {
- f.mu.Lock()
- index := len(f.freelist) - 1
- if index < 0 {
- f.mu.Unlock()
- return new(node[T])
- }
- n = f.freelist[index]
- f.freelist[index] = nil
- f.freelist = f.freelist[:index]
- f.mu.Unlock()
- return
-}
-
-func (f *FreeListG[T]) freeNode(n *node[T]) (out bool) {
- f.mu.Lock()
- if len(f.freelist) < cap(f.freelist) {
- f.freelist = append(f.freelist, n)
- out = true
- }
- f.mu.Unlock()
- return
-}
-
-// ItemIteratorG allows callers of {A/De}scend* to iterate in-order over portions of
-// the tree. When this function returns false, iteration will stop and the
-// associated Ascend* function will immediately return.
-type ItemIteratorG[T any] func(item T) bool
-
-// Ordered represents the set of types for which the '<' operator work.
-type Ordered interface {
- ~int | ~int8 | ~int16 | ~int32 | ~int64 | ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~float32 | ~float64 | ~string
-}
-
-// Less[T] returns a default LessFunc that uses the '<' operator for types that support it.
-func Less[T Ordered]() LessFunc[T] {
- return func(a, b T) bool { return a < b }
-}
-
-// NewOrderedG creates a new B-Tree for ordered types.
-func NewOrderedG[T Ordered](degree int) *BTreeG[T] {
- return NewG[T](degree, Less[T]())
-}
-
-// NewG creates a new B-Tree with the given degree.
-//
-// NewG(2), for example, will create a 2-3-4 tree (each node contains 1-3 items
-// and 2-4 children).
-//
-// The passed-in LessFunc determines how objects of type T are ordered.
-func NewG[T any](degree int, less LessFunc[T]) *BTreeG[T] {
- return NewWithFreeListG(degree, less, NewFreeListG[T](DefaultFreeListSize))
-}
-
-// NewWithFreeListG creates a new B-Tree that uses the given node free list.
-func NewWithFreeListG[T any](degree int, less LessFunc[T], f *FreeListG[T]) *BTreeG[T] {
- if degree <= 1 {
- panic("bad degree")
- }
- return &BTreeG[T]{
- degree: degree,
- cow: ©OnWriteContext[T]{freelist: f, less: less},
- }
-}
-
-// items stores items in a node.
-type items[T any] []T
-
-// insertAt inserts a value into the given index, pushing all subsequent values
-// forward.
-func (s *items[T]) insertAt(index int, item T) {
- var zero T
- *s = append(*s, zero)
- if index < len(*s) {
- copy((*s)[index+1:], (*s)[index:])
- }
- (*s)[index] = item
-}
-
-// removeAt removes a value at a given index, pulling all subsequent values
-// back.
-func (s *items[T]) removeAt(index int) T {
- item := (*s)[index]
- copy((*s)[index:], (*s)[index+1:])
- var zero T
- (*s)[len(*s)-1] = zero
- *s = (*s)[:len(*s)-1]
- return item
-}
-
-// pop removes and returns the last element in the list.
-func (s *items[T]) pop() (out T) {
- index := len(*s) - 1
- out = (*s)[index]
- var zero T
- (*s)[index] = zero
- *s = (*s)[:index]
- return
-}
-
-// truncate truncates this instance at index so that it contains only the
-// first index items. index must be less than or equal to length.
-func (s *items[T]) truncate(index int) {
- var toClear items[T]
- *s, toClear = (*s)[:index], (*s)[index:]
- var zero T
- for i := 0; i < len(toClear); i++ {
- toClear[i] = zero
- }
-}
-
-// find returns the index where the given item should be inserted into this
-// list. 'found' is true if the item already exists in the list at the given
-// index.
-func (s items[T]) find(item T, less func(T, T) bool) (index int, found bool) {
- i := sort.Search(len(s), func(i int) bool {
- return less(item, s[i])
- })
- if i > 0 && !less(s[i-1], item) {
- return i - 1, true
- }
- return i, false
-}
-
-// node is an internal node in a tree.
-//
-// It must at all times maintain the invariant that either
-// * len(children) == 0, len(items) unconstrained
-// * len(children) == len(items) + 1
-type node[T any] struct {
- items items[T]
- children items[*node[T]]
- cow *copyOnWriteContext[T]
-}
-
-func (n *node[T]) mutableFor(cow *copyOnWriteContext[T]) *node[T] {
- if n.cow == cow {
- return n
- }
- out := cow.newNode()
- if cap(out.items) >= len(n.items) {
- out.items = out.items[:len(n.items)]
- } else {
- out.items = make(items[T], len(n.items), cap(n.items))
- }
- copy(out.items, n.items)
- // Copy children
- if cap(out.children) >= len(n.children) {
- out.children = out.children[:len(n.children)]
- } else {
- out.children = make(items[*node[T]], len(n.children), cap(n.children))
- }
- copy(out.children, n.children)
- return out
-}
-
-func (n *node[T]) mutableChild(i int) *node[T] {
- c := n.children[i].mutableFor(n.cow)
- n.children[i] = c
- return c
-}
-
-// split splits the given node at the given index. The current node shrinks,
-// and this function returns the item that existed at that index and a new node
-// containing all items/children after it.
-func (n *node[T]) split(i int) (T, *node[T]) {
- item := n.items[i]
- next := n.cow.newNode()
- next.items = append(next.items, n.items[i+1:]...)
- n.items.truncate(i)
- if len(n.children) > 0 {
- next.children = append(next.children, n.children[i+1:]...)
- n.children.truncate(i + 1)
- }
- return item, next
-}
-
-// maybeSplitChild checks if a child should be split, and if so splits it.
-// Returns whether or not a split occurred.
-func (n *node[T]) maybeSplitChild(i, maxItems int) bool {
- if len(n.children[i].items) < maxItems {
- return false
- }
- first := n.mutableChild(i)
- item, second := first.split(maxItems / 2)
- n.items.insertAt(i, item)
- n.children.insertAt(i+1, second)
- return true
-}
-
-// insert inserts an item into the subtree rooted at this node, making sure
-// no nodes in the subtree exceed maxItems items. Should an equivalent item be
-// be found/replaced by insert, it will be returned.
-func (n *node[T]) insert(item T, maxItems int) (_ T, _ bool) {
- i, found := n.items.find(item, n.cow.less)
- if found {
- out := n.items[i]
- n.items[i] = item
- return out, true
- }
- if len(n.children) == 0 {
- n.items.insertAt(i, item)
- return
- }
- if n.maybeSplitChild(i, maxItems) {
- inTree := n.items[i]
- switch {
- case n.cow.less(item, inTree):
- // no change, we want first split node
- case n.cow.less(inTree, item):
- i++ // we want second split node
- default:
- out := n.items[i]
- n.items[i] = item
- return out, true
- }
- }
- return n.mutableChild(i).insert(item, maxItems)
-}
-
-// get finds the given key in the subtree and returns it.
-func (n *node[T]) get(key T) (_ T, _ bool) {
- i, found := n.items.find(key, n.cow.less)
- if found {
- return n.items[i], true
- } else if len(n.children) > 0 {
- return n.children[i].get(key)
- }
- return
-}
-
-// min returns the first item in the subtree.
-func min[T any](n *node[T]) (_ T, found bool) {
- if n == nil {
- return
- }
- for len(n.children) > 0 {
- n = n.children[0]
- }
- if len(n.items) == 0 {
- return
- }
- return n.items[0], true
-}
-
-// max returns the last item in the subtree.
-func max[T any](n *node[T]) (_ T, found bool) {
- if n == nil {
- return
- }
- for len(n.children) > 0 {
- n = n.children[len(n.children)-1]
- }
- if len(n.items) == 0 {
- return
- }
- return n.items[len(n.items)-1], true
-}
-
-// toRemove details what item to remove in a node.remove call.
-type toRemove int
-
-const (
- removeItem toRemove = iota // removes the given item
- removeMin // removes smallest item in the subtree
- removeMax // removes largest item in the subtree
-)
-
-// remove removes an item from the subtree rooted at this node.
-func (n *node[T]) remove(item T, minItems int, typ toRemove) (_ T, _ bool) {
- var i int
- var found bool
- switch typ {
- case removeMax:
- if len(n.children) == 0 {
- return n.items.pop(), true
- }
- i = len(n.items)
- case removeMin:
- if len(n.children) == 0 {
- return n.items.removeAt(0), true
- }
- i = 0
- case removeItem:
- i, found = n.items.find(item, n.cow.less)
- if len(n.children) == 0 {
- if found {
- return n.items.removeAt(i), true
- }
- return
- }
- default:
- panic("invalid type")
- }
- // If we get to here, we have children.
- if len(n.children[i].items) <= minItems {
- return n.growChildAndRemove(i, item, minItems, typ)
- }
- child := n.mutableChild(i)
- // Either we had enough items to begin with, or we've done some
- // merging/stealing, because we've got enough now and we're ready to return
- // stuff.
- if found {
- // The item exists at index 'i', and the child we've selected can give us a
- // predecessor, since if we've gotten here it's got > minItems items in it.
- out := n.items[i]
- // We use our special-case 'remove' call with typ=maxItem to pull the
- // predecessor of item i (the rightmost leaf of our immediate left child)
- // and set it into where we pulled the item from.
- var zero T
- n.items[i], _ = child.remove(zero, minItems, removeMax)
- return out, true
- }
- // Final recursive call. Once we're here, we know that the item isn't in this
- // node and that the child is big enough to remove from.
- return child.remove(item, minItems, typ)
-}
-
-// growChildAndRemove grows child 'i' to make sure it's possible to remove an
-// item from it while keeping it at minItems, then calls remove to actually
-// remove it.
-//
-// Most documentation says we have to do two sets of special casing:
-// 1) item is in this node
-// 2) item is in child
-// In both cases, we need to handle the two subcases:
-// A) node has enough values that it can spare one
-// B) node doesn't have enough values
-// For the latter, we have to check:
-// a) left sibling has node to spare
-// b) right sibling has node to spare
-// c) we must merge
-// To simplify our code here, we handle cases #1 and #2 the same:
-// If a node doesn't have enough items, we make sure it does (using a,b,c).
-// We then simply redo our remove call, and the second time (regardless of
-// whether we're in case 1 or 2), we'll have enough items and can guarantee
-// that we hit case A.
-func (n *node[T]) growChildAndRemove(i int, item T, minItems int, typ toRemove) (T, bool) {
- if i > 0 && len(n.children[i-1].items) > minItems {
- // Steal from left child
- child := n.mutableChild(i)
- stealFrom := n.mutableChild(i - 1)
- stolenItem := stealFrom.items.pop()
- child.items.insertAt(0, n.items[i-1])
- n.items[i-1] = stolenItem
- if len(stealFrom.children) > 0 {
- child.children.insertAt(0, stealFrom.children.pop())
- }
- } else if i < len(n.items) && len(n.children[i+1].items) > minItems {
- // steal from right child
- child := n.mutableChild(i)
- stealFrom := n.mutableChild(i + 1)
- stolenItem := stealFrom.items.removeAt(0)
- child.items = append(child.items, n.items[i])
- n.items[i] = stolenItem
- if len(stealFrom.children) > 0 {
- child.children = append(child.children, stealFrom.children.removeAt(0))
- }
- } else {
- if i >= len(n.items) {
- i--
- }
- child := n.mutableChild(i)
- // merge with right child
- mergeItem := n.items.removeAt(i)
- mergeChild := n.children.removeAt(i + 1)
- child.items = append(child.items, mergeItem)
- child.items = append(child.items, mergeChild.items...)
- child.children = append(child.children, mergeChild.children...)
- n.cow.freeNode(mergeChild)
- }
- return n.remove(item, minItems, typ)
-}
-
-type direction int
-
-const (
- descend = direction(-1)
- ascend = direction(+1)
-)
-
-type optionalItem[T any] struct {
- item T
- valid bool
-}
-
-func optional[T any](item T) optionalItem[T] {
- return optionalItem[T]{item: item, valid: true}
-}
-func empty[T any]() optionalItem[T] {
- return optionalItem[T]{}
-}
-
-// iterate provides a simple method for iterating over elements in the tree.
-//
-// When ascending, the 'start' should be less than 'stop' and when descending,
-// the 'start' should be greater than 'stop'. Setting 'includeStart' to true
-// will force the iterator to include the first item when it equals 'start',
-// thus creating a "greaterOrEqual" or "lessThanEqual" rather than just a
-// "greaterThan" or "lessThan" queries.
-func (n *node[T]) iterate(dir direction, start, stop optionalItem[T], includeStart bool, hit bool, iter ItemIteratorG[T]) (bool, bool) {
- var ok, found bool
- var index int
- switch dir {
- case ascend:
- if start.valid {
- index, _ = n.items.find(start.item, n.cow.less)
- }
- for i := index; i < len(n.items); i++ {
- if len(n.children) > 0 {
- if hit, ok = n.children[i].iterate(dir, start, stop, includeStart, hit, iter); !ok {
- return hit, false
- }
- }
- if !includeStart && !hit && start.valid && !n.cow.less(start.item, n.items[i]) {
- hit = true
- continue
- }
- hit = true
- if stop.valid && !n.cow.less(n.items[i], stop.item) {
- return hit, false
- }
- if !iter(n.items[i]) {
- return hit, false
- }
- }
- if len(n.children) > 0 {
- if hit, ok = n.children[len(n.children)-1].iterate(dir, start, stop, includeStart, hit, iter); !ok {
- return hit, false
- }
- }
- case descend:
- if start.valid {
- index, found = n.items.find(start.item, n.cow.less)
- if !found {
- index = index - 1
- }
- } else {
- index = len(n.items) - 1
- }
- for i := index; i >= 0; i-- {
- if start.valid && !n.cow.less(n.items[i], start.item) {
- if !includeStart || hit || n.cow.less(start.item, n.items[i]) {
- continue
- }
- }
- if len(n.children) > 0 {
- if hit, ok = n.children[i+1].iterate(dir, start, stop, includeStart, hit, iter); !ok {
- return hit, false
- }
- }
- if stop.valid && !n.cow.less(stop.item, n.items[i]) {
- return hit, false // continue
- }
- hit = true
- if !iter(n.items[i]) {
- return hit, false
- }
- }
- if len(n.children) > 0 {
- if hit, ok = n.children[0].iterate(dir, start, stop, includeStart, hit, iter); !ok {
- return hit, false
- }
- }
- }
- return hit, true
-}
-
-// print is used for testing/debugging purposes.
-func (n *node[T]) print(w io.Writer, level int) {
- fmt.Fprintf(w, "%sNODE:%v\n", strings.Repeat(" ", level), n.items)
- for _, c := range n.children {
- c.print(w, level+1)
- }
-}
-
-// BTreeG is a generic implementation of a B-Tree.
-//
-// BTreeG stores items of type T in an ordered structure, allowing easy insertion,
-// removal, and iteration.
-//
-// Write operations are not safe for concurrent mutation by multiple
-// goroutines, but Read operations are.
-type BTreeG[T any] struct {
- degree int
- length int
- root *node[T]
- cow *copyOnWriteContext[T]
-}
-
-// LessFunc[T] determines how to order a type 'T'. It should implement a strict
-// ordering, and should return true if within that ordering, 'a' < 'b'.
-type LessFunc[T any] func(a, b T) bool
-
-// copyOnWriteContext pointers determine node ownership... a tree with a write
-// context equivalent to a node's write context is allowed to modify that node.
-// A tree whose write context does not match a node's is not allowed to modify
-// it, and must create a new, writable copy (IE: it's a Clone).
-//
-// When doing any write operation, we maintain the invariant that the current
-// node's context is equal to the context of the tree that requested the write.
-// We do this by, before we descend into any node, creating a copy with the
-// correct context if the contexts don't match.
-//
-// Since the node we're currently visiting on any write has the requesting
-// tree's context, that node is modifiable in place. Children of that node may
-// not share context, but before we descend into them, we'll make a mutable
-// copy.
-type copyOnWriteContext[T any] struct {
- freelist *FreeListG[T]
- less LessFunc[T]
-}
-
-// Clone clones the btree, lazily. Clone should not be called concurrently,
-// but the original tree (t) and the new tree (t2) can be used concurrently
-// once the Clone call completes.
-//
-// The internal tree structure of b is marked read-only and shared between t and
-// t2. Writes to both t and t2 use copy-on-write logic, creating new nodes
-// whenever one of b's original nodes would have been modified. Read operations
-// should have no performance degredation. Write operations for both t and t2
-// will initially experience minor slow-downs caused by additional allocs and
-// copies due to the aforementioned copy-on-write logic, but should converge to
-// the original performance characteristics of the original tree.
-func (t *BTreeG[T]) Clone() (t2 *BTreeG[T]) {
- // Create two entirely new copy-on-write contexts.
- // This operation effectively creates three trees:
- // the original, shared nodes (old b.cow)
- // the new b.cow nodes
- // the new out.cow nodes
- cow1, cow2 := *t.cow, *t.cow
- out := *t
- t.cow = &cow1
- out.cow = &cow2
- return &out
-}
-
-// maxItems returns the max number of items to allow per node.
-func (t *BTreeG[T]) maxItems() int {
- return t.degree*2 - 1
-}
-
-// minItems returns the min number of items to allow per node (ignored for the
-// root node).
-func (t *BTreeG[T]) minItems() int {
- return t.degree - 1
-}
-
-func (c *copyOnWriteContext[T]) newNode() (n *node[T]) {
- n = c.freelist.newNode()
- n.cow = c
- return
-}
-
-type freeType int
-
-const (
- ftFreelistFull freeType = iota // node was freed (available for GC, not stored in freelist)
- ftStored // node was stored in the freelist for later use
- ftNotOwned // node was ignored by COW, since it's owned by another one
-)
-
-// freeNode frees a node within a given COW context, if it's owned by that
-// context. It returns what happened to the node (see freeType const
-// documentation).
-func (c *copyOnWriteContext[T]) freeNode(n *node[T]) freeType {
- if n.cow == c {
- // clear to allow GC
- n.items.truncate(0)
- n.children.truncate(0)
- n.cow = nil
- if c.freelist.freeNode(n) {
- return ftStored
- } else {
- return ftFreelistFull
- }
- } else {
- return ftNotOwned
- }
-}
-
-// ReplaceOrInsert adds the given item to the tree. If an item in the tree
-// already equals the given one, it is removed from the tree and returned,
-// and the second return value is true. Otherwise, (zeroValue, false)
-//
-// nil cannot be added to the tree (will panic).
-func (t *BTreeG[T]) ReplaceOrInsert(item T) (_ T, _ bool) {
- if t.root == nil {
- t.root = t.cow.newNode()
- t.root.items = append(t.root.items, item)
- t.length++
- return
- } else {
- t.root = t.root.mutableFor(t.cow)
- if len(t.root.items) >= t.maxItems() {
- item2, second := t.root.split(t.maxItems() / 2)
- oldroot := t.root
- t.root = t.cow.newNode()
- t.root.items = append(t.root.items, item2)
- t.root.children = append(t.root.children, oldroot, second)
- }
- }
- out, outb := t.root.insert(item, t.maxItems())
- if !outb {
- t.length++
- }
- return out, outb
-}
-
-// Delete removes an item equal to the passed in item from the tree, returning
-// it. If no such item exists, returns (zeroValue, false).
-func (t *BTreeG[T]) Delete(item T) (T, bool) {
- return t.deleteItem(item, removeItem)
-}
-
-// DeleteMin removes the smallest item in the tree and returns it.
-// If no such item exists, returns (zeroValue, false).
-func (t *BTreeG[T]) DeleteMin() (T, bool) {
- var zero T
- return t.deleteItem(zero, removeMin)
-}
-
-// DeleteMax removes the largest item in the tree and returns it.
-// If no such item exists, returns (zeroValue, false).
-func (t *BTreeG[T]) DeleteMax() (T, bool) {
- var zero T
- return t.deleteItem(zero, removeMax)
-}
-
-func (t *BTreeG[T]) deleteItem(item T, typ toRemove) (_ T, _ bool) {
- if t.root == nil || len(t.root.items) == 0 {
- return
- }
- t.root = t.root.mutableFor(t.cow)
- out, outb := t.root.remove(item, t.minItems(), typ)
- if len(t.root.items) == 0 && len(t.root.children) > 0 {
- oldroot := t.root
- t.root = t.root.children[0]
- t.cow.freeNode(oldroot)
- }
- if outb {
- t.length--
- }
- return out, outb
-}
-
-// AscendRange calls the iterator for every value in the tree within the range
-// [greaterOrEqual, lessThan), until iterator returns false.
-func (t *BTreeG[T]) AscendRange(greaterOrEqual, lessThan T, iterator ItemIteratorG[T]) {
- if t.root == nil {
- return
- }
- t.root.iterate(ascend, optional[T](greaterOrEqual), optional[T](lessThan), true, false, iterator)
-}
-
-// AscendLessThan calls the iterator for every value in the tree within the range
-// [first, pivot), until iterator returns false.
-func (t *BTreeG[T]) AscendLessThan(pivot T, iterator ItemIteratorG[T]) {
- if t.root == nil {
- return
- }
- t.root.iterate(ascend, empty[T](), optional(pivot), false, false, iterator)
-}
-
-// AscendGreaterOrEqual calls the iterator for every value in the tree within
-// the range [pivot, last], until iterator returns false.
-func (t *BTreeG[T]) AscendGreaterOrEqual(pivot T, iterator ItemIteratorG[T]) {
- if t.root == nil {
- return
- }
- t.root.iterate(ascend, optional[T](pivot), empty[T](), true, false, iterator)
-}
-
-// Ascend calls the iterator for every value in the tree within the range
-// [first, last], until iterator returns false.
-func (t *BTreeG[T]) Ascend(iterator ItemIteratorG[T]) {
- if t.root == nil {
- return
- }
- t.root.iterate(ascend, empty[T](), empty[T](), false, false, iterator)
-}
-
-// DescendRange calls the iterator for every value in the tree within the range
-// [lessOrEqual, greaterThan), until iterator returns false.
-func (t *BTreeG[T]) DescendRange(lessOrEqual, greaterThan T, iterator ItemIteratorG[T]) {
- if t.root == nil {
- return
- }
- t.root.iterate(descend, optional[T](lessOrEqual), optional[T](greaterThan), true, false, iterator)
-}
-
-// DescendLessOrEqual calls the iterator for every value in the tree within the range
-// [pivot, first], until iterator returns false.
-func (t *BTreeG[T]) DescendLessOrEqual(pivot T, iterator ItemIteratorG[T]) {
- if t.root == nil {
- return
- }
- t.root.iterate(descend, optional[T](pivot), empty[T](), true, false, iterator)
-}
-
-// DescendGreaterThan calls the iterator for every value in the tree within
-// the range [last, pivot), until iterator returns false.
-func (t *BTreeG[T]) DescendGreaterThan(pivot T, iterator ItemIteratorG[T]) {
- if t.root == nil {
- return
- }
- t.root.iterate(descend, empty[T](), optional[T](pivot), false, false, iterator)
-}
-
-// Descend calls the iterator for every value in the tree within the range
-// [last, first], until iterator returns false.
-func (t *BTreeG[T]) Descend(iterator ItemIteratorG[T]) {
- if t.root == nil {
- return
- }
- t.root.iterate(descend, empty[T](), empty[T](), false, false, iterator)
-}
-
-// Get looks for the key item in the tree, returning it. It returns
-// (zeroValue, false) if unable to find that item.
-func (t *BTreeG[T]) Get(key T) (_ T, _ bool) {
- if t.root == nil {
- return
- }
- return t.root.get(key)
-}
-
-// Min returns the smallest item in the tree, or (zeroValue, false) if the tree is empty.
-func (t *BTreeG[T]) Min() (_ T, _ bool) {
- return min(t.root)
-}
-
-// Max returns the largest item in the tree, or (zeroValue, false) if the tree is empty.
-func (t *BTreeG[T]) Max() (_ T, _ bool) {
- return max(t.root)
-}
-
-// Has returns true if the given key is in the tree.
-func (t *BTreeG[T]) Has(key T) bool {
- _, ok := t.Get(key)
- return ok
-}
-
-// Len returns the number of items currently in the tree.
-func (t *BTreeG[T]) Len() int {
- return t.length
-}
-
-// Clear removes all items from the btree. If addNodesToFreelist is true,
-// t's nodes are added to its freelist as part of this call, until the freelist
-// is full. Otherwise, the root node is simply dereferenced and the subtree
-// left to Go's normal GC processes.
-//
-// This can be much faster
-// than calling Delete on all elements, because that requires finding/removing
-// each element in the tree and updating the tree accordingly. It also is
-// somewhat faster than creating a new tree to replace the old one, because
-// nodes from the old tree are reclaimed into the freelist for use by the new
-// one, instead of being lost to the garbage collector.
-//
-// This call takes:
-// O(1): when addNodesToFreelist is false, this is a single operation.
-// O(1): when the freelist is already full, it breaks out immediately
-// O(freelist size): when the freelist is empty and the nodes are all owned
-// by this tree, nodes are added to the freelist until full.
-// O(tree size): when all nodes are owned by another tree, all nodes are
-// iterated over looking for nodes to add to the freelist, and due to
-// ownership, none are.
-func (t *BTreeG[T]) Clear(addNodesToFreelist bool) {
- if t.root != nil && addNodesToFreelist {
- t.root.reset(t.cow)
- }
- t.root, t.length = nil, 0
-}
-
-// reset returns a subtree to the freelist. It breaks out immediately if the
-// freelist is full, since the only benefit of iterating is to fill that
-// freelist up. Returns true if parent reset call should continue.
-func (n *node[T]) reset(c *copyOnWriteContext[T]) bool {
- for _, child := range n.children {
- if !child.reset(c) {
- return false
- }
- }
- return c.freeNode(n) != ftFreelistFull
-}
-
-// Int implements the Item interface for integers.
-type Int int
-
-// Less returns true if int(a) < int(b).
-func (a Int) Less(b Item) bool {
- return a < b.(Int)
-}
-
-// BTree is an implementation of a B-Tree.
-//
-// BTree stores Item instances in an ordered structure, allowing easy insertion,
-// removal, and iteration.
-//
-// Write operations are not safe for concurrent mutation by multiple
-// goroutines, but Read operations are.
-type BTree BTreeG[Item]
-
-var itemLess LessFunc[Item] = func(a, b Item) bool {
- return a.Less(b)
-}
-
-// New creates a new B-Tree with the given degree.
-//
-// New(2), for example, will create a 2-3-4 tree (each node contains 1-3 items
-// and 2-4 children).
-func New(degree int) *BTree {
- return (*BTree)(NewG[Item](degree, itemLess))
-}
-
-// FreeList represents a free list of btree nodes. By default each
-// BTree has its own FreeList, but multiple BTrees can share the same
-// FreeList.
-// Two Btrees using the same freelist are safe for concurrent write access.
-type FreeList FreeListG[Item]
-
-// NewFreeList creates a new free list.
-// size is the maximum size of the returned free list.
-func NewFreeList(size int) *FreeList {
- return (*FreeList)(NewFreeListG[Item](size))
-}
-
-// NewWithFreeList creates a new B-Tree that uses the given node free list.
-func NewWithFreeList(degree int, f *FreeList) *BTree {
- return (*BTree)(NewWithFreeListG[Item](degree, itemLess, (*FreeListG[Item])(f)))
-}
-
-// ItemIterator allows callers of Ascend* to iterate in-order over portions of
-// the tree. When this function returns false, iteration will stop and the
-// associated Ascend* function will immediately return.
-type ItemIterator ItemIteratorG[Item]
-
-// Clone clones the btree, lazily. Clone should not be called concurrently,
-// but the original tree (t) and the new tree (t2) can be used concurrently
-// once the Clone call completes.
-//
-// The internal tree structure of b is marked read-only and shared between t and
-// t2. Writes to both t and t2 use copy-on-write logic, creating new nodes
-// whenever one of b's original nodes would have been modified. Read operations
-// should have no performance degredation. Write operations for both t and t2
-// will initially experience minor slow-downs caused by additional allocs and
-// copies due to the aforementioned copy-on-write logic, but should converge to
-// the original performance characteristics of the original tree.
-func (t *BTree) Clone() (t2 *BTree) {
- return (*BTree)((*BTreeG[Item])(t).Clone())
-}
-
-// Delete removes an item equal to the passed in item from the tree, returning
-// it. If no such item exists, returns nil.
-func (t *BTree) Delete(item Item) Item {
- i, _ := (*BTreeG[Item])(t).Delete(item)
- return i
-}
-
-// DeleteMax removes the largest item in the tree and returns it.
-// If no such item exists, returns nil.
-func (t *BTree) DeleteMax() Item {
- i, _ := (*BTreeG[Item])(t).DeleteMax()
- return i
-}
-
-// DeleteMin removes the smallest item in the tree and returns it.
-// If no such item exists, returns nil.
-func (t *BTree) DeleteMin() Item {
- i, _ := (*BTreeG[Item])(t).DeleteMin()
- return i
-}
-
-// Get looks for the key item in the tree, returning it. It returns nil if
-// unable to find that item.
-func (t *BTree) Get(key Item) Item {
- i, _ := (*BTreeG[Item])(t).Get(key)
- return i
-}
-
-// Max returns the largest item in the tree, or nil if the tree is empty.
-func (t *BTree) Max() Item {
- i, _ := (*BTreeG[Item])(t).Max()
- return i
-}
-
-// Min returns the smallest item in the tree, or nil if the tree is empty.
-func (t *BTree) Min() Item {
- i, _ := (*BTreeG[Item])(t).Min()
- return i
-}
-
-// Has returns true if the given key is in the tree.
-func (t *BTree) Has(key Item) bool {
- return (*BTreeG[Item])(t).Has(key)
-}
-
-// ReplaceOrInsert adds the given item to the tree. If an item in the tree
-// already equals the given one, it is removed from the tree and returned.
-// Otherwise, nil is returned.
-//
-// nil cannot be added to the tree (will panic).
-func (t *BTree) ReplaceOrInsert(item Item) Item {
- i, _ := (*BTreeG[Item])(t).ReplaceOrInsert(item)
- return i
-}
-
-// AscendRange calls the iterator for every value in the tree within the range
-// [greaterOrEqual, lessThan), until iterator returns false.
-func (t *BTree) AscendRange(greaterOrEqual, lessThan Item, iterator ItemIterator) {
- (*BTreeG[Item])(t).AscendRange(greaterOrEqual, lessThan, (ItemIteratorG[Item])(iterator))
-}
-
-// AscendLessThan calls the iterator for every value in the tree within the range
-// [first, pivot), until iterator returns false.
-func (t *BTree) AscendLessThan(pivot Item, iterator ItemIterator) {
- (*BTreeG[Item])(t).AscendLessThan(pivot, (ItemIteratorG[Item])(iterator))
-}
-
-// AscendGreaterOrEqual calls the iterator for every value in the tree within
-// the range [pivot, last], until iterator returns false.
-func (t *BTree) AscendGreaterOrEqual(pivot Item, iterator ItemIterator) {
- (*BTreeG[Item])(t).AscendGreaterOrEqual(pivot, (ItemIteratorG[Item])(iterator))
-}
-
-// Ascend calls the iterator for every value in the tree within the range
-// [first, last], until iterator returns false.
-func (t *BTree) Ascend(iterator ItemIterator) {
- (*BTreeG[Item])(t).Ascend((ItemIteratorG[Item])(iterator))
-}
-
-// DescendRange calls the iterator for every value in the tree within the range
-// [lessOrEqual, greaterThan), until iterator returns false.
-func (t *BTree) DescendRange(lessOrEqual, greaterThan Item, iterator ItemIterator) {
- (*BTreeG[Item])(t).DescendRange(lessOrEqual, greaterThan, (ItemIteratorG[Item])(iterator))
-}
-
-// DescendLessOrEqual calls the iterator for every value in the tree within the range
-// [pivot, first], until iterator returns false.
-func (t *BTree) DescendLessOrEqual(pivot Item, iterator ItemIterator) {
- (*BTreeG[Item])(t).DescendLessOrEqual(pivot, (ItemIteratorG[Item])(iterator))
-}
-
-// DescendGreaterThan calls the iterator for every value in the tree within
-// the range [last, pivot), until iterator returns false.
-func (t *BTree) DescendGreaterThan(pivot Item, iterator ItemIterator) {
- (*BTreeG[Item])(t).DescendGreaterThan(pivot, (ItemIteratorG[Item])(iterator))
-}
-
-// Descend calls the iterator for every value in the tree within the range
-// [last, first], until iterator returns false.
-func (t *BTree) Descend(iterator ItemIterator) {
- (*BTreeG[Item])(t).Descend((ItemIteratorG[Item])(iterator))
-}
-
-// Len returns the number of items currently in the tree.
-func (t *BTree) Len() int {
- return (*BTreeG[Item])(t).Len()
-}
-
-// Clear removes all items from the btree. If addNodesToFreelist is true,
-// t's nodes are added to its freelist as part of this call, until the freelist
-// is full. Otherwise, the root node is simply dereferenced and the subtree
-// left to Go's normal GC processes.
-//
-// This can be much faster
-// than calling Delete on all elements, because that requires finding/removing
-// each element in the tree and updating the tree accordingly. It also is
-// somewhat faster than creating a new tree to replace the old one, because
-// nodes from the old tree are reclaimed into the freelist for use by the new
-// one, instead of being lost to the garbage collector.
-//
-// This call takes:
-// O(1): when addNodesToFreelist is false, this is a single operation.
-// O(1): when the freelist is already full, it breaks out immediately
-// O(freelist size): when the freelist is empty and the nodes are all owned
-// by this tree, nodes are added to the freelist until full.
-// O(tree size): when all nodes are owned by another tree, all nodes are
-// iterated over looking for nodes to add to the freelist, and due to
-// ownership, none are.
-func (t *BTree) Clear(addNodesToFreelist bool) {
- (*BTreeG[Item])(t).Clear(addNodesToFreelist)
-}
diff --git a/vendor/github.com/hashicorp/go-version/CHANGELOG.md b/vendor/github.com/hashicorp/go-version/CHANGELOG.md
index 6d48174bf..81b423151 100644
--- a/vendor/github.com/hashicorp/go-version/CHANGELOG.md
+++ b/vendor/github.com/hashicorp/go-version/CHANGELOG.md
@@ -1,3 +1,41 @@
+# 1.9.0 (Mar 30, 2026)
+
+ENHANCEMENTS:
+
+Support parsing versions with custom prefixes via opt-in option in https://github.com/hashicorp/go-version/pull/79
+
+INTERNAL:
+
+- Bump the github-actions-backward-compatible group across 1 directory with 2 updates in https://github.com/hashicorp/go-version/pull/179
+- Bump the github-actions-breaking group with 4 updates in https://github.com/hashicorp/go-version/pull/180
+- Bump the github-actions-backward-compatible group with 3 updates in https://github.com/hashicorp/go-version/pull/182
+- Update GitHub Actions to trigger on pull requests and update go version in https://github.com/hashicorp/go-version/pull/185
+- Bump actions/upload-artifact from 6.0.0 to 7.0.0 in the github-actions-breaking group across 1 directory in https://github.com/hashicorp/go-version/pull/183
+- Bump the github-actions-backward-compatible group across 1 directory with 2 updates in https://github.com/hashicorp/go-version/pull/186
+
+# 1.8.0 (Nov 28, 2025)
+
+ENHANCEMENTS:
+
+- Add benchmark test for version.String() in https://github.com/hashicorp/go-version/pull/159
+- Bytes implementation in https://github.com/hashicorp/go-version/pull/161
+
+INTERNAL:
+
+- Add CODEOWNERS file in .github/CODEOWNERS in https://github.com/hashicorp/go-version/pull/145
+- Linting in https://github.com/hashicorp/go-version/pull/151
+- Correct typos in comments in https://github.com/hashicorp/go-version/pull/134
+- Migrate GitHub Actions updates from TSCCR to Dependabot in https://github.com/hashicorp/go-version/pull/155
+- Bump the github-actions-backward-compatible group with 2 updates in https://github.com/hashicorp/go-version/pull/157
+- Update doc reference in README in https://github.com/hashicorp/go-version/pull/135
+- Bump the github-actions-breaking group with 3 updates in https://github.com/hashicorp/go-version/pull/156
+- [Compliance] - PR Template Changes Required in https://github.com/hashicorp/go-version/pull/158
+- Bump actions/cache from 4.2.3 to 4.2.4 in the github-actions-backward-compatible group in https://github.com/hashicorp/go-version/pull/167
+- Bump actions/checkout from 4.2.2 to 5.0.0 in the github-actions-breaking group in https://github.com/hashicorp/go-version/pull/166
+- Bump the github-actions-breaking group across 1 directory with 2 updates in https://github.com/hashicorp/go-version/pull/171
+- [IND-4226] [COMPLIANCE] Update Copyright Headers in https://github.com/hashicorp/go-version/pull/172
+- drop init() in https://github.com/hashicorp/go-version/pull/175
+
# 1.7.0 (May 24, 2024)
ENHANCEMENTS:
diff --git a/vendor/github.com/hashicorp/go-version/README.md b/vendor/github.com/hashicorp/go-version/README.md
index 83a8249f7..552896021 100644
--- a/vendor/github.com/hashicorp/go-version/README.md
+++ b/vendor/github.com/hashicorp/go-version/README.md
@@ -34,6 +34,32 @@ if v1.LessThan(v2) {
}
```
+#### Version Parsing and Comparison with Prefixes
+
+The library also supports parsing versions with a custom prefix.
+Using the `WithPrefix` option, you can specify a prefix to strip
+before parsing the version.
+
+Use `WithPrefix` when your input strings carry a known release prefix such as
+`deployment-`, `controller-`, etc.
+
+After parsing, the prefix is not part of the canonical version value. This
+means the regular comparison methods such as `Compare`, `LessThan`, `Equal`,
+and `GreaterThan` compare only the stripped version. If you compare versions
+from different prefixes with these methods, the prefixes are ignored. If you
+need to reject cross-prefix comparisons, inspect the parsed prefixes before
+comparing the versions.
+
+```go
+v1, _ := version.NewVersion("deployment-v1.2.3-beta+metadata", version.WithPrefix("deployment-"))
+v2, _ := version.NewVersion("deployment-v1.2.4", version.WithPrefix("deployment-"))
+
+if v1.LessThan(v2) {
+ fmt.Printf("%s (%s) is less than %s (%s)\n", v1, v1.Original(), v2, v2.Original())
+ // Outputs: 1.2.3-beta+metadata (deployment-v1.2.3-beta+metadata) is less than 1.2.4 (deployment-v1.2.4)
+}
+```
+
#### Version Constraints
```go
diff --git a/vendor/github.com/hashicorp/go-version/version.go b/vendor/github.com/hashicorp/go-version/version.go
index 17b29732e..b95503d3c 100644
--- a/vendor/github.com/hashicorp/go-version/version.go
+++ b/vendor/github.com/hashicorp/go-version/version.go
@@ -49,6 +49,23 @@ const (
`?`
)
+// Optional options for NewVersion function.
+type options struct {
+ // If set, this prefix will be trimmed from the version string before parsing.
+ prefix string
+}
+
+// Option is a functional option for NewVersion.
+type Option func(*options)
+
+// WithPrefix is a functional option that sets a prefix to be removed from the
+// version string before parsing.
+func WithPrefix(prefix string) Option {
+ return func(o *options) {
+ o.prefix = prefix
+ }
+}
+
// Version represents a single version.
type Version struct {
metadata string
@@ -56,12 +73,36 @@ type Version struct {
segments []int64
si int
original string
+ prefix string
}
-// NewVersion parses the given version and returns a new
-// Version.
-func NewVersion(v string) (*Version, error) {
- return newVersion(v, getVersionRegexp())
+// NewVersion parses the given version and returns a new Version.
+//
+// Optional parsing behavior can be enabled with Option values such as
+// WithPrefix, which validates and strips an expected prefix before parsing.
+func NewVersion(v string, opts ...Option) (*Version, error) {
+ options := &options{}
+ for _, opt := range opts {
+ if opt != nil {
+ opt(options)
+ }
+ }
+
+ vToParse := v
+ if options.prefix != "" {
+ if !strings.HasPrefix(v, options.prefix) {
+ return nil, fmt.Errorf("version %q does not have prefix %q", v, options.prefix)
+ }
+ vToParse = strings.TrimPrefix(v, options.prefix)
+ }
+
+ ver, err := newVersion(vToParse, getVersionRegexp())
+ if err != nil {
+ return nil, err
+ }
+ ver.prefix = options.prefix
+ ver.original = v
+ return ver, nil
}
// NewSemver parses the given version and returns a new
@@ -424,6 +465,11 @@ func (v *Version) Original() string {
return v.original
}
+// Prefix returns the explicit prefix used with WithPrefix, if any.
+func (v *Version) Prefix() string {
+ return v.prefix
+}
+
// UnmarshalText implements encoding.TextUnmarshaler interface.
func (v *Version) UnmarshalText(b []byte) error {
temp, err := NewVersion(string(b))
diff --git a/vendor/github.com/hashicorp/hcl/decoder.go b/vendor/github.com/hashicorp/hcl/decoder.go
index d9a00f21d..39e56f222 100644
--- a/vendor/github.com/hashicorp/hcl/decoder.go
+++ b/vendor/github.com/hashicorp/hcl/decoder.go
@@ -24,7 +24,18 @@ var (
// Unmarshal accepts a byte slice as input and writes the
// data to the value pointed to by v.
func Unmarshal(bs []byte, v interface{}) error {
- root, err := parse(bs)
+ root, err := parse(bs, false)
+ if err != nil {
+ return err
+ }
+
+ return DecodeObject(v, root)
+}
+
+// UnmarshalErrorOnDuplicates accepts a byte slice as input and writes the
+// data to the value pointed to by v but errors on duplicate attribute key.
+func UnmarshalErrorOnDuplicates(bs []byte, v interface{}) error {
+ root, err := parse(bs, true)
if err != nil {
return err
}
@@ -35,7 +46,19 @@ func Unmarshal(bs []byte, v interface{}) error {
// Decode reads the given input and decodes it into the structure
// given by `out`.
func Decode(out interface{}, in string) error {
- obj, err := Parse(in)
+ return decode(out, in, false)
+}
+
+// DecodeErrorOnDuplicates reads the given input and decodes it into the structure but errrors on duplicate attribute key
+// given by `out`.
+func DecodeErrorOnDuplicates(out interface{}, in string) error {
+ return decode(out, in, true)
+}
+
+// decode reads the given input and decodes it into the structure given by `out`.
+// takes in a boolean to determine if it should error on duplicate attribute
+func decode(out interface{}, in string, errorOnDuplicateAtributes bool) error {
+ obj, err := parse([]byte(in), errorOnDuplicateAtributes)
if err != nil {
return err
}
@@ -393,10 +416,16 @@ func (d *decoder) decodeMap(name string, node ast.Node, result reflect.Value) er
// Set the final map if we can
set.Set(resultMap)
+
return nil
}
func (d *decoder) decodePtr(name string, node ast.Node, result reflect.Value) error {
+ // if pointer is not nil, decode into existing value
+ if !result.IsNil() {
+ return d.decode(name, node, result.Elem())
+ }
+
// Create an element of the concrete (non pointer) type and decode
// into that. Then set the value of the pointer to this type.
resultType := result.Type()
diff --git a/vendor/github.com/hashicorp/hcl/hcl/parser/parser.go b/vendor/github.com/hashicorp/hcl/hcl/parser/parser.go
index 64c83bcfb..0f5d929c6 100644
--- a/vendor/github.com/hashicorp/hcl/hcl/parser/parser.go
+++ b/vendor/github.com/hashicorp/hcl/hcl/parser/parser.go
@@ -27,22 +27,35 @@ type Parser struct {
enableTrace bool
indent int
n int // buffer size (max = 1)
+
+ errorOnDuplicateKeys bool
}
-func newParser(src []byte) *Parser {
+func newParser(src []byte, errorOnDuplicateKeys bool) *Parser {
return &Parser{
- sc: scanner.New(src),
+ sc: scanner.New(src),
+ errorOnDuplicateKeys: errorOnDuplicateKeys,
}
}
// Parse returns the fully parsed source and returns the abstract syntax tree.
func Parse(src []byte) (*ast.File, error) {
+ return parse(src, true)
+}
+
+// Parse returns the fully parsed source and returns the abstract syntax tree.
+func ParseDontErrorOnDuplicateKeys(src []byte) (*ast.File, error) {
+ return parse(src, false)
+}
+
+// Parse returns the fully parsed source and returns the abstract syntax tree.
+func parse(src []byte, errorOnDuplicateKeys bool) (*ast.File, error) {
// normalize all line endings
// since the scanner and output only work with "\n" line endings, we may
// end up with dangling "\r" characters in the parsed data.
src = bytes.Replace(src, []byte("\r\n"), []byte("\n"), -1)
- p := newParser(src)
+ p := newParser(src, errorOnDuplicateKeys)
return p.Parse()
}
@@ -65,6 +78,7 @@ func (p *Parser) Parse() (*ast.File, error) {
}
f.Comments = p.comments
+
return f, nil
}
@@ -76,6 +90,7 @@ func (p *Parser) objectList(obj bool) (*ast.ObjectList, error) {
defer un(trace(p, "ParseObjectList"))
node := &ast.ObjectList{}
+ seenKeys := map[string]struct{}{}
for {
if obj {
tok := p.scan()
@@ -83,11 +98,29 @@ func (p *Parser) objectList(obj bool) (*ast.ObjectList, error) {
if tok.Type == token.RBRACE {
break
}
+
}
n, err := p.objectItem()
+
if err == errEofToken {
break // we are finished
+ } else if err != nil {
+ return nil, err
+ }
+
+ if n.Assign.String() != "-" {
+ for _, key := range n.Keys {
+ if !p.errorOnDuplicateKeys {
+ break
+ }
+ _, ok := seenKeys[key.Token.Text]
+ if ok {
+ return nil, errors.New(fmt.Sprintf("The argument %q at %s was already set. Each argument can only be defined once", key.Token.Text, key.Token.Pos.String()))
+
+ }
+ seenKeys[key.Token.Text] = struct{}{}
+ }
}
// we don't return a nil node, because might want to use already
@@ -324,6 +357,8 @@ func (p *Parser) objectType() (*ast.ObjectType, error) {
// not a RBRACE, it's an syntax error and we just return it.
if err != nil && p.tok.Type != token.RBRACE {
return nil, err
+ } else if err != nil {
+ return nil, err
}
// No error, scan and expect the ending to be a brace
@@ -365,6 +400,7 @@ func (p *Parser) listType() (*ast.ListType, error) {
}
switch tok.Type {
case token.BOOL, token.NUMBER, token.FLOAT, token.STRING, token.HEREDOC:
+
node, err := p.literalType()
if err != nil {
return nil, err
diff --git a/vendor/github.com/hashicorp/hcl/parse.go b/vendor/github.com/hashicorp/hcl/parse.go
index 1fca53c4c..f4cc1255e 100644
--- a/vendor/github.com/hashicorp/hcl/parse.go
+++ b/vendor/github.com/hashicorp/hcl/parse.go
@@ -12,17 +12,20 @@ import (
//
// Input can be either JSON or HCL
func ParseBytes(in []byte) (*ast.File, error) {
- return parse(in)
+ return parse(in, true)
}
// ParseString accepts input as a string and returns ast tree.
func ParseString(input string) (*ast.File, error) {
- return parse([]byte(input))
+ return parse([]byte(input), true)
}
-func parse(in []byte) (*ast.File, error) {
+func parse(in []byte, errorOnDuplicateKeys bool) (*ast.File, error) {
switch lexMode(in) {
case lexModeHcl:
+ if !errorOnDuplicateKeys {
+ return hclParser.ParseDontErrorOnDuplicateKeys(in)
+ }
return hclParser.Parse(in)
case lexModeJson:
return jsonParser.Parse(in)
@@ -35,5 +38,5 @@ func parse(in []byte) (*ast.File, error) {
//
// The input format can be either HCL or JSON.
func Parse(input string) (*ast.File, error) {
- return parse([]byte(input))
+ return parse([]byte(input), true)
}
diff --git a/vendor/github.com/huandu/xstrings/README.md b/vendor/github.com/huandu/xstrings/README.md
index 750c3c7eb..e809c79ab 100644
--- a/vendor/github.com/huandu/xstrings/README.md
+++ b/vendor/github.com/huandu/xstrings/README.md
@@ -39,8 +39,8 @@ _Keep this table sorted by Function in ascending order._
| [Count](https://godoc.org/github.com/huandu/xstrings#Count) | `String#count` in Ruby | [#16](https://github.com/huandu/xstrings/issues/16) |
| [Delete](https://godoc.org/github.com/huandu/xstrings#Delete) | `String#delete` in Ruby | [#17](https://github.com/huandu/xstrings/issues/17) |
| [ExpandTabs](https://godoc.org/github.com/huandu/xstrings#ExpandTabs) | `str.expandtabs` in Python | [#27](https://github.com/huandu/xstrings/issues/27) |
-| [FirstRuneToLower](https://godoc.org/github.com/huandu/xstrings#FirstRuneToLower) | `lcfirst` in PHP or Perl | [#15](https://github.com/huandu/xstrings/issues/15) |
-| [FirstRuneToUpper](https://godoc.org/github.com/huandu/xstrings#FirstRuneToUpper) | `String#capitalize` in Ruby; `ucfirst` in PHP or Perl | [#15](https://github.com/huandu/xstrings/issues/15) |
+| [FirstRuneToLower](https://godoc.org/github.com/huandu/xstrings#FirstRuneToLower) | `lcfirst` in PHP or Perl | [#15](https://github.com/huandu/xstrings/issues/15) |
+| [FirstRuneToUpper](https://godoc.org/github.com/huandu/xstrings#FirstRuneToUpper) | `String#capitalize` in Ruby; `ucfirst` in PHP or Perl | [#15](https://github.com/huandu/xstrings/issues/15) |
| [Insert](https://godoc.org/github.com/huandu/xstrings#Insert) | `String#insert` in Ruby | [#18](https://github.com/huandu/xstrings/issues/18) |
| [LastPartition](https://godoc.org/github.com/huandu/xstrings#LastPartition) | `str.rpartition` in Python; `String#rpartition` in Ruby | [#19](https://github.com/huandu/xstrings/issues/19) |
| [LeftJustify](https://godoc.org/github.com/huandu/xstrings#LeftJustify) | `str.ljust` in Python; `String#ljust` in Ruby | [#28](https://github.com/huandu/xstrings/issues/28) |
@@ -50,14 +50,15 @@ _Keep this table sorted by Function in ascending order._
| [RightJustify](https://godoc.org/github.com/huandu/xstrings#RightJustify) | `str.rjust` in Python; `String#rjust` in Ruby | [#29](https://github.com/huandu/xstrings/issues/29) |
| [RuneWidth](https://godoc.org/github.com/huandu/xstrings#RuneWidth) | - | [#27](https://github.com/huandu/xstrings/issues/27) |
| [Scrub](https://godoc.org/github.com/huandu/xstrings#Scrub) | `String#scrub` in Ruby | [#20](https://github.com/huandu/xstrings/issues/20) |
-| [Shuffle](https://godoc.org/github.com/huandu/xstrings#Shuffle) | `str_shuffle` in PHP | [#13](https://github.com/huandu/xstrings/issues/13) |
-| [ShuffleSource](https://godoc.org/github.com/huandu/xstrings#ShuffleSource) | `str_shuffle` in PHP | [#13](https://github.com/huandu/xstrings/issues/13) |
+| [Shuffle](https://godoc.org/github.com/huandu/xstrings#Shuffle) | `str_shuffle` in PHP | [#13](https://github.com/huandu/xstrings/issues/13) |
+| [ShuffleSource](https://godoc.org/github.com/huandu/xstrings#ShuffleSource) | `str_shuffle` in PHP | [#13](https://github.com/huandu/xstrings/issues/13) |
| [Slice](https://godoc.org/github.com/huandu/xstrings#Slice) | `mb_substr` in PHP | [#9](https://github.com/huandu/xstrings/issues/9) |
| [Squeeze](https://godoc.org/github.com/huandu/xstrings#Squeeze) | `String#squeeze` in Ruby | [#11](https://github.com/huandu/xstrings/issues/11) |
| [Successor](https://godoc.org/github.com/huandu/xstrings#Successor) | `String#succ` or `String#next` in Ruby | [#22](https://github.com/huandu/xstrings/issues/22) |
| [SwapCase](https://godoc.org/github.com/huandu/xstrings#SwapCase) | `str.swapcase` in Python; `String#swapcase` in Ruby | [#12](https://github.com/huandu/xstrings/issues/12) |
| [ToCamelCase](https://godoc.org/github.com/huandu/xstrings#ToCamelCase) | `String#camelize` in RoR | [#1](https://github.com/huandu/xstrings/issues/1) |
| [ToKebab](https://godoc.org/github.com/huandu/xstrings#ToKebabCase) | - | [#41](https://github.com/huandu/xstrings/issues/41) |
+| [ToPascalCase](https://godoc.org/github.com/huandu/xstrings#ToPascalCase) | - | [#1](https://github.com/huandu/xstrings/issues/1) |
| [ToSnakeCase](https://godoc.org/github.com/huandu/xstrings#ToSnakeCase) | `String#underscore` in RoR | [#1](https://github.com/huandu/xstrings/issues/1) |
| [Translate](https://godoc.org/github.com/huandu/xstrings#Translate) | `str.translate` in Python; `String#tr` in Ruby; `strtr` in PHP; `tr///` in Perl | [#21](https://github.com/huandu/xstrings/issues/21) |
| [Width](https://godoc.org/github.com/huandu/xstrings#Width) | `mb_strwidth` in PHP | [#26](https://github.com/huandu/xstrings/issues/26) |
diff --git a/vendor/github.com/huandu/xstrings/convert.go b/vendor/github.com/huandu/xstrings/convert.go
index 151c3151d..5d8cfee47 100644
--- a/vendor/github.com/huandu/xstrings/convert.go
+++ b/vendor/github.com/huandu/xstrings/convert.go
@@ -12,17 +12,38 @@ import (
// ToCamelCase is to convert words separated by space, underscore and hyphen to camel case.
//
// Some samples.
-// "some_words" => "SomeWords"
-// "http_server" => "HttpServer"
-// "no_https" => "NoHttps"
-// "_complex__case_" => "_Complex_Case_"
-// "some words" => "SomeWords"
+//
+// "some_words" => "someWords"
+// "http_server" => "httpServer"
+// "no_https" => "noHttps"
+// "_complex__case_" => "_complex_Case_"
+// "some words" => "someWords"
+// "GOLANG_IS_GREAT" => "golangIsGreat"
func ToCamelCase(str string) string {
+ return toCamelCase(str, false)
+}
+
+// ToPascalCase is to convert words separated by space, underscore and hyphen to pascal case.
+//
+// Some samples.
+//
+// "some_words" => "SomeWords"
+// "http_server" => "HttpServer"
+// "no_https" => "NoHttps"
+// "_complex__case_" => "_Complex_Case_"
+// "some words" => "SomeWords"
+// "GOLANG_IS_GREAT" => "GolangIsGreat"
+func ToPascalCase(str string) string {
+ return toCamelCase(str, true)
+}
+
+func toCamelCase(str string, isBig bool) string {
if len(str) == 0 {
return ""
}
buf := &stringBuilder{}
+ var isFirstRuneUpper bool
var r0, r1 rune
var size int
@@ -32,7 +53,14 @@ func ToCamelCase(str string) string {
str = str[size:]
if !isConnector(r0) {
- r0 = unicode.ToUpper(r0)
+ isFirstRuneUpper = unicode.IsUpper(r0)
+
+ if isBig {
+ r0 = unicode.ToUpper(r0)
+ } else {
+ r0 = unicode.ToLower(r0)
+ }
+
break
}
@@ -59,13 +87,25 @@ func ToCamelCase(str string) string {
}
if isConnector(r1) {
+ isFirstRuneUpper = unicode.IsUpper(r0)
r0 = unicode.ToUpper(r0)
} else {
- r0 = unicode.ToLower(r0)
+ if isFirstRuneUpper {
+ if unicode.IsUpper(r0) {
+ r0 = unicode.ToLower(r0)
+ } else {
+ isFirstRuneUpper = false
+ }
+ }
+
buf.WriteRune(r1)
}
}
+ if isFirstRuneUpper && !isBig {
+ r0 = unicode.ToLower(r0)
+ }
+
buf.WriteRune(r0)
return buf.String()
}
@@ -74,16 +114,17 @@ func ToCamelCase(str string) string {
// snake case format.
//
// Some samples.
-// "FirstName" => "first_name"
-// "HTTPServer" => "http_server"
-// "NoHTTPS" => "no_https"
-// "GO_PATH" => "go_path"
-// "GO PATH" => "go_path" // space is converted to underscore.
-// "GO-PATH" => "go_path" // hyphen is converted to underscore.
-// "http2xx" => "http_2xx" // insert an underscore before a number and after an alphabet.
-// "HTTP20xOK" => "http_20x_ok"
-// "Duration2m3s" => "duration_2m3s"
-// "Bld4Floor3rd" => "bld4_floor_3rd"
+//
+// "FirstName" => "first_name"
+// "HTTPServer" => "http_server"
+// "NoHTTPS" => "no_https"
+// "GO_PATH" => "go_path"
+// "GO PATH" => "go_path" // space is converted to underscore.
+// "GO-PATH" => "go_path" // hyphen is converted to underscore.
+// "http2xx" => "http_2xx" // insert an underscore before a number and after an alphabet.
+// "HTTP20xOK" => "http_20x_ok"
+// "Duration2m3s" => "duration_2m3s"
+// "Bld4Floor3rd" => "bld4_floor_3rd"
func ToSnakeCase(str string) string {
return camelCaseToLowerCase(str, '_')
}
@@ -92,16 +133,17 @@ func ToSnakeCase(str string) string {
// kebab case format.
//
// Some samples.
-// "FirstName" => "first-name"
-// "HTTPServer" => "http-server"
-// "NoHTTPS" => "no-https"
-// "GO_PATH" => "go-path"
-// "GO PATH" => "go-path" // space is converted to '-'.
-// "GO-PATH" => "go-path" // hyphen is converted to '-'.
-// "http2xx" => "http-2xx" // insert an underscore before a number and after an alphabet.
-// "HTTP20xOK" => "http-20x-ok"
-// "Duration2m3s" => "duration-2m3s"
-// "Bld4Floor3rd" => "bld4-floor-3rd"
+//
+// "FirstName" => "first-name"
+// "HTTPServer" => "http-server"
+// "NoHTTPS" => "no-https"
+// "GO_PATH" => "go-path"
+// "GO PATH" => "go-path" // space is converted to '-'.
+// "GO-PATH" => "go-path" // hyphen is converted to '-'.
+// "http2xx" => "http-2xx" // insert an underscore before a number and after an alphabet.
+// "HTTP20xOK" => "http-20x-ok"
+// "Duration2m3s" => "duration-2m3s"
+// "Bld4Floor3rd" => "bld4-floor-3rd"
func ToKebabCase(str string) string {
return camelCaseToLowerCase(str, '-')
}
@@ -510,17 +552,18 @@ func ShuffleSource(str string, src rand.Source) string {
// regardless whether the result is a valid rune or not.
//
// Only following characters are alphanumeric.
-// * a - z
-// * A - Z
-// * 0 - 9
+// - a - z
+// - A - Z
+// - 0 - 9
//
// Samples (borrowed from ruby's String#succ document):
-// "abcd" => "abce"
-// "THX1138" => "THX1139"
-// "<>" => "<>"
-// "1999zzz" => "2000aaa"
-// "ZZZ9999" => "AAAA0000"
-// "***" => "**+"
+//
+// "abcd" => "abce"
+// "THX1138" => "THX1139"
+// "<>" => "<>"
+// "1999zzz" => "2000aaa"
+// "ZZZ9999" => "AAAA0000"
+// "***" => "**+"
func Successor(str string) string {
if str == "" {
return str
diff --git a/vendor/github.com/huandu/xstrings/format.go b/vendor/github.com/huandu/xstrings/format.go
index 8cd76c525..b32219bbd 100644
--- a/vendor/github.com/huandu/xstrings/format.go
+++ b/vendor/github.com/huandu/xstrings/format.go
@@ -17,9 +17,10 @@ import (
// If tabSize <= 0, ExpandTabs panics with error.
//
// Samples:
-// ExpandTabs("a\tbc\tdef\tghij\tk", 4) => "a bc def ghij k"
-// ExpandTabs("abcdefg\thij\nk\tl", 4) => "abcdefg hij\nk l"
-// ExpandTabs("z中\t文\tw", 4) => "z中 文 w"
+//
+// ExpandTabs("a\tbc\tdef\tghij\tk", 4) => "a bc def ghij k"
+// ExpandTabs("abcdefg\thij\nk\tl", 4) => "abcdefg hij\nk l"
+// ExpandTabs("z中\t文\tw", 4) => "z中 文 w"
func ExpandTabs(str string, tabSize int) string {
if tabSize <= 0 {
panic("tab size must be positive")
@@ -74,9 +75,10 @@ func ExpandTabs(str string, tabSize int) string {
// If pad is an empty string, str will be returned.
//
// Samples:
-// LeftJustify("hello", 4, " ") => "hello"
-// LeftJustify("hello", 10, " ") => "hello "
-// LeftJustify("hello", 10, "123") => "hello12312"
+//
+// LeftJustify("hello", 4, " ") => "hello"
+// LeftJustify("hello", 10, " ") => "hello "
+// LeftJustify("hello", 10, "123") => "hello12312"
func LeftJustify(str string, length int, pad string) string {
l := Len(str)
@@ -100,9 +102,10 @@ func LeftJustify(str string, length int, pad string) string {
// If pad is an empty string, str will be returned.
//
// Samples:
-// RightJustify("hello", 4, " ") => "hello"
-// RightJustify("hello", 10, " ") => " hello"
-// RightJustify("hello", 10, "123") => "12312hello"
+//
+// RightJustify("hello", 4, " ") => "hello"
+// RightJustify("hello", 10, " ") => " hello"
+// RightJustify("hello", 10, "123") => "12312hello"
func RightJustify(str string, length int, pad string) string {
l := Len(str)
@@ -126,9 +129,10 @@ func RightJustify(str string, length int, pad string) string {
// If pad is an empty string, str will be returned.
//
// Samples:
-// Center("hello", 4, " ") => "hello"
-// Center("hello", 10, " ") => " hello "
-// Center("hello", 10, "123") => "12hello123"
+//
+// Center("hello", 4, " ") => "hello"
+// Center("hello", 10, " ") => " hello "
+// Center("hello", 10, "123") => "12hello123"
func Center(str string, length int, pad string) string {
l := Len(str)
diff --git a/vendor/github.com/huandu/xstrings/manipulate.go b/vendor/github.com/huandu/xstrings/manipulate.go
index 64075f9bb..ab42fe0fe 100644
--- a/vendor/github.com/huandu/xstrings/manipulate.go
+++ b/vendor/github.com/huandu/xstrings/manipulate.go
@@ -79,10 +79,12 @@ func Slice(str string, start, end int) string {
// The return value is a slice of strings with head, match and tail.
//
// If str contains sep, for example "hello" and "l", Partition returns
-// "he", "l", "lo"
+//
+// "he", "l", "lo"
//
// If str doesn't contain sep, for example "hello" and "x", Partition returns
-// "hello", "", ""
+//
+// "hello", "", ""
func Partition(str, sep string) (head, match, tail string) {
index := strings.Index(str, sep)
@@ -101,10 +103,12 @@ func Partition(str, sep string) (head, match, tail string) {
// The return value is a slice of strings with head, match and tail.
//
// If str contains sep, for example "hello" and "l", LastPartition returns
-// "hel", "l", "o"
+//
+// "hel", "l", "o"
//
// If str doesn't contain sep, for example "hello" and "x", LastPartition returns
-// "", "", "hello"
+//
+// "", "", "hello"
func LastPartition(str, sep string) (head, match, tail string) {
index := strings.LastIndex(str, sep)
diff --git a/vendor/github.com/huandu/xstrings/stringbuilder.go b/vendor/github.com/huandu/xstrings/stringbuilder.go
index bb0919d32..06812fea0 100644
--- a/vendor/github.com/huandu/xstrings/stringbuilder.go
+++ b/vendor/github.com/huandu/xstrings/stringbuilder.go
@@ -1,4 +1,5 @@
-//+build go1.10
+//go:build go1.10
+// +build go1.10
package xstrings
diff --git a/vendor/github.com/huandu/xstrings/stringbuilder_go110.go b/vendor/github.com/huandu/xstrings/stringbuilder_go110.go
index dac389d13..ccaa5aedd 100644
--- a/vendor/github.com/huandu/xstrings/stringbuilder_go110.go
+++ b/vendor/github.com/huandu/xstrings/stringbuilder_go110.go
@@ -1,4 +1,5 @@
-//+build !go1.10
+//go:build !go1.10
+// +build !go1.10
package xstrings
diff --git a/vendor/github.com/huandu/xstrings/translate.go b/vendor/github.com/huandu/xstrings/translate.go
index 42e694fb1..1fac6a00b 100644
--- a/vendor/github.com/huandu/xstrings/translate.go
+++ b/vendor/github.com/huandu/xstrings/translate.go
@@ -416,14 +416,16 @@ func (tr *Translator) HasPattern() bool {
//
// From and to are patterns representing a set of characters. Pattern is defined as following.
//
-// * Special characters
-// * '-' means a range of runes, e.g.
-// * "a-z" means all characters from 'a' to 'z' inclusive;
-// * "z-a" means all characters from 'z' to 'a' inclusive.
-// * '^' as first character means a set of all runes excepted listed, e.g.
-// * "^a-z" means all characters except 'a' to 'z' inclusive.
-// * '\' escapes special characters.
-// * Normal character represents itself, e.g. "abc" is a set including 'a', 'b' and 'c'.
+// Special characters:
+//
+// 1. '-' means a range of runes, e.g.
+// "a-z" means all characters from 'a' to 'z' inclusive;
+// "z-a" means all characters from 'z' to 'a' inclusive.
+// 2. '^' as first character means a set of all runes excepted listed, e.g.
+// "^a-z" means all characters except 'a' to 'z' inclusive.
+// 3. '\' escapes special characters.
+//
+// Normal character represents itself, e.g. "abc" is a set including 'a', 'b' and 'c'.
//
// Translate will try to find a 1:1 mapping from from to to.
// If to is smaller than from, last rune in to will be used to map "out of range" characters in from.
@@ -433,12 +435,13 @@ func (tr *Translator) HasPattern() bool {
// If the to pattern is an empty string, Translate works exactly the same as Delete.
//
// Samples:
-// Translate("hello", "aeiou", "12345") => "h2ll4"
-// Translate("hello", "a-z", "A-Z") => "HELLO"
-// Translate("hello", "z-a", "a-z") => "svool"
-// Translate("hello", "aeiou", "*") => "h*ll*"
-// Translate("hello", "^l", "*") => "**ll*"
-// Translate("hello ^ world", `\^lo`, "*") => "he*** * w*r*d"
+//
+// Translate("hello", "aeiou", "12345") => "h2ll4"
+// Translate("hello", "a-z", "A-Z") => "HELLO"
+// Translate("hello", "z-a", "a-z") => "svool"
+// Translate("hello", "aeiou", "*") => "h*ll*"
+// Translate("hello", "^l", "*") => "**ll*"
+// Translate("hello ^ world", `\^lo`, "*") => "he*** * w*r*d"
func Translate(str, from, to string) string {
tr := NewTranslator(from, to)
return tr.Translate(str)
@@ -448,9 +451,10 @@ func Translate(str, from, to string) string {
// Pattern is defined in Translate function.
//
// Samples:
-// Delete("hello", "aeiou") => "hll"
-// Delete("hello", "a-k") => "llo"
-// Delete("hello", "^a-k") => "he"
+//
+// Delete("hello", "aeiou") => "hll"
+// Delete("hello", "a-k") => "llo"
+// Delete("hello", "^a-k") => "he"
func Delete(str, pattern string) string {
tr := NewTranslator(pattern, "")
return tr.Translate(str)
@@ -460,9 +464,10 @@ func Delete(str, pattern string) string {
// Pattern is defined in Translate function.
//
// Samples:
-// Count("hello", "aeiou") => 3
-// Count("hello", "a-k") => 3
-// Count("hello", "^a-k") => 2
+//
+// Count("hello", "aeiou") => 3
+// Count("hello", "a-k") => 3
+// Count("hello", "^a-k") => 2
func Count(str, pattern string) int {
if pattern == "" || str == "" {
return 0
@@ -491,9 +496,10 @@ func Count(str, pattern string) int {
// If pattern is not empty, only runes matching the pattern will be squeezed.
//
// Samples:
-// Squeeze("hello", "") => "helo"
-// Squeeze("hello", "m-z") => "hello"
-// Squeeze("hello world", " ") => "hello world"
+//
+// Squeeze("hello", "") => "helo"
+// Squeeze("hello", "m-z") => "hello"
+// Squeeze("hello world", " ") => "hello world"
func Squeeze(str, pattern string) string {
var last, r rune
var size int
diff --git a/vendor/github.com/imdario/mergo/.deepsource.toml b/vendor/github.com/imdario/mergo/.deepsource.toml
deleted file mode 100644
index 8a0681af8..000000000
--- a/vendor/github.com/imdario/mergo/.deepsource.toml
+++ /dev/null
@@ -1,12 +0,0 @@
-version = 1
-
-test_patterns = [
- "*_test.go"
-]
-
-[[analyzers]]
-name = "go"
-enabled = true
-
- [analyzers.meta]
- import_path = "github.com/imdario/mergo"
\ No newline at end of file
diff --git a/vendor/github.com/imdario/mergo/.gitignore b/vendor/github.com/imdario/mergo/.gitignore
deleted file mode 100644
index 529c3412b..000000000
--- a/vendor/github.com/imdario/mergo/.gitignore
+++ /dev/null
@@ -1,33 +0,0 @@
-#### joe made this: http://goel.io/joe
-
-#### go ####
-# Binaries for programs and plugins
-*.exe
-*.dll
-*.so
-*.dylib
-
-# Test binary, build with `go test -c`
-*.test
-
-# Output of the go coverage tool, specifically when used with LiteIDE
-*.out
-
-# Project-local glide cache, RE: https://github.com/Masterminds/glide/issues/736
-.glide/
-
-#### vim ####
-# Swap
-[._]*.s[a-v][a-z]
-[._]*.sw[a-p]
-[._]s[a-v][a-z]
-[._]sw[a-p]
-
-# Session
-Session.vim
-
-# Temporary
-.netrwhist
-*~
-# Auto-generated tag files
-tags
diff --git a/vendor/github.com/imdario/mergo/README.md b/vendor/github.com/imdario/mergo/README.md
deleted file mode 100644
index ffbbb62c7..000000000
--- a/vendor/github.com/imdario/mergo/README.md
+++ /dev/null
@@ -1,242 +0,0 @@
-# Mergo
-
-[![GitHub release][5]][6]
-[![GoCard][7]][8]
-[![Test status][1]][2]
-[![OpenSSF Scorecard][21]][22]
-[![OpenSSF Best Practices][19]][20]
-[![Coverage status][9]][10]
-[![Sourcegraph][11]][12]
-[![FOSSA status][13]][14]
-
-[![GoDoc][3]][4]
-[![Become my sponsor][15]][16]
-[![Tidelift][17]][18]
-
-[1]: https://github.com/imdario/mergo/workflows/tests/badge.svg?branch=master
-[2]: https://github.com/imdario/mergo/actions/workflows/tests.yml
-[3]: https://godoc.org/github.com/imdario/mergo?status.svg
-[4]: https://godoc.org/github.com/imdario/mergo
-[5]: https://img.shields.io/github/release/imdario/mergo.svg
-[6]: https://github.com/imdario/mergo/releases
-[7]: https://goreportcard.com/badge/imdario/mergo
-[8]: https://goreportcard.com/report/github.com/imdario/mergo
-[9]: https://coveralls.io/repos/github/imdario/mergo/badge.svg?branch=master
-[10]: https://coveralls.io/github/imdario/mergo?branch=master
-[11]: https://sourcegraph.com/github.com/imdario/mergo/-/badge.svg
-[12]: https://sourcegraph.com/github.com/imdario/mergo?badge
-[13]: https://app.fossa.io/api/projects/git%2Bgithub.com%2Fimdario%2Fmergo.svg?type=shield
-[14]: https://app.fossa.io/projects/git%2Bgithub.com%2Fimdario%2Fmergo?ref=badge_shield
-[15]: https://img.shields.io/github/sponsors/imdario
-[16]: https://github.com/sponsors/imdario
-[17]: https://tidelift.com/badges/package/go/github.com%2Fimdario%2Fmergo
-[18]: https://tidelift.com/subscription/pkg/go-github.com-imdario-mergo
-[19]: https://bestpractices.coreinfrastructure.org/projects/7177/badge
-[20]: https://bestpractices.coreinfrastructure.org/projects/7177
-[21]: https://api.securityscorecards.dev/projects/github.com/imdario/mergo/badge
-[22]: https://api.securityscorecards.dev/projects/github.com/imdario/mergo
-
-A helper to merge structs and maps in Golang. Useful for configuration default values, avoiding messy if-statements.
-
-Mergo merges same-type structs and maps by setting default values in zero-value fields. Mergo won't merge unexported (private) fields. It will do recursively any exported one. It also won't merge structs inside maps (because they are not addressable using Go reflection).
-
-Also a lovely [comune](http://en.wikipedia.org/wiki/Mergo) (municipality) in the Province of Ancona in the Italian region of Marche.
-
-## Status
-
-It is ready for production use. [It is used in several projects by Docker, Google, The Linux Foundation, VMWare, Shopify, Microsoft, etc](https://github.com/imdario/mergo#mergo-in-the-wild).
-
-### Important note
-
-Please keep in mind that a problematic PR broke [0.3.9](//github.com/imdario/mergo/releases/tag/0.3.9). I reverted it in [0.3.10](//github.com/imdario/mergo/releases/tag/0.3.10), and I consider it stable but not bug-free. Also, this version adds support for go modules.
-
-Keep in mind that in [0.3.2](//github.com/imdario/mergo/releases/tag/0.3.2), Mergo changed `Merge()`and `Map()` signatures to support [transformers](#transformers). I added an optional/variadic argument so that it won't break the existing code.
-
-If you were using Mergo before April 6th, 2015, please check your project works as intended after updating your local copy with ```go get -u github.com/imdario/mergo```. I apologize for any issue caused by its previous behavior and any future bug that Mergo could cause in existing projects after the change (release 0.2.0).
-
-### Donations
-
-If Mergo is useful to you, consider buying me a coffee, a beer, or making a monthly donation to allow me to keep building great free software. :heart_eyes:
-
-
-
-
-
-### Mergo in the wild
-
-- [moby/moby](https://github.com/moby/moby)
-- [kubernetes/kubernetes](https://github.com/kubernetes/kubernetes)
-- [vmware/dispatch](https://github.com/vmware/dispatch)
-- [Shopify/themekit](https://github.com/Shopify/themekit)
-- [imdario/zas](https://github.com/imdario/zas)
-- [matcornic/hermes](https://github.com/matcornic/hermes)
-- [OpenBazaar/openbazaar-go](https://github.com/OpenBazaar/openbazaar-go)
-- [kataras/iris](https://github.com/kataras/iris)
-- [michaelsauter/crane](https://github.com/michaelsauter/crane)
-- [go-task/task](https://github.com/go-task/task)
-- [sensu/uchiwa](https://github.com/sensu/uchiwa)
-- [ory/hydra](https://github.com/ory/hydra)
-- [sisatech/vcli](https://github.com/sisatech/vcli)
-- [dairycart/dairycart](https://github.com/dairycart/dairycart)
-- [projectcalico/felix](https://github.com/projectcalico/felix)
-- [resin-os/balena](https://github.com/resin-os/balena)
-- [go-kivik/kivik](https://github.com/go-kivik/kivik)
-- [Telefonica/govice](https://github.com/Telefonica/govice)
-- [supergiant/supergiant](supergiant/supergiant)
-- [SergeyTsalkov/brooce](https://github.com/SergeyTsalkov/brooce)
-- [soniah/dnsmadeeasy](https://github.com/soniah/dnsmadeeasy)
-- [ohsu-comp-bio/funnel](https://github.com/ohsu-comp-bio/funnel)
-- [EagerIO/Stout](https://github.com/EagerIO/Stout)
-- [lynndylanhurley/defsynth-api](https://github.com/lynndylanhurley/defsynth-api)
-- [russross/canvasassignments](https://github.com/russross/canvasassignments)
-- [rdegges/cryptly-api](https://github.com/rdegges/cryptly-api)
-- [casualjim/exeggutor](https://github.com/casualjim/exeggutor)
-- [divshot/gitling](https://github.com/divshot/gitling)
-- [RWJMurphy/gorl](https://github.com/RWJMurphy/gorl)
-- [andrerocker/deploy42](https://github.com/andrerocker/deploy42)
-- [elwinar/rambler](https://github.com/elwinar/rambler)
-- [tmaiaroto/gopartman](https://github.com/tmaiaroto/gopartman)
-- [jfbus/impressionist](https://github.com/jfbus/impressionist)
-- [Jmeyering/zealot](https://github.com/Jmeyering/zealot)
-- [godep-migrator/rigger-host](https://github.com/godep-migrator/rigger-host)
-- [Dronevery/MultiwaySwitch-Go](https://github.com/Dronevery/MultiwaySwitch-Go)
-- [thoas/picfit](https://github.com/thoas/picfit)
-- [mantasmatelis/whooplist-server](https://github.com/mantasmatelis/whooplist-server)
-- [jnuthong/item_search](https://github.com/jnuthong/item_search)
-- [bukalapak/snowboard](https://github.com/bukalapak/snowboard)
-- [containerssh/containerssh](https://github.com/containerssh/containerssh)
-- [goreleaser/goreleaser](https://github.com/goreleaser/goreleaser)
-- [tjpnz/structbot](https://github.com/tjpnz/structbot)
-
-## Install
-
- go get github.com/imdario/mergo
-
- // use in your .go code
- import (
- "github.com/imdario/mergo"
- )
-
-## Usage
-
-You can only merge same-type structs with exported fields initialized as zero value of their type and same-types maps. Mergo won't merge unexported (private) fields but will do recursively any exported one. It won't merge empty structs value as [they are zero values](https://golang.org/ref/spec#The_zero_value) too. Also, maps will be merged recursively except for structs inside maps (because they are not addressable using Go reflection).
-
-```go
-if err := mergo.Merge(&dst, src); err != nil {
- // ...
-}
-```
-
-Also, you can merge overwriting values using the transformer `WithOverride`.
-
-```go
-if err := mergo.Merge(&dst, src, mergo.WithOverride); err != nil {
- // ...
-}
-```
-
-Additionally, you can map a `map[string]interface{}` to a struct (and otherwise, from struct to map), following the same restrictions as in `Merge()`. Keys are capitalized to find each corresponding exported field.
-
-```go
-if err := mergo.Map(&dst, srcMap); err != nil {
- // ...
-}
-```
-
-Warning: if you map a struct to map, it won't do it recursively. Don't expect Mergo to map struct members of your struct as `map[string]interface{}`. They will be just assigned as values.
-
-Here is a nice example:
-
-```go
-package main
-
-import (
- "fmt"
- "github.com/imdario/mergo"
-)
-
-type Foo struct {
- A string
- B int64
-}
-
-func main() {
- src := Foo{
- A: "one",
- B: 2,
- }
- dest := Foo{
- A: "two",
- }
- mergo.Merge(&dest, src)
- fmt.Println(dest)
- // Will print
- // {two 2}
-}
-```
-
-Note: if test are failing due missing package, please execute:
-
- go get gopkg.in/yaml.v3
-
-### Transformers
-
-Transformers allow to merge specific types differently than in the default behavior. In other words, now you can customize how some types are merged. For example, `time.Time` is a struct; it doesn't have zero value but IsZero can return true because it has fields with zero value. How can we merge a non-zero `time.Time`?
-
-```go
-package main
-
-import (
- "fmt"
- "github.com/imdario/mergo"
- "reflect"
- "time"
-)
-
-type timeTransformer struct {
-}
-
-func (t timeTransformer) Transformer(typ reflect.Type) func(dst, src reflect.Value) error {
- if typ == reflect.TypeOf(time.Time{}) {
- return func(dst, src reflect.Value) error {
- if dst.CanSet() {
- isZero := dst.MethodByName("IsZero")
- result := isZero.Call([]reflect.Value{})
- if result[0].Bool() {
- dst.Set(src)
- }
- }
- return nil
- }
- }
- return nil
-}
-
-type Snapshot struct {
- Time time.Time
- // ...
-}
-
-func main() {
- src := Snapshot{time.Now()}
- dest := Snapshot{}
- mergo.Merge(&dest, src, mergo.WithTransformers(timeTransformer{}))
- fmt.Println(dest)
- // Will print
- // { 2018-01-12 01:15:00 +0000 UTC m=+0.000000001 }
-}
-```
-
-## Contact me
-
-If I can help you, you have an idea or you are using Mergo in your projects, don't hesitate to drop me a line (or a pull request): [@im_dario](https://twitter.com/im_dario)
-
-## About
-
-Written by [Dario Castañé](http://dario.im).
-
-## License
-
-[BSD 3-Clause](http://opensource.org/licenses/BSD-3-Clause) license, as [Go language](http://golang.org/LICENSE).
-
-[](https://app.fossa.io/projects/git%2Bgithub.com%2Fimdario%2Fmergo?ref=badge_large)
diff --git a/vendor/github.com/imdario/mergo/doc.go b/vendor/github.com/imdario/mergo/doc.go
deleted file mode 100644
index fcd985f99..000000000
--- a/vendor/github.com/imdario/mergo/doc.go
+++ /dev/null
@@ -1,143 +0,0 @@
-// Copyright 2013 Dario Castañé. All rights reserved.
-// Copyright 2009 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.
-
-/*
-A helper to merge structs and maps in Golang. Useful for configuration default values, avoiding messy if-statements.
-
-Mergo merges same-type structs and maps by setting default values in zero-value fields. Mergo won't merge unexported (private) fields. It will do recursively any exported one. It also won't merge structs inside maps (because they are not addressable using Go reflection).
-
-Status
-
-It is ready for production use. It is used in several projects by Docker, Google, The Linux Foundation, VMWare, Shopify, etc.
-
-Important note
-
-Please keep in mind that a problematic PR broke 0.3.9. We reverted it in 0.3.10. We consider 0.3.10 as stable but not bug-free. . Also, this version adds suppot for go modules.
-
-Keep in mind that in 0.3.2, Mergo changed Merge() and Map() signatures to support transformers. We added an optional/variadic argument so that it won't break the existing code.
-
-If you were using Mergo before April 6th, 2015, please check your project works as intended after updating your local copy with go get -u github.com/imdario/mergo. I apologize for any issue caused by its previous behavior and any future bug that Mergo could cause in existing projects after the change (release 0.2.0).
-
-Install
-
-Do your usual installation procedure:
-
- go get github.com/imdario/mergo
-
- // use in your .go code
- import (
- "github.com/imdario/mergo"
- )
-
-Usage
-
-You can only merge same-type structs with exported fields initialized as zero value of their type and same-types maps. Mergo won't merge unexported (private) fields but will do recursively any exported one. It won't merge empty structs value as they are zero values too. Also, maps will be merged recursively except for structs inside maps (because they are not addressable using Go reflection).
-
- if err := mergo.Merge(&dst, src); err != nil {
- // ...
- }
-
-Also, you can merge overwriting values using the transformer WithOverride.
-
- if err := mergo.Merge(&dst, src, mergo.WithOverride); err != nil {
- // ...
- }
-
-Additionally, you can map a map[string]interface{} to a struct (and otherwise, from struct to map), following the same restrictions as in Merge(). Keys are capitalized to find each corresponding exported field.
-
- if err := mergo.Map(&dst, srcMap); err != nil {
- // ...
- }
-
-Warning: if you map a struct to map, it won't do it recursively. Don't expect Mergo to map struct members of your struct as map[string]interface{}. They will be just assigned as values.
-
-Here is a nice example:
-
- package main
-
- import (
- "fmt"
- "github.com/imdario/mergo"
- )
-
- type Foo struct {
- A string
- B int64
- }
-
- func main() {
- src := Foo{
- A: "one",
- B: 2,
- }
- dest := Foo{
- A: "two",
- }
- mergo.Merge(&dest, src)
- fmt.Println(dest)
- // Will print
- // {two 2}
- }
-
-Transformers
-
-Transformers allow to merge specific types differently than in the default behavior. In other words, now you can customize how some types are merged. For example, time.Time is a struct; it doesn't have zero value but IsZero can return true because it has fields with zero value. How can we merge a non-zero time.Time?
-
- package main
-
- import (
- "fmt"
- "github.com/imdario/mergo"
- "reflect"
- "time"
- )
-
- type timeTransformer struct {
- }
-
- func (t timeTransformer) Transformer(typ reflect.Type) func(dst, src reflect.Value) error {
- if typ == reflect.TypeOf(time.Time{}) {
- return func(dst, src reflect.Value) error {
- if dst.CanSet() {
- isZero := dst.MethodByName("IsZero")
- result := isZero.Call([]reflect.Value{})
- if result[0].Bool() {
- dst.Set(src)
- }
- }
- return nil
- }
- }
- return nil
- }
-
- type Snapshot struct {
- Time time.Time
- // ...
- }
-
- func main() {
- src := Snapshot{time.Now()}
- dest := Snapshot{}
- mergo.Merge(&dest, src, mergo.WithTransformers(timeTransformer{}))
- fmt.Println(dest)
- // Will print
- // { 2018-01-12 01:15:00 +0000 UTC m=+0.000000001 }
- }
-
-Contact me
-
-If I can help you, you have an idea or you are using Mergo in your projects, don't hesitate to drop me a line (or a pull request): https://twitter.com/im_dario
-
-About
-
-Written by Dario Castañé: https://da.rio.hn
-
-License
-
-BSD 3-Clause license, as Go language.
-
-*/
-package mergo
diff --git a/vendor/github.com/imdario/mergo/map.go b/vendor/github.com/imdario/mergo/map.go
deleted file mode 100644
index b50d5c2a4..000000000
--- a/vendor/github.com/imdario/mergo/map.go
+++ /dev/null
@@ -1,178 +0,0 @@
-// Copyright 2014 Dario Castañé. All rights reserved.
-// Copyright 2009 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.
-
-// Based on src/pkg/reflect/deepequal.go from official
-// golang's stdlib.
-
-package mergo
-
-import (
- "fmt"
- "reflect"
- "unicode"
- "unicode/utf8"
-)
-
-func changeInitialCase(s string, mapper func(rune) rune) string {
- if s == "" {
- return s
- }
- r, n := utf8.DecodeRuneInString(s)
- return string(mapper(r)) + s[n:]
-}
-
-func isExported(field reflect.StructField) bool {
- r, _ := utf8.DecodeRuneInString(field.Name)
- return r >= 'A' && r <= 'Z'
-}
-
-// Traverses recursively both values, assigning src's fields values to dst.
-// The map argument tracks comparisons that have already been seen, which allows
-// short circuiting on recursive types.
-func deepMap(dst, src reflect.Value, visited map[uintptr]*visit, depth int, config *Config) (err error) {
- overwrite := config.Overwrite
- if dst.CanAddr() {
- addr := dst.UnsafeAddr()
- h := 17 * addr
- seen := visited[h]
- typ := dst.Type()
- for p := seen; p != nil; p = p.next {
- if p.ptr == addr && p.typ == typ {
- return nil
- }
- }
- // Remember, remember...
- visited[h] = &visit{typ, seen, addr}
- }
- zeroValue := reflect.Value{}
- switch dst.Kind() {
- case reflect.Map:
- dstMap := dst.Interface().(map[string]interface{})
- for i, n := 0, src.NumField(); i < n; i++ {
- srcType := src.Type()
- field := srcType.Field(i)
- if !isExported(field) {
- continue
- }
- fieldName := field.Name
- fieldName = changeInitialCase(fieldName, unicode.ToLower)
- if v, ok := dstMap[fieldName]; !ok || (isEmptyValue(reflect.ValueOf(v), !config.ShouldNotDereference) || overwrite) {
- dstMap[fieldName] = src.Field(i).Interface()
- }
- }
- case reflect.Ptr:
- if dst.IsNil() {
- v := reflect.New(dst.Type().Elem())
- dst.Set(v)
- }
- dst = dst.Elem()
- fallthrough
- case reflect.Struct:
- srcMap := src.Interface().(map[string]interface{})
- for key := range srcMap {
- config.overwriteWithEmptyValue = true
- srcValue := srcMap[key]
- fieldName := changeInitialCase(key, unicode.ToUpper)
- dstElement := dst.FieldByName(fieldName)
- if dstElement == zeroValue {
- // We discard it because the field doesn't exist.
- continue
- }
- srcElement := reflect.ValueOf(srcValue)
- dstKind := dstElement.Kind()
- srcKind := srcElement.Kind()
- if srcKind == reflect.Ptr && dstKind != reflect.Ptr {
- srcElement = srcElement.Elem()
- srcKind = reflect.TypeOf(srcElement.Interface()).Kind()
- } else if dstKind == reflect.Ptr {
- // Can this work? I guess it can't.
- if srcKind != reflect.Ptr && srcElement.CanAddr() {
- srcPtr := srcElement.Addr()
- srcElement = reflect.ValueOf(srcPtr)
- srcKind = reflect.Ptr
- }
- }
-
- if !srcElement.IsValid() {
- continue
- }
- if srcKind == dstKind {
- if err = deepMerge(dstElement, srcElement, visited, depth+1, config); err != nil {
- return
- }
- } else if dstKind == reflect.Interface && dstElement.Kind() == reflect.Interface {
- if err = deepMerge(dstElement, srcElement, visited, depth+1, config); err != nil {
- return
- }
- } else if srcKind == reflect.Map {
- if err = deepMap(dstElement, srcElement, visited, depth+1, config); err != nil {
- return
- }
- } else {
- return fmt.Errorf("type mismatch on %s field: found %v, expected %v", fieldName, srcKind, dstKind)
- }
- }
- }
- return
-}
-
-// Map sets fields' values in dst from src.
-// src can be a map with string keys or a struct. dst must be the opposite:
-// if src is a map, dst must be a valid pointer to struct. If src is a struct,
-// dst must be map[string]interface{}.
-// It won't merge unexported (private) fields and will do recursively
-// any exported field.
-// If dst is a map, keys will be src fields' names in lower camel case.
-// Missing key in src that doesn't match a field in dst will be skipped. This
-// doesn't apply if dst is a map.
-// This is separated method from Merge because it is cleaner and it keeps sane
-// semantics: merging equal types, mapping different (restricted) types.
-func Map(dst, src interface{}, opts ...func(*Config)) error {
- return _map(dst, src, opts...)
-}
-
-// MapWithOverwrite will do the same as Map except that non-empty dst attributes will be overridden by
-// non-empty src attribute values.
-// Deprecated: Use Map(…) with WithOverride
-func MapWithOverwrite(dst, src interface{}, opts ...func(*Config)) error {
- return _map(dst, src, append(opts, WithOverride)...)
-}
-
-func _map(dst, src interface{}, opts ...func(*Config)) error {
- if dst != nil && reflect.ValueOf(dst).Kind() != reflect.Ptr {
- return ErrNonPointerArgument
- }
- var (
- vDst, vSrc reflect.Value
- err error
- )
- config := &Config{}
-
- for _, opt := range opts {
- opt(config)
- }
-
- if vDst, vSrc, err = resolveValues(dst, src); err != nil {
- return err
- }
- // To be friction-less, we redirect equal-type arguments
- // to deepMerge. Only because arguments can be anything.
- if vSrc.Kind() == vDst.Kind() {
- return deepMerge(vDst, vSrc, make(map[uintptr]*visit), 0, config)
- }
- switch vSrc.Kind() {
- case reflect.Struct:
- if vDst.Kind() != reflect.Map {
- return ErrExpectedMapAsDestination
- }
- case reflect.Map:
- if vDst.Kind() != reflect.Struct {
- return ErrExpectedStructAsDestination
- }
- default:
- return ErrNotSupported
- }
- return deepMap(vDst, vSrc, make(map[uintptr]*visit), 0, config)
-}
diff --git a/vendor/github.com/jgautheron/goconst/README.md b/vendor/github.com/jgautheron/goconst/README.md
index 727974d00..b08d7b7d1 100644
--- a/vendor/github.com/jgautheron/goconst/README.md
+++ b/vendor/github.com/jgautheron/goconst/README.md
@@ -8,6 +8,16 @@ There are obvious benefits to using constants instead of repeating strings, most
While this could be considered a beginner mistake, across time, multiple packages and large codebases, some repetition could have slipped in.
+### How it works
+
+goconst detects string (and optionally number) literals that appear multiple times and could be replaced by a constant.
+
+A few things to keep in mind:
+
+- **Exact literal matching** — goconst compares complete, unquoted literal values. Repeated substrings inside larger strings are not detected (e.g., a shared prefix across two different string literals will not be reported).
+- **`const` declarations are skipped by default** — constant values are only analyzed when `-match-constant` (match strings against existing constants) or `-find-duplicates` (find constants sharing the same value) is enabled.
+- **String length is measured in runes**, not bytes, so multi-byte Unicode characters are counted correctly against `-min-length`.
+
### Get Started
$ go install github.com/jgautheron/goconst/cmd/goconst@latest
@@ -30,6 +40,7 @@ Flags:
-match-constant look for existing constants matching the strings
-find-duplicates look for constants with identical values
-eval-const-expr enable evaluation of constant expressions (e.g., Prefix + "suffix")
+ -ignore-calls ignore string literals in calls to these functions (comma separated)
-numbers search also for duplicated numbers
-min minimum value, only works with -numbers
-max maximum value, only works with -numbers
@@ -45,6 +56,7 @@ Examples:
goconst -numbers -min 60 -max 512 .
goconst -min-occurrences 5 $(go list -m -f '{{.Dir}}')
goconst -eval-const-expr -match-constant . # Matches constant expressions like Prefix + "suffix"
+ goconst -ignore-calls slog.Info,slog.Warn,fmt.Errorf ./... # Ignore strings in logging/error calls
```
### Development
diff --git a/vendor/github.com/jgautheron/goconst/api.go b/vendor/github.com/jgautheron/goconst/api.go
index 10cece151..5e9e35e74 100644
--- a/vendor/github.com/jgautheron/goconst/api.go
+++ b/vendor/github.com/jgautheron/goconst/api.go
@@ -45,6 +45,9 @@ type Config struct {
FindDuplicates bool
// EvalConstExpressions enables evaluation of constant expressions like Prefix + "suffix"
EvalConstExpressions bool
+ // IgnoreFunctions is a list of function names whose string arguments should be ignored.
+ // Supports direct calls (e.g., "println") and one-level qualified calls (e.g., "slog.Info").
+ IgnoreFunctions []string
}
// NewWithIgnorePatterns creates a new instance of the parser with support for multiple ignore patterns.
@@ -108,6 +111,10 @@ func RunWithConfig(files []*ast.File, fset *token.FileSet, typeInfo *types.Info,
cfg.ExcludeTypes,
)
+ if len(cfg.IgnoreFunctions) > 0 {
+ p.SetIgnoreFunctions(cfg.IgnoreFunctions)
+ }
+
// Pre-allocate slice based on estimated result size
expectedIssues := len(files) * 5 // Assuming average of 5 issues per file
if expectedIssues > 1000 {
@@ -179,34 +186,40 @@ func RunWithConfig(files []*ast.File, fset *token.FileSet, typeInfo *types.Info,
sort.Strings(stringKeys)
- // Process strings in a predictable order for stable output
+ // Emit one issue per file where the string appears, so that
+ // path-based exclusion can independently filter each one without
+ // suppressing legitimate findings in other files.
for _, str := range stringKeys {
positions := p.strs[str]
if len(positions) == 0 {
continue
}
- // Use the first position as representative
- fi := positions[0]
+ occurrences := p.stringCount[str]
- // Create issue using the counted value to avoid recounting
- issue := Issue{
- Pos: fi.Position,
- OccurrencesCount: p.stringCount[str],
- Str: str,
- }
-
- // Check for matching constants
+ var matchingConst string
if len(p.consts) > 0 {
p.constMutex.RLock()
if csts, ok := p.consts[str]; ok && len(csts) > 0 {
- // const should be in the same package and exported
- issue.MatchingConst = csts[0].Name
+ matchingConst = csts[0].Name
}
p.constMutex.RUnlock()
}
- issueBuffer = append(issueBuffer, issue)
+ seen := make(map[string]bool)
+ for _, pos := range positions {
+ if seen[pos.Filename] {
+ continue
+ }
+ seen[pos.Filename] = true
+
+ issueBuffer = append(issueBuffer, Issue{
+ Pos: pos.Position,
+ OccurrencesCount: occurrences,
+ Str: str,
+ MatchingConst: matchingConst,
+ })
+ }
}
p.stringCountMutex.RUnlock()
diff --git a/vendor/github.com/jgautheron/goconst/parser.go b/vendor/github.com/jgautheron/goconst/parser.go
index 9505d463e..fca43279c 100644
--- a/vendor/github.com/jgautheron/goconst/parser.go
+++ b/vendor/github.com/jgautheron/goconst/parser.go
@@ -120,6 +120,7 @@ type Parser struct {
minLength, minOccurrences int
numberMin, numberMax int
excludeTypes map[Type]bool
+ ignoreFunctions map[string]struct{}
maxConcurrency int
evalConstExpressions bool // Whether to evaluate constant expressions
@@ -264,6 +265,24 @@ func (p *Parser) EnableBatchProcessing(batchSize int) {
}
}
+// SetIgnoreFunctions configures which function calls should have their string
+// arguments ignored. Supports direct calls (e.g., "println") and one-level
+// qualified calls (e.g., "slog.Info", "fmt.Errorf").
+func (p *Parser) SetIgnoreFunctions(names []string) {
+ if len(names) == 0 {
+ p.ignoreFunctions = nil
+ return
+ }
+ m := make(map[string]struct{}, len(names))
+ for _, name := range names {
+ name = strings.TrimSpace(name)
+ if name != "" {
+ m[name] = struct{}{}
+ }
+ }
+ p.ignoreFunctions = m
+}
+
// ParseTree will search the given path for occurrences that could be moved into constants.
// If "..." is appended, the search will be recursive.
//
@@ -881,4 +900,7 @@ const (
Return
// Call represents a string passed as an argument to a function call (e.g., f("foo"))
Call
+ // CompositeLit represents a string inside a composite literal
+ // (e.g., []string{"foo"}, map[string]string{"k": "v"}, MyStruct{Field: "foo"})
+ CompositeLit
)
diff --git a/vendor/github.com/jgautheron/goconst/visitor.go b/vendor/github.com/jgautheron/goconst/visitor.go
index 350e3ae62..a78893150 100644
--- a/vendor/github.com/jgautheron/goconst/visitor.go
+++ b/vendor/github.com/jgautheron/goconst/visitor.go
@@ -8,6 +8,7 @@ import (
"regexp"
"strconv"
"strings"
+ "unicode/utf8"
)
// treeVisitor is used to walk the AST and find strings that could be constants.
@@ -110,17 +111,68 @@ func (v *treeVisitor) Visit(node ast.Node) ast.Visitor {
// fn("http://")
case *ast.CallExpr:
- for _, item := range t.Args {
- lit, ok := item.(*ast.BasicLit)
- if ok && v.isSupported(lit.Kind) {
- v.addString(lit.Value, lit.Pos(), Call)
+ if !v.shouldIgnoreCall(t) {
+ for _, item := range t.Args {
+ lit, ok := item.(*ast.BasicLit)
+ if ok && v.isSupported(lit.Kind) {
+ v.addString(lit.Value, lit.Pos(), Call)
+ }
}
}
+
+ // []string{"foo"}, map[string]string{"k": "v"}, struct{A string}{A: "foo"}
+ case *ast.CompositeLit:
+ for _, item := range t.Elts {
+ v.addCompositeLiteralElement(item)
+ }
}
return v
}
+func (v *treeVisitor) addCompositeLiteralElement(node ast.Expr) {
+ if lit, ok := node.(*ast.BasicLit); ok && v.isSupported(lit.Kind) {
+ v.addString(lit.Value, lit.Pos(), CompositeLit)
+ return
+ }
+
+ kv, ok := node.(*ast.KeyValueExpr)
+ if !ok {
+ return
+ }
+
+ if keyLit, ok := kv.Key.(*ast.BasicLit); ok && v.isSupported(keyLit.Kind) {
+ v.addString(keyLit.Value, keyLit.Pos(), CompositeLit)
+ }
+
+ if valueLit, ok := kv.Value.(*ast.BasicLit); ok && v.isSupported(valueLit.Kind) {
+ v.addString(valueLit.Value, valueLit.Pos(), CompositeLit)
+ }
+}
+
+// shouldIgnoreCall returns true if the call expression matches a function
+// name in the ignoreFunctions set. Supports direct calls (e.g., "println")
+// and one-level qualified calls (e.g., "slog.Info").
+func (v *treeVisitor) shouldIgnoreCall(call *ast.CallExpr) bool {
+ if len(v.p.ignoreFunctions) == 0 {
+ return false
+ }
+ var name string
+ switch fn := call.Fun.(type) {
+ case *ast.Ident:
+ name = fn.Name
+ case *ast.SelectorExpr:
+ if ident, ok := fn.X.(*ast.Ident); ok {
+ name = ident.Name + "." + fn.Sel.Name
+ }
+ }
+ if name == "" {
+ return false
+ }
+ _, found := v.p.ignoreFunctions[name]
+ return found
+}
+
// addString adds a string in the map along with its position in the tree.
func (v *treeVisitor) addString(str string, pos token.Pos, typ Type) {
// Early type exclusion check
@@ -153,7 +205,7 @@ func (v *treeVisitor) addString(str string, pos token.Pos, typ Type) {
}
// Early length check
- if len(unquotedStr) == 0 || len(unquotedStr) < v.p.minLength {
+ if len(unquotedStr) == 0 || utf8.RuneCountInString(unquotedStr) < v.p.minLength {
return
}
@@ -175,29 +227,21 @@ func (v *treeVisitor) addString(str string, pos token.Pos, typ Type) {
// Use interned string to reduce memory usage - identical strings share the same memory
internedStr := InternString(unquotedStr)
- // Update the count first, this is faster than appending to slices
- count := v.p.IncrementStringCount(internedStr)
-
- // Only continue if we're still adding the position to the map
- // or if count has reached threshold
- if count == 1 || count == v.p.minOccurrences {
- // Lock to safely update the shared map
- v.p.stringMutex.Lock()
- defer v.p.stringMutex.Unlock()
+ // Update the count for fast threshold checks in ProcessResults
+ v.p.IncrementStringCount(internedStr)
- _, exists := v.p.strs[internedStr]
- if !exists {
- v.p.strs[internedStr] = make([]ExtendedPos, 0, v.p.minOccurrences) // Preallocate with expected size
- }
+ // Record every occurrence so that position lists and display counts stay accurate
+ v.p.stringMutex.Lock()
+ defer v.p.stringMutex.Unlock()
- // Create an optimized position record
- newPos := ExtendedPos{
- packageName: InternString(v.packageName), // Intern the package name to reduce memory
- Position: v.fileSet.Position(pos),
- }
-
- v.p.strs[internedStr] = append(v.p.strs[internedStr], newPos)
+ if _, exists := v.p.strs[internedStr]; !exists {
+ v.p.strs[internedStr] = make([]ExtendedPos, 0, v.p.minOccurrences)
}
+
+ v.p.strs[internedStr] = append(v.p.strs[internedStr], ExtendedPos{
+ packageName: InternString(v.packageName),
+ Position: v.fileSet.Position(pos),
+ })
}
// addConst adds a const in the map along with its position in the tree.
@@ -224,7 +268,7 @@ func (v *treeVisitor) addConst(name string, val string, pos token.Pos) {
}
// Skip constants with values that would be filtered anyway
- if len(unquotedVal) < v.p.minLength {
+ if utf8.RuneCountInString(unquotedVal) < v.p.minLength {
return
}
diff --git a/vendor/github.com/kisielk/errcheck/errcheck/excludes.go b/vendor/github.com/kisielk/errcheck/errcheck/excludes.go
index 450b798e4..3e28a2fdb 100644
--- a/vendor/github.com/kisielk/errcheck/errcheck/excludes.go
+++ b/vendor/github.com/kisielk/errcheck/errcheck/excludes.go
@@ -17,6 +17,9 @@ var DefaultExcludedSymbols = []string{
"(*bytes.Buffer).WriteRune",
"(*bytes.Buffer).WriteString",
+ // crypto
+ "crypto/rand.Read", // https://github.com/golang/go/issues/66821
+
// fmt
"fmt.Print",
"fmt.Printf",
diff --git a/vendor/github.com/lucasb-eyer/go-colorful/CHANGELOG.md b/vendor/github.com/lucasb-eyer/go-colorful/CHANGELOG.md
index 84f9c7b2c..3879f14aa 100644
--- a/vendor/github.com/lucasb-eyer/go-colorful/CHANGELOG.md
+++ b/vendor/github.com/lucasb-eyer/go-colorful/CHANGELOG.md
@@ -6,8 +6,38 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
The format of this file is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
but only releases after v1.0.3 properly adhere to it.
+## [Unreleased]
+
+## [1.4.0] - 2026-03-28
+### Added
+- Constructors, decomposers, and blend functions for the CSS Color Level 4 wide-gamut RGB color spaces `DisplayP3`, `A98Rgb`, `ProPhotoRgb`, and `Rec2020` (#81)
+- `XyzD50`, `Color.XyzD50`, `D50ToD65`, and `D65ToD50` for working with D50-based color spaces (#81)
+- `HexColor` now implements `fmt.Stringer`
+
+## [1.3.0] - 2025-09-08
+### Added
+- `BlendLinearRgb` (#50)
+- `DistanceRiemersma` (#52)
+- Introduce a function for sorting colors (#57)
+- YAML marshal/unmarshal support (#63)
+- Add support for OkLab and OkLch (#66)
+- Functions that use randomness now support specifying a custom source (#73)
+- Functions BlendOkLab and BlendOkLch (#70)
+
+## Changed
+- `Hex()` parsing is much faster (#78). However, it doesn't tolerate hex codes with alpha anymore (previously ignoring the alpha was unintentional).
+
+### Fixed
+- Fix bug when doing HSV/HCL blending between a gray color and non-gray color (#60)
+- Docs for HSV/HSL were updated to note that hue 360 is not allowed (#71)
+
+### Deprecated
+- `DistanceLinearRGB` is deprecated for the name `DistanceLinearRgb` which is more in-line with the rest of the library
+
## [1.2.0] - 2021-01-27
+This is the same as the v1.1.0 tag.
+
### Added
- HSLuv and HPLuv color spaces (#41, #51)
- CIE LCh(uv) color space, called `LuvLCh` in code (#51)
diff --git a/vendor/github.com/lucasb-eyer/go-colorful/README.md b/vendor/github.com/lucasb-eyer/go-colorful/README.md
index 8b9bd4999..1da19f703 100644
--- a/vendor/github.com/lucasb-eyer/go-colorful/README.md
+++ b/vendor/github.com/lucasb-eyer/go-colorful/README.md
@@ -1,6 +1,7 @@
go-colorful
===========
+[](https://pkg.go.dev/github.com/lucasb-eyer/go-colorful)
[](https://goreportcard.com/report/github.com/lucasb-eyer/go-colorful)
A library for playing with colors in Go. Supports Go 1.13 onwards.
@@ -29,10 +30,12 @@ Go-Colorful stores colors in RGB and provides methods from converting these to v
- **CIE-xyY:** encodes chromacity in x and y and luminance in Y, all in [0..1]
- **CIE-L\*a\*b\*:** A *perceptually uniform* color space, i.e. distances are meaningful. L\* in [0..1] and a\*, b\* almost in [-1..1].
- **CIE-L\*u\*v\*:** Very similar to CIE-L\*a\*b\*, there is [no consensus](http://en.wikipedia.org/wiki/CIELUV#Historical_background) on which one is "better".
-- **CIE-L\*C\*h° (HCL):** This is generally the [most useful](http://vis4.net/blog/posts/avoid-equidistant-hsv-colors/) one; CIE-L\*a\*b\* space in polar coordinates, i.e. a *better* HSV. H° is in [0..360], C\* almost in [-1..1] and L\* as in CIE-L\*a\*b\*.
-- **CIE LCh(uv):** Called `LuvLCh` in code, this is a cylindrical transformation of the CIE-L\*u\*v\* color space. Like HCL above: H° is in [0..360], C\* almost in [-1..1] and L\* as in CIE-L\*u\*v\*.
+- **CIE-L\*C\*h° (HCL):** This is generally the [most useful](http://vis4.net/blog/posts/avoid-equidistant-hsv-colors/) one; CIE-L\*a\*b\* space in polar coordinates, i.e. a *better* HSV. H° is in [0..360], C\* almost in [0..1] and L\* as in CIE-L\*a\*b\*.
+- **CIE LCh(uv):** Called `LuvLCh` in code, this is a cylindrical transformation of the CIE-L\*u\*v\* color space. Like HCL above: H° is in [0..360], C\* almost in [0..1] and L\* as in CIE-L\*u\*v\*.
- **HSLuv:** The better alternative to HSL, see [here](https://www.hsluv.org/) and [here](https://www.kuon.ch/post/2020-03-08-hsluv/). Hue in [0..360], Saturation and Luminance in [0..1].
-- **HPLuv:** A variant of HSLuv. The color space is smoother, but only pastel colors can be included. Because the valid colors are limited, it's easy to get invalid Saturation values way above 1.0, indicating the color can't be represented in HPLuv beccause it's not pastel.
+- **HPLuv:** A variant of HSLuv. The color space is smoother, but only pastel colors can be included. Because the valid colors are limited, it's easy to get invalid Saturation values way above 1.0, indicating the color can't be represented in HPLuv because it's not pastel.
+- **Oklab:** A perceptual color space by Björn Ottosson that improves on CIE-L\*a\*b\* with better perceptual uniformity, especially for blue hues. L in [0..1], a and b roughly in [-0.5..0.5]. See [Oklab](https://bottosson.github.io/posts/oklab/).
+- **Oklch:** The cylindrical (polar) representation of Oklab, similar to HCL. L in [0..1], C roughly in [0..0.5], h° in [0..360].
For the colorspaces where it makes sense (XYZ, Lab, Luv, HCl), the
[D65](http://en.wikipedia.org/wiki/Illuminant_D65) is used as reference white
@@ -52,14 +55,6 @@ Nice, but what's it useful for?
- Generating random colors under some constraints (e.g. colors of the same shade, or shades of one color.)
- Generating gorgeous random palettes with distinct colors of a same temperature.
-What not (yet)?
-===============
-There are a few features which are currently missing and might be useful.
-I just haven't implemented them yet because I didn't have the need for it.
-Pull requests welcome.
-
-- Sorting colors (potentially using above mentioned distances)
-
So which colorspace should I use?
=================================
It depends on what you want to do. I think the folks from *I want hue* are
@@ -103,6 +98,8 @@ c = colorful.Xyy(0.219895, 0.221839, 0.190837)
c = colorful.Lab(0.507850, 0.040585,-0.370945)
c = colorful.Luv(0.507849,-0.194172,-0.567924)
c = colorful.Hcl(276.2440, 0.373160, 0.507849)
+c = colorful.OkLab(0.577227, -0.021391, -0.104541)
+c = colorful.OkLch(0.577227, 0.106707, 258.435657)
fmt.Printf("RGB values: %v, %v, %v", c.R, c.G, c.B)
```
@@ -116,6 +113,8 @@ x, y, Y := c.Xyy()
l, a, b := c.Lab()
l, u, v := c.Luv()
h, c, l := c.Hcl()
+l, a, b = c.OkLab()
+l, c, h = c.OkLch()
```
Note that, because of Go's unfortunate choice of requiring an initial uppercase,
@@ -139,7 +138,7 @@ alpha colors, this means the RGB values are lost (set to 0) and it's impossible
to recover them. In such a case `MakeColor` will return `false` as its second value.
### Comparing colors
-In the RGB color space, the Euclidian distance between colors *doesn't* correspond
+In the RGB color space, the Euclidean distance between colors *doesn't* correspond
to visual/perceptual distance. This means that two pairs of colors which have the
same distance in RGB space can look much further apart. This is fixed by the
CIE-L\*a\*b\*, CIE-L\*u\*v\* and CIE-L\*C\*h° color spaces.
@@ -197,7 +196,7 @@ it only if you really know what you're doing. It will eat your cat.
Blending is highly connected to distance, since it basically "walks through" the
colorspace thus, if the colorspace maps distances well, the walk is "smooth".
-Colorful comes with blending functions in RGB, HSV and any of the LAB spaces.
+Colorful comes with blending functions in RGB, HSV, Oklab, Oklch, and any of the CIE-LAB spaces.
Of course, you'd rather want to use the blending functions of the LAB spaces since
these spaces map distances well but, just in case, here is an example showing
you how the blendings (`#fdffcc` to `#242a42`) are done in the various spaces:
@@ -208,7 +207,7 @@ What you see is that HSV is really bad: it adds some green, which is not present
in the original colors at all! RGB is much better, but it stays light a little
too long. LUV and LAB both hit the right lightness but LAB has a little more
color. HCL works in the same vein as HSV (both cylindrical interpolations) but
-it does it right in that there is no green appearing and the lighthness changes
+it does it right in that there is no green appearing and the lightness changes
in a linear manner.
While this seems all good, you need to know one thing: When interpolating in any
@@ -316,11 +315,11 @@ generating this picture in `doc/colorgens/colorgens.go`.
### Getting random palettes
As soon as you need to generate more than one random color, you probably want
-them to be distinguishible. Playing against an opponent which has almost the
+them to be distinguishable. Playing against an opponent which has almost the
same blue as I do is not fun. This is where random palettes can help.
These palettes are generated using an algorithm which ensures that all colors
-on the palette are as distinguishible as possible. Again, there is a `Fast`
+on the palette are as distinguishable as possible. Again, there is a `Fast`
method which works in HSV and is less perceptually uniform and a non-`Fast`
method which works in CIE spaces. For more theory on `SoftPalette`, check out
[I want hue](http://tools.medialab.sciences-po.fr/iwanthue/theory.php). Yet
@@ -372,10 +371,18 @@ from top to bottom: `Warm`, `FastWarm`, `Happy`, `FastHappy`, `Soft`,
Again, the code used for generating the above image is available as [doc/palettegens/palettegens.go](https://github.com/lucasb-eyer/go-colorful/blob/master/doc/palettegens/palettegens.go).
### Sorting colors
-TODO: Sort using dist fn.
+
+Sorting colors is not a well-defined operation. For example, {dark blue, dark red, light blue, light red} is already sorted if darker colors should precede lighter colors but would need to be re-sorted as {dark red, light red, dark blue, light blue} if longer-wavelength colors should precede shorter-wavelength colors.
+
+Go-Colorful's `Sorted` function orders a list of colors so as to minimize the average distance between adjacent colors, including between the last and the first. (`Sorted` does not necessarily find the true minimum, only a reasonably close approximation.) The following picture, drawn by [doc/colorsort/colorsort.go](https://github.com/lucasb-eyer/go-colorful/blob/master/doc/colorsort/colorsort.go), illustrates `Sorted`'s behavior:
+
+
+
+The first row represents the input: a slice of 512 randomly chosen colors. The second row shows the colors sorted in CIE-L\*C\*h° space, ordered first by lightness (L), then by hue angle (h), and finally by chroma (C). Note that distracting pinstripes permeate the colors. Sorting using *any* color space and *any* ordering of the channels yields a similar pinstriped pattern. The third row of the image was sorted using Go-Colorful's `Sorted` function. Although the colors do not appear to be in any particular order, the sequence at least appears smoother than the one sorted by channel.
+
### Using linear RGB for computations
-There are two methods for transforming RGB<->Linear RGB: a fast and almost precise one,
+There are two methods for transforming RGB⟷Linear RGB: a fast and almost precise one,
and a slow and precise one.
```go
@@ -471,11 +478,12 @@ section above.
Who?
====
-This library was developed by Lucas Beyer with contributions from
-Bastien Dejean (@baskerville), Phil Kulak (@pkulak) and Christian Muehlhaeuser (@muesli).
-
-It is now maintained by makeworld (@makeworld-the-better-one).
+This library was originally developed by Lucas Beyer, with notable
+contributions from Bastien Dejean (@baskerville), Phil Kulak (@pkulak),
+Christian Muehlhaeuser (@muesli), Scott Pakin (@spakin), and many others.
+See the [contributors list](https://github.com/lucasb-eyer/go-colorful/graphs/contributors) for the full roster.
+It is currently maintained by makeworld (@makew0rld).
## License
diff --git a/vendor/github.com/lucasb-eyer/go-colorful/colorgens.go b/vendor/github.com/lucasb-eyer/go-colorful/colorgens.go
index 2e2e49e19..ac697d655 100644
--- a/vendor/github.com/lucasb-eyer/go-colorful/colorgens.go
+++ b/vendor/github.com/lucasb-eyer/go-colorful/colorgens.go
@@ -2,28 +2,32 @@
package colorful
-import (
- "math/rand"
-)
-
// Creates a random dark, "warm" color through a restricted HSV space.
-func FastWarmColor() Color {
+func FastWarmColorWithRand(rand RandInterface) Color {
return Hsv(
rand.Float64()*360.0,
0.5+rand.Float64()*0.3,
0.3+rand.Float64()*0.3)
}
+func FastWarmColor() Color {
+ return FastWarmColorWithRand(getDefaultGlobalRand())
+}
+
// Creates a random dark, "warm" color through restricted HCL space.
// This is slower than FastWarmColor but will likely give you colors which have
// the same "warmness" if you run it many times.
-func WarmColor() (c Color) {
- for c = randomWarm(); !c.IsValid(); c = randomWarm() {
+func WarmColorWithRand(rand RandInterface) (c Color) {
+ for c = randomWarmWithRand(rand); !c.IsValid(); c = randomWarmWithRand(rand) {
}
return
}
-func randomWarm() Color {
+func WarmColor() (c Color) {
+ return WarmColorWithRand(getDefaultGlobalRand())
+}
+
+func randomWarmWithRand(rand RandInterface) Color {
return Hcl(
rand.Float64()*360.0,
0.1+rand.Float64()*0.3,
@@ -31,23 +35,31 @@ func randomWarm() Color {
}
// Creates a random bright, "pimpy" color through a restricted HSV space.
-func FastHappyColor() Color {
+func FastHappyColorWithRand(rand RandInterface) Color {
return Hsv(
rand.Float64()*360.0,
0.7+rand.Float64()*0.3,
0.6+rand.Float64()*0.3)
}
+func FastHappyColor() Color {
+ return FastHappyColorWithRand(getDefaultGlobalRand())
+}
+
// Creates a random bright, "pimpy" color through restricted HCL space.
// This is slower than FastHappyColor but will likely give you colors which
// have the same "brightness" if you run it many times.
-func HappyColor() (c Color) {
- for c = randomPimp(); !c.IsValid(); c = randomPimp() {
+func HappyColorWithRand(rand RandInterface) (c Color) {
+ for c = randomPimpWithRand(rand); !c.IsValid(); c = randomPimpWithRand(rand) {
}
return
}
-func randomPimp() Color {
+func HappyColor() (c Color) {
+ return HappyColorWithRand(getDefaultGlobalRand())
+}
+
+func randomPimpWithRand(rand RandInterface) Color {
return Hcl(
rand.Float64()*360.0,
0.5+rand.Float64()*0.3,
diff --git a/vendor/github.com/lucasb-eyer/go-colorful/colors.go b/vendor/github.com/lucasb-eyer/go-colorful/colors.go
index 0d5bffe5d..17441a8c6 100644
--- a/vendor/github.com/lucasb-eyer/go-colorful/colors.go
+++ b/vendor/github.com/lucasb-eyer/go-colorful/colors.go
@@ -5,6 +5,7 @@ import (
"fmt"
"image/color"
"math"
+ "strconv"
)
// A color is stored internally using sRGB (standard RGB) values in the range 0-1
@@ -94,15 +95,39 @@ func (c1 Color) DistanceRgb(c2 Color) float64 {
return math.Sqrt(sq(c1.R-c2.R) + sq(c1.G-c2.G) + sq(c1.B-c2.B))
}
-// DistanceLinearRGB computes the distance between two colors in linear RGB
+// DistanceLinearRgb computes the distance between two colors in linear RGB
// space. This is not useful for measuring how humans perceive color, but
// might be useful for other things, like dithering.
-func (c1 Color) DistanceLinearRGB(c2 Color) float64 {
+func (c1 Color) DistanceLinearRgb(c2 Color) float64 {
r1, g1, b1 := c1.LinearRgb()
r2, g2, b2 := c2.LinearRgb()
return math.Sqrt(sq(r1-r2) + sq(g1-g2) + sq(b1-b2))
}
+// DistanceLinearRGB is deprecated in favour of DistanceLinearRgb.
+// They do the exact same thing.
+func (c1 Color) DistanceLinearRGB(c2 Color) float64 {
+ return c1.DistanceLinearRgb(c2)
+}
+
+// DistanceRiemersma is a color distance algorithm developed by Thiadmer Riemersma.
+// It uses RGB coordinates, but he claims it has similar results to CIELUV.
+// This makes it both fast and accurate.
+//
+// Sources:
+//
+// https://www.compuphase.com/cmetric.htm
+// https://github.com/lucasb-eyer/go-colorful/issues/52
+func (c1 Color) DistanceRiemersma(c2 Color) float64 {
+ rAvg := (c1.R + c2.R) / 2.0
+ // Deltas
+ dR := c1.R - c2.R
+ dG := c1.G - c2.G
+ dB := c1.B - c2.B
+
+ return math.Sqrt((2+rAvg)*dR*dR + 4*dG*dG + (2+(1-rAvg))*dB*dB)
+}
+
// Check for equality between colors within the tolerance Delta (1/255).
func (c1 Color) AlmostEqualRgb(c2 Color) bool {
return math.Abs(c1.R-c2.R)+
@@ -112,9 +137,11 @@ func (c1 Color) AlmostEqualRgb(c2 Color) bool {
// You don't really want to use this, do you? Go for BlendLab, BlendLuv or BlendHcl.
func (c1 Color) BlendRgb(c2 Color, t float64) Color {
- return Color{c1.R + t*(c2.R-c1.R),
+ return Color{
+ c1.R + t*(c2.R-c1.R),
c1.G + t*(c2.G-c1.G),
- c1.B + t*(c2.B-c1.B)}
+ c1.B + t*(c2.B-c1.B),
+ }
}
// Utility used by Hxx color-spaces for interpolating between two angles in [0,360].
@@ -128,9 +155,9 @@ func interp_angle(a0, a1, t float64) float64 {
/// HSV ///
///////////
// From http://en.wikipedia.org/wiki/HSL_and_HSV
-// Note that h is in [0..360] and s,v in [0..1]
+// Note that h is in [0..359] and s,v in [0..1]
-// Hsv returns the Hue [0..360], Saturation and Value [0..1] of the color.
+// Hsv returns the Hue [0..359], Saturation and Value [0..1] of the color.
func (col Color) Hsv() (h, s, v float64) {
min := math.Min(math.Min(col.R, col.G), col.B)
v = math.Max(math.Max(col.R, col.G), col.B)
@@ -160,7 +187,7 @@ func (col Color) Hsv() (h, s, v float64) {
return
}
-// Hsv creates a new Color given a Hue in [0..360], a Saturation and a Value in [0..1]
+// Hsv creates a new Color given a Hue in [0..359], a Saturation and a Value in [0..1]
func Hsv(H, S, V float64) Color {
Hp := H / 60.0
C := V * S
@@ -198,6 +225,13 @@ func (c1 Color) BlendHsv(c2 Color, t float64) Color {
h1, s1, v1 := c1.Hsv()
h2, s2, v2 := c2.Hsv()
+ // https://github.com/lucasb-eyer/go-colorful/pull/60
+ if s1 == 0 && s2 != 0 {
+ h1 = h2
+ } else if s2 == 0 && s1 != 0 {
+ h2 = h1
+ }
+
// We know that h are both in [0..360]
return Hsv(interp_angle(h1, h2, t), s1+t*(s2-s1), v1+t*(v2-v1))
}
@@ -205,7 +239,7 @@ func (c1 Color) BlendHsv(c2 Color, t float64) Color {
/// HSL ///
///////////
-// Hsl returns the Hue [0..360], Saturation [0..1], and Luminance (lightness) [0..1] of the color.
+// Hsl returns the Hue [0..359], Saturation [0..1], and Luminance (lightness) [0..1] of the color.
func (col Color) Hsl() (h, s, l float64) {
min := math.Min(math.Min(col.R, col.G), col.B)
max := math.Max(math.Max(col.R, col.G), col.B)
@@ -240,7 +274,7 @@ func (col Color) Hsl() (h, s, l float64) {
return
}
-// Hsl creates a new Color given a Hue in [0..360], a Saturation [0..1], and a Luminance (lightness) in [0..1]
+// Hsl creates a new Color given a Hue in [0..359], a Saturation [0..1], and a Luminance (lightness) in [0..1]
func Hsl(h, s, l float64) Color {
if s == 0 {
return Color{l, l, l}
@@ -331,23 +365,46 @@ func (col Color) Hex() string {
// Hex parses a "html" hex color-string, either in the 3 "#f0c" or 6 "#ff1034" digits form.
func Hex(scol string) (Color, error) {
- format := "#%02x%02x%02x"
- factor := 1.0 / 255.0
- if len(scol) == 4 {
- format = "#%1x%1x%1x"
- factor = 1.0 / 15.0
+ if scol == "" || scol[0] != '#' {
+ return Color{}, fmt.Errorf("color: %v is not a hex-color", scol)
+ }
+ var c Color
+ var err error
+ switch len(scol) {
+ case 4:
+ c, err = parseHexColor(scol[1:2], scol[2:3], scol[3:4], 4, 1.0/15.0)
+ case 7:
+ c, err = parseHexColor(scol[1:3], scol[3:5], scol[5:7], 8, 1.0/255.0)
+ default:
+ return Color{}, fmt.Errorf("color: %v is not a hex-color", scol)
}
-
- var r, g, b uint8
- n, err := fmt.Sscanf(scol, format, &r, &g, &b)
if err != nil {
+ return Color{}, fmt.Errorf("color: %v is not a hex-color: %w", scol, err)
+ }
+ return c, nil
+}
+
+func parseHexColor(r, g, b string, bits int, factor float64) (Color, error) {
+ var c Color
+ var v uint64
+ var err error
+
+ if v, err = strconv.ParseUint(r, 16, bits); err != nil {
return Color{}, err
}
- if n != 3 {
- return Color{}, fmt.Errorf("color: %v is not a hex-color", scol)
+ c.R = float64(v) * factor
+
+ if v, err = strconv.ParseUint(g, 16, bits); err != nil {
+ return Color{}, err
}
+ c.G = float64(v) * factor
- return Color{float64(r) * factor, float64(g) * factor, float64(b) * factor}, nil
+ if v, err = strconv.ParseUint(b, 16, bits); err != nil {
+ return Color{}, err
+ }
+ c.B = float64(v) * factor
+
+ return c, err
}
/// Linear ///
@@ -377,7 +434,7 @@ func linearize_fast(v float64) float64 {
v2 := v1 * v1
v3 := v2 * v1
v4 := v2 * v2
- //v5 := v3*v2
+ // v5 := v3*v2
return -0.248750514614486 + 0.925583310193438*v + 1.16740237321695*v2 + 0.280457026598666*v3 - 0.0757991963780179*v4 //+ 0.0437040411548932*v5
}
@@ -450,6 +507,19 @@ func LinearRgbToXyz(r, g, b float64) (x, y, z float64) {
return
}
+// BlendLinearRgb blends two colors in the Linear RGB color-space.
+// Unlike BlendRgb, this will not produce dark color around the center.
+// t == 0 results in c1, t == 1 results in c2
+func (c1 Color) BlendLinearRgb(c2 Color, t float64) Color {
+ r1, g1, b1 := c1.LinearRgb()
+ r2, g2, b2 := c2.LinearRgb()
+ return LinearRgb(
+ r1+t*(r2-r1),
+ g1+t*(g2-g1),
+ b1+t*(b2-b1),
+ )
+}
+
/// XYZ ///
///////////
// http://www.sjbrown.co.uk/2004/05/14/gamma-correct-rendering/
@@ -784,7 +854,7 @@ func LuvToXyz(l, u, v float64) (x, y, z float64) {
}
func LuvToXyzWhiteRef(l, u, v float64, wref [3]float64) (x, y, z float64) {
- //y = wref[1] * lab_finv((l + 0.16) / 1.16)
+ // y = wref[1] * lab_finv((l + 0.16) / 1.16)
if l <= 0.08 {
y = wref[1] * l * 100.0 * 3.0 / 29.0 * 3.0 / 29.0 * 3.0 / 29.0
} else {
@@ -913,6 +983,13 @@ func (col1 Color) BlendHcl(col2 Color, t float64) Color {
h1, c1, l1 := col1.Hcl()
h2, c2, l2 := col2.Hcl()
+ // https://github.com/lucasb-eyer/go-colorful/pull/60
+ if c1 <= 0.00015 && c2 >= 0.00015 {
+ h1 = h2
+ } else if c2 <= 0.00015 && c1 >= 0.00015 {
+ h2 = h1
+ }
+
// We know that h are both in [0..360]
return Hcl(interp_angle(h1, h2, t), c1+t*(c2-c1), l1+t*(l2-l1)).Clamped()
}
@@ -977,3 +1054,103 @@ func (col1 Color) BlendLuvLCh(col2 Color, t float64) Color {
// We know that h are both in [0..360]
return LuvLCh(l1+t*(l2-l1), c1+t*(c2-c1), interp_angle(h1, h2, t))
}
+
+/// OkLab ///
+///////////
+
+func (col Color) OkLab() (l, a, b float64) {
+ return XyzToOkLab(col.Xyz())
+}
+
+func OkLab(l, a, b float64) Color {
+ return Xyz(OkLabToXyz(l, a, b))
+}
+
+func XyzToOkLab(x, y, z float64) (l, a, b float64) {
+ l_ := math.Cbrt(0.8189330101*x + 0.3618667424*y - 0.1288597137*z)
+ m_ := math.Cbrt(0.0329845436*x + 0.9293118715*y + 0.0361456387*z)
+ s_ := math.Cbrt(0.0482003018*x + 0.2643662691*y + 0.6338517070*z)
+ l = 0.2104542553*l_ + 0.7936177850*m_ - 0.0040720468*s_
+ a = 1.9779984951*l_ - 2.4285922050*m_ + 0.4505937099*s_
+ b = 0.0259040371*l_ + 0.7827717662*m_ - 0.8086757660*s_
+ return
+}
+
+func OkLabToXyz(l, a, b float64) (x, y, z float64) {
+ l_ := 0.9999999984505196*l + 0.39633779217376774*a + 0.2158037580607588*b
+ m_ := 1.0000000088817607*l - 0.10556134232365633*a - 0.0638541747717059*b
+ s_ := 1.0000000546724108*l - 0.08948418209496574*a - 1.2914855378640917*b
+
+ ll := math.Pow(l_, 3)
+ m := math.Pow(m_, 3)
+ s := math.Pow(s_, 3)
+
+ x = 1.2268798733741557*ll - 0.5578149965554813*m + 0.28139105017721594*s
+ y = -0.04057576262431372*ll + 1.1122868293970594*m - 0.07171106666151696*s
+ z = -0.07637294974672142*ll - 0.4214933239627916*m + 1.5869240244272422*s
+
+ return
+}
+
+// BlendOkLab blends two colors in the OkLab color-space, which should result in a better blend (even compared to BlendLab).
+func (c1 Color) BlendOkLab(c2 Color, t float64) Color {
+ l1, a1, b1 := c1.OkLab()
+ l2, a2, b2 := c2.OkLab()
+ return OkLab(l1+t*(l2-l1),
+ a1+t*(a2-a1),
+ b1+t*(b2-b1))
+}
+
+/// OkLch ///
+///////////
+
+func (col Color) OkLch() (l, c, h float64) {
+ return OkLabToOkLch(col.OkLab())
+}
+
+func OkLch(l, c, h float64) Color {
+ return Xyz(OkLchToXyz(l, c, h))
+}
+
+func XyzToOkLch(x, y, z float64) (float64, float64, float64) {
+ l, c, h := OkLabToOkLch(XyzToOkLab(x, y, z))
+ return l, c, h
+}
+
+func OkLchToXyz(l, c, h float64) (float64, float64, float64) {
+ x, y, z := OkLabToXyz(OkLchToOkLab(l, c, h))
+ return x, y, z
+}
+
+func OkLabToOkLch(l, a, b float64) (float64, float64, float64) {
+ c := math.Sqrt((a * a) + (b * b))
+ h := math.Atan2(b, a)
+ if h < 0 {
+ h += 2 * math.Pi
+ }
+
+ return l, c, h * 180 / math.Pi
+}
+
+func OkLchToOkLab(l, c, h float64) (float64, float64, float64) {
+ h *= math.Pi / 180
+ a := c * math.Cos(h)
+ b := c * math.Sin(h)
+ return l, a, b
+}
+
+// BlendOkLch blends two colors in the OkLch color-space, which should result in a better blend (even compared to BlendHcl).
+func (col1 Color) BlendOkLch(col2 Color, t float64) Color {
+ l1, c1, h1 := col1.OkLch()
+ l2, c2, h2 := col2.OkLch()
+
+ // https://github.com/lucasb-eyer/go-colorful/pull/60
+ if c1 <= 0.00015 && c2 >= 0.00015 {
+ h1 = h2
+ } else if c2 <= 0.00015 && c1 >= 0.00015 {
+ h2 = h1
+ }
+
+ // We know that h are both in [0..360]
+ return OkLch(l1+t*(l2-l1), c1+t*(c2-c1), interp_angle(h1, h2, t)).Clamped()
+}
diff --git a/vendor/github.com/lucasb-eyer/go-colorful/happy_palettegen.go b/vendor/github.com/lucasb-eyer/go-colorful/happy_palettegen.go
index bb66dfa4f..0cb9286cb 100644
--- a/vendor/github.com/lucasb-eyer/go-colorful/happy_palettegen.go
+++ b/vendor/github.com/lucasb-eyer/go-colorful/happy_palettegen.go
@@ -1,13 +1,9 @@
package colorful
-import (
- "math/rand"
-)
-
// Uses the HSV color space to generate colors with similar S,V but distributed
// evenly along their Hue. This is fast but not always pretty.
// If you've got time to spare, use Lab (the non-fast below).
-func FastHappyPalette(colorsCount int) (colors []Color) {
+func FastHappyPaletteWithRand(colorsCount int, rand RandInterface) (colors []Color) {
colors = make([]Color, colorsCount)
for i := 0; i < colorsCount; i++ {
@@ -16,10 +12,18 @@ func FastHappyPalette(colorsCount int) (colors []Color) {
return
}
-func HappyPalette(colorsCount int) ([]Color, error) {
+func FastHappyPalette(colorsCount int) (colors []Color) {
+ return FastHappyPaletteWithRand(colorsCount, getDefaultGlobalRand())
+}
+
+func HappyPaletteWithRand(colorsCount int, rand RandInterface) ([]Color, error) {
pimpy := func(l, a, b float64) bool {
_, c, _ := LabToHcl(l, a, b)
return 0.3 <= c && 0.4 <= l && l <= 0.8
}
- return SoftPaletteEx(colorsCount, SoftPaletteSettings{pimpy, 50, true})
+ return SoftPaletteExWithRand(colorsCount, SoftPaletteSettings{pimpy, 50, true}, rand)
+}
+
+func HappyPalette(colorsCount int) ([]Color, error) {
+ return HappyPaletteWithRand(colorsCount, getDefaultGlobalRand())
}
diff --git a/vendor/github.com/lucasb-eyer/go-colorful/hexcolor.go b/vendor/github.com/lucasb-eyer/go-colorful/hexcolor.go
index 76f31d8f9..26f357304 100644
--- a/vendor/github.com/lucasb-eyer/go-colorful/hexcolor.go
+++ b/vendor/github.com/lucasb-eyer/go-colorful/hexcolor.go
@@ -34,6 +34,10 @@ func (hc *HexColor) Value() (driver.Value, error) {
return Color(*hc).Hex(), nil
}
+func (hc HexColor) String() string {
+ return Color(hc).Hex()
+}
+
func (e errUnsupportedType) Error() string {
return fmt.Sprintf("unsupported type: got %v, want a %s", e.got, e.want)
}
@@ -65,3 +69,23 @@ func (hc *HexColor) Decode(hexCode string) error {
*hc = HexColor(col)
return nil
}
+
+func (hc HexColor) MarshalYAML() (interface{}, error) {
+ return Color(hc).Hex(), nil
+}
+
+func (hc *HexColor) UnmarshalYAML(unmarshal func(interface{}) error) error {
+ var hexCode string
+ if err := unmarshal(&hexCode); err != nil {
+ return err
+ }
+
+ var col, err = Hex(hexCode)
+ if err != nil {
+ return err
+ }
+
+ *hc = HexColor(col)
+
+ return nil
+}
diff --git a/vendor/github.com/lucasb-eyer/go-colorful/hsluv.go b/vendor/github.com/lucasb-eyer/go-colorful/hsluv.go
index d19fb6443..cc5148822 100644
--- a/vendor/github.com/lucasb-eyer/go-colorful/hsluv.go
+++ b/vendor/github.com/lucasb-eyer/go-colorful/hsluv.go
@@ -11,7 +11,8 @@ import "math"
// comparing to the test values, this modified white reference is used internally.
//
// See this GitHub thread for details on these values:
-// https://github.com/hsluv/hsluv/issues/79
+//
+// https://github.com/hsluv/hsluv/issues/79
var hSLuvD65 = [3]float64{0.95045592705167, 1.0, 1.089057750759878}
func LuvLChToHSLuv(l, c, h float64) (float64, float64, float64) {
@@ -115,7 +116,7 @@ func (col Color) HPLuv() (h, s, l float64) {
return LuvLChToHPLuv(col.LuvLChWhiteRef(hSLuvD65))
}
-// DistanceHSLuv calculates Euclidan distance in the HSLuv colorspace. No idea
+// DistanceHSLuv calculates Euclidean distance in the HSLuv colorspace. No idea
// how useful this is.
//
// The Hue value is divided by 100 before the calculation, so that H, S, and L
diff --git a/vendor/github.com/lucasb-eyer/go-colorful/rand.go b/vendor/github.com/lucasb-eyer/go-colorful/rand.go
new file mode 100644
index 000000000..d3a2d5b50
--- /dev/null
+++ b/vendor/github.com/lucasb-eyer/go-colorful/rand.go
@@ -0,0 +1,22 @@
+package colorful
+
+import "math/rand"
+
+type RandInterface interface {
+ Float64() float64
+ Intn(n int) int
+}
+
+type defaultGlobalRand struct{}
+
+func (df defaultGlobalRand) Float64() float64 {
+ return rand.Float64()
+}
+
+func (df defaultGlobalRand) Intn(n int) int {
+ return rand.Intn(n)
+}
+
+func getDefaultGlobalRand() RandInterface {
+ return defaultGlobalRand{}
+}
diff --git a/vendor/github.com/lucasb-eyer/go-colorful/soft_palettegen.go b/vendor/github.com/lucasb-eyer/go-colorful/soft_palettegen.go
index 9f7bf6f7c..6d8aa137e 100644
--- a/vendor/github.com/lucasb-eyer/go-colorful/soft_palettegen.go
+++ b/vendor/github.com/lucasb-eyer/go-colorful/soft_palettegen.go
@@ -6,7 +6,6 @@ package colorful
import (
"fmt"
"math"
- "math/rand"
)
// The algorithm works in L*a*b* color space and converts to RGB in the end.
@@ -32,7 +31,7 @@ type SoftPaletteSettings struct {
// as a new palette of distinctive colors. Falls back to K-medoid if the mean
// happens to fall outside of the color-space, which can only happen if you
// specify a CheckColor function.
-func SoftPaletteEx(colorsCount int, settings SoftPaletteSettings) ([]Color, error) {
+func SoftPaletteExWithRand(colorsCount int, settings SoftPaletteSettings, rand RandInterface) ([]Color, error) {
// Checks whether it's a valid RGB and also fulfills the potentially provided constraint.
check := func(col lab_t) bool {
@@ -79,7 +78,7 @@ func SoftPaletteEx(colorsCount int, settings SoftPaletteSettings) ([]Color, erro
// The actual k-means/medoid iterations
for i := 0; i < settings.Iterations; i++ {
- // Reassing the samples to clusters, i.e. to their closest mean.
+ // Reassigning the samples to clusters, i.e. to their closest mean.
// By the way, also check if any sample is used as a medoid and if so, mark that.
for isample, sample := range samples {
samples_used[isample] = false
@@ -100,7 +99,7 @@ func SoftPaletteEx(colorsCount int, settings SoftPaletteSettings) ([]Color, erro
// Compute new means according to the samples.
for imean := range means {
- // The new mean is the average of all samples belonging to it..
+ // The new mean is the average of all samples belonging to it.
nsamples := 0
newmean := lab_t{0.0, 0.0, 0.0}
for isample, sample := range samples {
@@ -148,9 +147,17 @@ func SoftPaletteEx(colorsCount int, settings SoftPaletteSettings) ([]Color, erro
return labs2cols(means), nil
}
+func SoftPaletteEx(colorsCount int, settings SoftPaletteSettings) ([]Color, error) {
+ return SoftPaletteExWithRand(colorsCount, settings, getDefaultGlobalRand())
+}
+
// A wrapper which uses common parameters.
+func SoftPaletteWithRand(colorsCount int, rand RandInterface) ([]Color, error) {
+ return SoftPaletteExWithRand(colorsCount, SoftPaletteSettings{nil, 50, false}, rand)
+}
+
func SoftPalette(colorsCount int) ([]Color, error) {
- return SoftPaletteEx(colorsCount, SoftPaletteSettings{nil, 50, false})
+ return SoftPaletteWithRand(colorsCount, getDefaultGlobalRand())
}
func in(haystack []lab_t, upto int, needle lab_t) bool {
diff --git a/vendor/github.com/lucasb-eyer/go-colorful/sort.go b/vendor/github.com/lucasb-eyer/go-colorful/sort.go
new file mode 100644
index 000000000..b1c1b6813
--- /dev/null
+++ b/vendor/github.com/lucasb-eyer/go-colorful/sort.go
@@ -0,0 +1,191 @@
+// This file provides functions for sorting colors.
+
+package colorful
+
+import (
+ "math"
+ "sort"
+)
+
+// An element represents a single element of a set. It is used to
+// implement a disjoint-set forest.
+type element struct {
+ parent *element // Parent element
+ rank int // Rank (approximate depth) of the subtree with this element as root
+}
+
+// newElement creates a singleton set and returns its sole element.
+func newElement() *element {
+ s := &element{}
+ s.parent = s
+ return s
+}
+
+// find returns an arbitrary element of a set when invoked on any element of
+// the set, The important feature is that it returns the same value when
+// invoked on any element of the set. Consequently, it can be used to test if
+// two elements belong to the same set.
+func (e *element) find() *element {
+ for e.parent != e {
+ e.parent = e.parent.parent
+ e = e.parent
+ }
+ return e
+}
+
+// union establishes the union of two sets when given an element from each set.
+// Afterwards, the original sets no longer exist as separate entities.
+func union(e1, e2 *element) {
+ // Ensure the two elements aren't already part of the same union.
+ e1Root := e1.find()
+ e2Root := e2.find()
+ if e1Root == e2Root {
+ return
+ }
+
+ // Create a union by making the shorter tree point to the root of the
+ // larger tree.
+ switch {
+ case e1Root.rank < e2Root.rank:
+ e1Root.parent = e2Root
+ case e1Root.rank > e2Root.rank:
+ e2Root.parent = e1Root
+ default:
+ e2Root.parent = e1Root
+ e1Root.rank++
+ }
+}
+
+// An edgeIdxs describes an edge in a graph or tree. The vertices in the edge
+// are indexes into a list of Color values.
+type edgeIdxs [2]int
+
+// An edgeDistance is a map from an edge (pair of indices) to a distance
+// between the two vertices.
+type edgeDistance map[edgeIdxs]float64
+
+// allToAllDistancesCIEDE2000 computes the CIEDE2000 distance between each pair of
+// colors. It returns a map from a pair of indices (u, v) with u < v to a
+// distance.
+func allToAllDistancesCIEDE2000(cs []Color) edgeDistance {
+ nc := len(cs)
+ m := make(edgeDistance, nc*nc)
+ for u := 0; u < nc-1; u++ {
+ for v := u + 1; v < nc; v++ {
+ m[edgeIdxs{u, v}] = cs[u].DistanceCIEDE2000(cs[v])
+ }
+ }
+ return m
+}
+
+// sortEdges sorts all edges in a distance map by increasing vertex distance.
+func sortEdges(m edgeDistance) []edgeIdxs {
+ es := make([]edgeIdxs, 0, len(m))
+ for uv := range m {
+ es = append(es, uv)
+ }
+ sort.Slice(es, func(i, j int) bool {
+ return m[es[i]] < m[es[j]]
+ })
+ return es
+}
+
+// minSpanTree computes a minimum spanning tree from a vertex count and a
+// distance-sorted edge list. It returns the subset of edges that belong to
+// the tree, including both (u, v) and (v, u) for each edge.
+func minSpanTree(nc int, es []edgeIdxs) map[edgeIdxs]struct{} {
+ // Start with each vertex in its own set.
+ elts := make([]*element, nc)
+ for i := range elts {
+ elts[i] = newElement()
+ }
+
+ // Run Kruskal's algorithm to construct a minimal spanning tree.
+ mst := make(map[edgeIdxs]struct{}, nc)
+ for _, uv := range es {
+ u, v := uv[0], uv[1]
+ if elts[u].find() == elts[v].find() {
+ continue // Same set: edge would introduce a cycle.
+ }
+ mst[uv] = struct{}{}
+ mst[edgeIdxs{v, u}] = struct{}{}
+ union(elts[u], elts[v])
+ }
+ return mst
+}
+
+// traverseMST walks a minimum spanning tree in prefix order.
+func traverseMST(mst map[edgeIdxs]struct{}, root int) []int {
+ // Compute a list of neighbors for each vertex.
+ neighs := make(map[int][]int, len(mst))
+ for uv := range mst {
+ u, v := uv[0], uv[1]
+ neighs[u] = append(neighs[u], v)
+ }
+ for u, vs := range neighs {
+ sort.Ints(vs)
+ copy(neighs[u], vs)
+ }
+
+ // Walk the tree from a given vertex.
+ order := make([]int, 0, len(neighs))
+ visited := make(map[int]bool, len(neighs))
+ var walkFrom func(int)
+ walkFrom = func(r int) {
+ // Visit the starting vertex.
+ order = append(order, r)
+ visited[r] = true
+
+ // Recursively visit each child in turn.
+ for _, c := range neighs[r] {
+ if !visited[c] {
+ walkFrom(c)
+ }
+ }
+ }
+ walkFrom(root)
+ return order
+}
+
+// Sorted sorts a list of Color values. Sorting is not a well-defined operation
+// for colors so the intention here primarily is to order colors so that the
+// transition from one to the next is fairly smooth.
+func Sorted(cs []Color) []Color {
+ // Do nothing in trivial cases.
+ newCs := make([]Color, len(cs))
+ if len(cs) < 2 {
+ copy(newCs, cs)
+ return newCs
+ }
+
+ // Compute the distance from each color to every other color.
+ dists := allToAllDistancesCIEDE2000(cs)
+
+ // Produce a list of edges in increasing order of the distance between
+ // their vertices.
+ edges := sortEdges(dists)
+
+ // Construct a minimum spanning tree from the list of edges.
+ mst := minSpanTree(len(cs), edges)
+
+ // Find the darkest color in the list.
+ var black Color
+ var dIdx int // Index of darkest color
+ light := math.MaxFloat64 // Lightness of darkest color (distance from black)
+ for i, c := range cs {
+ d := black.DistanceCIEDE2000(c)
+ if d < light {
+ dIdx = i
+ light = d
+ }
+ }
+
+ // Traverse the tree starting from the darkest color.
+ idxs := traverseMST(mst, dIdx)
+
+ // Convert the index list to a list of colors, overwriting the input.
+ for i, idx := range idxs {
+ newCs[i] = cs[idx]
+ }
+ return newCs
+}
diff --git a/vendor/github.com/lucasb-eyer/go-colorful/warm_palettegen.go b/vendor/github.com/lucasb-eyer/go-colorful/warm_palettegen.go
index 00f42a5cc..d294fb415 100644
--- a/vendor/github.com/lucasb-eyer/go-colorful/warm_palettegen.go
+++ b/vendor/github.com/lucasb-eyer/go-colorful/warm_palettegen.go
@@ -1,13 +1,9 @@
package colorful
-import (
- "math/rand"
-)
-
// Uses the HSV color space to generate colors with similar S,V but distributed
// evenly along their Hue. This is fast but not always pretty.
// If you've got time to spare, use Lab (the non-fast below).
-func FastWarmPalette(colorsCount int) (colors []Color) {
+func FastWarmPaletteWithRand(colorsCount int, rand RandInterface) (colors []Color) {
colors = make([]Color, colorsCount)
for i := 0; i < colorsCount; i++ {
@@ -16,10 +12,18 @@ func FastWarmPalette(colorsCount int) (colors []Color) {
return
}
-func WarmPalette(colorsCount int) ([]Color, error) {
+func FastWarmPalette(colorsCount int) (colors []Color) {
+ return FastWarmPaletteWithRand(colorsCount, getDefaultGlobalRand())
+}
+
+func WarmPaletteWithRand(colorsCount int, rand RandInterface) ([]Color, error) {
warmy := func(l, a, b float64) bool {
_, c, _ := LabToHcl(l, a, b)
return 0.1 <= c && c <= 0.4 && 0.2 <= l && l <= 0.5
}
- return SoftPaletteEx(colorsCount, SoftPaletteSettings{warmy, 50, true})
+ return SoftPaletteExWithRand(colorsCount, SoftPaletteSettings{warmy, 50, true}, rand)
+}
+
+func WarmPalette(colorsCount int) ([]Color, error) {
+ return WarmPaletteWithRand(colorsCount, getDefaultGlobalRand())
}
diff --git a/vendor/github.com/lucasb-eyer/go-colorful/widegamut.go b/vendor/github.com/lucasb-eyer/go-colorful/widegamut.go
new file mode 100644
index 000000000..6805a2b96
--- /dev/null
+++ b/vendor/github.com/lucasb-eyer/go-colorful/widegamut.go
@@ -0,0 +1,290 @@
+package colorful
+
+import "math"
+
+// Wide-gamut RGB color spaces from CSS Color Level 4.
+// https://www.w3.org/TR/css-color-4/#color-conversion-code
+
+/// Bradford ///
+////////////////
+// Bradford chromatic adaptation between D50 and D65 illuminants.
+
+func D50ToD65(x, y, z float64) (xo, yo, zo float64) {
+ xo = 0.9555766*x - 0.0230393*y + 0.0631636*z
+ yo = -0.0282895*x + 1.0099416*y + 0.0210077*z
+ zo = 0.0122982*x - 0.0204830*y + 1.3299098*z
+ return
+}
+
+func D65ToD50(x, y, z float64) (xo, yo, zo float64) {
+ xo = 1.0479298208405488*x + 0.022946793341019088*y - 0.05019222954313557*z
+ yo = 0.029627815688159344*x + 0.990434484573249*y - 0.01707382502938514*z
+ zo = -0.009243058152591178*x + 0.015055144896577895*y + 0.7518742899580008*z
+ return
+}
+
+/// XYZ D50 ///
+///////////////
+
+func XyzD50(x, y, z float64) Color {
+ return Xyz(D50ToD65(x, y, z))
+}
+
+func (col Color) XyzD50() (x, y, z float64) {
+ return D65ToD50(col.Xyz())
+}
+
+/// Display P3 ///
+//////////////////
+// Uses the sRGB transfer function with DCI-P3 primaries.
+
+func DisplayP3ToLinearRgb(r, g, b float64) (rl, gl, bl float64) {
+ rl = linearize(r)
+ gl = linearize(g)
+ bl = linearize(b)
+ return
+}
+
+func LinearDisplayP3ToXyz(r, g, b float64) (x, y, z float64) {
+ x = 0.4865709486482162*r + 0.26566769316909306*g + 0.1982172852343625*b
+ y = 0.2289745640697488*r + 0.6917385218365064*g + 0.079286914093745*b
+ z = 0.04511338185890264*g + 1.043944368900976*b
+ return
+}
+
+func XyzToLinearDisplayP3(x, y, z float64) (r, g, b float64) {
+ r = 2.493496911941425*x - 0.9313836179191239*y - 0.40271078445071684*z
+ g = -0.8294889695615747*x + 1.7626640603183463*y + 0.023624685841943577*z
+ b = 0.035845830243784335*x - 0.07617238926804182*y + 0.9568845240076872*z
+ return
+}
+
+func DisplayP3(r, g, b float64) Color {
+ rl, gl, bl := DisplayP3ToLinearRgb(r, g, b)
+ x, y, z := LinearDisplayP3ToXyz(rl, gl, bl)
+ return Xyz(x, y, z)
+}
+
+func (col Color) DisplayP3() (r, g, b float64) {
+ x, y, z := col.Xyz()
+ rl, gl, bl := XyzToLinearDisplayP3(x, y, z)
+ r = delinearize(rl)
+ g = delinearize(gl)
+ b = delinearize(bl)
+ return
+}
+
+// BlendDisplayP3 blends two colors in the Display P3 color-space.
+// t == 0 results in c1, t == 1 results in c2
+func (c1 Color) BlendDisplayP3(c2 Color, t float64) Color {
+ r1, g1, b1 := c1.DisplayP3()
+ r2, g2, b2 := c2.DisplayP3()
+ return DisplayP3(
+ r1+t*(r2-r1),
+ g1+t*(g2-g1),
+ b1+t*(b2-b1))
+}
+
+/// A98 RGB ///
+///////////////
+// Adobe RGB (1998) color space.
+
+func linearizeA98(v float64) float64 {
+ sign := 1.0
+ if v < 0 {
+ sign = -1.0
+ v = -v
+ }
+ return sign * math.Pow(v, 563.0/256.0)
+}
+
+func delinearizeA98(v float64) float64 {
+ sign := 1.0
+ if v < 0 {
+ sign = -1.0
+ v = -v
+ }
+ return sign * math.Pow(v, 256.0/563.0)
+}
+
+func A98RgbToLinearRgb(r, g, b float64) (rl, gl, bl float64) {
+ rl = linearizeA98(r)
+ gl = linearizeA98(g)
+ bl = linearizeA98(b)
+ return
+}
+
+func LinearA98RgbToXyz(r, g, b float64) (x, y, z float64) {
+ x = 0.5766690429101305*r + 0.1855582379065463*g + 0.1882286462349947*b
+ y = 0.29734497525053605*r + 0.6273635662554661*g + 0.07529145849399788*b
+ z = 0.02703136138641234*r + 0.07068885253582723*g + 0.9913375368376388*b
+ return
+}
+
+func XyzToLinearA98Rgb(x, y, z float64) (r, g, b float64) {
+ r = 2.0415879038107327*x - 0.5650069742788597*y - 0.34473135077832956*z
+ g = -0.9692436362808795*x + 1.8759675015077202*y + 0.04155505740717559*z
+ b = 0.013444280632031142*x - 0.11836239223101838*y + 1.0151749943912054*z
+ return
+}
+
+func A98Rgb(r, g, b float64) Color {
+ rl, gl, bl := A98RgbToLinearRgb(r, g, b)
+ x, y, z := LinearA98RgbToXyz(rl, gl, bl)
+ return Xyz(x, y, z)
+}
+
+func (col Color) A98Rgb() (r, g, b float64) {
+ x, y, z := col.Xyz()
+ rl, gl, bl := XyzToLinearA98Rgb(x, y, z)
+ r = delinearizeA98(rl)
+ g = delinearizeA98(gl)
+ b = delinearizeA98(bl)
+ return
+}
+
+// BlendA98Rgb blends two colors in the A98 RGB color-space.
+// t == 0 results in c1, t == 1 results in c2
+func (c1 Color) BlendA98Rgb(c2 Color, t float64) Color {
+ r1, g1, b1 := c1.A98Rgb()
+ r2, g2, b2 := c2.A98Rgb()
+ return A98Rgb(
+ r1+t*(r2-r1),
+ g1+t*(g2-g1),
+ b1+t*(b2-b1))
+}
+
+/// ProPhoto RGB ///
+////////////////////
+// ProPhoto RGB (ROMM RGB) uses D50 illuminant.
+
+func linearizeProPhoto(v float64) float64 {
+ if v <= 16.0/512.0 {
+ return v / 16.0
+ }
+ return math.Pow(v, 1.8)
+}
+
+func delinearizeProPhoto(v float64) float64 {
+ if v < 1.0/512.0 {
+ return 16.0 * v
+ }
+ return math.Pow(v, 1.0/1.8)
+}
+
+func ProPhotoRgbToLinearRgb(r, g, b float64) (rl, gl, bl float64) {
+ rl = linearizeProPhoto(r)
+ gl = linearizeProPhoto(g)
+ bl = linearizeProPhoto(b)
+ return
+}
+
+func LinearProPhotoRgbToXyzD50(r, g, b float64) (x, y, z float64) {
+ x = 0.7977604896723027*r + 0.13518583717574031*g + 0.0313493495815248*b
+ y = 0.2880711282292934*r + 0.7118432178101014*g + 0.00008565396060525902*b
+ z = 0.8251046025104602 * b
+ return
+}
+
+func XyzD50ToLinearProPhotoRgb(x, y, z float64) (r, g, b float64) {
+ r = 1.3457989731028281*x - 0.25558010007997534*y - 0.05110628506753401*z
+ g = -0.5446224939028347*x + 1.5082327413132781*y + 0.02053603239147973*z
+ b = 1.2119675456389454 * z
+ return
+}
+
+func ProPhotoRgb(r, g, b float64) Color {
+ rl, gl, bl := ProPhotoRgbToLinearRgb(r, g, b)
+ x, y, z := LinearProPhotoRgbToXyzD50(rl, gl, bl)
+ return XyzD50(x, y, z)
+}
+
+func (col Color) ProPhotoRgb() (r, g, b float64) {
+ x, y, z := col.XyzD50()
+ rl, gl, bl := XyzD50ToLinearProPhotoRgb(x, y, z)
+ r = delinearizeProPhoto(rl)
+ g = delinearizeProPhoto(gl)
+ b = delinearizeProPhoto(bl)
+ return
+}
+
+// BlendProPhotoRgb blends two colors in the ProPhoto RGB color-space.
+// t == 0 results in c1, t == 1 results in c2
+func (c1 Color) BlendProPhotoRgb(c2 Color, t float64) Color {
+ r1, g1, b1 := c1.ProPhotoRgb()
+ r2, g2, b2 := c2.ProPhotoRgb()
+ return ProPhotoRgb(
+ r1+t*(r2-r1),
+ g1+t*(g2-g1),
+ b1+t*(b2-b1))
+}
+
+/// Rec. 2020 ///
+/////////////////
+// ITU-R BT.2020 color space.
+
+const (
+ rec2020Alpha = 1.09929682680944
+ rec2020Beta = 0.018053968510807
+)
+
+func linearizeRec2020(v float64) float64 {
+ if v < rec2020Beta*4.5 {
+ return v / 4.5
+ }
+ return math.Pow((v+rec2020Alpha-1)/rec2020Alpha, 1.0/0.45)
+}
+
+func delinearizeRec2020(v float64) float64 {
+ if v < rec2020Beta {
+ return 4.5 * v
+ }
+ return rec2020Alpha*math.Pow(v, 0.45) - (rec2020Alpha - 1)
+}
+
+func Rec2020ToLinearRgb(r, g, b float64) (rl, gl, bl float64) {
+ rl = linearizeRec2020(r)
+ gl = linearizeRec2020(g)
+ bl = linearizeRec2020(b)
+ return
+}
+
+func LinearRec2020ToXyz(r, g, b float64) (x, y, z float64) {
+ x = 0.6369580483012914*r + 0.14461690358620832*g + 0.1688809751641721*b
+ y = 0.2627002120112671*r + 0.6779980715188708*g + 0.05930171646986196*b
+ z = 0.028072693049087428*g + 1.0609850577107909*b
+ return
+}
+
+func XyzToLinearRec2020(x, y, z float64) (r, g, b float64) {
+ r = 1.7166511879712674*x - 0.35567078377639233*y - 0.25336628137365974*z
+ g = -0.666684351832489*x + 1.616481236634939*y + 0.0157685458139402*z
+ b = 0.017639857445310783*x - 0.042770613257808524*y + 0.9421031212354738*z
+ return
+}
+
+func Rec2020(r, g, b float64) Color {
+ rl, gl, bl := Rec2020ToLinearRgb(r, g, b)
+ x, y, z := LinearRec2020ToXyz(rl, gl, bl)
+ return Xyz(x, y, z)
+}
+
+func (col Color) Rec2020() (r, g, b float64) {
+ x, y, z := col.Xyz()
+ rl, gl, bl := XyzToLinearRec2020(x, y, z)
+ r = delinearizeRec2020(rl)
+ g = delinearizeRec2020(gl)
+ b = delinearizeRec2020(bl)
+ return
+}
+
+// BlendRec2020 blends two colors in the Rec. 2020 color-space.
+// t == 0 results in c1, t == 1 results in c2
+func (c1 Color) BlendRec2020(c2 Color, t float64) Color {
+ r1, g1, b1 := c1.Rec2020()
+ r2, g2, b2 := c2.Rec2020()
+ return Rec2020(
+ r1+t*(r2-r1),
+ g1+t*(g2-g1),
+ b1+t*(b2-b1))
+}
diff --git a/vendor/github.com/manuelarte/funcorder/analyzer/analyzer.go b/vendor/github.com/manuelarte/funcorder/analyzer/analyzer.go
index c3112107d..1e439175c 100644
--- a/vendor/github.com/manuelarte/funcorder/analyzer/analyzer.go
+++ b/vendor/github.com/manuelarte/funcorder/analyzer/analyzer.go
@@ -14,6 +14,7 @@ const (
ConstructorCheckName = "constructor"
StructMethodCheckName = "struct-method"
AlphabeticalCheckName = "alphabetical"
+ FunctionCheckName = "function"
)
func NewAnalyzer() *analysis.Analyzer {
@@ -33,6 +34,8 @@ func NewAnalyzer() *analysis.Analyzer {
"Checks if the exported methods of a structure are placed before the unexported ones.")
a.Flags.BoolVar(&f.alphabeticalCheck, AlphabeticalCheckName, false,
"Checks if the constructors and/or structure methods are sorted alphabetically.")
+ a.Flags.BoolVar(&f.functionCheck, FunctionCheckName, false,
+ "Checks that exported functions are placed before unexported functions.")
return a
}
@@ -41,9 +44,16 @@ type funcorder struct {
constructorCheck bool
structMethodCheck bool
alphabeticalCheck bool
+ functionCheck bool
}
func (f *funcorder) run(pass *analysis.Pass) (any, error) {
+ insp, found := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector)
+ if !found {
+ //nolint:nilnil // impossible case.
+ return nil, nil
+ }
+
var enabledCheckers internal.Feature
if f.constructorCheck {
enabledCheckers.Enable(internal.ConstructorCheck)
@@ -57,14 +67,12 @@ func (f *funcorder) run(pass *analysis.Pass) (any, error) {
enabledCheckers.Enable(internal.AlphabeticalCheck)
}
- fp := internal.NewFileProcessor(pass.Fset, enabledCheckers)
-
- insp, found := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector)
- if !found {
- //nolint:nilnil // impossible case.
- return nil, nil
+ if f.functionCheck {
+ enabledCheckers.Enable(internal.FunctionCheck)
}
+ fp := internal.NewFileProcessor(enabledCheckers)
+
nodeFilter := []ast.Node{
(*ast.File)(nil),
(*ast.FuncDecl)(nil),
@@ -74,23 +82,18 @@ func (f *funcorder) run(pass *analysis.Pass) (any, error) {
insp.Preorder(nodeFilter, func(n ast.Node) {
switch node := n.(type) {
case *ast.File:
- for _, report := range fp.Analyze() {
- pass.Report(report)
- }
-
- fp.NewFileNode(node)
+ fp.Analyze(pass)
+ fp.ResetStructs()
case *ast.FuncDecl:
- fp.NewFuncDecl(node)
+ fp.AddFuncDecl(node)
case *ast.TypeSpec:
- fp.NewTypeSpec(node)
+ fp.AddTypeSpec(node)
}
})
- for _, report := range fp.Analyze() {
- pass.Report(report)
- }
+ fp.Analyze(pass)
//nolint:nilnil //any, error
return nil, nil
diff --git a/vendor/github.com/manuelarte/funcorder/internal/astutils.go b/vendor/github.com/manuelarte/funcorder/internal/astutils.go
deleted file mode 100644
index af7fa8c81..000000000
--- a/vendor/github.com/manuelarte/funcorder/internal/astutils.go
+++ /dev/null
@@ -1,93 +0,0 @@
-package internal
-
-import (
- "bytes"
- "go/ast"
- "go/format"
- "go/token"
- "strings"
-)
-
-func FuncCanBeConstructor(n *ast.FuncDecl) bool {
- if !n.Name.IsExported() || n.Recv != nil {
- return false
- }
-
- if n.Type.Results == nil || len(n.Type.Results.List) == 0 {
- return false
- }
-
- for _, prefix := range []string{"new", "must"} {
- if strings.HasPrefix(strings.ToLower(n.Name.Name), prefix) &&
- len(n.Name.Name) > len(prefix) { // TODO(ldez): bug if the name is just `New`.
- return true
- }
- }
-
- return false
-}
-
-func FuncIsMethod(n *ast.FuncDecl) (*ast.Ident, bool) {
- if n.Recv == nil {
- return nil, false
- }
-
- if len(n.Recv.List) != 1 {
- return nil, false
- }
-
- if recv, ok := GetIdent(n.Recv.List[0].Type); ok {
- return recv, true
- }
-
- return nil, false
-}
-
-func GetIdent(expr ast.Expr) (*ast.Ident, bool) {
- switch exp := expr.(type) {
- case *ast.StarExpr:
- return GetIdent(exp.X)
-
- case *ast.Ident:
- return exp, true
-
- default:
- return nil, false
- }
-}
-
-// GetStartingPos returns the token starting position of the function
-// taking into account if there are comments.
-func GetStartingPos(function *ast.FuncDecl) token.Pos {
- startingPos := function.Pos()
- if function.Doc != nil {
- startingPos = function.Doc.Pos()
- }
-
- return startingPos
-}
-
-// NodeToBytes convert the ast.Node in bytes.
-func NodeToBytes(fset *token.FileSet, node ast.Node) ([]byte, error) {
- var buf bytes.Buffer
- if err := format.Node(&buf, fset, node); err != nil {
- return nil, err
- }
-
- return buf.Bytes(), nil
-}
-
-// SplitExportedUnexported split functions/methods based on whether they are exported or not.
-//
-//nolint:nonamedreturns // names serve as documentation
-func SplitExportedUnexported(funcDecls []*ast.FuncDecl) (exported, unexported []*ast.FuncDecl) {
- for _, f := range funcDecls {
- if f.Name.IsExported() {
- exported = append(exported, f)
- } else {
- unexported = append(unexported, f)
- }
- }
-
- return exported, unexported
-}
diff --git a/vendor/github.com/manuelarte/funcorder/internal/diag.go b/vendor/github.com/manuelarte/funcorder/internal/diag.go
deleted file mode 100644
index faf2ffdd1..000000000
--- a/vendor/github.com/manuelarte/funcorder/internal/diag.go
+++ /dev/null
@@ -1,69 +0,0 @@
-package internal
-
-import (
- "fmt"
- "go/ast"
-
- "golang.org/x/tools/go/analysis"
-)
-
-func NewConstructorNotAfterStructType(structSpec *ast.TypeSpec, constructor *ast.FuncDecl) analysis.Diagnostic {
- return analysis.Diagnostic{
- Pos: constructor.Pos(),
- Message: fmt.Sprintf("constructor %q for struct %q should be placed after the struct declaration",
- constructor.Name, structSpec.Name),
- URL: "https://github.com/manuelarte/funcorder?tab=readme-ov-file#check-constructors-functions-are-placed-after-struct-declaration", //nolint:lll // url
- }
-}
-
-func NewConstructorNotBeforeStructMethod(
- structSpec *ast.TypeSpec,
- constructor *ast.FuncDecl,
- method *ast.FuncDecl,
-) analysis.Diagnostic {
- return analysis.Diagnostic{
- Pos: constructor.Pos(),
- URL: "https://github.com/manuelarte/funcorder?tab=readme-ov-file#check-constructors-functions-are-placed-after-struct-declaration", //nolint:lll // url
- Message: fmt.Sprintf("constructor %q for struct %q should be placed before struct method %q",
- constructor.Name, structSpec.Name, method.Name),
- }
-}
-
-func NewAdjacentConstructorsNotSortedAlphabetically(
- structSpec *ast.TypeSpec,
- constructorNotSorted *ast.FuncDecl,
- otherConstructorNotSorted *ast.FuncDecl,
-) analysis.Diagnostic {
- return analysis.Diagnostic{
- Pos: otherConstructorNotSorted.Pos(),
- URL: "https://github.com/manuelarte/funcorder?tab=readme-ov-file#check-constructorsmethods-are-sorted-alphabetically",
- Message: fmt.Sprintf("constructor %q for struct %q should be placed before constructor %q",
- otherConstructorNotSorted.Name, structSpec.Name, constructorNotSorted.Name),
- }
-}
-
-func NewUnexportedMethodBeforeExportedForStruct(
- structSpec *ast.TypeSpec,
- privateMethod *ast.FuncDecl,
- publicMethod *ast.FuncDecl,
-) analysis.Diagnostic {
- return analysis.Diagnostic{
- Pos: privateMethod.Pos(),
- URL: "https://github.com/manuelarte/funcorder?tab=readme-ov-file#check-exported-methods-are-placed-before-unexported-methods", //nolint:lll // url
- Message: fmt.Sprintf("unexported method %q for struct %q should be placed after the exported method %q",
- privateMethod.Name, structSpec.Name, publicMethod.Name),
- }
-}
-
-func NewAdjacentStructMethodsNotSortedAlphabetically(
- structSpec *ast.TypeSpec,
- method *ast.FuncDecl,
- otherMethod *ast.FuncDecl,
-) analysis.Diagnostic {
- return analysis.Diagnostic{
- Pos: otherMethod.Pos(),
- URL: "https://github.com/manuelarte/funcorder?tab=readme-ov-file#check-constructorsmethods-are-sorted-alphabetically",
- Message: fmt.Sprintf("method %q for struct %q should be placed before method %q",
- otherMethod.Name, structSpec.Name, method.Name),
- }
-}
diff --git a/vendor/github.com/manuelarte/funcorder/internal/features.go b/vendor/github.com/manuelarte/funcorder/internal/features.go
index 55d5caba3..7012a6880 100644
--- a/vendor/github.com/manuelarte/funcorder/internal/features.go
+++ b/vendor/github.com/manuelarte/funcorder/internal/features.go
@@ -4,6 +4,7 @@ const (
ConstructorCheck Feature = 1 << iota
StructMethodCheck
AlphabeticalCheck
+ FunctionCheck
)
type Feature uint8
diff --git a/vendor/github.com/manuelarte/funcorder/internal/file_processor.go b/vendor/github.com/manuelarte/funcorder/internal/file_processor.go
index 88ae00f2e..9276c4a06 100644
--- a/vendor/github.com/manuelarte/funcorder/internal/file_processor.go
+++ b/vendor/github.com/manuelarte/funcorder/internal/file_processor.go
@@ -2,69 +2,102 @@ package internal
import (
"go/ast"
- "go/token"
"golang.org/x/tools/go/analysis"
)
// FileProcessor Holder to store all the functions that are potential to be constructors and all the structs.
type FileProcessor struct {
- fset *token.FileSet
- structs map[string]*StructHolder
- features Feature
+ structs map[string]*StructHolder
+ features Feature
+ topLevelFuncs []*ast.FuncDecl
}
// NewFileProcessor creates a new file processor.
-func NewFileProcessor(fset *token.FileSet, checkers Feature) *FileProcessor {
+func NewFileProcessor(checkers Feature) *FileProcessor {
return &FileProcessor{
- fset: fset,
structs: make(map[string]*StructHolder),
features: checkers,
}
}
// Analyze check whether the order of the methods in the constructor is correct.
-func (fp *FileProcessor) Analyze() []analysis.Diagnostic {
- var reports []analysis.Diagnostic
-
+func (fp *FileProcessor) Analyze(pass *analysis.Pass) {
for _, sh := range fp.structs {
// filter out structs that are not declared inside that file
if sh.Struct != nil {
- reports = append(reports, sh.Analyze()...)
+ sh.Analyze(pass)
}
}
- return reports
+ if fp.features.IsEnabled(FunctionCheck) {
+ fp.analyzeFunctions(pass)
+ }
}
-func (fp *FileProcessor) NewFileNode(_ *ast.File) {
+func (fp *FileProcessor) ResetStructs() {
fp.structs = make(map[string]*StructHolder)
+ fp.topLevelFuncs = nil
}
-func (fp *FileProcessor) NewFuncDecl(n *ast.FuncDecl) {
- if sc, ok := NewStructConstructor(n); ok {
- fp.addConstructor(sc)
+func (fp *FileProcessor) AddFuncDecl(n *ast.FuncDecl) {
+ if fp.features.IsEnabled(FunctionCheck) && n.Recv == nil {
+ fp.topLevelFuncs = append(fp.topLevelFuncs, n)
+ }
+
+ if sc := NewStructConstructor(n); sc != nil {
+ sh := fp.getOrCreate(sc.StructReturn.Name)
+ sh.Constructors = append(sh.Constructors, sc.Constructor)
+
return
}
- if st, ok := FuncIsMethod(n); ok {
- fp.addMethod(st.Name, n)
+ if st := funcIsMethod(n); st != nil {
+ sh := fp.getOrCreate(st.Name)
+ sh.StructMethods = append(sh.StructMethods, n)
}
}
-func (fp *FileProcessor) NewTypeSpec(n *ast.TypeSpec) {
+func (fp *FileProcessor) AddTypeSpec(n *ast.TypeSpec) {
sh := fp.getOrCreate(n.Name.Name)
sh.Struct = n
}
-func (fp *FileProcessor) addConstructor(sc StructConstructor) {
- sh := fp.getOrCreate(sc.GetStructReturn().Name)
- sh.AddConstructor(sc.GetConstructor())
-}
+// analyzeFunctions reports every unexported top-level function that appears
+// before the last exported top-level function in source order.
+// The `init` function is excluded from this check.
+func (fp *FileProcessor) analyzeFunctions(pass *analysis.Pass) {
+ var lastExported *ast.FuncDecl
+
+ for _, fn := range fp.topLevelFuncs {
+ if fn.Name.Name == "init" {
+ continue
+ }
+
+ if !fn.Name.IsExported() {
+ continue
+ }
+
+ if lastExported == nil || fn.Pos() > lastExported.Pos() {
+ lastExported = fn
+ }
+ }
+
+ if lastExported == nil {
+ return
+ }
-func (fp *FileProcessor) addMethod(st string, n *ast.FuncDecl) {
- sh := fp.getOrCreate(st)
- sh.AddMethod(n)
+ for _, fn := range fp.topLevelFuncs {
+ if fn.Name.Name == "init" {
+ continue
+ }
+
+ if fn.Name.IsExported() || fn.Pos() >= lastExported.Pos() {
+ continue
+ }
+
+ reportUnexportedFuncBeforeExportedFunc(pass, fn, lastExported)
+ }
}
func (fp *FileProcessor) getOrCreate(structName string) *StructHolder {
@@ -73,10 +106,34 @@ func (fp *FileProcessor) getOrCreate(structName string) *StructHolder {
}
created := &StructHolder{
- Fset: fp.fset,
Features: fp.features,
}
fp.structs[structName] = created
return created
}
+
+func funcIsMethod(n *ast.FuncDecl) *ast.Ident {
+ if n.Recv == nil {
+ return nil
+ }
+
+ if len(n.Recv.List) != 1 {
+ return nil
+ }
+
+ return getIdent(n.Recv.List[0].Type)
+}
+
+func getIdent(expr ast.Expr) *ast.Ident {
+ switch exp := expr.(type) {
+ case *ast.StarExpr:
+ return getIdent(exp.X)
+
+ case *ast.Ident:
+ return exp
+
+ default:
+ return nil
+ }
+}
diff --git a/vendor/github.com/manuelarte/funcorder/internal/reports.go b/vendor/github.com/manuelarte/funcorder/internal/reports.go
new file mode 100644
index 000000000..350ac05eb
--- /dev/null
+++ b/vendor/github.com/manuelarte/funcorder/internal/reports.go
@@ -0,0 +1,78 @@
+package internal
+
+import (
+ "fmt"
+ "go/ast"
+
+ "golang.org/x/tools/go/analysis"
+)
+
+func reportConstructorNotAfterStructType(pass *analysis.Pass, structSpec *ast.TypeSpec, constructor *ast.FuncDecl) {
+ pass.Report(analysis.Diagnostic{
+ Pos: constructor.Pos(),
+ Message: fmt.Sprintf("constructor %q for struct %q should be placed after the struct declaration",
+ constructor.Name, structSpec.Name),
+ URL: "https://github.com/manuelarte/funcorder?tab=readme-ov-file#check-constructors-functions-are-placed-after-struct-declaration", //nolint:lll // url
+ })
+}
+
+func reportConstructorNotBeforeStructMethod(
+ pass *analysis.Pass,
+ structSpec *ast.TypeSpec,
+ constructor, method *ast.FuncDecl,
+) {
+ pass.Report(analysis.Diagnostic{
+ Pos: constructor.Pos(),
+ URL: "https://github.com/manuelarte/funcorder?tab=readme-ov-file#check-constructors-functions-are-placed-after-struct-declaration", //nolint:lll // url
+ Message: fmt.Sprintf("constructor %q for struct %q should be placed before struct method %q",
+ constructor.Name, structSpec.Name, method.Name),
+ })
+}
+
+func reportAdjacentConstructorsNotSortedAlphabetically(
+ pass *analysis.Pass,
+ structSpec *ast.TypeSpec,
+ constructorNotSorted, otherConstructorNotSorted *ast.FuncDecl,
+) {
+ pass.Report(analysis.Diagnostic{
+ Pos: otherConstructorNotSorted.Pos(),
+ URL: "https://github.com/manuelarte/funcorder?tab=readme-ov-file#check-constructorsmethods-are-sorted-alphabetically",
+ Message: fmt.Sprintf("constructor %q for struct %q should be placed before constructor %q",
+ otherConstructorNotSorted.Name, structSpec.Name, constructorNotSorted.Name),
+ })
+}
+
+func reportUnexportedMethodBeforeExportedForStruct(
+ pass *analysis.Pass,
+ structSpec *ast.TypeSpec,
+ privateMethod, publicMethod *ast.FuncDecl,
+) {
+ pass.Report(analysis.Diagnostic{
+ Pos: privateMethod.Pos(),
+ URL: "https://github.com/manuelarte/funcorder?tab=readme-ov-file#check-exported-methods-are-placed-before-unexported-methods", //nolint:lll // url
+ Message: fmt.Sprintf("unexported method %q for struct %q should be placed after the exported method %q",
+ privateMethod.Name, structSpec.Name, publicMethod.Name),
+ })
+}
+
+func reportAdjacentStructMethodsNotSortedAlphabetically(
+ pass *analysis.Pass,
+ structSpec *ast.TypeSpec,
+ method, otherMethod *ast.FuncDecl,
+) {
+ pass.Report(analysis.Diagnostic{
+ Pos: otherMethod.Pos(),
+ URL: "https://github.com/manuelarte/funcorder?tab=readme-ov-file#check-constructorsmethods-are-sorted-alphabetically",
+ Message: fmt.Sprintf("method %q for struct %q should be placed before method %q",
+ otherMethod.Name, structSpec.Name, method.Name),
+ })
+}
+
+func reportUnexportedFuncBeforeExportedFunc(pass *analysis.Pass, unexportedFunc, exportedFunc *ast.FuncDecl) {
+ pass.Report(analysis.Diagnostic{
+ Pos: unexportedFunc.Pos(),
+ URL: "https://github.com/manuelarte/funcorder?tab=readme-ov-file#check-exported-functions-are-placed-before-unexported-functions", //nolint:lll // url
+ Message: fmt.Sprintf("unexported function %q should be placed after the exported function %q",
+ unexportedFunc.Name, exportedFunc.Name),
+ })
+}
diff --git a/vendor/github.com/manuelarte/funcorder/internal/struct_constructor.go b/vendor/github.com/manuelarte/funcorder/internal/struct_constructor.go
index fc4b252df..c036fc138 100644
--- a/vendor/github.com/manuelarte/funcorder/internal/struct_constructor.go
+++ b/vendor/github.com/manuelarte/funcorder/internal/struct_constructor.go
@@ -2,36 +2,47 @@ package internal
import (
"go/ast"
+ "strings"
)
type StructConstructor struct {
- constructor *ast.FuncDecl
- structReturn *ast.Ident
+ Constructor *ast.FuncDecl
+ StructReturn *ast.Ident
}
-func NewStructConstructor(funcDec *ast.FuncDecl) (StructConstructor, bool) {
- if !FuncCanBeConstructor(funcDec) {
- return StructConstructor{}, false
+func NewStructConstructor(funcDec *ast.FuncDecl) *StructConstructor {
+ if !funcCanBeConstructor(funcDec) {
+ return nil
}
expr := funcDec.Type.Results.List[0].Type
- returnType, ok := GetIdent(expr)
- if !ok {
- return StructConstructor{}, false
+ returnType := getIdent(expr)
+ if returnType == nil {
+ return nil
}
- return StructConstructor{
- constructor: funcDec,
- structReturn: returnType,
- }, true
+ return &StructConstructor{
+ Constructor: funcDec,
+ StructReturn: returnType,
+ }
}
-// GetStructReturn Return the struct linked to this "constructor".
-func (sc StructConstructor) GetStructReturn() *ast.Ident {
- return sc.structReturn
-}
+func funcCanBeConstructor(n *ast.FuncDecl) bool {
+ if !n.Name.IsExported() || n.Recv != nil {
+ return false
+ }
+
+ if n.Type.Results == nil || len(n.Type.Results.List) == 0 {
+ return false
+ }
+
+ for _, prefix := range []string{"new", "must"} {
+ if strings.HasPrefix(strings.ToLower(n.Name.Name), prefix) &&
+ len(n.Name.Name) > len(prefix) { // TODO(ldez): bug if the name is just `New`.
+ return true
+ }
+ }
-func (sc StructConstructor) GetConstructor() *ast.FuncDecl {
- return sc.constructor
+ return false
}
diff --git a/vendor/github.com/manuelarte/funcorder/internal/structholder.go b/vendor/github.com/manuelarte/funcorder/internal/structholder.go
index 424b2ddd7..300422115 100644
--- a/vendor/github.com/manuelarte/funcorder/internal/structholder.go
+++ b/vendor/github.com/manuelarte/funcorder/internal/structholder.go
@@ -3,21 +3,13 @@ package internal
import (
"cmp"
"go/ast"
- "go/token"
"slices"
"golang.org/x/tools/go/analysis"
)
-type (
- ExportedMethods []*ast.FuncDecl
- UnexportedMethods []*ast.FuncDecl
-)
-
// StructHolder contains all the information around a Go struct.
type StructHolder struct {
- // The fileset
- Fset *token.FileSet
// The features to be analyzed
Features Feature
@@ -31,59 +23,42 @@ type StructHolder struct {
StructMethods []*ast.FuncDecl
}
-func (sh *StructHolder) AddConstructor(fn *ast.FuncDecl) {
- sh.Constructors = append(sh.Constructors, fn)
-}
-
-func (sh *StructHolder) AddMethod(fn *ast.FuncDecl) {
- sh.StructMethods = append(sh.StructMethods, fn)
-}
-
// Analyze applies the linter to the struct holder.
-func (sh *StructHolder) Analyze() []analysis.Diagnostic {
+func (sh *StructHolder) Analyze(pass *analysis.Pass) {
// TODO maybe sort constructors and then report also, like NewXXX before MustXXX
slices.SortFunc(sh.StructMethods, func(a, b *ast.FuncDecl) int {
return cmp.Compare(a.Pos(), b.Pos())
})
- var reports []analysis.Diagnostic
+ // TODO also check that the methods are declared after the struct
if sh.Features.IsEnabled(ConstructorCheck) {
- reports = append(reports, sh.analyzeConstructor()...)
+ sh.analyzeConstructor(pass)
}
if sh.Features.IsEnabled(StructMethodCheck) {
- reports = append(reports, sh.analyzeStructMethod()...)
+ sh.analyzeStructMethod(pass)
}
-
- // TODO also check that the methods are declared after the struct
- return reports
}
-func (sh *StructHolder) analyzeConstructor() []analysis.Diagnostic {
- var reports []analysis.Diagnostic
-
+func (sh *StructHolder) analyzeConstructor(pass *analysis.Pass) {
for i, constructor := range sh.Constructors {
if constructor.Pos() < sh.Struct.Pos() {
- reports = append(reports, NewConstructorNotAfterStructType(sh.Struct, constructor))
+ reportConstructorNotAfterStructType(pass, sh.Struct, constructor)
}
if len(sh.StructMethods) > 0 && constructor.Pos() > sh.StructMethods[0].Pos() {
- reports = append(reports, NewConstructorNotBeforeStructMethod(sh.Struct, constructor, sh.StructMethods[0]))
+ reportConstructorNotBeforeStructMethod(pass, sh.Struct, constructor, sh.StructMethods[0])
}
if sh.Features.IsEnabled(AlphabeticalCheck) &&
i < len(sh.Constructors)-1 && sh.Constructors[i].Name.Name > sh.Constructors[i+1].Name.Name {
- reports = append(reports,
- NewAdjacentConstructorsNotSortedAlphabetically(sh.Struct, sh.Constructors[i], sh.Constructors[i+1]),
- )
+ reportAdjacentConstructorsNotSortedAlphabetically(pass, sh.Struct, sh.Constructors[i], sh.Constructors[i+1])
}
}
-
- return reports
}
-func (sh *StructHolder) analyzeStructMethod() []analysis.Diagnostic {
+func (sh *StructHolder) analyzeStructMethod(pass *analysis.Pass) {
var lastExportedMethod *ast.FuncDecl
for _, m := range sh.StructMethods {
@@ -100,42 +75,46 @@ func (sh *StructHolder) analyzeStructMethod() []analysis.Diagnostic {
}
}
- var reports []analysis.Diagnostic
-
if lastExportedMethod != nil {
for _, m := range sh.StructMethods {
if m.Name.IsExported() || m.Pos() >= lastExportedMethod.Pos() {
continue
}
- reports = append(reports, NewUnexportedMethodBeforeExportedForStruct(sh.Struct, m, lastExportedMethod))
+ reportUnexportedMethodBeforeExportedForStruct(pass, sh.Struct, m, lastExportedMethod)
}
}
if sh.Features.IsEnabled(AlphabeticalCheck) {
- exported, unexported := SplitExportedUnexported(sh.StructMethods)
- reports = slices.Concat(reports,
- sortDiagnostics(sh.Struct, exported),
- sortDiagnostics(sh.Struct, unexported),
- )
+ exported, unexported := splitExportedUnexported(sh.StructMethods)
+ sh.sortDiagnostics(pass, exported)
+ sh.sortDiagnostics(pass, unexported)
}
-
- return reports
}
-func sortDiagnostics(typeSpec *ast.TypeSpec, funcDecls []*ast.FuncDecl) []analysis.Diagnostic {
- var reports []analysis.Diagnostic
-
+func (sh *StructHolder) sortDiagnostics(pass *analysis.Pass, funcDecls []*ast.FuncDecl) {
for i := range funcDecls {
if i >= len(funcDecls)-1 {
continue
}
if funcDecls[i].Name.Name > funcDecls[i+1].Name.Name {
- reports = append(reports,
- NewAdjacentStructMethodsNotSortedAlphabetically(typeSpec, funcDecls[i], funcDecls[i+1]))
+ reportAdjacentStructMethodsNotSortedAlphabetically(pass, sh.Struct, funcDecls[i], funcDecls[i+1])
+ }
+ }
+}
+
+// splitExportedUnexported split functions/methods based on whether they are exported or not.
+//
+//nolint:nonamedreturns // names serve as documentation
+func splitExportedUnexported(funcDecls []*ast.FuncDecl) (exported, unexported []*ast.FuncDecl) {
+ for _, f := range funcDecls {
+ if f.Name.IsExported() {
+ exported = append(exported, f)
+ } else {
+ unexported = append(unexported, f)
}
}
- return reports
+ return exported, unexported
}
diff --git a/vendor/github.com/mattn/go-runewidth/benchstat.txt b/vendor/github.com/mattn/go-runewidth/benchstat.txt
new file mode 100644
index 000000000..a9efdbde3
--- /dev/null
+++ b/vendor/github.com/mattn/go-runewidth/benchstat.txt
@@ -0,0 +1,43 @@
+goos: darwin
+goarch: arm64
+pkg: github.com/mattn/go-runewidth
+cpu: Apple M2
+ │ old.txt │ new.txt │
+ │ sec/op │ sec/op vs base │
+String1WidthAll/regular-8 108.92m ± 0% 35.09m ± 3% -67.78% (p=0.002 n=6)
+String1WidthAll/lut-8 93.97m ± 0% 18.70m ± 0% -80.10% (p=0.002 n=6)
+String1Width768/regular-8 60.62µ ± 1% 11.54µ ± 0% -80.97% (p=0.002 n=6)
+String1Width768/lut-8 60.66µ ± 1% 11.43µ ± 0% -81.16% (p=0.002 n=6)
+String1WidthAllEastAsian/regular-8 115.13m ± 1% 40.79m ± 8% -64.57% (p=0.002 n=6)
+String1WidthAllEastAsian/lut-8 93.65m ± 0% 18.70m ± 2% -80.03% (p=0.002 n=6)
+String1Width768EastAsian/regular-8 75.32µ ± 0% 23.49µ ± 0% -68.82% (p=0.002 n=6)
+String1Width768EastAsian/lut-8 60.76µ ± 0% 11.50µ ± 0% -81.07% (p=0.002 n=6)
+geomean 2.562m 604.5µ -76.41%
+
+ │ old.txt │ new.txt │
+ │ B/op │ B/op vs base │
+String1WidthAll/regular-8 106.3Mi ± 0% 0.0Mi ± 0% -100.00% (p=0.002 n=6)
+String1WidthAll/lut-8 106.3Mi ± 0% 0.0Mi ± 0% -100.00% (p=0.002 n=6)
+String1Width768/regular-8 75.00Ki ± 0% 0.00Ki ± 0% -100.00% (p=0.002 n=6)
+String1Width768/lut-8 75.00Ki ± 0% 0.00Ki ± 0% -100.00% (p=0.002 n=6)
+String1WidthAllEastAsian/regular-8 106.3Mi ± 0% 0.0Mi ± 0% -100.00% (p=0.002 n=6)
+String1WidthAllEastAsian/lut-8 106.3Mi ± 0% 0.0Mi ± 0% -100.00% (p=0.002 n=6)
+String1Width768EastAsian/regular-8 75.00Ki ± 0% 0.00Ki ± 0% -100.00% (p=0.002 n=6)
+String1Width768EastAsian/lut-8 75.00Ki ± 0% 0.00Ki ± 0% -100.00% (p=0.002 n=6)
+geomean 2.790Mi ? ¹ ²
+¹ summaries must be >0 to compute geomean
+² ratios must be >0 to compute geomean
+
+ │ old.txt │ new.txt │
+ │ allocs/op │ allocs/op vs base │
+String1WidthAll/regular-8 3.342M ± 0% 0.000M ± 0% -100.00% (p=0.002 n=6)
+String1WidthAll/lut-8 3.342M ± 0% 0.000M ± 0% -100.00% (p=0.002 n=6)
+String1Width768/regular-8 2.304k ± 0% 0.000k ± 0% -100.00% (p=0.002 n=6)
+String1Width768/lut-8 2.304k ± 0% 0.000k ± 0% -100.00% (p=0.002 n=6)
+String1WidthAllEastAsian/regular-8 3.342M ± 0% 0.000M ± 0% -100.00% (p=0.002 n=6)
+String1WidthAllEastAsian/lut-8 3.342M ± 0% 0.000M ± 0% -100.00% (p=0.002 n=6)
+String1Width768EastAsian/regular-8 2.304k ± 0% 0.000k ± 0% -100.00% (p=0.002 n=6)
+String1Width768EastAsian/lut-8 2.304k ± 0% 0.000k ± 0% -100.00% (p=0.002 n=6)
+geomean 87.75k ? ¹ ²
+¹ summaries must be >0 to compute geomean
+² ratios must be >0 to compute geomean
diff --git a/vendor/github.com/mattn/go-runewidth/new.txt b/vendor/github.com/mattn/go-runewidth/new.txt
new file mode 100644
index 000000000..889071256
--- /dev/null
+++ b/vendor/github.com/mattn/go-runewidth/new.txt
@@ -0,0 +1,54 @@
+goos: darwin
+goarch: arm64
+pkg: github.com/mattn/go-runewidth
+cpu: Apple M2
+BenchmarkString1WidthAll/regular-8 33 35033923 ns/op 0 B/op 0 allocs/op
+BenchmarkString1WidthAll/regular-8 33 34965112 ns/op 0 B/op 0 allocs/op
+BenchmarkString1WidthAll/regular-8 33 36307234 ns/op 0 B/op 0 allocs/op
+BenchmarkString1WidthAll/regular-8 33 35007705 ns/op 0 B/op 0 allocs/op
+BenchmarkString1WidthAll/regular-8 33 35154182 ns/op 0 B/op 0 allocs/op
+BenchmarkString1WidthAll/regular-8 34 35155400 ns/op 0 B/op 0 allocs/op
+BenchmarkString1WidthAll/lut-8 63 18688500 ns/op 0 B/op 0 allocs/op
+BenchmarkString1WidthAll/lut-8 63 18712474 ns/op 0 B/op 0 allocs/op
+BenchmarkString1WidthAll/lut-8 63 18700211 ns/op 0 B/op 0 allocs/op
+BenchmarkString1WidthAll/lut-8 62 18694179 ns/op 0 B/op 0 allocs/op
+BenchmarkString1WidthAll/lut-8 62 18708392 ns/op 0 B/op 0 allocs/op
+BenchmarkString1WidthAll/lut-8 63 18770608 ns/op 0 B/op 0 allocs/op
+BenchmarkString1Width768/regular-8 104137 11526 ns/op 0 B/op 0 allocs/op
+BenchmarkString1Width768/regular-8 103986 11540 ns/op 0 B/op 0 allocs/op
+BenchmarkString1Width768/regular-8 104079 11552 ns/op 0 B/op 0 allocs/op
+BenchmarkString1Width768/regular-8 103963 11530 ns/op 0 B/op 0 allocs/op
+BenchmarkString1Width768/regular-8 103714 11538 ns/op 0 B/op 0 allocs/op
+BenchmarkString1Width768/regular-8 104181 11537 ns/op 0 B/op 0 allocs/op
+BenchmarkString1Width768/lut-8 105150 11420 ns/op 0 B/op 0 allocs/op
+BenchmarkString1Width768/lut-8 104778 11423 ns/op 0 B/op 0 allocs/op
+BenchmarkString1Width768/lut-8 105069 11422 ns/op 0 B/op 0 allocs/op
+BenchmarkString1Width768/lut-8 105127 11475 ns/op 0 B/op 0 allocs/op
+BenchmarkString1Width768/lut-8 104742 11433 ns/op 0 B/op 0 allocs/op
+BenchmarkString1Width768/lut-8 105163 11432 ns/op 0 B/op 0 allocs/op
+BenchmarkString1WidthAllEastAsian/regular-8 28 40723347 ns/op 0 B/op 0 allocs/op
+BenchmarkString1WidthAllEastAsian/regular-8 28 40790299 ns/op 0 B/op 0 allocs/op
+BenchmarkString1WidthAllEastAsian/regular-8 28 40801338 ns/op 0 B/op 0 allocs/op
+BenchmarkString1WidthAllEastAsian/regular-8 28 40798216 ns/op 0 B/op 0 allocs/op
+BenchmarkString1WidthAllEastAsian/regular-8 28 44135253 ns/op 0 B/op 0 allocs/op
+BenchmarkString1WidthAllEastAsian/regular-8 28 40779546 ns/op 0 B/op 0 allocs/op
+BenchmarkString1WidthAllEastAsian/lut-8 62 18694165 ns/op 0 B/op 0 allocs/op
+BenchmarkString1WidthAllEastAsian/lut-8 62 18685047 ns/op 0 B/op 0 allocs/op
+BenchmarkString1WidthAllEastAsian/lut-8 62 18689273 ns/op 0 B/op 0 allocs/op
+BenchmarkString1WidthAllEastAsian/lut-8 62 19150346 ns/op 0 B/op 0 allocs/op
+BenchmarkString1WidthAllEastAsian/lut-8 63 19126154 ns/op 0 B/op 0 allocs/op
+BenchmarkString1WidthAllEastAsian/lut-8 62 18712619 ns/op 0 B/op 0 allocs/op
+BenchmarkString1Width768EastAsian/regular-8 50775 23595 ns/op 0 B/op 0 allocs/op
+BenchmarkString1Width768EastAsian/regular-8 51061 23563 ns/op 0 B/op 0 allocs/op
+BenchmarkString1Width768EastAsian/regular-8 51057 23492 ns/op 0 B/op 0 allocs/op
+BenchmarkString1Width768EastAsian/regular-8 51138 23445 ns/op 0 B/op 0 allocs/op
+BenchmarkString1Width768EastAsian/regular-8 51195 23469 ns/op 0 B/op 0 allocs/op
+BenchmarkString1Width768EastAsian/regular-8 51087 23482 ns/op 0 B/op 0 allocs/op
+BenchmarkString1Width768EastAsian/lut-8 104559 11549 ns/op 0 B/op 0 allocs/op
+BenchmarkString1Width768EastAsian/lut-8 104508 11483 ns/op 0 B/op 0 allocs/op
+BenchmarkString1Width768EastAsian/lut-8 104296 11503 ns/op 0 B/op 0 allocs/op
+BenchmarkString1Width768EastAsian/lut-8 104606 11485 ns/op 0 B/op 0 allocs/op
+BenchmarkString1Width768EastAsian/lut-8 104588 11495 ns/op 0 B/op 0 allocs/op
+BenchmarkString1Width768EastAsian/lut-8 104602 11518 ns/op 0 B/op 0 allocs/op
+PASS
+ok github.com/mattn/go-runewidth 64.455s
diff --git a/vendor/github.com/mattn/go-runewidth/old.txt b/vendor/github.com/mattn/go-runewidth/old.txt
new file mode 100644
index 000000000..5b9ac1646
--- /dev/null
+++ b/vendor/github.com/mattn/go-runewidth/old.txt
@@ -0,0 +1,54 @@
+goos: darwin
+goarch: arm64
+pkg: github.com/mattn/go-runewidth
+cpu: Apple M2
+BenchmarkString1WidthAll/regular-8 10 108559258 ns/op 111412145 B/op 3342342 allocs/op
+BenchmarkString1WidthAll/regular-8 10 108968079 ns/op 111412364 B/op 3342343 allocs/op
+BenchmarkString1WidthAll/regular-8 10 108890338 ns/op 111412388 B/op 3342344 allocs/op
+BenchmarkString1WidthAll/regular-8 10 108940704 ns/op 111412584 B/op 3342346 allocs/op
+BenchmarkString1WidthAll/regular-8 10 108632796 ns/op 111412348 B/op 3342343 allocs/op
+BenchmarkString1WidthAll/regular-8 10 109354546 ns/op 111412777 B/op 3342343 allocs/op
+BenchmarkString1WidthAll/lut-8 12 93844406 ns/op 111412569 B/op 3342345 allocs/op
+BenchmarkString1WidthAll/lut-8 12 93991080 ns/op 111412512 B/op 3342344 allocs/op
+BenchmarkString1WidthAll/lut-8 12 93980632 ns/op 111412413 B/op 3342343 allocs/op
+BenchmarkString1WidthAll/lut-8 12 94004083 ns/op 111412396 B/op 3342343 allocs/op
+BenchmarkString1WidthAll/lut-8 12 93959795 ns/op 111412445 B/op 3342343 allocs/op
+BenchmarkString1WidthAll/lut-8 12 93846198 ns/op 111412556 B/op 3342345 allocs/op
+BenchmarkString1Width768/regular-8 19785 60696 ns/op 76801 B/op 2304 allocs/op
+BenchmarkString1Width768/regular-8 19824 60520 ns/op 76801 B/op 2304 allocs/op
+BenchmarkString1Width768/regular-8 19832 60547 ns/op 76801 B/op 2304 allocs/op
+BenchmarkString1Width768/regular-8 19778 60543 ns/op 76800 B/op 2304 allocs/op
+BenchmarkString1Width768/regular-8 19842 61142 ns/op 76801 B/op 2304 allocs/op
+BenchmarkString1Width768/regular-8 19780 60696 ns/op 76801 B/op 2304 allocs/op
+BenchmarkString1Width768/lut-8 19598 61161 ns/op 76801 B/op 2304 allocs/op
+BenchmarkString1Width768/lut-8 19731 60707 ns/op 76801 B/op 2304 allocs/op
+BenchmarkString1Width768/lut-8 19738 60626 ns/op 76801 B/op 2304 allocs/op
+BenchmarkString1Width768/lut-8 19764 60670 ns/op 76801 B/op 2304 allocs/op
+BenchmarkString1Width768/lut-8 19797 60642 ns/op 76801 B/op 2304 allocs/op
+BenchmarkString1Width768/lut-8 19738 60608 ns/op 76800 B/op 2304 allocs/op
+BenchmarkString1WidthAllEastAsian/regular-8 9 115080431 ns/op 111412458 B/op 3342345 allocs/op
+BenchmarkString1WidthAllEastAsian/regular-8 9 114908880 ns/op 111412476 B/op 3342345 allocs/op
+BenchmarkString1WidthAllEastAsian/regular-8 9 115077134 ns/op 111412540 B/op 3342345 allocs/op
+BenchmarkString1WidthAllEastAsian/regular-8 9 115175292 ns/op 111412467 B/op 3342345 allocs/op
+BenchmarkString1WidthAllEastAsian/regular-8 9 115792653 ns/op 111412362 B/op 3342344 allocs/op
+BenchmarkString1WidthAllEastAsian/regular-8 9 115255417 ns/op 111412572 B/op 3342346 allocs/op
+BenchmarkString1WidthAllEastAsian/lut-8 12 93761542 ns/op 111412538 B/op 3342345 allocs/op
+BenchmarkString1WidthAllEastAsian/lut-8 12 94089990 ns/op 111412440 B/op 3342343 allocs/op
+BenchmarkString1WidthAllEastAsian/lut-8 12 93721410 ns/op 111412514 B/op 3342344 allocs/op
+BenchmarkString1WidthAllEastAsian/lut-8 12 93572951 ns/op 111412329 B/op 3342342 allocs/op
+BenchmarkString1WidthAllEastAsian/lut-8 12 93536052 ns/op 111412206 B/op 3342341 allocs/op
+BenchmarkString1WidthAllEastAsian/lut-8 12 93532365 ns/op 111412412 B/op 3342343 allocs/op
+BenchmarkString1Width768EastAsian/regular-8 15904 75401 ns/op 76800 B/op 2304 allocs/op
+BenchmarkString1Width768EastAsian/regular-8 15932 75449 ns/op 76801 B/op 2304 allocs/op
+BenchmarkString1Width768EastAsian/regular-8 15944 75181 ns/op 76801 B/op 2304 allocs/op
+BenchmarkString1Width768EastAsian/regular-8 15963 75311 ns/op 76801 B/op 2304 allocs/op
+BenchmarkString1Width768EastAsian/regular-8 15879 75292 ns/op 76801 B/op 2304 allocs/op
+BenchmarkString1Width768EastAsian/regular-8 15955 75334 ns/op 76801 B/op 2304 allocs/op
+BenchmarkString1Width768EastAsian/lut-8 19692 60692 ns/op 76801 B/op 2304 allocs/op
+BenchmarkString1Width768EastAsian/lut-8 19712 60699 ns/op 76801 B/op 2304 allocs/op
+BenchmarkString1Width768EastAsian/lut-8 19741 60819 ns/op 76801 B/op 2304 allocs/op
+BenchmarkString1Width768EastAsian/lut-8 19771 60653 ns/op 76801 B/op 2304 allocs/op
+BenchmarkString1Width768EastAsian/lut-8 19737 61027 ns/op 76801 B/op 2304 allocs/op
+BenchmarkString1Width768EastAsian/lut-8 19657 60820 ns/op 76801 B/op 2304 allocs/op
+PASS
+ok github.com/mattn/go-runewidth 76.165s
diff --git a/vendor/github.com/mattn/go-runewidth/runewidth.go b/vendor/github.com/mattn/go-runewidth/runewidth.go
index 7dfbb3be9..f6c005822 100644
--- a/vendor/github.com/mattn/go-runewidth/runewidth.go
+++ b/vendor/github.com/mattn/go-runewidth/runewidth.go
@@ -3,8 +3,9 @@ package runewidth
import (
"os"
"strings"
+ "unicode/utf8"
- "github.com/rivo/uniseg"
+ "github.com/clipperhouse/uax29/v2/graphemes"
)
//go:generate go run script/generate.go
@@ -23,10 +24,48 @@ var (
}
)
+var (
+ zerowidth table // combining + nonprint merged for faster zero-width lookup
+ widewidth table // ambiguous + doublewidth merged for EA path
+)
+
func init() {
+ zerowidth = mergeIntervals(combining, nonprint)
+ widewidth = mergeIntervals(ambiguous, doublewidth)
handleEnv()
}
+func mergeIntervals(t1, t2 table) table {
+ merged := make(table, 0, len(t1)+len(t2))
+ i, j := 0, 0
+ for i < len(t1) && j < len(t2) {
+ if t1[i].first <= t2[j].first {
+ merged = append(merged, t1[i])
+ i++
+ } else {
+ merged = append(merged, t2[j])
+ j++
+ }
+ }
+ merged = append(merged, t1[i:]...)
+ merged = append(merged, t2[j:]...)
+ if len(merged) == 0 {
+ return merged
+ }
+ result := merged[:1]
+ for _, iv := range merged[1:] {
+ last := &result[len(result)-1]
+ if iv.first <= last.last+1 {
+ if iv.last > last.last {
+ last.last = iv.last
+ }
+ } else {
+ result = append(result, iv)
+ }
+ }
+ return result
+}
+
func handleEnv() {
env := os.Getenv("RUNEWIDTH_EASTASIAN")
if env == "" {
@@ -51,19 +90,13 @@ type interval struct {
type table []interval
-func inTables(r rune, ts ...table) bool {
- for _, t := range ts {
- if inTable(r, t) {
- return true
- }
- }
- return false
-}
-
func inTable(r rune, t table) bool {
if r < t[0].first {
return false
}
+ if r > t[len(t)-1].last {
+ return false
+ }
bot := 0
top := len(t) - 1
@@ -127,9 +160,7 @@ func (c *Condition) RuneWidth(r rune) int {
return 0
case r < 0x300:
return 1
- case inTable(r, narrow):
- return 1
- case inTables(r, nonprint, combining):
+ case inTable(r, zerowidth):
return 0
case inTable(r, doublewidth):
return 2
@@ -138,13 +169,13 @@ func (c *Condition) RuneWidth(r rune) int {
}
} else {
switch {
- case inTables(r, nonprint, combining):
+ case inTable(r, zerowidth):
return 0
case inTable(r, narrow):
return 1
- case inTables(r, ambiguous, doublewidth):
+ case inTable(r, widewidth):
return 2
- case !c.StrictEmojiNeutral && inTables(r, ambiguous, emoji, narrow):
+ case !c.StrictEmojiNeutral && inTable(r, emoji):
return 2
default:
return 1
@@ -175,10 +206,26 @@ func (c *Condition) CreateLUT() {
// StringWidth return width as you can see
func (c *Condition) StringWidth(s string) (width int) {
- g := uniseg.NewGraphemes(s)
+ if len(s) > 0 && len(s) <= utf8.UTFMax {
+ r, size := utf8.DecodeRuneInString(s)
+ if size == len(s) {
+ return c.RuneWidth(r)
+ }
+ }
+ // ASCII fast path: no grapheme clustering needed for pure ASCII
+ if isAllASCII(s) {
+ for i := 0; i < len(s); i++ {
+ b := s[i]
+ if b >= 0x20 && b != 0x7F {
+ width++
+ }
+ }
+ return
+ }
+ g := graphemes.FromString(s)
for g.Next() {
var chWidth int
- for _, r := range g.Runes() {
+ for _, r := range g.Value() {
chWidth = c.RuneWidth(r)
if chWidth > 0 {
break // Our best guess at this point is to use the width of the first non-zero-width rune.
@@ -189,6 +236,15 @@ func (c *Condition) StringWidth(s string) (width int) {
return
}
+func isAllASCII(s string) bool {
+ for i := 0; i < len(s); i++ {
+ if s[i] >= 0x80 {
+ return false
+ }
+ }
+ return true
+}
+
// Truncate return string truncated with w cells
func (c *Condition) Truncate(s string, w int, tail string) string {
if c.StringWidth(s) <= w {
@@ -197,17 +253,17 @@ func (c *Condition) Truncate(s string, w int, tail string) string {
w -= c.StringWidth(tail)
var width int
pos := len(s)
- g := uniseg.NewGraphemes(s)
+ g := graphemes.FromString(s)
for g.Next() {
var chWidth int
- for _, r := range g.Runes() {
+ for _, r := range g.Value() {
chWidth = c.RuneWidth(r)
if chWidth > 0 {
break // See StringWidth() for details.
}
}
if width+chWidth > w {
- pos, _ = g.Positions()
+ pos = g.Start()
break
}
width += chWidth
@@ -224,10 +280,10 @@ func (c *Condition) TruncateLeft(s string, w int, prefix string) string {
var width int
pos := len(s)
- g := uniseg.NewGraphemes(s)
+ g := graphemes.FromString(s)
for g.Next() {
var chWidth int
- for _, r := range g.Runes() {
+ for _, r := range g.Value() {
chWidth = c.RuneWidth(r)
if chWidth > 0 {
break // See StringWidth() for details.
@@ -236,10 +292,10 @@ func (c *Condition) TruncateLeft(s string, w int, prefix string) string {
if width+chWidth > w {
if width < w {
- _, pos = g.Positions()
+ pos = g.End()
prefix += strings.Repeat(" ", width+chWidth-w)
} else {
- pos, _ = g.Positions()
+ pos = g.Start()
}
break
@@ -254,24 +310,25 @@ func (c *Condition) TruncateLeft(s string, w int, prefix string) string {
// Wrap return string wrapped with w cells
func (c *Condition) Wrap(s string, w int) string {
width := 0
- out := ""
+ var out strings.Builder
+ out.Grow(len(s) + len(s)/w + 1)
for _, r := range s {
cw := c.RuneWidth(r)
if r == '\n' {
- out += string(r)
+ out.WriteRune(r)
width = 0
continue
} else if width+cw > w {
- out += "\n"
+ out.WriteByte('\n')
width = 0
- out += string(r)
+ out.WriteRune(r)
width += cw
continue
}
- out += string(r)
+ out.WriteRune(r)
width += cw
}
- return out
+ return out.String()
}
// FillLeft return string filled in left by spaces in w cells
@@ -310,7 +367,12 @@ func RuneWidth(r rune) int {
// IsAmbiguousWidth returns whether is ambiguous width or not.
func IsAmbiguousWidth(r rune) bool {
- return inTables(r, private, ambiguous)
+ return inTable(r, private) || inTable(r, ambiguous)
+}
+
+// IsCombiningWidth returns whether is combining width or not.
+func IsCombiningWidth(r rune) bool {
+ return inTable(r, combining)
}
// IsNeutralWidth returns whether is neutral width or not.
diff --git a/vendor/github.com/mattn/go-runewidth/runewidth_table.go b/vendor/github.com/mattn/go-runewidth/runewidth_table.go
index ad025ad52..cdd003e64 100644
--- a/vendor/github.com/mattn/go-runewidth/runewidth_table.go
+++ b/vendor/github.com/mattn/go-runewidth/runewidth_table.go
@@ -5,47 +5,50 @@ package runewidth
var combining = table{
{0x0300, 0x036F}, {0x0483, 0x0489}, {0x07EB, 0x07F3},
{0x0C00, 0x0C00}, {0x0C04, 0x0C04}, {0x0CF3, 0x0CF3},
- {0x0D00, 0x0D01}, {0x135D, 0x135F}, {0x1A7F, 0x1A7F},
- {0x1AB0, 0x1ACE}, {0x1B6B, 0x1B73}, {0x1DC0, 0x1DFF},
+ {0x0D00, 0x0D01}, {0x135D, 0x135F}, {0x180B, 0x180D},
+ {0x180F, 0x180F}, {0x1A7F, 0x1A7F}, {0x1AB0, 0x1ADD},
+ {0x1AE0, 0x1AEB}, {0x1B6B, 0x1B73}, {0x1DC0, 0x1DFF},
{0x20D0, 0x20F0}, {0x2CEF, 0x2CF1}, {0x2DE0, 0x2DFF},
{0x3099, 0x309A}, {0xA66F, 0xA672}, {0xA674, 0xA67D},
{0xA69E, 0xA69F}, {0xA6F0, 0xA6F1}, {0xA8E0, 0xA8F1},
- {0xFE20, 0xFE2F}, {0x101FD, 0x101FD}, {0x10376, 0x1037A},
- {0x10EAB, 0x10EAC}, {0x10F46, 0x10F50}, {0x10F82, 0x10F85},
- {0x11300, 0x11301}, {0x1133B, 0x1133C}, {0x11366, 0x1136C},
- {0x11370, 0x11374}, {0x16AF0, 0x16AF4}, {0x1CF00, 0x1CF2D},
- {0x1CF30, 0x1CF46}, {0x1D165, 0x1D169}, {0x1D16D, 0x1D172},
- {0x1D17B, 0x1D182}, {0x1D185, 0x1D18B}, {0x1D1AA, 0x1D1AD},
- {0x1D242, 0x1D244}, {0x1E000, 0x1E006}, {0x1E008, 0x1E018},
- {0x1E01B, 0x1E021}, {0x1E023, 0x1E024}, {0x1E026, 0x1E02A},
- {0x1E08F, 0x1E08F}, {0x1E8D0, 0x1E8D6},
+ {0xFE00, 0xFE0F}, {0xFE20, 0xFE2F}, {0x101FD, 0x101FD},
+ {0x10376, 0x1037A}, {0x10EAB, 0x10EAC}, {0x10F46, 0x10F50},
+ {0x10F82, 0x10F85}, {0x11300, 0x11301}, {0x1133B, 0x1133C},
+ {0x11366, 0x1136C}, {0x11370, 0x11374}, {0x16AF0, 0x16AF4},
+ {0x1CF00, 0x1CF2D}, {0x1CF30, 0x1CF46}, {0x1D165, 0x1D169},
+ {0x1D16D, 0x1D172}, {0x1D17B, 0x1D182}, {0x1D185, 0x1D18B},
+ {0x1D1AA, 0x1D1AD}, {0x1D242, 0x1D244}, {0x1E000, 0x1E006},
+ {0x1E008, 0x1E018}, {0x1E01B, 0x1E021}, {0x1E023, 0x1E024},
+ {0x1E026, 0x1E02A}, {0x1E08F, 0x1E08F}, {0x1E8D0, 0x1E8D6},
+ {0xE0100, 0xE01EF},
}
var doublewidth = table{
{0x1100, 0x115F}, {0x231A, 0x231B}, {0x2329, 0x232A},
{0x23E9, 0x23EC}, {0x23F0, 0x23F0}, {0x23F3, 0x23F3},
- {0x25FD, 0x25FE}, {0x2614, 0x2615}, {0x2648, 0x2653},
- {0x267F, 0x267F}, {0x2693, 0x2693}, {0x26A1, 0x26A1},
- {0x26AA, 0x26AB}, {0x26BD, 0x26BE}, {0x26C4, 0x26C5},
- {0x26CE, 0x26CE}, {0x26D4, 0x26D4}, {0x26EA, 0x26EA},
- {0x26F2, 0x26F3}, {0x26F5, 0x26F5}, {0x26FA, 0x26FA},
- {0x26FD, 0x26FD}, {0x2705, 0x2705}, {0x270A, 0x270B},
- {0x2728, 0x2728}, {0x274C, 0x274C}, {0x274E, 0x274E},
- {0x2753, 0x2755}, {0x2757, 0x2757}, {0x2795, 0x2797},
- {0x27B0, 0x27B0}, {0x27BF, 0x27BF}, {0x2B1B, 0x2B1C},
- {0x2B50, 0x2B50}, {0x2B55, 0x2B55}, {0x2E80, 0x2E99},
- {0x2E9B, 0x2EF3}, {0x2F00, 0x2FD5}, {0x2FF0, 0x303E},
- {0x3041, 0x3096}, {0x3099, 0x30FF}, {0x3105, 0x312F},
- {0x3131, 0x318E}, {0x3190, 0x31E3}, {0x31EF, 0x321E},
- {0x3220, 0x3247}, {0x3250, 0x4DBF}, {0x4E00, 0xA48C},
- {0xA490, 0xA4C6}, {0xA960, 0xA97C}, {0xAC00, 0xD7A3},
- {0xF900, 0xFAFF}, {0xFE10, 0xFE19}, {0xFE30, 0xFE52},
- {0xFE54, 0xFE66}, {0xFE68, 0xFE6B}, {0xFF01, 0xFF60},
- {0xFFE0, 0xFFE6}, {0x16FE0, 0x16FE4}, {0x16FF0, 0x16FF1},
- {0x17000, 0x187F7}, {0x18800, 0x18CD5}, {0x18D00, 0x18D08},
- {0x1AFF0, 0x1AFF3}, {0x1AFF5, 0x1AFFB}, {0x1AFFD, 0x1AFFE},
- {0x1B000, 0x1B122}, {0x1B132, 0x1B132}, {0x1B150, 0x1B152},
- {0x1B155, 0x1B155}, {0x1B164, 0x1B167}, {0x1B170, 0x1B2FB},
+ {0x25FD, 0x25FE}, {0x2614, 0x2615}, {0x2630, 0x2637},
+ {0x2648, 0x2653}, {0x267F, 0x267F}, {0x268A, 0x268F},
+ {0x2693, 0x2693}, {0x26A1, 0x26A1}, {0x26AA, 0x26AB},
+ {0x26BD, 0x26BE}, {0x26C4, 0x26C5}, {0x26CE, 0x26CE},
+ {0x26D4, 0x26D4}, {0x26EA, 0x26EA}, {0x26F2, 0x26F3},
+ {0x26F5, 0x26F5}, {0x26FA, 0x26FA}, {0x26FD, 0x26FD},
+ {0x2705, 0x2705}, {0x270A, 0x270B}, {0x2728, 0x2728},
+ {0x274C, 0x274C}, {0x274E, 0x274E}, {0x2753, 0x2755},
+ {0x2757, 0x2757}, {0x2795, 0x2797}, {0x27B0, 0x27B0},
+ {0x27BF, 0x27BF}, {0x2B1B, 0x2B1C}, {0x2B50, 0x2B50},
+ {0x2B55, 0x2B55}, {0x2E80, 0x2E99}, {0x2E9B, 0x2EF3},
+ {0x2F00, 0x2FD5}, {0x2FF0, 0x303E}, {0x3041, 0x3096},
+ {0x3099, 0x30FF}, {0x3105, 0x312F}, {0x3131, 0x318E},
+ {0x3190, 0x31E5}, {0x31EF, 0x321E}, {0x3220, 0x3247},
+ {0x3250, 0xA48C}, {0xA490, 0xA4C6}, {0xA960, 0xA97C},
+ {0xAC00, 0xD7A3}, {0xF900, 0xFAFF}, {0xFE10, 0xFE19},
+ {0xFE30, 0xFE52}, {0xFE54, 0xFE66}, {0xFE68, 0xFE6B},
+ {0xFF01, 0xFF60}, {0xFFE0, 0xFFE6}, {0x16FE0, 0x16FE4},
+ {0x16FF0, 0x16FF6}, {0x17000, 0x18CD5}, {0x18CFF, 0x18D1E},
+ {0x18D80, 0x18DF2}, {0x1AFF0, 0x1AFF3}, {0x1AFF5, 0x1AFFB},
+ {0x1AFFD, 0x1AFFE}, {0x1B000, 0x1B122}, {0x1B132, 0x1B132},
+ {0x1B150, 0x1B152}, {0x1B155, 0x1B155}, {0x1B164, 0x1B167},
+ {0x1B170, 0x1B2FB}, {0x1D300, 0x1D356}, {0x1D360, 0x1D376},
{0x1F004, 0x1F004}, {0x1F0CF, 0x1F0CF}, {0x1F18E, 0x1F18E},
{0x1F191, 0x1F19A}, {0x1F200, 0x1F202}, {0x1F210, 0x1F23B},
{0x1F240, 0x1F248}, {0x1F250, 0x1F251}, {0x1F260, 0x1F265},
@@ -56,12 +59,12 @@ var doublewidth = table{
{0x1F54B, 0x1F54E}, {0x1F550, 0x1F567}, {0x1F57A, 0x1F57A},
{0x1F595, 0x1F596}, {0x1F5A4, 0x1F5A4}, {0x1F5FB, 0x1F64F},
{0x1F680, 0x1F6C5}, {0x1F6CC, 0x1F6CC}, {0x1F6D0, 0x1F6D2},
- {0x1F6D5, 0x1F6D7}, {0x1F6DC, 0x1F6DF}, {0x1F6EB, 0x1F6EC},
+ {0x1F6D5, 0x1F6D8}, {0x1F6DC, 0x1F6DF}, {0x1F6EB, 0x1F6EC},
{0x1F6F4, 0x1F6FC}, {0x1F7E0, 0x1F7EB}, {0x1F7F0, 0x1F7F0},
{0x1F90C, 0x1F93A}, {0x1F93C, 0x1F945}, {0x1F947, 0x1F9FF},
- {0x1FA70, 0x1FA7C}, {0x1FA80, 0x1FA88}, {0x1FA90, 0x1FABD},
- {0x1FABF, 0x1FAC5}, {0x1FACE, 0x1FADB}, {0x1FAE0, 0x1FAE8},
- {0x1FAF0, 0x1FAF8}, {0x20000, 0x2FFFD}, {0x30000, 0x3FFFD},
+ {0x1FA70, 0x1FA7C}, {0x1FA80, 0x1FA8A}, {0x1FA8E, 0x1FAC6},
+ {0x1FAC8, 0x1FAC8}, {0x1FACD, 0x1FADC}, {0x1FADF, 0x1FAEA},
+ {0x1FAEF, 0x1FAF8}, {0x20000, 0x2FFFD}, {0x30000, 0x3FFFD},
}
var ambiguous = table{
@@ -121,10 +124,9 @@ var ambiguous = table{
{0x26F4, 0x26F4}, {0x26F6, 0x26F9}, {0x26FB, 0x26FC},
{0x26FE, 0x26FF}, {0x273D, 0x273D}, {0x2776, 0x277F},
{0x2B56, 0x2B59}, {0x3248, 0x324F}, {0xE000, 0xF8FF},
- {0xFE00, 0xFE0F}, {0xFFFD, 0xFFFD}, {0x1F100, 0x1F10A},
- {0x1F110, 0x1F12D}, {0x1F130, 0x1F169}, {0x1F170, 0x1F18D},
- {0x1F18F, 0x1F190}, {0x1F19B, 0x1F1AC}, {0xE0100, 0xE01EF},
- {0xF0000, 0xFFFFD}, {0x100000, 0x10FFFD},
+ {0xFFFD, 0xFFFD}, {0x1F100, 0x1F10A}, {0x1F110, 0x1F12D},
+ {0x1F130, 0x1F169}, {0x1F170, 0x1F18D}, {0x1F18F, 0x1F190},
+ {0x1F19B, 0x1F1AC}, {0xF0000, 0xFFFFD}, {0x100000, 0x10FFFD},
}
var narrow = table{
{0x0020, 0x007E}, {0x00A2, 0x00A3}, {0x00A5, 0x00A6},
@@ -159,115 +161,116 @@ var neutral = table{
{0x0600, 0x070D}, {0x070F, 0x074A}, {0x074D, 0x07B1},
{0x07C0, 0x07FA}, {0x07FD, 0x082D}, {0x0830, 0x083E},
{0x0840, 0x085B}, {0x085E, 0x085E}, {0x0860, 0x086A},
- {0x0870, 0x088E}, {0x0890, 0x0891}, {0x0898, 0x0983},
- {0x0985, 0x098C}, {0x098F, 0x0990}, {0x0993, 0x09A8},
- {0x09AA, 0x09B0}, {0x09B2, 0x09B2}, {0x09B6, 0x09B9},
- {0x09BC, 0x09C4}, {0x09C7, 0x09C8}, {0x09CB, 0x09CE},
- {0x09D7, 0x09D7}, {0x09DC, 0x09DD}, {0x09DF, 0x09E3},
- {0x09E6, 0x09FE}, {0x0A01, 0x0A03}, {0x0A05, 0x0A0A},
- {0x0A0F, 0x0A10}, {0x0A13, 0x0A28}, {0x0A2A, 0x0A30},
- {0x0A32, 0x0A33}, {0x0A35, 0x0A36}, {0x0A38, 0x0A39},
- {0x0A3C, 0x0A3C}, {0x0A3E, 0x0A42}, {0x0A47, 0x0A48},
- {0x0A4B, 0x0A4D}, {0x0A51, 0x0A51}, {0x0A59, 0x0A5C},
- {0x0A5E, 0x0A5E}, {0x0A66, 0x0A76}, {0x0A81, 0x0A83},
- {0x0A85, 0x0A8D}, {0x0A8F, 0x0A91}, {0x0A93, 0x0AA8},
- {0x0AAA, 0x0AB0}, {0x0AB2, 0x0AB3}, {0x0AB5, 0x0AB9},
- {0x0ABC, 0x0AC5}, {0x0AC7, 0x0AC9}, {0x0ACB, 0x0ACD},
- {0x0AD0, 0x0AD0}, {0x0AE0, 0x0AE3}, {0x0AE6, 0x0AF1},
- {0x0AF9, 0x0AFF}, {0x0B01, 0x0B03}, {0x0B05, 0x0B0C},
- {0x0B0F, 0x0B10}, {0x0B13, 0x0B28}, {0x0B2A, 0x0B30},
- {0x0B32, 0x0B33}, {0x0B35, 0x0B39}, {0x0B3C, 0x0B44},
- {0x0B47, 0x0B48}, {0x0B4B, 0x0B4D}, {0x0B55, 0x0B57},
- {0x0B5C, 0x0B5D}, {0x0B5F, 0x0B63}, {0x0B66, 0x0B77},
- {0x0B82, 0x0B83}, {0x0B85, 0x0B8A}, {0x0B8E, 0x0B90},
- {0x0B92, 0x0B95}, {0x0B99, 0x0B9A}, {0x0B9C, 0x0B9C},
- {0x0B9E, 0x0B9F}, {0x0BA3, 0x0BA4}, {0x0BA8, 0x0BAA},
- {0x0BAE, 0x0BB9}, {0x0BBE, 0x0BC2}, {0x0BC6, 0x0BC8},
- {0x0BCA, 0x0BCD}, {0x0BD0, 0x0BD0}, {0x0BD7, 0x0BD7},
- {0x0BE6, 0x0BFA}, {0x0C00, 0x0C0C}, {0x0C0E, 0x0C10},
- {0x0C12, 0x0C28}, {0x0C2A, 0x0C39}, {0x0C3C, 0x0C44},
- {0x0C46, 0x0C48}, {0x0C4A, 0x0C4D}, {0x0C55, 0x0C56},
- {0x0C58, 0x0C5A}, {0x0C5D, 0x0C5D}, {0x0C60, 0x0C63},
- {0x0C66, 0x0C6F}, {0x0C77, 0x0C8C}, {0x0C8E, 0x0C90},
- {0x0C92, 0x0CA8}, {0x0CAA, 0x0CB3}, {0x0CB5, 0x0CB9},
- {0x0CBC, 0x0CC4}, {0x0CC6, 0x0CC8}, {0x0CCA, 0x0CCD},
- {0x0CD5, 0x0CD6}, {0x0CDD, 0x0CDE}, {0x0CE0, 0x0CE3},
- {0x0CE6, 0x0CEF}, {0x0CF1, 0x0CF3}, {0x0D00, 0x0D0C},
- {0x0D0E, 0x0D10}, {0x0D12, 0x0D44}, {0x0D46, 0x0D48},
- {0x0D4A, 0x0D4F}, {0x0D54, 0x0D63}, {0x0D66, 0x0D7F},
- {0x0D81, 0x0D83}, {0x0D85, 0x0D96}, {0x0D9A, 0x0DB1},
- {0x0DB3, 0x0DBB}, {0x0DBD, 0x0DBD}, {0x0DC0, 0x0DC6},
- {0x0DCA, 0x0DCA}, {0x0DCF, 0x0DD4}, {0x0DD6, 0x0DD6},
- {0x0DD8, 0x0DDF}, {0x0DE6, 0x0DEF}, {0x0DF2, 0x0DF4},
- {0x0E01, 0x0E3A}, {0x0E3F, 0x0E5B}, {0x0E81, 0x0E82},
- {0x0E84, 0x0E84}, {0x0E86, 0x0E8A}, {0x0E8C, 0x0EA3},
- {0x0EA5, 0x0EA5}, {0x0EA7, 0x0EBD}, {0x0EC0, 0x0EC4},
- {0x0EC6, 0x0EC6}, {0x0EC8, 0x0ECE}, {0x0ED0, 0x0ED9},
- {0x0EDC, 0x0EDF}, {0x0F00, 0x0F47}, {0x0F49, 0x0F6C},
- {0x0F71, 0x0F97}, {0x0F99, 0x0FBC}, {0x0FBE, 0x0FCC},
- {0x0FCE, 0x0FDA}, {0x1000, 0x10C5}, {0x10C7, 0x10C7},
- {0x10CD, 0x10CD}, {0x10D0, 0x10FF}, {0x1160, 0x1248},
- {0x124A, 0x124D}, {0x1250, 0x1256}, {0x1258, 0x1258},
- {0x125A, 0x125D}, {0x1260, 0x1288}, {0x128A, 0x128D},
- {0x1290, 0x12B0}, {0x12B2, 0x12B5}, {0x12B8, 0x12BE},
- {0x12C0, 0x12C0}, {0x12C2, 0x12C5}, {0x12C8, 0x12D6},
- {0x12D8, 0x1310}, {0x1312, 0x1315}, {0x1318, 0x135A},
- {0x135D, 0x137C}, {0x1380, 0x1399}, {0x13A0, 0x13F5},
- {0x13F8, 0x13FD}, {0x1400, 0x169C}, {0x16A0, 0x16F8},
- {0x1700, 0x1715}, {0x171F, 0x1736}, {0x1740, 0x1753},
- {0x1760, 0x176C}, {0x176E, 0x1770}, {0x1772, 0x1773},
- {0x1780, 0x17DD}, {0x17E0, 0x17E9}, {0x17F0, 0x17F9},
- {0x1800, 0x1819}, {0x1820, 0x1878}, {0x1880, 0x18AA},
- {0x18B0, 0x18F5}, {0x1900, 0x191E}, {0x1920, 0x192B},
- {0x1930, 0x193B}, {0x1940, 0x1940}, {0x1944, 0x196D},
- {0x1970, 0x1974}, {0x1980, 0x19AB}, {0x19B0, 0x19C9},
- {0x19D0, 0x19DA}, {0x19DE, 0x1A1B}, {0x1A1E, 0x1A5E},
- {0x1A60, 0x1A7C}, {0x1A7F, 0x1A89}, {0x1A90, 0x1A99},
- {0x1AA0, 0x1AAD}, {0x1AB0, 0x1ACE}, {0x1B00, 0x1B4C},
- {0x1B50, 0x1B7E}, {0x1B80, 0x1BF3}, {0x1BFC, 0x1C37},
- {0x1C3B, 0x1C49}, {0x1C4D, 0x1C88}, {0x1C90, 0x1CBA},
- {0x1CBD, 0x1CC7}, {0x1CD0, 0x1CFA}, {0x1D00, 0x1F15},
- {0x1F18, 0x1F1D}, {0x1F20, 0x1F45}, {0x1F48, 0x1F4D},
- {0x1F50, 0x1F57}, {0x1F59, 0x1F59}, {0x1F5B, 0x1F5B},
- {0x1F5D, 0x1F5D}, {0x1F5F, 0x1F7D}, {0x1F80, 0x1FB4},
- {0x1FB6, 0x1FC4}, {0x1FC6, 0x1FD3}, {0x1FD6, 0x1FDB},
- {0x1FDD, 0x1FEF}, {0x1FF2, 0x1FF4}, {0x1FF6, 0x1FFE},
- {0x2000, 0x200F}, {0x2011, 0x2012}, {0x2017, 0x2017},
- {0x201A, 0x201B}, {0x201E, 0x201F}, {0x2023, 0x2023},
- {0x2028, 0x202F}, {0x2031, 0x2031}, {0x2034, 0x2034},
- {0x2036, 0x203A}, {0x203C, 0x203D}, {0x203F, 0x2064},
- {0x2066, 0x2071}, {0x2075, 0x207E}, {0x2080, 0x2080},
- {0x2085, 0x208E}, {0x2090, 0x209C}, {0x20A0, 0x20A8},
- {0x20AA, 0x20AB}, {0x20AD, 0x20C0}, {0x20D0, 0x20F0},
- {0x2100, 0x2102}, {0x2104, 0x2104}, {0x2106, 0x2108},
- {0x210A, 0x2112}, {0x2114, 0x2115}, {0x2117, 0x2120},
- {0x2123, 0x2125}, {0x2127, 0x212A}, {0x212C, 0x2152},
- {0x2155, 0x215A}, {0x215F, 0x215F}, {0x216C, 0x216F},
- {0x217A, 0x2188}, {0x218A, 0x218B}, {0x219A, 0x21B7},
- {0x21BA, 0x21D1}, {0x21D3, 0x21D3}, {0x21D5, 0x21E6},
- {0x21E8, 0x21FF}, {0x2201, 0x2201}, {0x2204, 0x2206},
- {0x2209, 0x220A}, {0x220C, 0x220E}, {0x2210, 0x2210},
- {0x2212, 0x2214}, {0x2216, 0x2219}, {0x221B, 0x221C},
- {0x2221, 0x2222}, {0x2224, 0x2224}, {0x2226, 0x2226},
- {0x222D, 0x222D}, {0x222F, 0x2233}, {0x2238, 0x223B},
- {0x223E, 0x2247}, {0x2249, 0x224B}, {0x224D, 0x2251},
- {0x2253, 0x225F}, {0x2262, 0x2263}, {0x2268, 0x2269},
- {0x226C, 0x226D}, {0x2270, 0x2281}, {0x2284, 0x2285},
- {0x2288, 0x2294}, {0x2296, 0x2298}, {0x229A, 0x22A4},
- {0x22A6, 0x22BE}, {0x22C0, 0x2311}, {0x2313, 0x2319},
- {0x231C, 0x2328}, {0x232B, 0x23E8}, {0x23ED, 0x23EF},
- {0x23F1, 0x23F2}, {0x23F4, 0x2426}, {0x2440, 0x244A},
- {0x24EA, 0x24EA}, {0x254C, 0x254F}, {0x2574, 0x257F},
- {0x2590, 0x2591}, {0x2596, 0x259F}, {0x25A2, 0x25A2},
- {0x25AA, 0x25B1}, {0x25B4, 0x25B5}, {0x25B8, 0x25BB},
- {0x25BE, 0x25BF}, {0x25C2, 0x25C5}, {0x25C9, 0x25CA},
- {0x25CC, 0x25CD}, {0x25D2, 0x25E1}, {0x25E6, 0x25EE},
- {0x25F0, 0x25FC}, {0x25FF, 0x2604}, {0x2607, 0x2608},
- {0x260A, 0x260D}, {0x2610, 0x2613}, {0x2616, 0x261B},
- {0x261D, 0x261D}, {0x261F, 0x263F}, {0x2641, 0x2641},
- {0x2643, 0x2647}, {0x2654, 0x265F}, {0x2662, 0x2662},
- {0x2666, 0x2666}, {0x266B, 0x266B}, {0x266E, 0x266E},
- {0x2670, 0x267E}, {0x2680, 0x2692}, {0x2694, 0x269D},
+ {0x0870, 0x0891}, {0x0897, 0x0983}, {0x0985, 0x098C},
+ {0x098F, 0x0990}, {0x0993, 0x09A8}, {0x09AA, 0x09B0},
+ {0x09B2, 0x09B2}, {0x09B6, 0x09B9}, {0x09BC, 0x09C4},
+ {0x09C7, 0x09C8}, {0x09CB, 0x09CE}, {0x09D7, 0x09D7},
+ {0x09DC, 0x09DD}, {0x09DF, 0x09E3}, {0x09E6, 0x09FE},
+ {0x0A01, 0x0A03}, {0x0A05, 0x0A0A}, {0x0A0F, 0x0A10},
+ {0x0A13, 0x0A28}, {0x0A2A, 0x0A30}, {0x0A32, 0x0A33},
+ {0x0A35, 0x0A36}, {0x0A38, 0x0A39}, {0x0A3C, 0x0A3C},
+ {0x0A3E, 0x0A42}, {0x0A47, 0x0A48}, {0x0A4B, 0x0A4D},
+ {0x0A51, 0x0A51}, {0x0A59, 0x0A5C}, {0x0A5E, 0x0A5E},
+ {0x0A66, 0x0A76}, {0x0A81, 0x0A83}, {0x0A85, 0x0A8D},
+ {0x0A8F, 0x0A91}, {0x0A93, 0x0AA8}, {0x0AAA, 0x0AB0},
+ {0x0AB2, 0x0AB3}, {0x0AB5, 0x0AB9}, {0x0ABC, 0x0AC5},
+ {0x0AC7, 0x0AC9}, {0x0ACB, 0x0ACD}, {0x0AD0, 0x0AD0},
+ {0x0AE0, 0x0AE3}, {0x0AE6, 0x0AF1}, {0x0AF9, 0x0AFF},
+ {0x0B01, 0x0B03}, {0x0B05, 0x0B0C}, {0x0B0F, 0x0B10},
+ {0x0B13, 0x0B28}, {0x0B2A, 0x0B30}, {0x0B32, 0x0B33},
+ {0x0B35, 0x0B39}, {0x0B3C, 0x0B44}, {0x0B47, 0x0B48},
+ {0x0B4B, 0x0B4D}, {0x0B55, 0x0B57}, {0x0B5C, 0x0B5D},
+ {0x0B5F, 0x0B63}, {0x0B66, 0x0B77}, {0x0B82, 0x0B83},
+ {0x0B85, 0x0B8A}, {0x0B8E, 0x0B90}, {0x0B92, 0x0B95},
+ {0x0B99, 0x0B9A}, {0x0B9C, 0x0B9C}, {0x0B9E, 0x0B9F},
+ {0x0BA3, 0x0BA4}, {0x0BA8, 0x0BAA}, {0x0BAE, 0x0BB9},
+ {0x0BBE, 0x0BC2}, {0x0BC6, 0x0BC8}, {0x0BCA, 0x0BCD},
+ {0x0BD0, 0x0BD0}, {0x0BD7, 0x0BD7}, {0x0BE6, 0x0BFA},
+ {0x0C00, 0x0C0C}, {0x0C0E, 0x0C10}, {0x0C12, 0x0C28},
+ {0x0C2A, 0x0C39}, {0x0C3C, 0x0C44}, {0x0C46, 0x0C48},
+ {0x0C4A, 0x0C4D}, {0x0C55, 0x0C56}, {0x0C58, 0x0C5A},
+ {0x0C5C, 0x0C5D}, {0x0C60, 0x0C63}, {0x0C66, 0x0C6F},
+ {0x0C77, 0x0C8C}, {0x0C8E, 0x0C90}, {0x0C92, 0x0CA8},
+ {0x0CAA, 0x0CB3}, {0x0CB5, 0x0CB9}, {0x0CBC, 0x0CC4},
+ {0x0CC6, 0x0CC8}, {0x0CCA, 0x0CCD}, {0x0CD5, 0x0CD6},
+ {0x0CDC, 0x0CDE}, {0x0CE0, 0x0CE3}, {0x0CE6, 0x0CEF},
+ {0x0CF1, 0x0CF3}, {0x0D00, 0x0D0C}, {0x0D0E, 0x0D10},
+ {0x0D12, 0x0D44}, {0x0D46, 0x0D48}, {0x0D4A, 0x0D4F},
+ {0x0D54, 0x0D63}, {0x0D66, 0x0D7F}, {0x0D81, 0x0D83},
+ {0x0D85, 0x0D96}, {0x0D9A, 0x0DB1}, {0x0DB3, 0x0DBB},
+ {0x0DBD, 0x0DBD}, {0x0DC0, 0x0DC6}, {0x0DCA, 0x0DCA},
+ {0x0DCF, 0x0DD4}, {0x0DD6, 0x0DD6}, {0x0DD8, 0x0DDF},
+ {0x0DE6, 0x0DEF}, {0x0DF2, 0x0DF4}, {0x0E01, 0x0E3A},
+ {0x0E3F, 0x0E5B}, {0x0E81, 0x0E82}, {0x0E84, 0x0E84},
+ {0x0E86, 0x0E8A}, {0x0E8C, 0x0EA3}, {0x0EA5, 0x0EA5},
+ {0x0EA7, 0x0EBD}, {0x0EC0, 0x0EC4}, {0x0EC6, 0x0EC6},
+ {0x0EC8, 0x0ECE}, {0x0ED0, 0x0ED9}, {0x0EDC, 0x0EDF},
+ {0x0F00, 0x0F47}, {0x0F49, 0x0F6C}, {0x0F71, 0x0F97},
+ {0x0F99, 0x0FBC}, {0x0FBE, 0x0FCC}, {0x0FCE, 0x0FDA},
+ {0x1000, 0x10C5}, {0x10C7, 0x10C7}, {0x10CD, 0x10CD},
+ {0x10D0, 0x10FF}, {0x1160, 0x1248}, {0x124A, 0x124D},
+ {0x1250, 0x1256}, {0x1258, 0x1258}, {0x125A, 0x125D},
+ {0x1260, 0x1288}, {0x128A, 0x128D}, {0x1290, 0x12B0},
+ {0x12B2, 0x12B5}, {0x12B8, 0x12BE}, {0x12C0, 0x12C0},
+ {0x12C2, 0x12C5}, {0x12C8, 0x12D6}, {0x12D8, 0x1310},
+ {0x1312, 0x1315}, {0x1318, 0x135A}, {0x135D, 0x137C},
+ {0x1380, 0x1399}, {0x13A0, 0x13F5}, {0x13F8, 0x13FD},
+ {0x1400, 0x169C}, {0x16A0, 0x16F8}, {0x1700, 0x1715},
+ {0x171F, 0x1736}, {0x1740, 0x1753}, {0x1760, 0x176C},
+ {0x176E, 0x1770}, {0x1772, 0x1773}, {0x1780, 0x17DD},
+ {0x17E0, 0x17E9}, {0x17F0, 0x17F9}, {0x1800, 0x180A},
+ {0x180E, 0x180E}, {0x1810, 0x1819}, {0x1820, 0x1878},
+ {0x1880, 0x18AA}, {0x18B0, 0x18F5}, {0x1900, 0x191E},
+ {0x1920, 0x192B}, {0x1930, 0x193B}, {0x1940, 0x1940},
+ {0x1944, 0x196D}, {0x1970, 0x1974}, {0x1980, 0x19AB},
+ {0x19B0, 0x19C9}, {0x19D0, 0x19DA}, {0x19DE, 0x1A1B},
+ {0x1A1E, 0x1A5E}, {0x1A60, 0x1A7C}, {0x1A7F, 0x1A89},
+ {0x1A90, 0x1A99}, {0x1AA0, 0x1AAD}, {0x1AB0, 0x1ADD},
+ {0x1AE0, 0x1AEB}, {0x1B00, 0x1B4C}, {0x1B4E, 0x1BF3},
+ {0x1BFC, 0x1C37}, {0x1C3B, 0x1C49}, {0x1C4D, 0x1C8A},
+ {0x1C90, 0x1CBA}, {0x1CBD, 0x1CC7}, {0x1CD0, 0x1CFA},
+ {0x1D00, 0x1F15}, {0x1F18, 0x1F1D}, {0x1F20, 0x1F45},
+ {0x1F48, 0x1F4D}, {0x1F50, 0x1F57}, {0x1F59, 0x1F59},
+ {0x1F5B, 0x1F5B}, {0x1F5D, 0x1F5D}, {0x1F5F, 0x1F7D},
+ {0x1F80, 0x1FB4}, {0x1FB6, 0x1FC4}, {0x1FC6, 0x1FD3},
+ {0x1FD6, 0x1FDB}, {0x1FDD, 0x1FEF}, {0x1FF2, 0x1FF4},
+ {0x1FF6, 0x1FFE}, {0x2000, 0x200F}, {0x2011, 0x2012},
+ {0x2017, 0x2017}, {0x201A, 0x201B}, {0x201E, 0x201F},
+ {0x2023, 0x2023}, {0x2028, 0x202F}, {0x2031, 0x2031},
+ {0x2034, 0x2034}, {0x2036, 0x203A}, {0x203C, 0x203D},
+ {0x203F, 0x2064}, {0x2066, 0x2071}, {0x2075, 0x207E},
+ {0x2080, 0x2080}, {0x2085, 0x208E}, {0x2090, 0x209C},
+ {0x20A0, 0x20A8}, {0x20AA, 0x20AB}, {0x20AD, 0x20C1},
+ {0x20D0, 0x20F0}, {0x2100, 0x2102}, {0x2104, 0x2104},
+ {0x2106, 0x2108}, {0x210A, 0x2112}, {0x2114, 0x2115},
+ {0x2117, 0x2120}, {0x2123, 0x2125}, {0x2127, 0x212A},
+ {0x212C, 0x2152}, {0x2155, 0x215A}, {0x215F, 0x215F},
+ {0x216C, 0x216F}, {0x217A, 0x2188}, {0x218A, 0x218B},
+ {0x219A, 0x21B7}, {0x21BA, 0x21D1}, {0x21D3, 0x21D3},
+ {0x21D5, 0x21E6}, {0x21E8, 0x21FF}, {0x2201, 0x2201},
+ {0x2204, 0x2206}, {0x2209, 0x220A}, {0x220C, 0x220E},
+ {0x2210, 0x2210}, {0x2212, 0x2214}, {0x2216, 0x2219},
+ {0x221B, 0x221C}, {0x2221, 0x2222}, {0x2224, 0x2224},
+ {0x2226, 0x2226}, {0x222D, 0x222D}, {0x222F, 0x2233},
+ {0x2238, 0x223B}, {0x223E, 0x2247}, {0x2249, 0x224B},
+ {0x224D, 0x2251}, {0x2253, 0x225F}, {0x2262, 0x2263},
+ {0x2268, 0x2269}, {0x226C, 0x226D}, {0x2270, 0x2281},
+ {0x2284, 0x2285}, {0x2288, 0x2294}, {0x2296, 0x2298},
+ {0x229A, 0x22A4}, {0x22A6, 0x22BE}, {0x22C0, 0x2311},
+ {0x2313, 0x2319}, {0x231C, 0x2328}, {0x232B, 0x23E8},
+ {0x23ED, 0x23EF}, {0x23F1, 0x23F2}, {0x23F4, 0x2429},
+ {0x2440, 0x244A}, {0x24EA, 0x24EA}, {0x254C, 0x254F},
+ {0x2574, 0x257F}, {0x2590, 0x2591}, {0x2596, 0x259F},
+ {0x25A2, 0x25A2}, {0x25AA, 0x25B1}, {0x25B4, 0x25B5},
+ {0x25B8, 0x25BB}, {0x25BE, 0x25BF}, {0x25C2, 0x25C5},
+ {0x25C9, 0x25CA}, {0x25CC, 0x25CD}, {0x25D2, 0x25E1},
+ {0x25E6, 0x25EE}, {0x25F0, 0x25FC}, {0x25FF, 0x2604},
+ {0x2607, 0x2608}, {0x260A, 0x260D}, {0x2610, 0x2613},
+ {0x2616, 0x261B}, {0x261D, 0x261D}, {0x261F, 0x262F},
+ {0x2638, 0x263F}, {0x2641, 0x2641}, {0x2643, 0x2647},
+ {0x2654, 0x265F}, {0x2662, 0x2662}, {0x2666, 0x2666},
+ {0x266B, 0x266B}, {0x266E, 0x266E}, {0x2670, 0x267E},
+ {0x2680, 0x2689}, {0x2690, 0x2692}, {0x2694, 0x269D},
{0x26A0, 0x26A0}, {0x26A2, 0x26A9}, {0x26AC, 0x26BC},
{0x26C0, 0x26C3}, {0x26E2, 0x26E2}, {0x26E4, 0x26E7},
{0x2700, 0x2704}, {0x2706, 0x2709}, {0x270C, 0x2727},
@@ -276,175 +279,210 @@ var neutral = table{
{0x2780, 0x2794}, {0x2798, 0x27AF}, {0x27B1, 0x27BE},
{0x27C0, 0x27E5}, {0x27EE, 0x2984}, {0x2987, 0x2B1A},
{0x2B1D, 0x2B4F}, {0x2B51, 0x2B54}, {0x2B5A, 0x2B73},
- {0x2B76, 0x2B95}, {0x2B97, 0x2CF3}, {0x2CF9, 0x2D25},
- {0x2D27, 0x2D27}, {0x2D2D, 0x2D2D}, {0x2D30, 0x2D67},
- {0x2D6F, 0x2D70}, {0x2D7F, 0x2D96}, {0x2DA0, 0x2DA6},
- {0x2DA8, 0x2DAE}, {0x2DB0, 0x2DB6}, {0x2DB8, 0x2DBE},
- {0x2DC0, 0x2DC6}, {0x2DC8, 0x2DCE}, {0x2DD0, 0x2DD6},
- {0x2DD8, 0x2DDE}, {0x2DE0, 0x2E5D}, {0x303F, 0x303F},
- {0x4DC0, 0x4DFF}, {0xA4D0, 0xA62B}, {0xA640, 0xA6F7},
- {0xA700, 0xA7CA}, {0xA7D0, 0xA7D1}, {0xA7D3, 0xA7D3},
- {0xA7D5, 0xA7D9}, {0xA7F2, 0xA82C}, {0xA830, 0xA839},
- {0xA840, 0xA877}, {0xA880, 0xA8C5}, {0xA8CE, 0xA8D9},
- {0xA8E0, 0xA953}, {0xA95F, 0xA95F}, {0xA980, 0xA9CD},
- {0xA9CF, 0xA9D9}, {0xA9DE, 0xA9FE}, {0xAA00, 0xAA36},
- {0xAA40, 0xAA4D}, {0xAA50, 0xAA59}, {0xAA5C, 0xAAC2},
- {0xAADB, 0xAAF6}, {0xAB01, 0xAB06}, {0xAB09, 0xAB0E},
- {0xAB11, 0xAB16}, {0xAB20, 0xAB26}, {0xAB28, 0xAB2E},
- {0xAB30, 0xAB6B}, {0xAB70, 0xABED}, {0xABF0, 0xABF9},
- {0xD7B0, 0xD7C6}, {0xD7CB, 0xD7FB}, {0xD800, 0xDFFF},
- {0xFB00, 0xFB06}, {0xFB13, 0xFB17}, {0xFB1D, 0xFB36},
- {0xFB38, 0xFB3C}, {0xFB3E, 0xFB3E}, {0xFB40, 0xFB41},
- {0xFB43, 0xFB44}, {0xFB46, 0xFBC2}, {0xFBD3, 0xFD8F},
- {0xFD92, 0xFDC7}, {0xFDCF, 0xFDCF}, {0xFDF0, 0xFDFF},
- {0xFE20, 0xFE2F}, {0xFE70, 0xFE74}, {0xFE76, 0xFEFC},
- {0xFEFF, 0xFEFF}, {0xFFF9, 0xFFFC}, {0x10000, 0x1000B},
- {0x1000D, 0x10026}, {0x10028, 0x1003A}, {0x1003C, 0x1003D},
- {0x1003F, 0x1004D}, {0x10050, 0x1005D}, {0x10080, 0x100FA},
- {0x10100, 0x10102}, {0x10107, 0x10133}, {0x10137, 0x1018E},
- {0x10190, 0x1019C}, {0x101A0, 0x101A0}, {0x101D0, 0x101FD},
- {0x10280, 0x1029C}, {0x102A0, 0x102D0}, {0x102E0, 0x102FB},
- {0x10300, 0x10323}, {0x1032D, 0x1034A}, {0x10350, 0x1037A},
- {0x10380, 0x1039D}, {0x1039F, 0x103C3}, {0x103C8, 0x103D5},
- {0x10400, 0x1049D}, {0x104A0, 0x104A9}, {0x104B0, 0x104D3},
- {0x104D8, 0x104FB}, {0x10500, 0x10527}, {0x10530, 0x10563},
- {0x1056F, 0x1057A}, {0x1057C, 0x1058A}, {0x1058C, 0x10592},
- {0x10594, 0x10595}, {0x10597, 0x105A1}, {0x105A3, 0x105B1},
- {0x105B3, 0x105B9}, {0x105BB, 0x105BC}, {0x10600, 0x10736},
- {0x10740, 0x10755}, {0x10760, 0x10767}, {0x10780, 0x10785},
- {0x10787, 0x107B0}, {0x107B2, 0x107BA}, {0x10800, 0x10805},
- {0x10808, 0x10808}, {0x1080A, 0x10835}, {0x10837, 0x10838},
- {0x1083C, 0x1083C}, {0x1083F, 0x10855}, {0x10857, 0x1089E},
- {0x108A7, 0x108AF}, {0x108E0, 0x108F2}, {0x108F4, 0x108F5},
- {0x108FB, 0x1091B}, {0x1091F, 0x10939}, {0x1093F, 0x1093F},
- {0x10980, 0x109B7}, {0x109BC, 0x109CF}, {0x109D2, 0x10A03},
- {0x10A05, 0x10A06}, {0x10A0C, 0x10A13}, {0x10A15, 0x10A17},
- {0x10A19, 0x10A35}, {0x10A38, 0x10A3A}, {0x10A3F, 0x10A48},
- {0x10A50, 0x10A58}, {0x10A60, 0x10A9F}, {0x10AC0, 0x10AE6},
- {0x10AEB, 0x10AF6}, {0x10B00, 0x10B35}, {0x10B39, 0x10B55},
- {0x10B58, 0x10B72}, {0x10B78, 0x10B91}, {0x10B99, 0x10B9C},
- {0x10BA9, 0x10BAF}, {0x10C00, 0x10C48}, {0x10C80, 0x10CB2},
- {0x10CC0, 0x10CF2}, {0x10CFA, 0x10D27}, {0x10D30, 0x10D39},
- {0x10E60, 0x10E7E}, {0x10E80, 0x10EA9}, {0x10EAB, 0x10EAD},
- {0x10EB0, 0x10EB1}, {0x10EFD, 0x10F27}, {0x10F30, 0x10F59},
- {0x10F70, 0x10F89}, {0x10FB0, 0x10FCB}, {0x10FE0, 0x10FF6},
- {0x11000, 0x1104D}, {0x11052, 0x11075}, {0x1107F, 0x110C2},
- {0x110CD, 0x110CD}, {0x110D0, 0x110E8}, {0x110F0, 0x110F9},
- {0x11100, 0x11134}, {0x11136, 0x11147}, {0x11150, 0x11176},
- {0x11180, 0x111DF}, {0x111E1, 0x111F4}, {0x11200, 0x11211},
- {0x11213, 0x11241}, {0x11280, 0x11286}, {0x11288, 0x11288},
- {0x1128A, 0x1128D}, {0x1128F, 0x1129D}, {0x1129F, 0x112A9},
- {0x112B0, 0x112EA}, {0x112F0, 0x112F9}, {0x11300, 0x11303},
- {0x11305, 0x1130C}, {0x1130F, 0x11310}, {0x11313, 0x11328},
- {0x1132A, 0x11330}, {0x11332, 0x11333}, {0x11335, 0x11339},
- {0x1133B, 0x11344}, {0x11347, 0x11348}, {0x1134B, 0x1134D},
- {0x11350, 0x11350}, {0x11357, 0x11357}, {0x1135D, 0x11363},
- {0x11366, 0x1136C}, {0x11370, 0x11374}, {0x11400, 0x1145B},
+ {0x2B76, 0x2CF3}, {0x2CF9, 0x2D25}, {0x2D27, 0x2D27},
+ {0x2D2D, 0x2D2D}, {0x2D30, 0x2D67}, {0x2D6F, 0x2D70},
+ {0x2D7F, 0x2D96}, {0x2DA0, 0x2DA6}, {0x2DA8, 0x2DAE},
+ {0x2DB0, 0x2DB6}, {0x2DB8, 0x2DBE}, {0x2DC0, 0x2DC6},
+ {0x2DC8, 0x2DCE}, {0x2DD0, 0x2DD6}, {0x2DD8, 0x2DDE},
+ {0x2DE0, 0x2E5D}, {0x303F, 0x303F}, {0xA4D0, 0xA62B},
+ {0xA640, 0xA6F7}, {0xA700, 0xA7DC}, {0xA7F1, 0xA82C},
+ {0xA830, 0xA839}, {0xA840, 0xA877}, {0xA880, 0xA8C5},
+ {0xA8CE, 0xA8D9}, {0xA8E0, 0xA953}, {0xA95F, 0xA95F},
+ {0xA980, 0xA9CD}, {0xA9CF, 0xA9D9}, {0xA9DE, 0xA9FE},
+ {0xAA00, 0xAA36}, {0xAA40, 0xAA4D}, {0xAA50, 0xAA59},
+ {0xAA5C, 0xAAC2}, {0xAADB, 0xAAF6}, {0xAB01, 0xAB06},
+ {0xAB09, 0xAB0E}, {0xAB11, 0xAB16}, {0xAB20, 0xAB26},
+ {0xAB28, 0xAB2E}, {0xAB30, 0xAB6B}, {0xAB70, 0xABED},
+ {0xABF0, 0xABF9}, {0xD7B0, 0xD7C6}, {0xD7CB, 0xD7FB},
+ {0xD800, 0xDFFF}, {0xFB00, 0xFB06}, {0xFB13, 0xFB17},
+ {0xFB1D, 0xFB36}, {0xFB38, 0xFB3C}, {0xFB3E, 0xFB3E},
+ {0xFB40, 0xFB41}, {0xFB43, 0xFB44}, {0xFB46, 0xFDCF},
+ {0xFDF0, 0xFDFF}, {0xFE20, 0xFE2F}, {0xFE70, 0xFE74},
+ {0xFE76, 0xFEFC}, {0xFEFF, 0xFEFF}, {0xFFF9, 0xFFFC},
+ {0x10000, 0x1000B}, {0x1000D, 0x10026}, {0x10028, 0x1003A},
+ {0x1003C, 0x1003D}, {0x1003F, 0x1004D}, {0x10050, 0x1005D},
+ {0x10080, 0x100FA}, {0x10100, 0x10102}, {0x10107, 0x10133},
+ {0x10137, 0x1018E}, {0x10190, 0x1019C}, {0x101A0, 0x101A0},
+ {0x101D0, 0x101FD}, {0x10280, 0x1029C}, {0x102A0, 0x102D0},
+ {0x102E0, 0x102FB}, {0x10300, 0x10323}, {0x1032D, 0x1034A},
+ {0x10350, 0x1037A}, {0x10380, 0x1039D}, {0x1039F, 0x103C3},
+ {0x103C8, 0x103D5}, {0x10400, 0x1049D}, {0x104A0, 0x104A9},
+ {0x104B0, 0x104D3}, {0x104D8, 0x104FB}, {0x10500, 0x10527},
+ {0x10530, 0x10563}, {0x1056F, 0x1057A}, {0x1057C, 0x1058A},
+ {0x1058C, 0x10592}, {0x10594, 0x10595}, {0x10597, 0x105A1},
+ {0x105A3, 0x105B1}, {0x105B3, 0x105B9}, {0x105BB, 0x105BC},
+ {0x105C0, 0x105F3}, {0x10600, 0x10736}, {0x10740, 0x10755},
+ {0x10760, 0x10767}, {0x10780, 0x10785}, {0x10787, 0x107B0},
+ {0x107B2, 0x107BA}, {0x10800, 0x10805}, {0x10808, 0x10808},
+ {0x1080A, 0x10835}, {0x10837, 0x10838}, {0x1083C, 0x1083C},
+ {0x1083F, 0x10855}, {0x10857, 0x1089E}, {0x108A7, 0x108AF},
+ {0x108E0, 0x108F2}, {0x108F4, 0x108F5}, {0x108FB, 0x1091B},
+ {0x1091F, 0x10939}, {0x1093F, 0x10959}, {0x10980, 0x109B7},
+ {0x109BC, 0x109CF}, {0x109D2, 0x10A03}, {0x10A05, 0x10A06},
+ {0x10A0C, 0x10A13}, {0x10A15, 0x10A17}, {0x10A19, 0x10A35},
+ {0x10A38, 0x10A3A}, {0x10A3F, 0x10A48}, {0x10A50, 0x10A58},
+ {0x10A60, 0x10A9F}, {0x10AC0, 0x10AE6}, {0x10AEB, 0x10AF6},
+ {0x10B00, 0x10B35}, {0x10B39, 0x10B55}, {0x10B58, 0x10B72},
+ {0x10B78, 0x10B91}, {0x10B99, 0x10B9C}, {0x10BA9, 0x10BAF},
+ {0x10C00, 0x10C48}, {0x10C80, 0x10CB2}, {0x10CC0, 0x10CF2},
+ {0x10CFA, 0x10D27}, {0x10D30, 0x10D39}, {0x10D40, 0x10D65},
+ {0x10D69, 0x10D85}, {0x10D8E, 0x10D8F}, {0x10E60, 0x10E7E},
+ {0x10E80, 0x10EA9}, {0x10EAB, 0x10EAD}, {0x10EB0, 0x10EB1},
+ {0x10EC2, 0x10EC7}, {0x10ED0, 0x10ED8}, {0x10EFA, 0x10F27},
+ {0x10F30, 0x10F59}, {0x10F70, 0x10F89}, {0x10FB0, 0x10FCB},
+ {0x10FE0, 0x10FF6}, {0x11000, 0x1104D}, {0x11052, 0x11075},
+ {0x1107F, 0x110C2}, {0x110CD, 0x110CD}, {0x110D0, 0x110E8},
+ {0x110F0, 0x110F9}, {0x11100, 0x11134}, {0x11136, 0x11147},
+ {0x11150, 0x11176}, {0x11180, 0x111DF}, {0x111E1, 0x111F4},
+ {0x11200, 0x11211}, {0x11213, 0x11241}, {0x11280, 0x11286},
+ {0x11288, 0x11288}, {0x1128A, 0x1128D}, {0x1128F, 0x1129D},
+ {0x1129F, 0x112A9}, {0x112B0, 0x112EA}, {0x112F0, 0x112F9},
+ {0x11300, 0x11303}, {0x11305, 0x1130C}, {0x1130F, 0x11310},
+ {0x11313, 0x11328}, {0x1132A, 0x11330}, {0x11332, 0x11333},
+ {0x11335, 0x11339}, {0x1133B, 0x11344}, {0x11347, 0x11348},
+ {0x1134B, 0x1134D}, {0x11350, 0x11350}, {0x11357, 0x11357},
+ {0x1135D, 0x11363}, {0x11366, 0x1136C}, {0x11370, 0x11374},
+ {0x11380, 0x11389}, {0x1138B, 0x1138B}, {0x1138E, 0x1138E},
+ {0x11390, 0x113B5}, {0x113B7, 0x113C0}, {0x113C2, 0x113C2},
+ {0x113C5, 0x113C5}, {0x113C7, 0x113CA}, {0x113CC, 0x113D5},
+ {0x113D7, 0x113D8}, {0x113E1, 0x113E2}, {0x11400, 0x1145B},
{0x1145D, 0x11461}, {0x11480, 0x114C7}, {0x114D0, 0x114D9},
{0x11580, 0x115B5}, {0x115B8, 0x115DD}, {0x11600, 0x11644},
{0x11650, 0x11659}, {0x11660, 0x1166C}, {0x11680, 0x116B9},
- {0x116C0, 0x116C9}, {0x11700, 0x1171A}, {0x1171D, 0x1172B},
- {0x11730, 0x11746}, {0x11800, 0x1183B}, {0x118A0, 0x118F2},
- {0x118FF, 0x11906}, {0x11909, 0x11909}, {0x1190C, 0x11913},
- {0x11915, 0x11916}, {0x11918, 0x11935}, {0x11937, 0x11938},
- {0x1193B, 0x11946}, {0x11950, 0x11959}, {0x119A0, 0x119A7},
- {0x119AA, 0x119D7}, {0x119DA, 0x119E4}, {0x11A00, 0x11A47},
- {0x11A50, 0x11AA2}, {0x11AB0, 0x11AF8}, {0x11B00, 0x11B09},
- {0x11C00, 0x11C08}, {0x11C0A, 0x11C36}, {0x11C38, 0x11C45},
- {0x11C50, 0x11C6C}, {0x11C70, 0x11C8F}, {0x11C92, 0x11CA7},
- {0x11CA9, 0x11CB6}, {0x11D00, 0x11D06}, {0x11D08, 0x11D09},
- {0x11D0B, 0x11D36}, {0x11D3A, 0x11D3A}, {0x11D3C, 0x11D3D},
- {0x11D3F, 0x11D47}, {0x11D50, 0x11D59}, {0x11D60, 0x11D65},
- {0x11D67, 0x11D68}, {0x11D6A, 0x11D8E}, {0x11D90, 0x11D91},
- {0x11D93, 0x11D98}, {0x11DA0, 0x11DA9}, {0x11EE0, 0x11EF8},
- {0x11F00, 0x11F10}, {0x11F12, 0x11F3A}, {0x11F3E, 0x11F59},
+ {0x116C0, 0x116C9}, {0x116D0, 0x116E3}, {0x11700, 0x1171A},
+ {0x1171D, 0x1172B}, {0x11730, 0x11746}, {0x11800, 0x1183B},
+ {0x118A0, 0x118F2}, {0x118FF, 0x11906}, {0x11909, 0x11909},
+ {0x1190C, 0x11913}, {0x11915, 0x11916}, {0x11918, 0x11935},
+ {0x11937, 0x11938}, {0x1193B, 0x11946}, {0x11950, 0x11959},
+ {0x119A0, 0x119A7}, {0x119AA, 0x119D7}, {0x119DA, 0x119E4},
+ {0x11A00, 0x11A47}, {0x11A50, 0x11AA2}, {0x11AB0, 0x11AF8},
+ {0x11B00, 0x11B09}, {0x11B60, 0x11B67}, {0x11BC0, 0x11BE1},
+ {0x11BF0, 0x11BF9}, {0x11C00, 0x11C08}, {0x11C0A, 0x11C36},
+ {0x11C38, 0x11C45}, {0x11C50, 0x11C6C}, {0x11C70, 0x11C8F},
+ {0x11C92, 0x11CA7}, {0x11CA9, 0x11CB6}, {0x11D00, 0x11D06},
+ {0x11D08, 0x11D09}, {0x11D0B, 0x11D36}, {0x11D3A, 0x11D3A},
+ {0x11D3C, 0x11D3D}, {0x11D3F, 0x11D47}, {0x11D50, 0x11D59},
+ {0x11D60, 0x11D65}, {0x11D67, 0x11D68}, {0x11D6A, 0x11D8E},
+ {0x11D90, 0x11D91}, {0x11D93, 0x11D98}, {0x11DA0, 0x11DA9},
+ {0x11DB0, 0x11DDB}, {0x11DE0, 0x11DE9}, {0x11EE0, 0x11EF8},
+ {0x11F00, 0x11F10}, {0x11F12, 0x11F3A}, {0x11F3E, 0x11F5A},
{0x11FB0, 0x11FB0}, {0x11FC0, 0x11FF1}, {0x11FFF, 0x12399},
{0x12400, 0x1246E}, {0x12470, 0x12474}, {0x12480, 0x12543},
- {0x12F90, 0x12FF2}, {0x13000, 0x13455}, {0x14400, 0x14646},
- {0x16800, 0x16A38}, {0x16A40, 0x16A5E}, {0x16A60, 0x16A69},
- {0x16A6E, 0x16ABE}, {0x16AC0, 0x16AC9}, {0x16AD0, 0x16AED},
- {0x16AF0, 0x16AF5}, {0x16B00, 0x16B45}, {0x16B50, 0x16B59},
- {0x16B5B, 0x16B61}, {0x16B63, 0x16B77}, {0x16B7D, 0x16B8F},
- {0x16E40, 0x16E9A}, {0x16F00, 0x16F4A}, {0x16F4F, 0x16F87},
- {0x16F8F, 0x16F9F}, {0x1BC00, 0x1BC6A}, {0x1BC70, 0x1BC7C},
- {0x1BC80, 0x1BC88}, {0x1BC90, 0x1BC99}, {0x1BC9C, 0x1BCA3},
+ {0x12F90, 0x12FF2}, {0x13000, 0x13455}, {0x13460, 0x143FA},
+ {0x14400, 0x14646}, {0x16100, 0x16139}, {0x16800, 0x16A38},
+ {0x16A40, 0x16A5E}, {0x16A60, 0x16A69}, {0x16A6E, 0x16ABE},
+ {0x16AC0, 0x16AC9}, {0x16AD0, 0x16AED}, {0x16AF0, 0x16AF5},
+ {0x16B00, 0x16B45}, {0x16B50, 0x16B59}, {0x16B5B, 0x16B61},
+ {0x16B63, 0x16B77}, {0x16B7D, 0x16B8F}, {0x16D40, 0x16D79},
+ {0x16E40, 0x16E9A}, {0x16EA0, 0x16EB8}, {0x16EBB, 0x16ED3},
+ {0x16F00, 0x16F4A}, {0x16F4F, 0x16F87}, {0x16F8F, 0x16F9F},
+ {0x1BC00, 0x1BC6A}, {0x1BC70, 0x1BC7C}, {0x1BC80, 0x1BC88},
+ {0x1BC90, 0x1BC99}, {0x1BC9C, 0x1BCA3}, {0x1CC00, 0x1CCFC},
+ {0x1CD00, 0x1CEB3}, {0x1CEBA, 0x1CED0}, {0x1CEE0, 0x1CEF0},
{0x1CF00, 0x1CF2D}, {0x1CF30, 0x1CF46}, {0x1CF50, 0x1CFC3},
{0x1D000, 0x1D0F5}, {0x1D100, 0x1D126}, {0x1D129, 0x1D1EA},
{0x1D200, 0x1D245}, {0x1D2C0, 0x1D2D3}, {0x1D2E0, 0x1D2F3},
- {0x1D300, 0x1D356}, {0x1D360, 0x1D378}, {0x1D400, 0x1D454},
- {0x1D456, 0x1D49C}, {0x1D49E, 0x1D49F}, {0x1D4A2, 0x1D4A2},
- {0x1D4A5, 0x1D4A6}, {0x1D4A9, 0x1D4AC}, {0x1D4AE, 0x1D4B9},
- {0x1D4BB, 0x1D4BB}, {0x1D4BD, 0x1D4C3}, {0x1D4C5, 0x1D505},
- {0x1D507, 0x1D50A}, {0x1D50D, 0x1D514}, {0x1D516, 0x1D51C},
- {0x1D51E, 0x1D539}, {0x1D53B, 0x1D53E}, {0x1D540, 0x1D544},
- {0x1D546, 0x1D546}, {0x1D54A, 0x1D550}, {0x1D552, 0x1D6A5},
- {0x1D6A8, 0x1D7CB}, {0x1D7CE, 0x1DA8B}, {0x1DA9B, 0x1DA9F},
- {0x1DAA1, 0x1DAAF}, {0x1DF00, 0x1DF1E}, {0x1DF25, 0x1DF2A},
- {0x1E000, 0x1E006}, {0x1E008, 0x1E018}, {0x1E01B, 0x1E021},
- {0x1E023, 0x1E024}, {0x1E026, 0x1E02A}, {0x1E030, 0x1E06D},
- {0x1E08F, 0x1E08F}, {0x1E100, 0x1E12C}, {0x1E130, 0x1E13D},
- {0x1E140, 0x1E149}, {0x1E14E, 0x1E14F}, {0x1E290, 0x1E2AE},
- {0x1E2C0, 0x1E2F9}, {0x1E2FF, 0x1E2FF}, {0x1E4D0, 0x1E4F9},
- {0x1E7E0, 0x1E7E6}, {0x1E7E8, 0x1E7EB}, {0x1E7ED, 0x1E7EE},
- {0x1E7F0, 0x1E7FE}, {0x1E800, 0x1E8C4}, {0x1E8C7, 0x1E8D6},
- {0x1E900, 0x1E94B}, {0x1E950, 0x1E959}, {0x1E95E, 0x1E95F},
- {0x1EC71, 0x1ECB4}, {0x1ED01, 0x1ED3D}, {0x1EE00, 0x1EE03},
- {0x1EE05, 0x1EE1F}, {0x1EE21, 0x1EE22}, {0x1EE24, 0x1EE24},
- {0x1EE27, 0x1EE27}, {0x1EE29, 0x1EE32}, {0x1EE34, 0x1EE37},
- {0x1EE39, 0x1EE39}, {0x1EE3B, 0x1EE3B}, {0x1EE42, 0x1EE42},
- {0x1EE47, 0x1EE47}, {0x1EE49, 0x1EE49}, {0x1EE4B, 0x1EE4B},
- {0x1EE4D, 0x1EE4F}, {0x1EE51, 0x1EE52}, {0x1EE54, 0x1EE54},
- {0x1EE57, 0x1EE57}, {0x1EE59, 0x1EE59}, {0x1EE5B, 0x1EE5B},
- {0x1EE5D, 0x1EE5D}, {0x1EE5F, 0x1EE5F}, {0x1EE61, 0x1EE62},
- {0x1EE64, 0x1EE64}, {0x1EE67, 0x1EE6A}, {0x1EE6C, 0x1EE72},
- {0x1EE74, 0x1EE77}, {0x1EE79, 0x1EE7C}, {0x1EE7E, 0x1EE7E},
- {0x1EE80, 0x1EE89}, {0x1EE8B, 0x1EE9B}, {0x1EEA1, 0x1EEA3},
- {0x1EEA5, 0x1EEA9}, {0x1EEAB, 0x1EEBB}, {0x1EEF0, 0x1EEF1},
- {0x1F000, 0x1F003}, {0x1F005, 0x1F02B}, {0x1F030, 0x1F093},
- {0x1F0A0, 0x1F0AE}, {0x1F0B1, 0x1F0BF}, {0x1F0C1, 0x1F0CE},
- {0x1F0D1, 0x1F0F5}, {0x1F10B, 0x1F10F}, {0x1F12E, 0x1F12F},
- {0x1F16A, 0x1F16F}, {0x1F1AD, 0x1F1AD}, {0x1F1E6, 0x1F1FF},
- {0x1F321, 0x1F32C}, {0x1F336, 0x1F336}, {0x1F37D, 0x1F37D},
- {0x1F394, 0x1F39F}, {0x1F3CB, 0x1F3CE}, {0x1F3D4, 0x1F3DF},
- {0x1F3F1, 0x1F3F3}, {0x1F3F5, 0x1F3F7}, {0x1F43F, 0x1F43F},
- {0x1F441, 0x1F441}, {0x1F4FD, 0x1F4FE}, {0x1F53E, 0x1F54A},
- {0x1F54F, 0x1F54F}, {0x1F568, 0x1F579}, {0x1F57B, 0x1F594},
- {0x1F597, 0x1F5A3}, {0x1F5A5, 0x1F5FA}, {0x1F650, 0x1F67F},
- {0x1F6C6, 0x1F6CB}, {0x1F6CD, 0x1F6CF}, {0x1F6D3, 0x1F6D4},
- {0x1F6E0, 0x1F6EA}, {0x1F6F0, 0x1F6F3}, {0x1F700, 0x1F776},
- {0x1F77B, 0x1F7D9}, {0x1F800, 0x1F80B}, {0x1F810, 0x1F847},
+ {0x1D377, 0x1D378}, {0x1D400, 0x1D454}, {0x1D456, 0x1D49C},
+ {0x1D49E, 0x1D49F}, {0x1D4A2, 0x1D4A2}, {0x1D4A5, 0x1D4A6},
+ {0x1D4A9, 0x1D4AC}, {0x1D4AE, 0x1D4B9}, {0x1D4BB, 0x1D4BB},
+ {0x1D4BD, 0x1D4C3}, {0x1D4C5, 0x1D505}, {0x1D507, 0x1D50A},
+ {0x1D50D, 0x1D514}, {0x1D516, 0x1D51C}, {0x1D51E, 0x1D539},
+ {0x1D53B, 0x1D53E}, {0x1D540, 0x1D544}, {0x1D546, 0x1D546},
+ {0x1D54A, 0x1D550}, {0x1D552, 0x1D6A5}, {0x1D6A8, 0x1D7CB},
+ {0x1D7CE, 0x1DA8B}, {0x1DA9B, 0x1DA9F}, {0x1DAA1, 0x1DAAF},
+ {0x1DF00, 0x1DF1E}, {0x1DF25, 0x1DF2A}, {0x1E000, 0x1E006},
+ {0x1E008, 0x1E018}, {0x1E01B, 0x1E021}, {0x1E023, 0x1E024},
+ {0x1E026, 0x1E02A}, {0x1E030, 0x1E06D}, {0x1E08F, 0x1E08F},
+ {0x1E100, 0x1E12C}, {0x1E130, 0x1E13D}, {0x1E140, 0x1E149},
+ {0x1E14E, 0x1E14F}, {0x1E290, 0x1E2AE}, {0x1E2C0, 0x1E2F9},
+ {0x1E2FF, 0x1E2FF}, {0x1E4D0, 0x1E4F9}, {0x1E5D0, 0x1E5FA},
+ {0x1E5FF, 0x1E5FF}, {0x1E6C0, 0x1E6DE}, {0x1E6E0, 0x1E6F5},
+ {0x1E6FE, 0x1E6FF}, {0x1E7E0, 0x1E7E6}, {0x1E7E8, 0x1E7EB},
+ {0x1E7ED, 0x1E7EE}, {0x1E7F0, 0x1E7FE}, {0x1E800, 0x1E8C4},
+ {0x1E8C7, 0x1E8D6}, {0x1E900, 0x1E94B}, {0x1E950, 0x1E959},
+ {0x1E95E, 0x1E95F}, {0x1EC71, 0x1ECB4}, {0x1ED01, 0x1ED3D},
+ {0x1EE00, 0x1EE03}, {0x1EE05, 0x1EE1F}, {0x1EE21, 0x1EE22},
+ {0x1EE24, 0x1EE24}, {0x1EE27, 0x1EE27}, {0x1EE29, 0x1EE32},
+ {0x1EE34, 0x1EE37}, {0x1EE39, 0x1EE39}, {0x1EE3B, 0x1EE3B},
+ {0x1EE42, 0x1EE42}, {0x1EE47, 0x1EE47}, {0x1EE49, 0x1EE49},
+ {0x1EE4B, 0x1EE4B}, {0x1EE4D, 0x1EE4F}, {0x1EE51, 0x1EE52},
+ {0x1EE54, 0x1EE54}, {0x1EE57, 0x1EE57}, {0x1EE59, 0x1EE59},
+ {0x1EE5B, 0x1EE5B}, {0x1EE5D, 0x1EE5D}, {0x1EE5F, 0x1EE5F},
+ {0x1EE61, 0x1EE62}, {0x1EE64, 0x1EE64}, {0x1EE67, 0x1EE6A},
+ {0x1EE6C, 0x1EE72}, {0x1EE74, 0x1EE77}, {0x1EE79, 0x1EE7C},
+ {0x1EE7E, 0x1EE7E}, {0x1EE80, 0x1EE89}, {0x1EE8B, 0x1EE9B},
+ {0x1EEA1, 0x1EEA3}, {0x1EEA5, 0x1EEA9}, {0x1EEAB, 0x1EEBB},
+ {0x1EEF0, 0x1EEF1}, {0x1F000, 0x1F003}, {0x1F005, 0x1F02B},
+ {0x1F030, 0x1F093}, {0x1F0A0, 0x1F0AE}, {0x1F0B1, 0x1F0BF},
+ {0x1F0C1, 0x1F0CE}, {0x1F0D1, 0x1F0F5}, {0x1F10B, 0x1F10F},
+ {0x1F12E, 0x1F12F}, {0x1F16A, 0x1F16F}, {0x1F1AD, 0x1F1AD},
+ {0x1F1E6, 0x1F1FF}, {0x1F321, 0x1F32C}, {0x1F336, 0x1F336},
+ {0x1F37D, 0x1F37D}, {0x1F394, 0x1F39F}, {0x1F3CB, 0x1F3CE},
+ {0x1F3D4, 0x1F3DF}, {0x1F3F1, 0x1F3F3}, {0x1F3F5, 0x1F3F7},
+ {0x1F43F, 0x1F43F}, {0x1F441, 0x1F441}, {0x1F4FD, 0x1F4FE},
+ {0x1F53E, 0x1F54A}, {0x1F54F, 0x1F54F}, {0x1F568, 0x1F579},
+ {0x1F57B, 0x1F594}, {0x1F597, 0x1F5A3}, {0x1F5A5, 0x1F5FA},
+ {0x1F650, 0x1F67F}, {0x1F6C6, 0x1F6CB}, {0x1F6CD, 0x1F6CF},
+ {0x1F6D3, 0x1F6D4}, {0x1F6E0, 0x1F6EA}, {0x1F6F0, 0x1F6F3},
+ {0x1F700, 0x1F7D9}, {0x1F800, 0x1F80B}, {0x1F810, 0x1F847},
{0x1F850, 0x1F859}, {0x1F860, 0x1F887}, {0x1F890, 0x1F8AD},
- {0x1F8B0, 0x1F8B1}, {0x1F900, 0x1F90B}, {0x1F93B, 0x1F93B},
- {0x1F946, 0x1F946}, {0x1FA00, 0x1FA53}, {0x1FA60, 0x1FA6D},
- {0x1FB00, 0x1FB92}, {0x1FB94, 0x1FBCA}, {0x1FBF0, 0x1FBF9},
- {0xE0001, 0xE0001}, {0xE0020, 0xE007F},
+ {0x1F8B0, 0x1F8BB}, {0x1F8C0, 0x1F8C1}, {0x1F8D0, 0x1F8D8},
+ {0x1F900, 0x1F90B}, {0x1F93B, 0x1F93B}, {0x1F946, 0x1F946},
+ {0x1FA00, 0x1FA57}, {0x1FA60, 0x1FA6D}, {0x1FB00, 0x1FB92},
+ {0x1FB94, 0x1FBFA}, {0xE0001, 0xE0001}, {0xE0020, 0xE007F},
}
var emoji = table{
{0x203C, 0x203C}, {0x2049, 0x2049}, {0x2122, 0x2122},
{0x2139, 0x2139}, {0x2194, 0x2199}, {0x21A9, 0x21AA},
- {0x231A, 0x231B}, {0x2328, 0x2328}, {0x2388, 0x2388},
- {0x23CF, 0x23CF}, {0x23E9, 0x23F3}, {0x23F8, 0x23FA},
- {0x24C2, 0x24C2}, {0x25AA, 0x25AB}, {0x25B6, 0x25B6},
- {0x25C0, 0x25C0}, {0x25FB, 0x25FE}, {0x2600, 0x2605},
- {0x2607, 0x2612}, {0x2614, 0x2685}, {0x2690, 0x2705},
- {0x2708, 0x2712}, {0x2714, 0x2714}, {0x2716, 0x2716},
- {0x271D, 0x271D}, {0x2721, 0x2721}, {0x2728, 0x2728},
- {0x2733, 0x2734}, {0x2744, 0x2744}, {0x2747, 0x2747},
- {0x274C, 0x274C}, {0x274E, 0x274E}, {0x2753, 0x2755},
- {0x2757, 0x2757}, {0x2763, 0x2767}, {0x2795, 0x2797},
- {0x27A1, 0x27A1}, {0x27B0, 0x27B0}, {0x27BF, 0x27BF},
- {0x2934, 0x2935}, {0x2B05, 0x2B07}, {0x2B1B, 0x2B1C},
- {0x2B50, 0x2B50}, {0x2B55, 0x2B55}, {0x3030, 0x3030},
- {0x303D, 0x303D}, {0x3297, 0x3297}, {0x3299, 0x3299},
- {0x1F000, 0x1F0FF}, {0x1F10D, 0x1F10F}, {0x1F12F, 0x1F12F},
- {0x1F16C, 0x1F171}, {0x1F17E, 0x1F17F}, {0x1F18E, 0x1F18E},
- {0x1F191, 0x1F19A}, {0x1F1AD, 0x1F1E5}, {0x1F201, 0x1F20F},
- {0x1F21A, 0x1F21A}, {0x1F22F, 0x1F22F}, {0x1F232, 0x1F23A},
- {0x1F23C, 0x1F23F}, {0x1F249, 0x1F3FA}, {0x1F400, 0x1F53D},
- {0x1F546, 0x1F64F}, {0x1F680, 0x1F6FF}, {0x1F774, 0x1F77F},
- {0x1F7D5, 0x1F7FF}, {0x1F80C, 0x1F80F}, {0x1F848, 0x1F84F},
- {0x1F85A, 0x1F85F}, {0x1F888, 0x1F88F}, {0x1F8AE, 0x1F8FF},
- {0x1F90C, 0x1F93A}, {0x1F93C, 0x1F945}, {0x1F947, 0x1FAFF},
+ {0x231A, 0x231B}, {0x2328, 0x2328}, {0x23CF, 0x23CF},
+ {0x23E9, 0x23F3}, {0x23F8, 0x23FA}, {0x24C2, 0x24C2},
+ {0x25AA, 0x25AB}, {0x25B6, 0x25B6}, {0x25C0, 0x25C0},
+ {0x25FB, 0x25FE}, {0x2600, 0x2604}, {0x260E, 0x260E},
+ {0x2611, 0x2611}, {0x2614, 0x2615}, {0x2618, 0x2618},
+ {0x261D, 0x261D}, {0x2620, 0x2620}, {0x2622, 0x2623},
+ {0x2626, 0x2626}, {0x262A, 0x262A}, {0x262E, 0x262F},
+ {0x2638, 0x263A}, {0x2640, 0x2640}, {0x2642, 0x2642},
+ {0x2648, 0x2653}, {0x265F, 0x2660}, {0x2663, 0x2663},
+ {0x2665, 0x2666}, {0x2668, 0x2668}, {0x267B, 0x267B},
+ {0x267E, 0x267F}, {0x2692, 0x2697}, {0x2699, 0x2699},
+ {0x269B, 0x269C}, {0x26A0, 0x26A1}, {0x26A7, 0x26A7},
+ {0x26AA, 0x26AB}, {0x26B0, 0x26B1}, {0x26BD, 0x26BE},
+ {0x26C4, 0x26C5}, {0x26C8, 0x26C8}, {0x26CE, 0x26CF},
+ {0x26D1, 0x26D1}, {0x26D3, 0x26D4}, {0x26E9, 0x26EA},
+ {0x26F0, 0x26F5}, {0x26F7, 0x26FA}, {0x26FD, 0x26FD},
+ {0x2702, 0x2702}, {0x2705, 0x2705}, {0x2708, 0x270D},
+ {0x270F, 0x270F}, {0x2712, 0x2712}, {0x2714, 0x2714},
+ {0x2716, 0x2716}, {0x271D, 0x271D}, {0x2721, 0x2721},
+ {0x2728, 0x2728}, {0x2733, 0x2734}, {0x2744, 0x2744},
+ {0x2747, 0x2747}, {0x274C, 0x274C}, {0x274E, 0x274E},
+ {0x2753, 0x2755}, {0x2757, 0x2757}, {0x2763, 0x2764},
+ {0x2795, 0x2797}, {0x27A1, 0x27A1}, {0x27B0, 0x27B0},
+ {0x27BF, 0x27BF}, {0x2934, 0x2935}, {0x2B05, 0x2B07},
+ {0x2B1B, 0x2B1C}, {0x2B50, 0x2B50}, {0x2B55, 0x2B55},
+ {0x3030, 0x3030}, {0x303D, 0x303D}, {0x3297, 0x3297},
+ {0x3299, 0x3299}, {0x1F004, 0x1F004}, {0x1F02C, 0x1F02F},
+ {0x1F094, 0x1F09F}, {0x1F0AF, 0x1F0B0}, {0x1F0C0, 0x1F0C0},
+ {0x1F0CF, 0x1F0D0}, {0x1F0F6, 0x1F0FF}, {0x1F170, 0x1F171},
+ {0x1F17E, 0x1F17F}, {0x1F18E, 0x1F18E}, {0x1F191, 0x1F19A},
+ {0x1F1AE, 0x1F1E5}, {0x1F201, 0x1F20F}, {0x1F21A, 0x1F21A},
+ {0x1F22F, 0x1F22F}, {0x1F232, 0x1F23A}, {0x1F23C, 0x1F23F},
+ {0x1F249, 0x1F25F}, {0x1F266, 0x1F321}, {0x1F324, 0x1F393},
+ {0x1F396, 0x1F397}, {0x1F399, 0x1F39B}, {0x1F39E, 0x1F3F0},
+ {0x1F3F3, 0x1F3F5}, {0x1F3F7, 0x1F3FA}, {0x1F400, 0x1F4FD},
+ {0x1F4FF, 0x1F53D}, {0x1F549, 0x1F54E}, {0x1F550, 0x1F567},
+ {0x1F56F, 0x1F570}, {0x1F573, 0x1F57A}, {0x1F587, 0x1F587},
+ {0x1F58A, 0x1F58D}, {0x1F590, 0x1F590}, {0x1F595, 0x1F596},
+ {0x1F5A4, 0x1F5A5}, {0x1F5A8, 0x1F5A8}, {0x1F5B1, 0x1F5B2},
+ {0x1F5BC, 0x1F5BC}, {0x1F5C2, 0x1F5C4}, {0x1F5D1, 0x1F5D3},
+ {0x1F5DC, 0x1F5DE}, {0x1F5E1, 0x1F5E1}, {0x1F5E3, 0x1F5E3},
+ {0x1F5E8, 0x1F5E8}, {0x1F5EF, 0x1F5EF}, {0x1F5F3, 0x1F5F3},
+ {0x1F5FA, 0x1F64F}, {0x1F680, 0x1F6C5}, {0x1F6CB, 0x1F6D2},
+ {0x1F6D5, 0x1F6E5}, {0x1F6E9, 0x1F6E9}, {0x1F6EB, 0x1F6F0},
+ {0x1F6F3, 0x1F6FF}, {0x1F7DA, 0x1F7FF}, {0x1F80C, 0x1F80F},
+ {0x1F848, 0x1F84F}, {0x1F85A, 0x1F85F}, {0x1F888, 0x1F88F},
+ {0x1F8AE, 0x1F8AF}, {0x1F8BC, 0x1F8BF}, {0x1F8C2, 0x1F8CF},
+ {0x1F8D9, 0x1F8FF}, {0x1F90C, 0x1F93A}, {0x1F93C, 0x1F945},
+ {0x1F947, 0x1F9FF}, {0x1FA58, 0x1FA5F}, {0x1FA6E, 0x1FAFF},
{0x1FC00, 0x1FFFD},
}
diff --git a/vendor/github.com/mattn/go-runewidth/runewidth_windows.go b/vendor/github.com/mattn/go-runewidth/runewidth_windows.go
index 5f987a310..951500a24 100644
--- a/vendor/github.com/mattn/go-runewidth/runewidth_windows.go
+++ b/vendor/github.com/mattn/go-runewidth/runewidth_windows.go
@@ -4,6 +4,7 @@
package runewidth
import (
+ "os"
"syscall"
)
@@ -14,6 +15,11 @@ var (
// IsEastAsian return true if the current locale is CJK
func IsEastAsian() bool {
+ if os.Getenv("WT_SESSION") != "" {
+ // Windows Terminal always not use East Asian Ambiguous Width(s).
+ return false
+ }
+
r1, _, _ := procGetConsoleOutputCP.Call()
if r1 == 0 {
return false
diff --git a/vendor/github.com/mgechev/revive/config/config.go b/vendor/github.com/mgechev/revive/config/config.go
index 224644479..d01f409c5 100644
--- a/vendor/github.com/mgechev/revive/config/config.go
+++ b/vendor/github.com/mgechev/revive/config/config.go
@@ -1,4 +1,4 @@
-// Package config implements revive's configuration data structures and related methods
+// Package config implements revive's configuration data structures and related methods.
package config
import (
@@ -116,6 +116,9 @@ var allRules = append([]lint.Rule{
&rule.InefficientMapLookupRule{},
&rule.ForbiddenCallInWgGoRule{},
&rule.UnnecessaryIfRule{},
+ &rule.EpochNamingRule{},
+ &rule.UseSlicesSort{},
+ &rule.PackageNamingRule{},
}, defaultRules...)
// allFormatters is a list of all available formatters to output the linting results.
@@ -186,12 +189,8 @@ func actualRuleName(name string) string {
}
}
-func parseConfig(path string, config *lint.Config) error {
- file, err := os.ReadFile(path)
- if err != nil {
- return errors.New("cannot read the config file")
- }
- err = toml.Unmarshal(file, config)
+func parseConfig(data []byte, config *lint.Config) error {
+ err := toml.Unmarshal(data, config)
if err != nil {
return fmt.Errorf("cannot parse the config file: %w", err)
}
@@ -206,6 +205,13 @@ func parseConfig(path string, config *lint.Config) error {
return nil
}
+func validateConfig(config *lint.Config) error {
+ if config.EnableAllRules && config.EnableDefaultRules {
+ return errors.New("config options enableAllRules and enableDefaultRules cannot be combined")
+ }
+ return nil
+}
+
func normalizeConfig(config *lint.Config) {
if len(config.Rules) == 0 {
config.Rules = map[string]lint.RuleConfig{}
@@ -251,7 +257,11 @@ func GetConfig(configPath string) (*lint.Config, error) {
switch {
case configPath != "":
config.Confidence = defaultConfidence
- err := parseConfig(configPath, config)
+ data, err := os.ReadFile(configPath) //nolint:gosec // ignore G304: potential file inclusion via variable
+ if err != nil {
+ return nil, errors.New("cannot read the config file")
+ }
+ err = parseConfig(data, config)
if err != nil {
return nil, err
}
@@ -260,6 +270,10 @@ func GetConfig(configPath string) (*lint.Config, error) {
config = defaultConfig()
}
+ if err := validateConfig(config); err != nil {
+ return nil, err
+ }
+
normalizeConfig(config)
return config, nil
}
diff --git a/vendor/github.com/mgechev/revive/formatter/checkstyle.go b/vendor/github.com/mgechev/revive/formatter/checkstyle.go
index 1fb17d4d9..1df1f5573 100644
--- a/vendor/github.com/mgechev/revive/formatter/checkstyle.go
+++ b/vendor/github.com/mgechev/revive/formatter/checkstyle.go
@@ -8,7 +8,7 @@ import (
"github.com/mgechev/revive/lint"
)
-// Checkstyle is an implementation of the Formatter interface
+// Checkstyle is an implementation of the [lint.Formatter] interface
// which formats the errors to Checkstyle-like format.
type Checkstyle struct {
Metadata lint.FormatterMetadata
diff --git a/vendor/github.com/mgechev/revive/formatter/default.go b/vendor/github.com/mgechev/revive/formatter/default.go
index ffb9d5f3f..b6a6af223 100644
--- a/vendor/github.com/mgechev/revive/formatter/default.go
+++ b/vendor/github.com/mgechev/revive/formatter/default.go
@@ -7,7 +7,7 @@ import (
"github.com/mgechev/revive/lint"
)
-// Default is an implementation of the Formatter interface
+// Default is an implementation of the [lint.Formatter] interface
// which formats the errors to text.
type Default struct {
Metadata lint.FormatterMetadata
@@ -23,7 +23,10 @@ func (*Default) Format(failures <-chan lint.Failure, _ lint.Config) (string, err
var buf bytes.Buffer
prefix := ""
for failure := range failures {
- fmt.Fprintf(&buf, "%s%v: %s", prefix, failure.Position.Start, failure.Failure)
+ _, err := fmt.Fprintf(&buf, "%s%v: %s", prefix, failure.Position.Start, failure.Failure)
+ if err != nil {
+ return "", err
+ }
prefix = "\n"
}
return buf.String(), nil
diff --git a/vendor/github.com/mgechev/revive/formatter/friendly.go b/vendor/github.com/mgechev/revive/formatter/friendly.go
index de24df887..cb1afcb3d 100644
--- a/vendor/github.com/mgechev/revive/formatter/friendly.go
+++ b/vendor/github.com/mgechev/revive/formatter/friendly.go
@@ -14,8 +14,8 @@ import (
"github.com/mgechev/revive/lint"
)
-// Friendly is an implementation of the Formatter interface
-// which formats the errors to JSON.
+// Friendly is an implementation of the [lint.Formatter] interface
+// which formats the errors to a friendly, human-readable format.
type Friendly struct {
Metadata lint.FormatterMetadata
}
@@ -32,9 +32,17 @@ func (f *Friendly) Format(failures <-chan lint.Failure, config lint.Config) (str
warningMap := map[string]int{}
totalErrors := 0
totalWarnings := 0
+ warningEmoji := color.YellowString("⚠")
+ errorEmoji := color.RedString("✘")
for failure := range failures {
sev := severity(config, failure)
- f.printFriendlyFailure(&buf, failure, sev)
+ firstCol := warningEmoji
+ if sev == lint.SeverityError {
+ firstCol = errorEmoji
+ }
+ if err := f.printFriendlyFailure(&buf, firstCol, failure); err != nil {
+ return "", err
+ }
switch sev {
case lint.SeverityWarning:
warningMap[failure.RuleName]++
@@ -45,31 +53,38 @@ func (f *Friendly) Format(failures <-chan lint.Failure, config lint.Config) (str
}
}
- f.printSummary(&buf, totalErrors, totalWarnings)
- f.printStatistics(&buf, color.RedString("Errors:"), errorMap)
- f.printStatistics(&buf, color.YellowString("Warnings:"), warningMap)
+ emoji := warningEmoji
+ if totalErrors > 0 {
+ emoji = errorEmoji
+ }
+ if err := f.printSummary(&buf, emoji, totalErrors, totalWarnings); err != nil {
+ return "", err
+ }
+ if err := f.printStatistics(&buf, color.RedString("Errors:"), errorMap); err != nil {
+ return "", err
+ }
+ if err := f.printStatistics(&buf, color.YellowString("Warnings:"), warningMap); err != nil {
+ return "", err
+ }
return buf.String(), nil
}
-func (f *Friendly) printFriendlyFailure(sb *strings.Builder, failure lint.Failure, severity lint.Severity) {
- f.printHeaderRow(sb, failure, severity)
- f.printFilePosition(sb, failure)
- sb.WriteString("\n\n")
+func (f *Friendly) printFriendlyFailure(sb *strings.Builder, firstColumn string, failure lint.Failure) error {
+ f.printHeaderRow(sb, firstColumn, failure)
+ if err := f.printFilePosition(sb, failure); err != nil {
+ return err
+ }
+ _, err := sb.WriteString("\n\n")
+ return err
}
-var errorEmoji = color.RedString("✘")
-var warningEmoji = color.YellowString("⚠")
-
-func (*Friendly) printHeaderRow(sb *strings.Builder, failure lint.Failure, severity lint.Severity) {
- emoji := warningEmoji
- if severity == lint.SeverityError {
- emoji = errorEmoji
- }
- sb.WriteString(table([][]string{{emoji, ruleDescriptionURL(failure.RuleName), color.GreenString(failure.Failure)}}))
+func (*Friendly) printHeaderRow(sb *strings.Builder, firstColumn string, failure lint.Failure) {
+ sb.WriteString(table([][]string{{firstColumn, ruleDescriptionURL(failure.RuleName), color.GreenString(failure.Failure)}}))
}
-func (*Friendly) printFilePosition(sb *strings.Builder, failure lint.Failure) {
- fmt.Fprintf(sb, " %s:%d:%d", failure.Filename(), failure.Position.Start.Line, failure.Position.Start.Column)
+func (*Friendly) printFilePosition(sb *strings.Builder, failure lint.Failure) error {
+ _, err := fmt.Fprintf(sb, " %s:%d:%d", failure.Filename(), failure.Position.Start.Line, failure.Position.Start.Column)
+ return err
}
type statEntry struct {
@@ -77,11 +92,7 @@ type statEntry struct {
failures int
}
-func (*Friendly) printSummary(w io.Writer, errors, warnings int) {
- emoji := warningEmoji
- if errors > 0 {
- emoji = errorEmoji
- }
+func (*Friendly) printSummary(w io.Writer, firstColumn string, errors, warnings int) error {
problemsLabel := "problems"
if errors+warnings == 1 {
problemsLabel = "problem"
@@ -96,18 +107,19 @@ func (*Friendly) printSummary(w io.Writer, errors, warnings int) {
}
str := fmt.Sprintf("%d %s (%d %s, %d %s)", errors+warnings, problemsLabel, errors, errorsLabel, warnings, warningsLabel)
if errors > 0 {
- fmt.Fprintf(w, "%s %s\n\n", emoji, color.RedString(str))
- return
+ _, err := fmt.Fprintf(w, "%s %s\n\n", firstColumn, color.RedString(str))
+ return err
}
if warnings > 0 {
- fmt.Fprintf(w, "%s %s\n\n", emoji, color.YellowString(str))
- return
+ _, err := fmt.Fprintf(w, "%s %s\n\n", firstColumn, color.YellowString(str))
+ return err
}
+ return nil
}
-func (*Friendly) printStatistics(w io.Writer, header string, stats map[string]int) {
+func (*Friendly) printStatistics(w io.Writer, header string, stats map[string]int) error {
if len(stats) == 0 {
- return
+ return nil
}
data := make([]statEntry, 0, len(stats))
for name, total := range stats {
@@ -120,20 +132,28 @@ func (*Friendly) printStatistics(w io.Writer, header string, stats map[string]in
for _, entry := range data {
formatted = append(formatted, []string{color.GreenString(fmt.Sprintf("%d", entry.failures)), entry.name})
}
- fmt.Fprintln(w, header)
- fmt.Fprintln(w, table(formatted))
+ if _, err := fmt.Fprintln(w, header); err != nil {
+ return err
+ }
+ if _, err := fmt.Fprintln(w, table(formatted)); err != nil {
+ return err
+ }
+ return nil
}
func table(rows [][]string) string {
var buf bytes.Buffer
tw := tabwriter.NewWriter(&buf, 0, 0, 2, ' ', 0)
for _, row := range rows {
- tw.Write([]byte{'\t'})
- for _, col := range row {
- tw.Write(append([]byte(col), '\t'))
+ _, _ = tw.Write([]byte{'\t'})
+ for i, col := range row {
+ _, _ = tw.Write([]byte(col))
+ if i < len(row)-1 {
+ _, _ = tw.Write([]byte{'\t'})
+ }
}
- tw.Write([]byte{'\n'})
+ _, _ = tw.Write([]byte{'\n'})
}
- tw.Flush()
+ _ = tw.Flush()
return buf.String()
}
diff --git a/vendor/github.com/mgechev/revive/formatter/json.go b/vendor/github.com/mgechev/revive/formatter/json.go
index 292c06b36..46a61980c 100644
--- a/vendor/github.com/mgechev/revive/formatter/json.go
+++ b/vendor/github.com/mgechev/revive/formatter/json.go
@@ -6,7 +6,7 @@ import (
"github.com/mgechev/revive/lint"
)
-// JSON is an implementation of the Formatter interface
+// JSON is an implementation of the [lint.Formatter] interface
// which formats the errors to JSON.
type JSON struct {
Metadata lint.FormatterMetadata
@@ -19,7 +19,8 @@ func (*JSON) Name() string {
// jsonObject defines a JSON object of an failure.
type jsonObject struct {
- Severity lint.Severity `json:"Severity"`
+ Severity lint.Severity `json:"Severity"`
+ //nolint:embeddedstructfieldcheck // backward compatibility
lint.Failure `json:",inline"`
}
diff --git a/vendor/github.com/mgechev/revive/formatter/ndjson.go b/vendor/github.com/mgechev/revive/formatter/ndjson.go
index 66acff320..f80b5bcbc 100644
--- a/vendor/github.com/mgechev/revive/formatter/ndjson.go
+++ b/vendor/github.com/mgechev/revive/formatter/ndjson.go
@@ -7,7 +7,7 @@ import (
"github.com/mgechev/revive/lint"
)
-// NDJSON is an implementation of the Formatter interface
+// NDJSON is an implementation of the [lint.Formatter] interface
// which formats the errors to NDJSON stream.
type NDJSON struct {
Metadata lint.FormatterMetadata
diff --git a/vendor/github.com/mgechev/revive/formatter/plain.go b/vendor/github.com/mgechev/revive/formatter/plain.go
index 6c77926ea..80dede3a1 100644
--- a/vendor/github.com/mgechev/revive/formatter/plain.go
+++ b/vendor/github.com/mgechev/revive/formatter/plain.go
@@ -7,8 +7,8 @@ import (
"github.com/mgechev/revive/lint"
)
-// Plain is an implementation of the Formatter interface
-// which formats the errors to JSON.
+// Plain is an implementation of the [lint.Formatter] interface
+// which formats the errors to plain text.
type Plain struct {
Metadata lint.FormatterMetadata
}
@@ -22,7 +22,10 @@ func (*Plain) Name() string {
func (*Plain) Format(failures <-chan lint.Failure, _ lint.Config) (string, error) {
var sb strings.Builder
for failure := range failures {
- sb.WriteString(fmt.Sprintf("%v: %s %s\n", failure.Position.Start, failure.Failure, ruleDescriptionURL(failure.RuleName)))
+ _, err := fmt.Fprintf(&sb, "%v: %s %s\n", failure.Position.Start, failure.Failure, ruleDescriptionURL(failure.RuleName))
+ if err != nil {
+ return "", err
+ }
}
return sb.String(), nil
}
diff --git a/vendor/github.com/mgechev/revive/formatter/sarif.go b/vendor/github.com/mgechev/revive/formatter/sarif.go
index c17764902..cb1a97294 100644
--- a/vendor/github.com/mgechev/revive/formatter/sarif.go
+++ b/vendor/github.com/mgechev/revive/formatter/sarif.go
@@ -10,7 +10,7 @@ import (
"github.com/mgechev/revive/lint"
)
-// Sarif is an implementation of the Formatter interface
+// Sarif is an implementation of the [lint.Formatter] interface
// which formats revive failures into SARIF format.
type Sarif struct {
Metadata lint.FormatterMetadata
@@ -32,13 +32,17 @@ func (*Sarif) Format(failures <-chan lint.Failure, cfg lint.Config) (string, err
}
buf := new(bytes.Buffer)
- sarifLog.PrettyWrite(buf)
+ err := sarifLog.PrettyWrite(buf)
+ if err != nil {
+ return "", err
+ }
return buf.String(), nil
}
type reviveRunLog struct {
*garif.LogFile
+
run *garif.Run
rules map[string]lint.RuleConfig
}
diff --git a/vendor/github.com/mgechev/revive/formatter/stylish.go b/vendor/github.com/mgechev/revive/formatter/stylish.go
index 8185e8b8a..100a7927b 100644
--- a/vendor/github.com/mgechev/revive/formatter/stylish.go
+++ b/vendor/github.com/mgechev/revive/formatter/stylish.go
@@ -2,18 +2,21 @@ package formatter
import (
"fmt"
+ "slices"
"github.com/fatih/color"
"github.com/mgechev/revive/lint"
)
-// Stylish is an implementation of the Formatter interface
-// which formats the errors to JSON.
+// Stylish is an implementation of the [lint.Formatter] interface
+// which formats the errors to a stylish, human-readable format.
type Stylish struct {
Metadata lint.FormatterMetadata
}
+var _ lint.Formatter = (*Stylish)(nil)
+
// Name returns the name of the formatter.
func (*Stylish) Name() string {
return "stylish"
@@ -43,24 +46,27 @@ func (*Stylish) Format(failures <-chan lint.Failure, config lint.Config) (string
if currentType == lint.SeverityError {
totalErrors++
}
- result = append(result, formatFailure(f, lint.Severity(currentType)))
+ result = append(result, formatFailure(f, currentType))
}
fileReport := map[string][][]string{}
+ var files []string
for _, row := range result {
if _, ok := fileReport[row[0]]; !ok {
fileReport[row[0]] = [][]string{}
+ files = append(files, row[0])
}
fileReport[row[0]] = append(fileReport[row[0]], []string{row[1], row[2], row[3]})
}
+ slices.Sort(files)
output := ""
- for filename, val := range fileReport {
+ for _, filename := range files {
c := color.New(color.Underline)
output += c.SprintfFunc()(filename + "\n")
- output += table(val) + "\n"
+ output += table(fileReport[filename]) + "\n"
}
problemsLabel := "problems"
diff --git a/vendor/github.com/mgechev/revive/formatter/unix.go b/vendor/github.com/mgechev/revive/formatter/unix.go
index dd063a0d8..b79566859 100644
--- a/vendor/github.com/mgechev/revive/formatter/unix.go
+++ b/vendor/github.com/mgechev/revive/formatter/unix.go
@@ -7,8 +7,8 @@ import (
"github.com/mgechev/revive/lint"
)
-// Unix is an implementation of the Formatter interface
-// which formats the errors to a simple line based error format
+// Unix is an implementation of the [lint.Formatter] interface
+// which formats the errors to a simple line based error format:
//
// main.go:24:9: [errorf] should replace errors.New(fmt.Sprintf(...)) with fmt.Errorf(...)
type Unix struct {
@@ -24,7 +24,10 @@ func (*Unix) Name() string {
func (*Unix) Format(failures <-chan lint.Failure, _ lint.Config) (string, error) {
var sb strings.Builder
for failure := range failures {
- sb.WriteString(fmt.Sprintf("%v: [%s] %s\n", failure.Position.Start, failure.RuleName, failure.Failure))
+ _, err := fmt.Fprintf(&sb, "%v: [%s] %s\n", failure.Position.Start, failure.RuleName, failure.Failure)
+ if err != nil {
+ return "", err
+ }
}
return sb.String(), nil
}
diff --git a/vendor/github.com/mgechev/revive/internal/astutils/ast_utils.go b/vendor/github.com/mgechev/revive/internal/astutils/ast_utils.go
index fca3ee5a9..b0fbc5a0d 100644
--- a/vendor/github.com/mgechev/revive/internal/astutils/ast_utils.go
+++ b/vendor/github.com/mgechev/revive/internal/astutils/ast_utils.go
@@ -1,9 +1,9 @@
-// Package astutils provides utility functions for working with AST nodes
+// Package astutils provides utility functions for working with AST nodes.
package astutils
import (
"bytes"
- "crypto/md5"
+ "crypto/md5" //nolint:gosec // G501: Blocklisted import crypto/md5: weak cryptographic primitive
"encoding/hex"
"fmt"
"go/ast"
@@ -16,8 +16,13 @@ import (
// FuncSignatureIs returns true if the given func decl satisfies a signature characterized
// by the given name, parameters types and return types; false otherwise.
//
-// Example: to check if a function declaration has the signature Foo(int, string) (bool,error)
-// call to FuncSignatureIs(funcDecl,"Foo",[]string{"int","string"},[]string{"bool","error"}).
+// Example: To check if a function declaration has the signature
+//
+// Foo(int, string) (bool, error)
+//
+// call to
+//
+// FuncSignatureIs(funcDecl, "Foo", []string{"int", "string"}, []string{"bool", "error"})
func FuncSignatureIs(funcDecl *ast.FuncDecl, wantName string, wantParametersTypes, wantResultsTypes []string) bool {
if wantName != funcDecl.Name.String() {
return false // func name doesn't match expected one
@@ -201,14 +206,14 @@ var gofmtConfig = &printer.Config{Tabwidth: 8}
func GoFmt(x any) string {
buf := bytes.Buffer{}
fs := token.NewFileSet()
- gofmtConfig.Fprint(&buf, fs, x)
+ _ = gofmtConfig.Fprint(&buf, fs, x)
return buf.String()
}
// NodeHash yields the MD5 hash of the given AST node.
func NodeHash(node ast.Node) string {
hasher := func(in string) string {
- binHash := md5.Sum([]byte(in))
+ binHash := md5.Sum([]byte(in)) //nolint:gosec // G401: Weak cryptographic primitive
return hex.EncodeToString(binHash[:])
}
str := GoFmt(node)
diff --git a/vendor/github.com/mgechev/revive/internal/ifelse/branch.go b/vendor/github.com/mgechev/revive/internal/ifelse/branch.go
index 518362781..5acf83840 100644
--- a/vendor/github.com/mgechev/revive/internal/ifelse/branch.go
+++ b/vendor/github.com/mgechev/revive/internal/ifelse/branch.go
@@ -9,11 +9,12 @@ import (
// Branch contains information about a branch within an if-else chain.
type Branch struct {
BranchKind
- Call // The function called at the end for kind Panic or Exit.
+ Call // The function called at the end for kind Panic or Exit.
+
block []ast.Stmt
}
-// BlockBranch gets the Branch of an ast.BlockStmt.
+// BlockBranch gets the Branch of an [ast.BlockStmt].
func BlockBranch(block *ast.BlockStmt) Branch {
blockLen := len(block.List)
if blockLen == 0 {
@@ -25,7 +26,7 @@ func BlockBranch(block *ast.BlockStmt) Branch {
return branch
}
-// StmtBranch gets the Branch of an ast.Stmt.
+// StmtBranch gets the Branch of an [ast.Stmt].
func StmtBranch(stmt ast.Stmt) Branch {
switch stmt := stmt.(type) {
case *ast.ReturnStmt:
diff --git a/vendor/github.com/mgechev/revive/internal/ifelse/doc.go b/vendor/github.com/mgechev/revive/internal/ifelse/doc.go
index 7461b12aa..77d93cd00 100644
--- a/vendor/github.com/mgechev/revive/internal/ifelse/doc.go
+++ b/vendor/github.com/mgechev/revive/internal/ifelse/doc.go
@@ -1,6 +1,6 @@
// Package ifelse provides helpers for analyzing the control flow in if-else chains,
// presently used by the following rules:
-// - early-return
-// - indent-error-flow
-// - superfluous-else
+// - early-return
+// - indent-error-flow
+// - superfluous-else
package ifelse
diff --git a/vendor/github.com/mgechev/revive/internal/ifelse/func.go b/vendor/github.com/mgechev/revive/internal/ifelse/func.go
index 89e251129..cd27cc592 100644
--- a/vendor/github.com/mgechev/revive/internal/ifelse/func.go
+++ b/vendor/github.com/mgechev/revive/internal/ifelse/func.go
@@ -23,7 +23,7 @@ var DeviatingFuncs = map[Call]BranchKind{
{"log", "Panicln"}: Panic,
}
-// ExprCall gets the Call of an ExprStmt, if any.
+// ExprCall gets the [Call] of an [ast.ExprStmt], if any.
func ExprCall(expr *ast.ExprStmt) (Call, bool) {
call, ok := expr.X.(*ast.CallExpr)
if !ok {
diff --git a/vendor/github.com/mgechev/revive/internal/ifelse/rule.go b/vendor/github.com/mgechev/revive/internal/ifelse/rule.go
index 799f8b83d..347487661 100644
--- a/vendor/github.com/mgechev/revive/internal/ifelse/rule.go
+++ b/vendor/github.com/mgechev/revive/internal/ifelse/rule.go
@@ -15,7 +15,7 @@ type CheckFunc func(Chain) (string, bool)
// Apply evaluates the given Rule on if-else chains found within the given AST,
// and returns the failures.
//
-// Note that in if-else chain with multiple "if" blocks, only the *last* one is checked,
+// Note that in if-else chain with multiple "if" blocks, only the "last" one is checked,
// that is to say, given:
//
// if foo {
diff --git a/vendor/github.com/mgechev/revive/internal/syncset/syncset.go b/vendor/github.com/mgechev/revive/internal/syncset/syncset.go
new file mode 100644
index 000000000..8f20e91ca
--- /dev/null
+++ b/vendor/github.com/mgechev/revive/internal/syncset/syncset.go
@@ -0,0 +1,44 @@
+// Package syncset provides a simple, mutex-protected set for strings.
+package syncset
+
+import (
+ "maps"
+ "slices"
+ "sync"
+)
+
+// Set is a concurrency-safe set of strings.
+type Set struct {
+ mu sync.Mutex
+ elements map[string]struct{}
+}
+
+// New returns an initialized, empty Set.
+func New() *Set {
+ return &Set{elements: map[string]struct{}{}}
+}
+
+// AddIfAbsent adds str to the set if it is not already present, and reports whether it was added.
+func (s *Set) AddIfAbsent(str string) bool {
+ s.mu.Lock()
+ defer s.mu.Unlock()
+
+ if s.elements == nil {
+ s.elements = map[string]struct{}{str: {}}
+ return true
+ }
+
+ _, exists := s.elements[str]
+ if !exists {
+ s.elements[str] = struct{}{}
+ }
+ return !exists
+}
+
+// Elements returns a slice of all elements in the set.
+func (s *Set) Elements() []string {
+ s.mu.Lock()
+ defer s.mu.Unlock()
+
+ return slices.Collect(maps.Keys(s.elements))
+}
diff --git a/vendor/github.com/mgechev/revive/lint/config.go b/vendor/github.com/mgechev/revive/lint/config.go
index 3047fd29d..533ce054c 100644
--- a/vendor/github.com/mgechev/revive/lint/config.go
+++ b/vendor/github.com/mgechev/revive/lint/config.go
@@ -15,9 +15,9 @@ type RuleConfig struct {
Arguments Arguments
Severity Severity
Disabled bool
- // Exclude - rule-level file excludes, TOML related (strings)
+ // Exclude is rule-level file excludes, TOML related (strings).
Exclude []string
- // excludeFilters - regex-based file filters, initialized from Exclude
+ // excludeFilters is regex-based file filters, initialized from Exclude.
excludeFilters []*FileFilter
}
diff --git a/vendor/github.com/mgechev/revive/lint/failure.go b/vendor/github.com/mgechev/revive/lint/failure.go
index c25df4836..01ed09115 100644
--- a/vendor/github.com/mgechev/revive/lint/failure.go
+++ b/vendor/github.com/mgechev/revive/lint/failure.go
@@ -72,19 +72,18 @@ type FailurePosition struct {
// Failure defines a struct for a linting failure.
type Failure struct {
- Failure string `json:"Failure"`
- RuleName string `json:"RuleName"`
- Category FailureCategory `json:"Category"`
- Position FailurePosition `json:"Position"`
- Node ast.Node `json:"-"`
- Confidence float64 `json:"Confidence"`
- // For future use
- ReplacementLine string `json:"ReplacementLine"`
+ Failure string `json:"Failure"`
+ RuleName string `json:"RuleName"`
+ Category FailureCategory `json:"Category"`
+ Position FailurePosition `json:"Position"`
+ Node ast.Node `json:"-"`
+ Confidence float64 `json:"Confidence"`
+ ReplacementLine string `json:"ReplacementLine"`
}
// GetFilename returns the filename.
//
-// Deprecated: Use [Filename].
+// Deprecated: Use [Failure.Filename] instead.
func (f *Failure) GetFilename() string {
return f.Filename()
}
diff --git a/vendor/github.com/mgechev/revive/lint/file.go b/vendor/github.com/mgechev/revive/lint/file.go
index bf6aed452..15b7aa850 100644
--- a/vendor/github.com/mgechev/revive/lint/file.go
+++ b/vendor/github.com/mgechev/revive/lint/file.go
@@ -235,9 +235,8 @@ func (f *File) disabledIntervals(rules []Rule, mustSpecifyDisableReason bool, fa
continue
}
ruleNames := []string{}
- tempNames := strings.Split(match[rulesPos], ",")
- for _, name := range tempNames {
+ for name := range strings.SplitSeq(match[rulesPos], ",") {
name = strings.Trim(name, "\n")
if name != "" {
ruleNames = append(ruleNames, name)
@@ -274,7 +273,7 @@ func (f *File) disabledIntervals(rules []Rule, mustSpecifyDisableReason bool, fa
return getEnabledDisabledIntervals()
}
-func (File) filterFailures(failures []Failure, disabledIntervals disabledIntervalsMap) []Failure {
+func (*File) filterFailures(failures []Failure, disabledIntervals disabledIntervalsMap) []Failure {
result := []Failure{}
for _, failure := range failures {
fStart := failure.Position.Start.Line
diff --git a/vendor/github.com/mgechev/revive/lint/filefilter.go b/vendor/github.com/mgechev/revive/lint/filefilter.go
index 9978597f3..3a523f2a5 100644
--- a/vendor/github.com/mgechev/revive/lint/filefilter.go
+++ b/vendor/github.com/mgechev/revive/lint/filefilter.go
@@ -41,6 +41,7 @@ func ParseFileFilter(rawFilter string) (*FileFilter, error) {
return result, nil
}
+// String returns the original raw filter definition as it appears in the configuration.
func (ff *FileFilter) String() string { return ff.raw }
// MatchFileName checks if the file name matches the filter.
diff --git a/vendor/github.com/mgechev/revive/lint/linter.go b/vendor/github.com/mgechev/revive/lint/linter.go
index 2abbb699d..46ae3f9c1 100644
--- a/vendor/github.com/mgechev/revive/lint/linter.go
+++ b/vendor/github.com/mgechev/revive/lint/linter.go
@@ -37,7 +37,7 @@ func New(reader ReadFile, maxOpenFiles int) Linter {
}
}
-func (l Linter) readFile(path string) (result []byte, err error) {
+func (l *Linter) readFile(path string) (result []byte, err error) {
if l.fileReadTokens != nil {
// "take" a token by writing to the channel.
// It will block if no more space in the channel's buffer
@@ -162,7 +162,7 @@ func detectGoMod(dir string) (rootDir string, ver *goversion.Version, err error)
return "", nil, fmt.Errorf("%q doesn't seem to be part of a Go module", dir)
}
- mod, err := os.ReadFile(modFileName)
+ mod, err := os.ReadFile(modFileName) //nolint:gosec // ignore G304: potential file inclusion via variable
if err != nil {
return "", nil, fmt.Errorf("failed to read %q, got %w", modFileName, err)
}
@@ -202,7 +202,7 @@ func retrieveModFile(dir string) (string, error) {
}
// isGenerated reports whether the source file is generated code
-// according the rules from https://golang.org/s/generatedcode.
+// according to the rules from https://go.dev/s/generatedcode.
// This is inherited from the original go lint.
func isGenerated(src []byte) bool {
sc := bufio.NewScanner(bytes.NewReader(src))
diff --git a/vendor/github.com/mgechev/revive/lint/package.go b/vendor/github.com/mgechev/revive/lint/package.go
index cb78cb452..eaaf64134 100644
--- a/vendor/github.com/mgechev/revive/lint/package.go
+++ b/vendor/github.com/mgechev/revive/lint/package.go
@@ -142,7 +142,7 @@ func (p *Package) TypeCheck() error {
return err
}
-// check function encapsulates the call to go/types.Config.Check method and
+// check function encapsulates the call to [go/types.Config.Check] method and
// recovers if the called method panics (see issue #59).
func check(config *types.Config, n string, fset *token.FileSet, astFiles []*ast.File, info *types.Info) (p *types.Package, err error) {
defer func() {
diff --git a/vendor/github.com/mgechev/revive/logging/logger.go b/vendor/github.com/mgechev/revive/logging/logger.go
index 212419f27..12fef0160 100644
--- a/vendor/github.com/mgechev/revive/logging/logger.go
+++ b/vendor/github.com/mgechev/revive/logging/logger.go
@@ -5,33 +5,46 @@ import (
"io"
"log/slog"
"os"
+ "sync"
+ "testing"
)
-const logFile = "revive.log"
+// GetLogger retrieves an instance of an application logger.
+// The log level can be configured via the REVIVE_LOG_LEVEL environment variable.
+// If REVIVE_LOG_LEVEL is unset or empty, logging is disabled.
+// If it is set to an invalid value, the log level defaults to WARN.
+//
+//nolint:unparam // err is always nil, but is included in the signature for future extensibility.
+func GetLogger() (*slog.Logger, error) {
+ return getLogger(), nil
+}
-var logger *slog.Logger
+var getLogger = sync.OnceValue(initLogger(os.Stderr))
-// GetLogger retrieves an instance of an application logger which outputs
-// to a file if the debug flag is enabled.
-func GetLogger() (*slog.Logger, error) {
- if logger != nil {
- return logger, nil
- }
+func initLogger(out io.Writer) func() *slog.Logger {
+ return func() *slog.Logger {
+ logLevel := os.Getenv("REVIVE_LOG_LEVEL")
+ if logLevel == "" {
+ return slog.New(slog.DiscardHandler)
+ }
- debugModeEnabled := os.Getenv("DEBUG") != ""
- if !debugModeEnabled {
- // by default, suppress all logging output
- return slog.New(slog.NewTextHandler(io.Discard, nil)), nil // TODO: change to slog.New(slog.DiscardHandler) when we switch to Go 1.24
- }
+ leveler := &slog.LevelVar{}
+ opts := &slog.HandlerOptions{Level: leveler}
- fileWriter, err := os.Create(logFile)
- if err != nil {
- return nil, err
- }
+ level := slog.LevelWarn
+ _ = level.UnmarshalText([]byte(logLevel)) // Ignore error and default to WARN if invalid
+ leveler.Set(level)
+ logger := slog.New(slog.NewTextHandler(out, opts))
- logger = slog.New(slog.NewTextHandler(io.MultiWriter(os.Stderr, fileWriter), nil))
+ logger.Info("Logger initialized", "logLevel", logLevel)
- logger.Info("Logger initialized", "logFile", logFile)
+ return logger
+ }
+}
- return logger, nil
+// InitForTesting initializes the logger singleton cache for testing purposes.
+// This function should only be called in tests.
+func InitForTesting(tb testing.TB, out io.Writer) {
+ tb.Helper()
+ getLogger = sync.OnceValue(initLogger(out))
}
diff --git a/vendor/github.com/mgechev/revive/rule/add_constant.go b/vendor/github.com/mgechev/revive/rule/add_constant.go
index 90abd4e62..d0770a104 100644
--- a/vendor/github.com/mgechev/revive/rule/add_constant.go
+++ b/vendor/github.com/mgechev/revive/rule/add_constant.go
@@ -25,8 +25,7 @@ func newAllowList() allowList {
}
func (wl allowList) add(kind, list string) {
- elems := strings.Split(list, ",")
- for _, e := range elems {
+ for e := range strings.SplitSeq(list, ",") {
wl[kind][e] = true
}
}
@@ -247,7 +246,7 @@ func (r *AddConstantRule) Configure(arguments lint.Arguments) error {
return fmt.Errorf("invalid argument to the ignoreFuncs parameter of add-constant rule, string expected. Got '%v' (%T)", v, v)
}
- for _, exclude := range strings.Split(excludes, ",") {
+ for exclude := range strings.SplitSeq(excludes, ",") {
exclude = strings.Trim(exclude, " ")
if exclude == "" {
return errors.New("invalid argument to the ignoreFuncs parameter of add-constant rule, expected regular expression must not be empty")
diff --git a/vendor/github.com/mgechev/revive/rule/banned_characters.go b/vendor/github.com/mgechev/revive/rule/banned_characters.go
index 228156bb4..b113c8db9 100644
--- a/vendor/github.com/mgechev/revive/rule/banned_characters.go
+++ b/vendor/github.com/mgechev/revive/rule/banned_characters.go
@@ -20,10 +20,6 @@ const bannedCharsRuleName = "banned-characters"
// Configuration implements the [lint.ConfigurableRule] interface.
func (r *BannedCharsRule) Configure(arguments lint.Arguments) error {
if len(arguments) > 0 {
- err := checkNumberOfArguments(1, arguments, bannedCharsRuleName)
- if err != nil {
- return err
- }
list, err := r.getBannedCharsList(arguments)
if err != nil {
return err
diff --git a/vendor/github.com/mgechev/revive/rule/bool_literal_in_expr.go b/vendor/github.com/mgechev/revive/rule/bool_literal_in_expr.go
index c510ecc3e..f6c8cbc61 100644
--- a/vendor/github.com/mgechev/revive/rule/bool_literal_in_expr.go
+++ b/vendor/github.com/mgechev/revive/rule/bool_literal_in_expr.go
@@ -7,7 +7,7 @@ import (
"github.com/mgechev/revive/lint"
)
-// BoolLiteralRule warns when logic expressions contains Boolean literals.
+// BoolLiteralRule warns when logic expressions contain boolean literals.
type BoolLiteralRule struct{}
// Apply applies the rule to given file.
@@ -61,7 +61,7 @@ func (w *lintBoolLiteral) Visit(node ast.Node) ast.Visitor {
return w
}
-func (w lintBoolLiteral) addFailure(node ast.Node, msg string, cat lint.FailureCategory) {
+func (w *lintBoolLiteral) addFailure(node ast.Node, msg string, cat lint.FailureCategory) {
w.onFailure(lint.Failure{
Confidence: 1,
Node: node,
diff --git a/vendor/github.com/mgechev/revive/rule/cognitive_complexity.go b/vendor/github.com/mgechev/revive/rule/cognitive_complexity.go
index 901fc60be..d9937713e 100644
--- a/vendor/github.com/mgechev/revive/rule/cognitive_complexity.go
+++ b/vendor/github.com/mgechev/revive/rule/cognitive_complexity.go
@@ -95,7 +95,7 @@ func (v *cognitiveComplexityVisitor) subTreeComplexity(n ast.Node) int {
return v.complexity
}
-// Visit implements the ast.Visitor interface.
+// Visit implements the [ast.Visitor] interface.
func (v *cognitiveComplexityVisitor) Visit(n ast.Node) ast.Visitor {
switch n := n.(type) {
case *ast.IfStmt:
diff --git a/vendor/github.com/mgechev/revive/rule/comment_spacings.go b/vendor/github.com/mgechev/revive/rule/comment_spacings.go
index 0c35fe392..d28bce04f 100644
--- a/vendor/github.com/mgechev/revive/rule/comment_spacings.go
+++ b/vendor/github.com/mgechev/revive/rule/comment_spacings.go
@@ -7,8 +7,8 @@ import (
"github.com/mgechev/revive/lint"
)
-// CommentSpacingsRule check whether there is a space between
-// the comment symbol( // ) and the start of the comment text.
+// CommentSpacingsRule checks whether there is a space between
+// the comment symbol // and the start of the comment text.
type CommentSpacingsRule struct {
allowList []string
}
diff --git a/vendor/github.com/mgechev/revive/rule/confusing_naming.go b/vendor/github.com/mgechev/revive/rule/confusing_naming.go
index 83f53a596..ef78b60a7 100644
--- a/vendor/github.com/mgechev/revive/rule/confusing_naming.go
+++ b/vendor/github.com/mgechev/revive/rule/confusing_naming.go
@@ -70,7 +70,8 @@ func (*ConfusingNamingRule) Name() string {
return "confusing-naming"
}
-// checkMethodName checks if a given method/function name is similar (just case differences) to other method/function of the same struct/file.
+// checkMethodName checks if a given method/function name is similar (just case differences) to other method/function
+// of the same struct/file.
func checkMethodName(holder string, id *ast.Ident, w *lintConfusingNames) {
if id.Name == "init" && holder == defaultStructName {
// ignore init functions
diff --git a/vendor/github.com/mgechev/revive/rule/context_as_argument.go b/vendor/github.com/mgechev/revive/rule/context_as_argument.go
index 5a3e2cf69..588bbabf0 100644
--- a/vendor/github.com/mgechev/revive/rule/context_as_argument.go
+++ b/vendor/github.com/mgechev/revive/rule/context_as_argument.go
@@ -9,7 +9,7 @@ import (
"github.com/mgechev/revive/lint"
)
-// ContextAsArgumentRule suggests that `context.Context` should be the first argument of a function.
+// ContextAsArgumentRule suggests that [context.Context] should be the first argument of a function.
type ContextAsArgumentRule struct {
allowTypes map[string]struct{}
}
diff --git a/vendor/github.com/mgechev/revive/rule/context_keys_type.go b/vendor/github.com/mgechev/revive/rule/context_keys_type.go
index 562f31b22..98f631ee9 100644
--- a/vendor/github.com/mgechev/revive/rule/context_keys_type.go
+++ b/vendor/github.com/mgechev/revive/rule/context_keys_type.go
@@ -9,7 +9,7 @@ import (
"github.com/mgechev/revive/lint"
)
-// ContextKeysType disallows the usage of basic types in `context.WithValue`.
+// ContextKeysType disallows the usage of basic types in [context.WithValue].
type ContextKeysType struct{}
// Apply applies the rule to given file.
diff --git a/vendor/github.com/mgechev/revive/rule/cyclomatic.go b/vendor/github.com/mgechev/revive/rule/cyclomatic.go
index 088c45c85..6025b65e8 100644
--- a/vendor/github.com/mgechev/revive/rule/cyclomatic.go
+++ b/vendor/github.com/mgechev/revive/rule/cyclomatic.go
@@ -99,7 +99,7 @@ type complexityVisitor struct {
Complexity int
}
-// Visit implements the ast.Visitor interface.
+// Visit implements the [ast.Visitor] interface.
func (v *complexityVisitor) Visit(n ast.Node) ast.Visitor {
switch n := n.(type) {
case *ast.FuncDecl, *ast.IfStmt, *ast.ForStmt, *ast.RangeStmt, *ast.CaseClause, *ast.CommClause:
diff --git a/vendor/github.com/mgechev/revive/rule/datarace.go b/vendor/github.com/mgechev/revive/rule/datarace.go
index de63c068d..fd2dcdf2b 100644
--- a/vendor/github.com/mgechev/revive/rule/datarace.go
+++ b/vendor/github.com/mgechev/revive/rule/datarace.go
@@ -11,7 +11,8 @@ import (
//nolint:staticcheck // TODO: ast.Object is deprecated
type nodeUID *ast.Object // type of the unique id for AST nodes
-// DataRaceRule lints assignments to value method-receivers.
+// DataRaceRule spots potential dataraces caused by goroutines capturing (by-reference)
+// particular identifiers of the function from which goroutines are created.
type DataRaceRule struct{}
// Apply applies the rule to given file.
@@ -65,7 +66,6 @@ func (*DataRaceRule) extractReturnIDs(fields []*ast.Field) map[nodeUID]struct{}
}
type lintFunctionForDataRaces struct {
- _ struct{}
onFailure func(failure lint.Failure)
returnIDs map[nodeUID]struct{}
rangeIDs map[nodeUID]struct{}
diff --git a/vendor/github.com/mgechev/revive/rule/deep_exit.go b/vendor/github.com/mgechev/revive/rule/deep_exit.go
index ed3e34b53..c1042a6aa 100644
--- a/vendor/github.com/mgechev/revive/rule/deep_exit.go
+++ b/vendor/github.com/mgechev/revive/rule/deep_exit.go
@@ -11,7 +11,7 @@ import (
"github.com/mgechev/revive/lint"
)
-// DeepExitRule lints program exit at functions other than main or init.
+// DeepExitRule lints program exit in functions other than main or init.
type DeepExitRule struct{}
// Apply applies the rule to given file.
diff --git a/vendor/github.com/mgechev/revive/rule/dot_imports.go b/vendor/github.com/mgechev/revive/rule/dot_imports.go
index a5f2210c5..5252e716a 100644
--- a/vendor/github.com/mgechev/revive/rule/dot_imports.go
+++ b/vendor/github.com/mgechev/revive/rule/dot_imports.go
@@ -8,7 +8,7 @@ import (
"github.com/mgechev/revive/lint"
)
-// DotImportsRule forbids . imports.
+// DotImportsRule forbids dot imports.
type DotImportsRule struct {
allowedPackages allowPackages
}
diff --git a/vendor/github.com/mgechev/revive/rule/early_return.go b/vendor/github.com/mgechev/revive/rule/early_return.go
index 2c2b67f4d..7b158ccf1 100644
--- a/vendor/github.com/mgechev/revive/rule/early_return.go
+++ b/vendor/github.com/mgechev/revive/rule/early_return.go
@@ -18,6 +18,8 @@ type EarlyReturnRule struct {
allowJump bool
}
+var _ lint.ConfigurableRule = (*EarlyReturnRule)(nil)
+
// Configure validates the rule configuration, and configures the rule accordingly.
//
// Configuration implements the [lint.ConfigurableRule] interface.
diff --git a/vendor/github.com/mgechev/revive/rule/enforce_switch_style.go b/vendor/github.com/mgechev/revive/rule/enforce_switch_style.go
index 96093d620..5f2e31223 100644
--- a/vendor/github.com/mgechev/revive/rule/enforce_switch_style.go
+++ b/vendor/github.com/mgechev/revive/rule/enforce_switch_style.go
@@ -45,12 +45,20 @@ func (r *EnforceSwitchStyleRule) Apply(file *lint.File, _ lint.Arguments) []lint
var failures []lint.Failure
astFile := file.AST
ast.Inspect(astFile, func(n ast.Node) bool {
- switchNode, ok := n.(*ast.SwitchStmt)
- if !ok {
+ var body *ast.BlockStmt
+ var node ast.Node
+ switch s := n.(type) {
+ case *ast.SwitchStmt:
+ body = s.Body
+ node = s
+ case *ast.TypeSwitchStmt:
+ body = s.Body
+ node = s
+ default:
return true // not a switch statement
}
- defaultClause, isLast := r.seekDefaultCase(switchNode.Body)
+ defaultClause, isLast := r.seekDefaultCase(body)
hasDefault := defaultClause != nil
if !hasDefault && r.allowNoDefault {
@@ -59,10 +67,10 @@ func (r *EnforceSwitchStyleRule) Apply(file *lint.File, _ lint.Arguments) []lint
if !hasDefault && !r.allowNoDefault {
// switch without default
- if !r.allBranchesEndWithJumpStmt(switchNode) {
+ if !r.allBranchesEndWithJumpStmt(body) {
failures = append(failures, lint.Failure{
Confidence: 1,
- Node: switchNode,
+ Node: node,
Category: lint.FailureCategoryStyle,
Failure: "switch must have a default case clause",
})
@@ -103,8 +111,8 @@ func (*EnforceSwitchStyleRule) seekDefaultCase(body *ast.BlockStmt) (defaultClau
return defaultClause, defaultClause == last
}
-func (*EnforceSwitchStyleRule) allBranchesEndWithJumpStmt(switchStmt *ast.SwitchStmt) bool {
- for _, stmt := range switchStmt.Body.List {
+func (*EnforceSwitchStyleRule) allBranchesEndWithJumpStmt(body *ast.BlockStmt) bool {
+ for _, stmt := range body.List {
caseClause := stmt.(*ast.CaseClause) // safe to assume stmt is a case clause
caseBody := caseClause.Body
diff --git a/vendor/github.com/mgechev/revive/rule/epoch_naming.go b/vendor/github.com/mgechev/revive/rule/epoch_naming.go
new file mode 100644
index 000000000..ac5906713
--- /dev/null
+++ b/vendor/github.com/mgechev/revive/rule/epoch_naming.go
@@ -0,0 +1,149 @@
+package rule
+
+import (
+ "fmt"
+ "go/ast"
+ "go/token"
+ "go/types"
+ "strings"
+
+ "github.com/mgechev/revive/lint"
+)
+
+// EpochNamingRule lints epoch time variable naming.
+type EpochNamingRule struct{}
+
+// Apply applies the rule to given file.
+func (*EpochNamingRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure {
+ var failures []lint.Failure
+
+ walker := lintEpochNaming{
+ file: file,
+ onFailure: func(failure lint.Failure) {
+ failures = append(failures, failure)
+ },
+ }
+
+ if err := file.Pkg.TypeCheck(); err != nil {
+ return []lint.Failure{
+ lint.NewInternalFailure(fmt.Sprintf("Unable to type check file %q: %v", file.Name, err)),
+ }
+ }
+ ast.Walk(walker, file.AST)
+
+ return failures
+}
+
+// Name returns the rule name.
+func (*EpochNamingRule) Name() string {
+ return "epoch-naming"
+}
+
+type lintEpochNaming struct {
+ file *lint.File
+ onFailure func(lint.Failure)
+}
+
+var epochUnits = map[string][]string{
+ "Unix": {"Sec", "Second", "Seconds"},
+ "UnixMilli": {"Milli", "Ms"},
+ "UnixMicro": {"Micro", "Microsecond", "Microseconds", "Us"},
+ "UnixNano": {"Nano", "Ns"},
+}
+
+func (w lintEpochNaming) Visit(node ast.Node) ast.Visitor {
+ switch v := node.(type) {
+ case *ast.ValueSpec:
+ // Handle var declarations
+ valuesLen := len(v.Values)
+ for i, name := range v.Names {
+ if i >= valuesLen {
+ break
+ }
+
+ w.check(name, v.Values[i])
+ }
+ case *ast.AssignStmt:
+ // Handle both short variable declarations (:=) and regular assignments (=)
+ if v.Tok != token.DEFINE && v.Tok != token.ASSIGN {
+ return w
+ }
+
+ rhsLen := len(v.Rhs)
+
+ for i, lhs := range v.Lhs {
+ if i >= rhsLen {
+ break
+ }
+ ident, ok := lhs.(*ast.Ident)
+ if !ok || ident.Name == "_" {
+ continue
+ }
+ w.check(ident, v.Rhs[i])
+ }
+ }
+
+ return w
+}
+
+func (w lintEpochNaming) check(name *ast.Ident, value ast.Expr) {
+ call, ok := value.(*ast.CallExpr)
+ if !ok {
+ return
+ }
+
+ selector, ok := call.Fun.(*ast.SelectorExpr)
+ if !ok {
+ return
+ }
+
+ // Check if the receiver is of type time.Time
+ receiverType := w.file.Pkg.TypeOf(selector.X)
+ if receiverType == nil {
+ return
+ }
+ if !isTime(receiverType) {
+ return
+ }
+
+ methodName := selector.Sel.Name
+ suffixes, ok := epochUnits[methodName]
+ if !ok {
+ return
+ }
+
+ varName := name.Name
+ if !hasAnySuffix(varName, suffixes) {
+ w.onFailure(lint.Failure{
+ Confidence: 0.9,
+ Node: name,
+ Category: lint.FailureCategoryNaming,
+ Failure: fmt.Sprintf("var %s should have one of these suffixes: %s", varName, strings.Join(suffixes, ", ")),
+ })
+ }
+}
+
+func isTime(typ types.Type) bool {
+ named, ok := typ.(*types.Named)
+ if !ok {
+ return false
+ }
+
+ obj := named.Obj()
+ if obj == nil {
+ return false
+ }
+
+ pkg := obj.Pkg()
+ return pkg != nil && pkg.Path() == "time" && obj.Name() == "Time"
+}
+
+func hasAnySuffix(s string, suffixes []string) bool {
+ lowerName := strings.ToLower(s)
+ for _, suffix := range suffixes {
+ if strings.HasSuffix(lowerName, strings.ToLower(suffix)) {
+ return true
+ }
+ }
+ return false
+}
diff --git a/vendor/github.com/mgechev/revive/rule/exported.go b/vendor/github.com/mgechev/revive/rule/exported.go
index eb351cf4d..9d8ace8e5 100644
--- a/vendor/github.com/mgechev/revive/rule/exported.go
+++ b/vendor/github.com/mgechev/revive/rule/exported.go
@@ -170,15 +170,15 @@ func (w *lintExported) lintFuncDoc(fn *ast.FuncDecl) {
case exportedGoDocStatusOK:
return // comment is fine
case exportedGoDocStatusMissing:
- w.addFailuref(fn, status.Confidence(), lint.FailureCategoryComments,
+ w.addFailuref(fn, status.confidence(), lint.FailureCategoryComments,
"exported %s %s should have comment or be unexported", kind, name,
)
return
}
firstCommentLine := w.firstCommentLine(fn.Doc)
- w.addFailuref(fn.Doc, status.Confidence(), lint.FailureCategoryComments,
- `comment on exported %s %s should be of the form "%s ..."%s`, kind, name, fn.Name.Name, status.CorrectionHint(firstCommentLine),
+ w.addFailuref(fn.Doc, status.confidence(), lint.FailureCategoryComments,
+ `comment on exported %s %s should be of the form "%s ..."%s`, kind, name, fn.Name.Name, status.correctionHint(firstCommentLine),
)
}
@@ -264,8 +264,8 @@ func (w *lintExported) lintTypeDoc(t *ast.TypeSpec, doc *ast.CommentGroup, first
if status == exportedGoDocStatusOK {
return
}
- w.addFailuref(doc, status.Confidence(), lint.FailureCategoryComments,
- `comment on exported type %v should be of the form "%s ..." (with optional leading article)%s`, t.Name, typeName, status.CorrectionHint(firstCommentLine),
+ w.addFailuref(doc, status.confidence(), lint.FailureCategoryComments,
+ `comment on exported type %v should be of the form "%s ..." (with optional leading article)%s`, t.Name, typeName, status.correctionHint(firstCommentLine),
)
}
@@ -347,8 +347,8 @@ func (w *lintExported) lintValueSpecDoc(vs *ast.ValueSpec, gd *ast.GenDecl, genD
if status == exportedGoDocStatusOK {
return
}
- w.addFailuref(doc, status.Confidence(), lint.FailureCategoryComments,
- `comment on exported %s %s should be of the form "%s ..."%s`, kind, name, name, status.CorrectionHint(firstCommentLine),
+ w.addFailuref(doc, status.confidence(), lint.FailureCategoryComments,
+ `comment on exported %s %s should be of the form "%s ..."%s`, kind, name, name, status.correctionHint(firstCommentLine),
)
}
@@ -362,14 +362,14 @@ const (
exportedGoDocStatusUnexpected
)
-func (gds exportedGoDocStatus) Confidence() float64 {
+func (gds exportedGoDocStatus) confidence() float64 {
if gds == exportedGoDocStatusUnexpected {
return 0.8
}
return 1
}
-func (gds exportedGoDocStatus) CorrectionHint(firstCommentLine string) string {
+func (gds exportedGoDocStatus) correctionHint(firstCommentLine string) string {
firstWord := strings.Split(firstCommentLine, " ")[0]
switch gds {
case exportedGoDocStatusCaseMismatch:
@@ -408,17 +408,16 @@ func (w *lintExported) checkGoDocStatus(comment *ast.CommentGroup, name string)
}
// firstCommentLine yields the first line of interest in comment group or "" if there is nothing of interest.
-// An "interesting line" is a comment line that is neither a directive (e.g. //go:...) or a deprecation comment
-// (lines from the first line with a prefix // Deprecated: to the end of the comment group)
+// An "interesting line" is a comment line that is neither a directive (e.g. `//go:...`) or a deprecation comment
+// (lines from the first line with a prefix `// Deprecated:` to the end of the comment group).
// Empty or spaces-only lines are discarded.
-func (lintExported) firstCommentLine(comment *ast.CommentGroup) (result string) {
+func (*lintExported) firstCommentLine(comment *ast.CommentGroup) (result string) {
if comment == nil {
return ""
}
commentWithoutDirectives := comment.Text() // removes directives from the comment block
- lines := strings.Split(commentWithoutDirectives, "\n")
- for _, line := range lines {
+ for line := range strings.SplitSeq(commentWithoutDirectives, "\n") {
line := strings.TrimSpace(line)
if line == "" {
continue // ignore empty lines
@@ -501,15 +500,15 @@ func (w *lintExported) lintInterfaceMethod(typeName string, m *ast.Field) {
case exportedGoDocStatusOK:
return // comment is fine
case exportedGoDocStatusMissing:
- w.addFailuref(m, status.Confidence(), lint.FailureCategoryComments,
+ w.addFailuref(m, status.confidence(), lint.FailureCategoryComments,
"public interface method %s.%s should be commented", typeName, name,
)
return
}
firstCommentLine := w.firstCommentLine(m.Doc)
- w.addFailuref(m.Doc, status.Confidence(), lint.FailureCategoryComments,
- `comment on exported interface method %s.%s should be of the form "%s ..."%s`, typeName, name, name, status.CorrectionHint(firstCommentLine),
+ w.addFailuref(m.Doc, status.confidence(), lint.FailureCategoryComments,
+ `comment on exported interface method %s.%s should be of the form "%s ..."%s`, typeName, name, name, status.correctionHint(firstCommentLine),
)
}
diff --git a/vendor/github.com/mgechev/revive/rule/file_header.go b/vendor/github.com/mgechev/revive/rule/file_header.go
index 53d7ea9d0..a6538b51c 100644
--- a/vendor/github.com/mgechev/revive/rule/file_header.go
+++ b/vendor/github.com/mgechev/revive/rule/file_header.go
@@ -3,6 +3,7 @@ package rule
import (
"fmt"
"regexp"
+ "strings"
"github.com/mgechev/revive/lint"
)
@@ -55,7 +56,7 @@ func (r *FileHeaderRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure
if g == nil {
return failure
}
- comment := ""
+ var comment strings.Builder
for _, c := range g.List {
text := c.Text
if multiRegexp.MatchString(text) {
@@ -63,7 +64,7 @@ func (r *FileHeaderRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure
} else if singleRegexp.MatchString(text) {
text = text[2:]
}
- comment += text
+ comment.WriteString(text)
}
regex, err := regexp.Compile(r.header)
@@ -71,7 +72,7 @@ func (r *FileHeaderRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure
return newInternalFailureError(err)
}
- if !regex.MatchString(comment) {
+ if !regex.MatchString(comment.String()) {
return failure
}
return nil
diff --git a/vendor/github.com/mgechev/revive/rule/filename_format.go b/vendor/github.com/mgechev/revive/rule/filename_format.go
index 200ffbde0..960ebb0c8 100644
--- a/vendor/github.com/mgechev/revive/rule/filename_format.go
+++ b/vendor/github.com/mgechev/revive/rule/filename_format.go
@@ -4,6 +4,7 @@ import (
"fmt"
"path/filepath"
"regexp"
+ "strings"
"unicode"
"github.com/mgechev/revive/lint"
@@ -31,16 +32,16 @@ func (r *FilenameFormatRule) Apply(file *lint.File, _ lint.Arguments) []lint.Fai
}
func (*FilenameFormatRule) getMsgForNonASCIIChars(str string) string {
- result := ""
+ var result strings.Builder
for _, c := range str {
if c <= unicode.MaxASCII {
continue
}
- result += fmt.Sprintf(" Non ASCII character %c (%U) found.", c, c)
+ fmt.Fprintf(&result, " Non ASCII character %c (%U) found.", c, c)
}
- return result
+ return result.String()
}
// Name returns the rule name.
diff --git a/vendor/github.com/mgechev/revive/rule/forbidden_call_in_wg_go.go b/vendor/github.com/mgechev/revive/rule/forbidden_call_in_wg_go.go
index 63088e554..20a393621 100644
--- a/vendor/github.com/mgechev/revive/rule/forbidden_call_in_wg_go.go
+++ b/vendor/github.com/mgechev/revive/rule/forbidden_call_in_wg_go.go
@@ -9,7 +9,7 @@ import (
"github.com/mgechev/revive/lint"
)
-// ForbiddenCallInWgGoRule spots calls to panic or wg.Done when using WaitGroup.Go.
+// ForbiddenCallInWgGoRule spots calls to panic or wg.Done when using [sync.WaitGroup.Go].
type ForbiddenCallInWgGoRule struct{}
// Apply applies the rule to given file.
diff --git a/vendor/github.com/mgechev/revive/rule/increment_decrement.go b/vendor/github.com/mgechev/revive/rule/increment_decrement.go
index d8cebcf25..538bd9314 100644
--- a/vendor/github.com/mgechev/revive/rule/increment_decrement.go
+++ b/vendor/github.com/mgechev/revive/rule/increment_decrement.go
@@ -8,7 +8,7 @@ import (
"github.com/mgechev/revive/lint"
)
-// IncrementDecrementRule lints `i += 1` and `i -= 1` constructs.
+// IncrementDecrementRule suggests replacing `i += 1` and `i -= 1` with `i++` and `i--`.
type IncrementDecrementRule struct{}
// Apply applies the rule to given file.
diff --git a/vendor/github.com/mgechev/revive/rule/indent_error_flow.go b/vendor/github.com/mgechev/revive/rule/indent_error_flow.go
index be4734bad..f900d8e22 100644
--- a/vendor/github.com/mgechev/revive/rule/indent_error_flow.go
+++ b/vendor/github.com/mgechev/revive/rule/indent_error_flow.go
@@ -11,6 +11,8 @@ type IndentErrorFlowRule struct {
preserveScope bool
}
+var _ lint.ConfigurableRule = (*IndentErrorFlowRule)(nil)
+
// Configure validates the rule configuration, and configures the rule accordingly.
//
// Configuration implements the [lint.ConfigurableRule] interface.
diff --git a/vendor/github.com/mgechev/revive/rule/inefficient_map_lookup.go b/vendor/github.com/mgechev/revive/rule/inefficient_map_lookup.go
index b6e4bf921..c6944200b 100644
--- a/vendor/github.com/mgechev/revive/rule/inefficient_map_lookup.go
+++ b/vendor/github.com/mgechev/revive/rule/inefficient_map_lookup.go
@@ -155,6 +155,11 @@ func (w *lintInefficientMapLookup) isRangeOverMapKey(stmt ast.Stmt) bool {
return false // not a range
}
+ // Check if we range on the key
+ if rangeStmt.Key == nil {
+ return false // no key in range
+ }
+
// Check if we range only on key
// for key := range ...
// for key, _ := range ...
diff --git a/vendor/github.com/mgechev/revive/rule/line_length_limit.go b/vendor/github.com/mgechev/revive/rule/line_length_limit.go
index 5d0653975..f2c9a1467 100644
--- a/vendor/github.com/mgechev/revive/rule/line_length_limit.go
+++ b/vendor/github.com/mgechev/revive/rule/line_length_limit.go
@@ -12,7 +12,7 @@ import (
"github.com/mgechev/revive/lint"
)
-// LineLengthLimitRule lints number of characters in a line.
+// LineLengthLimitRule lints the number of characters in a line.
type LineLengthLimitRule struct {
max int
}
diff --git a/vendor/github.com/mgechev/revive/rule/max_control_nesting.go b/vendor/github.com/mgechev/revive/rule/max_control_nesting.go
index 5bb11d098..b1ac459dc 100644
--- a/vendor/github.com/mgechev/revive/rule/max_control_nesting.go
+++ b/vendor/github.com/mgechev/revive/rule/max_control_nesting.go
@@ -112,11 +112,6 @@ func (r *MaxControlNestingRule) Configure(arguments lint.Arguments) error {
return nil
}
- check := checkNumberOfArguments(1, arguments, r.Name())
- if check != nil {
- return check
- }
-
maxNesting, ok := arguments[0].(int64) // Alt. non panicking version
if !ok {
return errors.New(`invalid value passed as argument number to the "max-control-nesting" rule`)
diff --git a/vendor/github.com/mgechev/revive/rule/max_public_structs.go b/vendor/github.com/mgechev/revive/rule/max_public_structs.go
index c78116d3a..070277229 100644
--- a/vendor/github.com/mgechev/revive/rule/max_public_structs.go
+++ b/vendor/github.com/mgechev/revive/rule/max_public_structs.go
@@ -25,11 +25,6 @@ func (r *MaxPublicStructsRule) Configure(arguments lint.Arguments) error {
return nil
}
- err := checkNumberOfArguments(1, arguments, r.Name())
- if err != nil {
- return err
- }
-
maxStructs, ok := arguments[0].(int64) // Alt. non panicking version
if !ok {
return errors.New(`invalid value passed as argument number to the "max-public-structs" rule`)
diff --git a/vendor/github.com/mgechev/revive/rule/modifies_param.go b/vendor/github.com/mgechev/revive/rule/modifies_param.go
index 687ee8446..f35239027 100644
--- a/vendor/github.com/mgechev/revive/rule/modifies_param.go
+++ b/vendor/github.com/mgechev/revive/rule/modifies_param.go
@@ -29,7 +29,7 @@ func (*ModifiesParamRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failur
}
w := lintModifiesParamRule{onFailure: onFailure}
- ast.Walk(w, file.AST)
+ ast.Walk(&w, file.AST)
return failures
}
@@ -57,13 +57,13 @@ func retrieveParamNames(pl []*ast.Field) map[string]bool {
return result
}
-func (w lintModifiesParamRule) Visit(node ast.Node) ast.Visitor {
+func (w *lintModifiesParamRule) Visit(node ast.Node) ast.Visitor {
switch v := node.(type) {
case *ast.FuncDecl:
w.params = retrieveParamNames(v.Type.Params.List)
case *ast.IncDecStmt:
if id, ok := v.X.(*ast.Ident); ok {
- checkParam(id, &w)
+ checkParam(id, w)
}
case *ast.AssignStmt:
lhs := v.Lhs
@@ -76,7 +76,7 @@ func (w lintModifiesParamRule) Visit(node ast.Node) ast.Visitor {
if i < len(v.Rhs) {
w.checkModifyingFunction(v.Rhs[i])
}
- checkParam(id, &w)
+ checkParam(id, w)
}
case *ast.ExprStmt:
w.checkModifyingFunction(v.X)
diff --git a/vendor/github.com/mgechev/revive/rule/package_directory_mismatch.go b/vendor/github.com/mgechev/revive/rule/package_directory_mismatch.go
index 717805473..ea8df9d1e 100644
--- a/vendor/github.com/mgechev/revive/rule/package_directory_mismatch.go
+++ b/vendor/github.com/mgechev/revive/rule/package_directory_mismatch.go
@@ -77,7 +77,7 @@ func (*PackageDirectoryMismatchRule) buildIgnoreRegex(ignoredDirs []string) (*re
}
// skipDirs contains directory names that should be unconditionally ignored when checking.
-// These entries handle edge cases where filepath.Base might return these values.
+// These entries handle edge cases where [filepath.Base] might return these values.
var skipDirs = map[string]struct{}{
".": {}, // Current directory
"/": {}, // Root directory
@@ -85,7 +85,7 @@ var skipDirs = map[string]struct{}{
}
// semanticallyEqual checks if package and directory names are semantically equal to each other.
-func (PackageDirectoryMismatchRule) semanticallyEqual(packageName, dirName string) bool {
+func (*PackageDirectoryMismatchRule) semanticallyEqual(packageName, dirName string) bool {
normDir := normalizePath(dirName)
normPkg := normalizePath(packageName)
return normDir == normPkg || normDir == "go"+normPkg
diff --git a/vendor/github.com/mgechev/revive/rule/package_naming.go b/vendor/github.com/mgechev/revive/rule/package_naming.go
new file mode 100644
index 000000000..642b16a13
--- /dev/null
+++ b/vendor/github.com/mgechev/revive/rule/package_naming.go
@@ -0,0 +1,315 @@
+package rule
+
+import (
+ "errors"
+ "fmt"
+ "go/ast"
+ "path/filepath"
+ "regexp"
+ "strings"
+
+ gopackages "golang.org/x/tools/go/packages"
+
+ "github.com/mgechev/revive/internal/syncset"
+ "github.com/mgechev/revive/lint"
+)
+
+// defaultBadNames is the list of "bad" package names from https://go.dev/blog/package-names#bad-package-names.
+var defaultBadNames = map[string]struct{}{
+ "common": {},
+ "interface": {},
+ "interfaces": {},
+ "misc": {},
+ "type": {},
+ "types": {},
+ "util": {},
+ "utils": {},
+}
+
+// extraBadNames is the list of additional "bad" package names that are not recommended.
+var extraBadNames = map[string]struct{}{
+ "api": {},
+ "helpers": {},
+ "miscellaneous": {},
+ "models": {},
+ "shared": {},
+ "utilities": {},
+}
+
+// commonStdNames is the list of standard library package names that are commonly used in Go programs.
+// This list is based on the most popular standard library packages according to importedby tab in pkg.go.dev.
+// For example, "http" imported by 1,705,800 times https://pkg.go.dev/net/http?tab=importedby
+var commonStdNames = map[string]string{
+ "bytes": "bytes",
+ "bufio": "bufio",
+ "flag": "flag",
+ "context": "context",
+ "errors": "errors",
+ "filepath": "path/filepath",
+ "fmt": "fmt",
+ "http": "net/http",
+ "io": "io",
+ "ioutil": "io/ioutil",
+ "json": "encoding/json",
+ "log": "log",
+ "math": "math",
+ "net": "net",
+ "os": "os",
+ "strconv": "strconv",
+ "reflect": "reflect",
+ "regexp": "regexp",
+ "runtime": "runtime",
+ "sort": "sort",
+ "strings": "strings",
+ "sync": "sync",
+ "time": "time",
+ "url": "net/url",
+}
+
+// nonPublicPackageSegments are package path segments that indicate the std package is not public.
+var nonPublicPackageSegments = map[string]struct{}{
+ "internal": {},
+ "vendor": {},
+}
+
+// forbiddenTopLevelNames is the set of forbidden top level package names.
+var forbiddenTopLevelNames = map[string]struct{}{
+ "pkg": {},
+}
+
+// PackageNamingRule is a rule that checks package names.
+type PackageNamingRule struct {
+ skipConventionNameCheck bool // if true - skip checks for package name conventions (e.g., no underscores, no MixedCaps etc.)
+ conventionNameCheckRegex *regexp.Regexp // the regex used to check package name conventions
+
+ skipTopLevelCheck bool // if true - skip checks for top level package names (e.g., "pkg")
+
+ skipDefaultBadNameCheck bool // if true - skip checks for default bad package names (e.g., "util", "misc" etc.)
+ checkExtraBadName bool // if true - enable check for extra bad package names (e.g., "helpers", "models" etc.)
+ userDefinedBadNames map[string]struct{} // set of user defined bad package names
+
+ skipCollisionWithCommonStd bool // if true - skip checks for collisions with common Go standard library package names (e.g., "http", "json", "rand" etc.)
+
+ checkCollisionWithAllStd bool // if true - enable checks for collisions with all Go standard library package names (including "version", "metrics" etc.)
+ // allStdNames holds name -> path of standard library packages excluding internal and vendor.
+ // Populated only if checkCollisionWithAllStd is true. `net/http` stored as `http`, `math/rand/v2` as `rand` etc.
+ allStdNames map[string]string
+
+ // alreadyCheckedNames is keyed by fileDir (package directory path) to track which package directories
+ // have already been checked and avoid duplicate checks across files in the same package.
+ alreadyCheckedNames *syncset.Set
+}
+
+// Configure validates the rule configuration, and configures the rule accordingly.
+//
+// Configuration implements the [lint.ConfigurableRule] interface.
+func (r *PackageNamingRule) Configure(arguments lint.Arguments) error {
+ r.alreadyCheckedNames = syncset.New()
+
+ if len(arguments) == 0 {
+ return nil
+ }
+
+ if len(arguments) > 1 {
+ return fmt.Errorf("invalid arguments to the package-naming rule: expected at most 1 argument, but got %d", len(arguments))
+ }
+
+ args, ok := arguments[0].(map[string]any)
+ if !ok {
+ return fmt.Errorf("invalid argument to the package-naming rule: expecting a k,v map, but got %T", arguments[0])
+ }
+
+ for k, v := range args {
+ switch {
+ case isRuleOption(k, "skipConventionNameCheck"):
+ r.skipConventionNameCheck, ok = v.(bool)
+ if !ok {
+ return fmt.Errorf("invalid argument to the package-naming rule: expecting skipConventionNameCheck to be a boolean, but got %T", v)
+ }
+ case isRuleOption(k, "conventionNameCheckRegex"):
+ regexStr, ok := v.(string)
+ if !ok {
+ return fmt.Errorf("invalid argument to the package-naming rule: expecting conventionNameCheckRegex to be a string, but got %T", v)
+ }
+ if regexStr == "" {
+ return errors.New("invalid argument to the package-naming rule: conventionNameCheckRegex cannot be an empty string")
+ }
+ regex, err := regexp.Compile(regexStr)
+ if err != nil {
+ return fmt.Errorf("invalid argument to the package-naming rule: invalid regex for conventionNameCheckRegex: %w", err)
+ }
+ r.conventionNameCheckRegex = regex
+ case isRuleOption(k, "skipTopLevelCheck"):
+ r.skipTopLevelCheck, ok = v.(bool)
+ if !ok {
+ return fmt.Errorf("invalid argument to the package-naming rule: expecting skipTopLevelCheck to be a boolean, but got %T", v)
+ }
+ case isRuleOption(k, "skipDefaultBadNameCheck"):
+ r.skipDefaultBadNameCheck, ok = v.(bool)
+ if !ok {
+ return fmt.Errorf("invalid argument to the package-naming rule: expecting skipDefaultBadNameCheck to be a boolean, but got %T", v)
+ }
+ case isRuleOption(k, "checkExtraBadName"):
+ r.checkExtraBadName, ok = v.(bool)
+ if !ok {
+ return fmt.Errorf("invalid argument to the package-naming rule: expecting checkExtraBadName to be a boolean, but got %T", v)
+ }
+ case isRuleOption(k, "userDefinedBadNames"):
+ userDefinedBadNames, ok := v.([]any)
+ if !ok {
+ return fmt.Errorf("invalid argument to the package-naming rule: expecting userDefinedBadNames of type slice of strings, but got %T", v)
+ }
+ for i, name := range userDefinedBadNames {
+ if r.userDefinedBadNames == nil {
+ r.userDefinedBadNames = map[string]struct{}{}
+ }
+ n, ok := name.(string)
+ if !ok {
+ return fmt.Errorf("invalid argument to the package-naming rule: expecting element %d of userDefinedBadNames to be a string, but got %v(%T)", i, name, name)
+ }
+ if n == "" {
+ return fmt.Errorf("invalid argument to the package-naming rule: userDefinedBadNames cannot contain empty string (index %d)", i)
+ }
+ r.userDefinedBadNames[strings.ToLower(n)] = struct{}{}
+ }
+ case isRuleOption(k, "skipCollisionWithCommonStd"):
+ r.skipCollisionWithCommonStd, ok = v.(bool)
+ if !ok {
+ return fmt.Errorf("invalid argument to the package-naming rule: expecting skipCollisionWithCommonStd to be a boolean, but got %T", v)
+ }
+ case isRuleOption(k, "checkCollisionWithAllStd"):
+ r.checkCollisionWithAllStd, ok = v.(bool)
+ if !ok {
+ return fmt.Errorf("invalid argument to the package-naming rule: expecting checkCollisionWithAllStd to be a boolean, but got %T", v)
+ }
+ }
+ }
+
+ if r.skipConventionNameCheck && r.conventionNameCheckRegex != nil {
+ return errors.New("invalid configuration for package-naming rule: skipConventionNameCheck and conventionNameCheckRegex cannot be both set")
+ }
+
+ if r.skipCollisionWithCommonStd && r.checkCollisionWithAllStd {
+ return errors.New("invalid configuration for package-naming rule: skipCollisionWithCommonStd and checkCollisionWithAllStd cannot be both set")
+ }
+
+ if r.checkCollisionWithAllStd && r.allStdNames == nil {
+ pkgs, err := gopackages.Load(nil, "std")
+ if err != nil {
+ return fmt.Errorf("load std packages: %w", err)
+ }
+
+ r.allStdNames = map[string]string{}
+ for _, pkg := range pkgs {
+ if isNonPublicPackage(pkg.PkgPath) {
+ continue
+ }
+ if existingPath, ok := r.allStdNames[pkg.Name]; !ok || pkg.PkgPath < existingPath {
+ r.allStdNames[pkg.Name] = pkg.PkgPath
+ }
+ }
+ }
+
+ return nil
+}
+
+// isNonPublicPackage reports whether the path represents an internal or vendor directory.
+func isNonPublicPackage(path string) bool {
+ for p := range strings.SplitSeq(path, "/") {
+ if _, ok := nonPublicPackageSegments[p]; ok {
+ return true
+ }
+ }
+ return false
+}
+
+// Apply applies the rule to given file.
+func (r *PackageNamingRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure {
+ var failures []lint.Failure
+ onFailure := func(failure lint.Failure) {
+ failures = append(failures, failure)
+ }
+
+ fileDir := filepath.Dir(file.Name)
+
+ if !r.alreadyCheckedNames.AddIfAbsent(fileDir) {
+ return failures
+ }
+
+ node := file.AST.Name
+ pkgName := node.Name
+ pkgNameWithoutTestSuffix := strings.TrimSuffix(pkgName, "_test")
+
+ if r.conventionNameCheckRegex != nil {
+ if !r.conventionNameCheckRegex.MatchString(pkgNameWithoutTestSuffix) {
+ onFailure(r.pkgNameFailure(node, "package name %q doesn't match the convention defined by conventionNameCheckRegex", pkgName))
+ return failures
+ }
+ } else if !r.skipConventionNameCheck {
+ // Package names need slightly different handling than other names.
+ if strings.Contains(pkgNameWithoutTestSuffix, "_") {
+ onFailure(r.pkgNameFailure(node, "don't use package name %q that contains an underscore", pkgName))
+ return failures
+ }
+ if hasUpperCaseLetter(pkgNameWithoutTestSuffix) {
+ onFailure(r.pkgNameFailure(node, "don't use package name %q that contains MixedCaps", pkgName))
+ return failures
+ }
+ }
+
+ pkgNameLower := strings.ToLower(pkgName)
+ if !r.skipTopLevelCheck {
+ if _, ok := forbiddenTopLevelNames[pkgNameLower]; ok && filepath.Base(fileDir) != pkgName {
+ onFailure(r.pkgNameFailure(node, "don't use %q as a root level package name", pkgName))
+ return failures
+ }
+ }
+
+ if !r.skipDefaultBadNameCheck {
+ if _, ok := defaultBadNames[pkgNameLower]; ok {
+ onFailure(r.pkgNameFailure(node, "don't use %q because it is a bad package name according to https://go.dev/blog/package-names#bad-package-names", pkgName))
+ return failures
+ }
+ }
+
+ if r.checkExtraBadName {
+ if _, ok := extraBadNames[pkgNameLower]; ok {
+ onFailure(r.pkgNameFailure(node, "don't use %q because it is a bad package name (extra)", pkgName))
+ return failures
+ }
+ }
+
+ if r.userDefinedBadNames != nil {
+ if _, ok := r.userDefinedBadNames[pkgNameLower]; ok {
+ onFailure(r.pkgNameFailure(node, "don't use %q because it is a bad package name (user-defined)", pkgName))
+ return failures
+ }
+ }
+
+ if r.checkCollisionWithAllStd {
+ // all std names are also common std names, so no need to check separately
+ if std, ok := r.allStdNames[pkgNameLower]; ok {
+ onFailure(r.pkgNameFailure(node, "don't use %q because it conflicts with Go standard library package %q", pkgName, std))
+ }
+ } else if !r.skipCollisionWithCommonStd {
+ if std, ok := commonStdNames[pkgNameLower]; ok {
+ onFailure(r.pkgNameFailure(node, "don't use %q because it conflicts with common Go standard library package %q", pkgName, std))
+ }
+ }
+
+ return failures
+}
+
+// Name returns the rule name.
+func (*PackageNamingRule) Name() string {
+ return "package-naming"
+}
+
+func (*PackageNamingRule) pkgNameFailure(node ast.Node, msg string, args ...any) lint.Failure {
+ return lint.Failure{
+ Failure: fmt.Sprintf(msg, args...),
+ Confidence: 1,
+ Node: node,
+ Category: lint.FailureCategoryNaming,
+ }
+}
diff --git a/vendor/github.com/mgechev/revive/rule/redundant_test_main_exit.go b/vendor/github.com/mgechev/revive/rule/redundant_test_main_exit.go
index 717969ef6..04e643e5f 100644
--- a/vendor/github.com/mgechev/revive/rule/redundant_test_main_exit.go
+++ b/vendor/github.com/mgechev/revive/rule/redundant_test_main_exit.go
@@ -7,7 +7,7 @@ import (
"github.com/mgechev/revive/lint"
)
-// RedundantTestMainExitRule suggests removing Exit call in TestMain function for test files.
+// RedundantTestMainExitRule suggests removing redundant [os.Exit] or [syscall.Exit] calls in TestMain function.
type RedundantTestMainExitRule struct{}
// Apply applies the rule to given file.
@@ -65,6 +65,11 @@ func (w *lintRedundantTestMainExit) Visit(node ast.Node) ast.Visitor {
}
pkg := id.Name
+ // skip flag calls because they are commonly used in TestMain
+ if pkg == "flag" {
+ return w
+ }
+
fn := fc.Sel.Name
if isCallToExitFunction(pkg, fn, ce.Args) {
w.onFailure(lint.Failure{
diff --git a/vendor/github.com/mgechev/revive/rule/string_format.go b/vendor/github.com/mgechev/revive/rule/string_format.go
index b653cb13e..0cf05e37a 100644
--- a/vendor/github.com/mgechev/revive/rule/string_format.go
+++ b/vendor/github.com/mgechev/revive/rule/string_format.go
@@ -11,7 +11,7 @@ import (
"github.com/mgechev/revive/lint"
)
-// StringFormatRule lints strings and/or comments according to a set of regular expressions given as Arguments.
+// StringFormatRule lints strings and/or comments according to a set of regular expressions given as arguments.
type StringFormatRule struct {
rules []stringFormatSubrule
}
@@ -81,12 +81,13 @@ type stringFormatSubruleScope struct {
field string // (optional) If the argument to be checked is a struct, which member of the struct is checked against the rule (top level members only)
}
-// Regex inserted to match valid function/struct field identifiers.
+// identRegex matches valid function/struct field identifiers.
const identRegex = "[_A-Za-z][_A-Za-z0-9]*"
var parseStringFormatScope = regexp.MustCompile(
fmt.Sprintf("^(%s(?:\\.%s)?)(?:\\[([0-9]+)\\](?:\\.(%s))?)?$", identRegex, identRegex, identRegex))
+//revive:disable-next-line:function-result-limit
func (r *StringFormatRule) parseArgument(argument any, ruleNum int) (scopes stringFormatSubruleScopes, regex *regexp.Regexp, negated bool, errorMessage string, err error) {
g, ok := argument.([]any) // Cast to generic slice first
if !ok {
@@ -165,17 +166,18 @@ func (r *StringFormatRule) parseArgument(argument any, ruleNum int) (scopes stri
return scopes, regex, negated, errorMessage, nil
}
-// Report an invalid config, this is specifically the user's fault.
+// configError reports an invalid config, this is specifically the user's fault.
func (*StringFormatRule) configError(msg string, ruleNum, option int) error {
return fmt.Errorf("invalid configuration for string-format: %s [argument %d, option %d]", msg, ruleNum, option)
}
-// Report a general config parsing failure, this may be the user's fault, but it isn't known for certain.
+// parseError reports a general config parsing failure, this may be the user's fault, but it isn't known for certain.
func (*StringFormatRule) parseError(msg string, ruleNum, option int) error {
return fmt.Errorf("failed to parse configuration for string-format: %s [argument %d, option %d]", msg, ruleNum, option)
}
-// Report a general scope config parsing failure, this may be the user's fault, but it isn't known for certain.
+// parseScopeError reports a general scope config parsing failure, this may be the user's fault,
+// but it isn't known for certain.
func (*StringFormatRule) parseScopeError(msg string, ruleNum, option, scopeNum int) error {
return fmt.Errorf("failed to parse configuration for string-format: %s [argument %d, option %d, scope index %d]", msg, ruleNum, option, scopeNum)
}
@@ -204,7 +206,7 @@ func (w *lintStringFormatRule) Visit(node ast.Node) ast.Visitor {
return w
}
-// Return the name of a call expression in the form of package.Func or Func.
+// getCallName returns the name of a call expression in the form of package.Func or Func.
func (*lintStringFormatRule) getCallName(call *ast.CallExpr) (callName string, ok bool) {
if ident, ok := call.Fun.(*ast.Ident); ok {
// Local function call
@@ -227,7 +229,8 @@ func (*lintStringFormatRule) getCallName(call *ast.CallExpr) (callName string, o
return "", false
}
-// apply a single format rule to a call expression (should be done after verifying the that the call expression matches the rule's scope).
+// apply a single format rule to a call expression
+// (should be done after verifying the that the call expression matches the rule's scope).
func (r *stringFormatSubrule) apply(call *ast.CallExpr, scope *stringFormatSubruleScope) {
if len(call.Args) <= scope.argument {
return
diff --git a/vendor/github.com/mgechev/revive/rule/string_of_int.go b/vendor/github.com/mgechev/revive/rule/string_of_int.go
index 3bec1d6ac..839d0dfd5 100644
--- a/vendor/github.com/mgechev/revive/rule/string_of_int.go
+++ b/vendor/github.com/mgechev/revive/rule/string_of_int.go
@@ -7,7 +7,7 @@ import (
"github.com/mgechev/revive/lint"
)
-// StringOfIntRule warns when logic expressions contains Boolean literals.
+// StringOfIntRule warns when an integer is converted to a string using a string cast.
type StringOfIntRule struct{}
// Apply applies the rule to given file.
diff --git a/vendor/github.com/mgechev/revive/rule/struct_tag.go b/vendor/github.com/mgechev/revive/rule/struct_tag.go
index 0830a257d..c245f51fc 100644
--- a/vendor/github.com/mgechev/revive/rule/struct_tag.go
+++ b/vendor/github.com/mgechev/revive/rule/struct_tag.go
@@ -71,7 +71,7 @@ type checkContext struct {
isAtLeastGo124 bool
}
-func (checkCtx checkContext) isUserDefined(key tagKey, opt string) bool {
+func (checkCtx *checkContext) isUserDefined(key tagKey, opt string) bool {
if checkCtx.userDefined == nil {
return false
}
@@ -105,11 +105,6 @@ func (r *StructTagRule) Configure(arguments lint.Arguments) error {
return nil
}
- err := checkNumberOfArguments(1, arguments, r.Name())
- if err != nil {
- return err
- }
-
r.userDefined = map[tagKey][]string{}
r.omittedTags = map[tagKey]struct{}{}
for _, arg := range arguments {
@@ -636,7 +631,7 @@ func checkTOMLTag(checkCtx *checkContext, tag *structtag.Tag, _ *ast.Field) (mes
}
func checkURLTag(checkCtx *checkContext, tag *structtag.Tag, _ *ast.Field) (message string, succeeded bool) {
- var delimiter = ""
+ var delimiter string
for _, opt := range tag.Options {
switch opt {
case "int", "omitempty", "numbered", "brackets",
@@ -808,8 +803,7 @@ func (w lintStructTagRule) addFailuref(n ast.Node, msg string, args ...any) {
}
func areValidateOpts(opts string) (string, bool) {
- parts := strings.Split(opts, "|")
- for _, opt := range parts {
+ for opt := range strings.SplitSeq(opts, "|") {
_, ok := validateSingleOptions[opt]
if !ok {
return opt, false
@@ -1003,7 +997,7 @@ var validateSingleOptions = map[string]struct{}{
"validateFn": {},
}
-// These are options that are used in expressions of the form:
+// validateLHS are options that are used in expressions of the form:
//
// =
var validateLHS = map[string]struct{}{
diff --git a/vendor/github.com/mgechev/revive/rule/superfluous_else.go b/vendor/github.com/mgechev/revive/rule/superfluous_else.go
index dfa8a2fab..68bbd7815 100644
--- a/vendor/github.com/mgechev/revive/rule/superfluous_else.go
+++ b/vendor/github.com/mgechev/revive/rule/superfluous_else.go
@@ -13,6 +13,8 @@ type SuperfluousElseRule struct {
preserveScope bool
}
+var _ lint.ConfigurableRule = (*SuperfluousElseRule)(nil)
+
// Configure validates the rule configuration, and configures the rule accordingly.
//
// Configuration implements the [lint.ConfigurableRule] interface.
diff --git a/vendor/github.com/mgechev/revive/rule/time_date.go b/vendor/github.com/mgechev/revive/rule/time_date.go
index 939ea825c..cc0d380bb 100644
--- a/vendor/github.com/mgechev/revive/rule/time_date.go
+++ b/vendor/github.com/mgechev/revive/rule/time_date.go
@@ -14,7 +14,7 @@ import (
"github.com/mgechev/revive/logging"
)
-// TimeDateRule lints the way time.Date is used.
+// TimeDateRule lints the way [time.Date] is used.
type TimeDateRule struct{}
// Apply applies the rule to given file.
@@ -41,7 +41,7 @@ type lintTimeDate struct {
onFailure func(lint.Failure)
}
-// timeDateArgument is a type for the arguments of time.Date function.
+// timeDateArgument is a type for the arguments of [time.Date] function.
type timeDateArgument string
const (
@@ -56,7 +56,7 @@ const (
)
var (
- // timeDateArgumentNames are the names of the arguments of time.Date.
+ // timeDateArgumentNames are the names of the arguments of [time.Date].
timeDateArgumentNames = []timeDateArgument{
timeDateArgYear,
timeDateArgMonth,
@@ -68,7 +68,7 @@ var (
timeDateArgTimezone,
}
- // timeDateArity is the number of arguments of time.Date.
+ // timeDateArity is the number of arguments of [time.Date].
timeDateArity = len(timeDateArgumentNames)
)
@@ -86,7 +86,7 @@ type timeDateMonthYear struct {
year, month int64
}
-func (w lintTimeDate) Visit(n ast.Node) ast.Visitor {
+func (w *lintTimeDate) Visit(n ast.Node) ast.Visitor {
ce, ok := n.(*ast.CallExpr)
if !ok || len(ce.Args) != timeDateArity {
return w
@@ -361,7 +361,7 @@ func (w *lintTimeDate) checkArgSign(arg ast.Node, fieldName timeDateArgument) (*
// isLeapYear checks if the year is a leap year.
// This is used to check if the date is valid according to Go implementation.
-func (lintTimeDate) isLeapYear(year int64) bool {
+func (*lintTimeDate) isLeapYear(year int64) bool {
// We cannot use the classic formula of
// year%4 == 0 && (year%100 != 0 || year%400 == 0)
// because we want to ensure what time.Date will compute
@@ -369,7 +369,7 @@ func (lintTimeDate) isLeapYear(year int64) bool {
return time.Date(int(year), 2, 29, 0, 0, 0, 0, time.UTC).Format("01-02") == "02-29"
}
-func (w lintTimeDate) daysInMonth(year int64, month time.Month) int64 {
+func (w *lintTimeDate) daysInMonth(year int64, month time.Month) int64 {
switch month {
case time.April, time.June, time.September, time.November:
return 30
diff --git a/vendor/github.com/mgechev/revive/rule/time_equal.go b/vendor/github.com/mgechev/revive/rule/time_equal.go
index ec226fb91..db9758c5b 100644
--- a/vendor/github.com/mgechev/revive/rule/time_equal.go
+++ b/vendor/github.com/mgechev/revive/rule/time_equal.go
@@ -9,7 +9,7 @@ import (
"github.com/mgechev/revive/lint"
)
-// TimeEqualRule shows where "==" and "!=" used for equality check time.Time.
+// TimeEqualRule flags where "==" and "!=" are used for equality checks on [time.Time].
type TimeEqualRule struct{}
// Apply applies the rule to given file.
diff --git a/vendor/github.com/mgechev/revive/rule/unchecked_type_assertion.go b/vendor/github.com/mgechev/revive/rule/unchecked_type_assertion.go
index 08e854f79..51b3f2710 100644
--- a/vendor/github.com/mgechev/revive/rule/unchecked_type_assertion.go
+++ b/vendor/github.com/mgechev/revive/rule/unchecked_type_assertion.go
@@ -136,7 +136,8 @@ func (w *lintUncheckedTypeAssertion) handleAssignment(n *ast.AssignStmt) {
}
}
-// handles "return foo(.*bar)" - one of them is enough to fail as golang does not forward the type cast tuples in return statements.
+// handleReturn handles "return foo(.*bar)" - one of them is enough to fail
+// as Go does not forward the type cast tuples in return statements.
func (w *lintUncheckedTypeAssertion) handleReturn(n *ast.ReturnStmt) {
for _, r := range n.Results {
w.requireNoTypeAssert(r)
diff --git a/vendor/github.com/mgechev/revive/rule/unconditional_recursion.go b/vendor/github.com/mgechev/revive/rule/unconditional_recursion.go
index 772896c1f..738a9e71d 100644
--- a/vendor/github.com/mgechev/revive/rule/unconditional_recursion.go
+++ b/vendor/github.com/mgechev/revive/rule/unconditional_recursion.go
@@ -79,11 +79,14 @@ type lintUnconditionalRecursionRule struct {
}
// Visit will traverse function's body we search for calls to the function itself.
-// We do not search inside conditional control structures (if, for, switch, ...) because any recursive call inside them is conditioned.
-// We do search inside conditional control structures are statements that will take the control out of the function (return, exit, panic).
+// We do not search inside conditional control structures (if, for, switch etc.)
+// because any recursive call inside them is conditioned.
+// We do search inside conditional control structures are statements
+// that will take the control out of the function (return, exit, panic).
// If we find conditional control exits, it means the function is NOT unconditionally-recursive.
// If we find a recursive call before finding any conditional exit, a failure is generated.
-// In resume: if we found a recursive call control-dependent from the entry point of the function then we raise a failure.
+// In resume: if we found a recursive call control-dependent from the entry point of
+// the function then we raise a failure.
func (w *lintUnconditionalRecursionRule) Visit(node ast.Node) ast.Visitor {
switch n := node.(type) {
case *ast.CallExpr:
diff --git a/vendor/github.com/mgechev/revive/rule/unexported_return.go b/vendor/github.com/mgechev/revive/rule/unexported_return.go
index e82dcff09..dc567eee3 100644
--- a/vendor/github.com/mgechev/revive/rule/unexported_return.go
+++ b/vendor/github.com/mgechev/revive/rule/unexported_return.go
@@ -9,7 +9,7 @@ import (
"github.com/mgechev/revive/lint"
)
-// UnexportedReturnRule warns when a public return is from unexported type.
+// UnexportedReturnRule warns when a public function returns an unexported type.
type UnexportedReturnRule struct{}
// Apply applies the rule to given file.
diff --git a/vendor/github.com/mgechev/revive/rule/unhandled_error.go b/vendor/github.com/mgechev/revive/rule/unhandled_error.go
index 1e60538c1..9dd8e7f22 100644
--- a/vendor/github.com/mgechev/revive/rule/unhandled_error.go
+++ b/vendor/github.com/mgechev/revive/rule/unhandled_error.go
@@ -151,8 +151,8 @@ func (*lintUnhandledErrors) isTypeError(t *types.Named) bool {
}
func (w *lintUnhandledErrors) returnsAnError(tt *types.Tuple) bool {
- for i := range tt.Len() {
- nt, ok := tt.At(i).Type().(*types.Named)
+ for v := range tt.Variables() {
+ nt, ok := v.Type().(*types.Named)
if ok && w.isTypeError(nt) {
return true
}
diff --git a/vendor/github.com/mgechev/revive/rule/unnecessary_if.go b/vendor/github.com/mgechev/revive/rule/unnecessary_if.go
index f2f8174bd..4c8144872 100644
--- a/vendor/github.com/mgechev/revive/rule/unnecessary_if.go
+++ b/vendor/github.com/mgechev/revive/rule/unnecessary_if.go
@@ -72,8 +72,8 @@ func (w *lintUnnecessaryIf) Visit(node ast.Node) ast.Visitor {
return w // then and else branches do not have just one statement
}
- replacement := ""
- thenBool := false
+ var replacement string
+ var thenBool bool
switch thenStmt := thenStmts[0].(type) {
case *ast.ReturnStmt:
replacement, thenBool = w.replacementForReturnStmt(thenStmt, elseStmts)
diff --git a/vendor/github.com/mgechev/revive/rule/unsecure_url_scheme.go b/vendor/github.com/mgechev/revive/rule/unsecure_url_scheme.go
index f1ebdba8b..1aa095b47 100644
--- a/vendor/github.com/mgechev/revive/rule/unsecure_url_scheme.go
+++ b/vendor/github.com/mgechev/revive/rule/unsecure_url_scheme.go
@@ -10,7 +10,8 @@ import (
"github.com/mgechev/revive/lint"
)
-// UnsecureURLSchemeRule checks if a file contains string literals with unsecure URL schemes (for example: http://... in place of https://...).
+// UnsecureURLSchemeRule checks if a file contains string literals with unsecure URL schemes.
+// For example: "http://" in place of "https://".
type UnsecureURLSchemeRule struct{}
// Apply applied the rule to the given file.
@@ -41,13 +42,15 @@ type lintUnsecureURLSchemeRule struct {
onFailure func(lint.Failure)
}
-const schemeSeparator = "://"
-const schemeHTTP = "http"
-const schemeWS = "ws"
-const urlPrefixHTTP = schemeHTTP + schemeSeparator
-const urlPrefixWS = schemeWS + schemeSeparator
-const lenURLPrefixHTTP = len(urlPrefixHTTP)
-const lenURLPrefixWS = len(urlPrefixWS)
+const (
+ schemeSeparator = "://"
+ schemeHTTP = "http"
+ schemeWS = "ws"
+ urlPrefixHTTP = schemeHTTP + schemeSeparator
+ urlPrefixWS = schemeWS + schemeSeparator
+ lenURLPrefixHTTP = len(urlPrefixHTTP)
+ lenURLPrefixWS = len(urlPrefixWS)
+)
func (w lintUnsecureURLSchemeRule) Visit(node ast.Node) ast.Visitor {
n, ok := node.(*ast.BasicLit)
diff --git a/vendor/github.com/mgechev/revive/rule/use_errors_new.go b/vendor/github.com/mgechev/revive/rule/use_errors_new.go
index 95b1aa621..5473bc7e7 100644
--- a/vendor/github.com/mgechev/revive/rule/use_errors_new.go
+++ b/vendor/github.com/mgechev/revive/rule/use_errors_new.go
@@ -7,7 +7,7 @@ import (
"github.com/mgechev/revive/lint"
)
-// UseErrorsNewRule spots calls to fmt.Errorf that can be replaced by errors.New.
+// UseErrorsNewRule spots calls to [fmt.Errorf] that can be replaced by [errors.New].
type UseErrorsNewRule struct{}
// Apply applies the rule to given file.
diff --git a/vendor/github.com/mgechev/revive/rule/use_fmt_print.go b/vendor/github.com/mgechev/revive/rule/use_fmt_print.go
index b5f6d3c54..3da85ff7f 100644
--- a/vendor/github.com/mgechev/revive/rule/use_fmt_print.go
+++ b/vendor/github.com/mgechev/revive/rule/use_fmt_print.go
@@ -9,7 +9,8 @@ import (
"github.com/mgechev/revive/lint"
)
-// UseFmtPrintRule lints calls to print and println.
+// UseFmtPrintRule proposes to replace calls to built-in `print` and `println`
+// with their equivalents from [fmt] package.
type UseFmtPrintRule struct{}
// Apply applies the rule to given file.
@@ -85,7 +86,7 @@ func (lintUseFmtPrint) callArgsAsStr(args []ast.Expr) string {
return strings.Join(strs, ", ")
}
-func (UseFmtPrintRule) analyzeRedefinitions(decls []ast.Decl) (redefinesPrint, redefinesPrintln bool) {
+func (*UseFmtPrintRule) analyzeRedefinitions(decls []ast.Decl) (redefinesPrint, redefinesPrintln bool) {
for _, decl := range decls {
fnDecl, ok := decl.(*ast.FuncDecl)
if !ok {
diff --git a/vendor/github.com/mgechev/revive/rule/use_slices_sort.go b/vendor/github.com/mgechev/revive/rule/use_slices_sort.go
new file mode 100644
index 000000000..a0f460baa
--- /dev/null
+++ b/vendor/github.com/mgechev/revive/rule/use_slices_sort.go
@@ -0,0 +1,94 @@
+package rule
+
+import (
+ "fmt"
+ "go/ast"
+
+ "github.com/mgechev/revive/internal/astutils"
+ "github.com/mgechev/revive/lint"
+)
+
+// UseSlicesSort spots calls to sort.* that can be replaced by [slices] package methods.
+type UseSlicesSort struct{}
+
+// Apply applies the rule to given file.
+func (*UseSlicesSort) Apply(file *lint.File, _ lint.Arguments) []lint.Failure {
+ if !file.Pkg.IsAtLeastGoVersion(lint.Go121) {
+ return nil // nothing to do, the package slices was added in version 1.21
+ }
+
+ var failures []lint.Failure
+
+ walker := lintSort{
+ onFailure: func(failure lint.Failure) {
+ failures = append(failures, failure)
+ },
+ }
+
+ ast.Walk(walker, file.AST)
+
+ return failures
+}
+
+// Name returns the rule name.
+func (*UseSlicesSort) Name() string {
+ return "use-slices-sort"
+}
+
+type lintSort struct {
+ onFailure func(lint.Failure)
+}
+
+func (w lintSort) Visit(n ast.Node) ast.Visitor {
+ funcCall, ok := n.(*ast.CallExpr)
+ if !ok {
+ return w // not a function call
+ }
+
+ isCallToSort, sortMethod, sliceMethod := findCallToSortReplacement(funcCall.Fun)
+ if !isCallToSort {
+ return w
+ }
+
+ w.onFailure(lint.Failure{
+ Category: lint.FailureCategoryMaintenance,
+ Node: n,
+ Confidence: 1,
+ Failure: fmt.Sprintf("replace sort.%s by slices.%s", sortMethod, sliceMethod),
+ })
+
+ return nil
+}
+
+// findCallToSortReplacement returns true if the given function call is a call to a sort method that
+// can be replaced with a call to a slices package method, false otherwise.
+// Alongside with the boolean, the function returns the sort method name and the name of its
+// replacement method from the slices package.
+func findCallToSortReplacement(expr ast.Expr) (isCallToSort bool, sortMethod, slicesMethod string) {
+ sel, ok := expr.(*ast.SelectorExpr)
+ if !ok {
+ return false, "", ""
+ }
+
+ if !astutils.IsIdent(sel.X, "sort") {
+ return false, "", ""
+ }
+
+ sortMethod = sel.Sel.Name
+ switch sortMethod {
+ case "Float64s", "Ints", "Strings":
+ slicesMethod = "Sort"
+ case "Slice", "Sort":
+ slicesMethod = "SortFunc"
+ case "SliceStable", "Stable":
+ slicesMethod = "SortStableFunc"
+ case "Float64sAreSorted", "IntsAreSorted", "StringsAreSorted":
+ slicesMethod = "IsSorted"
+ case "IsSorted", "SliceIsSorted":
+ slicesMethod = "IsSortedFunc"
+ default:
+ return false, "", ""
+ }
+
+ return true, sortMethod, slicesMethod
+}
diff --git a/vendor/github.com/mgechev/revive/rule/use_waitgroup_go.go b/vendor/github.com/mgechev/revive/rule/use_waitgroup_go.go
index 2e58eb6fb..6f04fd65c 100644
--- a/vendor/github.com/mgechev/revive/rule/use_waitgroup_go.go
+++ b/vendor/github.com/mgechev/revive/rule/use_waitgroup_go.go
@@ -7,7 +7,7 @@ import (
"github.com/mgechev/revive/lint"
)
-// UseWaitGroupGoRule spots Go idioms that might be rewritten using WaitGroup.Go.
+// UseWaitGroupGoRule spots Go idioms that might be rewritten using [sync.WaitGroup.Go].
type UseWaitGroupGoRule struct{}
// Apply applies the rule to given file.
@@ -150,7 +150,7 @@ func (*lintUseWaitGroupGo) isCallToWgAdd(stmt ast.Stmt) bool {
return ok && astutils.IsPkgDotName(call.Fun, "wg", "Add")
}
-// function used when calling astutils.SeekNode that search for calls to wg.Done.
+// wgDonePicker is used when calling astutils.SeekNode that search for calls to wg.Done.
func wgDonePicker(n ast.Node) bool {
call, ok := n.(*ast.CallExpr)
result := ok && astutils.IsPkgDotName(call.Fun, "wg", "Done")
diff --git a/vendor/github.com/mgechev/revive/rule/utils.go b/vendor/github.com/mgechev/revive/rule/utils.go
index 0c9d7bc95..8d653227d 100644
--- a/vendor/github.com/mgechev/revive/rule/utils.go
+++ b/vendor/github.com/mgechev/revive/rule/utils.go
@@ -1,7 +1,6 @@
package rule
import (
- "fmt"
"go/ast"
"go/token"
"regexp"
@@ -11,7 +10,7 @@ import (
"github.com/mgechev/revive/lint"
)
-// exitChecker is a function type that checks whether a function call is an exit function.
+// exitFuncChecker is a function type that checks whether a function call is an exit function.
type exitFuncChecker func(args []ast.Expr) bool
var alwaysTrue exitFuncChecker = func([]ast.Expr) bool { return true }
@@ -51,14 +50,6 @@ func srcLine(src []byte, p token.Position) string {
return string(src[lo:hi])
}
-// checkNumberOfArguments fails if the given number of arguments is not, at least, the expected one.
-func checkNumberOfArguments(expected int, args lint.Arguments, ruleName string) error {
- if len(args) < expected {
- return fmt.Errorf("not enough arguments for %s rule, expected %d, got %d. Please check the rule's documentation", ruleName, expected, len(args))
- }
- return nil
-}
-
// isRuleOption returns true if arg and name are the same after normalization.
func isRuleOption(arg, name string) bool {
return normalizeRuleOption(arg) == normalizeRuleOption(name)
diff --git a/vendor/github.com/mgechev/revive/rule/var_naming.go b/vendor/github.com/mgechev/revive/rule/var_naming.go
index 8b893fabf..1c0b949f0 100644
--- a/vendor/github.com/mgechev/revive/rule/var_naming.go
+++ b/vendor/github.com/mgechev/revive/rule/var_naming.go
@@ -4,13 +4,12 @@ import (
"fmt"
"go/ast"
"go/token"
- "path/filepath"
"strings"
- "sync"
"github.com/mgechev/revive/internal/astutils"
"github.com/mgechev/revive/internal/rule"
"github.com/mgechev/revive/lint"
+ "github.com/mgechev/revive/logging"
)
var knownNameExceptions = map[string]bool{
@@ -18,63 +17,19 @@ var knownNameExceptions = map[string]bool{
"kWh": true,
}
-// defaultBadPackageNames is the list of "bad" package names from https://go.dev/wiki/CodeReviewComments#package-names
-// and https://go.dev/blog/package-names#bad-package-names.
-// The rule warns about the usage of any package name in this list if skipPackageNameChecks is false.
-// Values in the list should be lowercased.
-var defaultBadPackageNames = map[string]struct{}{
- "api": {},
- "common": {},
- "interface": {},
- "interfaces": {},
- "misc": {},
- "miscellaneous": {},
- "shared": {},
- "type": {},
- "types": {},
- "util": {},
- "utilities": {},
- "utils": {},
-}
-
-var stdLibPackageNames = map[string]struct{}{
- "bytes": {},
- "context": {},
- "crypto": {},
- "errors": {},
- "fmt": {},
- "hash": {},
- "http": {},
- "io": {},
- "json": {},
- "math": {},
- "net": {},
- "os": {},
- "sort": {},
- "string": {},
- "time": {},
- "xml": {},
-}
-
// VarNamingRule lints the name of a variable.
type VarNamingRule struct {
allowList []string
blockList []string
- allowUpperCaseConst bool // if true - allows to use UPPER_SOME_NAMES for constants
- skipInitialismNameChecks bool // if true - disable enforcing capitals for common initialisms
- skipPackageNameChecks bool // if true - disable check for meaningless and user-defined bad package names
- skipPackageNameCollisionWithGoStd bool // if true - disable checks for collisions with Go standard library package names
- extraBadPackageNames map[string]struct{} // inactive if skipPackageNameChecks is false
- pkgNameAlreadyChecked syncSet // set of packages names already checked
+ allowUpperCaseConst bool // if true - allows to use UPPER_SOME_NAMES for constants
+ skipInitialismNameChecks bool // if true - disable enforcing capitals for common initialisms
}
// Configure validates the rule configuration, and configures the rule accordingly.
//
// Configuration implements the [lint.ConfigurableRule] interface.
func (r *VarNamingRule) Configure(arguments lint.Arguments) error {
- r.pkgNameAlreadyChecked = syncSet{elements: map[string]struct{}{}}
-
if len(arguments) >= 1 {
list, err := getList(arguments[0], "allowlist")
if err != nil {
@@ -112,28 +67,25 @@ func (r *VarNamingRule) Configure(arguments lint.Arguments) error {
case isRuleOption(k, "upperCaseConst"):
r.allowUpperCaseConst = fmt.Sprint(v) == "true"
case isRuleOption(k, "skipPackageNameChecks"):
- r.skipPackageNameChecks = fmt.Sprint(v) == "true"
+ logger, err := logging.GetLogger()
+ if err == nil {
+ logger.Warn("The option var-naming.skipPackageNameChecks is no longer supported and will be ignored; use package-naming rule instead")
+ }
case isRuleOption(k, "extraBadPackageNames"):
- extraBadPackageNames, ok := v.([]any)
- if !ok {
- return fmt.Errorf("invalid third argument to the var-naming rule. Expecting extraBadPackageNames of type slice of strings, but %T", v)
+ logger, err := logging.GetLogger()
+ if err == nil {
+ logger.Warn("The option var-naming.extraBadPackageNames is no longer supported and will be ignored; use package-naming.userDefinedBadNames instead")
}
- for i, name := range extraBadPackageNames {
- if r.extraBadPackageNames == nil {
- r.extraBadPackageNames = map[string]struct{}{}
- }
- n, ok := name.(string)
- if !ok {
- return fmt.Errorf("invalid third argument to the var-naming rule: expected element %d of extraBadPackageNames to be a string, but got %v(%T)", i, name, name)
- }
- r.extraBadPackageNames[strings.ToLower(n)] = struct{}{}
+ case isRuleOption(k, "skipPackageNameCollisionWithGoStd"):
+ logger, err := logging.GetLogger()
+ if err == nil {
+ logger.Warn("The option var-naming.skipPackageNameCollisionWithGoStd is no longer supported and will be ignored; " +
+ "use package-naming.skipCollisionWithCommonStd instead (or package-naming.checkCollisionWithAllStd for the old 'all std' behavior)")
}
}
- if isRuleOption(k, "skipPackageNameCollisionWithGoStd") {
- r.skipPackageNameCollisionWithGoStd = true
- }
}
}
+
return nil
}
@@ -144,10 +96,6 @@ func (r *VarNamingRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure
failures = append(failures, failure)
}
- if !r.skipPackageNameChecks {
- r.applyPackageCheckRules(file, onFailure)
- }
-
fileAst := file.AST
walker := lintNames{
file: file,
@@ -169,59 +117,6 @@ func (*VarNamingRule) Name() string {
return "var-naming"
}
-func (r *VarNamingRule) applyPackageCheckRules(file *lint.File, onFailure func(failure lint.Failure)) {
- fileDir := filepath.Dir(file.Name)
-
- // Protect pkgsWithNameFailure from concurrent modifications
- r.pkgNameAlreadyChecked.Lock()
- defer r.pkgNameAlreadyChecked.Unlock()
- if r.pkgNameAlreadyChecked.has(fileDir) {
- return
- }
- r.pkgNameAlreadyChecked.add(fileDir) // mark this package as already checked
-
- pkgNameNode := file.AST.Name
- pkgName := pkgNameNode.Name
- pkgNameLower := strings.ToLower(pkgName)
-
- // Check if top level package
- if pkgNameLower == "pkg" && filepath.Base(fileDir) != pkgName {
- onFailure(r.pkgNameFailure(pkgNameNode, "should not have a root level package called pkg"))
- return
- }
-
- if _, ok := r.extraBadPackageNames[pkgNameLower]; ok {
- onFailure(r.pkgNameFailure(pkgNameNode, "avoid bad package names"))
- return
- }
-
- if _, ok := defaultBadPackageNames[pkgNameLower]; ok {
- onFailure(r.pkgNameFailure(pkgNameNode, "avoid meaningless package names"))
- return
- }
-
- if _, ok := stdLibPackageNames[pkgNameLower]; ok && !r.skipPackageNameCollisionWithGoStd {
- onFailure(r.pkgNameFailure(pkgNameNode, "avoid package names that conflict with Go standard library package names"))
- }
-
- // Package names need slightly different handling than other names.
- if strings.Contains(pkgName, "_") && !strings.HasSuffix(pkgName, "_test") {
- onFailure(r.pkgNameFailure(pkgNameNode, "don't use an underscore in package name"))
- }
- if hasUpperCaseLetter(pkgName) {
- onFailure(r.pkgNameFailure(pkgNameNode, "don't use MixedCaps in package names; %s should be %s", pkgName, pkgNameLower))
- }
-}
-
-func (*VarNamingRule) pkgNameFailure(node ast.Node, msg string, args ...any) lint.Failure {
- return lint.Failure{
- Failure: fmt.Sprintf(msg, args...),
- Confidence: 1,
- Node: node,
- Category: lint.FailureCategoryNaming,
- }
-}
-
type lintNames struct {
file *lint.File
fileAst *ast.File
@@ -372,7 +267,8 @@ func (w *lintNames) Visit(n ast.Node) ast.Visitor {
return w
}
-// isUpperCaseConst checks if a string is in constant name format like `SOME_CONST`, `SOME_CONST_2`, `X123_3`, `_SOME_PRIVATE_CONST`.
+// isUpperCaseConst checks if a string is in constant name format like `SOME_CONST`, `SOME_CONST_2`,
+// `X123_3`, `_SOME_PRIVATE_CONST`.
// See #851, #865.
func isUpperCaseConst(s string) bool {
if s == "" {
@@ -418,16 +314,16 @@ func isUpperOrDigit(r rune) bool {
return isUpper(r) || isDigit(r)
}
-// isUpper checks if rune is a simple digit.
+// isDigit checks if rune is a simple digit.
//
-// We don't use unicode.IsDigit as it returns true for a large variety of digits that are not 0-9.
+// We don't use [unicode.IsDigit] as it returns true for a large variety of digits that are not 0-9.
func isDigit(r rune) bool {
return r >= '0' && r <= '9'
}
// isUpper checks if rune is ASCII upper case letter
//
-// We restrict to A-Z because unicode.IsUpper returns true for a large variety of letters.
+// We restrict to A-Z because [unicode.IsUpper] returns true for a large variety of letters.
func isUpper(r rune) bool {
return r >= 'A' && r <= 'Z'
}
@@ -467,17 +363,3 @@ func getList(arg any, argName string) ([]string, error) {
}
return list, nil
}
-
-type syncSet struct {
- sync.Mutex
- elements map[string]struct{}
-}
-
-func (sm *syncSet) has(s string) bool {
- _, result := sm.elements[s]
- return result
-}
-
-func (sm *syncSet) add(s string) {
- sm.elements[s] = struct{}{}
-}
diff --git a/vendor/github.com/mgechev/revive/rule/waitgroup_by_value.go b/vendor/github.com/mgechev/revive/rule/waitgroup_by_value.go
index aa953bd9a..45eeb9b34 100644
--- a/vendor/github.com/mgechev/revive/rule/waitgroup_by_value.go
+++ b/vendor/github.com/mgechev/revive/rule/waitgroup_by_value.go
@@ -7,7 +7,7 @@ import (
"github.com/mgechev/revive/lint"
)
-// WaitGroupByValueRule lints sync.WaitGroup passed by copy in functions.
+// WaitGroupByValueRule lints [sync.WaitGroup] passed by copy in functions.
type WaitGroupByValueRule struct{}
// Apply applies the rule to given file.
diff --git a/vendor/github.com/muesli/termenv/.gitignore b/vendor/github.com/muesli/cancelreader/.gitignore
similarity index 100%
rename from vendor/github.com/muesli/termenv/.gitignore
rename to vendor/github.com/muesli/cancelreader/.gitignore
diff --git a/vendor/github.com/muesli/termenv/.golangci-soft.yml b/vendor/github.com/muesli/cancelreader/.golangci-soft.yml
similarity index 89%
rename from vendor/github.com/muesli/termenv/.golangci-soft.yml
rename to vendor/github.com/muesli/cancelreader/.golangci-soft.yml
index 84e3d41de..ef456e060 100644
--- a/vendor/github.com/muesli/termenv/.golangci-soft.yml
+++ b/vendor/github.com/muesli/cancelreader/.golangci-soft.yml
@@ -20,9 +20,10 @@ linters:
- goconst
- godot
- godox
- - mnd
+ - gomnd
- gomoddirectives
- goprintffuncname
+ - ifshort
# - lll
- misspell
- nakedret
@@ -34,10 +35,13 @@ linters:
# disable default linters, they are already enabled in .golangci.yml
disable:
+ - deadcode
- errcheck
- gosimple
- govet
- ineffassign
- staticcheck
+ - structcheck
- typecheck
- unused
+ - varcheck
diff --git a/vendor/github.com/muesli/cancelreader/.golangci.yml b/vendor/github.com/muesli/cancelreader/.golangci.yml
new file mode 100644
index 000000000..a5a91d0d9
--- /dev/null
+++ b/vendor/github.com/muesli/cancelreader/.golangci.yml
@@ -0,0 +1,29 @@
+run:
+ tests: false
+
+issues:
+ include:
+ - EXC0001
+ - EXC0005
+ - EXC0011
+ - EXC0012
+ - EXC0013
+
+ max-issues-per-linter: 0
+ max-same-issues: 0
+
+linters:
+ enable:
+ - bodyclose
+ - exportloopref
+ - goimports
+ - gosec
+ - nilerr
+ - predeclared
+ - revive
+ - rowserrcheck
+ - sqlclosecheck
+ - tparallel
+ - unconvert
+ - unparam
+ - whitespace
diff --git a/vendor/github.com/muesli/cancelreader/LICENSE b/vendor/github.com/muesli/cancelreader/LICENSE
new file mode 100644
index 000000000..4b19b92d5
--- /dev/null
+++ b/vendor/github.com/muesli/cancelreader/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2022 Erik Geiser and Christian Muehlhaeuser
+
+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.
diff --git a/vendor/github.com/muesli/cancelreader/README.md b/vendor/github.com/muesli/cancelreader/README.md
new file mode 100644
index 000000000..83609fbc7
--- /dev/null
+++ b/vendor/github.com/muesli/cancelreader/README.md
@@ -0,0 +1,64 @@
+# CancelReader
+
+[](https://github.com/muesli/cancelreader/releases)
+[](https://pkg.go.dev/github.com/muesli/cancelreader)
+[](/LICENSE)
+[](https://github.com/muesli/cancelreader/actions)
+[](https://goreportcard.com/report/muesli/cancelreader)
+
+A cancelable reader for Go
+
+This package is based on the fantastic work of [Erik Geiser](https://github.com/erikgeiser)
+in Charm's [Bubble Tea](https://github.com/charmbracelet/bubbletea) framework.
+
+## Usage
+
+`NewReader` returns a reader with a `Cancel` function. If the input reader is a
+`File`, the cancel function can be used to interrupt a blocking `Read` call.
+In this case, the cancel function returns true if the call was canceled
+successfully. If the input reader is not a `File`, the cancel function does
+nothing and always returns false.
+
+```go
+r, err := cancelreader.NewReader(file)
+if err != nil {
+ // handle error
+ ...
+}
+
+// cancel after five seconds
+go func() {
+ time.Sleep(5 * time.Second)
+ r.Cancel()
+}()
+
+// keep reading
+for {
+ var buf [1024]byte
+ _, err := r.Read(buf[:])
+
+ if errors.Is(err, cancelreader.ErrCanceled) {
+ fmt.Println("canceled!")
+ break
+ }
+ if err != nil {
+ // handle other errors
+ ...
+ }
+
+ // handle data
+ ...
+}
+```
+
+## Implementations
+
+- The Linux implementation is based on the epoll mechanism
+- The BSD and macOS implementation is based on the kqueue mechanism
+- The generic Unix implementation is based on the posix select syscall
+
+## Caution
+
+The Windows implementation is based on WaitForMultipleObject with overlapping
+reads from CONIN$. At this point it only supports canceling reads from
+`os.Stdin`.
diff --git a/vendor/github.com/muesli/cancelreader/cancelreader.go b/vendor/github.com/muesli/cancelreader/cancelreader.go
new file mode 100644
index 000000000..18d382553
--- /dev/null
+++ b/vendor/github.com/muesli/cancelreader/cancelreader.go
@@ -0,0 +1,93 @@
+package cancelreader
+
+import (
+ "fmt"
+ "io"
+ "sync"
+)
+
+// ErrCanceled gets returned when trying to read from a canceled reader.
+var ErrCanceled = fmt.Errorf("read canceled")
+
+// CancelReader is a io.Reader whose Read() calls can be canceled without data
+// being consumed. The cancelReader has to be closed.
+type CancelReader interface {
+ io.ReadCloser
+
+ // Cancel cancels ongoing and future reads an returns true if it succeeded.
+ Cancel() bool
+}
+
+// File represents an input/output resource with a file descriptor.
+type File interface {
+ io.ReadWriteCloser
+
+ // Fd returns its file descriptor
+ Fd() uintptr
+
+ // Name returns its file name.
+ Name() string
+}
+
+// fallbackCancelReader implements cancelReader but does not actually support
+// cancelation during an ongoing Read() call. Thus, Cancel() always returns
+// false. However, after calling Cancel(), new Read() calls immediately return
+// errCanceled and don't consume any data anymore.
+type fallbackCancelReader struct {
+ r io.Reader
+ cancelMixin
+}
+
+// newFallbackCancelReader is a fallback for NewReader that cannot actually
+// cancel an ongoing read but will immediately return on future reads if it has
+// been canceled.
+func newFallbackCancelReader(reader io.Reader) (CancelReader, error) {
+ return &fallbackCancelReader{r: reader}, nil
+}
+
+func (r *fallbackCancelReader) Read(data []byte) (int, error) {
+ if r.isCanceled() {
+ return 0, ErrCanceled
+ }
+
+ n, err := r.r.Read(data)
+ /*
+ If the underlying reader is a blocking reader (e.g. an open connection),
+ it might happen that 1 goroutine cancels the reader while its stuck in
+ the read call waiting for something.
+ If that happens, we should still cancel the read.
+ */
+ if r.isCanceled() {
+ return 0, ErrCanceled
+ }
+ return n, err // nolint: wrapcheck
+}
+
+func (r *fallbackCancelReader) Cancel() bool {
+ r.setCanceled()
+ return false
+}
+
+func (r *fallbackCancelReader) Close() error {
+ return nil
+}
+
+// cancelMixin represents a goroutine-safe cancelation status.
+type cancelMixin struct {
+ unsafeCanceled bool
+ lock sync.Mutex
+}
+
+func (c *cancelMixin) isCanceled() bool {
+ c.lock.Lock()
+ defer c.lock.Unlock()
+
+ return c.unsafeCanceled
+}
+
+func (c *cancelMixin) setCanceled() {
+ c.lock.Lock()
+ defer c.lock.Unlock()
+
+ c.unsafeCanceled = true
+}
diff --git a/vendor/github.com/muesli/cancelreader/cancelreader_bsd.go b/vendor/github.com/muesli/cancelreader/cancelreader_bsd.go
new file mode 100644
index 000000000..3ddb6cff0
--- /dev/null
+++ b/vendor/github.com/muesli/cancelreader/cancelreader_bsd.go
@@ -0,0 +1,146 @@
+//go:build darwin || freebsd || netbsd || openbsd || dragonfly
+// +build darwin freebsd netbsd openbsd dragonfly
+
+package cancelreader
+
+import (
+ "errors"
+ "fmt"
+ "io"
+ "os"
+ "strings"
+
+ "golang.org/x/sys/unix"
+)
+
+// NewReader returns a reader and a cancel function. If the input reader is a
+// File, the cancel function can be used to interrupt a blocking read call.
+// In this case, the cancel function returns true if the call was canceled
+// successfully. If the input reader is not a File, the cancel function
+// does nothing and always returns false. The BSD and macOS implementation is
+// based on the kqueue mechanism.
+func NewReader(reader io.Reader) (CancelReader, error) {
+ file, ok := reader.(File)
+ if !ok {
+ return newFallbackCancelReader(reader)
+ }
+
+ // kqueue returns instantly when polling /dev/tty so fallback to select
+ if file.Name() == "/dev/tty" {
+ return newSelectCancelReader(reader)
+ }
+
+ kQueue, err := unix.Kqueue()
+ if err != nil {
+ return nil, fmt.Errorf("create kqueue: %w", err)
+ }
+
+ r := &kqueueCancelReader{
+ file: file,
+ kQueue: kQueue,
+ }
+
+ r.cancelSignalReader, r.cancelSignalWriter, err = os.Pipe()
+ if err != nil {
+ _ = unix.Close(kQueue)
+ return nil, err
+ }
+
+ unix.SetKevent(&r.kQueueEvents[0], int(file.Fd()), unix.EVFILT_READ, unix.EV_ADD)
+ unix.SetKevent(&r.kQueueEvents[1], int(r.cancelSignalReader.Fd()), unix.EVFILT_READ, unix.EV_ADD)
+
+ return r, nil
+}
+
+type kqueueCancelReader struct {
+ file File
+ cancelSignalReader File
+ cancelSignalWriter File
+ cancelMixin
+ kQueue int
+ kQueueEvents [2]unix.Kevent_t
+}
+
+func (r *kqueueCancelReader) Read(data []byte) (int, error) {
+ if r.isCanceled() {
+ return 0, ErrCanceled
+ }
+
+ err := r.wait()
+ if err != nil {
+ if errors.Is(err, ErrCanceled) {
+ // remove signal from pipe
+ var b [1]byte
+ _, errRead := r.cancelSignalReader.Read(b[:])
+ if errRead != nil {
+ return 0, fmt.Errorf("reading cancel signal: %w", errRead)
+ }
+ }
+
+ return 0, err
+ }
+
+ return r.file.Read(data)
+}
+
+func (r *kqueueCancelReader) Cancel() bool {
+ r.setCanceled()
+
+ // send cancel signal
+ _, err := r.cancelSignalWriter.Write([]byte{'c'})
+ return err == nil
+}
+
+func (r *kqueueCancelReader) Close() error {
+ var errMsgs []string
+
+ // close kqueue
+ err := unix.Close(r.kQueue)
+ if err != nil {
+ errMsgs = append(errMsgs, fmt.Sprintf("closing kqueue: %v", err))
+ }
+
+ // close pipe
+ err = r.cancelSignalWriter.Close()
+ if err != nil {
+ errMsgs = append(errMsgs, fmt.Sprintf("closing cancel signal writer: %v", err))
+ }
+
+ err = r.cancelSignalReader.Close()
+ if err != nil {
+ errMsgs = append(errMsgs, fmt.Sprintf("closing cancel signal reader: %v", err))
+ }
+
+ if len(errMsgs) > 0 {
+ return fmt.Errorf(strings.Join(errMsgs, ", "))
+ }
+
+ return nil
+}
+
+func (r *kqueueCancelReader) wait() error {
+ events := make([]unix.Kevent_t, 1)
+
+ for {
+ _, err := unix.Kevent(r.kQueue, r.kQueueEvents[:], events, nil)
+ if errors.Is(err, unix.EINTR) {
+ continue // try again if the syscall was interrupted
+ }
+
+ if err != nil {
+ return fmt.Errorf("kevent: %w", err)
+ }
+
+ break
+ }
+
+ ident := uint64(events[0].Ident)
+ switch ident {
+ case uint64(r.file.Fd()):
+ return nil
+ case uint64(r.cancelSignalReader.Fd()):
+ return ErrCanceled
+ }
+
+ return fmt.Errorf("unknown error")
+}
diff --git a/vendor/github.com/muesli/cancelreader/cancelreader_default.go b/vendor/github.com/muesli/cancelreader/cancelreader_default.go
new file mode 100644
index 000000000..8e275fa44
--- /dev/null
+++ b/vendor/github.com/muesli/cancelreader/cancelreader_default.go
@@ -0,0 +1,12 @@
+//go:build !darwin && !windows && !linux && !solaris && !freebsd && !netbsd && !openbsd && !dragonfly
+// +build !darwin,!windows,!linux,!solaris,!freebsd,!netbsd,!openbsd,!dragonfly
+
+package cancelreader
+
+import "io"
+
+// NewReader returns a fallbackCancelReader that satisfies the CancelReader but
+// does not actually support cancellation.
+func NewReader(reader io.Reader) (CancelReader, error) {
+ return newFallbackCancelReader(reader)
+}
diff --git a/vendor/github.com/muesli/cancelreader/cancelreader_linux.go b/vendor/github.com/muesli/cancelreader/cancelreader_linux.go
new file mode 100644
index 000000000..09f7369f3
--- /dev/null
+++ b/vendor/github.com/muesli/cancelreader/cancelreader_linux.go
@@ -0,0 +1,154 @@
+//go:build linux
+// +build linux
+
+package cancelreader
+
+import (
+ "errors"
+ "fmt"
+ "io"
+ "os"
+ "strings"
+
+ "golang.org/x/sys/unix"
+)
+
+// NewReader returns a reader and a cancel function. If the input reader is a
+// File, the cancel function can be used to interrupt a blocking read call.
+// In this case, the cancel function returns true if the call was canceled
+// successfully. If the input reader is not a File, the cancel function
+// does nothing and always returns false. The Linux implementation is based on
+// the epoll mechanism.
+func NewReader(reader io.Reader) (CancelReader, error) {
+ file, ok := reader.(File)
+ if !ok {
+ return newFallbackCancelReader(reader)
+ }
+
+ epoll, err := unix.EpollCreate1(0)
+ if err != nil {
+ return nil, fmt.Errorf("create epoll: %w", err)
+ }
+
+ r := &epollCancelReader{
+ file: file,
+ epoll: epoll,
+ }
+
+ r.cancelSignalReader, r.cancelSignalWriter, err = os.Pipe()
+ if err != nil {
+ _ = unix.Close(epoll)
+ return nil, err
+ }
+
+ err = unix.EpollCtl(epoll, unix.EPOLL_CTL_ADD, int(file.Fd()), &unix.EpollEvent{
+ Events: unix.EPOLLIN,
+ Fd: int32(file.Fd()),
+ })
+ if err != nil {
+ _ = unix.Close(epoll)
+ return nil, fmt.Errorf("add reader to epoll interest list")
+ }
+
+ err = unix.EpollCtl(epoll, unix.EPOLL_CTL_ADD, int(r.cancelSignalReader.Fd()), &unix.EpollEvent{
+ Events: unix.EPOLLIN,
+ Fd: int32(r.cancelSignalReader.Fd()),
+ })
+ if err != nil {
+ _ = unix.Close(epoll)
+ return nil, fmt.Errorf("add reader to epoll interest list")
+ }
+
+ return r, nil
+}
+
+type epollCancelReader struct {
+ file File
+ cancelSignalReader File
+ cancelSignalWriter File
+ cancelMixin
+ epoll int
+}
+
+func (r *epollCancelReader) Read(data []byte) (int, error) {
+ if r.isCanceled() {
+ return 0, ErrCanceled
+ }
+
+ err := r.wait()
+ if err != nil {
+ if errors.Is(err, ErrCanceled) {
+ // remove signal from pipe
+ var b [1]byte
+ _, readErr := r.cancelSignalReader.Read(b[:])
+ if readErr != nil {
+ return 0, fmt.Errorf("reading cancel signal: %w", readErr)
+ }
+ }
+
+ return 0, err
+ }
+
+ return r.file.Read(data)
+}
+
+func (r *epollCancelReader) Cancel() bool {
+ r.setCanceled()
+
+ // send cancel signal
+ _, err := r.cancelSignalWriter.Write([]byte{'c'})
+ return err == nil
+}
+
+func (r *epollCancelReader) Close() error {
+ var errMsgs []string
+
+ // close kqueue
+ err := unix.Close(r.epoll)
+ if err != nil {
+ errMsgs = append(errMsgs, fmt.Sprintf("closing epoll: %v", err))
+ }
+
+ // close pipe
+ err = r.cancelSignalWriter.Close()
+ if err != nil {
+ errMsgs = append(errMsgs, fmt.Sprintf("closing cancel signal writer: %v", err))
+ }
+
+ err = r.cancelSignalReader.Close()
+ if err != nil {
+ errMsgs = append(errMsgs, fmt.Sprintf("closing cancel signal reader: %v", err))
+ }
+
+ if len(errMsgs) > 0 {
+ return fmt.Errorf(strings.Join(errMsgs, ", "))
+ }
+
+ return nil
+}
+
+func (r *epollCancelReader) wait() error {
+ events := make([]unix.EpollEvent, 1)
+
+ for {
+ _, err := unix.EpollWait(r.epoll, events, -1)
+ if errors.Is(err, unix.EINTR) {
+ continue // try again if the syscall was interrupted
+ }
+
+ if err != nil {
+ return fmt.Errorf("kevent: %w", err)
+ }
+
+ break
+ }
+
+ switch events[0].Fd {
+ case int32(r.file.Fd()):
+ return nil
+ case int32(r.cancelSignalReader.Fd()):
+ return ErrCanceled
+ }
+
+ return fmt.Errorf("unknown error")
+}
diff --git a/vendor/github.com/muesli/cancelreader/cancelreader_select.go b/vendor/github.com/muesli/cancelreader/cancelreader_select.go
new file mode 100644
index 000000000..03f2a3e1e
--- /dev/null
+++ b/vendor/github.com/muesli/cancelreader/cancelreader_select.go
@@ -0,0 +1,136 @@
+//go:build solaris || darwin || freebsd || netbsd || openbsd || dragonfly
+// +build solaris darwin freebsd netbsd openbsd dragonfly
+
+package cancelreader
+
+import (
+ "errors"
+ "fmt"
+ "io"
+ "os"
+ "strings"
+
+ "golang.org/x/sys/unix"
+)
+
+// newSelectCancelReader returns a reader and a cancel function. If the input
+// reader is a File, the cancel function can be used to interrupt a
+// blocking call read call. In this case, the cancel function returns true if
+// the call was canceled successfully. If the input reader is not a File or
+// the file descriptor is 1024 or larger, the cancel function does nothing and
+// always returns false. The generic unix implementation is based on the posix
+// select syscall.
+func newSelectCancelReader(reader io.Reader) (CancelReader, error) {
+ file, ok := reader.(File)
+ if !ok || file.Fd() >= unix.FD_SETSIZE {
+ return newFallbackCancelReader(reader)
+ }
+ r := &selectCancelReader{file: file}
+
+ var err error
+
+ r.cancelSignalReader, r.cancelSignalWriter, err = os.Pipe()
+ if err != nil {
+ return nil, err
+ }
+
+ return r, nil
+}
+
+type selectCancelReader struct {
+ file File
+ cancelSignalReader File
+ cancelSignalWriter File
+ cancelMixin
+}
+
+func (r *selectCancelReader) Read(data []byte) (int, error) {
+ if r.isCanceled() {
+ return 0, ErrCanceled
+ }
+
+ for {
+ err := waitForRead(r.file, r.cancelSignalReader)
+ if err != nil {
+ if errors.Is(err, unix.EINTR) {
+ continue // try again if the syscall was interrupted
+ }
+
+ if errors.Is(err, ErrCanceled) {
+ // remove signal from pipe
+ var b [1]byte
+ _, readErr := r.cancelSignalReader.Read(b[:])
+ if readErr != nil {
+ return 0, fmt.Errorf("reading cancel signal: %w", readErr)
+ }
+ }
+
+ return 0, err
+ }
+
+ return r.file.Read(data)
+ }
+}
+
+func (r *selectCancelReader) Cancel() bool {
+ r.setCanceled()
+
+ // send cancel signal
+ _, err := r.cancelSignalWriter.Write([]byte{'c'})
+ return err == nil
+}
+
+func (r *selectCancelReader) Close() error {
+ var errMsgs []string
+
+ // close pipe
+ err := r.cancelSignalWriter.Close()
+ if err != nil {
+ errMsgs = append(errMsgs, fmt.Sprintf("closing cancel signal writer: %v", err))
+ }
+
+ err = r.cancelSignalReader.Close()
+ if err != nil {
+ errMsgs = append(errMsgs, fmt.Sprintf("closing cancel signal reader: %v", err))
+ }
+
+ if len(errMsgs) > 0 {
+ return fmt.Errorf(strings.Join(errMsgs, ", "))
+ }
+
+ return nil
+}
+
+func waitForRead(reader, abort File) error {
+ readerFd := int(reader.Fd())
+ abortFd := int(abort.Fd())
+
+ maxFd := readerFd
+ if abortFd > maxFd {
+ maxFd = abortFd
+ }
+
+ // this is a limitation of the select syscall
+ if maxFd >= unix.FD_SETSIZE {
+ return fmt.Errorf("cannot select on file descriptor %d which is larger than 1024", maxFd)
+ }
+
+ fdSet := &unix.FdSet{}
+ fdSet.Set(int(reader.Fd()))
+ fdSet.Set(int(abort.Fd()))
+
+ _, err := unix.Select(maxFd+1, fdSet, nil, nil, nil)
+ if err != nil {
+ return fmt.Errorf("select: %w", err)
+ }
+
+ if fdSet.IsSet(abortFd) {
+ return ErrCanceled
+ }
+
+ if fdSet.IsSet(readerFd) {
+ return nil
+ }
+
+ return fmt.Errorf("select returned without setting a file descriptor")
+}
diff --git a/vendor/github.com/muesli/cancelreader/cancelreader_unix.go b/vendor/github.com/muesli/cancelreader/cancelreader_unix.go
new file mode 100644
index 000000000..3c10ee09e
--- /dev/null
+++ b/vendor/github.com/muesli/cancelreader/cancelreader_unix.go
@@ -0,0 +1,18 @@
+//go:build solaris
+// +build solaris
+
+package cancelreader
+
+import (
+ "io"
+)
+
+// NewReader returns a reader and a cancel function. If the input reader is a
+// File, the cancel function can be used to interrupt a blocking read call.
+// In this case, the cancel function returns true if the call was canceled
+// successfully. If the input reader is not a File or the file descriptor
+// is 1024 or larger, the cancel function does nothing and always returns false.
+// The generic unix implementation is based on the posix select syscall.
+func NewReader(reader io.Reader) (CancelReader, error) {
+ return newSelectCancelReader(reader)
+}
diff --git a/vendor/github.com/muesli/cancelreader/cancelreader_windows.go b/vendor/github.com/muesli/cancelreader/cancelreader_windows.go
new file mode 100644
index 000000000..c1dc8d500
--- /dev/null
+++ b/vendor/github.com/muesli/cancelreader/cancelreader_windows.go
@@ -0,0 +1,244 @@
+//go:build windows
+// +build windows
+
+package cancelreader
+
+import (
+ "fmt"
+ "io"
+ "os"
+ "syscall"
+ "time"
+ "unicode/utf16"
+
+ "golang.org/x/sys/windows"
+)
+
+var fileShareValidFlags uint32 = 0x00000007
+
+// NewReader returns a reader and a cancel function. If the input reader is a
+// File with the same file descriptor as os.Stdin, the cancel function can
+// be used to interrupt a blocking read call. In this case, the cancel function
+// returns true if the call was canceled successfully. If the input reader is
+// not a File with the same file descriptor as os.Stdin, the cancel
+// function does nothing and always returns false. The Windows implementation
+// is based on WaitForMultipleObject with overlapping reads from CONIN$.
+func NewReader(reader io.Reader) (CancelReader, error) {
+ if f, ok := reader.(File); !ok || f.Fd() != os.Stdin.Fd() {
+ return newFallbackCancelReader(reader)
+ }
+
+ // it is necessary to open CONIN$ (NOT windows.STD_INPUT_HANDLE) in
+ // overlapped mode to be able to use it with WaitForMultipleObjects.
+ conin, err := windows.CreateFile(
+ &(utf16.Encode([]rune("CONIN$\x00"))[0]), windows.GENERIC_READ|windows.GENERIC_WRITE,
+ fileShareValidFlags, nil, windows.OPEN_EXISTING, windows.FILE_FLAG_OVERLAPPED, 0)
+ if err != nil {
+ return nil, fmt.Errorf("open CONIN$ in overlapping mode: %w", err)
+ }
+
+ resetConsole, err := prepareConsole(conin)
+ if err != nil {
+ return nil, fmt.Errorf("prepare console: %w", err)
+ }
+
+ // flush input, otherwise it can contain events which trigger
+ // WaitForMultipleObjects but which ReadFile cannot read, resulting in an
+ // un-cancelable read
+ err = flushConsoleInputBuffer(conin)
+ if err != nil {
+ return nil, fmt.Errorf("flush console input buffer: %w", err)
+ }
+
+ cancelEvent, err := windows.CreateEvent(nil, 0, 0, nil)
+ if err != nil {
+ return nil, fmt.Errorf("create stop event: %w", err)
+ }
+
+ return &winCancelReader{
+ conin: conin,
+ cancelEvent: cancelEvent,
+ resetConsole: resetConsole,
+ blockingReadSignal: make(chan struct{}, 1),
+ }, nil
+}
+
+type winCancelReader struct {
+ conin windows.Handle
+ cancelEvent windows.Handle
+ cancelMixin
+
+ resetConsole func() error
+ blockingReadSignal chan struct{}
+}
+
+func (r *winCancelReader) Read(data []byte) (int, error) {
+ if r.isCanceled() {
+ return 0, ErrCanceled
+ }
+
+ err := r.wait()
+ if err != nil {
+ return 0, err
+ }
+
+ if r.isCanceled() {
+ return 0, ErrCanceled
+ }
+
+ // windows.Read does not work on overlapping windows.Handles
+ return r.readAsync(data)
+}
+
+// Cancel cancels ongoing and future Read() calls and returns true if the
+// cancelation of the ongoing Read() was successful. On Windows Terminal,
+// WaitForMultipleObjects sometimes immediately returns without input being
+// available. In this case, graceful cancelation is not possible and Cancel()
+// returns false.
+func (r *winCancelReader) Cancel() bool {
+ r.setCanceled()
+
+ select {
+ case r.blockingReadSignal <- struct{}{}:
+ err := windows.SetEvent(r.cancelEvent)
+ if err != nil {
+ return false
+ }
+ <-r.blockingReadSignal
+ case <-time.After(100 * time.Millisecond):
+ // Read() hangs in a GetOverlappedResult which is likely due to
+ // WaitForMultipleObjects returning without input being available
+ // so we cannot cancel this ongoing read.
+ return false
+ }
+
+ return true
+}
+
+func (r *winCancelReader) Close() error {
+ err := windows.CloseHandle(r.cancelEvent)
+ if err != nil {
+ return fmt.Errorf("closing cancel event handle: %w", err)
+ }
+
+ err = r.resetConsole()
+ if err != nil {
+ return err
+ }
+
+ err = windows.Close(r.conin)
+ if err != nil {
+ return fmt.Errorf("closing CONIN$")
+ }
+
+ return nil
+}
+
+func (r *winCancelReader) wait() error {
+ event, err := windows.WaitForMultipleObjects([]windows.Handle{r.conin, r.cancelEvent}, false, windows.INFINITE)
+ switch {
+ case windows.WAIT_OBJECT_0 <= event && event < windows.WAIT_OBJECT_0+2:
+ if event == windows.WAIT_OBJECT_0+1 {
+ return ErrCanceled
+ }
+
+ if event == windows.WAIT_OBJECT_0 {
+ return nil
+ }
+
+ return fmt.Errorf("unexpected wait object is ready: %d", event-windows.WAIT_OBJECT_0)
+ case windows.WAIT_ABANDONED <= event && event < windows.WAIT_ABANDONED+2:
+ return fmt.Errorf("abandoned")
+ case event == uint32(windows.WAIT_TIMEOUT):
+ return fmt.Errorf("timeout")
+ case event == windows.WAIT_FAILED:
+ return fmt.Errorf("failed")
+ default:
+ return fmt.Errorf("unexpected error: %w", error(err))
+ }
+}
+
+// readAsync is necessary to read from a windows.Handle in overlapping mode.
+func (r *winCancelReader) readAsync(data []byte) (int, error) {
+ hevent, err := windows.CreateEvent(nil, 0, 0, nil)
+ if err != nil {
+ return 0, fmt.Errorf("create event: %w", err)
+ }
+
+ overlapped := windows.Overlapped{
+ HEvent: hevent,
+ }
+
+ var n uint32
+
+ err = windows.ReadFile(r.conin, data, &n, &overlapped)
+ if err != nil && err != windows.ERROR_IO_PENDING {
+ return int(n), err
+ }
+
+ r.blockingReadSignal <- struct{}{}
+ err = windows.GetOverlappedResult(r.conin, &overlapped, &n, true)
+ if err != nil {
+ return int(n), nil
+ }
+ <-r.blockingReadSignal
+
+ return int(n), nil
+}
+
+func prepareConsole(input windows.Handle) (reset func() error, err error) {
+ var originalMode uint32
+
+ err = windows.GetConsoleMode(input, &originalMode)
+ if err != nil {
+ return nil, fmt.Errorf("get console mode: %w", err)
+ }
+
+ var newMode uint32
+ newMode &^= windows.ENABLE_ECHO_INPUT
+ newMode &^= windows.ENABLE_LINE_INPUT
+ newMode &^= windows.ENABLE_MOUSE_INPUT
+ newMode &^= windows.ENABLE_WINDOW_INPUT
+ newMode &^= windows.ENABLE_PROCESSED_INPUT
+
+ newMode |= windows.ENABLE_EXTENDED_FLAGS
+ newMode |= windows.ENABLE_INSERT_MODE
+ newMode |= windows.ENABLE_QUICK_EDIT_MODE
+
+ // Enabling virtual terminal input is necessary for processing certain
+ // types of input like X10 mouse events and arrows keys with the current
+ // bytes-based input reader. It does, however, prevent cancelReader from
+ // being able to cancel input. The planned solution for this is to read
+ // Windows events in a more native fashion, rather than the current simple
+ // bytes-based input reader which works well on unix systems.
+ newMode |= windows.ENABLE_VIRTUAL_TERMINAL_INPUT
+
+ err = windows.SetConsoleMode(input, newMode)
+ if err != nil {
+ return nil, fmt.Errorf("set console mode: %w", err)
+ }
+
+ return func() error {
+ err := windows.SetConsoleMode(input, originalMode)
+ if err != nil {
+ return fmt.Errorf("reset console mode: %w", err)
+ }
+
+ return nil
+ }, nil
+}
+
+var (
+ modkernel32 = windows.NewLazySystemDLL("kernel32.dll")
+ procFlushConsoleInputBuffer = modkernel32.NewProc("FlushConsoleInputBuffer")
+)
+
+func flushConsoleInputBuffer(consoleInput windows.Handle) error {
+ r, _, e := syscall.Syscall(procFlushConsoleInputBuffer.Addr(), 1,
+ uintptr(consoleInput), 0, 0)
+ if r == 0 {
+ return error(e)
+ }
+
+ return nil
+}
diff --git a/vendor/github.com/muesli/termenv/.golangci.yml b/vendor/github.com/muesli/termenv/.golangci.yml
deleted file mode 100644
index 684d54bfa..000000000
--- a/vendor/github.com/muesli/termenv/.golangci.yml
+++ /dev/null
@@ -1,28 +0,0 @@
-run:
- tests: false
-
-issues:
- include:
- - EXC0001
- - EXC0005
- - EXC0011
- - EXC0012
- - EXC0013
-
- max-issues-per-linter: 0
- max-same-issues: 0
-
-linters:
- enable:
- - bodyclose
- - goimports
- - gosec
- - nilerr
- - predeclared
- - revive
- - rowserrcheck
- - sqlclosecheck
- - tparallel
- - unconvert
- - unparam
- - whitespace
diff --git a/vendor/github.com/muesli/termenv/LICENSE b/vendor/github.com/muesli/termenv/LICENSE
deleted file mode 100644
index 8532c45c9..000000000
--- a/vendor/github.com/muesli/termenv/LICENSE
+++ /dev/null
@@ -1,21 +0,0 @@
-MIT License
-
-Copyright (c) 2019 Christian Muehlhaeuser
-
-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.
diff --git a/vendor/github.com/muesli/termenv/README.md b/vendor/github.com/muesli/termenv/README.md
deleted file mode 100644
index fa7929d4e..000000000
--- a/vendor/github.com/muesli/termenv/README.md
+++ /dev/null
@@ -1,431 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-`termenv` lets you safely use advanced styling options on the terminal. It
-gathers information about the terminal environment in terms of its ANSI & color
-support and offers you convenient methods to colorize and style your output,
-without you having to deal with all kinds of weird ANSI escape sequences and
-color conversions.
-
-## Features
-
-- RGB/TrueColor support
-- Detects the supported color range of your terminal
-- Automatically converts colors to the best matching, available colors
-- Terminal theme (light/dark) detection
-- Chainable syntax
-- Nested styles
-
-## Installation
-
-```bash
-go get github.com/muesli/termenv
-```
-
-## Usage
-
-```go
-output := termenv.NewOutput(os.Stdout)
-```
-
-`termenv` queries the terminal's capabilities it is running in, so you can
-safely use advanced features, like RGB colors or ANSI styles. `output.Profile`
-returns the supported profile:
-
-- `termenv.Ascii` - no ANSI support detected, ASCII only
-- `termenv.ANSI` - 16 color ANSI support
-- `termenv.ANSI256` - Extended 256 color ANSI support
-- `termenv.TrueColor` - RGB/TrueColor support
-
-Alternatively, you can use `termenv.EnvColorProfile` which evaluates the
-terminal like `ColorProfile`, but also respects the `NO_COLOR` and
-`CLICOLOR_FORCE` environment variables.
-
-You can also query the terminal for its color scheme, so you know whether your
-app is running in a light- or dark-themed environment:
-
-```go
-// Returns terminal's foreground color
-color := output.ForegroundColor()
-
-// Returns terminal's background color
-color := output.BackgroundColor()
-
-// Returns whether terminal uses a dark-ish background
-darkTheme := output.HasDarkBackground()
-```
-
-### Manual Profile Selection
-
-If you don't want to rely on the automatic detection, you can manually select
-the profile you want to use:
-
-```go
-output := termenv.NewOutput(os.Stdout, termenv.WithProfile(termenv.TrueColor))
-```
-
-## Colors
-
-`termenv` supports multiple color profiles: Ascii (black & white only),
-ANSI (16 colors), ANSI Extended (256 colors), and TrueColor (24-bit RGB). Colors
-will automatically be degraded to the best matching available color in the
-desired profile:
-
-`TrueColor` => `ANSI 256 Colors` => `ANSI 16 Colors` => `Ascii`
-
-```go
-s := output.String("Hello World")
-
-// Supports hex values
-// Will automatically degrade colors on terminals not supporting RGB
-s.Foreground(output.Color("#abcdef"))
-// but also supports ANSI colors (0-255)
-s.Background(output.Color("69"))
-// ...or the color.Color interface
-s.Foreground(output.FromColor(color.RGBA{255, 128, 0, 255}))
-
-// Combine fore- & background colors
-s.Foreground(output.Color("#ffffff")).Background(output.Color("#0000ff"))
-
-// Supports the fmt.Stringer interface
-fmt.Println(s)
-```
-
-## Styles
-
-You can use a chainable syntax to compose your own styles:
-
-```go
-s := output.String("foobar")
-
-// Text styles
-s.Bold()
-s.Faint()
-s.Italic()
-s.CrossOut()
-s.Underline()
-s.Overline()
-
-// Reverse swaps current fore- & background colors
-s.Reverse()
-
-// Blinking text
-s.Blink()
-
-// Combine multiple options
-s.Bold().Underline()
-```
-
-## Template Helpers
-
-`termenv` provides a set of helper functions to style your Go templates:
-
-```go
-// load template helpers
-f := output.TemplateFuncs()
-tpl := template.New("tpl").Funcs(f)
-
-// apply bold style in a template
-bold := `{{ Bold "Hello World" }}`
-
-// examples for colorized templates
-col := `{{ Color "#ff0000" "#0000ff" "Red on Blue" }}`
-fg := `{{ Foreground "#ff0000" "Red Foreground" }}`
-bg := `{{ Background "#0000ff" "Blue Background" }}`
-
-// wrap styles
-wrap := `{{ Bold (Underline "Hello World") }}`
-
-// parse and render
-tpl, err = tpl.Parse(bold)
-
-var buf bytes.Buffer
-tpl.Execute(&buf, nil)
-fmt.Println(&buf)
-```
-
-Other available helper functions are: `Faint`, `Italic`, `CrossOut`,
-`Underline`, `Overline`, `Reverse`, and `Blink`.
-
-## Positioning
-
-```go
-// Move the cursor to a given position
-output.MoveCursor(row, column)
-
-// Save the cursor position
-output.SaveCursorPosition()
-
-// Restore a saved cursor position
-output.RestoreCursorPosition()
-
-// Move the cursor up a given number of lines
-output.CursorUp(n)
-
-// Move the cursor down a given number of lines
-output.CursorDown(n)
-
-// Move the cursor up a given number of lines
-output.CursorForward(n)
-
-// Move the cursor backwards a given number of cells
-output.CursorBack(n)
-
-// Move the cursor down a given number of lines and place it at the beginning
-// of the line
-output.CursorNextLine(n)
-
-// Move the cursor up a given number of lines and place it at the beginning of
-// the line
-output.CursorPrevLine(n)
-```
-
-## Screen
-
-```go
-// Reset the terminal to its default style, removing any active styles
-output.Reset()
-
-// RestoreScreen restores a previously saved screen state
-output.RestoreScreen()
-
-// SaveScreen saves the screen state
-output.SaveScreen()
-
-// Switch to the altscreen. The former view can be restored with ExitAltScreen()
-output.AltScreen()
-
-// Exit the altscreen and return to the former terminal view
-output.ExitAltScreen()
-
-// Clear the visible portion of the terminal
-output.ClearScreen()
-
-// Clear the current line
-output.ClearLine()
-
-// Clear a given number of lines
-output.ClearLines(n)
-
-// Set the scrolling region of the terminal
-output.ChangeScrollingRegion(top, bottom)
-
-// Insert the given number of lines at the top of the scrollable region, pushing
-// lines below down
-output.InsertLines(n)
-
-// Delete the given number of lines, pulling any lines in the scrollable region
-// below up
-output.DeleteLines(n)
-```
-
-## Session
-
-```go
-// SetWindowTitle sets the terminal window title
-output.SetWindowTitle(title)
-
-// SetForegroundColor sets the default foreground color
-output.SetForegroundColor(color)
-
-// SetBackgroundColor sets the default background color
-output.SetBackgroundColor(color)
-
-// SetCursorColor sets the cursor color
-output.SetCursorColor(color)
-
-// Hide the cursor
-output.HideCursor()
-
-// Show the cursor
-output.ShowCursor()
-
-// Copy to clipboard
-output.Copy(message)
-
-// Copy to primary clipboard (X11)
-output.CopyPrimary(message)
-
-// Trigger notification
-output.Notify(title, body)
-```
-
-## Mouse
-
-```go
-// Enable X10 mouse mode, only button press events are sent
-output.EnableMousePress()
-
-// Disable X10 mouse mode
-output.DisableMousePress()
-
-// Enable Mouse Tracking mode
-output.EnableMouse()
-
-// Disable Mouse Tracking mode
-output.DisableMouse()
-
-// Enable Hilite Mouse Tracking mode
-output.EnableMouseHilite()
-
-// Disable Hilite Mouse Tracking mode
-output.DisableMouseHilite()
-
-// Enable Cell Motion Mouse Tracking mode
-output.EnableMouseCellMotion()
-
-// Disable Cell Motion Mouse Tracking mode
-output.DisableMouseCellMotion()
-
-// Enable All Motion Mouse mode
-output.EnableMouseAllMotion()
-
-// Disable All Motion Mouse mode
-output.DisableMouseAllMotion()
-```
-
-## Bracketed Paste
-
-```go
-// Enables bracketed paste mode
-termenv.EnableBracketedPaste()
-
-// Disables bracketed paste mode
-termenv.DisableBracketedPaste()
-```
-
-## Terminal Feature Support
-
-### Color Support
-
-- 24-bit (RGB): alacritty, foot, iTerm, kitty, Konsole, st, tmux, vte-based, wezterm, Ghostty, Windows Terminal
-- 8-bit (256): rxvt, screen, xterm, Apple Terminal
-- 4-bit (16): Linux Console
-
-### Control Sequences
-
-
-Click to show feature matrix
-
-| Terminal | Query Color Scheme | Query Cursor Position | Set Window Title | Change Cursor Color | Change Default Foreground Setting | Change Default Background Setting | Bracketed Paste | Extended Mouse (SGR) | Pixels Mouse (SGR-Pixels) |
-| ---------------- | :----------------: | :-------------------: | :--------------: | :-----------------: | :-------------------------------: | :-------------------------------: | :-------------: | :------------------: | :-----------------------: |
-| alacritty | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ |
-| foot | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
-| kitty | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
-| Konsole | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ✅ | ✅ | ❌ |
-| rxvt | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ |
-| urxvt | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ |
-| screen | ⛔[^mux] | ✅ | ✅ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ |
-| st | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ |
-| tmux | ⛔[^mux] | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ |
-| vte-based[^vte] | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ❌ |
-| wezterm | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
-| xterm | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ✅ | ✅ | ❌ |
-| Linux Console | ❌ | ✅ | ⛔ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
-| Apple Terminal | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ✅ | ✅ | ❌ |
-| iTerm | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ✅ | ✅ | ❌ |
-| Windows cmd | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ |
-| Windows Terminal | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ |
-
-[^vte]: This covers all vte-based terminals, including Gnome Terminal, guake, Pantheon Terminal, Terminator, Tilix, XFCE Terminal.
-[^mux]: Unavailable as multiplexers (like tmux or screen) can be connected to multiple terminals (with different color settings) at the same time.
-
-You can help improve this list! Check out [how to](ansi_compat.md) and open an issue or pull request.
-
-
-
-### System Commands
-
-
-Click to show feature matrix
-
-| Terminal | Copy to Clipboard (OSC52) | Hyperlinks (OSC8) | Notifications (OSC777) |
-| ---------------- | :-----------------------: | :---------------: | :--------------------: |
-| alacritty | ✅ | ✅[^alacritty] | ❌ |
-| foot | ✅ | ✅ | ✅ |
-| kitty | ✅ | ✅ | ✅ |
-| Konsole | ❌[^konsole] | ✅ | ❌ |
-| rxvt | ❌ | ❌ | ❌ |
-| urxvt | ✅[^urxvt] | ❌ | ✅ |
-| screen | ✅ | ❌[^screen] | ❌ |
-| st | ✅ | ❌ | ❌ |
-| tmux | ✅ | ❌[^tmux] | ❌ |
-| vte-based[^vte] | ❌[^vte] | ✅ | ❌ |
-| wezterm | ✅ | ✅ | ❌ |
-| xterm | ✅ | ❌ | ❌ |
-| Linux Console | ⛔ | ⛔ | ❌ |
-| Apple Terminal | ✅[^apple] | ❌ | ❌ |
-| iTerm | ✅ | ✅ | ❌ |
-| Windows cmd | ❌ | ❌ | ❌ |
-| Windows Terminal | ✅ | ✅ | ❌ |
-
-[^vte]: This covers all vte-based terminals, including Gnome Terminal, guake, Pantheon Terminal, Terminator, Tilix, XFCE Terminal. OSC52 is not supported, see [issue#2495](https://gitlab.gnome.org/GNOME/vte/-/issues/2495).
-[^urxvt]: Workaround for urxvt not supporting OSC52. See [this](https://unix.stackexchange.com/a/629485) for more information.
-[^konsole]: OSC52 is not supported, for more info see [bug#372116](https://bugs.kde.org/show_bug.cgi?id=372116).
-[^apple]: OSC52 works with a [workaround](https://github.com/roy2220/osc52pty).
-[^tmux]: OSC8 is not supported, for more info see [issue#911](https://github.com/tmux/tmux/issues/911).
-[^screen]: OSC8 is not supported, for more info see [bug#50952](https://savannah.gnu.org/bugs/index.php?50952).
-[^alacritty]: OSC8 is supported since [v0.11.0](https://github.com/alacritty/alacritty/releases/tag/v0.11.0)
-
-
-
-## Platform Support
-
-`termenv` works on Unix systems (like Linux, macOS, or BSD) and Windows. While
-terminal applications on Unix support ANSI styling out-of-the-box, on Windows
-you need to enable ANSI processing in your application first:
-
-```go
- restoreConsole, err := termenv.EnableVirtualTerminalProcessing(termenv.DefaultOutput())
- if err != nil {
- panic(err)
- }
- defer restoreConsole()
-```
-
-The above code is safe to include on non-Windows systems or when os.Stdout does
-not refer to a terminal (e.g. in tests).
-
-## Color Chart
-
-
-
-You can find the source code used to create this chart in `termenv`'s examples.
-
-## Related Projects
-
-- [reflow](https://github.com/muesli/reflow) - ANSI-aware text operations
-- [Lip Gloss](https://github.com/charmbracelet/lipgloss) - style definitions for nice terminal layouts 👄
-- [ansi](https://github.com/muesli/ansi) - ANSI sequence helpers
-
-## termenv in the Wild
-
-Need some inspiration or just want to see how others are using `termenv`? Check
-out these projects:
-
-- [Bubble Tea](https://github.com/charmbracelet/bubbletea) - a powerful little TUI framework 🏗
-- [Glamour](https://github.com/charmbracelet/glamour) - stylesheet-based markdown rendering for your CLI apps 💇🏻♀️
-- [Glow](https://github.com/charmbracelet/glow) - a markdown renderer for the command-line 💅🏻
-- [duf](https://github.com/muesli/duf) - Disk Usage/Free Utility - a better 'df' alternative
-- [gitty](https://github.com/muesli/gitty) - contextual information about your git projects
-- [slides](https://github.com/maaslalani/slides) - terminal-based presentation tool
-
-## Feedback
-
-Got some feedback or suggestions? Please open an issue or drop me a note!
-
-- [Twitter](https://twitter.com/mueslix)
-- [The Fediverse](https://mastodon.social/@fribbledom)
-
-## License
-
-[MIT](https://github.com/muesli/termenv/raw/master/LICENSE)
diff --git a/vendor/github.com/muesli/termenv/ansi_compat.md b/vendor/github.com/muesli/termenv/ansi_compat.md
deleted file mode 100644
index 6b68a3a9a..000000000
--- a/vendor/github.com/muesli/termenv/ansi_compat.md
+++ /dev/null
@@ -1,65 +0,0 @@
-## Change Foreground Color
-
-This command should enable a blue foreground color:
-
-```bash
-echo -ne "\033]10;#0000ff\007"
-```
-
-## Change Background Color
-
-This command should enable a green background color:
-
-```bash
-echo -ne "\033]11;#00ff00\007"
-```
-
-## Change Cursor Color
-
-This command should enable a red cursor color:
-
-```bash
-echo -ne "\033]12;#ff0000\007"
-```
-
-## Query Color Scheme
-
-These two commands should print out the currently active color scheme:
-
-```bash
-echo -ne "\033]10;?\033\\"
-echo -ne "\033]11;?\033\\"
-```
-
-## Query Cursor Position
-
-This command should print out the current cursor position:
-
-```bash
-echo -ne "\033[6n"
-```
-
-## Set Window Title
-
-This command should set the window title to "Test":
-
-```bash
-echo -ne "\033]2;Test\007" && sleep 10
-```
-
-## Bracketed paste
-
-Enter this command, then paste a word from the clipboard. The text
-displayed on the terminal should contain the codes `200~` and `201~`:
-
-```bash
-echo -ne "\033[?2004h" && sleep 10
-```
-
-## Trigger Notification
-
-This command should trigger a notification:
-
-```bash
-echo -ne "\033]777;notify;Title;Body\033\\"
-```
diff --git a/vendor/github.com/muesli/termenv/ansicolors.go b/vendor/github.com/muesli/termenv/ansicolors.go
deleted file mode 100644
index 1a301b0fe..000000000
--- a/vendor/github.com/muesli/termenv/ansicolors.go
+++ /dev/null
@@ -1,281 +0,0 @@
-package termenv
-
-// ANSI color codes.
-const (
- ANSIBlack ANSIColor = iota
- ANSIRed
- ANSIGreen
- ANSIYellow
- ANSIBlue
- ANSIMagenta
- ANSICyan
- ANSIWhite
- ANSIBrightBlack
- ANSIBrightRed
- ANSIBrightGreen
- ANSIBrightYellow
- ANSIBrightBlue
- ANSIBrightMagenta
- ANSIBrightCyan
- ANSIBrightWhite
-)
-
-// RGB values of ANSI colors (0-255).
-var ansiHex = []string{
- "#000000",
- "#800000",
- "#008000",
- "#808000",
- "#000080",
- "#800080",
- "#008080",
- "#c0c0c0",
- "#808080",
- "#ff0000",
- "#00ff00",
- "#ffff00",
- "#0000ff",
- "#ff00ff",
- "#00ffff",
- "#ffffff",
- "#000000",
- "#00005f",
- "#000087",
- "#0000af",
- "#0000d7",
- "#0000ff",
- "#005f00",
- "#005f5f",
- "#005f87",
- "#005faf",
- "#005fd7",
- "#005fff",
- "#008700",
- "#00875f",
- "#008787",
- "#0087af",
- "#0087d7",
- "#0087ff",
- "#00af00",
- "#00af5f",
- "#00af87",
- "#00afaf",
- "#00afd7",
- "#00afff",
- "#00d700",
- "#00d75f",
- "#00d787",
- "#00d7af",
- "#00d7d7",
- "#00d7ff",
- "#00ff00",
- "#00ff5f",
- "#00ff87",
- "#00ffaf",
- "#00ffd7",
- "#00ffff",
- "#5f0000",
- "#5f005f",
- "#5f0087",
- "#5f00af",
- "#5f00d7",
- "#5f00ff",
- "#5f5f00",
- "#5f5f5f",
- "#5f5f87",
- "#5f5faf",
- "#5f5fd7",
- "#5f5fff",
- "#5f8700",
- "#5f875f",
- "#5f8787",
- "#5f87af",
- "#5f87d7",
- "#5f87ff",
- "#5faf00",
- "#5faf5f",
- "#5faf87",
- "#5fafaf",
- "#5fafd7",
- "#5fafff",
- "#5fd700",
- "#5fd75f",
- "#5fd787",
- "#5fd7af",
- "#5fd7d7",
- "#5fd7ff",
- "#5fff00",
- "#5fff5f",
- "#5fff87",
- "#5fffaf",
- "#5fffd7",
- "#5fffff",
- "#870000",
- "#87005f",
- "#870087",
- "#8700af",
- "#8700d7",
- "#8700ff",
- "#875f00",
- "#875f5f",
- "#875f87",
- "#875faf",
- "#875fd7",
- "#875fff",
- "#878700",
- "#87875f",
- "#878787",
- "#8787af",
- "#8787d7",
- "#8787ff",
- "#87af00",
- "#87af5f",
- "#87af87",
- "#87afaf",
- "#87afd7",
- "#87afff",
- "#87d700",
- "#87d75f",
- "#87d787",
- "#87d7af",
- "#87d7d7",
- "#87d7ff",
- "#87ff00",
- "#87ff5f",
- "#87ff87",
- "#87ffaf",
- "#87ffd7",
- "#87ffff",
- "#af0000",
- "#af005f",
- "#af0087",
- "#af00af",
- "#af00d7",
- "#af00ff",
- "#af5f00",
- "#af5f5f",
- "#af5f87",
- "#af5faf",
- "#af5fd7",
- "#af5fff",
- "#af8700",
- "#af875f",
- "#af8787",
- "#af87af",
- "#af87d7",
- "#af87ff",
- "#afaf00",
- "#afaf5f",
- "#afaf87",
- "#afafaf",
- "#afafd7",
- "#afafff",
- "#afd700",
- "#afd75f",
- "#afd787",
- "#afd7af",
- "#afd7d7",
- "#afd7ff",
- "#afff00",
- "#afff5f",
- "#afff87",
- "#afffaf",
- "#afffd7",
- "#afffff",
- "#d70000",
- "#d7005f",
- "#d70087",
- "#d700af",
- "#d700d7",
- "#d700ff",
- "#d75f00",
- "#d75f5f",
- "#d75f87",
- "#d75faf",
- "#d75fd7",
- "#d75fff",
- "#d78700",
- "#d7875f",
- "#d78787",
- "#d787af",
- "#d787d7",
- "#d787ff",
- "#d7af00",
- "#d7af5f",
- "#d7af87",
- "#d7afaf",
- "#d7afd7",
- "#d7afff",
- "#d7d700",
- "#d7d75f",
- "#d7d787",
- "#d7d7af",
- "#d7d7d7",
- "#d7d7ff",
- "#d7ff00",
- "#d7ff5f",
- "#d7ff87",
- "#d7ffaf",
- "#d7ffd7",
- "#d7ffff",
- "#ff0000",
- "#ff005f",
- "#ff0087",
- "#ff00af",
- "#ff00d7",
- "#ff00ff",
- "#ff5f00",
- "#ff5f5f",
- "#ff5f87",
- "#ff5faf",
- "#ff5fd7",
- "#ff5fff",
- "#ff8700",
- "#ff875f",
- "#ff8787",
- "#ff87af",
- "#ff87d7",
- "#ff87ff",
- "#ffaf00",
- "#ffaf5f",
- "#ffaf87",
- "#ffafaf",
- "#ffafd7",
- "#ffafff",
- "#ffd700",
- "#ffd75f",
- "#ffd787",
- "#ffd7af",
- "#ffd7d7",
- "#ffd7ff",
- "#ffff00",
- "#ffff5f",
- "#ffff87",
- "#ffffaf",
- "#ffffd7",
- "#ffffff",
- "#080808",
- "#121212",
- "#1c1c1c",
- "#262626",
- "#303030",
- "#3a3a3a",
- "#444444",
- "#4e4e4e",
- "#585858",
- "#626262",
- "#6c6c6c",
- "#767676",
- "#808080",
- "#8a8a8a",
- "#949494",
- "#9e9e9e",
- "#a8a8a8",
- "#b2b2b2",
- "#bcbcbc",
- "#c6c6c6",
- "#d0d0d0",
- "#dadada",
- "#e4e4e4",
- "#eeeeee",
-}
diff --git a/vendor/github.com/muesli/termenv/color.go b/vendor/github.com/muesli/termenv/color.go
deleted file mode 100644
index 59e639b11..000000000
--- a/vendor/github.com/muesli/termenv/color.go
+++ /dev/null
@@ -1,205 +0,0 @@
-package termenv
-
-import (
- "errors"
- "fmt"
- "math"
- "strings"
-
- "github.com/lucasb-eyer/go-colorful"
-)
-
-// ErrInvalidColor gets returned when a color is invalid.
-var ErrInvalidColor = errors.New("invalid color")
-
-// Foreground and Background sequence codes.
-const (
- Foreground = "38"
- Background = "48"
-)
-
-// Color is an interface implemented by all colors that can be converted to an
-// ANSI sequence.
-type Color interface {
- // Sequence returns the ANSI Sequence for the color.
- Sequence(bg bool) string
-}
-
-// NoColor is a nop for terminals that don't support colors.
-type NoColor struct{}
-
-func (c NoColor) String() string {
- return ""
-}
-
-// ANSIColor is a color (0-15) as defined by the ANSI Standard.
-type ANSIColor int
-
-func (c ANSIColor) String() string {
- return ansiHex[c]
-}
-
-// ANSI256Color is a color (16-255) as defined by the ANSI Standard.
-type ANSI256Color int
-
-func (c ANSI256Color) String() string {
- return ansiHex[c]
-}
-
-// RGBColor is a hex-encoded color, e.g. "#abcdef".
-type RGBColor string
-
-// ConvertToRGB converts a Color to a colorful.Color.
-func ConvertToRGB(c Color) colorful.Color {
- var hex string
- switch v := c.(type) {
- case RGBColor:
- hex = string(v)
- case ANSIColor:
- hex = ansiHex[v]
- case ANSI256Color:
- hex = ansiHex[v]
- }
-
- ch, _ := colorful.Hex(hex)
- return ch
-}
-
-// Sequence returns the ANSI Sequence for the color.
-func (c NoColor) Sequence(_ bool) string {
- return ""
-}
-
-// Sequence returns the ANSI Sequence for the color.
-//
-//nolint:mnd
-func (c ANSIColor) Sequence(bg bool) string {
- col := int(c)
- bgMod := func(c int) int {
- if bg {
- return c + 10
- }
- return c
- }
-
- if col < 8 {
- return fmt.Sprintf("%d", bgMod(col)+30) //nolint:mnd
- }
- return fmt.Sprintf("%d", bgMod(col-8)+90) //nolint:mnd
-}
-
-// Sequence returns the ANSI Sequence for the color.
-func (c ANSI256Color) Sequence(bg bool) string {
- prefix := Foreground
- if bg {
- prefix = Background
- }
- return fmt.Sprintf("%s;5;%d", prefix, c)
-}
-
-// Sequence returns the ANSI Sequence for the color.
-func (c RGBColor) Sequence(bg bool) string {
- f, err := colorful.Hex(string(c))
- if err != nil {
- return ""
- }
-
- prefix := Foreground
- if bg {
- prefix = Background
- }
- return fmt.Sprintf("%s;2;%d;%d;%d", prefix, uint8(f.R*255), uint8(f.G*255), uint8(f.B*255)) //nolint:mnd
-}
-
-func xTermColor(s string) (RGBColor, error) {
- if len(s) < 24 || len(s) > 25 {
- return RGBColor(""), ErrInvalidColor
- }
-
- switch {
- case strings.HasSuffix(s, string(BEL)):
- s = strings.TrimSuffix(s, string(BEL))
- case strings.HasSuffix(s, string(ESC)):
- s = strings.TrimSuffix(s, string(ESC))
- case strings.HasSuffix(s, ST):
- s = strings.TrimSuffix(s, ST)
- default:
- return RGBColor(""), ErrInvalidColor
- }
-
- s = s[4:]
-
- prefix := ";rgb:"
- if !strings.HasPrefix(s, prefix) {
- return RGBColor(""), ErrInvalidColor
- }
- s = strings.TrimPrefix(s, prefix)
-
- h := strings.Split(s, "/")
- hex := fmt.Sprintf("#%s%s%s", h[0][:2], h[1][:2], h[2][:2])
- return RGBColor(hex), nil
-}
-
-func ansi256ToANSIColor(c ANSI256Color) ANSIColor {
- var r int
- md := math.MaxFloat64
-
- h, _ := colorful.Hex(ansiHex[c])
- for i := 0; i <= 15; i++ {
- hb, _ := colorful.Hex(ansiHex[i])
- d := h.DistanceHSLuv(hb)
-
- if d < md {
- md = d
- r = i
- }
- }
-
- return ANSIColor(r)
-}
-
-//nolint:mnd
-func hexToANSI256Color(c colorful.Color) ANSI256Color {
- v2ci := func(v float64) int {
- if v < 48 {
- return 0
- }
- if v < 115 {
- return 1
- }
- return int((v - 35) / 40)
- }
-
- // Calculate the nearest 0-based color index at 16..231
- r := v2ci(c.R * 255.0) // 0..5 each
- g := v2ci(c.G * 255.0)
- b := v2ci(c.B * 255.0)
- ci := 36*r + 6*g + b /* 0..215 */
-
- // Calculate the represented colors back from the index
- i2cv := [6]int{0, 0x5f, 0x87, 0xaf, 0xd7, 0xff}
- cr := i2cv[r] // r/g/b, 0..255 each
- cg := i2cv[g]
- cb := i2cv[b]
-
- // Calculate the nearest 0-based gray index at 232..255
- var grayIdx int
- average := (r + g + b) / 3
- if average > 238 {
- grayIdx = 23
- } else {
- grayIdx = (average - 3) / 10 // 0..23
- }
- gv := 8 + 10*grayIdx // same value for r/g/b, 0..255
-
- // Return the one which is nearer to the original input rgb value
- c2 := colorful.Color{R: float64(cr) / 255.0, G: float64(cg) / 255.0, B: float64(cb) / 255.0}
- g2 := colorful.Color{R: float64(gv) / 255.0, G: float64(gv) / 255.0, B: float64(gv) / 255.0}
- colorDist := c.DistanceHSLuv(c2)
- grayDist := c.DistanceHSLuv(g2)
-
- if colorDist <= grayDist {
- return ANSI256Color(16 + ci)
- }
- return ANSI256Color(232 + grayIdx)
-}
diff --git a/vendor/github.com/muesli/termenv/constants_linux.go b/vendor/github.com/muesli/termenv/constants_linux.go
deleted file mode 100644
index 4262f03b9..000000000
--- a/vendor/github.com/muesli/termenv/constants_linux.go
+++ /dev/null
@@ -1,8 +0,0 @@
-package termenv
-
-import "golang.org/x/sys/unix"
-
-const (
- tcgetattr = unix.TCGETS
- tcsetattr = unix.TCSETS
-)
diff --git a/vendor/github.com/muesli/termenv/constants_solaris.go b/vendor/github.com/muesli/termenv/constants_solaris.go
deleted file mode 100644
index 4262f03b9..000000000
--- a/vendor/github.com/muesli/termenv/constants_solaris.go
+++ /dev/null
@@ -1,8 +0,0 @@
-package termenv
-
-import "golang.org/x/sys/unix"
-
-const (
- tcgetattr = unix.TCGETS
- tcsetattr = unix.TCSETS
-)
diff --git a/vendor/github.com/muesli/termenv/constants_unix.go b/vendor/github.com/muesli/termenv/constants_unix.go
deleted file mode 100644
index 5d664245e..000000000
--- a/vendor/github.com/muesli/termenv/constants_unix.go
+++ /dev/null
@@ -1,13 +0,0 @@
-//go:build (darwin || dragonfly || freebsd || netbsd || openbsd) && !solaris && !illumos
-// +build darwin dragonfly freebsd netbsd openbsd
-// +build !solaris
-// +build !illumos
-
-package termenv
-
-import "golang.org/x/sys/unix"
-
-const (
- tcgetattr = unix.TIOCGETA
- tcsetattr = unix.TIOCSETA
-)
diff --git a/vendor/github.com/muesli/termenv/constants_zos.go b/vendor/github.com/muesli/termenv/constants_zos.go
deleted file mode 100644
index 4262f03b9..000000000
--- a/vendor/github.com/muesli/termenv/constants_zos.go
+++ /dev/null
@@ -1,8 +0,0 @@
-package termenv
-
-import "golang.org/x/sys/unix"
-
-const (
- tcgetattr = unix.TCGETS
- tcsetattr = unix.TCSETS
-)
diff --git a/vendor/github.com/muesli/termenv/copy.go b/vendor/github.com/muesli/termenv/copy.go
deleted file mode 100644
index 4bf5c9fea..000000000
--- a/vendor/github.com/muesli/termenv/copy.go
+++ /dev/null
@@ -1,37 +0,0 @@
-package termenv
-
-import (
- "strings"
-
- "github.com/aymanbagabas/go-osc52/v2"
-)
-
-// Copy copies text to clipboard using OSC 52 escape sequence.
-func (o Output) Copy(str string) {
- s := osc52.New(str)
- if strings.HasPrefix(o.environ.Getenv("TERM"), "screen") {
- s = s.Screen()
- }
- _, _ = s.WriteTo(o)
-}
-
-// CopyPrimary copies text to primary clipboard (X11) using OSC 52 escape
-// sequence.
-func (o Output) CopyPrimary(str string) {
- s := osc52.New(str).Primary()
- if strings.HasPrefix(o.environ.Getenv("TERM"), "screen") {
- s = s.Screen()
- }
- _, _ = s.WriteTo(o)
-}
-
-// Copy copies text to clipboard using OSC 52 escape sequence.
-func Copy(str string) {
- output.Copy(str)
-}
-
-// CopyPrimary copies text to primary clipboard (X11) using OSC 52 escape
-// sequence.
-func CopyPrimary(str string) {
- output.CopyPrimary(str)
-}
diff --git a/vendor/github.com/muesli/termenv/hyperlink.go b/vendor/github.com/muesli/termenv/hyperlink.go
deleted file mode 100644
index 97e760a3b..000000000
--- a/vendor/github.com/muesli/termenv/hyperlink.go
+++ /dev/null
@@ -1,11 +0,0 @@
-package termenv
-
-// Hyperlink creates a hyperlink using OSC8.
-func Hyperlink(link, name string) string {
- return output.Hyperlink(link, name)
-}
-
-// Hyperlink creates a hyperlink using OSC8.
-func (o *Output) Hyperlink(link, name string) string {
- return OSC + "8;;" + link + ST + name + OSC + "8;;" + ST
-}
diff --git a/vendor/github.com/muesli/termenv/notification.go b/vendor/github.com/muesli/termenv/notification.go
deleted file mode 100644
index 2a8cf06a9..000000000
--- a/vendor/github.com/muesli/termenv/notification.go
+++ /dev/null
@@ -1,11 +0,0 @@
-package termenv
-
-// Notify triggers a notification using OSC777.
-func Notify(title, body string) {
- output.Notify(title, body)
-}
-
-// Notify triggers a notification using OSC777.
-func (o *Output) Notify(title, body string) {
- _, _ = o.WriteString(OSC + "777;notify;" + title + ";" + body + ST)
-}
diff --git a/vendor/github.com/muesli/termenv/output.go b/vendor/github.com/muesli/termenv/output.go
deleted file mode 100644
index e4434de03..000000000
--- a/vendor/github.com/muesli/termenv/output.go
+++ /dev/null
@@ -1,205 +0,0 @@
-package termenv
-
-import (
- "io"
- "os"
- "sync"
-)
-
-// output is the default global output.
-var output = NewOutput(os.Stdout)
-
-// File represents a file descriptor.
-//
-// Deprecated: Use *os.File instead.
-type File interface {
- io.ReadWriter
- Fd() uintptr
-}
-
-// OutputOption sets an option on Output.
-type OutputOption = func(*Output)
-
-// Output is a terminal output.
-type Output struct {
- Profile
- w io.Writer
- environ Environ
-
- assumeTTY bool
- unsafe bool
- cache bool
- fgSync *sync.Once
- fgColor Color
- bgSync *sync.Once
- bgColor Color
-}
-
-// Environ is an interface for getting environment variables.
-type Environ interface {
- Environ() []string
- Getenv(string) string
-}
-
-type osEnviron struct{}
-
-func (oe *osEnviron) Environ() []string {
- return os.Environ()
-}
-
-func (oe *osEnviron) Getenv(key string) string {
- return os.Getenv(key)
-}
-
-// DefaultOutput returns the default global output.
-func DefaultOutput() *Output {
- return output
-}
-
-// SetDefaultOutput sets the default global output.
-func SetDefaultOutput(o *Output) {
- output = o
-}
-
-// NewOutput returns a new Output for the given writer.
-func NewOutput(w io.Writer, opts ...OutputOption) *Output {
- o := &Output{
- w: w,
- environ: &osEnviron{},
- Profile: -1,
- fgSync: &sync.Once{},
- fgColor: NoColor{},
- bgSync: &sync.Once{},
- bgColor: NoColor{},
- }
-
- if o.w == nil {
- o.w = os.Stdout
- }
- for _, opt := range opts {
- opt(o)
- }
- if o.Profile < 0 {
- o.Profile = o.EnvColorProfile()
- }
-
- return o
-}
-
-// WithEnvironment returns a new OutputOption for the given environment.
-func WithEnvironment(environ Environ) OutputOption {
- return func(o *Output) {
- o.environ = environ
- }
-}
-
-// WithProfile returns a new OutputOption for the given profile.
-func WithProfile(profile Profile) OutputOption {
- return func(o *Output) {
- o.Profile = profile
- }
-}
-
-// WithColorCache returns a new OutputOption with fore- and background color values
-// pre-fetched and cached.
-func WithColorCache(v bool) OutputOption {
- return func(o *Output) {
- o.cache = v
-
- // cache the values now
- _ = o.ForegroundColor()
- _ = o.BackgroundColor()
- }
-}
-
-// WithTTY returns a new OutputOption to assume whether or not the output is a TTY.
-// This is useful when mocking console output.
-func WithTTY(v bool) OutputOption {
- return func(o *Output) {
- o.assumeTTY = v
- }
-}
-
-// WithUnsafe returns a new OutputOption with unsafe mode enabled. Unsafe mode doesn't
-// check whether or not the terminal is a TTY.
-//
-// This option supersedes WithTTY.
-//
-// This is useful when mocking console output and enforcing ANSI escape output
-// e.g. on SSH sessions.
-func WithUnsafe() OutputOption {
- return func(o *Output) {
- o.unsafe = true
- }
-}
-
-// ForegroundColor returns the terminal's default foreground color.
-func (o *Output) ForegroundColor() Color {
- f := func() {
- if !o.isTTY() {
- return
- }
-
- o.fgColor = o.foregroundColor()
- }
-
- if o.cache {
- o.fgSync.Do(f)
- } else {
- f()
- }
-
- return o.fgColor
-}
-
-// BackgroundColor returns the terminal's default background color.
-func (o *Output) BackgroundColor() Color {
- f := func() {
- if !o.isTTY() {
- return
- }
-
- o.bgColor = o.backgroundColor()
- }
-
- if o.cache {
- o.bgSync.Do(f)
- } else {
- f()
- }
-
- return o.bgColor
-}
-
-// HasDarkBackground returns whether terminal uses a dark-ish background.
-func (o *Output) HasDarkBackground() bool {
- c := ConvertToRGB(o.BackgroundColor())
- _, _, l := c.Hsl()
- return l < 0.5 //nolint:mnd
-}
-
-// TTY returns the terminal's file descriptor. This may be nil if the output is
-// not a terminal.
-//
-// Deprecated: Use Writer() instead.
-func (o Output) TTY() File {
- if f, ok := o.w.(File); ok {
- return f
- }
- return nil
-}
-
-// Writer returns the underlying writer. This may be of type io.Writer,
-// io.ReadWriter, or *os.File.
-func (o Output) Writer() io.Writer {
- return o.w
-}
-
-func (o Output) Write(p []byte) (int, error) {
- return o.w.Write(p) //nolint:wrapcheck
-}
-
-// WriteString writes the given string to the output.
-func (o Output) WriteString(s string) (int, error) {
- return o.Write([]byte(s))
-}
diff --git a/vendor/github.com/muesli/termenv/profile.go b/vendor/github.com/muesli/termenv/profile.go
deleted file mode 100644
index 7d38f5fb0..000000000
--- a/vendor/github.com/muesli/termenv/profile.go
+++ /dev/null
@@ -1,112 +0,0 @@
-package termenv
-
-import (
- "image/color"
- "strconv"
- "strings"
-
- "github.com/lucasb-eyer/go-colorful"
-)
-
-// Profile is a color profile: Ascii, ANSI, ANSI256, or TrueColor.
-type Profile int
-
-const (
- // TrueColor, 24-bit color profile.
- TrueColor = Profile(iota)
- // ANSI256, 8-bit color profile.
- ANSI256
- // ANSI, 4-bit color profile.
- ANSI
- // Ascii, uncolored profile.
- Ascii //nolint:revive
-)
-
-// Name returns the profile name as a string.
-func (p Profile) Name() string {
- switch p {
- case Ascii:
- return "Ascii"
- case ANSI:
- return "ANSI"
- case ANSI256:
- return "ANSI256"
- case TrueColor:
- return "TrueColor"
- }
- return "Unknown"
-}
-
-// String returns a new Style.
-func (p Profile) String(s ...string) Style {
- return Style{
- profile: p,
- string: strings.Join(s, " "),
- }
-}
-
-// Convert transforms a given Color to a Color supported within the Profile.
-func (p Profile) Convert(c Color) Color {
- if p == Ascii {
- return NoColor{}
- }
-
- switch v := c.(type) {
- case ANSIColor:
- return v
-
- case ANSI256Color:
- if p == ANSI {
- return ansi256ToANSIColor(v)
- }
- return v
-
- case RGBColor:
- h, err := colorful.Hex(string(v))
- if err != nil {
- return nil
- }
- if p != TrueColor {
- ac := hexToANSI256Color(h)
- if p == ANSI {
- return ansi256ToANSIColor(ac)
- }
- return ac
- }
- return v
- }
-
- return c
-}
-
-// Color creates a Color from a string. Valid inputs are hex colors, as well as
-// ANSI color codes (0-15, 16-255).
-func (p Profile) Color(s string) Color {
- if len(s) == 0 {
- return nil
- }
-
- var c Color
- if strings.HasPrefix(s, "#") {
- c = RGBColor(s)
- } else {
- i, err := strconv.Atoi(s)
- if err != nil {
- return nil
- }
-
- if i < 16 { //nolint:mnd
- c = ANSIColor(i)
- } else {
- c = ANSI256Color(i)
- }
- }
-
- return p.Convert(c)
-}
-
-// FromColor creates a Color from a color.Color.
-func (p Profile) FromColor(c color.Color) Color {
- col, _ := colorful.MakeColor(c)
- return p.Color(col.Hex())
-}
diff --git a/vendor/github.com/muesli/termenv/screen.go b/vendor/github.com/muesli/termenv/screen.go
deleted file mode 100644
index 75c11d011..000000000
--- a/vendor/github.com/muesli/termenv/screen.go
+++ /dev/null
@@ -1,590 +0,0 @@
-package termenv
-
-import (
- "fmt"
- "strings"
-)
-
-// Sequence definitions.
-const (
- // Cursor positioning.
- CursorUpSeq = "%dA"
- CursorDownSeq = "%dB"
- CursorForwardSeq = "%dC"
- CursorBackSeq = "%dD"
- CursorNextLineSeq = "%dE"
- CursorPreviousLineSeq = "%dF"
- CursorHorizontalSeq = "%dG"
- CursorPositionSeq = "%d;%dH"
- EraseDisplaySeq = "%dJ"
- EraseLineSeq = "%dK"
- ScrollUpSeq = "%dS"
- ScrollDownSeq = "%dT"
- SaveCursorPositionSeq = "s"
- RestoreCursorPositionSeq = "u"
- ChangeScrollingRegionSeq = "%d;%dr"
- InsertLineSeq = "%dL"
- DeleteLineSeq = "%dM"
-
- // Explicit values for EraseLineSeq.
- EraseLineRightSeq = "0K"
- EraseLineLeftSeq = "1K"
- EraseEntireLineSeq = "2K"
-
- // Mouse.
- EnableMousePressSeq = "?9h" // press only (X10)
- DisableMousePressSeq = "?9l"
- EnableMouseSeq = "?1000h" // press, release, wheel
- DisableMouseSeq = "?1000l"
- EnableMouseHiliteSeq = "?1001h" // highlight
- DisableMouseHiliteSeq = "?1001l"
- EnableMouseCellMotionSeq = "?1002h" // press, release, move on pressed, wheel
- DisableMouseCellMotionSeq = "?1002l"
- EnableMouseAllMotionSeq = "?1003h" // press, release, move, wheel
- DisableMouseAllMotionSeq = "?1003l"
- EnableMouseExtendedModeSeq = "?1006h" // press, release, move, wheel, extended coordinates
- DisableMouseExtendedModeSeq = "?1006l"
- EnableMousePixelsModeSeq = "?1016h" // press, release, move, wheel, extended pixel coordinates
- DisableMousePixelsModeSeq = "?1016l"
-
- // Screen.
- RestoreScreenSeq = "?47l"
- SaveScreenSeq = "?47h"
- AltScreenSeq = "?1049h"
- ExitAltScreenSeq = "?1049l"
-
- // Bracketed paste.
- // https://en.wikipedia.org/wiki/Bracketed-paste
- EnableBracketedPasteSeq = "?2004h"
- DisableBracketedPasteSeq = "?2004l"
- StartBracketedPasteSeq = "200~"
- EndBracketedPasteSeq = "201~"
-
- // Session.
- SetWindowTitleSeq = "2;%s" + string(BEL)
- SetForegroundColorSeq = "10;%s" + string(BEL)
- SetBackgroundColorSeq = "11;%s" + string(BEL)
- SetCursorColorSeq = "12;%s" + string(BEL)
- ShowCursorSeq = "?25h"
- HideCursorSeq = "?25l"
-)
-
-// Reset the terminal to its default style, removing any active styles.
-func (o Output) Reset() {
- fmt.Fprint(o.w, CSI+ResetSeq+"m") //nolint:errcheck
-}
-
-// SetForegroundColor sets the default foreground color.
-func (o Output) SetForegroundColor(color Color) {
- fmt.Fprintf(o.w, OSC+SetForegroundColorSeq, color) //nolint:errcheck
-}
-
-// SetBackgroundColor sets the default background color.
-func (o Output) SetBackgroundColor(color Color) {
- fmt.Fprintf(o.w, OSC+SetBackgroundColorSeq, color) //nolint:errcheck
-}
-
-// SetCursorColor sets the cursor color.
-func (o Output) SetCursorColor(color Color) {
- fmt.Fprintf(o.w, OSC+SetCursorColorSeq, color) //nolint:errcheck
-}
-
-// RestoreScreen restores a previously saved screen state.
-func (o Output) RestoreScreen() {
- fmt.Fprint(o.w, CSI+RestoreScreenSeq) //nolint:errcheck
-}
-
-// SaveScreen saves the screen state.
-func (o Output) SaveScreen() {
- fmt.Fprint(o.w, CSI+SaveScreenSeq) //nolint:errcheck
-}
-
-// AltScreen switches to the alternate screen buffer. The former view can be
-// restored with ExitAltScreen().
-func (o Output) AltScreen() {
- fmt.Fprint(o.w, CSI+AltScreenSeq) //nolint:errcheck
-}
-
-// ExitAltScreen exits the alternate screen buffer and returns to the former
-// terminal view.
-func (o Output) ExitAltScreen() {
- fmt.Fprint(o.w, CSI+ExitAltScreenSeq) //nolint:errcheck
-}
-
-// ClearScreen clears the visible portion of the terminal.
-func (o Output) ClearScreen() {
- fmt.Fprintf(o.w, CSI+EraseDisplaySeq, 2) //nolint:errcheck,mnd
- o.MoveCursor(1, 1)
-}
-
-// MoveCursor moves the cursor to a given position.
-func (o Output) MoveCursor(row int, column int) {
- fmt.Fprintf(o.w, CSI+CursorPositionSeq, row, column) //nolint:errcheck
-}
-
-// HideCursor hides the cursor.
-func (o Output) HideCursor() {
- fmt.Fprint(o.w, CSI+HideCursorSeq) //nolint:errcheck
-}
-
-// ShowCursor shows the cursor.
-func (o Output) ShowCursor() {
- fmt.Fprint(o.w, CSI+ShowCursorSeq) //nolint:errcheck
-}
-
-// SaveCursorPosition saves the cursor position.
-func (o Output) SaveCursorPosition() {
- fmt.Fprint(o.w, CSI+SaveCursorPositionSeq) //nolint:errcheck
-}
-
-// RestoreCursorPosition restores a saved cursor position.
-func (o Output) RestoreCursorPosition() {
- fmt.Fprint(o.w, CSI+RestoreCursorPositionSeq) //nolint:errcheck
-}
-
-// CursorUp moves the cursor up a given number of lines.
-func (o Output) CursorUp(n int) {
- fmt.Fprintf(o.w, CSI+CursorUpSeq, n) //nolint:errcheck
-}
-
-// CursorDown moves the cursor down a given number of lines.
-func (o Output) CursorDown(n int) {
- fmt.Fprintf(o.w, CSI+CursorDownSeq, n) //nolint:errcheck
-}
-
-// CursorForward moves the cursor up a given number of lines.
-func (o Output) CursorForward(n int) {
- fmt.Fprintf(o.w, CSI+CursorForwardSeq, n) //nolint:errcheck
-}
-
-// CursorBack moves the cursor backwards a given number of cells.
-func (o Output) CursorBack(n int) {
- fmt.Fprintf(o.w, CSI+CursorBackSeq, n) //nolint:errcheck
-}
-
-// CursorNextLine moves the cursor down a given number of lines and places it at
-// the beginning of the line.
-func (o Output) CursorNextLine(n int) {
- fmt.Fprintf(o.w, CSI+CursorNextLineSeq, n) //nolint:errcheck
-}
-
-// CursorPrevLine moves the cursor up a given number of lines and places it at
-// the beginning of the line.
-func (o Output) CursorPrevLine(n int) {
- fmt.Fprintf(o.w, CSI+CursorPreviousLineSeq, n) //nolint:errcheck
-}
-
-// ClearLine clears the current line.
-func (o Output) ClearLine() {
- fmt.Fprint(o.w, CSI+EraseEntireLineSeq) //nolint:errcheck
-}
-
-// ClearLineLeft clears the line to the left of the cursor.
-func (o Output) ClearLineLeft() {
- fmt.Fprint(o.w, CSI+EraseLineLeftSeq) //nolint:errcheck
-}
-
-// ClearLineRight clears the line to the right of the cursor.
-func (o Output) ClearLineRight() {
- fmt.Fprint(o.w, CSI+EraseLineRightSeq) //nolint:errcheck
-}
-
-// ClearLines clears a given number of lines.
-func (o Output) ClearLines(n int) {
- clearLine := fmt.Sprintf(CSI+EraseLineSeq, 2) //nolint:mnd
- cursorUp := fmt.Sprintf(CSI+CursorUpSeq, 1)
- fmt.Fprint(o.w, clearLine+strings.Repeat(cursorUp+clearLine, n)) //nolint:errcheck
-}
-
-// ChangeScrollingRegion sets the scrolling region of the terminal.
-func (o Output) ChangeScrollingRegion(top, bottom int) {
- fmt.Fprintf(o.w, CSI+ChangeScrollingRegionSeq, top, bottom) //nolint:errcheck
-}
-
-// InsertLines inserts the given number of lines at the top of the scrollable
-// region, pushing lines below down.
-func (o Output) InsertLines(n int) {
- fmt.Fprintf(o.w, CSI+InsertLineSeq, n) //nolint:errcheck
-}
-
-// DeleteLines deletes the given number of lines, pulling any lines in
-// the scrollable region below up.
-func (o Output) DeleteLines(n int) {
- fmt.Fprintf(o.w, CSI+DeleteLineSeq, n) //nolint:errcheck
-}
-
-// EnableMousePress enables X10 mouse mode. Button press events are sent only.
-func (o Output) EnableMousePress() {
- fmt.Fprint(o.w, CSI+EnableMousePressSeq) //nolint:errcheck
-}
-
-// DisableMousePress disables X10 mouse mode.
-func (o Output) DisableMousePress() {
- fmt.Fprint(o.w, CSI+DisableMousePressSeq) //nolint:errcheck
-}
-
-// EnableMouse enables Mouse Tracking mode.
-func (o Output) EnableMouse() {
- fmt.Fprint(o.w, CSI+EnableMouseSeq) //nolint:errcheck
-}
-
-// DisableMouse disables Mouse Tracking mode.
-func (o Output) DisableMouse() {
- fmt.Fprint(o.w, CSI+DisableMouseSeq) //nolint:errcheck
-}
-
-// EnableMouseHilite enables Hilite Mouse Tracking mode.
-func (o Output) EnableMouseHilite() {
- fmt.Fprint(o.w, CSI+EnableMouseHiliteSeq) //nolint:errcheck
-}
-
-// DisableMouseHilite disables Hilite Mouse Tracking mode.
-func (o Output) DisableMouseHilite() {
- fmt.Fprint(o.w, CSI+DisableMouseHiliteSeq) //nolint:errcheck
-}
-
-// EnableMouseCellMotion enables Cell Motion Mouse Tracking mode.
-func (o Output) EnableMouseCellMotion() {
- fmt.Fprint(o.w, CSI+EnableMouseCellMotionSeq) //nolint:errcheck
-}
-
-// DisableMouseCellMotion disables Cell Motion Mouse Tracking mode.
-func (o Output) DisableMouseCellMotion() {
- fmt.Fprint(o.w, CSI+DisableMouseCellMotionSeq) //nolint:errcheck
-}
-
-// EnableMouseAllMotion enables All Motion Mouse mode.
-func (o Output) EnableMouseAllMotion() {
- fmt.Fprint(o.w, CSI+EnableMouseAllMotionSeq) //nolint:errcheck
-}
-
-// DisableMouseAllMotion disables All Motion Mouse mode.
-func (o Output) DisableMouseAllMotion() {
- fmt.Fprint(o.w, CSI+DisableMouseAllMotionSeq) //nolint:errcheck
-}
-
-// EnableMouseExtendedMotion enables Extended Mouse mode (SGR). This should be
-// enabled in conjunction with EnableMouseCellMotion, and EnableMouseAllMotion.
-func (o Output) EnableMouseExtendedMode() {
- fmt.Fprint(o.w, CSI+EnableMouseExtendedModeSeq) //nolint:errcheck
-}
-
-// DisableMouseExtendedMotion disables Extended Mouse mode (SGR).
-func (o Output) DisableMouseExtendedMode() {
- fmt.Fprint(o.w, CSI+DisableMouseExtendedModeSeq) //nolint:errcheck
-}
-
-// EnableMousePixelsMotion enables Pixel Motion Mouse mode (SGR-Pixels). This
-// should be enabled in conjunction with EnableMouseCellMotion, and
-// EnableMouseAllMotion.
-func (o Output) EnableMousePixelsMode() {
- fmt.Fprint(o.w, CSI+EnableMousePixelsModeSeq) //nolint:errcheck
-}
-
-// DisableMousePixelsMotion disables Pixel Motion Mouse mode (SGR-Pixels).
-func (o Output) DisableMousePixelsMode() {
- fmt.Fprint(o.w, CSI+DisableMousePixelsModeSeq) //nolint:errcheck
-}
-
-// SetWindowTitle sets the terminal window title.
-func (o Output) SetWindowTitle(title string) {
- fmt.Fprintf(o.w, OSC+SetWindowTitleSeq, title) //nolint:errcheck
-}
-
-// EnableBracketedPaste enables bracketed paste.
-func (o Output) EnableBracketedPaste() {
- fmt.Fprintf(o.w, CSI+EnableBracketedPasteSeq) //nolint:errcheck
-}
-
-// DisableBracketedPaste disables bracketed paste.
-func (o Output) DisableBracketedPaste() {
- fmt.Fprintf(o.w, CSI+DisableBracketedPasteSeq) //nolint:errcheck
-}
-
-// Legacy functions.
-
-// Reset the terminal to its default style, removing any active styles.
-//
-// Deprecated: please use termenv.Output instead.
-func Reset() {
- output.Reset()
-}
-
-// SetForegroundColor sets the default foreground color.
-//
-// Deprecated: please use termenv.Output instead.
-func SetForegroundColor(color Color) {
- output.SetForegroundColor(color)
-}
-
-// SetBackgroundColor sets the default background color.
-//
-// Deprecated: please use termenv.Output instead.
-func SetBackgroundColor(color Color) {
- output.SetBackgroundColor(color)
-}
-
-// SetCursorColor sets the cursor color.
-//
-// Deprecated: please use termenv.Output instead.
-func SetCursorColor(color Color) {
- output.SetCursorColor(color)
-}
-
-// RestoreScreen restores a previously saved screen state.
-//
-// Deprecated: please use termenv.Output instead.
-func RestoreScreen() {
- output.RestoreScreen()
-}
-
-// SaveScreen saves the screen state.
-//
-// Deprecated: please use termenv.Output instead.
-func SaveScreen() {
- output.SaveScreen()
-}
-
-// AltScreen switches to the alternate screen buffer. The former view can be
-// restored with ExitAltScreen().
-//
-// Deprecated: please use termenv.Output instead.
-func AltScreen() {
- output.AltScreen()
-}
-
-// ExitAltScreen exits the alternate screen buffer and returns to the former
-// terminal view.
-//
-// Deprecated: please use termenv.Output instead.
-func ExitAltScreen() {
- output.ExitAltScreen()
-}
-
-// ClearScreen clears the visible portion of the terminal.
-//
-// Deprecated: please use termenv.Output instead.
-func ClearScreen() {
- output.ClearScreen()
-}
-
-// MoveCursor moves the cursor to a given position.
-//
-// Deprecated: please use termenv.Output instead.
-func MoveCursor(row int, column int) {
- output.MoveCursor(row, column)
-}
-
-// HideCursor hides the cursor.
-//
-// Deprecated: please use termenv.Output instead.
-func HideCursor() {
- output.HideCursor()
-}
-
-// ShowCursor shows the cursor.
-//
-// Deprecated: please use termenv.Output instead.
-func ShowCursor() {
- output.ShowCursor()
-}
-
-// SaveCursorPosition saves the cursor position.
-//
-// Deprecated: please use termenv.Output instead.
-func SaveCursorPosition() {
- output.SaveCursorPosition()
-}
-
-// RestoreCursorPosition restores a saved cursor position.
-//
-// Deprecated: please use termenv.Output instead.
-func RestoreCursorPosition() {
- output.RestoreCursorPosition()
-}
-
-// CursorUp moves the cursor up a given number of lines.
-//
-// Deprecated: please use termenv.Output instead.
-func CursorUp(n int) {
- output.CursorUp(n)
-}
-
-// CursorDown moves the cursor down a given number of lines.
-//
-// Deprecated: please use termenv.Output instead.
-func CursorDown(n int) {
- output.CursorDown(n)
-}
-
-// CursorForward moves the cursor up a given number of lines.
-//
-// Deprecated: please use termenv.Output instead.
-func CursorForward(n int) {
- output.CursorForward(n)
-}
-
-// CursorBack moves the cursor backwards a given number of cells.
-//
-// Deprecated: please use termenv.Output instead.
-func CursorBack(n int) {
- output.CursorBack(n)
-}
-
-// CursorNextLine moves the cursor down a given number of lines and places it at
-// the beginning of the line.
-//
-// Deprecated: please use termenv.Output instead.
-func CursorNextLine(n int) {
- output.CursorNextLine(n)
-}
-
-// CursorPrevLine moves the cursor up a given number of lines and places it at
-// the beginning of the line.
-//
-// Deprecated: please use termenv.Output instead.
-func CursorPrevLine(n int) {
- output.CursorPrevLine(n)
-}
-
-// ClearLine clears the current line.
-//
-// Deprecated: please use termenv.Output instead.
-func ClearLine() {
- output.ClearLine()
-}
-
-// ClearLineLeft clears the line to the left of the cursor.
-//
-// Deprecated: please use termenv.Output instead.
-func ClearLineLeft() {
- output.ClearLineLeft()
-}
-
-// ClearLineRight clears the line to the right of the cursor.
-//
-// Deprecated: please use termenv.Output instead.
-func ClearLineRight() {
- output.ClearLineRight()
-}
-
-// ClearLines clears a given number of lines.
-//
-// Deprecated: please use termenv.Output instead.
-func ClearLines(n int) {
- output.ClearLines(n)
-}
-
-// ChangeScrollingRegion sets the scrolling region of the terminal.
-//
-// Deprecated: please use termenv.Output instead.
-func ChangeScrollingRegion(top, bottom int) {
- output.ChangeScrollingRegion(top, bottom)
-}
-
-// InsertLines inserts the given number of lines at the top of the scrollable
-// region, pushing lines below down.
-//
-// Deprecated: please use termenv.Output instead.
-func InsertLines(n int) {
- output.InsertLines(n)
-}
-
-// DeleteLines deletes the given number of lines, pulling any lines in
-// the scrollable region below up.
-//
-// Deprecated: please use termenv.Output instead.
-func DeleteLines(n int) {
- output.DeleteLines(n)
-}
-
-// EnableMousePress enables X10 mouse mode. Button press events are sent only.
-//
-// Deprecated: please use termenv.Output instead.
-func EnableMousePress() {
- output.EnableMousePress()
-}
-
-// DisableMousePress disables X10 mouse mode.
-//
-// Deprecated: please use termenv.Output instead.
-func DisableMousePress() {
- output.DisableMousePress()
-}
-
-// EnableMouse enables Mouse Tracking mode.
-//
-// Deprecated: please use termenv.Output instead.
-func EnableMouse() {
- output.EnableMouse()
-}
-
-// DisableMouse disables Mouse Tracking mode.
-//
-// Deprecated: please use termenv.Output instead.
-func DisableMouse() {
- output.DisableMouse()
-}
-
-// EnableMouseHilite enables Hilite Mouse Tracking mode.
-//
-// Deprecated: please use termenv.Output instead.
-func EnableMouseHilite() {
- output.EnableMouseHilite()
-}
-
-// DisableMouseHilite disables Hilite Mouse Tracking mode.
-//
-// Deprecated: please use termenv.Output instead.
-func DisableMouseHilite() {
- output.DisableMouseHilite()
-}
-
-// EnableMouseCellMotion enables Cell Motion Mouse Tracking mode.
-//
-// Deprecated: please use termenv.Output instead.
-func EnableMouseCellMotion() {
- output.EnableMouseCellMotion()
-}
-
-// DisableMouseCellMotion disables Cell Motion Mouse Tracking mode.
-//
-// Deprecated: please use termenv.Output instead.
-func DisableMouseCellMotion() {
- output.DisableMouseCellMotion()
-}
-
-// EnableMouseAllMotion enables All Motion Mouse mode.
-//
-// Deprecated: please use termenv.Output instead.
-func EnableMouseAllMotion() {
- output.EnableMouseAllMotion()
-}
-
-// DisableMouseAllMotion disables All Motion Mouse mode.
-//
-// Deprecated: please use termenv.Output instead.
-func DisableMouseAllMotion() {
- output.DisableMouseAllMotion()
-}
-
-// SetWindowTitle sets the terminal window title.
-//
-// Deprecated: please use termenv.Output instead.
-func SetWindowTitle(title string) {
- output.SetWindowTitle(title)
-}
-
-// EnableBracketedPaste enables bracketed paste.
-//
-// Deprecated: please use termenv.Output instead.
-func EnableBracketedPaste() {
- output.EnableBracketedPaste()
-}
-
-// DisableBracketedPaste disables bracketed paste.
-//
-// Deprecated: please use termenv.Output instead.
-func DisableBracketedPaste() {
- output.DisableBracketedPaste()
-}
diff --git a/vendor/github.com/muesli/termenv/style.go b/vendor/github.com/muesli/termenv/style.go
deleted file mode 100644
index dedc1f9fd..000000000
--- a/vendor/github.com/muesli/termenv/style.go
+++ /dev/null
@@ -1,126 +0,0 @@
-package termenv
-
-import (
- "fmt"
- "strings"
-
- "github.com/rivo/uniseg"
-)
-
-// Sequence definitions.
-const (
- ResetSeq = "0"
- BoldSeq = "1"
- FaintSeq = "2"
- ItalicSeq = "3"
- UnderlineSeq = "4"
- BlinkSeq = "5"
- ReverseSeq = "7"
- CrossOutSeq = "9"
- OverlineSeq = "53"
-)
-
-// Style is a string that various rendering styles can be applied to.
-type Style struct {
- profile Profile
- string
- styles []string
-}
-
-// String returns a new Style.
-func String(s ...string) Style {
- return Style{
- profile: ANSI,
- string: strings.Join(s, " "),
- }
-}
-
-func (t Style) String() string {
- return t.Styled(t.string)
-}
-
-// Styled renders s with all applied styles.
-func (t Style) Styled(s string) string {
- if t.profile == Ascii {
- return s
- }
- if len(t.styles) == 0 {
- return s
- }
-
- seq := strings.Join(t.styles, ";")
- if seq == "" {
- return s
- }
-
- return fmt.Sprintf("%s%sm%s%sm", CSI, seq, s, CSI+ResetSeq)
-}
-
-// Foreground sets a foreground color.
-func (t Style) Foreground(c Color) Style {
- if c != nil {
- t.styles = append(t.styles, c.Sequence(false))
- }
- return t
-}
-
-// Background sets a background color.
-func (t Style) Background(c Color) Style {
- if c != nil {
- t.styles = append(t.styles, c.Sequence(true))
- }
- return t
-}
-
-// Bold enables bold rendering.
-func (t Style) Bold() Style {
- t.styles = append(t.styles, BoldSeq)
- return t
-}
-
-// Faint enables faint rendering.
-func (t Style) Faint() Style {
- t.styles = append(t.styles, FaintSeq)
- return t
-}
-
-// Italic enables italic rendering.
-func (t Style) Italic() Style {
- t.styles = append(t.styles, ItalicSeq)
- return t
-}
-
-// Underline enables underline rendering.
-func (t Style) Underline() Style {
- t.styles = append(t.styles, UnderlineSeq)
- return t
-}
-
-// Overline enables overline rendering.
-func (t Style) Overline() Style {
- t.styles = append(t.styles, OverlineSeq)
- return t
-}
-
-// Blink enables blink mode.
-func (t Style) Blink() Style {
- t.styles = append(t.styles, BlinkSeq)
- return t
-}
-
-// Reverse enables reverse color mode.
-func (t Style) Reverse() Style {
- t.styles = append(t.styles, ReverseSeq)
- return t
-}
-
-// CrossOut enables crossed-out rendering.
-func (t Style) CrossOut() Style {
- t.styles = append(t.styles, CrossOutSeq)
- return t
-}
-
-// Width returns the width required to print all runes in Style.
-func (t Style) Width() int {
- return uniseg.StringWidth(t.string)
-}
diff --git a/vendor/github.com/muesli/termenv/templatehelper.go b/vendor/github.com/muesli/termenv/templatehelper.go
deleted file mode 100644
index 4c7c80f5b..000000000
--- a/vendor/github.com/muesli/termenv/templatehelper.go
+++ /dev/null
@@ -1,88 +0,0 @@
-package termenv
-
-import (
- "text/template"
-)
-
-// TemplateFuncs returns template helpers for the given output.
-func (o Output) TemplateFuncs() template.FuncMap {
- return TemplateFuncs(o.Profile)
-}
-
-// TemplateFuncs contains a few useful template helpers.
-//
-//nolint:mnd
-func TemplateFuncs(p Profile) template.FuncMap {
- if p == Ascii {
- return noopTemplateFuncs
- }
-
- return template.FuncMap{
- "Color": func(values ...interface{}) string {
- s := p.String(values[len(values)-1].(string))
- switch len(values) {
- case 2:
- s = s.Foreground(p.Color(values[0].(string)))
- case 3:
- s = s.
- Foreground(p.Color(values[0].(string))).
- Background(p.Color(values[1].(string)))
- }
-
- return s.String()
- },
- "Foreground": func(values ...interface{}) string {
- s := p.String(values[len(values)-1].(string))
- if len(values) == 2 {
- s = s.Foreground(p.Color(values[0].(string)))
- }
-
- return s.String()
- },
- "Background": func(values ...interface{}) string {
- s := p.String(values[len(values)-1].(string))
- if len(values) == 2 {
- s = s.Background(p.Color(values[0].(string)))
- }
-
- return s.String()
- },
- "Bold": styleFunc(p, Style.Bold),
- "Faint": styleFunc(p, Style.Faint),
- "Italic": styleFunc(p, Style.Italic),
- "Underline": styleFunc(p, Style.Underline),
- "Overline": styleFunc(p, Style.Overline),
- "Blink": styleFunc(p, Style.Blink),
- "Reverse": styleFunc(p, Style.Reverse),
- "CrossOut": styleFunc(p, Style.CrossOut),
- }
-}
-
-func styleFunc(p Profile, f func(Style) Style) func(...interface{}) string {
- return func(values ...interface{}) string {
- s := p.String(values[0].(string))
- return f(s).String()
- }
-}
-
-var noopTemplateFuncs = template.FuncMap{
- "Color": noColorFunc,
- "Foreground": noColorFunc,
- "Background": noColorFunc,
- "Bold": noStyleFunc,
- "Faint": noStyleFunc,
- "Italic": noStyleFunc,
- "Underline": noStyleFunc,
- "Overline": noStyleFunc,
- "Blink": noStyleFunc,
- "Reverse": noStyleFunc,
- "CrossOut": noStyleFunc,
-}
-
-func noColorFunc(values ...interface{}) string {
- return values[len(values)-1].(string)
-}
-
-func noStyleFunc(values ...interface{}) string {
- return values[0].(string)
-}
diff --git a/vendor/github.com/muesli/termenv/termenv.go b/vendor/github.com/muesli/termenv/termenv.go
deleted file mode 100644
index d702cd55e..000000000
--- a/vendor/github.com/muesli/termenv/termenv.go
+++ /dev/null
@@ -1,115 +0,0 @@
-package termenv
-
-import (
- "errors"
- "os"
-
- "github.com/mattn/go-isatty"
-)
-
-var (
- // ErrStatusReport gets returned when the terminal can't be queried.
- ErrStatusReport = errors.New("unable to retrieve status report")
-)
-
-const (
- // Escape character.
- ESC = '\x1b'
- // Bell.
- BEL = '\a'
- // Control Sequence Introducer.
- CSI = string(ESC) + "["
- // Operating System Command.
- OSC = string(ESC) + "]"
- // String Terminator.
- ST = string(ESC) + `\`
-)
-
-func (o *Output) isTTY() bool {
- if o.assumeTTY || o.unsafe {
- return true
- }
- if len(o.environ.Getenv("CI")) > 0 {
- return false
- }
- if f, ok := o.Writer().(*os.File); ok {
- return isatty.IsTerminal(f.Fd())
- }
-
- return false
-}
-
-// ColorProfile returns the supported color profile:
-// Ascii, ANSI, ANSI256, or TrueColor.
-func ColorProfile() Profile {
- return output.ColorProfile()
-}
-
-// ForegroundColor returns the terminal's default foreground color.
-func ForegroundColor() Color {
- return output.ForegroundColor()
-}
-
-// BackgroundColor returns the terminal's default background color.
-func BackgroundColor() Color {
- return output.BackgroundColor()
-}
-
-// HasDarkBackground returns whether terminal uses a dark-ish background.
-func HasDarkBackground() bool {
- return output.HasDarkBackground()
-}
-
-// EnvNoColor returns true if the environment variables explicitly disable color output
-// by setting NO_COLOR (https://no-color.org/)
-// or CLICOLOR/CLICOLOR_FORCE (https://bixense.com/clicolors/)
-// If NO_COLOR is set, this will return true, ignoring CLICOLOR/CLICOLOR_FORCE
-// If CLICOLOR=="0", it will be true only if CLICOLOR_FORCE is also "0" or is unset.
-func (o *Output) EnvNoColor() bool {
- return o.environ.Getenv("NO_COLOR") != "" || (o.environ.Getenv("CLICOLOR") == "0" && !o.cliColorForced())
-}
-
-// EnvNoColor returns true if the environment variables explicitly disable color output
-// by setting NO_COLOR (https://no-color.org/)
-// or CLICOLOR/CLICOLOR_FORCE (https://bixense.com/clicolors/)
-// If NO_COLOR is set, this will return true, ignoring CLICOLOR/CLICOLOR_FORCE
-// If CLICOLOR=="0", it will be true only if CLICOLOR_FORCE is also "0" or is unset.
-func EnvNoColor() bool {
- return output.EnvNoColor()
-}
-
-// EnvColorProfile returns the color profile based on environment variables set
-// Supports NO_COLOR (https://no-color.org/)
-// and CLICOLOR/CLICOLOR_FORCE (https://bixense.com/clicolors/)
-// If none of these environment variables are set, this behaves the same as ColorProfile()
-// It will return the Ascii color profile if EnvNoColor() returns true
-// If the terminal does not support any colors, but CLICOLOR_FORCE is set and not "0"
-// then the ANSI color profile will be returned.
-func EnvColorProfile() Profile {
- return output.EnvColorProfile()
-}
-
-// EnvColorProfile returns the color profile based on environment variables set
-// Supports NO_COLOR (https://no-color.org/)
-// and CLICOLOR/CLICOLOR_FORCE (https://bixense.com/clicolors/)
-// If none of these environment variables are set, this behaves the same as ColorProfile()
-// It will return the Ascii color profile if EnvNoColor() returns true
-// If the terminal does not support any colors, but CLICOLOR_FORCE is set and not "0"
-// then the ANSI color profile will be returned.
-func (o *Output) EnvColorProfile() Profile {
- if o.EnvNoColor() {
- return Ascii
- }
- p := o.ColorProfile()
- if o.cliColorForced() && p == Ascii {
- return ANSI
- }
- return p
-}
-
-func (o *Output) cliColorForced() bool {
- if forced := o.environ.Getenv("CLICOLOR_FORCE"); forced != "" {
- return forced != "0"
- }
- return false
-}
diff --git a/vendor/github.com/muesli/termenv/termenv_other.go b/vendor/github.com/muesli/termenv/termenv_other.go
deleted file mode 100644
index 93a43b6ac..000000000
--- a/vendor/github.com/muesli/termenv/termenv_other.go
+++ /dev/null
@@ -1,30 +0,0 @@
-//go:build js || plan9 || aix
-// +build js plan9 aix
-
-package termenv
-
-import "io"
-
-// ColorProfile returns the supported color profile:
-// ANSI256
-func (o Output) ColorProfile() Profile {
- return ANSI256
-}
-
-func (o Output) foregroundColor() Color {
- // default gray
- return ANSIColor(7)
-}
-
-func (o Output) backgroundColor() Color {
- // default black
- return ANSIColor(0)
-}
-
-// EnableVirtualTerminalProcessing enables virtual terminal processing on
-// Windows for w and returns a function that restores w to its previous state.
-// On non-Windows platforms, or if w does not refer to a terminal, then it
-// returns a non-nil no-op function and no error.
-func EnableVirtualTerminalProcessing(w io.Writer) (func() error, error) {
- return func() error { return nil }, nil
-}
diff --git a/vendor/github.com/muesli/termenv/termenv_posix.go b/vendor/github.com/muesli/termenv/termenv_posix.go
deleted file mode 100644
index c971dd998..000000000
--- a/vendor/github.com/muesli/termenv/termenv_posix.go
+++ /dev/null
@@ -1,17 +0,0 @@
-//go:build darwin || dragonfly || freebsd || linux || netbsd || openbsd || zos
-// +build darwin dragonfly freebsd linux netbsd openbsd zos
-
-package termenv
-
-import (
- "golang.org/x/sys/unix"
-)
-
-func isForeground(fd int) bool {
- pgrp, err := unix.IoctlGetInt(fd, unix.TIOCGPGRP)
- if err != nil {
- return false
- }
-
- return pgrp == unix.Getpgrp()
-}
diff --git a/vendor/github.com/muesli/termenv/termenv_solaris.go b/vendor/github.com/muesli/termenv/termenv_solaris.go
deleted file mode 100644
index 27a95a93e..000000000
--- a/vendor/github.com/muesli/termenv/termenv_solaris.go
+++ /dev/null
@@ -1,22 +0,0 @@
-//go:build solaris || illumos
-// +build solaris illumos
-
-package termenv
-
-import (
- "golang.org/x/sys/unix"
-)
-
-func isForeground(fd int) bool {
- pgrp, err := unix.IoctlGetInt(fd, unix.TIOCGPGRP)
- if err != nil {
- return false
- }
-
- g, err := unix.Getpgrp()
- if err != nil {
- return false
- }
-
- return pgrp == g
-}
diff --git a/vendor/github.com/muesli/termenv/termenv_unix.go b/vendor/github.com/muesli/termenv/termenv_unix.go
deleted file mode 100644
index bef49ca3b..000000000
--- a/vendor/github.com/muesli/termenv/termenv_unix.go
+++ /dev/null
@@ -1,301 +0,0 @@
-//go:build darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos
-// +build darwin dragonfly freebsd linux netbsd openbsd solaris zos
-
-package termenv
-
-import (
- "fmt"
- "io"
- "strconv"
- "strings"
- "time"
-
- "golang.org/x/sys/unix"
-)
-
-const (
- // timeout for OSC queries.
- OSCTimeout = 5 * time.Second
-)
-
-// ColorProfile returns the supported color profile:
-// Ascii, ANSI, ANSI256, or TrueColor.
-func (o *Output) ColorProfile() Profile {
- if !o.isTTY() {
- return Ascii
- }
-
- if o.environ.Getenv("GOOGLE_CLOUD_SHELL") == "true" {
- return TrueColor
- }
-
- term := o.environ.Getenv("TERM")
- colorTerm := o.environ.Getenv("COLORTERM")
-
- switch strings.ToLower(colorTerm) {
- case "24bit":
- fallthrough
- case "truecolor":
- if strings.HasPrefix(term, "screen") {
- // tmux supports TrueColor, screen only ANSI256
- if o.environ.Getenv("TERM_PROGRAM") != "tmux" {
- return ANSI256
- }
- }
- return TrueColor
- case "yes":
- fallthrough
- case "true":
- return ANSI256
- }
-
- switch term {
- case
- "alacritty",
- "contour",
- "rio",
- "wezterm",
- "xterm-ghostty",
- "xterm-kitty":
- return TrueColor
- case "linux", "xterm":
- return ANSI
- }
-
- if strings.Contains(term, "256color") {
- return ANSI256
- }
- if strings.Contains(term, "color") {
- return ANSI
- }
- if strings.Contains(term, "ansi") {
- return ANSI
- }
-
- return Ascii
-}
-
-//nolint:mnd
-func (o Output) foregroundColor() Color {
- s, err := o.termStatusReport(10)
- if err == nil {
- c, err := xTermColor(s)
- if err == nil {
- return c
- }
- }
-
- colorFGBG := o.environ.Getenv("COLORFGBG")
- if strings.Contains(colorFGBG, ";") {
- c := strings.Split(colorFGBG, ";")
- i, err := strconv.Atoi(c[0])
- if err == nil {
- return ANSIColor(i)
- }
- }
-
- // default gray
- return ANSIColor(7)
-}
-
-//nolint:mnd
-func (o Output) backgroundColor() Color {
- s, err := o.termStatusReport(11)
- if err == nil {
- c, err := xTermColor(s)
- if err == nil {
- return c
- }
- }
-
- colorFGBG := o.environ.Getenv("COLORFGBG")
- if strings.Contains(colorFGBG, ";") {
- c := strings.Split(colorFGBG, ";")
- i, err := strconv.Atoi(c[len(c)-1])
- if err == nil {
- return ANSIColor(i)
- }
- }
-
- // default black
- return ANSIColor(0)
-}
-
-func (o *Output) waitForData(timeout time.Duration) error {
- fd := o.TTY().Fd()
- tv := unix.NsecToTimeval(int64(timeout))
- var readfds unix.FdSet
- readfds.Set(int(fd)) //nolint:gosec
-
- for {
- n, err := unix.Select(int(fd)+1, &readfds, nil, nil, &tv) //nolint:gosec
- if err == unix.EINTR {
- continue
- }
- if err != nil {
- return err //nolint:wrapcheck
- }
- if n == 0 {
- return fmt.Errorf("timeout")
- }
-
- break
- }
-
- return nil
-}
-
-func (o *Output) readNextByte() (byte, error) {
- if !o.unsafe {
- if err := o.waitForData(OSCTimeout); err != nil {
- return 0, err
- }
- }
-
- var b [1]byte
- n, err := o.TTY().Read(b[:])
- if err != nil {
- return 0, err //nolint:wrapcheck
- }
-
- if n == 0 {
- panic("read returned no data")
- }
-
- return b[0], nil
-}
-
-// readNextResponse reads either an OSC response or a cursor position response:
-// - OSC response: "\x1b]11;rgb:1111/1111/1111\x1b\\"
-// - cursor position response: "\x1b[42;1R"
-func (o *Output) readNextResponse() (response string, isOSC bool, err error) {
- start, err := o.readNextByte()
- if err != nil {
- return "", false, err
- }
-
- // first byte must be ESC
- for start != ESC {
- start, err = o.readNextByte()
- if err != nil {
- return "", false, err
- }
- }
-
- response += string(start)
-
- // next byte is either '[' (cursor position response) or ']' (OSC response)
- tpe, err := o.readNextByte()
- if err != nil {
- return "", false, err
- }
-
- response += string(tpe)
-
- var oscResponse bool
- switch tpe {
- case '[':
- oscResponse = false
- case ']':
- oscResponse = true
- default:
- return "", false, ErrStatusReport
- }
-
- for {
- b, err := o.readNextByte()
- if err != nil {
- return "", false, err
- }
-
- response += string(b)
-
- if oscResponse {
- // OSC can be terminated by BEL (\a) or ST (ESC)
- if b == BEL || strings.HasSuffix(response, string(ESC)) {
- return response, true, nil
- }
- } else {
- // cursor position response is terminated by 'R'
- if b == 'R' {
- return response, false, nil
- }
- }
-
- // both responses have less than 25 bytes, so if we read more, that's an error
- if len(response) > 25 { //nolint:mnd
- break
- }
- }
-
- return "", false, ErrStatusReport
-}
-
-func (o Output) termStatusReport(sequence int) (string, error) {
- // screen/tmux can't support OSC, because they can be connected to multiple
- // terminals concurrently.
- term := o.environ.Getenv("TERM")
- if strings.HasPrefix(term, "screen") || strings.HasPrefix(term, "tmux") || strings.HasPrefix(term, "dumb") {
- return "", ErrStatusReport
- }
-
- tty := o.TTY()
- if tty == nil {
- return "", ErrStatusReport
- }
-
- if !o.unsafe {
- fd := int(tty.Fd()) //nolint:gosec
- // if in background, we can't control the terminal
- if !isForeground(fd) {
- return "", ErrStatusReport
- }
-
- t, err := unix.IoctlGetTermios(fd, tcgetattr)
- if err != nil {
- return "", fmt.Errorf("%s: %s", ErrStatusReport, err)
- }
- defer unix.IoctlSetTermios(fd, tcsetattr, t) //nolint:errcheck
-
- noecho := *t
- noecho.Lflag = noecho.Lflag &^ unix.ECHO
- noecho.Lflag = noecho.Lflag &^ unix.ICANON
- if err := unix.IoctlSetTermios(fd, tcsetattr, &noecho); err != nil {
- return "", fmt.Errorf("%s: %s", ErrStatusReport, err)
- }
- }
-
- // first, send OSC query, which is ignored by terminal which do not support it
- fmt.Fprintf(tty, OSC+"%d;?"+ST, sequence) //nolint:errcheck
-
- // then, query cursor position, should be supported by all terminals
- fmt.Fprintf(tty, CSI+"6n") //nolint:errcheck
-
- // read the next response
- res, isOSC, err := o.readNextResponse()
- if err != nil {
- return "", fmt.Errorf("%s: %s", ErrStatusReport, err)
- }
-
- // if this is not OSC response, then the terminal does not support it
- if !isOSC {
- return "", ErrStatusReport
- }
-
- // read the cursor query response next and discard the result
- _, _, err = o.readNextResponse()
- if err != nil {
- return "", err
- }
-
- // fmt.Println("Rcvd", res[1:])
- return res, nil
-}
-
-// EnableVirtualTerminalProcessing enables virtual terminal processing on
-// Windows for w and returns a function that restores w to its previous state.
-// On non-Windows platforms, or if w does not refer to a terminal, then it
-// returns a non-nil no-op function and no error.
-func EnableVirtualTerminalProcessing(_ io.Writer) (func() error, error) {
- return func() error { return nil }, nil
-}
diff --git a/vendor/github.com/muesli/termenv/termenv_windows.go b/vendor/github.com/muesli/termenv/termenv_windows.go
deleted file mode 100644
index f9b1def05..000000000
--- a/vendor/github.com/muesli/termenv/termenv_windows.go
+++ /dev/null
@@ -1,140 +0,0 @@
-//go:build windows
-// +build windows
-
-package termenv
-
-import (
- "fmt"
- "os"
- "strconv"
-
- "golang.org/x/sys/windows"
-)
-
-func (o *Output) ColorProfile() Profile {
- if !o.isTTY() {
- return Ascii
- }
-
- if o.environ.Getenv("ConEmuANSI") == "ON" {
- return TrueColor
- }
-
- winVersion, _, buildNumber := windows.RtlGetNtVersionNumbers()
- if buildNumber < 10586 || winVersion < 10 {
- // No ANSI support before Windows 10 build 10586.
- if o.environ.Getenv("ANSICON") != "" {
- conVersion := o.environ.Getenv("ANSICON_VER")
- cv, err := strconv.ParseInt(conVersion, 10, 64)
- if err != nil || cv < 181 {
- // No 8 bit color support before v1.81 release.
- return ANSI
- }
-
- return ANSI256
- }
-
- return Ascii
- }
- if buildNumber < 14931 {
- // No true color support before build 14931.
- return ANSI256
- }
-
- return TrueColor
-}
-
-func (o Output) foregroundColor() Color {
- // default gray
- return ANSIColor(7)
-}
-
-func (o Output) backgroundColor() Color {
- // default black
- return ANSIColor(0)
-}
-
-// EnableWindowsANSIConsole enables virtual terminal processing on Windows
-// platforms. This allows the use of ANSI escape sequences in Windows console
-// applications. Ensure this gets called before anything gets rendered with
-// termenv.
-//
-// Returns the original console mode and an error if one occurred.
-func EnableWindowsANSIConsole() (uint32, error) {
- handle, err := windows.GetStdHandle(windows.STD_OUTPUT_HANDLE)
- if err != nil {
- return 0, err
- }
-
- var mode uint32
- err = windows.GetConsoleMode(handle, &mode)
- if err != nil {
- return 0, err
- }
-
- // See https://docs.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences
- if mode&windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING != windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING {
- vtpmode := mode | windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING
- if err := windows.SetConsoleMode(handle, vtpmode); err != nil {
- return 0, err
- }
- }
-
- return mode, nil
-}
-
-// RestoreWindowsConsole restores the console mode to a previous state.
-func RestoreWindowsConsole(mode uint32) error {
- handle, err := windows.GetStdHandle(windows.STD_OUTPUT_HANDLE)
- if err != nil {
- return err
- }
-
- return windows.SetConsoleMode(handle, mode)
-}
-
-// EnableVirtualTerminalProcessing enables virtual terminal processing on
-// Windows for o and returns a function that restores o to its previous state.
-// On non-Windows platforms, or if o does not refer to a terminal, then it
-// returns a non-nil no-op function and no error.
-func EnableVirtualTerminalProcessing(o *Output) (restoreFunc func() error, err error) {
- // There is nothing to restore until we set the console mode.
- restoreFunc = func() error {
- return nil
- }
-
- // If o is not a tty, then there is nothing to do.
- tty, ok := o.Writer().(*os.File)
- if tty == nil || !ok {
- return
- }
-
- // Get the current console mode. If there is an error, assume that o is not
- // a terminal, discard the error, and return.
- var mode uint32
- if err2 := windows.GetConsoleMode(windows.Handle(tty.Fd()), &mode); err2 != nil {
- return
- }
-
- // If virtual terminal processing is already set, then there is nothing to
- // do and nothing to restore.
- if mode&windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING == windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING {
- return
- }
-
- // Enable virtual terminal processing. See
- // https://docs.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences
- if err2 := windows.SetConsoleMode(windows.Handle(tty.Fd()), mode|windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING); err2 != nil {
- err = fmt.Errorf("windows.SetConsoleMode: %w", err2)
- return
- }
-
- // Set the restore function. We maintain a reference to the tty in the
- // closure (rather than just its handle) to ensure that the tty is not
- // closed by a finalizer.
- restoreFunc = func() error {
- return windows.SetConsoleMode(windows.Handle(tty.Fd()), mode)
- }
-
- return
-}
diff --git a/vendor/github.com/mxk/go-flowrate/LICENSE b/vendor/github.com/mxk/go-flowrate/LICENSE
deleted file mode 100644
index e9f9f628b..000000000
--- a/vendor/github.com/mxk/go-flowrate/LICENSE
+++ /dev/null
@@ -1,29 +0,0 @@
-Copyright (c) 2014 The Go-FlowRate Authors. 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 the go-flowrate project 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.
diff --git a/vendor/github.com/mxk/go-flowrate/flowrate/flowrate.go b/vendor/github.com/mxk/go-flowrate/flowrate/flowrate.go
deleted file mode 100644
index 1b727721e..000000000
--- a/vendor/github.com/mxk/go-flowrate/flowrate/flowrate.go
+++ /dev/null
@@ -1,267 +0,0 @@
-//
-// Written by Maxim Khitrov (November 2012)
-//
-
-// Package flowrate provides the tools for monitoring and limiting the flow rate
-// of an arbitrary data stream.
-package flowrate
-
-import (
- "math"
- "sync"
- "time"
-)
-
-// Monitor monitors and limits the transfer rate of a data stream.
-type Monitor struct {
- mu sync.Mutex // Mutex guarding access to all internal fields
- active bool // Flag indicating an active transfer
- start time.Duration // Transfer start time (clock() value)
- bytes int64 // Total number of bytes transferred
- samples int64 // Total number of samples taken
-
- rSample float64 // Most recent transfer rate sample (bytes per second)
- rEMA float64 // Exponential moving average of rSample
- rPeak float64 // Peak transfer rate (max of all rSamples)
- rWindow float64 // rEMA window (seconds)
-
- sBytes int64 // Number of bytes transferred since sLast
- sLast time.Duration // Most recent sample time (stop time when inactive)
- sRate time.Duration // Sampling rate
-
- tBytes int64 // Number of bytes expected in the current transfer
- tLast time.Duration // Time of the most recent transfer of at least 1 byte
-}
-
-// New creates a new flow control monitor. Instantaneous transfer rate is
-// measured and updated for each sampleRate interval. windowSize determines the
-// weight of each sample in the exponential moving average (EMA) calculation.
-// The exact formulas are:
-//
-// sampleTime = currentTime - prevSampleTime
-// sampleRate = byteCount / sampleTime
-// weight = 1 - exp(-sampleTime/windowSize)
-// newRate = weight*sampleRate + (1-weight)*oldRate
-//
-// The default values for sampleRate and windowSize (if <= 0) are 100ms and 1s,
-// respectively.
-func New(sampleRate, windowSize time.Duration) *Monitor {
- if sampleRate = clockRound(sampleRate); sampleRate <= 0 {
- sampleRate = 5 * clockRate
- }
- if windowSize <= 0 {
- windowSize = 1 * time.Second
- }
- now := clock()
- return &Monitor{
- active: true,
- start: now,
- rWindow: windowSize.Seconds(),
- sLast: now,
- sRate: sampleRate,
- tLast: now,
- }
-}
-
-// Update records the transfer of n bytes and returns n. It should be called
-// after each Read/Write operation, even if n is 0.
-func (m *Monitor) Update(n int) int {
- m.mu.Lock()
- m.update(n)
- m.mu.Unlock()
- return n
-}
-
-// IO is a convenience method intended to wrap io.Reader and io.Writer method
-// execution. It calls m.Update(n) and then returns (n, err) unmodified.
-func (m *Monitor) IO(n int, err error) (int, error) {
- return m.Update(n), err
-}
-
-// Done marks the transfer as finished and prevents any further updates or
-// limiting. Instantaneous and current transfer rates drop to 0. Update, IO, and
-// Limit methods become NOOPs. It returns the total number of bytes transferred.
-func (m *Monitor) Done() int64 {
- m.mu.Lock()
- if now := m.update(0); m.sBytes > 0 {
- m.reset(now)
- }
- m.active = false
- m.tLast = 0
- n := m.bytes
- m.mu.Unlock()
- return n
-}
-
-// timeRemLimit is the maximum Status.TimeRem value.
-const timeRemLimit = 999*time.Hour + 59*time.Minute + 59*time.Second
-
-// Status represents the current Monitor status. All transfer rates are in bytes
-// per second rounded to the nearest byte.
-type Status struct {
- Active bool // Flag indicating an active transfer
- Start time.Time // Transfer start time
- Duration time.Duration // Time period covered by the statistics
- Idle time.Duration // Time since the last transfer of at least 1 byte
- Bytes int64 // Total number of bytes transferred
- Samples int64 // Total number of samples taken
- InstRate int64 // Instantaneous transfer rate
- CurRate int64 // Current transfer rate (EMA of InstRate)
- AvgRate int64 // Average transfer rate (Bytes / Duration)
- PeakRate int64 // Maximum instantaneous transfer rate
- BytesRem int64 // Number of bytes remaining in the transfer
- TimeRem time.Duration // Estimated time to completion
- Progress Percent // Overall transfer progress
-}
-
-// Status returns current transfer status information. The returned value
-// becomes static after a call to Done.
-func (m *Monitor) Status() Status {
- m.mu.Lock()
- now := m.update(0)
- s := Status{
- Active: m.active,
- Start: clockToTime(m.start),
- Duration: m.sLast - m.start,
- Idle: now - m.tLast,
- Bytes: m.bytes,
- Samples: m.samples,
- PeakRate: round(m.rPeak),
- BytesRem: m.tBytes - m.bytes,
- Progress: percentOf(float64(m.bytes), float64(m.tBytes)),
- }
- if s.BytesRem < 0 {
- s.BytesRem = 0
- }
- if s.Duration > 0 {
- rAvg := float64(s.Bytes) / s.Duration.Seconds()
- s.AvgRate = round(rAvg)
- if s.Active {
- s.InstRate = round(m.rSample)
- s.CurRate = round(m.rEMA)
- if s.BytesRem > 0 {
- if tRate := 0.8*m.rEMA + 0.2*rAvg; tRate > 0 {
- ns := float64(s.BytesRem) / tRate * 1e9
- if ns > float64(timeRemLimit) {
- ns = float64(timeRemLimit)
- }
- s.TimeRem = clockRound(time.Duration(ns))
- }
- }
- }
- }
- m.mu.Unlock()
- return s
-}
-
-// Limit restricts the instantaneous (per-sample) data flow to rate bytes per
-// second. It returns the maximum number of bytes (0 <= n <= want) that may be
-// transferred immediately without exceeding the limit. If block == true, the
-// call blocks until n > 0. want is returned unmodified if want < 1, rate < 1,
-// or the transfer is inactive (after a call to Done).
-//
-// At least one byte is always allowed to be transferred in any given sampling
-// period. Thus, if the sampling rate is 100ms, the lowest achievable flow rate
-// is 10 bytes per second.
-//
-// For usage examples, see the implementation of Reader and Writer in io.go.
-func (m *Monitor) Limit(want int, rate int64, block bool) (n int) {
- if want < 1 || rate < 1 {
- return want
- }
- m.mu.Lock()
-
- // Determine the maximum number of bytes that can be sent in one sample
- limit := round(float64(rate) * m.sRate.Seconds())
- if limit <= 0 {
- limit = 1
- }
-
- // If block == true, wait until m.sBytes < limit
- if now := m.update(0); block {
- for m.sBytes >= limit && m.active {
- now = m.waitNextSample(now)
- }
- }
-
- // Make limit <= want (unlimited if the transfer is no longer active)
- if limit -= m.sBytes; limit > int64(want) || !m.active {
- limit = int64(want)
- }
- m.mu.Unlock()
-
- if limit < 0 {
- limit = 0
- }
- return int(limit)
-}
-
-// SetTransferSize specifies the total size of the data transfer, which allows
-// the Monitor to calculate the overall progress and time to completion.
-func (m *Monitor) SetTransferSize(bytes int64) {
- if bytes < 0 {
- bytes = 0
- }
- m.mu.Lock()
- m.tBytes = bytes
- m.mu.Unlock()
-}
-
-// update accumulates the transferred byte count for the current sample until
-// clock() - m.sLast >= m.sRate. The monitor status is updated once the current
-// sample is done.
-func (m *Monitor) update(n int) (now time.Duration) {
- if !m.active {
- return
- }
- if now = clock(); n > 0 {
- m.tLast = now
- }
- m.sBytes += int64(n)
- if sTime := now - m.sLast; sTime >= m.sRate {
- t := sTime.Seconds()
- if m.rSample = float64(m.sBytes) / t; m.rSample > m.rPeak {
- m.rPeak = m.rSample
- }
-
- // Exponential moving average using a method similar to *nix load
- // average calculation. Longer sampling periods carry greater weight.
- if m.samples > 0 {
- w := math.Exp(-t / m.rWindow)
- m.rEMA = m.rSample + w*(m.rEMA-m.rSample)
- } else {
- m.rEMA = m.rSample
- }
- m.reset(now)
- }
- return
-}
-
-// reset clears the current sample state in preparation for the next sample.
-func (m *Monitor) reset(sampleTime time.Duration) {
- m.bytes += m.sBytes
- m.samples++
- m.sBytes = 0
- m.sLast = sampleTime
-}
-
-// waitNextSample sleeps for the remainder of the current sample. The lock is
-// released and reacquired during the actual sleep period, so it's possible for
-// the transfer to be inactive when this method returns.
-func (m *Monitor) waitNextSample(now time.Duration) time.Duration {
- const minWait = 5 * time.Millisecond
- current := m.sLast
-
- // sleep until the last sample time changes (ideally, just one iteration)
- for m.sLast == current && m.active {
- d := current + m.sRate - now
- m.mu.Unlock()
- if d < minWait {
- d = minWait
- }
- time.Sleep(d)
- m.mu.Lock()
- now = m.update(0)
- }
- return now
-}
diff --git a/vendor/github.com/mxk/go-flowrate/flowrate/io.go b/vendor/github.com/mxk/go-flowrate/flowrate/io.go
deleted file mode 100644
index fbe090972..000000000
--- a/vendor/github.com/mxk/go-flowrate/flowrate/io.go
+++ /dev/null
@@ -1,133 +0,0 @@
-//
-// Written by Maxim Khitrov (November 2012)
-//
-
-package flowrate
-
-import (
- "errors"
- "io"
-)
-
-// ErrLimit is returned by the Writer when a non-blocking write is short due to
-// the transfer rate limit.
-var ErrLimit = errors.New("flowrate: flow rate limit exceeded")
-
-// Limiter is implemented by the Reader and Writer to provide a consistent
-// interface for monitoring and controlling data transfer.
-type Limiter interface {
- Done() int64
- Status() Status
- SetTransferSize(bytes int64)
- SetLimit(new int64) (old int64)
- SetBlocking(new bool) (old bool)
-}
-
-// Reader implements io.ReadCloser with a restriction on the rate of data
-// transfer.
-type Reader struct {
- io.Reader // Data source
- *Monitor // Flow control monitor
-
- limit int64 // Rate limit in bytes per second (unlimited when <= 0)
- block bool // What to do when no new bytes can be read due to the limit
-}
-
-// NewReader restricts all Read operations on r to limit bytes per second.
-func NewReader(r io.Reader, limit int64) *Reader {
- return &Reader{r, New(0, 0), limit, true}
-}
-
-// Read reads up to len(p) bytes into p without exceeding the current transfer
-// rate limit. It returns (0, nil) immediately if r is non-blocking and no new
-// bytes can be read at this time.
-func (r *Reader) Read(p []byte) (n int, err error) {
- p = p[:r.Limit(len(p), r.limit, r.block)]
- if len(p) > 0 {
- n, err = r.IO(r.Reader.Read(p))
- }
- return
-}
-
-// SetLimit changes the transfer rate limit to new bytes per second and returns
-// the previous setting.
-func (r *Reader) SetLimit(new int64) (old int64) {
- old, r.limit = r.limit, new
- return
-}
-
-// SetBlocking changes the blocking behavior and returns the previous setting. A
-// Read call on a non-blocking reader returns immediately if no additional bytes
-// may be read at this time due to the rate limit.
-func (r *Reader) SetBlocking(new bool) (old bool) {
- old, r.block = r.block, new
- return
-}
-
-// Close closes the underlying reader if it implements the io.Closer interface.
-func (r *Reader) Close() error {
- defer r.Done()
- if c, ok := r.Reader.(io.Closer); ok {
- return c.Close()
- }
- return nil
-}
-
-// Writer implements io.WriteCloser with a restriction on the rate of data
-// transfer.
-type Writer struct {
- io.Writer // Data destination
- *Monitor // Flow control monitor
-
- limit int64 // Rate limit in bytes per second (unlimited when <= 0)
- block bool // What to do when no new bytes can be written due to the limit
-}
-
-// NewWriter restricts all Write operations on w to limit bytes per second. The
-// transfer rate and the default blocking behavior (true) can be changed
-// directly on the returned *Writer.
-func NewWriter(w io.Writer, limit int64) *Writer {
- return &Writer{w, New(0, 0), limit, true}
-}
-
-// Write writes len(p) bytes from p to the underlying data stream without
-// exceeding the current transfer rate limit. It returns (n, ErrLimit) if w is
-// non-blocking and no additional bytes can be written at this time.
-func (w *Writer) Write(p []byte) (n int, err error) {
- var c int
- for len(p) > 0 && err == nil {
- s := p[:w.Limit(len(p), w.limit, w.block)]
- if len(s) > 0 {
- c, err = w.IO(w.Writer.Write(s))
- } else {
- return n, ErrLimit
- }
- p = p[c:]
- n += c
- }
- return
-}
-
-// SetLimit changes the transfer rate limit to new bytes per second and returns
-// the previous setting.
-func (w *Writer) SetLimit(new int64) (old int64) {
- old, w.limit = w.limit, new
- return
-}
-
-// SetBlocking changes the blocking behavior and returns the previous setting. A
-// Write call on a non-blocking writer returns as soon as no additional bytes
-// may be written at this time due to the rate limit.
-func (w *Writer) SetBlocking(new bool) (old bool) {
- old, w.block = w.block, new
- return
-}
-
-// Close closes the underlying writer if it implements the io.Closer interface.
-func (w *Writer) Close() error {
- defer w.Done()
- if c, ok := w.Writer.(io.Closer); ok {
- return c.Close()
- }
- return nil
-}
diff --git a/vendor/github.com/mxk/go-flowrate/flowrate/util.go b/vendor/github.com/mxk/go-flowrate/flowrate/util.go
deleted file mode 100644
index 4caac583f..000000000
--- a/vendor/github.com/mxk/go-flowrate/flowrate/util.go
+++ /dev/null
@@ -1,67 +0,0 @@
-//
-// Written by Maxim Khitrov (November 2012)
-//
-
-package flowrate
-
-import (
- "math"
- "strconv"
- "time"
-)
-
-// clockRate is the resolution and precision of clock().
-const clockRate = 20 * time.Millisecond
-
-// czero is the process start time rounded down to the nearest clockRate
-// increment.
-var czero = time.Duration(time.Now().UnixNano()) / clockRate * clockRate
-
-// clock returns a low resolution timestamp relative to the process start time.
-func clock() time.Duration {
- return time.Duration(time.Now().UnixNano())/clockRate*clockRate - czero
-}
-
-// clockToTime converts a clock() timestamp to an absolute time.Time value.
-func clockToTime(c time.Duration) time.Time {
- return time.Unix(0, int64(czero+c))
-}
-
-// clockRound returns d rounded to the nearest clockRate increment.
-func clockRound(d time.Duration) time.Duration {
- return (d + clockRate>>1) / clockRate * clockRate
-}
-
-// round returns x rounded to the nearest int64 (non-negative values only).
-func round(x float64) int64 {
- if _, frac := math.Modf(x); frac >= 0.5 {
- return int64(math.Ceil(x))
- }
- return int64(math.Floor(x))
-}
-
-// Percent represents a percentage in increments of 1/1000th of a percent.
-type Percent uint32
-
-// percentOf calculates what percent of the total is x.
-func percentOf(x, total float64) Percent {
- if x < 0 || total <= 0 {
- return 0
- } else if p := round(x / total * 1e5); p <= math.MaxUint32 {
- return Percent(p)
- }
- return Percent(math.MaxUint32)
-}
-
-func (p Percent) Float() float64 {
- return float64(p) * 1e-3
-}
-
-func (p Percent) String() string {
- var buf [12]byte
- b := strconv.AppendUint(buf[:0], uint64(p)/1000, 10)
- n := len(b)
- b = strconv.AppendUint(b, 1000+uint64(p)%1000, 10)
- b[n] = '.'
- return string(append(b, '%'))
-}
diff --git a/vendor/github.com/nunnatsa/ginkgolinter/Makefile b/vendor/github.com/nunnatsa/ginkgolinter/Makefile
index 647ca1683..749ce0fe1 100644
--- a/vendor/github.com/nunnatsa/ginkgolinter/Makefile
+++ b/vendor/github.com/nunnatsa/ginkgolinter/Makefile
@@ -34,3 +34,9 @@ test: unit-test test-cli
goimports:
go install golang.org/x/tools/cmd/goimports@latest
goimports -w -local="github.com/nunnatsa/ginkgolinter" $(shell find . -type f -name '*.go' ! -path "*/vendor/*")
+
+build-txtar-updater:
+ go build -o bin/ ./tools/txtar_updater
+
+update-txtar: build-txtar-updater
+ bin/txtar_updater --target-dir="./tests/testdata" --source-dir="./testdata/src/a"
diff --git a/vendor/github.com/nunnatsa/ginkgolinter/internal/expression/actual/actual.go b/vendor/github.com/nunnatsa/ginkgolinter/internal/expression/actual/actual.go
index 5bd6dd6e7..b3359f2a6 100644
--- a/vendor/github.com/nunnatsa/ginkgolinter/internal/expression/actual/actual.go
+++ b/vendor/github.com/nunnatsa/ginkgolinter/internal/expression/actual/actual.go
@@ -7,7 +7,6 @@ import (
"golang.org/x/tools/go/analysis"
"github.com/nunnatsa/ginkgolinter/internal/gomegahandler"
- "github.com/nunnatsa/ginkgolinter/internal/gomegainfo"
)
type Actual struct {
@@ -21,13 +20,13 @@ type Actual struct {
actualOffset int
}
-func New(origExpr, cloneExpr *ast.CallExpr, orig *ast.CallExpr, clone *ast.CallExpr, pass *analysis.Pass, timePkg string, info *gomegahandler.GomegaBasicInfo) (*Actual, bool) {
- arg, actualOffset := getActualArgPayload(orig, clone, pass, info)
+func New(origExpr, cloneExpr *ast.CallExpr, clone *ast.CallExpr, pass *analysis.Pass, timePkg string, info *gomegahandler.GomegaBasicInfo) (*Actual, bool) {
+ arg, actualOffset := getActualArgPayload(clone, pass, info)
if arg == nil {
return nil, false
}
- argType := pass.TypesInfo.TypeOf(orig.Args[actualOffset])
+ argType := pass.TypesInfo.TypeOf(info.RootCall.Args[actualOffset])
isTuple := false
if tpl, ok := argType.(*gotypes.Tuple); ok {
@@ -40,15 +39,15 @@ func New(origExpr, cloneExpr *ast.CallExpr, orig *ast.CallExpr, clone *ast.CallE
isTuple = tpl.Len() > 1
}
- isAsyncExpr := gomegainfo.IsAsyncActualMethod(info.MethodName)
+ isAsyncExpr := info.RootCallType == gomegahandler.AsyncAssertionCall
var asyncArg *AsyncArg
if isAsyncExpr {
- asyncArg = newAsyncArg(origExpr, cloneExpr, orig, clone, argType, pass, actualOffset, timePkg)
+ asyncArg = newAsyncArg(origExpr, cloneExpr, info.RootCall, clone, argType, pass, actualOffset, timePkg)
}
return &Actual{
- Orig: orig,
+ Orig: info.RootCall,
Clone: clone,
Arg: arg,
argType: argType,
diff --git a/vendor/github.com/nunnatsa/ginkgolinter/internal/expression/actual/actualarg.go b/vendor/github.com/nunnatsa/ginkgolinter/internal/expression/actual/actualarg.go
index 05f640cc0..735c03c81 100644
--- a/vendor/github.com/nunnatsa/ginkgolinter/internal/expression/actual/actualarg.go
+++ b/vendor/github.com/nunnatsa/ginkgolinter/internal/expression/actual/actualarg.go
@@ -29,6 +29,7 @@ const (
FuncSigArgType
ErrFuncActualArgType
GomegaParamArgType
+ TBParamArgType
MultiRetsArgType
ErrorMethodArgType
@@ -42,8 +43,8 @@ func (a ArgType) Is(val ArgType) bool {
return a&val != 0
}
-func getActualArgPayload(origActualExpr, actualExprClone *ast.CallExpr, pass *analysis.Pass, info *gomegahandler.GomegaBasicInfo) (ArgPayload, int) {
- origArgExpr, argExprClone, actualOffset, isGomegaExpr := getActualArg(origActualExpr, actualExprClone, info.MethodName, pass)
+func getActualArgPayload(actualExprClone *ast.CallExpr, pass *analysis.Pass, info *gomegahandler.GomegaBasicInfo) (ArgPayload, int) {
+ origArgExpr, argExprClone, actualOffset, isGomegaExpr := getActualArg(actualExprClone, info, pass)
if !isGomegaExpr {
return nil, 0
}
@@ -79,13 +80,14 @@ func getActualArgPayload(origActualExpr, actualExprClone *ast.CallExpr, pass *an
return newRegularArgPayload(origArgExpr, argExprClone, pass), actualOffset
}
-func getActualArg(origActualExpr *ast.CallExpr, actualExprClone *ast.CallExpr, actualMethodName string, pass *analysis.Pass) (ast.Expr, ast.Expr, int, bool) {
+func getActualArg(actualExprClone *ast.CallExpr, info *gomegahandler.GomegaBasicInfo, pass *analysis.Pass) (ast.Expr, ast.Expr, int, bool) {
var (
- origArgExpr ast.Expr
- argExprClone ast.Expr
+ origArgExpr ast.Expr
+ argExprClone ast.Expr
+ origActualExpr = info.RootCall
)
- funcOffset := gomegainfo.ActualArgOffset(actualMethodName)
+ funcOffset := gomegainfo.ActualArgOffset(info.MethodName)
if funcOffset < 0 {
return nil, nil, 0, false
}
@@ -97,7 +99,7 @@ func getActualArg(origActualExpr *ast.CallExpr, actualExprClone *ast.CallExpr, a
origArgExpr = origActualExpr.Args[funcOffset]
argExprClone = actualExprClone.Args[funcOffset]
- if gomegainfo.IsAsyncActualMethod(actualMethodName) {
+ if info.RootCallType == gomegahandler.AsyncAssertionCall {
if ginkgoinfo.IsGinkgoContext(pass.TypesInfo.TypeOf(origArgExpr)) {
funcOffset++
if len(origActualExpr.Args) <= funcOffset {
diff --git a/vendor/github.com/nunnatsa/ginkgolinter/internal/expression/actual/asyncfuncarg.go b/vendor/github.com/nunnatsa/ginkgolinter/internal/expression/actual/asyncfuncarg.go
index 410425749..f8ef3aa89 100644
--- a/vendor/github.com/nunnatsa/ginkgolinter/internal/expression/actual/asyncfuncarg.go
+++ b/vendor/github.com/nunnatsa/ginkgolinter/internal/expression/actual/asyncfuncarg.go
@@ -17,8 +17,13 @@ func getAsyncFuncArg(sig *gotypes.Signature) ArgPayload {
if sig.Params().Len() > 0 {
arg := sig.Params().At(0).Type()
- if gomegainfo.IsGomegaType(arg) && sig.Results().Len() == 0 {
- argType |= FuncSigArgType | GomegaParamArgType
+ if sig.Results().Len() == 0 {
+ if gomegainfo.IsGomegaType(arg) {
+ argType |= FuncSigArgType | GomegaParamArgType
+ }
+ if typecheck.ImplementsTB(arg) {
+ argType |= FuncSigArgType | TBParamArgType
+ }
}
}
diff --git a/vendor/github.com/nunnatsa/ginkgolinter/internal/expression/expression.go b/vendor/github.com/nunnatsa/ginkgolinter/internal/expression/expression.go
index 1909207e2..133c84e2a 100644
--- a/vendor/github.com/nunnatsa/ginkgolinter/internal/expression/expression.go
+++ b/vendor/github.com/nunnatsa/ginkgolinter/internal/expression/expression.go
@@ -27,19 +27,26 @@ type GomegaExpression struct {
origAssertionFuncName string
actualFuncName string
- isAsync bool
- isUsingGomegaVar bool
+ isAsync bool
actual *actual.Actual
matcher *matcher.Matcher
- handler gomegahandler.Handler
+ handler *gomegahandler.Handler
}
-func New(origExpr *ast.CallExpr, pass *analysis.Pass, handler gomegahandler.Handler, timePkg string) (*GomegaExpression, bool) {
- info, ok := handler.GetGomegaBasicInfo(origExpr)
- if !ok || !gomegainfo.IsActualMethod(info.MethodName) {
- return nil, false
+func New(origExpr *ast.CallExpr, pass *analysis.Pass, handler *gomegahandler.Handler, timePkg string) (gexp *GomegaExpression) {
+ info := handler.GetGomegaBasicInfo(origExpr)
+ if info == nil {
+ return nil
+ }
+
+ switch info.RootCallType {
+ case gomegahandler.AsyncAssertionCall, gomegahandler.SyncAssertionCall:
+ // Okay, that's what we want here.
+ default:
+ // Cannot handle anything else.
+ return nil
}
origSel, ok := origExpr.Fun.(*ast.SelectorExpr)
@@ -47,42 +54,42 @@ func New(origExpr *ast.CallExpr, pass *analysis.Pass, handler gomegahandler.Hand
return &GomegaExpression{
orig: origExpr,
actualFuncName: info.MethodName,
- }, true
+ }
}
exprClone := astcopy.CallExpr(origExpr)
selClone := exprClone.Fun.(*ast.SelectorExpr)
- origActual := handler.GetActualExpr(origSel)
+ origActual := info.RootCall
if origActual == nil {
- return nil, false
+ return nil
}
- actualClone := handler.GetActualExprClone(origSel, selClone)
+ actualClone := handler.GetActualExprClone(origActual, origSel, selClone)
if actualClone == nil {
- return nil, false
+ return nil
}
- actl, ok := actual.New(origExpr, exprClone, origActual, actualClone, pass, timePkg, info)
+ actl, ok := actual.New(origExpr, exprClone, actualClone, pass, timePkg, info)
if !ok {
- return nil, false
+ return nil
}
origMatcher, ok := origExpr.Args[0].(*ast.CallExpr)
if !ok {
- return nil, false
+ return nil
}
matcherClone := exprClone.Args[0].(*ast.CallExpr)
- mtchr, ok := matcher.New(origMatcher, matcherClone, pass, handler)
- if !ok {
- return nil, false
+ mtchr := matcher.New(origMatcher, matcherClone, pass, handler)
+ if mtchr == nil {
+ return nil
}
exprClone.Args[0] = mtchr.Clone
- gexp := &GomegaExpression{
+ gexp = &GomegaExpression{
orig: origExpr,
clone: exprClone,
@@ -90,8 +97,7 @@ func New(origExpr *ast.CallExpr, pass *analysis.Pass, handler gomegahandler.Hand
origAssertionFuncName: origSel.Sel.Name,
actualFuncName: info.MethodName,
- isAsync: actl.IsAsync(),
- isUsingGomegaVar: info.UseGomegaVar,
+ isAsync: actl.IsAsync(),
actual: actl,
matcher: mtchr,
@@ -103,7 +109,7 @@ func New(origExpr *ast.CallExpr, pass *analysis.Pass, handler gomegahandler.Hand
gexp.ReverseAssertionFuncLogic()
}
- return gexp, true
+ return gexp
}
func (e *GomegaExpression) IsMissingAssertion() bool {
@@ -135,10 +141,6 @@ func (e *GomegaExpression) IsAsync() bool {
return e.isAsync
}
-func (e *GomegaExpression) IsUsingGomegaVar() bool {
- return e.isUsingGomegaVar
-}
-
func (e *GomegaExpression) ReverseAssertionFuncLogic() {
assertionFunc := e.clone.Fun.(*ast.SelectorExpr).Sel
newName := reverseassertion.ChangeAssertionLogic(assertionFunc.Name)
diff --git a/vendor/github.com/nunnatsa/ginkgolinter/internal/expression/matcher/matcher.go b/vendor/github.com/nunnatsa/ginkgolinter/internal/expression/matcher/matcher.go
index 0636278e2..208437a5d 100644
--- a/vendor/github.com/nunnatsa/ginkgolinter/internal/expression/matcher/matcher.go
+++ b/vendor/github.com/nunnatsa/ginkgolinter/internal/expression/matcher/matcher.go
@@ -34,19 +34,19 @@ type Matcher struct {
Clone *ast.CallExpr
info Info
reverseLogic bool
- handler gomegahandler.Handler
+ handler *gomegahandler.Handler
hasNotMatcher bool // true if the matcher is wrapped with a "Not" matcher
}
-func New(origMatcher, matcherClone *ast.CallExpr, pass *analysis.Pass, handler gomegahandler.Handler) (*Matcher, bool) {
+func New(origMatcher, matcherClone *ast.CallExpr, pass *analysis.Pass, handler *gomegahandler.Handler) *Matcher {
reverse := false
hasNotMatcher := false
var assertFuncName string
for {
- info, ok := handler.GetGomegaBasicInfo(origMatcher)
- if !ok {
- return nil, false
+ info := handler.GetGomegaBasicInfo(origMatcher)
+ if info == nil {
+ return nil
}
if info.MethodName != "Not" {
@@ -56,9 +56,10 @@ func New(origMatcher, matcherClone *ast.CallExpr, pass *analysis.Pass, handler g
hasNotMatcher = true
reverse = !reverse
+ var ok bool
origMatcher, ok = origMatcher.Args[0].(*ast.CallExpr)
if !ok {
- return nil, false
+ return nil
}
matcherClone = matcherClone.Args[0].(*ast.CallExpr)
}
@@ -71,7 +72,7 @@ func New(origMatcher, matcherClone *ast.CallExpr, pass *analysis.Pass, handler g
reverseLogic: reverse,
hasNotMatcher: hasNotMatcher,
handler: handler,
- }, true
+ }
}
func (m *Matcher) ShouldReverseLogic() bool {
diff --git a/vendor/github.com/nunnatsa/ginkgolinter/internal/expression/matcher/matcherinfo.go b/vendor/github.com/nunnatsa/ginkgolinter/internal/expression/matcher/matcherinfo.go
index de15526ec..612209998 100644
--- a/vendor/github.com/nunnatsa/ginkgolinter/internal/expression/matcher/matcherinfo.go
+++ b/vendor/github.com/nunnatsa/ginkgolinter/internal/expression/matcher/matcherinfo.go
@@ -53,7 +53,7 @@ type Info interface {
MatcherName() string
}
-func getMatcherInfo(orig, clone *ast.CallExpr, matcherName string, pass *analysis.Pass, handler gomegahandler.Handler) Info {
+func getMatcherInfo(orig, clone *ast.CallExpr, matcherName string, pass *analysis.Pass, handler *gomegahandler.Handler) Info {
switch matcherName {
case equal:
return newEqualMatcher(orig.Args[0], clone.Args[0], pass)
@@ -97,14 +97,14 @@ func getMatcherInfo(orig, clone *ast.CallExpr, matcherName string, pass *analysi
return newMatchErrorMatcher(orig.Args, pass)
case haveValue:
- if nestedMatcher, ok := getNestedMatcher(orig, clone, 0, pass, handler); ok {
+ if nestedMatcher := getNestedMatcher(orig, clone, 0, pass, handler); nestedMatcher != nil {
return &HaveValueMatcher{
nested: nestedMatcher,
}
}
case withTransform:
- if nestedMatcher, ok := getNestedMatcher(orig, clone, 1, pass, handler); ok {
+ if nestedMatcher := getNestedMatcher(orig, clone, 1, pass, handler); nestedMatcher != nil {
return newWithTransformMatcher(orig.Args[0], nestedMatcher, pass)
}
@@ -116,7 +116,7 @@ func getMatcherInfo(orig, clone *ast.CallExpr, matcherName string, pass *analysi
matcherType |= AndMatherType
}
- if m, ok := newMultipleMatchersMatcher(matcherType, orig.Args, clone.Args, pass, handler); ok {
+ if m := newMultipleMatchersMatcher(matcherType, orig.Args, clone.Args, pass, handler); m != nil {
return m
}
diff --git a/vendor/github.com/nunnatsa/ginkgolinter/internal/expression/matcher/matcherwithnest.go b/vendor/github.com/nunnatsa/ginkgolinter/internal/expression/matcher/matcherwithnest.go
index cc26e5ac2..7511bd28a 100644
--- a/vendor/github.com/nunnatsa/ginkgolinter/internal/expression/matcher/matcherwithnest.go
+++ b/vendor/github.com/nunnatsa/ginkgolinter/internal/expression/matcher/matcherwithnest.go
@@ -44,14 +44,14 @@ func (m *WithTransformMatcher) GetFuncType() gotypes.Type {
return m.funcType
}
-func getNestedMatcher(orig, clone *ast.CallExpr, offset int, pass *analysis.Pass, handler gomegahandler.Handler) (*Matcher, bool) {
+func getNestedMatcher(orig, clone *ast.CallExpr, offset int, pass *analysis.Pass, handler *gomegahandler.Handler) *Matcher {
if origNested, ok := orig.Args[offset].(*ast.CallExpr); ok {
cloneNested := clone.Args[offset].(*ast.CallExpr)
return New(origNested, cloneNested, pass, handler)
}
- return nil, false
+ return nil
}
func newWithTransformMatcher(fun ast.Expr, nested *Matcher, pass *analysis.Pass) *WithTransformMatcher {
diff --git a/vendor/github.com/nunnatsa/ginkgolinter/internal/expression/matcher/multiplematchers.go b/vendor/github.com/nunnatsa/ginkgolinter/internal/expression/matcher/multiplematchers.go
index 9ce0cf5b8..184d0302b 100644
--- a/vendor/github.com/nunnatsa/ginkgolinter/internal/expression/matcher/multiplematchers.go
+++ b/vendor/github.com/nunnatsa/ginkgolinter/internal/expression/matcher/multiplematchers.go
@@ -24,18 +24,18 @@ func (m *MultipleMatchersMatcher) MatcherName() string {
return and
}
-func newMultipleMatchersMatcher(matherType Type, orig, clone []ast.Expr, pass *analysis.Pass, handler gomegahandler.Handler) (*MultipleMatchersMatcher, bool) {
+func newMultipleMatchersMatcher(matherType Type, orig, clone []ast.Expr, pass *analysis.Pass, handler *gomegahandler.Handler) *MultipleMatchersMatcher {
matchers := make([]*Matcher, len(orig))
for i := range orig {
nestedOrig, ok := orig[i].(*ast.CallExpr)
if !ok {
- return nil, false
+ return nil
}
- m, ok := New(nestedOrig, clone[i].(*ast.CallExpr), pass, handler)
- if !ok {
- return nil, false
+ m := New(nestedOrig, clone[i].(*ast.CallExpr), pass, handler)
+ if m == nil {
+ return nil
}
m.reverseLogic = false
@@ -46,7 +46,7 @@ func newMultipleMatchersMatcher(matherType Type, orig, clone []ast.Expr, pass *a
return &MultipleMatchersMatcher{
matherType: matherType,
matchers: matchers,
- }, true
+ }
}
func (m *MultipleMatchersMatcher) Len() int {
diff --git a/vendor/github.com/nunnatsa/ginkgolinter/internal/gomegahandler/dothandler.go b/vendor/github.com/nunnatsa/ginkgolinter/internal/gomegahandler/dothandler.go
deleted file mode 100644
index 8ab87c76e..000000000
--- a/vendor/github.com/nunnatsa/ginkgolinter/internal/gomegahandler/dothandler.go
+++ /dev/null
@@ -1,109 +0,0 @@
-package gomegahandler
-
-import (
- "go/ast"
-
- "golang.org/x/tools/go/analysis"
-
- "github.com/nunnatsa/ginkgolinter/internal/gomegainfo"
-)
-
-// dotHandler is used when importing gomega with dot; i.e.
-// import . "github.com/onsi/gomega"
-type dotHandler struct {
- pass *analysis.Pass
-}
-
-// GetGomegaBasicInfo returns the name of the gomega function, e.g. `Expect` + some additional info
-func (h dotHandler) GetGomegaBasicInfo(expr *ast.CallExpr) (*GomegaBasicInfo, bool) {
- info := &GomegaBasicInfo{}
- for {
- switch actualFunc := expr.Fun.(type) {
- case *ast.Ident:
- info.MethodName = actualFunc.Name
- return info, true
- case *ast.SelectorExpr:
- if h.isGomegaVar(actualFunc.X) {
- info.UseGomegaVar = true
- info.MethodName = actualFunc.Sel.Name
- return info, true
- }
-
- if actualFunc.Sel.Name == "Error" {
- info.HasErrorMethod = true
- }
-
- if x, ok := actualFunc.X.(*ast.CallExpr); ok {
- expr = x
- } else {
- return nil, false
- }
- default:
- return nil, false
- }
- }
-}
-
-// ReplaceFunction replaces the function with another one, for fix suggestions
-func (dotHandler) ReplaceFunction(caller *ast.CallExpr, newExpr *ast.Ident) {
- switch f := caller.Fun.(type) {
- case *ast.Ident:
- caller.Fun = newExpr
- case *ast.SelectorExpr:
- f.Sel = newExpr
- }
-}
-
-func (dotHandler) GetNewWrapperMatcher(name string, existing *ast.CallExpr) *ast.CallExpr {
- return &ast.CallExpr{
- Fun: ast.NewIdent(name),
- Args: []ast.Expr{existing},
- }
-}
-
-func (h dotHandler) GetActualExpr(assertionFunc *ast.SelectorExpr) *ast.CallExpr {
- actualExpr, ok := assertionFunc.X.(*ast.CallExpr)
- if !ok {
- return nil
- }
-
- switch fun := actualExpr.Fun.(type) {
- case *ast.Ident:
- return actualExpr
- case *ast.SelectorExpr:
- if gomegainfo.IsActualMethod(fun.Sel.Name) {
- if h.isGomegaVar(fun.X) {
- return actualExpr
- }
- } else {
- return h.GetActualExpr(fun)
- }
- }
- return nil
-}
-
-func (h dotHandler) GetActualExprClone(origFunc, funcClone *ast.SelectorExpr) *ast.CallExpr {
- actualExpr, ok := funcClone.X.(*ast.CallExpr)
- if !ok {
- return nil
- }
-
- switch funClone := actualExpr.Fun.(type) {
- case *ast.Ident:
- return actualExpr
- case *ast.SelectorExpr:
- origFun := origFunc.X.(*ast.CallExpr).Fun.(*ast.SelectorExpr)
- if gomegainfo.IsActualMethod(funClone.Sel.Name) {
- if h.isGomegaVar(origFun.X) {
- return actualExpr
- }
- } else {
- return h.GetActualExprClone(origFun, funClone)
- }
- }
- return nil
-}
-
-func (h dotHandler) isGomegaVar(x ast.Expr) bool {
- return gomegainfo.IsGomegaVar(x, h.pass)
-}
diff --git a/vendor/github.com/nunnatsa/ginkgolinter/internal/gomegahandler/handler.go b/vendor/github.com/nunnatsa/ginkgolinter/internal/gomegahandler/handler.go
index 9eb8ce1dd..1705104cc 100644
--- a/vendor/github.com/nunnatsa/ginkgolinter/internal/gomegahandler/handler.go
+++ b/vendor/github.com/nunnatsa/ginkgolinter/internal/gomegahandler/handler.go
@@ -2,6 +2,8 @@ package gomegahandler
import (
"go/ast"
+ gotypes "go/types"
+ "strings"
"golang.org/x/tools/go/analysis"
)
@@ -10,45 +12,269 @@ const (
importPath = `"github.com/onsi/gomega"`
)
-// Handler provide different handling, depend on the way gomega was imported, whether
-// in imported with "." name, custom name or without any name.
-type Handler interface {
- // GetActualFuncName returns the name of the gomega function, e.g. `Expect`
- GetGomegaBasicInfo(*ast.CallExpr) (*GomegaBasicInfo, bool)
- // ReplaceFunction replaces the function with another one, for fix suggestions
- ReplaceFunction(*ast.CallExpr, *ast.Ident)
-
- GetActualExpr(assertionFunc *ast.SelectorExpr) *ast.CallExpr
+// GomegaBasicInfo is the result of [Handler.GetGomegaBasicInfo].
+type GomegaBasicInfo struct {
+ // MethodName is the top-level Gomega method in which an expression is rooted (e.g. Expect).
+ // Empty is unknown.
+ MethodName string
+ // True if the expression includes an Error call.
+ HasErrorMethod bool
- GetActualExprClone(origFunc, funcClone *ast.SelectorExpr) *ast.CallExpr
+ // RootCall is the call which is root of the expression that GetGomegaBasicInfo
+ // was called for.
+ //
+ // This is either the function which is passed the actual value (see IsAssertion
+ // and IsAsyncAssertion) or a function which is passed some expected value (see
+ // IsMatcher).
+ RootCall *ast.CallExpr
- GetNewWrapperMatcher(name string, existing *ast.CallExpr) *ast.CallExpr
+ // Type determines what kind of Gomega function is called.
+ RootCallType CallType
}
-type GomegaBasicInfo struct {
- MethodName string
- UseGomegaVar bool
- HasErrorMethod bool
-}
+// CallType determines what kind of function call is described by [GomegaBasicInfo].
+type CallType int
+
+const (
+ // OtherCall is the unspecified type. [GetGomegaBasicInfo] never returns a GomegaBasicInfo
+ // with this type.
+ OtherCall CallType = iota
+ // SyncAssertionCall returns gtypes.Assertion.
+ SyncAssertionCall
+ // AsyncAssertionCall returns gtypes.AsyncAssertion.
+ AsyncAssertionCall
+ // MatcherCall returns gtypes.GomegaMatcher.
+ MatcherCall
+)
// GetGomegaHandler returns a gomegar handler according to the way gomega was imported in the specific file
-func GetGomegaHandler(file *ast.File, pass *analysis.Pass) Handler {
+func GetGomegaHandler(file *ast.File, pass *analysis.Pass) *Handler {
+ // Look up the Gomega types package. It might be imported directly or indirectly.
+ gtypesPkg := getPackage(pass.Pkg, "github.com/onsi/gomega/types")
+ if gtypesPkg == nil {
+ return nil // No gomega import: this file does not use gomega, neither directly nor indirectly.
+ }
+
+ // Look up the interfaces. They may be nil if not in use.
+ assertionInterface := lookupInterface(gtypesPkg, "Assertion")
+ asyncAssertionInterface := lookupInterface(gtypesPkg, "AsyncAssertion")
+ matcherInterface := lookupInterface(gtypesPkg, "GomegaMatcher")
+
+ // If there is a direct import, then this gets replaced.
+ //
+ // Otherwise gomega might be used indirectly, in which case
+ // we have to make an educated guess what the package name
+ // should be when suggesting fixes.
+ //
+ // Let's assume that users would want named importing,
+ // because that is the recommended approach in Go.
+ //
+ // In practice it doesn't really matter because the only failure
+ // can be a generic "missing assertion", which doesn't
+ // reference a gomega method.
+ name := "gomega"
for _, imp := range file.Imports {
if imp.Path.Value != importPath {
continue
}
- switch name := imp.Name.String(); name {
+ switch n := imp.Name.String(); n {
case ".":
- return &dotHandler{
- pass: pass,
- }
- case "": // import with no local name
- return &nameHandler{name: "gomega", pass: pass}
+ name = ""
+ case "": // import with no local name, default is good
default:
- return &nameHandler{name: name, pass: pass}
+ name = n
+ }
+ }
+
+ return &Handler{
+ name: name,
+ pass: pass,
+ syncAssertionInterface: assertionInterface,
+ asyncAssertionInterface: asyncAssertionInterface,
+ matcherInterface: matcherInterface,
+ }
+}
+
+// getPackage searches recursively for a specific package, identified by it's full import name.
+//
+// Surprisingly, the imports may contain cycles (unsafe.unsafe -> ... internal/runtime/sys.sys ... -> unsafe.unsafe),
+// so we have to detect those. We also don't want to check the same package more than once.
+func getPackage(pkg *gotypes.Package, importName string) *gotypes.Package {
+ return getPackageRecursively(pkg, importName, make(map[*gotypes.Package]bool))
+}
+
+func getPackageRecursively(pkg *gotypes.Package, importName string, seen map[*gotypes.Package]bool) *gotypes.Package {
+ if seen[pkg] {
+ // Prevent recursion, don't check again.
+ return nil
+ }
+ seen[pkg] = true
+
+ // In unit testing, the actual path is a/vendor/github.com/onsi/gomega/types, so we have to relax
+ // the check a bit.
+ if strings.HasSuffix(pkg.Path(), importName) {
+ return pkg
+ }
+ for _, pkg := range pkg.Imports() {
+ if pkg := getPackageRecursively(pkg, importName, seen); pkg != nil {
+ return pkg
}
}
+ return nil
+}
+
+func lookupInterface(pkg *gotypes.Package, name string) *gotypes.Interface {
+ def := pkg.Scope().Lookup(name)
+ if def == nil {
+ return nil
+ }
+ if i, ok := def.Type().Underlying().(*gotypes.Interface); ok {
+ return i
+ }
+ return nil
+}
+
+// Handler provide different handling, depend on the way gomega was imported, whether
+// in imported with "." name, custom name or without any name.
+type Handler struct {
+ // name is the name under which the gomega package was imported, empty if a dot import
+ name string
+ pass *analysis.Pass
+
+ syncAssertionInterface, asyncAssertionInterface, matcherInterface *gotypes.Interface
+}
- return nil // no gomega import; this file does not use gomega
+// GetGomegaBasicInfo returns the name of the gomega function, e.g. `Expect` + some additional info.
+//
+// We identify gomega functions as:
+// - The result implements a gomega interface (Assertion/AsyncAssertion/GomegaMatcher).
+// - It's not a method called on such an interface.
+//
+// The type of the result doesn't matter, it could be interface type itself,
+// type alias, struct embedding gtypes.Assertion, some other type entirely,
+// etc.): if it walks like a duck, quacks like a duck, it's a duck...
+//
+// The method name is picked up from the identifier (dot import) or from the selector (gomega.Expect, gomega.NewWithT(t).Expect).
+// Returns nil if the root call cannot be determined or does not produce one of the Gomega interfaces.
+func (g *Handler) GetGomegaBasicInfo(expr *ast.CallExpr) (info *GomegaBasicInfo) {
+ hasErrorMethod := false
+ for {
+ // Dive deeper?
+ if actualFunc, ok := expr.Fun.(*ast.SelectorExpr); ok && (g.implements(actualFunc.X, g.syncAssertionInterface) || g.implements(actualFunc.X, g.asyncAssertionInterface) || g.implements(actualFunc.X, g.matcherInterface)) {
+ x, ok := actualFunc.X.(*ast.CallExpr)
+ if !ok {
+ // Could be a variable.
+ // We need to have an actual function call at the root
+ // for parameter checking. We don't have one, so give up.
+ return nil
+ }
+ if actualFunc.Sel.Name == "Error" {
+ hasErrorMethod = true
+ }
+
+ // Because actualFunc.X already implemented some gomega interface,
+ // actualFunc.Sel must be something like "WithOffset".
+ // It's not the root, so we have to keep looking.
+ expr = x
+ continue
+ }
+
+ if callType := g.callType(expr); callType != OtherCall {
+ // Cannot dive deeper and it returns one of the unique
+ // Gomega interfaces, so this must be our root.
+ info := &GomegaBasicInfo{
+ HasErrorMethod: hasErrorMethod,
+ RootCall: expr,
+ RootCallType: callType,
+ }
+ switch actualFunc := expr.Fun.(type) {
+ case *ast.Ident:
+ info.MethodName = actualFunc.Name
+ case *ast.SelectorExpr:
+ info.MethodName = actualFunc.Sel.Name
+ }
+ return info
+ }
+
+ // Give up.
+ return nil
+ }
+}
+
+// ReplaceFunction replaces the function with another one, for fix suggestions
+func (g *Handler) ReplaceFunction(caller *ast.CallExpr, newExpr *ast.Ident) {
+ switch f := caller.Fun.(type) {
+ case *ast.Ident:
+ caller.Fun = newExpr
+ case *ast.SelectorExpr:
+ f.Sel = newExpr
+ }
+}
+
+func (g *Handler) GetNewWrapperMatcher(name string, existing *ast.CallExpr) *ast.CallExpr {
+ if g.name == "" {
+ return &ast.CallExpr{
+ Fun: ast.NewIdent(name),
+ Args: []ast.Expr{existing},
+ }
+ }
+
+ return &ast.CallExpr{
+ Fun: &ast.SelectorExpr{
+ X: ast.NewIdent(g.name),
+ Sel: ast.NewIdent(name),
+ },
+ Args: []ast.Expr{existing},
+ }
+}
+
+func (g *Handler) implements(expr ast.Expr, i *gotypes.Interface) bool {
+ if i == nil {
+ // Interface wasn't found -> not in use -> the expression cannot implement it.
+ return false
+ }
+ exprType, ok := g.pass.TypesInfo.Types[expr]
+ return ok && gotypes.Implements(exprType.Type, i)
+}
+
+func (g *Handler) callType(expr ast.Expr) CallType {
+ switch {
+ case g.implements(expr, g.syncAssertionInterface):
+ return SyncAssertionCall
+ case g.implements(expr, g.asyncAssertionInterface):
+ return AsyncAssertionCall
+ case g.implements(expr, g.matcherInterface):
+ return MatcherCall
+ default:
+ return OtherCall
+ }
+}
+
+// GetActualExprClone dives into origFunc and funcClone in lockstep until it hits
+// origRootCall in origFunc, then returns the corresponding CallExpr in funcClone.
+func (g *Handler) GetActualExprClone(origRootCall *ast.CallExpr, origFunc, cloneFunc *ast.SelectorExpr) (cloneRootCall *ast.CallExpr) {
+ cloneExpr, ok := cloneFunc.X.(*ast.CallExpr)
+ if !ok {
+ return nil
+ }
+ origExpr, ok := origFunc.X.(*ast.CallExpr)
+ if !ok {
+ return nil
+ }
+
+ if origExpr == origRootCall {
+ // Found it!
+ return cloneExpr
+ }
+
+ cloneInnerFunc, ok := cloneExpr.Fun.(*ast.SelectorExpr)
+ if !ok {
+ return nil
+ }
+ origInnerFunc, ok := origExpr.Fun.(*ast.SelectorExpr)
+ if !ok {
+ return nil
+ }
+ return g.GetActualExprClone(origRootCall, origInnerFunc, cloneInnerFunc)
}
diff --git a/vendor/github.com/nunnatsa/ginkgolinter/internal/gomegahandler/namedhandler.go b/vendor/github.com/nunnatsa/ginkgolinter/internal/gomegahandler/namedhandler.go
deleted file mode 100644
index 87e0fc22e..000000000
--- a/vendor/github.com/nunnatsa/ginkgolinter/internal/gomegahandler/namedhandler.go
+++ /dev/null
@@ -1,123 +0,0 @@
-package gomegahandler
-
-import (
- "go/ast"
-
- "github.com/nunnatsa/ginkgolinter/internal/gomegainfo"
-
- "golang.org/x/tools/go/analysis"
-)
-
-// nameHandler is used when importing gomega without name; i.e.
-// import "github.com/onsi/gomega"
-//
-// or with a custom name; e.g.
-// import customname "github.com/onsi/gomega"
-type nameHandler struct {
- name string
- pass *analysis.Pass
-}
-
-// GetGomegaBasicInfo returns the name of the gomega function, e.g. `Expect` + some additional info
-func (g nameHandler) GetGomegaBasicInfo(expr *ast.CallExpr) (*GomegaBasicInfo, bool) {
- info := &GomegaBasicInfo{}
- for {
- selector, ok := expr.Fun.(*ast.SelectorExpr)
- if !ok {
- return nil, false
- }
-
- if selector.Sel.Name == "Error" {
- info.HasErrorMethod = true
- }
-
- switch x := selector.X.(type) {
- case *ast.Ident:
- if x.Name != g.name {
- if !g.isGomegaVar(x) {
- return nil, false
- }
- info.UseGomegaVar = true
- }
-
- info.MethodName = selector.Sel.Name
-
- return info, true
-
- case *ast.CallExpr:
- expr = x
-
- default:
- return nil, false
- }
- }
-}
-
-// ReplaceFunction replaces the function with another one, for fix suggestions
-func (nameHandler) ReplaceFunction(caller *ast.CallExpr, newExpr *ast.Ident) {
- caller.Fun.(*ast.SelectorExpr).Sel = newExpr
-}
-
-func (g nameHandler) isGomegaVar(x ast.Expr) bool {
- return gomegainfo.IsGomegaVar(x, g.pass)
-}
-
-func (g nameHandler) GetActualExpr(assertionFunc *ast.SelectorExpr) *ast.CallExpr {
- actualExpr, ok := assertionFunc.X.(*ast.CallExpr)
- if !ok {
- return nil
- }
-
- switch fun := actualExpr.Fun.(type) {
- case *ast.Ident:
- return actualExpr
- case *ast.SelectorExpr:
- if x, ok := fun.X.(*ast.Ident); ok && x.Name == g.name {
- return actualExpr
- }
- if gomegainfo.IsActualMethod(fun.Sel.Name) {
- if g.isGomegaVar(fun.X) {
- return actualExpr
- }
- } else {
- return g.GetActualExpr(fun)
- }
- }
- return nil
-}
-
-func (g nameHandler) GetActualExprClone(origFunc, funcClone *ast.SelectorExpr) *ast.CallExpr {
- actualExpr, ok := funcClone.X.(*ast.CallExpr)
- if !ok {
- return nil
- }
-
- switch funClone := actualExpr.Fun.(type) {
- case *ast.Ident:
- return actualExpr
- case *ast.SelectorExpr:
- if x, ok := funClone.X.(*ast.Ident); ok && x.Name == g.name {
- return actualExpr
- }
- origFun := origFunc.X.(*ast.CallExpr).Fun.(*ast.SelectorExpr)
- if gomegainfo.IsActualMethod(funClone.Sel.Name) {
- if g.isGomegaVar(origFun.X) {
- return actualExpr
- }
- } else {
- return g.GetActualExprClone(origFun, funClone)
- }
- }
-
- return nil
-}
-
-func (g nameHandler) GetNewWrapperMatcher(name string, existing *ast.CallExpr) *ast.CallExpr {
- return &ast.CallExpr{
- Fun: &ast.SelectorExpr{
- X: ast.NewIdent(g.name),
- Sel: ast.NewIdent(name),
- },
- Args: []ast.Expr{existing},
- }
-}
diff --git a/vendor/github.com/nunnatsa/ginkgolinter/internal/gomegainfo/gomegainfo.go b/vendor/github.com/nunnatsa/ginkgolinter/internal/gomegainfo/gomegainfo.go
index 93be55ec0..c773d055e 100644
--- a/vendor/github.com/nunnatsa/ginkgolinter/internal/gomegainfo/gomegainfo.go
+++ b/vendor/github.com/nunnatsa/ginkgolinter/internal/gomegainfo/gomegainfo.go
@@ -36,15 +36,11 @@ var funcOffsetMap = map[string]int{
consistentlyWithOffset: 1,
}
-func IsActualMethod(name string) bool {
- _, found := funcOffsetMap[name]
- return found
-}
-
func ActualArgOffset(methodName string) int {
funcOffset, ok := funcOffsetMap[methodName]
if !ok {
- return -1
+ // Assume first argument for unknown methods.
+ return 0
}
return funcOffset
}
@@ -61,22 +57,11 @@ func GetAllowedAssertionMethods(actualMethodName string) string {
return `"Should()", "To()", "ShouldNot()", "ToNot()" or "NotTo()"`
default:
- return ""
+ // Unknown wrapper or missing method name, mention all options.
+ return `one of "To/NotTo/ToNot" (for Expect assertions) or "Should/ShouldNot" (for Eventually/Consistently assertions)`
}
}
-var asyncFuncSet = map[string]struct{}{
- eventually: {},
- eventuallyWithOffset: {},
- consistently: {},
- consistentlyWithOffset: {},
-}
-
-func IsAsyncActualMethod(name string) bool {
- _, ok := asyncFuncSet[name]
- return ok
-}
-
func IsAssertionFunc(name string) bool {
switch name {
case to, toNot, notTo, should, shouldNot:
diff --git a/vendor/github.com/nunnatsa/ginkgolinter/internal/intervals/intervals.go b/vendor/github.com/nunnatsa/ginkgolinter/internal/intervals/intervals.go
index 51d55166d..868fb83ad 100644
--- a/vendor/github.com/nunnatsa/ginkgolinter/internal/intervals/intervals.go
+++ b/vendor/github.com/nunnatsa/ginkgolinter/internal/intervals/intervals.go
@@ -5,6 +5,7 @@ import (
"go/constant"
"go/token"
gotypes "go/types"
+ "strconv"
"time"
"golang.org/x/tools/go/analysis"
@@ -33,11 +34,12 @@ func GetDuration(pass *analysis.Pass, argOffset int, origInterval, intervalClone
if basic.Info()&gotypes.IsInteger != 0 {
if num, ok := constant.Int64Val(tv.Value); ok {
return &NumericDurationValue{
- timePkg: timePkg,
- numSeconds: num,
- offset: argOffset,
- dur: time.Duration(num) * time.Second,
- expr: intervalClone,
+ timePkg: timePkg,
+ numSeconds: num,
+ offset: argOffset,
+ dur: time.Duration(num) * time.Second,
+ expr: intervalClone,
+ useOrigExpr: tv.Type.String() == "int",
}
}
}
@@ -45,14 +47,33 @@ func GetDuration(pass *analysis.Pass, argOffset int, origInterval, intervalClone
if basic.Info()&gotypes.IsFloat != 0 {
if num, ok := constant.Float64Val(tv.Value); ok {
return &NumericDurationValue{
- timePkg: timePkg,
- numSeconds: int64(num),
- offset: argOffset,
- dur: time.Duration(num) * time.Second,
- expr: intervalClone,
+ timePkg: timePkg,
+ numSeconds: int64(num),
+ offset: argOffset,
+ dur: time.Duration(num) * time.Second,
+ expr: intervalClone,
+ useOrigExpr: false,
}
}
}
+
+ if basic.Info()&gotypes.IsString != 0 {
+ val, err := strconv.Unquote(tv.Value.ExactString())
+ if err != nil {
+ val = tv.Value.String()
+ }
+ duration, err := time.ParseDuration(val)
+ if err != nil {
+ return &UnknownDurationValue{expr: intervalClone}
+ }
+
+ return &StringDurationValue{
+ timePkg: timePkg,
+ dur: duration,
+ expr: intervalClone,
+ offset: argOffset,
+ }
+ }
}
return &UnknownDurationValue{expr: intervalClone}
@@ -90,11 +111,12 @@ func (r RealDurationValue) Duration() time.Duration {
}
type NumericDurationValue struct {
- timePkg string
- numSeconds int64
- offset int
- dur time.Duration
- expr ast.Expr
+ timePkg string
+ numSeconds int64
+ offset int
+ dur time.Duration
+ expr ast.Expr
+ useOrigExpr bool
}
func (r *NumericDurationValue) Duration() time.Duration {
@@ -107,9 +129,13 @@ func (r *NumericDurationValue) GetOffset() int {
func (r *NumericDurationValue) GetDurationExpr() ast.Expr {
var newArg ast.Expr
- second := &ast.SelectorExpr{
- Sel: ast.NewIdent("Second"),
- X: ast.NewIdent(r.timePkg),
+ second := getUnit(r.timePkg, "Second")
+
+ var y ast.Expr
+ if r.useOrigExpr {
+ y = r.expr
+ } else {
+ y = &ast.BasicLit{Value: strconv.Itoa(int(r.numSeconds)), Kind: token.INT}
}
if r.numSeconds == 1 {
@@ -118,7 +144,7 @@ func (r *NumericDurationValue) GetDurationExpr() ast.Expr {
newArg = &ast.BinaryExpr{
X: second,
Op: token.MUL,
- Y: r.expr,
+ Y: y,
}
}
@@ -134,8 +160,9 @@ func (r UnknownDurationValue) Duration() time.Duration {
}
type UnknownNumericValue struct {
- expr ast.Expr
- offset int
+ expr ast.Expr
+ offset int
+ timePkg string
}
func (r UnknownNumericValue) Duration() time.Duration {
@@ -144,10 +171,7 @@ func (r UnknownNumericValue) Duration() time.Duration {
func (r UnknownNumericValue) GetDurationExpr() ast.Expr {
return &ast.BinaryExpr{
- X: &ast.SelectorExpr{
- Sel: ast.NewIdent("Second"),
- X: ast.NewIdent("time"),
- },
+ X: getUnit(r.timePkg, "Second"),
Op: token.MUL,
Y: r.expr,
}
@@ -164,3 +188,133 @@ type UnknownDurationTypeValue struct {
func (r UnknownDurationTypeValue) Duration() time.Duration {
return 0
}
+
+type StringDurationValue struct {
+ timePkg string
+ dur time.Duration
+ expr ast.Expr
+ offset int
+}
+
+func (r StringDurationValue) Duration() time.Duration {
+ return r.dur
+}
+
+func (r StringDurationValue) GetOffset() int {
+ return r.offset
+}
+
+func (r StringDurationValue) GetDurationExpr() ast.Expr {
+ return durationToExpr(r.dur, r.timePkg)
+}
+
+func durationToExpr(duration time.Duration, timePkg string) ast.Expr {
+ var durationExpr ast.Expr
+
+ if duration >= time.Hour {
+ hours := duration / time.Hour
+ duration -= hours * time.Hour
+ durationExpr = getDurationExpression("Hour", timePkg, hours)
+ }
+
+ if duration >= time.Minute {
+ minutes := duration / time.Minute
+ duration -= minutes * time.Minute
+ minExp := getDurationExpression("Minute", timePkg, minutes)
+
+ if durationExpr == nil {
+ durationExpr = minExp
+ } else {
+ durationExpr = &ast.BinaryExpr{
+ X: durationExpr,
+ Op: token.ADD,
+ Y: minExp,
+ }
+ }
+ }
+
+ if duration >= time.Second {
+ seconds := duration / time.Second
+ duration -= seconds * time.Second
+ secExpr := getDurationExpression("Second", timePkg, seconds)
+
+ if durationExpr == nil {
+ durationExpr = secExpr
+ } else {
+ durationExpr = &ast.BinaryExpr{
+ X: durationExpr,
+ Op: token.ADD,
+ Y: secExpr,
+ }
+ }
+ }
+
+ if duration >= time.Millisecond {
+ milliseconds := duration / time.Millisecond
+ duration -= milliseconds * time.Millisecond
+ millisecondsExpr := getDurationExpression("Millisecond", timePkg, milliseconds)
+
+ if durationExpr == nil {
+ durationExpr = millisecondsExpr
+ } else {
+ durationExpr = &ast.BinaryExpr{
+ X: durationExpr,
+ Op: token.ADD,
+ Y: millisecondsExpr,
+ }
+ }
+ }
+
+ if duration >= time.Microsecond {
+ microseconds := duration / time.Microsecond
+ duration -= microseconds * time.Microsecond
+ microsecondsExpr := getDurationExpression("Microsecond", timePkg, microseconds)
+
+ if durationExpr == nil {
+ durationExpr = microsecondsExpr
+ } else {
+ durationExpr = &ast.BinaryExpr{
+ X: durationExpr,
+ Op: token.ADD,
+ Y: microsecondsExpr,
+ }
+ }
+ }
+
+ if duration > 0 {
+ nanosecondsExpr := getDurationExpression("Nanosecond", timePkg, duration)
+
+ if durationExpr == nil {
+ durationExpr = nanosecondsExpr
+ } else {
+ durationExpr = &ast.BinaryExpr{
+ X: durationExpr,
+ Op: token.ADD,
+ Y: nanosecondsExpr,
+ }
+ }
+ }
+
+ return durationExpr
+}
+
+func getDurationExpression(unitName, timePkg string, amount time.Duration) ast.Expr {
+ unit := getUnit(timePkg, unitName)
+
+ if amount == 1 {
+ return unit
+ }
+
+ return &ast.BinaryExpr{
+ X: unit,
+ Op: token.MUL,
+ Y: &ast.BasicLit{Value: strconv.FormatInt(int64(amount), 10), Kind: token.INT},
+ }
+}
+
+func getUnit(timePkg, unitName string) ast.Expr {
+ return &ast.SelectorExpr{
+ X: ast.NewIdent(timePkg),
+ Sel: ast.NewIdent(unitName),
+ }
+}
diff --git a/vendor/github.com/nunnatsa/ginkgolinter/internal/rules/asyncsucceedrule.go b/vendor/github.com/nunnatsa/ginkgolinter/internal/rules/asyncsucceedrule.go
index e1d68b0dc..71cb88172 100644
--- a/vendor/github.com/nunnatsa/ginkgolinter/internal/rules/asyncsucceedrule.go
+++ b/vendor/github.com/nunnatsa/ginkgolinter/internal/rules/asyncsucceedrule.go
@@ -17,7 +17,7 @@ func (AsyncSucceedRule) isApply(gexp *expression.GomegaExpression) bool {
return gexp.IsAsync() &&
gexp.MatcherTypeIs(matcher.SucceedMatcherType) &&
gexp.ActualArgTypeIs(actual.FuncSigArgType) &&
- !gexp.ActualArgTypeIs(actual.ErrorTypeArgType|actual.GomegaParamArgType)
+ !gexp.ActualArgTypeIs(actual.ErrorTypeArgType|actual.GomegaParamArgType|actual.TBParamArgType)
}
func (r AsyncSucceedRule) Apply(gexp *expression.GomegaExpression, _ config.Config, reportBuilder *reports.Builder) bool {
@@ -25,6 +25,9 @@ func (r AsyncSucceedRule) Apply(gexp *expression.GomegaExpression, _ config.Conf
if gexp.ActualArgTypeIs(actual.MultiRetsArgType) {
reportBuilder.AddIssue(false, "Success matcher does not support multiple values")
} else {
+ // The message intentionally does not call out "function with a TB implementation" as another alternative because
+ // that alternative is not valid for generic Gomega - it would be confusing for many users. Users
+ // of a Gomega wrapper which supports such functions must figure that out themselves.
reportBuilder.AddIssue(false, "Success matcher only support a single error value, or function with Gomega as its first parameter")
}
}
diff --git a/vendor/github.com/nunnatsa/ginkgolinter/internal/rules/asynctimeintervalsrule.go b/vendor/github.com/nunnatsa/ginkgolinter/internal/rules/asynctimeintervalsrule.go
index ffac8bc13..309f12aa7 100644
--- a/vendor/github.com/nunnatsa/ginkgolinter/internal/rules/asynctimeintervalsrule.go
+++ b/vendor/github.com/nunnatsa/ginkgolinter/internal/rules/asynctimeintervalsrule.go
@@ -80,7 +80,7 @@ func checkInterval(gexp *expression.GomegaExpression, durVal intervals.DurationV
switch to := durVal.(type) {
case *intervals.RealDurationValue, *intervals.UnknownDurationTypeValue:
- case *intervals.NumericDurationValue:
+ case *intervals.NumericDurationValue, *intervals.StringDurationValue:
if checkNumericInterval(gexp.GetActualClone(), to) {
reportBuilder.AddIssue(true, onlyUseTimeDurationForInterval)
}
diff --git a/vendor/github.com/nunnatsa/ginkgolinter/internal/rules/missingassertionrule.go b/vendor/github.com/nunnatsa/ginkgolinter/internal/rules/missingassertionrule.go
index e96ac2902..8857d8f34 100644
--- a/vendor/github.com/nunnatsa/ginkgolinter/internal/rules/missingassertionrule.go
+++ b/vendor/github.com/nunnatsa/ginkgolinter/internal/rules/missingassertionrule.go
@@ -9,12 +9,6 @@ import (
const missingAssertionMessage = `%q: missing assertion method. Expected %s`
-type MissingAssertionRule struct{}
-
-func (r MissingAssertionRule) isApplied(gexp *expression.GomegaExpression) bool {
- return gexp.IsMissingAssertion()
-}
-
// MissingAssertionRule checks if the assertion method is missing. In this case, the test does not make any assertion.
// This is mostly relevant for the async actual methods, that tend to be longer, and so harder to spot the missing assertion
// by just reading the test code.
@@ -32,6 +26,12 @@ func (r MissingAssertionRule) isApplied(gexp *expression.GomegaExpression) bool
// Eventually(func() error {
// return nil
// }).Should(Succeed())
+type MissingAssertionRule struct{}
+
+func (r MissingAssertionRule) isApplied(gexp *expression.GomegaExpression) bool {
+ return gexp.IsMissingAssertion()
+}
+
func (r MissingAssertionRule) Apply(gexp *expression.GomegaExpression, _ config.Config, reportBuilder *reports.Builder) bool {
if !r.isApplied(gexp) {
return false
diff --git a/vendor/github.com/nunnatsa/ginkgolinter/internal/typecheck/interfaces.go b/vendor/github.com/nunnatsa/ginkgolinter/internal/typecheck/interfaces.go
index 34ad44753..8c51faa4c 100644
--- a/vendor/github.com/nunnatsa/ginkgolinter/internal/typecheck/interfaces.go
+++ b/vendor/github.com/nunnatsa/ginkgolinter/internal/typecheck/interfaces.go
@@ -8,6 +8,16 @@ import (
var (
errorType *gotypes.Interface
gomegaMatcherType *gotypes.Interface
+ tbTypes = []*gotypes.Interface{
+ // In practice, interfaces which mimick testing.TB probably implement
+ // more than one of these at the same time. But for ImplementsTB
+ // it's sufficient to have just one method which can be used
+ // to report a test failure.
+ tbInterface("Error", false),
+ tbInterface("Errorf", true),
+ tbInterface("Fatal", false),
+ tbInterface("Fatalf", true),
+ }
)
func init() {
@@ -76,3 +86,32 @@ func ImplementsError(t gotypes.Type) bool {
func ImplementsGomegaMatcher(t gotypes.Type) bool {
return t != nil && gotypes.Implements(t, gomegaMatcherType)
}
+
+// ImplementsTB checks if the argument type implements any of the methods in testing.TB which
+// can be used to report test failures. Such a type is a potential alternative to a Gomega
+// parameter in some Gomega wrappers.
+func ImplementsTB(t gotypes.Type) bool {
+ for _, tbType := range tbTypes {
+ if gotypes.Implements(t, tbType) {
+ return true
+ }
+ }
+ return false
+}
+
+// tbInterface generates an interface type with exactly one method
+// which has the given name and Printf or Println signature.
+func tbInterface(name string, printf bool) *gotypes.Interface {
+ var params []*gotypes.Var
+ if printf {
+ params = append(params, gotypes.NewVar(0, nil, "", gotypes.Typ[gotypes.String]))
+ }
+ params = append(params, gotypes.NewVar(0, nil, "", gotypes.NewSlice(gotypes.Universe.Lookup("any").Type())))
+ signature := gotypes.NewSignatureType(nil, nil, nil,
+ gotypes.NewTuple(params...),
+ gotypes.NewTuple(),
+ true,
+ )
+ method := gotypes.NewFunc(0, nil, name, signature)
+ return gotypes.NewInterfaceType([]*gotypes.Func{method}, nil)
+}
diff --git a/vendor/github.com/nunnatsa/ginkgolinter/linter/ginkgo_linter.go b/vendor/github.com/nunnatsa/ginkgolinter/linter/ginkgo_linter.go
index fefb8d63e..338262e1a 100644
--- a/vendor/github.com/nunnatsa/ginkgolinter/linter/ginkgo_linter.go
+++ b/vendor/github.com/nunnatsa/ginkgolinter/linter/ginkgo_linter.go
@@ -41,7 +41,8 @@ func (l *GinkgoLinter) Run(pass *analysis.Pass) (any, error) {
gomegaHndlr := gomegahandler.GetGomegaHandler(file, pass)
ginkgoHndlr := ginkgohandler.GetGinkgoHandler(file)
- if gomegaHndlr == nil && ginkgoHndlr == nil { // no gomega or ginkgo imports => no use in gomega in this file; nothing to do here
+ if gomegaHndlr == nil && ginkgoHndlr == nil {
+ // no gomega or ginkgo imports or dependencies => no use in gomega in this file; nothing to do here
continue
}
@@ -86,8 +87,8 @@ func (l *GinkgoLinter) Run(pass *analysis.Pass) (any, error) {
return true
}
- gexp, ok := expression.New(assertionExp, pass, gomegaHndlr, getTimePkg(file))
- if !ok || gexp == nil {
+ gexp := expression.New(assertionExp, pass, gomegaHndlr, getTimePkg(file))
+ if gexp == nil {
return true
}
diff --git a/vendor/github.com/onsi/ginkgo/v2/.gitignore b/vendor/github.com/onsi/ginkgo/v2/.gitignore
index 6faaaf315..c9f054620 100644
--- a/vendor/github.com/onsi/ginkgo/v2/.gitignore
+++ b/vendor/github.com/onsi/ginkgo/v2/.gitignore
@@ -1,6 +1,7 @@
.DS_Store
TODO
tmp/**/*
+integration/tmp_*/
*.coverprofile
.vscode
.idea/
diff --git a/vendor/github.com/onsi/ginkgo/v2/CHANGELOG.md b/vendor/github.com/onsi/ginkgo/v2/CHANGELOG.md
index 69be62380..4d1ed9523 100644
--- a/vendor/github.com/onsi/ginkgo/v2/CHANGELOG.md
+++ b/vendor/github.com/onsi/ginkgo/v2/CHANGELOG.md
@@ -1,3 +1,80 @@
+## 2.32.1
+
+### Fixes
+- Defer AfterAll until repeated spec completes [e647b3b]
+
+## 2.32.0
+
+`-fd` generate RSpec-style documentation output. Thank @woodie !
+--sleep-on-failure pauses a failed spec before teardown. Thanks @qinqon !
+
+## 2.31.0
+
+Add a bunch of Claude Skills via the marketplace:
+
+```
+/plugin marketplace add onsi/ginkgo
+/plugin install ginkgo@ginkgo
+```
+
+## 2.30.0
+
+### Features
+Ginkgo now allows `extentions/global.Reset` to support running multiple suites from within a single process. This may take some massaging on your part (see [1672](https://github.com/onsi/ginkgo/issues/1672)) but can dramatically speed up codebases with O(hundreds) of test suites.
+
+Thanks @lawrencejones !
+
+### Fixes
+
+- Fix nested --github-output group for progress report nested inside timeline [4f62d7a]
+
+## 2.29.0
+
+`GinkgoHelperGo` makes it easier to write test helpers that need to run in goroutines. Specifically, it makes managing the failure state and capturing failure panics correctly straightforward.
+
+`ginkgo outline` now includes entries defined in `DescribeTableSubtree`
+
+## 2.28.3
+
+### Maintenance
+Bump all dependencies
+
+## 2.28.2
+
+- Add ArtifactDir() to support Go 1.26 testing.TB interface [f3a36b6]
+- Implement shell completion [94151c8]
+- Add asan CLI option mirroring msan implementation [4d21dbb]
+- Bump uri from 1.0.3 to 1.0.4 in /docs (#1630) [c102161]
+- fix aspect ratio [9619647]
+- update logos [5779304]
+
+## 2.28.1
+
+Update all dependencies. This auto-updated the required version of Go to 1.24, consistent with the fact that Go 1.23 has been out of support for almost six months.
+
+## 2.28.0
+
+Ginkgo's SemVer filter now supports filtering multiple components by SemVer version:
+
+```go
+It("should work in a specific version range (1.0.0, 2.0.0) and third-party dependency redis in [8.0.0, ~)", SemVerConstraint(">= 3.2.0"), ComponentSemVerConstraint("redis", ">= 8.0.0") func() {
+ // This test will only run when version is between 1.0.0 (exclusive) and 2.0.0 (exclusive) and redis version is >= 8.0.0
+})
+```
+
+can be filtered in or out with an invocation like:
+
+```bash
+ginkgo --sem-ver-filter="2.1.1, redis=8.2.0"
+```
+
+Huge thanks to @Icarus9913 for working on this!
+
+## 2.27.5
+
+### Fixes
+Don't make a new formatter for each GinkgoT(); that's just silly and uses precious memory
+
## 2.27.4
### Fixes
diff --git a/vendor/github.com/onsi/ginkgo/v2/README.md b/vendor/github.com/onsi/ginkgo/v2/README.md
index 7b7ab9e39..ad5e45f67 100644
--- a/vendor/github.com/onsi/ginkgo/v2/README.md
+++ b/vendor/github.com/onsi/ginkgo/v2/README.md
@@ -106,6 +106,19 @@ And that's just Ginkgo! [Gomega](https://onsi.github.io/gomega/) brings a rich,
Happy Testing!
+## Using Ginkgo with Claude Code
+
+Ginkgo ships a set of [Claude Code](https://claude.com/claude-code) skills as a plugin, with this repo doubling as the marketplace, so an agent writing specs in *your* project has Ginkgo's idioms, decorators, and gotchas on hand. From inside Claude Code:
+
+```
+/plugin marketplace add onsi/ginkgo
+/plugin install ginkgo@ginkgo
+```
+
+(or non-interactively: `claude plugin marketplace add onsi/ginkgo` then `claude plugin install ginkgo@ginkgo`)
+
+This installs a family of `ginkgo:*` skills that activate automatically while you write and run specs. Start with `ginkgo:overview`; see the [plugin README](plugins/ginkgo/README.md) for the full list.
+
## License
Ginkgo is MIT-Licensed
@@ -119,7 +132,7 @@ See [CONTRIBUTING.md](CONTRIBUTING.md)
Sponsors commit to a [sponsorship](https://github.com/sponsors/onsi) for a year. If you're an organization that makes use of Ginkgo please consider becoming a sponsor!
Browser testing via
-
-
+
+
diff --git a/vendor/github.com/onsi/ginkgo/v2/core_dsl.go b/vendor/github.com/onsi/ginkgo/v2/core_dsl.go
index 7e165e473..fb5761c1f 100644
--- a/vendor/github.com/onsi/ginkgo/v2/core_dsl.go
+++ b/vendor/github.com/onsi/ginkgo/v2/core_dsl.go
@@ -20,6 +20,7 @@ import (
"io"
"os"
"path/filepath"
+ "slices"
"strings"
"github.com/go-logr/logr"
@@ -38,7 +39,6 @@ var flagSet types.GinkgoFlagSet
var deprecationTracker = types.NewDeprecationTracker()
var suiteConfig = types.NewDefaultSuiteConfig()
var reporterConfig = types.NewDefaultReporterConfig()
-var suiteDidRun = false
var outputInterceptor internal.OutputInterceptor
var client parallel_support.Client
@@ -258,17 +258,17 @@ for more on how specs are parallelized in Ginkgo.
You can also pass suite-level Label() decorators to RunSpecs. The passed-in labels will apply to all specs in the suite.
*/
func RunSpecs(t GinkgoTestingT, description string, args ...any) bool {
- if suiteDidRun {
+ if global.SuiteDidRun {
exitIfErr(types.GinkgoErrors.RerunningSuite())
}
- suiteDidRun = true
+ global.SuiteDidRun = true
err := global.PushClone()
if err != nil {
exitIfErr(err)
}
defer global.PopClone()
- suiteLabels, suiteSemVerConstraints, suiteAroundNodes := extractSuiteConfiguration(args)
+ suiteLabels, suiteSemVerConstraints, suiteComponentSemVerConstraints, suiteAroundNodes := extractSuiteConfiguration(args)
var reporter reporters.Reporter
if suiteConfig.ParallelTotal == 1 {
@@ -311,7 +311,7 @@ func RunSpecs(t GinkgoTestingT, description string, args ...any) bool {
suitePath, err = filepath.Abs(suitePath)
exitIfErr(err)
- passed, hasFocusedTests := global.Suite.Run(description, suiteLabels, suiteSemVerConstraints, suiteAroundNodes, suitePath, global.Failer, reporter, writer, outputInterceptor, interrupt_handler.NewInterruptHandler(client), client, internal.RegisterForProgressSignal, suiteConfig)
+ passed, hasFocusedTests := global.Suite.Run(description, suiteLabels, suiteSemVerConstraints, suiteComponentSemVerConstraints, suiteAroundNodes, suitePath, global.Failer, reporter, writer, outputInterceptor, interrupt_handler.NewInterruptHandler(client), client, internal.RegisterForProgressSignal, suiteConfig)
outputInterceptor.Shutdown()
flagSet.ValidateDeprecations(deprecationTracker)
@@ -330,9 +330,10 @@ func RunSpecs(t GinkgoTestingT, description string, args ...any) bool {
return passed
}
-func extractSuiteConfiguration(args []any) (Labels, SemVerConstraints, types.AroundNodes) {
+func extractSuiteConfiguration(args []any) (Labels, SemVerConstraints, ComponentSemVerConstraints, types.AroundNodes) {
suiteLabels := Labels{}
suiteSemVerConstraints := SemVerConstraints{}
+ suiteComponentSemVerConstraints := ComponentSemVerConstraints{}
aroundNodes := types.AroundNodes{}
configErrors := []error{}
for _, arg := range args {
@@ -345,6 +346,11 @@ func extractSuiteConfiguration(args []any) (Labels, SemVerConstraints, types.Aro
suiteLabels = append(suiteLabels, arg...)
case SemVerConstraints:
suiteSemVerConstraints = append(suiteSemVerConstraints, arg...)
+ case ComponentSemVerConstraints:
+ for component, constraints := range arg {
+ suiteComponentSemVerConstraints[component] = append(suiteComponentSemVerConstraints[component], constraints...)
+ suiteComponentSemVerConstraints[component] = slices.Compact(suiteComponentSemVerConstraints[component])
+ }
case types.AroundNodeDecorator:
aroundNodes = append(aroundNodes, arg)
default:
@@ -355,14 +361,14 @@ func extractSuiteConfiguration(args []any) (Labels, SemVerConstraints, types.Aro
configErrors = types.VetConfig(flagSet, suiteConfig, reporterConfig)
if len(configErrors) > 0 {
- fmt.Fprintf(formatter.ColorableStdErr, formatter.F("{{red}}Ginkgo detected configuration issues:{{/}}\n"))
+ fmt.Fprint(formatter.ColorableStdErr, formatter.F("{{red}}Ginkgo detected configuration issues:{{/}}\n"))
for _, err := range configErrors {
- fmt.Fprintf(formatter.ColorableStdErr, err.Error())
+ fmt.Fprint(formatter.ColorableStdErr, err.Error())
}
os.Exit(1)
}
- return suiteLabels, suiteSemVerConstraints, aroundNodes
+ return suiteLabels, suiteSemVerConstraints, suiteComponentSemVerConstraints, aroundNodes
}
func getwd() (string, error) {
@@ -385,7 +391,7 @@ func PreviewSpecs(description string, args ...any) Report {
}
defer global.PopClone()
- suiteLabels, suiteSemVerConstraints, suiteAroundNodes := extractSuiteConfiguration(args)
+ suiteLabels, suiteSemVerConstraints, suiteComponentSemVerConstraints, suiteAroundNodes := extractSuiteConfiguration(args)
priorDryRun, priorParallelTotal, priorParallelProcess := suiteConfig.DryRun, suiteConfig.ParallelTotal, suiteConfig.ParallelProcess
suiteConfig.DryRun, suiteConfig.ParallelTotal, suiteConfig.ParallelProcess = true, 1, 1
defer func() {
@@ -403,7 +409,7 @@ func PreviewSpecs(description string, args ...any) Report {
suitePath, err = filepath.Abs(suitePath)
exitIfErr(err)
- global.Suite.Run(description, suiteLabels, suiteSemVerConstraints, suiteAroundNodes, suitePath, global.Failer, reporter, writer, outputInterceptor, interrupt_handler.NewInterruptHandler(client), client, internal.RegisterForProgressSignal, suiteConfig)
+ global.Suite.Run(description, suiteLabels, suiteSemVerConstraints, suiteComponentSemVerConstraints, suiteAroundNodes, suitePath, global.Failer, reporter, writer, outputInterceptor, interrupt_handler.NewInterruptHandler(client), client, internal.RegisterForProgressSignal, suiteConfig)
return global.Suite.GetPreviewReport()
}
diff --git a/vendor/github.com/onsi/ginkgo/v2/decorator_dsl.go b/vendor/github.com/onsi/ginkgo/v2/decorator_dsl.go
index e331d7cf8..ce1d71cec 100644
--- a/vendor/github.com/onsi/ginkgo/v2/decorator_dsl.go
+++ b/vendor/github.com/onsi/ginkgo/v2/decorator_dsl.go
@@ -117,6 +117,27 @@ You can learn more here: https://onsi.github.io/ginkgo/#spec-semantic-version-fi
*/
type SemVerConstraints = internal.SemVerConstraints
+/*
+ComponentSemVerConstraint decorates specs with ComponentSemVerConstraints. Multiple components semantic version constraints can be passed to ComponentSemVerConstraint and the component can't be empy, also the version strings must follow the semantic version constraint rules.
+ComponentSemVerConstraints can be applied to container and subject nodes, but not setup nodes. You can provide multiple ComponentSemVerConstraints to a given node and a spec's component semantic version constraints is the union of all component semantic version constraints in its node hierarchy.
+
+You can learn more here: https://onsi.github.io/ginkgo/#spec-semantic-version-filtering
+You can learn more about decorators here: https://onsi.github.io/ginkgo/#decorator-reference
+*/
+func ComponentSemVerConstraint(component string, semVerConstraints ...string) ComponentSemVerConstraints {
+ componentSemVerConstraints := ComponentSemVerConstraints{
+ component: semVerConstraints,
+ }
+
+ return componentSemVerConstraints
+}
+
+/*
+ComponentSemVerConstraints are the type for spec ComponentSemVerConstraint decorators. Use ComponentSemVerConstraint(...) to construct ComponentSemVerConstraints.
+You can learn more here: https://onsi.github.io/ginkgo/#spec-semantic-version-filtering
+*/
+type ComponentSemVerConstraints = internal.ComponentSemVerConstraints
+
/*
PollProgressAfter allows you to override the configured value for --poll-progress-after for a particular node.
diff --git a/vendor/github.com/onsi/ginkgo/v2/ginkgo/command/command.go b/vendor/github.com/onsi/ginkgo/v2/ginkgo/command/command.go
index 79b83a3af..a30a2ecc9 100644
--- a/vendor/github.com/onsi/ginkgo/v2/ginkgo/command/command.go
+++ b/vendor/github.com/onsi/ginkgo/v2/ginkgo/command/command.go
@@ -22,11 +22,11 @@ type Command struct {
func (c Command) Run(args []string, additionalArgs []string) {
args, err := c.Flags.Parse(args)
if err != nil {
- AbortWithUsage(err.Error())
+ AbortWithUsage("%s", err.Error())
}
for _, arg := range args {
if len(arg) > 1 && strings.HasPrefix(arg, "-") {
- AbortWith(types.GinkgoErrors.FlagAfterPositionalParameter().Error())
+ AbortWith("%s", types.GinkgoErrors.FlagAfterPositionalParameter().Error())
}
}
c.Command(args, additionalArgs)
@@ -49,6 +49,6 @@ func (c Command) EmitUsage(writer io.Writer) {
}
flagUsage := c.Flags.Usage()
if flagUsage != "" {
- fmt.Fprintf(writer, formatter.F(flagUsage))
+ fmt.Fprint(writer, formatter.F(flagUsage))
}
}
diff --git a/vendor/github.com/onsi/ginkgo/v2/ginkgo/command/program.go b/vendor/github.com/onsi/ginkgo/v2/ginkgo/command/program.go
index c3f6d3a11..53114904c 100644
--- a/vendor/github.com/onsi/ginkgo/v2/ginkgo/command/program.go
+++ b/vendor/github.com/onsi/ginkgo/v2/ginkgo/command/program.go
@@ -1,9 +1,13 @@
package command
import (
+ "bufio"
"fmt"
"io"
+ "maps"
"os"
+ "path/filepath"
+ "slices"
"strings"
"github.com/onsi/ginkgo/v2/formatter"
@@ -158,6 +162,166 @@ func (p Program) handleHelpRequestsAndExit(writer io.Writer, args []string) {
}
}
+type completionOptions = struct {
+ Complete bool
+ Install bool
+}
+
+func (p *Program) BuildCompletionCommand() Command {
+ opts := completionOptions{}
+ flags, err := types.NewGinkgoFlagSet(
+ types.GinkgoFlags{
+ {Name: "complete", KeyPath: "Complete", Usage: "Generate completion for arguments after --"},
+ {Name: "install", KeyPath: "Install", Usage: "Install shell completion script into $XDG_DATA_HOME, ~/.local/share"},
+ },
+ &opts,
+ types.GinkgoFlagSections{},
+ )
+ if err != nil {
+ panic(err)
+ }
+ return Command{
+ Name: "completion",
+ Usage: "ginkgo completion [-- ]",
+ Flags: flags,
+ ShortDoc: "Generate shell completion",
+ Documentation: `To use install completion script for your shell (bash, fish, zsh).
+Or load completion code by: {{bold}}source <(ginkgo completion ){{/}}.`,
+ Command: func(args []string, completeArgs []string) {
+ p.handleCompletionAndExit(args, completeArgs, opts)
+ },
+ }
+}
+
+func (p Program) generateShellCompletionScript(shell string) (scriptPath string, script string) {
+ switch shell {
+ case "bash":
+ scriptPath = fmt.Sprintf("bash-completion/completions/%s", p.Name)
+ script = fmt.Sprintf(`__%s_complete_bash() {
+ mapfile -t COMPREPLY < <("${COMP_WORDS[0]}" completion --complete bash -- "${COMP_WORDS[@]:1:COMP_CWORD}")
+}
+complete -o bashdefault -o default -F __%[1]s_complete_bash %[1]s
+`, p.Name)
+
+ case "fish":
+ scriptPath = fmt.Sprintf("fish/vendor_completions.d/%s.fish", p.Name)
+ script = fmt.Sprintf(`function __fish_%[1]s_complete
+ set -l args (commandline -opc) (commandline -ct)
+ set -e args[1]
+ %[1]s completion --complete fish -- $args
+end
+complete -c %[1]s -a "(__fish_%[1]s_complete)"
+`, p.Name)
+
+ case "zsh":
+ scriptPath = fmt.Sprintf("zsh/site-functions/_%s", p.Name)
+ script = fmt.Sprintf(`#compdef %[1]s
+_%[1]s() {
+ local -a completions
+ completions=(${(f)"$("${words[1]}" completion --complete zsh -- "${words[@]:1:$((CURRENT-1))}")"})
+ if (( ${#completions[@]} )); then
+ _describe 'completions' completions
+ else
+ _default
+ fi
+}
+compdef _%[1]s %[1]s
+if [ "$funcstack[1]" = "_%[1]s" ]; then
+ _%[1]s
+fi
+`, p.Name)
+
+ case "":
+ AbortWithUsage("Shell is not specified")
+ default:
+ AbortWith("Shell %q is not supported yet. Choose: bash, fish, zsh", shell)
+ }
+
+ return scriptPath, script
+}
+
+func (p Program) handleCompletionAndExit(args, completeArgs []string, opts completionOptions) {
+ writer := p.OutWriter
+ if writer == nil {
+ writer = os.Stdout
+ }
+ buffer := bufio.NewWriter(writer)
+ defer buffer.Flush()
+
+ var shell string
+ if len(args) > 0 {
+ shell = args[0]
+ }
+
+ if !opts.Complete {
+ scriptPath, script := p.generateShellCompletionScript(shell)
+ if opts.Install {
+ dataHomeDir := os.Getenv("XDG_DATA_HOME")
+ if dataHomeDir == "" {
+ userHomeDir, err := os.UserHomeDir()
+ AbortIfError("Failed to find home", err)
+ dataHomeDir = filepath.Join(userHomeDir, ".local/share")
+ }
+ scriptPath = filepath.Join(dataHomeDir, scriptPath)
+ fmt.Fprintf(buffer, "Installing completion script: %v\n", scriptPath)
+ err := os.WriteFile(scriptPath, []byte(script), 0644)
+ AbortIfError("Failed to install completion script", err)
+ } else {
+ buffer.Write([]byte(script))
+ }
+ Abort(AbortDetails{})
+ }
+
+ var lastArg string
+ var result map[string]string
+ if len(completeArgs) > 0 {
+ lastArg = completeArgs[len(completeArgs)-1]
+ }
+
+ if delim := slices.Index(completeArgs, "--"); delim >= 0 && delim != len(completeArgs)-1 {
+ // No completion for pass-through arguments after "--"
+ } else if len(lastArg) > 0 && lastArg[0] == '-' {
+ // Complete flags
+ cmd := &p.DefaultCommand
+ for i := range p.Commands {
+ if p.Commands[i].Name == completeArgs[0] {
+ cmd = &p.Commands[i]
+ break
+ }
+ }
+ result = cmd.Flags.Completion(lastArg)
+ } else if len(completeArgs) <= 1 {
+ // Complete commands
+ result = make(map[string]string, len(p.Commands)+1)
+ for _, cmd := range append(p.Commands, p.DefaultCommand) {
+ if strings.HasPrefix(cmd.Name, lastArg) {
+ result[cmd.Name] = cmd.Usage
+ }
+ }
+ }
+
+ width := 0
+ for suggest := range result {
+ width = max(width, len(suggest))
+ }
+
+ for _, suggest := range slices.Sorted(maps.Keys(result)) {
+ usage := result[suggest]
+ switch {
+ case shell == "bash" && usage != "" && len(result) > 1:
+ fmt.Fprintf(buffer, "%*s (%s)\n", -width-2, suggest, usage)
+ case shell == "fish":
+ fmt.Fprintf(buffer, "%s\t%s\n", suggest, usage)
+ case shell == "zsh":
+ fmt.Fprintf(buffer, "%s:%s\n", suggest, usage)
+ default:
+ fmt.Fprintln(buffer, suggest)
+ }
+ }
+
+ Abort(AbortDetails{})
+}
+
func (p Program) EmitUsage(writer io.Writer) {
fmt.Fprintln(writer, formatter.F(p.Heading))
fmt.Fprintln(writer, formatter.F("{{gray}}%s{{/}}", strings.Repeat("-", len(p.Heading))))
diff --git a/vendor/github.com/onsi/ginkgo/v2/ginkgo/internal/run.go b/vendor/github.com/onsi/ginkgo/v2/ginkgo/internal/run.go
index 48c69a1d8..68830d9ae 100644
--- a/vendor/github.com/onsi/ginkgo/v2/ginkgo/internal/run.go
+++ b/vendor/github.com/onsi/ginkgo/v2/ginkgo/internal/run.go
@@ -268,9 +268,9 @@ func runParallel(suite TestSuite, ginkgoConfig types.SuiteConfig, reporterConfig
fmt.Fprint(formatter.ColorableStdErr, formatter.Fiw(0, formatter.COLS, "This occurs if a parallel process exits before it reports its results to the Ginkgo CLI. The CLI will now print out all the stdout/stderr output it's collected from the running processes. However you may not see anything useful in these logs because the individual test processes usually intercept output to stdout/stderr in order to capture it in the spec reports.\n\nYou may want to try rerunning your test suite with {{light-gray}}--output-interceptor-mode=none{{/}} to see additional output here and debug your suite.\n"))
fmt.Fprintln(formatter.ColorableStdErr, " ")
for proc := 1; proc <= cliConfig.ComputedProcs(); proc++ {
- fmt.Fprintf(formatter.ColorableStdErr, formatter.F("{{bold}}Output from proc %d:{{/}}\n", proc))
+ fmt.Fprint(formatter.ColorableStdErr, formatter.F("{{bold}}Output from proc %d:{{/}}\n", proc))
fmt.Fprintln(os.Stderr, formatter.Fi(1, "%s", procOutput[proc-1].String()))
- fmt.Fprintf(formatter.ColorableStdErr, formatter.F("{{bold}}Exit result of proc %d:{{/}}\n", proc))
+ fmt.Fprint(formatter.ColorableStdErr, formatter.F("{{bold}}Exit result of proc %d:{{/}}\n", proc))
fmt.Fprintln(os.Stderr, formatter.Fi(1, "%s\n", procExitResult[proc-1]))
}
fmt.Fprintf(os.Stderr, "** End **")
diff --git a/vendor/github.com/onsi/ginkgo/v2/ginkgo/main.go b/vendor/github.com/onsi/ginkgo/v2/ginkgo/main.go
index 419589b48..596c210cf 100644
--- a/vendor/github.com/onsi/ginkgo/v2/ginkgo/main.go
+++ b/vendor/github.com/onsi/ginkgo/v2/ginkgo/main.go
@@ -41,6 +41,7 @@ func main() {
{Name: "nodot", Deprecation: types.Deprecations.Nodot()},
},
}
+ program.Commands = append(program.Commands, program.BuildCompletionCommand())
program.RunAndExit(os.Args)
}
diff --git a/vendor/github.com/onsi/ginkgo/v2/ginkgo/outline/ginkgo.go b/vendor/github.com/onsi/ginkgo/v2/ginkgo/outline/ginkgo.go
index 5d8d00bb1..c380bbf21 100644
--- a/vendor/github.com/onsi/ginkgo/v2/ginkgo/outline/ginkgo.go
+++ b/vendor/github.com/onsi/ginkgo/v2/ginkgo/outline/ginkgo.go
@@ -163,17 +163,17 @@ func ginkgoNodeFromCallExpr(fset *token.FileSet, ce *ast.CallExpr, ginkgoPackage
n.Text = textOrAltFromCallExpr(ce, undefinedTextAlt)
n.Labels = labelFromCallExpr(ce)
return &n, ginkgoPackageName != nil && *ginkgoPackageName == packageName
- case "Context", "Describe", "When", "DescribeTable":
+ case "Context", "Describe", "When", "DescribeTable", "DescribeTableSubtree":
n.Text = textOrAltFromCallExpr(ce, undefinedTextAlt)
n.Labels = labelFromCallExpr(ce)
n.Pending = pendingFromCallExpr(ce)
return &n, ginkgoPackageName != nil && *ginkgoPackageName == packageName
- case "FContext", "FDescribe", "FWhen", "FDescribeTable":
+ case "FContext", "FDescribe", "FWhen", "FDescribeTable", "FDescribeTableSubtree":
n.Focused = true
n.Text = textOrAltFromCallExpr(ce, undefinedTextAlt)
n.Labels = labelFromCallExpr(ce)
return &n, ginkgoPackageName != nil && *ginkgoPackageName == packageName
- case "PContext", "PDescribe", "PWhen", "XContext", "XDescribe", "XWhen", "PDescribeTable", "XDescribeTable":
+ case "PContext", "PDescribe", "PWhen", "XContext", "XDescribe", "XWhen", "PDescribeTable", "XDescribeTable", "PDescribeTableSubtree", "XDescribeTableSubtree":
n.Pending = true
n.Text = textOrAltFromCallExpr(ce, undefinedTextAlt)
n.Labels = labelFromCallExpr(ce)
diff --git a/vendor/github.com/onsi/ginkgo/v2/ginkgo/outline/outline.go b/vendor/github.com/onsi/ginkgo/v2/ginkgo/outline/outline.go
index e99d557d1..206043f1d 100644
--- a/vendor/github.com/onsi/ginkgo/v2/ginkgo/outline/outline.go
+++ b/vendor/github.com/onsi/ginkgo/v2/ginkgo/outline/outline.go
@@ -54,6 +54,7 @@ func FromASTFile(fset *token.FileSet, src *ast.File) (*outline, error) {
// Node is not a Ginkgo spec or container, so it was not pushed onto the stack, continue
return true
}
+ expandSubtree(lastVisitedGinkgoNode)
stack = stack[0 : len(stack)-1]
return true
})
@@ -128,3 +129,29 @@ func (o *outline) StringIndent(width int) string {
return b.String()
}
+
+// expandSubtree restructures a DescribeTableSubtree node so that each Entry
+// child gets a copy of the subtree's spec nodes as its children. This mirrors
+// the runtime behavior where each Entry generates a container with the specs
+// defined in the DescribeTableSubtree body.
+func expandSubtree(gn *ginkgoNode) {
+ if !strings.Contains(gn.Name, "DescribeTableSubtree") {
+ return
+ }
+ subNodes, entries := splitSubtreeSubnodes(gn.Nodes)
+ gn.Nodes = entries
+ for _, entry := range entries {
+ entry.Nodes = subNodes
+ }
+}
+
+// splitSubtreeSubnodes splits the child nodes of a DescribeTableSubtree into
+// spec/container nodes (defined in the body) and Entry nodes.
+func splitSubtreeSubnodes(nodes []*ginkgoNode) ([]*ginkgoNode, []*ginkgoNode) {
+ for i, node := range nodes {
+ if strings.Contains(node.Name, "Entry") {
+ return nodes[:i], nodes[i:]
+ }
+ }
+ return nodes, nil
+}
diff --git a/vendor/github.com/onsi/ginkgo/v2/ginkgo/run/run_command.go b/vendor/github.com/onsi/ginkgo/v2/ginkgo/run/run_command.go
index 03875b979..7b6c2cc22 100644
--- a/vendor/github.com/onsi/ginkgo/v2/ginkgo/run/run_command.go
+++ b/vendor/github.com/onsi/ginkgo/v2/ginkgo/run/run_command.go
@@ -33,12 +33,16 @@ func BuildRunCommand() command.Command {
Usage: "ginkgo run -- ",
ShortDoc: "Run the tests in the passed in (or the package in the current directory if left blank)",
Documentation: "Any arguments after -- will be passed to the test.",
- DocLink: "running-tests",
+ DocLink: "running-specs",
Command: func(args []string, additionalArgs []string) {
var errors []error
cliConfig, goFlagsConfig, errors = types.VetAndInitializeCLIAndGoConfig(cliConfig, goFlagsConfig)
command.AbortIfErrors("Ginkgo detected configuration issues:", errors)
+ if types.ReconcileFdOutputConfiguration(reporterConfig, &suiteConfig, &cliConfig) {
+ fmt.Println("--fd is incompatible with parallel runs (-p/-procs) and -randomize-all; ignoring those flags and running specs in series, in declaration order.")
+ }
+
runner := &SpecRunner{
cliConfig: cliConfig,
goFlagsConfig: goFlagsConfig,
diff --git a/vendor/github.com/onsi/ginkgo/v2/ginkgo/watch/watch_command.go b/vendor/github.com/onsi/ginkgo/v2/ginkgo/watch/watch_command.go
index fe1ca3051..c60d7115f 100644
--- a/vendor/github.com/onsi/ginkgo/v2/ginkgo/watch/watch_command.go
+++ b/vendor/github.com/onsi/ginkgo/v2/ginkgo/watch/watch_command.go
@@ -37,6 +37,10 @@ func BuildWatchCommand() command.Command {
cliConfig, goFlagsConfig, errors = types.VetAndInitializeCLIAndGoConfig(cliConfig, goFlagsConfig)
command.AbortIfErrors("Ginkgo detected configuration issues:", errors)
+ if types.ReconcileFdOutputConfiguration(reporterConfig, &suiteConfig, &cliConfig) {
+ fmt.Println("--fd is incompatible with parallel runs (-p/-procs) and -randomize-all; ignoring those flags and running specs in series, in declaration order.")
+ }
+
watcher := &SpecWatcher{
cliConfig: cliConfig,
goFlagsConfig: goFlagsConfig,
diff --git a/vendor/github.com/onsi/ginkgo/v2/ginkgo_t_dsl.go b/vendor/github.com/onsi/ginkgo/v2/ginkgo_t_dsl.go
index 40d1e1ab5..db3e24847 100644
--- a/vendor/github.com/onsi/ginkgo/v2/ginkgo_t_dsl.go
+++ b/vendor/github.com/onsi/ginkgo/v2/ginkgo_t_dsl.go
@@ -72,6 +72,7 @@ type GinkgoTInterface interface {
TempDir() string
Attr(key, value string)
Output() io.Writer
+ ArtifactDir() string
}
/*
@@ -196,3 +197,6 @@ func (g *GinkgoTBWrapper) Attr(key, value string) {
func (g *GinkgoTBWrapper) Output() io.Writer {
return g.GinkgoT.Output()
}
+func (g *GinkgoTBWrapper) ArtifactDir() string {
+ return g.GinkgoT.ArtifactDir()
+}
diff --git a/vendor/github.com/onsi/ginkgo/v2/helpergo_dsl.go b/vendor/github.com/onsi/ginkgo/v2/helpergo_dsl.go
new file mode 100644
index 000000000..9d04cc845
--- /dev/null
+++ b/vendor/github.com/onsi/ginkgo/v2/helpergo_dsl.go
@@ -0,0 +1,143 @@
+package ginkgo
+
+import (
+ "github.com/onsi/ginkgo/v2/internal/global"
+ ginkgotypes "github.com/onsi/ginkgo/v2/types"
+)
+
+// GinkgoHelperGo synchronously calls the specified “helper” function in a new
+// go routine and with a “defer GinkgoRecover()” already in place, passing the
+// function a “helper Fail”. GinkgoHelperGo is typically called from custom test
+// helpers that in turn need to synchronously execute caller-supplied custom
+// test code in a new Go routine while waiting for this new Go routine to
+// terminate (either successfully or failing).
+//
+// GinkgoHelperGo hides the non-trivial details of correctly unblocking the
+// caller's waiting go routine as well as reporting the correct call sites,
+// depending on whether the test helper failed, or the caller-supplied function
+// had its assertions failing or panicked.
+//
+// Let's take the following example of a test helper named “EnsureSprockets”
+// that runs a set of caller-supplied assertions synchronously on a new Go
+// routine and waits for the outcome before returning to the caller of the test
+// helper. This is just using Ginkgo:
+//
+// func EnsureSprockets(sprockets int, assertions func()) {
+// GinkgoHelper()
+// GinkgoHelperGo(func(helperFail func(string, ...int)) {
+// if sprockets == 0 {
+// helperFail("sprockets must not be zero")
+// }
+// assertions()
+// })
+// }
+//
+// And now for an example that additionally uses Gomega assertions.
+//
+// func EnsureSprockets(sprockets int, assertions func()) {
+// GinkgoHelper()
+// GinkgoHelperGo(func(helperFail func(string, ...int)) {
+// g := gomega.NewGomega(helperFail)
+// g.Expect(sprockets).Not(BeZero())
+// assertions()
+// })
+// }
+//
+// The called helper function should make any custom helper-related assertions
+// using the passed “helper Fail”. Gomega users will want to create a new Gomega
+// wired into this helper Fail. It is expected for the helper function at some
+// point to call into a user-supplied function that might contain its own
+// assertions. In the example above, that would be the function passed as
+// assertions.
+//
+// Any failing assertion using the helper Gomega in the helper function will be
+// reported as a fail at the call site of GinkgoHelperGo. Preferably, only
+// custom test helpers call GinkgoHelperGo and thus mark themselves as
+// [GinkgoHelper] also: in this case, the fail will be shown at the call site of
+// the custom test helper.
+//
+// Any other failing assertions inside the caller-supplied custom test code and
+// thus inside the helper function will instead be reported at the location of
+// the failed assertion.
+//
+// If the caller-supplied custom test code panics, GinkgoHelperGo will fail at
+// its call site, or at the call site of the custom test helper if it uses
+// GinkgoHelper, reporting the usual stack trace for the panic, as a plain
+// GinkgoRecover would also do.
+//
+// Important: the Gomega passed to the called function must only be used in
+// assertions belonging to the test helper, but not any user test code called
+// from the test helper. Thus, do not pass the Gomega passed to the helper
+// function further on to any user test code functions.
+func GinkgoHelperGo(fn func(fail func(message string, callerSkip ...int))) {
+ // userPanicked signals that the called user code panicked, such as due to a
+ // failed Gomega assertion.
+ type userPanicked struct{}
+
+ // helperPanicked signals that some helper code assertion panicked in the
+ // separate Go routine and we are expected to Fail the current test with that
+ // reason, but on the caller's Go routine.
+ type helperPanicked string
+
+ GinkgoHelper()
+
+ // possible types of values sent over the result channel:
+ // - nil (untyped): no problem at all, proceed.
+ // - helperPanicked: the message with which to (re)fail in the caller's
+ // go routine.
+ // - userPanicked: indication to (also) fail on the caller's go routine;
+ // the message doesn't matter as the user code fail takes precedence.
+ ch := make(chan any)
+
+ go func() {
+ isHelperPanic := false
+ helperFail := func(message string, callerSkip ...int) {
+ isHelperPanic = true
+ Fail(message, callerSkip...)
+ }
+ // Please note that we cannot simply recover a helper panic before
+ // GinkgoRecover kicks in as then GinkgoRecover would always report the
+ // stack trace only from the place of rethrown panic ... and that's
+ // pretty useless, because it would just consist of the panic rethrow.
+ defer func() {
+ // We need to unblock and immediately fail the waiting caller's
+ // go routine either for a reason, or just "because" when
+ // GinkgoRecover has already failed the current test on the
+ // separate go routine.
+ if global.Failer.GetState() != ginkgotypes.SpecStatePassed {
+ if isHelperPanic {
+ _, failure := global.Failer.Drain()
+ ch <- helperPanicked(failure.Message)
+ } else {
+ // keep the panic failure already recorded by GinkgoRecover.
+ ch <- userPanicked{}
+ }
+ }
+ close(ch) // causes a nil in case there were no panics anywhere.
+ }()
+ // Nota bene: GinkgoRecover always eats any user panic and channel the
+ // panic value into Ginkgo's Failer.Panic(). We can peek at the last
+ // failure recorded, which should be nil if GinkgoRecover didn't swallow
+ // a user code panic. The "problem" with GinkgoRecover is that it turns
+ // any panic value into a string message, so we loose any specific
+ // typing.
+ defer GinkgoRecover()
+
+ fn(helperFail)
+ }()
+
+ // Did we run into trouble?
+ switch v := (<-ch).(type) {
+ case userPanicked:
+ // The message actually is irrelevant, as it comes only second to
+ // the already registered user panic message. We just need Fail to
+ // panic on the caller's go routine in order to unblock the test.
+ Fail("fn panicked", 1)
+ case helperPanicked:
+ // Report the failure on the new go routine instead on the caller's go
+ // routine.
+ Fail(string(v), 1)
+ default:
+ // It's all fine!
+ }
+}
diff --git a/vendor/github.com/onsi/ginkgo/v2/internal/focus.go b/vendor/github.com/onsi/ginkgo/v2/internal/focus.go
index a39daf5a6..498e707db 100644
--- a/vendor/github.com/onsi/ginkgo/v2/internal/focus.go
+++ b/vendor/github.com/onsi/ginkgo/v2/internal/focus.go
@@ -56,7 +56,7 @@ This function sets the `Skip` property on specs by applying Ginkgo's focus polic
*Note:* specs with pending nodes are Skipped when created by NewSpec.
*/
-func ApplyFocusToSpecs(specs Specs, description string, suiteLabels Labels, suiteSemVerConstraints SemVerConstraints, suiteConfig types.SuiteConfig) (Specs, bool) {
+func ApplyFocusToSpecs(specs Specs, description string, suiteLabels Labels, suiteSemVerConstraints SemVerConstraints, suiteComponentSemVerConstraints ComponentSemVerConstraints, suiteConfig types.SuiteConfig) (Specs, bool) {
focusString := strings.Join(suiteConfig.FocusStrings, "|")
skipString := strings.Join(suiteConfig.SkipStrings, "|")
@@ -87,7 +87,24 @@ func ApplyFocusToSpecs(specs Specs, description string, suiteLabels Labels, suit
if suiteConfig.SemVerFilter != "" {
semVerFilter, _ := types.ParseSemVerFilter(suiteConfig.SemVerFilter)
skipChecks = append(skipChecks, func(spec Spec) bool {
- return !semVerFilter(UnionOfSemVerConstraints(suiteSemVerConstraints, spec.Nodes.UnionOfSemVerConstraints()))
+ noRun := false
+
+ // non-component-specific constraints
+ constraints := UnionOfSemVerConstraints(suiteSemVerConstraints, spec.Nodes.UnionOfSemVerConstraints())
+ if len(constraints) != 0 && semVerFilter("", constraints) == false {
+ noRun = true
+ }
+
+ // component-specific constraints
+ componentConstraints := UnionOfComponentSemVerConstraints(suiteComponentSemVerConstraints, spec.Nodes.UnionOfComponentSemVerConstraints())
+ for component, constraints := range componentConstraints {
+ if semVerFilter(component, constraints) == false {
+ noRun = true
+ break
+ }
+ }
+
+ return noRun
})
}
diff --git a/vendor/github.com/onsi/ginkgo/v2/internal/global/init.go b/vendor/github.com/onsi/ginkgo/v2/internal/global/init.go
index 464e3c97f..14d2552b7 100644
--- a/vendor/github.com/onsi/ginkgo/v2/internal/global/init.go
+++ b/vendor/github.com/onsi/ginkgo/v2/internal/global/init.go
@@ -8,6 +8,12 @@ var Suite *internal.Suite
var Failer *internal.Failer
var backupSuite *internal.Suite
+// SuiteDidRun tracks whether RunSpecs has already been invoked for the current global
+// suite. It lives here (rather than in package ginkgo) so that InitializeGlobals can
+// clear it, allowing extensions/globals.Reset to support running multiple suites
+// sequentially in a single process.
+var SuiteDidRun bool
+
func init() {
InitializeGlobals()
}
@@ -15,6 +21,7 @@ func init() {
func InitializeGlobals() {
Failer = internal.NewFailer()
Suite = internal.NewSuite()
+ SuiteDidRun = false
}
func PushClone() error {
diff --git a/vendor/github.com/onsi/ginkgo/v2/internal/group.go b/vendor/github.com/onsi/ginkgo/v2/internal/group.go
index cc794903e..781adf6fa 100644
--- a/vendor/github.com/onsi/ginkgo/v2/internal/group.go
+++ b/vendor/github.com/onsi/ginkgo/v2/internal/group.go
@@ -113,22 +113,24 @@ func newGroup(suite *Suite) *group {
// initialReportForSpec constructs a new SpecReport right before running the spec.
func (g *group) initialReportForSpec(spec Spec) types.SpecReport {
return types.SpecReport{
- ContainerHierarchyTexts: spec.Nodes.WithType(types.NodeTypeContainer).Texts(),
- ContainerHierarchyLocations: spec.Nodes.WithType(types.NodeTypeContainer).CodeLocations(),
- ContainerHierarchyLabels: spec.Nodes.WithType(types.NodeTypeContainer).Labels(),
- ContainerHierarchySemVerConstraints: spec.Nodes.WithType(types.NodeTypeContainer).SemVerConstraints(),
- LeafNodeLocation: spec.FirstNodeWithType(types.NodeTypeIt).CodeLocation,
- LeafNodeType: types.NodeTypeIt,
- LeafNodeText: spec.FirstNodeWithType(types.NodeTypeIt).Text,
- LeafNodeLabels: []string(spec.FirstNodeWithType(types.NodeTypeIt).Labels),
- LeafNodeSemVerConstraints: []string(spec.FirstNodeWithType(types.NodeTypeIt).SemVerConstraints),
- ParallelProcess: g.suite.config.ParallelProcess,
- RunningInParallel: g.suite.isRunningInParallel(),
- IsSerial: spec.Nodes.HasNodeMarkedSerial(),
- IsInOrderedContainer: !spec.Nodes.FirstNodeMarkedOrdered().IsZero(),
- MaxFlakeAttempts: spec.Nodes.GetMaxFlakeAttempts(),
- MaxMustPassRepeatedly: spec.Nodes.GetMaxMustPassRepeatedly(),
- SpecPriority: spec.Nodes.GetSpecPriority(),
+ ContainerHierarchyTexts: spec.Nodes.WithType(types.NodeTypeContainer).Texts(),
+ ContainerHierarchyLocations: spec.Nodes.WithType(types.NodeTypeContainer).CodeLocations(),
+ ContainerHierarchyLabels: spec.Nodes.WithType(types.NodeTypeContainer).Labels(),
+ ContainerHierarchySemVerConstraints: spec.Nodes.WithType(types.NodeTypeContainer).SemVerConstraints(),
+ ContainerHierarchyComponentSemVerConstraints: spec.Nodes.WithType(types.NodeTypeContainer).ComponentSemVerConstraints(),
+ LeafNodeLocation: spec.FirstNodeWithType(types.NodeTypeIt).CodeLocation,
+ LeafNodeType: types.NodeTypeIt,
+ LeafNodeText: spec.FirstNodeWithType(types.NodeTypeIt).Text,
+ LeafNodeLabels: []string(spec.FirstNodeWithType(types.NodeTypeIt).Labels),
+ LeafNodeSemVerConstraints: []string(spec.FirstNodeWithType(types.NodeTypeIt).SemVerConstraints),
+ LeafNodeComponentSemVerConstraints: map[string][]string(spec.FirstNodeWithType(types.NodeTypeIt).ComponentSemVerConstraints),
+ ParallelProcess: g.suite.config.ParallelProcess,
+ RunningInParallel: g.suite.isRunningInParallel(),
+ IsSerial: spec.Nodes.HasNodeMarkedSerial(),
+ IsInOrderedContainer: !spec.Nodes.FirstNodeMarkedOrdered().IsZero(),
+ MaxFlakeAttempts: spec.Nodes.GetMaxFlakeAttempts(),
+ MaxMustPassRepeatedly: spec.Nodes.GetMaxMustPassRepeatedly(),
+ SpecPriority: spec.Nodes.GetSpecPriority(),
}
}
@@ -152,6 +154,7 @@ func addNodeToReportForNode(report *types.ConstructionNodeReport, node *TreeNode
report.ContainerHierarchyLocations = append(report.ContainerHierarchyLocations, node.Node.CodeLocation)
report.ContainerHierarchyLabels = append(report.ContainerHierarchyLabels, node.Node.Labels)
report.ContainerHierarchySemVerConstraints = append(report.ContainerHierarchySemVerConstraints, node.Node.SemVerConstraints)
+ report.ContainerHierarchyComponentSemVerConstraints = append(report.ContainerHierarchyComponentSemVerConstraints, node.Node.ComponentSemVerConstraints)
if node.Node.MarkedSerial {
report.IsSerial = true
}
@@ -208,6 +211,21 @@ func (g *group) isLastSpecWithPair(specID uint, pair runOncePair) bool {
return lastSpecID == specID
}
+func (g *group) willRunAnotherAttempt(isFinalAttempt bool) bool {
+ if isFinalAttempt {
+ return false
+ }
+
+ if g.suite.currentSpecReport.MaxMustPassRepeatedly > 0 {
+ return g.suite.currentSpecReport.State.Is(types.SpecStatePassed)
+ }
+ if g.suite.currentSpecReport.MaxFlakeAttempts > 0 {
+ return g.suite.currentSpecReport.State.Is(types.SpecStateFailureStates)
+ }
+
+ return false
+}
+
func (g *group) attemptSpec(isFinalAttempt bool, spec Spec) bool {
failedInARunOnceBefore := false
pairs := g.runOncePairs[spec.SubjectID()]
@@ -277,10 +295,11 @@ func (g *group) attemptSpec(isFinalAttempt bool, spec Spec) bool {
}
// it's our last chance to run if we're the last spec for our oncePair
isLastSpecWithPair := g.isLastSpecWithPair(spec.SubjectID(), pair)
+ willRunAnotherAttempt := g.willRunAnotherAttempt(isFinalAttempt)
switch g.suite.currentSpecReport.State {
case types.SpecStatePassed: //this attempt is passing...
- return isLastSpecWithPair //...we should run-once if we'this is our last chance
+ return isLastSpecWithPair && !willRunAnotherAttempt //...we should run-once if this is our last chance
case types.SpecStateSkipped: //the spec was skipped by the user...
if isLastSpecWithPair {
return true //...we're the last spec, so we should run the AfterNode
@@ -289,7 +308,7 @@ func (g *group) attemptSpec(isFinalAttempt bool, spec Spec) bool {
return true //...or, a run-once node at our nesting level was skipped which means this is our last chance to run
}
case types.SpecStateFailed, types.SpecStatePanicked, types.SpecStateTimedout: // the spec has failed...
- if isFinalAttempt {
+ if !willRunAnotherAttempt {
if g.continueOnFailure {
return isLastSpecWithPair || failedInARunOnceBefore //...we're configured to continue on failures - so we should only run if we're the last spec for this pair or if we failed in a runOnceBefore (which means we _are_ the last spec to run)
} else {
diff --git a/vendor/github.com/onsi/ginkgo/v2/internal/node.go b/vendor/github.com/onsi/ginkgo/v2/internal/node.go
index 2bccec2db..b0c8de8d6 100644
--- a/vendor/github.com/onsi/ginkgo/v2/internal/node.go
+++ b/vendor/github.com/onsi/ginkgo/v2/internal/node.go
@@ -57,6 +57,7 @@ type Node struct {
MustPassRepeatedly int
Labels Labels
SemVerConstraints SemVerConstraints
+ ComponentSemVerConstraints ComponentSemVerConstraints
PollProgressAfter time.Duration
PollProgressInterval time.Duration
NodeTimeout time.Duration
@@ -106,7 +107,24 @@ func (l Labels) MatchesLabelFilter(query string) bool {
type SemVerConstraints []string
func (svc SemVerConstraints) MatchesSemVerFilter(version string) bool {
- return types.MustParseSemVerFilter(version)(svc)
+ return types.MustParseSemVerFilter(version)("", svc)
+}
+
+type ComponentSemVerConstraints map[string][]string
+
+func (csvc ComponentSemVerConstraints) MatchesSemVerFilter(component, version string) bool {
+ for comp, constraints := range csvc {
+ if comp != component {
+ continue
+ }
+
+ input := version
+ if len(component) > 0 {
+ input = fmt.Sprintf("%s=%s", component, version)
+ }
+ return types.MustParseSemVerFilter(input)(component, constraints)
+ }
+ return false
}
func unionOf[S ~[]E, E comparable](slices ...S) S {
@@ -131,6 +149,16 @@ func UnionOfSemVerConstraints(semVerConstraints ...SemVerConstraints) SemVerCons
return unionOf(semVerConstraints...)
}
+func UnionOfComponentSemVerConstraints(componentSemVerConstraintsSlice ...ComponentSemVerConstraints) ComponentSemVerConstraints {
+ unionComponentSemVerConstraints := ComponentSemVerConstraints{}
+ for _, componentSemVerConstraints := range componentSemVerConstraintsSlice {
+ for component, constraints := range componentSemVerConstraints {
+ unionComponentSemVerConstraints[component] = unionOf(unionComponentSemVerConstraints[component], constraints)
+ }
+ }
+ return unionComponentSemVerConstraints
+}
+
func PartitionDecorations(args ...any) ([]any, []any) {
decorations := []any{}
remainingArgs := []any{}
@@ -174,6 +202,8 @@ func isDecoration(arg any) bool {
return true
case t == reflect.TypeOf(SemVerConstraints{}):
return true
+ case t == reflect.TypeOf(ComponentSemVerConstraints{}):
+ return true
case t == reflect.TypeOf(PollProgressInterval(0)):
return true
case t == reflect.TypeOf(PollProgressAfter(0)):
@@ -214,16 +244,17 @@ var specContextType = reflect.TypeOf(new(SpecContext)).Elem()
func NewNode(deprecationTracker *types.DeprecationTracker, nodeType types.NodeType, text string, args ...any) (Node, []error) {
baseOffset := 2
node := Node{
- ID: UniqueNodeID(),
- NodeType: nodeType,
- Text: text,
- Labels: Labels{},
- SemVerConstraints: SemVerConstraints{},
- CodeLocation: types.NewCodeLocation(baseOffset),
- NestingLevel: -1,
- PollProgressAfter: -1,
- PollProgressInterval: -1,
- GracePeriod: -1,
+ ID: UniqueNodeID(),
+ NodeType: nodeType,
+ Text: text,
+ Labels: Labels{},
+ SemVerConstraints: SemVerConstraints{},
+ ComponentSemVerConstraints: ComponentSemVerConstraints{},
+ CodeLocation: types.NewCodeLocation(baseOffset),
+ NestingLevel: -1,
+ PollProgressAfter: -1,
+ PollProgressInterval: -1,
+ GracePeriod: -1,
}
errors := []error{}
@@ -360,6 +391,36 @@ func NewNode(deprecationTracker *types.DeprecationTracker, nodeType types.NodeTy
appendError(err)
}
}
+ case t == reflect.TypeOf(ComponentSemVerConstraints{}):
+ if !nodeType.Is(types.NodeTypesForContainerAndIt) {
+ appendError(types.GinkgoErrors.InvalidDecoratorForNodeType(node.CodeLocation, nodeType, "ComponentSemVerConstraint"))
+ }
+ for component, semVerConstraints := range arg.(ComponentSemVerConstraints) {
+ // while using ComponentSemVerConstraints, we should not allow empty component names.
+ // you should use SemVerConstraints for that.
+ hasErr := false
+ if len(component) == 0 {
+ appendError(types.GinkgoErrors.InvalidEmptyComponentForSemVerConstraint(node.CodeLocation))
+ hasErr = true
+ }
+ for _, semVerConstraint := range semVerConstraints {
+ _, err := types.ValidateAndCleanupSemVerConstraint(semVerConstraint, node.CodeLocation)
+ if err != nil {
+ appendError(err)
+ hasErr = true
+ }
+ }
+
+ if !hasErr {
+ // merge constraints if the component already exists
+ constraints := slices.Clone(semVerConstraints)
+ if existingConstraints, exists := node.ComponentSemVerConstraints[component]; exists {
+ constraints = UnionOfSemVerConstraints([]string(existingConstraints), constraints)
+ }
+
+ node.ComponentSemVerConstraints[component] = slices.Clone(constraints)
+ }
+ }
case t.Kind() == reflect.Func:
if nodeType.Is(types.NodeTypeContainer) {
if node.Body != nil {
@@ -899,6 +960,34 @@ func (n Nodes) UnionOfSemVerConstraints() []string {
return out
}
+func (n Nodes) ComponentSemVerConstraints() []map[string][]string {
+ out := make([]map[string][]string, len(n))
+ for i := range n {
+ if n[i].ComponentSemVerConstraints == nil {
+ out[i] = map[string][]string{}
+ } else {
+ out[i] = map[string][]string(n[i].ComponentSemVerConstraints)
+ }
+ }
+ return out
+}
+
+func (n Nodes) UnionOfComponentSemVerConstraints() map[string][]string {
+ out := map[string][]string{}
+ seen := map[string]bool{}
+ for i := range n {
+ for component := range n[i].ComponentSemVerConstraints {
+ if !seen[component] {
+ seen[component] = true
+ out[component] = n[i].ComponentSemVerConstraints[component]
+ } else {
+ out[component] = UnionOfSemVerConstraints(out[component], n[i].ComponentSemVerConstraints[component])
+ }
+ }
+ }
+ return out
+}
+
func (n Nodes) CodeLocations() []types.CodeLocation {
out := make([]types.CodeLocation, len(n))
for i := range n {
diff --git a/vendor/github.com/onsi/ginkgo/v2/internal/reporters/gojson.go b/vendor/github.com/onsi/ginkgo/v2/internal/reporters/gojson.go
index 8b7a9ceab..751543ea7 100644
--- a/vendor/github.com/onsi/ginkgo/v2/internal/reporters/gojson.go
+++ b/vendor/github.com/onsi/ginkgo/v2/internal/reporters/gojson.go
@@ -83,7 +83,7 @@ func goJSONActionFromSpecState(state types.SpecState) GoJSONAction {
type gojsonReport struct {
o types.Report
// Extra calculated fields
- goPkg string
+ goPkg string
elapsed float64
}
@@ -109,8 +109,8 @@ type gojsonSpecReport struct {
o types.SpecReport
// extra calculated fields
testName string
- elapsed float64
- action GoJSONAction
+ elapsed float64
+ action GoJSONAction
}
func newSpecReport(in types.SpecReport) *gojsonSpecReport {
@@ -141,18 +141,31 @@ func suitePathToPkg(dir string) (string, error) {
}
func createTestName(spec types.SpecReport) string {
- name := fmt.Sprintf("[%s]", spec.LeafNodeType)
- if spec.FullText() != "" {
- name = name + " " + spec.FullText()
- }
- labels := spec.Labels()
- if len(labels) > 0 {
- name = name + " [" + strings.Join(labels, ", ") + "]"
- }
- semVerConstraints := spec.SemVerConstraints()
- if len(semVerConstraints) > 0 {
- name = name + " [" + strings.Join(semVerConstraints, ", ") + "]"
- }
- name = strings.TrimSpace(name)
- return name
+ name := fmt.Sprintf("[%s]", spec.LeafNodeType)
+ if spec.FullText() != "" {
+ name = name + " " + spec.FullText()
+ }
+ labels := spec.Labels()
+ if len(labels) > 0 {
+ name = name + " [" + strings.Join(labels, ", ") + "]"
+ }
+ semVerConstraints := spec.SemVerConstraints()
+ if len(semVerConstraints) > 0 {
+ name = name + " [" + strings.Join(semVerConstraints, ", ") + "]"
+ }
+ componentSemVerConstraints := spec.ComponentSemVerConstraints()
+ if len(componentSemVerConstraints) > 0 {
+ name = name + " [" + formatComponentSemVerConstraintsToString(componentSemVerConstraints) + "]"
+ }
+ name = strings.TrimSpace(name)
+ return name
+}
+
+func formatComponentSemVerConstraintsToString(componentSemVerConstraints map[string][]string) string {
+ var tmpStr string
+ for component, semVerConstraints := range componentSemVerConstraints {
+ tmpStr = tmpStr + fmt.Sprintf("%s: %s, ", component, semVerConstraints)
+ }
+ tmpStr = strings.TrimSuffix(tmpStr, ", ")
+ return tmpStr
}
diff --git a/vendor/github.com/onsi/ginkgo/v2/internal/suite.go b/vendor/github.com/onsi/ginkgo/v2/internal/suite.go
index 9d5f59001..6c879855e 100644
--- a/vendor/github.com/onsi/ginkgo/v2/internal/suite.go
+++ b/vendor/github.com/onsi/ginkgo/v2/internal/suite.go
@@ -108,13 +108,13 @@ func (suite *Suite) BuildTree() error {
return nil
}
-func (suite *Suite) Run(description string, suiteLabels Labels, suiteSemVerConstraints SemVerConstraints, suiteAroundNodes types.AroundNodes, suitePath string, failer *Failer, reporter reporters.Reporter, writer WriterInterface, outputInterceptor OutputInterceptor, interruptHandler interrupt_handler.InterruptHandlerInterface, client parallel_support.Client, progressSignalRegistrar ProgressSignalRegistrar, suiteConfig types.SuiteConfig) (bool, bool) {
+func (suite *Suite) Run(description string, suiteLabels Labels, suiteSemVerConstraints SemVerConstraints, suiteComponentSemVerConstraints ComponentSemVerConstraints, suiteAroundNodes types.AroundNodes, suitePath string, failer *Failer, reporter reporters.Reporter, writer WriterInterface, outputInterceptor OutputInterceptor, interruptHandler interrupt_handler.InterruptHandlerInterface, client parallel_support.Client, progressSignalRegistrar ProgressSignalRegistrar, suiteConfig types.SuiteConfig) (bool, bool) {
if suite.phase != PhaseBuildTree {
panic("cannot run before building the tree = call suite.BuildTree() first")
}
ApplyNestedFocusPolicyToTree(suite.tree)
specs := GenerateSpecsFromTreeRoot(suite.tree)
- specs, hasProgrammaticFocus := ApplyFocusToSpecs(specs, description, suiteLabels, suiteSemVerConstraints, suiteConfig)
+ specs, hasProgrammaticFocus := ApplyFocusToSpecs(specs, description, suiteLabels, suiteSemVerConstraints, suiteComponentSemVerConstraints, suiteConfig)
specs = ComputeAroundNodes(specs)
suite.phase = PhaseRun
@@ -133,7 +133,7 @@ func (suite *Suite) Run(description string, suiteLabels Labels, suiteSemVerConst
cancelProgressHandler := progressSignalRegistrar(suite.handleProgressSignal)
- success := suite.runSpecs(description, suiteLabels, suiteSemVerConstraints, suitePath, hasProgrammaticFocus, specs)
+ success := suite.runSpecs(description, suiteLabels, suiteSemVerConstraints, suiteComponentSemVerConstraints, suitePath, hasProgrammaticFocus, specs)
cancelProgressHandler()
@@ -456,16 +456,17 @@ func (suite *Suite) processCurrentSpecReport() {
}
}
-func (suite *Suite) runSpecs(description string, suiteLabels Labels, suiteSemVerConstraints SemVerConstraints, suitePath string, hasProgrammaticFocus bool, specs Specs) bool {
+func (suite *Suite) runSpecs(description string, suiteLabels Labels, suiteSemVerConstraints SemVerConstraints, suiteComponentSemVerConstraints ComponentSemVerConstraints, suitePath string, hasProgrammaticFocus bool, specs Specs) bool {
numSpecsThatWillBeRun := specs.CountWithoutSkip()
suite.report = types.Report{
- SuitePath: suitePath,
- SuiteDescription: description,
- SuiteLabels: suiteLabels,
- SuiteSemVerConstraints: suiteSemVerConstraints,
- SuiteConfig: suite.config,
- SuiteHasProgrammaticFocus: hasProgrammaticFocus,
+ SuitePath: suitePath,
+ SuiteDescription: description,
+ SuiteLabels: suiteLabels,
+ SuiteSemVerConstraints: suiteSemVerConstraints,
+ SuiteComponentSemVerConstraints: suiteComponentSemVerConstraints,
+ SuiteConfig: suite.config,
+ SuiteHasProgrammaticFocus: hasProgrammaticFocus,
PreRunStats: types.PreRunStats{
TotalSpecs: len(specs),
SpecsThatWillRun: numSpecsThatWillBeRun,
@@ -995,6 +996,7 @@ func (suite *Suite) runNode(node Node, specDeadline time.Time, text string) (typ
} else {
failure.Message, failure.Location, failure.ForwardedPanic, failure.TimelineLocation = failureFromRun.Message, failureFromRun.Location, failureFromRun.ForwardedPanic, failureFromRun.TimelineLocation
suite.reporter.EmitFailure(outcomeFromRun, failure)
+ suite.pauseOnFailureIfRequested(node)
return outcomeFromRun, failure
}
case <-gracePeriodChannel:
@@ -1042,7 +1044,7 @@ func (suite *Suite) runNode(node Node, specDeadline time.Time, text string) (typ
}
progressReport = progressReport.WithoutOtherGoroutines()
- sc.cancel(fmt.Errorf(interruptStatus.Message()))
+ sc.cancel(fmt.Errorf("%s", interruptStatus.Message()))
if interruptStatus.Level == interrupt_handler.InterruptLevelBailOut {
if interruptStatus.ShouldIncludeProgressReport() {
@@ -1078,6 +1080,42 @@ func (suite *Suite) runNode(node Node, specDeadline time.Time, text string) (typ
}
}
+// pauseOnFailureIfRequested pauses the suite at the moment a failure is identified,
+// when the user has set --sleep-on-failure. This hooks directly into runNode's failure
+// path so the pause happens immediately at the point of failure - before any teardown
+// or cleanup runs - leaving the system live for inspection.
+//
+// We only pause for failures in setup and subject nodes (It, Before*, BeforeSuite...),
+// i.e. nodes that run before teardown. Pausing on a failure in a teardown/cleanup or
+// reporting node would be pointless (the system is already being torn down) and could
+// interfere with interrupt handling, so those are skipped.
+//
+// The pause is interruptible: pressing ^C (or any interrupt) ends the pause early and
+// the suite proceeds to run cleanup as usual. It is a no-op if the feature is disabled.
+func (suite *Suite) pauseOnFailureIfRequested(node Node) {
+ if suite.config.SleepOnFailure <= 0 {
+ return
+ }
+ // only pause before teardown - skip teardown/cleanup/reporting nodes
+ if node.NodeType.Is(types.NodeTypesAllowedDuringCleanupInterrupt | types.NodeTypesAllowedDuringReportInterrupt) {
+ return
+ }
+
+ duration := suite.config.SleepOnFailure
+ report := suite.generateProgressReport(false)
+ report.Message = fmt.Sprintf("{{bold}}{{orange}}Paused on failure for up to %s.{{/}}\nThe spec failed and Ginkgo has paused before running any teardown so you can inspect the live system.\nPress {{bold}}^C{{/}} to end the pause and proceed to cleanup.", duration)
+ suite.emitProgressReport(report)
+
+ timer := time.NewTimer(duration)
+ defer timer.Stop()
+ // wait for the pause to elapse, or for the user to interrupt - in which case we end
+ // the pause early and let runNode return so cleanup can proceed
+ select {
+ case <-timer.C:
+ case <-suite.interruptHandler.Status().Channel:
+ }
+}
+
// TODO: search for usages and consider if reporter.EmitFailure() is necessary
func (suite *Suite) failureForLeafNodeWithMessage(node Node, message string) types.Failure {
return types.Failure{
diff --git a/vendor/github.com/onsi/ginkgo/v2/internal/testingtproxy/testing_t_proxy.go b/vendor/github.com/onsi/ginkgo/v2/internal/testingtproxy/testing_t_proxy.go
index 9806e315a..e6fbaee41 100644
--- a/vendor/github.com/onsi/ginkgo/v2/internal/testingtproxy/testing_t_proxy.go
+++ b/vendor/github.com/onsi/ginkgo/v2/internal/testingtproxy/testing_t_proxy.go
@@ -27,6 +27,11 @@ type ginkgoWriterInterface interface {
type ginkgoRecoverFunc func()
type attachProgressReporterFunc func(func() string) func()
+var formatters = map[bool]formatter.Formatter{
+ true: formatter.NewWithNoColorBool(true),
+ false: formatter.NewWithNoColorBool(false),
+}
+
func New(writer ginkgoWriterInterface, fail failFunc, skip skipFunc, cleanup cleanupFunc, report reportFunc, addReportEntry addReportEntryFunc, ginkgoRecover ginkgoRecoverFunc, attachProgressReporter attachProgressReporterFunc, randomSeed int64, parallelProcess int, parallelTotal int, noColor bool, offset int) *ginkgoTestingTProxy {
return &ginkgoTestingTProxy{
fail: fail,
@@ -41,7 +46,7 @@ func New(writer ginkgoWriterInterface, fail failFunc, skip skipFunc, cleanup cle
randomSeed: randomSeed,
parallelProcess: parallelProcess,
parallelTotal: parallelTotal,
- f: formatter.NewWithNoColorBool(noColor),
+ f: formatters[noColor], //minimize allocations by reusing formatters
}
}
@@ -176,6 +181,15 @@ func (t *ginkgoTestingTProxy) TempDir() string {
return tmpDir
}
+func (t *ginkgoTestingTProxy) ArtifactDir() string {
+ artifactDir, err := os.MkdirTemp("", "ginkgo")
+ if err != nil {
+ t.fail(fmt.Sprintf("Failed to create artifact directory: %v", err), 1)
+ return ""
+ }
+ return artifactDir
+}
+
// FullGinkgoTInterface
func (t *ginkgoTestingTProxy) AddReportEntryVisibilityAlways(name string, args ...any) {
finalArgs := []any{internal.Offset(1), types.ReportEntryVisibilityAlways}
diff --git a/vendor/github.com/onsi/ginkgo/v2/reporters/default_reporter.go b/vendor/github.com/onsi/ginkgo/v2/reporters/default_reporter.go
index 026d9cf9b..f3e15a913 100644
--- a/vendor/github.com/onsi/ginkgo/v2/reporters/default_reporter.go
+++ b/vendor/github.com/onsi/ginkgo/v2/reporters/default_reporter.go
@@ -31,6 +31,7 @@ type DefaultReporter struct {
specDenoter string
retryDenoter string
formatter formatter.Formatter
+ fdHierarchy []string
runningInParallel bool
lock *sync.Mutex
@@ -75,10 +76,15 @@ func (r *DefaultReporter) SuiteWillBegin(report types.Report) {
if len(report.SuiteSemVerConstraints) > 0 {
r.emit(r.f("{{coral}}[%s]{{/}} ", strings.Join(report.SuiteSemVerConstraints, ", ")))
}
+ if len(report.SuiteComponentSemVerConstraints) > 0 {
+ r.emit(r.f("{{coral}}[Components: %s]{{/}} ", formatComponentSemVerConstraintsToString(report.SuiteComponentSemVerConstraints)))
+ }
r.emit(r.f("- %d/%d specs ", report.PreRunStats.SpecsThatWillRun, report.PreRunStats.TotalSpecs))
if report.SuiteConfig.ParallelTotal > 1 {
r.emit(r.f("- %d procs ", report.SuiteConfig.ParallelTotal))
}
+ } else if r.conf.FdOutput {
+ return
} else {
banner := r.f("Running Suite: %s - %s", report.SuiteDescription, report.SuitePath)
r.emitBlock(banner)
@@ -97,6 +103,13 @@ func (r *DefaultReporter) SuiteWillBegin(report types.Report) {
bannerWidth = len(semVerConstraints) + 2
}
}
+ if len(report.SuiteComponentSemVerConstraints) > 0 {
+ componentSemVerConstraints := formatComponentSemVerConstraintsToString(report.SuiteComponentSemVerConstraints)
+ r.emitBlock(r.f("{{coral}}[Components: %s]{{/}} ", componentSemVerConstraints))
+ if len(componentSemVerConstraints)+2 > bannerWidth {
+ bannerWidth = len(componentSemVerConstraints) + 2
+ }
+ }
r.emitBlock(strings.Repeat("=", bannerWidth))
out := r.f("Random Seed: {{bold}}%d{{/}}", report.SuiteConfig.RandomSeed)
@@ -114,7 +127,7 @@ func (r *DefaultReporter) SuiteWillBegin(report types.Report) {
func (r *DefaultReporter) SuiteDidEnd(report types.Report) {
failures := report.SpecReports.WithState(types.SpecStateFailureStates)
- if len(failures) > 0 {
+ if !r.conf.FdOutput && len(failures) > 0 {
r.emitBlock("\n")
if len(failures) > 1 {
r.emitBlock(r.f("{{red}}{{bold}}Summarizing %d Failures:{{/}}", len(failures)))
@@ -217,6 +230,10 @@ func (r *DefaultReporter) DidRun(report types.SpecReport) {
return
}
+ if r.conf.FdOutput {
+ r.didRunFd(report)
+ return
+ }
header := r.specDenoter
if report.LeafNodeType.Is(types.NodeTypesForSuiteLevelNodes) {
header = fmt.Sprintf("[%s]", report.LeafNodeType)
@@ -348,6 +365,51 @@ func (r *DefaultReporter) DidRun(report types.SpecReport) {
r.emitDelimiter(0)
}
+func (r *DefaultReporter) didRunFd(report types.SpecReport) {
+ r.lock.Lock()
+ defer r.lock.Unlock()
+
+ if !report.LeafNodeType.Is(types.NodeTypeIt) {
+ return
+ }
+
+ hierarchy := report.ContainerHierarchyTexts
+
+ // blank line when top-level container changes
+ if len(r.fdHierarchy) > 0 &&
+ (len(hierarchy) == 0 || hierarchy[0] != r.fdHierarchy[0]) {
+ fmt.Fprintln(r.writer)
+ }
+
+ // emit newly-diverged container lines
+ divergeAt := 0
+ for divergeAt < len(r.fdHierarchy) && divergeAt < len(hierarchy) &&
+ r.fdHierarchy[divergeAt] == hierarchy[divergeAt] {
+ divergeAt++
+ }
+ for i := divergeAt; i < len(hierarchy); i++ {
+ fmt.Fprintf(r.writer, "%s%s\n", strings.Repeat(" ", i), hierarchy[i])
+ }
+
+ // leaf label
+ depth := len(hierarchy)
+ indent := strings.Repeat(" ", depth)
+ label := report.LeafNodeText
+
+ switch report.State {
+ case types.SpecStateFailed, types.SpecStatePanicked:
+ label = fmt.Sprintf("%s (FAILED)", label)
+ case types.SpecStatePending:
+ label = fmt.Sprintf("%s (PENDING)", label)
+ case types.SpecStateSkipped:
+ label = fmt.Sprintf("%s (SKIPPED)", label)
+ }
+
+ color := r.highlightColorForState(report.State)
+ fmt.Fprintf(r.writer, "%s%s\n", indent, r.f(color+"%s{{/}}", label))
+ r.fdHierarchy = hierarchy
+}
+
func (r *DefaultReporter) highlightColorForState(state types.SpecState) string {
switch state {
case types.SpecStatePassed:
@@ -413,7 +475,7 @@ func (r *DefaultReporter) emitTimeline(indent uint, report types.SpecReport, tim
case types.ReportEntry:
r.emitReportEntry(indent, x)
case types.ProgressReport:
- r.emitProgressReport(indent, false, isVeryVerbose, x)
+ r.emitProgressReport(indent, isVeryVerbose, false, x)
case types.SpecEvent:
if isVeryVerbose || !x.IsOnlyVisibleAtVeryVerbose() || r.conf.ShowNodeEvents {
r.emitSpecEvent(indent, x, isVeryVerbose)
@@ -523,6 +585,7 @@ func (r *DefaultReporter) emitProgressReport(indent uint, emitGinkgoWriterOutput
indent -= 1
}
+ // Emit only top-level groups because github logging cannot handle nested groups correctly.
if r.conf.GithubOutput && emitGroup {
r.emitBlock(r.fi(indent, "::group::Progress Report"))
}
@@ -725,8 +788,12 @@ func (r *DefaultReporter) cycleJoin(elements []string, joiner string) string {
}
func (r *DefaultReporter) codeLocationBlock(report types.SpecReport, highlightColor string, veryVerbose bool, usePreciseFailureLocation bool) string {
- texts, locations, labels, semVerConstraints := []string{}, []types.CodeLocation{}, [][]string{}, [][]string{}
- texts, locations, labels, semVerConstraints = append(texts, report.ContainerHierarchyTexts...), append(locations, report.ContainerHierarchyLocations...), append(labels, report.ContainerHierarchyLabels...), append(semVerConstraints, report.ContainerHierarchySemVerConstraints...)
+ texts, locations, labels, semVerConstraints, componentSemVerConstraints := []string{}, []types.CodeLocation{}, [][]string{}, [][]string{}, []map[string][]string{}
+ texts = append(texts, report.ContainerHierarchyTexts...)
+ locations = append(locations, report.ContainerHierarchyLocations...)
+ labels = append(labels, report.ContainerHierarchyLabels...)
+ semVerConstraints = append(semVerConstraints, report.ContainerHierarchySemVerConstraints...)
+ componentSemVerConstraints = append(componentSemVerConstraints, report.ContainerHierarchyComponentSemVerConstraints...)
if report.LeafNodeType.Is(types.NodeTypesForSuiteLevelNodes) {
texts = append(texts, r.f("[%s] %s", report.LeafNodeType, report.LeafNodeText))
@@ -735,6 +802,7 @@ func (r *DefaultReporter) codeLocationBlock(report types.SpecReport, highlightCo
}
labels = append(labels, report.LeafNodeLabels)
semVerConstraints = append(semVerConstraints, report.LeafNodeSemVerConstraints)
+ componentSemVerConstraints = append(componentSemVerConstraints, report.LeafNodeComponentSemVerConstraints)
locations = append(locations, report.LeafNodeLocation)
failureLocation := report.Failure.FailureNodeLocation
@@ -749,6 +817,7 @@ func (r *DefaultReporter) codeLocationBlock(report types.SpecReport, highlightCo
locations = append([]types.CodeLocation{failureLocation}, locations...)
labels = append([][]string{{}}, labels...)
semVerConstraints = append([][]string{{}}, semVerConstraints...)
+ componentSemVerConstraints = append([]map[string][]string{{}}, componentSemVerConstraints...)
highlightIndex = 0
case types.FailureNodeInContainer:
i := report.Failure.FailureNodeContainerIndex
@@ -779,6 +848,9 @@ func (r *DefaultReporter) codeLocationBlock(report types.SpecReport, highlightCo
if len(semVerConstraints[i]) > 0 {
out += r.f(" {{coral}}[%s]{{/}}", strings.Join(semVerConstraints[i], ", "))
}
+ if len(componentSemVerConstraints[i]) > 0 {
+ out += r.f(" {{coral}}[%s]{{/}}", formatComponentSemVerConstraintsToString(componentSemVerConstraints[i]))
+ }
out += "\n"
out += r.fi(uint(i), "{{gray}}%s{{/}}\n", locations[i])
}
@@ -806,6 +878,10 @@ func (r *DefaultReporter) codeLocationBlock(report types.SpecReport, highlightCo
if len(flattenedSemVerConstraints) > 0 {
out += r.f(" {{coral}}[%s]{{/}}", strings.Join(flattenedSemVerConstraints, ", "))
}
+ flattenedComponentSemVerConstraints := report.ComponentSemVerConstraints()
+ if len(flattenedComponentSemVerConstraints) > 0 {
+ out += r.f(" {{coral}}[%s]{{/}}", formatComponentSemVerConstraintsToString(flattenedComponentSemVerConstraints))
+ }
out += "\n"
if usePreciseFailureLocation {
out += r.f("{{gray}}%s{{/}}", failureLocation)
diff --git a/vendor/github.com/onsi/ginkgo/v2/reporters/junit_report.go b/vendor/github.com/onsi/ginkgo/v2/reporters/junit_report.go
index 828f893fb..d4720ee94 100644
--- a/vendor/github.com/onsi/ginkgo/v2/reporters/junit_report.go
+++ b/vendor/github.com/onsi/ginkgo/v2/reporters/junit_report.go
@@ -13,9 +13,11 @@ package reporters
import (
"encoding/xml"
"fmt"
+ "maps"
"os"
"path"
"regexp"
+ "slices"
"strings"
"github.com/onsi/ginkgo/v2/config"
@@ -39,6 +41,9 @@ type JunitReportConfig struct {
// Enable OmitSpecSemVerConstraints to prevent semantic version constraints from appearing in the spec name
OmitSpecSemVerConstraints bool
+ // Enable OmitSpecComponentSemVerConstraints to prevent component semantic version constraints from appearing in the spec name
+ OmitSpecComponentSemVerConstraints bool
+
// Enable OmitLeafNodeType to prevent the spec leaf node type from appearing in the spec name
OmitLeafNodeType bool
@@ -173,6 +178,7 @@ func GenerateJUnitReportWithConfig(report types.Report, dst string, config Junit
{"SpecialSuiteFailureReason", strings.Join(report.SpecialSuiteFailureReasons, ",")},
{"SuiteLabels", fmt.Sprintf("[%s]", strings.Join(report.SuiteLabels, ","))},
{"SuiteSemVerConstraints", fmt.Sprintf("[%s]", strings.Join(report.SuiteSemVerConstraints, ","))},
+ {"SuiteComponentSemVerConstraints", fmt.Sprintf("[%s]", formatComponentSemVerConstraintsToString(report.SuiteComponentSemVerConstraints))},
{"RandomSeed", fmt.Sprintf("%d", report.SuiteConfig.RandomSeed)},
{"RandomizeAllSpecs", fmt.Sprintf("%t", report.SuiteConfig.RandomizeAllSpecs)},
{"LabelFilter", report.SuiteConfig.LabelFilter},
@@ -216,6 +222,10 @@ func GenerateJUnitReportWithConfig(report types.Report, dst string, config Junit
if len(semVerConstraints) > 0 && !config.OmitSpecSemVerConstraints {
name = name + " [" + strings.Join(semVerConstraints, ", ") + "]"
}
+ componentSemVerConstraints := spec.ComponentSemVerConstraints()
+ if len(componentSemVerConstraints) > 0 && !config.OmitSpecComponentSemVerConstraints {
+ name = name + " [" + formatComponentSemVerConstraintsToString(componentSemVerConstraints) + "]"
+ }
name = strings.TrimSpace(name)
test := JUnitTestCase{
@@ -387,6 +397,16 @@ func systemOutForUnstructuredReporters(spec types.SpecReport) string {
return spec.CapturedStdOutErr
}
+func formatComponentSemVerConstraintsToString(componentSemVerConstraints map[string][]string) string {
+ var tmpStr string
+ for _, key := range slices.Sorted(maps.Keys(componentSemVerConstraints)) {
+ tmpStr = tmpStr + fmt.Sprintf("%s: %s, ", key, componentSemVerConstraints[key])
+ }
+
+ tmpStr = strings.TrimSuffix(tmpStr, ", ")
+ return tmpStr
+}
+
// Deprecated JUnitReporter (so folks can still compile their suites)
type JUnitReporter struct{}
diff --git a/vendor/github.com/onsi/ginkgo/v2/reporters/teamcity_report.go b/vendor/github.com/onsi/ginkgo/v2/reporters/teamcity_report.go
index 55e1d1f4f..ed3e3a2bb 100644
--- a/vendor/github.com/onsi/ginkgo/v2/reporters/teamcity_report.go
+++ b/vendor/github.com/onsi/ginkgo/v2/reporters/teamcity_report.go
@@ -39,12 +39,16 @@ func GenerateTeamcityReport(report types.Report, dst string) error {
name := report.SuiteDescription
labels := report.SuiteLabels
semVerConstraints := report.SuiteSemVerConstraints
+ componentSemVerConstraints := report.SuiteComponentSemVerConstraints
if len(labels) > 0 {
name = name + " [" + strings.Join(labels, ", ") + "]"
}
if len(semVerConstraints) > 0 {
name = name + " [" + strings.Join(semVerConstraints, ", ") + "]"
}
+ if len(componentSemVerConstraints) > 0 {
+ name = name + " [" + formatComponentSemVerConstraintsToString(componentSemVerConstraints) + "]"
+ }
fmt.Fprintf(f, "##teamcity[testSuiteStarted name='%s']\n", tcEscape(name))
for _, spec := range report.SpecReports {
name := fmt.Sprintf("[%s]", spec.LeafNodeType)
@@ -59,6 +63,10 @@ func GenerateTeamcityReport(report types.Report, dst string) error {
if len(semVerConstraints) > 0 {
name = name + " [" + strings.Join(semVerConstraints, ", ") + "]"
}
+ componentSemVerConstraints := spec.ComponentSemVerConstraints()
+ if len(componentSemVerConstraints) > 0 {
+ name = name + " [" + formatComponentSemVerConstraintsToString(componentSemVerConstraints) + "]"
+ }
name = tcEscape(name)
fmt.Fprintf(f, "##teamcity[testStarted name='%s']\n", name)
diff --git a/vendor/github.com/onsi/ginkgo/v2/types/config.go b/vendor/github.com/onsi/ginkgo/v2/types/config.go
index f84703604..854fec6a3 100644
--- a/vendor/github.com/onsi/ginkgo/v2/types/config.go
+++ b/vendor/github.com/onsi/ginkgo/v2/types/config.go
@@ -38,6 +38,7 @@ type SuiteConfig struct {
OutputInterceptorMode string
SourceRoots []string
GracePeriod time.Duration
+ SleepOnFailure time.Duration
ParallelProcess int
ParallelTotal int
@@ -94,6 +95,7 @@ type ReporterConfig struct {
GithubOutput bool
SilenceSkips bool
ForceNewlines bool
+ FdOutput bool
JSONReport string
GoJSONReport string
@@ -215,6 +217,7 @@ type GoFlagsConfig struct {
N bool
ModFile string
ModCacheRW bool
+ ASan bool
MSan bool
PkgDir string
Tags string
@@ -292,6 +295,8 @@ var SuiteConfigFlags = GinkgoFlags{
Usage: "Make up to this many attempts to run each spec. If any of the attempts succeed, the suite will not be failed."},
{KeyPath: "S.FailOnEmpty", Name: "fail-on-empty", SectionKey: "failure",
Usage: "If set, ginkgo will mark the test suite as failed if no specs are run."},
+ {KeyPath: "S.SleepOnFailure", Name: "sleep-on-failure", SectionKey: "failure", UsageDefaultValue: "0 - disabled",
+ Usage: "If set, ginkgo will pause for this duration after a spec fails - before its teardown (AfterEach/JustAfterEach/DeferCleanup) runs - so you can inspect the live system. Press ^C to end the pause early and proceed to cleanup. Serial only: cannot be combined with -p/--procs."},
{KeyPath: "S.DryRun", Name: "dry-run", SectionKey: "debug", DeprecatedName: "dryRun", DeprecatedDocLink: "changed-command-line-flags",
Usage: "If set, ginkgo will walk the test hierarchy without actually running anything. Best paired with -v."},
@@ -357,7 +362,8 @@ var ReporterConfigFlags = GinkgoFlags{
Usage: "If set, default reporter will not print out skipped tests."},
{KeyPath: "R.ForceNewlines", Name: "force-newlines", SectionKey: "output",
Usage: "If set, default reporter will ensure a newline appears after each test."},
-
+ {KeyPath: "R.FdOutput", Name: "fd", SectionKey: "output",
+ Usage: "If set, emits RSpec-style 'format documentation' output instead of Ginkgo's default output. --fd is exclusive: it overrides -p/-procs and -randomize-all, forcing specs to run serially in declaration order, since fd's hierarchical output can't be rendered sensibly when specs are parallelized or randomized."},
{KeyPath: "R.JSONReport", Name: "json-report", UsageArgument: "filename.json", SectionKey: "output",
Usage: "If set, Ginkgo will generate a JSON-formatted test report at the specified location."},
{KeyPath: "R.GoJSONReport", Name: "gojson-report", UsageArgument: "filename.json", SectionKey: "output",
@@ -428,6 +434,14 @@ func VetConfig(flagSet GinkgoFlagSet, suiteConfig SuiteConfig, reporterConfig Re
errors = append(errors, GinkgoErrors.GracePeriodCannotBeZero())
}
+ if suiteConfig.SleepOnFailure < 0 {
+ errors = append(errors, GinkgoErrors.InvalidSleepOnFailureConfiguration())
+ }
+
+ if suiteConfig.SleepOnFailure > 0 && suiteConfig.ParallelTotal > 1 {
+ errors = append(errors, GinkgoErrors.SleepOnFailureInParallelConfiguration())
+ }
+
if len(suiteConfig.FocusFiles) > 0 {
_, err := ParseFileFilters(suiteConfig.FocusFiles)
if err != nil {
@@ -475,6 +489,30 @@ func VetConfig(flagSet GinkgoFlagSet, suiteConfig SuiteConfig, reporterConfig Re
return errors
}
+// ReconcileFdOutputConfiguration forces serial, in-order execution when --fd is combined with
+// -p, -procs (>1), or -randomize-all. fd's RSpec-style hierarchical output assumes specs run
+// one at a time, in declaration order -- parallelism and randomization both break that assumption
+// and produce fragmented, hard-to-read output. Rather than refusing to run, Ginkgo ignores those
+// flags and runs in series instead. suiteConfig and cliConfig are mutated in place; the return
+// value is true if anything was overridden, so callers can let the user know what was ignored.
+func ReconcileFdOutputConfiguration(reporterConfig ReporterConfig, suiteConfig *SuiteConfig, cliConfig *CLIConfig) bool {
+ if !reporterConfig.FdOutput {
+ return false
+ }
+
+ changed := false
+ if cliConfig.ComputedProcs() > 1 {
+ cliConfig.Procs = 1
+ cliConfig.Parallel = false
+ changed = true
+ }
+ if suiteConfig.RandomizeAllSpecs {
+ suiteConfig.RandomizeAllSpecs = false
+ changed = true
+ }
+ return changed
+}
+
// GinkgoCLISharedFlags provides flags shared by the Ginkgo CLI's build, watch, and run commands
var GinkgoCLISharedFlags = GinkgoFlags{
{KeyPath: "C.Recurse", Name: "r", SectionKey: "multiple-suites",
@@ -570,6 +608,8 @@ var GoBuildFlags = GinkgoFlags{
Usage: "leave newly-created directories in the module cache read-write instead of making them read-only."},
{KeyPath: "Go.ModFile", Name: "modfile", UsageArgument: "file", SectionKey: "go-build",
Usage: `in module aware mode, read (and possibly write) an alternate go.mod file instead of the one in the module root directory. A file named go.mod must still be present in order to determine the module root directory, but it is not accessed. When -modfile is specified, an alternate go.sum file is also used: its path is derived from the -modfile flag by trimming the ".mod" extension and appending ".sum".`},
+ {KeyPath: "Go.ASan", Name: "asan", SectionKey: "go-build",
+ Usage: "enable interoperation with address sanitizer."},
{KeyPath: "Go.MSan", Name: "msan", SectionKey: "go-build",
Usage: "enable interoperation with memory sanitizer. Supported only on linux/amd64, linux/arm64 and only with Clang/LLVM as the host C compiler. On linux/arm64, pie build mode will be used."},
{KeyPath: "Go.N", Name: "n", SectionKey: "go-build",
diff --git a/vendor/github.com/onsi/ginkgo/v2/types/errors.go b/vendor/github.com/onsi/ginkgo/v2/types/errors.go
index 59313238c..636070c12 100644
--- a/vendor/github.com/onsi/ginkgo/v2/types/errors.go
+++ b/vendor/github.com/onsi/ginkgo/v2/types/errors.go
@@ -450,6 +450,15 @@ func (g ginkgoErrors) InvalidEmptySemVerConstraint(cl CodeLocation) error {
}
}
+func (g ginkgoErrors) InvalidEmptyComponentForSemVerConstraint(cl CodeLocation) error {
+ return GinkgoError{
+ Heading: "Invalid Empty Component for ComponentSemVerConstraint",
+ Message: "ComponentSemVerConstraint requires a non-empty component name",
+ CodeLocation: cl,
+ DocLink: "spec-semantic-version-filtering",
+ }
+}
+
/* Table errors */
func (g ginkgoErrors) MultipleEntryBodyFunctionsForTable(cl CodeLocation) error {
return GinkgoError{
@@ -612,6 +621,21 @@ func (g ginkgoErrors) GracePeriodCannotBeZero() error {
}
}
+func (g ginkgoErrors) InvalidSleepOnFailureConfiguration() error {
+ return GinkgoError{
+ Heading: "Ginkgo requires a non-negative --sleep-on-failure.",
+ Message: "Please set --sleep-on-failure to a positive duration (e.g. 5m), or 0 to disable it.",
+ }
+}
+
+func (g ginkgoErrors) SleepOnFailureInParallelConfiguration() error {
+ return GinkgoError{
+ Heading: "Ginkgo only supports --sleep-on-failure in serial mode.",
+ Message: "--sleep-on-failure pauses a failed spec on a live system for inspection, which only makes sense when the suite runs serially. Please run again without -p or --procs, or unset --sleep-on-failure.",
+ DocLink: "spec-timeouts-and-interruptible-nodes",
+ }
+}
+
func (g ginkgoErrors) ConflictingVerbosityConfiguration() error {
return GinkgoError{
Heading: "Conflicting reporter verbosity settings.",
diff --git a/vendor/github.com/onsi/ginkgo/v2/types/flags.go b/vendor/github.com/onsi/ginkgo/v2/types/flags.go
index 8409653f9..eb04c3e78 100644
--- a/vendor/github.com/onsi/ginkgo/v2/types/flags.go
+++ b/vendor/github.com/onsi/ginkgo/v2/types/flags.go
@@ -212,6 +212,24 @@ func (f GinkgoFlagSet) IsZero() bool {
return f.flagSet == nil
}
+func (f GinkgoFlagSet) Completion(arg string) map[string]string {
+ if f.IsZero() {
+ return nil
+ }
+ prefix := strings.TrimLeft(arg, "-")
+ dash := arg[:len(arg)-len(prefix)]
+ if len(dash) < 1 || len(dash) > 3 {
+ return nil
+ }
+ result := make(map[string]string, len(f.flags))
+ for _, flag := range f.flags {
+ if flag.Name != "" && strings.HasPrefix(flag.Name, prefix) {
+ result[dash+flag.Name] = flag.Usage
+ }
+ }
+ return result
+}
+
func (f GinkgoFlagSet) WasSet(name string) bool {
found := false
f.flagSet.Visit(func(f *flag.Flag) {
diff --git a/vendor/github.com/onsi/ginkgo/v2/types/semver_filter.go b/vendor/github.com/onsi/ginkgo/v2/types/semver_filter.go
index 3fc2ed144..71778078d 100644
--- a/vendor/github.com/onsi/ginkgo/v2/types/semver_filter.go
+++ b/vendor/github.com/onsi/ginkgo/v2/types/semver_filter.go
@@ -2,11 +2,12 @@ package types
import (
"fmt"
+ "strings"
"github.com/Masterminds/semver/v3"
)
-type SemVerFilter func([]string) bool
+type SemVerFilter func(component string, constraints []string) bool
func MustParseSemVerFilter(input string) SemVerFilter {
filter, err := ParseSemVerFilter(input)
@@ -16,30 +17,90 @@ func MustParseSemVerFilter(input string) SemVerFilter {
return filter
}
-func ParseSemVerFilter(filterVersion string) (SemVerFilter, error) {
- if filterVersion == "" {
- return func(_ []string) bool { return true }, nil
+// ParseSemVerFilter parses non-component and component-specific semantic version filter string.
+// The filter string can contain multiple non-component and component-specific versions separated by commas.
+// Each component-specific version is in the format "component=version".
+// If a version is specified without a component, it applies to non-component-specific constraints.
+func ParseSemVerFilter(componentFilterVersions string) (SemVerFilter, error) {
+ if componentFilterVersions == "" {
+ return func(_ string, _ []string) bool { return true }, nil
}
- targetVersion, err := semver.NewVersion(filterVersion)
- if err != nil {
- return nil, fmt.Errorf("invalid filter version: %w", err)
+ result := map[string]*semver.Version{}
+ parts := strings.Split(componentFilterVersions, ",")
+ for _, part := range parts {
+ part = strings.TrimSpace(part)
+ if len(part) == 0 {
+ continue
+ }
+ if strings.Contains(part, "=") {
+ // validate component-specific version string
+ invalidPart, invalidErr := false, fmt.Errorf("invalid component filter version: %s", part)
+ subParts := strings.Split(part, "=")
+ if len(subParts) != 2 {
+ invalidPart = true
+ }
+ component := strings.TrimSpace(subParts[0])
+ versionStr := strings.TrimSpace(subParts[1])
+ if len(component) == 0 || len(versionStr) == 0 {
+ invalidPart = true
+ }
+ if invalidPart {
+ return nil, invalidErr
+ }
+
+ // validate semver
+ v, err := semver.NewVersion(versionStr)
+ if err != nil {
+ return nil, fmt.Errorf("invalid component filter version: %s, error: %w", part, err)
+ }
+ result[component] = v
+ } else {
+ v, err := semver.NewVersion(part)
+ if err != nil {
+ return nil, fmt.Errorf("invalid filter version: %s, error: %w", part, err)
+ }
+ result[""] = v
+ }
}
- return func(constraints []string) bool {
+ return func(component string, constraints []string) bool {
// unconstrained specs always run
- if len(constraints) == 0 {
+ if len(component) == 0 && len(constraints) == 0 {
return true
}
- for _, constraintStr := range constraints {
- constraint, err := semver.NewConstraint(constraintStr)
- if err != nil {
- return false
+ // check non-component specific version constraints
+ if len(component) == 0 && len(constraints) != 0 {
+ v := result[""]
+ if v != nil {
+ for _, constraintStr := range constraints {
+ constraint, err := semver.NewConstraint(constraintStr)
+ if err != nil {
+ return false
+ }
+
+ if !constraint.Check(v) {
+ return false
+ }
+ }
}
+ }
+
+ // check component-specific version constraints
+ if len(component) != 0 && len(constraints) != 0 {
+ v := result[component]
+ if v != nil {
+ for _, constraintStr := range constraints {
+ constraint, err := semver.NewConstraint(constraintStr)
+ if err != nil {
+ return false
+ }
- if !constraint.Check(targetVersion) {
- return false
+ if !constraint.Check(v) {
+ return false
+ }
+ }
}
}
diff --git a/vendor/github.com/onsi/ginkgo/v2/types/types.go b/vendor/github.com/onsi/ginkgo/v2/types/types.go
index 9981a0dd6..240150512 100644
--- a/vendor/github.com/onsi/ginkgo/v2/types/types.go
+++ b/vendor/github.com/onsi/ginkgo/v2/types/types.go
@@ -38,6 +38,10 @@ type ConstructionNodeReport struct {
// all Describe/Context/When containers in this spec's hierarchy
ContainerHierarchySemVerConstraints [][]string
+ // ContainerHierarchyComponentSemVerConstraints is a slice containing the component-specific semVerConstraints of
+ // all Describe/Context/When containers in this spec's hierarchy
+ ContainerHierarchyComponentSemVerConstraints []map[string][]string
+
// IsSerial captures whether the any container has the Serial decorator
IsSerial bool
@@ -85,6 +89,9 @@ type Report struct {
//SuiteSemVerConstraints captures any semVerConstraints attached to the suite by the DSL's RunSpecs() function
SuiteSemVerConstraints []string
+ //SuiteComponentSemVerConstraints captures any component-specific semVerConstraints attached to the suite by the DSL's RunSpecs() function
+ SuiteComponentSemVerConstraints map[string][]string
+
//SuiteSucceeded captures the success or failure status of the test run
//If true, the test run is considered successful.
//If false, the test run is considered unsuccessful
@@ -188,14 +195,19 @@ type SpecReport struct {
// all Describe/Context/When containers in this spec's hierarchy
ContainerHierarchySemVerConstraints [][]string
+ // ContainerHierarchyComponentSemVerConstraints is a slice containing the component-specific semVerConstraints of
+ // all Describe/Context/When containers in this spec's hierarchy
+ ContainerHierarchyComponentSemVerConstraints []map[string][]string
+
// LeafNodeType, LeafNodeLocation, LeafNodeLabels, LeafNodeSemVerConstraints and LeafNodeText capture the NodeType, CodeLocation, and text
// of the Ginkgo node being tested (typically an NodeTypeIt node, though this can also be
// one of the NodeTypesForSuiteLevelNodes node types)
- LeafNodeType NodeType
- LeafNodeLocation CodeLocation
- LeafNodeLabels []string
- LeafNodeSemVerConstraints []string
- LeafNodeText string
+ LeafNodeType NodeType
+ LeafNodeLocation CodeLocation
+ LeafNodeLabels []string
+ LeafNodeSemVerConstraints []string
+ LeafNodeComponentSemVerConstraints map[string][]string
+ LeafNodeText string
// Captures the Spec Priority
SpecPriority int
@@ -261,52 +273,54 @@ type SpecReport struct {
func (report SpecReport) MarshalJSON() ([]byte, error) {
//All this to avoid emitting an empty Failure struct in the JSON
out := struct {
- ContainerHierarchyTexts []string
- ContainerHierarchyLocations []CodeLocation
- ContainerHierarchyLabels [][]string
- ContainerHierarchySemVerConstraints [][]string
- LeafNodeType NodeType
- LeafNodeLocation CodeLocation
- LeafNodeLabels []string
- LeafNodeSemVerConstraints []string
- LeafNodeText string
- State SpecState
- StartTime time.Time
- EndTime time.Time
- RunTime time.Duration
- ParallelProcess int
- Failure *Failure `json:",omitempty"`
- NumAttempts int
- MaxFlakeAttempts int
- MaxMustPassRepeatedly int
- CapturedGinkgoWriterOutput string `json:",omitempty"`
- CapturedStdOutErr string `json:",omitempty"`
- ReportEntries ReportEntries `json:",omitempty"`
- ProgressReports []ProgressReport `json:",omitempty"`
- AdditionalFailures []AdditionalFailure `json:",omitempty"`
- SpecEvents SpecEvents `json:",omitempty"`
+ ContainerHierarchyTexts []string
+ ContainerHierarchyLocations []CodeLocation
+ ContainerHierarchyLabels [][]string
+ ContainerHierarchySemVerConstraints [][]string
+ ContainerHierarchyComponentSemVerConstraints []map[string][]string
+ LeafNodeType NodeType
+ LeafNodeLocation CodeLocation
+ LeafNodeLabels []string
+ LeafNodeSemVerConstraints []string
+ LeafNodeText string
+ State SpecState
+ StartTime time.Time
+ EndTime time.Time
+ RunTime time.Duration
+ ParallelProcess int
+ Failure *Failure `json:",omitempty"`
+ NumAttempts int
+ MaxFlakeAttempts int
+ MaxMustPassRepeatedly int
+ CapturedGinkgoWriterOutput string `json:",omitempty"`
+ CapturedStdOutErr string `json:",omitempty"`
+ ReportEntries ReportEntries `json:",omitempty"`
+ ProgressReports []ProgressReport `json:",omitempty"`
+ AdditionalFailures []AdditionalFailure `json:",omitempty"`
+ SpecEvents SpecEvents `json:",omitempty"`
}{
- ContainerHierarchyTexts: report.ContainerHierarchyTexts,
- ContainerHierarchyLocations: report.ContainerHierarchyLocations,
- ContainerHierarchyLabels: report.ContainerHierarchyLabels,
- ContainerHierarchySemVerConstraints: report.ContainerHierarchySemVerConstraints,
- LeafNodeType: report.LeafNodeType,
- LeafNodeLocation: report.LeafNodeLocation,
- LeafNodeLabels: report.LeafNodeLabels,
- LeafNodeSemVerConstraints: report.LeafNodeSemVerConstraints,
- LeafNodeText: report.LeafNodeText,
- State: report.State,
- StartTime: report.StartTime,
- EndTime: report.EndTime,
- RunTime: report.RunTime,
- ParallelProcess: report.ParallelProcess,
- Failure: nil,
- ReportEntries: nil,
- NumAttempts: report.NumAttempts,
- MaxFlakeAttempts: report.MaxFlakeAttempts,
- MaxMustPassRepeatedly: report.MaxMustPassRepeatedly,
- CapturedGinkgoWriterOutput: report.CapturedGinkgoWriterOutput,
- CapturedStdOutErr: report.CapturedStdOutErr,
+ ContainerHierarchyTexts: report.ContainerHierarchyTexts,
+ ContainerHierarchyLocations: report.ContainerHierarchyLocations,
+ ContainerHierarchyLabels: report.ContainerHierarchyLabels,
+ ContainerHierarchySemVerConstraints: report.ContainerHierarchySemVerConstraints,
+ ContainerHierarchyComponentSemVerConstraints: report.ContainerHierarchyComponentSemVerConstraints,
+ LeafNodeType: report.LeafNodeType,
+ LeafNodeLocation: report.LeafNodeLocation,
+ LeafNodeLabels: report.LeafNodeLabels,
+ LeafNodeSemVerConstraints: report.LeafNodeSemVerConstraints,
+ LeafNodeText: report.LeafNodeText,
+ State: report.State,
+ StartTime: report.StartTime,
+ EndTime: report.EndTime,
+ RunTime: report.RunTime,
+ ParallelProcess: report.ParallelProcess,
+ Failure: nil,
+ ReportEntries: nil,
+ NumAttempts: report.NumAttempts,
+ MaxFlakeAttempts: report.MaxFlakeAttempts,
+ MaxMustPassRepeatedly: report.MaxMustPassRepeatedly,
+ CapturedGinkgoWriterOutput: report.CapturedGinkgoWriterOutput,
+ CapturedStdOutErr: report.CapturedStdOutErr,
}
if !report.Failure.IsZero() {
@@ -404,6 +418,34 @@ func (report SpecReport) SemVerConstraints() []string {
return out
}
+// ComponentSemVerConstraints returns a deduped map of all the spec's component-specific SemVerConstraints.
+func (report SpecReport) ComponentSemVerConstraints() map[string][]string {
+ out := map[string][]string{}
+ seen := map[string]bool{}
+ for _, compSemVerConstraints := range report.ContainerHierarchyComponentSemVerConstraints {
+ for component := range compSemVerConstraints {
+ if !seen[component] {
+ seen[component] = true
+ out[component] = compSemVerConstraints[component]
+ } else {
+ out[component] = append(out[component], compSemVerConstraints[component]...)
+ out[component] = slices.Compact(out[component])
+ }
+ }
+ }
+ for component := range report.LeafNodeComponentSemVerConstraints {
+ if !seen[component] {
+ seen[component] = true
+ out[component] = report.LeafNodeComponentSemVerConstraints[component]
+ } else {
+ out[component] = append(out[component], report.LeafNodeComponentSemVerConstraints[component]...)
+ out[component] = slices.Compact(out[component])
+ }
+ }
+
+ return out
+}
+
// MatchesLabelFilter returns true if the spec satisfies the passed in label filter query
func (report SpecReport) MatchesLabelFilter(query string) (bool, error) {
filter, err := ParseLabelFilter(query)
@@ -419,7 +461,22 @@ func (report SpecReport) MatchesSemVerFilter(version string) (bool, error) {
if err != nil {
return false, err
}
- return filter(report.SemVerConstraints()), nil
+
+ semVerConstraints := report.SemVerConstraints()
+ if len(semVerConstraints) != 0 && filter("", report.SemVerConstraints()) == false {
+ return false, nil
+ }
+
+ componentSemVerConstraints := report.ComponentSemVerConstraints()
+ if len(componentSemVerConstraints) != 0 {
+ for component, constraints := range componentSemVerConstraints {
+ if filter(component, constraints) == false {
+ return false, nil
+ }
+ }
+ }
+
+ return true, nil
}
// FileName() returns the name of the file containing the spec
diff --git a/vendor/github.com/onsi/ginkgo/v2/types/version.go b/vendor/github.com/onsi/ginkgo/v2/types/version.go
index 66cbbcf3c..177baed9b 100644
--- a/vendor/github.com/onsi/ginkgo/v2/types/version.go
+++ b/vendor/github.com/onsi/ginkgo/v2/types/version.go
@@ -1,3 +1,3 @@
package types
-const VERSION = "2.27.4"
+const VERSION = "2.32.1"
diff --git a/vendor/github.com/onsi/gomega/CHANGELOG.md b/vendor/github.com/onsi/gomega/CHANGELOG.md
index cf020605c..9c94d0e6c 100644
--- a/vendor/github.com/onsi/gomega/CHANGELOG.md
+++ b/vendor/github.com/onsi/gomega/CHANGELOG.md
@@ -1,3 +1,15 @@
+## 1.40.0
+
+We're adopting a new release strategy to minimize dependency bloat in projects that consume Gomega. It is a limitation of the go mod toolchain that _test_ subdependencies of your project's direct dependencies get pulled in as *indirect* dependencies. In the case of Gomega, this ends up pulling in all of Ginkgo into your `go.mod` even if you are only using Gomega (Gomega uses Ginkgo for its own tests).
+
+Going forward, releases will strip out all tests, tidy up the `go.mod` and then push this stripped down version to a new `master-lite` branch. These stripped-down versions will receive the `vx.y.z` git tag and will be picked up by the go toolchain.
+
+Please open an issue if this new release process causes unexpected changes for your projects.
+
+## 1.39.1
+
+Update all dependencies. This auto-updated the required version of Go to 1.24, consistent with the fact that Go 1.23 has been out of support for almost six months.
+
## 1.39.0
### Features
diff --git a/vendor/github.com/onsi/gomega/gomega_dsl.go b/vendor/github.com/onsi/gomega/gomega_dsl.go
index cd6ce450f..af1341bdb 100644
--- a/vendor/github.com/onsi/gomega/gomega_dsl.go
+++ b/vendor/github.com/onsi/gomega/gomega_dsl.go
@@ -22,7 +22,7 @@ import (
"github.com/onsi/gomega/types"
)
-const GOMEGA_VERSION = "1.39.0"
+const GOMEGA_VERSION = "1.40.0"
const nilGomegaPanic = `You are trying to make an assertion, but haven't registered Gomega's fail handler.
If you're using Ginkgo then you probably forgot to put your assertion in an It().
diff --git a/vendor/github.com/openshift/build-machinery-go/.gitignore b/vendor/github.com/openshift/build-machinery-go/.gitignore
index 19607d9e6..0ff90ea9b 100644
--- a/vendor/github.com/openshift/build-machinery-go/.gitignore
+++ b/vendor/github.com/openshift/build-machinery-go/.gitignore
@@ -1 +1,2 @@
*.log.raw
+make/examples/golang-versions-check/_output/
diff --git a/vendor/github.com/openshift/build-machinery-go/OWNERS b/vendor/github.com/openshift/build-machinery-go/OWNERS
index 1bbac46c7..c54ee52b6 100644
--- a/vendor/github.com/openshift/build-machinery-go/OWNERS
+++ b/vendor/github.com/openshift/build-machinery-go/OWNERS
@@ -1,9 +1,9 @@
reviewers:
+ - control-plane-approvers
- 2uasimojo
- - benluddy
- jsafrane
- sanchezl
approvers:
- - benluddy
+ - control-plane-approvers
- jsafrane
- sanchezl
diff --git a/vendor/github.com/openshift/build-machinery-go/OWNERS_ALIASES b/vendor/github.com/openshift/build-machinery-go/OWNERS_ALIASES
new file mode 100644
index 000000000..66464a003
--- /dev/null
+++ b/vendor/github.com/openshift/build-machinery-go/OWNERS_ALIASES
@@ -0,0 +1,16 @@
+aliases:
+ control-plane-approvers:
+ - ardaguclu
+ - atiratree
+ - benluddy
+ - bertinatto
+ - everettraven
+ - flavianmissi
+ - gangwgr
+ - ingvagabund
+ - kaleemsiddiqu
+ - p0lyn0mial
+ - rh-roman
+ - ricardomaraschini
+ - tjungblu
+ - xueqzhan
diff --git a/vendor/github.com/openshift/build-machinery-go/make/lib/golang.mk b/vendor/github.com/openshift/build-machinery-go/make/lib/golang.mk
index d08f74a42..6674f7eb6 100644
--- a/vendor/github.com/openshift/build-machinery-go/make/lib/golang.mk
+++ b/vendor/github.com/openshift/build-machinery-go/make/lib/golang.mk
@@ -60,10 +60,17 @@ ifndef OS_GIT_VERSION
OS_GIT_VERSION = $(SOURCE_GIT_TAG)
endif
+# OS_MAJOR_VERSION is populated by ART
+# If building out of the ART pipeline, fallback to '0' and let implementations decide how they handle it
+ifndef OS_MAJOR_VERSION
+ OS_MAJOR_VERSION = "0"
+endif
+
define version-ldflags
-X $(1).versionFromGit="$(OS_GIT_VERSION)" \
-X $(1).commitFromGit="$(SOURCE_GIT_COMMIT)" \
-X $(1).gitTreeState="$(SOURCE_GIT_TREE_STATE)" \
--X $(1).buildDate="$(shell date -u +'%Y-%m-%dT%H:%M:%SZ')"
+-X $(1).buildDate="$(shell date -u +'%Y-%m-%dT%H:%M:%SZ')" \
+-X $(1).majorFromGit="$(OS_MAJOR_VERSION)"
endef
GO_LD_FLAGS ?=-ldflags "$(call version-ldflags,$(GO_PACKAGE)/pkg/version) $(GO_LD_EXTRAFLAGS)"
diff --git a/vendor/github.com/openshift/build-machinery-go/make/targets/golang/version.mk b/vendor/github.com/openshift/build-machinery-go/make/targets/golang/version.mk
index bdd7f479d..9692c1d82 100644
--- a/vendor/github.com/openshift/build-machinery-go/make/targets/golang/version.mk
+++ b/vendor/github.com/openshift/build-machinery-go/make/targets/golang/version.mk
@@ -1,3 +1,23 @@
+# verify-golang-versions — ensure Go versions are consistent across build sources.
+#
+# OpenShift repos declare a Go version in up to three places: go.mod,
+# Dockerfile (builder image tag), and .ci-operator.yaml (CI build root).
+# When these drift apart, builds can silently use the wrong Go version or
+# fail in hard-to-diagnose ways. In particular, if go.mod declares a version
+# higher than the CI builder, the build fails because GOTOOLCHAIN=local
+# prevents Go from downloading a newer toolchain. This target catches
+# that drift at verify time by extracting the Go MAJOR.MINOR from each source
+# and comparing them.
+#
+# Rules:
+# 1. All CI sources (Dockerfile, .ci-operator.yaml) must declare the same Go version.
+# 2. go.mod may declare a version <= the CI version (Go is backward-compatible).
+# 3. go.mod must NOT declare a version higher than the CI builder.
+# 4. Every extracted version must be a valid MAJOR.MINOR number.
+#
+# Usage:
+# $(call verify-golang-versions,Dockerfile.rhel7)
+
include $(addprefix $(dir $(lastword $(MAKEFILE_LIST))), \
../../lib/golang.mk \
../../lib/tmp.mk \
@@ -9,11 +29,28 @@ include $(addprefix $(dir $(lastword $(MAKEFILE_LIST))), \
verify-golang-versions:
@if [ -f "$(PERMANENT_TMP)/golang-versions" ]; then \
- LINES=$$(cat "$(PERMANENT_TMP)/golang-versions" | sort | uniq | wc -l); \
- if [ $${LINES} -gt 1 ]; then \
+ GOMOD_VER=""; \
+ CI_VER=""; \
+ if [ -f "$(PERMANENT_TMP)/named-golang-versions" ]; then \
+ GOMOD_VER=$$(grep '^go\.mod:' "$(PERMANENT_TMP)/named-golang-versions" | sed 's/go\.mod: *//'); \
+ CI_VER=$$(grep -v '^go\.mod:' "$(PERMANENT_TMP)/named-golang-versions" | sed 's/^[^:]*: *//' | sort | uniq); \
+ fi; \
+ CI_COUNT=$$(echo "$${CI_VER}" | grep -c . 2>/dev/null || :); \
+ if [ "$${CI_COUNT}" -gt 1 ]; then \
echo "Golang version mismatch:"; \
cat "$(PERMANENT_TMP)/named-golang-versions" | sort | sed 's/^/- /'; \
false; \
+ elif [ -n "$${GOMOD_VER}" ] && [ -n "$${CI_VER}" ]; then \
+ GOMOD_MAJOR=$$(echo "$${GOMOD_VER}" | cut -d. -f1); \
+ GOMOD_MINOR=$$(echo "$${GOMOD_VER}" | cut -d. -f2); \
+ CI_MAJOR=$$(echo "$${CI_VER}" | cut -d. -f1); \
+ CI_MINOR=$$(echo "$${CI_VER}" | cut -d. -f2); \
+ if [ "$${GOMOD_MAJOR}" -gt "$${CI_MAJOR}" ] 2>/dev/null || \
+ { [ "$${GOMOD_MAJOR}" -eq "$${CI_MAJOR}" ] 2>/dev/null && [ "$${GOMOD_MINOR}" -gt "$${CI_MINOR}" ] 2>/dev/null; }; then \
+ echo "Golang version mismatch:"; \
+ cat "$(PERMANENT_TMP)/named-golang-versions" | sort | sed 's/^/- /'; \
+ false; \
+ fi; \
fi; \
fi
.PHONY: verify-golang-versions
@@ -24,6 +61,10 @@ define verify-golang-version-reference-internal
verify-golang-versions-$(1): .empty-golang-versions-files
verify-golang-versions-$(1):
@mkdir -p "$(PERMANENT_TMP)"
+ @if ! echo "$(2)" | grep -qxE '[0-9]+\.[0-9]+'; then \
+ echo "Error: could not extract a valid golang version from $(1) (got '$(2)')"; \
+ false; \
+ fi
@echo "$(1): $(2)" >> "$(PERMANENT_TMP)/named-golang-versions"
@echo "$(2)" >> "$(PERMANENT_TMP)/golang-versions"
.PHONY: verify-golang-versions-$(1)
diff --git a/vendor/github.com/pelletier/go-toml/v2/.gitignore b/vendor/github.com/pelletier/go-toml/v2/.gitignore
index 4b7c4eda3..eaf580dfd 100644
--- a/vendor/github.com/pelletier/go-toml/v2/.gitignore
+++ b/vendor/github.com/pelletier/go-toml/v2/.gitignore
@@ -5,3 +5,4 @@ cmd/tomljson/tomljson
cmd/tomltestgen/tomltestgen
dist
tests/
+test-results
diff --git a/vendor/github.com/pelletier/go-toml/v2/.golangci.toml b/vendor/github.com/pelletier/go-toml/v2/.golangci.toml
index 067db5517..7d2e5b04c 100644
--- a/vendor/github.com/pelletier/go-toml/v2/.golangci.toml
+++ b/vendor/github.com/pelletier/go-toml/v2/.golangci.toml
@@ -1,84 +1,76 @@
-[service]
-golangci-lint-version = "1.39.0"
-
-[linters-settings.wsl]
-allow-assign-and-anything = true
-
-[linters-settings.exhaustive]
-default-signifies-exhaustive = true
+version = "2"
[linters]
-disable-all = true
+default = "none"
enable = [
"asciicheck",
"bodyclose",
- "cyclop",
- "deadcode",
- "depguard",
"dogsled",
"dupl",
"durationcheck",
"errcheck",
"errorlint",
"exhaustive",
- # "exhaustivestruct",
- "exportloopref",
"forbidigo",
- # "forcetypeassert",
- "funlen",
- "gci",
- # "gochecknoglobals",
"gochecknoinits",
- "gocognit",
"goconst",
"gocritic",
- "gocyclo",
- "godot",
- "godox",
- # "goerr113",
- "gofmt",
- "gofumpt",
+ "godoclint",
"goheader",
- "goimports",
- "golint",
- "gomnd",
- # "gomoddirectives",
"gomodguard",
"goprintffuncname",
"gosec",
- "gosimple",
"govet",
- # "ifshort",
"importas",
"ineffassign",
"lll",
"makezero",
+ "mirror",
"misspell",
"nakedret",
- "nestif",
"nilerr",
- # "nlreturn",
"noctx",
"nolintlint",
- #"paralleltest",
+ "perfsprint",
"prealloc",
"predeclared",
"revive",
"rowserrcheck",
"sqlclosecheck",
"staticcheck",
- "structcheck",
- "stylecheck",
- # "testpackage",
"thelper",
"tparallel",
- "typecheck",
"unconvert",
"unparam",
"unused",
- "varcheck",
+ "usetesting",
"wastedassign",
"whitespace",
- # "wrapcheck",
- # "wsl"
+]
+
+[linters.settings.exhaustive]
+default-signifies-exhaustive = true
+
+[linters.settings.lll]
+line-length = 150
+
+[[linters.exclusions.rules]]
+path = ".test.go"
+linters = ["goconst", "gosec"]
+
+[[linters.exclusions.rules]]
+path = "main.go"
+linters = ["forbidigo"]
+
+[[linters.exclusions.rules]]
+path = "internal"
+linters = ["revive"]
+text = "(exported|indent-error-flow): "
+
+[formatters]
+enable = [
+ "gci",
+ "gofmt",
+ "gofumpt",
+ "goimports",
]
diff --git a/vendor/github.com/pelletier/go-toml/v2/.goreleaser.yaml b/vendor/github.com/pelletier/go-toml/v2/.goreleaser.yaml
index 47f0f5914..3e19ea710 100644
--- a/vendor/github.com/pelletier/go-toml/v2/.goreleaser.yaml
+++ b/vendor/github.com/pelletier/go-toml/v2/.goreleaser.yaml
@@ -22,7 +22,6 @@ builds:
- linux_riscv64
- windows_amd64
- windows_arm64
- - windows_arm
- darwin_amd64
- darwin_arm64
- id: tomljson
@@ -42,7 +41,6 @@ builds:
- linux_riscv64
- windows_amd64
- windows_arm64
- - windows_arm
- darwin_amd64
- darwin_arm64
- id: jsontoml
@@ -62,7 +60,6 @@ builds:
- linux_arm
- windows_amd64
- windows_arm64
- - windows_arm
- darwin_amd64
- darwin_arm64
universal_binaries:
diff --git a/vendor/github.com/pelletier/go-toml/v2/AGENTS.md b/vendor/github.com/pelletier/go-toml/v2/AGENTS.md
new file mode 100644
index 000000000..dafe44d76
--- /dev/null
+++ b/vendor/github.com/pelletier/go-toml/v2/AGENTS.md
@@ -0,0 +1,64 @@
+# Agent Guidelines for go-toml
+
+This file provides guidelines for AI agents contributing to go-toml. All agents must follow these rules derived from [CONTRIBUTING.md](./CONTRIBUTING.md).
+
+## Project Overview
+
+go-toml is a TOML library for Go. The goal is to provide an easy-to-use and efficient TOML implementation that gets the job done without getting in the way.
+
+## Code Change Rules
+
+### Backward Compatibility
+
+- **No backward-incompatible changes** unless explicitly discussed and approved
+- Avoid breaking people's programs unless absolutely necessary
+
+### Testing Requirements
+
+- **All bug fixes must include regression tests**
+- **All new code must be tested**
+- Run tests before submitting: `go test -race ./...`
+- Test coverage must not decrease. Check with:
+ ```bash
+ go test -covermode=atomic -coverprofile=coverage.out
+ go tool cover -func=coverage.out
+ ```
+- All lines of code touched by changes should be covered by tests
+
+### Performance Requirements
+
+- go-toml aims to stay efficient; avoid performance regressions
+- Run benchmarks to verify: `go test ./... -bench=. -count=10`
+- Compare results using [benchstat](https://pkg.go.dev/golang.org/x/perf/cmd/benchstat)
+
+### Documentation
+
+- New features or feature extensions must include documentation
+- Documentation lives in [README.md](./README.md) and throughout source code
+
+### Code Style
+
+- Follow existing code format and structure
+- Code must pass `go fmt`
+- Code must pass linting with the same golangci-lint version as CI (see version in `.github/workflows/lint.yml`):
+ ```bash
+ # Install specific version (check lint.yml for current version)
+ curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/HEAD/install.sh | sh -s -- -b $(go env GOPATH)/bin
+ # Run linter
+ golangci-lint run ./...
+ ```
+
+### Commit Messages
+
+- Commit messages must explain **why** the change is needed
+- Keep messages clear and informative even if details are in the PR description
+
+## Pull Request Checklist
+
+Before submitting:
+
+1. Tests pass (`go test -race ./...`)
+2. No backward-incompatible changes (unless discussed)
+3. Relevant documentation added/updated
+4. No performance regression (verify with benchmarks)
+5. Title is clear and understandable for changelog
diff --git a/vendor/github.com/pelletier/go-toml/v2/CONTRIBUTING.md b/vendor/github.com/pelletier/go-toml/v2/CONTRIBUTING.md
index 96ecf9e2b..28b88ec33 100644
--- a/vendor/github.com/pelletier/go-toml/v2/CONTRIBUTING.md
+++ b/vendor/github.com/pelletier/go-toml/v2/CONTRIBUTING.md
@@ -33,7 +33,7 @@ The documentation is present in the [README][readme] and thorough the source
code. On release, it gets updated on [pkg.go.dev][pkg.go.dev]. To make a change
to the documentation, create a pull request with your proposed changes. For
simple changes like that, the easiest way to go is probably the "Fork this
-project and edit the file" button on Github, displayed at the top right of the
+project and edit the file" button on GitHub, displayed at the top right of the
file. Unless it's a trivial change (for example a typo), provide a little bit of
context in your pull request description or commit message.
@@ -92,6 +92,48 @@ However, given GitHub's new policy to _not_ run Actions on pull requests until a
maintainer clicks on button, it is highly recommended that you run them locally
as you make changes.
+### Test across Go versions
+
+The repository includes tooling to test go-toml across multiple Go versions
+(1.11 through 1.25) both locally and in GitHub Actions.
+
+#### Local testing with Docker
+
+Prerequisites: Docker installed and running, Bash shell, `rsync` command.
+
+```bash
+# Test all Go versions in parallel (default)
+./test-go-versions.sh
+
+# Test specific versions
+./test-go-versions.sh 1.21 1.22 1.23
+
+# Test sequentially (slower but uses less resources)
+./test-go-versions.sh --sequential
+
+# Verbose output with custom results directory
+./test-go-versions.sh --verbose --output ./my-results 1.24 1.25
+
+# Show all options
+./test-go-versions.sh --help
+```
+
+The script creates Docker containers for each Go version and runs the full test
+suite. Results are saved to a `test-results/` directory with individual logs and
+a comprehensive summary report.
+
+The script only exits with a non-zero status code if either of the two most
+recent Go versions fail.
+
+#### GitHub Actions testing (maintainers)
+
+1. Go to the **Actions** tab in the GitHub repository
+2. Select **"Go Versions Compatibility Test"** from the workflow list
+3. Click **"Run workflow"**
+4. Optionally customize:
+ - **Go versions**: Space-separated list (e.g., `1.21 1.22 1.23`)
+ - **Execution mode**: Parallel (faster) or sequential (more stable)
+
### Check coverage
We use `go tool cover` to compute test coverage. Most code editors have a way to
@@ -111,7 +153,7 @@ code lowers the coverage.
Go-toml aims to stay efficient. We rely on a set of scenarios executed with Go's
builtin benchmark systems. Because of their noisy nature, containers provided by
-Github Actions cannot be reliably used for benchmarking. As a result, you are
+GitHub Actions cannot be reliably used for benchmarking. As a result, you are
responsible for checking that your changes do not incur a performance penalty.
You can run their following to execute benchmarks:
@@ -168,13 +210,13 @@ Checklist:
1. Decide on the next version number. Use semver. Review commits since last
version to assess.
2. Tag release. For example:
-```
-git checkout v2
-git pull
-git tag v2.2.0
-git push --tags
-```
-3. CI automatically builds a draft Github release. Review it and edit as
+ ```
+ git checkout v2
+ git pull
+ git tag v2.2.0
+ git push --tags
+ ```
+3. CI automatically builds a draft GitHub release. Review it and edit as
necessary. Look for "Other changes". That would indicate a pull request not
labeled properly. Tweak labels and pull request titles until changelog looks
good for users.
diff --git a/vendor/github.com/pelletier/go-toml/v2/README.md b/vendor/github.com/pelletier/go-toml/v2/README.md
index 0755e5564..14e656449 100644
--- a/vendor/github.com/pelletier/go-toml/v2/README.md
+++ b/vendor/github.com/pelletier/go-toml/v2/README.md
@@ -21,8 +21,6 @@ documentation.
import "github.com/pelletier/go-toml/v2"
```
-See [Modules](#Modules).
-
## Features
### Stdlib behavior
@@ -107,7 +105,11 @@ type MyConfig struct {
### Unmarshaling
[`Unmarshal`][unmarshal] reads a TOML document and fills a Go structure with its
-content. For example:
+content.
+
+Note that the struct variable names are _capitalized_, while the variables in the toml document are _lowercase_.
+
+For example:
```go
doc := `
@@ -133,6 +135,62 @@ fmt.Println("tags:", cfg.Tags)
[unmarshal]: https://pkg.go.dev/github.com/pelletier/go-toml/v2#Unmarshal
+
+Here is an example using tables with some simple nesting:
+
+```go
+doc := `
+age = 45
+fruits = ["apple", "pear"]
+
+# these are very important!
+[my-variables]
+first = 1
+second = 0.2
+third = "abc"
+
+# this is not so important.
+[my-variables.b]
+bfirst = 123
+`
+
+var Document struct {
+ Age int
+ Fruits []string
+
+ Myvariables struct {
+ First int
+ Second float64
+ Third string
+
+ B struct {
+ Bfirst int
+ }
+ } `toml:"my-variables"`
+}
+
+err := toml.Unmarshal([]byte(doc), &Document)
+if err != nil {
+ panic(err)
+}
+
+fmt.Println("age:", Document.Age)
+fmt.Println("fruits:", Document.Fruits)
+fmt.Println("my-variables.first:", Document.Myvariables.First)
+fmt.Println("my-variables.second:", Document.Myvariables.Second)
+fmt.Println("my-variables.third:", Document.Myvariables.Third)
+fmt.Println("my-variables.B.Bfirst:", Document.Myvariables.B.Bfirst)
+
+// Output:
+// age: 45
+// fruits: [apple pear]
+// my-variables.first: 1
+// my-variables.second: 0.2
+// my-variables.third: abc
+// my-variables.B.Bfirst: 123
+```
+
+
### Marshaling
[`Marshal`][marshal] is the opposite of Unmarshal: it represents a Go structure
@@ -175,17 +233,17 @@ the AST level. See https://pkg.go.dev/github.com/pelletier/go-toml/v2/unstable.
Execution time speedup compared to other Go TOML libraries:
-
- Benchmark go-toml v1 BurntSushi/toml
-
-
- Marshal/HugoFrontMatter-2 1.9x 2.2x
- Marshal/ReferenceFile/map-2 1.7x 2.1x
- Marshal/ReferenceFile/struct-2 2.2x 3.0x
- Unmarshal/HugoFrontMatter-2 2.9x 2.7x
- Unmarshal/ReferenceFile/map-2 2.6x 2.7x
- Unmarshal/ReferenceFile/struct-2 4.6x 5.1x
-
+
+ Benchmark go-toml v1 BurntSushi/toml
+
+
+ Marshal/HugoFrontMatter-2 2.1x 2.0x
+ Marshal/ReferenceFile/map-2 2.0x 2.0x
+ Marshal/ReferenceFile/struct-2 2.3x 2.5x
+ Unmarshal/HugoFrontMatter-2 3.3x 2.8x
+ Unmarshal/ReferenceFile/map-2 2.9x 3.0x
+ Unmarshal/ReferenceFile/struct-2 4.8x 5.0x
+
See more
The table above has the results of the most common use-cases. The table below
@@ -193,40 +251,26 @@ contains the results of all benchmarks, including unrealistic ones. It is
provided for completeness.
-
- Benchmark go-toml v1 BurntSushi/toml
-
-
- Marshal/SimpleDocument/map-2 1.8x 2.7x
- Marshal/SimpleDocument/struct-2 2.7x 3.8x
- Unmarshal/SimpleDocument/map-2 3.8x 3.0x
- Unmarshal/SimpleDocument/struct-2 5.6x 4.1x
- UnmarshalDataset/example-2 3.0x 3.2x
- UnmarshalDataset/code-2 2.3x 2.9x
- UnmarshalDataset/twitter-2 2.6x 2.7x
- UnmarshalDataset/citm_catalog-2 2.2x 2.3x
- UnmarshalDataset/canada-2 1.8x 1.5x
- UnmarshalDataset/config-2 4.1x 2.9x
- geomean 2.7x 2.8x
-
+
+ Benchmark go-toml v1 BurntSushi/toml
+
+
+ Marshal/SimpleDocument/map-2 2.0x 2.9x
+ Marshal/SimpleDocument/struct-2 2.5x 3.6x
+ Unmarshal/SimpleDocument/map-2 4.2x 3.4x
+ Unmarshal/SimpleDocument/struct-2 5.9x 4.4x
+ UnmarshalDataset/example-2 3.2x 2.9x
+ UnmarshalDataset/code-2 2.4x 2.8x
+ UnmarshalDataset/twitter-2 2.7x 2.5x
+ UnmarshalDataset/citm_catalog-2 2.3x 2.3x
+ UnmarshalDataset/canada-2 1.9x 1.5x
+ UnmarshalDataset/config-2 5.4x 3.0x
+ geomean 2.9x 2.8x
+
This table can be generated with ./ci.sh benchmark -a -html.
-## Modules
-
-go-toml uses Go's standard modules system.
-
-Installation instructions:
-
-- Go ≥ 1.16: Nothing to do. Use the import in your code. The `go` command deals
- with it automatically.
-- Go ≥ 1.13: `GO111MODULE=on go get github.com/pelletier/go-toml/v2`.
-
-In case of trouble: [Go Modules FAQ][mod-faq].
-
-[mod-faq]: https://github.com/golang/go/wiki/Modules#why-does-installing-a-tool-via-go-get-fail-with-error-cannot-find-main-module
-
## Tools
Go-toml provides three handy command line tools:
diff --git a/vendor/github.com/pelletier/go-toml/v2/ci.sh b/vendor/github.com/pelletier/go-toml/v2/ci.sh
index 86217a9b0..30c23d1a1 100644
--- a/vendor/github.com/pelletier/go-toml/v2/ci.sh
+++ b/vendor/github.com/pelletier/go-toml/v2/ci.sh
@@ -147,7 +147,7 @@ bench() {
pushd "$dir"
if [ "${replace}" != "" ]; then
- find ./benchmark/ -iname '*.go' -exec sed -i -E "s|github.com/pelletier/go-toml/v2|${replace}|g" {} \;
+ find ./benchmark/ -iname '*.go' -exec sed -i -E "s|github.com/pelletier/go-toml/v2\"|${replace}\"|g" {} \;
go get "${replace}"
fi
@@ -195,6 +195,11 @@ for line in reversed(lines[2:]):
"%.1fx" % (float(line[3])/v2), # v1
"%.1fx" % (float(line[7])/v2), # bs
])
+
+if not results:
+ print("No benchmark results to display.", file=sys.stderr)
+ sys.exit(1)
+
# move geomean to the end
results.append(results[0])
del results[0]
diff --git a/vendor/github.com/pelletier/go-toml/v2/decode.go b/vendor/github.com/pelletier/go-toml/v2/decode.go
index f0ec3b170..f3f14eff1 100644
--- a/vendor/github.com/pelletier/go-toml/v2/decode.go
+++ b/vendor/github.com/pelletier/go-toml/v2/decode.go
@@ -230,8 +230,8 @@ func parseLocalTime(b []byte) (LocalTime, []byte, error) {
return t, nil, err
}
- if t.Second > 60 {
- return t, nil, unstable.NewParserError(b[6:8], "seconds cannot be greater 60")
+ if t.Second > 59 {
+ return t, nil, unstable.NewParserError(b[6:8], "seconds cannot be greater than 59")
}
b = b[8:]
@@ -279,7 +279,6 @@ func parseLocalTime(b []byte) (LocalTime, []byte, error) {
return t, b, nil
}
-//nolint:cyclop
func parseFloat(b []byte) (float64, error) {
if len(b) == 4 && (b[0] == '+' || b[0] == '-') && b[1] == 'n' && b[2] == 'a' && b[3] == 'n' {
return math.NaN(), nil
diff --git a/vendor/github.com/pelletier/go-toml/v2/errors.go b/vendor/github.com/pelletier/go-toml/v2/errors.go
index 309733f1f..d68835dfa 100644
--- a/vendor/github.com/pelletier/go-toml/v2/errors.go
+++ b/vendor/github.com/pelletier/go-toml/v2/errors.go
@@ -2,10 +2,10 @@ package toml
import (
"fmt"
+ "reflect"
"strconv"
"strings"
- "github.com/pelletier/go-toml/v2/internal/danger"
"github.com/pelletier/go-toml/v2/unstable"
)
@@ -54,6 +54,18 @@ func (s *StrictMissingError) String() string {
return buf.String()
}
+// Unwrap returns wrapped decode errors
+//
+// Implements errors.Join() interface.
+func (s *StrictMissingError) Unwrap() []error {
+ errs := make([]error, len(s.Errors))
+ for i := range s.Errors {
+ errs[i] = &s.Errors[i]
+ }
+ return errs
+}
+
+// Key represents a TOML key as a sequence of key parts.
type Key []string
// Error returns the error message contained in the DecodeError.
@@ -78,7 +90,7 @@ func (e *DecodeError) Key() Key {
return e.key
}
-// decodeErrorFromHighlight creates a DecodeError referencing a highlighted
+// wrapDecodeError creates a DecodeError referencing a highlighted
// range of bytes from document.
//
// highlight needs to be a sub-slice of document, or this function panics.
@@ -88,7 +100,7 @@ func (e *DecodeError) Key() Key {
//
//nolint:funlen
func wrapDecodeError(document []byte, de *unstable.ParserError) *DecodeError {
- offset := danger.SubsliceOffset(document, de.Highlight)
+ offset := subsliceOffset(document, de.Highlight)
errMessage := de.Error()
errLine, errColumn := positionAtEnd(document[:offset])
@@ -248,5 +260,24 @@ func positionAtEnd(b []byte) (row int, column int) {
}
}
- return
+ return row, column
+}
+
+// subsliceOffset returns the byte offset of subslice within data.
+// subslice must share the same backing array as data.
+func subsliceOffset(data []byte, subslice []byte) int {
+ if len(subslice) == 0 {
+ return 0
+ }
+
+ // Use reflect to get the data pointers of both slices.
+ // This is safe because we're only reading the pointer values for comparison.
+ dataPtr := reflect.ValueOf(data).Pointer()
+ subPtr := reflect.ValueOf(subslice).Pointer()
+
+ offset := int(subPtr - dataPtr)
+ if offset < 0 || offset > len(data) {
+ panic("subslice is not within data")
+ }
+ return offset
}
diff --git a/vendor/github.com/pelletier/go-toml/v2/internal/characters/ascii.go b/vendor/github.com/pelletier/go-toml/v2/internal/characters/ascii.go
index 80f698db4..50a6d1702 100644
--- a/vendor/github.com/pelletier/go-toml/v2/internal/characters/ascii.go
+++ b/vendor/github.com/pelletier/go-toml/v2/internal/characters/ascii.go
@@ -1,6 +1,6 @@
package characters
-var invalidAsciiTable = [256]bool{
+var invalidASCIITable = [256]bool{
0x00: true,
0x01: true,
0x02: true,
@@ -37,6 +37,6 @@ var invalidAsciiTable = [256]bool{
0x7F: true,
}
-func InvalidAscii(b byte) bool {
- return invalidAsciiTable[b]
+func InvalidASCII(b byte) bool {
+ return invalidASCIITable[b]
}
diff --git a/vendor/github.com/pelletier/go-toml/v2/internal/characters/utf8.go b/vendor/github.com/pelletier/go-toml/v2/internal/characters/utf8.go
index db4f45acb..7c5cb55e4 100644
--- a/vendor/github.com/pelletier/go-toml/v2/internal/characters/utf8.go
+++ b/vendor/github.com/pelletier/go-toml/v2/internal/characters/utf8.go
@@ -1,20 +1,12 @@
+// Package characters provides functions for working with string encodings.
package characters
import (
"unicode/utf8"
)
-type utf8Err struct {
- Index int
- Size int
-}
-
-func (u utf8Err) Zero() bool {
- return u.Size == 0
-}
-
-// Verified that a given string is only made of valid UTF-8 characters allowed
-// by the TOML spec:
+// Utf8TomlValidAlreadyEscaped verifies that a given string is only made of
+// valid UTF-8 characters allowed by the TOML spec:
//
// Any Unicode character may be used except those that must be escaped:
// quotation mark, backslash, and the control characters other than tab (U+0000
@@ -23,8 +15,8 @@ func (u utf8Err) Zero() bool {
// It is a copy of the Go 1.17 utf8.Valid implementation, tweaked to exit early
// when a character is not allowed.
//
-// The returned utf8Err is Zero() if the string is valid, or contains the byte
-// index and size of the invalid character.
+// The returned slice is empty if the string is valid, or contains the bytes
+// of the invalid character.
//
// quotation mark => already checked
// backslash => already checked
@@ -32,9 +24,8 @@ func (u utf8Err) Zero() bool {
// 0x9 => tab, ok
// 0xA - 0x1F => invalid
// 0x7F => invalid
-func Utf8TomlValidAlreadyEscaped(p []byte) (err utf8Err) {
+func Utf8TomlValidAlreadyEscaped(p []byte) []byte {
// Fast path. Check for and skip 8 bytes of ASCII characters per iteration.
- offset := 0
for len(p) >= 8 {
// Combining two 32 bit loads allows the same code to be used
// for 32 and 64 bit platforms.
@@ -48,24 +39,19 @@ func Utf8TomlValidAlreadyEscaped(p []byte) (err utf8Err) {
}
for i, b := range p[:8] {
- if InvalidAscii(b) {
- err.Index = offset + i
- err.Size = 1
- return
+ if InvalidASCII(b) {
+ return p[i : i+1]
}
}
p = p[8:]
- offset += 8
}
n := len(p)
for i := 0; i < n; {
pi := p[i]
if pi < utf8.RuneSelf {
- if InvalidAscii(pi) {
- err.Index = offset + i
- err.Size = 1
- return
+ if InvalidASCII(pi) {
+ return p[i : i+1]
}
i++
continue
@@ -73,44 +59,34 @@ func Utf8TomlValidAlreadyEscaped(p []byte) (err utf8Err) {
x := first[pi]
if x == xx {
// Illegal starter byte.
- err.Index = offset + i
- err.Size = 1
- return
+ return p[i : i+1]
}
size := int(x & 7)
if i+size > n {
// Short or invalid.
- err.Index = offset + i
- err.Size = n - i
- return
+ return p[i:n]
}
accept := acceptRanges[x>>4]
if c := p[i+1]; c < accept.lo || accept.hi < c {
- err.Index = offset + i
- err.Size = 2
- return
- } else if size == 2 {
+ return p[i : i+2]
+ } else if size == 2 { //revive:disable:empty-block
} else if c := p[i+2]; c < locb || hicb < c {
- err.Index = offset + i
- err.Size = 3
- return
- } else if size == 3 {
+ return p[i : i+3]
+ } else if size == 3 { //revive:disable:empty-block
} else if c := p[i+3]; c < locb || hicb < c {
- err.Index = offset + i
- err.Size = 4
- return
+ return p[i : i+4]
}
i += size
}
- return
+ return nil
}
-// Return the size of the next rune if valid, 0 otherwise.
+// Utf8ValidNext returns the size of the next rune if valid, 0 otherwise.
func Utf8ValidNext(p []byte) int {
c := p[0]
if c < utf8.RuneSelf {
- if InvalidAscii(c) {
+ if InvalidASCII(c) {
return 0
}
return 1
@@ -129,10 +105,10 @@ func Utf8ValidNext(p []byte) int {
accept := acceptRanges[x>>4]
if c := p[1]; c < accept.lo || accept.hi < c {
return 0
- } else if size == 2 {
+ } else if size == 2 { //nolint:revive
} else if c := p[2]; c < locb || hicb < c {
return 0
- } else if size == 3 {
+ } else if size == 3 { //nolint:revive
} else if c := p[3]; c < locb || hicb < c {
return 0
}
diff --git a/vendor/github.com/pelletier/go-toml/v2/internal/danger/danger.go b/vendor/github.com/pelletier/go-toml/v2/internal/danger/danger.go
deleted file mode 100644
index e38e1131b..000000000
--- a/vendor/github.com/pelletier/go-toml/v2/internal/danger/danger.go
+++ /dev/null
@@ -1,65 +0,0 @@
-package danger
-
-import (
- "fmt"
- "reflect"
- "unsafe"
-)
-
-const maxInt = uintptr(int(^uint(0) >> 1))
-
-func SubsliceOffset(data []byte, subslice []byte) int {
- datap := (*reflect.SliceHeader)(unsafe.Pointer(&data))
- hlp := (*reflect.SliceHeader)(unsafe.Pointer(&subslice))
-
- if hlp.Data < datap.Data {
- panic(fmt.Errorf("subslice address (%d) is before data address (%d)", hlp.Data, datap.Data))
- }
- offset := hlp.Data - datap.Data
-
- if offset > maxInt {
- panic(fmt.Errorf("slice offset larger than int (%d)", offset))
- }
-
- intoffset := int(offset)
-
- if intoffset > datap.Len {
- panic(fmt.Errorf("slice offset (%d) is farther than data length (%d)", intoffset, datap.Len))
- }
-
- if intoffset+hlp.Len > datap.Len {
- panic(fmt.Errorf("slice ends (%d+%d) is farther than data length (%d)", intoffset, hlp.Len, datap.Len))
- }
-
- return intoffset
-}
-
-func BytesRange(start []byte, end []byte) []byte {
- if start == nil || end == nil {
- panic("cannot call BytesRange with nil")
- }
- startp := (*reflect.SliceHeader)(unsafe.Pointer(&start))
- endp := (*reflect.SliceHeader)(unsafe.Pointer(&end))
-
- if startp.Data > endp.Data {
- panic(fmt.Errorf("start pointer address (%d) is after end pointer address (%d)", startp.Data, endp.Data))
- }
-
- l := startp.Len
- endLen := int(endp.Data-startp.Data) + endp.Len
- if endLen > l {
- l = endLen
- }
-
- if l > startp.Cap {
- panic(fmt.Errorf("range length is larger than capacity"))
- }
-
- return start[:l]
-}
-
-func Stride(ptr unsafe.Pointer, size uintptr, offset int) unsafe.Pointer {
- // TODO: replace with unsafe.Add when Go 1.17 is released
- // https://github.com/golang/go/issues/40481
- return unsafe.Pointer(uintptr(ptr) + uintptr(int(size)*offset))
-}
diff --git a/vendor/github.com/pelletier/go-toml/v2/internal/danger/typeid.go b/vendor/github.com/pelletier/go-toml/v2/internal/danger/typeid.go
deleted file mode 100644
index 9d41c28a2..000000000
--- a/vendor/github.com/pelletier/go-toml/v2/internal/danger/typeid.go
+++ /dev/null
@@ -1,23 +0,0 @@
-package danger
-
-import (
- "reflect"
- "unsafe"
-)
-
-// typeID is used as key in encoder and decoder caches to enable using
-// the optimize runtime.mapaccess2_fast64 function instead of the more
-// expensive lookup if we were to use reflect.Type as map key.
-//
-// typeID holds the pointer to the reflect.Type value, which is unique
-// in the program.
-//
-// https://github.com/segmentio/encoding/blob/master/json/codec.go#L59-L61
-type TypeID unsafe.Pointer
-
-func MakeTypeID(t reflect.Type) TypeID {
- // reflect.Type has the fields:
- // typ unsafe.Pointer
- // ptr unsafe.Pointer
- return TypeID((*[2]unsafe.Pointer)(unsafe.Pointer(&t))[1])
-}
diff --git a/vendor/github.com/pelletier/go-toml/v2/internal/tracker/key.go b/vendor/github.com/pelletier/go-toml/v2/internal/tracker/key.go
index 149b17f53..6344fd047 100644
--- a/vendor/github.com/pelletier/go-toml/v2/internal/tracker/key.go
+++ b/vendor/github.com/pelletier/go-toml/v2/internal/tracker/key.go
@@ -36,7 +36,7 @@ func (t *KeyTracker) Pop(node *unstable.Node) {
}
}
-// Key returns the current key
+// Key returns the current key.
func (t *KeyTracker) Key() []string {
k := make([]string, len(t.k))
copy(k, t.k)
diff --git a/vendor/github.com/pelletier/go-toml/v2/internal/tracker/seen.go b/vendor/github.com/pelletier/go-toml/v2/internal/tracker/seen.go
index 76df2d5b6..206235800 100644
--- a/vendor/github.com/pelletier/go-toml/v2/internal/tracker/seen.go
+++ b/vendor/github.com/pelletier/go-toml/v2/internal/tracker/seen.go
@@ -288,11 +288,12 @@ func (s *SeenTracker) checkKeyValue(node *unstable.Node) (bool, error) {
idx = s.create(parentIdx, k, tableKind, false, true)
} else {
entry := s.entries[idx]
- if it.IsLast() {
+ switch {
+ case it.IsLast():
return false, fmt.Errorf("toml: key %s is already defined", string(k))
- } else if entry.kind != tableKind {
+ case entry.kind != tableKind:
return false, fmt.Errorf("toml: expected %s to be a table, not a %s", string(k), entry.kind)
- } else if entry.explicit {
+ case entry.explicit:
return false, fmt.Errorf("toml: cannot redefine table %s that has already been explicitly defined", string(k))
}
}
@@ -309,16 +310,16 @@ func (s *SeenTracker) checkKeyValue(node *unstable.Node) (bool, error) {
return s.checkInlineTable(value)
case unstable.Array:
return s.checkArray(value)
+ default:
+ return false, nil
}
-
- return false, nil
}
func (s *SeenTracker) checkArray(node *unstable.Node) (first bool, err error) {
it := node.Children()
for it.Next() {
n := it.Node()
- switch n.Kind {
+ switch n.Kind { //nolint:exhaustive
case unstable.InlineTable:
first, err = s.checkInlineTable(n)
if err != nil {
diff --git a/vendor/github.com/pelletier/go-toml/v2/internal/tracker/tracker.go b/vendor/github.com/pelletier/go-toml/v2/internal/tracker/tracker.go
index bf0317392..ed510382c 100644
--- a/vendor/github.com/pelletier/go-toml/v2/internal/tracker/tracker.go
+++ b/vendor/github.com/pelletier/go-toml/v2/internal/tracker/tracker.go
@@ -1 +1,2 @@
+// Package tracker provides functions for keeping track of AST nodes.
package tracker
diff --git a/vendor/github.com/pelletier/go-toml/v2/localtime.go b/vendor/github.com/pelletier/go-toml/v2/localtime.go
index a856bfdb0..502ef2f2f 100644
--- a/vendor/github.com/pelletier/go-toml/v2/localtime.go
+++ b/vendor/github.com/pelletier/go-toml/v2/localtime.go
@@ -45,7 +45,7 @@ func (d *LocalDate) UnmarshalText(b []byte) error {
type LocalTime struct {
Hour int // Hour of the day: [0; 24[
Minute int // Minute of the hour: [0; 60[
- Second int // Second of the minute: [0; 60[
+ Second int // Second of the minute: [0; 59]
Nanosecond int // Nanoseconds within the second: [0, 1000000000[
Precision int // Number of digits to display for Nanosecond.
}
diff --git a/vendor/github.com/pelletier/go-toml/v2/marshaler.go b/vendor/github.com/pelletier/go-toml/v2/marshaler.go
index 161acd934..ca462d40e 100644
--- a/vendor/github.com/pelletier/go-toml/v2/marshaler.go
+++ b/vendor/github.com/pelletier/go-toml/v2/marshaler.go
@@ -4,6 +4,7 @@ import (
"bytes"
"encoding"
"encoding/json"
+ "errors"
"fmt"
"io"
"math"
@@ -42,7 +43,7 @@ type Encoder struct {
arraysMultiline bool
indentSymbol string
indentTables bool
- marshalJsonNumbers bool
+ marshalJSONNumbers bool
}
// NewEncoder returns a new Encoder that writes to w.
@@ -89,14 +90,14 @@ func (enc *Encoder) SetIndentTables(indent bool) *Encoder {
return enc
}
-// SetMarshalJsonNumbers forces the encoder to serialize `json.Number` as a
+// SetMarshalJSONNumbers forces the encoder to serialize `json.Number` as a
// float or integer instead of relying on TextMarshaler to emit a string.
//
// *Unstable:* This method does not follow the compatibility guarantees of
// semver. It can be changed or removed without a new major version being
// issued.
-func (enc *Encoder) SetMarshalJsonNumbers(indent bool) *Encoder {
- enc.marshalJsonNumbers = indent
+func (enc *Encoder) SetMarshalJSONNumbers(indent bool) *Encoder {
+ enc.marshalJSONNumbers = indent
return enc
}
@@ -161,6 +162,8 @@ func (enc *Encoder) SetMarshalJsonNumbers(indent bool) *Encoder {
//
// The "omitempty" option prevents empty values or groups from being emitted.
//
+// The "omitzero" option prevents zero values or groups from being emitted.
+//
// The "commented" option prefixes the value and all its children with a comment
// symbol.
//
@@ -177,7 +180,7 @@ func (enc *Encoder) Encode(v interface{}) error {
ctx.inline = enc.tablesInline
if v == nil {
- return fmt.Errorf("toml: cannot encode a nil interface")
+ return errors.New("toml: cannot encode a nil interface")
}
b, err := enc.encode(b, ctx, reflect.ValueOf(v))
@@ -196,6 +199,7 @@ func (enc *Encoder) Encode(v interface{}) error {
type valueOptions struct {
multiline bool
omitempty bool
+ omitzero bool
commented bool
comment string
}
@@ -266,16 +270,15 @@ func (enc *Encoder) encode(b []byte, ctx encoderCtx, v reflect.Value) ([]byte, e
case LocalDateTime:
return append(b, x.String()...), nil
case json.Number:
- if enc.marshalJsonNumbers {
+ if enc.marshalJSONNumbers {
if x == "" { /// Useful zero value.
return append(b, "0"...), nil
} else if v, err := x.Int64(); err == nil {
return enc.encode(b, ctx, reflect.ValueOf(v))
} else if f, err := x.Float64(); err == nil {
return enc.encode(b, ctx, reflect.ValueOf(f))
- } else {
- return nil, fmt.Errorf("toml: unable to convert %q to int64 or float64", x)
}
+ return nil, fmt.Errorf("toml: unable to convert %q to int64 or float64", x)
}
}
@@ -309,7 +312,7 @@ func (enc *Encoder) encode(b []byte, ctx encoderCtx, v reflect.Value) ([]byte, e
return enc.encodeSlice(b, ctx, v)
case reflect.Interface:
if v.IsNil() {
- return nil, fmt.Errorf("toml: encoding a nil interface is not supported")
+ return nil, errors.New("toml: encoding a nil interface is not supported")
}
return enc.encode(b, ctx, v.Elem())
@@ -326,28 +329,30 @@ func (enc *Encoder) encode(b []byte, ctx encoderCtx, v reflect.Value) ([]byte, e
case reflect.Float32:
f := v.Float()
- if math.IsNaN(f) {
+ switch {
+ case math.IsNaN(f):
b = append(b, "nan"...)
- } else if f > math.MaxFloat32 {
+ case f > math.MaxFloat32:
b = append(b, "inf"...)
- } else if f < -math.MaxFloat32 {
+ case f < -math.MaxFloat32:
b = append(b, "-inf"...)
- } else if math.Trunc(f) == f {
+ case math.Trunc(f) == f:
b = strconv.AppendFloat(b, f, 'f', 1, 32)
- } else {
+ default:
b = strconv.AppendFloat(b, f, 'f', -1, 32)
}
case reflect.Float64:
f := v.Float()
- if math.IsNaN(f) {
+ switch {
+ case math.IsNaN(f):
b = append(b, "nan"...)
- } else if f > math.MaxFloat64 {
+ case f > math.MaxFloat64:
b = append(b, "inf"...)
- } else if f < -math.MaxFloat64 {
+ case f < -math.MaxFloat64:
b = append(b, "-inf"...)
- } else if math.Trunc(f) == f {
+ case math.Trunc(f) == f:
b = strconv.AppendFloat(b, f, 'f', 1, 64)
- } else {
+ default:
b = strconv.AppendFloat(b, f, 'f', -1, 64)
}
case reflect.Bool:
@@ -384,6 +389,31 @@ func shouldOmitEmpty(options valueOptions, v reflect.Value) bool {
return options.omitempty && isEmptyValue(v)
}
+func shouldOmitZero(options valueOptions, v reflect.Value) bool {
+ if !options.omitzero {
+ return false
+ }
+
+ // Check if the type implements isZeroer interface (has a custom IsZero method).
+ if v.Type().Implements(isZeroerType) {
+ return v.Interface().(isZeroer).IsZero()
+ }
+
+ // Check if pointer type implements isZeroer.
+ if reflect.PointerTo(v.Type()).Implements(isZeroerType) {
+ if v.CanAddr() {
+ return v.Addr().Interface().(isZeroer).IsZero()
+ }
+ // Create a temporary addressable copy to call the pointer receiver method.
+ pv := reflect.New(v.Type())
+ pv.Elem().Set(v)
+ return pv.Interface().(isZeroer).IsZero()
+ }
+
+ // Fall back to reflect's IsZero for types without custom IsZero method.
+ return v.IsZero()
+}
+
func (enc *Encoder) encodeKv(b []byte, ctx encoderCtx, options valueOptions, v reflect.Value) ([]byte, error) {
var err error
@@ -434,8 +464,9 @@ func isEmptyValue(v reflect.Value) bool {
return v.Float() == 0
case reflect.Interface, reflect.Ptr:
return v.IsNil()
+ default:
+ return false
}
- return false
}
func isEmptyStruct(v reflect.Value) bool {
@@ -479,7 +510,7 @@ func (enc *Encoder) encodeString(b []byte, v string, options valueOptions) []byt
func needsQuoting(v string) bool {
// TODO: vectorize
for _, b := range []byte(v) {
- if b == '\'' || b == '\r' || b == '\n' || characters.InvalidAscii(b) {
+ if b == '\'' || b == '\r' || b == '\n' || characters.InvalidASCII(b) {
return true
}
}
@@ -517,12 +548,26 @@ func (enc *Encoder) encodeQuotedString(multiline bool, b []byte, v string) []byt
del = 0x7f
)
- for _, r := range []byte(v) {
+ bv := []byte(v)
+ for i := 0; i < len(bv); i++ {
+ r := bv[i]
switch r {
case '\\':
b = append(b, `\\`...)
case '"':
- b = append(b, `\"`...)
+ if multiline {
+ // Quotation marks do not need to be quoted in multiline strings unless
+ // it contains 3 consecutive. If 3+ quotes appear, quote all of them
+ // because it's visually better
+ if i+2 > len(bv) || bv[i+1] != '"' || bv[i+2] != '"' {
+ b = append(b, r)
+ } else {
+ b = append(b, `\"\"\"`...)
+ i += 2
+ }
+ } else {
+ b = append(b, `\"`...)
+ }
case '\b':
b = append(b, `\b`...)
case '\f':
@@ -559,9 +604,9 @@ func (enc *Encoder) encodeUnquotedKey(b []byte, v string) []byte {
return append(b, v...)
}
-func (enc *Encoder) encodeTableHeader(ctx encoderCtx, b []byte) ([]byte, error) {
+func (enc *Encoder) encodeTableHeader(ctx encoderCtx, b []byte) []byte {
if len(ctx.parentKey) == 0 {
- return b, nil
+ return b
}
b = enc.encodeComment(ctx.indent, ctx.options.comment, b)
@@ -581,10 +626,9 @@ func (enc *Encoder) encodeTableHeader(ctx encoderCtx, b []byte) ([]byte, error)
b = append(b, "]\n"...)
- return b, nil
+ return b
}
-//nolint:cyclop
func (enc *Encoder) encodeKey(b []byte, k string) []byte {
needsQuotation := false
cannotUseLiteral := false
@@ -621,30 +665,33 @@ func (enc *Encoder) encodeKey(b []byte, k string) []byte {
func (enc *Encoder) keyToString(k reflect.Value) (string, error) {
keyType := k.Type()
- switch {
- case keyType.Kind() == reflect.String:
- return k.String(), nil
-
- case keyType.Implements(textMarshalerType):
+ if keyType.Implements(textMarshalerType) {
keyB, err := k.Interface().(encoding.TextMarshaler).MarshalText()
if err != nil {
return "", fmt.Errorf("toml: error marshalling key %v from text: %w", k, err)
}
return string(keyB), nil
+ }
+
+ switch keyType.Kind() {
+ case reflect.String:
+ return k.String(), nil
- case keyType.Kind() == reflect.Int || keyType.Kind() == reflect.Int8 || keyType.Kind() == reflect.Int16 || keyType.Kind() == reflect.Int32 || keyType.Kind() == reflect.Int64:
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
return strconv.FormatInt(k.Int(), 10), nil
- case keyType.Kind() == reflect.Uint || keyType.Kind() == reflect.Uint8 || keyType.Kind() == reflect.Uint16 || keyType.Kind() == reflect.Uint32 || keyType.Kind() == reflect.Uint64:
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
return strconv.FormatUint(k.Uint(), 10), nil
- case keyType.Kind() == reflect.Float32:
+ case reflect.Float32:
return strconv.FormatFloat(k.Float(), 'f', -1, 32), nil
- case keyType.Kind() == reflect.Float64:
+ case reflect.Float64:
return strconv.FormatFloat(k.Float(), 'f', -1, 64), nil
+
+ default:
+ return "", fmt.Errorf("toml: type %s is not supported as a map key", keyType.Kind())
}
- return "", fmt.Errorf("toml: type %s is not supported as a map key", keyType.Kind())
}
func (enc *Encoder) encodeMap(b []byte, ctx encoderCtx, v reflect.Value) ([]byte, error) {
@@ -657,8 +704,18 @@ func (enc *Encoder) encodeMap(b []byte, ctx encoderCtx, v reflect.Value) ([]byte
for iter.Next() {
v := iter.Value()
- if isNil(v) {
- continue
+ // Handle nil values: convert nil pointers to zero value,
+ // skip nil interfaces and nil maps.
+ switch v.Kind() {
+ case reflect.Ptr:
+ if v.IsNil() {
+ v = reflect.Zero(v.Type().Elem())
+ }
+ case reflect.Interface, reflect.Map:
+ if v.IsNil() {
+ continue
+ }
+ default:
}
k, err := enc.keyToString(iter.Key())
@@ -748,9 +805,8 @@ func walkStruct(ctx encoderCtx, t *table, v reflect.Value) {
walkStruct(ctx, t, f.Elem())
}
continue
- } else {
- k = fieldType.Name
}
+ k = fieldType.Name
}
if isNil(f) {
@@ -760,6 +816,7 @@ func walkStruct(ctx encoderCtx, t *table, v reflect.Value) {
options := valueOptions{
multiline: opts.multiline,
omitempty: opts.omitempty,
+ omitzero: opts.omitzero,
commented: opts.commented,
comment: fieldType.Tag.Get("comment"),
}
@@ -820,6 +877,7 @@ type tagOptions struct {
multiline bool
inline bool
omitempty bool
+ omitzero bool
commented bool
}
@@ -832,7 +890,7 @@ func parseTag(tag string) (string, tagOptions) {
}
raw := tag[idx+1:]
- tag = string(tag[:idx])
+ tag = tag[:idx]
for raw != "" {
var o string
i := strings.Index(raw, ",")
@@ -848,6 +906,8 @@ func parseTag(tag string) (string, tagOptions) {
opts.inline = true
case "omitempty":
opts.omitempty = true
+ case "omitzero":
+ opts.omitzero = true
case "commented":
opts.commented = true
}
@@ -866,10 +926,7 @@ func (enc *Encoder) encodeTable(b []byte, ctx encoderCtx, t table) ([]byte, erro
}
if !ctx.skipTableHeader {
- b, err = enc.encodeTableHeader(ctx, b)
- if err != nil {
- return nil, err
- }
+ b = enc.encodeTableHeader(ctx, b)
if enc.indentTables && len(ctx.parentKey) > 0 {
ctx.indent++
@@ -882,6 +939,9 @@ func (enc *Encoder) encodeTable(b []byte, ctx encoderCtx, t table) ([]byte, erro
if shouldOmitEmpty(kv.Options, kv.Value) {
continue
}
+ if kv.Options.omitzero && shouldOmitZero(kv.Options, kv.Value) {
+ continue
+ }
hasNonEmptyKV = true
ctx.setKey(kv.Key)
@@ -901,6 +961,9 @@ func (enc *Encoder) encodeTable(b []byte, ctx encoderCtx, t table) ([]byte, erro
if shouldOmitEmpty(table.Options, table.Value) {
continue
}
+ if table.Options.omitzero && shouldOmitZero(table.Options, table.Value) {
+ continue
+ }
if first {
first = false
if hasNonEmptyKV {
@@ -935,6 +998,9 @@ func (enc *Encoder) encodeTableInline(b []byte, ctx encoderCtx, t table) ([]byte
if shouldOmitEmpty(kv.Options, kv.Value) {
continue
}
+ if kv.Options.omitzero && shouldOmitZero(kv.Options, kv.Value) {
+ continue
+ }
if first {
first = false
@@ -963,11 +1029,14 @@ func willConvertToTable(ctx encoderCtx, v reflect.Value) bool {
if !v.IsValid() {
return false
}
- if v.Type() == timeType || v.Type().Implements(textMarshalerType) || (v.Kind() != reflect.Ptr && v.CanAddr() && reflect.PointerTo(v.Type()).Implements(textMarshalerType)) {
+ t := v.Type()
+ if t == timeType || t.Implements(textMarshalerType) {
+ return false
+ }
+ if v.Kind() != reflect.Ptr && v.CanAddr() && reflect.PointerTo(t).Implements(textMarshalerType) {
return false
}
- t := v.Type()
switch t.Kind() {
case reflect.Map, reflect.Struct:
return !ctx.inline
diff --git a/vendor/github.com/pelletier/go-toml/v2/strict.go b/vendor/github.com/pelletier/go-toml/v2/strict.go
index 802e7e4d1..e9a4be2c3 100644
--- a/vendor/github.com/pelletier/go-toml/v2/strict.go
+++ b/vendor/github.com/pelletier/go-toml/v2/strict.go
@@ -1,7 +1,6 @@
package toml
import (
- "github.com/pelletier/go-toml/v2/internal/danger"
"github.com/pelletier/go-toml/v2/internal/tracker"
"github.com/pelletier/go-toml/v2/unstable"
)
@@ -13,6 +12,9 @@ type strict struct {
key tracker.KeyTracker
missing []unstable.ParserError
+
+ // Reference to the document for computing key ranges.
+ doc []byte
}
func (s *strict) EnterTable(node *unstable.Node) {
@@ -53,7 +55,7 @@ func (s *strict) MissingTable(node *unstable.Node) {
}
s.missing = append(s.missing, unstable.ParserError{
- Highlight: keyLocation(node),
+ Highlight: s.keyLocation(node),
Message: "missing table",
Key: s.key.Key(),
})
@@ -65,8 +67,8 @@ func (s *strict) MissingField(node *unstable.Node) {
}
s.missing = append(s.missing, unstable.ParserError{
- Highlight: keyLocation(node),
- Message: "missing field",
+ Highlight: s.keyLocation(node),
+ Message: "unknown field",
Key: s.key.Key(),
})
}
@@ -88,7 +90,7 @@ func (s *strict) Error(doc []byte) error {
return err
}
-func keyLocation(node *unstable.Node) []byte {
+func (s *strict) keyLocation(node *unstable.Node) []byte {
k := node.Key()
hasOne := k.Next()
@@ -96,12 +98,17 @@ func keyLocation(node *unstable.Node) []byte {
panic("should not be called with empty key")
}
- start := k.Node().Data
- end := k.Node().Data
+ // Get the range from the first key to the last key.
+ firstRaw := k.Node().Raw
+ lastRaw := firstRaw
for k.Next() {
- end = k.Node().Data
+ lastRaw = k.Node().Raw
}
- return danger.BytesRange(start, end)
+ // Compute the slice from the document using the ranges.
+ start := firstRaw.Offset
+ end := lastRaw.Offset + lastRaw.Length
+
+ return s.doc[start:end]
}
diff --git a/vendor/github.com/pelletier/go-toml/v2/test-go-versions.sh b/vendor/github.com/pelletier/go-toml/v2/test-go-versions.sh
new file mode 100644
index 000000000..5fe5c7772
--- /dev/null
+++ b/vendor/github.com/pelletier/go-toml/v2/test-go-versions.sh
@@ -0,0 +1,597 @@
+#!/usr/bin/env bash
+
+set -uo pipefail
+
+# Colors for output
+RED='\033[0;31m'
+GREEN='\033[0;32m'
+YELLOW='\033[1;33m'
+BLUE='\033[0;34m'
+NC='\033[0m' # No Color
+
+# Go versions to test (1.11 through 1.26)
+GO_VERSIONS=(
+ "1.11"
+ "1.12"
+ "1.13"
+ "1.14"
+ "1.15"
+ "1.16"
+ "1.17"
+ "1.18"
+ "1.19"
+ "1.20"
+ "1.21"
+ "1.22"
+ "1.23"
+ "1.24"
+ "1.25"
+ "1.26"
+)
+
+# Default values
+PARALLEL=true
+VERBOSE=false
+OUTPUT_DIR="test-results"
+DOCKER_TIMEOUT="10m"
+
+usage() {
+ cat << EOF
+Usage: $0 [OPTIONS] [GO_VERSIONS...]
+
+Test go-toml across multiple Go versions using Docker containers.
+
+The script reports the lowest continuous supported Go version (where all subsequent
+versions pass) and only exits with non-zero status if either of the two most recent
+Go versions fail, indicating immediate attention is needed.
+
+Note: For Go versions < 1.21, the script automatically updates go.mod to match the
+target version, but older versions may still fail due to missing standard library
+features (e.g., the 'slices' package introduced in Go 1.21).
+
+OPTIONS:
+ -h, --help Show this help message
+ -s, --sequential Run tests sequentially instead of in parallel
+ -v, --verbose Enable verbose output
+ -o, --output DIR Output directory for test results (default: test-results)
+ -t, --timeout TIME Docker timeout for each test (default: 10m)
+ --list List available Go versions and exit
+
+ARGUMENTS:
+ GO_VERSIONS Specific Go versions to test (default: all supported versions)
+ Examples: 1.21 1.22 1.23
+
+EXAMPLES:
+ $0 # Test all Go versions in parallel
+ $0 --sequential # Test all Go versions sequentially
+ $0 1.21 1.22 1.23 # Test specific versions
+ $0 --verbose --output ./results 1.25 1.26 # Verbose output to custom directory
+
+EXIT CODES:
+ 0 Recent Go versions pass (good compatibility)
+ 1 Recent Go versions fail (needs attention) or script error
+
+EOF
+}
+
+log() {
+ echo -e "${BLUE}[$(date +'%H:%M:%S')]${NC} $*" >&2
+}
+
+log_success() {
+ echo -e "${GREEN}[$(date +'%H:%M:%S')] ✓${NC} $*" >&2
+}
+
+log_error() {
+ echo -e "${RED}[$(date +'%H:%M:%S')] ✗${NC} $*" >&2
+}
+
+log_warning() {
+ echo -e "${YELLOW}[$(date +'%H:%M:%S')] ⚠${NC} $*" >&2
+}
+
+# Parse command line arguments
+while [[ $# -gt 0 ]]; do
+ case $1 in
+ -h|--help)
+ usage
+ exit 0
+ ;;
+ -s|--sequential)
+ PARALLEL=false
+ shift
+ ;;
+ -v|--verbose)
+ VERBOSE=true
+ shift
+ ;;
+ -o|--output)
+ OUTPUT_DIR="$2"
+ shift 2
+ ;;
+ -t|--timeout)
+ DOCKER_TIMEOUT="$2"
+ shift 2
+ ;;
+ --list)
+ echo "Available Go versions:"
+ printf '%s\n' "${GO_VERSIONS[@]}"
+ exit 0
+ ;;
+ -*)
+ echo "Unknown option: $1" >&2
+ usage
+ exit 1
+ ;;
+ *)
+ # Remaining arguments are Go versions
+ break
+ ;;
+ esac
+done
+
+# If specific versions provided, use those instead of defaults
+if [[ $# -gt 0 ]]; then
+ GO_VERSIONS=("$@")
+fi
+
+# Validate Go versions
+for version in "${GO_VERSIONS[@]}"; do
+ if ! [[ "$version" =~ ^1\.(1[1-9]|2[0-6])$ ]]; then
+ log_error "Invalid Go version: $version. Supported versions: 1.11-1.26"
+ exit 1
+ fi
+done
+
+# Check if Docker is available
+if ! command -v docker &> /dev/null; then
+ log_error "Docker is required but not installed or not in PATH"
+ exit 1
+fi
+
+# Check if Docker daemon is running
+if ! docker info &> /dev/null; then
+ log_error "Docker daemon is not running"
+ exit 1
+fi
+
+# Create output directory
+mkdir -p "$OUTPUT_DIR"
+
+# Function to test a single Go version
+test_go_version() {
+ local go_version="$1"
+ local container_name="go-toml-test-${go_version}"
+ local result_file="${OUTPUT_DIR}/go-${go_version}.txt"
+ local dockerfile_content
+
+ log "Testing Go $go_version..."
+
+ # Create a temporary Dockerfile for this version
+ # For Go versions < 1.21, we need to update go.mod to match the Go version
+ local needs_go_mod_update=false
+ if [[ $(echo "$go_version 1.21" | tr ' ' '\n' | sort -V | head -n1) == "$go_version" && "$go_version" != "1.21" ]]; then
+ needs_go_mod_update=true
+ fi
+
+ dockerfile_content="FROM golang:${go_version}-alpine
+
+# Install git (required for go mod)
+RUN apk add --no-cache git
+
+# Set working directory
+WORKDIR /app
+
+# Copy source code
+COPY . ."
+
+ # Add go.mod update step for older Go versions
+ if [[ "$needs_go_mod_update" == true ]]; then
+ dockerfile_content="$dockerfile_content
+
+# Update go.mod to match Go version (required for Go < 1.21)
+RUN if [ -f go.mod ]; then sed -i 's/^go [0-9]\\+\\.[0-9]\\+\\(\\.[0-9]\\+\\)\\?/go $go_version/' go.mod; fi
+
+# Note: Go versions < 1.21 may fail due to missing standard library packages (e.g., slices)
+# This is expected for projects that use Go 1.21+ features"
+ fi
+
+ dockerfile_content="$dockerfile_content
+
+# Run tests
+CMD [\"sh\", \"-c\", \"go version && echo '--- Running go test ./... ---' && go test ./...\"]"
+
+ # Create temporary directory for this test
+ local temp_dir
+ temp_dir=$(mktemp -d)
+
+ # Copy source to temp directory (excluding test results and git)
+ rsync -a --exclude="$OUTPUT_DIR" --exclude=".git" --exclude="*.test" . "$temp_dir/"
+
+ # Create Dockerfile in temp directory
+ echo "$dockerfile_content" > "$temp_dir/Dockerfile"
+
+ # Build and run container
+ local exit_code=0
+ local output
+
+ if $VERBOSE; then
+ log "Building Docker image for Go $go_version..."
+ fi
+
+ # Capture both stdout and stderr, and the exit code
+ if output=$(cd "$temp_dir" && timeout "$DOCKER_TIMEOUT" docker build -t "$container_name" . 2>&1 && \
+ timeout "$DOCKER_TIMEOUT" docker run --rm "$container_name" 2>&1); then
+ log_success "Go $go_version: PASSED"
+ echo "PASSED" > "${result_file}.status"
+ else
+ exit_code=$?
+ log_error "Go $go_version: FAILED (exit code: $exit_code)"
+ echo "FAILED" > "${result_file}.status"
+ fi
+
+ # Save full output
+ echo "$output" > "$result_file"
+
+ # Clean up
+ docker rmi "$container_name" &> /dev/null || true
+ rm -rf "$temp_dir"
+
+ if $VERBOSE; then
+ echo "--- Go $go_version output ---"
+ echo "$output"
+ echo "--- End Go $go_version output ---"
+ fi
+
+ return $exit_code
+}
+
+# Function to run tests in parallel
+run_parallel() {
+ local pids=()
+ local failed_versions=()
+
+ log "Starting parallel tests for ${#GO_VERSIONS[@]} Go versions..."
+
+ # Start all tests in background
+ for version in "${GO_VERSIONS[@]}"; do
+ test_go_version "$version" &
+ pids+=($!)
+ done
+
+ # Wait for all tests to complete
+ for i in "${!pids[@]}"; do
+ local pid=${pids[$i]}
+ local version=${GO_VERSIONS[$i]}
+
+ if ! wait $pid; then
+ failed_versions+=("$version")
+ fi
+ done
+
+ return ${#failed_versions[@]}
+}
+
+# Function to run tests sequentially
+run_sequential() {
+ local failed_versions=()
+
+ log "Starting sequential tests for ${#GO_VERSIONS[@]} Go versions..."
+
+ for version in "${GO_VERSIONS[@]}"; do
+ if ! test_go_version "$version"; then
+ failed_versions+=("$version")
+ fi
+ done
+
+ return ${#failed_versions[@]}
+}
+
+# Main execution
+main() {
+ local start_time
+ start_time=$(date +%s)
+
+ log "Starting Go version compatibility tests..."
+ log "Testing versions: ${GO_VERSIONS[*]}"
+ log "Output directory: $OUTPUT_DIR"
+ log "Parallel execution: $PARALLEL"
+
+ local failed_count
+ if $PARALLEL; then
+ run_parallel
+ failed_count=$?
+ else
+ run_sequential
+ failed_count=$?
+ fi
+
+ local end_time
+ end_time=$(date +%s)
+ local duration=$((end_time - start_time))
+
+ # Collect results for display
+ local passed_versions=()
+ local failed_versions=()
+ local unknown_versions=()
+ local passed_count=0
+
+ for version in "${GO_VERSIONS[@]}"; do
+ local status_file="${OUTPUT_DIR}/go-${version}.txt.status"
+ if [[ -f "$status_file" ]]; then
+ local status
+ status=$(cat "$status_file")
+ if [[ "$status" == "PASSED" ]]; then
+ passed_versions+=("$version")
+ ((passed_count++))
+ else
+ failed_versions+=("$version")
+ fi
+ else
+ unknown_versions+=("$version")
+ fi
+ done
+
+ # Generate summary report
+ local summary_file="${OUTPUT_DIR}/summary.txt"
+ {
+ echo "Go Version Compatibility Test Summary"
+ echo "====================================="
+ echo "Date: $(date)"
+ echo "Duration: ${duration}s"
+ echo "Parallel: $PARALLEL"
+ echo ""
+ echo "Results:"
+
+ for version in "${GO_VERSIONS[@]}"; do
+ local status_file="${OUTPUT_DIR}/go-${version}.txt.status"
+ if [[ -f "$status_file" ]]; then
+ local status
+ status=$(cat "$status_file")
+ if [[ "$status" == "PASSED" ]]; then
+ echo " Go $version: ✓ PASSED"
+ else
+ echo " Go $version: ✗ FAILED"
+ fi
+ else
+ echo " Go $version: ? UNKNOWN (no status file)"
+ fi
+ done
+
+ echo ""
+ echo "Summary: $passed_count/${#GO_VERSIONS[@]} versions passed"
+
+ if [[ $failed_count -gt 0 ]]; then
+ echo ""
+ echo "Failed versions details:"
+ for version in "${failed_versions[@]}"; do
+ echo ""
+ echo "--- Go $version (FAILED) ---"
+ local result_file="${OUTPUT_DIR}/go-${version}.txt"
+ if [[ -f "$result_file" ]]; then
+ tail -n 30 "$result_file"
+ fi
+ done
+ fi
+ } > "$summary_file"
+
+ # Find lowest continuous supported version and check recent versions
+ local lowest_continuous_version=""
+ local recent_versions_failed=false
+
+ # Sort versions to ensure proper order
+ local sorted_versions=()
+ for version in "${GO_VERSIONS[@]}"; do
+ sorted_versions+=("$version")
+ done
+ # Sort versions numerically (1.11, 1.12, ..., 1.25)
+ IFS=$'\n' sorted_versions=($(sort -V <<< "${sorted_versions[*]}"))
+
+ # Find lowest continuous supported version (all versions from this point onwards pass)
+ for version in "${sorted_versions[@]}"; do
+ local status_file="${OUTPUT_DIR}/go-${version}.txt.status"
+ local all_subsequent_pass=true
+
+ # Check if this version and all subsequent versions pass
+ local found_current=false
+ for check_version in "${sorted_versions[@]}"; do
+ if [[ "$check_version" == "$version" ]]; then
+ found_current=true
+ fi
+
+ if [[ "$found_current" == true ]]; then
+ local check_status_file="${OUTPUT_DIR}/go-${check_version}.txt.status"
+ if [[ -f "$check_status_file" ]]; then
+ local status
+ status=$(cat "$check_status_file")
+ if [[ "$status" != "PASSED" ]]; then
+ all_subsequent_pass=false
+ break
+ fi
+ else
+ all_subsequent_pass=false
+ break
+ fi
+ fi
+ done
+
+ if [[ "$all_subsequent_pass" == true ]]; then
+ lowest_continuous_version="$version"
+ break
+ fi
+ done
+
+ # Check if the two most recent versions failed
+ local num_versions=${#sorted_versions[@]}
+ if [[ $num_versions -ge 2 ]]; then
+ local second_recent="${sorted_versions[$((num_versions-2))]}"
+ local most_recent="${sorted_versions[$((num_versions-1))]}"
+
+ local second_recent_status_file="${OUTPUT_DIR}/go-${second_recent}.txt.status"
+ local most_recent_status_file="${OUTPUT_DIR}/go-${most_recent}.txt.status"
+
+ local second_recent_failed=false
+ local most_recent_failed=false
+
+ if [[ -f "$second_recent_status_file" ]]; then
+ local status
+ status=$(cat "$second_recent_status_file")
+ if [[ "$status" != "PASSED" ]]; then
+ second_recent_failed=true
+ fi
+ else
+ second_recent_failed=true
+ fi
+
+ if [[ -f "$most_recent_status_file" ]]; then
+ local status
+ status=$(cat "$most_recent_status_file")
+ if [[ "$status" != "PASSED" ]]; then
+ most_recent_failed=true
+ fi
+ else
+ most_recent_failed=true
+ fi
+
+ if [[ "$second_recent_failed" == true || "$most_recent_failed" == true ]]; then
+ recent_versions_failed=true
+ fi
+ elif [[ $num_versions -eq 1 ]]; then
+ # Only one version tested, check if it's the most recent and failed
+ local only_version="${sorted_versions[0]}"
+ local only_status_file="${OUTPUT_DIR}/go-${only_version}.txt.status"
+
+ if [[ -f "$only_status_file" ]]; then
+ local status
+ status=$(cat "$only_status_file")
+ if [[ "$status" != "PASSED" ]]; then
+ recent_versions_failed=true
+ fi
+ else
+ recent_versions_failed=true
+ fi
+ fi
+
+ # Display summary
+ echo ""
+ log "Test completed in ${duration}s"
+ log "Summary report: $summary_file"
+
+ echo ""
+ echo "========================================"
+ echo " FINAL RESULTS"
+ echo "========================================"
+ echo ""
+
+ # Display passed versions
+ if [[ ${#passed_versions[@]} -gt 0 ]]; then
+ log_success "PASSED (${#passed_versions[@]}/${#GO_VERSIONS[@]}):"
+ # Sort passed versions for display
+ local sorted_passed=()
+ for version in "${sorted_versions[@]}"; do
+ for passed_version in "${passed_versions[@]}"; do
+ if [[ "$version" == "$passed_version" ]]; then
+ sorted_passed+=("$version")
+ break
+ fi
+ done
+ done
+ for version in "${sorted_passed[@]}"; do
+ echo -e " ${GREEN}✓${NC} Go $version"
+ done
+ echo ""
+ fi
+
+ # Display failed versions
+ if [[ ${#failed_versions[@]} -gt 0 ]]; then
+ log_error "FAILED (${#failed_versions[@]}/${#GO_VERSIONS[@]}):"
+ # Sort failed versions for display
+ local sorted_failed=()
+ for version in "${sorted_versions[@]}"; do
+ for failed_version in "${failed_versions[@]}"; do
+ if [[ "$version" == "$failed_version" ]]; then
+ sorted_failed+=("$version")
+ break
+ fi
+ done
+ done
+ for version in "${sorted_failed[@]}"; do
+ echo -e " ${RED}✗${NC} Go $version"
+ done
+ echo ""
+
+ # Show failure details
+ echo "========================================"
+ echo " FAILURE DETAILS"
+ echo "========================================"
+ echo ""
+
+ for version in "${sorted_failed[@]}"; do
+ echo -e "${RED}--- Go $version FAILURE LOGS (last 30 lines) ---${NC}"
+ local result_file="${OUTPUT_DIR}/go-${version}.txt"
+ if [[ -f "$result_file" ]]; then
+ tail -n 30 "$result_file" | sed 's/^/ /'
+ else
+ echo " No log file found: $result_file"
+ fi
+ echo ""
+ done
+ fi
+
+ # Display unknown versions
+ if [[ ${#unknown_versions[@]} -gt 0 ]]; then
+ log_warning "UNKNOWN (${#unknown_versions[@]}/${#GO_VERSIONS[@]}):"
+ for version in "${unknown_versions[@]}"; do
+ echo -e " ${YELLOW}?${NC} Go $version (no status file)"
+ done
+ echo ""
+ fi
+
+ echo "========================================"
+ echo " COMPATIBILITY SUMMARY"
+ echo "========================================"
+ echo ""
+
+ if [[ -n "$lowest_continuous_version" ]]; then
+ log_success "Lowest continuous supported version: Go $lowest_continuous_version"
+ echo " (All versions from Go $lowest_continuous_version onwards pass)"
+ else
+ log_error "No continuous version support found"
+ echo " (No version has all subsequent versions passing)"
+ fi
+
+ echo ""
+ echo "========================================"
+ echo "Full detailed logs available in: $OUTPUT_DIR"
+ echo "========================================"
+
+ # Determine exit code based on recent versions
+ if [[ "$recent_versions_failed" == true ]]; then
+ log_error "OVERALL RESULT: Recent Go versions failed - this needs attention!"
+ if [[ -n "$lowest_continuous_version" ]]; then
+ echo "Note: Continuous support starts from Go $lowest_continuous_version"
+ fi
+ exit 1
+ else
+ log_success "OVERALL RESULT: Recent Go versions pass - compatibility looks good!"
+ if [[ -n "$lowest_continuous_version" ]]; then
+ echo "Continuous support starts from Go $lowest_continuous_version"
+ fi
+ exit 0
+ fi
+}
+
+# Trap to clean up on exit
+cleanup() {
+ # Kill any remaining background processes
+ jobs -p | xargs -r kill 2>/dev/null || true
+
+ # Clean up any remaining Docker containers
+ docker ps -q --filter "name=go-toml-test-" | xargs -r docker stop 2>/dev/null || true
+ docker images -q --filter "reference=go-toml-test-*" | xargs -r docker rmi 2>/dev/null || true
+}
+
+trap cleanup EXIT
+
+# Run main function
+main
diff --git a/vendor/github.com/pelletier/go-toml/v2/types.go b/vendor/github.com/pelletier/go-toml/v2/types.go
index 3c6b8fe57..6d12fe580 100644
--- a/vendor/github.com/pelletier/go-toml/v2/types.go
+++ b/vendor/github.com/pelletier/go-toml/v2/types.go
@@ -6,9 +6,18 @@ import (
"time"
)
-var timeType = reflect.TypeOf((*time.Time)(nil)).Elem()
-var textMarshalerType = reflect.TypeOf((*encoding.TextMarshaler)(nil)).Elem()
-var textUnmarshalerType = reflect.TypeOf((*encoding.TextUnmarshaler)(nil)).Elem()
-var mapStringInterfaceType = reflect.TypeOf(map[string]interface{}(nil))
-var sliceInterfaceType = reflect.TypeOf([]interface{}(nil))
-var stringType = reflect.TypeOf("")
+// isZeroer is used to check if a type has a custom IsZero method.
+// This allows custom types to define their own zero-value semantics.
+type isZeroer interface {
+ IsZero() bool
+}
+
+var (
+ timeType = reflect.TypeOf((*time.Time)(nil)).Elem()
+ textMarshalerType = reflect.TypeOf((*encoding.TextMarshaler)(nil)).Elem()
+ textUnmarshalerType = reflect.TypeOf((*encoding.TextUnmarshaler)(nil)).Elem()
+ isZeroerType = reflect.TypeOf((*isZeroer)(nil)).Elem()
+ mapStringInterfaceType = reflect.TypeOf(map[string]interface{}(nil))
+ sliceInterfaceType = reflect.TypeOf([]interface{}(nil))
+ stringType = reflect.TypeOf("")
+)
diff --git a/vendor/github.com/pelletier/go-toml/v2/unmarshaler.go b/vendor/github.com/pelletier/go-toml/v2/unmarshaler.go
index 189be525e..e7db8128c 100644
--- a/vendor/github.com/pelletier/go-toml/v2/unmarshaler.go
+++ b/vendor/github.com/pelletier/go-toml/v2/unmarshaler.go
@@ -12,7 +12,6 @@ import (
"sync/atomic"
"time"
- "github.com/pelletier/go-toml/v2/internal/danger"
"github.com/pelletier/go-toml/v2/internal/tracker"
"github.com/pelletier/go-toml/v2/unstable"
)
@@ -57,13 +56,18 @@ func (d *Decoder) DisallowUnknownFields() *Decoder {
// EnableUnmarshalerInterface allows to enable unmarshaler interface.
//
-// With this feature enabled, types implementing the unstable/Unmarshaler
+// With this feature enabled, types implementing the unstable.Unmarshaler
// interface can be decoded from any structure of the document. It allows types
// that don't have a straightforward TOML representation to provide their own
// decoding logic.
//
-// Currently, types can only decode from a single value. Tables and array tables
-// are not supported.
+// The UnmarshalTOML method receives raw TOML bytes:
+// - For single values: the raw value bytes (e.g., `"hello"` for a string)
+// - For tables: all key-value lines belonging to that table
+// - For inline tables/arrays: the raw bytes of the inline structure
+//
+// The unstable.RawMessage type can be used to capture raw TOML bytes for
+// later processing, similar to json.RawMessage.
//
// *Unstable:* This method does not follow the compatibility guarantees of
// semver. It can be changed or removed without a new major version being
@@ -123,6 +127,7 @@ func (d *Decoder) Decode(v interface{}) error {
dec := decoder{
strict: strict{
Enabled: d.strict,
+ doc: b,
},
unmarshalerInterface: d.unmarshalerInterface,
}
@@ -226,7 +231,7 @@ func (d *decoder) FromParser(v interface{}) error {
}
if r.IsNil() {
- return fmt.Errorf("toml: decoding pointer target cannot be nil")
+ return errors.New("toml: decoding pointer target cannot be nil")
}
r = r.Elem()
@@ -273,7 +278,7 @@ func (d *decoder) handleRootExpression(expr *unstable.Node, v reflect.Value) err
var err error
var first bool // used for to clear array tables on first use
- if !(d.skipUntilTable && expr.Kind == unstable.KeyValue) {
+ if !d.skipUntilTable || expr.Kind != unstable.KeyValue {
first, err = d.seen.CheckExpression(expr)
if err != nil {
return err
@@ -378,7 +383,7 @@ func (d *decoder) handleArrayTableCollectionLast(key unstable.Iterator, v reflec
case reflect.Array:
idx := d.arrayIndex(true, v)
if idx >= v.Len() {
- return v, fmt.Errorf("%s at position %d", d.typeMismatchError("array table", v.Type()), idx)
+ return v, fmt.Errorf("%w at position %d", d.typeMismatchError("array table", v.Type()), idx)
}
elem := v.Index(idx)
_, err := d.handleArrayTable(key, elem)
@@ -416,27 +421,51 @@ func (d *decoder) handleArrayTableCollection(key unstable.Iterator, v reflect.Va
return v, nil
case reflect.Slice:
- elem := v.Index(v.Len() - 1)
+ // Create a new element when the slice is empty; otherwise operate on
+ // the last element.
+ var (
+ elem reflect.Value
+ created bool
+ )
+ if v.Len() == 0 {
+ created = true
+ elemType := v.Type().Elem()
+ if elemType.Kind() == reflect.Interface {
+ elem = makeMapStringInterface()
+ } else {
+ elem = reflect.New(elemType).Elem()
+ }
+ } else {
+ elem = v.Index(v.Len() - 1)
+ }
+
x, err := d.handleArrayTable(key, elem)
if err != nil || d.skipUntilTable {
return reflect.Value{}, err
}
if x.IsValid() {
- elem.Set(x)
+ if created {
+ elem = x
+ } else {
+ elem.Set(x)
+ }
}
+ if created {
+ return reflect.Append(v, elem), nil
+ }
return v, err
case reflect.Array:
idx := d.arrayIndex(false, v)
if idx >= v.Len() {
- return v, fmt.Errorf("%s at position %d", d.typeMismatchError("array table", v.Type()), idx)
+ return v, fmt.Errorf("%w at position %d", d.typeMismatchError("array table", v.Type()), idx)
}
elem := v.Index(idx)
_, err := d.handleArrayTable(key, elem)
return v, err
+ default:
+ return d.handleArrayTable(key, v)
}
-
- return d.handleArrayTable(key, v)
}
func (d *decoder) handleKeyPart(key unstable.Iterator, v reflect.Value, nextFn handlerFn, makeFn valueMakerFn) (reflect.Value, error) {
@@ -470,7 +499,8 @@ func (d *decoder) handleKeyPart(key unstable.Iterator, v reflect.Value, nextFn h
mv := v.MapIndex(mk)
set := false
- if !mv.IsValid() {
+ switch {
+ case !mv.IsValid():
// If there is no value in the map, create a new one according to
// the map type. If the element type is interface, create either a
// map[string]interface{} or a []interface{} depending on whether
@@ -483,13 +513,13 @@ func (d *decoder) handleKeyPart(key unstable.Iterator, v reflect.Value, nextFn h
mv = reflect.New(t).Elem()
}
set = true
- } else if mv.Kind() == reflect.Interface {
+ case mv.Kind() == reflect.Interface:
mv = mv.Elem()
if !mv.IsValid() {
mv = makeFn()
}
set = true
- } else if !mv.CanAddr() {
+ case !mv.CanAddr():
vt := v.Type()
t := vt.Elem()
oldmv := mv
@@ -574,18 +604,28 @@ func (d *decoder) handleArrayTablePart(key unstable.Iterator, v reflect.Value) (
// cannot handle it.
func (d *decoder) handleTable(key unstable.Iterator, v reflect.Value) (reflect.Value, error) {
if v.Kind() == reflect.Slice {
- if v.Len() == 0 {
- return reflect.Value{}, unstable.NewParserError(key.Node().Data, "cannot store a table in a slice")
- }
- elem := v.Index(v.Len() - 1)
- x, err := d.handleTable(key, elem)
- if err != nil {
- return reflect.Value{}, err
+ // For non-empty slices, work with the last element
+ if v.Len() > 0 {
+ elem := v.Index(v.Len() - 1)
+ x, err := d.handleTable(key, elem)
+ if err != nil {
+ return reflect.Value{}, err
+ }
+ if x.IsValid() {
+ elem.Set(x)
+ }
+ return reflect.Value{}, nil
}
- if x.IsValid() {
- elem.Set(x)
+ // Empty slice - check if it implements Unmarshaler (e.g., RawMessage)
+ // and we're at the end of the key path
+ if d.unmarshalerInterface && !key.Next() {
+ if v.CanAddr() && v.Addr().CanInterface() {
+ if outi, ok := v.Addr().Interface().(unstable.Unmarshaler); ok {
+ return d.handleKeyValuesUnmarshaler(outi)
+ }
+ }
}
- return reflect.Value{}, nil
+ return reflect.Value{}, unstable.NewParserError(key.Node().Data, "cannot store a table in a slice")
}
if key.Next() {
// Still scoping the key
@@ -599,6 +639,24 @@ func (d *decoder) handleTable(key unstable.Iterator, v reflect.Value) (reflect.V
// Handle root expressions until the end of the document or the next
// non-key-value.
func (d *decoder) handleKeyValues(v reflect.Value) (reflect.Value, error) {
+ // Check if target implements Unmarshaler before processing key-values.
+ // This allows types to handle entire tables themselves.
+ if d.unmarshalerInterface {
+ vv := v
+ for vv.Kind() == reflect.Ptr {
+ if vv.IsNil() {
+ vv.Set(reflect.New(vv.Type().Elem()))
+ }
+ vv = vv.Elem()
+ }
+ if vv.CanAddr() && vv.Addr().CanInterface() {
+ if outi, ok := vv.Addr().Interface().(unstable.Unmarshaler); ok {
+ // Collect all key-value expressions for this table
+ return d.handleKeyValuesUnmarshaler(outi)
+ }
+ }
+ }
+
var rv reflect.Value
for d.nextExpr() {
expr := d.expr()
@@ -628,6 +686,41 @@ func (d *decoder) handleKeyValues(v reflect.Value) (reflect.Value, error) {
return rv, nil
}
+// handleKeyValuesUnmarshaler collects all key-value expressions for a table
+// and passes them to the Unmarshaler as raw TOML bytes.
+func (d *decoder) handleKeyValuesUnmarshaler(u unstable.Unmarshaler) (reflect.Value, error) {
+ // Collect raw bytes from all key-value expressions for this table.
+ // We use the Raw field on each KeyValue expression to preserve the
+ // original formatting (whitespace, quoting style, etc.) from the document.
+ var buf []byte
+
+ for d.nextExpr() {
+ expr := d.expr()
+ if expr.Kind != unstable.KeyValue {
+ d.stashExpr()
+ break
+ }
+
+ _, err := d.seen.CheckExpression(expr)
+ if err != nil {
+ return reflect.Value{}, err
+ }
+
+ // Use the raw bytes from the original document to preserve formatting
+ if expr.Raw.Length > 0 {
+ raw := d.p.Raw(expr.Raw)
+ buf = append(buf, raw...)
+ }
+ buf = append(buf, '\n')
+ }
+
+ if err := u.UnmarshalTOML(buf); err != nil {
+ return reflect.Value{}, err
+ }
+
+ return reflect.Value{}, nil
+}
+
type (
handlerFn func(key unstable.Iterator, v reflect.Value) (reflect.Value, error)
valueMakerFn func() reflect.Value
@@ -672,14 +765,21 @@ func (d *decoder) handleValue(value *unstable.Node, v reflect.Value) error {
if d.unmarshalerInterface {
if v.CanAddr() && v.Addr().CanInterface() {
if outi, ok := v.Addr().Interface().(unstable.Unmarshaler); ok {
- return outi.UnmarshalTOML(value)
+ // Pass raw bytes from the original document
+ return outi.UnmarshalTOML(d.p.Raw(value.Raw))
}
}
}
- ok, err := d.tryTextUnmarshaler(value, v)
- if ok || err != nil {
- return err
+ // Only try TextUnmarshaler for scalar types. For Array and InlineTable,
+ // fall through to struct/map unmarshaling to allow flexible unmarshaling
+ // where a type can implement UnmarshalText for string values but still
+ // be populated field-by-field from a table. See issue #974.
+ if value.Kind != unstable.Array && value.Kind != unstable.InlineTable {
+ ok, err := d.tryTextUnmarshaler(value, v)
+ if ok || err != nil {
+ return err
+ }
}
switch value.Kind {
@@ -821,6 +921,9 @@ func (d *decoder) unmarshalDateTime(value *unstable.Node, v reflect.Value) error
return err
}
+ if v.Kind() != reflect.Interface && v.Type() != timeType {
+ return unstable.NewParserError(d.p.Raw(value.Raw), "%s", d.typeMismatchString("datetime", v.Type()))
+ }
v.Set(reflect.ValueOf(dt))
return nil
}
@@ -831,14 +934,14 @@ func (d *decoder) unmarshalLocalDate(value *unstable.Node, v reflect.Value) erro
return err
}
+ if v.Kind() != reflect.Interface && v.Type() != timeType {
+ return unstable.NewParserError(d.p.Raw(value.Raw), "%s", d.typeMismatchString("local date", v.Type()))
+ }
if v.Type() == timeType {
- cast := ld.AsTime(time.Local)
- v.Set(reflect.ValueOf(cast))
+ v.Set(reflect.ValueOf(ld.AsTime(time.Local)))
return nil
}
-
v.Set(reflect.ValueOf(ld))
-
return nil
}
@@ -852,6 +955,9 @@ func (d *decoder) unmarshalLocalTime(value *unstable.Node, v reflect.Value) erro
return unstable.NewParserError(rest, "extra characters at the end of a local time")
}
+ if v.Kind() != reflect.Interface {
+ return unstable.NewParserError(d.p.Raw(value.Raw), "%s", d.typeMismatchString("local time", v.Type()))
+ }
v.Set(reflect.ValueOf(lt))
return nil
}
@@ -866,15 +972,14 @@ func (d *decoder) unmarshalLocalDateTime(value *unstable.Node, v reflect.Value)
return unstable.NewParserError(rest, "extra characters at the end of a local date time")
}
+ if v.Kind() != reflect.Interface && v.Type() != timeType {
+ return unstable.NewParserError(d.p.Raw(value.Raw), "%s", d.typeMismatchString("local datetime", v.Type()))
+ }
if v.Type() == timeType {
- cast := ldt.AsTime(time.Local)
-
- v.Set(reflect.ValueOf(cast))
+ v.Set(reflect.ValueOf(ldt.AsTime(time.Local)))
return nil
}
-
v.Set(reflect.ValueOf(ldt))
-
return nil
}
@@ -929,8 +1034,9 @@ const (
// compile time, so it is computed during initialization.
var maxUint int64 = math.MaxInt64
-func init() {
+func init() { //nolint:gochecknoinits
m := uint64(^uint(0))
+ // #nosec G115
if m < uint64(maxUint) {
maxUint = int64(m)
}
@@ -1010,7 +1116,7 @@ func (d *decoder) unmarshalInteger(value *unstable.Node, v reflect.Value) error
case reflect.Interface:
r = reflect.ValueOf(i)
default:
- return unstable.NewParserError(d.p.Raw(value.Raw), d.typeMismatchString("integer", v.Type()))
+ return unstable.NewParserError(d.p.Raw(value.Raw), "%s", d.typeMismatchString("integer", v.Type()))
}
if !r.Type().AssignableTo(v.Type()) {
@@ -1029,7 +1135,7 @@ func (d *decoder) unmarshalString(value *unstable.Node, v reflect.Value) error {
case reflect.Interface:
v.Set(reflect.ValueOf(string(value.Data)))
default:
- return unstable.NewParserError(d.p.Raw(value.Raw), d.typeMismatchString("string", v.Type()))
+ return unstable.NewParserError(d.p.Raw(value.Raw), "%s", d.typeMismatchString("string", v.Type()))
}
return nil
@@ -1080,35 +1186,39 @@ func (d *decoder) keyFromData(keyType reflect.Type, data []byte) (reflect.Value,
return reflect.Value{}, fmt.Errorf("toml: error unmarshalling key type %s from text: %w", stringType, err)
}
return mk.Elem(), nil
+ }
- case keyType.Kind() == reflect.Int || keyType.Kind() == reflect.Int8 || keyType.Kind() == reflect.Int16 || keyType.Kind() == reflect.Int32 || keyType.Kind() == reflect.Int64:
+ switch keyType.Kind() {
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
key, err := strconv.ParseInt(string(data), 10, 64)
if err != nil {
return reflect.Value{}, fmt.Errorf("toml: error parsing key of type %s from integer: %w", stringType, err)
}
return reflect.ValueOf(key).Convert(keyType), nil
- case keyType.Kind() == reflect.Uint || keyType.Kind() == reflect.Uint8 || keyType.Kind() == reflect.Uint16 || keyType.Kind() == reflect.Uint32 || keyType.Kind() == reflect.Uint64:
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
key, err := strconv.ParseUint(string(data), 10, 64)
if err != nil {
return reflect.Value{}, fmt.Errorf("toml: error parsing key of type %s from unsigned integer: %w", stringType, err)
}
return reflect.ValueOf(key).Convert(keyType), nil
- case keyType.Kind() == reflect.Float32:
+ case reflect.Float32:
key, err := strconv.ParseFloat(string(data), 32)
if err != nil {
return reflect.Value{}, fmt.Errorf("toml: error parsing key of type %s from float: %w", stringType, err)
}
return reflect.ValueOf(float32(key)), nil
- case keyType.Kind() == reflect.Float64:
+ case reflect.Float64:
key, err := strconv.ParseFloat(string(data), 64)
if err != nil {
return reflect.Value{}, fmt.Errorf("toml: error parsing key of type %s from float: %w", stringType, err)
}
return reflect.ValueOf(float64(key)), nil
+
+ default:
+ return reflect.Value{}, fmt.Errorf("toml: cannot convert map key of type %s to expected type %s", stringType, keyType)
}
- return reflect.Value{}, fmt.Errorf("toml: cannot convert map key of type %s to expected type %s", stringType, keyType)
}
func (d *decoder) handleKeyValuePart(key unstable.Iterator, value *unstable.Node, v reflect.Value) (reflect.Value, error) {
@@ -1154,6 +1264,18 @@ func (d *decoder) handleKeyValuePart(key unstable.Iterator, value *unstable.Node
case reflect.Struct:
path, found := structFieldPath(v, string(key.Node().Data))
if !found {
+ // If no matching struct field is found but the target implements the
+ // unstable.Unmarshaler interface (and it is enabled), delegate the
+ // decoding of this value to the custom unmarshaler.
+ if d.unmarshalerInterface {
+ if v.CanAddr() && v.Addr().CanInterface() {
+ if outi, ok := v.Addr().Interface().(unstable.Unmarshaler); ok {
+ // Pass raw bytes from the original document
+ return reflect.Value{}, outi.UnmarshalTOML(d.p.Raw(value.Raw))
+ }
+ }
+ }
+ // Otherwise, keep previous behavior and skip until the next table.
d.skipUntilTable = true
break
}
@@ -1259,13 +1381,13 @@ func fieldByIndex(v reflect.Value, path []int) reflect.Value {
type fieldPathsMap = map[string][]int
-var globalFieldPathsCache atomic.Value // map[danger.TypeID]fieldPathsMap
+var globalFieldPathsCache atomic.Value // map[reflect.Type]fieldPathsMap
func structFieldPath(v reflect.Value, name string) ([]int, bool) {
t := v.Type()
- cache, _ := globalFieldPathsCache.Load().(map[danger.TypeID]fieldPathsMap)
- fieldPaths, ok := cache[danger.MakeTypeID(t)]
+ cache, _ := globalFieldPathsCache.Load().(map[reflect.Type]fieldPathsMap)
+ fieldPaths, ok := cache[t]
if !ok {
fieldPaths = map[string][]int{}
@@ -1276,8 +1398,8 @@ func structFieldPath(v reflect.Value, name string) ([]int, bool) {
fieldPaths[strings.ToLower(name)] = path
})
- newCache := make(map[danger.TypeID]fieldPathsMap, len(cache)+1)
- newCache[danger.MakeTypeID(t)] = fieldPaths
+ newCache := make(map[reflect.Type]fieldPathsMap, len(cache)+1)
+ newCache[t] = fieldPaths
for k, v := range cache {
newCache[k] = v
}
@@ -1301,7 +1423,9 @@ func forEachField(t reflect.Type, path []int, do func(name string, path []int))
continue
}
- fieldPath := append(path, i)
+ fieldPath := make([]int, 0, len(path)+1)
+ fieldPath = append(fieldPath, path...)
+ fieldPath = append(fieldPath, i)
fieldPath = fieldPath[:len(fieldPath):len(fieldPath)]
name := f.Tag.Get("toml")
diff --git a/vendor/github.com/pelletier/go-toml/v2/unstable/ast.go b/vendor/github.com/pelletier/go-toml/v2/unstable/ast.go
index f526bf2c0..6b21592d6 100644
--- a/vendor/github.com/pelletier/go-toml/v2/unstable/ast.go
+++ b/vendor/github.com/pelletier/go-toml/v2/unstable/ast.go
@@ -1,10 +1,8 @@
package unstable
import (
+ "errors"
"fmt"
- "unsafe"
-
- "github.com/pelletier/go-toml/v2/internal/danger"
)
// Iterator over a sequence of nodes.
@@ -19,30 +17,43 @@ import (
// // do something with n
// }
type Iterator struct {
+ nodes *[]Node
+ idx int32
started bool
- node *Node
}
// Next moves the iterator forward and returns true if points to a
// node, false otherwise.
func (c *Iterator) Next() bool {
+ if c.nodes == nil {
+ return false
+ }
+ nodes := *c.nodes
if !c.started {
c.started = true
- } else if c.node.Valid() {
- c.node = c.node.Next()
+ } else {
+ idx := c.idx
+ if idx >= 0 && int(idx) < len(nodes) {
+ c.idx = nodes[idx].next
+ }
}
- return c.node.Valid()
+ return c.idx >= 0 && int(c.idx) < len(nodes)
}
// IsLast returns true if the current node of the iterator is the last
// one. Subsequent calls to Next() will return false.
func (c *Iterator) IsLast() bool {
- return c.node.next == 0
+ return c.nodes == nil || c.idx < 0 || (*c.nodes)[c.idx].next < 0
}
// Node returns a pointer to the node pointed at by the iterator.
func (c *Iterator) Node() *Node {
- return c.node
+ if c.nodes == nil || c.idx < 0 {
+ return nil
+ }
+ n := &(*c.nodes)[c.idx]
+ n.nodes = c.nodes
+ return n
}
// Node in a TOML expression AST.
@@ -65,11 +76,12 @@ type Node struct {
Raw Range // Raw bytes from the input.
Data []byte // Node value (either allocated or referencing the input).
- // References to other nodes, as offsets in the backing array
- // from this node. References can go backward, so those can be
- // negative.
- next int // 0 if last element
- child int // 0 if no child
+ // Absolute indices into the backing nodes slice. -1 means none.
+ next int32
+ child int32
+
+ // Reference to the backing nodes slice for navigation.
+ nodes *[]Node
}
// Range of bytes in the document.
@@ -80,24 +92,24 @@ type Range struct {
// Next returns a pointer to the next node, or nil if there is no next node.
func (n *Node) Next() *Node {
- if n.next == 0 {
+ if n.next < 0 {
return nil
}
- ptr := unsafe.Pointer(n)
- size := unsafe.Sizeof(Node{})
- return (*Node)(danger.Stride(ptr, size, n.next))
+ next := &(*n.nodes)[n.next]
+ next.nodes = n.nodes
+ return next
}
// Child returns a pointer to the first child node of this node. Other children
-// can be accessed calling Next on the first child. Returns an nil if this Node
+// can be accessed calling Next on the first child. Returns nil if this Node
// has no child.
func (n *Node) Child() *Node {
- if n.child == 0 {
+ if n.child < 0 {
return nil
}
- ptr := unsafe.Pointer(n)
- size := unsafe.Sizeof(Node{})
- return (*Node)(danger.Stride(ptr, size, n.child))
+ child := &(*n.nodes)[n.child]
+ child.nodes = n.nodes
+ return child
}
// Valid returns true if the node's kind is set (not to Invalid).
@@ -111,13 +123,14 @@ func (n *Node) Valid() bool {
func (n *Node) Key() Iterator {
switch n.Kind {
case KeyValue:
- value := n.Child()
- if !value.Valid() {
- panic(fmt.Errorf("KeyValue should have at least two children"))
+ child := n.child
+ if child < 0 {
+ panic(errors.New("KeyValue should have at least two children"))
}
- return Iterator{node: value.Next()}
+ valueNode := &(*n.nodes)[child]
+ return Iterator{nodes: n.nodes, idx: valueNode.next}
case Table, ArrayTable:
- return Iterator{node: n.Child()}
+ return Iterator{nodes: n.nodes, idx: n.child}
default:
panic(fmt.Errorf("Key() is not supported on a %s", n.Kind))
}
@@ -132,5 +145,5 @@ func (n *Node) Value() *Node {
// Children returns an iterator over a node's children.
func (n *Node) Children() Iterator {
- return Iterator{node: n.Child()}
+ return Iterator{nodes: n.nodes, idx: n.child}
}
diff --git a/vendor/github.com/pelletier/go-toml/v2/unstable/builder.go b/vendor/github.com/pelletier/go-toml/v2/unstable/builder.go
index 9538e30df..e4354985b 100644
--- a/vendor/github.com/pelletier/go-toml/v2/unstable/builder.go
+++ b/vendor/github.com/pelletier/go-toml/v2/unstable/builder.go
@@ -7,15 +7,6 @@ type root struct {
nodes []Node
}
-// Iterator over the top level nodes.
-func (r *root) Iterator() Iterator {
- it := Iterator{}
- if len(r.nodes) > 0 {
- it.node = &r.nodes[0]
- }
- return it
-}
-
func (r *root) at(idx reference) *Node {
return &r.nodes[idx]
}
@@ -33,12 +24,10 @@ type builder struct {
lastIdx int
}
-func (b *builder) Tree() *root {
- return &b.tree
-}
-
func (b *builder) NodeAt(ref reference) *Node {
- return b.tree.at(ref)
+ n := b.tree.at(ref)
+ n.nodes = &b.tree.nodes
+ return n
}
func (b *builder) Reset() {
@@ -48,24 +37,28 @@ func (b *builder) Reset() {
func (b *builder) Push(n Node) reference {
b.lastIdx = len(b.tree.nodes)
+ n.next = -1
+ n.child = -1
b.tree.nodes = append(b.tree.nodes, n)
return reference(b.lastIdx)
}
func (b *builder) PushAndChain(n Node) reference {
newIdx := len(b.tree.nodes)
+ n.next = -1
+ n.child = -1
b.tree.nodes = append(b.tree.nodes, n)
if b.lastIdx >= 0 {
- b.tree.nodes[b.lastIdx].next = newIdx - b.lastIdx
+ b.tree.nodes[b.lastIdx].next = int32(newIdx) //nolint:gosec // TOML ASTs are small
}
b.lastIdx = newIdx
return reference(b.lastIdx)
}
func (b *builder) AttachChild(parent reference, child reference) {
- b.tree.nodes[parent].child = int(child) - int(parent)
+ b.tree.nodes[parent].child = int32(child) //nolint:gosec // TOML ASTs are small
}
func (b *builder) Chain(from reference, to reference) {
- b.tree.nodes[from].next = int(to) - int(from)
+ b.tree.nodes[from].next = int32(to) //nolint:gosec // TOML ASTs are small
}
diff --git a/vendor/github.com/pelletier/go-toml/v2/unstable/kind.go b/vendor/github.com/pelletier/go-toml/v2/unstable/kind.go
index ff9df1bef..f87a95a78 100644
--- a/vendor/github.com/pelletier/go-toml/v2/unstable/kind.go
+++ b/vendor/github.com/pelletier/go-toml/v2/unstable/kind.go
@@ -6,28 +6,40 @@ import "fmt"
type Kind int
const (
- // Meta
+ // Invalid represents an invalid meta node.
Invalid Kind = iota
+ // Comment represents a comment meta node.
Comment
+ // Key represents a key meta node.
Key
- // Top level structures
+ // Table represents a top-level table.
Table
+ // ArrayTable represents a top-level array table.
ArrayTable
+ // KeyValue represents a top-level key value.
KeyValue
- // Containers values
+ // Array represents an array container value.
Array
+ // InlineTable represents an inline table container value.
InlineTable
- // Values
+ // String represents a string value.
String
+ // Bool represents a boolean value.
Bool
+ // Float represents a floating point value.
Float
+ // Integer represents an integer value.
Integer
+ // LocalDate represents a a local date value.
LocalDate
+ // LocalTime represents a local time value.
LocalTime
+ // LocalDateTime represents a local date/time value.
LocalDateTime
+ // DateTime represents a data/time value.
DateTime
)
diff --git a/vendor/github.com/pelletier/go-toml/v2/unstable/parser.go b/vendor/github.com/pelletier/go-toml/v2/unstable/parser.go
index 50358a44f..153830123 100644
--- a/vendor/github.com/pelletier/go-toml/v2/unstable/parser.go
+++ b/vendor/github.com/pelletier/go-toml/v2/unstable/parser.go
@@ -3,10 +3,10 @@ package unstable
import (
"bytes"
"fmt"
+ "reflect"
"unicode"
"github.com/pelletier/go-toml/v2/internal/characters"
- "github.com/pelletier/go-toml/v2/internal/danger"
)
// ParserError describes an error relative to the content of the document.
@@ -70,11 +70,34 @@ func (p *Parser) Data() []byte {
// panics.
func (p *Parser) Range(b []byte) Range {
return Range{
- Offset: uint32(danger.SubsliceOffset(p.data, b)),
- Length: uint32(len(b)),
+ Offset: uint32(p.subsliceOffset(b)), //nolint:gosec // TOML documents are small
+ Length: uint32(len(b)), //nolint:gosec // TOML documents are small
}
}
+// rangeOfToken computes the Range of a token given the remaining bytes after the token.
+// This is used when the token was extracted from the beginning of some position,
+// and 'rest' is what remains after the token.
+func (p *Parser) rangeOfToken(token, rest []byte) Range {
+ offset := len(p.data) - len(token) - len(rest)
+ return Range{Offset: uint32(offset), Length: uint32(len(token))} //nolint:gosec // TOML documents are small
+}
+
+// subsliceOffset returns the byte offset of subslice b within p.data.
+// b must share the same backing array as p.data.
+func (p *Parser) subsliceOffset(b []byte) int {
+ if len(b) == 0 {
+ return len(p.data)
+ }
+ dataPtr := reflect.ValueOf(p.data).Pointer()
+ subPtr := reflect.ValueOf(b).Pointer()
+ offset := int(subPtr - dataPtr)
+ if offset < 0 || offset > len(p.data) {
+ panic("subslice is not within data")
+ }
+ return offset
+}
+
// Raw returns the slice corresponding to the bytes in the given range.
func (p *Parser) Raw(raw Range) []byte {
return p.data[raw.Offset : raw.Offset+raw.Length]
@@ -158,9 +181,17 @@ type Shape struct {
End Position
}
-func (p *Parser) position(b []byte) Position {
- offset := danger.SubsliceOffset(p.data, b)
+// Shape returns the shape of the given range in the input. Will
+// panic if the range is not a subslice of the input.
+func (p *Parser) Shape(r Range) Shape {
+ return Shape{
+ Start: p.positionAt(int(r.Offset)),
+ End: p.positionAt(int(r.Offset + r.Length)),
+ }
+}
+// positionAt returns the position at the given byte offset in the document.
+func (p *Parser) positionAt(offset int) Position {
lead := p.data[:offset]
return Position{
@@ -170,16 +201,6 @@ func (p *Parser) position(b []byte) Position {
}
}
-// Shape returns the shape of the given range in the input. Will
-// panic if the range is not a subslice of the input.
-func (p *Parser) Shape(r Range) Shape {
- raw := p.Raw(r)
- return Shape{
- Start: p.position(raw),
- End: p.position(raw[r.Length:]),
- }
-}
-
func (p *Parser) parseNewline(b []byte) ([]byte, error) {
if b[0] == '\n' {
return b[1:], nil
@@ -199,7 +220,7 @@ func (p *Parser) parseComment(b []byte) (reference, []byte, error) {
if p.KeepComments && err == nil {
ref = p.builder.Push(Node{
Kind: Comment,
- Raw: p.Range(data),
+ Raw: p.rangeOfToken(data, rest),
Data: data,
})
}
@@ -316,6 +337,9 @@ func (p *Parser) parseStdTable(b []byte) (reference, []byte, error) {
func (p *Parser) parseKeyval(b []byte) (reference, []byte, error) {
// keyval = key keyval-sep val
+ // Track the start position for Raw range
+ startB := b
+
ref := p.builder.Push(Node{
Kind: KeyValue,
})
@@ -330,7 +354,7 @@ func (p *Parser) parseKeyval(b []byte) (reference, []byte, error) {
b = p.parseWhitespace(b)
if len(b) == 0 {
- return invalidReference, nil, NewParserError(b, "expected = after a key, but the document ends there")
+ return invalidReference, nil, NewParserError(startB[:len(startB)-len(b)], "expected = after a key, but the document ends there")
}
b, err = expect('=', b)
@@ -348,6 +372,11 @@ func (p *Parser) parseKeyval(b []byte) (reference, []byte, error) {
p.builder.Chain(valRef, key)
p.builder.AttachChild(ref, valRef)
+ // Set Raw to span the entire key-value expression.
+ // Access the node directly in the slice to avoid the write barrier
+ // that NodeAt's nodes-pointer setup would trigger.
+ p.builder.tree.nodes[ref].Raw = p.rangeOfToken(startB[:len(startB)-len(b)], b)
+
return ref, b, err
}
@@ -376,7 +405,7 @@ func (p *Parser) parseVal(b []byte) (reference, []byte, error) {
if err == nil {
ref = p.builder.Push(Node{
Kind: String,
- Raw: p.Range(raw),
+ Raw: p.rangeOfToken(raw, b),
Data: v,
})
}
@@ -394,7 +423,7 @@ func (p *Parser) parseVal(b []byte) (reference, []byte, error) {
if err == nil {
ref = p.builder.Push(Node{
Kind: String,
- Raw: p.Range(raw),
+ Raw: p.rangeOfToken(raw, b),
Data: v,
})
}
@@ -456,7 +485,7 @@ func (p *Parser) parseInlineTable(b []byte) (reference, []byte, error) {
// inline-table-keyvals = keyval [ inline-table-sep inline-table-keyvals ]
parent := p.builder.Push(Node{
Kind: InlineTable,
- Raw: p.Range(b[:1]),
+ Raw: p.rangeOfToken(b[:1], b[1:]),
})
first := true
@@ -542,7 +571,7 @@ func (p *Parser) parseValArray(b []byte) (reference, []byte, error) {
var err error
for len(b) > 0 {
- cref := invalidReference
+ var cref reference
cref, b, err = p.parseOptionalWhitespaceCommentNewline(b)
if err != nil {
return parent, nil, err
@@ -611,12 +640,13 @@ func (p *Parser) parseOptionalWhitespaceCommentNewline(b []byte) (reference, []b
latestCommentRef := invalidReference
addComment := func(ref reference) {
- if rootCommentRef == invalidReference {
+ switch {
+ case rootCommentRef == invalidReference:
rootCommentRef = ref
- } else if latestCommentRef == invalidReference {
+ case latestCommentRef == invalidReference:
p.builder.AttachChild(rootCommentRef, ref)
latestCommentRef = ref
- } else {
+ default:
p.builder.Chain(latestCommentRef, ref)
latestCommentRef = ref
}
@@ -704,11 +734,11 @@ func (p *Parser) parseMultilineBasicString(b []byte) ([]byte, []byte, []byte, er
if !escaped {
str := token[startIdx:endIdx]
- verr := characters.Utf8TomlValidAlreadyEscaped(str)
- if verr.Zero() {
+ highlight := characters.Utf8TomlValidAlreadyEscaped(str)
+ if len(highlight) == 0 {
return token, str, rest, nil
}
- return nil, nil, nil, NewParserError(str[verr.Index:verr.Index+verr.Size], "invalid UTF-8")
+ return nil, nil, nil, NewParserError(highlight, "invalid UTF-8")
}
var builder bytes.Buffer
@@ -744,7 +774,7 @@ func (p *Parser) parseMultilineBasicString(b []byte) ([]byte, []byte, []byte, er
i += j
for ; i < len(token)-3; i++ {
c := token[i]
- if !(c == '\n' || c == '\r' || c == ' ' || c == '\t') {
+ if c != '\n' && c != '\r' && c != ' ' && c != '\t' {
i--
break
}
@@ -820,7 +850,7 @@ func (p *Parser) parseKey(b []byte) (reference, []byte, error) {
ref := p.builder.Push(Node{
Kind: Key,
- Raw: p.Range(raw),
+ Raw: p.rangeOfToken(raw, b),
Data: key,
})
@@ -836,7 +866,7 @@ func (p *Parser) parseKey(b []byte) (reference, []byte, error) {
p.builder.PushAndChain(Node{
Kind: Key,
- Raw: p.Range(raw),
+ Raw: p.rangeOfToken(raw, b),
Data: key,
})
} else {
@@ -897,11 +927,11 @@ func (p *Parser) parseBasicString(b []byte) ([]byte, []byte, []byte, error) {
// validate the string and return a direct reference to the buffer.
if !escaped {
str := token[startIdx:endIdx]
- verr := characters.Utf8TomlValidAlreadyEscaped(str)
- if verr.Zero() {
+ highlight := characters.Utf8TomlValidAlreadyEscaped(str)
+ if len(highlight) == 0 {
return token, str, rest, nil
}
- return nil, nil, nil, NewParserError(str[verr.Index:verr.Index+verr.Size], "invalid UTF-8")
+ return nil, nil, nil, NewParserError(highlight, "invalid UTF-8")
}
i := startIdx
@@ -972,7 +1002,7 @@ func hexToRune(b []byte, length int) (rune, error) {
var r uint32
for i, c := range b {
- d := uint32(0)
+ var d uint32
switch {
case '0' <= c && c <= '9':
d = uint32(c - '0')
@@ -1013,7 +1043,7 @@ func (p *Parser) parseIntOrFloatOrDateTime(b []byte) (reference, []byte, error)
return p.builder.Push(Node{
Kind: Float,
Data: b[:3],
- Raw: p.Range(b[:3]),
+ Raw: p.rangeOfToken(b[:3], b[3:]),
}), b[3:], nil
case 'n':
if !scanFollowsNan(b) {
@@ -1023,7 +1053,7 @@ func (p *Parser) parseIntOrFloatOrDateTime(b []byte) (reference, []byte, error)
return p.builder.Push(Node{
Kind: Float,
Data: b[:3],
- Raw: p.Range(b[:3]),
+ Raw: p.rangeOfToken(b[:3], b[3:]),
}), b[3:], nil
case '+', '-':
return p.scanIntOrFloat(b)
@@ -1076,7 +1106,7 @@ byteLoop:
}
case c == 'T' || c == 't' || c == ':' || c == '.':
hasTime = true
- case c == '+' || c == '-' || c == 'Z' || c == 'z':
+ case c == '+' || c == 'Z' || c == 'z':
hasTz = true
case c == ' ':
if !seenSpace && i+1 < len(b) && isDigit(b[i+1]) {
@@ -1148,7 +1178,7 @@ func (p *Parser) scanIntOrFloat(b []byte) (reference, []byte, error) {
return p.builder.Push(Node{
Kind: Integer,
Data: b[:i],
- Raw: p.Range(b[:i]),
+ Raw: p.rangeOfToken(b[:i], b[i:]),
}), b[i:], nil
}
@@ -1172,7 +1202,7 @@ func (p *Parser) scanIntOrFloat(b []byte) (reference, []byte, error) {
return p.builder.Push(Node{
Kind: Float,
Data: b[:i+3],
- Raw: p.Range(b[:i+3]),
+ Raw: p.rangeOfToken(b[:i+3], b[i+3:]),
}), b[i+3:], nil
}
@@ -1184,7 +1214,7 @@ func (p *Parser) scanIntOrFloat(b []byte) (reference, []byte, error) {
return p.builder.Push(Node{
Kind: Float,
Data: b[:i+3],
- Raw: p.Range(b[:i+3]),
+ Raw: p.rangeOfToken(b[:i+3], b[i+3:]),
}), b[i+3:], nil
}
@@ -1207,7 +1237,7 @@ func (p *Parser) scanIntOrFloat(b []byte) (reference, []byte, error) {
return p.builder.Push(Node{
Kind: kind,
Data: b[:i],
- Raw: p.Range(b[:i]),
+ Raw: p.rangeOfToken(b[:i], b[i:]),
}), b[i:], nil
}
diff --git a/vendor/github.com/pelletier/go-toml/v2/unstable/unmarshaler.go b/vendor/github.com/pelletier/go-toml/v2/unstable/unmarshaler.go
index 00cfd6de4..5a79da88e 100644
--- a/vendor/github.com/pelletier/go-toml/v2/unstable/unmarshaler.go
+++ b/vendor/github.com/pelletier/go-toml/v2/unstable/unmarshaler.go
@@ -1,7 +1,32 @@
package unstable
-// The Unmarshaler interface may be implemented by types to customize their
-// behavior when being unmarshaled from a TOML document.
+// Unmarshaler is implemented by types that can unmarshal a TOML
+// description of themselves. The input is a valid TOML document
+// containing the relevant portion of the parsed document.
+//
+// For tables (including split tables defined in multiple places),
+// the data contains the raw key-value bytes from the original document
+// with adjusted table headers to be relative to the unmarshaling target.
type Unmarshaler interface {
- UnmarshalTOML(value *Node) error
+ UnmarshalTOML(data []byte) error
+}
+
+// RawMessage is a raw encoded TOML value. It implements Unmarshaler
+// and can be used to delay TOML decoding or capture raw content.
+//
+// Example usage:
+//
+// type Config struct {
+// Plugin RawMessage `toml:"plugin"`
+// }
+//
+// var cfg Config
+// toml.NewDecoder(r).EnableUnmarshalerInterface().Decode(&cfg)
+// // cfg.Plugin now contains the raw TOML bytes for [plugin]
+type RawMessage []byte
+
+// UnmarshalTOML implements Unmarshaler.
+func (m *RawMessage) UnmarshalTOML(data []byte) error {
+ *m = append((*m)[0:0], data...)
+ return nil
}
diff --git a/vendor/github.com/prometheus/procfs/.golangci.yml b/vendor/github.com/prometheus/procfs/.golangci.yml
index 23ecd4505..eac920ba8 100644
--- a/vendor/github.com/prometheus/procfs/.golangci.yml
+++ b/vendor/github.com/prometheus/procfs/.golangci.yml
@@ -34,6 +34,14 @@ linters:
capital: true
misspell:
locale: US
+ revive:
+ rules:
+ - name: var-naming
+ # TODO(SuperQ): See: https://github.com/prometheus/prometheus/issues/17766
+ arguments:
+ - []
+ - []
+ - - skip-package-name-checks: true
exclusions:
presets:
- comments
diff --git a/vendor/github.com/prometheus/procfs/Makefile.common b/vendor/github.com/prometheus/procfs/Makefile.common
index 6f61bec48..cce3ef1d1 100644
--- a/vendor/github.com/prometheus/procfs/Makefile.common
+++ b/vendor/github.com/prometheus/procfs/Makefile.common
@@ -1,4 +1,4 @@
-# Copyright 2018 The Prometheus Authors
+# Copyright The Prometheus Authors
# 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
@@ -55,13 +55,13 @@ ifneq ($(shell command -v gotestsum 2> /dev/null),)
endif
endif
-PROMU_VERSION ?= 0.17.0
+PROMU_VERSION ?= 0.18.0
PROMU_URL := https://github.com/prometheus/promu/releases/download/v$(PROMU_VERSION)/promu-$(PROMU_VERSION).$(GO_BUILD_PLATFORM).tar.gz
SKIP_GOLANGCI_LINT :=
GOLANGCI_LINT :=
GOLANGCI_LINT_OPTS ?=
-GOLANGCI_LINT_VERSION ?= v2.1.5
+GOLANGCI_LINT_VERSION ?= v2.10.1
GOLANGCI_FMT_OPTS ?=
# golangci-lint only supports linux, darwin and windows platforms on i386/amd64/arm64.
# windows isn't included here because of the path separator being different.
@@ -82,11 +82,50 @@ endif
PREFIX ?= $(shell pwd)
BIN_DIR ?= $(shell pwd)
DOCKER_IMAGE_TAG ?= $(subst /,-,$(shell git rev-parse --abbrev-ref HEAD))
-DOCKERFILE_PATH ?= ./Dockerfile
DOCKERBUILD_CONTEXT ?= ./
DOCKER_REPO ?= prom
+# Check if deprecated DOCKERFILE_PATH is set
+ifdef DOCKERFILE_PATH
+$(error DOCKERFILE_PATH is deprecated. Use DOCKERFILE_VARIANTS ?= $(DOCKERFILE_PATH) in the Makefile)
+endif
+
DOCKER_ARCHS ?= amd64
+DOCKERFILE_VARIANTS ?= Dockerfile $(wildcard Dockerfile.*)
+
+# Function to extract variant from Dockerfile label.
+# Returns the variant name from io.prometheus.image.variant label, or "default" if not found.
+define dockerfile_variant
+$(strip $(or $(shell sed -n 's/.*io\.prometheus\.image\.variant="\([^"]*\)".*/\1/p' $(1)),default))
+endef
+
+# Check for duplicate variant names (including default for Dockerfiles without labels).
+DOCKERFILE_VARIANT_NAMES := $(foreach df,$(DOCKERFILE_VARIANTS),$(call dockerfile_variant,$(df)))
+DOCKERFILE_VARIANT_NAMES_SORTED := $(sort $(DOCKERFILE_VARIANT_NAMES))
+ifneq ($(words $(DOCKERFILE_VARIANT_NAMES)),$(words $(DOCKERFILE_VARIANT_NAMES_SORTED)))
+$(error Duplicate variant names found. Each Dockerfile must have a unique io.prometheus.image.variant label, and only one can be without a label (default))
+endif
+
+# Build variant:dockerfile pairs for shell iteration.
+DOCKERFILE_VARIANTS_WITH_NAMES := $(foreach df,$(DOCKERFILE_VARIANTS),$(call dockerfile_variant,$(df)):$(df))
+
+# Shell helper to check whether a dockerfile/arch pair is excluded.
+define dockerfile_arch_is_excluded
+case " $(DOCKERFILE_ARCH_EXCLUSIONS) " in \
+ *" $$dockerfile:$(1) "*) true ;; \
+ *) false ;; \
+esac
+endef
+
+# Shell helper to check whether a registry/arch pair is excluded.
+# Extracts registry from DOCKER_REPO (e.g., quay.io/prometheus -> quay.io)
+define registry_arch_is_excluded
+registry=$$(echo "$(DOCKER_REPO)" | cut -d'/' -f1); \
+case " $(DOCKER_REGISTRY_ARCH_EXCLUSIONS) " in \
+ *" $$registry:$(1) "*) true ;; \
+ *) false ;; \
+esac
+endef
BUILD_DOCKER_ARCHS = $(addprefix common-docker-,$(DOCKER_ARCHS))
PUBLISH_DOCKER_ARCHS = $(addprefix common-docker-publish-,$(DOCKER_ARCHS))
@@ -112,7 +151,7 @@ common-all: precheck style check_license lint yamllint unused build test
.PHONY: common-style
common-style:
@echo ">> checking code style"
- @fmtRes=$$($(GOFMT) -d $$(find . -path ./vendor -prune -o -name '*.go' -print)); \
+ @fmtRes=$$($(GOFMT) -d $$(git ls-files '*.go' ':!:vendor/*' || find . -path ./vendor -prune -o -name '*.go' -print)); \
if [ -n "$${fmtRes}" ]; then \
echo "gofmt checking failed!"; echo "$${fmtRes}"; echo; \
echo "Please ensure you are using $$($(GO) version) for formatting code."; \
@@ -122,13 +161,19 @@ common-style:
.PHONY: common-check_license
common-check_license:
@echo ">> checking license header"
- @licRes=$$(for file in $$(find . -type f -iname '*.go' ! -path './vendor/*') ; do \
+ @licRes=$$(for file in $$(git ls-files '*.go' ':!:vendor/*' || find . -path ./vendor -prune -o -type f -iname '*.go' -print) ; do \
awk 'NR<=3' $$file | grep -Eq "(Copyright|generated|GENERATED)" || echo $$file; \
done); \
if [ -n "$${licRes}" ]; then \
echo "license header checking failed:"; echo "$${licRes}"; \
exit 1; \
fi
+ @echo ">> checking for copyright years 2026 or later"
+ @futureYearRes=$$(git grep -E 'Copyright (202[6-9]|20[3-9][0-9])' -- '*.go' ':!:vendor/*' || true); \
+ if [ -n "$${futureYearRes}" ]; then \
+ echo "Files with copyright year 2026 or later found (should use 'Copyright The Prometheus Authors'):"; echo "$${futureYearRes}"; \
+ exit 1; \
+ fi
.PHONY: common-deps
common-deps:
@@ -220,28 +265,194 @@ common-docker-repo-name:
.PHONY: common-docker $(BUILD_DOCKER_ARCHS)
common-docker: $(BUILD_DOCKER_ARCHS)
$(BUILD_DOCKER_ARCHS): common-docker-%:
- docker build -t "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:$(SANITIZED_DOCKER_IMAGE_TAG)" \
- -f $(DOCKERFILE_PATH) \
- --build-arg ARCH="$*" \
- --build-arg OS="linux" \
- $(DOCKERBUILD_CONTEXT)
+ @for variant in $(DOCKERFILE_VARIANTS_WITH_NAMES); do \
+ dockerfile=$${variant#*:}; \
+ variant_name=$${variant%%:*}; \
+ if $(call dockerfile_arch_is_excluded,$*); then \
+ echo "Skipping $$variant_name variant for linux-$* (excluded by DOCKERFILE_ARCH_EXCLUSIONS)"; \
+ continue; \
+ fi; \
+ distroless_arch="$*"; \
+ if [ "$*" = "armv7" ]; then \
+ distroless_arch="arm"; \
+ fi; \
+ if [ "$$dockerfile" = "Dockerfile" ]; then \
+ echo "Building default variant ($$variant_name) for linux-$* using $$dockerfile"; \
+ docker build -t "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:$(SANITIZED_DOCKER_IMAGE_TAG)" \
+ -f $$dockerfile \
+ --build-arg ARCH="$*" \
+ --build-arg OS="linux" \
+ --build-arg DISTROLESS_ARCH="$$distroless_arch" \
+ $(DOCKERBUILD_CONTEXT); \
+ if [ "$$variant_name" != "default" ]; then \
+ echo "Tagging default variant with $$variant_name suffix"; \
+ docker tag "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:$(SANITIZED_DOCKER_IMAGE_TAG)" \
+ "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:$(SANITIZED_DOCKER_IMAGE_TAG)-$$variant_name"; \
+ fi; \
+ else \
+ echo "Building $$variant_name variant for linux-$* using $$dockerfile"; \
+ docker build -t "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:$(SANITIZED_DOCKER_IMAGE_TAG)-$$variant_name" \
+ -f $$dockerfile \
+ --build-arg ARCH="$*" \
+ --build-arg OS="linux" \
+ --build-arg DISTROLESS_ARCH="$$distroless_arch" \
+ $(DOCKERBUILD_CONTEXT); \
+ fi; \
+ done
.PHONY: common-docker-publish $(PUBLISH_DOCKER_ARCHS)
common-docker-publish: $(PUBLISH_DOCKER_ARCHS)
$(PUBLISH_DOCKER_ARCHS): common-docker-publish-%:
- docker push "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:$(SANITIZED_DOCKER_IMAGE_TAG)"
+ @for variant in $(DOCKERFILE_VARIANTS_WITH_NAMES); do \
+ dockerfile=$${variant#*:}; \
+ variant_name=$${variant%%:*}; \
+ if $(call dockerfile_arch_is_excluded,$*); then \
+ echo "Skipping push for $$variant_name variant on linux-$* (excluded by DOCKERFILE_ARCH_EXCLUSIONS)"; \
+ continue; \
+ fi; \
+ if $(call registry_arch_is_excluded,$*); then \
+ echo "Skipping push for $$variant_name variant on linux-$* to $(DOCKER_REPO) (excluded by DOCKER_REGISTRY_ARCH_EXCLUSIONS)"; \
+ continue; \
+ fi; \
+ if [ "$$dockerfile" != "Dockerfile" ] || [ "$$variant_name" != "default" ]; then \
+ echo "Pushing $$variant_name variant for linux-$*"; \
+ docker push "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:$(SANITIZED_DOCKER_IMAGE_TAG)-$$variant_name"; \
+ fi; \
+ if [ "$$dockerfile" = "Dockerfile" ]; then \
+ echo "Pushing default variant ($$variant_name) for linux-$*"; \
+ docker push "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:$(SANITIZED_DOCKER_IMAGE_TAG)"; \
+ fi; \
+ if [ "$(DOCKER_IMAGE_TAG)" = "latest" ]; then \
+ if [ "$$dockerfile" != "Dockerfile" ] || [ "$$variant_name" != "default" ]; then \
+ echo "Pushing $$variant_name variant version tags for linux-$*"; \
+ docker push "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:v$(DOCKER_MAJOR_VERSION_TAG)-$$variant_name"; \
+ fi; \
+ if [ "$$dockerfile" = "Dockerfile" ]; then \
+ echo "Pushing default variant version tag for linux-$*"; \
+ docker push "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:v$(DOCKER_MAJOR_VERSION_TAG)"; \
+ fi; \
+ fi; \
+ done
DOCKER_MAJOR_VERSION_TAG = $(firstword $(subst ., ,$(shell cat VERSION)))
.PHONY: common-docker-tag-latest $(TAG_DOCKER_ARCHS)
common-docker-tag-latest: $(TAG_DOCKER_ARCHS)
$(TAG_DOCKER_ARCHS): common-docker-tag-latest-%:
- docker tag "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:$(SANITIZED_DOCKER_IMAGE_TAG)" "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:latest"
- docker tag "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:$(SANITIZED_DOCKER_IMAGE_TAG)" "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:v$(DOCKER_MAJOR_VERSION_TAG)"
+ @for variant in $(DOCKERFILE_VARIANTS_WITH_NAMES); do \
+ dockerfile=$${variant#*:}; \
+ variant_name=$${variant%%:*}; \
+ if $(call dockerfile_arch_is_excluded,$*); then \
+ echo "Skipping tag for $$variant_name variant on linux-$* (excluded by DOCKERFILE_ARCH_EXCLUSIONS)"; \
+ continue; \
+ fi; \
+ if $(call registry_arch_is_excluded,$*); then \
+ echo "Skipping tag for $$variant_name variant on linux-$* for $(DOCKER_REPO) (excluded by DOCKER_REGISTRY_ARCH_EXCLUSIONS)"; \
+ continue; \
+ fi; \
+ if [ "$$dockerfile" != "Dockerfile" ] || [ "$$variant_name" != "default" ]; then \
+ echo "Tagging $$variant_name variant for linux-$* as latest"; \
+ docker tag "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:$(SANITIZED_DOCKER_IMAGE_TAG)-$$variant_name" "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:latest-$$variant_name"; \
+ docker tag "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:$(SANITIZED_DOCKER_IMAGE_TAG)-$$variant_name" "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:v$(DOCKER_MAJOR_VERSION_TAG)-$$variant_name"; \
+ fi; \
+ if [ "$$dockerfile" = "Dockerfile" ]; then \
+ echo "Tagging default variant ($$variant_name) for linux-$* as latest"; \
+ docker tag "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:$(SANITIZED_DOCKER_IMAGE_TAG)" "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:latest"; \
+ docker tag "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:$(SANITIZED_DOCKER_IMAGE_TAG)" "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:v$(DOCKER_MAJOR_VERSION_TAG)"; \
+ fi; \
+ done
.PHONY: common-docker-manifest
common-docker-manifest:
- DOCKER_CLI_EXPERIMENTAL=enabled docker manifest create -a "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME):$(SANITIZED_DOCKER_IMAGE_TAG)" $(foreach ARCH,$(DOCKER_ARCHS),$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$(ARCH):$(SANITIZED_DOCKER_IMAGE_TAG))
- DOCKER_CLI_EXPERIMENTAL=enabled docker manifest push "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME):$(SANITIZED_DOCKER_IMAGE_TAG)"
+ @for variant in $(DOCKERFILE_VARIANTS_WITH_NAMES); do \
+ dockerfile=$${variant#*:}; \
+ variant_name=$${variant%%:*}; \
+ if [ "$$dockerfile" != "Dockerfile" ] || [ "$$variant_name" != "default" ]; then \
+ echo "Creating manifest for $$variant_name variant"; \
+ refs=""; \
+ for arch in $(DOCKER_ARCHS); do \
+ if $(call dockerfile_arch_is_excluded,$$arch); then \
+ echo " Skipping $$arch for $$variant_name (excluded by DOCKERFILE_ARCH_EXCLUSIONS)"; \
+ continue; \
+ fi; \
+ if $(call registry_arch_is_excluded,$$arch); then \
+ echo " Skipping $$arch for $$variant_name on $(DOCKER_REPO) (excluded by DOCKER_REGISTRY_ARCH_EXCLUSIONS)"; \
+ continue; \
+ fi; \
+ refs="$$refs $(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$$arch:$(SANITIZED_DOCKER_IMAGE_TAG)-$$variant_name"; \
+ done; \
+ if [ -z "$$refs" ]; then \
+ echo "Skipping manifest for $$variant_name variant (no supported architectures)"; \
+ continue; \
+ fi; \
+ DOCKER_CLI_EXPERIMENTAL=enabled docker manifest create -a "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME):$(SANITIZED_DOCKER_IMAGE_TAG)-$$variant_name" $$refs; \
+ DOCKER_CLI_EXPERIMENTAL=enabled docker manifest push "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME):$(SANITIZED_DOCKER_IMAGE_TAG)-$$variant_name"; \
+ fi; \
+ if [ "$$dockerfile" = "Dockerfile" ]; then \
+ echo "Creating default variant ($$variant_name) manifest"; \
+ refs=""; \
+ for arch in $(DOCKER_ARCHS); do \
+ if $(call dockerfile_arch_is_excluded,$$arch); then \
+ echo " Skipping $$arch for default variant (excluded by DOCKERFILE_ARCH_EXCLUSIONS)"; \
+ continue; \
+ fi; \
+ if $(call registry_arch_is_excluded,$$arch); then \
+ echo " Skipping $$arch for default variant on $(DOCKER_REPO) (excluded by DOCKER_REGISTRY_ARCH_EXCLUSIONS)"; \
+ continue; \
+ fi; \
+ refs="$$refs $(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$$arch:$(SANITIZED_DOCKER_IMAGE_TAG)"; \
+ done; \
+ if [ -z "$$refs" ]; then \
+ echo "Skipping default variant manifest (no supported architectures)"; \
+ continue; \
+ fi; \
+ DOCKER_CLI_EXPERIMENTAL=enabled docker manifest create -a "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME):$(SANITIZED_DOCKER_IMAGE_TAG)" $$refs; \
+ DOCKER_CLI_EXPERIMENTAL=enabled docker manifest push "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME):$(SANITIZED_DOCKER_IMAGE_TAG)"; \
+ fi; \
+ if [ "$(DOCKER_IMAGE_TAG)" = "latest" ]; then \
+ if [ "$$dockerfile" != "Dockerfile" ] || [ "$$variant_name" != "default" ]; then \
+ echo "Creating manifest for $$variant_name variant version tag"; \
+ refs=""; \
+ for arch in $(DOCKER_ARCHS); do \
+ if $(call dockerfile_arch_is_excluded,$$arch); then \
+ echo " Skipping $$arch for $$variant_name version tag (excluded by DOCKERFILE_ARCH_EXCLUSIONS)"; \
+ continue; \
+ fi; \
+ if $(call registry_arch_is_excluded,$$arch); then \
+ echo " Skipping $$arch for $$variant_name version tag on $(DOCKER_REPO) (excluded by DOCKER_REGISTRY_ARCH_EXCLUSIONS)"; \
+ continue; \
+ fi; \
+ refs="$$refs $(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$$arch:v$(DOCKER_MAJOR_VERSION_TAG)-$$variant_name"; \
+ done; \
+ if [ -z "$$refs" ]; then \
+ echo "Skipping version-tag manifest for $$variant_name variant (no supported architectures)"; \
+ continue; \
+ fi; \
+ DOCKER_CLI_EXPERIMENTAL=enabled docker manifest create -a "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME):v$(DOCKER_MAJOR_VERSION_TAG)-$$variant_name" $$refs; \
+ DOCKER_CLI_EXPERIMENTAL=enabled docker manifest push "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME):v$(DOCKER_MAJOR_VERSION_TAG)-$$variant_name"; \
+ fi; \
+ if [ "$$dockerfile" = "Dockerfile" ]; then \
+ echo "Creating default variant version tag manifest"; \
+ refs=""; \
+ for arch in $(DOCKER_ARCHS); do \
+ if $(call dockerfile_arch_is_excluded,$$arch); then \
+ echo " Skipping $$arch for default variant version tag (excluded by DOCKERFILE_ARCH_EXCLUSIONS)"; \
+ continue; \
+ fi; \
+ if $(call registry_arch_is_excluded,$$arch); then \
+ echo " Skipping $$arch for default variant version tag on $(DOCKER_REPO) (excluded by DOCKER_REGISTRY_ARCH_EXCLUSIONS)"; \
+ continue; \
+ fi; \
+ refs="$$refs $(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$$arch:v$(DOCKER_MAJOR_VERSION_TAG)"; \
+ done; \
+ if [ -z "$$refs" ]; then \
+ echo "Skipping default variant version-tag manifest (no supported architectures)"; \
+ continue; \
+ fi; \
+ DOCKER_CLI_EXPERIMENTAL=enabled docker manifest create -a "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME):v$(DOCKER_MAJOR_VERSION_TAG)" $$refs; \
+ DOCKER_CLI_EXPERIMENTAL=enabled docker manifest push "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME):v$(DOCKER_MAJOR_VERSION_TAG)"; \
+ fi; \
+ fi; \
+ done
.PHONY: promu
promu: $(PROMU)
@@ -266,6 +477,10 @@ $(GOLANGCI_LINT):
| sh -s -- -b $(FIRST_GOPATH)/bin $(GOLANGCI_LINT_VERSION)
endif
+.PHONY: common-print-golangci-lint-version
+common-print-golangci-lint-version:
+ @echo $(GOLANGCI_LINT_VERSION)
+
.PHONY: precheck
precheck::
diff --git a/vendor/github.com/prometheus/procfs/cpuinfo.go b/vendor/github.com/prometheus/procfs/cpuinfo.go
index 5fe6cecd3..4b23d8d6b 100644
--- a/vendor/github.com/prometheus/procfs/cpuinfo.go
+++ b/vendor/github.com/prometheus/procfs/cpuinfo.go
@@ -12,7 +12,6 @@
// limitations under the License.
//go:build linux
-// +build linux
package procfs
@@ -502,7 +501,7 @@ func parseCPUInfoRISCV(info []byte) ([]CPUInfo, error) {
return cpuinfo, nil
}
-func parseCPUInfoDummy(_ []byte) ([]CPUInfo, error) { // nolint:unused,deadcode
+func parseCPUInfoDummy(_ []byte) ([]CPUInfo, error) { //nolint:unused
return nil, errors.New("not implemented")
}
diff --git a/vendor/github.com/prometheus/procfs/cpuinfo_armx.go b/vendor/github.com/prometheus/procfs/cpuinfo_armx.go
index 8f155551e..b09035ff3 100644
--- a/vendor/github.com/prometheus/procfs/cpuinfo_armx.go
+++ b/vendor/github.com/prometheus/procfs/cpuinfo_armx.go
@@ -12,8 +12,6 @@
// limitations under the License.
//go:build linux && (arm || arm64)
-// +build linux
-// +build arm arm64
package procfs
diff --git a/vendor/github.com/prometheus/procfs/cpuinfo_loong64.go b/vendor/github.com/prometheus/procfs/cpuinfo_loong64.go
index e81a5db94..7bb20211f 100644
--- a/vendor/github.com/prometheus/procfs/cpuinfo_loong64.go
+++ b/vendor/github.com/prometheus/procfs/cpuinfo_loong64.go
@@ -12,7 +12,6 @@
// limitations under the License.
//go:build linux
-// +build linux
package procfs
diff --git a/vendor/github.com/prometheus/procfs/cpuinfo_mipsx.go b/vendor/github.com/prometheus/procfs/cpuinfo_mipsx.go
index 4be2b1cc5..fd75d0f79 100644
--- a/vendor/github.com/prometheus/procfs/cpuinfo_mipsx.go
+++ b/vendor/github.com/prometheus/procfs/cpuinfo_mipsx.go
@@ -12,8 +12,6 @@
// limitations under the License.
//go:build linux && (mips || mipsle || mips64 || mips64le)
-// +build linux
-// +build mips mipsle mips64 mips64le
package procfs
diff --git a/vendor/github.com/prometheus/procfs/cpuinfo_others.go b/vendor/github.com/prometheus/procfs/cpuinfo_others.go
index e713bae8d..3d36ba0e6 100644
--- a/vendor/github.com/prometheus/procfs/cpuinfo_others.go
+++ b/vendor/github.com/prometheus/procfs/cpuinfo_others.go
@@ -12,7 +12,6 @@
// limitations under the License.
//go:build linux && !386 && !amd64 && !arm && !arm64 && !loong64 && !mips && !mips64 && !mips64le && !mipsle && !ppc64 && !ppc64le && !riscv64 && !s390x
-// +build linux,!386,!amd64,!arm,!arm64,!loong64,!mips,!mips64,!mips64le,!mipsle,!ppc64,!ppc64le,!riscv64,!s390x
package procfs
diff --git a/vendor/github.com/prometheus/procfs/cpuinfo_ppcx.go b/vendor/github.com/prometheus/procfs/cpuinfo_ppcx.go
index 0825aa1a8..b3425051e 100644
--- a/vendor/github.com/prometheus/procfs/cpuinfo_ppcx.go
+++ b/vendor/github.com/prometheus/procfs/cpuinfo_ppcx.go
@@ -12,8 +12,6 @@
// limitations under the License.
//go:build linux && (ppc64 || ppc64le)
-// +build linux
-// +build ppc64 ppc64le
package procfs
diff --git a/vendor/github.com/prometheus/procfs/cpuinfo_riscvx.go b/vendor/github.com/prometheus/procfs/cpuinfo_riscvx.go
index 496770b05..72598230c 100644
--- a/vendor/github.com/prometheus/procfs/cpuinfo_riscvx.go
+++ b/vendor/github.com/prometheus/procfs/cpuinfo_riscvx.go
@@ -12,8 +12,6 @@
// limitations under the License.
//go:build linux && (riscv || riscv64)
-// +build linux
-// +build riscv riscv64
package procfs
diff --git a/vendor/github.com/prometheus/procfs/cpuinfo_s390x.go b/vendor/github.com/prometheus/procfs/cpuinfo_s390x.go
index b3228ce3d..50a8239cb 100644
--- a/vendor/github.com/prometheus/procfs/cpuinfo_s390x.go
+++ b/vendor/github.com/prometheus/procfs/cpuinfo_s390x.go
@@ -12,7 +12,6 @@
// limitations under the License.
//go:build linux
-// +build linux
package procfs
diff --git a/vendor/github.com/prometheus/procfs/cpuinfo_x86.go b/vendor/github.com/prometheus/procfs/cpuinfo_x86.go
index 575eb022e..00edb30a5 100644
--- a/vendor/github.com/prometheus/procfs/cpuinfo_x86.go
+++ b/vendor/github.com/prometheus/procfs/cpuinfo_x86.go
@@ -12,8 +12,6 @@
// limitations under the License.
//go:build linux && (386 || amd64)
-// +build linux
-// +build 386 amd64
package procfs
diff --git a/vendor/github.com/prometheus/procfs/fs_statfs_notype.go b/vendor/github.com/prometheus/procfs/fs_statfs_notype.go
index 3c53023c5..0bef25bdd 100644
--- a/vendor/github.com/prometheus/procfs/fs_statfs_notype.go
+++ b/vendor/github.com/prometheus/procfs/fs_statfs_notype.go
@@ -12,7 +12,6 @@
// limitations under the License.
//go:build !freebsd && !linux
-// +build !freebsd,!linux
package procfs
diff --git a/vendor/github.com/prometheus/procfs/fs_statfs_type.go b/vendor/github.com/prometheus/procfs/fs_statfs_type.go
index 80fce4847..d18333039 100644
--- a/vendor/github.com/prometheus/procfs/fs_statfs_type.go
+++ b/vendor/github.com/prometheus/procfs/fs_statfs_type.go
@@ -12,7 +12,6 @@
// limitations under the License.
//go:build freebsd || linux
-// +build freebsd linux
package procfs
diff --git a/vendor/github.com/prometheus/procfs/internal/util/sysreadfile.go b/vendor/github.com/prometheus/procfs/internal/util/sysreadfile.go
index 8318d8dfd..f6a4a4de6 100644
--- a/vendor/github.com/prometheus/procfs/internal/util/sysreadfile.go
+++ b/vendor/github.com/prometheus/procfs/internal/util/sysreadfile.go
@@ -12,8 +12,6 @@
// limitations under the License.
//go:build (linux || darwin) && !appengine
-// +build linux darwin
-// +build !appengine
package util
diff --git a/vendor/github.com/prometheus/procfs/internal/util/sysreadfile_compat.go b/vendor/github.com/prometheus/procfs/internal/util/sysreadfile_compat.go
index 15bb096ee..c80e082cb 100644
--- a/vendor/github.com/prometheus/procfs/internal/util/sysreadfile_compat.go
+++ b/vendor/github.com/prometheus/procfs/internal/util/sysreadfile_compat.go
@@ -12,7 +12,6 @@
// limitations under the License.
//go:build (linux && appengine) || (!linux && !darwin)
-// +build linux,appengine !linux,!darwin
package util
diff --git a/vendor/github.com/prometheus/procfs/kernel_hung.go b/vendor/github.com/prometheus/procfs/kernel_hung.go
index 539c11151..0c7a69f99 100644
--- a/vendor/github.com/prometheus/procfs/kernel_hung.go
+++ b/vendor/github.com/prometheus/procfs/kernel_hung.go
@@ -12,7 +12,6 @@
// limitations under the License.
//go:build !windows
-// +build !windows
package procfs
diff --git a/vendor/github.com/prometheus/procfs/kernel_random.go b/vendor/github.com/prometheus/procfs/kernel_random.go
index b66565a10..e7c5b8cf2 100644
--- a/vendor/github.com/prometheus/procfs/kernel_random.go
+++ b/vendor/github.com/prometheus/procfs/kernel_random.go
@@ -12,7 +12,6 @@
// limitations under the License.
//go:build !windows
-// +build !windows
package procfs
diff --git a/vendor/github.com/prometheus/procfs/net_tcp.go b/vendor/github.com/prometheus/procfs/net_tcp.go
index 610ea78e5..2c7f9bc7c 100644
--- a/vendor/github.com/prometheus/procfs/net_tcp.go
+++ b/vendor/github.com/prometheus/procfs/net_tcp.go
@@ -25,6 +25,7 @@ type (
// NetTCP returns the IPv4 kernel/networking statistics for TCP datagrams
// read from /proc/net/tcp.
+//
// Deprecated: Use github.com/mdlayher/netlink#Conn (with syscall.AF_INET) instead.
func (fs FS) NetTCP() (NetTCP, error) {
return newNetTCP(fs.proc.Path("net/tcp"))
@@ -32,6 +33,7 @@ func (fs FS) NetTCP() (NetTCP, error) {
// NetTCP6 returns the IPv6 kernel/networking statistics for TCP datagrams
// read from /proc/net/tcp6.
+//
// Deprecated: Use github.com/mdlayher/netlink#Conn (with syscall.AF_INET6) instead.
func (fs FS) NetTCP6() (NetTCP, error) {
return newNetTCP(fs.proc.Path("net/tcp6"))
@@ -39,6 +41,7 @@ func (fs FS) NetTCP6() (NetTCP, error) {
// NetTCPSummary returns already computed statistics like the total queue lengths
// for TCP datagrams read from /proc/net/tcp.
+//
// Deprecated: Use github.com/mdlayher/netlink#Conn (with syscall.AF_INET) instead.
func (fs FS) NetTCPSummary() (*NetTCPSummary, error) {
return newNetTCPSummary(fs.proc.Path("net/tcp"))
@@ -46,6 +49,7 @@ func (fs FS) NetTCPSummary() (*NetTCPSummary, error) {
// NetTCP6Summary returns already computed statistics like the total queue lengths
// for TCP datagrams read from /proc/net/tcp6.
+//
// Deprecated: Use github.com/mdlayher/netlink#Conn (with syscall.AF_INET6) instead.
func (fs FS) NetTCP6Summary() (*NetTCPSummary, error) {
return newNetTCPSummary(fs.proc.Path("net/tcp6"))
diff --git a/vendor/github.com/prometheus/procfs/proc_interrupts.go b/vendor/github.com/prometheus/procfs/proc_interrupts.go
index b942c5072..643b500d5 100644
--- a/vendor/github.com/prometheus/procfs/proc_interrupts.go
+++ b/vendor/github.com/prometheus/procfs/proc_interrupts.go
@@ -42,7 +42,7 @@ type Interrupts map[string]Interrupt
// Interrupts creates a new instance from a given Proc instance.
func (p Proc) Interrupts() (Interrupts, error) {
- data, err := util.ReadFileNoStat(p.path("interrupts"))
+ data, err := util.ReadFileNoStat(p.fs.proc.Path("interrupts"))
if err != nil {
return nil, err
}
diff --git a/vendor/github.com/prometheus/procfs/proc_maps.go b/vendor/github.com/prometheus/procfs/proc_maps.go
index cc519f92f..08b89a6eb 100644
--- a/vendor/github.com/prometheus/procfs/proc_maps.go
+++ b/vendor/github.com/prometheus/procfs/proc_maps.go
@@ -12,8 +12,6 @@
// limitations under the License.
//go:build (aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris) && !js
-// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
-// +build !js
package procfs
diff --git a/vendor/github.com/prometheus/procfs/proc_smaps.go b/vendor/github.com/prometheus/procfs/proc_smaps.go
index 3e48afd1d..f637309b3 100644
--- a/vendor/github.com/prometheus/procfs/proc_smaps.go
+++ b/vendor/github.com/prometheus/procfs/proc_smaps.go
@@ -12,7 +12,6 @@
// limitations under the License.
//go:build !windows
-// +build !windows
package procfs
diff --git a/vendor/github.com/prometheus/procfs/proc_statm.go b/vendor/github.com/prometheus/procfs/proc_statm.go
index b0a936016..6bcc97ec9 100644
--- a/vendor/github.com/prometheus/procfs/proc_statm.go
+++ b/vendor/github.com/prometheus/procfs/proc_statm.go
@@ -45,6 +45,7 @@ type ProcStatm struct {
}
// NewStatm returns the current status information of the process.
+//
// Deprecated: Use p.Statm() instead.
func (p Proc) NewStatm() (ProcStatm, error) {
return p.Statm()
diff --git a/vendor/github.com/prometheus/procfs/proc_status.go b/vendor/github.com/prometheus/procfs/proc_status.go
index 1ed2bced4..12d65581c 100644
--- a/vendor/github.com/prometheus/procfs/proc_status.go
+++ b/vendor/github.com/prometheus/procfs/proc_status.go
@@ -83,6 +83,19 @@ type ProcStatus struct {
// CpusAllowedList: List of cpu cores processes are allowed to run on.
CpusAllowedList []uint64
+
+ // CapInh is the bitmap of inheritable capabilities
+ //
+ // See: https://www.kernel.org/doc/man-pages/online/pages/man7/capabilities.7.html
+ CapInh uint64
+ // CapPrm is the bitmap of permitted capabilities
+ CapPrm uint64
+ // CapEff is the bitmap of effective capabilities
+ CapEff uint64
+ // CapBnd is the bitmap of bounding capabilities
+ CapBnd uint64
+ // CapAmb is the bitmap of ambient capabilities
+ CapAmb uint64
}
// NewStatus returns the current status information of the process.
@@ -190,6 +203,36 @@ func (s *ProcStatus) fillStatus(k string, vString string, vUint uint64, vUintByt
s.NonVoluntaryCtxtSwitches = vUint
case "Cpus_allowed_list":
s.CpusAllowedList = calcCpusAllowedList(vString)
+ case "CapInh":
+ var err error
+ s.CapInh, err = strconv.ParseUint(vString, 16, 64)
+ if err != nil {
+ return err
+ }
+ case "CapPrm":
+ var err error
+ s.CapPrm, err = strconv.ParseUint(vString, 16, 64)
+ if err != nil {
+ return err
+ }
+ case "CapEff":
+ var err error
+ s.CapEff, err = strconv.ParseUint(vString, 16, 64)
+ if err != nil {
+ return err
+ }
+ case "CapBnd":
+ var err error
+ s.CapBnd, err = strconv.ParseUint(vString, 16, 64)
+ if err != nil {
+ return err
+ }
+ case "CapAmb":
+ var err error
+ s.CapAmb, err = strconv.ParseUint(vString, 16, 64)
+ if err != nil {
+ return err
+ }
}
return nil
diff --git a/vendor/github.com/prometheus/procfs/vm.go b/vendor/github.com/prometheus/procfs/vm.go
index 2a8d76390..52180c03e 100644
--- a/vendor/github.com/prometheus/procfs/vm.go
+++ b/vendor/github.com/prometheus/procfs/vm.go
@@ -12,7 +12,6 @@
// limitations under the License.
//go:build !windows
-// +build !windows
package procfs
diff --git a/vendor/github.com/prometheus/procfs/zoneinfo.go b/vendor/github.com/prometheus/procfs/zoneinfo.go
index 806e17114..63d1898bc 100644
--- a/vendor/github.com/prometheus/procfs/zoneinfo.go
+++ b/vendor/github.com/prometheus/procfs/zoneinfo.go
@@ -12,7 +12,6 @@
// limitations under the License.
//go:build !windows
-// +build !windows
package procfs
diff --git a/vendor/github.com/ryancurrah/gomodguard/v2/.dockerignore b/vendor/github.com/ryancurrah/gomodguard/v2/.dockerignore
new file mode 100644
index 000000000..77738287f
--- /dev/null
+++ b/vendor/github.com/ryancurrah/gomodguard/v2/.dockerignore
@@ -0,0 +1 @@
+dist/
\ No newline at end of file
diff --git a/vendor/github.com/ryancurrah/gomodguard/v2/.gitignore b/vendor/github.com/ryancurrah/gomodguard/v2/.gitignore
new file mode 100644
index 000000000..4ebc79c5d
--- /dev/null
+++ b/vendor/github.com/ryancurrah/gomodguard/v2/.gitignore
@@ -0,0 +1,25 @@
+# Binaries for programs and plugins
+*.exe
+*.exe~
+*.dll
+*.so
+*.dylib
+
+# Test binary, built with `go test -c`
+*.test
+
+# Output of the go coverage tool, specifically when used with LiteIDE
+*.out
+
+# Dependency directories (remove the comment below to include it)
+# vendor/
+
+/gomodguard
+
+*.xml
+
+dist/
+
+coverage.*
+
+.idea/
diff --git a/vendor/github.com/ryancurrah/gomodguard/v2/.golangci.yml b/vendor/github.com/ryancurrah/gomodguard/v2/.golangci.yml
new file mode 100644
index 000000000..2e3266adb
--- /dev/null
+++ b/vendor/github.com/ryancurrah/gomodguard/v2/.golangci.yml
@@ -0,0 +1,35 @@
+version: "2"
+
+linters:
+ default: all
+ disable:
+ - lll
+ - gomodguard
+ - gomoddirectives
+ - gochecknoglobals
+ - paralleltest
+ - varnamelen
+ - exhaustruct
+ - depguard
+ - forbidigo
+ - funlen
+ - nlreturn
+ - nonamedreturns
+ - cyclop
+ - err113
+ - perfsprint
+ - tagliatelle
+ - wrapcheck
+ - mnd
+ - wsl
+ - noinlineerr
+ settings:
+ revive:
+ rules:
+ - name: package-comments
+ disabled: true
+ exclusions:
+ rules:
+ - path: _test\.go$
+ linters:
+ - goconst
diff --git a/vendor/github.com/ryancurrah/gomodguard/v2/LICENSE b/vendor/github.com/ryancurrah/gomodguard/v2/LICENSE
new file mode 100644
index 000000000..acd8a81e1
--- /dev/null
+++ b/vendor/github.com/ryancurrah/gomodguard/v2/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2020 Ryan Currah
+
+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.
diff --git a/vendor/github.com/ryancurrah/gomodguard/v2/Makefile b/vendor/github.com/ryancurrah/gomodguard/v2/Makefile
new file mode 100644
index 000000000..d30a2255b
--- /dev/null
+++ b/vendor/github.com/ryancurrah/gomodguard/v2/Makefile
@@ -0,0 +1,87 @@
+current_dir = $(shell pwd)
+
+.PHONY: goimports
+goimports:
+ find . -name '*.go' -exec goimports -w -local github.com/ryancurrah/gomodguard {} +
+
+.PHONY: lint
+lint:
+ golangci-lint run ./...
+ cd cmd/gomodguard && golangci-lint run ./...
+
+.PHONY: tidy
+tidy:
+ go mod tidy
+ cd cmd/gomodguard && go mod tidy
+
+.PHONY: build
+build:
+ cd cmd/gomodguard && go build -o "$$(go env GOPATH)/bin/gomodguard" main.go
+
+.PHONY: run
+run: build
+ ./gomodguard
+
+.PHONY: test
+test:
+ go test -v -coverprofile coverage.out
+ cd cmd/gomodguard && go test -v -coverprofile coverage.out ./...
+ cat cmd/gomodguard/coverage.out | tail -n +2 >> coverage.out
+
+.PHONY: cover
+cover:
+ gocover-cobertura < coverage.out > coverage.xml
+
+.PHONY: dockerrun
+dockerrun: dockerbuild
+ docker run -v "${current_dir}/.gomodguard.yaml:/.gomodguard.yaml" ryancurrah/gomodguard:latest
+
+.PHONY: snapshot
+snapshot:
+ cd cmd/gomodguard && goreleaser --clean --snapshot
+
+.PHONY: release
+release:
+ cd cmd/gomodguard && goreleaser --clean
+
+.PHONY: clean
+clean:
+ rm -rf dist/
+ rm -f gomodguard coverage.xml coverage.out
+ rm -f cmd/gomodguard/coverage.out
+
+.PHONY: tag
+tag:
+ @if [ -n "$$(git status --porcelain)" ]; then \
+ echo "error: working tree not clean"; exit 1; \
+ fi; \
+ current=$$(git tag --sort=-v:refname --list 'v*' | head -n1 || echo "none"); \
+ read -p "Current version: $$current. Enter new version: " version; \
+ if [ -z "$$version" ]; then echo "error: version required"; exit 1; fi; \
+ bump_branch="bump-library-to-$$version"; \
+ git tag "$$version" && \
+ git push origin "$$version" && \
+ git checkout -b "$$bump_branch" && \
+ (cd cmd/gomodguard && GOWORK=off go get "github.com/ryancurrah/gomodguard/v2@$$version" && GOWORK=off go mod tidy) && \
+ git add cmd/gomodguard/go.mod cmd/gomodguard/go.sum && \
+ git commit -m "chore: bump library to $$version" && \
+ git tag "cmd/gomodguard/$$version" && \
+ git push -u origin "$$bump_branch" "cmd/gomodguard/$$version" && \
+ gh pr create --title "chore: bump library to $$version" --body "Required by cmd/gomodguard/$$version release." && \
+ echo "waiting for PR to merge..." && \
+ while :; do \
+ state=$$(gh pr view --json state -q .state); \
+ if [ "$$state" = "MERGED" ]; then break; fi; \
+ if [ "$$state" = "CLOSED" ]; then echo "error: PR closed without merge"; exit 1; fi; \
+ sleep 30; \
+ done && \
+ git checkout main && git pull --ff-only origin main && \
+ git branch -D "$$bump_branch"
+
+.PHONY: install-mac-tools
+install-tools-mac:
+ brew install goreleaser/tap/goreleaser
+
+.PHONY: install-go-tools
+install-go-tools:
+ go install -v github.com/t-yuki/gocover-cobertura@latest
diff --git a/vendor/github.com/ryancurrah/gomodguard/v2/README.md b/vendor/github.com/ryancurrah/gomodguard/v2/README.md
new file mode 100644
index 000000000..a0bea99f0
--- /dev/null
+++ b/vendor/github.com/ryancurrah/gomodguard/v2/README.md
@@ -0,0 +1,219 @@
+# gomodguard
+[](/LICENSE)
+[](https://codecov.io/gh/ryancurrah/gomodguard)
+[](https://github.com/ryancurrah/gomodguard/actions?query=workflow%3AGo)
+[](https://github.com/ryancurrah/gomodguard/releases/latest)
+[](https://hub.docker.com/r/ryancurrah/gomodguard)
+[](https://somsubhra.com/github-release-stats/?username=ryancurrah&repository=gomodguard)
+
+
+
+Allow and block list linter for direct Go module dependencies. This is useful for organizations where they want to standardize on the modules used and be able to recommend alternative modules.
+
+## Description
+
+Allowed and blocked modules are defined in a `./.gomodguard.yaml` or `~/.gomodguard.yaml` file.
+
+Modules can be allowed by module or prefix name. When allowed modules are specified any modules not in the allowed configuration are blocked.
+
+If no allowed modules or module prefixes are specified then all modules are allowed except for blocked ones.
+
+The linter looks for blocked modules in `go.mod` and searches for imported packages where the imported packages module is blocked. Indirect modules are not considered.
+
+Alternative modules can be optionally recommended in the blocked modules list.
+
+If the linted module imports a blocked module but the linted module is in the recommended modules list the blocked module is ignored. Usually, this means the linted module wraps that blocked module for use by other modules, therefore the import of the blocked module should not be blocked.
+
+Version constraints can be specified for modules as well which lets you block new or old versions of modules or specific versions.
+
+Results are printed to `stdout`.
+
+Logging statements are printed to `stderr`.
+
+Results can be exported to different report formats. Which can be imported into CI tools. See the help section for more information.
+
+# Configuration
+
+```yaml
+# allowed defines the modules that are permitted as direct dependencies.
+# When this section is non-empty, any module not matched by an entry is blocked.
+# When omitted entirely, all modules are allowed except those in the blocked list.
+allowed:
+ # Exact match (default when match-type is omitted).
+ - module: go.yaml.in/yaml/v4
+ - module: github.com/go-xmlfmt/xmlfmt
+
+ # version constrains which versions of the module are allowed.
+ # Uses semver constraint syntax (e.g. ">= 1.0.0", "~1.2", "== 2.5.0").
+ - module: github.com/confluentinc/confluent-kafka-go/v2
+ version: "== 2.5.0"
+
+ # match-type controls how the module is matched against module paths.
+ # Options: exact (default), prefix, regex
+ - module: github.com/kubernetes
+ match-type: prefix
+ - module: github.com/apache/arrow-go
+ match-type: prefix
+ - module: "github.com/somecompany/.*"
+ match-type: regex
+
+# blocked defines modules that are not permitted as direct dependencies.
+blocked:
+ - module: github.com/uudashr/go-module
+ # match-type controls how the module is matched against module paths.
+ # Options: exact (default), prefix, regex
+ match-type: exact
+
+ # recommendations lists alternative modules to suggest in the lint error.
+ recommendations:
+ - golang.org/x/mod
+
+ # reason is a human-readable explanation appended to the lint error.
+ reason: "`mod` is the official go.mod parser library."
+
+ - module: github.com/mitchellh/go-homedir
+ # version constrains which versions of the module are blocked.
+ # Uses semver constraint syntax. When omitted, all versions are blocked.
+ version: "<= 1.1.0"
+ reason: "old versions have a known bug."
+
+ - module: "github.com/badcompany/.*"
+ match-type: regex
+ reason: "No badcompany packages are permitted."
+
+# Blocks 'replace' directives using local filesystem paths to prevent
+# accidental commits of dev overrides. Sibling modules in multi-module
+# repos are automatically detected and permitted.
+local_replace_directives: true
+```
+
+### Field reference
+
+#### Top-level fields
+
+| Field | Type | Default | Description |
+|---|---|---|---|
+| `allowed` | list | *(none)* | Modules that are permitted. When non-empty, anything not matched is blocked. |
+| `blocked` | list | *(none)* | Modules that are explicitly blocked. |
+| `local_replace_directives` | bool | `false` | Block any module whose `replace` directive points to a local filesystem path. Multi-module repo aware: sibling modules whose replacement path contains a matching `go.mod` are not blocked. |
+
+#### `allowed` / `blocked` entry fields
+
+| Field | Type | Description |
+|---|---|---|
+| `module` | string | The module path to match against. |
+| `match-type` | `exact` \| `prefix` \| `regex` | How `module` is matched against dependency paths. Defaults to `exact`. |
+| `version` | semver constraint string | Restricts the rule to specific versions (e.g. `<= 1.2.0`, `>= 2.0.0`). When omitted, all versions match. |
+| `recommendations` | list of module paths | *(blocked only)* Alternative modules to suggest in the lint error. If the module being linted is itself in this list, the block is skipped. |
+| `reason` | string | *(blocked only)* Human-readable explanation appended to the lint error. |
+
+#### Match type precedence
+
+When multiple rules can match the same module the following precedence applies:
+
+1. **Exact match** — highest priority; wins over prefix and regex.
+2. **Prefix match** — next priority; longest matching prefix wins.
+3. **Regex match** — lowest priority; evaluated in alphabetical key order; first match wins.
+
+## Example .gomodguard.yaml Files
+
+The following example configuration files are available:
+
+- [examples/alloptions/.gomodguard.yaml](examples/alloptions/.gomodguard.yaml)
+- [examples/allowedversion/.gomodguard.yaml](examples/allowedversion/.gomodguard.yaml)
+- [examples/emptyallowlist/.gomodguard.yaml](examples/emptyallowlist/.gomodguard.yaml)
+- [examples/indirectdep/.gomodguard.yaml](examples/indirectdep/.gomodguard.yaml)
+- [examples/majorversion/.gomodguard.yaml](examples/majorversion/.gomodguard.yaml)
+- [examples/regexversion/.gomodguard.yaml](examples/regexversion/.gomodguard.yaml)
+- [examples/regextest/.gomodguard.yaml](examples/regextest/.gomodguard.yaml)
+
+### Migrating from v1
+
+If you have a v1 `.gomodguard.yaml` file, you can automatically migrate it to the new v2 schema by running:
+
+```
+gomodguard migrate > .gomodguard-v2.yaml
+mv .gomodguard-v2.yaml .gomodguard.yaml
+```
+
+## Usage
+
+```
+╰─ gomodguard -help
+Usage: gomodguard [files...]
+Also supports package syntax but will use it in relative path, i.e. ./pkg/...
+
+Commands:
+ (default) Lint Go module dependencies using the configuration file
+ migrate Convert a v1 .gomodguard.yaml config file to v2 format and print to stdout
+
+Flags:
+ -f string
+ Report results to the specified file. A report type must also be specified
+ -file string
+
+ -h Show this help text
+ -help
+
+ -i int
+ Exit code when issues were found (default 2)
+ -issues-exit-code int
+ (default 2)
+ -n Don't lint test files
+ -no-test
+
+ -r string
+ Report results to one of the following formats: checkstyle. A report file destination must also be specified
+ -report string
+
+ -version
+ Print the version
+```
+
+## Example
+
+```
+╰─ cd examples/alloptions
+╰─ gomodguard -r checkstyle -f gomodguard-checkstyle.xml ./...
+
+info: allowed modules, [github.com/Masterminds/semver/v3 github.com/go-xmlfmt/xmlfmt golang.org gopkg.in/yaml.v3]
+info: blocked modules, [github.com/gofrs/uuid github.com/mitchellh/go-homedir github.com/uudashr/go-module]
+blocked_example.go:6:1 import of package `github.com/gofrs/uuid` is blocked because the module is in the blocked modules list. `github.com/ryancurrah/gomodguard` is a recommended module. testing if module is not blocked when it is recommended.
+blocked_example.go:7:1 import of package `github.com/mitchellh/go-homedir` is blocked because the module is in the blocked modules list. version `v1.1.0` is blocked because it does not meet the version constraint `<=1.1.0`. testing if blocked version constraint works.
+blocked_example.go:8:1 import of package `github.com/uudashr/go-module` is blocked because the module is in the blocked modules list. `golang.org/x/mod` is a recommended module. `mod` is the official go.mod parser library.
+```
+
+Resulting checkstyle file
+
+```
+╰─ cat gomodguard-checkstyle.xml
+
+
+
+
+
+
+
+
+
+```
+
+## Install
+
+```
+go install github.com/ryancurrah/gomodguard/cmd/gomodguard/v2@latest
+```
+
+## Develop
+
+```
+git clone https://github.com/ryancurrah/gomodguard.git && cd gomodguard/cmd/gomodguard
+
+go build -o gomodguard main.go
+```
+
+The repository is a multi-module workspace: the library lives at the root and the CLI lives under `cmd/gomodguard`. A `go.work` file at the repo root wires them together so local CLI builds pick up local library changes without needing a `replace` directive in `cmd/gomodguard/go.mod`.
+
+## License
+
+**MIT**
diff --git a/vendor/github.com/ryancurrah/gomodguard/v2/allowed.go b/vendor/github.com/ryancurrah/gomodguard/v2/allowed.go
new file mode 100644
index 000000000..536a74cbe
--- /dev/null
+++ b/vendor/github.com/ryancurrah/gomodguard/v2/allowed.go
@@ -0,0 +1,42 @@
+package gomodguard
+
+import (
+ "fmt"
+
+ "github.com/Masterminds/semver/v3"
+)
+
+// Allowed is a list of modules that are allowed to be used.
+type Allowed []AllowedModule
+
+// AllowedModule is a single entry in the allowed list.
+type AllowedModule struct {
+ Module string `yaml:"module"`
+ MatchType MatchType `yaml:"match-type"`
+ Version *semver.Constraints `yaml:"version"`
+ Matcher Matcher `yaml:"-"`
+}
+
+// CheckVersion returns true if the module version matches the allowed constraint,
+// or if no version constraint is specified.
+func (r *AllowedModule) CheckVersion(moduleVersion string) (bool, error) {
+ if r.Version == nil {
+ return true, nil
+ }
+
+ version, err := semver.NewVersion(moduleVersion)
+ if err != nil {
+ return false, err
+ }
+
+ return r.Version.Check(version), nil
+}
+
+// NotAllowedReason returns the reason why the module version is not allowed.
+func (r *AllowedModule) NotAllowedReason(moduleVersion string) string {
+ if r == nil || r.Version == nil {
+ return "the module is not in the allowed modules list."
+ }
+
+ return fmt.Sprintf("version `%s` does not meet the allowed version constraint `%s`.", moduleVersion, r.Version)
+}
diff --git a/vendor/github.com/ryancurrah/gomodguard/v2/blocked.go b/vendor/github.com/ryancurrah/gomodguard/v2/blocked.go
new file mode 100644
index 000000000..5ba7ee1f3
--- /dev/null
+++ b/vendor/github.com/ryancurrah/gomodguard/v2/blocked.go
@@ -0,0 +1,99 @@
+package gomodguard
+
+import (
+ "fmt"
+ "strings"
+
+ "github.com/Masterminds/semver/v3"
+)
+
+// Blocked is a list of modules that are blocked and not to be used.
+type Blocked []BlockedModule
+
+// BlockedModule is a single entry in the blocked list.
+type BlockedModule struct {
+ Module string `yaml:"module"`
+ MatchType MatchType `yaml:"match-type"`
+ Recommendations []string `yaml:"recommendations"`
+ Reason string `yaml:"reason"`
+ Version *semver.Constraints `yaml:"version"`
+ Matcher Matcher `yaml:"-"`
+}
+
+// CheckVersion returns true if the module version matches the blocked constraint.
+// If no version constraint is specified, all versions are considered blocked.
+func (r *BlockedModule) CheckVersion(moduleVersion string) (bool, error) {
+ if r.Version == nil {
+ return true, nil
+ }
+
+ version, err := semver.NewVersion(moduleVersion)
+ if err != nil {
+ return true, err
+ }
+
+ return r.Version.Check(version), nil
+}
+
+// BlockReason returns the reason why the module or version is blocked.
+func (r *BlockedModule) BlockReason(currentModuleVersion string) string {
+ var sb strings.Builder
+
+ if r.Version != nil {
+ _, _ = fmt.Fprintf(&sb, "version `%s` is blocked because it does not meet the version constraint `%s`.",
+ currentModuleVersion, r.Version)
+ }
+
+ if len(r.Recommendations) > 0 {
+ if sb.Len() > 0 {
+ sb.WriteString(" ")
+ }
+
+ for i := range r.Recommendations {
+ switch {
+ case len(r.Recommendations) == 1:
+ _, _ = fmt.Fprintf(&sb, "`%s` is a recommended module.", r.Recommendations[i])
+ case (i+1) != len(r.Recommendations) && (i+1) == (len(r.Recommendations)-1):
+ _, _ = fmt.Fprintf(&sb, "`%s` ", r.Recommendations[i])
+ case (i + 1) != len(r.Recommendations):
+ _, _ = fmt.Fprintf(&sb, "`%s`, ", r.Recommendations[i])
+ default:
+ _, _ = fmt.Fprintf(&sb, "and `%s` are recommended modules.", r.Recommendations[i])
+ }
+ }
+ }
+
+ if r.Reason != "" {
+ if sb.Len() > 0 {
+ _, _ = fmt.Fprintf(&sb, " %s.", strings.TrimRight(r.Reason, "."))
+ } else {
+ _, _ = fmt.Fprintf(&sb, "%s.", strings.TrimRight(r.Reason, "."))
+ }
+ }
+
+ return sb.String()
+}
+
+// IsCurrentModuleARecommendation returns true if the current module is in the Recommendations list.
+func (r *BlockedModule) IsCurrentModuleARecommendation(currentModuleName string) bool {
+ if r == nil {
+ return false
+ }
+
+ for n := range r.Recommendations {
+ if strings.TrimSpace(currentModuleName) == strings.TrimSpace(r.Recommendations[n]) {
+ return true
+ }
+ }
+
+ return false
+}
+
+// HasRecommendations returns true if the blocked package has recommended modules.
+func (r *BlockedModule) HasRecommendations() bool {
+ if r == nil {
+ return false
+ }
+
+ return len(r.Recommendations) > 0
+}
diff --git a/vendor/github.com/ryancurrah/gomodguard/v2/codecov.yml b/vendor/github.com/ryancurrah/gomodguard/v2/codecov.yml
new file mode 100644
index 000000000..4c475c7ca
--- /dev/null
+++ b/vendor/github.com/ryancurrah/gomodguard/v2/codecov.yml
@@ -0,0 +1,9 @@
+coverage:
+ status:
+ project:
+ default:
+ target: auto
+ threshold: 5%
+ patch:
+ default:
+ target: auto
diff --git a/vendor/github.com/ryancurrah/gomodguard/v2/filesearch.go b/vendor/github.com/ryancurrah/gomodguard/v2/filesearch.go
new file mode 100644
index 000000000..4c4769d71
--- /dev/null
+++ b/vendor/github.com/ryancurrah/gomodguard/v2/filesearch.go
@@ -0,0 +1,66 @@
+package gomodguard
+
+import (
+ "os"
+ "path/filepath"
+ "strings"
+)
+
+// Find returns files based on search string arguments and filters.
+func Find(cwd string, skipTests bool, args []string) []string {
+ var (
+ foundFiles = []string{}
+ filteredFiles = []string{}
+ )
+
+ for _, f := range args {
+ if strings.HasSuffix(f, "/...") {
+ dir, _ := filepath.Split(f)
+
+ foundFiles = append(foundFiles, expandGoWildcard(dir)...)
+
+ continue
+ }
+
+ if _, err := os.Stat(f); err == nil {
+ foundFiles = append(foundFiles, f)
+ }
+ }
+
+ // Use relative path to print shorter names, sort out test foundFiles if chosen.
+ for _, f := range foundFiles {
+ if skipTests {
+ if strings.HasSuffix(f, "_test.go") {
+ continue
+ }
+ }
+
+ if relativePath, err := filepath.Rel(cwd, f); err == nil {
+ filteredFiles = append(filteredFiles, relativePath)
+
+ continue
+ }
+
+ filteredFiles = append(filteredFiles, f)
+ }
+
+ return filteredFiles
+}
+
+// expandGoWildcard path provided.
+func expandGoWildcard(root string) []string {
+ foundFiles := []string{}
+
+ _ = filepath.Walk(root, func(path string, info os.FileInfo, _ error) error {
+ // Only append go foundFiles.
+ if !strings.HasSuffix(info.Name(), ".go") {
+ return nil
+ }
+
+ foundFiles = append(foundFiles, path)
+
+ return nil
+ })
+
+ return foundFiles
+}
diff --git a/vendor/github.com/ryancurrah/gomodguard/v2/go.work b/vendor/github.com/ryancurrah/gomodguard/v2/go.work
new file mode 100644
index 000000000..63d63678e
--- /dev/null
+++ b/vendor/github.com/ryancurrah/gomodguard/v2/go.work
@@ -0,0 +1,6 @@
+go 1.25.0
+
+use (
+ .
+ ./cmd/gomodguard
+)
diff --git a/vendor/github.com/ryancurrah/gomodguard/v2/go.work.sum b/vendor/github.com/ryancurrah/gomodguard/v2/go.work.sum
new file mode 100644
index 000000000..fc90f0f3b
--- /dev/null
+++ b/vendor/github.com/ryancurrah/gomodguard/v2/go.work.sum
@@ -0,0 +1,8 @@
+github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
+github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
+github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
+golang.org/x/net v0.52.0/go.mod h1:R1MAz7uMZxVMualyPXb+VaqGSa3LIaUqk0eEt3w36Sw=
+golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
+golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
+golang.org/x/telemetry v0.0.0-20260311193753-579e4da9a98c/go.mod h1:TpUTTEp9frx7rTdLpC9gFG9kdI7zVLFTFFlqaH2Cncw=
+golang.org/x/tools v0.43.0/go.mod h1:uHkMso649BX2cZK6+RpuIPXS3ho2hZo4FVwfoy1vIk0=
diff --git a/vendor/github.com/ryancurrah/gomodguard/v2/issue.go b/vendor/github.com/ryancurrah/gomodguard/v2/issue.go
new file mode 100644
index 000000000..d60fc3a86
--- /dev/null
+++ b/vendor/github.com/ryancurrah/gomodguard/v2/issue.go
@@ -0,0 +1,20 @@
+package gomodguard
+
+import (
+ "fmt"
+ "go/token"
+)
+
+// Issue represents the result of one error.
+type Issue struct {
+ FileName string
+ LineNumber int
+ Position token.Position
+ Reason string
+}
+
+// String returns the filename, line
+// number and reason of a Issue.
+func (r *Issue) String() string {
+ return fmt.Sprintf("%s:%d:1 %s", r.FileName, r.LineNumber, r.Reason)
+}
diff --git a/vendor/github.com/ryancurrah/gomodguard/v2/matchers.go b/vendor/github.com/ryancurrah/gomodguard/v2/matchers.go
new file mode 100644
index 000000000..ae74b978a
--- /dev/null
+++ b/vendor/github.com/ryancurrah/gomodguard/v2/matchers.go
@@ -0,0 +1,77 @@
+package gomodguard
+
+import (
+ "fmt"
+ "regexp"
+ "strings"
+)
+
+// MatchType represents the type of matching to be performed for a module name.
+type MatchType string
+
+const (
+ // ExactMatch matches a module name exactly.
+ ExactMatch MatchType = "exact"
+ // PrefixMatch matches a module name by prefix.
+ PrefixMatch MatchType = "prefix"
+ // RegexMatch matches a module name by regex.
+ RegexMatch MatchType = "regex"
+)
+
+// Matcher interface for matching module names.
+type Matcher interface {
+ Match(moduleName string) bool
+}
+
+// ExactMatcher matches a module name exactly.
+type ExactMatcher struct {
+ Target string
+}
+
+func (m ExactMatcher) Match(moduleName string) bool {
+ return strings.TrimSpace(moduleName) == m.Target
+}
+
+// PrefixMatcher matches a module name by prefix.
+type PrefixMatcher struct {
+ Prefix string
+}
+
+// Match returns true if the moduleName starts with the Prefix, ignoring leading/trailing whitespace and case.
+func (m PrefixMatcher) Match(moduleName string) bool {
+ return strings.HasPrefix(strings.TrimSpace(strings.ToLower(moduleName)), strings.ToLower(m.Prefix))
+}
+
+// RegexMatcher matches a module name by regex.
+type RegexMatcher struct {
+ Regex *regexp.Regexp
+}
+
+func (m RegexMatcher) Match(moduleName string) bool {
+ if m.Regex == nil {
+ return false
+ }
+
+ return m.Regex.MatchString(strings.TrimSpace(moduleName))
+}
+
+// compileMatcher creates a Matcher based on the match type and pattern.
+//
+//nolint:ireturn // This factory intentionally returns the Matcher interface.
+func compileMatcher(matchType MatchType, pattern string) (Matcher, error) {
+ switch matchType {
+ case PrefixMatch:
+ return PrefixMatcher{Prefix: strings.TrimSpace(pattern)}, nil
+ case RegexMatch:
+ re, err := regexp.Compile(strings.TrimSpace(pattern))
+ if err != nil {
+ return nil, err
+ }
+
+ return RegexMatcher{Regex: re}, nil
+ case ExactMatch, "":
+ return ExactMatcher{Target: strings.TrimSpace(pattern)}, nil
+ default:
+ return nil, fmt.Errorf("unknown match-type %q for pattern %q", matchType, pattern)
+ }
+}
diff --git a/vendor/github.com/ryancurrah/gomodguard/v2/processor.go b/vendor/github.com/ryancurrah/gomodguard/v2/processor.go
new file mode 100644
index 000000000..82fa4c2df
--- /dev/null
+++ b/vendor/github.com/ryancurrah/gomodguard/v2/processor.go
@@ -0,0 +1,517 @@
+package gomodguard
+
+import (
+ "bytes"
+ "cmp"
+ "encoding/json"
+ "errors"
+ "fmt"
+ "go/parser"
+ "go/token"
+ "os"
+ "os/exec"
+ "path/filepath"
+ "regexp"
+ "slices"
+ "strings"
+
+ "golang.org/x/mod/modfile"
+)
+
+const (
+ goModFilename = "go.mod"
+ errReadingGoModFile = "unable to read module file %s: %w"
+ errParsingGoModFile = "unable to parse module file %s: %w"
+)
+
+var (
+ blockReasonInBlockedList = "import of package `%s` is blocked because the module is in the blocked modules list."
+ blockReasonHasLocalReplaceDirective = "import of package `%s` is blocked because the module has a local replace directive."
+
+ // startsWithVersion is used to test when a string begins with the version identifier of a module,
+ // after having stripped the prefix base module name. IE "github.com/foo/bar/v2/baz" => "v2/baz"
+ // probably indicates that the module is actually github.com/foo/bar/v2, not github.com/foo/bar.
+ startsWithVersion = regexp.MustCompile(`^v[0-9]+`)
+)
+
+// ruleIndex provides deterministic, specificity-based rule matching.
+// Rules are evaluated in three tiers:
+// 1. Exact match — O(1) map lookup.
+// 2. Prefix match — longest matching prefix wins.
+// 3. Regex match — evaluated in alphabetical key order; first match wins.
+type ruleIndex struct {
+ exactLookup map[string]string // trimmed module name -> original map key
+ prefixKeys []string // sorted by length desc, then alphabetically
+ regexKeys []string // sorted alphabetically
+ matchers map[string]Matcher // key -> compiled matcher
+}
+
+// newRuleIndex categorises rule keys into exact, prefix, and regex tiers
+// and pre-sorts the prefix and regex tiers for deterministic evaluation.
+func newRuleIndex(keys []string, matchTypes map[string]MatchType, matchers map[string]Matcher) *ruleIndex {
+ idx := &ruleIndex{
+ exactLookup: make(map[string]string, len(keys)),
+ matchers: matchers,
+ }
+
+ for _, k := range keys {
+ switch matchTypes[k] {
+ case ExactMatch:
+ idx.exactLookup[strings.TrimSpace(k)] = k
+ case PrefixMatch:
+ idx.prefixKeys = append(idx.prefixKeys, k)
+ case RegexMatch:
+ idx.regexKeys = append(idx.regexKeys, k)
+ default:
+ idx.exactLookup[strings.TrimSpace(k)] = k
+ }
+ }
+
+ // Longest prefix first for most-specific match.
+ slices.SortFunc(idx.prefixKeys, func(a, b string) int {
+ return cmp.Compare(len(b), len(a))
+ })
+
+ // Alphabetical order for deterministic regex evaluation.
+ slices.Sort(idx.regexKeys)
+
+ return idx
+}
+
+// bestMatch returns the key of the best-matching rule for moduleName,
+// following the tiered precedence: exact > longest prefix > first regex.
+func (idx *ruleIndex) bestMatch(moduleName string) (string, bool) {
+ trimmed := strings.TrimSpace(moduleName)
+
+ // Tier 1: exact match (O(1))
+ if key, ok := idx.exactLookup[trimmed]; ok {
+ return key, true
+ }
+
+ // Tier 2: longest prefix match
+ for _, key := range idx.prefixKeys {
+ if idx.matchers[key].Match(moduleName) {
+ return key, true
+ }
+ }
+
+ // Tier 3: first regex match (alphabetical order)
+ for _, key := range idx.regexKeys {
+ if idx.matchers[key].Match(moduleName) {
+ return key, true
+ }
+ }
+
+ return "", false
+}
+
+// Configuration of gomodguard allow and block lists.
+type Configuration struct {
+ Allowed Allowed `yaml:"allowed"`
+ Blocked Blocked `yaml:"blocked"`
+ LocalReplaceDirectives bool `yaml:"local_replace_directives"`
+}
+
+// InitMatchers initializes matchers for the configuration rules.
+func (c *Configuration) InitMatchers() error {
+ for i := range c.Allowed {
+ m, err := compileMatcher(c.Allowed[i].MatchType, c.Allowed[i].Module)
+ if err != nil {
+ return fmt.Errorf("failed compiling allowed matcher for '%s': %w", c.Allowed[i].Module, err)
+ }
+
+ c.Allowed[i].Matcher = m
+ }
+
+ for i := range c.Blocked {
+ m, err := compileMatcher(c.Blocked[i].MatchType, c.Blocked[i].Module)
+ if err != nil {
+ return fmt.Errorf("failed compiling blocked matcher for '%s': %w", c.Blocked[i].Module, err)
+ }
+
+ c.Blocked[i].Matcher = m
+ }
+
+ return nil
+}
+
+// Processor processes Go files.
+type Processor struct {
+ Config *Configuration
+ Modfile *modfile.File
+ blockedModulesFromModFile map[string][]string
+}
+
+// NewProcessor will create a Processor to lint blocked packages.
+func NewProcessor(config *Configuration) (*Processor, error) {
+ goModFileBytes, err := loadGoModFile()
+ if err != nil {
+ return nil, fmt.Errorf(errReadingGoModFile, goModFilename, err)
+ }
+
+ modFile, err := modfile.Parse(goModFilename, goModFileBytes, nil)
+ if err != nil {
+ return nil, fmt.Errorf(errParsingGoModFile, goModFilename, err)
+ }
+
+ if err := config.InitMatchers(); err != nil {
+ return nil, err
+ }
+
+ p := &Processor{
+ Config: config,
+ Modfile: modFile,
+ }
+
+ p.SetBlockedModules()
+
+ return p, nil
+}
+
+// ProcessFiles takes a string slice with file names (full paths)
+// and lints them.
+func (p *Processor) ProcessFiles(filenames []string) (issues []Issue) {
+ for _, filename := range filenames {
+ data, err := os.ReadFile(filepath.Clean(filename))
+ if err != nil {
+ issues = append(issues, Issue{
+ FileName: filename,
+ LineNumber: 0,
+ Reason: fmt.Sprintf("unable to read file, file cannot be linted (%s)", err.Error()),
+ })
+
+ continue
+ }
+
+ issues = append(issues, p.process(filename, data)...)
+ }
+
+ return issues
+}
+
+// SetBlockedModules determines and sets which modules are blocked by reading
+// the go.mod file of the current module.
+//
+// It works by iterating over the required modules specified in the require
+// directive, checking if the module prefix or full name is in the allowed list.
+//
+// Rules are evaluated using a layered strategy for deterministic results:
+// 1. Exact match — O(1) lookup; wins immediately.
+// 2. Prefix match — longest matching prefix wins.
+// 3. Regex match — evaluated in alphabetical key order; first match wins.
+func (p *Processor) SetBlockedModules() { //nolint:gocognit // Ack this is a long func.
+ blockedModules := make(map[string][]string, len(p.Modfile.Require))
+ currentModuleName := p.Modfile.Module.Mod.Path
+ requiredModules := p.Modfile.Require
+
+ // Build tiered rule indices for blocked and allowed rules.
+ blockedIdx, blockedLookup := buildRuleIndex(
+ p.Config.Blocked,
+ func(r BlockedModule) string { return r.Module },
+ func(r BlockedModule) MatchType { return r.MatchType },
+ func(r BlockedModule) Matcher { return r.Matcher },
+ )
+ allowedIdx, allowedLookup := buildRuleIndex(
+ p.Config.Allowed,
+ func(r AllowedModule) string { return r.Module },
+ func(r AllowedModule) MatchType { return r.MatchType },
+ func(r AllowedModule) Matcher { return r.Matcher },
+ )
+
+ for i := range requiredModules {
+ requiredModuleName := strings.TrimSpace(requiredModules[i].Mod.Path)
+ requiredModuleVersion := strings.TrimSpace(requiredModules[i].Mod.Version)
+
+ var matchedBlockRule *BlockedModule
+
+ // Check against blocked rules first (exact > longest prefix > first regex)
+ if key, ok := blockedIdx.bestMatch(requiredModuleName); ok {
+ rule := blockedLookup[key] // copy
+ matchedBlockRule = &rule
+ }
+
+ if matchedBlockRule != nil && matchedBlockRule.IsCurrentModuleARecommendation(currentModuleName) {
+ // The current module is a recommended alternative for this blocked module, allowing it.
+ matchedBlockRule = nil
+ }
+
+ if matchedBlockRule != nil {
+ isVersBlocked, err := matchedBlockRule.CheckVersion(requiredModuleVersion)
+ if err != nil {
+ // NOTE: Unreachable via real go.mod files; modfile.Parse rejects invalid versions
+ // earlier. Left untested by design as this branch cannot be triggered.
+ blockedModules[requiredModuleName] = append(blockedModules[requiredModuleName],
+ fmt.Sprintf("%s unable to parse version `%s`: %s",
+ blockReasonInBlockedList, requiredModuleVersion, err,
+ ),
+ )
+
+ continue
+ }
+
+ if !isVersBlocked {
+ // Doesn't match the blocked version constraint, so we let it pass the block check
+ matchedBlockRule = nil
+ }
+ }
+
+ // If it's blocked, record it and move to next
+ if matchedBlockRule != nil {
+ blockedModules[requiredModuleName] = append(blockedModules[requiredModuleName],
+ fmt.Sprintf("%s %s", blockReasonInBlockedList,
+ matchedBlockRule.BlockReason(requiredModuleVersion),
+ ),
+ )
+
+ continue
+ }
+
+ // If no allowed list is specified, default mapping is to allow all
+ if len(p.Config.Allowed) == 0 {
+ continue
+ }
+
+ isAllowed := false
+
+ var matchedButWrongVersion *AllowedModule
+
+ if key, ok := allowedIdx.bestMatch(requiredModuleName); ok {
+ rule := allowedLookup[key] // copy
+
+ ok, err := rule.CheckVersion(requiredModuleVersion)
+
+ switch {
+ case err != nil:
+ // NOTE: Unreachable via real go.mod files; modfile.Parse rejects invalid versions
+ // earlier. Left untested by design as this branch cannot be triggered.
+ blockedModules[requiredModuleName] = append(blockedModules[requiredModuleName],
+ fmt.Sprintf("import of package `%%s` is blocked because the module version `%s` could not be parsed: %s",
+ requiredModuleVersion, err,
+ ),
+ )
+
+ isAllowed = true // skip the generic "not allowed" message below
+ case ok:
+ isAllowed = true
+ default:
+ matchedButWrongVersion = &rule
+ }
+ }
+
+ if !isAllowed {
+ blockedModules[requiredModuleName] = append(blockedModules[requiredModuleName],
+ fmt.Sprintf("import of package `%%s` is blocked because %s", matchedButWrongVersion.NotAllowedReason(requiredModuleVersion)))
+ }
+ }
+
+ // Blocks local 'replace' directives to prevent committing dev overrides.
+ // Legitimate sibling modules in multi-module repos (sharing the same
+ // module name) are exempt.
+ if p.Config.LocalReplaceDirectives {
+ for _, r := range p.Modfile.Replace {
+ if isBlockedLocalReplace(r) {
+ blockedModules[r.Old.Path] = append(blockedModules[r.Old.Path],
+ blockReasonHasLocalReplaceDirective,
+ )
+ }
+ }
+ }
+
+ p.blockedModulesFromModFile = blockedModules
+}
+
+// buildRuleIndex constructs a ruleIndex and a key→rule lookup from any slice of rules.
+// The three accessor functions extract the module name, match type, and compiled matcher
+// from each rule, keeping this function independent of the concrete rule type.
+func buildRuleIndex[R any](
+ rules []R,
+ moduleFn func(R) string,
+ matchTypeFn func(R) MatchType,
+ matcherFn func(R) Matcher,
+) (*ruleIndex, map[string]R) {
+ keys := make([]string, 0, len(rules))
+ matchTypes := make(map[string]MatchType, len(rules))
+ matchers := make(map[string]Matcher, len(rules))
+ lookup := make(map[string]R, len(rules))
+
+ for _, r := range rules {
+ mod := moduleFn(r)
+ keys = append(keys, mod)
+ matchTypes[mod] = matchTypeFn(r)
+ matchers[mod] = matcherFn(r)
+ lookup[mod] = r
+ }
+
+ return newRuleIndex(keys, matchTypes, matchers), lookup
+}
+
+// process file imports and add lint error if blocked package is imported.
+func (p *Processor) process(filename string, data []byte) (issues []Issue) {
+ fileSet := token.NewFileSet()
+
+ file, err := parser.ParseFile(fileSet, filename, data, parser.ParseComments)
+ if err != nil {
+ issues = append(issues, Issue{
+ FileName: filename,
+ LineNumber: 0,
+ Reason: fmt.Sprintf("invalid syntax, file cannot be linted (%s)", err.Error()),
+ })
+
+ return
+ }
+
+ imports := file.Imports
+ for n := range imports {
+ importedPkg := strings.TrimSpace(strings.Trim(imports[n].Path.Value, "\""))
+
+ blockReasons := p.isBlockedPackageFromModFile(importedPkg)
+ if blockReasons == nil {
+ continue
+ }
+
+ for _, blockReason := range blockReasons {
+ issues = append(issues, p.addError(fileSet, imports[n].Pos(), blockReason))
+ }
+ }
+
+ return issues
+}
+
+// addError adds an error for the file and line number for the current token.Pos
+// with the given reason.
+func (p *Processor) addError(fileset *token.FileSet, pos token.Pos, reason string) Issue {
+ position := fileset.Position(pos)
+
+ return Issue{
+ FileName: position.Filename,
+ LineNumber: position.Line,
+ Position: position,
+ Reason: reason,
+ }
+}
+
+// isBlockedPackageFromModFile returns the block reason if the package is blocked.
+func (p *Processor) isBlockedPackageFromModFile(packageName string) []string {
+ for blockedModuleName, blockReasons := range p.blockedModulesFromModFile {
+ if isPackageInModule(packageName, blockedModuleName) {
+ formattedReasons := make([]string, 0, len(blockReasons))
+
+ for _, blockReason := range blockReasons {
+ formattedReasons = append(formattedReasons, fmt.Sprintf(blockReason, packageName))
+ }
+
+ return formattedReasons
+ }
+ }
+
+ return nil
+}
+
+// loadGoModFile loads the contents of the go.mod file in the current working directory.
+// It first checks the "GOMOD" environment variable to determine the path of the go.mod file.
+// If the environment variable is not set or the file does not exist, it falls back to reading the go.mod file in the current directory.
+// If the "GOMOD" environment variable is set to "/dev/null", it returns an error indicating that the current working directory must have a go.mod file.
+// The function returns the contents of the go.mod file as a byte slice and any error encountered during the process.
+func loadGoModFile() ([]byte, error) {
+ cmd := exec.Command("go", "env", "-json") //nolint:noctx // Ack at some point might use os/exec.CommandContext.
+ stdout, _ := cmd.StdoutPipe()
+ _ = cmd.Start()
+
+ if stdout == nil {
+ return os.ReadFile(filepath.Clean(goModFilename))
+ }
+
+ buf := new(bytes.Buffer)
+ _, _ = buf.ReadFrom(stdout)
+
+ goEnv := make(map[string]string)
+
+ err := json.Unmarshal(buf.Bytes(), &goEnv)
+ if err != nil {
+ return os.ReadFile(goModFilename)
+ }
+
+ if _, ok := goEnv["GOMOD"]; !ok {
+ return os.ReadFile(goModFilename)
+ }
+
+ if _, err = os.Stat(goEnv["GOMOD"]); os.IsNotExist(err) {
+ return os.ReadFile(goModFilename)
+ }
+
+ if goEnv["GOMOD"] == "/dev/null" || goEnv["GOMOD"] == "NUL" {
+ return nil, errors.New("current working directory must have a go.mod file")
+ }
+
+ return os.ReadFile(goEnv["GOMOD"])
+}
+
+// isBlockedLocalReplace returns true if the replace directive points to a local
+// filesystem path that is not a legitimate sibling module.
+func isBlockedLocalReplace(r *modfile.Replace) bool {
+ if r.New.Path == "" || r.New.Version != "" {
+ return false
+ }
+
+ replacePath := r.New.Path
+ if !filepath.IsAbs(replacePath) {
+ wd, err := os.Getwd()
+ if err != nil {
+ wd = "."
+ }
+
+ replacePath = filepath.Join(wd, replacePath)
+ }
+
+ return !isModuleAtPath(replacePath, r.Old.Path)
+}
+
+// isModuleAtPath returns true if the directory at path contains a go.mod file
+// that declares moduleName as its module, indicating a legitimate sibling module
+// in a multi-module repository rather than a local development override.
+func isModuleAtPath(path, moduleName string) bool {
+ data, err := os.ReadFile(filepath.Clean(filepath.Join(path, goModFilename)))
+ if err != nil {
+ return false
+ }
+
+ mf, err := modfile.Parse(goModFilename, data, nil)
+ if err != nil {
+ return false
+ }
+
+ return mf.Module.Mod.Path == moduleName
+}
+
+// isPackageInModule determines if a package is a part of the specified Go module.
+func isPackageInModule(pkg, mod string) bool {
+ // Split pkg and mod paths into parts
+ pkgPart := strings.Split(pkg, "/")
+ modPart := strings.Split(mod, "/")
+
+ pkgPartMatches := 0
+
+ // Count number of times pkg path matches the mod path
+ for i, m := range modPart {
+ if len(pkgPart) > i && pkgPart[i] == m {
+ pkgPartMatches++
+ }
+ }
+
+ // If pkgPartMatches are not the same length as modPart
+ // than the package is not in this module
+ if pkgPartMatches != len(modPart) {
+ return false
+ }
+
+ if len(pkgPart) > len(modPart) {
+ // If pkgPart path starts with a major version
+ // than the package is not in this module as
+ // major versions are completely different modules
+ if startsWithVersion.MatchString(pkgPart[len(modPart)]) {
+ return false
+ }
+ }
+
+ return true
+}
diff --git a/vendor/github.com/ryanrolds/sqlclosecheck/pkg/analyzer/analyzer.go b/vendor/github.com/ryanrolds/sqlclosecheck/pkg/analyzer/analyzer.go
index 55e931a89..8dd836255 100644
--- a/vendor/github.com/ryanrolds/sqlclosecheck/pkg/analyzer/analyzer.go
+++ b/vendor/github.com/ryanrolds/sqlclosecheck/pkg/analyzer/analyzer.go
@@ -1,405 +1,35 @@
package analyzer
import (
- "go/types"
+ "flag"
"golang.org/x/tools/go/analysis"
"golang.org/x/tools/go/analysis/passes/buildssa"
- "golang.org/x/tools/go/ssa"
)
-const (
- rowsName = "Rows"
- stmtName = "Stmt"
- namedStmtName = "NamedStmt"
- closeMethod = "Close"
-)
-
-type action uint8
-
-const (
- actionUnhandled action = iota
- actionHandled
- actionReturned
- actionPassed
- actionClosed
- actionUnvaluedCall
- actionUnvaluedDefer
- actionNoOp
-)
+// NewAnalyzer returns a non-configurable analyzer that defaults to the defer-only mode.
+// Deprecated, this will be removed in v1.0.0.
+func NewAnalyzer() *analysis.Analyzer {
+ flags := flag.NewFlagSet("analyzer", flag.ExitOnError)
+ return newAnalyzer(run, flags)
+}
-var (
- sqlPackages = []string{
- "database/sql",
- "github.com/jmoiron/sqlx",
- "github.com/jackc/pgx/v5",
- "github.com/jackc/pgx/v5/pgxpool",
- }
-)
+func run(pass *analysis.Pass) (interface{}, error) {
+ opinionatedAnalyzer := &deferOnlyAnalyzer{}
+ return opinionatedAnalyzer.Run(pass)
+}
-func NewAnalyzer() *analysis.Analyzer {
+// newAnalyzer returns a new analyzer with the given run function, should be used by all analyzers.
+func newAnalyzer(
+ r func(pass *analysis.Pass) (interface{}, error),
+ flags *flag.FlagSet,
+) *analysis.Analyzer {
return &analysis.Analyzer{
Name: "sqlclosecheck",
Doc: "Checks that sql.Rows, sql.Stmt, sqlx.NamedStmt, pgx.Query are closed.",
- Run: run,
+ Run: r,
Requires: []*analysis.Analyzer{
buildssa.Analyzer,
},
}
}
-
-func run(pass *analysis.Pass) (interface{}, error) {
- pssa, ok := pass.ResultOf[buildssa.Analyzer].(*buildssa.SSA)
- if !ok {
- return nil, nil
- }
-
- // Build list of types we are looking for
- targetTypes := getTargetTypes(pssa, sqlPackages)
-
- // If non of the types are found, skip
- if len(targetTypes) == 0 {
- return nil, nil
- }
-
- funcs := pssa.SrcFuncs
- for _, f := range funcs {
- for _, b := range f.Blocks {
- for i := range b.Instrs {
- // Check if instruction is call that returns a target pointer type
- targetValues := getTargetTypesValues(b, i, targetTypes)
- if len(targetValues) == 0 {
- continue
- }
-
- // For each found target check if they are closed and deferred
- for _, targetValue := range targetValues {
- refs := (*targetValue.value).Referrers()
- isClosed := checkClosed(refs, targetTypes)
- if !isClosed {
- pass.Reportf((targetValue.instr).Pos(), "Rows/Stmt/NamedStmt was not closed")
- }
-
- checkDeferred(pass, refs, targetTypes, false)
- }
- }
- }
- }
-
- return nil, nil
-}
-
-func getTargetTypes(pssa *buildssa.SSA, targetPackages []string) []any {
- targets := []any{}
-
- for _, sqlPkg := range targetPackages {
- pkg := pssa.Pkg.Prog.ImportedPackage(sqlPkg)
- if pkg == nil {
- // the SQL package being checked isn't imported
- continue
- }
-
- rowsPtrType := getTypePointerFromName(pkg, rowsName)
- if rowsPtrType != nil {
- targets = append(targets, rowsPtrType)
- }
-
- rowsType := getTypeFromName(pkg, rowsName)
- if rowsType != nil {
- targets = append(targets, rowsType)
- }
-
- stmtType := getTypePointerFromName(pkg, stmtName)
- if stmtType != nil {
- targets = append(targets, stmtType)
- }
-
- namedStmtType := getTypePointerFromName(pkg, namedStmtName)
- if namedStmtType != nil {
- targets = append(targets, namedStmtType)
- }
- }
-
- return targets
-}
-
-func getTypePointerFromName(pkg *ssa.Package, name string) *types.Pointer {
- pkgType := pkg.Type(name)
- if pkgType == nil {
- // this package does not use Rows/Stmt/NamedStmt
- return nil
- }
-
- obj := pkgType.Object()
- named, ok := obj.Type().(*types.Named)
- if !ok {
- return nil
- }
-
- return types.NewPointer(named)
-}
-
-func getTypeFromName(pkg *ssa.Package, name string) *types.Named {
- pkgType := pkg.Type(name)
- if pkgType == nil {
- // this package does not use Rows/Stmt
- return nil
- }
-
- obj := pkgType.Object()
- named, ok := obj.Type().(*types.Named)
- if !ok {
- return nil
- }
-
- return named
-}
-
-type targetValue struct {
- value *ssa.Value
- instr ssa.Instruction
-}
-
-func getTargetTypesValues(b *ssa.BasicBlock, i int, targetTypes []any) []targetValue {
- targetValues := []targetValue{}
-
- instr := b.Instrs[i]
- call, ok := instr.(*ssa.Call)
- if !ok {
- return targetValues
- }
-
- signature := call.Call.Signature()
- results := signature.Results()
- for i := 0; i < results.Len(); i++ {
- v := results.At(i)
- varType := v.Type()
-
- for _, targetType := range targetTypes {
- var tt types.Type
-
- switch t := targetType.(type) {
- case *types.Pointer:
- tt = t
- case *types.Named:
- tt = t
- default:
- continue
- }
-
- if !types.Identical(varType, tt) {
- continue
- }
-
- for _, cRef := range *call.Referrers() {
- switch instr := cRef.(type) {
- case *ssa.Call:
- if len(instr.Call.Args) >= 1 && types.Identical(instr.Call.Args[0].Type(), tt) {
- targetValues = append(targetValues, targetValue{
- value: &instr.Call.Args[0],
- instr: call,
- })
- }
- case ssa.Value:
- if types.Identical(instr.Type(), tt) {
- targetValues = append(targetValues, targetValue{
- value: &instr,
- instr: call,
- })
- }
- }
- }
- }
- }
-
- return targetValues
-}
-
-func checkClosed(refs *[]ssa.Instruction, targetTypes []any) bool {
- numInstrs := len(*refs)
- for idx, ref := range *refs {
- action := getAction(ref, targetTypes)
- switch action {
- case actionClosed, actionReturned, actionHandled:
- return true
- case actionPassed:
- // Passed and not used after
- if numInstrs == idx+1 {
- return true
- }
- }
- }
-
- return false
-}
-
-func getAction(instr ssa.Instruction, targetTypes []any) action {
- switch instr := instr.(type) {
- case *ssa.Defer:
- if instr.Call.Value != nil {
- name := instr.Call.Value.Name()
- if name == closeMethod {
- return actionClosed
- }
- }
-
- if instr.Call.Method != nil {
- name := instr.Call.Method.Name()
- if name == closeMethod {
- return actionClosed
- }
- }
-
- return actionUnvaluedDefer
- case *ssa.Call:
- if instr.Call.Value == nil {
- return actionUnvaluedCall
- }
-
- isTarget := false
- staticCallee := instr.Call.StaticCallee()
- if staticCallee != nil {
- receiver := instr.Call.StaticCallee().Signature.Recv()
- if receiver != nil {
- isTarget = isTargetType(receiver.Type(), targetTypes)
- }
- }
-
- name := instr.Call.Value.Name()
- if isTarget && name == closeMethod {
- return actionClosed
- }
-
- if !isTarget {
- return actionPassed
- }
- case *ssa.Phi:
- return actionPassed
- case *ssa.MakeInterface:
- return actionPassed
- case *ssa.Store:
- // A Row/Stmt is stored in a struct, which may be closed later
- // by a different flow.
- if _, ok := instr.Addr.(*ssa.FieldAddr); ok {
- return actionReturned
- }
-
- if len(*instr.Addr.Referrers()) == 0 {
- return actionNoOp
- }
-
- for _, aRef := range *instr.Addr.Referrers() {
- if c, ok := aRef.(*ssa.MakeClosure); ok {
- if f, ok := c.Fn.(*ssa.Function); ok {
- for _, b := range f.Blocks {
- if checkClosed(&b.Instrs, targetTypes) {
- return actionHandled
- }
- }
- }
- }
- }
- case *ssa.UnOp:
- instrType := instr.Type()
- for _, targetType := range targetTypes {
- var tt types.Type
-
- switch t := targetType.(type) {
- case *types.Pointer:
- tt = t
- case *types.Named:
- tt = t
- default:
- continue
- }
-
- if types.Identical(instrType, tt) {
- if checkClosed(instr.Referrers(), targetTypes) {
- return actionHandled
- }
- }
- }
- case *ssa.FieldAddr:
- if checkClosed(instr.Referrers(), targetTypes) {
- return actionHandled
- }
- case *ssa.Return:
- return actionReturned
- }
-
- return actionUnhandled
-}
-
-func checkDeferred(pass *analysis.Pass, instrs *[]ssa.Instruction, targetTypes []any, inDefer bool) {
- for _, instr := range *instrs {
- switch instr := instr.(type) {
- case *ssa.Defer:
- if instr.Call.Value != nil && instr.Call.Value.Name() == closeMethod {
- return
- }
-
- if instr.Call.Method != nil && instr.Call.Method.Name() == closeMethod {
- return
- }
- case *ssa.Call:
- if instr.Call.Value != nil && instr.Call.Value.Name() == closeMethod {
- if !inDefer {
- pass.Reportf(instr.Pos(), "Close should use defer")
- }
-
- return
- }
- case *ssa.Store:
- if len(*instr.Addr.Referrers()) == 0 {
- return
- }
-
- for _, aRef := range *instr.Addr.Referrers() {
- if c, ok := aRef.(*ssa.MakeClosure); ok {
- if f, ok := c.Fn.(*ssa.Function); ok {
- for _, b := range f.Blocks {
- checkDeferred(pass, &b.Instrs, targetTypes, true)
- }
- }
- }
- }
- case *ssa.UnOp:
- instrType := instr.Type()
- for _, targetType := range targetTypes {
- var tt types.Type
-
- switch t := targetType.(type) {
- case *types.Pointer:
- tt = t
- case *types.Named:
- tt = t
- default:
- continue
- }
-
- if types.Identical(instrType, tt) {
- checkDeferred(pass, instr.Referrers(), targetTypes, inDefer)
- }
- }
- case *ssa.FieldAddr:
- checkDeferred(pass, instr.Referrers(), targetTypes, inDefer)
- }
- }
-}
-
-func isTargetType(t types.Type, targetTypes []any) bool {
- for _, targetType := range targetTypes {
- switch tt := targetType.(type) {
- case *types.Pointer:
- if types.Identical(t, tt) {
- return true
- }
- case *types.Named:
- if types.Identical(t, tt) {
- return true
- }
- }
- }
-
- return false
-}
diff --git a/vendor/github.com/ryanrolds/sqlclosecheck/pkg/analyzer/closed.go b/vendor/github.com/ryanrolds/sqlclosecheck/pkg/analyzer/closed.go
new file mode 100644
index 000000000..72fdbdf9c
--- /dev/null
+++ b/vendor/github.com/ryanrolds/sqlclosecheck/pkg/analyzer/closed.go
@@ -0,0 +1,25 @@
+package analyzer
+
+import (
+ "flag"
+
+ "golang.org/x/tools/go/analysis"
+)
+
+type closedAnalyzer struct{}
+
+func NewClosedAnalyzer() *analysis.Analyzer {
+ analyzer := &closedAnalyzer{}
+ flags := flag.NewFlagSet("closedAnalyzer", flag.ExitOnError)
+ return newAnalyzer(analyzer.Run, flags)
+}
+
+// Run implements the main analysis pass
+func (a *closedAnalyzer) Run(pass *analysis.Pass) (interface{}, error) {
+ // pssa, ok := pass.ResultOf[buildssa.Analyzer].(*buildssa.SSA)
+ // if !ok {
+ // return nil, nil
+ // }
+
+ return nil, nil
+}
diff --git a/vendor/github.com/ryanrolds/sqlclosecheck/pkg/analyzer/configurable.go b/vendor/github.com/ryanrolds/sqlclosecheck/pkg/analyzer/configurable.go
new file mode 100644
index 000000000..d7e96ff12
--- /dev/null
+++ b/vendor/github.com/ryanrolds/sqlclosecheck/pkg/analyzer/configurable.go
@@ -0,0 +1,40 @@
+package analyzer
+
+import (
+ "flag"
+ "fmt"
+
+ "golang.org/x/tools/go/analysis"
+)
+
+type ConfigurableModeType string
+
+const (
+ ConfigurableAnalyzerDeferOnly ConfigurableModeType = "defer-only"
+ ConfigurableAnalyzerClosed ConfigurableModeType = "closed"
+)
+
+type ConifgurableAnalyzer struct {
+ Mode string
+}
+
+func NewConfigurableAnalyzer(mode ConfigurableModeType) *analysis.Analyzer {
+ cfgAnalyzer := &ConifgurableAnalyzer{}
+ flags := flag.NewFlagSet("cfgAnalyzer", flag.ExitOnError)
+ flags.StringVar(&cfgAnalyzer.Mode, "mode", string(mode),
+ "Mode to run the analyzer in. (defer-only, closed)")
+ return newAnalyzer(cfgAnalyzer.run, flags)
+}
+
+func (c *ConifgurableAnalyzer) run(pass *analysis.Pass) (interface{}, error) {
+ switch c.Mode {
+ case string(ConfigurableAnalyzerDeferOnly):
+ analyzer := &deferOnlyAnalyzer{}
+ return analyzer.Run(pass)
+ case string(ConfigurableAnalyzerClosed):
+ analyzer := &closedAnalyzer{}
+ return analyzer.Run(pass)
+ default:
+ return nil, fmt.Errorf("invalid mode: %s", c.Mode)
+ }
+}
diff --git a/vendor/github.com/ryanrolds/sqlclosecheck/pkg/analyzer/defer_only.go b/vendor/github.com/ryanrolds/sqlclosecheck/pkg/analyzer/defer_only.go
new file mode 100644
index 000000000..701c7c6f6
--- /dev/null
+++ b/vendor/github.com/ryanrolds/sqlclosecheck/pkg/analyzer/defer_only.go
@@ -0,0 +1,441 @@
+package analyzer
+
+import (
+ "flag"
+ "go/types"
+
+ "golang.org/x/tools/go/analysis"
+ "golang.org/x/tools/go/analysis/passes/buildssa"
+ "golang.org/x/tools/go/ssa"
+)
+
+const (
+ rowsName = "Rows"
+ stmtName = "Stmt"
+ namedStmtName = "NamedStmt"
+ closeMethod = "Close"
+)
+
+type action uint8
+
+const (
+ actionUnhandled action = iota
+ actionHandled
+ actionReturned
+ actionPassed
+ actionClosed
+ actionUnvaluedCall
+ actionUnvaluedDefer
+ actionNoOp
+)
+
+var (
+ sqlPackages = []string{
+ "database/sql",
+ "github.com/jmoiron/sqlx",
+ "github.com/jackc/pgx/v5",
+ "github.com/jackc/pgx/v5/pgxpool",
+ }
+)
+
+type deferOnlyAnalyzer struct{}
+
+func NewDeferOnlyAnalyzer() *analysis.Analyzer {
+ analyzer := &deferOnlyAnalyzer{}
+ flags := flag.NewFlagSet("deferOnlyAnalyzer", flag.ExitOnError)
+ return newAnalyzer(analyzer.Run, flags)
+}
+
+// Run implements the main analysis pass
+func (a *deferOnlyAnalyzer) Run(pass *analysis.Pass) (interface{}, error) {
+ pssa, ok := pass.ResultOf[buildssa.Analyzer].(*buildssa.SSA)
+ if !ok {
+ return nil, nil
+ }
+
+ // Build list of types we are looking for
+ targetTypes := getTargetTypes(pssa, sqlPackages)
+
+ // If non of the types are found, skip
+ if len(targetTypes) == 0 {
+ return nil, nil
+ }
+
+ funcs := pssa.SrcFuncs
+ for _, f := range funcs {
+ for _, b := range f.Blocks {
+ for i := range b.Instrs {
+ // Check if instruction is call that returns a target pointer type
+ targetValues := getTargetTypesValues(b, i, targetTypes)
+ if len(targetValues) == 0 {
+ continue
+ }
+
+ // For each found target check if they are closed and deferred
+ for _, targetValue := range targetValues {
+ refs := (*targetValue.value).Referrers()
+ isClosed := checkClosed(refs, targetTypes)
+ if !isClosed {
+ pass.Reportf((targetValue.instr).Pos(), "Rows/Stmt/NamedStmt was not closed")
+ }
+
+ checkDeferred(pass, refs, targetTypes, false)
+ }
+ }
+ }
+ }
+
+ return nil, nil
+}
+
+func getTargetTypes(pssa *buildssa.SSA, targetPackages []string) []any {
+ targets := []any{}
+
+ for _, sqlPkg := range targetPackages {
+ pkg := pssa.Pkg.Prog.ImportedPackage(sqlPkg)
+ if pkg == nil {
+ // the SQL package being checked isn't imported
+ continue
+ }
+
+ rowsPtrType := getTypePointerFromName(pkg, rowsName)
+ if rowsPtrType != nil {
+ targets = append(targets, rowsPtrType)
+ }
+
+ rowsType := getTypeFromName(pkg, rowsName)
+ if rowsType != nil {
+ targets = append(targets, rowsType)
+ }
+
+ stmtType := getTypePointerFromName(pkg, stmtName)
+ if stmtType != nil {
+ targets = append(targets, stmtType)
+ }
+
+ namedStmtType := getTypePointerFromName(pkg, namedStmtName)
+ if namedStmtType != nil {
+ targets = append(targets, namedStmtType)
+ }
+ }
+
+ return targets
+}
+
+func getTypePointerFromName(pkg *ssa.Package, name string) *types.Pointer {
+ pkgType := pkg.Type(name)
+ if pkgType == nil {
+ // this package does not use Rows/Stmt/NamedStmt
+ return nil
+ }
+
+ obj := pkgType.Object()
+ named, ok := obj.Type().(*types.Named)
+ if !ok {
+ return nil
+ }
+
+ return types.NewPointer(named)
+}
+
+func getTypeFromName(pkg *ssa.Package, name string) *types.Named {
+ pkgType := pkg.Type(name)
+ if pkgType == nil {
+ // this package does not use Rows/Stmt
+ return nil
+ }
+
+ obj := pkgType.Object()
+ named, ok := obj.Type().(*types.Named)
+ if !ok {
+ return nil
+ }
+
+ return named
+}
+
+type targetValue struct {
+ value *ssa.Value
+ instr ssa.Instruction
+}
+
+func getTargetTypesValues(b *ssa.BasicBlock, i int, targetTypes []any) []targetValue {
+ targetValues := []targetValue{}
+
+ instr := b.Instrs[i]
+ call, ok := instr.(*ssa.Call)
+ if !ok {
+ return targetValues
+ }
+
+ signature := call.Call.Signature()
+ results := signature.Results()
+ for i := 0; i < results.Len(); i++ {
+ v := results.At(i)
+ varType := v.Type()
+
+ for _, targetType := range targetTypes {
+ var tt types.Type
+
+ switch t := targetType.(type) {
+ case *types.Pointer:
+ tt = t
+ case *types.Named:
+ tt = t
+ default:
+ continue
+ }
+
+ if !types.Identical(varType, tt) {
+ continue
+ }
+
+ for _, cRef := range *call.Referrers() {
+ switch instr := cRef.(type) {
+ case *ssa.Call:
+ if len(instr.Call.Args) >= 1 && types.Identical(instr.Call.Args[0].Type(), tt) {
+ targetValues = append(targetValues, targetValue{
+ value: &instr.Call.Args[0],
+ instr: call,
+ })
+ }
+ case ssa.Value:
+ if types.Identical(instr.Type(), tt) {
+ targetValues = append(targetValues, targetValue{
+ value: &instr,
+ instr: call,
+ })
+ }
+ }
+ }
+ }
+ }
+
+ return targetValues
+}
+
+func checkClosed(refs *[]ssa.Instruction, targetTypes []any) bool {
+ numInstrs := len(*refs)
+ for idx, ref := range *refs {
+ action := getAction(ref, targetTypes)
+ switch action {
+ case actionClosed, actionReturned, actionHandled:
+ return true
+ case actionPassed:
+ // Passed and not used after
+ if numInstrs == idx+1 {
+ return true
+ }
+ }
+ }
+
+ return false
+}
+
+func getAction(instr ssa.Instruction, targetTypes []any) action {
+ switch instr := instr.(type) {
+ case *ssa.Defer:
+ if instr.Call.Value != nil {
+ name := instr.Call.Value.Name()
+ if name == closeMethod {
+ return actionClosed
+ }
+ }
+
+ if instr.Call.Method != nil {
+ name := instr.Call.Method.Name()
+ if name == closeMethod {
+ return actionClosed
+ }
+ } else if instr.Call.Value != nil {
+ // If it is a deferred function, go further down the call chain
+ if f, ok := instr.Call.Value.(*ssa.Function); ok {
+ for _, b := range f.Blocks {
+ if checkClosed(&b.Instrs, targetTypes) {
+ return actionHandled
+ }
+ }
+ }
+ }
+
+ return actionUnvaluedDefer
+ case *ssa.Call:
+ if instr.Call.Value == nil {
+ return actionUnvaluedCall
+ }
+
+ isTarget := false
+ staticCallee := instr.Call.StaticCallee()
+ if staticCallee != nil {
+ receiver := instr.Call.StaticCallee().Signature.Recv()
+ if receiver != nil {
+ isTarget = isTargetType(receiver.Type(), targetTypes)
+ }
+ }
+
+ name := instr.Call.Value.Name()
+ if isTarget && name == closeMethod {
+ return actionClosed
+ }
+
+ if !isTarget {
+ return actionPassed
+ }
+ case *ssa.Phi:
+ return actionPassed
+ case *ssa.MakeInterface:
+ return actionPassed
+ case *ssa.Store:
+ // A Row/Stmt is stored in a struct, which may be closed later
+ // by a different flow.
+ if _, ok := instr.Addr.(*ssa.FieldAddr); ok {
+ return actionReturned
+ }
+
+ if instr.Addr.Referrers() == nil {
+ return actionNoOp
+ }
+
+ if len(*instr.Addr.Referrers()) == 0 {
+ return actionNoOp
+ }
+
+ for _, aRef := range *instr.Addr.Referrers() {
+ if c, ok := aRef.(*ssa.MakeClosure); ok {
+ if f, ok := c.Fn.(*ssa.Function); ok {
+ for _, b := range f.Blocks {
+ if checkClosed(&b.Instrs, targetTypes) {
+ return actionHandled
+ }
+ }
+ }
+ }
+ }
+ case *ssa.UnOp:
+ instrType := instr.Type()
+ for _, targetType := range targetTypes {
+ var tt types.Type
+
+ switch t := targetType.(type) {
+ case *types.Pointer:
+ tt = t
+ case *types.Named:
+ tt = t
+ default:
+ continue
+ }
+
+ if types.Identical(instrType, tt) {
+ if checkClosed(instr.Referrers(), targetTypes) {
+ return actionHandled
+ }
+ }
+ }
+ case *ssa.FieldAddr:
+ if checkClosed(instr.Referrers(), targetTypes) {
+ return actionHandled
+ }
+ case *ssa.Return:
+ if len(instr.Results) != 0 {
+ for _, result := range instr.Results {
+ resultType := result.Type()
+ for _, targetType := range targetTypes {
+ var tt types.Type
+
+ switch t := targetType.(type) {
+ case *types.Pointer:
+ tt = t
+ case *types.Named:
+ tt = t
+ default:
+ continue
+ }
+
+ if types.Identical(resultType, tt) {
+ return actionReturned
+ }
+ }
+ }
+ }
+ }
+
+ return actionUnhandled
+}
+
+func checkDeferred(pass *analysis.Pass, instrs *[]ssa.Instruction, targetTypes []any, inDefer bool) {
+ for _, instr := range *instrs {
+ switch instr := instr.(type) {
+ case *ssa.Defer:
+ if instr.Call.Value != nil && instr.Call.Value.Name() == closeMethod {
+ return
+ }
+
+ if instr.Call.Method != nil && instr.Call.Method.Name() == closeMethod {
+ return
+ }
+ case *ssa.Call:
+ if instr.Call.Value != nil && instr.Call.Value.Name() == closeMethod {
+ if !inDefer {
+ pass.Reportf(instr.Pos(), "Close should use defer")
+ }
+
+ return
+ }
+ case *ssa.Store:
+ if instr.Addr.Referrers() == nil {
+ return
+ }
+
+ if len(*instr.Addr.Referrers()) == 0 {
+ return
+ }
+
+ for _, aRef := range *instr.Addr.Referrers() {
+ if c, ok := aRef.(*ssa.MakeClosure); ok {
+ if f, ok := c.Fn.(*ssa.Function); ok {
+ for _, b := range f.Blocks {
+ checkDeferred(pass, &b.Instrs, targetTypes, true)
+ }
+ }
+ }
+ }
+ case *ssa.UnOp:
+ instrType := instr.Type()
+ for _, targetType := range targetTypes {
+ var tt types.Type
+
+ switch t := targetType.(type) {
+ case *types.Pointer:
+ tt = t
+ case *types.Named:
+ tt = t
+ default:
+ continue
+ }
+
+ if types.Identical(instrType, tt) {
+ checkDeferred(pass, instr.Referrers(), targetTypes, inDefer)
+ }
+ }
+ case *ssa.FieldAddr:
+ checkDeferred(pass, instr.Referrers(), targetTypes, inDefer)
+ }
+ }
+}
+
+func isTargetType(t types.Type, targetTypes []any) bool {
+ for _, targetType := range targetTypes {
+ switch tt := targetType.(type) {
+ case *types.Pointer:
+ if types.Identical(t, tt) {
+ return true
+ }
+ case *types.Named:
+ if types.Identical(t, tt) {
+ return true
+ }
+ }
+ }
+
+ return false
+}
diff --git a/vendor/github.com/securego/gosec/v2/.gitignore b/vendor/github.com/securego/gosec/v2/.gitignore
index 45460260f..d9f5c1fc9 100644
--- a/vendor/github.com/securego/gosec/v2/.gitignore
+++ b/vendor/github.com/securego/gosec/v2/.gitignore
@@ -7,6 +7,7 @@
*.so
*.swp
/gosec
+/gosec-debug
# Folders
_obj
@@ -25,6 +26,7 @@ _cgo_gotypes.go
_cgo_export.*
_testmain.go
+coverage.out
*.exe
*.test
diff --git a/vendor/github.com/securego/gosec/v2/.goreleaser.yml b/vendor/github.com/securego/gosec/v2/.goreleaser.yml
index 7ef0d7a3d..d242e880c 100644
--- a/vendor/github.com/securego/gosec/v2/.goreleaser.yml
+++ b/vendor/github.com/securego/gosec/v2/.goreleaser.yml
@@ -27,12 +27,12 @@ builds:
signs:
- cmd: cosign
+ signature: "${artifact}.sigstore.json"
stdin: '{{ .Env.COSIGN_PASSWORD}}'
args:
- "sign-blob"
- "--key=/tmp/cosign.key"
- - "--output=${signature}"
+ - "--bundle=${signature}"
- "${artifact}"
- "--yes"
artifacts: all
-
diff --git a/vendor/github.com/securego/gosec/v2/CLAUDE.md b/vendor/github.com/securego/gosec/v2/CLAUDE.md
new file mode 100644
index 000000000..f3e0b72d2
--- /dev/null
+++ b/vendor/github.com/securego/gosec/v2/CLAUDE.md
@@ -0,0 +1,51 @@
+# gosec - Go Security Checker
+
+gosec is a Go static analysis tool that inspects Go source code for security vulnerabilities by scanning the Go AST and SSA form.
+
+## Build & Test
+
+```bash
+# Build
+go build ./cmd/gosec/
+
+# Run all tests
+go test ./...
+
+# Run a specific test
+go test -run TestName ./path/to/package/
+
+# Lint
+golangci-lint run
+
+# Run gosec against a sample file
+go run ./cmd/gosec/ ./path/to/sample.go
+```
+
+## Code Style
+
+- Idiomatic Go; follow existing patterns in the codebase.
+- Prefer SSA-based analyzers over AST-based rules when feasible.
+- Optimize for performance — avoid unnecessary repeated AST or SSA traversals.
+
+## Project Structure
+
+- `rules/` — AST-based rule implementations
+- `analyzers/` — SSA-based analyzer implementations
+- `cmd/gosec/` — CLI entry point
+- `testutils/` — sample files used in tests (positive and negative cases)
+- `issue/` — issue and CWE type definitions
+- `report/` — output formatters
+
+## Adding Rules
+
+- Select an appropriate CWE aligned with current repository mappings.
+- Integrate the rule in all required registration points.
+- Add sample files in `testutils/` with at least 2 positive and 2 negative cases.
+- Update rule documentation in `README.md` in the same style as other rules.
+
+## Custom Commands
+
+- `/create-gosec-rule` — Design and implement a new gosec rule from an issue description
+- `/fix-gosec-bug` — Investigate and fix a bug from a GitHub issue URL
+- `/update-go-versions` — Bump supported Go versions across the repo
+- `/update-action-version` — Update the gosec GHCR image version in action.yml
diff --git a/vendor/github.com/securego/gosec/v2/CONTRIBUTING.md b/vendor/github.com/securego/gosec/v2/CONTRIBUTING.md
deleted file mode 100644
index 32752ad59..000000000
--- a/vendor/github.com/securego/gosec/v2/CONTRIBUTING.md
+++ /dev/null
@@ -1,81 +0,0 @@
-# Contributing
-
-## Adding a new rule
-
-New rules can be implemented in two ways:
-
-- as a `gosec.Rule` -- these define an arbitrary function which will be called on every AST node in the analyzed file, and are appropriate for rules that mostly need to reason about a single statement.
-- as an Analyzer -- these can operate on the entire program, and receive an [SSA](https://pkg.go.dev/golang.org/x/tools/go/ssa) representation of the package. This type of rule is useful when you need to perform a more complex analysis that requires a great deal of context.
-
-### Adding a gosec.Rule
-
-1. Copy an existing rule file as a starting point-- `./rules/unsafe.go` is a good option, as it implements a very simple rule with no additional supporting logic. Put the copied file in the `./rules/` directory.
-2. Change the name of the rule constructor function and of the types in the rule file you've copied so they will be unique.
-3. Edit the `Generate` function in `./rules/rulelist.go` to include your rule.
-4. Add a RuleID to CWE ID mapping for your rule to the `ruleToCWE` map in `./issue/issue.go`. If you need a CWE that isn't already defined in `./cwe/data.go`, add it to the `idWeaknessess` map in that file.
-5. Use `make` to compile `gosec`. The binary will now contain your rule.
-
-To make your rule actually useful, you will likely want to use the support functions defined in `./resolve.go`, `./helpers.go` and `./call_list.go`. There are inline comments explaining the purpose of most of these functions, and you can find usage examples in the existing rule files.
-
-### Adding an Analyzer
-
-1. Create a new go file under `./analyzers/` with the following scaffolding in it:
-
-```go
-package analyzers
-
-import (
- "fmt"
-
- "golang.org/x/tools/go/analysis"
- "golang.org/x/tools/go/analysis/passes/buildssa"
- "github.com/securego/gosec/v2/issue"
-)
-
-const defaultIssueDescriptionMyAnalyzer = "My new analyzer!"
-
-func newMyAnalyzer(id string, description string) *analysis.Analyzer {
- return &analysis.Analyzer{
- Name: id,
- Doc: description,
- Run: runMyAnalyzer,
- Requires: []*analysis.Analyzer{buildssa.Analyzer},
- }
-}
-
-func runMyAnalyzer(pass *analysis.Pass) (interface{}, error) {
- ssaResult, err := getSSAResult(pass)
- if err != nil {
- return nil, fmt.Errorf("building ssa representation: %w", err)
- }
- var issues []*issue.Issue
- fmt.Printf("My Analyzer ran! %+v\n", ssaResult)
-
- return issues, nil
-}
-```
-
-2. Add the analyzer to `./analyzers/analyzerslist.go` in the `defaultAnalyzers` variable under an entry like `{"G999", "My test analyzer", newMyAnalyzer}`
-3. Add a RuleID to CWE ID mapping for your rule to the `ruleToCWE` map in `./issue/issue.go`. If you need a CWE that isn't already defined in `./cwe/data.go`, add it to the `idWeaknessess` map in that file.
-4. `make`; then run the `gosec` binary produced. You should see the output from our print statement.
-5. You now have a working example analyzer to play with-- look at the other implemented analyzers for ideas on how to make useful rules.
-
-## Developing your rule
-
-There are some utility tools which are useful for analyzing the SSA and AST representation `gosec` works with before writing rules or analyzers.
-
-For instance to dump the SSA, the [ssadump](https://pkg.go.dev/golang.org/x/tools/cmd/ssadump) tool can be used as following:
-
-```bash
-ssadump -build F main.go
-```
-
-Consult the documentation for ssadump for an overview of available output flags and options.
-
-For outputting the AST and supporting information, there is a utility tool in which can be compiled and used as standalone.
-
-```bash
-gosecutil -tool ast main.go
-```
-
-Valid tool arguments for this command are `ast`, `callobj`, `uses`, `types`, `defs`, `comments`, and `imports`.
diff --git a/vendor/github.com/securego/gosec/v2/DEVELOPMENT.md b/vendor/github.com/securego/gosec/v2/DEVELOPMENT.md
new file mode 100644
index 000000000..5a8a0e3cc
--- /dev/null
+++ b/vendor/github.com/securego/gosec/v2/DEVELOPMENT.md
@@ -0,0 +1,435 @@
+# Development
+
+## Table of Contents
+
+- [Local workflow](#local-workflow)
+- [Contributing: adding rules and analyzers](#contributing-adding-rules-and-analyzers)
+ - [Add an AST rule](#add-an-ast-rule)
+ - [Add an SSA analyzer](#add-an-ssa-analyzer)
+ - [Creating taint analysis rules](#creating-taint-analysis-rules)
+ - [Steps](#steps)
+ - [Taint configuration reference](#taint-configuration-reference)
+ - [Sources](#sources)
+ - [Sinks](#sinks)
+ - [Sanitizers](#sanitizers)
+ - [Common taint sources](#common-taint-sources)
+- [AI-generated rule workflow (Copilot)](#ai-generated-rule-workflow-copilot)
+- [AI-generated bug fix workflow (Copilot)](#ai-generated-bug-fix-workflow-copilot)
+- [AI-supported Go version update workflow (Copilot)](#ai-supported-go-version-update-workflow-copilot)
+- [Rule development utilities](#rule-development-utilities)
+- [SARIF types generation](#sarif-types-generation)
+- [Performance regression guard](#performance-regression-guard)
+- [Generate TLS rule data](#generate-tls-rule-data)
+- [Release](#release)
+- [Docker image](#docker-image)
+
+## Local workflow
+
+- Go version: `1.25+` (see `go.mod`)
+- Build: `make`
+- Run all checks used in CI (format, vet, security scan, vulnerability scan, tests): `make test`
+- Run linter only: `make golangci`
+
+## Contributing: adding rules and analyzers
+
+gosec supports three implementation styles:
+
+- **AST rules** (`gosec.Rule`) for node-level checks in `rules/`
+- **SSA analyzers** (`analysis.Analyzer`) for whole-program context in `analyzers/`
+- **Taint analyzers** for source-to-sink data-flow checks in `analyzers/` via `taint.NewGosecAnalyzer`
+
+### Add an AST rule
+
+1. Create a new file in `rules/` (for example, use `rules/unsafe.go` as a simple template).
+2. Implement your rule constructor and `Match` logic.
+3. Register the rule in `rules/rulelist.go`.
+4. Add rule-to-CWE mapping in `issue/issue.go` (and add CWE data in `cwe/data.go` only if needed).
+5. Add tests and samples:
+ - sample code in `testutils/`
+ - rule tests in `rules/` or integration tests in `analyzer_test.go`
+
+### Add an SSA analyzer
+
+1. Create a new file in `analyzers/`.
+2. Define the analyzer and require `buildssa.Analyzer`.
+3. Read SSA input using `ssautil.GetSSAResult(pass)`.
+4. Return findings as `[]*issue.Issue`.
+5. Register in `analyzers/analyzerslist.go`.
+6. Add rule-to-CWE mapping in `issue/issue.go`.
+7. Add tests and sample code in `analyzers/` and `testutils/`.
+
+Minimal skeleton:
+
+```go
+package analyzers
+
+import (
+ "fmt"
+
+ "golang.org/x/tools/go/analysis"
+ "golang.org/x/tools/go/analysis/passes/buildssa"
+
+ "github.com/securego/gosec/v2/internal/ssautil"
+ "github.com/securego/gosec/v2/issue"
+)
+
+func newMyAnalyzer(id, description string) *analysis.Analyzer {
+ return &analysis.Analyzer{
+ Name: id,
+ Doc: description,
+ Run: runMyAnalyzer,
+ Requires: []*analysis.Analyzer{buildssa.Analyzer},
+ }
+}
+
+func runMyAnalyzer(pass *analysis.Pass) (interface{}, error) {
+ ssaResult, err := ssautil.GetSSAResult(pass)
+ if err != nil {
+ return nil, fmt.Errorf("getting SSA result: %w", err)
+ }
+ _ = ssaResult
+
+ var issues []*issue.Issue
+ return issues, nil
+}
+```
+
+### Creating taint analysis rules
+
+gosec taint analyzers track data flow from untrusted sources to dangerous sinks.
+Current taint rules include SQL injection, command injection, path traversal, SSRF, XSS, log injection, SMTP injection, server-side template injection, unsafe deserialization, and open redirect.
+
+#### Steps
+
+1. Create a new analyzer file in `analyzers/` (for example `analyzers/newvuln.go`) with both:
+ - the taint `Config` (sources, sinks, optional sanitizers)
+ - the analyzer constructor that returns `taint.NewGosecAnalyzer(...)`
+
+```go
+package analyzers
+
+import (
+ "golang.org/x/tools/go/analysis"
+
+ "github.com/securego/gosec/v2/taint"
+)
+
+func NewVulnerability() taint.Config {
+ return taint.Config{
+ Sources: []taint.Source{
+ {Package: "net/http", Name: "Request", Pointer: true},
+ {Package: "os", Name: "Args", IsFunc: true},
+ },
+ Sinks: []taint.Sink{
+ {Package: "dangerous/package", Method: "DangerousFunc"},
+ },
+ }
+}
+
+func newNewVulnAnalyzer(id string, description string) *analysis.Analyzer {
+ config := NewVulnerability()
+ rule := NewVulnerabilityRule
+ rule.ID = id
+ rule.Description = description
+ return taint.NewGosecAnalyzer(&rule, &config)
+}
+```
+
+2. Register the analyzer in `analyzers/analyzerslist.go`:
+
+```go
+var defaultAnalyzers = []AnalyzerDefinition{
+ // ... existing analyzers ...
+ {"G7XX", "Description of vulnerability", newNewVulnAnalyzer},
+}
+```
+
+3. Add sample programs in `testutils/g7xx_samples.go`.
+
+4. Add the analyzer test in `analyzers/analyzers_test.go`:
+
+```go
+It("should detect your new vulnerability", func() {
+ runner("G7XX", testutils.SampleCodeG7XX)
+})
+```
+
+Each taint analyzer keeps its configuration function in the same file as the analyzer.
+Reference implementations:
+- `analyzers/sqlinjection.go` (G701)
+- `analyzers/commandinjection.go` (G702)
+- `analyzers/pathtraversal.go` (G703)
+
+#### Taint configuration reference
+
+##### Sources
+
+Sources define where untrusted data starts:
+- `Package`: import path (for example `"net/http"`)
+- `Name`: type or function name (for example `"Request"`, `"Getenv"`)
+- `Pointer`: set `true` for pointer types (for example `*http.Request`)
+- `IsFunc`: set `true` when the source is a function that returns tainted data
+
+##### Sinks
+
+Sinks define where tainted data must not reach:
+- `Package`
+- `Receiver`: method receiver type, empty for package functions
+- `Method`
+- `Pointer`: whether receiver is a pointer
+- `CheckArgs`: optional argument indexes to inspect; if omitted, all args are inspected
+
+Example:
+
+```go
+// For *sql.DB.Query, Args[1] is the query string.
+{Package: "database/sql", Receiver: "DB", Method: "Query", Pointer: true, CheckArgs: []int{1}}
+
+// Skip writer arg in fmt.Fprintf and check the rest.
+{Package: "fmt", Method: "Fprintf", CheckArgs: []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}}
+```
+
+##### Sanitizers
+
+Sanitizers break taint flow after validation/escaping:
+- `Package`
+- `Receiver`
+- `Method`
+- `Pointer`
+
+If data passes through a configured sanitizer, it is treated as safe for subsequent sinks.
+
+#### Common taint sources
+
+| Source Type | Package | Type/Method | Pointer | IsFunc |
+|-------------|---------|-------------|---------|--------|
+| HTTP Request | `net/http` | `Request` | `true` | `false` |
+| Command Line Args | `os` | `Args` | `false` | `true` |
+| Environment Variables | `os` | `Getenv` | `false` | `true` |
+| File Content | `bufio` | `Reader` | `true` | `false` |
+
+## AI-generated rule workflow (Copilot)
+
+This repository includes a reusable Copilot skill and prompt for creating new gosec rules from an issue description.
+
+- Skill file: `.github/skills/gosec-new-rule/SKILL.md`
+- Prompt file: `.github/prompts/create-gosec-rule.prompt.md`
+
+### Use via `/prompt` (recommended)
+
+1. In VS Code Copilot Chat, run `/prompt` and select **Create Gosec Rule**.
+2. Fill in the issue fields (`Summary`, repro steps, versions, environment, expected, actual).
+3. Submit the prompt.
+4. First response should only propose:
+ - rule ID
+ - implementation approach (SSA / taint / AST)
+ - relevance for Go `1.25` and `1.26`
+ - confirmation request
+5. Reply with explicit confirmation (for example: `Confirmed. Proceed with implementation.`).
+
+### Use the skill directly (without `/prompt`)
+
+Send this in Copilot Chat:
+
+```text
+Use the skill "Create New Gosec Rule" from .github/skills/gosec-new-rule/SKILL.md.
+```
+
+Then paste the same issue template fields and confirm after the proposal step.
+
+### If `/prompt` does not list the prompt
+
+1. Ensure the workspace root is this repository.
+2. Confirm the file exists at `.github/prompts/create-gosec-rule.prompt.md`.
+3. Reload VS Code window and start a new chat session.
+4. As fallback, open the prompt file and send its content directly in chat.
+
+## AI-generated bug fix workflow (Copilot)
+
+This repository also includes a Copilot skill and prompt for fixing bugs described in GitHub issues.
+
+- Skill file: `.github/skills/gosec-fix-issue/SKILL.md`
+- Prompt file: `.github/prompts/fix-gosec-bug-from-issue.prompt.md`
+
+### Use via `/prompt` (recommended)
+
+1. In VS Code Copilot Chat, run `/prompt` and select **Fix Gosec Bug From Issue**.
+2. Fill in at least the `GitHub issue URL` field (other fields are optional but useful).
+3. Submit the prompt.
+4. First response should only include:
+ - reproduction status on `master` (or clear blocker)
+ - root cause analysis
+ - detailed fix plan
+ - confirmation request
+5. Reply with explicit confirmation (for example: `Confirmed. Proceed with fix.`).
+
+### Use the skill directly (without `/prompt`)
+
+Send this in Copilot Chat:
+
+```text
+Use the skill "Fix Gosec Bug From Issue" from .github/skills/gosec-fix-issue/SKILL.md.
+```
+
+Then provide the GitHub issue URL and confirm after the analysis and plan step.
+
+### Expected implementation guardrails
+
+After confirmation, the workflow should:
+
+- keep the fix small and isolated to the problem
+- use idiomatic Go and good design
+- add positive and negative tests
+- add or update `testutils/` code samples when appropriate for reproducing/validating the issue
+- validate with build, tests, `golangci-lint`, and a `gosec` CLI run against a sample
+
+## AI-supported Go version update workflow (Copilot)
+
+This repository includes a Copilot skill and prompt to update supported Go versions to the latest patch versions of the two newest major Go series.
+
+- Skill file: `.github/skills/gosec-update-go-versions/SKILL.md`
+- Prompt file: `.github/prompts/update-supported-go-versions.prompt.md`
+
+### Use via `/prompt` (recommended)
+
+1. In VS Code Copilot Chat, run `/prompt` and select **Update Supported Go Versions**.
+2. Submit the prompt (no additional fields required).
+3. The workflow should:
+ - read `https://go.dev/doc/devel/release`
+ - detect latest two supported Go series and latest patch for each
+ - update all active repository locations where supported Go versions are configured or documented
+ - run validation checks
+ - create branch, commit, push, and open a PR
+
+### Use the skill directly (without `/prompt`)
+
+Send this in Copilot Chat:
+
+```text
+Use the skill "Update Supported Go Versions" from .github/skills/gosec-update-go-versions/SKILL.md.
+```
+
+### Expected outputs
+
+The result should include:
+
+- detected versions (`previous_patch`, `latest_patch`, `previous_minor`, `latest_minor`)
+- grouped file update summary
+- test command result
+- branch, commit SHA, PR title, and PR URL
+
+## Rule development utilities
+
+Use these tools while building or debugging rules:
+
+- Dump SSA with [`ssadump`](https://pkg.go.dev/golang.org/x/tools/cmd/ssadump):
+
+```bash
+ssadump -build F main.go
+```
+
+- Inspect AST/types/defs/imports with `gosecutil`:
+
+```bash
+gosecutil -tool ast main.go
+```
+
+Valid `-tool` values: `ast`, `callobj`, `uses`, `types`, `defs`, `comments`, `imports`.
+
+
+## SARIF types generation
+
+Install `schema-generate`:
+
+```bash
+go install github.com/a-h/generate/cmd/schema-generate@latest
+```
+
+Generate types:
+
+```bash
+schema-generate -i sarif-schema-2.1.0.json -o path/to/types.go
+```
+
+Most `MarshalJSON`/`UnmarshalJSON` helpers can be removed after generation, except `PropertyBag` where inlined additional properties are useful.
+
+## Performance regression guard
+
+CI includes a taint benchmark guard based on `BenchmarkTaintPackageAnalyzers_SharedCache`.
+
+- Baseline and thresholds: `.github/benchmarks/taint_benchmark_baseline.env`
+- Guard script: `tools/check_taint_benchmark.sh`
+
+Run locally:
+
+```bash
+bash tools/check_taint_benchmark.sh
+```
+
+Update baseline after intentional changes:
+
+```bash
+BENCH_COUNT=10 bash tools/check_taint_benchmark.sh --update-baseline
+```
+
+If you update the baseline, commit both the benchmark-related code and the baseline file.
+
+## Generate TLS rule data
+
+The TLS rule data is generated from Mozilla recommendations.
+
+From the repository root:
+
+```bash
+go generate ./...
+```
+
+If `go generate` fails with `exec: "tlsconfig": executable file not found in $PATH`, install the local generator and add `$(go env GOPATH)/bin` to `PATH`:
+
+```bash
+export PATH="$(go env GOPATH)/bin:$PATH"
+go install ./cmd/tlsconfig
+go generate ./...
+```
+
+This updates `rules/tls_config.go`.
+
+If you need to install the generator binary outside this repository:
+
+```bash
+go install github.com/securego/gosec/v2/cmd/tlsconfig@latest
+```
+
+## Release
+
+Tag and push:
+
+```bash
+git tag v1.0.0 -m "Release version v1.0.0"
+git push origin v1.0.0
+```
+
+The release workflow builds binaries and Docker images, then signs artifacts.
+
+Verify signatures:
+
+```bash
+cosign verify --key cosign.pub ghcr.io/securego/gosec:
+cosign verify-blob --key cosign.pub --signature gosec__darwin_amd64.tar.gz.sig gosec__darwin_amd64.tar.gz
+```
+
+## Docker image
+
+Build locally:
+
+```bash
+make image
+```
+
+Run against a local project:
+
+```bash
+docker run --rm -it -w // -v /:/ ghcr.io/securego/gosec:latest //...
+```
+
+Set `-w` so module dependencies resolve from the mounted project root.
\ No newline at end of file
diff --git a/vendor/github.com/securego/gosec/v2/Makefile b/vendor/github.com/securego/gosec/v2/Makefile
index d9880bbf4..f91529ca6 100644
--- a/vendor/github.com/securego/gosec/v2/Makefile
+++ b/vendor/github.com/securego/gosec/v2/Makefile
@@ -16,7 +16,7 @@ GOBIN ?= $(GOPATH)/bin
GOSEC ?= $(GOBIN)/gosec
GO_MINOR_VERSION = $(shell $(GO) version | cut -c 14- | cut -d' ' -f1 | cut -d'.' -f2)
GOVULN_MIN_VERSION = 17
-GO_VERSION = 1.25
+GO_VERSION = 1.26
LDFLAGS = -ldflags "\
-X 'main.Version=$(shell git describe --tags --always)' \
-X 'main.GitTag=$(shell git describe --tags --abbrev=0)' \
@@ -33,6 +33,9 @@ install-govulncheck:
test: build-race fmt vet sec govulncheck
go run github.com/onsi/ginkgo/v2/ginkgo -- --ginkgo.v --ginkgo.fail-fast
+test-nocache: build-race fmt vet sec govulncheck
+ go test -count=1 -v ./...
+
fmt:
@echo "FORMATTING"
@FORMATTED=`$(GO) fmt ./...`
@@ -48,7 +51,7 @@ golangci:
sec:
@echo "SECURITY SCANNING"
- ./$(BIN) ./...
+ ./$(BIN) -exclude-dir=testdata ./...
govulncheck: install-govulncheck
@echo "CHECKING VULNERABILITIES"
@@ -57,7 +60,7 @@ govulncheck: install-govulncheck
fi
test-coverage:
- go test -race -v -count=1 -coverprofile=coverage.out ./...
+ go test -race -v -count=1 -coverpkg=./... -coverprofile=coverage.out ./...
build:
go build $(LDFLAGS) -o $(BIN) ./cmd/gosec/
@@ -65,9 +68,15 @@ build:
build-race:
go build -race $(LDFLAGS) -o $(BIN) ./cmd/gosec/
+build-debug:
+ go build -tags debug $(LDFLAGS) -o $(BIN)-debug ./cmd/gosec/
+
+build-debug-race:
+ go build -race -tags debug $(LDFLAGS) -o $(BIN)-debug ./cmd/gosec/
+
clean:
rm -rf build vendor dist coverage.out
- rm -f release image $(BIN)
+ rm -f release image $(BIN) $(BIN)-debug
release:
@echo "Releasing the gosec binary..."
@@ -93,4 +102,4 @@ tlsconfig:
perf-diff:
./perf-diff.sh
-.PHONY: test build clean release image image-push tlsconfig perf-diff
+.PHONY: test test-nocache build clean release image image-push tlsconfig perf-diff
diff --git a/vendor/github.com/securego/gosec/v2/README.md b/vendor/github.com/securego/gosec/v2/README.md
index 355d4375b..283d8533b 100644
--- a/vendor/github.com/securego/gosec/v2/README.md
+++ b/vendor/github.com/securego/gosec/v2/README.md
@@ -1,15 +1,37 @@
# gosec - Go Security Checker
-Inspects source code for security problems by scanning the Go AST and SSA code representation.
+Inspects source code for security problems by scanning the Go AST
+and SSA code representation.
+## Quick links
+
+- [GitHub Action](#github-action)
+- [Local installation](#local-installation)
+- [Quick start](#quick-start)
+- [Common usage patterns](#common-usage-patterns)
+- [Selecting rules](#selecting-rules)
+- [Output formats](#output-formats)
+
+## Features
+
+- **Pattern-based rules** for detecting common security issues
+ in Go code
+- **SSA-based analyzers** for type conversions, slice bounds,
+ and crypto issues
+- **Taint analysis** for tracking data flow from user input to
+ dangerous functions (SQL injection, command injection, path
+ traversal, SSRF, XSS, log injection, SMTP injection, SSTI,
+ unsafe deserialization, open redirect)
+
## License
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 [here](http://www.apache.org/licenses/LICENSE-2.0).
+You may obtain a copy of the License
+[here](http://www.apache.org/licenses/LICENSE-2.0).
## Project status
@@ -20,38 +42,54 @@ You may obtain a copy of the License [here](http://www.apache.org/licenses/LICEN
[](https://pkg.go.dev/github.com/securego/gosec/v2)
[](https://securego.io/)
[](https://github.com/securego/gosec/releases)
-[](https://hub.docker.com/r/securego/gosec/tags)
+[](https://github.com/orgs/securego/packages/container/package/gosec)
[](http://securego.slack.com)
[](https://github.com/nikolaydubina/go-recipes)
-## Install
-
-### CI Installation
-
-```bash
-# binary will be $(go env GOPATH)/bin/gosec
-curl -sfL https://raw.githubusercontent.com/securego/gosec/master/install.sh | sh -s -- -b $(go env GOPATH)/bin vX.Y.Z
-
-# or install it into ./bin/
-curl -sfL https://raw.githubusercontent.com/securego/gosec/master/install.sh | sh -s vX.Y.Z
+## Installation
-# In alpine linux (as it does not come with curl by default)
-wget -O - -q https://raw.githubusercontent.com/securego/gosec/master/install.sh | sh -s vX.Y.Z
+### GitHub Action
-# If you want to use the checksums provided on the "Releases" page
-# then you will have to download a tar.gz file for your operating system instead of a binary file
-wget https://github.com/securego/gosec/releases/download/vX.Y.Z/gosec_vX.Y.Z_OS.tar.gz
+You can run `gosec` as a GitHub action as follows:
-# The file will be in the current folder where you run the command
-# and you can check the checksum like this
-echo " gosec_vX.Y.Z_OS.tar.gz" | sha256sum -c -
+Use the versioned tag with `@master` which is pinned to the
+latest stable release. This will provide a stable behavior.
-gosec --help
+```yaml
+name: Run Gosec
+on:
+ push:
+ branches:
+ - master
+ pull_request:
+ branches:
+ - master
+jobs:
+ tests:
+ runs-on: ubuntu-latest
+ env:
+ GO111MODULE: on
+ steps:
+ - name: Checkout Source
+ uses: actions/checkout@v3
+ - name: Run Gosec Security Scanner
+ uses: securego/gosec@master
+ with:
+ args: ./...
```
-### GitHub Action
+#### Scanning Projects with Private Modules
-You can run `gosec` as a GitHub action as follows:
+If your project imports private Go modules, you need to
+configure authentication so that `gosec` can fetch the
+dependencies. Set the following environment variables in
+your workflow:
+
+- `GOPRIVATE`: A comma-separated list of module path prefixes
+ that should be considered private
+ (e.g., `github.com/your-org/*`).
+- `GITHUB_AUTHENTICATION_TOKEN`: A GitHub token with read
+ access to your private repositories.
```yaml
name: Run Gosec
@@ -67,20 +105,26 @@ jobs:
runs-on: ubuntu-latest
env:
GO111MODULE: on
+ GOPRIVATE: github.com/your-org/*
+ GITHUB_AUTHENTICATION_TOKEN: ${{ secrets.PRIVATE_REPO_TOKEN }}
steps:
- name: Checkout Source
uses: actions/checkout@v3
- name: Run Gosec Security Scanner
- uses: securego/gosec@master
+ uses: securego/gosec@v2
with:
args: ./...
```
### Integrating with code scanning
-You can [integrate third-party code analysis tools](https://docs.github.com/en/github/finding-security-vulnerabilities-and-errors-in-your-code/integrating-with-code-scanning) with GitHub code scanning by uploading data as SARIF files.
+You can [integrate third-party code analysis tools](https://docs.github.com/en/github/finding-security-vulnerabilities-and-errors-in-your-code/integrating-with-code-scanning)
+with GitHub code scanning by uploading data as SARIF files.
-The workflow shows an example of running the `gosec` as a step in a GitHub action workflow which outputs the `results.sarif` file. The workflow then uploads the `results.sarif` file to GitHub using the `upload-sarif` action.
+The workflow shows an example of running the `gosec` as a step
+in a GitHub action workflow which outputs the `results.sarif`
+file. The workflow then uploads the `results.sarif` file to
+GitHub using the `upload-sarif` action.
```yaml
name: "Security Scan"
@@ -101,7 +145,7 @@ jobs:
- name: Checkout Source
uses: actions/checkout@v3
- name: Run Gosec Security Scanner
- uses: securego/gosec@master
+ uses: securego/gosec@v2
with:
# we let the report trigger content trigger a failure using the GitHub Security features.
args: '-no-fail -fmt sarif -out results.sarif ./...'
@@ -112,72 +156,97 @@ jobs:
sarif_file: results.sarif
```
+### Go Analysis
+
+The `goanalysis` package provides a
+[`golang.org/x/tools/go/analysis.Analyzer`](https://pkg.go.dev/golang.org/x/tools/go/analysis)
+for integration with tools that support the standard Go
+analysis interface, such as Bazel's
+[nogo](https://github.com/bazelbuild/rules_go/blob/master/go/nogo.rst)
+framework:
+
+```starlark
+nogo(
+ name = "nogo",
+ deps = [
+ "@com_github_securego_gosec_v2//goanalysis",
+ # add more analyzers as needed
+ ],
+ visibility = ["//visibility:public"],
+)
+```
+
### Local Installation
+gosec requires Go 1.25 or newer.
+
```bash
go install github.com/securego/gosec/v2/cmd/gosec@latest
```
+## Quick start
+
+```bash
+# Scan all packages in current module
+gosec ./...
+
+# Write JSON report
+gosec -fmt json -out results.json ./...
+
+# Write SARIF report for code scanning
+gosec -fmt sarif -out results.sarif ./...
+```
+
+### Exit codes
+
+- `0`: scan finished without unsuppressed findings/errors
+- `1`: at least one unsuppressed finding or processing error
+- Use `-no-fail` to always return `0`
+
## Usage
-Gosec can be configured to only run a subset of rules, to exclude certain file
-paths, and produce reports in different formats. By default all rules will be
-run against the supplied input files. To recursively scan from the current
-directory you can supply `./...` as the input argument.
+Gosec can be configured to only run a subset of rules, to
+exclude certain file paths, and produce reports in different
+formats. By default all rules will be run against the supplied
+input files. To recursively scan from the current directory you
+can supply `./...` as the input argument.
### Available rules
-- G101: Look for hard coded credentials
-- G102: Bind to all interfaces
-- G103: Audit the use of unsafe block
-- G104: Audit errors not checked
-- G106: Audit the use of ssh.InsecureIgnoreHostKey
-- G107: Url provided to HTTP request as taint input
-- G108: Profiling endpoint automatically exposed on /debug/pprof
-- G109: Potential Integer overflow made by strconv.Atoi result conversion to int16/32
-- G110: Potential DoS vulnerability via decompression bomb
-- G111: Potential directory traversal
-- G112: Potential slowloris attack
-- G114: Use of net/http serve function that has no support for setting timeouts
-- G115: Potential integer overflow when converting between integer types
-- G201: SQL query construction using format string
-- G202: SQL query construction using string concatenation
-- G203: Use of unescaped data in HTML templates
-- G204: Audit use of command execution
-- G301: Poor file permissions used when creating a directory
-- G302: Poor file permissions used with chmod
-- G303: Creating tempfile using a predictable path
-- G304: File path provided as taint input
-- G305: File traversal when extracting zip/tar archive
-- G306: Poor file permissions used when writing to a new file
-- G307: Poor file permissions used when creating a file with os.Create
-- G401: Detect the usage of MD5 or SHA1
-- G402: Look for bad TLS connection settings
-- G403: Ensure minimum RSA key length of 2048 bits
-- G404: Insecure random number source (rand)
-- G405: Detect the usage of DES or RC4
-- G406: Detect the usage of MD4 or RIPEMD160
-- G407: Detect the usage of hardcoded Initialization Vector(IV)/Nonce
-- G501: Import blocklist: crypto/md5
-- G502: Import blocklist: crypto/des
-- G503: Import blocklist: crypto/rc4
-- G504: Import blocklist: net/http/cgi
-- G505: Import blocklist: crypto/sha1
-- G506: Import blocklist: golang.org/x/crypto/md4
-- G507: Import blocklist: golang.org/x/crypto/ripemd160
-- G601: Implicit memory aliasing of items from a range statement (only for Go 1.21 or lower)
-- G602: Slice access out of bounds
+gosec includes rules across these categories:
+
+- `G1xx`: general secure coding issues (for example hardcoded
+ credentials, unsafe usage, HTTP hardening, cookie security)
+- `G2xx`: injection risks in query/template/command
+ construction
+- `G3xx`: file and path handling risks (permissions, traversal,
+ temp files, archive extraction)
+- `G4xx`: crypto and TLS weaknesses
+- `G5xx`: blocklisted imports
+- `G6xx`: Go-specific correctness/security checks (for example
+ range aliasing and slice bounds)
+- `G7xx`: taint analysis rules (SQL injection, command
+ injection, path traversal, SSRF, XSS, log, SMTP injection,
+ SSTI, unsafe deserialization, and open redirect)
+
+For the full list, rule descriptions, and per-rule
+configuration, see [RULES.md](RULES.md).
### Retired rules
-- G105: Audit the use of math/big.Int.Exp - [CVE is fixed](https://github.com/golang/go/issues/15184)
-- G113: Usage of Rat.SetString in math/big with an overflow (CVE-2022-23772). This affected Go <1.16.14 and Go <1.17.7, which are no longer supported by gosec.
-- G307: Deferring a method which returns an error - causing more inconvenience than fixing a security issue, despite the details from this [blog post](https://www.joeshaw.org/dont-defer-close-on-writable-files/)
+- G105: Audit the use of math/big.Int.Exp -
+ [CVE is fixed](https://github.com/golang/go/issues/15184)
+- G307: Deferring a method which returns an error - causing
+ more inconvenience than fixing a security issue, despite the
+ details from this
+ [blog post](https://www.joeshaw.org/dont-defer-close-on-writable-files/)
### Selecting rules
-By default, gosec will run all rules against the supplied file paths. It is however possible to select a subset of rules to run via the `-include=` flag,
-or to specify a set of rules to explicitly exclude using the `-exclude=` flag.
+By default, gosec will run all rules against the supplied file
+paths. It is however possible to select a subset of rules to
+run via the `-include=` flag, or to specify a set of rules to
+explicitly exclude using the `-exclude=` flag.
```bash
# Run a specific set of rules
@@ -189,11 +258,16 @@ $ gosec -exclude=G303 ./...
### CWE Mapping
-Every issue detected by `gosec` is mapped to a [CWE (Common Weakness Enumeration)](http://cwe.mitre.org/data/index.html) which describes in more generic terms the vulnerability. The exact mapping can be found [here](https://github.com/securego/gosec/blob/master/issue/issue.go#L50).
+Every issue detected by `gosec` is mapped to a
+[CWE (Common Weakness Enumeration)](http://cwe.mitre.org/data/index.html)
+which describes in more generic terms the vulnerability. The
+exact mapping can be found
+[here](https://github.com/securego/gosec/blob/master/issue/issue.go#L50).
### Configuration
-A number of global settings can be provided in a configuration file as follows:
+A number of global settings can be provided in a configuration
+file as follows:
```JSON
{
@@ -204,34 +278,92 @@ A number of global settings can be provided in a configuration file as follows:
}
```
-- `nosec`: this setting will overwrite all `#nosec` directives defined throughout the code base
-- `audit`: runs in audit mode which enables addition checks that for normal code analysis might be too nosy
+- `nosec`: this setting will overwrite all `#nosec` directives
+ defined throughout the code base
+- `audit`: runs in audit mode which enables addition checks
+ that for normal code analysis might be too nosy
```bash
# Run with a global configuration file
$ gosec -conf config.json .
```
+### Path-Based Rule Exclusions
+
+Large repositories with multiple components may need different
+security rules for different paths. Use `exclude-rules` to
+suppress specific rules for specific paths.
+
+**Configuration File:**
+```json
+{
+ "exclude-rules": [
+ {
+ "path": "cmd/.*",
+ "rules": ["G204", "G304"]
+ },
+ {
+ "path": "scripts/.*",
+ "rules": ["*"]
+ }
+ ]
+}
+```
+
+**CLI Flag:**
+```bash
+# Exclude G204 and G304 from cmd/ directory
+gosec --exclude-rules="cmd/.*:G204,G304" ./...
+
+# Exclude all rules from scripts/ directory
+gosec --exclude-rules="scripts/.*:*" ./...
+
+# Multiple exclusions
+gosec --exclude-rules="cmd/.*:G204,G304;test/.*:G101" ./...
+```
+
+| Field | Type | Description |
+|-------|------|-------------|
+| `path` | string (regex) | Regex matched against file paths |
+| `rules` | []string | Rule IDs to exclude. `*` for all |
+
#### Rule Configuration
-Some rules accept configuration flags as well; these flags are documented in [RULES.md](https://github.com/securego/gosec/blob/master/RULES.md).
+Some rules accept configuration flags as well; these flags are
+documented in
+[RULES.md](https://github.com/securego/gosec/blob/master/RULES.md).
#### Go version
-Some rules require a specific Go version which is retrieved from the Go module file present in the project. If this version cannot be found, it will fallback to Go runtime version.
+Some rules require a specific Go version which is retrieved
+from the Go module file present in the project. If this version
+cannot be found, it will fallback to Go runtime version.
-The Go module version is parsed using the `go list` command which in some cases might lead to performance degradation. In this situation, the go module version can be easily provided by setting the environment variable `GOSECGOVERSION=go1.21.1`.
+The Go module version is parsed using the `go list` command
+which in some cases might lead to performance degradation. In
+this situation, the go module version can be easily provided by
+setting the environment variable
+`GOSECGOVERSION=go1.21.1`.
### Dependencies
-gosec will fetch automatically the dependencies of the code which is being analyzed when go module is turned on (e.g.`GO111MODULE=on`). If this is not the case,
-the dependencies need to be explicitly downloaded by running the `go get -d` command before the scan.
+gosec loads packages using Go modules. In most projects,
+dependencies are resolved automatically during scanning.
+
+If dependencies are missing, run:
+
+```bash
+go mod tidy
+go mod download
+```
### Excluding test files and folders
-gosec will ignore test files across all packages and any dependencies in your vendor directory.
+gosec will ignore test files across all packages and any
+dependencies in your vendor directory.
-The scanning of test files can be enabled with the following flag:
+The scanning of test files can be enabled with the following
+flag:
```bash
gosec -tests ./...
@@ -245,7 +377,8 @@ Also additional folders can be excluded as follows:
### Excluding generated files
-gosec can ignore generated go files with default generated code comment.
+gosec can ignore generated go files with default generated
+code comment.
```
// Code generated by some generator DO NOT EDIT.
@@ -257,36 +390,56 @@ gosec -exclude-generated ./...
### Auto fixing vulnerabilities
-gosec can suggest fixes based on AI recommendation. It will call an AI API to receive a suggestion for a security finding.
-
-You can enable this feature by providing the following command line arguments:
-
-- `ai-api-provider`: the name of the AI API provider. Supported providers:
- - **Gemini**: `gemini-2.5-pro`, `gemini-2.5-flash`, `gemini-2.5-flash-lite`, `gemini-2.0-flash`, `gemini-2.0-flash-lite` (default)
- - **Claude**: `claude-sonnet-4-0` (default), `claude-opus-4-0`, `claude-opus-4-1`, `claude-sonnet-3-7`
- - **OpenAI**: `gpt-4o` (default), `gpt-4o-mini`
- - **Custom OpenAI-compatible**: Any custom model name (requires `ai-base-url`)
-- `ai-api-key` or set the environment variable `GOSEC_AI_API_KEY`: the key to access the AI API
- - For Gemini, you can create an API key following [these instructions](https://ai.google.dev/gemini-api/docs/api-key)
- - For Claude, get your API key from [Anthropic Console](https://console.anthropic.com/)
- - For OpenAI, get your API key from [OpenAI Platform](https://platform.openai.com/api-keys)
-- `ai-base-url`: (optional) custom base URL for OpenAI-compatible APIs (e.g., Azure OpenAI, LocalAI, Ollama)
-- `ai-skip-ssl`: (optional) skip SSL certificate verification for AI API (useful for self-signed certificates)
+gosec can suggest fixes based on AI recommendation. It will
+call an AI API to receive a suggestion for a security finding.
+
+You can enable this feature by providing the following command
+line arguments:
+
+- `ai-api-provider`: the name of the AI API provider.
+ Supported providers:
+ - **Gemini**: `gemini-3-pro-preview` (default),
+ `gemini-2.5-pro`, `gemini-2.5-flash`,
+ `gemini-2.5-flash-lite`
+ - **Claude**: `claude-sonnet-4-6` (default),
+ `claude-opus-4-7`, `claude-opus-4-6`,
+ `claude-sonnet-4-5`, `claude-opus-4-5`,
+ `claude-haiku-4-5`
+ - **OpenAI**: `gpt-5.4` (default), `gpt-5.4-mini`,
+ `gpt-5.4-nano`
+ - **Custom OpenAI-compatible**: Any custom model name
+ (requires `ai-base-url`)
+- `ai-api-key` or set the environment variable
+ `GOSEC_AI_API_KEY`: the key to access the AI API
+ - For Gemini, you can create an API key following
+ [these instructions](https://ai.google.dev/gemini-api/docs/api-key)
+ - For Claude, get your API key from
+ [Anthropic Console](https://console.anthropic.com/)
+ - For OpenAI, get your API key from
+ [OpenAI Platform](https://platform.openai.com/api-keys)
+- `ai-base-url`: (optional) custom base URL for
+ OpenAI-compatible APIs (e.g., Azure OpenAI, LocalAI,
+ Ollama)
+- `ai-skip-ssl`: (optional) skip SSL certificate verification
+ for AI API (useful for self-signed certificates)
**Examples:**
```bash
# Using Gemini
-gosec -ai-api-provider="gemini-2.0-flash" -ai-api-key="your_key" ./...
+gosec -ai-api-provider="gemini-3-pro-preview" \
+ -ai-api-key="your_key" ./...
# Using Claude
-gosec -ai-api-provider="claude-sonnet-4-0" -ai-api-key="your_key" ./...
+gosec -ai-api-provider="claude-sonnet-4-6" \
+ -ai-api-key="your_key" ./...
# Using OpenAI
-gosec -ai-api-provider="gpt-4o" -ai-api-key="your_key" ./...
+gosec -ai-api-provider="gpt-5.4" \
+ -ai-api-key="your_key" ./...
# Using Azure OpenAI
-gosec -ai-api-provider="gpt-4o" \
+gosec -ai-api-provider="gpt-5.4" \
-ai-api-key="your_azure_key" \
-ai-base-url="https://your-resource.openai.azure.com/openai/deployments/your-deployment" \
./...
@@ -306,13 +459,16 @@ gosec -ai-api-provider="custom-model" \
### Annotating code
-As with all automated detection tools, there will be cases of false positives.
-In cases where gosec reports a failure that has been manually verified as being safe,
-it is possible to annotate the code with a comment that starts with `#nosec`.
+As with all automated detection tools, there will be cases of
+false positives. In cases where gosec reports a failure that
+has been manually verified as being safe, it is possible to
+annotate the code with a comment that starts with `#nosec`.
-The `#nosec` comment should have the format `#nosec [RuleList] [-- Justification]`.
+The `#nosec` comment should have the format
+`#nosec [RuleList] [- Justification]`.
-The `#nosec` comment needs to be placed on the line where the warning is reported.
+The `#nosec` comment needs to be placed on the line where the
+warning is reported.
```go
func main() {
@@ -330,24 +486,29 @@ func main() {
}
```
-When a specific false positive has been identified and verified as safe, you may
-wish to suppress only that single rule (or a specific set of rules) within a section of code,
-while continuing to scan for other problems. To do this, you can list the rule(s) to be suppressed within
-the `#nosec` annotation, e.g: `/* #nosec G401 */` or `//#nosec G201 G202 G203`
+When a specific false positive has been identified and verified
+as safe, you may wish to suppress only that single rule (or a
+specific set of rules) within a section of code, while
+continuing to scan for other problems. To do this, you can list
+the rule(s) to be suppressed within the `#nosec` annotation,
+e.g: `/* #nosec G401 */` or `//#nosec G201 G202 G203`
-You could put the description or justification text for the annotation. The
-justification should be after the rule(s) to suppress and start with two or
-more dashes, e.g: `//#nosec G101 G102 -- This is a false positive`
+You could put the description or justification text for the
+annotation. The justification should be after the rule(s) to
+suppress and start with two or more dashes,
+e.g: `//#nosec G101 G102 -- This is a false positive`
-Alternatively, gosec also supports the `//gosec:disable` directive, which functions similar to `#nosec`:
+Alternatively, gosec also supports the `//gosec:disable`
+directive, which functions similar to `#nosec`:
```go
//gosec:disable G101 -- This is a false positive
```
-In some cases you may also want to revisit places where `#nosec` or `//gosec:disable` annotations
-have been used. To run the scanner and ignore any `#nosec` annotations you
-can do the following:
+In some cases you may also want to revisit places where
+`#nosec` or `//gosec:disable` annotations have been used. To
+run the scanner and ignore any `#nosec` annotations you can do
+the following:
```bash
gosec -nosec=true ./...
@@ -355,28 +516,31 @@ gosec -nosec=true ./...
### Tracking suppressions
-As described above, we could suppress violations externally (using `-include`/
-`-exclude`) or inline (using `#nosec` annotations) in gosec. This suppression
-inflammation can be used to generate corresponding signals for auditing
-purposes.
+As described above, we could suppress violations externally
+(using `-include`/`-exclude`) or inline (using `#nosec`
+annotations). Suppression metadata can be emitted for auditing.
-We could track suppressions by the `-track-suppressions` flag as follows:
+Enable suppression tracking with `-track-suppressions`:
```bash
-gosec -track-suppressions -exclude=G101 -fmt=sarif -out=results.sarif ./...
+gosec -track-suppressions -exclude=G101 \
+ -fmt=sarif -out=results.sarif ./...
```
-- For external suppressions, gosec records suppression info where `kind` is
-`external` and `justification` is a certain sentence "Globally suppressed".
-- For inline suppressions, gosec records suppression info where `kind` is
-`inSource` and `justification` is the text after two or more dashes in the
-comment.
+- For external suppressions, gosec records suppression info
+ where `kind` is `external` and `justification` is
+ `Globally suppressed.`.
+- For inline suppressions, gosec records suppression info
+ where `kind` is `inSource` and `justification` is the text
+ after two or more dashes in the comment.
-**Note:** Only SARIF and JSON formats support tracking suppressions.
+**Note:** Only SARIF and JSON formats support tracking
+suppressions.
### Build tags
-gosec is able to pass your [Go build tags](https://pkg.go.dev/go/build/) to the analyzer.
+gosec is able to pass your
+[Go build tags](https://pkg.go.dev/go/build/) to the analyzer.
They can be provided as a comma separated list as follows:
```bash
@@ -385,123 +549,59 @@ gosec -tags debug,ignore ./...
### Output formats
-gosec currently supports `text`, `json`, `yaml`, `csv`, `sonarqube`, `JUnit XML`, `html` and `golint` output formats. By default
-results will be reported to stdout, but can also be written to an output
-file. The output format is controlled by the `-fmt` flag, and the output file is controlled by the `-out` flag as follows:
+gosec supports `text`, `json`, `yaml`, `csv`, `junit-xml`,
+`html`, `sonarqube`, `golint`, and `sarif`. By default,
+results will be reported to stdout, but can also be written to
+an output file. The output format is controlled by the `-fmt`
+flag, and the output file is controlled by the `-out` flag as
+follows:
```bash
# Write output in json format to results.json
$ gosec -fmt=json -out=results.json *.go
```
-Results will be reported to stdout as well as to the provided output file by `-stdout` flag. The `-verbose` flag overrides the
-output format when stdout the results while saving them in the output file
+Use `-stdout` to print results while also writing `-out`.
+Use `-verbose` to override stdout format while preserving the
+file format.
```bash
# Write output in json format to results.json as well as stdout
$ gosec -fmt=json -out=results.json -stdout *.go
-# Overrides the output format to 'text' when stdout the results, while writing it to results.json
+# Overrides the output format to 'text' when stdout the results,
+# while writing it to results.json
$ gosec -fmt=json -out=results.json -stdout -verbose=text *.go
```
-**Note:** gosec generates the [generic issue import format](https://docs.sonarqube.org/latest/analysis/generic-issue/) for SonarQube, and a report has to be imported into SonarQube using `sonar.externalIssuesReportPaths=path/to/gosec-report.json`.
-
-## Development
-
-[CONTRIBUTING.md](https://github.com/securego/gosec/blob/master/CONTRIBUTING.md) contains detailed information about adding new rules to gosec.
-
-### Build
-
-You can build the binary with:
-
-```bash
-make
-```
-
-### Note on Sarif Types Generation
-
-Install the tool with :
-
-```bash
-go get -u github.com/a-h/generate/cmd/schema-generate
-```
-
-Then generate the types with :
-
-```bash
-schema-generate -i sarif-schema-2.1.0.json -o mypath/types.go
-```
-
-Most of the MarshallJSON/UnmarshalJSON are removed except the one for PropertyBag which is handy to inline the additional properties. The rest can be removed.
-The URI,ID, UUID, GUID were renamed so it fits the Go convention defined [here](https://github.com/golang/lint/blob/master/lint.go#L700)
-
-### Tests
-
-You can run all unit tests using:
-
-```bash
-make test
-```
-
-### Release
-
-You can create a release by tagging the version as follows:
-
-``` bash
-git tag v1.0.0 -m "Release version v1.0.0"
-git push origin v1.0.0
-```
-
-The GitHub [release workflow](.github/workflows/release.yml) triggers immediately after the tag is pushed upstream. This flow will
-release the binaries using the [goreleaser](https://goreleaser.com/actions/) action and then it will build and publish the docker image into Docker Hub.
-
-The released artifacts are signed using [cosign](https://docs.sigstore.dev/). You can use the public key from [cosign.pub](cosign.pub)
-file to verify the signature of docker image and binaries files.
-
-The docker image signature can be verified with the following command:
-```
-cosign verify --key cosign.pub securego/gosec:
-```
-
-The binary files signature can be verified with the following command:
-```
-cosign verify-blob --key cosign.pub --signature gosec__darwin_amd64.tar.gz.sig gosec__darwin_amd64.tar.gz
-```
+**Note:** gosec generates the
+[generic issue import format](https://docs.sonarqube.org/latest/analysis/generic-issue/)
+for SonarQube, and a report has to be imported into SonarQube
+using
+`sonar.externalIssuesReportPaths=path/to/gosec-report.json`.
-### Docker image
-
-You can also build locally the docker image by using the command:
+## Common usage patterns
```bash
-make image
-```
-
-You can run the `gosec` tool in a container against your local Go project. You only have to mount the project
-into a volume as follows:
-
-```bash
-docker run --rm -it -w // -v /:/ securego/gosec //...
-```
-
-**Note:** the current working directory needs to be set with `-w` option in order to get successfully resolved the dependencies from go module file
+# Fail only on medium+ severity findings
+gosec -severity medium ./...
-### Generate TLS rule
+# Fail only on medium+ confidence findings
+gosec -confidence medium ./...
-The configuration of TLS rule can be generated from [Mozilla's TLS ciphers recommendation](https://statics.tls.security.mozilla.org/server-side-tls-conf.json).
+# Exclude specific rules for specific paths
+gosec --exclude-rules="cmd/.*:G204,G304;scripts/.*:*" ./...
-First you need to install the generator tool:
+# Exclude generated files in scan
+gosec -exclude-generated ./...
-```bash
-go get github.com/securego/gosec/v2/cmd/tlsconfig/...
+# Include test files in scan
+gosec -tests ./...
```
-You can invoke now the `go generate` in the root of the project:
-
-```bash
-go generate ./...
-```
+## Development
-This will generate the `rules/tls_config.go` file which will contain the current ciphers recommendation from Mozilla.
+Development documentation was moved to
+[DEVELOPMENT.md](DEVELOPMENT.md).
## Who is using gosec?
@@ -509,6 +609,7 @@ This is a [list](USERS.md) with some of the gosec's users.
## Sponsors
-Support this project by becoming a sponsor. Your logo will show up here with a link to your website
+Support this project by becoming a sponsor. Your logo will
+show up here with a link to your website
diff --git a/vendor/github.com/securego/gosec/v2/RULES.md b/vendor/github.com/securego/gosec/v2/RULES.md
index 94cfd76a8..badc3b189 100644
--- a/vendor/github.com/securego/gosec/v2/RULES.md
+++ b/vendor/github.com/securego/gosec/v2/RULES.md
@@ -1,61 +1,289 @@
# Rule Documentation
-## Rules accepting parameters
+## Table of Contents
-As [README.md](https://github.com/securego/gosec/blob/master/README.md) mentions, some rules can be configured by adding parameters to the gosec JSON config. Per rule configs are encoded as top level objects in the gosec config, with the rule ID (`Gxxx`) as the key.
+- [Rules List](#rules-list)
+ - [G1xx: General Secure Coding](#g1xx-general-secure-coding)
+ - [G2xx: Injection Patterns](#g2xx-injection-patterns)
+ - [G3xx: Filesystem and Permissions](#g3xx-filesystem-and-permissions)
+ - [G4xx: Crypto and Protocol security](#g4xx-crypto-and-protocol-security)
+ - [G5xx: Import Blocklist](#g5xx-import-blocklist)
+ - [G6xx: Language/Runtime safety](#g6xx-languageruntime-safety)
+ - [G7xx: Taint Analysis](#g7xx-taint-analysis)
+ - [Retired and reassigned IDs](#retired-and-reassigned-ids)
+- [Rules configuration](#rules-configuration)
+ - [G101](#g101)
+ - [G104](#g104)
+ - [G111](#g111)
+ - [G117](#g117)
+ - [G118](#g118)
+ - [G301, G302, G306, G307](#g301-g302-g306-g307)
-Currently, the following rules accept parameters. This list is manually maintained; if you notice an omission please add it!
+## Rules List
+
+### G1xx: General Secure Coding
+
+- [G101](#g101) — Look for hardcoded credentials (**AST**)
+- G102 — Bind to all interfaces (**AST**)
+- G103 — Audit the use of unsafe block (**AST**)
+- [G104](#g104) — Audit errors not checked (**AST**)
+- G106 — Audit the use of `ssh.InsecureIgnoreHostKey` function (**AST**)
+- G107 — URL provided to HTTP request as taint input (**AST**)
+- G108 — Profiling endpoint is automatically exposed (**AST**)
+- G109 — Converting `strconv.Atoi` result to `int32/int16` (**AST**)
+- G110 — Detect `io.Copy` instead of `io.CopyN` when decompressing (**AST**)
+- [G111](#g111) — Detect `http.Dir('/')` as a potential risk (**AST**)
+- G112 — Detect `ReadHeaderTimeout` not configured as a potential risk (**AST**)
+- G113 — HTTP request smuggling via conflicting headers or bare LF in body parsing (**SSA**)
+- G114 — Use of `net/http` serve function that has no support for setting timeouts (**AST**)
+- G115 — Type conversion which leads to integer overflow (**SSA**)
+- G116 — Detect Trojan Source attacks using bidirectional Unicode characters (**AST**)
+- [G117](#g117) — Potential exposure of secrets via JSON/YAML/XML/TOML marshaling (**AST**)
+- [G118](#g118) — Context propagation failure leading to goroutine/resource leaks (**SSA**)
+- G119 — Unsafe redirect policy may propagate sensitive headers (**SSA**)
+- G120 — Unbounded `ParseMultipartForm` in HTTP handlers can cause memory exhaustion (**Taint**)
+- G121 — Unsafe CrossOriginProtection bypass patterns (**SSA**)
+- G122 — Filesystem TOCTOU race risk in `filepath.Walk/WalkDir` callbacks (**SSA**)
+- G123 — TLS resumption may bypass `VerifyPeerCertificate` when `VerifyConnection` is unset (**SSA**)
+- G124 — Insecure HTTP cookie configuration missing Secure, HttpOnly, or SameSite attributes (**SSA**)
+
+### G2xx: Injection Patterns
+
+- G201 — SQL query construction using format string (**AST**)
+- G202 — SQL query construction using string concatenation (**AST**)
+- G203 — Use of unescaped data in HTML templates (**AST**)
+- G204 — Audit use of command execution (**AST**)
+
+### G3xx: Filesystem and Permissions
+
+- [G301](#g301-g302-g306-g307) — Poor file permissions used when creating a directory (**AST**)
+- [G302](#g301-g302-g306-g307) — Poor file permissions used when creating file or using `chmod` (**AST**)
+- G303 — Creating tempfile using a predictable path (**AST**)
+- G304 — File path provided as taint input (**AST**)
+- G305 — File path traversal when extracting zip archive (**AST**)
+- [G306](#g301-g302-g306-g307) — Poor file permissions used when writing to a file (**AST**)
+- [G307](#g301-g302-g306-g307) — Poor file permissions used when creating a file with `os.Create` (**AST**)
+
+### G4xx: Crypto and Protocol security
+
+- G401 — Detect the usage of MD5 or SHA1 (**AST**)
+- G402 — Look for bad TLS connection settings (**AST**)
+- G403 — Ensure minimum RSA key length of 2048 bits (**AST**)
+- G404 — Insecure random number source (`rand`) (**AST**)
+- G405 — Detect the usage of DES or RC4 (**AST**)
+- G406 — Detect the usage of deprecated MD4 or RIPEMD160 (**AST**)
+- G407 — Use of hardcoded IV/nonce for encryption (**SSA**)
+- G408 — Stateful misuse of `ssh.PublicKeyCallback` leading to auth bypass (**SSA**)
+
+### G5xx: Import Blocklist
+
+- G501 — Import blocklist: `crypto/md5` (**AST**)
+- G502 — Import blocklist: `crypto/des` (**AST**)
+- G503 — Import blocklist: `crypto/rc4` (**AST**)
+- G504 — Import blocklist: `net/http/cgi` (**AST**)
+- G505 — Import blocklist: `crypto/sha1` (**AST**)
+- G506 — Import blocklist: `golang.org/x/crypto/md4` (**AST**)
+- G507 — Import blocklist: `golang.org/x/crypto/ripemd160` (**AST**)
+
+### G6xx: Language/Runtime safety
+
+- G601 — Implicit memory aliasing in `RangeStmt` (Go 1.21 or lower) (**AST**)
+- G602 — Possible slice bounds out of range (**SSA**)
+
+### G7xx: Taint Analysis
+
+- G701 — SQL injection via taint analysis (**Taint**)
+- G702 — Command injection via taint analysis (**Taint**)
+- G703 — Path traversal via taint analysis (**Taint**)
+- G704 — SSRF via taint analysis (**Taint**)
+- G705 — XSS via taint analysis (**Taint**)
+- G706 — Log injection via taint analysis (**Taint**)
+- G707 — SMTP command/header injection via taint analysis (**Taint**)
+- G708 — Server-side template injection via `text/template` (**Taint**)
+- G709 — Unsafe deserialization of untrusted data (**Taint**)
+- G710 — Open redirect via taint analysis (**Taint**)
+
+_Note: Implementation types used in this document:_
+- **AST**: rule implemented in `rules/` and evaluated on AST patterns
+- **SSA**: analyzer implemented in `analyzers/` using the analyzer framework (SSA-backed execution path)
+- **Taint**: taint analysis rule implemented via `taint.NewGosecAnalyzer`
+
+### Retired and reassigned IDs
+
+- G105 is retired.
+- G307 (old meaning: deferred method error handling) is retired; the ID now refers to file creation permissions.
+- G113 was previously used for a retired `math/big` check and is now used for HTTP request smuggling.
+
+## Rules configuration
+
+Some rules accept configuration in the gosec JSON config file.
+Per-rule settings are top-level objects keyed by rule ID (`Gxxx`).
+
+Configurable rules (alphabetical): [G101](#g101), [G104](#g104), [G111](#g111), [G117](#g117), [G301](#g301-g302-g306-g307), [G302](#g301-g302-g306-g307), [G306](#g301-g302-g306-g307), [G307](#g301-g302-g306-g307).
### G101
-The hard-coded credentials rule `G101` can be configured with additional patterns, and the entropy threshold can be adjusted:
+`G101` (hardcoded credentials) can be configured with custom patterns and entropy thresholds:
-```JSON
+```json
{
- "G101": {
- "pattern": "(?i)passwd|pass|password|pwd|secret|private_key|token",
- "ignore_entropy": false,
- "entropy_threshold": "80.0",
- "per_char_threshold": "3.0",
- "truncate": "32"
- }
+ "G101": {
+ "pattern": "(?i)passwd|pass|password|pwd|secret|private_key|token",
+ "ignore_entropy": false,
+ "entropy_threshold": "80.0",
+ "per_char_threshold": "3.0",
+ "truncate": "32",
+ "min_entropy_length": "8"
+ }
}
```
### G104
-The unchecked error value rule `G104` can be configured with additional functions that should be permitted to be called without checking errors.
+`G104` (unchecked errors) can be configured with function allowlists:
-```JSON
+```json
{
- "G104": {
- "ioutil": ["WriteFile"]
- }
+ "G104": {
+ "ioutil": ["WriteFile"]
+ }
}
```
### G111
-The HTTP Directory serving rule `G111` can be configured with a different regex for detecting potentially overly permissive servers. Note that this *replaces* the default pattern of `http\.Dir\("\/"\)|http\.Dir\('\/'\)`.
+`G111` (HTTP directory serving) can be configured with a custom detection regex.
+This replaces the default pattern.
-```JSON
+```json
{
- "G111": {
- "pattern": "http\\.Dir\\(\"\\\/\"\\)|http\\.Dir\\('\\\/'\\)"
+ "G111": {
+ "pattern": "http\\.Dir\\(\"\\/\"\\)|http\\.Dir\\('\\/'\\)"
+ }
+}
+```
+
+### G117
+
+`G117` (secret serialization) can be configured with a custom field-name pattern.
+
+```json
+{
+ "G117": {
+ "pattern": "(?i)secret|token|password"
+ }
+}
+```
+
+### G118
+
+`G118` detects three classes of context-propagation failure using SSA-level analysis:
+
+**1. Lost cancel function (CWE-400)**
+
+Reports when a `context.WithCancel`, `context.WithTimeout`, or `context.WithDeadline` call
+returns a cancel function that is never called, potentially leaking resources.
+
+```go
+// Flagged: cancel never called
+func work(ctx context.Context) {
+ child, _ := context.WithTimeout(ctx, time.Second)
+ _ = child
+}
+
+// Safe: cancel deferred
+func work(ctx context.Context) {
+ child, cancel := context.WithTimeout(ctx, time.Second)
+ defer cancel()
+ _ = child
+}
+```
+
+The following patterns are all recognised as *safe* (cancel is considered called):
+
+| Pattern | Description |
+|---|---|
+| `defer cancel()` | Direct deferred call |
+| `defer func() { cancel() }()` | Cancel in a deferred closure |
+| `cancelCopy := cancel; defer cancelCopy()` | Alias via variable |
+| `return ctx, cancel` | Cancel returned to caller (responsibility transferred) |
+| `s.cancelFn = cancel` + method `s.cancelFn()` | Stored in struct field, called via receiver method |
+| `s.cancel = cancel; defer s.cancel()` | Stored in struct field, deferred in same function |
+| `s.cancel = cancel; defer func() { s.cancel() }()` | Stored in struct field, called in closure |
+| Struct containing field is returned | Caller inherits cancel responsibility |
+| `var cancel CancelFunc` in `init()` + `cancel()` in another function | Package-level variable assigned in init, called in any function (e.g., signal handlers) |
+
+Example of package-level variable pattern:
+
+```go
+// Safe: cancel stored in package-level variable and called in signal handler
+var cancel context.CancelFunc
+
+func init() {
+ ctx, c := context.WithCancel(context.Background())
+ cancel = c
+}
+
+func handleShutdown() {
+ cancel() // Called from signal handler
+}
+```
+
+**2. Goroutine uses `context.Background`/`TODO` when request context is available (CWE-400)**
+
+Reports when a goroutine spawned inside an HTTP handler or a function accepting a
+`context.Context` / `*http.Request` uses `context.Background()` or `context.TODO()`
+instead of the request-scoped context.
+
+```go
+// Flagged
+func handler(w http.ResponseWriter, r *http.Request) {
+ go func() {
+ ctx := context.Background() // ignores request context
+ doWork(ctx)
+ }()
+}
+```
+
+**3. Long-running loop without `ctx.Done()` guard (CWE-400)**
+
+Reports an infinite loop that performs blocking I/O (e.g. `http.Get`, `db.Query`,
+`time.Sleep`, interface methods such as `Read`/`Write`) but never checks `ctx.Done()`,
+making the loop impossible to cancel.
+
+```go
+// Flagged
+func poll(ctx context.Context) {
+ for {
+ http.Get("https://example.com") // blocks, no cancellation path
+ time.Sleep(time.Second)
}
}
+// Safe
+func poll(ctx context.Context) {
+ for {
+ select {
+ case <-ctx.Done():
+ return
+ case <-time.After(time.Second):
+ http.Get("https://example.com")
+ }
+ }
+}
```
+Loops with an external exit path (e.g. a `break` or bounded `for i < n`) are not flagged.
+
### G301, G302, G306, G307
-The various file and directory permission checking rules can be configured with a different maximum allowable file permission.
+File and directory permission rules can be configured with stricter maximum permissions:
-```JSON
+```json
{
- "G301":"0o600",
- "G302":"0o600",
- "G306":"0o750",
- "G307":"0o750"
+ "G301": "0o600",
+ "G302": "0o600",
+ "G306": "0o750",
+ "G307": "0o750"
}
```
diff --git a/vendor/github.com/securego/gosec/v2/action.yml b/vendor/github.com/securego/gosec/v2/action.yml
index bc5d4a8dd..caedf343e 100644
--- a/vendor/github.com/securego/gosec/v2/action.yml
+++ b/vendor/github.com/securego/gosec/v2/action.yml
@@ -10,7 +10,7 @@ inputs:
runs:
using: "docker"
- image: "docker://securego/gosec:2.22.10"
+ image: "docker://ghcr.io/securego/gosec:2.25.0"
args:
- ${{ inputs.args }}
diff --git a/vendor/github.com/securego/gosec/v2/analyzer.go b/vendor/github.com/securego/gosec/v2/analyzer.go
index 0508bcea6..c0eb3b1d7 100644
--- a/vendor/github.com/securego/gosec/v2/analyzer.go
+++ b/vendor/github.com/securego/gosec/v2/analyzer.go
@@ -16,6 +16,7 @@
package gosec
import (
+ "context"
"errors"
"fmt"
"go/ast"
@@ -23,16 +24,16 @@ import (
"go/token"
"go/types"
"log"
+ "maps"
"os"
"path"
"path/filepath"
"reflect"
- "regexp"
"runtime/debug"
"strconv"
"strings"
- "sync"
+ "golang.org/x/sync/errgroup"
"golang.org/x/tools/go/analysis"
"golang.org/x/tools/go/analysis/passes/buildssa"
"golang.org/x/tools/go/analysis/passes/ctrlflow"
@@ -40,9 +41,15 @@ import (
"golang.org/x/tools/go/packages"
"github.com/securego/gosec/v2/analyzers"
+ "github.com/securego/gosec/v2/internal/ssautil"
"github.com/securego/gosec/v2/issue"
)
+var (
+ ErrNoPackageTypeInfo = errors.New("package has no type information")
+ ErrNilPackage = errors.New("nil package provided")
+)
+
// LoadMode controls the amount of details to return when loading the packages
const LoadMode = packages.NeedName |
packages.NeedFiles |
@@ -56,11 +63,11 @@ const LoadMode = packages.NeedName |
packages.NeedEmbedFiles |
packages.NeedEmbedPatterns
-const externalSuppressionJustification = "Globally suppressed."
-
-const aliasOfAllRules = "*"
-
-var directiveRegexp = regexp.MustCompile("^//gosec:disable(?: (.+))?$")
+const (
+ externalSuppressionJustification = "Globally suppressed."
+ aliasOfAllRules = "*"
+ directivePrefix = "//gosec:disable"
+)
type ignore struct {
start int
@@ -149,7 +156,8 @@ type Context struct {
Imports *ImportTracker
Config Config
Ignores ignores
- PassedValues map[string]interface{}
+ PassedValues map[string]any
+ callCache map[ast.Node]callInfo
}
// GetFileAtNodePos returns the file at the node position in the file set available in the context.
@@ -172,11 +180,32 @@ type Metrics struct {
NumFound int `json:"found"`
}
-// Analyzer object is the main object of gosec. It has methods traverse an AST
-// and invoke the correct checking rules as on each node as required.
+// Merge merges the metrics from another Metrics object into this one.
+func (m *Metrics) Merge(other *Metrics) {
+ if other == nil {
+ return
+ }
+ m.NumFiles += other.NumFiles
+ m.NumLines += other.NumLines
+ m.NumNosec += other.NumNosec
+ m.NumFound += other.NumFound
+}
+
+// Analyzer object is the main object of gosec. It has methods to load and analyze
+// packages, traverse ASTs, and invoke the correct checking rules on each node as required.
type Analyzer struct {
- ignoreNosec bool
- ruleset RuleSet
+ ignoreNosec bool
+ ruleset RuleSet
+ // ruleBuilders and ruleSuppressed store the original arguments passed to
+ // LoadRules so that checkRules can call buildPackageRuleset to produce a
+ // goroutine-local RuleSet for every concurrent package walk. Each walk
+ // therefore owns its own freshly allocated rule instances, which means
+ // rules are free to keep per-package mutable state (e.g. maps tracking
+ // cleaned or joined variables) without any synchronisation. The shared
+ // gosec.ruleset is kept for callers that use the public CheckRules API
+ // directly (backward-compatible path).
+ ruleBuilders map[string]RuleBuilder
+ ruleSuppressed map[string]bool
context *Context
config Config
logger *log.Logger
@@ -235,12 +264,32 @@ func (gosec *Analyzer) Config() Config {
// LoadRules instantiates all the rules to be used when analyzing source
// packages
func (gosec *Analyzer) LoadRules(ruleDefinitions map[string]RuleBuilder, ruleSuppressed map[string]bool) {
+ // Persist the builders so checkRules can produce per-package rule
+ // instances via buildPackageRuleset, eliminating shared mutable state
+ // across concurrent goroutines without requiring locks inside rules.
+ gosec.ruleBuilders = ruleDefinitions
+ gosec.ruleSuppressed = ruleSuppressed
+
for id, def := range ruleDefinitions {
r, nodes := def(id, gosec.config)
gosec.ruleset.Register(r, ruleSuppressed[id], nodes...)
}
}
+// buildPackageRuleset constructs a brand-new RuleSet by re-invoking every
+// stored RuleBuilder. The returned ruleset is intended to be used for a single
+// package walk: because each concurrent worker calls buildPackageRuleset
+// independently, every goroutine gets its own rule instances with their own
+// internal state (maps, caches, etc.), so rules require no synchronisation.
+func (gosec *Analyzer) buildPackageRuleset() RuleSet {
+ rs := NewRuleSet()
+ for id, def := range gosec.ruleBuilders {
+ r, nodes := def(id, gosec.config)
+ rs.Register(r, gosec.ruleSuppressed[id], nodes...)
+ }
+ return rs
+}
+
// LoadAnalyzers instantiates all the analyzers to be used when analyzing source
// packages
func (gosec *Analyzer) LoadAnalyzers(analyzerDefinitions map[string]analyzers.AnalyzerDefinition, analyzerSuppressed map[string]bool) {
@@ -252,73 +301,119 @@ func (gosec *Analyzer) LoadAnalyzers(analyzerDefinitions map[string]analyzers.An
// Process kicks off the analysis process for a given package
func (gosec *Analyzer) Process(buildTags []string, packagePaths ...string) error {
+ ctx, cancel := context.WithCancel(context.Background())
+ defer cancel()
+
type result struct {
pkgPath string
pkgs []*packages.Package
+ issues []*issue.Issue
+ stats *Metrics
+ errors map[string][]Error
err error
}
- results := make(chan result)
+ results := make(chan result, len(packagePaths)) // Buffer for all potential results
jobs := make(chan string, len(packagePaths))
- quit := make(chan struct{})
- var wg sync.WaitGroup
+ // Fill jobs channel and close it to signal no more work
+ for _, pkgPath := range packagePaths {
+ jobs <- pkgPath
+ }
+ close(jobs)
+
+ g := errgroup.Group{}
+ g.SetLimit(gosec.concurrency)
- worker := func(j chan string, r chan result, quit chan struct{}) {
+ worker := func() error {
for {
select {
- case s := <-j:
- pkgs, err := gosec.load(s, buildTags)
- select {
- case r <- result{pkgPath: s, pkgs: pkgs, err: err}:
- case <-quit:
- // we've been told to stop, probably an error while
- // processing a previous result.
- wg.Done()
- return
+ case pkgPath, ok := <-jobs:
+ if !ok {
+ return nil // Jobs drained, worker done
}
- default:
- // j is empty and there are no jobs left
- wg.Done()
- return
+
+ pkgs, err := gosec.load(pkgPath, buildTags)
+ if err != nil {
+ results <- result{pkgPath: pkgPath, err: err}
+ continue
+ }
+
+ var funcIssues []*issue.Issue
+ funcStats := &Metrics{}
+ funcErrors := make(map[string][]Error)
+
+ for _, pkg := range pkgs {
+ if pkg.Name == "" {
+ continue
+ }
+
+ errs, err := ParseErrors(pkg)
+ if err != nil {
+ results <- result{
+ pkgPath: pkgPath,
+ err: fmt.Errorf("parsing errors in pkg %q: %w", pkg.Name, err),
+ }
+ return nil // Parsing error in worker stops this package
+ }
+ // Collect parsing errors if any
+ if len(errs) > 0 {
+ for k, v := range errs {
+ funcErrors[k] = append(funcErrors[k], v...)
+ }
+ }
+
+ // Run AST-based rules (stateless)
+ issues, stats, allIgnores := gosec.checkRules(pkg)
+ funcIssues = append(funcIssues, issues...)
+ funcStats.Merge(stats)
+
+ // Run SSA-based analyzers (stateless)
+ ssaIssues, ssaStats := gosec.checkAnalyzers(pkg, allIgnores)
+ funcIssues = append(funcIssues, ssaIssues...)
+ funcStats.Merge(ssaStats)
+ }
+
+ results <- result{
+ pkgPath: pkgPath,
+ pkgs: pkgs,
+ issues: funcIssues,
+ stats: funcStats,
+ errors: funcErrors,
+ err: nil,
+ }
+ case <-ctx.Done():
+ return ctx.Err() // Early shutdown
}
}
}
- // fill the buffer
- for _, pkgPath := range packagePaths {
- jobs <- pkgPath
- }
-
+ // Start workers
for i := 0; i < gosec.concurrency; i++ {
- wg.Add(1)
- go worker(jobs, results, quit)
+ g.Go(worker)
}
+ // Wait for workers; first error cancels context via errgroup
go func() {
- wg.Wait()
+ if err := g.Wait(); err != nil && !errors.Is(err, context.Canceled) {
+ cancel()
+ }
close(results)
}()
+ // Aggregate results
for r := range results {
if r.err != nil {
gosec.AppendError(r.pkgPath, r.err)
}
- for _, pkg := range r.pkgs {
- if pkg.Name != "" {
- err := gosec.ParseErrors(pkg)
- if err != nil {
- close(quit)
- wg.Wait() // wait for the goroutines to stop
- return fmt.Errorf("parsing errors in pkg %q: %w", pkg.Name, err)
- }
- gosec.CheckRules(pkg)
- gosec.CheckAnalyzers(pkg)
- }
+ gosec.issues = append(gosec.issues, r.issues...)
+ gosec.stats.Merge(r.stats)
+ for file, matches := range r.errors {
+ gosec.errors[file] = append(gosec.errors[file], matches...)
}
}
sortErrors(gosec.errors)
- return nil
+ return g.Wait() // Return any aggregated error from workers
}
func (gosec *Analyzer) load(pkgPath string, buildTags []string) ([]*packages.Package, error) {
@@ -355,12 +450,16 @@ func (gosec *Analyzer) load(pkgPath string, buildTags []string) ([]*packages.Pac
}
}
- // step 2/2: pass in cli encoded build flags to build correctly.
+ // step 2/2: pass in cli encoded build flags to build correctly,
+ // and set Dir to the module root of the package being loaded.
conf := &packages.Config{
Mode: LoadMode,
BuildFlags: CLIBuildTags(buildTags),
Tests: gosec.tests,
}
+ if modRoot := FindModuleRoot(abspath); modRoot != "" {
+ conf.Dir = modRoot
+ }
pkgs, err := packages.Load(conf, packageFiles...)
if err != nil {
return []*packages.Package{}, fmt.Errorf("loading files from package %q: %w", pkgPath, err)
@@ -370,7 +469,48 @@ func (gosec *Analyzer) load(pkgPath string, buildTags []string) ([]*packages.Pac
// CheckRules runs analysis on the given package.
func (gosec *Analyzer) CheckRules(pkg *packages.Package) {
+ issues, stats, ignores := gosec.checkRules(pkg)
+ gosec.issues = append(gosec.issues, issues...)
+ gosec.stats.Merge(stats)
+ if gosec.context.Ignores == nil {
+ gosec.context.Ignores = newIgnores()
+ }
+ maps.Copy(gosec.context.Ignores, ignores)
+}
+
+// checkRules runs analysis on the given package (Stateless API).
+func (gosec *Analyzer) checkRules(pkg *packages.Package) ([]*issue.Issue, *Metrics, ignores) {
gosec.logger.Println("Checking package:", pkg.Name)
+ stats := &Metrics{}
+ allIgnores := newIgnores()
+
+ callCache := callCachePool.Get().(map[ast.Node]callInfo)
+ defer func() {
+ clear(callCache)
+ callCachePool.Put(callCache)
+ }()
+
+ // Build a goroutine-local RuleSet so this package walk owns its own fresh
+ // rule instances. Rules with internal maps (e.g. readfile.cleanedVar,
+ // joinedVar) are therefore safe to use without any synchronisation: each
+ // concurrent worker has completely independent rule objects. Falls back to
+ // the shared ruleset when builders are unavailable (direct CheckRules path).
+ var pkgRuleset *RuleSet
+ if len(gosec.ruleBuilders) > 0 {
+ rs := gosec.buildPackageRuleset()
+ pkgRuleset = &rs
+ }
+
+ visitor := &astVisitor{
+ gosec: gosec,
+ ruleset: pkgRuleset,
+ issues: make([]*issue.Issue, 0, 16),
+ stats: stats,
+ ignoreNosec: gosec.ignoreNosec,
+ showIgnored: gosec.showIgnored,
+ trackSuppressions: gosec.trackSuppressions,
+ }
+
for _, file := range pkg.Syntax {
fp := pkg.Fset.File(file.Pos())
if fp == nil {
@@ -389,27 +529,49 @@ func (gosec *Analyzer) CheckRules(pkg *packages.Package) {
}
gosec.logger.Println("Checking file:", checkedFile)
- gosec.context.FileSet = pkg.Fset
- gosec.context.Config = gosec.config
- gosec.context.Comments = ast.NewCommentMap(gosec.context.FileSet, file, file.Comments)
- gosec.context.Root = file
- gosec.context.Info = pkg.TypesInfo
- gosec.context.Pkg = pkg.Types
- gosec.context.PkgFiles = pkg.Syntax
- gosec.context.Imports = NewImportTracker()
- gosec.context.PassedValues = make(map[string]interface{})
- gosec.updateIgnores()
- ast.Walk(gosec, file)
- gosec.stats.NumFiles++
- gosec.stats.NumLines += pkg.Fset.File(file.Pos()).LineCount()
+ ctx := &Context{
+ FileSet: pkg.Fset,
+ Config: gosec.config,
+ Comments: ast.NewCommentMap(pkg.Fset, file, file.Comments),
+ Root: file,
+ Info: pkg.TypesInfo,
+ Pkg: pkg.Types,
+ PkgFiles: pkg.Syntax,
+ Imports: NewImportTracker(),
+ PassedValues: make(map[string]any),
+ callCache: callCache,
+ }
+
+ visitor.context = ctx
+ visitor.updateIgnores()
+ if len(visitor.activeRuleset().Rules) > 0 {
+ ast.Walk(visitor, file)
+ }
+ stats.NumFiles++
+ stats.NumLines += pkg.Fset.File(file.Pos()).LineCount()
+
+ // Collect ignores
+ if ctx.Ignores != nil {
+ maps.Copy(allIgnores, ctx.Ignores)
+ }
}
+
+ return visitor.issues, stats, allIgnores
}
// CheckAnalyzers runs analyzers on a given package.
func (gosec *Analyzer) CheckAnalyzers(pkg *packages.Package) {
+ // Rely on gosec.context.Ignores being populated by CheckRules
+ issues, stats := gosec.checkAnalyzers(pkg, gosec.context.Ignores)
+ gosec.issues = append(gosec.issues, issues...)
+ gosec.stats.Merge(stats)
+}
+
+// checkAnalyzers runs analyzers on a given package (Stateless API).
+func (gosec *Analyzer) checkAnalyzers(pkg *packages.Package, allIgnores ignores) ([]*issue.Issue, *Metrics) {
// significant performance improvement if no analyzers are loaded
if len(gosec.analyzerSet.Analyzers) == 0 {
- return
+ return nil, &Metrics{}
}
ssaResult, err := gosec.buildSSA(pkg)
@@ -425,56 +587,94 @@ func (gosec *Analyzer) CheckAnalyzers(pkg *packages.Package) {
errMessage += "no ssa result"
}
gosec.logger.Print(errMessage)
- return
+ return nil, &Metrics{}
}
+ return gosec.checkAnalyzersWithSSA(pkg, ssaResult, allIgnores)
+}
- resultMap := map[*analysis.Analyzer]interface{}{
- buildssa.Analyzer: &analyzers.SSAAnalyzerResult{
- Config: gosec.Config(),
- Logger: gosec.logger,
- SSA: ssaResult,
- },
+// CheckAnalyzersWithSSA runs analyzers on a given package using an existing SSA result.
+func (gosec *Analyzer) CheckAnalyzersWithSSA(pkg *packages.Package, ssaResult *buildssa.SSA) {
+ issues, stats := gosec.checkAnalyzersWithSSA(pkg, ssaResult, gosec.context.Ignores)
+ gosec.issues = append(gosec.issues, issues...)
+ gosec.stats.Merge(stats)
+}
+
+// checkAnalyzersWithSSA runs analyzers on a given package using an existing SSA result (Stateless API).
+func (gosec *Analyzer) checkAnalyzersWithSSA(pkg *packages.Package, ssaResult *buildssa.SSA, allIgnores ignores) ([]*issue.Issue, *Metrics) {
+ sharedCache := ssautil.NewPackageAnalysisCache(ssaResult)
+ ssaAnalyzerResult := &ssautil.SSAAnalyzerResult{
+ Config: gosec.Config(),
+ Logger: gosec.logger,
+ SSA: ssaResult,
+ Shared: sharedCache,
}
generatedFiles := gosec.generatedFiles(pkg)
+ issues := make([]*issue.Issue, 0)
+ stats := &Metrics{}
+ analyzerRuns := make([][]*issue.Issue, len(gosec.analyzerSet.Analyzers))
+
+ runner := errgroup.Group{}
+ runner.SetLimit(max(gosec.concurrency, 1))
+
+ for index, analyzer := range gosec.analyzerSet.Analyzers {
+ runner.Go(func() error {
+ pass := &analysis.Pass{
+ Analyzer: analyzer,
+ Fset: pkg.Fset,
+ Files: pkg.Syntax,
+ OtherFiles: pkg.OtherFiles,
+ IgnoredFiles: pkg.IgnoredFiles,
+ Pkg: pkg.Types,
+ TypesInfo: pkg.TypesInfo,
+ TypesSizes: pkg.TypesSizes,
+ ResultOf: map[*analysis.Analyzer]any{
+ buildssa.Analyzer: ssaAnalyzerResult,
+ },
+ Report: func(d analysis.Diagnostic) {},
+ ImportObjectFact: nil,
+ ExportObjectFact: nil,
+ ImportPackageFact: nil,
+ ExportPackageFact: nil,
+ AllObjectFacts: nil,
+ AllPackageFacts: nil,
+ }
+
+ result, err := pass.Analyzer.Run(pass)
+ if err != nil {
+ gosec.logger.Printf("Error running analyzer %s: %s\n", analyzer.Name, err)
+ return nil
+ }
+
+ if result == nil {
+ return nil
+ }
- for _, analyzer := range gosec.analyzerSet.Analyzers {
- pass := &analysis.Pass{
- Analyzer: analyzer,
- Fset: pkg.Fset,
- Files: pkg.Syntax,
- OtherFiles: pkg.OtherFiles,
- IgnoredFiles: pkg.IgnoredFiles,
- Pkg: pkg.Types,
- TypesInfo: pkg.TypesInfo,
- TypesSizes: pkg.TypesSizes,
- ResultOf: resultMap,
- Report: func(d analysis.Diagnostic) {},
- ImportObjectFact: nil,
- ExportObjectFact: nil,
- ImportPackageFact: nil,
- ExportPackageFact: nil,
- AllObjectFacts: nil,
- AllPackageFacts: nil,
- }
- result, err := pass.Analyzer.Run(pass)
- if err != nil {
- gosec.logger.Printf("Error running analyzer %s: %s\n", analyzer.Name, err)
- continue
- }
- if result != nil {
if passIssues, ok := result.([]*issue.Issue); ok {
- for _, iss := range passIssues {
- if gosec.excludeGenerated {
- if _, ok := generatedFiles[iss.File]; ok {
- continue
- }
- }
- gosec.updateIssues(iss)
+ analyzerRuns[index] = passIssues
+ }
+
+ return nil
+ })
+ }
+
+ if err := runner.Wait(); err != nil {
+ gosec.logger.Printf("Error waiting for analyzers: %s\n", err)
+ }
+
+ for _, passIssues := range analyzerRuns {
+ for _, iss := range passIssues {
+ if gosec.excludeGenerated {
+ if _, ok := generatedFiles[iss.File]; ok {
+ continue
}
}
+
+ // issue filtering logic
+ issues = gosec.updateIssues(iss, issues, stats, allIgnores)
}
}
+ return issues, stats
}
func (gosec *Analyzer) generatedFiles(pkg *packages.Package) map[string]bool {
@@ -503,13 +703,16 @@ func (gosec *Analyzer) buildSSA(pkg *packages.Package) (*buildssa.SSA, error) {
}
}()
if pkg == nil {
- return nil, errors.New("nil package provided")
+ return nil, ErrNilPackage
}
if pkg.Types == nil {
return nil, fmt.Errorf("package %s has no type information (compilation failed?)", pkg.Name)
}
if pkg.TypesInfo == nil {
- return nil, fmt.Errorf("package %s has no type information", pkg.Name)
+ return nil, fmt.Errorf("%w: %s", ErrNoPackageTypeInfo, pkg.Name)
+ }
+ if pkg.IllTyped {
+ return nil, fmt.Errorf("package %s has type errors, skipping SSA analysis", pkg.Name)
}
pass := &analysis.Pass{
Fset: pkg.Fset,
@@ -519,7 +722,7 @@ func (gosec *Analyzer) buildSSA(pkg *packages.Package) (*buildssa.SSA, error) {
Pkg: pkg.Types,
TypesInfo: pkg.TypesInfo,
TypesSizes: pkg.TypesSizes,
- ResultOf: make(map[*analysis.Analyzer]interface{}),
+ ResultOf: make(map[*analysis.Analyzer]any),
Report: func(d analysis.Diagnostic) {},
ImportObjectFact: func(obj types.Object, fact analysis.Fact) bool { return false },
ExportObjectFact: func(obj types.Object, fact analysis.Fact) {},
@@ -552,11 +755,12 @@ func (gosec *Analyzer) buildSSA(pkg *packages.Package) (*buildssa.SSA, error) {
return ssaResult, nil
}
-// ParseErrors parses the errors from given package
-func (gosec *Analyzer) ParseErrors(pkg *packages.Package) error {
+// ParseErrors parses errors from the package and returns them as a map.
+func ParseErrors(pkg *packages.Package) (map[string][]Error, error) {
if len(pkg.Errors) == 0 {
- return nil
+ return nil, nil
}
+ errs := make(map[string][]Error)
for _, pkgErr := range pkg.Errors {
parts := strings.Split(pkgErr.Pos, ":")
file := parts[0]
@@ -564,25 +768,20 @@ func (gosec *Analyzer) ParseErrors(pkg *packages.Package) error {
var line int
if len(parts) > 1 {
if line, err = strconv.Atoi(parts[1]); err != nil {
- return fmt.Errorf("parsing line: %w", err)
+ return nil, fmt.Errorf("parsing line: %w", err)
}
}
var column int
if len(parts) > 2 {
if column, err = strconv.Atoi(parts[2]); err != nil {
- return fmt.Errorf("parsing column: %w", err)
+ return nil, fmt.Errorf("parsing column: %w", err)
}
}
msg := strings.TrimSpace(pkgErr.Msg)
newErr := NewError(line, column, msg)
- if errSlice, ok := gosec.errors[file]; ok {
- gosec.errors[file] = append(errSlice, *newErr)
- } else {
- errSlice = []Error{}
- gosec.errors[file] = append(errSlice, *newErr)
- }
+ errs[file] = append(errs[file], *newErr)
}
- return nil
+ return errs, nil
}
// AppendError appends an error to the file errors
@@ -601,180 +800,264 @@ func (gosec *Analyzer) AppendError(file string, err error) {
gosec.errors[file] = errors
}
-// ignore a node (and sub-tree) if it is tagged with a nosec tag comment
-func (gosec *Analyzer) ignore(n ast.Node) map[string]issue.SuppressionInfo {
- if gosec.ignoreNosec {
- return nil
- }
- groups, ok := gosec.context.Comments[n]
- if !ok {
- return nil
- }
-
- // Checks if an alternative for #nosec is set and, if not, uses the default.
- noSecDefaultTag, err := gosec.config.GetGlobal(Nosec)
- if err != nil {
- noSecDefaultTag = NoSecTag(string(Nosec))
- } else {
- noSecDefaultTag = NoSecTag(noSecDefaultTag)
- }
- noSecAlternativeTag, err := gosec.config.GetGlobal(NoSecAlternative)
- if err != nil {
- noSecAlternativeTag = noSecDefaultTag
- } else {
- noSecAlternativeTag = NoSecTag(noSecAlternativeTag)
+// findNoSecDirective checks if the comment group contains `#nosec` or `//gosec:disable` directive.
+// If found, it returns true and the directive's arguments.
+func findNoSecDirective(group *ast.CommentGroup, noSecDefaultTag, noSecAlternativeTag string) (bool, string) {
+ if group == nil {
+ return false, ""
}
- for _, group := range groups {
- found, args := findNoSecDirective(group, noSecDefaultTag, noSecAlternativeTag)
- if !found {
- continue
- }
-
- gosec.stats.NumNosec++
+ // Join all comments in the group once to support multi-line nosec tags
+ text := group.Text()
- // Extract the directive and the justification.
- justification := ""
- commentParts := regexp.MustCompile(`-{2,}`).Split(args, 2)
- directive := commentParts[0]
- if len(commentParts) > 1 {
- justification = strings.TrimSpace(strings.TrimRight(commentParts[1], "\n"))
+ // Check for nosec tags
+ for _, tag := range []string{noSecDefaultTag, noSecAlternativeTag} {
+ if found, args := findNoSecTag(text, tag); found {
+ return true, args
}
+ }
- // Pull out the specific rules that are listed to be ignored.
- re := regexp.MustCompile(`(G\d{3})`)
- matches := re.FindAllStringSubmatch(directive, -1)
-
- suppression := issue.SuppressionInfo{
- Kind: "inSource",
- Justification: justification,
+ // Check for directive comments individually
+ for _, c := range group.List {
+ if after, ok := strings.CutPrefix(c.Text, directivePrefix); ok {
+ if len(after) == 0 || after[0] == ' ' {
+ return true, strings.TrimSpace(after)
+ }
}
+ }
- // Find the rule IDs to ignore.
- ignores := make(map[string]issue.SuppressionInfo)
- for _, v := range matches {
- ignores[v[1]] = suppression
- }
+ return false, ""
+}
- // If no specific rules were given, ignore everything.
- if len(matches) == 0 {
- ignores[aliasOfAllRules] = suppression
- }
- return ignores
+func findNoSecTag(text, tag string) (bool, string) {
+ text = strings.TrimSpace(text)
+ if text == "" {
+ return false, ""
}
- return nil
-}
-// findNoSecDirective checks if the comment group contains `#nosec` or `//gosec:disable` directive.
-// If found, it returns true and the directive's arguments.
-func findNoSecDirective(group *ast.CommentGroup, noSecDefaultTag, noSecAlternativeTag string) (bool, string) {
- // Check if the comment grounp has a nosec comment.
- for _, tag := range []string{noSecDefaultTag, noSecAlternativeTag} {
- if found, args := findNoSecTag(group, tag); found {
- return true, args
- }
+ if strings.HasPrefix(text, tag) {
+ return true, text[len(tag):]
}
- // Check if the comment group has a directive comment.
- for _, c := range group.List {
- match := directiveRegexp.FindStringSubmatch(c.Text)
- if len(match) > 0 {
- return true, match[0]
+ if idx := strings.Index(text, tag); idx > 0 {
+ // Check if it's at the beginning of a line (possibly with space)
+ for i := idx - 1; i >= 0; i-- {
+ if text[i] == '\n' {
+ return true, text[idx+len(tag):]
+ }
+ if text[i] != ' ' && text[i] != '\t' {
+ break
+ }
}
}
return false, ""
}
-func findNoSecTag(group *ast.CommentGroup, tag string) (bool, string) {
- comment := strings.TrimSpace(group.Text())
+// astVisitor implements ast.Visitor for per-file rule checking and issue collection.
+type astVisitor struct {
+ gosec *Analyzer
+ // ruleset is a package-local RuleSet built fresh by buildPackageRuleset
+ // for each concurrent package walk. It is non-nil when invoked through
+ // the normal Process → checkRules path and nil when the public CheckRules
+ // API is called directly (falling back to the shared gosec.ruleset).
+ ruleset *RuleSet
+ context *Context
+ issues []*issue.Issue
+ stats *Metrics
+ ignoreNosec bool
+ showIgnored bool
+ trackSuppressions bool
+}
- if strings.HasPrefix(comment, tag) || regexp.MustCompile("\n *"+tag).MatchString(comment) {
- // Discard what's in front of the nosec tag.
- return true, strings.SplitN(comment, tag, 2)[1]
+// activeRuleset returns the package-local ruleset when available, falling back
+// to the shared analyzer ruleset for direct CheckRules callers.
+func (v *astVisitor) activeRuleset() *RuleSet {
+ if v.ruleset != nil {
+ return v.ruleset
}
-
- return false, ""
+ return &v.gosec.ruleset
}
-// Visit runs the gosec visitor logic over an AST created by parsing go code.
-// Rule methods added with AddRule will be invoked as necessary.
-func (gosec *Analyzer) Visit(n ast.Node) ast.Visitor {
- // Using ast.File instead of ast.ImportSpec, so that we can track all imports at once.
+func (v *astVisitor) Visit(n ast.Node) ast.Visitor {
switch i := n.(type) {
case *ast.File:
- gosec.context.Imports.TrackFile(i)
+ v.context.Imports.TrackFile(i)
}
- for _, rule := range gosec.ruleset.RegisteredFor(n) {
- issue, err := rule.Match(n, gosec.context)
+ for _, rule := range v.activeRuleset().RegisteredFor(n) {
+ issue, err := rule.Match(n, v.context)
if err != nil {
- file, line := GetLocation(n, gosec.context)
+ file, line := GetLocation(n, v.context)
file = path.Base(file)
- gosec.logger.Printf("Rule error: %v => %s (%s:%d)\n", reflect.TypeOf(rule), err, file, line)
+ v.gosec.logger.Printf("Rule error: %v => %s (%s:%d)\n", reflect.TypeOf(rule), err, file, line)
}
- gosec.updateIssues(issue)
+ v.issues = v.gosec.updateIssues(issue, v.issues, v.stats, v.context.Ignores)
}
- return gosec
+ return v
}
-func (gosec *Analyzer) updateIgnores() {
- for n := range gosec.context.Comments {
- gosec.updateIgnoredRulesForNode(n)
+// updateIgnores parses comments to find and update ignored rules.
+func (v *astVisitor) updateIgnores() {
+ for c := range v.context.Comments {
+ v.updateIgnoredRulesForNode(c)
}
}
-func (gosec *Analyzer) updateIgnoredRulesForNode(n ast.Node) {
- ignoredRules := gosec.ignore(n)
+// updateIgnoredRulesForNode parses comments for a specific node and updates ignored rules.
+func (v *astVisitor) updateIgnoredRulesForNode(n ast.Node) {
+ ignoredRules, group := v.ignore(n)
if len(ignoredRules) > 0 {
- if gosec.context.Ignores == nil {
- gosec.context.Ignores = newIgnores()
+ if v.context.Ignores == nil {
+ v.context.Ignores = newIgnores()
}
- line := issue.GetLine(gosec.context.FileSet.File(n.Pos()), n)
- gosec.context.Ignores.add(
- gosec.context.FileSet.File(n.Pos()).Name(),
+
+ // Calculate the range to include both the node and the comment group
+ // This handles cases where the comment is associated with a subsequent node
+ // but we still want to ignore the line where the comment is located.
+ startPos := n.Pos()
+ endPos := n.End()
+ if group != nil {
+ if group.Pos() < startPos {
+ startPos = group.Pos()
+ }
+ if group.End() > endPos {
+ endPos = group.End()
+ }
+ }
+
+ startLine := v.context.FileSet.File(startPos).Line(startPos)
+ endLine := v.context.FileSet.File(endPos).Line(endPos)
+ line := strconv.Itoa(startLine)
+ if startLine != endLine {
+ line = fmt.Sprintf("%d-%d", startLine, endLine)
+ }
+ v.context.Ignores.add(
+ v.context.FileSet.File(startPos).Name(),
line,
ignoredRules,
)
}
}
-func (gosec *Analyzer) getSuppressionsAtLineInFile(file string, line string, id string) ([]issue.SuppressionInfo, bool) {
- ignoredRules := gosec.context.Ignores.get(file, line)
+// ignore checks if a node is tagged with a nosec comment and returns the suppressed rules.
+func (v *astVisitor) ignore(n ast.Node) (map[string]issue.SuppressionInfo, *ast.CommentGroup) {
+ if v.ignoreNosec {
+ return nil, nil
+ }
+ groups, ok := v.context.Comments[n]
+ if !ok {
+ return nil, nil
+ }
- // Check if the rule was specifically suppressed at this location.
- generalSuppressions, generalIgnored := ignoredRules[aliasOfAllRules]
- ruleSuppressions, ruleIgnored := ignoredRules[id]
- ignored := generalIgnored || ruleIgnored
- suppressions := append(generalSuppressions, ruleSuppressions...)
+ noSecDefaultTag, err := v.gosec.config.GetGlobal(Nosec)
+ if err != nil {
+ noSecDefaultTag = NoSecTag(string(Nosec))
+ } else {
+ noSecDefaultTag = NoSecTag(noSecDefaultTag)
+ }
+ noSecAlternativeTag, err := v.gosec.config.GetGlobal(NoSecAlternative)
+ if err != nil {
+ noSecAlternativeTag = noSecDefaultTag
+ } else {
+ noSecAlternativeTag = NoSecTag(noSecAlternativeTag)
+ }
- // Track external suppressions of this rule.
- if gosec.ruleset.IsRuleSuppressed(id) || gosec.analyzerSet.IsSuppressed(id) {
- ignored = true
- suppressions = append(suppressions, issue.SuppressionInfo{
- Kind: "external",
- Justification: externalSuppressionJustification,
- })
+ for _, group := range groups {
+ found, args := findNoSecDirective(group, noSecDefaultTag, noSecAlternativeTag)
+ if !found {
+ continue
+ }
+ v.stats.NumNosec++
+
+ justification := ""
+ if idx := strings.Index(args, "--"); idx > -1 {
+ justification = strings.TrimSpace(strings.TrimLeft(args[idx+2:], "-"))
+ args = args[:idx]
+ }
+
+ directive := strings.TrimSpace(args)
+ // If the directive is empty or contains "block" (legacy), ignore all rules
+ if len(directive) == 0 || directive == "block" {
+ return map[string]issue.SuppressionInfo{
+ aliasOfAllRules: {
+ Kind: "inSource",
+ Justification: justification,
+ },
+ }, group
+ }
+
+ ignores := make(map[string]issue.SuppressionInfo)
+ suppression := issue.SuppressionInfo{
+ Kind: "inSource",
+ Justification: justification,
+ }
+
+ // Manually parse identifiers starting with 'G' followed by 3 digits
+ for i := 0; i < len(directive); {
+ if directive[i] == 'G' && i+4 <= len(directive) {
+ ruleID := directive[i : i+4]
+ valid := true
+ for j := 1; j < 4; j++ {
+ if directive[i+j] < '0' || directive[i+j] > '9' {
+ valid = false
+ break
+ }
+ }
+ if valid {
+ ignores[ruleID] = suppression
+ i += 4
+ continue
+ }
+ }
+ i++
+ }
+
+ if len(ignores) == 0 {
+ ignores[aliasOfAllRules] = suppression
+ }
+ return ignores, group
}
- return suppressions, ignored
+ return nil, nil
}
-func (gosec *Analyzer) updateIssues(issue *issue.Issue) {
+// updateIssues updates the issues list with the given issue, handling suppressions.
+func (gosec *Analyzer) updateIssues(issue *issue.Issue, issues []*issue.Issue, stats *Metrics, allIgnores ignores) []*issue.Issue {
if issue != nil {
- suppressions, ignored := gosec.getSuppressionsAtLineInFile(issue.File, issue.Line, issue.RuleID)
+ suppressions, ignored := getSuppressions(allIgnores, issue.File, issue.Line, issue.RuleID, gosec.ruleset, gosec.analyzerSet)
if gosec.showIgnored {
issue.NoSec = ignored
}
if !ignored || !gosec.showIgnored {
- gosec.stats.NumFound++
+ stats.NumFound++
}
if ignored && gosec.trackSuppressions {
issue.WithSuppressions(suppressions)
- gosec.issues = append(gosec.issues, issue)
+ issues = append(issues, issue)
} else if !ignored || gosec.showIgnored || gosec.ignoreNosec {
- gosec.issues = append(gosec.issues, issue)
+ issues = append(issues, issue)
}
}
+ return issues
+}
+
+// getSuppressions returns the suppressions for a given issue location and rule ID.
+func getSuppressions(ignores ignores, file, line, ruleID string, ruleset RuleSet, analyzerSet *analyzers.AnalyzerSet) ([]issue.SuppressionInfo, bool) {
+ ignoredRules := ignores.get(file, line)
+ generalSuppressions, generalIgnored := ignoredRules[aliasOfAllRules]
+ ruleSuppressions, ruleIgnored := ignoredRules[ruleID]
+ ignored := generalIgnored || ruleIgnored
+ suppressions := append(generalSuppressions, ruleSuppressions...)
+
+ // Track external suppressions of this rule.
+ if ruleset.IsRuleSuppressed(ruleID) || analyzerSet.IsSuppressed(ruleID) {
+ ignored = true
+ suppressions = append(suppressions, issue.SuppressionInfo{
+ Kind: "external",
+ Justification: externalSuppressionJustification,
+ })
+ }
+ return suppressions, ignored
}
// Report returns the current issues discovered and the metrics about the scan
@@ -788,5 +1071,7 @@ func (gosec *Analyzer) Reset() {
gosec.issues = make([]*issue.Issue, 0, 16)
gosec.stats = &Metrics{}
gosec.ruleset = NewRuleSet()
+ gosec.ruleBuilders = nil
+ gosec.ruleSuppressed = nil
gosec.analyzerSet = analyzers.NewAnalyzerSet()
}
diff --git a/vendor/github.com/securego/gosec/v2/analyzers/analyzerslist.go b/vendor/github.com/securego/gosec/v2/analyzers/analyzerslist.go
index 8d222384a..0a541e908 100644
--- a/vendor/github.com/securego/gosec/v2/analyzers/analyzerslist.go
+++ b/vendor/github.com/securego/gosec/v2/analyzers/analyzerslist.go
@@ -16,6 +16,8 @@ package analyzers
import (
"golang.org/x/tools/go/analysis"
+
+ "github.com/securego/gosec/v2/taint"
)
// AnalyzerDefinition contains the description of an analyzer and a mechanism to
@@ -29,6 +31,86 @@ type AnalyzerDefinition struct {
// AnalyzerBuilder is used to register an analyzer definition with the analyzer
type AnalyzerBuilder func(id string, description string) *analysis.Analyzer
+// Taint analysis rule definitions
+var (
+ SQLInjectionRule = taint.RuleInfo{
+ ID: "G701",
+ Description: "SQL injection via string concatenation",
+ Severity: "HIGH",
+ CWE: "CWE-89",
+ }
+
+ CommandInjectionRule = taint.RuleInfo{
+ ID: "G702",
+ Description: "Command injection via user input",
+ Severity: "CRITICAL",
+ CWE: "CWE-78",
+ }
+
+ PathTraversalRule = taint.RuleInfo{
+ ID: "G703",
+ Description: "Path traversal via user input",
+ Severity: "HIGH",
+ CWE: "CWE-22",
+ }
+
+ SSRFRule = taint.RuleInfo{
+ ID: "G704",
+ Description: "SSRF via user-controlled URL",
+ Severity: "HIGH",
+ CWE: "CWE-918",
+ }
+
+ XSSRule = taint.RuleInfo{
+ ID: "G705",
+ Description: "XSS via unescaped user input",
+ Severity: "MEDIUM",
+ CWE: "CWE-79",
+ }
+
+ LogInjectionRule = taint.RuleInfo{
+ ID: "G706",
+ Description: "Log injection via user input",
+ Severity: "LOW",
+ CWE: "CWE-117",
+ }
+
+ SMTPInjectionRule = taint.RuleInfo{
+ ID: "G707",
+ Description: "SMTP command/header injection via user input",
+ Severity: "HIGH",
+ CWE: "CWE-93",
+ }
+
+ SSTIRule = taint.RuleInfo{
+ ID: "G708",
+ Description: "Server-side template injection via text/template",
+ Severity: "CRITICAL",
+ CWE: "CWE-94",
+ }
+
+ UnsafeDeserializationRule = taint.RuleInfo{
+ ID: "G709",
+ Description: "Unsafe deserialization of untrusted data",
+ Severity: "HIGH",
+ CWE: "CWE-502",
+ }
+
+ OpenRedirectRule = taint.RuleInfo{
+ ID: "G710",
+ Description: "Open redirect: user-controlled URL flows into http.Redirect",
+ Severity: "MEDIUM",
+ CWE: "CWE-601",
+ }
+
+ FormParsingLimitRule = taint.RuleInfo{
+ ID: "G120",
+ Description: "Unbounded multipart form parsing can cause memory exhaustion",
+ Severity: "MEDIUM",
+ CWE: "CWE-400",
+ }
+)
+
// AnalyzerList contains a mapping of analyzer ID's to analyzer definitions and a mapping
// of analyzer ID's to whether analyzers are suppressed.
type AnalyzerList struct {
@@ -66,9 +148,28 @@ func NewAnalyzerFilter(action bool, analyzerIDs ...string) AnalyzerFilter {
}
var defaultAnalyzers = []AnalyzerDefinition{
+ {"G113", "HTTP request smuggling via conflicting headers or bare LF in body parsing", newRequestSmugglingAnalyzer},
{"G115", "Type conversion which leads to integer overflow", newConversionOverflowAnalyzer},
+ {"G118", "Context propagation failure leading to goroutine/resource leaks", newContextPropagationAnalyzer},
+ {"G119", "Unsafe redirect policy may propagate sensitive headers", newRedirectHeaderPropagationAnalyzer},
+ {"G120", "Unbounded form parsing in HTTP handlers can cause memory exhaustion", newFormParsingLimitAnalyzer},
+ {"G121", "Unsafe CrossOriginProtection bypass patterns", newCORSBypassPatternAnalyzer},
+ {"G122", "Filesystem TOCTOU race risk in filepath.Walk/WalkDir callbacks", newWalkSymlinkRaceAnalyzer},
+ {"G123", "TLS resumption may bypass VerifyPeerCertificate when VerifyConnection is unset", newTLSResumptionVerifyPeerAnalyzer},
+ {"G124", "Insecure HTTP cookie configuration missing Secure, HttpOnly, or SameSite attributes", newInsecureCookieAnalyzer},
{"G602", "Possible slice bounds out of range", newSliceBoundsAnalyzer},
{"G407", "Use of hardcoded IV/nonce for encryption", newHardCodedNonce},
+ {"G408", "Stateful misuse of ssh.PublicKeyCallback leading to auth bypass", newSSHCallbackAnalyzer},
+ {"G701", "SQL injection via taint analysis", newSQLInjectionAnalyzer},
+ {"G702", "Command injection via taint analysis", newCommandInjectionAnalyzer},
+ {"G703", "Path traversal via taint analysis", newPathTraversalAnalyzer},
+ {"G704", "SSRF via taint analysis", newSSRFAnalyzer},
+ {"G705", "XSS via taint analysis", newXSSAnalyzer},
+ {"G706", "Log injection via taint analysis", newLogInjectionAnalyzer},
+ {"G707", "SMTP command/header injection via taint analysis", newSMTPInjectionAnalyzer},
+ {"G708", "Server-side template injection via taint analysis", newSSTIAnalyzer},
+ {"G709", "Unsafe deserialization of untrusted data via taint analysis", newUnsafeDeserializationAnalyzer},
+ {"G710", "Open redirect via taint analysis", newOpenRedirectAnalyzer},
}
// Generate the list of analyzers to use
@@ -93,3 +194,32 @@ func Generate(trackSuppressions bool, filters ...AnalyzerFilter) *AnalyzerList {
}
return &AnalyzerList{Analyzers: analyzerMap, AnalyzerSuppressed: analyzerSuppressedMap}
}
+
+// DefaultTaintAnalyzers returns all predefined taint analysis analyzers.
+func DefaultTaintAnalyzers() []*analysis.Analyzer {
+ sqlConfig := SQLInjection()
+ cmdConfig := CommandInjection()
+ pathConfig := PathTraversal()
+ ssrfConfig := SSRF()
+ xssConfig := XSS()
+ logConfig := LogInjection()
+ smtpConfig := SMTPInjection()
+ sstiConfig := SSTI()
+ deserConfig := UnsafeDeserialization()
+ formConfig := FormParsingLimits()
+ openRedirectConfig := OpenRedirect()
+
+ return []*analysis.Analyzer{
+ taint.NewGosecAnalyzer(&SQLInjectionRule, &sqlConfig),
+ taint.NewGosecAnalyzer(&CommandInjectionRule, &cmdConfig),
+ taint.NewGosecAnalyzer(&PathTraversalRule, &pathConfig),
+ taint.NewGosecAnalyzer(&SSRFRule, &ssrfConfig),
+ taint.NewGosecAnalyzer(&XSSRule, &xssConfig),
+ taint.NewGosecAnalyzer(&LogInjectionRule, &logConfig),
+ taint.NewGosecAnalyzer(&SMTPInjectionRule, &smtpConfig),
+ taint.NewGosecAnalyzer(&SSTIRule, &sstiConfig),
+ taint.NewGosecAnalyzer(&UnsafeDeserializationRule, &deserConfig),
+ taint.NewGosecAnalyzer(&FormParsingLimitRule, &formConfig),
+ taint.NewGosecAnalyzer(&OpenRedirectRule, &openRedirectConfig),
+ }
+}
diff --git a/vendor/github.com/securego/gosec/v2/analyzers/commandinjection.go b/vendor/github.com/securego/gosec/v2/analyzers/commandinjection.go
new file mode 100644
index 000000000..0a16d8e3f
--- /dev/null
+++ b/vendor/github.com/securego/gosec/v2/analyzers/commandinjection.go
@@ -0,0 +1,60 @@
+// (c) Copyright gosec's authors
+//
+// 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 analyzers
+
+import (
+ "golang.org/x/tools/go/analysis"
+
+ "github.com/securego/gosec/v2/taint"
+)
+
+// CommandInjection returns a configuration for detecting command injection vulnerabilities.
+func CommandInjection() taint.Config {
+ return taint.Config{
+ Sources: []taint.Source{
+ // Type sources: tainted when received as parameters
+ {Package: "net/http", Name: "Request", Pointer: true},
+ {Package: "bufio", Name: "Reader", Pointer: true},
+ {Package: "bufio", Name: "Scanner", Pointer: true},
+
+ // Function sources
+ {Package: "os", Name: "Args", IsFunc: true},
+ {Package: "os", Name: "Getenv", IsFunc: true},
+ },
+ Sinks: []taint.Sink{
+ // Detect at command creation, not execution (avoids double detection)
+ {Package: "os/exec", Method: "Command"},
+ {Package: "os/exec", Method: "CommandContext"},
+ {Package: "os", Method: "StartProcess"},
+ {Package: "syscall", Method: "Exec"},
+ {Package: "syscall", Method: "ForkExec"},
+ {Package: "syscall", Method: "StartProcess"},
+ },
+ Sanitizers: []taint.Sanitizer{
+ // No general-purpose stdlib sanitizer for command injection.
+ // The proper fix is to use exec.Command with separate args, not shell strings.
+ },
+ }
+}
+
+// newCommandInjectionAnalyzer creates an analyzer for detecting command injection vulnerabilities
+// via taint analysis (G702)
+func newCommandInjectionAnalyzer(id string, description string) *analysis.Analyzer {
+ config := CommandInjection()
+ rule := CommandInjectionRule
+ rule.ID = id
+ rule.Description = description
+ return taint.NewGosecAnalyzer(&rule, &config)
+}
diff --git a/vendor/github.com/securego/gosec/v2/analyzers/context_propagation.go b/vendor/github.com/securego/gosec/v2/analyzers/context_propagation.go
new file mode 100644
index 000000000..178d41169
--- /dev/null
+++ b/vendor/github.com/securego/gosec/v2/analyzers/context_propagation.go
@@ -0,0 +1,1147 @@
+// (c) Copyright gosec's authors
+//
+// 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 analyzers
+
+import (
+ "go/token"
+ "go/types"
+
+ "golang.org/x/tools/go/analysis"
+ "golang.org/x/tools/go/analysis/passes/buildssa"
+ "golang.org/x/tools/go/ssa"
+
+ "github.com/securego/gosec/v2/internal/ssautil"
+ "github.com/securego/gosec/v2/issue"
+)
+
+const (
+ contextPkgPath = "context"
+ httpPkgPath = "net/http"
+
+ msgContextBackground = "Goroutine uses context.Background/TODO while request-scoped context is available"
+ msgLostCancel = "context cancellation function returned by WithCancel/WithTimeout/WithDeadline is not called"
+ msgLoopWithoutDone = "Long-running loop performs calls without a ctx.Done() cancellation guard"
+)
+
+func newContextPropagationAnalyzer(id string, description string) *analysis.Analyzer {
+ return &analysis.Analyzer{
+ Name: id,
+ Doc: description,
+ Run: runContextPropagationAnalysis,
+ Requires: []*analysis.Analyzer{buildssa.Analyzer},
+ }
+}
+
+type contextPropagationState struct {
+ *BaseAnalyzerState
+ ssaFuncs []*ssa.Function
+ issues map[token.Pos]*issue.Issue
+}
+
+func newContextPropagationState(pass *analysis.Pass, funcs []*ssa.Function) *contextPropagationState {
+ return &contextPropagationState{
+ BaseAnalyzerState: NewBaseState(pass),
+ ssaFuncs: funcs,
+ issues: make(map[token.Pos]*issue.Issue),
+ }
+}
+
+func (s *contextPropagationState) addIssue(pos token.Pos, what string, severity issue.Score, confidence issue.Score) {
+ if pos == token.NoPos {
+ return
+ }
+ if _, found := s.issues[pos]; found {
+ return
+ }
+ s.issues[pos] = newIssue(s.Pass.Analyzer.Name, what, s.Pass.Fset, pos, severity, confidence)
+}
+
+func runContextPropagationAnalysis(pass *analysis.Pass) (any, error) {
+ ssaResult, err := ssautil.GetSSAResult(pass)
+ if err != nil {
+ return nil, err
+ }
+
+ state := newContextPropagationState(pass, ssaResult.SSA.SrcFuncs)
+ defer state.Release()
+
+ for _, fn := range state.ssaFuncs {
+ if fn == nil || len(fn.Blocks) == 0 {
+ continue
+ }
+
+ hasRequestContext := functionHasRequestContext(fn)
+ ctxValues := collectContextValues(fn)
+
+ if hasRequestContext {
+ state.detectUnsafeGoroutines(fn, ctxValues)
+ state.detectLoopsWithoutCancellationGuard(fn, ctxValues)
+ }
+
+ state.detectLostCancel(fn)
+ }
+
+ if len(state.issues) == 0 {
+ return nil, nil
+ }
+
+ issues := make([]*issue.Issue, 0, len(state.issues))
+ for _, i := range state.issues {
+ issues = append(issues, i)
+ }
+
+ return issues, nil
+}
+
+func functionHasRequestContext(fn *ssa.Function) bool {
+ if fn.Signature == nil {
+ return false
+ }
+
+ params := fn.Signature.Params()
+ for i := 0; i < params.Len(); i++ {
+ p := params.At(i)
+ if p == nil {
+ continue
+ }
+ if isContextType(p.Type()) {
+ return true
+ }
+ if isHTTPRequestPointerType(p.Type()) {
+ return true
+ }
+ }
+
+ return false
+}
+
+func collectContextValues(fn *ssa.Function) map[ssa.Value]struct{} {
+ ctxVals := make(map[ssa.Value]struct{})
+
+ for _, param := range fn.Params {
+ if param == nil {
+ continue
+ }
+ if isContextType(param.Type()) {
+ ctxVals[param] = struct{}{}
+ }
+ }
+
+ for _, block := range fn.Blocks {
+ for _, instr := range block.Instrs {
+ callInstr, ok := instr.(ssa.CallInstruction)
+ if !ok {
+ continue
+ }
+ common := callInstr.Common()
+ if common == nil {
+ continue
+ }
+
+ if isHTTPRequestContextCall(common) {
+ if val := callInstr.Value(); val != nil {
+ ctxVals[val] = struct{}{}
+ }
+ continue
+ }
+
+ if !isContextWithFamily(common) {
+ continue
+ }
+
+ tuple := callInstr.Value()
+ for _, ref := range safeReferrers(tuple) {
+ extract, ok := ref.(*ssa.Extract)
+ if !ok {
+ continue
+ }
+ if extract.Index == 0 {
+ ctxVals[extract] = struct{}{}
+ }
+ }
+ }
+ }
+
+ return ctxVals
+}
+
+func (s *contextPropagationState) detectUnsafeGoroutines(fn *ssa.Function, contextValues map[ssa.Value]struct{}) {
+ for _, block := range fn.Blocks {
+ for _, instr := range block.Instrs {
+ goInstr, ok := instr.(*ssa.Go)
+ if !ok {
+ continue
+ }
+
+ hasBackgroundCtx := false
+ for _, arg := range goInstr.Call.Args {
+ if isBackgroundOrTodoValue(arg) {
+ hasBackgroundCtx = true
+ break
+ }
+ }
+
+ if !hasBackgroundCtx {
+ for _, callee := range resolveGoCallTargets(goInstr) {
+ if callee == nil {
+ continue
+ }
+ if functionCallsBackground(callee) {
+ hasBackgroundCtx = true
+ break
+ }
+ }
+ }
+
+ if hasBackgroundCtx && len(contextValues) > 0 {
+ s.addIssue(goInstr.Pos(), msgContextBackground, issue.High, issue.Medium)
+ }
+ }
+ }
+}
+
+func (s *contextPropagationState) detectLostCancel(fn *ssa.Function) {
+ for _, block := range fn.Blocks {
+ for _, instr := range block.Instrs {
+ callInstr, ok := instr.(ssa.CallInstruction)
+ if !ok {
+ continue
+ }
+ common := callInstr.Common()
+ if common == nil || !isContextWithFamily(common) {
+ continue
+ }
+
+ tupleCall := callInstr.Value()
+ if tupleCall == nil {
+ continue
+ }
+
+ cancelValue := findCancelResult(tupleCall)
+ if cancelValue == nil {
+ continue
+ }
+
+ if !isCancelCalled(cancelValue, s.ssaFuncs) {
+ s.addIssue(instr.Pos(), msgLostCancel, issue.Medium, issue.High)
+ }
+ }
+ }
+}
+
+func (s *contextPropagationState) detectLoopsWithoutCancellationGuard(fn *ssa.Function, contextValues map[ssa.Value]struct{}) {
+ if len(contextValues) == 0 {
+ return
+ }
+ if len(fn.Blocks) == 0 {
+ return
+ }
+
+ features := make(map[*ssa.BasicBlock]blockFeatures, len(fn.Blocks))
+ for _, block := range fn.Blocks {
+ if block == nil {
+ continue
+ }
+ features[block] = analyzeBlockFeatures(block)
+ }
+
+ regions := findLoopRegions(fn)
+ for _, region := range regions {
+ if region.hasExternalExit {
+ continue
+ }
+
+ hasDoneGuard := false
+ hasBlocking := false
+ for _, block := range region.blocks {
+ feature := features[block]
+ if feature.hasDoneGuard {
+ hasDoneGuard = true
+ }
+ if feature.hasBlocking {
+ hasBlocking = true
+ }
+ if hasDoneGuard && hasBlocking {
+ break
+ }
+ }
+
+ if hasDoneGuard || !hasBlocking {
+ continue
+ }
+
+ s.addIssue(region.pos, msgLoopWithoutDone, issue.High, issue.Low)
+ }
+}
+
+type blockFeatures struct {
+ hasDoneGuard bool
+ hasBlocking bool
+}
+
+func analyzeBlockFeatures(block *ssa.BasicBlock) blockFeatures {
+ features := blockFeatures{}
+ for _, instr := range block.Instrs {
+ callInstr, ok := instr.(ssa.CallInstruction)
+ if !ok {
+ switch i := instr.(type) {
+ case *ssa.Go:
+ features.hasBlocking = true
+ case *ssa.Call:
+ if looksLikeBlockingCall(i.Common()) {
+ features.hasBlocking = true
+ }
+ case *ssa.Defer:
+ if looksLikeBlockingCall(i.Common()) {
+ features.hasBlocking = true
+ }
+ }
+ continue
+ }
+ common := callInstr.Common()
+ if common == nil {
+ continue
+ }
+ if isContextDoneCall(common) {
+ features.hasDoneGuard = true
+ }
+ if looksLikeBlockingCall(common) {
+ features.hasBlocking = true
+ }
+ }
+ return features
+}
+
+type loopRegion struct {
+ blocks []*ssa.BasicBlock
+ hasExternalExit bool
+ pos token.Pos
+}
+
+func findLoopRegions(fn *ssa.Function) []loopRegion {
+ if fn == nil || len(fn.Blocks) == 0 {
+ return nil
+ }
+
+ var regions []loopRegion
+ index := 0
+ stack := make([]*ssa.BasicBlock, 0, len(fn.Blocks))
+ onStack := make(map[*ssa.BasicBlock]bool, len(fn.Blocks))
+ indexMap := make(map[*ssa.BasicBlock]int, len(fn.Blocks))
+ lowLink := make(map[*ssa.BasicBlock]int, len(fn.Blocks))
+
+ var strongConnect func(v *ssa.BasicBlock)
+ strongConnect = func(v *ssa.BasicBlock) {
+ indexMap[v] = index
+ lowLink[v] = index
+ index++
+
+ stack = append(stack, v)
+ onStack[v] = true
+
+ for _, w := range v.Succs {
+ if w == nil {
+ continue
+ }
+ if _, seen := indexMap[w]; !seen {
+ strongConnect(w)
+ if lowLink[w] < lowLink[v] {
+ lowLink[v] = lowLink[w]
+ }
+ } else if onStack[w] {
+ if indexMap[w] < lowLink[v] {
+ lowLink[v] = indexMap[w]
+ }
+ }
+ }
+
+ if lowLink[v] != indexMap[v] {
+ return
+ }
+
+ scc := make([]*ssa.BasicBlock, 0, 4)
+ sccSet := make(map[*ssa.BasicBlock]bool, 4)
+ for {
+ n := stack[len(stack)-1]
+ stack = stack[:len(stack)-1]
+ onStack[n] = false
+ scc = append(scc, n)
+ sccSet[n] = true
+ if n == v {
+ break
+ }
+ }
+
+ if !isLoopSCC(scc, sccSet) {
+ return
+ }
+
+ hasExternalExit := false
+ pos := token.NoPos
+ for _, b := range scc {
+ if pos == token.NoPos && len(b.Instrs) > 0 {
+ pos = b.Instrs[0].Pos()
+ }
+ for _, succ := range b.Succs {
+ if succ == nil {
+ continue
+ }
+ if !sccSet[succ] {
+ hasExternalExit = true
+ break
+ }
+ }
+ if hasExternalExit {
+ break
+ }
+ }
+
+ if pos == token.NoPos {
+ for _, instr := range v.Instrs {
+ if instr.Pos() != token.NoPos {
+ pos = instr.Pos()
+ break
+ }
+ }
+ }
+
+ regions = append(regions, loopRegion{
+ blocks: scc,
+ hasExternalExit: hasExternalExit,
+ pos: pos,
+ })
+ }
+
+ for _, block := range fn.Blocks {
+ if block == nil {
+ continue
+ }
+ if _, seen := indexMap[block]; seen {
+ continue
+ }
+ strongConnect(block)
+ }
+
+ return regions
+}
+
+func isLoopSCC(scc []*ssa.BasicBlock, sccSet map[*ssa.BasicBlock]bool) bool {
+ if len(scc) > 1 {
+ return true
+ }
+ if len(scc) == 0 {
+ return false
+ }
+ b := scc[0]
+ for _, succ := range b.Succs {
+ if succ == b || sccSet[succ] {
+ return true
+ }
+ }
+ return false
+}
+
+func looksLikeBlockingCall(common *ssa.CallCommon) bool {
+ if common == nil {
+ return false
+ }
+
+ if common.IsInvoke() {
+ name := ""
+ if common.Method != nil {
+ name = common.Method.Name()
+ }
+ switch name {
+ case "Do", "RoundTrip", "QueryContext", "ExecContext", "Read", "Write", "Recv", "Send":
+ return true
+ }
+ return false
+ }
+
+ callee := common.StaticCallee()
+ if callee == nil || callee.Pkg == nil || callee.Pkg.Pkg == nil {
+ return false
+ }
+
+ pkgPath := callee.Pkg.Pkg.Path()
+ name := callee.Name()
+
+ if pkgPath == "time" && name == "Sleep" {
+ return true
+ }
+
+ if pkgPath == "net/http" {
+ switch name {
+ case "Get", "Head", "Post", "PostForm":
+ return true
+ }
+ }
+
+ if pkgPath == "database/sql" {
+ switch name {
+ case "Query", "QueryContext", "Exec", "ExecContext", "Begin", "BeginTx":
+ return true
+ }
+ }
+
+ if pkgPath == "os" {
+ switch name {
+ case "ReadFile", "WriteFile", "Open", "OpenFile":
+ return true
+ }
+ }
+
+ return false
+}
+
+func resolveGoCallTargets(goInstr *ssa.Go) []*ssa.Function {
+ var funcs []*ssa.Function
+ if goInstr == nil {
+ return funcs
+ }
+
+ value := goInstr.Call.Value
+ if value == nil {
+ return funcs
+ }
+
+ s := &BaseAnalyzerState{ClosureCache: make(map[ssa.Value]bool)}
+ s.ResolveFuncs(value, &funcs)
+ return funcs
+}
+
+func safeReferrers(v ssa.Value) []ssa.Instruction {
+ if v == nil {
+ return nil
+ }
+ refs := v.Referrers()
+ if refs == nil {
+ return nil
+ }
+ return *refs
+}
+
+func functionCallsBackground(fn *ssa.Function) bool {
+ if fn == nil {
+ return false
+ }
+ for _, block := range fn.Blocks {
+ for _, instr := range block.Instrs {
+ callInstr, ok := instr.(ssa.CallInstruction)
+ if !ok {
+ continue
+ }
+ common := callInstr.Common()
+ if common == nil {
+ continue
+ }
+ if isBackgroundOrTodoCall(common) {
+ return true
+ }
+ }
+ }
+ return false
+}
+
+func isBackgroundOrTodoValue(v ssa.Value) bool {
+ call, ok := v.(*ssa.Call)
+ if !ok {
+ return false
+ }
+ return isBackgroundOrTodoCall(call.Common())
+}
+
+func isBackgroundOrTodoCall(common *ssa.CallCommon) bool {
+ if common == nil {
+ return false
+ }
+ callee := common.StaticCallee()
+ if callee == nil || callee.Pkg == nil || callee.Pkg.Pkg == nil {
+ return false
+ }
+ if callee.Pkg.Pkg.Path() != contextPkgPath {
+ return false
+ }
+ switch callee.Name() {
+ case "Background", "TODO":
+ return true
+ default:
+ return false
+ }
+}
+
+func isContextWithFamily(common *ssa.CallCommon) bool {
+ if common == nil {
+ return false
+ }
+ callee := common.StaticCallee()
+ if callee == nil || callee.Pkg == nil || callee.Pkg.Pkg == nil {
+ return false
+ }
+ if callee.Pkg.Pkg.Path() != contextPkgPath {
+ return false
+ }
+ switch callee.Name() {
+ case "WithCancel", "WithTimeout", "WithDeadline":
+ return true
+ default:
+ return false
+ }
+}
+
+func isHTTPRequestContextCall(common *ssa.CallCommon) bool {
+ if common == nil || common.IsInvoke() {
+ return false
+ }
+ callee := common.StaticCallee()
+ if callee == nil || callee.Signature == nil || callee.Pkg == nil || callee.Pkg.Pkg == nil {
+ return false
+ }
+ if callee.Name() != "Context" {
+ return false
+ }
+ if callee.Pkg.Pkg.Path() != httpPkgPath {
+ return false
+ }
+
+ recv := callee.Signature.Recv()
+ return recv != nil && isHTTPRequestPointerType(recv.Type())
+}
+
+func isContextDoneCall(common *ssa.CallCommon) bool {
+ if common == nil {
+ return false
+ }
+
+ if common.IsInvoke() {
+ if common.Method == nil || common.Method.Name() != "Done" {
+ return false
+ }
+ recv := common.Value
+ return recv != nil && isContextType(recv.Type())
+ }
+
+ callee := common.StaticCallee()
+ if callee == nil || callee.Signature == nil || callee.Name() != "Done" {
+ return false
+ }
+ recv := callee.Signature.Recv()
+ return recv != nil && isContextType(recv.Type())
+}
+
+func findCancelResult(tupleCall *ssa.Call) ssa.Value {
+ if tupleCall == nil {
+ return nil
+ }
+
+ for _, ref := range safeReferrers(tupleCall) {
+ extract, ok := ref.(*ssa.Extract)
+ if !ok {
+ continue
+ }
+ if extract.Index != 1 {
+ continue
+ }
+ if isCancelFuncType(extract.Type()) {
+ return extract
+ }
+ }
+
+ return nil
+}
+
+func isCancelFuncType(t types.Type) bool {
+ sig, ok := t.Underlying().(*types.Signature)
+ if !ok {
+ return false
+ }
+ if sig.Params().Len() != 0 || sig.Results().Len() != 0 {
+ return false
+ }
+ return true
+}
+
+func isCancelCalled(cancelValue ssa.Value, allFuncs []*ssa.Function) bool {
+ if cancelValue == nil {
+ return false
+ }
+
+ queue := []ssa.Value{cancelValue}
+ visited := make(map[ssa.Value]bool, 8)
+
+ for len(queue) > 0 {
+ current := queue[0]
+ queue = queue[1:]
+ if current == nil || visited[current] {
+ continue
+ }
+ visited[current] = true
+
+ for _, ref := range safeReferrers(current) {
+ switch r := ref.(type) {
+ case ssa.CallInstruction:
+ if isUsedInCall(r.Common(), current) {
+ return true
+ }
+ case *ssa.Store:
+ if r.Val != current {
+ continue
+ }
+ // Check if storing to a struct field — if so, search other
+ // methods of the same type for loads of that field + call.
+ if fa, ok := r.Addr.(*ssa.FieldAddr); ok {
+ if isCancelCalledViaStructField(fa, allFuncs) {
+ return true
+ }
+ // Check if the struct containing this field is returned,
+ // transferring cancel responsibility to the caller.
+ if isStructFieldReturnedFromFunc(fa) {
+ return true
+ }
+ // Check if any function (including closures capturing the
+ // struct) loads and calls the same field. This handles
+ // post-construction storage such as:
+ // s.cancel = cancel; defer s.cancel()
+ // s.cancel = cancel; defer func() { s.cancel() }()
+ if isFieldCalledInAnyFunc(fa, allFuncs) {
+ return true
+ }
+ }
+ // Check if storing to a package-level global variable.
+ // When cancel is stored to a global (e.g., in init()), we need
+ // to search all functions in the package for loads of that global
+ // followed by a call.
+ if global, ok := r.Addr.(*ssa.Global); ok {
+ if isGlobalCalledInAnyFunc(global, allFuncs) {
+ return true
+ }
+ }
+ queue = append(queue, r.Addr)
+ case *ssa.UnOp:
+ if r.Op == token.MUL && r.X == current {
+ queue = append(queue, r)
+ }
+ case *ssa.Phi:
+ queue = append(queue, r)
+ case *ssa.ChangeType:
+ if r.X == current {
+ queue = append(queue, r)
+ }
+ case *ssa.Convert:
+ if r.X == current {
+ queue = append(queue, r)
+ }
+ case *ssa.MakeInterface:
+ if r.X == current {
+ queue = append(queue, r)
+ }
+ case *ssa.MakeClosure:
+ // The cancel value is captured as a free variable in a closure.
+ // Find the corresponding FreeVar inside the closure body and
+ // follow it so that calls within the closure are detected.
+ if fn, ok := r.Fn.(*ssa.Function); ok {
+ for i, binding := range r.Bindings {
+ if binding == current && i < len(fn.FreeVars) {
+ queue = append(queue, fn.FreeVars[i])
+ }
+ }
+ }
+ case *ssa.Return:
+ // Cancel function is returned to the caller — responsibility
+ // is transferred; treat as "called".
+ for _, result := range r.Results {
+ if result == current {
+ return true
+ }
+ }
+ }
+ }
+ }
+
+ return false
+}
+
+// isStructFieldReturnedFromFunc checks whether the struct that owns a FieldAddr
+// is loaded and returned from the enclosing function. When a cancel is stored in
+// a struct field and the struct is returned, responsibility for calling the
+// cancel is transferred to the caller.
+func isStructFieldReturnedFromFunc(fa *ssa.FieldAddr) bool {
+ structBase := fa.X
+ if structBase == nil {
+ return false
+ }
+
+ // Follow referrers of the struct base pointer to find loads (*struct)
+ // that are then returned.
+ for _, ref := range safeReferrers(structBase) {
+ load, ok := ref.(*ssa.UnOp)
+ if !ok || load.Op != token.MUL {
+ continue
+ }
+ for _, loadRef := range safeReferrers(load) {
+ if _, ok := loadRef.(*ssa.Return); ok {
+ return true
+ }
+ }
+ }
+
+ return false
+}
+
+// isFieldCalledInAnyFunc checks whether a cancel function stored into a struct
+// field is subsequently called in any function (including closures) that
+// accesses the same field by struct pointer type and field index. This covers
+// post-construction storage patterns not handled by isCancelCalledViaStructField:
+//
+// s.cancel = cancel; defer s.cancel()
+// s.cancel = cancel; defer func() { s.cancel() }()
+func isFieldCalledInAnyFunc(fa *ssa.FieldAddr, allFuncs []*ssa.Function) bool {
+ structPtrType := fa.X.Type()
+ fieldIdx := fa.Field
+
+ for _, fn := range allFuncs {
+ if fn == nil {
+ continue
+ }
+ for _, block := range fn.Blocks {
+ for _, instr := range block.Instrs {
+ otherFA, ok := instr.(*ssa.FieldAddr)
+ if !ok || otherFA.Field != fieldIdx {
+ continue
+ }
+ if !types.Identical(otherFA.X.Type(), structPtrType) {
+ continue
+ }
+ if isFieldValueCalled(otherFA) {
+ return true
+ }
+ }
+ }
+ }
+ return false
+}
+
+// isGlobalCalledInAnyFunc checks whether a cancel function stored into a
+// package-level global variable is subsequently called in any function
+// (including init(), main(), signal handlers, etc.). This handles patterns
+// like:
+//
+// var cancel context.CancelFunc
+// func init() { _, cancel = context.WithCancel(ctx) }
+// func shutdown() { cancel() }
+func isGlobalCalledInAnyFunc(global *ssa.Global, allFuncs []*ssa.Function) bool {
+ if global == nil {
+ return false
+ }
+
+ // Iterate through all functions in the package to find loads from this global
+ for _, fn := range allFuncs {
+ if fn == nil || fn.Blocks == nil {
+ continue
+ }
+
+ for _, block := range fn.Blocks {
+ for _, instr := range block.Instrs {
+ // Look for UnOp (dereference/load) from the global
+ unop, ok := instr.(*ssa.UnOp)
+ if !ok || unop.Op != token.MUL {
+ continue
+ }
+
+ // Check if this load is from our global
+ if unop.X != global {
+ continue
+ }
+
+ // Check if the loaded value is eventually called
+ if isValueCalled(unop) {
+ return true
+ }
+ }
+ }
+ }
+
+ return false
+}
+
+// isValueCalled checks if a value (typically a loaded function pointer) is
+// eventually used as a callee. This performs a BFS through value referrers
+// to find calls, handling phi nodes, stores/loads, type conversions, and closures.
+func isValueCalled(value ssa.Value) bool {
+ if value == nil {
+ return false
+ }
+
+ refs := value.Referrers()
+ if refs == nil {
+ return false
+ }
+
+ queue := []ssa.Value{value}
+ visited := make(map[ssa.Value]bool)
+
+ for len(queue) > 0 {
+ cur := queue[0]
+ queue = queue[1:]
+
+ if cur == nil || visited[cur] {
+ continue
+ }
+ visited[cur] = true
+
+ curRefs := cur.Referrers()
+ if curRefs == nil {
+ continue
+ }
+
+ for _, ref := range *curRefs {
+ switch r := ref.(type) {
+ case ssa.CallInstruction:
+ // Check if cur is used as the callee or an argument
+ if isUsedInCall(r.Common(), cur) {
+ return true
+ }
+ case *ssa.Phi:
+ // Value flows through phi node - continue tracking
+ queue = append(queue, r)
+ case *ssa.Store:
+ // Stored then loaded elsewhere - follow the address
+ if r.Val == cur {
+ queue = append(queue, r.Addr)
+ }
+ case *ssa.UnOp:
+ // Dereference or other operation - continue tracking
+ if r.X == cur {
+ queue = append(queue, r)
+ }
+ case *ssa.ChangeType:
+ // Type conversion - continue tracking
+ if r.X == cur {
+ queue = append(queue, r)
+ }
+ case *ssa.Convert:
+ // Type conversion - continue tracking
+ if r.X == cur {
+ queue = append(queue, r)
+ }
+ case *ssa.MakeInterface:
+ // Wrapped in interface - continue tracking
+ if r.X == cur {
+ queue = append(queue, r)
+ }
+ case *ssa.MakeClosure:
+ // Captured in closure - follow into closure body
+ if fn, ok := r.Fn.(*ssa.Function); ok {
+ for i, binding := range r.Bindings {
+ if binding == cur && i < len(fn.FreeVars) {
+ queue = append(queue, fn.FreeVars[i])
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return false
+}
+
+// isCancelCalledViaStructField checks whether a cancel function stored into a
+// struct field (e.g., job.cancelFn = cancel) is subsequently called in any other
+// method of the same receiver type (e.g., job.Close() calls job.cancelFn()).
+func isCancelCalledViaStructField(storeFA *ssa.FieldAddr, allFuncs []*ssa.Function) bool {
+ // Get the field index and the receiver pointer type
+ fieldIdx := storeFA.Field
+ structPtrType := storeFA.X.Type()
+
+ for _, fn := range allFuncs {
+ if fn == nil || fn.Blocks == nil {
+ continue
+ }
+ // Only check methods on the same receiver type
+ if fn.Signature == nil || fn.Signature.Recv() == nil {
+ continue
+ }
+ if !types.Identical(fn.Signature.Recv().Type(), structPtrType) {
+ continue
+ }
+
+ // Look for a load of the same field followed by a call
+ for _, block := range fn.Blocks {
+ for _, instr := range block.Instrs {
+ fa, ok := instr.(*ssa.FieldAddr)
+ if !ok || fa.Field != fieldIdx {
+ continue
+ }
+ // Check that this FieldAddr is on the receiver (Params[0])
+ if len(fn.Params) == 0 {
+ continue
+ }
+ if !reachesParam(fa.X, fn.Params[0]) {
+ continue
+ }
+ // Check if the value loaded from this field is eventually called
+ if isFieldValueCalled(fa) {
+ return true
+ }
+ }
+ }
+ }
+ return false
+}
+
+// reachesParam checks if a value traces back to the given parameter,
+// following through pointer dereferences and phi nodes.
+func reachesParam(v ssa.Value, param *ssa.Parameter) bool {
+ seen := make(map[ssa.Value]bool)
+ return reachesParamImpl(v, param, seen)
+}
+
+func reachesParamImpl(v ssa.Value, param *ssa.Parameter, seen map[ssa.Value]bool) bool {
+ if v == nil || seen[v] {
+ return false
+ }
+ seen[v] = true
+
+ if v == param {
+ return true
+ }
+ switch val := v.(type) {
+ case *ssa.UnOp:
+ return reachesParamImpl(val.X, param, seen)
+ case *ssa.Phi:
+ for _, e := range val.Edges {
+ if reachesParamImpl(e, param, seen) {
+ return true
+ }
+ }
+ case *ssa.FieldAddr:
+ return reachesParamImpl(val.X, param, seen)
+ }
+ return false
+}
+
+// isFieldValueCalled checks if the value loaded from a FieldAddr is eventually
+// used as a callee (i.e., the loaded function pointer is called).
+func isFieldValueCalled(fa *ssa.FieldAddr) bool {
+ refs := fa.Referrers()
+ if refs == nil {
+ return false
+ }
+ for _, ref := range *refs {
+ // Look for a load (UnOp MUL = pointer dereference)
+ unop, ok := ref.(*ssa.UnOp)
+ if !ok || unop.Op != token.MUL {
+ continue
+ }
+ // Check if the loaded value is called
+ loadRefs := unop.Referrers()
+ if loadRefs == nil {
+ continue
+ }
+ queue := []ssa.Value{unop}
+ visited := make(map[ssa.Value]bool)
+ for len(queue) > 0 {
+ cur := queue[0]
+ queue = queue[1:]
+ if cur == nil || visited[cur] {
+ continue
+ }
+ visited[cur] = true
+ curRefs := cur.Referrers()
+ if curRefs == nil {
+ continue
+ }
+ for _, r := range *curRefs {
+ switch rr := r.(type) {
+ case ssa.CallInstruction:
+ if isUsedInCall(rr.Common(), cur) {
+ return true
+ }
+ case *ssa.Phi:
+ queue = append(queue, rr)
+ case *ssa.Store:
+ // stored then loaded elsewhere — follow addr
+ if rr.Val == cur {
+ queue = append(queue, rr.Addr)
+ }
+ case *ssa.UnOp:
+ if rr.X == cur {
+ queue = append(queue, rr)
+ }
+ }
+ }
+ }
+ }
+ return false
+}
+
+func isUsedInCall(common *ssa.CallCommon, target ssa.Value) bool {
+ if common == nil || target == nil {
+ return false
+ }
+ if common.Value == target {
+ return true
+ }
+ for _, arg := range common.Args {
+ if arg == target {
+ return true
+ }
+ }
+ return false
+}
+
+func isContextType(t types.Type) bool {
+ named, ok := t.(*types.Named)
+ if ok {
+ if obj := named.Obj(); obj != nil && obj.Name() == "Context" {
+ if pkg := obj.Pkg(); pkg != nil && pkg.Path() == contextPkgPath {
+ return true
+ }
+ }
+ }
+
+ iface, ok := t.Underlying().(*types.Interface)
+ if !ok {
+ return false
+ }
+
+ methodDone, _, _ := types.LookupFieldOrMethod(t, true, nil, "Done")
+ methodErr, _, _ := types.LookupFieldOrMethod(t, true, nil, "Err")
+ methodValue, _, _ := types.LookupFieldOrMethod(t, true, nil, "Value")
+ methodDeadline, _, _ := types.LookupFieldOrMethod(t, true, nil, "Deadline")
+
+ if iface.NumMethods() < 4 {
+ return false
+ }
+
+ return methodDone != nil && methodErr != nil && methodValue != nil && methodDeadline != nil
+}
+
+func isHTTPRequestPointerType(t types.Type) bool {
+ ptr, ok := t.(*types.Pointer)
+ if !ok {
+ return false
+ }
+ named, ok := ptr.Elem().(*types.Named)
+ if !ok {
+ return false
+ }
+ obj := named.Obj()
+ if obj == nil || obj.Name() != "Request" {
+ return false
+ }
+ pkg := obj.Pkg()
+ return pkg != nil && pkg.Path() == httpPkgPath
+}
diff --git a/vendor/github.com/securego/gosec/v2/analyzers/conversion_overflow.go b/vendor/github.com/securego/gosec/v2/analyzers/conversion_overflow.go
index 42e186710..2c3c7d869 100644
--- a/vendor/github.com/securego/gosec/v2/analyzers/conversion_overflow.go
+++ b/vendor/github.com/securego/gosec/v2/analyzers/conversion_overflow.go
@@ -15,45 +15,19 @@
package analyzers
import (
- "cmp"
"fmt"
- "go/token"
+ "go/types"
"math"
- "regexp"
- "strconv"
- "strings"
"golang.org/x/tools/go/analysis"
"golang.org/x/tools/go/analysis/passes/buildssa"
"golang.org/x/tools/go/ssa"
+ "github.com/securego/gosec/v2/internal/ssautil"
"github.com/securego/gosec/v2/issue"
)
-type integer struct {
- signed bool
- size int
- min int
- max uint
-}
-
-type rangeResult struct {
- minValue int
- maxValue uint
- explicitPositiveVals []uint
- explicitNegativeVals []int
- isRangeCheck bool
- convertFound bool
-}
-
-type branchResults struct {
- minValue *int
- maxValue *uint
- explicitPositiveVals []uint
- explicitNegativeVals []int
- convertFound bool
-}
-
+// newConversionOverflowAnalyzer creates a new analysis.Analyzer for detecting integer overflows in conversions.
func newConversionOverflowAnalyzer(id string, description string) *analysis.Analyzer {
return &analysis.Analyzer{
Name: id,
@@ -63,32 +37,84 @@ func newConversionOverflowAnalyzer(id string, description string) *analysis.Anal
}
}
-func runConversionOverflow(pass *analysis.Pass) (interface{}, error) {
- ssaResult, err := getSSAResult(pass)
+type conversionPair struct {
+ src types.BasicKind
+ dst types.BasicKind
+}
+
+type overflowState struct {
+ *BaseAnalyzerState
+ msgCache map[conversionPair]string
+}
+
+func newOverflowState(pass *analysis.Pass) *overflowState {
+ return &overflowState{
+ BaseAnalyzerState: NewBaseState(pass),
+ msgCache: make(map[conversionPair]string),
+ }
+}
+
+// runConversionOverflow analyzes the SSA representation of the code to find potential integer overflows in type conversions.
+func runConversionOverflow(pass *analysis.Pass) (any, error) {
+ ssaResult, err := ssautil.GetSSAResult(pass)
if err != nil {
return nil, fmt.Errorf("building ssa representation: %w", err)
}
+ state := newOverflowState(pass)
+ defer state.Release()
issues := []*issue.Issue{}
for _, mcall := range ssaResult.SSA.SrcFuncs {
+ state.Reset()
for _, block := range mcall.DomPreorder() {
for _, instr := range block.Instrs {
switch instr := instr.(type) {
case *ssa.Convert:
- src := instr.X.Type().Underlying().String()
- dst := instr.Type().Underlying().String()
- if isIntOverflow(src, dst) {
- if isSafeConversion(instr) {
+ srcInfo, err := GetIntTypeInfo(instr.X.Type())
+ if err != nil {
+ continue
+ }
+ dstInfo, err := GetIntTypeInfo(instr.Type())
+ if err != nil {
+ continue
+ }
+
+ // Skip conversions between platform-word-sized
+ // types (e.g. uintptr -> int) since they never
+ // truncate bits.
+ if isSameWidthPlatformConversion(instr.X.Type(), instr.Type()) {
+ continue
+ }
+
+ if hasOverflow(srcInfo, dstInfo) {
+ if state.isSafeConversion(instr, dstInfo) {
continue
}
- issue := newIssue(pass.Analyzer.Name,
- fmt.Sprintf("integer overflow conversion %s -> %s", src, dst),
+
+ srcBasic, _ := instr.X.Type().Underlying().(*types.Basic)
+ dstBasic, _ := instr.Type().Underlying().(*types.Basic)
+
+ if srcBasic == nil || dstBasic == nil {
+ continue
+ }
+
+ pair := conversionPair{
+ src: srcBasic.Kind(),
+ dst: dstBasic.Kind(),
+ }
+ msg, ok := state.msgCache[pair]
+ if !ok {
+ msg = fmt.Sprintf("integer overflow conversion %s -> %s", srcBasic.Name(), dstBasic.Name())
+ state.msgCache[pair] = msg
+ }
+
+ issues = append(issues, newIssue(pass.Analyzer.Name,
+ msg,
pass.Fset,
instr.Pos(),
issue.High,
issue.Medium,
- )
- issues = append(issues, issue)
+ ))
}
}
}
@@ -101,459 +127,213 @@ func runConversionOverflow(pass *analysis.Pass) (interface{}, error) {
return nil, nil
}
-func isIntOverflow(src string, dst string) bool {
- srcInt, err := parseIntType(src)
- if err != nil {
- return false
- }
-
- dstInt, err := parseIntType(dst)
- if err != nil {
- return false
- }
-
- return srcInt.min < dstInt.min || srcInt.max > dstInt.max
-}
-
-func parseIntType(intType string) (integer, error) {
- re := regexp.MustCompile(`^(?Pu?int)(?P\d{1,2})?$`)
- matches := re.FindStringSubmatch(intType)
- if matches == nil {
- return integer{}, fmt.Errorf("no integer type match found for %s", intType)
- }
-
- it := matches[re.SubexpIndex("type")]
- is := matches[re.SubexpIndex("size")]
-
- signed := it == "int"
-
- // use default system int type in case size is not present in the type.
- intSize := strconv.IntSize
- if is != "" {
- var err error
- intSize, err = strconv.Atoi(is)
- if err != nil {
- return integer{}, fmt.Errorf("failed to parse the integer type size: %w", err)
- }
- }
-
- if intSize != 8 && intSize != 16 && intSize != 32 && intSize != 64 && is != "" {
- return integer{}, fmt.Errorf("invalid bit size: %d", intSize)
- }
-
- var minVal int
- var maxVal uint
-
- if signed {
- shiftAmount := intSize - 1
-
- // Perform a bounds check.
- if shiftAmount < 0 {
- return integer{}, fmt.Errorf("invalid shift amount: %d", shiftAmount)
- }
-
- maxVal = (1 << uint(shiftAmount)) - 1
- minVal = -1 << (intSize - 1)
-
- } else {
- maxVal = (1 << uint(intSize)) - 1
- minVal = 0
- }
-
- return integer{
- signed: signed,
- size: intSize,
- min: minVal,
- max: maxVal,
- }, nil
-}
-
-func isSafeConversion(instr *ssa.Convert) bool {
- dstType := instr.Type().Underlying().String()
-
+// isSafeConversion checks if a specific conversion instruction is safe from overflow, considering logic and constraints.
+func (s *overflowState) isSafeConversion(instr *ssa.Convert, dstInt IntTypeInfo) bool {
// Check for constant conversions.
if constVal, ok := instr.X.(*ssa.Const); ok {
- if isConstantInRange(constVal, dstType) {
+ if IsConstantInTypeRange(constVal, dstInt) {
return true
}
}
- // Check for string to integer conversions with specified bit size.
- if isStringToIntConversion(instr, dstType) {
- return true
- }
-
// Check for explicit range checks.
- if hasExplicitRangeCheck(instr, dstType) {
+ if s.hasRangeCheck(instr.X, dstInt, instr.Block()) {
return true
}
-
return false
}
-func isConstantInRange(constVal *ssa.Const, dstType string) bool {
- value, err := strconv.ParseInt(constVal.Value.String(), 10, 64)
- if err != nil {
- return false
- }
+func hasOverflow(srcInfo, dstInfo IntTypeInfo) bool {
+ return srcInfo.Min < dstInfo.Min || srcInfo.Max > dstInfo.Max
+}
- dstInt, err := parseIntType(dstType)
- if err != nil {
+// isSameWidthPlatformConversion returns true when both the source
+// and destination are platform-word-sized integer types (e.g.
+// uintptr -> int). These conversions never truncate bits because
+// Go guarantees both types have the same width on every platform.
+func isSameWidthPlatformConversion(src, dst types.Type) bool {
+ srcBasic, _ := src.Underlying().(*types.Basic)
+ dstBasic, _ := dst.Underlying().(*types.Basic)
+ if srcBasic == nil || dstBasic == nil {
return false
}
-
- if dstInt.signed {
- return value >= -(1<<(dstInt.size-1)) && value <= (1<<(dstInt.size-1))-1
- }
- return value >= 0 && value <= (1< dstInt.min && maxValue < dstInt.max {
+ // Check for explicit values
+ if ExplicitValsInRange(res.explicitPositiveVals, res.explicitNegativeVals, dstInt) {
return true
}
- visitedIfs := make(map[*ssa.If]bool)
- for _, block := range instr.Parent().Blocks {
- for _, blockInstr := range block.Instrs {
- switch v := blockInstr.(type) {
- case *ssa.If:
- result := getResultRange(v, instr, visitedIfs)
- if result.isRangeCheck {
- minValue = max(minValue, result.minValue)
- maxValue = min(maxValue, result.maxValue)
- explicitPositiveVals = append(explicitPositiveVals, result.explicitPositiveVals...)
- explicitNegativeVals = append(explicitNegativeVals, result.explicitNegativeVals...)
- }
- case *ssa.Call:
- // These function return an int of a guaranteed size.
- if v != instr.X {
- continue
- }
- if fn, isBuiltin := v.Call.Value.(*ssa.Builtin); isBuiltin {
- switch fn.Name() {
- case "len", "cap":
- minValue = 0
- }
- }
- }
-
- if explicitValsInRange(explicitPositiveVals, explicitNegativeVals, dstInt) {
- return true
- } else if minValue >= dstInt.min && maxValue <= dstInt.max {
- return true
+ // Check all predecessors for OR support.
+ if len(block.Preds) > 1 {
+ allPredsSafe := true
+ for _, pred := range block.Preds {
+ if !s.isSafeFromPredecessor(v, dstInt, pred, block) {
+ allPredsSafe = false
+ break
}
}
+ if allPredsSafe {
+ return true
+ }
}
- return false
-}
-
-// getResultRange is a recursive function that walks the branches of the if statement to find the range of the variable.
-func getResultRange(ifInstr *ssa.If, instr *ssa.Convert, visitedIfs map[*ssa.If]bool) rangeResult {
- if visitedIfs[ifInstr] {
- return rangeResult{minValue: math.MinInt, maxValue: math.MaxUint}
- }
- visitedIfs[ifInstr] = true
-
- cond := ifInstr.Cond
- binOp, ok := cond.(*ssa.BinOp)
- if !ok || !isRangeCheck(binOp, instr.X) {
- return rangeResult{minValue: math.MinInt, maxValue: math.MaxUint}
- }
-
- result := rangeResult{
- minValue: math.MinInt,
- maxValue: math.MaxUint,
- isRangeCheck: true,
- }
-
- thenBounds := walkBranchForConvert(ifInstr.Block().Succs[0], instr, visitedIfs)
- elseBounds := walkBranchForConvert(ifInstr.Block().Succs[1], instr, visitedIfs)
- updateResultFromBinOp(&result, binOp, instr, thenBounds.convertFound)
+ // Relax requirement: If we have a definitive range (both set) and it's safe,
+ // we allow it even if not explicitly "checked" by an IF,
+ // because definition-based ranges (like constants or arithmetic on constants) are certain.
+ isDefinitiveSafe := res.minValueSet && res.maxValueSet
- if thenBounds.convertFound {
- result.convertFound = true
- result.minValue = maxWithPtr(result.minValue, thenBounds.minValue)
- result.maxValue = minWithPtr(result.maxValue, thenBounds.maxValue)
- } else if elseBounds.convertFound {
- result.convertFound = true
- result.minValue = maxWithPtr(result.minValue, elseBounds.minValue)
- result.maxValue = minWithPtr(result.maxValue, elseBounds.maxValue)
+ if !res.isRangeCheck && !isDefinitiveSafe {
+ return false
}
- result.explicitPositiveVals = append(result.explicitPositiveVals, thenBounds.explicitPositiveVals...)
- result.explicitNegativeVals = append(result.explicitNegativeVals, thenBounds.explicitNegativeVals...)
- result.explicitPositiveVals = append(result.explicitPositiveVals, elseBounds.explicitPositiveVals...)
- result.explicitNegativeVals = append(result.explicitNegativeVals, elseBounds.explicitNegativeVals...)
-
- return result
+ return s.validateRangeLimits(v, res, dstInt)
}
-// updateResultFromBinOp updates the rangeResult based on the BinOp instruction and the location of the Convert instruction.
-func updateResultFromBinOp(result *rangeResult, binOp *ssa.BinOp, instr *ssa.Convert, successPathConvert bool) {
- x, y := binOp.X, binOp.Y
- operandsFlipped := false
+func (s *overflowState) validateRangeLimits(v ssa.Value, res *rangeResult, dstInt IntTypeInfo) bool {
+ minValue, minValueSet, maxValue, maxValueSet := res.minValue, res.minValueSet, res.maxValue, res.maxValueSet
+ isSrcUnsigned := isUint(v)
- compareVal, op := getRealValueFromOperation(instr.X)
-
- // Handle FieldAddr
- if fieldAddr, ok := compareVal.(*ssa.FieldAddr); ok {
- compareVal = fieldAddr
+ // Check for impossible ranges (disjoint)
+ if !isSrcUnsigned {
+ if minValueSet && maxValueSet && toInt64(minValue) > toInt64(maxValue) {
+ return true
+ }
}
-
- if !isSameOrRelated(x, compareVal) {
- y = x
- operandsFlipped = true
+ if isSrcUnsigned && minValueSet && maxValueSet && minValue > maxValue {
+ return true
}
- constVal, ok := y.(*ssa.Const)
- if !ok {
- return
- }
- // TODO: constVal.Value nil check avoids #1229 panic but seems to be hiding a bug in the code above or in x/tools/go/ssa.
- if constVal.Value == nil {
- // log.Fatalf("[gosec] constVal.Value is nil flipped=%t, constVal=%#v, binOp=%#v", operandsFlipped, constVal, binOp)
- return
- }
- switch binOp.Op {
- case token.LEQ, token.LSS:
- updateMinMaxForLessOrEqual(result, constVal, binOp.Op, operandsFlipped, successPathConvert)
- case token.GEQ, token.GTR:
- updateMinMaxForGreaterOrEqual(result, constVal, binOp.Op, operandsFlipped, successPathConvert)
- case token.EQL:
- if !successPathConvert {
- break
- }
- updateExplicitValues(result, constVal)
- case token.NEQ:
- if successPathConvert {
- break
- }
- updateExplicitValues(result, constVal)
+ srcInt, err := GetIntTypeInfo(v.Type())
+ if err != nil {
+ return false
}
- if op == "neg" {
- minVal := result.minValue
- maxVal := result.maxValue
-
- if minVal >= 0 {
- result.maxValue = uint(minVal)
+ if dstInt.Signed {
+ if isSrcUnsigned {
+ return maxValueSet && maxValue <= dstInt.Max
}
- if maxVal <= math.MaxInt {
- result.minValue = int(maxVal)
+ minSafe := true
+ if srcInt.Min < dstInt.Min {
+ minSafe = minValueSet && toInt64(minValue) >= dstInt.Min
}
+ maxSafe := true
+ if srcInt.Max > dstInt.Max {
+ maxSafe = maxValueSet && toInt64(maxValue) <= toInt64(dstInt.Max)
+ }
+ return minSafe && maxSafe
}
-}
-
-func updateExplicitValues(result *rangeResult, constVal *ssa.Const) {
- if strings.Contains(constVal.String(), "-") {
- result.explicitNegativeVals = append(result.explicitNegativeVals, int(constVal.Int64()))
- } else {
- result.explicitPositiveVals = append(result.explicitPositiveVals, uint(constVal.Uint64()))
+ if isSrcUnsigned {
+ return maxValueSet && maxValue <= dstInt.Max
}
-}
-
-func updateMinMaxForLessOrEqual(result *rangeResult, constVal *ssa.Const, op token.Token, operandsFlipped bool, successPathConvert bool) {
- // If the success path has a conversion and the operands are not flipped, then the constant value is the maximum value.
- if successPathConvert && !operandsFlipped {
- result.maxValue = uint(constVal.Uint64())
- if op == token.LEQ {
- result.maxValue--
- }
- } else {
- result.minValue = int(constVal.Int64())
- if op == token.GTR {
- result.minValue++
+ minSafe := true
+ if srcInt.Min < 0 {
+ minBound := int64(0)
+ if res.isRangeCheck && maxValueSet && toInt64(maxValue) > signedMaxForUnsignedSize(dstInt.Size) {
+ minBound = signedMinForUnsignedSize(dstInt.Size)
}
+ minSafe = minValueSet && toInt64(minValue) >= minBound
}
-}
-
-func updateMinMaxForGreaterOrEqual(result *rangeResult, constVal *ssa.Const, op token.Token, operandsFlipped bool, successPathConvert bool) {
- // If the success path has a conversion and the operands are not flipped, then the constant value is the minimum value.
- if successPathConvert && !operandsFlipped {
- result.minValue = int(constVal.Int64())
- if op == token.GEQ {
- result.minValue++
- }
- } else {
- result.maxValue = uint(constVal.Uint64())
- if op == token.LSS {
- result.maxValue--
- }
+ maxSafe := true
+ if srcInt.Max > dstInt.Max {
+ maxSafe = maxValueSet && maxValue <= dstInt.Max
}
+ return minSafe && maxSafe
}
-// walkBranchForConvert walks the branch of the if statement to find the range of the variable and where the conversion is.
-func walkBranchForConvert(block *ssa.BasicBlock, instr *ssa.Convert, visitedIfs map[*ssa.If]bool) branchResults {
- bounds := branchResults{}
-
- for _, blockInstr := range block.Instrs {
- switch v := blockInstr.(type) {
- case *ssa.If:
- result := getResultRange(v, instr, visitedIfs)
- bounds.convertFound = bounds.convertFound || result.convertFound
-
- if result.isRangeCheck {
- bounds.minValue = toPtr(maxWithPtr(result.minValue, bounds.minValue))
- bounds.maxValue = toPtr(minWithPtr(result.maxValue, bounds.maxValue))
- bounds.explicitPositiveVals = append(bounds.explicitPositiveVals, result.explicitPositiveVals...)
- bounds.explicitNegativeVals = append(bounds.explicitNegativeVals, result.explicitNegativeVals...)
- }
- case *ssa.Call:
- if v == instr.X {
- if fn, isBuiltin := v.Call.Value.(*ssa.Builtin); isBuiltin && (fn.Name() == "len" || fn.Name() == "cap") {
- bounds.minValue = toPtr(0)
- }
- }
- case *ssa.Convert:
- if v == instr {
- bounds.convertFound = true
- return bounds
- }
- }
+func signedMinForUnsignedSize(size int) int64 {
+ if size >= 64 {
+ return math.MinInt64
}
-
- return bounds
+ return -(int64(1) << (size - 1))
}
-func isRangeCheck(v ssa.Value, x ssa.Value) bool {
- compareVal, _ := getRealValueFromOperation(x)
-
- switch op := v.(type) {
- case *ssa.BinOp:
- switch op.Op {
- case token.LSS, token.LEQ, token.GTR, token.GEQ, token.EQL, token.NEQ:
- leftMatch := isSameOrRelated(op.X, compareVal)
- rightMatch := isSameOrRelated(op.Y, compareVal)
- return leftMatch || rightMatch
- }
+func signedMaxForUnsignedSize(size int) int64 {
+ if size >= 64 {
+ return math.MaxInt64
}
- return false
+ return (int64(1) << (size - 1)) - 1
}
-func getRealValueFromOperation(v ssa.Value) (ssa.Value, string) {
- switch v := v.(type) {
- case *ssa.UnOp:
- if v.Op == token.SUB {
- val, _ := getRealValueFromOperation(v.X)
- return val, "neg"
+func (s *overflowState) isSafeFromPredecessor(v ssa.Value, dstInt IntTypeInfo, pred *ssa.BasicBlock, targetBlock *ssa.BasicBlock) bool {
+ edgeValue := v
+ if phi, ok := v.(*ssa.Phi); ok && phi.Block() == targetBlock {
+ for i, p := range targetBlock.Preds {
+ if p == pred && i < len(phi.Edges) {
+ edgeValue = phi.Edges[i]
+ break
+ }
}
- return getRealValueFromOperation(v.X)
- case *ssa.FieldAddr:
- return v, "field"
- case *ssa.Alloc:
- return v, "alloc"
}
- return v, ""
-}
-func isSameOrRelated(a, b ssa.Value) bool {
- aVal, _ := getRealValueFromOperation(a)
- bVal, _ := getRealValueFromOperation(b)
-
- if aVal == bVal {
- return true
+ if len(pred.Instrs) > 0 {
+ if vIf, ok := pred.Instrs[len(pred.Instrs)-1].(*ssa.If); ok {
+ for i, succ := range pred.Succs {
+ if succ == targetBlock {
+ result := s.Analyzer.getResultRangeForIfEdge(vIf, i == 0, edgeValue)
+ defer s.Analyzer.releaseResult(result)
+ if s.isSafeIfEdgeResult(edgeValue, dstInt, result) {
+ return true
+ }
+ }
+ }
+ }
}
- // Check if both are FieldAddr operations referring to the same field of the same struct
- if aField, aOk := aVal.(*ssa.FieldAddr); aOk {
- if bField, bOk := bVal.(*ssa.FieldAddr); bOk {
- return aField.X == bField.X && aField.Field == bField.Field
+ if len(pred.Preds) == 1 {
+ parent := pred.Preds[0]
+ if len(parent.Instrs) > 0 {
+ if vIf, ok := parent.Instrs[len(parent.Instrs)-1].(*ssa.If); ok {
+ for i, succ := range parent.Succs {
+ if succ == pred {
+ result := s.Analyzer.getResultRangeForIfEdge(vIf, i == 0, edgeValue)
+ defer s.Analyzer.releaseResult(result)
+ if s.isSafeIfEdgeResult(edgeValue, dstInt, result) {
+ return true
+ }
+ }
+ }
+ }
}
}
return false
}
-func explicitValsInRange(explicitPosVals []uint, explicitNegVals []int, dstInt integer) bool {
- if len(explicitPosVals) == 0 && len(explicitNegVals) == 0 {
+func (s *overflowState) isSafeIfEdgeResult(v ssa.Value, dstInt IntTypeInfo, result *rangeResult) bool {
+ if !result.isRangeCheck {
return false
}
- for _, val := range explicitPosVals {
- if val > dstInt.max {
- return false
+ isSrcUnsigned := isUint(v)
+ if dstInt.Signed {
+ if isSrcUnsigned {
+ return result.maxValueSet && result.maxValue <= dstInt.Max
}
+ return (result.minValueSet && toInt64(result.minValue) >= dstInt.Min) && (result.maxValueSet && toInt64(result.maxValue) <= toInt64(dstInt.Max))
}
- for _, val := range explicitNegVals {
- if val < dstInt.min {
- return false
- }
- }
-
- return true
-}
-
-func minWithPtr[T cmp.Ordered](a T, b *T) T {
- if b == nil {
- return a
+ if isSrcUnsigned {
+ return result.maxValueSet && result.maxValue <= dstInt.Max
}
- return min(a, *b)
-}
-
-func maxWithPtr[T cmp.Ordered](a T, b *T) T {
- if b == nil {
- return a
- }
- return max(a, *b)
-}
-func toPtr[T any](a T) *T {
- return &a
+ return (result.minValueSet && toInt64(result.minValue) >= 0) && (result.maxValueSet && result.maxValue <= dstInt.Max)
}
diff --git a/vendor/github.com/securego/gosec/v2/analyzers/cors_bypass_pattern.go b/vendor/github.com/securego/gosec/v2/analyzers/cors_bypass_pattern.go
new file mode 100644
index 000000000..9ddc9da61
--- /dev/null
+++ b/vendor/github.com/securego/gosec/v2/analyzers/cors_bypass_pattern.go
@@ -0,0 +1,206 @@
+// (c) Copyright gosec's authors
+//
+// 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 analyzers
+
+import (
+ "go/token"
+ "go/types"
+ "strings"
+
+ "golang.org/x/tools/go/analysis"
+ "golang.org/x/tools/go/analysis/passes/buildssa"
+ "golang.org/x/tools/go/ssa"
+
+ "github.com/securego/gosec/v2/internal/ssautil"
+ "github.com/securego/gosec/v2/issue"
+)
+
+const (
+ msgOverbroadBypassPattern = "Overbroad AddInsecureBypassPattern disables cross-origin protections for too many paths" // #nosec G101 -- Message string includes API name, not credentials.
+ msgRequestBypassPattern = "AddInsecureBypassPattern argument derived from request data can allow bypass of cross-origin protections" // #nosec G101 -- Message string includes API name, not credentials.
+)
+
+func newCORSBypassPatternAnalyzer(id string, description string) *analysis.Analyzer {
+ return &analysis.Analyzer{
+ Name: id,
+ Doc: description,
+ Run: runCORSBypassPatternAnalysis,
+ Requires: []*analysis.Analyzer{buildssa.Analyzer},
+ }
+}
+
+func runCORSBypassPatternAnalysis(pass *analysis.Pass) (any, error) {
+ ssaResult, err := ssautil.GetSSAResult(pass)
+ if err != nil {
+ return nil, err
+ }
+
+ issuesByPos := make(map[token.Pos]*issue.Issue)
+
+ for _, fn := range collectAnalyzerFunctions(ssaResult.SSA.SrcFuncs) {
+ requestParam := findHTTPRequestParam(fn)
+
+ for _, block := range fn.Blocks {
+ for _, instr := range block.Instrs {
+ callInstr, ok := instr.(ssa.CallInstruction)
+ if !ok {
+ continue
+ }
+
+ common := callInstr.Common()
+ if common == nil {
+ continue
+ }
+
+ if !isAddInsecureBypassPatternCall(common) {
+ continue
+ }
+
+ if len(common.Args) < 2 {
+ continue
+ }
+
+ patternArg := common.Args[1]
+ if pattern, ok := extractStringValue(patternArg, 0); ok {
+ if isOverbroadBypassPattern(pattern) {
+ addG121Issue(issuesByPos, pass, instr.Pos(), msgOverbroadBypassPattern, issue.High, issue.High)
+ }
+ continue
+ }
+
+ if requestParam != nil && valueDependsOn(patternArg, requestParam, 0) {
+ addG121Issue(issuesByPos, pass, instr.Pos(), msgRequestBypassPattern, issue.High, issue.Medium)
+ }
+ }
+ }
+ }
+
+ if len(issuesByPos) == 0 {
+ return nil, nil
+ }
+
+ issues := make([]*issue.Issue, 0, len(issuesByPos))
+ for _, i := range issuesByPos {
+ issues = append(issues, i)
+ }
+
+ return issues, nil
+}
+
+func addG121Issue(issues map[token.Pos]*issue.Issue, pass *analysis.Pass, pos token.Pos, what string, severity issue.Score, confidence issue.Score) {
+ if pos == token.NoPos {
+ return
+ }
+ if _, exists := issues[pos]; exists {
+ return
+ }
+ issues[pos] = newIssue(pass.Analyzer.Name, what, pass.Fset, pos, severity, confidence)
+}
+
+func findHTTPRequestParam(fn *ssa.Function) *ssa.Parameter {
+ if fn == nil {
+ return nil
+ }
+ for _, param := range fn.Params {
+ if param == nil {
+ continue
+ }
+ if isHTTPRequestPointerType(param.Type()) {
+ return param
+ }
+ }
+ return nil
+}
+
+func isAddInsecureBypassPatternCall(call *ssa.CallCommon) bool {
+ callee := call.StaticCallee()
+ if callee == nil || callee.Name() != "AddInsecureBypassPattern" {
+ return false
+ }
+
+ sig := callee.Signature
+ if sig == nil || sig.Recv() == nil {
+ return false
+ }
+
+ return isCrossOriginProtectionType(sig.Recv().Type())
+}
+
+func isCrossOriginProtectionType(t types.Type) bool {
+ if ptr, ok := t.(*types.Pointer); ok {
+ t = ptr.Elem()
+ }
+
+ named, ok := t.(*types.Named)
+ if !ok {
+ return false
+ }
+ obj := named.Obj()
+ if obj == nil || obj.Name() != "CrossOriginProtection" {
+ return false
+ }
+ pkg := obj.Pkg()
+ return pkg != nil && pkg.Path() == "net/http"
+}
+
+func extractStringValue(v ssa.Value, depth int) (string, bool) {
+ if v == nil || depth > MaxDepth {
+ return "", false
+ }
+
+ if value := extractStringConst(v); value != "" {
+ return value, true
+ }
+
+ switch x := v.(type) {
+ case *ssa.ChangeType:
+ return extractStringValue(x.X, depth+1)
+ case *ssa.MakeInterface:
+ return extractStringValue(x.X, depth+1)
+ case *ssa.TypeAssert:
+ return extractStringValue(x.X, depth+1)
+ case *ssa.Phi:
+ if len(x.Edges) == 0 {
+ return "", false
+ }
+ var candidate string
+ for _, edge := range x.Edges {
+ val, ok := extractStringValue(edge, depth+1)
+ if !ok {
+ return "", false
+ }
+ if candidate == "" {
+ candidate = val
+ continue
+ }
+ if candidate != val {
+ return "", false
+ }
+ }
+ return candidate, true
+ }
+
+ return "", false
+}
+
+func isOverbroadBypassPattern(pattern string) bool {
+ normalized := strings.TrimSpace(pattern)
+ switch normalized {
+ case "", "/", "*", "/*", "/**", ".*", "/.*":
+ return true
+ default:
+ return false
+ }
+}
diff --git a/vendor/github.com/securego/gosec/v2/analyzers/dependency_checker.go b/vendor/github.com/securego/gosec/v2/analyzers/dependency_checker.go
new file mode 100644
index 000000000..2f800ab21
--- /dev/null
+++ b/vendor/github.com/securego/gosec/v2/analyzers/dependency_checker.go
@@ -0,0 +1,116 @@
+// (c) Copyright gosec's authors
+//
+// 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 analyzers
+
+import "golang.org/x/tools/go/ssa"
+
+type dependencyKey struct {
+ value ssa.Value
+ target ssa.Value
+}
+
+type dependencyChecker struct {
+ memo map[dependencyKey]bool
+ visiting map[dependencyKey]struct{}
+}
+
+func newDependencyChecker() *dependencyChecker {
+ return &dependencyChecker{
+ memo: make(map[dependencyKey]bool),
+ visiting: make(map[dependencyKey]struct{}),
+ }
+}
+
+func (c *dependencyChecker) dependsOn(value ssa.Value, target ssa.Value) bool {
+ return c.dependsOnDepth(value, target, 0)
+}
+
+func (c *dependencyChecker) dependsOnDepth(value ssa.Value, target ssa.Value, depth int) bool {
+ if value == nil || target == nil || depth > MaxDepth {
+ return false
+ }
+ if value == target {
+ return true
+ }
+
+ key := dependencyKey{value: value, target: target}
+ if result, ok := c.memo[key]; ok {
+ return result
+ }
+ if _, ok := c.visiting[key]; ok {
+ return false
+ }
+
+ c.visiting[key] = struct{}{}
+ result := false
+
+ switch v := value.(type) {
+ case *ssa.ChangeType:
+ result = c.dependsOnDepth(v.X, target, depth+1)
+ case *ssa.MakeInterface:
+ result = c.dependsOnDepth(v.X, target, depth+1)
+ case *ssa.TypeAssert:
+ result = c.dependsOnDepth(v.X, target, depth+1)
+ case *ssa.UnOp:
+ result = c.dependsOnDepth(v.X, target, depth+1)
+ case *ssa.FieldAddr:
+ result = c.dependsOnDepth(v.X, target, depth+1)
+ case *ssa.Field:
+ result = c.dependsOnDepth(v.X, target, depth+1)
+ case *ssa.IndexAddr:
+ result = c.dependsOnDepth(v.X, target, depth+1) || c.dependsOnDepth(v.Index, target, depth+1)
+ case *ssa.Index:
+ result = c.dependsOnDepth(v.X, target, depth+1) || c.dependsOnDepth(v.Index, target, depth+1)
+ case *ssa.Slice:
+ if c.dependsOnDepth(v.X, target, depth+1) {
+ result = true
+ break
+ }
+ if v.Low != nil && c.dependsOnDepth(v.Low, target, depth+1) {
+ result = true
+ break
+ }
+ if v.High != nil && c.dependsOnDepth(v.High, target, depth+1) {
+ result = true
+ break
+ }
+ result = v.Max != nil && c.dependsOnDepth(v.Max, target, depth+1)
+ case *ssa.Extract:
+ result = c.dependsOnDepth(v.Tuple, target, depth+1)
+ case *ssa.Phi:
+ for _, edge := range v.Edges {
+ if c.dependsOnDepth(edge, target, depth+1) {
+ result = true
+ break
+ }
+ }
+ case *ssa.Call:
+ if v.Call.Value != nil && c.dependsOnDepth(v.Call.Value, target, depth+1) {
+ result = true
+ break
+ }
+ for _, arg := range v.Call.Args {
+ if c.dependsOnDepth(arg, target, depth+1) {
+ result = true
+ break
+ }
+ }
+ }
+
+ delete(c.visiting, key)
+ c.memo[key] = result
+
+ return result
+}
diff --git a/vendor/github.com/securego/gosec/v2/analyzers/form_parsing_limits.go b/vendor/github.com/securego/gosec/v2/analyzers/form_parsing_limits.go
new file mode 100644
index 000000000..8b27d6d1e
--- /dev/null
+++ b/vendor/github.com/securego/gosec/v2/analyzers/form_parsing_limits.go
@@ -0,0 +1,52 @@
+// (c) Copyright gosec's authors
+//
+// 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 analyzers
+
+import (
+ "golang.org/x/tools/go/analysis"
+
+ "github.com/securego/gosec/v2/taint"
+)
+
+// FormParsingLimits returns a taint analysis configuration for detecting
+// unbounded multipart form parsing in HTTP handlers.
+//
+// Only ParseMultipartForm is flagged because ParseForm, FormValue, and
+// PostFormValue already enforce a built-in 10 MiB body limit in Go's
+// standard library (see net/http.Request.ParseForm documentation).
+func FormParsingLimits() taint.Config {
+ return taint.Config{
+ Sources: []taint.Source{
+ {Package: "net/http", Name: "Request", Pointer: true},
+ },
+ Sinks: []taint.Sink{
+ // ParseMultipartForm reads the entire body into memory/disk with
+ // no automatic cap — the caller-supplied maxMemory only limits the
+ // in-memory portion while the total can be maxMemory + 10 MiB.
+ // Without http.MaxBytesReader the full body is consumed.
+ // CheckArgs: [0] checks only the receiver (*http.Request).
+ {Package: "net/http", Receiver: "Request", Method: "ParseMultipartForm", Pointer: true, CheckArgs: []int{0}},
+ },
+ Sanitizers: []taint.Sanitizer{},
+ }
+}
+
+func newFormParsingLimitAnalyzer(id string, description string) *analysis.Analyzer {
+ config := FormParsingLimits()
+ rule := FormParsingLimitRule
+ rule.ID = id
+ rule.Description = description
+ return taint.NewGosecAnalyzer(&rule, &config)
+}
diff --git a/vendor/github.com/securego/gosec/v2/analyzers/hardcoded_nonce.go b/vendor/github.com/securego/gosec/v2/analyzers/hardcoded_nonce.go
index 4501fb65a..210631fd3 100644
--- a/vendor/github.com/securego/gosec/v2/analyzers/hardcoded_nonce.go
+++ b/vendor/github.com/securego/gosec/v2/analyzers/hardcoded_nonce.go
@@ -15,20 +15,61 @@
package analyzers
import (
- "errors"
"fmt"
+ "go/constant"
"go/token"
+ "slices"
"strings"
+ "sync"
"golang.org/x/tools/go/analysis"
"golang.org/x/tools/go/analysis/passes/buildssa"
"golang.org/x/tools/go/ssa"
+ "github.com/securego/gosec/v2/internal/ssautil"
"github.com/securego/gosec/v2/issue"
)
const defaultIssueDescription = "Use of hardcoded IV/nonce for encryption"
+// tracked holds the function name as key, the number of arguments that the function accepts,
+// and the index of the argument that is the nonce/IV.
+// Example: "crypto/cipher.NewCBCEncrypter": {2, 1} means the function accepts 2 arguments,
+// and the nonce arg is at index 1 (the second argument).
+// Note: We only track encryption functions, not decryption functions (like NewCBCDecrypter, NewCFBDecrypter, etc.)
+// because decryption must use the same nonce as encryption, which will naturally appear as a known/hardcoded value.
+var tracked = map[string][]int{
+ "(crypto/cipher.AEAD).Seal": {4, 1},
+ "crypto/cipher.NewCBCEncrypter": {2, 1},
+ "crypto/cipher.NewCFBEncrypter": {2, 1},
+ "crypto/cipher.NewCTREncrypter": {2, 1},
+ "crypto/cipher.NewCTR": {2, 1},
+ "crypto/cipher.NewOFB": {2, 1},
+ "crypto/cipher.NewCFB": {2, 1},
+ "crypto/cipher.NewCBC": {2, 1},
+}
+
+var dynamicFuncs = map[string]bool{
+ "crypto/rand.Read": true,
+ "io.ReadFull": true,
+}
+
+var dynamicPkgs = map[string]bool{
+ "crypto/rand": true,
+ "io": true,
+}
+
+var cipherPkgPrefixes = []string{
+ "crypto/cipher",
+ "crypto/aes",
+}
+
+const (
+ statusVisiting = 1 << 0
+ statusHard = 1 << 1
+ statusDyn = 1 << 2
+)
+
func newHardCodedNonce(id string, description string) *analysis.Analyzer {
return &analysis.Analyzer{
Name: id,
@@ -38,32 +79,20 @@ func newHardCodedNonce(id string, description string) *analysis.Analyzer {
}
}
-func runHardCodedNonce(pass *analysis.Pass) (interface{}, error) {
- ssaResult, err := getSSAResult(pass)
+func runHardCodedNonce(pass *analysis.Pass) (any, error) {
+ ssaResult, err := ssautil.GetSSAResult(pass)
if err != nil {
- return nil, fmt.Errorf("building ssa representation: %w", err)
+ return nil, err
}
- // Holds the function name as key, the number of arguments that the function accepts, and at which index of those accepted arguments is the nonce/IV
- // Example "Test" 3, 1 -- means the function "Test" which accepts 3 arguments, and has the nonce arg as second argument
- calls := map[string][]int{
- "(crypto/cipher.AEAD).Seal": {4, 1},
- "crypto/cipher.NewCBCEncrypter": {2, 1},
- "crypto/cipher.NewCFBEncrypter": {2, 1},
- "crypto/cipher.NewCTR": {2, 1},
- "crypto/cipher.NewOFB": {2, 1},
- }
- ssaPkgFunctions := ssaResult.SSA.SrcFuncs
- args := getArgsFromTrackedFunctions(ssaPkgFunctions, calls)
- if args == nil {
- return nil, errors.New("no tracked functions found, resulting in no variables to track")
- }
+ state := newAnalysisState(pass, ssaResult.SSA.SrcFuncs)
+ defer state.Release()
+
+ args := state.getInitialArgs(tracked)
var issues []*issue.Issue
- for _, arg := range args {
- if arg == nil {
- continue
- }
- i, err := raiseIssue(*arg, calls, ssaPkgFunctions, pass, "")
+ for _, argInfo := range args {
+ state.Reset() // Clear visited map for each top-level arg
+ i, err := state.raiseIssue(argInfo.val, "", argInfo.instr)
if err != nil {
return issues, fmt.Errorf("raising issue error: %w", err)
}
@@ -72,180 +101,778 @@ func runHardCodedNonce(pass *analysis.Pass) (interface{}, error) {
return issues, nil
}
-func raiseIssue(val ssa.Value, funcsToTrack map[string][]int, ssaFuncs []*ssa.Function,
- pass *analysis.Pass, issueDescription string,
-) ([]*issue.Issue, error) {
+type analysisState struct {
+ *BaseAnalyzerState
+ ssaFuncs []*ssa.Function
+ usageCache map[ssa.Value]uint8
+ callerMap map[string][]*ssa.Call
+}
+
+var (
+ usageCachePool = sync.Pool{
+ New: func() any {
+ return make(map[ssa.Value]uint8, 64)
+ },
+ }
+ callerMapPool = sync.Pool{
+ New: func() any {
+ return make(map[string][]*ssa.Call, 32)
+ },
+ }
+)
+
+type ssaValueAndInstr struct {
+ val ssa.Value
+ instr ssa.Instruction
+}
+
+func newAnalysisState(pass *analysis.Pass, funcs []*ssa.Function) *analysisState {
+ s := &analysisState{
+ BaseAnalyzerState: NewBaseState(pass),
+ ssaFuncs: funcs,
+ usageCache: usageCachePool.Get().(map[ssa.Value]uint8),
+ callerMap: callerMapPool.Get().(map[string][]*ssa.Call),
+ }
+ BuildCallerMap(funcs, s.callerMap)
+ return s
+}
+
+func (s *analysisState) Release() {
+ if s.usageCache != nil {
+ clear(s.usageCache)
+ usageCachePool.Put(s.usageCache)
+ s.usageCache = nil
+ }
+ if s.callerMap != nil {
+ clear(s.callerMap)
+ callerMapPool.Put(s.callerMap)
+ s.callerMap = nil
+ }
+ s.BaseAnalyzerState.Release()
+}
+
+// isAEADOpenCall checks if a call is to AEAD.Open (decryption), which should not be flagged.
+func isAEADOpenCall(c *ssa.Call) bool {
+ if c.Call.IsInvoke() && c.Call.Method != nil {
+ name := c.Call.Method.FullName()
+ // Check if this is (crypto/cipher.AEAD).Open
+ return strings.Contains(name, "AEAD") && strings.HasSuffix(name, "Open")
+ }
+ return false
+}
+
+// getInitialArgs is now unified in util.go TraverseSSA or kept here if specific.
+// It seems specific to tracked functions, so we keep it but can use TraverseSSA.
+func (s *analysisState) getInitialArgs(tracked map[string][]int) []ssaValueAndInstr {
+ var result []ssaValueAndInstr
+ TraverseSSA(s.ssaFuncs, func(b *ssa.BasicBlock, i ssa.Instruction) {
+ if c, ok := i.(*ssa.Call); ok {
+ if c.Call.IsInvoke() {
+ // Handle interface method calls (e.g. (crypto/cipher.AEAD).Seal)
+ // Skip AEAD.Open (decryption) as it must use the same nonce as encryption
+ if isAEADOpenCall(c) {
+ return
+ }
+ name := c.Call.Method.FullName()
+ if info, ok := tracked[name]; ok {
+ if len(c.Call.Args) == info[0] {
+ result = append(result, ssaValueAndInstr{
+ val: c.Call.Args[info[1]],
+ instr: c,
+ })
+ }
+ }
+ return
+ }
+ // Handle function calls (direct or indirect)
+ clear(s.ClosureCache)
+ var funcs []*ssa.Function
+ s.ResolveFuncs(c.Call.Value, &funcs)
+ for _, fn := range funcs {
+ name := fn.String()
+ if info, ok := tracked[name]; ok {
+ if len(c.Call.Args) == info[0] {
+ result = append(result, ssaValueAndInstr{
+ val: c.Call.Args[info[1]],
+ instr: c,
+ })
+ break
+ }
+ continue
+ }
+ // Fallback to manual prefixing if needed (some SSA versions return different String())
+ name = fn.Name()
+ if fn.Pkg != nil && fn.Pkg.Pkg != nil {
+ name = fn.Pkg.Pkg.Path() + "." + name
+ }
+ if info, ok := tracked[name]; ok {
+ if len(c.Call.Args) == info[0] {
+ result = append(result, ssaValueAndInstr{
+ val: c.Call.Args[info[1]],
+ instr: c,
+ })
+ break
+ }
+ }
+ }
+ }
+ })
+ return result
+}
+
+// raiseIssue recursively analyzes the usage of a value and returns a list of issues
+// if it's found to be hardcoded or otherwise insecure.
+func (s *analysisState) raiseIssue(val ssa.Value, issueDescription string, fromInstr ssa.Instruction) ([]*issue.Issue, error) {
+ if s.Visited[val] {
+ return nil, nil
+ }
+ s.Visited[val] = true
+
+ res := s.analyzeUsage(val)
+ foundDyn := res&statusDyn != 0
+
+ if foundDyn {
+ if s.allTaintedEventsCovered(val, fromInstr) {
+ return nil, nil
+ }
+ }
+
if issueDescription == "" {
issueDescription = defaultIssueDescription
}
- var err error
+
var allIssues []*issue.Issue
- var issues []*issue.Issue
- switch valType := (val).(type) {
+ switch v := val.(type) {
case *ssa.Slice:
- issueDescription += " by passing hardcoded slice/array"
- issues, err = iterateThroughReferrers(val, funcsToTrack, pass.Analyzer.Name, issueDescription, pass.Fset, issue.High)
- allIssues = append(allIssues, issues...)
+ if s.isHardcoded(v.X) {
+ issueDescription += " by passing hardcoded slice/array"
+ }
+ return s.raiseIssue(v.X, issueDescription, fromInstr)
case *ssa.UnOp:
- // Check if it's a dereference operation (a.k.a pointer)
- if valType.Op == token.MUL {
- issueDescription += " by passing pointer which points to hardcoded variable"
- issues, err = iterateThroughReferrers(val, funcsToTrack, pass.Analyzer.Name, issueDescription, pass.Fset, issue.Low)
- allIssues = append(allIssues, issues...)
- }
- // When the value assigned to a variable is a function call.
- // It goes and check if this function contains call to crypto/rand.Read
- // in it's body(Assuming that calling crypto/rand.Read in a function,
- // is used for the generation of nonce/iv )
+ if v.Op == token.MUL {
+ if s.isHardcoded(v.X) {
+ issueDescription += " by passing pointer which points to hardcoded variable"
+ }
+ return s.raiseIssue(v.X, issueDescription, fromInstr)
+ }
+ case *ssa.Convert:
+ if v.Type().String() == "[]byte" && v.X.Type().String() == "string" {
+ if s.isHardcoded(v.X) {
+ issueDescription += " by passing converted string"
+ }
+ }
+ return s.raiseIssue(v.X, issueDescription, fromInstr)
+ case *ssa.Const:
+ issueDescription += " by passing hardcoded constant"
+ allIssues = append(allIssues, newIssue(s.Pass.Analyzer.Name, issueDescription, s.Pass.Fset, fromInstr.Pos(), issue.High, issue.High))
+ case *ssa.Global:
+ issueDescription += " by passing hardcoded global"
+ allIssues = append(allIssues, newIssue(s.Pass.Analyzer.Name, issueDescription, s.Pass.Fset, fromInstr.Pos(), issue.High, issue.High))
+ case *ssa.Alloc:
+ switch v.Comment {
+ case "slicelit":
+ issueDescription += " by passing hardcoded slice literal"
+ allIssues = append(allIssues, newIssue(s.Pass.Analyzer.Name, issueDescription, s.Pass.Fset, fromInstr.Pos(), issue.High, issue.High))
+ case "makeslice":
+ res := s.analyzeUsage(v)
+ foundHard := res&statusHard != 0
+ if foundHard {
+ if s.allTaintedEventsCovered(v, fromInstr) {
+ return nil, nil
+ }
+ issueDescription += " by passing a buffer from make modified with hardcoded values"
+ allIssues = append(allIssues, newIssue(s.Pass.Analyzer.Name, issueDescription, s.Pass.Fset, fromInstr.Pos(), issue.High, issue.High))
+ } else {
+ if s.allTaintedEventsCovered(v, fromInstr) {
+ return nil, nil
+ }
+ issueDescription += " by passing a zeroed buffer from make"
+ allIssues = append(allIssues, newIssue(s.Pass.Analyzer.Name, issueDescription, s.Pass.Fset, fromInstr.Pos(), issue.High, issue.High))
+ }
+ default:
+ // Ensure we trace the specific Store that tainted this Alloc
+ if refs := v.Referrers(); refs != nil {
+ for _, ref := range *refs {
+ if store, ok := ref.(*ssa.Store); ok && store.Addr == v {
+ issues, err := s.raiseIssue(store.Val, issueDescription, fromInstr)
+ if err != nil {
+ return nil, err
+ }
+ allIssues = append(allIssues, issues...)
+ }
+ }
+ }
+ }
+ case *ssa.MakeSlice:
+ res := s.analyzeUsage(v)
+ foundDyn := res&statusDyn != 0
+ foundHard := res&statusHard != 0
+ if foundHard {
+ issueDescription += " by passing a buffer from make modified with hardcoded values"
+ allIssues = append(allIssues, newIssue(s.Pass.Analyzer.Name, issueDescription, s.Pass.Fset, fromInstr.Pos(), issue.High, issue.High))
+ } else if !foundDyn {
+ issueDescription += " by passing a zeroed buffer from make"
+ allIssues = append(allIssues, newIssue(s.Pass.Analyzer.Name, issueDescription, s.Pass.Fset, fromInstr.Pos(), issue.High, issue.High))
+ }
case *ssa.Call:
- if callValue := valType.Call.Value; callValue != nil {
- if calledFunction, ok := callValue.(*ssa.Function); ok {
- if contains, funcErr := isFuncContainsCryptoRand(calledFunction); !contains && funcErr == nil {
- issueDescription += " by passing a value from function which doesn't use crypto/rand"
- issues, err = iterateThroughReferrers(val, funcsToTrack, pass.Analyzer.Name, issueDescription, pass.Fset, issue.Medium)
- allIssues = append(allIssues, issues...)
- } else if funcErr != nil {
- err = funcErr
+ if s.isHardcoded(v) {
+ issueDescription += " by passing a value from function which returns hardcoded value"
+ allIssues = append(allIssues, newIssue(s.Pass.Analyzer.Name, issueDescription, s.Pass.Fset, fromInstr.Pos(), issue.High, issue.High))
+ }
+ case *ssa.Parameter:
+ if v.Parent() != nil {
+ parentName := v.Parent().String()
+ paramIdx := -1
+ for i, p := range v.Parent().Params {
+ if p == v {
+ paramIdx = i
+ break
+ }
+ }
+ if paramIdx != -1 {
+ numParams := len(v.Parent().Params)
+ issueDescription += " by passing a parameter to a function and"
+ if callers, ok := s.callerMap[parentName]; ok {
+ for _, c := range callers {
+ if len(c.Call.Args) == numParams {
+ issues, _ := s.raiseIssue(c.Call.Args[paramIdx], issueDescription, c)
+ allIssues = append(allIssues, issues...)
+ }
+ }
}
}
}
- // only checks from strings->[]byte
- // might need to add additional types
+ }
+ return allIssues, nil
+}
+
+// isHardcoded determines if a value is derived from a hardcoded constant
+// or specific patterns (e.g. "slicelit" comment on Alloc).
+func (s *analysisState) isHardcoded(val ssa.Value) bool {
+ if s.Depth > MaxDepth {
+ return false
+ }
+ s.Depth++
+ defer func() { s.Depth-- }()
+
+ switch v := val.(type) {
+ case *ssa.Const, *ssa.Global:
+ return true
case *ssa.Convert:
- if valType.Type().String() == "[]byte" && valType.X.Type().String() == "string" {
- issueDescription += " by passing converted string"
- issues, err = iterateThroughReferrers(val, funcsToTrack, pass.Analyzer.Name, issueDescription, pass.Fset, issue.High)
- allIssues = append(allIssues, issues...)
+ return s.isHardcoded(v.X)
+ case *ssa.Slice:
+ return s.isHardcoded(v.X)
+ case *ssa.UnOp:
+ if v.Op == token.MUL {
+ return s.isHardcoded(v.X)
+ }
+ case *ssa.Alloc:
+ return v.Comment == "slicelit"
+ case *ssa.MakeSlice:
+ res := s.analyzeUsage(v)
+ foundDyn := res&statusDyn != 0
+ foundHard := res&statusHard != 0
+ return foundHard || !foundDyn
+ case *ssa.Call:
+ if fn, ok := v.Call.Value.(*ssa.Function); ok {
+ // Reuse FuncMap for recursion protection.
+ // For result caching, we can use use usageCache if we cast.
+ if s.FuncMap[fn] {
+ return false
+ }
+ s.FuncMap[fn] = true
+ defer delete(s.FuncMap, fn)
+ return s.isFuncReturnsHardcoded(fn)
}
case *ssa.Parameter:
- // arg given to tracked function is wrapped in another function, example:
- // func encrypt(..,nonce,...){
- // aesgcm.Seal(nonce)
- // }
- // save parameter position, by checking the name of the variable used in
- // tracked functions and comparing it with the name of the arg
- if valType.Parent() != nil {
- trackedFunctions := make(map[string][]int)
- for index, funcArgs := range valType.Parent().Params {
- if funcArgs.Name() == valType.Name() && funcArgs.Type() == valType.Type() {
- trackedFunctions[valType.Parent().String()] = []int{len(valType.Parent().Params), index}
- }
- }
- args := getArgsFromTrackedFunctions(ssaFuncs, trackedFunctions)
-
- issueDescription += " by passing a parameter to a function and"
- // recursively backtrack to where the origin of a variable passed to multiple functions is
- for _, arg := range args {
- if arg == nil {
- continue
+ if v.Parent() != nil {
+ // Avoid infinite recursion for recursive functions
+ if s.FuncMap[v.Parent()] {
+ return false
+ }
+ s.FuncMap[v.Parent()] = true
+ defer delete(s.FuncMap, v.Parent())
+
+ // Trace parameters by looking at all call sites of the parent function.
+ name := v.Parent().Name()
+ if v.Parent().Pkg != nil && v.Parent().Pkg.Pkg != nil {
+ name = v.Parent().Pkg.Pkg.Path() + "." + name
+ }
+ if calls, ok := s.callerMap[name]; ok {
+ for _, call := range calls {
+ for i, param := range v.Parent().Params {
+ if param == v && i < len(call.Call.Args) {
+ if s.isHardcoded(call.Call.Args[i]) {
+ return true
+ }
+ }
+ }
}
- issues, err = raiseIssue(*arg, trackedFunctions, ssaFuncs, pass, issueDescription)
- allIssues = append(allIssues, issues...)
}
}
}
- return allIssues, err
+ return false
}
-// iterateThroughReferrers iterates through all places that use the `variable` argument and check if it's used in one of the tracked functions.
-func iterateThroughReferrers(variable ssa.Value, funcsToTrack map[string][]int,
- analyzerID string, issueDescription string,
- fileSet *token.FileSet, issueConfidence issue.Score,
-) ([]*issue.Issue, error) {
- if funcsToTrack == nil || variable == nil || analyzerID == "" || issueDescription == "" || fileSet == nil {
- return nil, errors.New("received a nil object")
+func (s *analysisState) isFuncReturnsHardcoded(fn *ssa.Function) bool {
+ for _, block := range fn.Blocks {
+ for _, instr := range block.Instrs {
+ if ret, ok := instr.(*ssa.Return); ok {
+ if slices.ContainsFunc(ret.Results, s.isHardcoded) {
+ return true
+ }
+ }
+ }
}
- var gosecIssues []*issue.Issue
- refs := variable.Referrers()
- if refs == nil {
- return gosecIssues, nil
+ return false
+}
+
+// analyzeUsage performs data-flow analysis to determine if a value is derived from
+// a dynamic source (like crypto/rand) or if it's fixed/hardcoded.
+func (s *analysisState) analyzeUsage(val ssa.Value) uint8 {
+ if val == nil {
+ return 0
+ }
+ if s.Depth > MaxDepth {
+ return statusDyn // assume dynamic avoid infinite recursion
+ }
+ if res, ok := s.usageCache[val]; ok {
+ return res
+ }
+ s.usageCache[val] = statusVisiting
+
+ s.Depth++
+ defer func() { s.Depth-- }()
+
+ var res uint8
+ switch v := val.(type) {
+ case *ssa.Const, *ssa.Global:
+ res |= statusHard
+ case *ssa.Alloc:
+ if v.Comment == "slicelit" {
+ res |= statusHard
+ }
+ case *ssa.Convert:
+ res |= s.analyzeUsage(v.X)
+ case *ssa.Slice:
+ res |= s.analyzeUsage(v.X)
+ case *ssa.UnOp:
+ if v.Op == token.MUL {
+ res |= s.analyzeUsage(v.X)
+ }
+ case *ssa.Call:
+ if s.isHardcoded(v) {
+ res |= statusHard
+ }
+ case *ssa.Parameter:
+ if s.isHardcoded(v) {
+ res |= statusHard
+ }
}
- // Go through all functions that use the given arg variable
- for _, ref := range *refs {
- // Iterate through the functions we are interested
- for trackedFunc := range funcsToTrack {
- // Split the functions we are interested in, by the '.' because we will use the function name to do the comparison
- // MIGHT GIVE SOME FALSE POSITIVES THIS WAY
- trackedFuncParts := strings.Split(trackedFunc, ".")
- trackedFuncPartsName := trackedFuncParts[len(trackedFuncParts)-1]
- if strings.Contains(ref.String(), trackedFuncPartsName) {
- gosecIssues = append(gosecIssues, newIssue(analyzerID, issueDescription, fileSet, ref.Pos(), issue.High, issueConfidence))
+ if refs := val.Referrers(); refs != nil {
+ for _, ref := range *refs {
+ res |= s.analyzeReferrer(ref, val)
+ if (res&statusDyn != 0) && (res&statusHard != 0) {
+ finalRes := res & (^uint8(statusVisiting))
+ s.usageCache[val] = finalRes
+ return finalRes
}
}
}
- return gosecIssues, nil
-}
-// isFuncContainsCryptoRand checks whether a function contains a call to crypto/rand.Read in it's function body.
-func isFuncContainsCryptoRand(funcCall *ssa.Function) (bool, error) {
- if funcCall == nil {
- return false, errors.New("passed ssa.Function object is nil")
+ if sl, ok := val.(*ssa.Slice); ok && (res&statusDyn == 0) {
+ if sourceRefs := sl.X.Referrers(); sourceRefs != nil {
+ for _, sr := range *sourceRefs {
+ if other, ok := sr.(*ssa.Slice); ok && other != sl {
+ if IsSubSlice(sl, other) {
+ otherRes := s.analyzeUsage(other)
+ if (otherRes&(^uint8(statusVisiting)))&statusDyn != 0 {
+ res |= statusDyn
+ break
+ }
+ }
+ }
+ }
+ }
}
- for _, block := range funcCall.Blocks {
- for _, instr := range block.Instrs {
- if call, ok := instr.(*ssa.Call); ok {
- if calledFunction, ok := call.Call.Value.(*ssa.Function); ok {
- if calledFunction.Pkg != nil && calledFunction.Pkg.Pkg.Path() == "crypto/rand" && calledFunction.Name() == "Read" {
- return true, nil
+
+ // Store final result (removing visiting bit)
+ finalRes := res & (^uint8(statusVisiting))
+ s.usageCache[val] = finalRes
+ return finalRes
+}
+
+func (s *analysisState) analyzeReferrer(ref ssa.Instruction, val ssa.Value) uint8 {
+ var res uint8
+ switch r := ref.(type) {
+ case *ssa.Call:
+ isDynamic := false
+ isCipher := false
+ callValue := r.Call.Value
+
+ // 1. Determine fast path status (Dynamic/Cipher)
+ if fn, ok := callValue.(*ssa.Function); ok && fn.Pkg != nil && fn.Pkg.Pkg != nil {
+ path := fn.Pkg.Pkg.Path()
+ funcName := path + "." + fn.Name()
+ if dynamicFuncs[funcName] {
+ isDynamic = true
+ } else {
+ for _, prefix := range cipherPkgPrefixes {
+ if strings.HasPrefix(path, prefix) {
+ isCipher = true
+ break
+ }
+ }
+ }
+ } else if r.Call.IsInvoke() && r.Call.Method != nil && r.Call.Method.Pkg() != nil {
+ // Interface method invocation
+ path := r.Call.Method.Pkg().Path()
+ if dynamicPkgs[path] {
+ isDynamic = true
+ } else {
+ for _, prefix := range cipherPkgPrefixes {
+ if strings.HasPrefix(path, prefix) {
+ isCipher = true
+ break
+ }
+ }
+ }
+ } else {
+ // Fallback string matching
+ callStr := callValue.String()
+ for k := range dynamicFuncs {
+ if strings.Contains(callStr, k) {
+ isDynamic = true
+ break
+ }
+ }
+ if !isDynamic {
+ for _, prefix := range cipherPkgPrefixes {
+ if strings.Contains(callStr, prefix) {
+ isCipher = true
+ break
}
}
}
}
+
+ if isDynamic {
+ return res | statusDyn
+ }
+ if isCipher {
+ return res
+ }
+
+ // 2. Generic Function Resolution and Recursive Analysis
+ clear(s.ClosureCache)
+ var funcs []*ssa.Function
+ s.ResolveFuncs(callValue, &funcs)
+ if len(funcs) == 0 {
+ // If we couldn't resolve any functions (unknown library or dynamic call),
+ // assume it might be dynamic/safe to avoid false positives.
+ return statusDyn
+ }
+ for _, fn := range funcs {
+ for i, arg := range r.Call.Args {
+ if arg == val && i < len(fn.Params) {
+ res |= s.analyzeUsage(fn.Params[i])
+ }
+ }
+ }
+ return res
+
+ case *ssa.Slice:
+ if refs := r.Referrers(); refs != nil {
+ for _, ref := range *refs {
+ res |= s.analyzeReferrer(ref, r)
+ }
+ }
+ if !IsFullSlice(r, s.Analyzer.BufferedLen(r.X)) {
+ res &= ^uint8(statusDyn)
+ }
+ case *ssa.IndexAddr, *ssa.Index, *ssa.Lookup:
+ if vVal, ok := r.(ssa.Value); ok {
+ rRes := s.analyzeUsage(vVal)
+ res |= (rRes & statusHard)
+ }
+ case *ssa.UnOp:
+ if r.Op == token.MUL {
+ res |= s.analyzeUsage(r)
+ }
+ case *ssa.Convert:
+ res |= s.analyzeUsage(r)
+ case *ssa.Store:
+ if r.Addr == val {
+ valRes := s.analyzeUsage(r.Val)
+ res |= (valRes & statusHard)
+ res |= (valRes & statusDyn)
+ }
}
- return false, nil
+ return res
}
-func addToVarsMap(value ssa.Value, mapToAddTo map[string]*ssa.Value) {
- var parent string
- if value.Parent() != nil {
- parent = value.Parent().String()
+// allTaintedEventsCovered checks if all "tainting events" (Alloc, Store of hardcoded data)
+// related to 'val' are effectively overwritten/covered by dynamic reads (e.g. crypto/rand.Read)
+// before 'usage'. It handles partial overwrites by tracking byte ranges and execution order.
+func (s *analysisState) allTaintedEventsCovered(val ssa.Value, usage ssa.Instruction) bool {
+ // 1. Collection Phase: Gathering all Safe (Reads) and Unsafe (Allocs/Stores) actions.
+ var actions []RangeAction
+
+ v := val
+ for {
+ s.collectTaintedEvents(v, usage, &actions)
+ s.collectCoveredRanges(v, usage, &actions)
+
+ if unop, ok := v.(*ssa.UnOp); ok && unop.Op == token.MUL {
+ v = unop.X
+ } else if sl, ok := v.(*ssa.Slice); ok {
+ v = sl.X
+ } else if conv, ok := v.(*ssa.Convert); ok {
+ v = conv.X
+ } else if idx, ok := v.(*ssa.IndexAddr); ok {
+ v = idx.X
+ } else if alloc, ok := v.(*ssa.Alloc); ok {
+ // Try to follow a local variable back to its source
+ found := false
+ if refs := alloc.Referrers(); refs != nil {
+ for _, ref := range *refs {
+ if st, ok := ref.(*ssa.Store); ok && st.Addr == alloc {
+ v = st.Val
+ found = true
+ break
+ }
+ }
+ }
+ if !found {
+ break
+ }
+ } else {
+ break
+ }
+ }
+
+ // 2. Identify and track the root allocation as the initial Unsafe Action.
+ var bufLen int64
+ if alloc, ok := v.(*ssa.Alloc); ok {
+ bufLen = s.Analyzer.BufferedLen(alloc)
+ if alloc.Comment == "slicelit" || alloc.Comment == "makeslice" {
+ actions = append(actions, RangeAction{
+ Instr: alloc,
+ Range: ByteRange{0, bufLen},
+ IsSafe: false,
+ })
+ }
+ } else if mk, ok := v.(*ssa.MakeSlice); ok {
+ if l, ok := GetConstantInt64(mk.Len); ok && l > 0 {
+ bufLen = l
+ actions = append(actions, RangeAction{
+ Instr: mk,
+ Range: ByteRange{0, bufLen},
+ IsSafe: false,
+ })
+ }
+ } else if conv, ok := val.(*ssa.Convert); ok {
+ if c, ok := conv.X.(*ssa.Const); ok && c.Value.Kind() == constant.String {
+ bufLen = int64(len(constant.StringVal(c.Value)))
+ }
+ } else {
+ if bufRange, ok := s.resolveAbsoluteRange(v); ok {
+ bufLen = bufRange.High
+ }
+ }
+
+ if bufLen <= 0 {
+ return false
+ }
+
+ // 3. Sequence Phase: Sort actions based on their execution order in the SSA graph.
+ slices.SortFunc(actions, func(a, b RangeAction) int {
+ if s.Analyzer.Precedes(a.Instr, b.Instr) {
+ return -1
+ }
+ if a.Instr == b.Instr {
+ return 0
+ }
+ return 1
+ })
+
+ // 4. Replay Phase: Simulate the buffer state sequentially.
+ var safeRanges []ByteRange
+ var scratchRanges []ByteRange
+ for i := 0; i < len(actions); {
+ if actions[i].IsSafe {
+ // Collect and batch safe actions to minimize mergeRanges overhead
+ j := i
+ for j < len(actions) && actions[j].IsSafe {
+ safeRanges = append(safeRanges, actions[j].Range)
+ j++
+ }
+ mergedSafe := mergeRanges(safeRanges)
+ safeRanges = mergedSafe
+ i = j
+ } else {
+ // Subtract range
+ subtractRange(safeRanges, actions[i].Range, &scratchRanges)
+ safeRanges, scratchRanges = scratchRanges, safeRanges
+ i++
+ }
+ }
+
+ // 5. Verification Phase: Check if the resulting safe ranges cover the target range.
+ targetRange, ok := s.resolveAbsoluteRange(val)
+ if !ok {
+ return false
}
- key := value.Name() + value.Type().String() + value.String() + parent
- mapToAddTo[key] = &value
+
+ for _, r := range safeRanges {
+ if r.Low <= targetRange.Low && r.High >= targetRange.High {
+ return true
+ }
+ }
+ return false
}
-func isContainedInMap(value ssa.Value, mapToCheck map[string]*ssa.Value) bool {
- var parent string
- if value.Parent() != nil {
- parent = value.Parent().String()
+// collectTaintedEvents traverses the SSA referrers of 'val' to find hardcoded stores.
+// It recursively follows slices and pointer aliases to find indirect taints.
+func (s *analysisState) collectTaintedEvents(val ssa.Value, usage ssa.Instruction, actions *[]RangeAction) {
+ refs := val.Referrers()
+ if refs == nil {
+ return
+ }
+
+ for _, ref := range *refs {
+ isHard := s.analyzeReferrer(ref, val)&statusHard != 0
+ if isHard {
+ if s.Analyzer.Precedes(ref, usage) {
+ // Determine range of the Store
+ if store, ok := ref.(*ssa.Store); ok && store.Addr == val {
+ // Storing hardcoded data into this buffer
+ if absRange, ok := s.resolveAbsoluteRange(store.Addr); ok {
+ *actions = append(*actions, RangeAction{
+ Instr: ref,
+ Range: absRange,
+ IsSafe: false,
+ })
+ }
+ }
+ }
+ }
+
+ // Follow stores into pointers/interfaces
+ if store, ok := ref.(*ssa.Store); ok && store.Addr == val {
+ s.collectTaintedEvents(store.Val, usage, actions)
+ }
+
+ // Trace into slices/indexers
+ if v, ok := ref.(ssa.Value); ok {
+ switch r := ref.(type) {
+ case *ssa.Slice, *ssa.IndexAddr:
+ s.collectTaintedEvents(v, usage, actions)
+ case *ssa.UnOp:
+ if r.Op == token.MUL {
+ s.collectTaintedEvents(v, usage, actions)
+ }
+ }
+ }
}
- key := value.Name() + value.Type().String() + value.String() + parent
- _, contained := mapToCheck[key]
- return contained
}
-func getArgsFromTrackedFunctions(ssaFuncs []*ssa.Function, trackedFunc map[string][]int) map[string]*ssa.Value {
- values := make(map[string]*ssa.Value)
- for _, pkgFunc := range ssaFuncs {
- for _, funcBlock := range pkgFunc.Blocks {
- for _, funcBlocInstr := range funcBlock.Instrs {
- iterateTrackedFunctionsAndAddArgs(funcBlocInstr, trackedFunc, values)
+// collectCoveredRanges traverses the SSA referrers to find dynamic read operations
+// that safely overwrite portions of the buffer before it is used.
+func (s *analysisState) collectCoveredRanges(val ssa.Value, usage ssa.Instruction, actions *[]RangeAction) {
+ refs := val.Referrers()
+ if refs == nil {
+ return
+ }
+
+ for _, ref := range *refs {
+ if s.isFullDynamicRead(ref, val) {
+ if s.Analyzer.Precedes(ref, usage) {
+ if absRange, ok := s.resolveAbsoluteRange(val); ok {
+ *actions = append(*actions, RangeAction{
+ Instr: ref,
+ Range: absRange,
+ IsSafe: true,
+ })
+ }
+ }
+ }
+
+ // Follow stores into pointers/interfaces
+ if store, ok := ref.(*ssa.Store); ok && store.Addr == val {
+ s.collectCoveredRanges(store.Val, usage, actions)
+ }
+
+ // Recurse into slices/indexers to find reads on sub-slices
+ if v, ok := ref.(ssa.Value); ok {
+ switch r := ref.(type) {
+ case *ssa.Slice, *ssa.IndexAddr:
+ s.collectCoveredRanges(v, usage, actions)
+ case *ssa.UnOp:
+ if r.Op == token.MUL {
+ s.collectCoveredRanges(v, usage, actions)
+ }
}
}
}
- return values
}
-func iterateTrackedFunctionsAndAddArgs(funcBlocInstr ssa.Instruction, trackedFunc map[string][]int, values map[string]*ssa.Value) {
- if funcCall, ok := (funcBlocInstr).(*ssa.Call); ok {
- for trackedFuncName, trackedFuncArgsInfo := range trackedFunc {
- // only process functions that have the same number of arguments as the ones we track
- if len(funcCall.Call.Args) == trackedFuncArgsInfo[0] {
- tmpArg := funcCall.Call.Args[trackedFuncArgsInfo[1]]
- // check if the function is called from an object or directly from the package
- if funcCall.Call.Method != nil {
- if methodFullname := funcCall.Call.Method.FullName(); methodFullname == trackedFuncName {
- if !isContainedInMap(tmpArg, values) {
- addToVarsMap(tmpArg, values)
- }
- }
- } else if funcCall.Call.Value.String() == trackedFuncName {
- if !isContainedInMap(tmpArg, values) {
- addToVarsMap(tmpArg, values)
- }
+// isFullDynamicRead checks if the given 'ref' instruction is a call to a known dynamic function
+// (like io.ReadFull or crypto/rand.Read) and if 'val' is passed as an argument to it.
+func (s *analysisState) isFullDynamicRead(ref ssa.Instruction, val ssa.Value) bool {
+ call, ok := ref.(*ssa.Call)
+ if !ok {
+ return false
+ }
+ callValue := call.Call.Value
+
+ // 1. Check immediate calls to known dynamic functions
+ isDynamic := false
+ if fn, ok := callValue.(*ssa.Function); ok && fn.Pkg != nil && fn.Pkg.Pkg != nil {
+ if dynamicFuncs[fn.Pkg.Pkg.Path()+"."+fn.Name()] {
+ isDynamic = true
+ }
+ } else if call.Call.IsInvoke() && call.Call.Method != nil && call.Call.Method.Pkg() != nil {
+ if dynamicPkgs[call.Call.Method.Pkg().Path()] {
+ isDynamic = true
+ }
+ }
+
+ if isDynamic {
+ // Verify if val is passed as an argument
+ return slices.Contains(call.Call.Args, val)
+ }
+
+ // 2. Check calls to user-defined functions that eventually call dynamic reads.
+ // We use analyzeUsage on the function parameters to determine this.
+ // We only trust it as a safeguard if it is purely dynamic (not hardcoded).
+ // If we cannot resolve the function, assume it is safe to avoid False Positives.
+ clear(s.ClosureCache)
+ var funcs []*ssa.Function
+ s.ResolveFuncs(callValue, &funcs)
+ if len(funcs) == 0 {
+ return true
+ }
+ for _, fn := range funcs {
+ for i, arg := range call.Call.Args {
+ if arg == val && i < len(fn.Params) {
+ status := s.analyzeUsage(fn.Params[i])
+ if (status&statusDyn != 0) && (status&statusHard == 0) {
+ return true
}
}
}
}
+
+ return false
+}
+
+// resolveAbsoluteRange is now unified in RangeAnalyzer.ResolveByteRange.
+// We keep a thin wrapper for backward compatibility if needed, but better to call directly.
+
+func (s *analysisState) resolveAbsoluteRange(val ssa.Value) (ByteRange, bool) {
+ return s.Analyzer.ResolveByteRange(val)
}
+
+// ByteRange represents a range [Low, High)
diff --git a/vendor/github.com/securego/gosec/v2/analyzers/insecure_cookie.go b/vendor/github.com/securego/gosec/v2/analyzers/insecure_cookie.go
new file mode 100644
index 000000000..5c22eeb69
--- /dev/null
+++ b/vendor/github.com/securego/gosec/v2/analyzers/insecure_cookie.go
@@ -0,0 +1,269 @@
+// (c) Copyright gosec's authors
+//
+// 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 analyzers
+
+import (
+ "go/constant"
+ "go/token"
+ "go/types"
+
+ "golang.org/x/tools/go/analysis"
+ "golang.org/x/tools/go/analysis/passes/buildssa"
+ "golang.org/x/tools/go/ssa"
+
+ "github.com/securego/gosec/v2/internal/ssautil"
+ "github.com/securego/gosec/v2/issue"
+)
+
+func newInsecureCookieAnalyzer(id string, description string) *analysis.Analyzer {
+ return &analysis.Analyzer{
+ Name: id,
+ Doc: description,
+ Run: runInsecureCookieAnalysis,
+ Requires: []*analysis.Analyzer{buildssa.Analyzer},
+ }
+}
+
+// cookieState tracks the security-relevant fields set on a single http.Cookie allocation.
+type cookieState struct {
+ allocPos token.Pos
+ secureSet bool
+ httpOnlySet bool
+ sameSiteSet bool
+ // Track the actual values when explicitly set
+ secureTrue bool
+ httpOnlyTrue bool
+ sameSiteSafe bool // SameSiteStrictMode (3) or SameSiteLaxMode (2)
+}
+
+type insecureCookieState struct {
+ *BaseAnalyzerState
+ cookies map[ssa.Value]*cookieState
+ issuesByPos map[token.Pos]*issue.Issue
+}
+
+func newInsecureCookieState(pass *analysis.Pass) *insecureCookieState {
+ return &insecureCookieState{
+ BaseAnalyzerState: NewBaseState(pass),
+ cookies: make(map[ssa.Value]*cookieState),
+ issuesByPos: make(map[token.Pos]*issue.Issue),
+ }
+}
+
+func runInsecureCookieAnalysis(pass *analysis.Pass) (any, error) {
+ ssaResult, err := ssautil.GetSSAResult(pass)
+ if err != nil {
+ return nil, err
+ }
+
+ state := newInsecureCookieState(pass)
+ defer state.Release()
+
+ funcs := collectAnalyzerFunctions(ssaResult.SSA.SrcFuncs)
+ if len(funcs) == 0 {
+ return nil, nil
+ }
+
+ // Phase 1: Collect field stores on http.Cookie allocations.
+ TraverseSSA(funcs, func(_ *ssa.BasicBlock, instr ssa.Instruction) {
+ store, ok := instr.(*ssa.Store)
+ if !ok {
+ return
+ }
+ state.trackCookieFieldStore(store)
+ })
+
+ // Phase 2: Report cookies missing secure attributes.
+ state.reportInsecureCookies()
+
+ if len(state.issuesByPos) == 0 {
+ return nil, nil
+ }
+
+ issues := make([]*issue.Issue, 0, len(state.issuesByPos))
+ for _, i := range state.issuesByPos {
+ issues = append(issues, i)
+ }
+ return issues, nil
+}
+
+func (s *insecureCookieState) trackCookieFieldStore(store *ssa.Store) {
+ fieldAddr, ok := store.Addr.(*ssa.FieldAddr)
+ if !ok {
+ return
+ }
+
+ if !isHTTPCookiePointerType(fieldAddr.X.Type()) {
+ return
+ }
+
+ fieldName, ok := httpCookieFieldName(fieldAddr)
+ if !ok {
+ return
+ }
+
+ root := cookieRoot(fieldAddr.X, 0)
+ if root == nil {
+ return
+ }
+
+ cs := s.getOrCreateCookieState(root)
+
+ switch fieldName {
+ case "Secure":
+ cs.secureSet = true
+ if b, ok := boolConstValue(store.Val); ok {
+ cs.secureTrue = b
+ }
+ case "HttpOnly":
+ cs.httpOnlySet = true
+ if b, ok := boolConstValue(store.Val); ok {
+ cs.httpOnlyTrue = b
+ }
+ case "SameSite":
+ cs.sameSiteSet = true
+ if c, ok := store.Val.(*ssa.Const); ok && c.Value != nil {
+ // http.SameSiteLaxMode = 2, http.SameSiteStrictMode = 3
+ val, isInt := intConstValue(c)
+ if isInt && (val == 2 || val == 3) {
+ cs.sameSiteSafe = true
+ }
+ }
+ }
+}
+
+func (s *insecureCookieState) getOrCreateCookieState(root ssa.Value) *cookieState {
+ if cs, ok := s.cookies[root]; ok {
+ return cs
+ }
+ cs := &cookieState{allocPos: root.Pos()}
+ s.cookies[root] = cs
+ return cs
+}
+
+func (s *insecureCookieState) reportInsecureCookies() {
+ for _, cs := range s.cookies {
+ if cs.allocPos == token.NoPos {
+ continue
+ }
+
+ // Check: Secure must be explicitly set to true
+ if !cs.secureSet || !cs.secureTrue {
+ s.addIssue(cs.allocPos, "http.Cookie missing or has insecure Secure, HttpOnly, or SameSite attribute")
+ continue
+ }
+ // Check: HttpOnly must be explicitly set to true
+ if !cs.httpOnlySet || !cs.httpOnlyTrue {
+ s.addIssue(cs.allocPos, "http.Cookie missing or has insecure Secure, HttpOnly, or SameSite attribute")
+ continue
+ }
+ // Check: SameSite must be Lax or Strict
+ if !cs.sameSiteSet || !cs.sameSiteSafe {
+ s.addIssue(cs.allocPos, "http.Cookie missing or has insecure Secure, HttpOnly, or SameSite attribute")
+ continue
+ }
+ }
+}
+
+func (s *insecureCookieState) addIssue(pos token.Pos, msg string) {
+ if pos == token.NoPos {
+ return
+ }
+ if _, exists := s.issuesByPos[pos]; exists {
+ return
+ }
+ s.issuesByPos[pos] = newIssue(s.Pass.Analyzer.Name, msg, s.Pass.Fset, pos, issue.Medium, issue.High)
+}
+
+// isHTTPCookiePointerType returns true if t is *net/http.Cookie.
+func isHTTPCookiePointerType(t types.Type) bool {
+ ptr, ok := t.(*types.Pointer)
+ if !ok {
+ return false
+ }
+ named, ok := ptr.Elem().(*types.Named)
+ if !ok {
+ return false
+ }
+ obj := named.Obj()
+ if obj == nil || obj.Name() != "Cookie" {
+ return false
+ }
+ pkg := obj.Pkg()
+ return pkg != nil && pkg.Path() == "net/http"
+}
+
+// httpCookieFieldName returns the field name for a FieldAddr on *http.Cookie.
+func httpCookieFieldName(fieldAddr *ssa.FieldAddr) (string, bool) {
+ if fieldAddr == nil {
+ return "", false
+ }
+ t := fieldAddr.X.Type()
+ if ptr, ok := t.(*types.Pointer); ok {
+ t = ptr.Elem()
+ }
+ named, ok := t.(*types.Named)
+ if !ok {
+ return "", false
+ }
+ if named.Obj() == nil || named.Obj().Pkg() == nil ||
+ named.Obj().Pkg().Path() != "net/http" || named.Obj().Name() != "Cookie" {
+ return "", false
+ }
+ st, ok := named.Underlying().(*types.Struct)
+ if !ok || fieldAddr.Field >= st.NumFields() {
+ return "", false
+ }
+ return st.Field(fieldAddr.Field).Name(), true
+}
+
+// cookieRoot traces a value back to its http.Cookie allocation root.
+func cookieRoot(v ssa.Value, depth int) ssa.Value {
+ if v == nil || depth > MaxDepth {
+ return nil
+ }
+ if isHTTPCookiePointerType(v.Type()) {
+ return v
+ }
+ switch value := v.(type) {
+ case *ssa.ChangeType:
+ return cookieRoot(value.X, depth+1)
+ case *ssa.MakeInterface:
+ return cookieRoot(value.X, depth+1)
+ case *ssa.TypeAssert:
+ return cookieRoot(value.X, depth+1)
+ case *ssa.UnOp:
+ return cookieRoot(value.X, depth+1)
+ case *ssa.FieldAddr:
+ return cookieRoot(value.X, depth+1)
+ case *ssa.Phi:
+ if len(value.Edges) > 0 {
+ return cookieRoot(value.Edges[0], depth+1)
+ }
+ }
+ return nil
+}
+
+// intConstValue extracts an int64 from an ssa.Const.
+func intConstValue(c *ssa.Const) (int64, bool) {
+ if c == nil || c.Value == nil {
+ return 0, false
+ }
+ if c.Value.Kind() != constant.Int {
+ return 0, false
+ }
+ val, ok := constant.Int64Val(c.Value)
+ return val, ok
+}
diff --git a/vendor/github.com/securego/gosec/v2/analyzers/loginjection.go b/vendor/github.com/securego/gosec/v2/analyzers/loginjection.go
new file mode 100644
index 000000000..a6abe2f95
--- /dev/null
+++ b/vendor/github.com/securego/gosec/v2/analyzers/loginjection.go
@@ -0,0 +1,97 @@
+// (c) Copyright gosec's authors
+//
+// 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 analyzers
+
+import (
+ "golang.org/x/tools/go/analysis"
+
+ "github.com/securego/gosec/v2/taint"
+)
+
+// LogInjection returns a configuration for detecting log injection vulnerabilities.
+func LogInjection() taint.Config {
+ return taint.Config{
+ Sources: []taint.Source{
+ // Type sources: tainted when received as parameters
+ {Package: "net/http", Name: "Request", Pointer: true},
+ {Package: "net/url", Name: "URL", Pointer: true},
+
+ // Function sources
+ {Package: "os", Name: "Args", IsFunc: true},
+ {Package: "os", Name: "Getenv", IsFunc: true},
+
+ // I/O sources
+ {Package: "bufio", Name: "Reader", Pointer: true},
+ {Package: "bufio", Name: "Scanner", Pointer: true},
+ },
+ Sinks: []taint.Sink{
+ {Package: "log", Method: "Print"},
+ {Package: "log", Method: "Printf"},
+ {Package: "log", Method: "Println"},
+ {Package: "log", Method: "Fatal"},
+ {Package: "log", Method: "Fatalf"},
+ {Package: "log", Method: "Fatalln"},
+ {Package: "log", Method: "Panic"},
+ {Package: "log", Method: "Panicf"},
+ {Package: "log", Method: "Panicln"},
+ // log/slog structured logging functions have the signature:
+ // func Warn(msg string, args ...any)
+ // The variadic `args` are key-value attribute pairs whose values are
+ // automatically escaped by both TextHandler (JSON-quoted) and JSONHandler
+ // (JSON-encoded), making them safe against log injection.
+ // Only the `msg` argument (args[0]) is a real injection vector because
+ // TextHandler writes it verbatim without quoting.
+ // CheckArgs: []int{0} scopes the taint check to the message only,
+ // preventing false positives on: slog.Warn("msg", "key", taintedVal)
+ {Package: "log/slog", Method: "Info", CheckArgs: []int{0}},
+ {Package: "log/slog", Method: "Warn", CheckArgs: []int{0}},
+ {Package: "log/slog", Method: "Error", CheckArgs: []int{0}},
+ {Package: "log/slog", Method: "Debug", CheckArgs: []int{0}},
+ },
+ Sanitizers: []taint.Sanitizer{
+ // strings.ReplaceAll can strip newlines/CRLF for log injection
+ {Package: "strings", Method: "ReplaceAll"},
+ // strconv.Quote safely quotes a string (escapes special chars)
+ {Package: "strconv", Method: "Quote"},
+ // url.QueryEscape encodes special characters
+ {Package: "net/url", Method: "QueryEscape"},
+
+ // JSON encoding escapes all special characters including newlines,
+ // producing structurally safe output for log entries.
+ {Package: "encoding/json", Method: "Marshal"},
+ {Package: "encoding/json", Method: "MarshalIndent"},
+
+ // Numeric conversions produce strings that cannot contain
+ // log injection characters (newlines, carriage returns).
+ {Package: "strconv", Method: "Atoi"},
+ {Package: "strconv", Method: "Itoa"},
+ {Package: "strconv", Method: "ParseInt"},
+ {Package: "strconv", Method: "ParseUint"},
+ {Package: "strconv", Method: "ParseFloat"},
+ {Package: "strconv", Method: "FormatInt"},
+ {Package: "strconv", Method: "FormatFloat"},
+ },
+ }
+}
+
+// newLogInjectionAnalyzer creates an analyzer for detecting log injection vulnerabilities
+// via taint analysis (G706)
+func newLogInjectionAnalyzer(id string, description string) *analysis.Analyzer {
+ config := LogInjection()
+ rule := LogInjectionRule
+ rule.ID = id
+ rule.Description = description
+ return taint.NewGosecAnalyzer(&rule, &config)
+}
diff --git a/vendor/github.com/securego/gosec/v2/analyzers/openredirect.go b/vendor/github.com/securego/gosec/v2/analyzers/openredirect.go
new file mode 100644
index 000000000..bcdddc965
--- /dev/null
+++ b/vendor/github.com/securego/gosec/v2/analyzers/openredirect.go
@@ -0,0 +1,67 @@
+// (c) Copyright gosec's authors
+//
+// 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 analyzers
+
+import (
+ "golang.org/x/tools/go/analysis"
+
+ "github.com/securego/gosec/v2/taint"
+)
+
+// OpenRedirect returns a configuration for detecting open-redirect vulnerabilities
+// where user-controlled data flows into the URL argument of net/http.Redirect.
+// See CWE-601.
+func OpenRedirect() taint.Config {
+ return taint.Config{
+ Sources: []taint.Source{
+ // Type sources: tainted when received as parameters from external callers.
+ // Any read from a *http.Request (FormValue, URL.Query().Get, Cookie, etc.)
+ // propagates taint through the existing receiver-based logic in isTainted.
+ {Package: "net/http", Name: "Request", Pointer: true},
+ {Package: "net/url", Name: "URL", Pointer: true},
+ {Package: "net/url", Name: "Values"},
+ },
+ Sinks: []taint.Sink{
+ // http.Redirect(w, r, url, code): only the URL string (arg index 2)
+ // is the redirect target. Skipping arg 1 (*http.Request) prevents the
+ // receiver itself from being treated as a tainted sink argument.
+ {Package: "net/http", Method: "Redirect", CheckArgs: []int{2}},
+ },
+ Sanitizers: []taint.Sanitizer{
+ // url.PathEscape / QueryEscape neutralize untrusted path or query
+ // fragments embedded into a hard-coded base URL.
+ {Package: "net/url", Method: "PathEscape"},
+ {Package: "net/url", Method: "QueryEscape"},
+
+ // Numeric conversions cannot produce a URL host or scheme.
+ {Package: "strconv", Method: "Atoi"},
+ {Package: "strconv", Method: "Itoa"},
+ {Package: "strconv", Method: "ParseInt"},
+ {Package: "strconv", Method: "ParseUint"},
+ {Package: "strconv", Method: "FormatInt"},
+ {Package: "strconv", Method: "FormatUint"},
+ },
+ }
+}
+
+// newOpenRedirectAnalyzer creates an analyzer for detecting open-redirect
+// vulnerabilities via taint analysis (G710).
+func newOpenRedirectAnalyzer(id string, description string) *analysis.Analyzer {
+ config := OpenRedirect()
+ rule := OpenRedirectRule
+ rule.ID = id
+ rule.Description = description
+ return taint.NewGosecAnalyzer(&rule, &config)
+}
diff --git a/vendor/github.com/securego/gosec/v2/analyzers/pathtraversal.go b/vendor/github.com/securego/gosec/v2/analyzers/pathtraversal.go
new file mode 100644
index 000000000..ba9b72e81
--- /dev/null
+++ b/vendor/github.com/securego/gosec/v2/analyzers/pathtraversal.go
@@ -0,0 +1,105 @@
+// (c) Copyright gosec's authors
+//
+// 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 analyzers
+
+import (
+ "golang.org/x/tools/go/analysis"
+
+ "github.com/securego/gosec/v2/taint"
+)
+
+// PathTraversal returns a configuration for detecting path traversal vulnerabilities.
+func PathTraversal() taint.Config {
+ return taint.Config{
+ Sources: []taint.Source{
+ // Type sources: tainted when received as function parameters
+ {Package: "net/http", Name: "Request", Pointer: true},
+ {Package: "net/url", Name: "URL", Pointer: true},
+ {Package: "bufio", Name: "Reader", Pointer: true},
+ {Package: "bufio", Name: "Scanner", Pointer: true},
+
+ // Function sources: always produce tainted data
+ {Package: "os", Name: "Args", IsFunc: true},
+ {Package: "os", Name: "Getenv", IsFunc: true},
+ {Package: "os", Name: "ReadFile", IsFunc: true},
+
+ // NOTE: os.File is NOT a source type. Reading from a locally-opened file
+ // with a hardcoded path is not tainted. The file path argument to os.Open
+ // is what the sink checks. If someone opens a file from user input and
+ // then reads from it, the taint flows through the path argument, not the
+ // File type itself.
+ },
+ Sinks: []taint.Sink{
+ {Package: "os", Method: "Open"},
+ {Package: "os", Method: "OpenFile"},
+ {Package: "os", Method: "Create"},
+ {Package: "os", Method: "ReadFile"},
+ {Package: "os", Method: "WriteFile"},
+ {Package: "os", Method: "Remove"},
+ {Package: "os", Method: "RemoveAll"},
+ {Package: "os", Method: "Rename"},
+ {Package: "os", Method: "Mkdir"},
+ {Package: "os", Method: "MkdirAll"},
+ {Package: "os", Method: "Stat"},
+ {Package: "os", Method: "Lstat"},
+ {Package: "os", Method: "Chmod"},
+ {Package: "os", Method: "Chown"},
+ {Package: "io/ioutil", Method: "ReadFile"},
+ {Package: "io/ioutil", Method: "WriteFile"},
+ {Package: "io/ioutil", Method: "ReadDir"},
+ {Package: "path/filepath", Method: "Walk"},
+ {Package: "path/filepath", Method: "WalkDir"},
+ // HTTP file-serving functions: user-controlled path = arbitrary file read
+ {Package: "net/http", Method: "ServeFile", CheckArgs: []int{2}},
+ {Package: "net/http", Method: "ServeFileFS", CheckArgs: []int{3}},
+ },
+ Sanitizers: []taint.Sanitizer{
+ // filepath.Clean normalizes and removes traversal components
+ {Package: "path/filepath", Method: "Clean"},
+ // filepath.Abs calls Clean internally (per Go docs)
+ {Package: "path/filepath", Method: "Abs"},
+ // filepath.Base extracts just the filename, removing directory traversal
+ {Package: "path/filepath", Method: "Base"},
+ // filepath.Rel computes a relative path safely
+ {Package: "path/filepath", Method: "Rel"},
+ // url.PathEscape escapes path components
+ {Package: "net/url", Method: "PathEscape"},
+
+ // path.Base and path.Clean provide identical traversal-stripping
+ // semantics as their filepath counterparts (the only difference is
+ // separator handling, which is irrelevant for security).
+ {Package: "path", Method: "Base"},
+ {Package: "path", Method: "Clean"},
+
+ // Integer conversions eliminate path traversal vectors entirely —
+ // the result can never contain "/" or ".." characters.
+ {Package: "strconv", Method: "Atoi"},
+ {Package: "strconv", Method: "ParseInt"},
+ {Package: "strconv", Method: "ParseUint"},
+ {Package: "strconv", Method: "ParseFloat"},
+ {Package: "strconv", Method: "ParseBool"},
+ },
+ }
+}
+
+// newPathTraversalAnalyzer creates an analyzer for detecting path traversal vulnerabilities
+// via taint analysis (G703)
+func newPathTraversalAnalyzer(id string, description string) *analysis.Analyzer {
+ config := PathTraversal()
+ rule := PathTraversalRule
+ rule.ID = id
+ rule.Description = description
+ return taint.NewGosecAnalyzer(&rule, &config)
+}
diff --git a/vendor/github.com/securego/gosec/v2/analyzers/range_analyzer.go b/vendor/github.com/securego/gosec/v2/analyzers/range_analyzer.go
new file mode 100644
index 000000000..93f77666b
--- /dev/null
+++ b/vendor/github.com/securego/gosec/v2/analyzers/range_analyzer.go
@@ -0,0 +1,1524 @@
+// (c) Copyright gosec's authors
+//
+// 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 analyzers
+
+import (
+ "cmp"
+ "go/constant"
+ "go/token"
+ "go/types"
+ "math/bits"
+ "slices"
+ "strings"
+ "sync"
+
+ "golang.org/x/tools/go/ssa"
+)
+
+// ByteRange represents a range [Low, High)
+type ByteRange struct {
+ Low int64
+ High int64
+}
+
+// RangeAction represents a read/write action on a byte range.
+type RangeAction struct {
+ Instr ssa.Instruction
+ Range ByteRange
+ IsSafe bool // true = Read (Dynamic), false = Write/Alloc (Hardcoded)
+}
+
+type rangeCacheKey struct {
+ block *ssa.BasicBlock
+ val ssa.Value
+}
+
+type rangeResult struct {
+ minValue uint64
+ maxValue uint64
+ minValueSet bool
+ maxValueSet bool
+ explicitPositiveVals []uint
+ explicitNegativeVals []int
+ isRangeCheck bool
+ shared bool // If true, do not release to pool
+}
+
+type RangeAnalyzer struct {
+ RangeCache map[rangeCacheKey]*rangeResult
+ ResultPool []*rangeResult
+ Depth int
+ BlockMap map[*ssa.BasicBlock]bool
+ ValueMap map[ssa.Value]bool
+ ByteRangeCache map[ssa.Value]ByteRange
+ BufferLenCache map[ssa.Value]int64
+ reachStack []*ssa.BasicBlock
+}
+
+var rangeAnalyzerPool = sync.Pool{
+ New: func() any {
+ return &RangeAnalyzer{
+ RangeCache: make(map[rangeCacheKey]*rangeResult),
+ ResultPool: make([]*rangeResult, 0, 32),
+ BlockMap: make(map[*ssa.BasicBlock]bool),
+ ValueMap: make(map[ssa.Value]bool),
+ ByteRangeCache: make(map[ssa.Value]ByteRange),
+ BufferLenCache: make(map[ssa.Value]int64),
+ reachStack: make([]*ssa.BasicBlock, 0, 32),
+ }
+ },
+}
+
+func (res *rangeResult) Reset() {
+ res.minValue = toUint64(minInt64)
+ res.maxValue = maxUint64
+ res.minValueSet = false
+ res.maxValueSet = false
+ res.explicitPositiveVals = res.explicitPositiveVals[:0]
+ res.explicitNegativeVals = res.explicitNegativeVals[:0]
+ res.isRangeCheck = false
+ res.shared = false
+}
+
+func (res *rangeResult) CopyFrom(other *rangeResult) {
+ res.minValue = other.minValue
+ res.maxValue = other.maxValue
+ res.minValueSet = other.minValueSet
+ res.maxValueSet = other.maxValueSet
+ res.explicitPositiveVals = append(res.explicitPositiveVals[:0], other.explicitPositiveVals...)
+ res.explicitNegativeVals = append(res.explicitNegativeVals[:0], other.explicitNegativeVals...)
+ res.isRangeCheck = other.isRangeCheck
+}
+
+// NewRangeAnalyzer acquires a RangeAnalyzer from the pool.
+func NewRangeAnalyzer() *RangeAnalyzer {
+ return rangeAnalyzerPool.Get().(*RangeAnalyzer)
+}
+
+// Release returns the RangeAnalyzer to the pool after clearing its caches.
+func (ra *RangeAnalyzer) Release() {
+ ra.ResetCache()
+ rangeAnalyzerPool.Put(ra)
+}
+
+func (ra *RangeAnalyzer) ResetCache() {
+ for _, res := range ra.RangeCache {
+ res.shared = false
+ ra.releaseResult(res)
+ }
+ clear(ra.RangeCache)
+ clear(ra.BlockMap)
+ clear(ra.ValueMap)
+ clear(ra.ByteRangeCache)
+ clear(ra.BufferLenCache)
+ ra.reachStack = ra.reachStack[:0]
+ ra.Depth = 0
+}
+
+func (ra *RangeAnalyzer) acquireResult() *rangeResult {
+ if len(ra.ResultPool) > 0 {
+ idx := len(ra.ResultPool) - 1
+ res := ra.ResultPool[idx]
+ ra.ResultPool = ra.ResultPool[:idx]
+ res.Reset()
+ return res
+ }
+ res := &rangeResult{}
+ res.Reset()
+ return res
+}
+
+func (ra *RangeAnalyzer) releaseResult(res *rangeResult) {
+ if res != nil && !res.shared {
+ ra.ResultPool = append(ra.ResultPool, res)
+ }
+}
+
+// ResolveRange combines definition-based range analysis (computeRange) with dominator-based constraints (If blocks) to determine the full range of a value.
+func (ra *RangeAnalyzer) ResolveRange(v ssa.Value, block *ssa.BasicBlock) *rangeResult {
+ key := rangeCacheKey{block: block, val: v}
+ if res, ok := ra.RangeCache[key]; ok {
+ return res
+ }
+
+ isSrcUnsigned := isUint(v)
+ result := ra.acquireResult()
+ // result is initialized to wide range (MinInt64, MaxUint64) by acquireResult/Reset
+ if isSrcUnsigned {
+ result.minValue = 0
+ } else {
+ result.maxValue = maxInt64
+ }
+
+ // Check for explicit range checks.
+ if vIndex, ok := v.(*ssa.IndexAddr); ok {
+ res := ra.ResolveRange(vIndex.Index, vIndex.Block())
+ if res.isRangeCheck && res.minValueSet && res.maxValueSet {
+ // If the index itself has a known range, apply it.
+ result.minValue = maxBounds(result.minValue, result.minValueSet, res.minValue, res.minValueSet, isSrcUnsigned)
+ result.maxValue = minBounds(result.maxValue, result.maxValueSet, res.maxValue, res.maxValueSet, isSrcUnsigned)
+ result.minValueSet = true
+ result.maxValueSet = true
+ result.isRangeCheck = true
+ }
+ ra.releaseResult(res)
+ }
+
+ if ra.Depth > MaxDepth {
+ result.shared = true
+ ra.RangeCache[key] = result
+ return result
+ }
+
+ ra.Depth++
+ defer func() { ra.Depth-- }()
+
+ // Basic properties
+ isNonNeg := ra.IsNonNegative(v)
+ if isNonNeg {
+ result.minValue = 0
+ result.minValueSet = true
+ result.isRangeCheck = true
+ }
+
+ // Range from definition
+ defRange := ra.ComputeRange(v, block)
+ if defRange.isRangeCheck || defRange.minValueSet || defRange.maxValueSet {
+ result.isRangeCheck = true
+ if defRange.minValueSet {
+ result.minValue = maxBounds(result.minValue, result.minValueSet, defRange.minValue, defRange.minValueSet, isSrcUnsigned)
+ result.minValueSet = true
+ }
+ if defRange.maxValueSet {
+ result.maxValue = minBounds(result.maxValue, result.maxValueSet, defRange.maxValue, defRange.maxValueSet, isSrcUnsigned)
+ result.maxValueSet = true
+ }
+ }
+ // ComputeRange returns a temporary result, release it
+ ra.releaseResult(defRange)
+
+ // Range from control flow constraints
+ currDom := block.Idom()
+ for currDom != nil {
+ if vIf, ok := currDom.Instrs[len(currDom.Instrs)-1].(*ssa.If); ok {
+ var finalResIf *rangeResult
+ matchCount := 0
+ for i, succ := range currDom.Succs {
+ reach := ra.IsReachable(succ, block, currDom)
+ if reach {
+ matchCount++
+ if resIf := ra.getResultRangeForIfEdge(vIf, i == 0, v); resIf != nil {
+ if matchCount == 1 {
+ finalResIf = resIf
+ } else {
+ ra.releaseResult(resIf)
+ if finalResIf != nil {
+ ra.releaseResult(finalResIf)
+ finalResIf = nil
+ }
+ }
+ }
+ }
+ }
+ if matchCount == 1 && finalResIf != nil {
+ if finalResIf.minValueSet {
+ result.minValue = maxBounds(result.minValue, result.minValueSet, finalResIf.minValue, finalResIf.minValueSet, isSrcUnsigned)
+ result.minValueSet = true
+ }
+ if finalResIf.maxValueSet {
+ result.maxValue = minBounds(result.maxValue, result.maxValueSet, finalResIf.maxValue, finalResIf.maxValueSet, isSrcUnsigned)
+ result.maxValueSet = true
+ }
+ if finalResIf.isRangeCheck {
+ result.isRangeCheck = true
+ }
+ ra.releaseResult(finalResIf)
+ }
+ }
+ currDom = currDom.Idom()
+ }
+
+ // Persist in cache
+ result.shared = true
+ ra.RangeCache[key] = result
+ return result
+}
+
+// IsReachable returns true if there is a path from the start block to the target block in the CFG.
+// It uses iterative stack-based traversal and the RangeAnalyzer's BlockMap to avoid allocations.
+// An optional exclude block can be provided to prevent traversal through it (used to avoid loop back edges).
+func (ra *RangeAnalyzer) IsReachable(start, target *ssa.BasicBlock, exclude ...*ssa.BasicBlock) bool {
+ if start == target {
+ return true
+ }
+ clear(ra.BlockMap)
+ for _, ex := range exclude {
+ ra.BlockMap[ex] = true
+ }
+ ra.reachStack = ra.reachStack[:0]
+ ra.reachStack = append(ra.reachStack, start)
+
+ for len(ra.reachStack) > 0 {
+ curr := ra.reachStack[len(ra.reachStack)-1]
+ ra.reachStack = ra.reachStack[:len(ra.reachStack)-1]
+
+ if curr == target {
+ return true
+ }
+ if ra.BlockMap[curr] {
+ continue
+ }
+ ra.BlockMap[curr] = true
+
+ for _, succ := range curr.Succs {
+ if !ra.BlockMap[succ] {
+ ra.reachStack = append(ra.reachStack, succ)
+ }
+ }
+ }
+ return false
+}
+
+func (ra *RangeAnalyzer) getResultRangeForIfEdge(vIf *ssa.If, isTrue bool, v ssa.Value) *rangeResult {
+ res := ra.acquireResult()
+ binOp, _ := vIf.Cond.(*ssa.BinOp)
+ if binOp != nil && IsRangeCheck(vIf.Cond, v) {
+ ra.updateResultFromBinOpForValue(res, binOp, v, isTrue)
+ }
+
+ return res
+}
+
+func (ra *RangeAnalyzer) updateResultFromBinOpForValue(result *rangeResult, binOp *ssa.BinOp, v ssa.Value, successPathConvert bool) {
+ operandsFlipped := false
+ compareVal, op := getRealValueFromOperation(v)
+ if fieldAddr, ok := compareVal.(*ssa.FieldAddr); ok {
+ compareVal = fieldAddr
+ }
+
+ var matchSide ssa.Value
+ var inverseOp operationInfo
+ if isEquivalent(binOp.X, v) {
+ matchSide = binOp.Y
+ op = operationInfo{}
+ } else if isEquivalent(binOp.Y, v) {
+ matchSide = binOp.X
+ operandsFlipped = true
+ op = operationInfo{}
+ } else if isSameOrRelated(binOp.X, compareVal) {
+ matchSide = binOp.Y
+ // check if binOp.X has an operation relative to compareVal
+ if rVal, rOp := getRealValueFromOperation(binOp.X); rVal == compareVal {
+ inverseOp = rOp
+ }
+ } else if rVal, rOp := getRealValueFromOperation(binOp.X); rVal == compareVal {
+ matchSide = binOp.Y
+ inverseOp = rOp
+ } else if isSameOrRelated(binOp.Y, compareVal) {
+ matchSide = binOp.X
+ operandsFlipped = true
+ // check if binOp.Y has an operation relative to compareVal
+ if rVal, rOp := getRealValueFromOperation(binOp.Y); rVal == compareVal {
+ inverseOp = rOp
+ }
+ } else if rVal, rOp := getRealValueFromOperation(binOp.Y); rVal == compareVal {
+ matchSide = binOp.X
+ operandsFlipped = true
+ inverseOp = rOp
+ } else {
+ return
+ }
+
+ val, ok := GetConstantInt64(matchSide)
+ if !ok {
+ return
+ }
+
+ // Apply inverse operations to the limit 'val' before updating min/max
+ if inverseOp.op != "" {
+ switch inverseOp.op {
+ case "<<":
+ if vShift, ok := GetConstantInt64(inverseOp.extra); ok && vShift >= 0 {
+ val = val >> uint(vShift)
+ }
+ case "+":
+ if vAdd, ok := GetConstantInt64(inverseOp.extra); ok {
+ val -= vAdd
+ }
+ case "-":
+ if vSub, ok := GetConstantInt64(inverseOp.extra); ok {
+ if inverseOp.flipped { // val = extra - x => x = extra - val
+ val = vSub - val
+ operandsFlipped = !operandsFlipped
+ } else { // val = x - extra => x = val + extra
+ val += vSub
+ }
+ }
+ case "neg":
+ val = -val
+ operandsFlipped = !operandsFlipped
+ case ">>":
+ if vShift, ok := GetConstantInt64(inverseOp.extra); ok && vShift >= 0 {
+ val = val << uint(vShift)
+ }
+ case "*":
+ if vMul, ok := GetConstantUint64(inverseOp.extra); ok && vMul > 0 {
+ val = toInt64(toUint64(val) / vMul)
+ }
+ case "/":
+ if vQuo, ok := GetConstantUint64(inverseOp.extra); ok && vQuo > 0 {
+ if inverseOp.flipped { // val = extra / x => x = extra / val
+ if val != 0 {
+ val = toInt64(vQuo / toUint64(val))
+ }
+ operandsFlipped = !operandsFlipped
+ } else { // val = x / extra => x = val * vQuo
+ val = toInt64(toUint64(val) * vQuo)
+ }
+ }
+ }
+ }
+
+ // Apply forward operations from 'op' to the limit 'val'
+ if op.op != "" {
+ switch op.op {
+ case "<<":
+ if vShift, ok := GetConstantInt64(op.extra); ok && vShift >= 0 {
+ val = val << uint(vShift)
+ }
+ case "+":
+ if vAdd, ok := GetConstantInt64(op.extra); ok {
+ val += vAdd
+ }
+ case "-":
+ if vSub, ok := GetConstantInt64(op.extra); ok {
+ if op.flipped { // v = extra - x. x < val => v > extra - val
+ val = vSub - val
+ operandsFlipped = !operandsFlipped
+ } else { // v = x - extra. x < val => v < val - extra
+ val -= vSub
+ }
+ }
+ case ">>":
+ if vShift, ok := GetConstantInt64(op.extra); ok && vShift >= 0 {
+ val = val >> uint(vShift)
+ }
+ case "*":
+ isSrcUnsigned := isUint(v)
+ if isSrcUnsigned {
+ if vMul, ok := GetConstantUint64(op.extra); ok && vMul != 0 {
+ hi, lo := bits.Mul64(toUint64(val), vMul)
+ if hi != 0 {
+ return
+ }
+ val = toInt64(lo)
+ }
+ } else {
+ if vMul, ok := GetConstantInt64(op.extra); ok && vMul != 0 {
+ if vMul > 0 {
+ if val >= 0 {
+ hi, lo := bits.Mul64(toUint64(val), toUint64(vMul))
+ if hi != 0 {
+ return
+ }
+ val = toInt64(lo)
+ } else {
+ if val < minInt64/vMul {
+ return
+ }
+ val = val * vMul
+ }
+ } else {
+ val = val * vMul
+ operandsFlipped = !operandsFlipped
+ }
+ }
+ }
+ case "/":
+ if vQuo, ok := GetConstantInt64(op.extra); ok && vQuo > 0 {
+ if op.flipped { // v = extra / x. x < val => v > extra / val
+ if val != 0 {
+ val = vQuo / val
+ }
+ operandsFlipped = !operandsFlipped
+ } else { // v = x / extra. x < val => v < val / vQuo
+ val = val / vQuo
+ }
+ }
+ case "neg":
+ val = -val
+ operandsFlipped = !operandsFlipped
+ }
+ }
+
+ switch binOp.Op {
+ case token.LEQ, token.LSS:
+ updateMinMaxForLessOrEqual(result, val, binOp.Op, operandsFlipped, successPathConvert)
+ case token.GEQ, token.GTR:
+ updateMinMaxForGreaterOrEqual(result, val, binOp.Op, operandsFlipped, successPathConvert)
+ case token.EQL:
+ if successPathConvert {
+ updateExplicitValues(result, val)
+ }
+ case token.NEQ:
+ if !successPathConvert {
+ updateExplicitValues(result, val)
+ }
+ }
+}
+
+func (ra *RangeAnalyzer) IsNonNegative(v ssa.Value) bool {
+ clear(ra.ValueMap)
+ return ra.isNonNegativeRecursive(v)
+}
+
+func (ra *RangeAnalyzer) isNonNegativeRecursive(v ssa.Value) bool {
+ if ra.ValueMap[v] {
+ return true // Assume non-negative to break cycles
+ }
+ ra.ValueMap[v] = true
+
+ if isUint(v) {
+ return true
+ }
+
+ // Elements loaded from a []rune slice created by converting a
+ // string are valid Unicode code points, guaranteed non-negative.
+ if isElementOfStringRuneSlice(v) {
+ return true
+ }
+
+ v, info := getRealValueFromOperation(v)
+ if info.op == "neg" || info.op == "-" {
+ return false
+ }
+ switch v := v.(type) {
+ case *ssa.Extract:
+ // For range loops, only the index (extract 0) is guaranteed non-negative.
+ // Extract 1 is the element value which can be any integer.
+ if _, ok := v.Tuple.(*ssa.Next); ok && v.Index == 0 {
+ return true
+ }
+ case *ssa.Call:
+ if fn, ok := v.Call.Value.(*ssa.Builtin); ok {
+ switch fn.Name() {
+ case "len", "cap":
+ return true
+ case "min":
+ for _, arg := range v.Call.Args {
+ if !ra.isNonNegativeRecursive(arg) {
+ return false
+ }
+ }
+ return len(v.Call.Args) > 0
+ case "max":
+ for _, arg := range v.Call.Args {
+ if ra.isNonNegativeRecursive(arg) {
+ return true
+ }
+ }
+ return false
+ }
+ }
+ if callee := v.Call.StaticCallee(); callee != nil {
+ name := callee.String()
+ if strings.Contains(name, "UnixMilli") || strings.Contains(name, "UnixMicro") || strings.Contains(name, "UnixNano") {
+ return true
+ }
+ }
+ case *ssa.BinOp:
+ switch v.Op {
+ case token.ADD, token.MUL, token.QUO:
+ return ra.isNonNegativeRecursive(v.X) && ra.isNonNegativeRecursive(v.Y)
+ case token.REM, token.AND, token.SHR:
+ return ra.isNonNegativeRecursive(v.X)
+ }
+ case *ssa.Const:
+ if val, ok := GetConstantInt64(v); ok && val >= 0 {
+ return true
+ }
+ case *ssa.Phi:
+ allNonNeg := true
+ for _, edge := range v.Edges {
+ if !ra.isNonNegativeRecursive(edge) {
+ if constVal, ok := edge.(*ssa.Const); ok {
+ if val, ok := GetConstantInt64(constVal); ok && val == -1 {
+ continue
+ }
+ }
+ allNonNeg = false
+ break
+ }
+ }
+ return allNonNeg
+ case *ssa.Convert:
+ if isUint(v.X) {
+ return true
+ }
+ }
+ return false
+}
+
+// isElementOfStringRuneSlice checks whether v is a value loaded
+// from a []rune slice that was created by converting a string.
+// Go guarantees that string-to-[]rune conversions produce valid
+// Unicode code points (>= 0), so every element is non-negative.
+func isElementOfStringRuneSlice(v ssa.Value) bool {
+ unOp, ok := v.(*ssa.UnOp)
+ if !ok || unOp.Op != token.MUL {
+ return false
+ }
+ idx, ok := unOp.X.(*ssa.IndexAddr)
+ if !ok {
+ return false
+ }
+ return isStringToRuneConversion(idx.X)
+}
+
+// isStringToRuneConversion returns true when v is a Convert from
+// string to []int32 (i.e. []rune).
+func isStringToRuneConversion(v ssa.Value) bool {
+ conv, ok := v.(*ssa.Convert)
+ if !ok {
+ return false
+ }
+ srcBasic, ok := conv.X.Type().Underlying().(*types.Basic)
+ if !ok || srcBasic.Kind() != types.String {
+ return false
+ }
+ dstSlice, ok := conv.Type().Underlying().(*types.Slice)
+ if !ok {
+ return false
+ }
+ elemBasic, ok := dstSlice.Elem().Underlying().(*types.Basic)
+ if !ok {
+ return false
+ }
+ return elemBasic.Kind() == types.Int32
+}
+
+func (ra *RangeAnalyzer) ComputeRange(v ssa.Value, block *ssa.BasicBlock) *rangeResult {
+ res := ra.acquireResult()
+ isSrcUnsigned := isUint(v)
+
+ switch v := v.(type) {
+ case *ssa.BinOp:
+ switch v.Op {
+ case token.ADD:
+ if val, ok := GetConstantInt64(v.Y); ok {
+ subRes := ra.ResolveRange(v.X, block)
+ if subRes.isRangeCheck {
+ if subRes.minValueSet {
+ res.minValue = toUint64(toInt64(subRes.minValue) + val)
+ res.minValueSet = true
+ }
+ if subRes.maxValueSet {
+ res.maxValue = toUint64(toInt64(subRes.maxValue) + val)
+ res.maxValueSet = true
+ }
+ if res.minValueSet || res.maxValueSet {
+ res.isRangeCheck = true
+ }
+ }
+ ra.releaseResult(subRes)
+ } else if val, ok := GetConstantInt64(v.X); ok {
+ subRes := ra.ResolveRange(v.Y, block)
+ if subRes.isRangeCheck {
+ if subRes.minValueSet {
+ res.minValue = toUint64(val + toInt64(subRes.minValue))
+ res.minValueSet = true
+ }
+ if subRes.maxValueSet {
+ res.maxValue = toUint64(val + toInt64(subRes.maxValue))
+ res.maxValueSet = true
+ }
+ if res.minValueSet || res.maxValueSet {
+ res.isRangeCheck = true
+ }
+ }
+ ra.releaseResult(subRes)
+ } else {
+ subResX := ra.ResolveRange(v.X, block)
+ subResY := ra.ResolveRange(v.Y, block)
+ if subResX.isRangeCheck || subResY.isRangeCheck {
+ if subResX.minValueSet && subResY.minValueSet {
+ constrainRange(res, toUint64(toInt64(subResX.minValue)+toInt64(subResY.minValue)), true, isSrcUnsigned)
+ }
+ if subResX.maxValueSet && subResY.maxValueSet {
+ constrainRange(res, toUint64(toInt64(subResX.maxValue)+toInt64(subResY.maxValue)), false, isSrcUnsigned)
+ }
+ // Ensure we set isRangeCheck if we computed valid bounds, even if inputs were not "range checks"
+ // per se but just constant propagations.
+ if res.minValueSet || res.maxValueSet {
+ res.isRangeCheck = true
+ }
+ } else if subResX.minValueSet && subResX.maxValueSet && subResY.minValueSet && subResY.maxValueSet {
+ // Constant folding case: inputs might be plain constants.
+ constrainRange(res, toUint64(toInt64(subResX.minValue)+toInt64(subResY.minValue)), true, isSrcUnsigned)
+ constrainRange(res, toUint64(toInt64(subResX.maxValue)+toInt64(subResY.maxValue)), false, isSrcUnsigned)
+ res.isRangeCheck = true
+ }
+ ra.releaseResult(subResX)
+ ra.releaseResult(subResY)
+ }
+ case token.SUB:
+ if val, ok := GetConstantInt64(v.Y); ok {
+ subRes := ra.ResolveRange(v.X, block)
+ if subRes.isRangeCheck {
+ if subRes.minValueSet {
+ constrainRange(res, toUint64(toInt64(subRes.minValue)-val), true, isSrcUnsigned)
+ }
+ if subRes.maxValueSet {
+ constrainRange(res, toUint64(toInt64(subRes.maxValue)-val), false, isSrcUnsigned)
+ }
+ }
+ ra.releaseResult(subRes)
+ } else if val, ok := GetConstantInt64(v.X); ok {
+ subRes := ra.ResolveRange(v.Y, block)
+ if subRes.isRangeCheck {
+ if subRes.maxValueSet {
+ // res = val - subRes.maxValue (this is the new min if subtract max)
+ constrainRange(res, toUint64(val-toInt64(subRes.maxValue)), true, isSrcUnsigned)
+ }
+ if subRes.minValueSet {
+ // res = val - subRes.minValue (this is the new max if subtract min)
+ constrainRange(res, toUint64(val-toInt64(subRes.minValue)), false, isSrcUnsigned)
+ }
+ }
+ ra.releaseResult(subRes)
+ } else {
+ subResX := ra.ResolveRange(v.X, block)
+ subResY := ra.ResolveRange(v.Y, block)
+ if subResX.isRangeCheck || subResY.isRangeCheck {
+ if subResX.minValueSet && subResY.maxValueSet {
+ // Min = MinX - MaxY
+ constrainRange(res, toUint64(toInt64(subResX.minValue)-toInt64(subResY.maxValue)), true, isSrcUnsigned)
+ }
+ if subResX.maxValueSet && subResY.minValueSet {
+ // Max = MaxX - MinY
+ constrainRange(res, toUint64(toInt64(subResX.maxValue)-toInt64(subResY.minValue)), false, isSrcUnsigned)
+ }
+ if res.minValueSet || res.maxValueSet {
+ res.isRangeCheck = true
+ }
+ } else if subResX.minValueSet && subResX.maxValueSet && subResY.minValueSet && subResY.maxValueSet {
+ // Constant folding case for SUB
+ constrainRange(res, toUint64(toInt64(subResX.minValue)-toInt64(subResY.maxValue)), true, isSrcUnsigned)
+ constrainRange(res, toUint64(toInt64(subResX.maxValue)-toInt64(subResY.minValue)), false, isSrcUnsigned)
+ res.isRangeCheck = true
+ }
+ ra.releaseResult(subResX)
+ ra.releaseResult(subResY)
+ }
+ case token.MUL:
+ val, ok := GetConstantInt64(v.Y)
+ if !ok {
+ val, ok = GetConstantInt64(v.X)
+ }
+ if ok && val != 0 {
+ var subRes *rangeResult
+ if _, isConst := v.Y.(*ssa.Const); isConst {
+ subRes = ra.ResolveRange(v.X, block)
+ } else {
+ subRes = ra.ResolveRange(v.Y, block)
+ }
+
+ if subRes.isRangeCheck || subRes.minValueSet || subRes.maxValueSet {
+ srcInt, _ := GetIntTypeInfo(v.X.Type())
+ if srcInt.Signed {
+ // Signed multiplication
+ if subRes.minValueSet && subRes.maxValueSet {
+ v1 := toInt64(subRes.minValue) * val
+ v2 := toInt64(subRes.maxValue) * val
+ vMin, vMax := v1, v2
+ if vMin > vMax {
+ vMin, vMax = vMax, vMin
+ }
+ if (val > 0 && v1/val == toInt64(subRes.minValue)) || (val < 0 && v1/val == toInt64(subRes.minValue)) {
+ constrainRange(res, toUint64(vMin), true, false)
+ constrainRange(res, toUint64(vMax), false, false)
+ res.isRangeCheck = subRes.isRangeCheck
+ }
+ }
+ } else {
+ // Unsigned multiplication
+ uVal := toUint64(val)
+ if subRes.maxValueSet {
+ hi, _ := bits.Mul64(subRes.maxValue, uVal)
+ if hi == 0 {
+ if subRes.minValueSet && subRes.isRangeCheck {
+ constrainRange(res, subRes.minValue*uVal, true, true)
+ }
+ if subRes.maxValueSet && subRes.isRangeCheck {
+ constrainRange(res, subRes.maxValue*uVal, false, true)
+ }
+ }
+ }
+ }
+ }
+ }
+ case token.SHL:
+ if val, ok := GetConstantInt64(v.Y); ok && val >= 0 {
+ subRes := ra.ResolveRange(v.X, block)
+ if subRes.minValueSet {
+ newMin := subRes.minValue << uint(val) // #nosec G115 - WORKAROUND for old golangci-lint, remove when updated
+ // #nosec G115 - WORKAROUND for old golangci-lint, remove when updated
+ if newMin>>uint(val) == subRes.minValue {
+ constrainRange(res, newMin, true, isSrcUnsigned)
+ }
+ }
+ if subRes.maxValueSet {
+ newMax := subRes.maxValue << uint(val) // #nosec G115 - WORKAROUND for old golangci-lint, remove when updated
+ // #nosec G115 - WORKAROUND for old golangci-lint, remove when updated
+ if newMax>>uint(val) == subRes.maxValue {
+ constrainRange(res, newMax, false, isSrcUnsigned)
+ }
+ }
+ }
+ case token.SHR:
+ if val, ok := GetConstantInt64(v.Y); ok && val >= 0 {
+ subRes := ra.ResolveRange(v.X, block)
+ if subRes.minValueSet {
+ constrainRange(res, subRes.minValue>>uint(val), true, isSrcUnsigned) // #nosec G115 - WORKAROUND for old golangci-lint, remove when updated
+ }
+ if subRes.maxValueSet {
+ constrainRange(res, subRes.maxValue>>uint(val), false, isSrcUnsigned) // #nosec G115 - WORKAROUND for old golangci-lint, remove when updated
+ } else {
+ // Even if we don't have a max value set, we know the upper bound from the type.
+ srcInt, _ := GetIntTypeInfo(v.X.Type())
+ res.maxValue = srcInt.Max >> uint(val) // #nosec G115 - WORKAROUND for old golangci-lint, remove when updated
+ res.maxValueSet = true
+ res.isRangeCheck = true
+ }
+ }
+ case token.QUO:
+ if val, ok := GetConstantInt64(v.Y); ok && val != 0 {
+ subRes := ra.ResolveRange(v.X, block)
+ if val > 0 {
+ if subRes.minValueSet && subRes.isRangeCheck {
+ constrainRange(res, toUint64(toInt64(subRes.minValue)/val), true, isSrcUnsigned)
+ }
+ if subRes.maxValueSet && subRes.isRangeCheck {
+ constrainRange(res, toUint64(toInt64(subRes.maxValue)/val), false, isSrcUnsigned)
+ }
+ } else {
+ if subRes.maxValueSet && subRes.isRangeCheck {
+ constrainRange(res, toUint64(toInt64(subRes.maxValue)/val), true, isSrcUnsigned)
+ }
+ if subRes.minValueSet && subRes.isRangeCheck {
+ constrainRange(res, toUint64(toInt64(subRes.minValue)/val), false, isSrcUnsigned)
+ }
+ }
+ }
+ case token.REM:
+ if val, ok := GetConstantInt64(v.Y); ok && val > 0 {
+ res.minValue = toUint64(-(val - 1))
+ res.maxValue = toUint64(val - 1)
+ res.minValueSet = true
+ res.maxValueSet = true
+ res.isRangeCheck = true
+ // If we know x >= 0, we can refine to [0, val-1]
+ subRes := ra.ResolveRange(v.X, block)
+ if (subRes.minValueSet && toInt64(subRes.minValue) >= 0) || ra.IsNonNegative(v.X) {
+ res.minValue = 0
+ }
+ ra.releaseResult(subRes)
+ }
+ case token.AND:
+ if val, ok := GetConstantInt64(v.Y); ok && val >= 0 {
+ res.minValue = 0
+ res.maxValue = uint64(val)
+ res.minValueSet = true
+ res.maxValueSet = true
+ res.isRangeCheck = true
+ } else if val, ok := GetConstantInt64(v.X); ok && val >= 0 {
+ res.minValue = 0
+ res.maxValue = uint64(val)
+ res.minValueSet = true
+ res.maxValueSet = true
+ res.isRangeCheck = true
+ }
+ }
+ case *ssa.UnOp:
+ switch v.Op {
+ case token.MUL:
+ // Dereference (Load)
+ if alloc, ok := v.X.(*ssa.Alloc); ok {
+ return ra.resolveAllocRange(alloc, block, v)
+ }
+ // Don't recurse through IndexAddr: *(&data[i]) yields the element value,
+ // whose range is unrelated to the index i's range.
+ if _, ok := v.X.(*ssa.IndexAddr); ok {
+ break
+ }
+ // Just recurse
+ subRes := ra.ResolveRange(v.X, block)
+ res.CopyFrom(subRes)
+ ra.releaseResult(subRes)
+ case token.SUB:
+ // Negation (-X)
+ subRes := ra.ResolveRange(v.X, block)
+
+ // If X in [min, max], then -X in [-max, -min]
+ // We need to work with int64 views for negation
+ srcBuff, _ := GetIntTypeInfo(v.X.Type())
+ if srcBuff.Signed {
+ // Negation only meaningful for signed integers.
+ if subRes.minValueSet && subRes.maxValueSet {
+ // If X in [min, max], then -X in [-max, -min].
+ // Internal uint64 representation handles -MinInt overflow correctly.
+
+ oldMin := toInt64(subRes.minValue)
+ oldMax := toInt64(subRes.maxValue)
+
+ res.minValue = toUint64(-oldMax)
+ res.maxValue = toUint64(-oldMin)
+ res.minValueSet = true
+ res.maxValueSet = true
+ res.isRangeCheck = subRes.isRangeCheck
+
+ res.maxValueSet = true
+ res.isRangeCheck = subRes.isRangeCheck
+ }
+ }
+ ra.releaseResult(subRes)
+ }
+ case *ssa.Convert:
+ subRes := ra.ResolveRange(v.X, block)
+ if subRes.minValueSet && subRes.maxValueSet {
+ srcInt, err := GetIntTypeInfo(v.X.Type())
+ if err != nil {
+ return res
+ }
+ dstInt, err := GetIntTypeInfo(v.Type())
+ if err != nil {
+ return res
+ }
+
+ // Helper to convert/truncate a value to destination size
+ convertBound := func(val uint64) uint64 {
+ // Truncate/Mask to destination size
+ var newVal uint64
+ switch dstInt.Size {
+ case 8:
+ newVal = val & 0xFF
+ if dstInt.Signed {
+ // Sign extend 8->64
+ if newVal&0x80 != 0 {
+ newVal |= 0xFFFFFFFFFFFFFF00
+ }
+ }
+ case 16:
+ newVal = val & 0xFFFF
+ if dstInt.Signed {
+ // Sign extend 16->64
+ if newVal&0x8000 != 0 {
+ newVal |= 0xFFFFFFFFFFFF0000
+ }
+ }
+ case 32:
+ newVal = val & 0xFFFFFFFF
+ if dstInt.Signed {
+ // Sign extend 32->64
+ if newVal&0x80000000 != 0 {
+ newVal |= 0xFFFFFFFF00000000
+ }
+ }
+ default: // 64 or ptr
+ newVal = val
+ }
+ return newVal
+ }
+
+ newMin := convertBound(subRes.minValue)
+ newMax := convertBound(subRes.maxValue)
+
+ valid := false
+ if dstInt.Signed {
+ if toInt64(newMin) <= toInt64(newMax) {
+ // Check if old min/max are "safe" for the new type
+ // This heuristic ensures we don't accidentally wrap disjoint ranges into a safe interval.
+ // We only propagate if the source values fit into destination type OR
+ // if they were safe before and remain safe (e.g. extension).
+
+ // Checking if source values fit in destination domain is key for safety.
+ // If they fit, then min <= max holds and range is contiguous.
+
+ fits := func(v uint64) bool {
+ var v64 int64
+ if srcInt.Signed {
+ v64 = toInt64(v)
+ return v64 >= dstInt.Min && (dstInt.Size == 64 || v64 <= toInt64(dstInt.Max))
+ }
+ // Unsigned src
+ return v <= dstInt.Max
+ }
+
+ if fits(subRes.minValue) && fits(subRes.maxValue) {
+ valid = true
+ }
+ }
+ } else {
+ // Destination Unsigned
+ if newMin <= newMax {
+ fits := func(v uint64) bool {
+ var v64 int64
+ if srcInt.Signed {
+ v64 = toInt64(v)
+ return v64 >= 0 && uint64(v64) <= dstInt.Max
+ }
+ return v <= dstInt.Max
+ }
+ if fits(subRes.minValue) && fits(subRes.maxValue) {
+ valid = true
+ }
+ }
+ }
+
+ if valid {
+ res.minValue = newMin
+ res.maxValue = newMax
+ res.minValueSet = true
+ res.maxValueSet = true
+ res.isRangeCheck = true
+ }
+ }
+ ra.releaseResult(subRes)
+ case *ssa.Call:
+ if fn, ok := v.Call.Value.(*ssa.Builtin); ok {
+ switch fn.Name() {
+ case "min":
+ if len(v.Call.Args) > 0 {
+ for i, arg := range v.Call.Args {
+ argRes := ra.ResolveRange(arg, block)
+ if i == 0 {
+ res.CopyFrom(argRes)
+ } else {
+ res.minValue = minBounds(res.minValue, res.minValueSet, argRes.minValue, argRes.minValueSet, isSrcUnsigned)
+ res.minValueSet = res.minValueSet && argRes.minValueSet
+ res.maxValue = minBounds(res.maxValue, res.maxValueSet, argRes.maxValue, argRes.maxValueSet, isSrcUnsigned)
+ res.maxValueSet = res.maxValueSet && argRes.maxValueSet
+ }
+ ra.releaseResult(argRes)
+ }
+ res.isRangeCheck = true
+ }
+ case "max":
+ if len(v.Call.Args) > 0 {
+ for i, arg := range v.Call.Args {
+ argRes := ra.ResolveRange(arg, block)
+ if i == 0 {
+ res.CopyFrom(argRes)
+ } else {
+ res.minValue = maxBounds(res.minValue, res.minValueSet, argRes.minValue, argRes.minValueSet, isSrcUnsigned)
+ res.minValueSet = res.minValueSet && argRes.minValueSet
+ res.maxValue = maxBounds(res.maxValue, res.maxValueSet, argRes.maxValue, argRes.maxValueSet, isSrcUnsigned)
+ res.maxValueSet = res.maxValueSet && argRes.maxValueSet
+ }
+ ra.releaseResult(argRes)
+ }
+ res.isRangeCheck = true
+ }
+ }
+ }
+ case *ssa.Phi:
+ isSrcUnsigned := isUint(v)
+ for _, edge := range v.Edges {
+ subRes := ra.ResolveRange(edge, block)
+ if subRes.minValueSet {
+ expandRange(res, subRes.minValue, true, isSrcUnsigned)
+ }
+ if subRes.maxValueSet {
+ expandRange(res, subRes.maxValue, false, isSrcUnsigned)
+ }
+ ra.releaseResult(subRes)
+ }
+ case *ssa.Extract:
+ if v.Index == 0 {
+ if call, ok := v.Tuple.(*ssa.Call); ok {
+ if callee := call.Call.StaticCallee(); callee != nil {
+ switch callee.Name() {
+ case "ParseInt":
+ if len(call.Call.Args) == 3 {
+ if bitSizeVal, ok := GetConstantInt64(call.Call.Args[2]); ok {
+ shift := int(bitSizeVal) - 1
+ if shift >= 0 && shift < 64 {
+ res.minValue = toUint64(-1 << shift)
+ res.maxValue = toUint64((1 << shift) - 1)
+ res.minValueSet = true
+ res.maxValueSet = true
+ res.isRangeCheck = true
+ }
+ }
+ }
+ case "ParseUint":
+ if len(call.Call.Args) == 3 {
+ if bitSizeVal, ok := GetConstantInt64(call.Call.Args[2]); ok {
+ if bitSizeVal == 64 {
+ res.maxValue = maxUint64
+ } else if bitSizeVal > 0 && bitSizeVal < 64 {
+ res.maxValue = (1 << bitSizeVal) - 1
+ }
+ res.minValue = 0
+ res.minValueSet = true
+ res.maxValueSet = true
+ res.isRangeCheck = true
+ }
+ }
+ }
+ }
+ }
+ }
+ case *ssa.Const:
+ if val, ok := GetConstantInt64(v); ok {
+ res.minValue = toUint64(val)
+ res.maxValue = toUint64(val)
+ res.minValueSet = true
+ res.maxValueSet = true
+ res.isRangeCheck = true
+ }
+ }
+
+ return res
+}
+
+// ResolveByteRange determines the absolute byte range of 'val' relative to its
+// underlying root allocation by recursively resolving slice offsets and indices.
+func (ra *RangeAnalyzer) ResolveByteRange(val ssa.Value) (ByteRange, bool) {
+ if r, ok := ra.ByteRangeCache[val]; ok {
+ return r, true
+ }
+
+ if ra.Depth > MaxDepth {
+ return ByteRange{}, false
+ }
+ ra.Depth++
+ defer func() { ra.Depth-- }()
+
+ res, ok := ra.recursiveByteRange(val)
+ if ok {
+ ra.ByteRangeCache[val] = res
+ }
+ return res, ok
+}
+
+// recursiveByteRange is a helper for ResolveByteRange that traverses up the SSA value chain
+// (handling Slice, IndexAddr, Convert, etc.) to compute the range.
+func (ra *RangeAnalyzer) recursiveByteRange(val ssa.Value) (ByteRange, bool) {
+ switch v := val.(type) {
+ case *ssa.Alloc:
+ l := ra.BufferedLen(v)
+ if l <= 0 {
+ // If it is a local variable slot, try to find what was stored in it
+ if refs := v.Referrers(); refs != nil {
+ for _, ref := range *refs {
+ if st, ok := ref.(*ssa.Store); ok && st.Addr == v {
+ return ra.recursiveByteRange(st.Val)
+ }
+ }
+ }
+ return ByteRange{}, false
+ }
+ return ByteRange{0, l}, true
+ case *ssa.MakeSlice:
+ if l, ok := GetConstantInt64(v.Len); ok && l > 0 {
+ return ByteRange{0, l}, true
+ }
+ return ByteRange{}, false
+ case *ssa.Convert:
+ if c, ok := v.X.(*ssa.Const); ok && c.Value.Kind() == constant.String {
+ l := int64(len(constant.StringVal(c.Value)))
+ if l > 0 {
+ return ByteRange{0, l}, true
+ }
+ }
+ return ByteRange{}, false
+ case *ssa.Slice:
+ parentRange, ok := ra.recursiveByteRange(v.X)
+ if !ok {
+ return ByteRange{}, false
+ }
+
+ var low int64
+ if v.Low != nil {
+ l, ok := GetConstantInt64(v.Low)
+ if !ok {
+ res := ra.ResolveRange(v.Low, v.Block())
+ if res.isRangeCheck && res.maxValueSet {
+ l = toInt64(res.maxValue)
+ } else {
+ return ByteRange{}, false
+ }
+ ra.releaseResult(res)
+ }
+ low = l
+ }
+
+ var high int64
+ if v.High == nil {
+ high = parentRange.High
+ } else {
+ h, ok := GetConstantInt64(v.High)
+ if !ok {
+ res := ra.ResolveRange(v.High, v.Block())
+ if res.isRangeCheck && res.maxValueSet {
+ h = toInt64(res.maxValue)
+ } else {
+ return ByteRange{}, false
+ }
+ ra.releaseResult(res)
+ }
+ high = parentRange.Low + h
+ }
+
+ newLow := parentRange.Low + low
+ newHigh := min(high, parentRange.High)
+ if newLow >= newHigh {
+ return ByteRange{newLow, newLow}, true // Handle empty slices consistently
+ }
+ return ByteRange{newLow, newHigh}, true
+ case *ssa.IndexAddr:
+ parentRange, ok := ra.recursiveByteRange(v.X)
+ if !ok {
+ return ByteRange{}, false
+ }
+ if c, ok := GetConstantInt64(v.Index); ok {
+ start := parentRange.Low + c
+ return ByteRange{start, start + 1}, true
+ }
+ // Check for explicit range checks.
+ res := ra.ResolveRange(v.Index, v.Block())
+ if res.isRangeCheck && res.minValueSet && res.maxValueSet {
+ minVal := toInt64(res.minValue)
+ maxVal := toInt64(res.maxValue)
+ if minVal > maxVal {
+ // Contradictory range.
+ return ByteRange{parentRange.Low, parentRange.High}, true
+ }
+ start := parentRange.Low + minVal
+ end := parentRange.Low + maxVal + 1
+ ra.releaseResult(res)
+ return ByteRange{start, end}, true
+ }
+ ra.releaseResult(res)
+ return ByteRange{}, false
+ case *ssa.UnOp:
+ if v.Op == token.MUL {
+ return ra.recursiveByteRange(v.X)
+ }
+ }
+ return ByteRange{}, false
+}
+
+// BufferedLen attempts to find the constant length of a buffer/slice/array, using cache if available.
+func (ra *RangeAnalyzer) BufferedLen(val ssa.Value) int64 {
+ if res, ok := ra.BufferLenCache[val]; ok {
+ return res
+ }
+ length := GetBufferLen(val)
+ ra.BufferLenCache[val] = length
+ return length
+}
+
+// Precedes returns true if instruction a is executed before instruction b.
+// It assumes both instructions belong to the same function.
+func (ra *RangeAnalyzer) Precedes(a, b ssa.Instruction) bool {
+ if a == b {
+ return true
+ }
+ if a.Block() != b.Block() {
+ return ra.IsReachable(a.Block(), b.Block())
+ }
+ // Same block: check order in Instrs
+ for _, instr := range a.Block().Instrs {
+ if instr == a {
+ return true
+ }
+ if instr == b {
+ return false
+ }
+ }
+ return false
+}
+
+// IsRangeCheck determines if an instruction is part of a range check for a value.
+func IsRangeCheck(v ssa.Value, x ssa.Value) bool {
+ compareVal, _ := getRealValueFromOperation(x)
+ switch op := v.(type) {
+ case *ssa.BinOp:
+ switch op.Op {
+ case token.LSS, token.LEQ, token.GTR, token.GEQ, token.EQL, token.NEQ:
+ leftMatch := isSameOrRelated(op.X, x) || isSameOrRelated(op.X, compareVal)
+ if !leftMatch {
+ if rVal, _ := getRealValueFromOperation(op.X); rVal == x || (compareVal != nil && rVal == compareVal) {
+ leftMatch = true
+ }
+ }
+ rightMatch := isSameOrRelated(op.Y, x) || isSameOrRelated(op.Y, compareVal)
+ if !rightMatch {
+ if rVal, _ := getRealValueFromOperation(op.Y); rVal == x || (compareVal != nil && rVal == compareVal) {
+ rightMatch = true
+ }
+ }
+ return leftMatch || rightMatch
+ }
+ }
+ return false
+}
+
+func updateExplicitValues(result *rangeResult, val int64) {
+ if val < 0 {
+ result.explicitNegativeVals = append(result.explicitNegativeVals, int(val))
+ } else {
+ result.explicitPositiveVals = append(result.explicitPositiveVals, uint(val))
+ }
+ result.minValue = toUint64(val)
+ result.maxValue = toUint64(val)
+ result.minValueSet = true
+ result.maxValueSet = true
+ result.isRangeCheck = true
+}
+
+func updateMinMaxForLessOrEqual(result *rangeResult, val int64, op token.Token, operandsFlipped bool, successPathConvert bool) {
+ if successPathConvert != operandsFlipped {
+ result.maxValue = toUint64(val)
+ if (op == token.LSS && successPathConvert) || (op == token.LEQ && !successPathConvert) {
+ result.maxValue--
+ }
+ result.maxValueSet = true
+ result.isRangeCheck = true
+ } else {
+ // Path where x >= val
+ result.minValue = toUint64(val)
+ if (op == token.LEQ && !successPathConvert) || (op == token.LSS && successPathConvert) {
+ result.minValue++ // !(x <= val) -> x > val
+ }
+ result.minValueSet = true
+ result.isRangeCheck = true
+ }
+}
+
+func updateMinMaxForGreaterOrEqual(result *rangeResult, val int64, op token.Token, operandsFlipped bool, successPathConvert bool) {
+ if successPathConvert != operandsFlipped {
+ result.minValue = toUint64(val)
+ if (op == token.GTR && successPathConvert) || (op == token.GEQ && !successPathConvert) {
+ result.minValue++
+ }
+ result.minValueSet = true
+ result.isRangeCheck = true
+ } else {
+ // Path where x < val
+ result.maxValue = toUint64(val)
+ if (op == token.GEQ && !successPathConvert) || (op == token.GTR && successPathConvert) {
+ result.maxValue-- // !(x >= val) -> x < val
+ }
+ result.maxValueSet = true
+ result.isRangeCheck = true
+ }
+}
+
+// constrainRange updates the min or max value of the result range if the new value is tighter (intersection).
+func constrainRange(result *rangeResult, newVal uint64, isMin bool, isSrcUnsigned bool) {
+ if isMin {
+ if !result.minValueSet || (isSrcUnsigned && newVal > result.minValue) || (!isSrcUnsigned && toInt64(newVal) > toInt64(result.minValue)) {
+ result.minValue = newVal
+ result.minValueSet = true
+ result.isRangeCheck = true
+ }
+ } else {
+ if !result.maxValueSet || (isSrcUnsigned && newVal < result.maxValue) || (!isSrcUnsigned && toInt64(newVal) < toInt64(result.maxValue)) {
+ result.maxValue = newVal
+ result.maxValueSet = true
+ result.isRangeCheck = true
+ }
+ }
+}
+
+// mergeRanges takes a list of ByteRanges and merges overlapping or contiguous ranges.
+// It modifies the input slice in-place to reduce allocations and returns a slice of disjoint ranges.
+func mergeRanges(ranges []ByteRange) []ByteRange {
+ if len(ranges) <= 1 {
+ return ranges
+ }
+ slices.SortFunc(ranges, func(a, b ByteRange) int {
+ return cmp.Compare(a.Low, b.Low)
+ })
+
+ // In-place merge
+ // 'idx' points to the position of the 'current' merged range being built.
+ idx := 0
+ for _, r := range ranges[1:] {
+ if r.Low <= ranges[idx].High {
+ ranges[idx].High = max(ranges[idx].High, r.High)
+ } else {
+ idx++
+ ranges[idx] = r
+ }
+ }
+ return ranges[:idx+1]
+}
+
+// subtractRange removes 'taint' range from the list of 'safe' ranges, potentially
+// splitting existing safe ranges into two separate fragments. The results are appended to 'dest'.
+func subtractRange(safe []ByteRange, taint ByteRange, dest *[]ByteRange) {
+ *dest = (*dest)[:0]
+ for _, r := range safe {
+ // No overlap
+ if r.High <= taint.Low || r.Low >= taint.High {
+ *dest = append(*dest, r)
+ continue
+ }
+
+ if r.Low < taint.Low {
+ *dest = append(*dest, ByteRange{r.Low, taint.Low})
+ }
+ if r.High > taint.High {
+ *dest = append(*dest, ByteRange{taint.High, r.High})
+ }
+ }
+}
+
+// expandRange updates the min or max value of the result range if the new value expands the range (union).
+func expandRange(result *rangeResult, newVal uint64, isMin bool, isSrcUnsigned bool) {
+ if isMin {
+ if !result.minValueSet {
+ result.minValue = newVal
+ result.minValueSet = true
+ } else {
+ if isSrcUnsigned {
+ if newVal < result.minValue {
+ result.minValue = newVal
+ }
+ } else {
+ if toInt64(newVal) < toInt64(result.minValue) {
+ result.minValue = newVal
+ }
+ }
+ }
+ } else {
+ if !result.maxValueSet {
+ result.maxValue = newVal
+ result.maxValueSet = true
+ } else {
+ if isSrcUnsigned {
+ if newVal > result.maxValue {
+ result.maxValue = newVal
+ }
+ } else {
+ if toInt64(newVal) > toInt64(result.maxValue) {
+ result.maxValue = newVal
+ }
+ }
+ }
+ }
+}
+
+func (ra *RangeAnalyzer) resolveAllocRange(alloc *ssa.Alloc, block *ssa.BasicBlock, loadInstr ssa.Instruction) *rangeResult {
+ res := ra.acquireResult()
+
+ // 1. Same-block reaching definition check.
+ if loadInstr != nil && loadInstr.Block() == block {
+ // Traverse backwards from loadInstr
+ found := false
+ var nearestStore *ssa.Store
+
+ // Scan backwards
+ instrs := block.Instrs
+ startIndex := -1
+
+ // Find the index of the load instruction to start scanning backwards from it.
+ for i := len(instrs) - 1; i >= 0; i-- {
+ if instrs[i] == loadInstr {
+ startIndex = i
+ break
+ }
+ }
+
+ if startIndex != -1 {
+ for i := startIndex - 1; i >= 0; i-- {
+ if store, ok := instrs[i].(*ssa.Store); ok && store.Addr == alloc {
+ nearestStore = store
+ found = true
+ break
+ }
+ }
+ }
+
+ if found {
+ storeRes := ra.ResolveRange(nearestStore.Val, block)
+ res.CopyFrom(storeRes)
+ res.isRangeCheck = storeRes.isRangeCheck // Inherit properties
+ ra.releaseResult(storeRes)
+ return res
+ }
+ }
+
+ // 2. Fallback: Union of all stores.
+ first := true
+
+ refs := alloc.Referrers()
+ if refs == nil {
+ return res // No refs, unknown
+ }
+
+ for _, ref := range *refs {
+ if store, ok := ref.(*ssa.Store); ok && store.Addr == alloc {
+ storeRes := ra.ResolveRange(store.Val, block)
+
+ if first {
+ res.CopyFrom(storeRes)
+ if storeRes.minValueSet || storeRes.maxValueSet {
+ first = false
+ }
+ } else {
+ // Merge: broaden the range
+ // Union:
+ // Min = Min(currentMin, newMin)
+ // Max = Max(currentMax, newMax)
+
+ // Handling signed/unsigned mix is tricky. Assuming types match generally for the alloc.
+ elemType := alloc.Type().(*types.Pointer).Elem()
+ basic, ok := elemType.Underlying().(*types.Basic)
+ isUnsignedElem := ok && (basic.Info()&types.IsUnsigned != 0)
+
+ if storeRes.minValueSet {
+ expandRange(res, storeRes.minValue, true, isUnsignedElem)
+ } else {
+ res.minValueSet = false // If one path has unknown min, union is unknown
+ }
+
+ if storeRes.maxValueSet {
+ expandRange(res, storeRes.maxValue, false, isUnsignedElem)
+ } else {
+ res.maxValueSet = false
+ }
+
+ // Propagate isRangeCheck if any of the sources have it.
+ res.isRangeCheck = res.isRangeCheck || storeRes.isRangeCheck
+ }
+ ra.releaseResult(storeRes)
+ }
+ }
+
+ // If no stores were found, assume default/zero value.
+ if first {
+ // Default 0.
+ res.minValue = 0
+ res.maxValue = 0
+ res.maxValueSet = true
+ }
+
+ return res
+}
diff --git a/vendor/github.com/securego/gosec/v2/analyzers/redirect_header_propagation.go b/vendor/github.com/securego/gosec/v2/analyzers/redirect_header_propagation.go
new file mode 100644
index 000000000..d00c3ec43
--- /dev/null
+++ b/vendor/github.com/securego/gosec/v2/analyzers/redirect_header_propagation.go
@@ -0,0 +1,266 @@
+// (c) Copyright gosec's authors
+//
+// 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 analyzers
+
+import (
+ "go/constant"
+ "go/token"
+ "go/types"
+ "strings"
+
+ "golang.org/x/tools/go/analysis"
+ "golang.org/x/tools/go/analysis/passes/buildssa"
+ "golang.org/x/tools/go/ssa"
+
+ "github.com/securego/gosec/v2/internal/ssautil"
+ "github.com/securego/gosec/v2/issue"
+)
+
+const (
+ msgUnsafeRedirectHeaderCopy = "Unsafe redirect policy may propagate sensitive headers across origins"
+ msgSensitiveRedirectHeader = "Sensitive headers should not be re-added in redirect policy callbacks"
+)
+
+var sensitiveRedirectHeaders = map[string]struct{}{
+ "authorization": {},
+ "proxy-authorization": {},
+ "cookie": {},
+}
+
+func newRedirectHeaderPropagationAnalyzer(id string, description string) *analysis.Analyzer {
+ return &analysis.Analyzer{
+ Name: id,
+ Doc: description,
+ Run: runRedirectHeaderPropagationAnalysis,
+ Requires: []*analysis.Analyzer{buildssa.Analyzer},
+ }
+}
+
+func runRedirectHeaderPropagationAnalysis(pass *analysis.Pass) (any, error) {
+ ssaResult, err := ssautil.GetSSAResult(pass)
+ if err != nil {
+ return nil, err
+ }
+
+ issuesByPos := make(map[token.Pos]*issue.Issue)
+ for _, fn := range collectAnalyzerFunctions(ssaResult.SSA.SrcFuncs) {
+ reqParam, hasVia := findRedirectLikeParams(fn)
+ if reqParam == nil || !hasVia {
+ continue
+ }
+
+ for _, block := range fn.Blocks {
+ for _, instr := range block.Instrs {
+ switch v := instr.(type) {
+ case *ssa.Store:
+ if isRequestHeaderStore(v, reqParam) {
+ addRedirectIssue(issuesByPos, pass, v.Pos(), msgUnsafeRedirectHeaderCopy, issue.High, issue.High)
+ }
+ case *ssa.Call:
+ if !isHeaderMutationCall(v) {
+ continue
+ }
+ if len(v.Call.Args) < 2 {
+ continue
+ }
+ if !isRequestHeaderValue(v.Call.Args[0], reqParam) {
+ continue
+ }
+ headerName := extractStringConst(v.Call.Args[1])
+ if _, ok := sensitiveRedirectHeaders[strings.ToLower(headerName)]; ok {
+ addRedirectIssue(issuesByPos, pass, v.Pos(), msgSensitiveRedirectHeader, issue.High, issue.Medium)
+ }
+ }
+ }
+ }
+ }
+
+ if len(issuesByPos) == 0 {
+ return nil, nil
+ }
+
+ issues := make([]*issue.Issue, 0, len(issuesByPos))
+ for _, i := range issuesByPos {
+ issues = append(issues, i)
+ }
+
+ return issues, nil
+}
+
+func collectAnalyzerFunctions(srcFuncs []*ssa.Function) []*ssa.Function {
+ if len(srcFuncs) == 0 {
+ return nil
+ }
+
+ seen := make(map[*ssa.Function]struct{}, len(srcFuncs))
+ queue := make([]*ssa.Function, 0, len(srcFuncs))
+ all := make([]*ssa.Function, 0, len(srcFuncs))
+
+ enqueue := func(fn *ssa.Function) {
+ if fn == nil {
+ return
+ }
+ if _, ok := seen[fn]; ok {
+ return
+ }
+ seen[fn] = struct{}{}
+ queue = append(queue, fn)
+ all = append(all, fn)
+ }
+
+ for _, fn := range srcFuncs {
+ enqueue(fn)
+ }
+
+ for i := 0; i < len(queue); i++ {
+ fn := queue[i]
+ for _, block := range fn.Blocks {
+ for _, instr := range block.Instrs {
+ if makeClosure, ok := instr.(*ssa.MakeClosure); ok {
+ if closureFn, ok := makeClosure.Fn.(*ssa.Function); ok {
+ enqueue(closureFn)
+ }
+ }
+
+ if callInstr, ok := instr.(ssa.CallInstruction); ok {
+ common := callInstr.Common()
+ if common == nil {
+ continue
+ }
+ if callee := common.StaticCallee(); callee != nil {
+ enqueue(callee)
+ }
+ }
+ }
+ }
+ }
+
+ return all
+}
+
+func addRedirectIssue(issues map[token.Pos]*issue.Issue, pass *analysis.Pass, pos token.Pos, what string, severity issue.Score, confidence issue.Score) {
+ if pos == token.NoPos {
+ return
+ }
+ if _, exists := issues[pos]; exists {
+ return
+ }
+ issues[pos] = newIssue(pass.Analyzer.Name, what, pass.Fset, pos, severity, confidence)
+}
+
+func findRedirectLikeParams(fn *ssa.Function) (*ssa.Parameter, bool) {
+ if fn == nil {
+ return nil, false
+ }
+
+ var reqParam *ssa.Parameter
+ hasVia := false
+
+ for _, param := range fn.Params {
+ if param == nil {
+ continue
+ }
+ if reqParam == nil && isHTTPRequestPointerType(param.Type()) {
+ reqParam = param
+ continue
+ }
+ if isRequestSliceType(param.Type()) {
+ hasVia = true
+ }
+ }
+
+ return reqParam, hasVia
+}
+
+func isRequestSliceType(t types.Type) bool {
+ slice, ok := t.(*types.Slice)
+ if !ok {
+ return false
+ }
+ return isHTTPRequestPointerType(slice.Elem())
+}
+
+func isRequestHeaderStore(store *ssa.Store, reqParam *ssa.Parameter) bool {
+ fieldAddr, ok := store.Addr.(*ssa.FieldAddr)
+ if !ok {
+ return false
+ }
+ fieldType := fieldAddr.Type()
+ if fieldType == nil {
+ return false
+ }
+ if !isHTTPHeaderType(fieldType) {
+ return false
+ }
+ return valueDependsOn(fieldAddr.X, reqParam, 0)
+}
+
+func isRequestHeaderValue(val ssa.Value, reqParam *ssa.Parameter) bool {
+ if val == nil {
+ return false
+ }
+ if isHTTPHeaderType(val.Type()) && valueDependsOn(val, reqParam, 0) {
+ return true
+ }
+ return false
+}
+
+func isHeaderMutationCall(call *ssa.Call) bool {
+ if call == nil {
+ return false
+ }
+ callee := call.Call.StaticCallee()
+ if callee == nil {
+ return false
+ }
+ if callee.Name() != "Set" && callee.Name() != "Add" {
+ return false
+ }
+ recv := callee.Signature.Recv()
+ if recv == nil {
+ return false
+ }
+ return isHTTPHeaderType(recv.Type())
+}
+
+func isHTTPHeaderType(t types.Type) bool {
+ if ptr, ok := t.(*types.Pointer); ok {
+ t = ptr.Elem()
+ }
+
+ named, ok := t.(*types.Named)
+ if !ok {
+ return false
+ }
+ obj := named.Obj()
+ if obj == nil || obj.Name() != "Header" {
+ return false
+ }
+ pkg := obj.Pkg()
+ return pkg != nil && pkg.Path() == "net/http"
+}
+
+func extractStringConst(v ssa.Value) string {
+ c, ok := v.(*ssa.Const)
+ if !ok || c.Value == nil || c.Value.Kind() != constant.String {
+ return ""
+ }
+ return constant.StringVal(c.Value)
+}
+
+func valueDependsOn(value ssa.Value, target ssa.Value, depth int) bool {
+ checker := newDependencyChecker()
+ return checker.dependsOnDepth(value, target, depth)
+}
diff --git a/vendor/github.com/securego/gosec/v2/analyzers/request_smuggling.go b/vendor/github.com/securego/gosec/v2/analyzers/request_smuggling.go
new file mode 100644
index 000000000..39b54524c
--- /dev/null
+++ b/vendor/github.com/securego/gosec/v2/analyzers/request_smuggling.go
@@ -0,0 +1,303 @@
+// (c) Copyright gosec's authors
+//
+// 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 analyzers
+
+import (
+ "go/constant"
+ "go/token"
+ "go/types"
+ "strings"
+
+ "golang.org/x/tools/go/analysis"
+ "golang.org/x/tools/go/analysis/passes/buildssa"
+ "golang.org/x/tools/go/ssa"
+
+ "github.com/securego/gosec/v2/internal/ssautil"
+ "github.com/securego/gosec/v2/issue"
+)
+
+const (
+ msgConflictingHeaders = "Setting both Transfer-Encoding and Content-Length headers may enable request smuggling attacks"
+)
+
+// newRequestSmugglingAnalyzer creates an analyzer for detecting HTTP request smuggling
+// vulnerabilities (G113) related to CVE-2025-22871 and CWE-444
+func newRequestSmugglingAnalyzer(id string, description string) *analysis.Analyzer {
+ return &analysis.Analyzer{
+ Name: id,
+ Doc: description,
+ Run: runRequestSmugglingAnalysis,
+ Requires: []*analysis.Analyzer{buildssa.Analyzer},
+ }
+}
+
+// runRequestSmugglingAnalysis performs a single SSA traversal to detect multiple
+// HTTP request smuggling patterns for optimal performance
+func runRequestSmugglingAnalysis(pass *analysis.Pass) (any, error) {
+ ssaResult, err := ssautil.GetSSAResult(pass)
+ if err != nil {
+ return nil, err
+ }
+
+ if len(ssaResult.SSA.SrcFuncs) == 0 {
+ return nil, nil
+ }
+
+ state := newRequestSmugglingState(pass, ssaResult.SSA.SrcFuncs)
+ defer state.Release()
+
+ var issues []*issue.Issue
+
+ // Single traversal to detect all patterns
+ TraverseSSA(ssaResult.SSA.SrcFuncs, func(b *ssa.BasicBlock, instr ssa.Instruction) {
+ // Track header operations for conflicts
+ state.trackHeaderOperation(instr)
+ })
+
+ // Check for header conflicts after traversal
+ headerIssues := state.detectHeaderConflicts()
+ issues = append(issues, headerIssues...)
+
+ if len(issues) > 0 {
+ return issues, nil
+ }
+ return nil, nil
+}
+
+// requestSmugglingState maintains analysis state across the SSA traversal
+type requestSmugglingState struct {
+ *BaseAnalyzerState
+ ssaFuncs []*ssa.Function
+ // Track header operations per ResponseWriter to detect conflicts
+ headerOps map[ssa.Value]*headerTracker
+}
+
+// headerTracker records header operations on a specific ResponseWriter instance
+type headerTracker struct {
+ hasTransferEncoding bool
+ hasContentLength bool
+ tePos token.Pos
+ clPos token.Pos
+}
+
+func newRequestSmugglingState(pass *analysis.Pass, funcs []*ssa.Function) *requestSmugglingState {
+ return &requestSmugglingState{
+ BaseAnalyzerState: NewBaseState(pass),
+ ssaFuncs: funcs,
+ headerOps: make(map[ssa.Value]*headerTracker),
+ }
+}
+
+func (s *requestSmugglingState) Release() {
+ s.headerOps = nil
+ s.BaseAnalyzerState.Release()
+}
+
+// trackHeaderOperation tracks Header().Set() calls on ResponseWriter instances
+func (s *requestSmugglingState) trackHeaderOperation(instr ssa.Instruction) {
+ call, ok := instr.(*ssa.Call)
+ if !ok {
+ return
+ }
+
+ // Check if it's a Header().Set() call
+ callee := call.Call.StaticCallee()
+ if callee == nil || callee.Name() != "Set" {
+ return
+ }
+
+ // Check if the receiver is http.Header
+ if !s.isHTTPHeaderSet(call) {
+ return
+ }
+
+ // Extract the header key being set
+ // In SSA, for bound method calls, Args[0] is the receiver (http.Header)
+ // Args[1] is the key, Args[2] is the value
+ if len(call.Call.Args) < 3 {
+ return
+ }
+
+ headerKey := s.extractStringConstant(call.Call.Args[1])
+ if headerKey == "" {
+ return
+ }
+
+ // Find the ResponseWriter this header belongs to
+ writer := s.findResponseWriter(call)
+ if writer == nil {
+ return
+ }
+
+ // Track this header operation
+ if _, exists := s.headerOps[writer]; !exists {
+ s.headerOps[writer] = &headerTracker{}
+ }
+
+ tracker := s.headerOps[writer]
+
+ normalizedKey := strings.ToLower(headerKey)
+ switch normalizedKey {
+ case "transfer-encoding":
+ tracker.hasTransferEncoding = true
+ tracker.tePos = call.Pos()
+ case "content-length":
+ tracker.hasContentLength = true
+ tracker.clPos = call.Pos()
+ }
+}
+
+// isHTTPHeaderSet checks if a call is to http.Header.Set
+func (s *requestSmugglingState) isHTTPHeaderSet(call *ssa.Call) bool {
+ callee := call.Call.StaticCallee()
+ if callee == nil {
+ return false
+ }
+
+ // Check receiver type
+ if callee.Signature == nil {
+ return false
+ }
+
+ recv := callee.Signature.Recv()
+ if recv == nil {
+ return false
+ }
+
+ recvType := recv.Type()
+ if recvType == nil {
+ return false
+ }
+
+ // Check if it's http.Header
+ namedType, ok := recvType.(*types.Named)
+ if !ok {
+ return false
+ }
+
+ obj := namedType.Obj()
+ if obj == nil || obj.Name() != "Header" {
+ return false
+ }
+
+ pkg := obj.Pkg()
+ return pkg != nil && pkg.Path() == "net/http"
+}
+
+// extractStringConstant extracts a string value from a constant expression
+func (s *requestSmugglingState) extractStringConstant(val ssa.Value) string {
+ if constVal, ok := val.(*ssa.Const); ok {
+ if constVal.Value != nil && constVal.Value.Kind() == constant.String {
+ return constant.StringVal(constVal.Value)
+ }
+ }
+ return ""
+}
+
+// findResponseWriter traces back from Header().Set() to find the ResponseWriter
+func (s *requestSmugglingState) findResponseWriter(headerSetCall *ssa.Call) ssa.Value {
+ // The receiver of Set is the Header, which comes from calling Header() on ResponseWriter
+ if len(headerSetCall.Call.Args) == 0 {
+ return nil
+ }
+
+ // In SSA, the receiver is the first argument for method calls
+ receiver := headerSetCall.Call.Args[0]
+
+ // Trace back through Header() call
+ for depth := 0; depth < 5; depth++ {
+ switch v := receiver.(type) {
+ case *ssa.Call:
+ // Check if this is a Header() call
+ if s.isHeaderMethodCall(v) {
+ // For invoke (interface method), the receiver is in Call.Value
+ if v.Call.IsInvoke() {
+ return v.Call.Value
+ }
+ // For static calls, the receiver is in Args[0]
+ if len(v.Call.Args) > 0 {
+ return v.Call.Args[0]
+ }
+ return nil
+ }
+ // Continue tracing
+ if len(v.Call.Args) > 0 {
+ receiver = v.Call.Args[0]
+ } else {
+ return nil
+ }
+
+ case *ssa.Phi:
+ // For simplicity, use the first edge
+ if len(v.Edges) > 0 {
+ receiver = v.Edges[0]
+ } else {
+ return nil
+ }
+
+ case *ssa.Parameter, *ssa.UnOp, *ssa.FieldAddr:
+ // Found a potential ResponseWriter
+ return receiver
+
+ default:
+ return nil
+ }
+ }
+
+ return nil
+}
+
+// isHeaderMethodCall checks if a call is to the Header() method of ResponseWriter
+func (s *requestSmugglingState) isHeaderMethodCall(call *ssa.Call) bool {
+ // Check for static calls (concrete types)
+ callee := call.Call.StaticCallee()
+ if callee != nil {
+ return callee.Name() == "Header"
+ }
+
+ // Check for interface method calls (invoke)
+ if call.Call.IsInvoke() && call.Call.Method != nil {
+ return call.Call.Method.Name() == "Header"
+ }
+
+ return false
+}
+
+// detectHeaderConflicts checks for Transfer-Encoding and Content-Length conflicts
+func (s *requestSmugglingState) detectHeaderConflicts() []*issue.Issue {
+ var issues []*issue.Issue
+
+ for _, tracker := range s.headerOps {
+ if tracker.hasTransferEncoding && tracker.hasContentLength {
+ // Use the position of the second header set (either could be first)
+ pos := tracker.clPos
+ if tracker.tePos > tracker.clPos {
+ pos = tracker.tePos
+ }
+
+ issue := newIssue(
+ s.Pass.Analyzer.Name,
+ msgConflictingHeaders,
+ s.Pass.Fset,
+ pos,
+ issue.High,
+ issue.High,
+ )
+ issues = append(issues, issue)
+ }
+ }
+
+ return issues
+}
diff --git a/vendor/github.com/securego/gosec/v2/analyzers/slice_bounds.go b/vendor/github.com/securego/gosec/v2/analyzers/slice_bounds.go
index 2347af07e..cfe13a5b8 100644
--- a/vendor/github.com/securego/gosec/v2/analyzers/slice_bounds.go
+++ b/vendor/github.com/securego/gosec/v2/analyzers/slice_bounds.go
@@ -16,19 +16,22 @@ package analyzers
import (
"errors"
- "fmt"
+ "go/constant"
"go/token"
- "regexp"
- "strconv"
- "strings"
+ "go/types"
+ "maps"
+ "sync"
"golang.org/x/tools/go/analysis"
"golang.org/x/tools/go/analysis/passes/buildssa"
"golang.org/x/tools/go/ssa"
+ "github.com/securego/gosec/v2/internal/ssautil"
"github.com/securego/gosec/v2/issue"
)
+var errNoFound = errors.New("no found")
+
type bound int
const (
@@ -36,10 +39,9 @@ const (
upperUnbounded
unbounded
upperBounded
+ bounded
)
-const maxDepth = 20
-
func newSliceBoundsAnalyzer(id string, description string) *analysis.Analyzer {
return &analysis.Analyzer{
Name: id,
@@ -49,35 +51,139 @@ func newSliceBoundsAnalyzer(id string, description string) *analysis.Analyzer {
}
}
-func runSliceBounds(pass *analysis.Pass) (interface{}, error) {
- ssaResult, err := getSSAResult(pass)
+type valOffset struct {
+ val ssa.Value
+ offset int
+}
+
+type sliceBoundsState struct {
+ *BaseAnalyzerState
+ trackCache map[trackCacheKey]*trackCacheValue
+ valQueue []valOffset
+}
+
+var (
+ trackValuePool = sync.Pool{
+ New: func() any {
+ return &trackCacheValue{
+ violations: make([]ssa.Instruction, 0, 4),
+ ifs: make(map[ssa.If]*ssa.BinOp),
+ }
+ },
+ }
+ trackMapPool = sync.Pool{
+ New: func() any {
+ return make(map[trackCacheKey]*trackCacheValue, 32)
+ },
+ }
+)
+
+type trackCacheKey struct {
+ node ssa.Node
+ sliceCap int
+}
+
+type trackCacheValue struct {
+ violations []ssa.Instruction
+ ifs map[ssa.If]*ssa.BinOp
+}
+
+func newSliceBoundsState(pass *analysis.Pass) *sliceBoundsState {
+ return &sliceBoundsState{
+ BaseAnalyzerState: NewBaseState(pass),
+ trackCache: trackMapPool.Get().(map[trackCacheKey]*trackCacheValue),
+ valQueue: make([]valOffset, 0, 32),
+ }
+}
+
+func (s *sliceBoundsState) Release() {
+ if s.trackCache != nil {
+ for _, res := range s.trackCache {
+ if res != nil {
+ res.Reset()
+ trackValuePool.Put(res)
+ }
+ }
+ clear(s.trackCache)
+ trackMapPool.Put(s.trackCache)
+ s.trackCache = nil
+ }
+ s.BaseAnalyzerState.Release()
+}
+
+func (s *sliceBoundsState) acquireTrackCacheValue() *trackCacheValue {
+ res := trackValuePool.Get().(*trackCacheValue)
+ res.Reset()
+ return res
+}
+
+func (s *sliceBoundsState) releaseTrackCacheValue(res *trackCacheValue) {
+ if res != nil {
+ res.Reset()
+ trackValuePool.Put(res)
+ }
+}
+
+func (v *trackCacheValue) Reset() {
+ v.violations = v.violations[:0]
+ clear(v.ifs)
+}
+
+func (s *sliceBoundsState) Reset() {
+ s.BaseAnalyzerState.Reset()
+ for _, res := range s.trackCache {
+ if res != nil {
+ s.releaseTrackCacheValue(res)
+ }
+ }
+ clear(s.trackCache)
+}
+
+func runSliceBounds(pass *analysis.Pass) (result any, err error) {
+ defer func() {
+ if r := recover(); r != nil {
+ result = nil
+ err = nil // Return nil error to allow other analyzers to continue
+ }
+ }()
+
+ ssaResult, err := ssautil.GetSSAResult(pass)
if err != nil {
return nil, err
}
+ state := newSliceBoundsState(pass)
+ defer state.Release()
issues := map[ssa.Instruction]*issue.Issue{}
ifs := map[ssa.If]*ssa.BinOp{}
+ var violations []ssa.Instruction
for _, mcall := range ssaResult.SSA.SrcFuncs {
+ state.Reset()
for _, block := range mcall.DomPreorder() {
for _, instr := range block.Instrs {
switch instr := instr.(type) {
case *ssa.Alloc:
- sliceCap, err := extractSliceCapFromAlloc(instr.String())
- if err != nil {
- break
- }
- allocRefs := instr.Referrers()
- if allocRefs == nil {
- break
- }
- for _, instr := range *allocRefs {
- if slice, ok := instr.(*ssa.Slice); ok {
- if _, ok := slice.X.(*ssa.Alloc); ok {
+ if sliceCap, ok := extractArrayLen(instr.Type()); ok {
+ allocRefs := instr.Referrers()
+ if allocRefs == nil {
+ break
+ }
+ for _, refInstr := range *allocRefs {
+ if slice, ok := refInstr.(*ssa.Slice); ok {
if slice.Parent() != nil {
- l, h := extractSliceBounds(slice)
- newCap := computeSliceNewCap(l, h, sliceCap)
- violations := []ssa.Instruction{}
- trackSliceBounds(0, newCap, slice, &violations, ifs)
+ l, h, maxIdx := GetSliceBounds(slice)
+ violations = violations[:0]
+ if maxIdx > 0 {
+ if !isThreeIndexSliceInsideBounds(l, h, maxIdx, sliceCap) {
+ violations = append(violations, slice)
+ }
+ } else {
+ if !isSliceInsideBounds(0, sliceCap, l, h) {
+ violations = append(violations, slice)
+ }
+ }
+ newCap := ComputeSliceNewCap(l, h, maxIdx, sliceCap)
+ state.trackSliceBounds(0, newCap, slice, &violations, ifs)
for _, s := range violations {
switch s := s.(type) {
case *ssa.Slice:
@@ -89,6 +195,10 @@ func runSliceBounds(pass *analysis.Pass) (interface{}, error) {
issue.Low,
issue.High)
case *ssa.IndexAddr:
+ // Skip IndexAddr that directly accesses the original array (not the slice)
+ if s.X == instr {
+ continue
+ }
issues[s] = newIssue(
pass.Analyzer.Name,
"slice index out of range",
@@ -103,9 +213,12 @@ func runSliceBounds(pass *analysis.Pass) (interface{}, error) {
}
}
case *ssa.IndexAddr:
+ if instr.X == nil {
+ break
+ }
switch indexInstr := instr.X.(type) {
case *ssa.Const:
- if indexInstr.Type().String()[:2] == "[]" {
+ if _, ok := indexInstr.Type().Underlying().(*types.Slice); ok {
if indexInstr.Value == nil {
issues[instr] = newIssue(
pass.Analyzer.Name,
@@ -120,23 +233,18 @@ func runSliceBounds(pass *analysis.Pass) (interface{}, error) {
}
case *ssa.Alloc:
if instr.Pos() > 0 {
- typeStr := indexInstr.Type().String()
- arrayLen, err := extractArrayAllocValue(typeStr) // preallocated array
- if err != nil {
- break
- }
-
- _, err = extractIntValueIndexAddr(instr, arrayLen)
- if err != nil {
- break
+ if arrayLen, ok := extractArrayLen(indexInstr.Type()); ok {
+ indexValue, err := state.extractIntValueIndexAddr(instr, arrayLen)
+ if err == nil && !isSliceIndexInsideBounds(arrayLen, indexValue) {
+ issues[instr] = newIssue(
+ pass.Analyzer.Name,
+ "slice index out of range",
+ pass.Fset,
+ instr.Pos(),
+ issue.Low,
+ issue.High)
+ }
}
- issues[instr] = newIssue(
- pass.Analyzer.Name,
- "slice index out of range",
- pass.Fset,
- instr.Pos(),
- issue.Low,
- issue.High)
}
}
}
@@ -146,16 +254,36 @@ func runSliceBounds(pass *analysis.Pass) (interface{}, error) {
for ifref, binop := range ifs {
bound, value, err := extractBinOpBound(binop)
+
+ // New logic: attempt to handle dynamic bounds (e.g. i < len - 1)
+ var loopVar ssa.Value
+ var lenOffset int
+ var isLenBound bool
+
if err != nil {
+ // If constant extraction failed, try extracting length-based bound
+ if v, off, ok := extractLenBound(binop); ok {
+ loopVar = v
+ lenOffset = off
+ isLenBound = true
+ bound = upperBounded // Assume i < len... is an upper bound check
+ } else {
+ continue
+ }
+ }
+
+ // Guard against nil Block()
+ ifBlock := ifref.Block()
+ if ifBlock == nil {
continue
}
- for i, block := range ifref.Block().Succs {
+ for i, block := range ifBlock.Succs {
if i == 1 {
bound = invBound(bound)
}
var processBlock func(block *ssa.BasicBlock, depth int)
processBlock = func(block *ssa.BasicBlock, depth int) {
- if depth == maxDepth {
+ if depth == MaxDepth {
return
}
depth++
@@ -169,23 +297,46 @@ func runSliceBounds(pass *analysis.Pass) (interface{}, error) {
case upperBounded:
switch tinstr := instr.(type) {
case *ssa.Slice:
- lower, upper := extractSliceBounds(tinstr)
- if isSliceInsideBounds(0, value, lower, upper) {
+ _, _, m := GetSliceBounds(tinstr)
+ if !isLenBound && isSliceInsideBounds(0, value, m, value) {
delete(issues, instr)
}
case *ssa.IndexAddr:
- indexValue, err := extractIntValue(tinstr.Index.String())
- if err != nil {
- break
+ if isLenBound {
+ if idxOffset, ok := extractIndexOffset(tinstr.Index, loopVar); ok {
+ if lenOffset+idxOffset-1 < 0 {
+ delete(issues, instr)
+ }
+ }
+ } else {
+ if indexValue, ok := GetConstantInt64(tinstr.Index); ok {
+ if isSliceIndexInsideBounds(value, int(indexValue)) {
+ delete(issues, instr)
+ }
+ }
}
- if isSliceIndexInsideBounds(value, indexValue) {
+ }
+ case bounded:
+ switch tinstr := instr.(type) {
+ case *ssa.Slice:
+ _, _, m := GetSliceBounds(tinstr)
+ if isSliceInsideBounds(value, value, m, value) {
delete(issues, instr)
}
+ case *ssa.IndexAddr:
+ if indexValue, ok := GetConstantInt64(tinstr.Index); ok {
+ if int(indexValue) == value {
+ delete(issues, instr)
+ }
+ }
}
}
} else if nestedIfInstr, ok := instr.(*ssa.If); ok {
- for _, nestedBlock := range nestedIfInstr.Block().Succs {
- processBlock(nestedBlock, depth)
+ // Guard against nil Block()
+ if nestedIfBlock := nestedIfInstr.Block(); nestedIfBlock != nil {
+ for _, nestedBlock := range nestedIfBlock.Succs {
+ processBlock(nestedBlock, depth)
+ }
}
}
}
@@ -205,11 +356,173 @@ func runSliceBounds(pass *analysis.Pass) (interface{}, error) {
return nil, nil
}
-func trackSliceBounds(depth int, sliceCap int, slice ssa.Node, violations *[]ssa.Instruction, ifs map[ssa.If]*ssa.BinOp) {
- if depth == maxDepth {
+// extractLenBound checks if the binop is of form "Var < Len + Offset" or equivalent patterns
+// (including offsets on the left-hand side like "(Var + Const) < Len")
+func extractLenBound(binop *ssa.BinOp) (ssa.Value, int, bool) {
+ if binop == nil {
+ return nil, 0, false
+ }
+ // Only handle Less Than for now
+ if binop.Op != token.LSS {
+ return nil, 0, false
+ }
+
+ var loopVar ssa.Value
+ var lenOffset int
+
+ // First, try to interpret RHS as the length expression (len +/- const) and LHS as plain loop var
+ loopVar = binop.X // candidate loop variable
+
+ if _, isConst := binop.Y.(*ssa.Const); isConst {
+ // RHS is a constant → cannot be a length-bound check
+ return nil, 0, false
+ }
+
+ // Try to pull an offset from RHS if it is len +/- const
+ if rhsBinOp, ok := binop.Y.(*ssa.BinOp); ok && (rhsBinOp.Op == token.ADD || rhsBinOp.Op == token.SUB) {
+ var constVal int
+ var foundConst bool
+
+ // Check both sides for the constant (symmetric for ADD, careful for SUB)
+ if val, ok := GetConstantInt64(rhsBinOp.Y); ok {
+ constVal = int(val)
+ foundConst = true
+ } else if val, ok := GetConstantInt64(rhsBinOp.X); ok {
+ constVal = int(val)
+ foundConst = true
+ }
+
+ if foundConst {
+ switch rhsBinOp.Op {
+ case token.ADD:
+ // len + k or k + len → same meaning
+ lenOffset = constVal
+ case token.SUB:
+ if _, isConstOnLeft := rhsBinOp.X.(*ssa.Const); isConstOnLeft {
+ // k - len → unusual for a strict upper bound, skip this pattern
+ foundConst = false
+ } else {
+ // len - k
+ lenOffset = -constVal
+ }
+ }
+ if foundConst {
+ return loopVar, lenOffset, true
+ }
+ }
+ }
+
+ // If we get here, RHS is a plain length (no extractable offset) or extraction failed.
+ // Now try the alternative pattern: LHS is (loopVar +/- const), RHS is plain len
+ if lhsBinOp, ok := binop.X.(*ssa.BinOp); ok && (lhsBinOp.Op == token.ADD || lhsBinOp.Op == token.SUB) {
+ var constVal int
+ var varVal ssa.Value
+ var found bool
+
+ if val, ok := GetConstantInt64(lhsBinOp.Y); ok {
+ constVal = int(val)
+ varVal = lhsBinOp.X
+ found = true
+ } else if val, ok := GetConstantInt64(lhsBinOp.X); ok {
+ constVal = int(val)
+ varVal = lhsBinOp.Y
+ found = true
+ }
+
+ if found {
+ loopVar = varVal
+ switch lhsBinOp.Op {
+ case token.ADD:
+ // (i + k) < len → equivalent to i < len - k
+ lenOffset = -constVal
+ case token.SUB:
+ // (i - k) < len → equivalent to i < len + k (rare but safe)
+ lenOffset = constVal
+ }
+ return loopVar, lenOffset, true
+ }
+ }
+
+ // Fallback: plain i < len (offset 0)
+ return loopVar, 0, true
+}
+
+// extractIndexOffset checks if indexVal is "loopVar + C"
+// returns the constant C and true if successful
+func extractIndexOffset(indexVal ssa.Value, loopVar ssa.Value) (int, bool) {
+ if indexVal == loopVar {
+ return 0, true
+ }
+
+ if binOp, ok := indexVal.(*ssa.BinOp); ok {
+ switch binOp.Op {
+ case token.ADD:
+ if binOp.X == loopVar {
+ if val, ok := GetConstantInt64(binOp.Y); ok {
+ return int(val), true
+ }
+ }
+ if binOp.Y == loopVar {
+ if val, ok := GetConstantInt64(binOp.X); ok {
+ return int(val), true
+ }
+ }
+ case token.SUB:
+ if binOp.X == loopVar {
+ if val, ok := GetConstantInt64(binOp.Y); ok {
+ return int(-val), true
+ }
+ }
+ }
+ }
+ return 0, false
+}
+
+// decomposeIndex splits an SSA Value into a base value and a constant offset.
+func decomposeIndex(v ssa.Value) (ssa.Value, int) {
+ if binOp, ok := v.(*ssa.BinOp); ok {
+ switch binOp.Op {
+ case token.ADD:
+ if val, ok := GetConstantInt64(binOp.Y); ok {
+ base, offset := decomposeIndex(binOp.X)
+ return base, offset + int(val)
+ }
+ if val, ok := GetConstantInt64(binOp.X); ok {
+ base, offset := decomposeIndex(binOp.Y)
+ return base, offset + int(val)
+ }
+ case token.SUB:
+ if val, ok := GetConstantInt64(binOp.Y); ok {
+ base, offset := decomposeIndex(binOp.X)
+ return base, offset - int(val)
+ }
+ }
+ }
+ return v, 0
+}
+
+// trackSliceBounds recursively follows slice referrers to check for index and boundary violations.
+func (s *sliceBoundsState) trackSliceBounds(depth int, sliceCap int, slice ssa.Node, violations *[]ssa.Instruction, ifs map[ssa.If]*ssa.BinOp) {
+ if depth == MaxDepth {
return
}
depth++
+
+ key := trackCacheKey{slice, sliceCap}
+ if res, ok := s.trackCache[key]; ok {
+ if res == nil { // visiting
+ return
+ }
+ *violations = append(*violations, res.violations...)
+ maps.Copy(ifs, res.ifs)
+ return
+ }
+ s.trackCache[key] = nil // mark as visiting
+
+ res := s.acquireTrackCacheValue()
+ localViolations := &res.violations
+ localIfs := res.ifs
+
if violations == nil {
violations = &[]ssa.Instruction{}
}
@@ -218,25 +531,24 @@ func trackSliceBounds(depth int, sliceCap int, slice ssa.Node, violations *[]ssa
for _, refinstr := range *referrers {
switch refinstr := refinstr.(type) {
case *ssa.Slice:
- checkAllSlicesBounds(depth, sliceCap, refinstr, violations, ifs)
+ s.checkAllSlicesBounds(depth, sliceCap, refinstr, localViolations, localIfs)
switch refinstr.X.(type) {
- case *ssa.Alloc, *ssa.Parameter:
- l, h := extractSliceBounds(refinstr)
- newCap := computeSliceNewCap(l, h, sliceCap)
- trackSliceBounds(depth, newCap, refinstr, violations, ifs)
+ case *ssa.Alloc, *ssa.Parameter, *ssa.Slice:
+ l, h, maxIdx := GetSliceBounds(refinstr)
+ newCap := ComputeSliceNewCap(l, h, maxIdx, sliceCap)
+ s.trackSliceBounds(depth, newCap, refinstr, localViolations, localIfs)
}
case *ssa.IndexAddr:
- indexValue, err := extractIntValue(refinstr.Index.String())
- if err == nil && !isSliceIndexInsideBounds(sliceCap, indexValue) {
- *violations = append(*violations, refinstr)
+ if indexValue, ok := GetConstantInt64(refinstr.Index); ok && !isSliceIndexInsideBounds(sliceCap, int(indexValue)) {
+ *localViolations = append(*localViolations, refinstr)
}
- indexValue, err = extractIntValueIndexAddr(refinstr, sliceCap)
+ indexValue, err := s.extractIntValueIndexAddr(refinstr, sliceCap)
if err == nil && !isSliceIndexInsideBounds(sliceCap, indexValue) {
- *violations = append(*violations, refinstr)
+ *localViolations = append(*localViolations, refinstr)
}
case *ssa.Call:
if ifref, cond := extractSliceIfLenCondition(refinstr); ifref != nil && cond != nil {
- ifs[*ifref] = cond
+ localIfs[*ifref] = cond
} else {
parPos := -1
for pos, arg := range refinstr.Call.Args {
@@ -247,58 +559,237 @@ func trackSliceBounds(depth int, sliceCap int, slice ssa.Node, violations *[]ssa
if fn, ok := refinstr.Call.Value.(*ssa.Function); ok {
if len(fn.Params) > parPos && parPos > -1 {
param := fn.Params[parPos]
- trackSliceBounds(depth, sliceCap, param, violations, ifs)
+ s.trackSliceBounds(depth, sliceCap, param, localViolations, localIfs)
}
}
}
}
}
}
+
+ *violations = append(*violations, *localViolations...)
+ maps.Copy(ifs, localIfs)
+ s.trackCache[key] = res
}
-func extractIntValueIndexAddr(refinstr *ssa.IndexAddr, sliceCap int) (int, error) {
- var indexIncr, sliceIncr int
+func (s *sliceBoundsState) extractIntValueIndexAddr(refinstr *ssa.IndexAddr, sliceCap int) (int, error) {
+ base, offset := decomposeIndex(refinstr.Index)
+ var sliceIncr int
- for _, block := range refinstr.Block().Preds {
- for _, instr := range block.Instrs {
- switch instr := instr.(type) {
- case *ssa.BinOp:
- _, index, err := extractBinOpBound(instr)
- if err != nil {
- return 0, err
+ canNormalizeToBase := func(bin *ssa.BinOp) bool {
+ if bin == nil || refinstr == nil {
+ return false
+ }
+ binBlock := bin.Block()
+ idxBlock := refinstr.Block()
+ if binBlock == nil || idxBlock == nil {
+ return false
+ }
+ if binBlock != idxBlock {
+ return true
+ }
+ binPos := -1
+ idxPos := -1
+ for i, ins := range binBlock.Instrs {
+ if ins == bin {
+ binPos = i
+ }
+ if ins == refinstr {
+ idxPos = i
+ }
+ if binPos >= 0 && idxPos >= 0 {
+ break
+ }
+ }
+ if binPos < 0 || idxPos < 0 {
+ return false
+ }
+ return binPos < idxPos
+ }
+
+ // Case 1: Base is a constant (e.g., s[0+3])
+ if val, ok := GetConstantInt64(base); ok {
+ finalIdx := int(val) + offset
+ if !isSliceIndexInsideBounds(sliceCap+sliceIncr, finalIdx) {
+ return finalIdx, nil
+ }
+ // Constant index is within bounds; avoid BFS exploring shared SSA constant referrers
+ return 0, errNoFound
+ }
+
+ // Case 2: Base is a Phi node (loop counter)
+ if p, ok := base.(*ssa.Phi); ok {
+ var start int
+ var hasStart bool
+ var next ssa.Value
+ for _, edge := range p.Edges {
+ // Guard against nil edges
+ if edge == nil {
+ continue
+ }
+ eBase, eOffset := decomposeIndex(edge)
+ if val, ok := GetConstantInt64(eBase); ok {
+ start = int(val) + eOffset
+ hasStart = true
+ // Direct check for initial value violation
+ if !isSliceIndexInsideBounds(sliceCap+sliceIncr, start+offset) {
+ return start + offset, nil
+ }
+ } else {
+ next = edge
+ }
+ }
+
+ if hasStart && next != nil {
+ // Look for loop limit: next < limit or p < limit
+ nBase, nOffset := decomposeIndex(next)
+ var searchVals [3]ssa.Value
+ searchVals[0] = p
+ searchVals[1] = nBase
+ numVals := 2
+ if nBase != next {
+ searchVals[2] = next
+ numVals = 3
+ }
+
+ for _, v := range searchVals[:numVals] {
+ if v == nil {
+ continue
}
- switch instr.Op {
- case token.LSS:
- indexIncr--
+ refs := v.Referrers()
+ if refs == nil {
+ continue
}
+ for _, r := range *refs {
+ if bin, ok := r.(*ssa.BinOp); ok {
+ // Check for constant bound
+ bound, limit, err := extractBinOpBound(bin)
+ if err == nil {
+ incr := 0
+ if bin.Op == token.LSS {
+ incr = -1
+ }
+ maxV := limit + incr
+
+ // If the limit is found on an incremented value (next or nBase != p),
+ // normalize it back to the base loop variable before applying index offset.
+ boundAdjust := 0
+ if (v == next && base != next && canNormalizeToBase(bin)) || (v == nBase && nBase != p && base != nBase) {
+ boundAdjust = -nOffset
+ }
- if !isSliceIndexInsideBounds(sliceCap+sliceIncr, index+indexIncr) {
- return index, nil
+ if bound == lowerUnbounded || bound == upperBounded {
+ finalMaxV := maxV + boundAdjust
+ if !isSliceIndexInsideBounds(sliceCap+sliceIncr, finalMaxV+offset) {
+ return finalMaxV + offset, nil
+ }
+ }
+ } else if _, off, ok := extractLenBound(bin); ok {
+ // Check for length bound (e.g. i < len(s) + off)
+ // Here the limit is effectively sliceCap
+ limit := sliceCap
+ incr := -1 // extractLenBound only handles LSS for now
+ maxV := limit + off + incr
+
+ boundAdjust := 0
+ if (v == next && base != next && canNormalizeToBase(bin)) || (v == nBase && nBase != p && base != nBase) {
+ boundAdjust = -nOffset
+ }
+ finalMaxV := maxV + boundAdjust
+ if !isSliceIndexInsideBounds(sliceCap+sliceIncr, finalMaxV+offset) {
+ return finalMaxV + offset, nil
+ }
+ }
+ }
}
}
}
}
- return 0, errors.New("no found")
+ // Falls back to existing queue search for complex dependencies
+ s.valQueue = s.valQueue[:0]
+ s.valQueue = append(s.valQueue, valOffset{base, offset})
+ clear(s.Visited)
+ depth := 0
+
+ head := 0
+ for head < len(s.valQueue) && depth < MaxDepth {
+ levelSize := len(s.valQueue) - head
+ for i := 0; i < levelSize; i++ {
+ item := s.valQueue[head]
+ head++
+ if s.Visited[item.val] {
+ continue
+ }
+ s.Visited[item.val] = true
+
+ idxRefs := item.val.Referrers()
+ if idxRefs == nil {
+ continue
+ }
+ for _, instr := range *idxRefs {
+ switch instr := instr.(type) {
+ case *ssa.BinOp:
+ switch instr.Op {
+ case token.ADD:
+ if val, ok := GetConstantInt64(instr.Y); ok {
+ s.valQueue = append(s.valQueue, valOffset{instr, item.offset - int(val)})
+ }
+ case token.SUB:
+ if val, ok := GetConstantInt64(instr.Y); ok {
+ s.valQueue = append(s.valQueue, valOffset{instr, item.offset + int(val)})
+ }
+ case token.LSS, token.LEQ, token.GTR, token.GEQ:
+ // Already handled by loop counter logic for Phi,
+ // but handle other variables here
+ if _, ok := item.val.(*ssa.Phi); !ok {
+ _, index, err := extractBinOpBound(instr)
+ if err != nil {
+ continue
+ }
+ incr := 0
+ if instr.Op == token.LSS {
+ incr = -1
+ }
+
+ if !isSliceIndexInsideBounds(sliceCap+sliceIncr, index+incr+item.offset) {
+ return index + item.offset, nil
+ }
+ }
+ }
+ }
+ }
+ }
+ depth++
+ }
+
+ return 0, errNoFound
}
-func checkAllSlicesBounds(depth int, sliceCap int, slice *ssa.Slice, violations *[]ssa.Instruction, ifs map[ssa.If]*ssa.BinOp) {
- if depth == maxDepth {
+// checkAllSlicesBounds validates slice operation boundaries against the known capacity or limit.
+func (s *sliceBoundsState) checkAllSlicesBounds(depth int, sliceCap int, slice *ssa.Slice, violations *[]ssa.Instruction, ifs map[ssa.If]*ssa.BinOp) {
+ if depth == MaxDepth {
return
}
depth++
if violations == nil {
violations = &[]ssa.Instruction{}
}
- sliceLow, sliceHigh := extractSliceBounds(slice)
- if !isSliceInsideBounds(0, sliceCap, sliceLow, sliceHigh) {
- *violations = append(*violations, slice)
+ sliceLow, sliceHigh, sliceMax := GetSliceBounds(slice)
+ if sliceMax > 0 {
+ if !isThreeIndexSliceInsideBounds(sliceLow, sliceHigh, sliceMax, sliceCap) {
+ *violations = append(*violations, slice)
+ }
+ } else {
+ if !isSliceInsideBounds(0, sliceCap, sliceLow, sliceHigh) {
+ *violations = append(*violations, slice)
+ }
}
switch slice.X.(type) {
case *ssa.Alloc, *ssa.Parameter, *ssa.Slice:
- l, h := extractSliceBounds(slice)
- newCap := computeSliceNewCap(l, h, sliceCap)
- trackSliceBounds(depth, newCap, slice, violations, ifs)
+ l, h, maxIdx := GetSliceBounds(slice)
+ newCap := ComputeSliceNewCap(l, h, maxIdx, sliceCap)
+ s.trackSliceBounds(depth, newCap, slice, violations, ifs)
}
references := slice.Referrers()
@@ -306,14 +797,14 @@ func checkAllSlicesBounds(depth int, sliceCap int, slice *ssa.Slice, violations
return
}
for _, ref := range *references {
- switch s := ref.(type) {
+ switch r := ref.(type) {
case *ssa.Slice:
- checkAllSlicesBounds(depth, sliceCap, s, violations, ifs)
- switch s.X.(type) {
- case *ssa.Alloc, *ssa.Parameter:
- l, h := extractSliceBounds(s)
- newCap := computeSliceNewCap(l, h, sliceCap)
- trackSliceBounds(depth, newCap, s, violations, ifs)
+ s.checkAllSlicesBounds(depth, sliceCap, r, violations, ifs)
+ switch r.X.(type) {
+ case *ssa.Alloc, *ssa.Parameter, *ssa.Slice:
+ l, h, maxIdx := GetSliceBounds(r)
+ newCap := ComputeSliceNewCap(l, h, maxIdx, sliceCap)
+ s.trackSliceBounds(depth, newCap, r, violations, ifs)
}
}
}
@@ -322,37 +813,33 @@ func checkAllSlicesBounds(depth int, sliceCap int, slice *ssa.Slice, violations
func extractSliceIfLenCondition(call *ssa.Call) (*ssa.If, *ssa.BinOp) {
if builtInLen, ok := call.Call.Value.(*ssa.Builtin); ok {
if builtInLen.Name() == "len" {
- refs := call.Referrers()
- if refs != nil {
- for _, ref := range *refs {
+ refs := []ssa.Instruction{}
+ if call.Referrers() != nil {
+ refs = append(refs, *call.Referrers()...)
+ }
+ depth := 0
+ for len(refs) > 0 && depth < MaxDepth {
+ newrefs := []ssa.Instruction{}
+ for _, ref := range refs {
if binop, ok := ref.(*ssa.BinOp); ok {
binoprefs := binop.Referrers()
for _, ref := range *binoprefs {
if ifref, ok := ref.(*ssa.If); ok {
return ifref, binop
}
+ newrefs = append(newrefs, ref)
}
}
}
+ refs = newrefs
+ depth++
}
+
}
}
return nil, nil
}
-func computeSliceNewCap(l, h, oldCap int) int {
- if l == 0 && h == 0 {
- return oldCap
- }
- if l > 0 && h == 0 {
- return oldCap - l
- }
- if l == 0 && h > 0 {
- return h
- }
- return h - l
-}
-
func invBound(bound bound) bound {
switch bound {
case lowerUnbounded:
@@ -363,30 +850,36 @@ func invBound(bound bound) bound {
return unbounded
case unbounded:
return upperBounded
+ case bounded:
+ return bounded
default:
return unbounded
}
}
-var errExtractBinOp = fmt.Errorf("unable to extract constant from binop")
+var errExtractBinOp = errors.New("unable to extract constant from binop")
func extractBinOpBound(binop *ssa.BinOp) (bound, int, error) {
+ if binop == nil {
+ return lowerUnbounded, 0, errExtractBinOp
+ }
if binop.X != nil {
if x, ok := binop.X.(*ssa.Const); ok {
if x.Value == nil {
return lowerUnbounded, 0, errExtractBinOp
}
- value, err := strconv.Atoi(x.Value.String())
- if err != nil {
- return lowerUnbounded, value, err
+ val, ok := constant.Int64Val(x.Value)
+ if !ok {
+ return lowerUnbounded, 0, errExtractBinOp
}
+ value := int(val)
switch binop.Op {
case token.LSS, token.LEQ:
return upperUnbounded, value, nil
case token.GTR, token.GEQ:
return lowerUnbounded, value, nil
case token.EQL:
- return upperBounded, value, nil
+ return bounded, value, nil
case token.NEQ:
return unbounded, value, nil
}
@@ -397,17 +890,18 @@ func extractBinOpBound(binop *ssa.BinOp) (bound, int, error) {
if y.Value == nil {
return lowerUnbounded, 0, errExtractBinOp
}
- value, err := strconv.Atoi(y.Value.String())
- if err != nil {
- return lowerUnbounded, value, err
+ val, ok := constant.Int64Val(y.Value)
+ if !ok {
+ return lowerUnbounded, 0, errExtractBinOp
}
+ value := int(val)
switch binop.Op {
case token.LSS, token.LEQ:
return lowerUnbounded, value, nil
case token.GTR, token.GEQ:
return upperUnbounded, value, nil
case token.EQL:
- return upperBounded, value, nil
+ return bounded, value, nil
case token.NEQ:
return unbounded, value, nil
}
@@ -420,93 +914,13 @@ func isSliceIndexInsideBounds(h int, index int) bool {
return (0 <= index && index < h)
}
-func isSliceInsideBounds(l, h int, cl, ch int) bool {
- return (l <= cl && h >= ch) && (l <= ch && h >= cl)
-}
-
-func extractSliceBounds(slice *ssa.Slice) (int, int) {
- var low int
- if slice.Low != nil {
- l, err := extractIntValue(slice.Low.String())
- if err == nil {
- low = l
- }
- }
- var high int
- if slice.High != nil {
- h, err := extractIntValue(slice.High.String())
- if err == nil {
- high = h
- }
- }
- return low, high
-}
-
-func extractIntValue(value string) (int, error) {
- if i, err := extractIntValuePhi(value); err == nil {
- return i, nil
- }
-
- parts := strings.Split(value, ":")
- if len(parts) != 2 {
- return 0, fmt.Errorf("invalid value: %s", value)
- }
- if parts[1] != "int" {
- return 0, fmt.Errorf("invalid value: %s", value)
- }
- return strconv.Atoi(parts[0])
-}
-
-func extractSliceCapFromAlloc(instr string) (int, error) {
- re := regexp.MustCompile(`new \[(\d+)\].*`)
- var sliceCap int
- matches := re.FindAllStringSubmatch(instr, -1)
- if matches == nil {
- return sliceCap, errors.New("no slice cap found")
- }
-
- if len(matches) > 0 {
- m := matches[0]
- if len(m) > 1 {
- return strconv.Atoi(m[1])
- }
- }
-
- return 0, errors.New("no slice cap found")
-}
-
-func extractIntValuePhi(value string) (int, error) {
- re := regexp.MustCompile(`phi \[.+: (\d+):.+, .*\].*`)
- var sliceCap int
- matches := re.FindAllStringSubmatch(value, -1)
- if matches == nil {
- return sliceCap, fmt.Errorf("invalid value: %s", value)
+// extractArrayLen attempts to determine the length of an array type, stripping pointers if necessary.
+func extractArrayLen(t types.Type) (int, bool) {
+ if ptr, ok := t.Underlying().(*types.Pointer); ok {
+ t = ptr.Elem()
}
-
- if len(matches) > 0 {
- m := matches[0]
- if len(m) > 1 {
- return strconv.Atoi(m[1])
- }
+ if arr, ok := t.Underlying().(*types.Array); ok {
+ return int(arr.Len()), true
}
-
- return 0, fmt.Errorf("invalid value: %s", value)
-}
-
-func extractArrayAllocValue(value string) (int, error) {
- re := regexp.MustCompile(`.*\[(\d+)\].*`)
- var sliceCap int
- matches := re.FindAllStringSubmatch(value, -1)
- if matches == nil {
- return sliceCap, fmt.Errorf("invalid value: %s", value)
- }
-
- if len(matches) > 0 {
- m := matches[0]
- if len(m) > 1 {
- return strconv.Atoi(m[1])
- }
- }
-
- return 0, fmt.Errorf("invalid value: %s", value)
+ return 0, false
}
diff --git a/vendor/github.com/securego/gosec/v2/analyzers/smtpinjection.go b/vendor/github.com/securego/gosec/v2/analyzers/smtpinjection.go
new file mode 100644
index 000000000..88fd8a39b
--- /dev/null
+++ b/vendor/github.com/securego/gosec/v2/analyzers/smtpinjection.go
@@ -0,0 +1,67 @@
+// (c) Copyright gosec's authors
+//
+// 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 analyzers
+
+import (
+ "golang.org/x/tools/go/analysis"
+
+ "github.com/securego/gosec/v2/taint"
+)
+
+// SMTPInjection returns a configuration for detecting SMTP command/header injection vulnerabilities.
+func SMTPInjection() taint.Config {
+ return taint.Config{
+ Sources: []taint.Source{
+ // Type sources: tainted when received as parameters
+ {Package: "net/http", Name: "Request", Pointer: true},
+ {Package: "net/url", Name: "URL", Pointer: true},
+ {Package: "net/url", Name: "Values"},
+ {Package: "bufio", Name: "Reader", Pointer: true},
+ {Package: "bufio", Name: "Scanner", Pointer: true},
+
+ // Function sources
+ {Package: "os", Name: "Args", IsFunc: true},
+ {Package: "os", Name: "Getenv", IsFunc: true},
+ },
+ Sinks: []taint.Sink{
+ // net/smtp.SendMail(addr, auth, from, to, msg)
+ // Check sender and recipient envelope fields.
+ {Package: "net/smtp", Method: "SendMail", CheckArgs: []int{2, 3}},
+
+ // For smtp.Client methods, Args[0] is receiver.
+ {Package: "net/smtp", Receiver: "Client", Method: "Mail", Pointer: true, CheckArgs: []int{1}},
+ {Package: "net/smtp", Receiver: "Client", Method: "Rcpt", Pointer: true, CheckArgs: []int{1}},
+ },
+ Sanitizers: []taint.Sanitizer{
+ // net/mail parsers enforce RFC-compatible mailbox/address syntax.
+ {Package: "net/mail", Method: "ParseAddress"},
+ {Package: "net/mail", Method: "ParseAddressList"},
+
+ // AddressParser methods also provide structured parsing.
+ {Package: "net/mail", Receiver: "AddressParser", Method: "Parse", Pointer: true},
+ {Package: "net/mail", Receiver: "AddressParser", Method: "ParseList", Pointer: true},
+ },
+ }
+}
+
+// newSMTPInjectionAnalyzer creates an analyzer for detecting SMTP injection vulnerabilities
+// via taint analysis (G707)
+func newSMTPInjectionAnalyzer(id string, description string) *analysis.Analyzer {
+ config := SMTPInjection()
+ rule := SMTPInjectionRule
+ rule.ID = id
+ rule.Description = description
+ return taint.NewGosecAnalyzer(&rule, &config)
+}
diff --git a/vendor/github.com/securego/gosec/v2/analyzers/sqlinjection.go b/vendor/github.com/securego/gosec/v2/analyzers/sqlinjection.go
new file mode 100644
index 000000000..5207bca5c
--- /dev/null
+++ b/vendor/github.com/securego/gosec/v2/analyzers/sqlinjection.go
@@ -0,0 +1,73 @@
+// (c) Copyright gosec's authors
+//
+// 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 analyzers
+
+import (
+ "golang.org/x/tools/go/analysis"
+
+ "github.com/securego/gosec/v2/taint"
+)
+
+// SQLInjection returns a configuration for detecting SQL injection vulnerabilities.
+func SQLInjection() taint.Config {
+ return taint.Config{
+ Sources: []taint.Source{
+ // Type sources: tainted when received as parameters
+ {Package: "net/http", Name: "Request", Pointer: true},
+ {Package: "net/url", Name: "URL", Pointer: true},
+ {Package: "net/url", Name: "Values"},
+ {Package: "bufio", Name: "Reader", Pointer: true},
+ {Package: "bufio", Name: "Scanner", Pointer: true},
+
+ // Function sources
+ {Package: "os", Name: "Args", IsFunc: true},
+ {Package: "os", Name: "Getenv", IsFunc: true},
+ },
+ Sinks: []taint.Sink{
+ // For SQL methods, Args[0] is receiver, Args[1] is query string
+ // Only check query string argument; prepared statement params are safe
+ {Package: "database/sql", Receiver: "DB", Method: "Query", Pointer: true, CheckArgs: []int{1}},
+ {Package: "database/sql", Receiver: "DB", Method: "QueryContext", Pointer: true, CheckArgs: []int{2}},
+ {Package: "database/sql", Receiver: "DB", Method: "QueryRow", Pointer: true, CheckArgs: []int{1}},
+ {Package: "database/sql", Receiver: "DB", Method: "QueryRowContext", Pointer: true, CheckArgs: []int{2}},
+ {Package: "database/sql", Receiver: "DB", Method: "Exec", Pointer: true, CheckArgs: []int{1}},
+ {Package: "database/sql", Receiver: "DB", Method: "ExecContext", Pointer: true, CheckArgs: []int{2}},
+ {Package: "database/sql", Receiver: "DB", Method: "Prepare", Pointer: true, CheckArgs: []int{1}},
+ {Package: "database/sql", Receiver: "DB", Method: "PrepareContext", Pointer: true, CheckArgs: []int{2}},
+ {Package: "database/sql", Receiver: "Tx", Method: "Query", Pointer: true, CheckArgs: []int{1}},
+ {Package: "database/sql", Receiver: "Tx", Method: "QueryContext", Pointer: true, CheckArgs: []int{2}},
+ {Package: "database/sql", Receiver: "Tx", Method: "QueryRow", Pointer: true, CheckArgs: []int{1}},
+ {Package: "database/sql", Receiver: "Tx", Method: "QueryRowContext", Pointer: true, CheckArgs: []int{2}},
+ {Package: "database/sql", Receiver: "Tx", Method: "Exec", Pointer: true, CheckArgs: []int{1}},
+ {Package: "database/sql", Receiver: "Tx", Method: "ExecContext", Pointer: true, CheckArgs: []int{2}},
+ {Package: "database/sql", Receiver: "Tx", Method: "Prepare", Pointer: true, CheckArgs: []int{1}},
+ {Package: "database/sql", Receiver: "Tx", Method: "PrepareContext", Pointer: true, CheckArgs: []int{2}},
+ },
+ Sanitizers: []taint.Sanitizer{
+ // No stdlib sanitizers for SQL — use parameterized queries instead.
+ // The CheckArgs configuration already excludes prepared statement params.
+ },
+ }
+}
+
+// newSQLInjectionAnalyzer creates an analyzer for detecting SQL injection vulnerabilities
+// via taint analysis (G701)
+func newSQLInjectionAnalyzer(id string, description string) *analysis.Analyzer {
+ config := SQLInjection()
+ rule := SQLInjectionRule
+ rule.ID = id
+ rule.Description = description
+ return taint.NewGosecAnalyzer(&rule, &config)
+}
diff --git a/vendor/github.com/securego/gosec/v2/analyzers/ssh_callback.go b/vendor/github.com/securego/gosec/v2/analyzers/ssh_callback.go
new file mode 100644
index 000000000..b43e63395
--- /dev/null
+++ b/vendor/github.com/securego/gosec/v2/analyzers/ssh_callback.go
@@ -0,0 +1,381 @@
+// (c) Copyright gosec's authors
+//
+// 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 analyzers
+
+import (
+ "go/types"
+
+ "golang.org/x/tools/go/analysis"
+ "golang.org/x/tools/go/analysis/passes/buildssa"
+ "golang.org/x/tools/go/ssa"
+
+ "github.com/securego/gosec/v2/internal/ssautil"
+ "github.com/securego/gosec/v2/issue"
+)
+
+const defaultSSHCallbackIssueDescription = "Stateful misuse of ssh.PublicKeyCallback leading to auth bypass"
+
+// newSSHCallbackAnalyzer creates an analyzer for detecting stateful misuse of
+// ssh.ServerConfig.PublicKeyCallback that can lead to authentication bypass (G408)
+func newSSHCallbackAnalyzer(id string, description string) *analysis.Analyzer {
+ return &analysis.Analyzer{
+ Name: id,
+ Doc: description,
+ Run: runSSHCallbackAnalysis,
+ Requires: []*analysis.Analyzer{buildssa.Analyzer},
+ }
+}
+
+// callbackInfo holds information about a detected PublicKeyCallback assignment
+type callbackInfo struct {
+ makeClosure *ssa.MakeClosure
+ closure *ssa.Function
+ storeInstr ssa.Instruction
+}
+
+func runSSHCallbackAnalysis(pass *analysis.Pass) (any, error) {
+ ssaResult, err := ssautil.GetSSAResult(pass)
+ if err != nil {
+ return nil, err
+ }
+
+ state := newSSHCallbackState(pass, ssaResult.SSA.SrcFuncs)
+ defer state.Release()
+
+ // Find all PublicKeyCallback assignments
+ callbacks := state.findCallbackAssignments()
+
+ // DEBUG: Report found callbacks
+ if len(callbacks) == 0 {
+ // No callbacks found - this is expected for most files
+ return nil, nil
+ }
+
+ var issues []*issue.Issue
+ for _, cb := range callbacks {
+ // Clear visited map before analyzing each callback to prevent interference
+ state.Reset()
+ if issue := state.analyzeCallback(cb); issue != nil {
+ issues = append(issues, issue)
+ }
+ }
+
+ if len(issues) > 0 {
+ return issues, nil
+ }
+ return nil, nil
+}
+
+type sshCallbackState struct {
+ *BaseAnalyzerState
+ ssaFuncs []*ssa.Function
+}
+
+func newSSHCallbackState(pass *analysis.Pass, funcs []*ssa.Function) *sshCallbackState {
+ return &sshCallbackState{
+ BaseAnalyzerState: NewBaseState(pass),
+ ssaFuncs: funcs,
+ }
+}
+
+// findCallbackAssignments scans the SSA for assignments to ssh.ServerConfig.PublicKeyCallback
+func (s *sshCallbackState) findCallbackAssignments() []callbackInfo {
+ var callbacks []callbackInfo
+
+ if len(s.ssaFuncs) == 0 {
+ return callbacks
+ }
+
+ TraverseSSA(s.ssaFuncs, func(b *ssa.BasicBlock, instr ssa.Instruction) {
+ // Check for stores to field addresses
+ store, ok := instr.(*ssa.Store)
+ if !ok {
+ return
+ }
+
+ // Check if we're storing to a field address
+ fieldAddr, ok := store.Addr.(*ssa.FieldAddr)
+ if !ok {
+ return
+ }
+
+ // Try to get the type information
+ xType := fieldAddr.X.Type()
+ if xType == nil {
+ return
+ }
+
+ // Look through pointer types
+ underlyingType := xType
+ if ptrType, ok := xType.(*types.Pointer); ok {
+ underlyingType = ptrType.Elem()
+ }
+
+ // Get the named type
+ namedType, ok := underlyingType.(*types.Named)
+ if !ok {
+ return
+ }
+
+ obj := namedType.Obj()
+ if obj == nil {
+ return
+ }
+
+ // Check type name first
+ if obj.Name() != "ServerConfig" {
+ return
+ }
+
+ // Check the field name
+ structType, ok := namedType.Underlying().(*types.Struct)
+ if !ok || fieldAddr.Field >= structType.NumFields() {
+ return
+ }
+
+ field := structType.Field(fieldAddr.Field)
+ if field.Name() != "PublicKeyCallback" {
+ return
+ }
+
+ // The combination of ServerConfig type with PublicKeyCallback field
+ // is unique to SSH server configurations
+
+ // Extract the closure being stored
+ var closureFn *ssa.Function
+ var makeClosure *ssa.MakeClosure
+
+ // Try different ways the closure might be stored
+ switch val := store.Val.(type) {
+ case *ssa.MakeClosure:
+ // Direct MakeClosure
+ makeClosure = val
+ if fn, ok := val.Fn.(*ssa.Function); ok {
+ closureFn = fn
+ }
+ case *ssa.Function:
+ // Direct function assignment (anonymous functions)
+ if val.Parent() != nil {
+ // This is a closure (has a parent function)
+ closureFn = val
+ }
+ case *ssa.MakeInterface:
+ // MakeClosure wrapped in MakeInterface
+ if mc, ok := val.X.(*ssa.MakeClosure); ok {
+ makeClosure = mc
+ if fn, ok := mc.Fn.(*ssa.Function); ok {
+ closureFn = fn
+ }
+ }
+ }
+
+ if closureFn == nil {
+ return
+ }
+
+ callbacks = append(callbacks, callbackInfo{
+ makeClosure: makeClosure, // May be nil for direct function assignments
+ closure: closureFn,
+ storeInstr: store,
+ })
+ })
+
+ return callbacks
+}
+
+// analyzeCallback checks if a closure writes to captured variables
+func (s *sshCallbackState) analyzeCallback(cb callbackInfo) *issue.Issue {
+ if cb.closure == nil || cb.closure.Blocks == nil {
+ return nil
+ }
+
+ // Check if the closure writes to any captured variables (FreeVars)
+ if !s.hasWritesToCapturedVars(cb.closure, cb.makeClosure) {
+ return nil
+ }
+
+ // Flag as vulnerable
+ return newIssue(
+ s.Pass.Analyzer.Name,
+ defaultSSHCallbackIssueDescription,
+ s.Pass.Fset,
+ cb.storeInstr.Pos(),
+ issue.High,
+ issue.High,
+ )
+}
+
+// hasWritesToCapturedVars checks if a closure writes to any of its captured variables
+// or to package-level global variables (which can also lead to auth bypass)
+func (s *sshCallbackState) hasWritesToCapturedVars(closure *ssa.Function, mkClosure *ssa.MakeClosure) bool {
+ // Build a map of FreeVar to binding for quick lookup (if any)
+ freeVarSet := make(map[*ssa.FreeVar]ssa.Value)
+
+ // If we have a MakeClosure, use its bindings
+ if mkClosure != nil {
+ for i, fv := range closure.FreeVars {
+ if i < len(mkClosure.Bindings) {
+ freeVarSet[fv] = mkClosure.Bindings[i]
+ }
+ }
+ } else {
+ // For direct function assignments, just track FreeVars without specific bindings
+ for _, fv := range closure.FreeVars {
+ freeVarSet[fv] = nil
+ }
+ }
+
+ // Traverse the closure body looking for writes to captured variables or globals
+ for _, block := range closure.Blocks {
+ for _, instr := range block.Instrs {
+ if s.isWriteToCapturedVar(instr, freeVarSet) {
+ return true
+ }
+ }
+ }
+
+ return false
+}
+
+// isWriteToCapturedVar checks if an instruction writes to a captured variable
+func (s *sshCallbackState) isWriteToCapturedVar(instr ssa.Instruction, freeVarSet map[*ssa.FreeVar]ssa.Value) bool {
+ switch inst := instr.(type) {
+ case *ssa.Store:
+ // Check direct stores to FreeVars or dereferenced FreeVars
+ return s.isStoreToCapturedVar(inst, freeVarSet)
+
+ case *ssa.MapUpdate:
+ // Check if updating a map that is a captured variable
+ if fv, ok := inst.Map.(*ssa.FreeVar); ok {
+ if _, captured := freeVarSet[fv]; captured {
+ return true
+ }
+ }
+ // Check if the map comes from a FreeVar indirectly
+ return s.isValueFromCapturedVar(inst.Map, freeVarSet, 0)
+
+ case *ssa.Send:
+ // Sending on a channel that is a captured variable (modifies channel state)
+ if fv, ok := inst.Chan.(*ssa.FreeVar); ok {
+ if _, captured := freeVarSet[fv]; captured {
+ return true
+ }
+ }
+ return s.isValueFromCapturedVar(inst.Chan, freeVarSet, 0)
+ }
+
+ return false
+}
+
+// isStoreToCapturedVar checks if a Store instruction writes to a captured variable or global
+func (s *sshCallbackState) isStoreToCapturedVar(store *ssa.Store, freeVarSet map[*ssa.FreeVar]ssa.Value) bool {
+ // Direct store to a FreeVar
+ if fv, ok := store.Addr.(*ssa.FreeVar); ok {
+ if _, captured := freeVarSet[fv]; captured {
+ return true
+ }
+ }
+
+ // Store to a package-level global variable (critical for auth bypass)
+ if _, ok := store.Addr.(*ssa.Global); ok {
+ return true
+ }
+
+ // Store through a pointer dereferenced from a FreeVar
+ if unOp, ok := store.Addr.(*ssa.UnOp); ok {
+ if fv, ok := unOp.X.(*ssa.FreeVar); ok {
+ if _, captured := freeVarSet[fv]; captured {
+ return true
+ }
+ }
+ // Store through dereferenced global pointer
+ if _, ok := unOp.X.(*ssa.Global); ok {
+ return true
+ }
+ }
+
+ // Store to a field of a struct that is a captured variable
+ if fieldAddr, ok := store.Addr.(*ssa.FieldAddr); ok {
+ if fv, ok := fieldAddr.X.(*ssa.FreeVar); ok {
+ if _, captured := freeVarSet[fv]; captured {
+ return true
+ }
+ }
+ // Field of a pointer from a FreeVar
+ if unOp, ok := fieldAddr.X.(*ssa.UnOp); ok {
+ if fv, ok := unOp.X.(*ssa.FreeVar); ok {
+ if _, captured := freeVarSet[fv]; captured {
+ return true
+ }
+ }
+ }
+ // Recursively check if the base is from a captured variable
+ return s.isValueFromCapturedVar(fieldAddr.X, freeVarSet, 0)
+ }
+
+ // Store to an index of an array/slice that is a captured variable
+ if indexAddr, ok := store.Addr.(*ssa.IndexAddr); ok {
+ if fv, ok := indexAddr.X.(*ssa.FreeVar); ok {
+ if _, captured := freeVarSet[fv]; captured {
+ return true
+ }
+ }
+ return s.isValueFromCapturedVar(indexAddr.X, freeVarSet, 0)
+ }
+
+ return false
+}
+
+// isValueFromCapturedVar recursively checks if a value originates from a captured variable
+func (s *sshCallbackState) isValueFromCapturedVar(val ssa.Value, freeVarSet map[*ssa.FreeVar]ssa.Value, depth int) bool {
+ // Prevent infinite recursion
+ if depth > 5 {
+ return false
+ }
+
+ // Check if visited to prevent cycles
+ if s.Visited[val] {
+ return false
+ }
+ s.Visited[val] = true
+
+ switch v := val.(type) {
+ case *ssa.FreeVar:
+ _, captured := freeVarSet[v]
+ return captured
+
+ case *ssa.UnOp:
+ // Dereference or other unary operation
+ return s.isValueFromCapturedVar(v.X, freeVarSet, depth+1)
+
+ case *ssa.FieldAddr:
+ // Field access
+ return s.isValueFromCapturedVar(v.X, freeVarSet, depth+1)
+
+ case *ssa.IndexAddr:
+ // Array/slice index
+ return s.isValueFromCapturedVar(v.X, freeVarSet, depth+1)
+
+ case *ssa.Phi:
+ // Check all incoming values
+ for _, edge := range v.Edges {
+ if s.isValueFromCapturedVar(edge, freeVarSet, depth+1) {
+ return true
+ }
+ }
+ }
+
+ return false
+}
diff --git a/vendor/github.com/securego/gosec/v2/analyzers/ssrf.go b/vendor/github.com/securego/gosec/v2/analyzers/ssrf.go
new file mode 100644
index 000000000..506eccd62
--- /dev/null
+++ b/vendor/github.com/securego/gosec/v2/analyzers/ssrf.go
@@ -0,0 +1,81 @@
+// (c) Copyright gosec's authors
+//
+// 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 analyzers
+
+import (
+ "golang.org/x/tools/go/analysis"
+
+ "github.com/securego/gosec/v2/taint"
+)
+
+// SSRF returns a configuration for detecting Server-Side Request Forgery vulnerabilities.
+func SSRF() taint.Config {
+ return taint.Config{
+ Sources: []taint.Source{
+ // Type sources: tainted when received as function parameters from external callers
+ {Package: "net/http", Name: "Request", Pointer: true},
+
+ // Function sources: always produce tainted data
+ {Package: "os", Name: "Args", IsFunc: true},
+ {Package: "os", Name: "Getenv", IsFunc: true},
+
+ // I/O sources that read from external input
+ {Package: "bufio", Name: "Reader", Pointer: true},
+ {Package: "bufio", Name: "Scanner", Pointer: true},
+
+ // NOTE: *os.File is NOT a source type here. A file opened with a
+ // hardcoded path (e.g., config file) is not an external input source.
+ // If the file was opened from user-controlled input, the taint would
+ // flow through the path argument, and that's a path traversal issue (G703),
+ // not SSRF.
+ },
+ Sinks: []taint.Sink{
+ // URL argument is what we check - these are the first data arg
+ {Package: "net/http", Method: "Get", CheckArgs: []int{0}},
+ {Package: "net/http", Method: "Post", CheckArgs: []int{0}},
+ {Package: "net/http", Method: "Head", CheckArgs: []int{0}},
+ {Package: "net/http", Method: "PostForm", CheckArgs: []int{0}},
+ // NewRequest/NewRequestWithContext: URL is arg index 1 (method=0, url=1, body=2)
+ // or for WithContext: ctx=0, method=1, url=2, body=3
+ {Package: "net/http", Method: "NewRequest", CheckArgs: []int{1}},
+ {Package: "net/http", Method: "NewRequestWithContext", CheckArgs: []int{2}},
+ // Client methods - the request object carries the taint
+ {Package: "net/http", Receiver: "Client", Method: "Do", Pointer: true, CheckArgs: []int{1}},
+ {Package: "net/http", Receiver: "Client", Method: "Get", Pointer: true, CheckArgs: []int{1}},
+ {Package: "net/http", Receiver: "Client", Method: "Post", Pointer: true, CheckArgs: []int{1}},
+ {Package: "net/http", Receiver: "Client", Method: "Head", Pointer: true, CheckArgs: []int{1}},
+ {Package: "net", Method: "Dial", CheckArgs: []int{1}},
+ {Package: "net", Method: "DialTimeout", CheckArgs: []int{1}},
+ {Package: "net", Method: "LookupHost", CheckArgs: []int{0}},
+ {Package: "net/http/httputil", Method: "NewSingleHostReverseProxy", CheckArgs: []int{0}},
+ },
+ Sanitizers: []taint.Sanitizer{
+ // URL validation/parsing that enforces allowlists would be custom;
+ // there are no stdlib sanitizers that truly prevent SSRF.
+ // However, url.Parse itself is not a sanitizer — it doesn't restrict
+ // which hosts can be accessed.
+ },
+ }
+}
+
+// newSSRFAnalyzer creates an analyzer for detecting SSRF vulnerabilities
+// via taint analysis (G704)
+func newSSRFAnalyzer(id string, description string) *analysis.Analyzer {
+ config := SSRF()
+ rule := SSRFRule
+ rule.ID = id
+ rule.Description = description
+ return taint.NewGosecAnalyzer(&rule, &config)
+}
diff --git a/vendor/github.com/securego/gosec/v2/analyzers/ssti.go b/vendor/github.com/securego/gosec/v2/analyzers/ssti.go
new file mode 100644
index 000000000..f40d74d57
--- /dev/null
+++ b/vendor/github.com/securego/gosec/v2/analyzers/ssti.go
@@ -0,0 +1,104 @@
+// (c) Copyright gosec's authors
+//
+// 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 analyzers
+
+import (
+ "golang.org/x/tools/go/analysis"
+
+ "github.com/securego/gosec/v2/taint"
+)
+
+// SSTI returns a configuration for detecting Server-Side Template Injection
+// vulnerabilities via text/template.
+//
+// The text/template package performs NO auto-escaping and allows calling any
+// exported method on the data object passed to Execute. When user-controlled
+// input flows into Template.Parse, an attacker can invoke arbitrary methods,
+// read files, or achieve remote code execution depending on available gadgets.
+//
+// Even when the template string is static, rendering user data through
+// text/template into an HTTP response produces unescaped HTML, enabling XSS.
+func SSTI() taint.Config {
+ return taint.Config{
+ Sources: []taint.Source{
+ // Type sources: tainted when received as parameters
+ {Package: "net/http", Name: "Request", Pointer: true},
+ {Package: "net/url", Name: "Values"},
+
+ // Function sources
+ {Package: "os", Name: "Args", IsFunc: true},
+ {Package: "os", Name: "Getenv", IsFunc: true},
+
+ // I/O sources
+ {Package: "bufio", Name: "Reader", Pointer: true},
+ {Package: "bufio", Name: "Scanner", Pointer: true},
+ },
+ Sinks: []taint.Sink{
+ // CRITICAL: user input flows into the template string itself.
+ // Template.Parse takes a single string argument (the template text).
+ {Package: "text/template", Receiver: "Template", Method: "Parse", Pointer: true, CheckArgs: []int{1}},
+
+ // text/template.Must wraps Parse; arg[0] is the (*Template, error) pair
+ // but in practice the taint flows through the Parse call above.
+
+ // HIGH: text/template.Execute writes unescaped output to an HTTP response.
+ // Guard: only flag when the writer (arg 1) implements net/http.ResponseWriter.
+ {
+ Package: "text/template",
+ Receiver: "Template",
+ Method: "Execute",
+ Pointer: true,
+ CheckArgs: []int{2},
+ ArgTypeGuards: map[int]string{1: "net/http.ResponseWriter"},
+ },
+ {
+ Package: "text/template",
+ Receiver: "Template",
+ Method: "ExecuteTemplate",
+ Pointer: true,
+ CheckArgs: []int{3},
+ ArgTypeGuards: map[int]string{1: "net/http.ResponseWriter"},
+ },
+ },
+ Sanitizers: []taint.Sanitizer{
+ // HTML escaping neutralizes both SSTI template directives and XSS payloads
+ {Package: "html", Method: "EscapeString"},
+ {Package: "html/template", Method: "HTMLEscapeString"},
+ {Package: "html/template", Method: "JSEscapeString"},
+ {Package: "net/url", Method: "QueryEscape"},
+ {Package: "net/url", Method: "PathEscape"},
+
+ // Numeric conversions produce safe output
+ {Package: "strconv", Method: "Atoi"},
+ {Package: "strconv", Method: "Itoa"},
+ {Package: "strconv", Method: "ParseInt"},
+ {Package: "strconv", Method: "ParseUint"},
+ {Package: "strconv", Method: "ParseFloat"},
+ {Package: "strconv", Method: "FormatInt"},
+ {Package: "strconv", Method: "FormatUint"},
+ {Package: "strconv", Method: "FormatFloat"},
+ },
+ }
+}
+
+// newSSTIAnalyzer creates an analyzer for detecting Server-Side Template
+// Injection vulnerabilities via taint analysis (G708).
+func newSSTIAnalyzer(id string, description string) *analysis.Analyzer {
+ config := SSTI()
+ rule := SSTIRule
+ rule.ID = id
+ rule.Description = description
+ return taint.NewGosecAnalyzer(&rule, &config)
+}
diff --git a/vendor/github.com/securego/gosec/v2/analyzers/tls_resumption_verifypeer.go b/vendor/github.com/securego/gosec/v2/analyzers/tls_resumption_verifypeer.go
new file mode 100644
index 000000000..ab520887c
--- /dev/null
+++ b/vendor/github.com/securego/gosec/v2/analyzers/tls_resumption_verifypeer.go
@@ -0,0 +1,385 @@
+// (c) Copyright gosec's authors
+//
+// 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 analyzers
+
+import (
+ "go/constant"
+ "go/token"
+ "go/types"
+
+ "golang.org/x/tools/go/analysis"
+ "golang.org/x/tools/go/analysis/passes/buildssa"
+ "golang.org/x/tools/go/ssa"
+
+ "github.com/securego/gosec/v2/internal/ssautil"
+ "github.com/securego/gosec/v2/issue"
+)
+
+const msgTLSResumptionVerifyPeerBypass = "tls.Config uses VerifyPeerCertificate while session resumption may remain enabled and VerifyConnection is not set; resumed sessions can bypass custom certificate checks" // #nosec G101 -- Message string includes API identifiers, not credentials.
+
+func newTLSResumptionVerifyPeerAnalyzer(id string, description string) *analysis.Analyzer {
+ return &analysis.Analyzer{
+ Name: id,
+ Doc: description,
+ Run: runTLSResumptionVerifyPeerAnalysis,
+ Requires: []*analysis.Analyzer{buildssa.Analyzer},
+ }
+}
+
+type tlsConfigState struct {
+ verifyPeerSet bool
+ verifyPeerPos token.Pos
+ verifyConnectionSet bool
+ sessionTicketsDisabledTrue bool
+ clientSessionCacheSet bool
+ getConfigForClientSet bool
+ getConfigForClientPos token.Pos
+ getConfigForClientFns []*ssa.Function
+}
+
+type tlsResumptionState struct {
+ *BaseAnalyzerState
+ configs map[ssa.Value]*tlsConfigState
+ issuesByPos map[token.Pos]*issue.Issue
+}
+
+func newTLSResumptionState(pass *analysis.Pass) *tlsResumptionState {
+ return &tlsResumptionState{
+ BaseAnalyzerState: NewBaseState(pass),
+ configs: make(map[ssa.Value]*tlsConfigState),
+ issuesByPos: make(map[token.Pos]*issue.Issue),
+ }
+}
+
+func runTLSResumptionVerifyPeerAnalysis(pass *analysis.Pass) (any, error) {
+ ssaResult, err := ssautil.GetSSAResult(pass)
+ if err != nil {
+ return nil, err
+ }
+
+ state := newTLSResumptionState(pass)
+ defer state.Release()
+
+ funcs := collectAnalyzerFunctions(ssaResult.SSA.SrcFuncs)
+ if len(funcs) == 0 {
+ return nil, nil
+ }
+
+ TraverseSSA(funcs, func(_ *ssa.BasicBlock, instr ssa.Instruction) {
+ store, ok := instr.(*ssa.Store)
+ if !ok {
+ return
+ }
+ state.trackTLSConfigFieldStore(store)
+ })
+
+ state.reportDirectTLSConfigs()
+ state.reportGetConfigForClientBypassCandidates()
+
+ if len(state.issuesByPos) == 0 {
+ return nil, nil
+ }
+
+ issues := make([]*issue.Issue, 0, len(state.issuesByPos))
+ for _, i := range state.issuesByPos {
+ issues = append(issues, i)
+ }
+
+ return issues, nil
+}
+
+func (s *tlsResumptionState) trackTLSConfigFieldStore(store *ssa.Store) {
+ fieldAddr, ok := store.Addr.(*ssa.FieldAddr)
+ if !ok {
+ return
+ }
+
+ if !isTLSConfigPointerType(fieldAddr.X.Type()) {
+ return
+ }
+
+ fieldName, ok := tlsConfigFieldName(fieldAddr)
+ if !ok {
+ return
+ }
+
+ root := tlsConfigRoot(fieldAddr.X, 0)
+ if root == nil {
+ return
+ }
+
+ cfg := s.getOrCreateConfigState(root)
+
+ switch fieldName {
+ case "VerifyPeerCertificate":
+ if !isNilValue(store.Val) {
+ cfg.verifyPeerSet = true
+ cfg.verifyPeerPos = store.Pos()
+ }
+ case "VerifyConnection":
+ if !isNilValue(store.Val) {
+ cfg.verifyConnectionSet = true
+ }
+ case "SessionTicketsDisabled":
+ if b, ok := boolConstValue(store.Val); ok {
+ cfg.sessionTicketsDisabledTrue = b
+ }
+ case "ClientSessionCache":
+ if !isNilValue(store.Val) {
+ cfg.clientSessionCacheSet = true
+ }
+ case "GetConfigForClient":
+ if isNilValue(store.Val) {
+ return
+ }
+
+ cfg.getConfigForClientSet = true
+ cfg.getConfigForClientPos = store.Pos()
+ cfg.getConfigForClientFns = s.resolveFunctions(store.Val)
+ }
+}
+
+func (s *tlsResumptionState) getOrCreateConfigState(root ssa.Value) *tlsConfigState {
+ if cfg, ok := s.configs[root]; ok {
+ return cfg
+ }
+ cfg := &tlsConfigState{}
+ s.configs[root] = cfg
+ return cfg
+}
+
+func (s *tlsResumptionState) resolveFunctions(v ssa.Value) []*ssa.Function {
+ var out []*ssa.Function
+ s.Reset()
+ s.ResolveFuncs(v, &out)
+ if len(out) <= 1 {
+ return out
+ }
+
+ seen := make(map[*ssa.Function]struct{}, len(out))
+ unique := make([]*ssa.Function, 0, len(out))
+ for _, fn := range out {
+ if fn == nil {
+ continue
+ }
+ if _, ok := seen[fn]; ok {
+ continue
+ }
+ seen[fn] = struct{}{}
+ unique = append(unique, fn)
+ }
+
+ return unique
+}
+
+func (s *tlsResumptionState) reportDirectTLSConfigs() {
+ for _, cfg := range s.configs {
+ if !cfg.verifyPeerSet {
+ continue
+ }
+ if cfg.verifyConnectionSet {
+ continue
+ }
+ if cfg.sessionTicketsDisabledTrue {
+ continue
+ }
+
+ s.addIssue(cfg.verifyPeerPos)
+ }
+}
+
+func (s *tlsResumptionState) reportGetConfigForClientBypassCandidates() {
+ for _, parent := range s.configs {
+ if !parent.getConfigForClientSet {
+ continue
+ }
+ if parent.sessionTicketsDisabledTrue {
+ continue
+ }
+
+ if s.getConfigForClientReturnsRiskyTLSConfig(parent.getConfigForClientFns) {
+ s.addIssue(parent.getConfigForClientPos)
+ }
+ }
+}
+
+func (s *tlsResumptionState) getConfigForClientReturnsRiskyTLSConfig(fns []*ssa.Function) bool {
+ for _, fn := range fns {
+ if fn == nil {
+ continue
+ }
+
+ for _, block := range fn.Blocks {
+ for _, instr := range block.Instrs {
+ ret, ok := instr.(*ssa.Return)
+ if !ok {
+ continue
+ }
+ if len(ret.Results) == 0 {
+ continue
+ }
+
+ first := ret.Results[0]
+ configs := s.extractTLSConfigsFromValue(first, map[ssa.Value]struct{}{}, 0)
+ for _, cfg := range configs {
+ if cfg.verifyPeerSet && !cfg.verifyConnectionSet && !cfg.sessionTicketsDisabledTrue {
+ return true
+ }
+ }
+ }
+ }
+ }
+
+ return false
+}
+
+func (s *tlsResumptionState) extractTLSConfigsFromValue(v ssa.Value, visited map[ssa.Value]struct{}, depth int) []*tlsConfigState {
+ if v == nil || depth > MaxDepth {
+ return nil
+ }
+ if _, ok := visited[v]; ok {
+ return nil
+ }
+ visited[v] = struct{}{}
+
+ root := tlsConfigRoot(v, 0)
+ if root != nil {
+ if cfg, ok := s.configs[root]; ok {
+ return []*tlsConfigState{cfg}
+ }
+ }
+
+ switch val := v.(type) {
+ case *ssa.Phi:
+ out := make([]*tlsConfigState, 0, len(val.Edges))
+ for _, edge := range val.Edges {
+ out = append(out, s.extractTLSConfigsFromValue(edge, visited, depth+1)...)
+ }
+ return out
+ case *ssa.Extract:
+ return s.extractTLSConfigsFromValue(val.Tuple, visited, depth+1)
+ case *ssa.ChangeType:
+ return s.extractTLSConfigsFromValue(val.X, visited, depth+1)
+ case *ssa.TypeAssert:
+ return s.extractTLSConfigsFromValue(val.X, visited, depth+1)
+ case *ssa.MakeInterface:
+ return s.extractTLSConfigsFromValue(val.X, visited, depth+1)
+ }
+
+ return nil
+}
+
+func (s *tlsResumptionState) addIssue(pos token.Pos) {
+ if pos == token.NoPos {
+ return
+ }
+ if _, exists := s.issuesByPos[pos]; exists {
+ return
+ }
+
+ s.issuesByPos[pos] = newIssue(s.Pass.Analyzer.Name, msgTLSResumptionVerifyPeerBypass, s.Pass.Fset, pos, issue.High, issue.High)
+}
+
+func tlsConfigRoot(v ssa.Value, depth int) ssa.Value {
+ if v == nil || depth > MaxDepth {
+ return nil
+ }
+
+ if isTLSConfigPointerType(v.Type()) {
+ return v
+ }
+
+ switch value := v.(type) {
+ case *ssa.ChangeType:
+ return tlsConfigRoot(value.X, depth+1)
+ case *ssa.MakeInterface:
+ return tlsConfigRoot(value.X, depth+1)
+ case *ssa.TypeAssert:
+ return tlsConfigRoot(value.X, depth+1)
+ case *ssa.UnOp:
+ return tlsConfigRoot(value.X, depth+1)
+ case *ssa.FieldAddr:
+ return tlsConfigRoot(value.X, depth+1)
+ case *ssa.Phi:
+ if len(value.Edges) > 0 {
+ return tlsConfigRoot(value.Edges[0], depth+1)
+ }
+ }
+
+ return nil
+}
+
+func tlsConfigFieldName(fieldAddr *ssa.FieldAddr) (string, bool) {
+ if fieldAddr == nil {
+ return "", false
+ }
+
+ t := fieldAddr.X.Type()
+ if ptr, ok := t.(*types.Pointer); ok {
+ t = ptr.Elem()
+ }
+
+ named, ok := t.(*types.Named)
+ if !ok {
+ return "", false
+ }
+ if named.Obj() == nil || named.Obj().Pkg() == nil || named.Obj().Pkg().Path() != "crypto/tls" || named.Obj().Name() != "Config" {
+ return "", false
+ }
+
+ st, ok := named.Underlying().(*types.Struct)
+ if !ok || fieldAddr.Field >= st.NumFields() {
+ return "", false
+ }
+
+ return st.Field(fieldAddr.Field).Name(), true
+}
+
+func isTLSConfigPointerType(t types.Type) bool {
+ ptr, ok := t.(*types.Pointer)
+ if !ok {
+ return false
+ }
+
+ named, ok := ptr.Elem().(*types.Named)
+ if !ok {
+ return false
+ }
+ obj := named.Obj()
+ if obj == nil || obj.Name() != "Config" {
+ return false
+ }
+ pkg := obj.Pkg()
+ return pkg != nil && pkg.Path() == "crypto/tls"
+}
+
+func boolConstValue(v ssa.Value) (bool, bool) {
+ c, ok := v.(*ssa.Const)
+ if !ok || c.Value == nil {
+ return false, false
+ }
+ if c.Value.Kind() != constant.Bool {
+ return false, false
+ }
+ return constant.BoolVal(c.Value), true
+}
+
+func isNilValue(v ssa.Value) bool {
+ c, ok := v.(*ssa.Const)
+ if !ok || c.Value != nil {
+ return false
+ }
+ return c.IsNil()
+}
diff --git a/vendor/github.com/securego/gosec/v2/analyzers/unsafe_deserialization.go b/vendor/github.com/securego/gosec/v2/analyzers/unsafe_deserialization.go
new file mode 100644
index 000000000..bbdac51e5
--- /dev/null
+++ b/vendor/github.com/securego/gosec/v2/analyzers/unsafe_deserialization.go
@@ -0,0 +1,87 @@
+// (c) Copyright gosec's authors
+//
+// 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 analyzers
+
+import (
+ "golang.org/x/tools/go/analysis"
+
+ "github.com/securego/gosec/v2/taint"
+)
+
+// UnsafeDeserialization returns a configuration for detecting unsafe
+// deserialization of untrusted data.
+//
+// Go's encoding/gob package embeds full type information in its wire format
+// and will instantiate arbitrary registered types during decode. When an HTTP
+// handler passes r.Body directly to gob.NewDecoder().Decode(), an attacker
+// controls which types get instantiated, leading to denial-of-service or
+// potential RCE (CVE-2024-34156).
+//
+// gopkg.in/yaml.v2's Unmarshal into interface{} can instantiate arbitrary Go
+// types via YAML tags. encoding/xml is susceptible to deeply-nested structure
+// DoS and external entity expansion.
+func UnsafeDeserialization() taint.Config {
+ return taint.Config{
+ Sources: []taint.Source{
+ // Type sources: tainted when received as parameters
+ {Package: "net/http", Name: "Request", Pointer: true},
+ {Package: "net/url", Name: "Values"},
+
+ // Function sources
+ {Package: "os", Name: "Args", IsFunc: true},
+ {Package: "os", Name: "Getenv", IsFunc: true},
+
+ // I/O sources
+ {Package: "bufio", Name: "Reader", Pointer: true},
+ {Package: "bufio", Name: "Scanner", Pointer: true},
+ },
+ Sinks: []taint.Sink{
+ // encoding/gob — highest risk: arbitrary type instantiation from wire format
+ // gob.NewDecoder takes an io.Reader (arg 0), so if the reader is tainted
+ // the decoder will process attacker-controlled data.
+ {Package: "encoding/gob", Method: "NewDecoder", CheckArgs: []int{0}},
+
+ // gopkg.in/yaml.v2 — Unmarshal([]byte, interface{}) can instantiate arbitrary types
+ {Package: "gopkg.in/yaml.v2", Method: "Unmarshal", CheckArgs: []int{0}},
+ // yaml.NewDecoder takes an io.Reader (arg 0)
+ {Package: "gopkg.in/yaml.v2", Method: "NewDecoder", CheckArgs: []int{0}},
+
+ // encoding/xml — deeply-nested structure DoS, entity expansion
+ {Package: "encoding/xml", Method: "NewDecoder", CheckArgs: []int{0}},
+ {Package: "encoding/xml", Method: "Unmarshal", CheckArgs: []int{0}},
+ },
+ Sanitizers: []taint.Sanitizer{
+ // io.LimitReader bounds the amount of data read, mitigating DoS amplification
+ {Package: "io", Method: "LimitReader"},
+
+ // Numeric conversions — result is safe
+ {Package: "strconv", Method: "Atoi"},
+ {Package: "strconv", Method: "Itoa"},
+ {Package: "strconv", Method: "ParseInt"},
+ {Package: "strconv", Method: "ParseUint"},
+ {Package: "strconv", Method: "ParseFloat"},
+ },
+ }
+}
+
+// newUnsafeDeserializationAnalyzer creates an analyzer for detecting unsafe
+// deserialization of untrusted data via taint analysis (G709).
+func newUnsafeDeserializationAnalyzer(id string, description string) *analysis.Analyzer {
+ config := UnsafeDeserialization()
+ rule := UnsafeDeserializationRule
+ rule.ID = id
+ rule.Description = description
+ return taint.NewGosecAnalyzer(&rule, &config)
+}
diff --git a/vendor/github.com/securego/gosec/v2/analyzers/util.go b/vendor/github.com/securego/gosec/v2/analyzers/util.go
index 57cc42bd0..3d3464653 100644
--- a/vendor/github.com/securego/gosec/v2/analyzers/util.go
+++ b/vendor/github.com/securego/gosec/v2/analyzers/util.go
@@ -16,23 +16,174 @@ package analyzers
import (
"fmt"
+ "go/constant"
"go/token"
- "log"
+ "go/types"
+ "math"
"os"
"strconv"
+ "sync"
"golang.org/x/tools/go/analysis"
- "golang.org/x/tools/go/analysis/passes/buildssa"
+ "golang.org/x/tools/go/ssa"
+ "github.com/securego/gosec/v2/internal/ssautil"
"github.com/securego/gosec/v2/issue"
)
-// SSAAnalyzerResult contains various information returned by the
-// SSA analysis along with some configuration
-type SSAAnalyzerResult struct {
- Config map[string]interface{}
- Logger *log.Logger
- SSA *buildssa.SSA
+// MaxDepth defines the maximum recursion depth for SSA analysis to avoid infinite loops and memory exhaustion.
+const MaxDepth = 20
+
+const (
+ minInt64 = int64(math.MinInt64)
+ maxUint64 = uint64(math.MaxUint64)
+ maxInt64 = uint64(math.MaxInt64)
+)
+
+// SSAAnalyzerResult is a type alias for the shared SSA result type
+type SSAAnalyzerResult = ssautil.SSAAnalyzerResult
+
+// BaseAnalyzerState provides a shared state for Gosec analyzers,
+// encapsulating common fields and reusable objects to reduce allocations.
+type BaseAnalyzerState struct {
+ Pass *analysis.Pass
+ Analyzer *RangeAnalyzer
+ Visited map[ssa.Value]bool
+ FuncMap map[*ssa.Function]bool // General purpose function set
+ BlockMap map[*ssa.BasicBlock]bool
+ ClosureCache map[ssa.Value]bool
+ Depth int
+}
+
+// Error aliases for backward compatibility
+var (
+ ErrNoSSAResult = ssautil.ErrNoSSAResult
+ ErrInvalidSSAType = ssautil.ErrInvalidSSAType
+)
+
+var (
+ visitedPool = sync.Pool{
+ New: func() any {
+ return make(map[ssa.Value]bool, 64)
+ },
+ }
+ funcMapPool = sync.Pool{
+ New: func() any {
+ return make(map[*ssa.Function]bool, 32)
+ },
+ }
+ closureCachePool = sync.Pool{
+ New: func() any {
+ return make(map[ssa.Value]bool, 32)
+ },
+ }
+ blockMapPool = sync.Pool{
+ New: func() any {
+ return make(map[*ssa.BasicBlock]bool, 32)
+ },
+ }
+)
+
+// NewBaseState creates a new BaseAnalyzerState with pooled maps.
+func NewBaseState(pass *analysis.Pass) *BaseAnalyzerState {
+ return &BaseAnalyzerState{
+ Pass: pass,
+ Analyzer: NewRangeAnalyzer(),
+ Visited: visitedPool.Get().(map[ssa.Value]bool),
+ FuncMap: funcMapPool.Get().(map[*ssa.Function]bool),
+ BlockMap: blockMapPool.Get().(map[*ssa.BasicBlock]bool),
+ ClosureCache: closureCachePool.Get().(map[ssa.Value]bool),
+ }
+}
+
+// Reset clears the caches and maps for reuse within an analyzer run.
+func (s *BaseAnalyzerState) Reset() {
+ if s.Analyzer != nil {
+ s.Analyzer.ResetCache()
+ }
+ clear(s.Visited)
+ clear(s.FuncMap)
+ clear(s.BlockMap)
+ clear(s.ClosureCache)
+ s.Depth = 0
+}
+
+// Release returns the pooled maps and analyzer to their pools.
+func (s *BaseAnalyzerState) Release() {
+ if s.Analyzer != nil {
+ s.Analyzer.Release()
+ s.Analyzer = nil
+ }
+ if s.Visited != nil {
+ clear(s.Visited)
+ visitedPool.Put(s.Visited)
+ s.Visited = nil
+ }
+ if s.FuncMap != nil {
+ clear(s.FuncMap)
+ funcMapPool.Put(s.FuncMap)
+ s.FuncMap = nil
+ }
+ if s.ClosureCache != nil {
+ clear(s.ClosureCache)
+ closureCachePool.Put(s.ClosureCache)
+ s.ClosureCache = nil
+ }
+ if s.BlockMap != nil {
+ clear(s.BlockMap)
+ blockMapPool.Put(s.BlockMap)
+ s.BlockMap = nil
+ }
+}
+
+// ResolveFuncs resolves a value to a list of possible functions (e.g., closures, phi nodes).
+// It reuses the state's ClosureCache to avoid cycles and redundant work.
+func (s *BaseAnalyzerState) ResolveFuncs(val ssa.Value, funcs *[]*ssa.Function) {
+ if val == nil || s.Depth > MaxDepth {
+ return
+ }
+ if s.ClosureCache[val] {
+ return
+ }
+ s.ClosureCache[val] = true
+
+ s.Depth++
+ defer func() { s.Depth-- }()
+
+ switch v := val.(type) {
+ case *ssa.Function:
+ *funcs = append(*funcs, v)
+ case *ssa.MakeClosure:
+ *funcs = append(*funcs, v.Fn.(*ssa.Function))
+ case *ssa.Phi:
+ for _, edge := range v.Edges {
+ s.ResolveFuncs(edge, funcs)
+ }
+ case *ssa.ChangeType:
+ s.ResolveFuncs(v.X, funcs)
+ case *ssa.UnOp:
+ if v.Op == token.MUL {
+ s.ResolveFuncs(v.X, funcs)
+ }
+ }
+}
+
+// IntTypeInfo represents integer type properties
+type IntTypeInfo struct {
+ Signed bool
+ Size int
+ Min int64
+ Max uint64
+}
+
+// isSliceInsideBounds checks if the requested slice range is within the parent slice's boundaries.
+func isSliceInsideBounds(l, h int, cl, ch int) bool {
+ return (l <= cl && h >= ch) && (l <= ch && h >= cl)
+}
+
+// isThreeIndexSliceInsideBounds validates the boundaries and capacity of a 3-index slice (s[i:j:k]).
+func isThreeIndexSliceInsideBounds(l, h, maxIdx int, oldCap int) bool {
+ return l >= 0 && h >= l && maxIdx >= h && maxIdx <= oldCap
}
// BuildDefaultAnalyzers returns the default list of analyzers
@@ -44,19 +195,6 @@ func BuildDefaultAnalyzers() []*analysis.Analyzer {
}
}
-// getSSAResult retrieves the SSA result from analysis pass
-func getSSAResult(pass *analysis.Pass) (*SSAAnalyzerResult, error) {
- result, ok := pass.ResultOf[buildssa.Analyzer]
- if !ok {
- return nil, fmt.Errorf("no SSA result found in the analysis pass")
- }
- ssaResult, ok := result.(*SSAAnalyzerResult)
- if !ok {
- return nil, fmt.Errorf("the analysis pass result is not of type SSA")
- }
- return ssaResult, nil
-}
-
// newIssue creates a new gosec issue
func newIssue(analyzerID string, desc string, fileSet *token.FileSet,
pos token.Pos, severity, confidence issue.Score,
@@ -102,3 +240,420 @@ func issueCodeSnippet(fileSet *token.FileSet, pos token.Pos) string {
}
return code
}
+
+// GetIntTypeInfo extracts properties of an integer type.
+func GetIntTypeInfo(t types.Type) (IntTypeInfo, error) {
+ u := t.Underlying()
+ if ptr, ok := u.(*types.Pointer); ok {
+ u = ptr.Elem().Underlying()
+ }
+ basic, ok := u.(*types.Basic)
+ if !ok {
+ return IntTypeInfo{}, fmt.Errorf("not a basic type: %T", u)
+ }
+
+ var info IntTypeInfo
+ switch basic.Kind() {
+ case types.Int:
+ info = IntTypeInfo{Signed: true, Size: 64, Min: math.MinInt64, Max: math.MaxInt64}
+ case types.Int8:
+ info = IntTypeInfo{Signed: true, Size: 8, Min: math.MinInt8, Max: math.MaxInt8}
+ case types.Int16:
+ info = IntTypeInfo{Signed: true, Size: 16, Min: math.MinInt16, Max: math.MaxInt16}
+ case types.Int32:
+ info = IntTypeInfo{Signed: true, Size: 32, Min: math.MinInt32, Max: math.MaxInt32}
+ case types.Int64:
+ info = IntTypeInfo{Signed: true, Size: 64, Min: math.MinInt64, Max: math.MaxInt64}
+ case types.Uint:
+ info = IntTypeInfo{Signed: false, Size: 64, Min: 0, Max: math.MaxUint64}
+ case types.Uint8:
+ // Byte is often an alias for Uint8
+ info = IntTypeInfo{Signed: false, Size: 8, Min: 0, Max: math.MaxUint8}
+ case types.Uint16:
+ info = IntTypeInfo{Signed: false, Size: 16, Min: 0, Max: math.MaxUint16}
+ case types.Uint32:
+ info = IntTypeInfo{Signed: false, Size: 32, Min: 0, Max: math.MaxUint32}
+ case types.Uint64, types.Uintptr:
+ info = IntTypeInfo{Signed: false, Size: 64, Min: 0, Max: math.MaxUint64}
+ default:
+ return IntTypeInfo{}, fmt.Errorf("unsupported basic type: %v", basic.Kind())
+ }
+ return info, nil
+}
+
+// GetConstantInt64 extracts a constant int64 value from an ssa.Value
+func GetConstantInt64(v ssa.Value) (int64, bool) {
+ if c, ok := v.(*ssa.Const); ok {
+ if c.Value != nil && c.Value.Kind() == constant.Int {
+ if val, ok := constant.Int64Val(c.Value); ok {
+ return val, true
+ }
+ }
+ }
+ if unOp, ok := v.(*ssa.UnOp); ok && unOp.Op == token.SUB {
+ if val, ok := GetConstantInt64(unOp.X); ok {
+ return -val, true
+ }
+ }
+ return 0, false
+}
+
+// GetConstantUint64 extracts a constant uint64 value from an ssa.Value
+func GetConstantUint64(v ssa.Value) (uint64, bool) {
+ if c, ok := v.(*ssa.Const); ok {
+ if c.Value != nil && c.Value.Kind() == constant.Int {
+ if val, ok := constant.Uint64Val(c.Value); ok {
+ return val, true
+ }
+ }
+ }
+ return 0, false
+}
+
+// GetSliceBounds extracts low, high, and max indices from a slice instruction
+func GetSliceBounds(s *ssa.Slice) (int, int, int) {
+ var low, high, maxIdx int
+ if s.Low != nil {
+ if val, ok := GetConstantInt64(s.Low); ok {
+ low = int(val)
+ }
+ }
+ if s.High != nil {
+ if val, ok := GetConstantInt64(s.High); ok {
+ high = int(val)
+ }
+ }
+ if s.Max != nil {
+ if val, ok := GetConstantInt64(s.Max); ok {
+ maxIdx = int(val)
+ }
+ }
+ return low, high, maxIdx
+}
+
+// GetSliceRange extracts low and high indices as int64.
+// High is returned as -1 if it's missing (extends to the end).
+func GetSliceRange(s *ssa.Slice) (int64, int64) {
+ var low, high int64 = 0, -1
+ if s.Low != nil {
+ if val, ok := GetConstantInt64(s.Low); ok {
+ low = val
+ }
+ }
+ if s.High != nil {
+ if val, ok := GetConstantInt64(s.High); ok {
+ high = val
+ }
+ }
+ return low, high
+}
+
+// ComputeSliceNewCap determines the new capacity of a slice based on the slicing operation.
+// l, h, maxIdx are the extracted low, high, and max indices. oldCap is the capacity of the original slice.
+// It handles both 2-index ([:]) and 3-index ([: :]) slice expressions.
+func ComputeSliceNewCap(l, h, maxIdx, oldCap int) int {
+ if maxIdx > 0 {
+ return maxIdx - l
+ }
+ if l == 0 && h == 0 {
+ return oldCap
+ }
+ if l > 0 && h == 0 {
+ return oldCap - l
+ }
+ if l == 0 && h > 0 {
+ return h
+ }
+ return h - l
+}
+
+// IsFullSlice checks if the slice operation covers the entire buffer.
+func IsFullSlice(sl *ssa.Slice, bufferLen int64) bool {
+ l, h := GetSliceRange(sl)
+ if l != 0 {
+ return false
+ }
+ if h < 0 {
+ return true
+ }
+ return bufferLen >= 0 && h == bufferLen
+}
+
+// IsSubSlice checks if the 'sub' slice is contained within the 'super' slice.
+func IsSubSlice(sub, super *ssa.Slice) bool {
+ l1, h1 := GetSliceRange(sub) // child
+ l2, h2 := GetSliceRange(super) // parent
+ if l2 > l1 {
+ return false
+ }
+ if h2 < 0 {
+ return true // parent covers all, so child is sub
+ }
+ if h1 < 0 {
+ return false // parent has bound but child doesn't
+ }
+ return h1 <= h2
+}
+
+// GetBufferLen attempts to find the constant length of a buffer/slice/array
+func GetBufferLen(val ssa.Value) int64 {
+ current := val
+ for {
+ t := current.Type()
+ if ptr, ok := t.Underlying().(*types.Pointer); ok {
+ t = ptr.Elem().Underlying()
+ }
+ if arr, ok := t.(*types.Array); ok {
+ return arr.Len()
+ }
+ if sl, ok := current.(*ssa.Slice); ok {
+ current = sl.X
+ continue
+ }
+ break
+ }
+ return -1
+}
+
+// BuildCallerMap builds a map of function names to their call sites
+// BuildCallerMap fills the provided map with all calls found in the given functions.
+func BuildCallerMap(funcs []*ssa.Function, callerMap map[string][]*ssa.Call) {
+ TraverseSSA(funcs, func(b *ssa.BasicBlock, i ssa.Instruction) {
+ if c, ok := i.(*ssa.Call); ok {
+ var name string
+ if c.Call.Method != nil {
+ name = c.Call.Method.FullName()
+ } else {
+ name = c.Call.Value.String()
+ }
+ callerMap[name] = append(callerMap[name], c)
+ }
+ })
+}
+
+// toUint64 casts int64 to uint64 preserving the bit pattern (2's complement) and suppresses the linter warning.
+func toUint64(i int64) uint64 {
+ return uint64(i) // #nosec
+}
+
+// toInt64 casts uint64 to int64 preserving the bit pattern and suppresses the linter warning.
+func toInt64(u uint64) int64 {
+ return int64(u) // #nosec
+}
+
+// GetDominators returns a list of dominator blocks for the given block, in order from root to the block.
+func GetDominators(block *ssa.BasicBlock) []*ssa.BasicBlock {
+ var doms []*ssa.BasicBlock
+ curr := block
+ for curr != nil {
+ doms = append(doms, curr)
+ curr = curr.Idom()
+ }
+ // Reverse to get root-to-block order
+ for i, j := 0, len(doms)-1; i < j; i, j = i+1, j-1 {
+ doms[i], doms[j] = doms[j], doms[i]
+ }
+ return doms
+}
+
+// isConstantInRange checks if a constant value fits within the range of the destination type.
+func IsConstantInTypeRange(constVal *ssa.Const, dstInt IntTypeInfo) bool {
+ if constVal.Value == nil || constVal.Value.Kind() != constant.Int {
+ return false
+ }
+ if dstInt.Signed {
+ val, ok := constant.Int64Val(constVal.Value)
+ if !ok {
+ return false
+ }
+ return val >= dstInt.Min && toUint64(val) <= dstInt.Max
+ }
+ val, ok := constant.Uint64Val(constVal.Value)
+ if !ok {
+ return false
+ }
+ return val <= dstInt.Max
+}
+
+// ExplicitValsInRange checks if any of the explicit positive or negative values are within the range of the destination type.
+func ExplicitValsInRange(pos []uint, neg []int, dstInt IntTypeInfo) bool {
+ for _, v := range pos {
+ if uint64(v) <= dstInt.Max {
+ return true
+ }
+ }
+ for _, v := range neg {
+ if int64(v) >= dstInt.Min {
+ return true
+ }
+ }
+ return false
+}
+
+// TraverseSSA visits every instruction in the provided functions using the visitor callback.
+func TraverseSSA(funcs []*ssa.Function, visitor func(block *ssa.BasicBlock, instr ssa.Instruction)) {
+ for _, f := range funcs {
+ for _, b := range f.Blocks {
+ for _, i := range b.Instrs {
+ visitor(b, i)
+ }
+ }
+ }
+}
+
+type operationInfo struct {
+ op string
+ extra ssa.Value
+ flipped bool
+}
+
+// minBounds computes the minimum of two uint64 values, considering whether they are set and treating them as signed if !isSrcUnsigned.
+func minBounds(aVal uint64, aSet bool, bVal uint64, bSet bool, isSrcUnsigned bool) uint64 {
+ if !aSet {
+ return bVal
+ }
+ if !bSet {
+ return aVal
+ }
+ if !isSrcUnsigned {
+ if toInt64(aVal) < toInt64(bVal) {
+ return aVal
+ }
+ return bVal
+ }
+ if aVal < bVal {
+ return aVal
+ }
+ return bVal
+}
+
+// maxBounds computes the maximum of two uint64 values, considering whether they are set and treating them as signed if !isSrcUnsigned.
+func maxBounds(aVal uint64, aSet bool, bVal uint64, bSet bool, isSrcUnsigned bool) uint64 {
+ if !aSet {
+ return bVal
+ }
+ if !bSet {
+ return aVal
+ }
+ if !isSrcUnsigned {
+ if toInt64(aVal) > toInt64(bVal) {
+ return aVal
+ }
+ return bVal
+ }
+ if aVal > bVal {
+ return aVal
+ }
+ return bVal
+}
+
+// isUint checks if the value's type is an unsigned integer.
+func isUint(v ssa.Value) bool {
+ if basic, ok := v.Type().Underlying().(*types.Basic); ok {
+ return basic.Info()&types.IsUnsigned != 0
+ }
+ return false
+}
+
+// getRealValueFromOperation decomposes an SSA value into its base value and any simple arithmetic operation applied to it.
+func getRealValueFromOperation(v ssa.Value) (ssa.Value, operationInfo) {
+ switch v := v.(type) {
+ case *ssa.BinOp:
+ switch v.Op {
+ case token.SHL, token.ADD, token.SUB, token.SHR, token.MUL, token.QUO:
+ if _, ok := GetConstantInt64(v.Y); ok {
+ return v.X, operationInfo{op: v.Op.String(), extra: v.Y}
+ }
+ if _, ok := GetConstantInt64(v.X); ok {
+ return v.Y, operationInfo{op: v.Op.String(), extra: v.X, flipped: true}
+ }
+ }
+ case *ssa.Convert:
+ return getRealValueFromOperation(v.X)
+ case *ssa.UnOp:
+ switch v.Op {
+ case token.SUB:
+ return v.X, operationInfo{op: "neg"}
+ case token.MUL:
+ // Follow pointer dereference.
+ if unOp, ok := v.X.(*ssa.UnOp); ok && unOp.Op == token.MUL {
+ return getRealValueFromOperation(unOp)
+ }
+ // If it's a field address, keep going.
+ if fieldAddr, ok := v.X.(*ssa.FieldAddr); ok {
+ return fieldAddr, operationInfo{op: "field"}
+ }
+ }
+ case *ssa.FieldAddr:
+ return v, operationInfo{op: "field"}
+ case *ssa.Alloc:
+ return v, operationInfo{op: "alloc"}
+ }
+ return v, operationInfo{}
+}
+
+// isEquivalent checks if two SSA values are structurally equivalent.
+func isEquivalent(a, b ssa.Value) bool {
+ if a == b {
+ return true
+ }
+ if a == nil || b == nil {
+ return false
+ }
+ // Handle distinct constant pointers
+ if aConst, ok := a.(*ssa.Const); ok {
+ if bConst, ok := b.(*ssa.Const); ok {
+ return aConst.Value == bConst.Value && aConst.Type() == bConst.Type()
+ }
+ }
+
+ switch va := a.(type) {
+ case *ssa.BinOp:
+ if vb, ok := b.(*ssa.BinOp); ok {
+ return va.Op == vb.Op && isEquivalent(va.X, vb.X) && isEquivalent(va.Y, vb.Y)
+ }
+ case *ssa.UnOp:
+ if vb, ok := b.(*ssa.UnOp); ok {
+ return va.Op == vb.Op && isEquivalent(va.X, vb.X)
+ }
+ }
+ return false
+}
+
+// isSameOrRelated checks if two SSA values represent the same underlying variable or related struct fields.
+func isSameOrRelated(a, b ssa.Value) bool {
+ if a == b {
+ return true
+ }
+ if a == nil || b == nil {
+ return false
+ }
+ if aExt, ok := a.(*ssa.Extract); ok {
+ if bExt, ok := b.(*ssa.Extract); ok {
+ return aExt.Index == bExt.Index && isSameOrRelated(aExt.Tuple, bExt.Tuple)
+ }
+ }
+ aVal, aInfo := getRealValueFromOperation(a)
+ bVal, bInfo := getRealValueFromOperation(b)
+ if aVal == bVal && aInfo.op == bInfo.op {
+ return true
+ }
+ if aField, ok := aVal.(*ssa.FieldAddr); ok {
+ if bField, ok := bVal.(*ssa.FieldAddr); ok {
+ return aField.Field == bField.Field && isSameOrRelated(aField.X, bField.X)
+ }
+ }
+ if aIndex, ok := aVal.(*ssa.IndexAddr); ok {
+ if bIndex, ok := bVal.(*ssa.IndexAddr); ok {
+ return isSameOrRelated(aIndex.X, bIndex.X) && isSameOrRelated(aIndex.Index, bIndex.Index)
+ }
+ }
+ if aUnOp, ok := aVal.(*ssa.UnOp); ok {
+ if aUnOp.Op == token.MUL {
+ if bUnOp, ok := bVal.(*ssa.UnOp); ok && bUnOp.Op == token.MUL {
+ return isSameOrRelated(aUnOp.X, bUnOp.X)
+ }
+ }
+ }
+ return false
+}
diff --git a/vendor/github.com/securego/gosec/v2/analyzers/walk_symlink_race.go b/vendor/github.com/securego/gosec/v2/analyzers/walk_symlink_race.go
new file mode 100644
index 000000000..416b97a1d
--- /dev/null
+++ b/vendor/github.com/securego/gosec/v2/analyzers/walk_symlink_race.go
@@ -0,0 +1,326 @@
+// (c) Copyright gosec's authors
+//
+// 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 analyzers
+
+import (
+ "go/token"
+ "go/types"
+
+ "golang.org/x/tools/go/analysis"
+ "golang.org/x/tools/go/analysis/passes/buildssa"
+ "golang.org/x/tools/go/ssa"
+
+ "github.com/securego/gosec/v2/internal/ssautil"
+ "github.com/securego/gosec/v2/issue"
+)
+
+const msgWalkSymlinkRace = "Filesystem operation in filepath.Walk/WalkDir callback uses race-prone path; consider root-scoped APIs (e.g. os.Root) to prevent symlink TOCTOU traversal"
+
+func newWalkSymlinkRaceAnalyzer(id string, description string) *analysis.Analyzer {
+ return &analysis.Analyzer{
+ Name: id,
+ Doc: description,
+ Run: runWalkSymlinkRaceAnalysis,
+ Requires: []*analysis.Analyzer{buildssa.Analyzer},
+ }
+}
+
+func runWalkSymlinkRaceAnalysis(pass *analysis.Pass) (any, error) {
+ ssaResult, err := ssautil.GetSSAResult(pass)
+ if err != nil {
+ return nil, err
+ }
+
+ state := newWalkSymlinkRaceState(pass)
+ defer state.Release()
+
+ for _, fn := range collectAnalyzerFunctions(ssaResult.SSA.SrcFuncs) {
+ for _, block := range fn.Blocks {
+ for _, instr := range block.Instrs {
+ callInstr, ok := instr.(ssa.CallInstruction)
+ if !ok {
+ continue
+ }
+
+ common := callInstr.Common()
+ if common == nil {
+ continue
+ }
+
+ cbArgIdx, ok := walkCallbackArgIndex(common)
+ if !ok || cbArgIdx >= len(common.Args) {
+ continue
+ }
+
+ callbacks := state.resolveFunctions(common.Args[cbArgIdx])
+ for _, cb := range callbacks {
+ if cb == nil || len(cb.Params) == 0 {
+ continue
+ }
+ pathParam := cb.Params[0]
+ if !isStringType(pathParam.Type()) {
+ continue
+ }
+
+ state.scanCallbackForRaceSinks(cb, pathParam)
+ }
+ }
+ }
+ }
+
+ if len(state.issuesByPos) == 0 {
+ return nil, nil
+ }
+
+ issues := make([]*issue.Issue, 0, len(state.issuesByPos))
+ for _, i := range state.issuesByPos {
+ issues = append(issues, i)
+ }
+
+ return issues, nil
+}
+
+type walkSymlinkRaceState struct {
+ *BaseAnalyzerState
+ issuesByPos map[token.Pos]*issue.Issue
+}
+
+func newWalkSymlinkRaceState(pass *analysis.Pass) *walkSymlinkRaceState {
+ return &walkSymlinkRaceState{
+ BaseAnalyzerState: NewBaseState(pass),
+ issuesByPos: make(map[token.Pos]*issue.Issue),
+ }
+}
+
+func (s *walkSymlinkRaceState) resolveFunctions(v ssa.Value) []*ssa.Function {
+ var out []*ssa.Function
+ s.Reset()
+ s.ResolveFuncs(v, &out)
+ if len(out) <= 1 {
+ return out
+ }
+
+ seen := make(map[*ssa.Function]struct{}, len(out))
+ unique := make([]*ssa.Function, 0, len(out))
+ for _, fn := range out {
+ if fn == nil {
+ continue
+ }
+ if _, ok := seen[fn]; ok {
+ continue
+ }
+ seen[fn] = struct{}{}
+ unique = append(unique, fn)
+ }
+ return unique
+}
+
+func (s *walkSymlinkRaceState) scanCallbackForRaceSinks(fn *ssa.Function, pathParam *ssa.Parameter) {
+ for _, block := range fn.Blocks {
+ for _, instr := range block.Instrs {
+ callInstr, ok := instr.(ssa.CallInstruction)
+ if !ok {
+ continue
+ }
+
+ common := callInstr.Common()
+ if common == nil {
+ continue
+ }
+
+ argIndexes, ok := filesystemSinkArgIndexes(common)
+ if !ok {
+ continue
+ }
+
+ for _, idx := range argIndexes {
+ if idx >= len(common.Args) {
+ continue
+ }
+ if pathDependsOn(common.Args[idx], pathParam, 0, map[ssa.Value]struct{}{}) {
+ s.addIssue(instr.Pos())
+ break
+ }
+ }
+ }
+ }
+}
+
+func (s *walkSymlinkRaceState) addIssue(pos token.Pos) {
+ if pos == token.NoPos {
+ return
+ }
+ if _, exists := s.issuesByPos[pos]; exists {
+ return
+ }
+ s.issuesByPos[pos] = newIssue(s.Pass.Analyzer.Name, msgWalkSymlinkRace, s.Pass.Fset, pos, issue.High, issue.Medium)
+}
+
+func walkCallbackArgIndex(common *ssa.CallCommon) (int, bool) {
+ callee := common.StaticCallee()
+ if callee == nil || callee.Pkg == nil || callee.Pkg.Pkg == nil {
+ return 0, false
+ }
+
+ pkgPath := callee.Pkg.Pkg.Path()
+ switch pkgPath {
+ case "path/filepath":
+ switch callee.Name() {
+ case "Walk", "WalkDir":
+ return 1, true
+ }
+ case "io/fs":
+ if callee.Name() == "WalkDir" {
+ return 2, true
+ }
+ }
+
+ return 0, false
+}
+
+func filesystemSinkArgIndexes(common *ssa.CallCommon) ([]int, bool) {
+ callee := common.StaticCallee()
+ if callee == nil || callee.Pkg == nil || callee.Pkg.Pkg == nil {
+ return nil, false
+ }
+
+ if isRootScopedFilesystemCall(callee) {
+ return nil, false
+ }
+
+ pkgPath := callee.Pkg.Pkg.Path()
+ name := callee.Name()
+
+ switch pkgPath {
+ case "os":
+ switch name {
+ case "Open", "OpenFile", "Create", "WriteFile", "ReadFile",
+ "Remove", "RemoveAll", "Mkdir", "MkdirAll", "Chmod", "Chown", "Lchown", "Chtimes":
+ return []int{0}, true
+ case "Rename", "Symlink", "Link":
+ return []int{0, 1}, true
+ }
+ case "io/ioutil":
+ switch name {
+ case "ReadFile", "WriteFile":
+ return []int{0}, true
+ }
+ }
+
+ return nil, false
+}
+
+func isRootScopedFilesystemCall(callee *ssa.Function) bool {
+ if callee == nil || callee.Signature == nil {
+ return false
+ }
+ recv := callee.Signature.Recv()
+ if recv == nil {
+ return false
+ }
+
+ return isOSRootType(recv.Type())
+}
+
+func isOSRootType(t types.Type) bool {
+ if ptr, ok := t.(*types.Pointer); ok {
+ t = ptr.Elem()
+ }
+
+ named, ok := t.(*types.Named)
+ if !ok {
+ return false
+ }
+ obj := named.Obj()
+ if obj == nil || obj.Name() != "Root" {
+ return false
+ }
+ pkg := obj.Pkg()
+ return pkg != nil && pkg.Path() == "os"
+}
+
+func isStringType(t types.Type) bool {
+ basic, ok := t.Underlying().(*types.Basic)
+ if !ok {
+ return false
+ }
+ return basic.Kind() == types.String
+}
+
+func pathDependsOn(value ssa.Value, target ssa.Value, depth int, visited map[ssa.Value]struct{}) bool {
+ if value == nil || target == nil || depth > MaxDepth {
+ return false
+ }
+ if value == target {
+ return true
+ }
+ if _, seen := visited[value]; seen {
+ return false
+ }
+ visited[value] = struct{}{}
+
+ if valueDependsOn(value, target, depth) {
+ return true
+ }
+
+ switch v := value.(type) {
+ case *ssa.BinOp:
+ return pathDependsOn(v.X, target, depth+1, visited) || pathDependsOn(v.Y, target, depth+1, visited)
+ case *ssa.Convert:
+ return pathDependsOn(v.X, target, depth+1, visited)
+ case *ssa.UnOp:
+ if pathDependsOn(v.X, target, depth+1, visited) {
+ return true
+ }
+ if v.Op == token.MUL {
+ for _, stored := range storedValues(v.X) {
+ if pathDependsOn(stored, target, depth+1, visited) {
+ return true
+ }
+ }
+ }
+ case *ssa.Call:
+ for _, arg := range v.Call.Args {
+ if pathDependsOn(arg, target, depth+1, visited) {
+ return true
+ }
+ }
+ }
+
+ return false
+}
+
+func storedValues(ptr ssa.Value) []ssa.Value {
+ if ptr == nil {
+ return nil
+ }
+ refs := ptr.Referrers()
+ if refs == nil {
+ return nil
+ }
+
+ vals := make([]ssa.Value, 0, len(*refs))
+ for _, ref := range *refs {
+ store, ok := ref.(*ssa.Store)
+ if !ok {
+ continue
+ }
+ if store.Addr != ptr {
+ continue
+ }
+ vals = append(vals, store.Val)
+ }
+ return vals
+}
diff --git a/vendor/github.com/securego/gosec/v2/analyzers/xss.go b/vendor/github.com/securego/gosec/v2/analyzers/xss.go
new file mode 100644
index 000000000..28fb39317
--- /dev/null
+++ b/vendor/github.com/securego/gosec/v2/analyzers/xss.go
@@ -0,0 +1,115 @@
+// (c) Copyright gosec's authors
+//
+// 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 analyzers
+
+import (
+ "golang.org/x/tools/go/analysis"
+
+ "github.com/securego/gosec/v2/taint"
+)
+
+// XSS returns a configuration for detecting Cross-Site Scripting vulnerabilities.
+func XSS() taint.Config {
+ return taint.Config{
+ Sources: []taint.Source{
+ // Type sources: tainted when received as parameters
+ {Package: "net/http", Name: "Request", Pointer: true},
+ {Package: "net/url", Name: "Values"},
+
+ // Function sources
+ {Package: "os", Name: "Args", IsFunc: true},
+
+ // I/O sources
+ {Package: "bufio", Name: "Reader", Pointer: true},
+ {Package: "bufio", Name: "Scanner", Pointer: true},
+ },
+ Sinks: []taint.Sink{
+ // Direct write on the response writer itself — receiver already scopes it.
+ {Package: "net/http", Receiver: "ResponseWriter", Method: "Write"},
+ // fmt print family: arg[0] is the io.Writer target; args[1..n] are the
+ // format string and variadic data (all checked for taint).
+ // Guard: only treat as a sink when arg[0] implements net/http.ResponseWriter.
+ // Writing to os.Stdout, os.Stderr, bytes.Buffer, exec pipes, etc. is NOT flagged.
+ {
+ Package: "fmt",
+ Method: "Fprintf",
+ CheckArgs: []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10},
+ ArgTypeGuards: map[int]string{0: "net/http.ResponseWriter"},
+ },
+ {
+ Package: "fmt",
+ Method: "Fprint",
+ CheckArgs: []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10},
+ ArgTypeGuards: map[int]string{0: "net/http.ResponseWriter"},
+ },
+ {
+ Package: "fmt",
+ Method: "Fprintln",
+ CheckArgs: []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10},
+ ArgTypeGuards: map[int]string{0: "net/http.ResponseWriter"},
+ },
+ // io.WriteString: same rationale — only a sink when the writer is HTTP.
+ {
+ Package: "io",
+ Method: "WriteString",
+ CheckArgs: []int{1},
+ ArgTypeGuards: map[int]string{0: "net/http.ResponseWriter"},
+ },
+ // Template functions that unsafely inject untrusted content
+ {Package: "html/template", Method: "HTML"},
+ {Package: "html/template", Method: "HTMLAttr"},
+ {Package: "html/template", Method: "JS"},
+ {Package: "html/template", Method: "CSS"},
+ },
+ Sanitizers: []taint.Sanitizer{
+ // html.EscapeString escapes HTML special characters
+ {Package: "html", Method: "EscapeString"},
+ // html/template auto-escaping functions
+ {Package: "html/template", Method: "HTMLEscapeString"},
+ {Package: "html/template", Method: "JSEscapeString"},
+ {Package: "html/template", Method: "URLQueryEscaper"},
+ // url.QueryEscape for URL parameter escaping
+ {Package: "net/url", Method: "QueryEscape"},
+ {Package: "net/url", Method: "PathEscape"},
+
+ // JSON encoding produces structurally safe output that cannot
+ // contain unescaped HTML tags or script injections. The output
+ // is served as application/json, not text/html.
+ {Package: "encoding/json", Method: "Marshal"},
+ {Package: "encoding/json", Method: "MarshalIndent"},
+
+ // Integer/float conversions produce numeric strings that cannot
+ // contain XSS payloads.
+ {Package: "strconv", Method: "Atoi"},
+ {Package: "strconv", Method: "Itoa"},
+ {Package: "strconv", Method: "ParseInt"},
+ {Package: "strconv", Method: "ParseUint"},
+ {Package: "strconv", Method: "ParseFloat"},
+ {Package: "strconv", Method: "FormatInt"},
+ {Package: "strconv", Method: "FormatUint"},
+ {Package: "strconv", Method: "FormatFloat"},
+ },
+ }
+}
+
+// newXSSAnalyzer creates an analyzer for detecting XSS vulnerabilities
+// via taint analysis (G705)
+func newXSSAnalyzer(id string, description string) *analysis.Analyzer {
+ config := XSS()
+ rule := XSSRule
+ rule.ID = id
+ rule.Description = description
+ return taint.NewGosecAnalyzer(&rule, &config)
+}
diff --git a/vendor/github.com/securego/gosec/v2/config.go b/vendor/github.com/securego/gosec/v2/config.go
index fc355d8ff..69b8f13e2 100644
--- a/vendor/github.com/securego/gosec/v2/config.go
+++ b/vendor/github.com/securego/gosec/v2/config.go
@@ -11,6 +11,8 @@ const (
// Globals are applicable to all rules and used for general
// configuration settings for gosec.
Globals = "global"
+ // ExcludeRulesKey is the config key for path-based rule exclusions
+ ExcludeRulesKey = "exclude-rules"
)
// GlobalOption defines the name of the global options
@@ -135,3 +137,38 @@ func (c Config) IsGlobalEnabled(option GlobalOption) (bool, error) {
}
return (value == "true" || value == "enabled"), nil
}
+
+// GetExcludeRules retrieves the path-based exclusion rules from the configuration.
+// Returns nil if no exclusion rules are configured.
+func (c Config) GetExcludeRules() ([]PathExcludeRule, error) {
+ if c == nil {
+ return nil, nil
+ }
+
+ rawRules, exists := c[ExcludeRulesKey]
+ if !exists {
+ return nil, nil
+ }
+
+ // The config is unmarshaled as map[string]interface{}, so we need to
+ // re-marshal and unmarshal to get the proper typed struct
+ rulesJSON, err := json.Marshal(rawRules)
+ if err != nil {
+ return nil, fmt.Errorf("failed to marshal exclude-rules: %w", err)
+ }
+
+ var rules []PathExcludeRule
+ if err := json.Unmarshal(rulesJSON, &rules); err != nil {
+ return nil, fmt.Errorf("failed to parse exclude-rules: %w", err)
+ }
+
+ return rules, nil
+}
+
+// SetExcludeRules sets the path-based exclusion rules in the configuration.
+func (c Config) SetExcludeRules(rules []PathExcludeRule) {
+ if c == nil {
+ return
+ }
+ c[ExcludeRulesKey] = rules
+}
diff --git a/vendor/github.com/securego/gosec/v2/cwe/data.go b/vendor/github.com/securego/gosec/v2/cwe/data.go
index a9568ba4d..16f7645c2 100644
--- a/vendor/github.com/securego/gosec/v2/cwe/data.go
+++ b/vendor/github.com/securego/gosec/v2/cwe/data.go
@@ -43,6 +43,16 @@ var idWeaknesses = map[string]*Weakness{
Description: "The software constructs all or part of an SQL command using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the intended SQL command when it is sent to a downstream component.",
Name: "Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection')",
},
+ "93": {
+ ID: "93",
+ Description: "The software does not properly neutralize CRLF sequences before using externally-influenced input in protocol elements that rely on CRLF as delimiters, allowing attackers to inject additional commands or headers.",
+ Name: "Improper Neutralization of CRLF Sequences ('CRLF Injection')",
+ },
+ "94": {
+ ID: "94",
+ Description: "The software constructs all or part of a code segment using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the syntax or behavior of the intended code segment.",
+ Name: "Improper Control of Generation of Code ('Code Injection')",
+ },
"118": {
ID: "118",
Description: "The software does not restrict or incorrectly restricts operations within the boundaries of a resource that is accessed using an index or pointer, such as memory or files.",
@@ -68,6 +78,11 @@ var idWeaknesses = map[string]*Weakness{
Description: "During installation, installed file permissions are set to allow anyone to modify those files.",
Name: "Incorrect Default Permissions",
},
+ "287": {
+ ID: "287",
+ Description: "The software does not perform or incorrectly performs authentication.",
+ Name: "Improper Authentication",
+ },
"295": {
ID: "295",
Description: "The software does not validate, or incorrectly validates, a certificate.",
@@ -103,6 +118,11 @@ var idWeaknesses = map[string]*Weakness{
Description: "The product uses a Pseudo-Random Number Generator (PRNG) in a security context, but the PRNG's algorithm is not cryptographically strong.",
Name: "Use of Cryptographically Weak Pseudo-Random Number Generator (PRNG)",
},
+ "367": {
+ ID: "367",
+ Description: "The software checks the state of a resource before using that resource, but the resource's state can change between the check and the use in a way that invalidates the results of the check.",
+ Name: "Time-of-check Time-of-use (TOCTOU) Race Condition",
+ },
"377": {
ID: "377",
Description: "Creating and using insecure temporary files can leave application and system data vulnerable to attack.",
@@ -118,6 +138,16 @@ var idWeaknesses = map[string]*Weakness{
Description: "The software does not handle or incorrectly handles a compressed input with a very high compression ratio that produces a large output.",
Name: "Improper Handling of Highly Compressed Data (Data Amplification)",
},
+ "444": {
+ ID: "444",
+ Description: "When malformed or unexpected HTTP requests are inconsistently interpreted by one or more entities in the data flow between the user and the web server, such as a proxy or firewall, attackers can abuse this discrepancy to smuggle requests to one system without the other system being aware of it.",
+ Name: "Inconsistent Interpretation of HTTP Requests ('HTTP Request Smuggling')",
+ },
+ "499": {
+ ID: "499",
+ Description: "The code contains a class with sensitive data, but the class does not explicitly deny serialization. The data can be accessed by serializing the class through another class.",
+ Name: "Serializable Class Containing Sensitive Data",
+ },
"676": {
ID: "676",
Description: "The program invokes a potentially dangerous function that could introduce a vulnerability if it is used incorrectly, but the function can also be used safely.",
@@ -138,6 +168,26 @@ var idWeaknesses = map[string]*Weakness{
Description: "The product uses a cryptographic primitive that uses an Initialization Vector (IV), but the product does not generate IVs that are sufficiently unpredictable or unique according to the expected cryptographic requirements for that primitive.",
Name: "Generation of Weak Initialization Vector (IV)",
},
+ "117": {
+ ID: "117",
+ Description: "The software does not neutralize or incorrectly neutralizes output that is written to logs.",
+ Name: "Improper Output Neutralization for Logs",
+ },
+ "502": {
+ ID: "502",
+ Description: "The application deserializes untrusted data without sufficiently verifying that the resulting data will be valid.",
+ Name: "Deserialization of Untrusted Data",
+ },
+ "614": {
+ ID: "614",
+ Description: "The Secure attribute for a sensitive cookie is not set, which could cause the user agent to send that cookie in plaintext over an HTTP session.",
+ Name: "Sensitive Cookie in HTTPS Session Without 'Secure' Attribute",
+ },
+ "918": {
+ ID: "918",
+ Description: "The web server receives a URL or similar request from an upstream component and retrieves the contents of this URL, but it does not sufficiently ensure that the request is being sent to the expected destination.",
+ Name: "Server-Side Request Forgery (SSRF)",
+ },
}
// Get Retrieves a CWE weakness by it's id
diff --git a/vendor/github.com/securego/gosec/v2/gosec_cache.go b/vendor/github.com/securego/gosec/v2/gosec_cache.go
new file mode 100644
index 000000000..a46c42d20
--- /dev/null
+++ b/vendor/github.com/securego/gosec/v2/gosec_cache.go
@@ -0,0 +1,81 @@
+package gosec
+
+import (
+ "container/list"
+ "sync"
+)
+
+// GlobalCache is a shared LRU cache for expensive operations.
+// Each use case should define its own named key type to avoid collisions.
+//
+// Key type requirements:
+// - The key type must be comparable (no slices, maps, or funcs)
+// - Use type definitions (type MyKey struct{...}), not type aliases (type MyKey = ...)
+// - Avoid anonymous structs - they collide if the structure matches
+var GlobalCache = NewLRUCache[any, any](1 << 16)
+
+// LRUCache is a simple thread-safe generic LRU cache.
+type LRUCache[K comparable, V any] struct {
+ capacity int
+ items map[K]*list.Element
+ evictList *list.List
+ lock sync.Mutex
+}
+
+type entry[K comparable, V any] struct {
+ key K
+ value V
+}
+
+// NewLRUCache creates a new thread-safe LRU cache with the given capacity.
+func NewLRUCache[K comparable, V any](capacity int) *LRUCache[K, V] {
+ return &LRUCache[K, V]{
+ capacity: capacity,
+ items: make(map[K]*list.Element),
+ evictList: list.New(),
+ }
+}
+
+// Get retrieves a value from the cache. Returns the value and true if found,
+// or the zero value and false if not found. Moves the entry to the front of the LRU list.
+func (c *LRUCache[K, V]) Get(key K) (V, bool) {
+ c.lock.Lock()
+ defer c.lock.Unlock()
+
+ var zero V
+ if ent, ok := c.items[key]; ok {
+ c.evictList.MoveToFront(ent)
+ return ent.Value.(*entry[K, V]).value, true
+ }
+ return zero, false
+}
+
+// Add inserts or updates a key-value pair in the cache.
+// If the key exists, its value is updated and moved to the front.
+// If the cache is full, the least recently used entry is evicted.
+func (c *LRUCache[K, V]) Add(key K, value V) {
+ c.lock.Lock()
+ defer c.lock.Unlock()
+
+ if ent, ok := c.items[key]; ok {
+ c.evictList.MoveToFront(ent)
+ ent.Value.(*entry[K, V]).value = value
+ return
+ }
+
+ ent := &entry[K, V]{key, value}
+ element := c.evictList.PushFront(ent)
+ c.items[key] = element
+
+ if c.evictList.Len() > c.capacity {
+ c.removeOldest()
+ }
+}
+
+func (c *LRUCache[K, V]) removeOldest() {
+ ent := c.evictList.Back()
+ if ent != nil {
+ c.evictList.Remove(ent)
+ delete(c.items, ent.Value.(*entry[K, V]).key)
+ }
+}
diff --git a/vendor/github.com/securego/gosec/v2/helpers.go b/vendor/github.com/securego/gosec/v2/helpers.go
index 7f5724b33..4fb552ab2 100644
--- a/vendor/github.com/securego/gosec/v2/helpers.go
+++ b/vendor/github.com/securego/gosec/v2/helpers.go
@@ -30,6 +30,13 @@ import (
"runtime"
"strconv"
"strings"
+ "sync"
+)
+
+var (
+ ErrUnexpectedASTNode = errors.New("unexpected AST node type")
+ ErrNoProjectRelativePath = errors.New("no project relative path found")
+ ErrNoProjectAbsolutePath = errors.New("no project absolute path found")
)
// envGoModVersion overrides the Go version detection.
@@ -83,7 +90,7 @@ func GetInt(n ast.Node) (int64, error) {
if node, ok := n.(*ast.BasicLit); ok && node.Kind == token.INT {
return strconv.ParseInt(node.Value, 0, 64)
}
- return 0, fmt.Errorf("unexpected AST node type: %T", n)
+ return 0, fmt.Errorf("%w: %T", ErrUnexpectedASTNode, n)
}
// GetFloat will read and return a float value from an ast.BasicLit
@@ -91,7 +98,7 @@ func GetFloat(n ast.Node) (float64, error) {
if node, ok := n.(*ast.BasicLit); ok && node.Kind == token.FLOAT {
return strconv.ParseFloat(node.Value, 64)
}
- return 0.0, fmt.Errorf("unexpected AST node type: %T", n)
+ return 0.0, fmt.Errorf("%w: %T", ErrUnexpectedASTNode, n)
}
// GetChar will read and return a char value from an ast.BasicLit
@@ -99,7 +106,7 @@ func GetChar(n ast.Node) (byte, error) {
if node, ok := n.(*ast.BasicLit); ok && node.Kind == token.CHAR {
return node.Value[0], nil
}
- return 0, fmt.Errorf("unexpected AST node type: %T", n)
+ return 0, fmt.Errorf("%w: %T", ErrUnexpectedASTNode, n)
}
// GetStringRecursive will recursively walk down a tree of *ast.BinaryExpr. It will then concat the results, and return.
@@ -142,7 +149,7 @@ func GetString(n ast.Node) (string, error) {
return strconv.Unquote(node.Value)
}
- return "", fmt.Errorf("unexpected AST node type: %T", n)
+ return "", fmt.Errorf("%w: %T", ErrUnexpectedASTNode, n)
}
// GetCallObject returns the object and call expression and associated
@@ -161,9 +168,35 @@ func GetCallObject(n ast.Node, ctx *Context) (*ast.CallExpr, types.Object) {
return nil, nil
}
+type callInfo struct {
+ packageName string
+ funcName string
+ err error
+}
+
+var callCachePool = sync.Pool{
+ New: func() any {
+ return make(map[ast.Node]callInfo)
+ },
+}
+
// GetCallInfo returns the package or type and name associated with a
// call expression.
func GetCallInfo(n ast.Node, ctx *Context) (string, string, error) {
+ if ctx.callCache != nil {
+ if res, ok := ctx.callCache[n]; ok {
+ return res.packageName, res.funcName, res.err
+ }
+ }
+
+ packageName, funcName, err := getCallInfo(n, ctx)
+ if ctx.callCache != nil {
+ ctx.callCache[n] = callInfo{packageName, funcName, err}
+ }
+ return packageName, funcName, err
+}
+
+func getCallInfo(n ast.Node, ctx *Context) (string, string, error) {
switch node := n.(type) {
case *ast.CallExpr:
switch fn := node.Fun.(type) {
@@ -369,7 +402,7 @@ func GetPkgRelativePath(path string) (string, error) {
return strings.TrimPrefix(abspath, projectRoot), nil
}
}
- return "", errors.New("no project relative path found")
+ return "", ErrNoProjectRelativePath
}
// GetPkgAbsPath returns the Go package absolute path derived from
@@ -380,34 +413,49 @@ func GetPkgAbsPath(pkgPath string) (string, error) {
return "", err
}
if _, err := os.Stat(absPath); os.IsNotExist(err) {
- return "", errors.New("no project absolute path found")
+ return "", ErrNoProjectAbsolutePath
}
return absPath, nil
}
-// ConcatString recursively concatenates strings from a binary expression
-func ConcatString(n *ast.BinaryExpr) (string, bool) {
- var s string
- // sub expressions are found in X object, Y object is always last BasicLit
- if rightOperand, ok := n.Y.(*ast.BasicLit); ok {
- if str, err := GetString(rightOperand); err == nil {
- s = str + s
- }
- } else {
+// ConcatString recursively concatenates constant strings from an expression
+// if the entire chain is fully constant-derived (using TryResolve).
+// Returns the concatenated string and true if successful.
+func ConcatString(expr ast.Expr, ctx *Context) (string, bool) {
+ if expr == nil || !TryResolve(expr, ctx) {
return "", false
}
- if leftOperand, ok := n.X.(*ast.BinaryExpr); ok {
- if recursion, ok := ConcatString(leftOperand); ok {
- s = recursion + s
- }
- } else if leftOperand, ok := n.X.(*ast.BasicLit); ok {
- if str, err := GetString(leftOperand); err == nil {
- s = str + s
+
+ var build strings.Builder
+ var traverse func(ast.Expr) bool
+ traverse = func(e ast.Expr) bool {
+ switch node := e.(type) {
+ case *ast.BasicLit:
+ if str, err := GetString(node); err == nil {
+ build.WriteString(str)
+ return true
+ }
+ return false
+ case *ast.Ident:
+ values := GetIdentStringValuesRecursive(node)
+ for _, v := range values {
+ build.WriteString(v)
+ }
+ return len(values) > 0
+ case *ast.BinaryExpr:
+ if node.Op != token.ADD {
+ return false
+ }
+ return traverse(node.X) && traverse(node.Y)
+ default:
+ return false
}
- } else {
- return "", false
}
- return s, true
+
+ if traverse(expr) {
+ return build.String(), true
+ }
+ return "", false
}
// FindVarIdentities returns array of all variable identities in a given binary expression
@@ -440,6 +488,30 @@ func FindVarIdentities(n *ast.BinaryExpr, c *Context) ([]*ast.Ident, bool) {
return nil, false
}
+// FindModuleRoot returns the directory containing the go.mod file that
+// governs the given directory. It walks upward from dir until it finds
+// a go.mod file or reaches the filesystem root.
+// Returns "" if no go.mod is found.
+//
+// This is needed to correctly load packages in multi-module repositories:
+// without setting packages.Config.Dir to the module root, packages.Load
+// uses the current working directory for module resolution, which fails
+// when the CWD belongs to a different module than the package being loaded.
+func FindModuleRoot(dir string) string {
+ dir = filepath.Clean(dir)
+ for {
+ if fi, err := os.Stat(filepath.Join(dir, "go.mod")); err == nil && !fi.IsDir() {
+ return dir
+ }
+ parent := filepath.Dir(dir)
+ if parent == dir {
+ // Reached filesystem root
+ return ""
+ }
+ dir = parent
+ }
+}
+
// PackagePaths returns a slice with all packages path at given root directory
func PackagePaths(root string, excludes []*regexp.Regexp) ([]string, error) {
if strings.HasSuffix(root, "...") {
@@ -499,18 +571,30 @@ func RootPath(root string) (string, error) {
return filepath.Abs(root)
}
+var (
+ goVersionCache struct {
+ major, minor, build int
+ }
+ goVersionOnce sync.Once
+)
+
// GoVersion returns parsed version of Go mod version and fallback to runtime version if not found.
func GoVersion() (int, int, int) {
- if env, ok := os.LookupEnv(envGoModVersion); ok {
- return parseGoVersion(strings.TrimPrefix(env, "go"))
- }
+ goVersionOnce.Do(func() {
+ if env, ok := os.LookupEnv(envGoModVersion); ok {
+ goVersionCache.major, goVersionCache.minor, goVersionCache.build = parseGoVersion(strings.TrimPrefix(env, "go"))
+ return
+ }
- goVersion, err := goModVersion()
- if err != nil {
- return parseGoVersion(strings.TrimPrefix(runtime.Version(), "go"))
- }
+ goVersion, err := goModVersion()
+ if err != nil {
+ goVersionCache.major, goVersionCache.minor, goVersionCache.build = parseGoVersion(strings.TrimPrefix(runtime.Version(), "go"))
+ return
+ }
- return parseGoVersion(goVersion)
+ goVersionCache.major, goVersionCache.minor, goVersionCache.build = parseGoVersion(goVersion)
+ })
+ return goVersionCache.major, goVersionCache.minor, goVersionCache.build
}
type goListOutput struct {
@@ -574,3 +658,22 @@ func CLIBuildTags(buildTags []string) []string {
return buildFlags
}
+
+// ContainingFile returns the *ast.File from ctx.PkgFiles that contains the given position provider.
+// A position provider can be an ast.Node, a types.Object, or any type with a Pos() token.Pos method.
+// Returns nil if not found or if the provider is nil/invalid.
+func ContainingFile(p interface{ Pos() token.Pos }, ctx *Context) *ast.File {
+ if p == nil {
+ return nil
+ }
+ pos := p.Pos()
+ if !pos.IsValid() {
+ return nil
+ }
+ for _, f := range ctx.PkgFiles {
+ if f.Pos() <= pos && pos < f.End() {
+ return f
+ }
+ }
+ return nil
+}
diff --git a/vendor/github.com/securego/gosec/v2/internal/ssautil/package_analysis_cache.go b/vendor/github.com/securego/gosec/v2/internal/ssautil/package_analysis_cache.go
new file mode 100644
index 000000000..bd04edd1a
--- /dev/null
+++ b/vendor/github.com/securego/gosec/v2/internal/ssautil/package_analysis_cache.go
@@ -0,0 +1,40 @@
+package ssautil
+
+import (
+ "sync"
+
+ "golang.org/x/tools/go/analysis/passes/buildssa"
+ "golang.org/x/tools/go/callgraph"
+ "golang.org/x/tools/go/callgraph/cha"
+)
+
+// PackageAnalysisCache stores expensive SSA-derived artifacts that can be
+// shared by multiple analyzers running on the same package.
+type PackageAnalysisCache struct {
+ ssa *buildssa.SSA
+
+ callGraphOnce sync.Once
+ callGraph *callgraph.Graph
+}
+
+// NewPackageAnalysisCache builds a cache object for a package-level SSA result.
+func NewPackageAnalysisCache(ssaResult *buildssa.SSA) *PackageAnalysisCache {
+ return &PackageAnalysisCache{ssa: ssaResult}
+}
+
+// CallGraph returns a lazily initialized CHA call graph for the package.
+// It is safe for concurrent use by multiple analyzers.
+func (c *PackageAnalysisCache) CallGraph() *callgraph.Graph {
+ if c == nil {
+ return nil
+ }
+
+ c.callGraphOnce.Do(func() {
+ if c.ssa == nil || len(c.ssa.SrcFuncs) == 0 || c.ssa.SrcFuncs[0] == nil {
+ return
+ }
+ c.callGraph = cha.CallGraph(c.ssa.SrcFuncs[0].Prog)
+ })
+
+ return c.callGraph
+}
diff --git a/vendor/github.com/securego/gosec/v2/internal/ssautil/ssa_result.go b/vendor/github.com/securego/gosec/v2/internal/ssautil/ssa_result.go
new file mode 100644
index 000000000..3b339db0e
--- /dev/null
+++ b/vendor/github.com/securego/gosec/v2/internal/ssautil/ssa_result.go
@@ -0,0 +1,37 @@
+// Package ssautil provides shared SSA analysis utilities for gosec analyzers.
+package ssautil
+
+import (
+ "errors"
+ "log"
+
+ "golang.org/x/tools/go/analysis"
+ "golang.org/x/tools/go/analysis/passes/buildssa"
+)
+
+var (
+ ErrNoSSAResult = errors.New("no SSA result found in the analysis pass")
+ ErrInvalidSSAType = errors.New("the analysis pass result is not of type SSA")
+)
+
+// SSAAnalyzerResult contains various information returned by the
+// SSA analysis along with some configuration
+type SSAAnalyzerResult struct {
+ Config map[string]any
+ Logger *log.Logger
+ SSA *buildssa.SSA
+ Shared *PackageAnalysisCache
+}
+
+// GetSSAResult retrieves the SSA result from analysis pass
+func GetSSAResult(pass *analysis.Pass) (*SSAAnalyzerResult, error) {
+ result, ok := pass.ResultOf[buildssa.Analyzer]
+ if !ok {
+ return nil, ErrNoSSAResult
+ }
+ ssaResult, ok := result.(*SSAAnalyzerResult)
+ if !ok {
+ return nil, ErrInvalidSSAType
+ }
+ return ssaResult, nil
+}
diff --git a/vendor/github.com/securego/gosec/v2/issue/issue.go b/vendor/github.com/securego/gosec/v2/issue/issue.go
index 28c876b33..f2cc986d2 100644
--- a/vendor/github.com/securego/gosec/v2/issue/issue.go
+++ b/vendor/github.com/securego/gosec/v2/issue/issue.go
@@ -52,7 +52,9 @@ func GetCweByRule(id string) *cwe.Weakness {
return nil
}
-// ruleToCWE maps gosec rules to CWEs
+// ruleToCWE maps gosec rules to CWEs. The key is the rule ID
+// and the value is the CWE ID. If a rule does not have a CWE,
+// it will not be included in this map.
var ruleToCWE = map[string]string{
"G101": "798",
"G102": "200",
@@ -65,9 +67,21 @@ var ruleToCWE = map[string]string{
"G110": "409",
"G111": "22",
"G112": "400",
+ "G113": "444",
+ "G707": "93",
+ "G708": "94",
+ "G709": "502",
"G114": "676",
"G115": "190",
"G116": "838",
+ "G117": "499",
+ "G118": "400",
+ "G119": "200",
+ "G120": "400",
+ "G121": "346",
+ "G122": "367",
+ "G123": "295",
+ "G124": "614",
"G201": "89",
"G202": "89",
"G203": "79",
@@ -78,6 +92,7 @@ var ruleToCWE = map[string]string{
"G304": "22",
"G305": "22",
"G306": "276",
+ "G307": "276",
"G401": "328",
"G402": "295",
"G403": "310",
@@ -85,6 +100,7 @@ var ruleToCWE = map[string]string{
"G405": "327",
"G406": "328",
"G407": "1204",
+ "G408": "287",
"G501": "327",
"G502": "327",
"G503": "327",
@@ -94,6 +110,13 @@ var ruleToCWE = map[string]string{
"G507": "327",
"G601": "118",
"G602": "118",
+ "G701": "89",
+ "G702": "78",
+ "G703": "22",
+ "G704": "918",
+ "G705": "79",
+ "G706": "117",
+ "G710": "601",
}
// Issue is returned by a gosec rule if it discovers an issue with the scanned code.
@@ -127,12 +150,28 @@ func (i *Issue) FileLocation() string {
// MetaData is embedded in all gosec rules. The Severity, Confidence and What message
// will be passed through to reported issues.
type MetaData struct {
- ID string
+ RuleID string
Severity Score
Confidence Score
What string
}
+// NewMetaData creates a new MetaData object
+func NewMetaData(id, what string, severity, confidence Score) MetaData {
+ return MetaData{
+ RuleID: id,
+ What: what,
+ Severity: severity,
+ Confidence: confidence,
+ }
+}
+
+// ID returns the rule ID. This satisfies part of the gosec.Rule interface
+// when MetaData is embedded in a rule struct.
+func (m MetaData) ID() string {
+ return m.RuleID
+}
+
// MarshalJSON is used convert a Score object into a JSON representation
func (c Score) MarshalJSON() ([]byte, error) {
return json.Marshal(c.String())
@@ -185,8 +224,16 @@ func codeSnippetEndLine(node ast.Node, fobj *token.File) int64 {
// New creates a new Issue
func New(fobj *token.File, node ast.Node, ruleID, desc string, severity, confidence Score) *Issue {
name := fobj.Name()
- line := GetLine(fobj, node)
- col := strconv.Itoa(fobj.Position(node.Pos()).Column)
+ var line string
+ var col string
+
+ if node == nil {
+ line = "0"
+ col = "0"
+ } else {
+ line = GetLine(fobj, node)
+ col = strconv.Itoa(fobj.Position(node.Pos()).Column)
+ }
var code string
if node == nil {
diff --git a/vendor/github.com/securego/gosec/v2/path_filter.go b/vendor/github.com/securego/gosec/v2/path_filter.go
new file mode 100644
index 000000000..eeb4d1b90
--- /dev/null
+++ b/vendor/github.com/securego/gosec/v2/path_filter.go
@@ -0,0 +1,213 @@
+package gosec
+
+import (
+ "fmt"
+ "regexp"
+ "strings"
+
+ "github.com/securego/gosec/v2/issue"
+)
+
+// PathExcludeRule defines rules to exclude for specific file paths
+type PathExcludeRule struct {
+ Path string `json:"path"` // Regex pattern for matching file paths
+ Rules []string `json:"rules"` // Rule IDs to exclude. Use "*" to exclude all rules
+}
+
+// compiledPathRule is a pre-compiled version of PathExcludeRule for efficient matching
+type compiledPathRule struct {
+ pathRegex *regexp.Regexp
+ ruleSet map[string]bool // Set of rule IDs to exclude
+ excludeAll bool // True if "*" was specified in rules
+ original PathExcludeRule // Keep original for error messages
+}
+
+// PathExclusionFilter handles filtering of issues based on path and rule combinations
+type PathExclusionFilter struct {
+ rules []compiledPathRule
+}
+
+// NewPathExclusionFilter creates a new filter from the provided exclusion rules.
+// Returns an error if any path regex is invalid.
+func NewPathExclusionFilter(rules []PathExcludeRule) (*PathExclusionFilter, error) {
+ if len(rules) == 0 {
+ return &PathExclusionFilter{rules: nil}, nil
+ }
+
+ compiled := make([]compiledPathRule, 0, len(rules))
+
+ for i, rule := range rules {
+ if rule.Path == "" {
+ return nil, fmt.Errorf("exclude-rules[%d]: path cannot be empty", i)
+ }
+
+ regex, err := regexp.Compile(rule.Path)
+ if err != nil {
+ return nil, fmt.Errorf("exclude-rules[%d]: invalid path regex %q: %w", i, rule.Path, err)
+ }
+
+ ruleSet := make(map[string]bool)
+ excludeAll := false
+
+ for _, ruleID := range rule.Rules {
+ ruleID = strings.TrimSpace(ruleID)
+ if ruleID == "*" {
+ excludeAll = true
+ } else if ruleID != "" {
+ ruleSet[ruleID] = true
+ }
+ }
+
+ compiled = append(compiled, compiledPathRule{
+ pathRegex: regex,
+ ruleSet: ruleSet,
+ excludeAll: excludeAll,
+ original: rule,
+ })
+ }
+
+ return &PathExclusionFilter{rules: compiled}, nil
+}
+
+// ShouldExclude returns true if the given issue should be excluded based on
+// its file path and rule ID
+func (f *PathExclusionFilter) ShouldExclude(filePath, ruleID string) bool {
+ if f == nil || len(f.rules) == 0 {
+ return false
+ }
+
+ // Normalize path separators for consistent matching
+ normalizedPath := strings.ReplaceAll(filePath, "\\", "/")
+
+ for _, rule := range f.rules {
+ if rule.pathRegex.MatchString(normalizedPath) {
+ if rule.excludeAll {
+ return true
+ }
+ if rule.ruleSet[ruleID] {
+ return true
+ }
+ }
+ }
+
+ return false
+}
+
+// FilterIssues applies path-based exclusions to a slice of issues.
+// Returns the filtered issues and the count of excluded issues.
+func (f *PathExclusionFilter) FilterIssues(issues []*issue.Issue) ([]*issue.Issue, int) {
+ if f == nil || len(f.rules) == 0 || len(issues) == 0 {
+ return issues, 0
+ }
+
+ filtered := make([]*issue.Issue, 0, len(issues))
+ excluded := 0
+
+ for _, iss := range issues {
+ if f.ShouldExclude(iss.File, iss.RuleID) {
+ excluded++
+ continue
+ }
+ filtered = append(filtered, iss)
+ }
+
+ return filtered, excluded
+}
+
+// ParseCLIExcludeRules parses the CLI format for exclude-rules.
+// Format: "path:rule1,rule2;path2:rule3,rule4"
+// Example: "cmd/.*:G204,G304;test/.*:G101"
+func ParseCLIExcludeRules(input string) ([]PathExcludeRule, error) {
+ if input == "" {
+ return nil, nil
+ }
+
+ var rules []PathExcludeRule
+
+ // Split by semicolon for multiple rules
+ parts := strings.Split(input, ";")
+
+ for i, part := range parts {
+ part = strings.TrimSpace(part)
+ if part == "" {
+ continue
+ }
+
+ // Split by colon to separate path and rules
+ colonIdx := strings.LastIndex(part, ":")
+ if colonIdx == -1 {
+ return nil, fmt.Errorf("exclude-rules part %d: missing ':' separator in %q", i+1, part)
+ }
+
+ pathPattern := strings.TrimSpace(part[:colonIdx])
+ rulesPart := strings.TrimSpace(part[colonIdx+1:])
+
+ if pathPattern == "" {
+ return nil, fmt.Errorf("exclude-rules part %d: path pattern cannot be empty", i+1)
+ }
+
+ if rulesPart == "" {
+ return nil, fmt.Errorf("exclude-rules part %d: rules list cannot be empty", i+1)
+ }
+
+ // Split rules by comma
+ ruleIDs := strings.Split(rulesPart, ",")
+ cleanedRules := make([]string, 0, len(ruleIDs))
+ for _, r := range ruleIDs {
+ r = strings.TrimSpace(r)
+ if r != "" {
+ cleanedRules = append(cleanedRules, r)
+ }
+ }
+
+ if len(cleanedRules) == 0 {
+ return nil, fmt.Errorf("exclude-rules part %d: no valid rules specified", i+1)
+ }
+
+ rules = append(rules, PathExcludeRule{
+ Path: pathPattern,
+ Rules: cleanedRules,
+ })
+ }
+
+ return rules, nil
+}
+
+// MergeExcludeRules combines exclude rules from multiple sources (config file + CLI).
+// CLI rules take precedence and are processed first.
+func MergeExcludeRules(configRules, cliRules []PathExcludeRule) []PathExcludeRule {
+ if len(cliRules) == 0 {
+ return configRules
+ }
+ if len(configRules) == 0 {
+ return cliRules
+ }
+
+ // CLI rules first, then config rules
+ merged := make([]PathExcludeRule, 0, len(cliRules)+len(configRules))
+ merged = append(merged, cliRules...)
+ merged = append(merged, configRules...)
+ return merged
+}
+
+// String returns a human-readable representation of the filter
+func (f *PathExclusionFilter) String() string {
+ if f == nil || len(f.rules) == 0 {
+ return "PathExclusionFilter{empty}"
+ }
+
+ var parts []string
+ for _, rule := range f.rules {
+ if rule.excludeAll {
+ parts = append(parts, fmt.Sprintf("%s:*", rule.original.Path))
+ } else {
+ ruleIDs := make([]string, 0, len(rule.ruleSet))
+ for id := range rule.ruleSet {
+ ruleIDs = append(ruleIDs, id)
+ }
+ parts = append(parts, fmt.Sprintf("%s:[%s]", rule.original.Path, strings.Join(ruleIDs, ",")))
+ }
+ }
+
+ return fmt.Sprintf("PathExclusionFilter{%s}", strings.Join(parts, "; "))
+}
diff --git a/vendor/github.com/securego/gosec/v2/regex_cache.go b/vendor/github.com/securego/gosec/v2/regex_cache.go
new file mode 100644
index 000000000..5eddc23c5
--- /dev/null
+++ b/vendor/github.com/securego/gosec/v2/regex_cache.go
@@ -0,0 +1,21 @@
+package gosec
+
+import "regexp"
+
+// regexCacheKey is the cache key for regex match results.
+type regexCacheKey struct {
+ Re *regexp.Regexp
+ Str string
+}
+
+// RegexMatchWithCache returns the result of re.MatchString(s), using GlobalCache
+// to store previous results for improved performance on repeated lookups.
+func RegexMatchWithCache(re *regexp.Regexp, s string) bool {
+ key := regexCacheKey{Re: re, Str: s}
+ if val, ok := GlobalCache.Get(key); ok {
+ return val.(bool)
+ }
+ res := re.MatchString(s)
+ GlobalCache.Add(key, res)
+ return res
+}
diff --git a/vendor/github.com/securego/gosec/v2/resolve.go b/vendor/github.com/securego/gosec/v2/resolve.go
index a201b8d32..18f9ad9c1 100644
--- a/vendor/github.com/securego/gosec/v2/resolve.go
+++ b/vendor/github.com/securego/gosec/v2/resolve.go
@@ -90,6 +90,12 @@ func TryResolve(n ast.Node, c *Context) bool {
return resolveCallExpr(node, c)
case *ast.BinaryExpr:
return resolveBinExpr(node, c)
+ case *ast.KeyValueExpr:
+ return TryResolve(node.Key, c) && TryResolve(node.Value, c)
+ case *ast.IndexExpr:
+ return TryResolve(node.X, c)
+ case *ast.SliceExpr:
+ return TryResolve(node.X, c)
}
return false
}
diff --git a/vendor/github.com/securego/gosec/v2/rules/archive.go b/vendor/github.com/securego/gosec/v2/rules/archive.go
index 987047435..e1c241c16 100644
--- a/vendor/github.com/securego/gosec/v2/rules/archive.go
+++ b/vendor/github.com/securego/gosec/v2/rules/archive.go
@@ -2,45 +2,62 @@ package rules
import (
"go/ast"
+ "go/token"
"go/types"
+ "slices"
"github.com/securego/gosec/v2"
"github.com/securego/gosec/v2/issue"
)
type archive struct {
- issue.MetaData
- calls gosec.CallList
+ callListRule
argTypes []string
}
-func (a *archive) ID() string {
- return a.MetaData.ID
-}
-
-// Match inspects AST nodes to determine if the filepath.Joins uses any argument derived from type zip.File or tar.Header
-func (a *archive) Match(n ast.Node, c *gosec.Context) (*issue.Issue, error) {
- if node := a.calls.ContainsPkgCallExpr(n, c, false); node != nil {
- for _, arg := range node.Args {
- var argType types.Type
- if selector, ok := arg.(*ast.SelectorExpr); ok {
- argType = c.Info.TypeOf(selector.X)
- } else if ident, ok := arg.(*ast.Ident); ok {
- if ident.Obj != nil && ident.Obj.Kind == ast.Var {
- decl := ident.Obj.Decl
- if assign, ok := decl.(*ast.AssignStmt); ok {
- if selector, ok := assign.Rhs[0].(*ast.SelectorExpr); ok {
- argType = c.Info.TypeOf(selector.X)
+// getArchiveBaseType returns the underlying type (*archive/zip.File or *archive/tar.Header)
+// if the expression is a direct .Name selector on such a type or a short-declared variable
+// assigned from such a selector (e.g., name := file.Name).
+func getArchiveBaseType(expr ast.Expr, ctx *gosec.Context, file *ast.File) types.Type {
+ switch e := expr.(type) {
+ case *ast.SelectorExpr:
+ return ctx.Info.TypeOf(e.X)
+ case *ast.Ident:
+ obj := ctx.Info.ObjectOf(e)
+ if v, ok := obj.(*types.Var); ok && file != nil {
+ var baseType types.Type
+ ast.Inspect(file, func(n ast.Node) bool {
+ if assign, ok := n.(*ast.AssignStmt); ok && assign.Tok == token.DEFINE {
+ for i, lhs := range assign.Lhs {
+ if id, ok := lhs.(*ast.Ident); ok &&
+ id.Pos() == v.Pos() && ctx.Info.ObjectOf(id) == v {
+ if i < len(assign.Rhs) {
+ if sel, ok := assign.Rhs[i].(*ast.SelectorExpr); ok {
+ baseType = ctx.Info.TypeOf(sel.X)
+ }
+ }
+ return false // Stop once defining assignment found
}
}
}
- }
+ return true
+ })
+ return baseType
+ }
+ }
+ return nil
+}
- if argType != nil {
- for _, t := range a.argTypes {
- if argType.String() == t {
- return c.NewIssue(n, a.ID(), a.What, a.Severity, a.Confidence), nil
- }
+// Match inspects AST nodes to determine if filepath.Join uses an argument derived
+// from zip.File or tar.Header (typically the unsafe .Name field).
+func (a *archive) Match(n ast.Node, ctx *gosec.Context) (*issue.Issue, error) {
+ if node := a.calls.ContainsPkgCallExpr(n, ctx, false); node != nil {
+ // All relevant variables are local (archive extraction context), so inspect the file containing the call
+ file := gosec.ContainingFile(node, ctx)
+ for _, arg := range node.Args {
+ if baseType := getArchiveBaseType(arg, ctx, file); baseType != nil {
+ if slices.Contains(a.argTypes, baseType.String()) {
+ return ctx.NewIssue(n, a.ID(), a.What, a.Severity, a.Confidence), nil
}
}
}
@@ -48,19 +65,12 @@ func (a *archive) Match(n ast.Node, c *gosec.Context) (*issue.Issue, error) {
return nil, nil
}
-// NewArchive creates a new rule which detects the file traversal when extracting zip/tar archives
+// NewArchive creates a new rule which detects file traversal when extracting zip/tar archives.
func NewArchive(id string, _ gosec.Config) (gosec.Rule, []ast.Node) {
- calls := gosec.NewCallList()
- calls.Add("path/filepath", "Join")
- calls.Add("path", "Join")
- return &archive{
- calls: calls,
- argTypes: []string{"*archive/zip.File", "*archive/tar.Header"},
- MetaData: issue.MetaData{
- ID: id,
- Severity: issue.Medium,
- Confidence: issue.High,
- What: "File traversal when extracting zip/tar archive",
- },
- }, []ast.Node{(*ast.CallExpr)(nil)}
+ rule := &archive{
+ callListRule: newCallListRule(id, "File traversal when extracting zip/tar archive", issue.Medium, issue.High),
+ argTypes: []string{"*archive/zip.File", "*archive/tar.Header"},
+ }
+ rule.Add("path/filepath", "Join").Add("path", "Join")
+ return rule, []ast.Node{(*ast.CallExpr)(nil)}
}
diff --git a/vendor/github.com/securego/gosec/v2/rules/base.go b/vendor/github.com/securego/gosec/v2/rules/base.go
new file mode 100644
index 000000000..cc882d37c
--- /dev/null
+++ b/vendor/github.com/securego/gosec/v2/rules/base.go
@@ -0,0 +1,39 @@
+package rules
+
+import (
+ "go/ast"
+
+ "github.com/securego/gosec/v2"
+ "github.com/securego/gosec/v2/issue"
+)
+
+// callListRule is a base for rules that simply check a CallList and issue on match.
+// It provides the standard Match() implementation used by most call-based rules.
+type callListRule struct {
+ issue.MetaData
+ calls gosec.CallList
+}
+
+func newCallListRule(id, what string, severity, confidence issue.Score) callListRule {
+ return callListRule{
+ MetaData: issue.NewMetaData(id, what, severity, confidence),
+ calls: gosec.NewCallList(),
+ }
+}
+
+func (r *callListRule) Add(selector, ident string) *callListRule {
+ r.calls.Add(selector, ident)
+ return r
+}
+
+func (r *callListRule) AddAll(selector string, idents ...string) *callListRule {
+ r.calls.AddAll(selector, idents...)
+ return r
+}
+
+func (r *callListRule) Match(n ast.Node, c *gosec.Context) (*issue.Issue, error) {
+ if r.calls.ContainsPkgCallExpr(n, c, false) != nil {
+ return c.NewIssue(n, r.ID(), r.What, r.Severity, r.Confidence), nil
+ }
+ return nil, nil
+}
diff --git a/vendor/github.com/securego/gosec/v2/rules/bind.go b/vendor/github.com/securego/gosec/v2/rules/bind.go
index fef760c80..8b0e6a5c1 100644
--- a/vendor/github.com/securego/gosec/v2/rules/bind.go
+++ b/vendor/github.com/securego/gosec/v2/rules/bind.go
@@ -24,15 +24,10 @@ import (
// Looks for net.Listen("0.0.0.0") or net.Listen(":8080")
type bindsToAllNetworkInterfaces struct {
- issue.MetaData
- calls gosec.CallList
+ callListRule
pattern *regexp.Regexp
}
-func (r *bindsToAllNetworkInterfaces) ID() string {
- return r.MetaData.ID
-}
-
func (r *bindsToAllNetworkInterfaces) Match(n ast.Node, c *gosec.Context) (*issue.Issue, error) {
callExpr := r.calls.ContainsPkgCallExpr(n, c, false)
if callExpr == nil {
@@ -42,14 +37,14 @@ func (r *bindsToAllNetworkInterfaces) Match(n ast.Node, c *gosec.Context) (*issu
arg := callExpr.Args[1]
if bl, ok := arg.(*ast.BasicLit); ok {
if arg, err := gosec.GetString(bl); err == nil {
- if r.pattern.MatchString(arg) {
+ if gosec.RegexMatchWithCache(r.pattern, arg) {
return c.NewIssue(n, r.ID(), r.What, r.Severity, r.Confidence), nil
}
}
} else if ident, ok := arg.(*ast.Ident); ok {
values := gosec.GetIdentStringValues(ident)
for _, value := range values {
- if r.pattern.MatchString(value) {
+ if gosec.RegexMatchWithCache(r.pattern, value) {
return c.NewIssue(n, r.ID(), r.What, r.Severity, r.Confidence), nil
}
}
@@ -57,7 +52,7 @@ func (r *bindsToAllNetworkInterfaces) Match(n ast.Node, c *gosec.Context) (*issu
} else if len(callExpr.Args) > 0 {
values := gosec.GetCallStringArgsValues(callExpr.Args[0], c)
for _, value := range values {
- if r.pattern.MatchString(value) {
+ if gosec.RegexMatchWithCache(r.pattern, value) {
return c.NewIssue(n, r.ID(), r.What, r.Severity, r.Confidence), nil
}
}
@@ -68,17 +63,10 @@ func (r *bindsToAllNetworkInterfaces) Match(n ast.Node, c *gosec.Context) (*issu
// NewBindsToAllNetworkInterfaces detects socket connections that are setup to
// listen on all network interfaces.
func NewBindsToAllNetworkInterfaces(id string, _ gosec.Config) (gosec.Rule, []ast.Node) {
- calls := gosec.NewCallList()
- calls.Add("net", "Listen")
- calls.Add("crypto/tls", "Listen")
- return &bindsToAllNetworkInterfaces{
- calls: calls,
- pattern: regexp.MustCompile(`^(0.0.0.0|:).*$`),
- MetaData: issue.MetaData{
- ID: id,
- Severity: issue.Medium,
- Confidence: issue.High,
- What: "Binds to all network interfaces",
- },
- }, []ast.Node{(*ast.CallExpr)(nil)}
+ rule := &bindsToAllNetworkInterfaces{
+ callListRule: newCallListRule(id, "Binds to all network interfaces", issue.Medium, issue.High),
+ pattern: regexp.MustCompile(`^(0.0.0.0|:).*$`),
+ }
+ rule.Add("net", "Listen").Add("crypto/tls", "Listen")
+ return rule, []ast.Node{(*ast.CallExpr)(nil)}
}
diff --git a/vendor/github.com/securego/gosec/v2/rules/blocklist.go b/vendor/github.com/securego/gosec/v2/rules/blocklist.go
index a4376b19a..e877f48b9 100644
--- a/vendor/github.com/securego/gosec/v2/rules/blocklist.go
+++ b/vendor/github.com/securego/gosec/v2/rules/blocklist.go
@@ -33,10 +33,6 @@ func unquote(original string) string {
return strings.TrimRight(cleaned, `"`)
}
-func (r *blocklistedImport) ID() string {
- return r.MetaData.ID
-}
-
func (r *blocklistedImport) Match(n ast.Node, c *gosec.Context) (*issue.Issue, error) {
if node, ok := n.(*ast.ImportSpec); ok {
if description, ok := r.Blocklisted[unquote(node.Path.Value)]; ok {
@@ -50,11 +46,7 @@ func (r *blocklistedImport) Match(n ast.Node, c *gosec.Context) (*issue.Issue, e
// Typically when a deprecated technology is being used.
func NewBlocklistedImports(id string, _ gosec.Config, blocklist map[string]string) (gosec.Rule, []ast.Node) {
return &blocklistedImport{
- MetaData: issue.MetaData{
- ID: id,
- Severity: issue.Medium,
- Confidence: issue.High,
- },
+ MetaData: issue.NewMetaData(id, "", issue.Medium, issue.High),
Blocklisted: blocklist,
}, []ast.Node{(*ast.ImportSpec)(nil)}
}
diff --git a/vendor/github.com/securego/gosec/v2/rules/decompression_bomb.go b/vendor/github.com/securego/gosec/v2/rules/decompression_bomb.go
index 7e57f1a5b..d9bddde5a 100644
--- a/vendor/github.com/securego/gosec/v2/rules/decompression_bomb.go
+++ b/vendor/github.com/securego/gosec/v2/rules/decompression_bomb.go
@@ -17,6 +17,7 @@ package rules
import (
"fmt"
"go/ast"
+ "go/types"
"github.com/securego/gosec/v2"
"github.com/securego/gosec/v2/issue"
@@ -28,52 +29,54 @@ type decompressionBombCheck struct {
copyCalls gosec.CallList
}
-func (d *decompressionBombCheck) ID() string {
- return d.MetaData.ID
-}
-
func containsReaderCall(node ast.Node, ctx *gosec.Context, list gosec.CallList) bool {
if list.ContainsPkgCallExpr(node, ctx, false) != nil {
return true
}
- // Resolve type info of ident (for *archive/zip.File.Open)
+ // Resolve type info for selector calls like file.Open()
s, idt, _ := gosec.GetCallInfo(node, ctx)
return list.Contains(s, idt)
}
func (d *decompressionBombCheck) Match(node ast.Node, ctx *gosec.Context) (*issue.Issue, error) {
- var readerVarObj map[*ast.Object]struct{}
+ var readerVars map[*types.Var]struct{}
- // To check multiple lines, ctx.PassedValues is used to store temporary data.
+ // Use ctx.PassedValues for stateful tracking across statements.
if _, ok := ctx.PassedValues[d.ID()]; !ok {
- readerVarObj = make(map[*ast.Object]struct{})
- ctx.PassedValues[d.ID()] = readerVarObj
- } else if pv, ok := ctx.PassedValues[d.ID()].(map[*ast.Object]struct{}); ok {
- readerVarObj = pv
+ readerVars = make(map[*types.Var]struct{})
+ ctx.PassedValues[d.ID()] = readerVars
+ } else if pv, ok := ctx.PassedValues[d.ID()].(map[*types.Var]struct{}); ok {
+ readerVars = pv
} else {
- return nil, fmt.Errorf("PassedValues[%s] of Context is not map[*ast.Object]struct{}, but %T", d.ID(), ctx.PassedValues[d.ID()])
+ return nil, fmt.Errorf("PassedValues[%s] of Context is not map[*types.Var]struct{}, but %T", d.ID(), ctx.PassedValues[d.ID()])
}
- // io.Copy is a common function.
- // To reduce false positives, This rule detects code which is used for compressed data only.
switch n := node.(type) {
case *ast.AssignStmt:
- for _, expr := range n.Rhs {
+ for i, expr := range n.Rhs {
if callExpr, ok := expr.(*ast.CallExpr); ok && containsReaderCall(callExpr, ctx, d.readerCalls) {
- if idt, ok := n.Lhs[0].(*ast.Ident); ok && idt.Name != "_" {
- // Example:
- // r, _ := zlib.NewReader(buf)
- // Add r's Obj to readerVarObj map
- readerVarObj[idt.Obj] = struct{}{}
+ if i < len(n.Lhs) {
+ if idt, ok := n.Lhs[i].(*ast.Ident); ok && idt.Name != "_" {
+ if obj := ctx.Info.ObjectOf(idt); obj != nil {
+ if v, ok := obj.(*types.Var); ok {
+ readerVars[v] = struct{}{}
+ }
+ }
+ }
}
}
}
case *ast.CallExpr:
if d.copyCalls.ContainsPkgCallExpr(n, ctx, false) != nil {
- if idt, ok := n.Args[1].(*ast.Ident); ok {
- if _, ok := readerVarObj[idt.Obj]; ok {
- // Detect io.Copy(x, r)
- return ctx.NewIssue(n, d.ID(), d.What, d.Severity, d.Confidence), nil
+ if len(n.Args) > 1 {
+ if idt, ok := n.Args[1].(*ast.Ident); ok {
+ if obj := ctx.Info.ObjectOf(idt); obj != nil {
+ if v, ok := obj.(*types.Var); ok {
+ if _, tracked := readerVars[v]; tracked {
+ return ctx.NewIssue(n, d.ID(), d.What, d.Severity, d.Confidence), nil
+ }
+ }
+ }
}
}
}
@@ -82,30 +85,23 @@ func (d *decompressionBombCheck) Match(node ast.Node, ctx *gosec.Context) (*issu
return nil, nil
}
-// NewDecompressionBombCheck detects if there is potential DoS vulnerability via decompression bomb
+// NewDecompressionBombCheck detects potential DoS via decompression bomb
func NewDecompressionBombCheck(id string, _ gosec.Config) (gosec.Rule, []ast.Node) {
- readerCalls := gosec.NewCallList()
- readerCalls.Add("compress/gzip", "NewReader")
- readerCalls.AddAll("compress/zlib", "NewReader", "NewReaderDict")
- readerCalls.Add("compress/bzip2", "NewReader")
- readerCalls.AddAll("compress/flate", "NewReader", "NewReaderDict")
- readerCalls.Add("compress/lzw", "NewReader")
- readerCalls.Add("archive/tar", "NewReader")
- readerCalls.Add("archive/zip", "NewReader")
- readerCalls.Add("*archive/zip.File", "Open")
+ rule := &decompressionBombCheck{
+ MetaData: issue.NewMetaData(id, "Potential DoS vulnerability via decompression bomb", issue.Medium, issue.Medium),
+ readerCalls: gosec.NewCallList(),
+ copyCalls: gosec.NewCallList(),
+ }
+ rule.readerCalls.Add("compress/gzip", "NewReader")
+ rule.readerCalls.AddAll("compress/zlib", "NewReader", "NewReaderDict")
+ rule.readerCalls.Add("compress/bzip2", "NewReader")
+ rule.readerCalls.AddAll("compress/flate", "NewReader", "NewReaderDict")
+ rule.readerCalls.Add("compress/lzw", "NewReader")
+ rule.readerCalls.Add("archive/tar", "NewReader")
+ rule.readerCalls.Add("archive/zip", "NewReader")
+ rule.readerCalls.Add("*archive/zip.File", "Open")
- copyCalls := gosec.NewCallList()
- copyCalls.Add("io", "Copy")
- copyCalls.Add("io", "CopyBuffer")
+ rule.copyCalls.AddAll("io", "Copy", "CopyBuffer")
- return &decompressionBombCheck{
- MetaData: issue.MetaData{
- ID: id,
- Severity: issue.Medium,
- Confidence: issue.Medium,
- What: "Potential DoS vulnerability via decompression bomb",
- },
- readerCalls: readerCalls,
- copyCalls: copyCalls,
- }, []ast.Node{(*ast.FuncDecl)(nil), (*ast.AssignStmt)(nil), (*ast.CallExpr)(nil)}
+ return rule, []ast.Node{(*ast.AssignStmt)(nil), (*ast.CallExpr)(nil)}
}
diff --git a/vendor/github.com/securego/gosec/v2/rules/directory_traversal.go b/vendor/github.com/securego/gosec/v2/rules/directory_traversal.go
index 47bcb2dc4..d18bfd4e4 100644
--- a/vendor/github.com/securego/gosec/v2/rules/directory_traversal.go
+++ b/vendor/github.com/securego/gosec/v2/rules/directory_traversal.go
@@ -13,10 +13,6 @@ type traversal struct {
issue.MetaData
}
-func (r *traversal) ID() string {
- return r.MetaData.ID
-}
-
func (r *traversal) Match(n ast.Node, ctx *gosec.Context) (*issue.Issue, error) {
switch node := n.(type) {
case *ast.CallExpr:
@@ -31,7 +27,7 @@ func (r *traversal) matchCallExpr(assign *ast.CallExpr, ctx *gosec.Context) (*is
if fun, ok2 := assign.Fun.(*ast.SelectorExpr); ok2 {
if x, ok3 := fun.X.(*ast.Ident); ok3 {
str := x.Name + "." + fun.Sel.Name + "(" + basiclit.Value + ")"
- if r.pattern.MatchString(str) {
+ if gosec.RegexMatchWithCache(r.pattern, str) {
return ctx.NewIssue(assign, r.ID(), r.What, r.Severity, r.Confidence), nil
}
}
@@ -54,12 +50,7 @@ func NewDirectoryTraversal(id string, conf gosec.Config) (gosec.Rule, []ast.Node
}
return &traversal{
- pattern: regexp.MustCompile(pattern),
- MetaData: issue.MetaData{
- ID: id,
- What: "Potential directory traversal",
- Confidence: issue.Medium,
- Severity: issue.Medium,
- },
+ pattern: regexp.MustCompile(pattern),
+ MetaData: issue.NewMetaData(id, "Potential directory traversal", issue.Medium, issue.Medium),
}, []ast.Node{(*ast.CallExpr)(nil)}
}
diff --git a/vendor/github.com/securego/gosec/v2/rules/errors.go b/vendor/github.com/securego/gosec/v2/rules/errors.go
index 278642655..4f1972b82 100644
--- a/vendor/github.com/securego/gosec/v2/rules/errors.go
+++ b/vendor/github.com/securego/gosec/v2/rules/errors.go
@@ -27,10 +27,6 @@ type noErrorCheck struct {
whitelist gosec.CallList
}
-func (r *noErrorCheck) ID() string {
- return r.MetaData.ID
-}
-
func returnsError(callExpr *ast.CallExpr, ctx *gosec.Context) int {
if tv := ctx.Info.TypeOf(callExpr); tv != nil {
switch t := tv.(type) {
@@ -89,6 +85,7 @@ func NewNoErrorCheck(id string, conf gosec.Config) (gosec.Rule, []ast.Node) {
whitelist.Add("io.PipeWriter", "CloseWithError")
whitelist.Add("hash.Hash", "Write")
whitelist.Add("os", "Unsetenv")
+ whitelist.Add("rand", "Read")
if configured, ok := conf[id]; ok {
if whitelisted, ok := configured.(map[string]interface{}); ok {
@@ -101,12 +98,7 @@ func NewNoErrorCheck(id string, conf gosec.Config) (gosec.Rule, []ast.Node) {
}
return &noErrorCheck{
- MetaData: issue.MetaData{
- ID: id,
- Severity: issue.Low,
- Confidence: issue.High,
- What: "Errors unhandled",
- },
+ MetaData: issue.NewMetaData(id, "Errors unhandled", issue.Low, issue.High),
whitelist: whitelist,
}, []ast.Node{(*ast.AssignStmt)(nil), (*ast.ExprStmt)(nil)}
}
diff --git a/vendor/github.com/securego/gosec/v2/rules/fileperms.go b/vendor/github.com/securego/gosec/v2/rules/fileperms.go
index bf2a95953..4ce06c72d 100644
--- a/vendor/github.com/securego/gosec/v2/rules/fileperms.go
+++ b/vendor/github.com/securego/gosec/v2/rules/fileperms.go
@@ -30,11 +30,6 @@ type filePermissions struct {
calls []string
}
-// ID returns the ID of the rule.
-func (r *filePermissions) ID() string {
- return r.MetaData.ID
-}
-
func getConfiguredMode(conf map[string]interface{}, configKey string, defaultMode int64) int64 {
mode := defaultMode
if value, ok := conf[configKey]; ok {
@@ -85,15 +80,10 @@ func isOsPerm(n ast.Node) bool {
func NewWritePerms(id string, conf gosec.Config) (gosec.Rule, []ast.Node) {
mode := getConfiguredMode(conf, id, 0o600)
return &filePermissions{
- mode: mode,
- pkgs: []string{"io/ioutil", "os"},
- calls: []string{"WriteFile"},
- MetaData: issue.MetaData{
- ID: id,
- Severity: issue.Medium,
- Confidence: issue.High,
- What: fmt.Sprintf("Expect WriteFile permissions to be %#o or less", mode),
- },
+ mode: mode,
+ pkgs: []string{"io/ioutil", "os"},
+ calls: []string{"WriteFile"},
+ MetaData: issue.NewMetaData(id, fmt.Sprintf("Expect WriteFile permissions to be %#o or less", mode), issue.Medium, issue.High),
}, []ast.Node{(*ast.CallExpr)(nil)}
}
@@ -102,15 +92,10 @@ func NewWritePerms(id string, conf gosec.Config) (gosec.Rule, []ast.Node) {
func NewFilePerms(id string, conf gosec.Config) (gosec.Rule, []ast.Node) {
mode := getConfiguredMode(conf, id, 0o600)
return &filePermissions{
- mode: mode,
- pkgs: []string{"os"},
- calls: []string{"OpenFile", "Chmod"},
- MetaData: issue.MetaData{
- ID: id,
- Severity: issue.Medium,
- Confidence: issue.High,
- What: fmt.Sprintf("Expect file permissions to be %#o or less", mode),
- },
+ mode: mode,
+ pkgs: []string{"os"},
+ calls: []string{"OpenFile", "Chmod"},
+ MetaData: issue.NewMetaData(id, fmt.Sprintf("Expect file permissions to be %#o or less", mode), issue.Medium, issue.High),
}, []ast.Node{(*ast.CallExpr)(nil)}
}
@@ -119,15 +104,10 @@ func NewFilePerms(id string, conf gosec.Config) (gosec.Rule, []ast.Node) {
func NewMkdirPerms(id string, conf gosec.Config) (gosec.Rule, []ast.Node) {
mode := getConfiguredMode(conf, id, 0o750)
return &filePermissions{
- mode: mode,
- pkgs: []string{"os"},
- calls: []string{"Mkdir", "MkdirAll"},
- MetaData: issue.MetaData{
- ID: id,
- Severity: issue.Medium,
- Confidence: issue.High,
- What: fmt.Sprintf("Expect directory permissions to be %#o or less", mode),
- },
+ mode: mode,
+ pkgs: []string{"os"},
+ calls: []string{"Mkdir", "MkdirAll"},
+ MetaData: issue.NewMetaData(id, fmt.Sprintf("Expect directory permissions to be %#o or less", mode), issue.Medium, issue.High),
}, []ast.Node{(*ast.CallExpr)(nil)}
}
@@ -140,11 +120,6 @@ type osCreatePermissions struct {
const defaultOsCreateMode = 0o666
-// ID returns the ID of the rule.
-func (r *osCreatePermissions) ID() string {
- return r.MetaData.ID
-}
-
// Match checks if the rule is matched.
func (r *osCreatePermissions) Match(n ast.Node, c *gosec.Context) (*issue.Issue, error) {
for _, pkg := range r.pkgs {
@@ -165,12 +140,7 @@ func NewOsCreatePerms(id string, conf gosec.Config) (gosec.Rule, []ast.Node) {
mode: mode,
pkgs: []string{"os"},
calls: []string{"Create"},
- MetaData: issue.MetaData{
- ID: id,
- Severity: issue.Medium,
- Confidence: issue.High,
- What: fmt.Sprintf("Expect file permissions to be %#o or less but os.Create used with default permissions %#o",
- mode, defaultOsCreateMode),
- },
+ MetaData: issue.NewMetaData(id, fmt.Sprintf("Expect file permissions to be %#o or less but os.Create used with default permissions %#o",
+ mode, defaultOsCreateMode), issue.Medium, issue.High),
}, []ast.Node{(*ast.CallExpr)(nil)}
}
diff --git a/vendor/github.com/securego/gosec/v2/rules/hardcoded_credentials.go b/vendor/github.com/securego/gosec/v2/rules/hardcoded_credentials.go
index c10d18b30..b0d5fdad5 100644
--- a/vendor/github.com/securego/gosec/v2/rules/hardcoded_credentials.go
+++ b/vendor/github.com/securego/gosec/v2/rules/hardcoded_credentials.go
@@ -32,6 +32,12 @@ type secretPattern struct {
regexp *regexp.Regexp
}
+// entropyCacheKey is the cache key for entropy analysis results.
+type entropyCacheKey string
+
+// secretPatternCacheKey is the cache key for secret pattern scan results.
+type secretPatternCacheKey string
+
var secretsPatterns = [...]secretPattern{
{
name: "RSA private key",
@@ -78,49 +84,25 @@ var secretsPatterns = [...]secretPattern{
regexp: regexp.MustCompile(`ghs_[a-zA-Z0-9]{36}`),
},
{
- name: "Google API Key",
- regexp: regexp.MustCompile(`AIza[0-9A-Za-z\-_]{35}`),
- },
- {
- name: "Google Cloud Platform API Key",
+ name: "Google API Key", // Also Google Cloud Platform, Gmail, Drive, YouTube, etc.
regexp: regexp.MustCompile(`AIza[0-9A-Za-z\-_]{35}`),
},
+
{
- name: "Google Cloud Platform OAuth",
- regexp: regexp.MustCompile(`[0-9]+-[0-9A-Za-z_]{32}\.apps\.googleusercontent\.com`),
- },
- {
- name: "Google Drive API Key",
- regexp: regexp.MustCompile(`AIza[0-9A-Za-z\-_]{35}`),
- },
- {
- name: "Google Drive OAuth",
+ name: "Google Cloud Platform OAuth", // Also Gmail, Drive, YouTube, etc.
regexp: regexp.MustCompile(`[0-9]+-[0-9A-Za-z_]{32}\.apps\.googleusercontent\.com`),
},
+
{
name: "Google (GCP) Service-account",
regexp: regexp.MustCompile(`"type": "service_account"`),
},
- {
- name: "Google Gmail API Key",
- regexp: regexp.MustCompile(`AIza[0-9A-Za-z\-_]{35}`),
- },
- {
- name: "Google Gmail OAuth",
- regexp: regexp.MustCompile(`[0-9]+-[0-9A-Za-z_]{32}\.apps\.googleusercontent\.com`),
- },
+
{
name: "Google OAuth Access Token",
regexp: regexp.MustCompile(`ya29\.[0-9A-Za-z\-_]+`),
},
- {
- name: "Google YouTube API Key",
- regexp: regexp.MustCompile(`AIza[0-9A-Za-z\-_]{35}`),
- },
- {
- name: "Google YouTube OAuth",
- regexp: regexp.MustCompile(`[0-9]+-[0-9A-Za-z_]{32}\.apps\.googleusercontent\.com`),
- },
+
{
name: "Generic API Key",
regexp: regexp.MustCompile(`[aA][pP][iI]_?[kK][eE][yY].*[''|"][0-9a-zA-Z]{32,45}[''|"]`),
@@ -143,7 +125,7 @@ var secretsPatterns = [...]secretPattern{
},
{
name: "Password in URL",
- regexp: regexp.MustCompile(`[a-zA-Z]{3,10}://[^/\\s:@]{3,20}:[^/\\s:@]{3,20}@.{1,100}["'\\s]`),
+ regexp: regexp.MustCompile(`[a-zA-Z]{3,10}://[a-zA-Z0-9\.\-\_\+]{1,64}:[a-zA-Z0-9\.\-\_\!\$\%\&\*\+\=\^\(\)]{1,128}@[a-zA-Z0-9\.\-\_]+(:[0-9]+)?(/[^"'\s]*)?(["'\s]|$)`),
},
{
name: "Slack Webhook",
@@ -190,10 +172,7 @@ type credentials struct {
perCharThreshold float64
truncate int
ignoreEntropy bool
-}
-
-func (r *credentials) ID() string {
- return r.MetaData.ID
+ minEntropyLength int
}
func truncate(s string, n int) string {
@@ -204,20 +183,45 @@ func truncate(s string, n int) string {
}
func (r *credentials) isHighEntropyString(str string) bool {
+ if len(str) < r.minEntropyLength {
+ return false
+ }
s := truncate(str, r.truncate)
+ key := entropyCacheKey(s)
+ if val, ok := gosec.GlobalCache.Get(key); ok {
+ return val.(bool)
+ }
+
info := zxcvbn.PasswordStrength(s, []string{})
entropyPerChar := info.Entropy / float64(len(s))
- return (info.Entropy >= r.entropyThreshold ||
+ res := (info.Entropy >= r.entropyThreshold ||
(info.Entropy >= (r.entropyThreshold/2) &&
entropyPerChar >= r.perCharThreshold))
+ gosec.GlobalCache.Add(key, res)
+ return res
+}
+
+type secretResult struct {
+ ok bool
+ patternName string
}
func (r *credentials) isSecretPattern(str string) (bool, string) {
+ if len(str) < r.minEntropyLength {
+ return false, ""
+ }
+ key := secretPatternCacheKey(str)
+ if res, ok := gosec.GlobalCache.Get(key); ok {
+ secretRes := res.(secretResult)
+ return secretRes.ok, secretRes.patternName
+ }
for _, pattern := range secretsPatterns {
- if pattern.regexp.MatchString(str) {
+ if gosec.RegexMatchWithCache(pattern.regexp, str) {
+ gosec.GlobalCache.Add(key, secretResult{true, pattern.name})
return true, pattern.name
}
}
+ gosec.GlobalCache.Add(key, secretResult{false, ""})
return false, ""
}
@@ -229,6 +233,8 @@ func (r *credentials) Match(n ast.Node, ctx *gosec.Context) (*issue.Issue, error
return r.matchValueSpec(node, ctx)
case *ast.BinaryExpr:
return r.matchEqualityCheck(node, ctx)
+ case *ast.CompositeLit:
+ return r.matchCompositeLit(node, ctx)
}
return nil, nil
}
@@ -237,7 +243,7 @@ func (r *credentials) matchAssign(assign *ast.AssignStmt, ctx *gosec.Context) (*
for _, i := range assign.Lhs {
if ident, ok := i.(*ast.Ident); ok {
// First check LHS to find anything being assigned to variables whose name appears to be a cred
- if r.pattern.MatchString(ident.Name) {
+ if gosec.RegexMatchWithCache(r.pattern, ident.Name) {
for _, e := range assign.Rhs {
if val, err := gosec.GetString(e); err == nil {
if r.ignoreEntropy || (!r.ignoreEntropy && r.isHighEntropyString(val)) {
@@ -269,7 +275,7 @@ func (r *credentials) matchValueSpec(valueSpec *ast.ValueSpec, ctx *gosec.Contex
// Running match against the variable name(s) first. Will catch any creds whose var name matches the pattern,
// then will go back over to check the values themselves.
for index, ident := range valueSpec.Names {
- if r.pattern.MatchString(ident.Name) && valueSpec.Values != nil {
+ if gosec.RegexMatchWithCache(r.pattern, ident.Name) && valueSpec.Values != nil {
// const foo, bar = "same value"
if len(valueSpec.Values) <= index {
index = len(valueSpec.Values) - 1
@@ -303,7 +309,7 @@ func (r *credentials) matchEqualityCheck(binaryExpr *ast.BinaryExpr, ctx *gosec.
ident, _ = binaryExpr.Y.(*ast.Ident)
}
- if ident != nil && r.pattern.MatchString(ident.Name) {
+ if ident != nil && gosec.RegexMatchWithCache(r.pattern, ident.Name) {
valueNode := binaryExpr.Y
if !ok {
valueNode = binaryExpr.X
@@ -334,6 +340,44 @@ func (r *credentials) matchEqualityCheck(binaryExpr *ast.BinaryExpr, ctx *gosec.
return nil, nil
}
+func (r *credentials) matchCompositeLit(lit *ast.CompositeLit, ctx *gosec.Context) (*issue.Issue, error) {
+ for _, elt := range lit.Elts {
+ if kv, ok := elt.(*ast.KeyValueExpr); ok {
+ // Check if the key matches the credential pattern (struct field name or map string literal key)
+ matchedKey := false
+ if ident, ok := kv.Key.(*ast.Ident); ok {
+ if gosec.RegexMatchWithCache(r.pattern, ident.Name) {
+ matchedKey = true
+ }
+ }
+ if keyStr, err := gosec.GetString(kv.Key); err == nil {
+ if gosec.RegexMatchWithCache(r.pattern, keyStr) {
+ matchedKey = true
+ }
+ }
+
+ // If key matches, check value for high entropy (generic credential warning)
+ if matchedKey {
+ if val, err := gosec.GetString(kv.Value); err == nil {
+ if r.ignoreEntropy || r.isHighEntropyString(val) {
+ return ctx.NewIssue(lit, r.ID(), r.What, r.Severity, r.Confidence), nil
+ }
+ }
+ }
+
+ // Separately check value for specific secret patterns (regardless of key)
+ if val, err := gosec.GetString(kv.Value); err == nil {
+ if r.ignoreEntropy || r.isHighEntropyString(val) {
+ if ok, patternName := r.isSecretPattern(val); ok {
+ return ctx.NewIssue(lit, r.ID(), fmt.Sprintf("%s: %s", r.What, patternName), r.Severity, r.Confidence), nil
+ }
+ }
+ }
+ }
+ }
+ return nil, nil
+}
+
// NewHardcodedCredentials attempts to find high entropy string constants being
// assigned to variables that appear to be related to credentials.
func NewHardcodedCredentials(id string, conf gosec.Config) (gosec.Rule, []ast.Node) {
@@ -342,6 +386,7 @@ func NewHardcodedCredentials(id string, conf gosec.Config) (gosec.Rule, []ast.No
perCharThreshold := 3.0
ignoreEntropy := false
truncateString := 16
+ minEntropyLength := 8
if val, ok := conf[id]; ok {
conf := val.(map[string]interface{})
if configPattern, ok := conf["pattern"]; ok {
@@ -376,6 +421,13 @@ func NewHardcodedCredentials(id string, conf gosec.Config) (gosec.Rule, []ast.No
}
}
}
+ if configMinEntropyLength, ok := conf["min_entropy_length"]; ok {
+ if cfgMinEntropyLength, ok := configMinEntropyLength.(string); ok {
+ if parsedInt, err := strconv.Atoi(cfgMinEntropyLength); err == nil {
+ minEntropyLength = parsedInt
+ }
+ }
+ }
}
return &credentials{
@@ -384,11 +436,7 @@ func NewHardcodedCredentials(id string, conf gosec.Config) (gosec.Rule, []ast.No
perCharThreshold: perCharThreshold,
ignoreEntropy: ignoreEntropy,
truncate: truncateString,
- MetaData: issue.MetaData{
- ID: id,
- What: "Potential hardcoded credentials",
- Confidence: issue.Low,
- Severity: issue.High,
- },
- }, []ast.Node{(*ast.AssignStmt)(nil), (*ast.ValueSpec)(nil), (*ast.BinaryExpr)(nil)}
+ minEntropyLength: minEntropyLength,
+ MetaData: issue.NewMetaData(id, "Potential hardcoded credentials", issue.High, issue.Low),
+ }, []ast.Node{(*ast.AssignStmt)(nil), (*ast.ValueSpec)(nil), (*ast.BinaryExpr)(nil), (*ast.CompositeLit)(nil)}
}
diff --git a/vendor/github.com/securego/gosec/v2/rules/http_serve.go b/vendor/github.com/securego/gosec/v2/rules/http_serve.go
index 525ed4ebc..ecb2a1940 100644
--- a/vendor/github.com/securego/gosec/v2/rules/http_serve.go
+++ b/vendor/github.com/securego/gosec/v2/rules/http_serve.go
@@ -8,32 +8,14 @@ import (
)
type httpServeWithoutTimeouts struct {
- issue.MetaData
- pkg string
- calls []string
-}
-
-func (r *httpServeWithoutTimeouts) ID() string {
- return r.MetaData.ID
-}
-
-func (r *httpServeWithoutTimeouts) Match(n ast.Node, c *gosec.Context) (gi *issue.Issue, err error) {
- if _, matches := gosec.MatchCallByPackage(n, c, r.pkg, r.calls...); matches {
- return c.NewIssue(n, r.ID(), r.What, r.Severity, r.Confidence), nil
- }
- return nil, nil
+ callListRule
}
// NewHTTPServeWithoutTimeouts detects use of net/http serve functions that have no support for setting timeouts.
func NewHTTPServeWithoutTimeouts(id string, _ gosec.Config) (gosec.Rule, []ast.Node) {
- return &httpServeWithoutTimeouts{
- pkg: "net/http",
- calls: []string{"ListenAndServe", "ListenAndServeTLS", "Serve", "ServeTLS"},
- MetaData: issue.MetaData{
- ID: id,
- What: "Use of net/http serve function that has no support for setting timeouts",
- Severity: issue.Medium,
- Confidence: issue.High,
- },
- }, []ast.Node{(*ast.CallExpr)(nil)}
+ rule := &httpServeWithoutTimeouts{
+ callListRule: newCallListRule(id, "Use of net/http serve function that has no support for setting timeouts", issue.Medium, issue.High),
+ }
+ rule.AddAll("net/http", "ListenAndServe", "ListenAndServeTLS", "Serve", "ServeTLS")
+ return rule, []ast.Node{(*ast.CallExpr)(nil)}
}
diff --git a/vendor/github.com/securego/gosec/v2/rules/implicit_aliasing.go b/vendor/github.com/securego/gosec/v2/rules/implicit_aliasing.go
index ee2358c76..349e4d0e9 100644
--- a/vendor/github.com/securego/gosec/v2/rules/implicit_aliasing.go
+++ b/vendor/github.com/securego/gosec/v2/rules/implicit_aliasing.go
@@ -11,15 +11,11 @@ import (
type implicitAliasing struct {
issue.MetaData
- aliases map[*ast.Object]struct{}
+ aliases map[*types.Var]struct{}
rightBrace token.Pos
acceptableAlias []*ast.UnaryExpr
}
-func (r *implicitAliasing) ID() string {
- return r.MetaData.ID
-}
-
func containsUnary(exprs []*ast.UnaryExpr, expr *ast.UnaryExpr) bool {
for _, e := range exprs {
if e == expr {
@@ -47,68 +43,64 @@ func doGetIdentExpr(expr ast.Expr, hasSelector bool) (*ast.Ident, bool) {
}
func (r *implicitAliasing) Match(n ast.Node, c *gosec.Context) (*issue.Issue, error) {
- // This rule does not apply for Go 1.22, see https://go.dev/doc/go1.22#language.
+ // This rule does not apply for Go 1.22+, where range loop variables have per-iteration scope.
+ // See https://go.dev/doc/go1.22#language.
major, minor, _ := gosec.GoVersion()
- if major >= 1 && minor >= 22 {
+ if major == 1 && minor >= 22 || major > 1 {
return nil, nil
}
switch node := n.(type) {
case *ast.RangeStmt:
- // When presented with a range statement, get the underlying Object bound to
- // by assignment and add it to our set (r.aliases) of objects to check for.
- if key, ok := node.Value.(*ast.Ident); ok {
- if key.Obj != nil {
- if assignment, ok := key.Obj.Decl.(*ast.AssignStmt); ok {
- if len(assignment.Lhs) < 2 {
- return nil, nil
- }
-
- if object, ok := assignment.Lhs[1].(*ast.Ident); ok {
- r.aliases[object.Obj] = struct{}{}
-
- if r.rightBrace < node.Body.Rbrace {
- r.rightBrace = node.Body.Rbrace
- }
+ // Add the range value variable (if it's an identifier) to the set of aliased loop vars.
+ if valueIdent, ok := node.Value.(*ast.Ident); ok {
+ if obj := c.Info.ObjectOf(valueIdent); obj != nil {
+ if v, ok := obj.(*types.Var); ok {
+ r.aliases[v] = struct{}{}
+ if r.rightBrace < node.Body.Rbrace {
+ r.rightBrace = node.Body.Rbrace
}
}
}
}
case *ast.UnaryExpr:
- // If this unary expression is outside of the last range statement we were looking at
- // then clear the list of objects we're concerned about because they're no longer in
- // scope
+ // Clear aliases if we're outside the last tracked range loop body.
if node.Pos() > r.rightBrace {
- r.aliases = make(map[*ast.Object]struct{})
+ r.aliases = make(map[*types.Var]struct{})
r.acceptableAlias = make([]*ast.UnaryExpr, 0)
}
- // Short circuit logic to skip checking aliases if we have nothing to check against.
+ // Short-circuit if no aliases to check.
if len(r.aliases) == 0 {
return nil, nil
}
- // If this unary is at the top level of a return statement then it is okay--
- // see *ast.ReturnStmt comment below.
+ // Acceptable if this &expr is directly returned (top-level in return stmt).
if containsUnary(r.acceptableAlias, node) {
return nil, nil
}
- // If we find a unary op of & (reference) of an object within r.aliases, complain.
- if identExpr, hasSelector := getIdentExpr(node); identExpr != nil && node.Op.String() == "&" {
- if _, contains := r.aliases[identExpr.Obj]; contains {
- _, isPointer := c.Info.TypeOf(identExpr).(*types.Pointer)
-
- if !hasSelector || !isPointer {
- return c.NewIssue(n, r.ID(), r.What, r.Severity, r.Confidence), nil
+ // Check for & on a tracked loop variable.
+ if node.Op == token.AND {
+ if identExpr, hasSelector := getIdentExpr(node.X); identExpr != nil {
+ if obj := c.Info.ObjectOf(identExpr); obj != nil {
+ if v, ok := obj.(*types.Var); ok {
+ if _, aliased := r.aliases[v]; aliased {
+ _, isPointer := c.Info.TypeOf(identExpr).(*types.Pointer)
+ if !hasSelector || !isPointer {
+ return c.NewIssue(n, r.ID(), r.What, r.Severity, r.Confidence), nil
+ }
+ }
+ }
}
}
}
+
case *ast.ReturnStmt:
- // Returning a rangeStmt yielded value is acceptable since only one value will be returned
- for _, item := range node.Results {
- if unary, ok := item.(*ast.UnaryExpr); ok && unary.Op.String() == "&" {
+ // Mark direct &loopVar in return statements as acceptable (only one iteration's value returned).
+ for _, res := range node.Results {
+ if unary, ok := res.(*ast.UnaryExpr); ok && unary.Op == token.AND {
r.acceptableAlias = append(r.acceptableAlias, unary)
}
}
@@ -117,18 +109,13 @@ func (r *implicitAliasing) Match(n ast.Node, c *gosec.Context) (*issue.Issue, er
return nil, nil
}
-// NewImplicitAliasing detects implicit memory aliasing of type: for blah := SomeCall() {... SomeOtherCall(&blah) ...}
+// NewImplicitAliasing detects implicit memory aliasing in range loops (pre-Go 1.22).
func NewImplicitAliasing(id string, _ gosec.Config) (gosec.Rule, []ast.Node) {
return &implicitAliasing{
- aliases: make(map[*ast.Object]struct{}),
+ aliases: make(map[*types.Var]struct{}),
rightBrace: token.NoPos,
acceptableAlias: make([]*ast.UnaryExpr, 0),
- MetaData: issue.MetaData{
- ID: id,
- Severity: issue.Medium,
- Confidence: issue.Medium,
- What: "Implicit memory aliasing in for loop.",
- },
+ MetaData: issue.NewMetaData(id, "Implicit memory aliasing in for loop.", issue.Medium, issue.Medium),
}, []ast.Node{(*ast.RangeStmt)(nil), (*ast.UnaryExpr)(nil), (*ast.ReturnStmt)(nil)}
}
diff --git a/vendor/github.com/securego/gosec/v2/rules/integer_overflow.go b/vendor/github.com/securego/gosec/v2/rules/integer_overflow.go
index 1d5790664..b82b35638 100644
--- a/vendor/github.com/securego/gosec/v2/rules/integer_overflow.go
+++ b/vendor/github.com/securego/gosec/v2/rules/integer_overflow.go
@@ -17,54 +17,56 @@ package rules
import (
"fmt"
"go/ast"
+ "go/types"
"github.com/securego/gosec/v2"
"github.com/securego/gosec/v2/issue"
)
type integerOverflowCheck struct {
- issue.MetaData
- calls gosec.CallList
-}
-
-func (i *integerOverflowCheck) ID() string {
- return i.MetaData.ID
+ callListRule
}
func (i *integerOverflowCheck) Match(node ast.Node, ctx *gosec.Context) (*issue.Issue, error) {
- var atoiVarObj map[*ast.Object]ast.Node
+ var atoiVars map[*types.Var]struct{}
- // To check multiple lines, ctx.PassedValues is used to store temporary data.
+ // Stateful tracking via ctx.PassedValues
if _, ok := ctx.PassedValues[i.ID()]; !ok {
- atoiVarObj = make(map[*ast.Object]ast.Node)
- ctx.PassedValues[i.ID()] = atoiVarObj
- } else if pv, ok := ctx.PassedValues[i.ID()].(map[*ast.Object]ast.Node); ok {
- atoiVarObj = pv
+ atoiVars = make(map[*types.Var]struct{})
+ ctx.PassedValues[i.ID()] = atoiVars
+ } else if pv, ok := ctx.PassedValues[i.ID()].(map[*types.Var]struct{}); ok {
+ atoiVars = pv
} else {
- return nil, fmt.Errorf("PassedValues[%s] of Context is not map[*ast.Object]ast.Node, but %T", i.ID(), ctx.PassedValues[i.ID()])
+ return nil, fmt.Errorf("PassedValues[%s] of Context is not map[*types.Var]struct{}, but %T", i.ID(), ctx.PassedValues[i.ID()])
}
- // strconv.Atoi is a common function.
- // To reduce false positives, This rule detects code which is converted to int32/int16 only.
switch n := node.(type) {
case *ast.AssignStmt:
for _, expr := range n.Rhs {
if callExpr, ok := expr.(*ast.CallExpr); ok && i.calls.ContainsPkgCallExpr(callExpr, ctx, false) != nil {
- if idt, ok := n.Lhs[0].(*ast.Ident); ok && idt.Name != "_" {
- // Example:
- // v, _ := strconv.Atoi("1111")
- // Add v's Obj to atoiVarObj map
- atoiVarObj[idt.Obj] = n
+ if len(n.Lhs) > 0 {
+ if idt, ok := n.Lhs[0].(*ast.Ident); ok && idt.Name != "_" {
+ if obj := ctx.Info.ObjectOf(idt); obj != nil {
+ if v, ok := obj.(*types.Var); ok {
+ atoiVars[v] = struct{}{}
+ }
+ }
+ }
}
}
}
case *ast.CallExpr:
if fun, ok := n.Fun.(*ast.Ident); ok {
if fun.Name == "int32" || fun.Name == "int16" {
- if idt, ok := n.Args[0].(*ast.Ident); ok {
- if _, ok := atoiVarObj[idt.Obj]; ok {
- // Detect int32(v) and int16(v)
- return ctx.NewIssue(n, i.ID(), i.What, i.Severity, i.Confidence), nil
+ if len(n.Args) > 0 {
+ if idt, ok := n.Args[0].(*ast.Ident); ok {
+ if obj := ctx.Info.ObjectOf(idt); obj != nil {
+ if v, ok := obj.(*types.Var); ok {
+ if _, tracked := atoiVars[v]; tracked {
+ return ctx.NewIssue(n, i.ID(), i.What, i.Severity, i.Confidence), nil
+ }
+ }
+ }
}
}
}
@@ -74,17 +76,11 @@ func (i *integerOverflowCheck) Match(node ast.Node, ctx *gosec.Context) (*issue.
return nil, nil
}
-// NewIntegerOverflowCheck detects if there is potential Integer OverFlow
+// NewIntegerOverflowCheck detects potential integer overflow from strconv.Atoi conversion to int16/int32
func NewIntegerOverflowCheck(id string, _ gosec.Config) (gosec.Rule, []ast.Node) {
- calls := gosec.NewCallList()
- calls.Add("strconv", "Atoi")
- return &integerOverflowCheck{
- MetaData: issue.MetaData{
- ID: id,
- Severity: issue.High,
- Confidence: issue.Medium,
- What: "Potential Integer overflow made by strconv.Atoi result conversion to int16/32",
- },
- calls: calls,
- }, []ast.Node{(*ast.FuncDecl)(nil), (*ast.AssignStmt)(nil), (*ast.CallExpr)(nil)}
+ rule := &integerOverflowCheck{
+ callListRule: newCallListRule(id, "Potential Integer overflow made by strconv.Atoi result conversion to int16/32", issue.High, issue.Medium),
+ }
+ rule.Add("strconv", "Atoi")
+ return rule, []ast.Node{(*ast.AssignStmt)(nil), (*ast.CallExpr)(nil)}
}
diff --git a/vendor/github.com/securego/gosec/v2/rules/pprof.go b/vendor/github.com/securego/gosec/v2/rules/pprof.go
index 68498dd5e..a48198d7c 100644
--- a/vendor/github.com/securego/gosec/v2/rules/pprof.go
+++ b/vendor/github.com/securego/gosec/v2/rules/pprof.go
@@ -13,11 +13,6 @@ type pprofCheck struct {
importName string
}
-// ID returns the ID of the check
-func (p *pprofCheck) ID() string {
- return p.MetaData.ID
-}
-
// Match checks for pprof imports
func (p *pprofCheck) Match(n ast.Node, c *gosec.Context) (*issue.Issue, error) {
if node, ok := n.(*ast.ImportSpec); ok {
@@ -31,12 +26,7 @@ func (p *pprofCheck) Match(n ast.Node, c *gosec.Context) (*issue.Issue, error) {
// NewPprofCheck detects when the profiling endpoint is automatically exposed
func NewPprofCheck(id string, _ gosec.Config) (gosec.Rule, []ast.Node) {
return &pprofCheck{
- MetaData: issue.MetaData{
- ID: id,
- Severity: issue.High,
- Confidence: issue.High,
- What: "Profiling endpoint is automatically exposed on /debug/pprof",
- },
+ MetaData: issue.NewMetaData(id, "Profiling endpoint is automatically exposed on /debug/pprof", issue.High, issue.High),
importPath: "net/http/pprof",
importName: "_",
}, []ast.Node{(*ast.ImportSpec)(nil)}
diff --git a/vendor/github.com/securego/gosec/v2/rules/rand.go b/vendor/github.com/securego/gosec/v2/rules/rand.go
index fe34ca9c3..a1d3508a0 100644
--- a/vendor/github.com/securego/gosec/v2/rules/rand.go
+++ b/vendor/github.com/securego/gosec/v2/rules/rand.go
@@ -22,42 +22,18 @@ import (
)
type weakRand struct {
- issue.MetaData
- blocklist map[string][]string
-}
-
-func (w *weakRand) ID() string {
- return w.MetaData.ID
-}
-
-func (w *weakRand) Match(n ast.Node, c *gosec.Context) (*issue.Issue, error) {
- for pkg, funcs := range w.blocklist {
- if _, matched := gosec.MatchCallByPackage(n, c, pkg, funcs...); matched {
- return c.NewIssue(n, w.ID(), w.What, w.Severity, w.Confidence), nil
- }
- }
-
- return nil, nil
+ callListRule
}
// NewWeakRandCheck detects the use of random number generator that isn't cryptographically secure
func NewWeakRandCheck(id string, _ gosec.Config) (gosec.Rule, []ast.Node) {
- calls := make(map[string][]string)
- calls["math/rand"] = []string{
- "New", "Read", "Float32", "Float64", "Int", "Int31", "Int31n",
- "Int63", "Int63n", "Intn", "NormFloat64", "Uint32", "Uint64",
- }
- calls["math/rand/v2"] = []string{
- "New", "Float32", "Float64", "Int", "Int32", "Int32N",
- "Int64", "Int64N", "IntN", "N", "NormFloat64", "Uint32", "Uint32N", "Uint64", "Uint64N", "UintN",
- }
- return &weakRand{
- blocklist: calls,
- MetaData: issue.MetaData{
- ID: id,
- Severity: issue.High,
- Confidence: issue.Medium,
- What: "Use of weak random number generator (math/rand or math/rand/v2 instead of crypto/rand)",
- },
- }, []ast.Node{(*ast.CallExpr)(nil)}
+ rule := &weakRand{newCallListRule(id,
+ "Use of weak random number generator (math/rand or math/rand/v2 instead of crypto/rand)",
+ issue.High, issue.Medium)}
+ rule.AddAll("math/rand", "New", "Read", "Float32", "Float64", "Int", "Int31", "Int31n",
+ "Int63", "Int63n", "Intn", "NormFloat64", "Uint32", "Uint64")
+ rule.AddAll("math/rand/v2", "New", "Float32", "Float64", "Int", "Int32", "Int32N",
+ "Int64", "Int64N", "IntN", "N", "NormFloat64", "Uint32", "Uint32N", "Uint64", "Uint64N", "UintN")
+
+ return rule, []ast.Node{(*ast.CallExpr)(nil)}
}
diff --git a/vendor/github.com/securego/gosec/v2/rules/readfile.go b/vendor/github.com/securego/gosec/v2/rules/readfile.go
index aa0fbb51c..d1bb47637 100644
--- a/vendor/github.com/securego/gosec/v2/rules/readfile.go
+++ b/vendor/github.com/securego/gosec/v2/rules/readfile.go
@@ -23,38 +23,31 @@ import (
)
type readfile struct {
- issue.MetaData
- gosec.CallList
+ callListRule
pathJoin gosec.CallList
clean gosec.CallList
- // cleanedVar maps the declaration node of an identifier to the Clean() call node
- cleanedVar map[any]ast.Node
- // joinedVar maps the declaration node of an identifier to the Join() call node
- joinedVar map[any]ast.Node
-}
-// ID returns the identifier for this rule
-func (r *readfile) ID() string {
- return r.MetaData.ID
+ // cleanedVar maps the defining *types.Var (result of Clean) to the Clean call node
+ cleanedVar map[*types.Var]ast.Node
+ // joinedVar maps the defining *types.Var (result of Join) to the Join call node
+ joinedVar map[*types.Var]ast.Node
}
-// isJoinFunc checks if there is a filepath.Join or other join function
+// isJoinFunc checks if the call is a filepath.Join with at least one non-constant argument
func (r *readfile) isJoinFunc(n ast.Node, c *gosec.Context) bool {
if call := r.pathJoin.ContainsPkgCallExpr(n, c, false); call != nil {
for _, arg := range call.Args {
- // edge case: check if one of the args is a BinaryExpr
if binExp, ok := arg.(*ast.BinaryExpr); ok {
- // iterate and resolve all found identities from the BinaryExpr
if _, ok := gosec.FindVarIdentities(binExp, c); ok {
return true
}
}
- // try and resolve identity
if ident, ok := arg.(*ast.Ident); ok {
- obj := c.Info.ObjectOf(ident)
- if _, ok := obj.(*types.Var); ok && !gosec.TryResolve(ident, c) {
- return true
+ if obj := c.Info.ObjectOf(ident); obj != nil {
+ if _, ok := obj.(*types.Var); ok && !gosec.TryResolve(ident, c) {
+ return true
+ }
}
}
}
@@ -62,147 +55,118 @@ func (r *readfile) isJoinFunc(n ast.Node, c *gosec.Context) bool {
return false
}
-// isFilepathClean checks if there is a filepath.Clean for given variable
-func (r *readfile) isFilepathClean(n *ast.Ident, c *gosec.Context) bool {
- // quick lookup: was this var's declaration recorded as a Clean() call?
- if _, ok := r.cleanedVar[n.Obj.Decl]; ok {
- return true
- }
- if n.Obj.Kind != ast.Var {
- return false
- }
- if node, ok := n.Obj.Decl.(*ast.AssignStmt); ok {
- if call, ok := node.Rhs[0].(*ast.CallExpr); ok {
- if clean := r.clean.ContainsPkgCallExpr(call, c, false); clean != nil {
- return true
- }
- }
- }
- return false
+// isFilepathClean checks if the variable is the result of a filepath.Clean (or similar) call
+func (r *readfile) isFilepathClean(v *types.Var, _ *gosec.Context) bool {
+ _, ok := r.cleanedVar[v]
+ return ok
}
-// trackFilepathClean tracks back the declaration of variable from filepath.Clean argument
-func (r *readfile) trackFilepathClean(n ast.Node) {
- if clean, ok := n.(*ast.CallExpr); ok && len(clean.Args) > 0 {
- if ident, ok := clean.Args[0].(*ast.Ident); ok {
- // ident.Obj may be nil if the referenced declaration is in another file. It also may be incorrect.
- // if it is nil, do not follow it.
- if ident.Obj != nil {
- r.cleanedVar[ident.Obj.Decl] = n
+// trackCleanAssign records a variable defined as the result of a Clean() call
+func (r *readfile) trackCleanAssign(assign *ast.AssignStmt, c *gosec.Context) {
+ if len(assign.Rhs) == 0 {
+ return
+ }
+ if cleanCall, ok := assign.Rhs[0].(*ast.CallExpr); ok {
+ if r.clean.ContainsPkgCallExpr(cleanCall, c, false) != nil {
+ if len(assign.Lhs) > 0 {
+ if ident, ok := assign.Lhs[0].(*ast.Ident); ok {
+ if obj := c.Info.ObjectOf(ident); obj != nil {
+ if v, ok := obj.(*types.Var); ok {
+ r.cleanedVar[v] = cleanCall
+ }
+ }
+ }
}
}
}
}
-// trackJoinAssignStmt tracks assignments where RHS is a Join(...) call and LHS is an identifier
-func (r *readfile) trackJoinAssignStmt(node *ast.AssignStmt, c *gosec.Context) {
- if len(node.Rhs) == 0 {
+// trackJoinAssignStmt records a variable defined from a Join() call
+func (r *readfile) trackJoinAssignStmt(assign *ast.AssignStmt, c *gosec.Context) {
+ if len(assign.Rhs) == 0 {
return
}
- if call, ok := node.Rhs[0].(*ast.CallExpr); ok {
+ if call, ok := assign.Rhs[0].(*ast.CallExpr); ok {
if r.pathJoin.ContainsPkgCallExpr(call, c, false) != nil {
- // LHS must be an identifier (simple case)
- if len(node.Lhs) > 0 {
- if ident, ok := node.Lhs[0].(*ast.Ident); ok && ident.Obj != nil {
- r.joinedVar[ident.Obj.Decl] = call
+ if len(assign.Lhs) > 0 {
+ if ident, ok := assign.Lhs[0].(*ast.Ident); ok {
+ if obj := c.Info.ObjectOf(ident); obj != nil {
+ if v, ok := obj.(*types.Var); ok {
+ r.joinedVar[v] = call
+ }
+ }
}
}
}
}
}
-// osRootSuggestion returns an Autofix suggesting the use of os.Root where supported
-// to constrain file access under a fixed directory and mitigate traversal risks.
+// osRootSuggestion returns an Autofix suggestion for os.Root (Go 1.24+)
func (r *readfile) osRootSuggestion() string {
major, minor, _ := gosec.GoVersion()
- if major == 1 && minor >= 24 {
+ if major == 1 && minor >= 24 || major > 1 {
return "Consider using os.Root to scope file access under a fixed root (Go >=1.24). Prefer root.Open/root.Stat over os.Open/os.Stat to prevent directory traversal."
}
return ""
}
-// isSafeJoin checks if path is baseDir + filepath.Clean(fn) joined.
-// improvements over earlier naive version:
-// - allow baseDir as a BasicLit or as an identifier that resolves to a string constant
-// - accept Clean(...) being either a CallExpr or an identifier previously recorded as Clean result
+// isSafeJoin checks for safe Join(baseConstant, cleanedOrConstant)
func (r *readfile) isSafeJoin(call *ast.CallExpr, c *gosec.Context) bool {
- join := r.pathJoin.ContainsPkgCallExpr(call, c, false)
- if join == nil {
+ if r.pathJoin.ContainsPkgCallExpr(call, c, false) == nil {
return false
}
- // We expect join.Args to include a baseDir-like arg and a cleaned path arg.
- var foundBaseDir bool
- var foundCleanArg bool
+ var hasBaseDir bool
+ var hasCleanArg bool
- for _, arg := range join.Args {
+ for _, arg := range call.Args {
switch a := arg.(type) {
case *ast.BasicLit:
- // literal string or similar — treat as possible baseDir
- foundBaseDir = true
+ hasBaseDir = true
case *ast.Ident:
- // If ident is resolvable to a constant string (TryResolve true), treat as baseDir.
- // Or if ident refers to a variable that was itself assigned from a constant BasicLit,
- // it's considered safe as baseDir.
if gosec.TryResolve(a, c) {
- foundBaseDir = true
- } else {
- // It might be a cleaned variable: e.g. cleanPath := filepath.Clean(fn)
- if r.isFilepathClean(a, c) {
- foundCleanArg = true
+ hasBaseDir = true
+ } else if obj := c.Info.ObjectOf(a); obj != nil {
+ if v, ok := obj.(*types.Var); ok && r.isFilepathClean(v, c) {
+ hasCleanArg = true
}
}
case *ast.CallExpr:
- // If an argument is a Clean() call directly, mark clean arg found.
if r.clean.ContainsPkgCallExpr(a, c, false) != nil {
- foundCleanArg = true
+ hasCleanArg = true
}
- default:
- // ignore other types
}
}
-
- return foundBaseDir && foundCleanArg
+ return hasBaseDir && hasCleanArg
}
func (r *readfile) Match(n ast.Node, c *gosec.Context) (*issue.Issue, error) {
- // Track filepath.Clean usages so identifiers assigned from Clean() are known.
- if node := r.clean.ContainsPkgCallExpr(n, c, false); node != nil {
- r.trackFilepathClean(n)
- return nil, nil
- }
-
- // Track Join assignments if we see an AssignStmt whose RHS is a Join call.
+ // Track assignments from Clean() or Join()
if assign, ok := n.(*ast.AssignStmt); ok {
- // track join result assigned to a variable, e.g., fullPath := filepath.Join(baseDir, cleanPath)
+ r.trackCleanAssign(assign, c)
r.trackJoinAssignStmt(assign, c)
- // also track Clean assignment if present on RHS
- if len(assign.Rhs) > 0 {
- if call, ok := assign.Rhs[0].(*ast.CallExpr); ok {
- if r.clean.ContainsPkgCallExpr(call, c, false) != nil {
- r.trackFilepathClean(call)
- }
- }
- }
- // continue, don't return here — other checks may apply
}
- // Now check for file-reading calls (os.Open, os.OpenFile, ioutil.ReadFile etc.)
- if node := r.ContainsPkgCallExpr(n, c, false); node != nil {
- if len(node.Args) == 0 {
+ // Main check: file reading calls
+ if readCall := r.calls.ContainsPkgCallExpr(n, c, false); readCall != nil {
+ if len(readCall.Args) == 0 {
return nil, nil
}
- arg := node.Args[0]
+ pathArg := readCall.Args[0]
+
+ // Direct Clean() call as argument → safe
+ if cleanCall, ok := pathArg.(*ast.CallExpr); ok {
+ if r.clean.ContainsPkgCallExpr(cleanCall, c, false) != nil {
+ return nil, nil
+ }
+ }
- // If argument is a call expression, check for Join/Clean patterns.
- if callExpr, ok := arg.(*ast.CallExpr); ok {
- // If this call matches a safe Join(baseDir, Clean(...)) pattern, treat as safe.
- if r.isSafeJoin(callExpr, c) {
- // safe pattern detected; do not raise an issue
+ // Direct Join() call as argument
+ if joinCall, ok := pathArg.(*ast.CallExpr); ok {
+ if r.isSafeJoin(joinCall, c) {
return nil, nil
}
- // If the argument is a Join call but not safe per above, flag it (as before)
- if r.isJoinFunc(callExpr, c) {
+ if r.isJoinFunc(joinCall, c) {
iss := c.NewIssue(n, r.ID(), r.What, r.Severity, r.Confidence)
if s := r.osRootSuggestion(); s != "" {
iss.Autofix = s
@@ -211,20 +175,17 @@ func (r *readfile) Match(n ast.Node, c *gosec.Context) (*issue.Issue, error) {
}
}
- // If arg is an identifier that was assigned from a Join(...) call, check that recorded Join call.
- if ident, ok := arg.(*ast.Ident); ok {
- if ident.Obj != nil {
- if joinCall, ok := r.joinedVar[ident.Obj.Decl]; ok {
- // If the identifier itself was later cleaned, treat as safe regardless of original Join args
- if r.isFilepathClean(ident, c) {
- return nil, nil
- }
- // joinCall is a *ast.CallExpr; check if that join is a safe join
- if jc, ok := joinCall.(*ast.CallExpr); ok {
- if r.isSafeJoin(jc, c) {
+ // Variable assigned from Join()
+ if ident, ok := pathArg.(*ast.Ident); ok {
+ if obj := c.Info.ObjectOf(ident); obj != nil {
+ if v, ok := obj.(*types.Var); ok {
+ if joinCall, ok := r.joinedVar[v]; ok {
+ if r.isFilepathClean(v, c) {
+ return nil, nil
+ }
+ if jc, ok := joinCall.(*ast.CallExpr); ok && r.isSafeJoin(jc, c) {
return nil, nil
}
- // join exists but is not safe: flag it
iss := c.NewIssue(n, r.ID(), r.What, r.Severity, r.Confidence)
if s := r.osRootSuggestion(); s != "" {
iss.Autofix = s
@@ -235,9 +196,8 @@ func (r *readfile) Match(n ast.Node, c *gosec.Context) (*issue.Issue, error) {
}
}
- // handles binary string concatenation eg. ioutil.Readfile("/tmp/" + file + "/blob")
- if binExp, ok := arg.(*ast.BinaryExpr); ok {
- // resolve all found identities from the BinaryExpr
+ // Binary concatenation
+ if binExp, ok := pathArg.(*ast.BinaryExpr); ok {
if _, ok := gosec.FindVarIdentities(binExp, c); ok {
iss := c.NewIssue(n, r.ID(), r.What, r.Severity, r.Confidence)
if s := r.osRootSuggestion(); s != "" {
@@ -247,37 +207,33 @@ func (r *readfile) Match(n ast.Node, c *gosec.Context) (*issue.Issue, error) {
}
}
- // if it's a plain identifier, and not resolved and not cleaned, flag it
- if ident, ok := arg.(*ast.Ident); ok {
- obj := c.Info.ObjectOf(ident)
- if _, ok := obj.(*types.Var); ok &&
- !gosec.TryResolve(ident, c) &&
- !r.isFilepathClean(ident, c) {
- iss := c.NewIssue(n, r.ID(), r.What, r.Severity, r.Confidence)
- if s := r.osRootSuggestion(); s != "" {
- iss.Autofix = s
+ // Plain variable — tainted unless constant or cleaned
+ if ident, ok := pathArg.(*ast.Ident); ok {
+ if obj := c.Info.ObjectOf(ident); obj != nil {
+ if v, ok := obj.(*types.Var); ok {
+ if gosec.TryResolve(ident, c) || r.isFilepathClean(v, c) {
+ return nil, nil
+ }
+ iss := c.NewIssue(n, r.ID(), r.What, r.Severity, r.Confidence)
+ if s := r.osRootSuggestion(); s != "" {
+ iss.Autofix = s
+ }
+ return iss, nil
}
- return iss, nil
}
}
}
return nil, nil
}
-// NewReadFile detects cases where we read files
+// NewReadFile detects potential file inclusion via variable in file read operations
func NewReadFile(id string, _ gosec.Config) (gosec.Rule, []ast.Node) {
rule := &readfile{
- pathJoin: gosec.NewCallList(),
- clean: gosec.NewCallList(),
- CallList: gosec.NewCallList(),
- MetaData: issue.MetaData{
- ID: id,
- What: "Potential file inclusion via variable",
- Severity: issue.Medium,
- Confidence: issue.High,
- },
- cleanedVar: map[any]ast.Node{},
- joinedVar: map[any]ast.Node{},
+ callListRule: newCallListRule(id, "Potential file inclusion via variable", issue.Medium, issue.High),
+ pathJoin: gosec.NewCallList(),
+ clean: gosec.NewCallList(),
+ cleanedVar: make(map[*types.Var]ast.Node),
+ joinedVar: make(map[*types.Var]ast.Node),
}
rule.pathJoin.Add("path/filepath", "Join")
rule.pathJoin.Add("path", "Join")
@@ -285,9 +241,6 @@ func NewReadFile(id string, _ gosec.Config) (gosec.Rule, []ast.Node) {
rule.clean.Add("path/filepath", "Rel")
rule.clean.Add("path/filepath", "EvalSymlinks")
rule.Add("io/ioutil", "ReadFile")
- rule.Add("os", "ReadFile")
- rule.Add("os", "Open")
- rule.Add("os", "OpenFile")
- rule.Add("os", "Create")
+ rule.AddAll("os", "ReadFile", "Open", "OpenFile", "Create")
return rule, []ast.Node{(*ast.CallExpr)(nil), (*ast.AssignStmt)(nil)}
}
diff --git a/vendor/github.com/securego/gosec/v2/rules/rsa.go b/vendor/github.com/securego/gosec/v2/rules/rsa.go
index 331e7fc80..ca4f138f6 100644
--- a/vendor/github.com/securego/gosec/v2/rules/rsa.go
+++ b/vendor/github.com/securego/gosec/v2/rules/rsa.go
@@ -23,15 +23,11 @@ import (
)
type weakKeyStrength struct {
- issue.MetaData
- calls gosec.CallList
- bits int
-}
-
-func (w *weakKeyStrength) ID() string {
- return w.MetaData.ID
+ callListRule
+ bits int
}
+// Match overrides the base to check the bits argument of rsa.GenerateKey
func (w *weakKeyStrength) Match(n ast.Node, c *gosec.Context) (*issue.Issue, error) {
if callExpr := w.calls.ContainsPkgCallExpr(n, c, false); callExpr != nil {
if bits, err := gosec.GetInt(callExpr.Args[1]); err == nil && bits < (int64)(w.bits) {
@@ -43,17 +39,11 @@ func (w *weakKeyStrength) Match(n ast.Node, c *gosec.Context) (*issue.Issue, err
// NewWeakKeyStrength builds a rule that detects RSA keys < 2048 bits
func NewWeakKeyStrength(id string, _ gosec.Config) (gosec.Rule, []ast.Node) {
- calls := gosec.NewCallList()
- calls.Add("crypto/rsa", "GenerateKey")
bits := 2048
- return &weakKeyStrength{
- calls: calls,
- bits: bits,
- MetaData: issue.MetaData{
- ID: id,
- Severity: issue.Medium,
- Confidence: issue.High,
- What: fmt.Sprintf("RSA keys should be at least %d bits", bits),
- },
- }, []ast.Node{(*ast.CallExpr)(nil)}
+ rule := &weakKeyStrength{
+ callListRule: newCallListRule(id, fmt.Sprintf("RSA keys should be at least %d bits", bits), issue.Medium, issue.High),
+ bits: bits,
+ }
+ rule.Add("crypto/rsa", "GenerateKey")
+ return rule, []ast.Node{(*ast.CallExpr)(nil)}
}
diff --git a/vendor/github.com/securego/gosec/v2/rules/rulelist.go b/vendor/github.com/securego/gosec/v2/rules/rulelist.go
index bd8dbbb7d..431ed0348 100644
--- a/vendor/github.com/securego/gosec/v2/rules/rulelist.go
+++ b/vendor/github.com/securego/gosec/v2/rules/rulelist.go
@@ -77,6 +77,7 @@ func Generate(trackSuppressions bool, filters ...RuleFilter) RuleList {
{"G112", "Detect ReadHeaderTimeout not configured as a potential risk", NewSlowloris},
{"G114", "Use of net/http serve function that has no support for setting timeouts", NewHTTPServeWithoutTimeouts},
{"G116", "Detect Trojan Source attacks using bidirectional Unicode characters", NewTrojanSource},
+ {"G117", "Potential exposure of secrets via JSON/YAML/XML/TOML marshaling", NewSecretSerialization},
// injection
{"G201", "SQL query construction using format string", NewSQLStrFormat},
diff --git a/vendor/github.com/securego/gosec/v2/rules/secret_serialization.go b/vendor/github.com/securego/gosec/v2/rules/secret_serialization.go
new file mode 100644
index 000000000..6389309cf
--- /dev/null
+++ b/vendor/github.com/securego/gosec/v2/rules/secret_serialization.go
@@ -0,0 +1,588 @@
+package rules
+
+import (
+ "fmt"
+ "go/ast"
+ "go/types"
+ "reflect"
+ "regexp"
+ "strconv"
+ "strings"
+ "sync"
+
+ "github.com/securego/gosec/v2"
+ "github.com/securego/gosec/v2/issue"
+)
+
+type secretSerialization struct {
+ issue.MetaData
+ pattern *regexp.Regexp
+ cache sync.Map
+}
+
+type formatSpec struct {
+ name string
+ tagKey string
+ marshalerMethod string // e.g. "MarshalJSON"; empty if no standard interface exists
+ functionSinks []functionSink
+ methodSinks []methodSink
+}
+
+type functionSink struct {
+ pkgPath string
+ names []string
+}
+
+type methodSink struct {
+ pkgPath string
+ typeName string
+ method string
+}
+
+type typeAnalysisCacheKey struct {
+ typ types.Type
+ tagKey string
+}
+
+type sensitiveFieldMatch struct {
+ fieldName string
+ serializedKey string
+ found bool
+}
+
+var g117Formats = []formatSpec{
+ {
+ name: "JSON",
+ tagKey: "json",
+ marshalerMethod: "MarshalJSON",
+ functionSinks: []functionSink{
+ {pkgPath: "encoding/json", names: []string{"Marshal", "MarshalIndent"}},
+ },
+ methodSinks: []methodSink{
+ {pkgPath: "encoding/json", typeName: "Encoder", method: "Encode"},
+ },
+ },
+ {
+ name: "YAML",
+ tagKey: "yaml",
+ marshalerMethod: "MarshalYAML",
+ functionSinks: []functionSink{
+ {pkgPath: "go.yaml.in/yaml/v3", names: []string{"Marshal"}},
+ {pkgPath: "gopkg.in/yaml.v3", names: []string{"Marshal"}},
+ {pkgPath: "gopkg.in/yaml.v2", names: []string{"Marshal"}},
+ {pkgPath: "sigs.k8s.io/yaml", names: []string{"Marshal"}},
+ },
+ methodSinks: []methodSink{
+ {pkgPath: "go.yaml.in/yaml/v3", typeName: "Encoder", method: "Encode"},
+ {pkgPath: "gopkg.in/yaml.v3", typeName: "Encoder", method: "Encode"},
+ {pkgPath: "gopkg.in/yaml.v2", typeName: "Encoder", method: "Encode"},
+ },
+ },
+ {
+ name: "XML",
+ tagKey: "xml",
+ marshalerMethod: "MarshalXML",
+ functionSinks: []functionSink{
+ {pkgPath: "encoding/xml", names: []string{"Marshal", "MarshalIndent"}},
+ },
+ methodSinks: []methodSink{
+ {pkgPath: "encoding/xml", typeName: "Encoder", method: "Encode"},
+ },
+ },
+ {
+ name: "TOML",
+ tagKey: "toml",
+ functionSinks: []functionSink{
+ {pkgPath: "github.com/pelletier/go-toml", names: []string{"Marshal"}},
+ {pkgPath: "github.com/pelletier/go-toml/v2", names: []string{"Marshal"}},
+ },
+ methodSinks: []methodSink{
+ {pkgPath: "github.com/pelletier/go-toml", typeName: "Encoder", method: "Encode"},
+ {pkgPath: "github.com/pelletier/go-toml/v2", typeName: "Encoder", method: "Encode"},
+ {pkgPath: "github.com/BurntSushi/toml", typeName: "Encoder", method: "Encode"},
+ },
+ },
+}
+
+func (r *secretSerialization) Match(n ast.Node, ctx *gosec.Context) (*issue.Issue, error) {
+ callExpr, ok := n.(*ast.CallExpr)
+ if !ok {
+ return nil, nil
+ }
+
+ serializedArg, format, ok := r.findSerializedArgument(callExpr, ctx)
+ if !ok || serializedArg == nil || ctx.Info == nil {
+ return nil, nil
+ }
+
+ if isInsideCustomMarshaler(callExpr, ctx) {
+ return nil, nil
+ }
+
+ typ := ctx.Info.TypeOf(serializedArg)
+ if typ == nil {
+ return nil, nil
+ }
+
+ if typeImplementsMarshaler(typ, format.marshalerMethod) {
+ return nil, nil
+ }
+
+ match := r.findSensitiveFieldForType(typ, format.tagKey)
+ if !match.found {
+ return nil, nil
+ }
+
+ if compositeLitFieldIsTransformed(serializedArg, match.fieldName) {
+ return nil, nil
+ }
+
+ msg := fmt.Sprintf("Marshaled struct field %q (%s key %q) matches secret pattern", match.fieldName, format.name, match.serializedKey)
+ return ctx.NewIssue(callExpr, r.ID(), msg, r.Severity, r.Confidence), nil
+}
+
+// customMarshalerMethods lists method names that indicate a custom marshaler
+// implementation. When a marshal call occurs inside one of these methods, the
+// developer is explicitly controlling serialization, so G117 should not flag it.
+var customMarshalerMethods = map[string]bool{
+ "MarshalJSON": true,
+ "MarshalYAML": true,
+ "MarshalXML": true,
+ "MarshalText": true,
+ "MarshalTOML": true,
+ "MarshalBSON": true,
+}
+
+// isInsideCustomMarshaler reports whether callExpr is located inside a method
+// whose name matches a known custom marshaler (e.g. MarshalJSON).
+func isInsideCustomMarshaler(callExpr *ast.CallExpr, ctx *gosec.Context) bool {
+ if ctx.Root == nil {
+ return false
+ }
+
+ pos := callExpr.Pos()
+ var found bool
+
+ ast.Inspect(ctx.Root, func(n ast.Node) bool {
+ if found {
+ return false
+ }
+ funcDecl, ok := n.(*ast.FuncDecl)
+ if !ok || funcDecl.Body == nil {
+ return true
+ }
+ // Check if the call is inside this function body.
+ if pos < funcDecl.Body.Pos() || pos >= funcDecl.Body.End() {
+ return true
+ }
+ // Must be a method (has a receiver) with a recognized marshaler name.
+ if funcDecl.Recv != nil && funcDecl.Recv.NumFields() > 0 {
+ if customMarshalerMethods[funcDecl.Name.Name] {
+ found = true
+ }
+ }
+ return false
+ })
+
+ return found
+}
+
+// typeImplementsMarshaler reports whether typ (or its element type for
+// containers) has a method with the given name, indicating it implements a
+// custom marshaler interface (e.g. json.Marshaler). When a type has a custom
+// marshaler, the serialization library calls that method instead of serializing
+// fields directly, making struct field analysis irrelevant.
+func typeImplementsMarshaler(typ types.Type, methodName string) bool {
+ if methodName == "" {
+ return false
+ }
+ named := elementNamedType(typ)
+ if named == nil {
+ return false
+ }
+ // Check both value and pointer receiver methods via the pointer method set,
+ // which is a superset of the value method set.
+ mset := types.NewMethodSet(types.NewPointer(named))
+ for i := 0; i < mset.Len(); i++ {
+ if mset.At(i).Obj().Name() == methodName {
+ return true
+ }
+ }
+ return false
+}
+
+// elementNamedType unwraps pointers, slices, arrays, and maps to find the
+// innermost Named type. Returns nil if no Named type is found.
+func elementNamedType(typ types.Type) *types.Named {
+ switch t := typ.(type) {
+ case *types.Named:
+ return t
+ case *types.Pointer:
+ return elementNamedType(t.Elem())
+ case *types.Slice:
+ return elementNamedType(t.Elem())
+ case *types.Array:
+ return elementNamedType(t.Elem())
+ case *types.Map:
+ return elementNamedType(t.Elem())
+ }
+ return nil
+}
+
+// compositeLitFieldIsTransformed checks whether expr is a composite literal
+// in which the given field name is assigned a function call result. A function
+// call indicates the value is being transformed (e.g. masked or redacted)
+// before serialization.
+func compositeLitFieldIsTransformed(expr ast.Expr, fieldName string) bool {
+ // Unwrap address-of operator: &Struct{...}
+ if unary, ok := expr.(*ast.UnaryExpr); ok {
+ expr = unary.X
+ }
+ lit, ok := expr.(*ast.CompositeLit)
+ if !ok {
+ return false
+ }
+ for _, elt := range lit.Elts {
+ kv, ok := elt.(*ast.KeyValueExpr)
+ if !ok {
+ continue
+ }
+ ident, ok := kv.Key.(*ast.Ident)
+ if !ok || ident.Name != fieldName {
+ continue
+ }
+ _, isCall := kv.Value.(*ast.CallExpr)
+ return isCall
+ }
+ return false
+}
+
+func isNamedTypeInPackage(typ types.Type, pkgPath, typeName string) bool {
+ if typ == nil {
+ return false
+ }
+
+ switch t := typ.(type) {
+ case *types.Pointer:
+ return isNamedTypeInPackage(t.Elem(), pkgPath, typeName)
+ case *types.Named:
+ if obj := t.Obj(); obj != nil && obj.Name() == typeName {
+ if pkg := obj.Pkg(); pkg != nil && pkg.Path() == pkgPath {
+ return true
+ }
+ }
+ }
+
+ return false
+}
+
+func (r *secretSerialization) findSerializedArgument(callExpr *ast.CallExpr, ctx *gosec.Context) (ast.Expr, formatSpec, bool) {
+ for _, format := range g117Formats {
+ for _, sink := range format.functionSinks {
+ if callMatchesPackageFunction(callExpr, ctx, sink.pkgPath, sink.names...) {
+ if len(callExpr.Args) > 0 {
+ return callExpr.Args[0], format, true
+ }
+ return nil, format, true
+ }
+ }
+
+ for _, sink := range format.methodSinks {
+ if !callMatchesMethodSink(callExpr, ctx, sink) {
+ continue
+ }
+ if len(callExpr.Args) > 0 {
+ return callExpr.Args[0], format, true
+ }
+ return nil, format, true
+ }
+ }
+
+ return nil, formatSpec{}, false
+}
+
+func callMatchesMethodSink(callExpr *ast.CallExpr, ctx *gosec.Context, sink methodSink) bool {
+ selector, ok := callExpr.Fun.(*ast.SelectorExpr)
+ if !ok || selector.Sel == nil || selector.Sel.Name != sink.method {
+ return false
+ }
+
+ if ctx != nil && ctx.Info != nil {
+ receiverType := ctx.Info.TypeOf(selector.X)
+ if isNamedTypeInPackage(receiverType, sink.pkgPath, sink.typeName) {
+ return true
+ }
+ }
+
+ constructorCall, ok := selector.X.(*ast.CallExpr)
+ if !ok {
+ return false
+ }
+
+ constructorName := "New" + sink.typeName
+ if callMatchesPackageFunction(constructorCall, ctx, sink.pkgPath, constructorName) {
+ return true
+ }
+
+ if strings.Contains(strings.ToLower(sink.pkgPath), "toml") {
+ ctorSelector, ok := constructorCall.Fun.(*ast.SelectorExpr)
+ if !ok || ctorSelector.Sel == nil || ctorSelector.Sel.Name != constructorName {
+ return false
+ }
+ pkgIdent, ok := ctorSelector.X.(*ast.Ident)
+ if !ok {
+ return false
+ }
+ return importAliasPathContains(ctx, pkgIdent.Name, "toml")
+ }
+
+ return false
+}
+
+func callMatchesPackageFunction(callExpr *ast.CallExpr, ctx *gosec.Context, pkgPath string, names ...string) bool {
+ if callExpr == nil || ctx == nil {
+ return false
+ }
+
+ selector, ok := callExpr.Fun.(*ast.SelectorExpr)
+ if !ok || selector.Sel == nil {
+ return false
+ }
+
+ matchedName := false
+ for _, name := range names {
+ if selector.Sel.Name == name {
+ matchedName = true
+ break
+ }
+ }
+ if !matchedName {
+ return false
+ }
+
+ if ctx.Info != nil {
+ obj := ctx.Info.Uses[selector.Sel]
+ if obj != nil && obj.Pkg() != nil && packagePathMatches(obj.Pkg().Path(), pkgPath) {
+ return true
+ }
+ }
+
+ if _, matched := gosec.MatchCallByPackage(callExpr, ctx, pkgPath, names...); matched {
+ return true
+ }
+
+ pkgIdent, ok := selector.X.(*ast.Ident)
+ if !ok {
+ return false
+ }
+
+ return importAliasMatchesPath(ctx, pkgIdent.Name, pkgPath)
+}
+
+func importAliasMatchesPath(ctx *gosec.Context, alias, pkgPath string) bool {
+ if ctx == nil || ctx.Root == nil {
+ return false
+ }
+
+ for _, imp := range ctx.Root.Imports {
+ pathValue, err := strconv.Unquote(imp.Path.Value)
+ if err != nil || !packagePathMatches(pathValue, pkgPath) {
+ continue
+ }
+
+ importAlias := packageNameFromPath(pathValue)
+ if imp.Name != nil {
+ importAlias = imp.Name.Name
+ }
+
+ if importAlias == alias {
+ return true
+ }
+ }
+
+ return false
+}
+
+func importAliasPathContains(ctx *gosec.Context, alias, fragment string) bool {
+ if ctx == nil || ctx.Root == nil {
+ return false
+ }
+
+ for _, imp := range ctx.Root.Imports {
+ pathValue, err := strconv.Unquote(imp.Path.Value)
+ if err != nil {
+ continue
+ }
+
+ importAlias := packageNameFromPath(pathValue)
+ if imp.Name != nil {
+ importAlias = imp.Name.Name
+ }
+
+ if importAlias == alias && strings.Contains(strings.ToLower(pathValue), strings.ToLower(fragment)) {
+ return true
+ }
+ }
+
+ return false
+}
+
+func packageNameFromPath(path string) string {
+ if idx := strings.LastIndexByte(path, '/'); idx >= 0 && idx+1 < len(path) {
+ return path[idx+1:]
+ }
+ return path
+}
+
+func packagePathMatches(actual, expected string) bool {
+ if actual == expected {
+ return true
+ }
+
+ if strings.Contains(expected, "toml") {
+ actualLower := strings.ToLower(actual)
+ return strings.Contains(actualLower, "toml")
+ }
+
+ return false
+}
+
+func (r *secretSerialization) findSensitiveFieldForType(typ types.Type, tagKey string) sensitiveFieldMatch {
+ return r.findSensitiveFieldForTypeWithVisited(typ, tagKey, make(map[types.Type]struct{}))
+}
+
+func (r *secretSerialization) findSensitiveFieldForTypeWithVisited(typ types.Type, tagKey string, visited map[types.Type]struct{}) sensitiveFieldMatch {
+ if typ == nil {
+ return sensitiveFieldMatch{}
+ }
+
+ cacheKey := typeAnalysisCacheKey{typ: typ, tagKey: tagKey}
+ if cached, ok := r.cache.Load(cacheKey); ok {
+ return cached.(sensitiveFieldMatch)
+ }
+
+ if _, seen := visited[typ]; seen {
+ return sensitiveFieldMatch{}
+ }
+ visited[typ] = struct{}{}
+
+ var match sensitiveFieldMatch
+
+ switch t := typ.(type) {
+ case *types.Named:
+ match = r.findSensitiveFieldForTypeWithVisited(t.Underlying(), tagKey, visited)
+ case *types.Pointer:
+ match = r.findSensitiveFieldForTypeWithVisited(t.Elem(), tagKey, visited)
+ case *types.Struct:
+ match = r.findSensitiveSerializedField(t, tagKey)
+ case *types.Slice:
+ match = r.findSensitiveFieldForTypeWithVisited(t.Elem(), tagKey, visited)
+ case *types.Array:
+ match = r.findSensitiveFieldForTypeWithVisited(t.Elem(), tagKey, visited)
+ case *types.Map:
+ match = r.findSensitiveFieldForTypeWithVisited(t.Elem(), tagKey, visited)
+ case *types.Interface:
+ for i := 0; i < t.NumEmbeddeds(); i++ {
+ match = r.findSensitiveFieldForTypeWithVisited(t.EmbeddedType(i), tagKey, visited)
+ if match.found {
+ break
+ }
+ }
+ }
+
+ r.cache.Store(cacheKey, match)
+ return match
+}
+
+func (r *secretSerialization) findSensitiveSerializedField(st *types.Struct, tagKey string) sensitiveFieldMatch {
+ if st == nil {
+ return sensitiveFieldMatch{}
+ }
+
+ for i := 0; i < st.NumFields(); i++ {
+ field := st.Field(i)
+ if field == nil || !field.Exported() || field.Name() == "_" {
+ continue
+ }
+
+ if !isSecretCandidateType(field.Type()) {
+ continue
+ }
+
+ effectiveKey, omitted := serializedNameFromTag(field.Name(), st.Tag(i), tagKey)
+ if omitted {
+ continue
+ }
+
+ if gosec.RegexMatchWithCache(r.pattern, field.Name()) || gosec.RegexMatchWithCache(r.pattern, effectiveKey) {
+ return sensitiveFieldMatch{fieldName: field.Name(), serializedKey: effectiveKey, found: true}
+ }
+ }
+
+ return sensitiveFieldMatch{}
+}
+
+func isSecretCandidateType(typ types.Type) bool {
+ switch t := typ.(type) {
+ case *types.Named:
+ return isSecretCandidateType(t.Underlying())
+ case *types.Basic:
+ return t.Kind() == types.String
+ case *types.Pointer:
+ return isSecretCandidateType(t.Elem())
+ case *types.Slice:
+ if elemBasic, ok := t.Elem().(*types.Basic); ok && elemBasic.Kind() == types.Uint8 {
+ return true
+ }
+ return isSecretCandidateType(t.Elem())
+ case *types.Array:
+ if elemBasic, ok := t.Elem().(*types.Basic); ok && elemBasic.Kind() == types.Uint8 {
+ return true
+ }
+ return isSecretCandidateType(t.Elem())
+ }
+
+ return false
+}
+
+func serializedNameFromTag(defaultName, tag, tagKey string) (name string, omitted bool) {
+ if tag == "" {
+ return defaultName, false
+ }
+
+ tagValue := reflect.StructTag(tag).Get(tagKey)
+ if tagValue == "" {
+ return defaultName, false
+ }
+ if tagValue == "-" {
+ return "", true
+ }
+
+ name = tagValue
+ if idx := strings.IndexByte(tagValue, ','); idx >= 0 {
+ name = tagValue[:idx]
+ }
+
+ if name == "" {
+ return defaultName, false
+ }
+
+ return name, false
+}
+
+func NewSecretSerialization(id string, conf gosec.Config) (gosec.Rule, []ast.Node) {
+ patternStr := `(?i)\b((?:api|access|auth|bearer|client|oauth|private|refresh|session|jwt)[_-]?(?:key|secret|token)s?|password|passwd|pwd|pass|secret|cred|jwt)\b`
+
+ if val, ok := conf[id]; ok {
+ if m, ok := val.(map[string]interface{}); ok {
+ if p, ok := m["pattern"].(string); ok && p != "" {
+ patternStr = p
+ }
+ }
+ }
+
+ return &secretSerialization{
+ pattern: regexp.MustCompile(patternStr),
+ MetaData: issue.NewMetaData(id, "Exported struct field appears to be a secret and is serialized by JSON/YAML/XML/TOML", issue.Medium, issue.Medium),
+ }, []ast.Node{(*ast.CallExpr)(nil)}
+}
diff --git a/vendor/github.com/securego/gosec/v2/rules/slowloris.go b/vendor/github.com/securego/gosec/v2/rules/slowloris.go
index 70db73f5f..3732fcf8e 100644
--- a/vendor/github.com/securego/gosec/v2/rules/slowloris.go
+++ b/vendor/github.com/securego/gosec/v2/rules/slowloris.go
@@ -25,10 +25,6 @@ type slowloris struct {
issue.MetaData
}
-func (r *slowloris) ID() string {
- return r.MetaData.ID
-}
-
func containsReadHeaderTimeout(node *ast.CompositeLit) bool {
if node == nil {
return false
@@ -58,14 +54,8 @@ func (r *slowloris) Match(n ast.Node, ctx *gosec.Context) (*issue.Issue, error)
return nil, nil
}
-// NewSlowloris attempts to find the http.Server struct and check if the ReadHeaderTimeout is configured.
func NewSlowloris(id string, _ gosec.Config) (gosec.Rule, []ast.Node) {
return &slowloris{
- MetaData: issue.MetaData{
- ID: id,
- What: "Potential Slowloris Attack because ReadHeaderTimeout is not configured in the http.Server",
- Confidence: issue.Low,
- Severity: issue.Medium,
- },
+ MetaData: issue.NewMetaData(id, "Potential Slowloris Attack because ReadHeaderTimeout is not configured in the http.Server", issue.Medium, issue.Low),
}, []ast.Node{(*ast.CompositeLit)(nil)}
}
diff --git a/vendor/github.com/securego/gosec/v2/rules/sql.go b/vendor/github.com/securego/gosec/v2/rules/sql.go
index 622c2fe2b..f6377b1f9 100644
--- a/vendor/github.com/securego/gosec/v2/rules/sql.go
+++ b/vendor/github.com/securego/gosec/v2/rules/sql.go
@@ -17,6 +17,8 @@ package rules
import (
"fmt"
"go/ast"
+ "go/token"
+ "go/types"
"regexp"
"github.com/securego/gosec/v2"
@@ -60,36 +62,31 @@ var sqlCallIdents = map[string]map[string]int{
},
}
-// findQueryArg locates the argument taking raw SQL
+var (
+ sqlRegexp = regexp.MustCompile("(?i)(SELECT|DELETE|INSERT|UPDATE|INTO|FROM|WHERE)( |\n|\r|\t)")
+ sqlFormatRegexp = regexp.MustCompile("%[^bdoxXfFp]")
+)
+
+// findQueryArg locates the argument taking raw SQL.
func findQueryArg(call *ast.CallExpr, ctx *gosec.Context) (ast.Expr, error) {
typeName, fnName, err := gosec.GetCallInfo(call, ctx)
if err != nil {
return nil, err
}
- i := -1
- if ni, ok := sqlCallIdents[typeName]; ok {
- if i, ok = ni[fnName]; !ok {
- i = -1
+
+ if methods, ok := sqlCallIdents[typeName]; ok {
+ if i, ok := methods[fnName]; ok && i < len(call.Args) {
+ return call.Args[i], nil
}
}
- if i == -1 {
- return nil, fmt.Errorf("SQL argument index not found for %s.%s", typeName, fnName)
- }
- if i >= len(call.Args) {
- return nil, nil
- }
- query := call.Args[i]
- return query, nil
-}
-func (s *sqlStatement) ID() string {
- return s.MetaData.ID
+ return nil, fmt.Errorf("SQL argument index not found for %s.%s", typeName, fnName)
}
-// See if the string matches the patterns for the statement.
+// MatchPatterns checks if the string matches all required SQL patterns.
func (s *sqlStatement) MatchPatterns(str string) bool {
for _, pattern := range s.patterns {
- if !pattern.MatchString(str) {
+ if !gosec.RegexMatchWithCache(pattern, str) {
return false
}
}
@@ -100,12 +97,9 @@ type sqlStrConcat struct {
sqlStatement
}
-func (s *sqlStrConcat) ID() string {
- return s.MetaData.ID
-}
-
-// findInjectionInBranch walks diwb a set if expressions, and will create new issues if it finds SQL injections
-// This method assumes you've already verified that the branch contains SQL syntax
+// findInjectionInBranch walks through a set of expressions and returns the first
+// binary expression containing a potential injection (non-constant operand).
+// This method assumes the branch already contains SQL syntax.
func (s *sqlStrConcat) findInjectionInBranch(ctx *gosec.Context, branch []ast.Expr) *ast.BinaryExpr {
for _, node := range branch {
be, ok := node.(*ast.BinaryExpr)
@@ -113,133 +107,208 @@ func (s *sqlStrConcat) findInjectionInBranch(ctx *gosec.Context, branch []ast.Ex
continue
}
- operands := gosec.GetBinaryExprOperands(be)
-
- for _, op := range operands {
- if _, ok := op.(*ast.BasicLit); ok {
- continue
- }
-
- if ident, ok := op.(*ast.Ident); ok && s.checkObject(ident, ctx) {
+ for _, op := range gosec.GetBinaryExprOperands(be) {
+ if gosec.TryResolve(op, ctx) {
continue
}
-
return be
}
}
return nil
}
-// see if we can figure out what it is
-func (s *sqlStrConcat) checkObject(n *ast.Ident, c *gosec.Context) bool {
- if n.Obj != nil {
- return n.Obj.Kind != ast.Var && n.Obj.Kind != ast.Fun
- }
-
- // Try to resolve unresolved identifiers using other files in same package
- for _, file := range c.PkgFiles {
- if node, ok := file.Scope.Objects[n.String()]; ok {
- return node.Kind != ast.Var && node.Kind != ast.Fun
- }
- }
- return false
-}
-
-// checkQuery verifies if the query parameters is a string concatenation
+// checkQuery verifies if the query parameter involves risky string concatenation.
func (s *sqlStrConcat) checkQuery(call *ast.CallExpr, ctx *gosec.Context) (*issue.Issue, error) {
query, err := findQueryArg(call, ctx)
if err != nil {
return nil, err
}
+ // Direct binary concatenation (e.g., "SELECT ..." + tainted)
if be, ok := query.(*ast.BinaryExpr); ok {
operands := gosec.GetBinaryExprOperands(be)
if start, ok := operands[0].(*ast.BasicLit); ok {
- if str, e := gosec.GetString(start); e == nil {
- if !s.MatchPatterns(str) {
- return nil, nil
+ if str, e := gosec.GetString(start); e == nil && s.MatchPatterns(str) {
+ for _, op := range operands[1:] {
+ if gosec.TryResolve(op, ctx) {
+ continue
+ }
+ return ctx.NewIssue(be, s.ID(), s.What, s.Severity, s.Confidence), nil
}
}
- for _, op := range operands[1:] {
- if _, ok := op.(*ast.BasicLit); ok {
- continue
- }
- if op, ok := op.(*ast.Ident); ok && s.checkObject(op, ctx) {
- continue
+ }
+ return nil, nil
+ }
+
+ // Must be an identifier to continue (e.g., var query = ...; query += ...)
+ ident, ok := query.(*ast.Ident)
+ if !ok {
+ return nil, nil
+ }
+
+ v, ok := ctx.Info.ObjectOf(ident).(*types.Var)
+ if !ok {
+ return nil, nil
+ }
+
+ // Determine search scope (package-level or local)
+ isPkgLevel := ctx.Pkg != nil && v.Parent() == ctx.Pkg.Scope()
+
+ var filesToSearch []*ast.File
+ if isPkgLevel {
+ filesToSearch = ctx.PkgFiles
+ } else {
+ callFile := gosec.ContainingFile(call, ctx)
+ if callFile == nil {
+ return nil, nil
+ }
+ filesToSearch = []*ast.File{callFile}
+ }
+
+ // Find the defining declaration and check for SQL patterns / initial risky concatenation
+ declRHS := []ast.Expr{}
+ foundDecl := false
+
+ // Determine the file containing the variable's defining position
+ var declFile *ast.File
+ if ctx.FileSet != nil {
+ if posFile := ctx.FileSet.File(v.Pos()); posFile != nil {
+ targetName := posFile.Name()
+ for _, f := range filesToSearch {
+ if fileInfo := ctx.FileSet.File(f.Pos()); fileInfo != nil && fileInfo.Name() == targetName {
+ declFile = f
+ break
}
- return ctx.NewIssue(be, s.ID(), s.What, s.Severity, s.Confidence), nil
}
}
}
- // Handle the case where an injection occurs as an infixed string concatenation, ie "SELECT * FROM foo WHERE name = '" + os.Args[0] + "' AND 1=1"
- if id, ok := query.(*ast.Ident); ok {
- var match bool
- for _, str := range gosec.GetIdentStringValuesRecursive(id) {
- if s.MatchPatterns(str) {
- match = true
+ if declFile != nil {
+ ast.Inspect(declFile, func(n ast.Node) bool {
+ switch d := n.(type) {
+ case *ast.ValueSpec:
+ for _, name := range d.Names {
+ if name.Pos() == v.Pos() && ctx.Info.ObjectOf(name) == v {
+ declRHS = d.Values
+ foundDecl = true
+ return false // Stop inspection
+ }
+ }
+ case *ast.AssignStmt:
+ if d.Tok == token.DEFINE { // Only short variable declarations define new vars
+ for _, lhs := range d.Lhs {
+ if id, ok := lhs.(*ast.Ident); ok && id.Pos() == v.Pos() && ctx.Info.ObjectOf(id) == v {
+ declRHS = d.Rhs
+ foundDecl = true
+ return false // Stop inspection
+ }
+ }
+ }
+ }
+ return true
+ })
+ }
+
+ if foundDecl {
+ // Check for SQL patterns in initial values
+ hasSQLPattern := false
+ for _, val := range declRHS {
+ if str, err := gosec.GetStringRecursive(val); err == nil && s.MatchPatterns(str) {
+ hasSQLPattern = true
break
}
}
- if !match {
+ // Check for risky initial concatenation
+ if inj := s.findInjectionInBranch(ctx, declRHS); inj != nil {
+ return ctx.NewIssue(inj, s.ID(), s.What, s.Severity, s.Confidence), nil
+ }
+
+ if !hasSQLPattern {
return nil, nil
}
+ } else {
+ // No defining declaration found → assume not SQL-related
+ return nil, nil
+ }
+
+ // Check for risky mutations (query += tainted or query = query + tainted)
+ for _, f := range filesToSearch {
+ var found *ast.AssignStmt
+ ast.Inspect(f, func(n ast.Node) bool {
+ assign, ok := n.(*ast.AssignStmt)
+ if !ok || len(assign.Lhs) != 1 || len(assign.Rhs) != 1 {
+ return true
+ }
+ lIdent, ok := assign.Lhs[0].(*ast.Ident)
+ if !ok || ctx.Info.ObjectOf(lIdent) != v {
+ return true
+ }
- switch decl := id.Obj.Decl.(type) {
- case *ast.AssignStmt:
- if injection := s.findInjectionInBranch(ctx, decl.Rhs); injection != nil {
- return ctx.NewIssue(injection, s.ID(), s.What, s.Severity, s.Confidence), nil
+ var appended ast.Expr
+ switch assign.Tok {
+ case token.ADD_ASSIGN:
+ appended = assign.Rhs[0]
+ case token.ASSIGN:
+ be, ok := assign.Rhs[0].(*ast.BinaryExpr)
+ if !ok || be.Op != token.ADD {
+ return true
+ }
+ left, ok := be.X.(*ast.Ident)
+ if !ok || ctx.Info.ObjectOf(left) != v {
+ return true
+ }
+ appended = be.Y
+ default:
+ return true
}
- case *ast.ValueSpec:
- // handle: var query string = "SELECT ...'" + user
- if injection := s.findInjectionInBranch(ctx, decl.Values); injection != nil {
- return ctx.NewIssue(injection, s.ID(), s.What, s.Severity, s.Confidence), nil
+
+ if !gosec.TryResolve(appended, ctx) {
+ found = assign
+ return false
}
+ return true
+ })
+ if found != nil {
+ return ctx.NewIssue(found, s.ID(), s.What, s.Severity, s.Confidence), nil
}
}
return nil, nil
}
-// Checks SQL query concatenation issues such as "SELECT * FROM table WHERE " + " ' OR 1=1"
+// Match looks for SQL execution calls and checks for concatenation issues.
func (s *sqlStrConcat) Match(n ast.Node, ctx *gosec.Context) (*issue.Issue, error) {
switch stmt := n.(type) {
case *ast.AssignStmt:
for _, expr := range stmt.Rhs {
- if sqlQueryCall, ok := expr.(*ast.CallExpr); ok && s.ContainsCallExpr(expr, ctx) != nil {
- return s.checkQuery(sqlQueryCall, ctx)
+ if call, ok := expr.(*ast.CallExpr); ok && s.ContainsCallExpr(expr, ctx) != nil {
+ return s.checkQuery(call, ctx)
}
}
case *ast.ExprStmt:
- if sqlQueryCall, ok := stmt.X.(*ast.CallExpr); ok && s.ContainsCallExpr(stmt.X, ctx) != nil {
- return s.checkQuery(sqlQueryCall, ctx)
+ if call, ok := stmt.X.(*ast.CallExpr); ok && s.ContainsCallExpr(call, ctx) != nil {
+ return s.checkQuery(call, ctx)
}
}
-
return nil, nil
}
-// NewSQLStrConcat looks for cases where we are building SQL strings via concatenation
+// NewSQLStrConcat creates a rule for detecting SQL string concatenation.
func NewSQLStrConcat(id string, _ gosec.Config) (gosec.Rule, []ast.Node) {
rule := &sqlStrConcat{
sqlStatement: sqlStatement{
patterns: []*regexp.Regexp{
- regexp.MustCompile("(?i)(SELECT|DELETE|INSERT|UPDATE|INTO|FROM|WHERE)( |\n|\r|\t)"),
- },
- MetaData: issue.MetaData{
- ID: id,
- Severity: issue.Medium,
- Confidence: issue.High,
- What: "SQL string concatenation",
+ sqlRegexp,
},
+ MetaData: issue.NewMetaData(id, "SQL string concatenation", issue.Medium, issue.High),
CallList: gosec.NewCallList(),
},
}
- for s, si := range sqlCallIdents {
- for i := range si {
- rule.Add(s, i)
+ for typ, methods := range sqlCallIdents {
+ for method := range methods {
+ rule.Add(typ, method)
}
}
return rule, []ast.Node{(*ast.AssignStmt)(nil), (*ast.ExprStmt)(nil)}
@@ -253,65 +322,77 @@ type sqlStrFormat struct {
noIssueQuoted gosec.CallList
}
-// see if we can figure out what it is
-func (s *sqlStrFormat) constObject(e ast.Expr, c *gosec.Context) bool {
- n, ok := e.(*ast.Ident)
- if !ok {
- return false
+// checkQuery verifies if the query parameter involves risky formatting.
+func (s *sqlStrFormat) checkQuery(call *ast.CallExpr, ctx *gosec.Context) (*issue.Issue, error) {
+ query, err := findQueryArg(call, ctx)
+ if err != nil {
+ return nil, err
}
- if n.Obj != nil {
- return n.Obj.Kind == ast.Con
+ // Must be a variable identifier (short-declared with :=)
+ ident, ok := query.(*ast.Ident)
+ if !ok {
+ return nil, nil
}
- // Try to resolve unresolved identifiers using other files in same package
- for _, file := range c.PkgFiles {
- if node, ok := file.Scope.Objects[n.String()]; ok {
- return node.Kind == ast.Con
- }
+ v, ok := ctx.Info.ObjectOf(ident).(*types.Var)
+ if !ok {
+ return nil, nil
}
- return false
-}
-func (s *sqlStrFormat) checkQuery(call *ast.CallExpr, ctx *gosec.Context) (*issue.Issue, error) {
- query, err := findQueryArg(call, ctx)
- if err != nil {
- return nil, err
+ // Short variable declarations are always local → use the file containing the call
+ callFile := gosec.ContainingFile(call, ctx)
+ if callFile == nil {
+ return nil, nil
}
- if ident, ok := query.(*ast.Ident); ok && ident.Obj != nil {
- decl := ident.Obj.Decl
- if assign, ok := decl.(*ast.AssignStmt); ok {
- for _, expr := range assign.Rhs {
- issue := s.checkFormatting(expr, ctx)
- if issue != nil {
- return issue, err
+ // Find the defining short declaration (query := fmt.Sprintf(...))
+ var foundIssue *issue.Issue
+ ast.Inspect(callFile, func(n ast.Node) bool {
+ assign, ok := n.(*ast.AssignStmt)
+ if !ok || assign.Tok != token.DEFINE {
+ return true
+ }
+
+ // Find the LHS identifier that defines this variable
+ for _, lhs := range assign.Lhs {
+ if defIdent, ok := lhs.(*ast.Ident); ok &&
+ defIdent.Pos() == v.Pos() && ctx.Info.ObjectOf(defIdent) == v {
+
+ // Check every initializer expression on the RHS
+ for _, expr := range assign.Rhs {
+ if expr == nil {
+ continue
+ }
+ if iss := s.checkFormatting(expr, ctx); iss != nil {
+ foundIssue = iss
+ return false // Stop entire inspection
+ }
}
+ return false // Declaration found and processed
}
}
- }
+ return true
+ })
- return nil, nil
+ return foundIssue, nil
}
+// checkFormatting checks if a formatting call builds a risky SQL query.
func (s *sqlStrFormat) checkFormatting(n ast.Node, ctx *gosec.Context) *issue.Issue {
// argIndex changes the function argument which gets matched to the regex
argIndex := 0
if node := s.fmtCalls.ContainsPkgCallExpr(n, ctx, false); node != nil {
// if the function is fmt.Fprintf, search for SQL statement in Args[1] instead
- if sel, ok := node.Fun.(*ast.SelectorExpr); ok {
- if sel.Sel.Name == "Fprintf" {
- // if os.Stderr or os.Stdout is in Arg[0], mark as no issue
- if arg, ok := node.Args[0].(*ast.SelectorExpr); ok {
- if ident, ok := arg.X.(*ast.Ident); ok {
- if s.noIssue.Contains(ident.Name, arg.Sel.Name) {
- return nil
- }
- }
+ if sel, ok := node.Fun.(*ast.SelectorExpr); ok && sel.Sel.Name == "Fprintf" {
+ // if os.Stderr or os.Stdout is in Arg[0], mark as no issue
+ if arg, ok := node.Args[0].(*ast.SelectorExpr); ok {
+ if ident, ok := arg.X.(*ast.Ident); ok && s.noIssue.Contains(ident.Name, arg.Sel.Name) {
+ return nil
}
- // the function is Fprintf so set argIndex = 1
- argIndex = 1
}
+ // the function is Fprintf so set argIndex = 1
+ argIndex = 1
}
// no formatter
@@ -319,17 +400,8 @@ func (s *sqlStrFormat) checkFormatting(n ast.Node, ctx *gosec.Context) *issue.Is
return nil
}
- var formatter string
-
- // concats callexpr arg strings together if needed before regex evaluation
- if argExpr, ok := node.Args[argIndex].(*ast.BinaryExpr); ok {
- if fullStr, ok := gosec.ConcatString(argExpr); ok {
- formatter = fullStr
- }
- } else if arg, e := gosec.GetString(node.Args[argIndex]); e == nil {
- formatter = arg
- }
- if len(formatter) <= 0 {
+ formatter, ok := gosec.ConcatString(node.Args[argIndex], ctx)
+ if !ok || formatter == "" {
return nil
}
@@ -337,7 +409,7 @@ func (s *sqlStrFormat) checkFormatting(n ast.Node, ctx *gosec.Context) *issue.Is
if argIndex+1 < len(node.Args) {
allSafe := true
for _, arg := range node.Args[argIndex+1:] {
- if n := s.noIssueQuoted.ContainsPkgCallExpr(arg, ctx, true); n == nil && !s.constObject(arg, ctx) {
+ if s.noIssueQuoted.ContainsPkgCallExpr(arg, ctx, true) == nil && !gosec.TryResolve(arg, ctx) {
allSafe = false
break
}
@@ -346,6 +418,7 @@ func (s *sqlStrFormat) checkFormatting(n ast.Node, ctx *gosec.Context) *issue.Is
return nil
}
}
+
if s.MatchPatterns(formatter) {
return ctx.NewIssue(n, s.ID(), s.What, s.Severity, s.Confidence)
}
@@ -353,37 +426,31 @@ func (s *sqlStrFormat) checkFormatting(n ast.Node, ctx *gosec.Context) *issue.Is
return nil
}
-// Check SQL query formatting issues such as "fmt.Sprintf("SELECT * FROM foo where '%s', userInput)"
+// Match looks for SQL calls involving formatted strings.
func (s *sqlStrFormat) Match(n ast.Node, ctx *gosec.Context) (*issue.Issue, error) {
switch stmt := n.(type) {
case *ast.AssignStmt:
for _, expr := range stmt.Rhs {
if call, ok := expr.(*ast.CallExpr); ok {
- selector, ok := call.Fun.(*ast.SelectorExpr)
- if !ok {
- continue
- }
- sqlQueryCall, ok := selector.X.(*ast.CallExpr)
- if ok && s.ContainsCallExpr(sqlQueryCall, ctx) != nil {
- issue, err := s.checkQuery(sqlQueryCall, ctx)
- if err == nil && issue != nil {
- return issue, err
+ if sel, ok := call.Fun.(*ast.SelectorExpr); ok {
+ if sqlCall, ok := sel.X.(*ast.CallExpr); ok && s.ContainsCallExpr(sqlCall, ctx) != nil {
+ return s.checkQuery(sqlCall, ctx)
}
}
- }
- if sqlQueryCall, ok := expr.(*ast.CallExpr); ok && s.ContainsCallExpr(expr, ctx) != nil {
- return s.checkQuery(sqlQueryCall, ctx)
+ if s.ContainsCallExpr(expr, ctx) != nil {
+ return s.checkQuery(call, ctx)
+ }
}
}
case *ast.ExprStmt:
- if sqlQueryCall, ok := stmt.X.(*ast.CallExpr); ok && s.ContainsCallExpr(stmt.X, ctx) != nil {
- return s.checkQuery(sqlQueryCall, ctx)
+ if call, ok := stmt.X.(*ast.CallExpr); ok && s.ContainsCallExpr(call, ctx) != nil {
+ return s.checkQuery(call, ctx)
}
}
return nil, nil
}
-// NewSQLStrFormat looks for cases where we're building SQL query strings using format strings
+// NewSQLStrFormat creates a rule for detecting SQL string formatting.
func NewSQLStrFormat(id string, _ gosec.Config) (gosec.Rule, []ast.Node) {
rule := &sqlStrFormat{
CallList: gosec.NewCallList(),
@@ -392,25 +459,19 @@ func NewSQLStrFormat(id string, _ gosec.Config) (gosec.Rule, []ast.Node) {
noIssueQuoted: gosec.NewCallList(),
sqlStatement: sqlStatement{
patterns: []*regexp.Regexp{
- regexp.MustCompile("(?i)(SELECT|DELETE|INSERT|UPDATE|INTO|FROM|WHERE)( |\n|\r|\t)"),
- regexp.MustCompile("%[^bdoxXfFp]"),
- },
- MetaData: issue.MetaData{
- ID: id,
- Severity: issue.Medium,
- Confidence: issue.High,
- What: "SQL string formatting",
+ sqlRegexp,
+ sqlFormatRegexp,
},
+ MetaData: issue.NewMetaData(id, "SQL string formatting", issue.Medium, issue.High),
},
}
- for s, si := range sqlCallIdents {
- for i := range si {
- rule.Add(s, i)
+ for typ, methods := range sqlCallIdents {
+ for method := range methods {
+ rule.Add(typ, method)
}
}
rule.fmtCalls.AddAll("fmt", "Sprint", "Sprintf", "Sprintln", "Fprintf")
rule.noIssue.AddAll("os", "Stdout", "Stderr")
rule.noIssueQuoted.Add("github.com/lib/pq", "QuoteIdentifier")
-
return rule, []ast.Node{(*ast.AssignStmt)(nil), (*ast.ExprStmt)(nil)}
}
diff --git a/vendor/github.com/securego/gosec/v2/rules/ssh.go b/vendor/github.com/securego/gosec/v2/rules/ssh.go
index e2ba5a3f4..4d548f3a9 100644
--- a/vendor/github.com/securego/gosec/v2/rules/ssh.go
+++ b/vendor/github.com/securego/gosec/v2/rules/ssh.go
@@ -8,32 +8,13 @@ import (
)
type sshHostKey struct {
- issue.MetaData
- pkg string
- calls []string
-}
-
-func (r *sshHostKey) ID() string {
- return r.MetaData.ID
-}
-
-func (r *sshHostKey) Match(n ast.Node, c *gosec.Context) (gi *issue.Issue, err error) {
- if _, matches := gosec.MatchCallByPackage(n, c, r.pkg, r.calls...); matches {
- return c.NewIssue(n, r.ID(), r.What, r.Severity, r.Confidence), nil
- }
- return nil, nil
+ callListRule
}
// NewSSHHostKey rule detects the use of insecure ssh HostKeyCallback.
func NewSSHHostKey(id string, _ gosec.Config) (gosec.Rule, []ast.Node) {
- return &sshHostKey{
- pkg: "golang.org/x/crypto/ssh",
- calls: []string{"InsecureIgnoreHostKey"},
- MetaData: issue.MetaData{
- ID: id,
- What: "Use of ssh InsecureIgnoreHostKey should be audited",
- Severity: issue.Medium,
- Confidence: issue.High,
- },
- }, []ast.Node{(*ast.CallExpr)(nil)}
+ // This is a call list rule that checks for insecure SSH host key handling.
+ rule := &sshHostKey{newCallListRule(id, "Use of ssh InsecureIgnoreHostKey should be audited", issue.Medium, issue.High)}
+ rule.Add("golang.org/x/crypto/ssh", "InsecureIgnoreHostKey")
+ return rule, []ast.Node{(*ast.CallExpr)(nil)}
}
diff --git a/vendor/github.com/securego/gosec/v2/rules/ssrf.go b/vendor/github.com/securego/gosec/v2/rules/ssrf.go
index dbf01081b..c89cbc274 100644
--- a/vendor/github.com/securego/gosec/v2/rules/ssrf.go
+++ b/vendor/github.com/securego/gosec/v2/rules/ssrf.go
@@ -9,13 +9,7 @@ import (
)
type ssrf struct {
- issue.MetaData
- gosec.CallList
-}
-
-// ID returns the identifier for this rule
-func (r *ssrf) ID() string {
- return r.MetaData.ID
+ callListRule
}
// ResolveVar tries to resolve the first argument of a call expression
@@ -43,7 +37,7 @@ func (r *ssrf) ResolveVar(n *ast.CallExpr, c *gosec.Context) bool {
// Match inspects AST nodes to determine if certain net/http methods are called with variable input
func (r *ssrf) Match(n ast.Node, c *gosec.Context) (*issue.Issue, error) {
// Call expression is using http package directly
- if node := r.ContainsPkgCallExpr(n, c, false); node != nil {
+ if node := r.calls.ContainsPkgCallExpr(n, c, false); node != nil {
if r.ResolveVar(node, c) {
return c.NewIssue(n, r.ID(), r.What, r.Severity, r.Confidence), nil
}
@@ -53,15 +47,7 @@ func (r *ssrf) Match(n ast.Node, c *gosec.Context) (*issue.Issue, error) {
// NewSSRFCheck detects cases where HTTP requests are sent
func NewSSRFCheck(id string, _ gosec.Config) (gosec.Rule, []ast.Node) {
- rule := &ssrf{
- CallList: gosec.NewCallList(),
- MetaData: issue.MetaData{
- ID: id,
- What: "Potential HTTP request made with variable url",
- Severity: issue.Medium,
- Confidence: issue.Medium,
- },
- }
+ rule := &ssrf{newCallListRule(id, "Potential HTTP request made with variable url", issue.Medium, issue.Medium)}
rule.AddAll("net/http", "Do", "Get", "Head", "Post", "PostForm", "RoundTrip")
return rule, []ast.Node{(*ast.CallExpr)(nil)}
}
diff --git a/vendor/github.com/securego/gosec/v2/rules/subproc.go b/vendor/github.com/securego/gosec/v2/rules/subproc.go
index 1e2cedaa5..0dd274749 100644
--- a/vendor/github.com/securego/gosec/v2/rules/subproc.go
+++ b/vendor/github.com/securego/gosec/v2/rules/subproc.go
@@ -16,6 +16,7 @@ package rules
import (
"go/ast"
+ "go/token"
"go/types"
"github.com/securego/gosec/v2"
@@ -23,12 +24,30 @@ import (
)
type subprocess struct {
- issue.MetaData
- gosec.CallList
+ callListRule
}
-func (r *subprocess) ID() string {
- return r.MetaData.ID
+// getEnclosingBodyStart returns the position of the '{' for the innermost function body enclosing the given position.
+// Returns token.NoPos if no enclosing body found.
+func getEnclosingBodyStart(pos token.Pos, ctx *gosec.Context) token.Pos {
+ if ctx.Root == nil {
+ return token.NoPos
+ }
+ var bodyStart token.Pos
+ ast.Inspect(ctx.Root, func(n ast.Node) bool {
+ var body *ast.BlockStmt
+ switch f := n.(type) {
+ case *ast.FuncDecl:
+ body = f.Body
+ case *ast.FuncLit:
+ body = f.Body
+ }
+ if body != nil && body.Pos() <= pos && pos < body.End() && body.Lbrace.IsValid() {
+ bodyStart = body.Lbrace
+ }
+ return true
+ })
+ return bodyStart
}
// TODO(gm) The only real potential for command injection with a Go project
@@ -41,54 +60,32 @@ func (r *subprocess) ID() string {
//
// syscall.Exec("echo", "foobar" + tainted)
func (r *subprocess) Match(n ast.Node, c *gosec.Context) (*issue.Issue, error) {
- if node := r.ContainsPkgCallExpr(n, c, false); node != nil {
+ if node := r.calls.ContainsPkgCallExpr(n, c, false); node != nil {
args := node.Args
if r.isContext(n, c) {
args = args[1:]
}
- for _, arg := range args {
+ for i, arg := range args {
if ident, ok := arg.(*ast.Ident); ok {
obj := c.Info.ObjectOf(ident)
-
- // need to cast and check whether it is for a variable ?
- _, variable := obj.(*types.Var)
-
- // .. indeed it is a variable then processing is different than a normal
- // field assignment
- if variable {
- // skip the check when the declaration is not available
- if ident.Obj == nil {
- continue
- }
- switch ident.Obj.Decl.(type) {
- case *ast.AssignStmt:
- _, assignment := ident.Obj.Decl.(*ast.AssignStmt)
- if variable && assignment {
- if !gosec.TryResolve(ident, c) {
- return c.NewIssue(n, r.ID(), "Subprocess launched with variable", issue.Medium, issue.High), nil
- }
+ if v, ok := obj.(*types.Var); ok {
+ // Special case: struct fields OR function parameters/receivers used as executable name (i==0) -> skip
+ if i == 0 {
+ if v.IsField() {
+ continue
}
- case *ast.Field:
- _, field := ident.Obj.Decl.(*ast.Field)
- if variable && field {
- // check if the variable exist in the scope
- vv, vvok := obj.(*types.Var)
-
- if vvok && vv.Parent().Lookup(ident.Name) == nil {
- return c.NewIssue(n, r.ID(), "Subprocess launched with variable", issue.Medium, issue.High), nil
- }
- }
- case *ast.ValueSpec:
- _, valueSpec := ident.Obj.Decl.(*ast.ValueSpec)
- if variable && valueSpec {
- if !gosec.TryResolve(ident, c) {
- return c.NewIssue(n, r.ID(), "Subprocess launched with variable", issue.Medium, issue.High), nil
- }
+ bodyStart := getEnclosingBodyStart(ident.Pos(), c)
+ if bodyStart != token.NoPos && obj.Pos() < bodyStart {
+ continue // Parameter or receiver (declared before body brace)
}
}
+ // For all variables: flag if not resolvable to a constant
+ if !gosec.TryResolve(ident, c) {
+ return c.NewIssue(n, r.ID(), "Subprocess launched with variable", issue.Medium, issue.High), nil
+ }
}
} else if !gosec.TryResolve(arg, c) {
- // the arg is not a constant or a variable but instead a function call or os.Args[i]
+ // Non-identifier arguments that cannot be resolved
return c.NewIssue(n, r.ID(), "Subprocess launched with a potential tainted input or cmd arguments", issue.Medium, issue.High), nil
}
}
@@ -111,7 +108,7 @@ func (r *subprocess) isContext(n ast.Node, ctx *gosec.Context) bool {
// NewSubproc detects cases where we are forking out to an external process
func NewSubproc(id string, _ gosec.Config) (gosec.Rule, []ast.Node) {
- rule := &subprocess{issue.MetaData{ID: id}, gosec.NewCallList()}
+ rule := &subprocess{newCallListRule(id, "Subprocess launched with variable", issue.Medium, issue.High)}
rule.Add("os/exec", "Command")
rule.Add("os/exec", "CommandContext")
rule.Add("syscall", "Exec")
diff --git a/vendor/github.com/securego/gosec/v2/rules/tempfiles.go b/vendor/github.com/securego/gosec/v2/rules/tempfiles.go
index 6fef52a2c..b6406137b 100644
--- a/vendor/github.com/securego/gosec/v2/rules/tempfiles.go
+++ b/vendor/github.com/securego/gosec/v2/rules/tempfiles.go
@@ -23,20 +23,15 @@ import (
)
type badTempFile struct {
- issue.MetaData
- calls gosec.CallList
+ callListRule
args *regexp.Regexp
argCalls gosec.CallList
nestedCalls gosec.CallList
}
-func (t *badTempFile) ID() string {
- return t.MetaData.ID
-}
-
func (t *badTempFile) findTempDirArgs(n ast.Node, c *gosec.Context, suspect ast.Node) *issue.Issue {
if s, e := gosec.GetString(suspect); e == nil {
- if t.args.MatchString(s) {
+ if gosec.RegexMatchWithCache(t.args, s) {
return c.NewIssue(n, t.ID(), t.What, t.Severity, t.Confidence)
}
return nil
@@ -65,24 +60,16 @@ func (t *badTempFile) Match(n ast.Node, c *gosec.Context) (gi *issue.Issue, err
// NewBadTempFile detects direct writes to predictable path in temporary directory
func NewBadTempFile(id string, _ gosec.Config) (gosec.Rule, []ast.Node) {
- calls := gosec.NewCallList()
- calls.Add("io/ioutil", "WriteFile")
- calls.AddAll("os", "Create", "WriteFile")
- argCalls := gosec.NewCallList()
- argCalls.Add("os", "TempDir")
- nestedCalls := gosec.NewCallList()
- nestedCalls.Add("path", "Join")
- nestedCalls.Add("path/filepath", "Join")
- return &badTempFile{
- calls: calls,
- args: regexp.MustCompile(`^(/(usr|var))?/tmp(/.*)?$`),
- argCalls: argCalls,
- nestedCalls: nestedCalls,
- MetaData: issue.MetaData{
- ID: id,
- Severity: issue.Medium,
- Confidence: issue.High,
- What: "File creation in shared tmp directory without using ioutil.Tempfile",
- },
- }, []ast.Node{(*ast.CallExpr)(nil)}
+ rule := &badTempFile{
+ callListRule: newCallListRule(id, "File creation in shared tmp directory without using ioutil.Tempfile", issue.Medium, issue.High),
+ args: regexp.MustCompile(`^(/(usr|var))?/tmp(/.*)?$`),
+ argCalls: gosec.NewCallList(),
+ nestedCalls: gosec.NewCallList(),
+ }
+ rule.Add("io/ioutil", "WriteFile")
+ rule.AddAll("os", "Create", "WriteFile")
+ rule.argCalls.Add("os", "TempDir")
+ rule.nestedCalls.AddAll("path", "Join")
+ rule.nestedCalls.Add("path/filepath", "Join")
+ return rule, []ast.Node{(*ast.CallExpr)(nil)}
}
diff --git a/vendor/github.com/securego/gosec/v2/rules/templates.go b/vendor/github.com/securego/gosec/v2/rules/templates.go
index 3d5f9a977..c5732b380 100644
--- a/vendor/github.com/securego/gosec/v2/rules/templates.go
+++ b/vendor/github.com/securego/gosec/v2/rules/templates.go
@@ -22,18 +22,15 @@ import (
)
type templateCheck struct {
- issue.MetaData
- calls gosec.CallList
-}
-
-func (t *templateCheck) ID() string {
- return t.MetaData.ID
+ callListRule
}
+// Match checks for calls to html/template methods that do not auto-escape
+// inputs. Basic literals are considered safe.
func (t *templateCheck) Match(n ast.Node, c *gosec.Context) (*issue.Issue, error) {
- if node := t.calls.ContainsPkgCallExpr(n, c, false); node != nil {
- for _, arg := range node.Args {
- if _, ok := arg.(*ast.BasicLit); !ok { // basic lits are safe
+ if call := t.calls.ContainsPkgCallExpr(n, c, false); call != nil {
+ for _, arg := range call.Args {
+ if _, ok := arg.(*ast.BasicLit); !ok {
return c.NewIssue(n, t.ID(), t.What, t.Severity, t.Confidence), nil
}
}
@@ -44,21 +41,9 @@ func (t *templateCheck) Match(n ast.Node, c *gosec.Context) (*issue.Issue, error
// NewTemplateCheck constructs the template check rule. This rule is used to
// find use of templates where HTML/JS escaping is not being used
func NewTemplateCheck(id string, _ gosec.Config) (gosec.Rule, []ast.Node) {
- calls := gosec.NewCallList()
- calls.Add("html/template", "CSS")
- calls.Add("html/template", "HTML")
- calls.Add("html/template", "HTMLAttr")
- calls.Add("html/template", "JS")
- calls.Add("html/template", "JSStr")
- calls.Add("html/template", "Srcset")
- calls.Add("html/template", "URL")
- return &templateCheck{
- calls: calls,
- MetaData: issue.MetaData{
- ID: id,
- Severity: issue.Medium,
- Confidence: issue.Low,
- What: "The used method does not auto-escape HTML. This can potentially lead to 'Cross-site Scripting' vulnerabilities, in case the attacker controls the input.",
- },
- }, []ast.Node{(*ast.CallExpr)(nil)}
+ rule := &templateCheck{newCallListRule(id,
+ "The used method does not auto-escape HTML. This can potentially lead to 'Cross-site Scripting' vulnerabilities, in case the attacker controls the input.",
+ issue.Medium, issue.Low)}
+ rule.AddAll("html/template", "CSS", "HTML", "HTMLAttr", "JS", "JSStr", "Srcset", "URL")
+ return rule, []ast.Node{(*ast.CallExpr)(nil)}
}
diff --git a/vendor/github.com/securego/gosec/v2/rules/tls.go b/vendor/github.com/securego/gosec/v2/rules/tls.go
index 65a0b5a33..6f7cb399e 100644
--- a/vendor/github.com/securego/gosec/v2/rules/tls.go
+++ b/vendor/github.com/securego/gosec/v2/rules/tls.go
@@ -20,8 +20,9 @@ import (
"crypto/tls"
"fmt"
"go/ast"
+ "go/token"
"go/types"
- "strconv"
+ "slices"
"github.com/securego/gosec/v2"
"github.com/securego/gosec/v2/issue"
@@ -35,28 +36,29 @@ type insecureConfigTLS struct {
goodCiphers []string
actualMinVersion int64
actualMaxVersion int64
+ minVersionSet bool
+ maxVersionSet bool
}
-func (t *insecureConfigTLS) ID() string {
- return t.MetaData.ID
+var tlsVersionMap = map[string]int64{
+ "VersionTLS10": tls.VersionTLS10,
+ "VersionTLS11": tls.VersionTLS11,
+ "VersionTLS12": tls.VersionTLS12,
+ "VersionTLS13": tls.VersionTLS13,
}
-func stringInSlice(a string, list []string) bool {
- for _, b := range list {
- if b == a {
- return true
- }
- }
- return false
+func (t *insecureConfigTLS) mapVersion(version string) int64 {
+ return tlsVersionMap[version]
}
func (t *insecureConfigTLS) processTLSCipherSuites(n ast.Node, c *gosec.Context) *issue.Issue {
if ciphers, ok := n.(*ast.CompositeLit); ok {
- for _, cipher := range ciphers.Elts {
- if ident, ok := cipher.(*ast.SelectorExpr); ok {
- if !stringInSlice(ident.Sel.Name, t.goodCiphers) {
- err := fmt.Sprintf("TLS Bad Cipher Suite: %s", ident.Sel.Name)
- return c.NewIssue(ident, t.ID(), err, issue.High, issue.High)
+ for _, elt := range ciphers.Elts {
+ if ident, ok := elt.(*ast.SelectorExpr); ok {
+ cipherName := ident.Sel.Name
+ if !slices.Contains(t.goodCiphers, cipherName) {
+ msg := fmt.Sprintf("TLS Bad Cipher Suite: %s", cipherName)
+ return c.NewIssue(ident, t.ID(), msg, issue.High, issue.High)
}
}
}
@@ -64,176 +66,238 @@ func (t *insecureConfigTLS) processTLSCipherSuites(n ast.Node, c *gosec.Context)
return nil
}
-func (t *insecureConfigTLS) processTLSConf(n ast.Node, c *gosec.Context) *issue.Issue {
- if kve, ok := n.(*ast.KeyValueExpr); ok {
- issue := t.processTLSConfVal(kve.Key, kve.Value, c)
- if issue != nil {
- return issue
- }
- } else if assign, ok := n.(*ast.AssignStmt); ok {
- if len(assign.Lhs) < 1 || len(assign.Rhs) < 1 {
- return nil
- }
- if selector, ok := assign.Lhs[0].(*ast.SelectorExpr); ok {
- issue := t.processTLSConfVal(selector.Sel, assign.Rhs[0], c)
- if issue != nil {
- return issue
+func (t *insecureConfigTLS) resolveTLSVersion(expr ast.Expr, c *gosec.Context) int64 {
+ if val, err := gosec.GetInt(expr); err == nil {
+ return val
+ }
+
+ if se, ok := expr.(*ast.SelectorExpr); ok {
+ if x, ok := se.X.(*ast.Ident); ok {
+ if ip, ok := gosec.GetImportPath(x.Name, c); ok && ip == "crypto/tls" {
+ return t.mapVersion(se.Sel.Name)
}
}
}
- return nil
-}
-func (t *insecureConfigTLS) processTLSConfVal(key ast.Expr, value ast.Expr, c *gosec.Context) *issue.Issue {
- if ident, ok := key.(*ast.Ident); ok {
- switch ident.Name {
- case "InsecureSkipVerify":
- if node, ok := value.(*ast.Ident); ok {
- if node.Name != "false" {
- return c.NewIssue(value, t.ID(), "TLS InsecureSkipVerify set true.", issue.High, issue.High)
+ if id, ok := expr.(*ast.Ident); ok {
+ obj := c.Info.ObjectOf(id)
+ if obj != nil {
+ init := t.findDefinition(obj, c)
+ if init != nil {
+ if val, err := gosec.GetInt(init); err == nil {
+ return val
+ }
+ if se, ok := init.(*ast.SelectorExpr); ok {
+ if x, ok := se.X.(*ast.Ident); ok {
+ if ip, ok := gosec.GetImportPath(x.Name, c); ok && ip == "crypto/tls" {
+ return t.mapVersion(se.Sel.Name)
+ }
+ }
}
- } else {
- // TODO(tk): symbol tab look up to get the actual value
- return c.NewIssue(value, t.ID(), "TLS InsecureSkipVerify may be true.", issue.High, issue.Low)
}
+ }
+ }
- case "PreferServerCipherSuites":
- if node, ok := value.(*ast.Ident); ok {
- if node.Name == "false" {
- return c.NewIssue(value, t.ID(), "TLS PreferServerCipherSuites set false.", issue.Medium, issue.High)
- }
- } else {
- // TODO(tk): symbol tab look up to get the actual value
- return c.NewIssue(value, t.ID(), "TLS PreferServerCipherSuites may be false.", issue.Medium, issue.Low)
+ return 0 // unknown / unresolved
+}
+
+func (t *insecureConfigTLS) resolveBoolConst(expr ast.Expr, c *gosec.Context) (bool, bool) {
+ if id, ok := expr.(*ast.Ident); ok {
+ if id.Name == "true" {
+ return true, true
+ }
+ if id.Name == "false" {
+ return false, true
+ }
+ }
+
+ if u, ok := expr.(*ast.UnaryExpr); ok && u.Op == token.NOT {
+ if op, ok := u.X.(*ast.Ident); ok {
+ if op.Name == "true" {
+ return false, true
+ }
+ if op.Name == "false" {
+ return true, true
}
+ }
+ }
- case "MinVersion":
- if d, ok := value.(*ast.Ident); ok {
- obj := d.Obj
- if obj == nil {
- for _, f := range c.PkgFiles {
- obj = f.Scope.Lookup(d.Name)
- if obj != nil {
- break
- }
- }
- }
- if vs, ok := obj.Decl.(*ast.ValueSpec); ok && len(vs.Values) > 0 {
- if s, ok := vs.Values[0].(*ast.SelectorExpr); ok {
- x := s.X.(*ast.Ident).Name
- sel := s.Sel.Name
-
- for _, imp := range c.Pkg.Imports() {
- if imp.Name() == x {
- tObj := imp.Scope().Lookup(sel)
- if cst, ok := tObj.(*types.Const); ok {
- // ..got the value check if this can be translated
- if minVersion, err := strconv.ParseInt(cst.Val().String(), 0, 64); err == nil {
- t.actualMinVersion = minVersion
- }
- }
- }
- }
+ if id, ok := expr.(*ast.Ident); ok {
+ obj := c.Info.ObjectOf(id)
+ if obj != nil {
+ init := t.findDefinition(obj, c)
+ if init != nil {
+ if iid, ok := init.(*ast.Ident); ok {
+ if iid.Name == "true" {
+ return true, true
}
- if ival, ierr := gosec.GetInt(vs.Values[0]); ierr == nil {
- t.actualMinVersion = ival
+ if iid.Name == "false" {
+ return false, true
}
}
- } else if ival, ierr := gosec.GetInt(value); ierr == nil {
- t.actualMinVersion = ival
- } else {
- if se, ok := value.(*ast.SelectorExpr); ok {
- if pkg, ok := se.X.(*ast.Ident); ok {
- if ip, ok := gosec.GetImportPath(pkg.Name, c); ok && ip == "crypto/tls" {
- t.actualMinVersion = t.mapVersion(se.Sel.Name)
+ if uu, ok := init.(*ast.UnaryExpr); ok && uu.Op == token.NOT {
+ if op, ok := uu.X.(*ast.Ident); ok {
+ if op.Name == "true" {
+ return false, true
+ }
+ if op.Name == "false" {
+ return true, true
}
}
}
}
+ }
+ }
- case "MaxVersion":
- if ival, ierr := gosec.GetInt(value); ierr == nil {
- t.actualMaxVersion = ival
- } else {
- if se, ok := value.(*ast.SelectorExpr); ok {
- if pkg, ok := se.X.(*ast.Ident); ok {
- if ip, ok := gosec.GetImportPath(pkg.Name, c); ok && ip == "crypto/tls" {
- t.actualMaxVersion = t.mapVersion(se.Sel.Name)
- }
- }
- }
+ return false, false // unknown
+}
+
+func (t *insecureConfigTLS) processTLSConfVal(key ast.Expr, value ast.Expr, c *gosec.Context) *issue.Issue {
+ if ident, ok := key.(*ast.Ident); ok {
+ switch ident.Name {
+ case "InsecureSkipVerify":
+ val, known := t.resolveBoolConst(value, c)
+ if known && val {
+ return c.NewIssue(value, t.ID(), "TLS InsecureSkipVerify set to true.", issue.High, issue.High)
+ }
+ if !known {
+ return c.NewIssue(value, t.ID(), "TLS InsecureSkipVerify may be set to true.", issue.High, issue.Low)
}
- case "CipherSuites":
- if ret := t.processTLSCipherSuites(value, c); ret != nil {
- return ret
+ case "PreferServerCipherSuites":
+ val, known := t.resolveBoolConst(value, c)
+ if known && !val {
+ return c.NewIssue(value, t.ID(), "TLS PreferServerCipherSuites set to false.", issue.Medium, issue.High)
}
+ if !known {
+ return c.NewIssue(value, t.ID(), "TLS PreferServerCipherSuites may be set to false.", issue.Medium, issue.Low)
+ }
+
+ case "MinVersion":
+ t.minVersionSet = true
+ t.actualMinVersion = t.resolveTLSVersion(value, c)
+ case "MaxVersion":
+ t.maxVersionSet = true
+ t.actualMaxVersion = t.resolveTLSVersion(value, c)
+
+ case "CipherSuites":
+ return t.processTLSCipherSuites(value, c)
}
}
return nil
}
-func (t *insecureConfigTLS) mapVersion(version string) int64 {
- var v int64
- switch version {
- case "VersionTLS13":
- v = tls.VersionTLS13
- case "VersionTLS12":
- v = tls.VersionTLS12
- case "VersionTLS11":
- v = tls.VersionTLS11
- case "VersionTLS10":
- v = tls.VersionTLS10
+func (t *insecureConfigTLS) processTLSConf(n ast.Node, c *gosec.Context) *issue.Issue {
+ if kve, ok := n.(*ast.KeyValueExpr); ok {
+ return t.processTLSConfVal(kve.Key, kve.Value, c)
}
- return v
+
+ if assign, ok := n.(*ast.AssignStmt); ok {
+ if len(assign.Lhs) < 1 || len(assign.Rhs) < 1 {
+ return nil
+ }
+ if selector, ok := assign.Lhs[0].(*ast.SelectorExpr); ok {
+ return t.processTLSConfVal(selector.Sel, assign.Rhs[0], c)
+ }
+ }
+ return nil
}
-func (t *insecureConfigTLS) checkVersion(n ast.Node, c *gosec.Context) *issue.Issue {
- if t.actualMaxVersion == 0 && t.actualMinVersion >= t.MinVersion {
- // no warning is generated since the min version is greater than the secure min version
+func (t *insecureConfigTLS) findDefinition(obj types.Object, c *gosec.Context) ast.Expr {
+ file := gosec.ContainingFile(obj, c)
+ if file == nil {
return nil
}
- if t.actualMinVersion < t.MinVersion {
+
+ var initializer ast.Expr
+ ast.Inspect(file, func(n ast.Node) bool {
+ if initializer != nil {
+ return false
+ }
+ switch n := n.(type) {
+ case *ast.ValueSpec:
+ for i, name := range n.Names {
+ if name.Pos() == obj.Pos() && i < len(n.Values) {
+ initializer = n.Values[i]
+ return false
+ }
+ }
+ case *ast.AssignStmt:
+ for i, lhs := range n.Lhs {
+ if id, ok := lhs.(*ast.Ident); ok && id.Pos() == obj.Pos() && i < len(n.Rhs) {
+ initializer = n.Rhs[i]
+ return false
+ }
+ }
+ }
+ return true
+ })
+ return initializer
+}
+
+func (t *insecureConfigTLS) isSafeDefault() bool {
+ major, minor, _ := gosec.GoVersion()
+ return major > 1 || (major == 1 && minor >= 18)
+}
+
+func (t *insecureConfigTLS) checkVersion(n ast.Node, c *gosec.Context) *issue.Issue {
+ // Flag explicitly low MinVersion.
+ // Since Go 1.18+, MinVersion 0 means "use default" which is
+ // TLS 1.2 — safe and not worth flagging.
+ if t.minVersionSet && t.actualMinVersion < t.MinVersion {
+ if t.actualMinVersion == 0 && t.isSafeDefault() {
+ return nil
+ }
return c.NewIssue(n, t.ID(), "TLS MinVersion too low.", issue.High, issue.High)
}
- if t.actualMaxVersion < t.MaxVersion {
- return c.NewIssue(n, t.ID(), "TLS MaxVersion too low.", issue.High, issue.High)
+
+ // Handle MaxVersion.
+ // MaxVersion 0 means "use latest" which is always safe.
+ if t.maxVersionSet {
+ if t.actualMaxVersion == 0 {
+ return nil
+ }
+ if t.actualMaxVersion < t.MaxVersion {
+ return c.NewIssue(n, t.ID(), "TLS MaxVersion too low.", issue.High, issue.High)
+ }
}
+
return nil
}
func (t *insecureConfigTLS) resetVersion() {
- t.actualMaxVersion = 0
t.actualMinVersion = 0
+ t.actualMaxVersion = 0
+ t.minVersionSet = false
+ t.maxVersionSet = false
}
func (t *insecureConfigTLS) Match(n ast.Node, c *gosec.Context) (*issue.Issue, error) {
if complit, ok := n.(*ast.CompositeLit); ok && complit.Type != nil {
actualType := c.Info.TypeOf(complit.Type)
if actualType != nil && actualType.String() == t.requiredType {
+ defer t.resetVersion()
for _, elt := range complit.Elts {
- issue := t.processTLSConf(elt, c)
- if issue != nil {
+ if issue := t.processTLSConf(elt, c); issue != nil {
return issue, nil
}
}
- issue := t.checkVersion(complit, c)
- t.resetVersion()
- return issue, nil
- }
- } else {
- if assign, ok := n.(*ast.AssignStmt); ok && len(assign.Lhs) > 0 {
- if selector, ok := assign.Lhs[0].(*ast.SelectorExpr); ok {
- actualType := c.Info.TypeOf(selector.X)
- if actualType != nil && actualType.String() == t.requiredType {
- issue := t.processTLSConf(assign, c)
- if issue != nil {
- return issue, nil
- }
- }
+ if issue := t.checkVersion(complit, c); issue != nil {
+ return issue, nil
}
+ return nil, nil
}
}
+
+ if assign, ok := n.(*ast.AssignStmt); ok && len(assign.Lhs) > 0 {
+ if selector, ok := assign.Lhs[0].(*ast.SelectorExpr); ok {
+ actualType := c.Info.TypeOf(selector.X)
+ if actualType != nil && actualType.String() == t.requiredType {
+ return t.processTLSConf(assign, c), nil
+ }
+ }
+ }
+
return nil, nil
}
diff --git a/vendor/github.com/securego/gosec/v2/rules/tls_config.go b/vendor/github.com/securego/gosec/v2/rules/tls_config.go
index cbbdf7983..d71bd0da8 100644
--- a/vendor/github.com/securego/gosec/v2/rules/tls_config.go
+++ b/vendor/github.com/securego/gosec/v2/rules/tls_config.go
@@ -9,9 +9,9 @@ import (
// NewModernTLSCheck creates a check for Modern TLS ciphers
// DO NOT EDIT - generated by tlsconfig tool
-func NewModernTLSCheck(id string, _ gosec.Config) (gosec.Rule, []ast.Node) {
+func NewModernTLSCheck(id string, conf gosec.Config) (gosec.Rule, []ast.Node) {
return &insecureConfigTLS{
- MetaData: issue.MetaData{ID: id},
+ MetaData: issue.MetaData{RuleID: id},
requiredType: "crypto/tls.Config",
MinVersion: 0x0304,
MaxVersion: 0x0304,
@@ -25,9 +25,9 @@ func NewModernTLSCheck(id string, _ gosec.Config) (gosec.Rule, []ast.Node) {
// NewIntermediateTLSCheck creates a check for Intermediate TLS ciphers
// DO NOT EDIT - generated by tlsconfig tool
-func NewIntermediateTLSCheck(id string, _ gosec.Config) (gosec.Rule, []ast.Node) {
+func NewIntermediateTLSCheck(id string, conf gosec.Config) (gosec.Rule, []ast.Node) {
return &insecureConfigTLS{
- MetaData: issue.MetaData{ID: id},
+ MetaData: issue.MetaData{RuleID: id},
requiredType: "crypto/tls.Config",
MinVersion: 0x0303,
MaxVersion: 0x0304,
@@ -51,9 +51,9 @@ func NewIntermediateTLSCheck(id string, _ gosec.Config) (gosec.Rule, []ast.Node)
// NewOldTLSCheck creates a check for Old TLS ciphers
// DO NOT EDIT - generated by tlsconfig tool
-func NewOldTLSCheck(id string, _ gosec.Config) (gosec.Rule, []ast.Node) {
+func NewOldTLSCheck(id string, conf gosec.Config) (gosec.Rule, []ast.Node) {
return &insecureConfigTLS{
- MetaData: issue.MetaData{ID: id},
+ MetaData: issue.MetaData{RuleID: id},
requiredType: "crypto/tls.Config",
MinVersion: 0x0301,
MaxVersion: 0x0304,
diff --git a/vendor/github.com/securego/gosec/v2/rules/trojansource.go b/vendor/github.com/securego/gosec/v2/rules/trojansource.go
index e2765d269..aebac99ba 100644
--- a/vendor/github.com/securego/gosec/v2/rules/trojansource.go
+++ b/vendor/github.com/securego/gosec/v2/rules/trojansource.go
@@ -13,10 +13,6 @@ type trojanSource struct {
bidiChars map[rune]struct{}
}
-func (r *trojanSource) ID() string {
- return r.MetaData.ID
-}
-
func (r *trojanSource) Match(node ast.Node, c *gosec.Context) (*issue.Issue, error) {
if file, ok := node.(*ast.File); ok {
fobj := c.FileSet.File(file.Pos())
@@ -73,12 +69,7 @@ func (r *trojanSource) Match(node ast.Node, c *gosec.Context) (*issue.Issue, err
func NewTrojanSource(id string, _ gosec.Config) (gosec.Rule, []ast.Node) {
return &trojanSource{
- MetaData: issue.MetaData{
- ID: id,
- Severity: issue.High,
- Confidence: issue.Medium,
- What: "Potential Trojan Source vulnerability via use of bidirectional text control characters",
- },
+ MetaData: issue.NewMetaData(id, "Potential Trojan Source vulnerability via use of bidirectional text control characters", issue.High, issue.Medium),
bidiChars: map[rune]struct{}{
'\u202a': {},
'\u202b': {},
diff --git a/vendor/github.com/securego/gosec/v2/rules/unsafe.go b/vendor/github.com/securego/gosec/v2/rules/unsafe.go
index 2e2adca7c..eab891af8 100644
--- a/vendor/github.com/securego/gosec/v2/rules/unsafe.go
+++ b/vendor/github.com/securego/gosec/v2/rules/unsafe.go
@@ -22,33 +22,15 @@ import (
)
type usingUnsafe struct {
- issue.MetaData
- pkg string
- calls []string
-}
-
-func (r *usingUnsafe) ID() string {
- return r.MetaData.ID
-}
-
-func (r *usingUnsafe) Match(n ast.Node, c *gosec.Context) (gi *issue.Issue, err error) {
- if _, matches := gosec.MatchCallByPackage(n, c, r.pkg, r.calls...); matches {
- return c.NewIssue(n, r.ID(), r.What, r.Severity, r.Confidence), nil
- }
- return nil, nil
+ callListRule
}
// NewUsingUnsafe rule detects the use of the unsafe package. This is only
// really useful for auditing purposes.
func NewUsingUnsafe(id string, _ gosec.Config) (gosec.Rule, []ast.Node) {
- return &usingUnsafe{
- pkg: "unsafe",
- calls: []string{"Pointer", "String", "StringData", "Slice", "SliceData"},
- MetaData: issue.MetaData{
- ID: id,
- What: "Use of unsafe calls should be audited",
- Severity: issue.Low,
- Confidence: issue.High,
- },
- }, []ast.Node{(*ast.CallExpr)(nil)}
+ rule := &usingUnsafe{
+ callListRule: newCallListRule(id, "Use of unsafe calls should be audited", issue.Low, issue.High),
+ }
+ rule.AddAll("unsafe", "Pointer", "String", "StringData", "Slice", "SliceData")
+ return rule, []ast.Node{(*ast.CallExpr)(nil)}
}
diff --git a/vendor/github.com/securego/gosec/v2/rules/weakcrypto.go b/vendor/github.com/securego/gosec/v2/rules/weakcrypto.go
index 143f67d4e..879997fa9 100644
--- a/vendor/github.com/securego/gosec/v2/rules/weakcrypto.go
+++ b/vendor/github.com/securego/gosec/v2/rules/weakcrypto.go
@@ -21,37 +21,27 @@ import (
"github.com/securego/gosec/v2/issue"
)
-type usesWeakCryptographyEncryption struct {
- issue.MetaData
- blocklist map[string][]string
+type weakCryptoUsage struct {
+ callListRule
}
-func (r *usesWeakCryptographyEncryption) ID() string {
- return r.MetaData.ID
+// NewUsesWeakCryptographyHash detects uses of md5.*, sha1.* (G401)
+func NewUsesWeakCryptographyHash(id string, _ gosec.Config) (gosec.Rule, []ast.Node) {
+ rule := &weakCryptoUsage{newCallListRule(id, "Use of weak cryptographic primitive", issue.Medium, issue.High)}
+ rule.AddAll("crypto/md5", "New", "Sum").AddAll("crypto/sha1", "New", "Sum")
+ return rule, []ast.Node{(*ast.CallExpr)(nil)}
}
-func (r *usesWeakCryptographyEncryption) Match(n ast.Node, c *gosec.Context) (*issue.Issue, error) {
- for pkg, funcs := range r.blocklist {
- if _, matched := gosec.MatchCallByPackage(n, c, pkg, funcs...); matched {
- return c.NewIssue(n, r.ID(), r.What, r.Severity, r.Confidence), nil
- }
- }
- return nil, nil
+// NewUsesWeakCryptographyEncryption detects uses of des.*, rc4.* (G405)
+func NewUsesWeakCryptographyEncryption(id string, _ gosec.Config) (gosec.Rule, []ast.Node) {
+ rule := &weakCryptoUsage{newCallListRule(id, "Use of weak cryptographic primitive", issue.Medium, issue.High)}
+ rule.AddAll("crypto/des", "NewCipher", "NewTripleDESCipher").Add("crypto/rc4", "NewCipher")
+ return rule, []ast.Node{(*ast.CallExpr)(nil)}
}
-// NewUsesWeakCryptographyEncryption detects uses of des.*, rc4.*
-func NewUsesWeakCryptographyEncryption(id string, _ gosec.Config) (gosec.Rule, []ast.Node) {
- calls := make(map[string][]string)
- calls["crypto/des"] = []string{"NewCipher", "NewTripleDESCipher"}
- calls["crypto/rc4"] = []string{"NewCipher"}
- rule := &usesWeakCryptographyEncryption{
- blocklist: calls,
- MetaData: issue.MetaData{
- ID: id,
- Severity: issue.Medium,
- Confidence: issue.High,
- What: "Use of weak cryptographic primitive",
- },
- }
+// NewUsesWeakDeprecatedCryptographyHash detects uses of md4.New, ripemd160.New (G406)
+func NewUsesWeakDeprecatedCryptographyHash(id string, _ gosec.Config) (gosec.Rule, []ast.Node) {
+ rule := &weakCryptoUsage{newCallListRule(id, "Use of deprecated weak cryptographic primitive", issue.Medium, issue.High)}
+ rule.Add("golang.org/x/crypto/md4", "New").Add("golang.org/x/crypto/ripemd160", "New")
return rule, []ast.Node{(*ast.CallExpr)(nil)}
}
diff --git a/vendor/github.com/securego/gosec/v2/rules/weakcryptohash.go b/vendor/github.com/securego/gosec/v2/rules/weakcryptohash.go
deleted file mode 100644
index 298555de1..000000000
--- a/vendor/github.com/securego/gosec/v2/rules/weakcryptohash.go
+++ /dev/null
@@ -1,55 +0,0 @@
-// 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 rules
-
-import (
- "go/ast"
-
- "github.com/securego/gosec/v2"
- "github.com/securego/gosec/v2/issue"
-)
-
-type usesWeakCryptographyHash struct {
- issue.MetaData
- blocklist map[string][]string
-}
-
-func (r *usesWeakCryptographyHash) ID() string {
- return r.MetaData.ID
-}
-
-func (r *usesWeakCryptographyHash) Match(n ast.Node, c *gosec.Context) (*issue.Issue, error) {
- for pkg, funcs := range r.blocklist {
- if _, matched := gosec.MatchCallByPackage(n, c, pkg, funcs...); matched {
- return c.NewIssue(n, r.ID(), r.What, r.Severity, r.Confidence), nil
- }
- }
- return nil, nil
-}
-
-// NewUsesWeakCryptographyHash detects uses of md5.*, sha1.*
-func NewUsesWeakCryptographyHash(id string, _ gosec.Config) (gosec.Rule, []ast.Node) {
- calls := make(map[string][]string)
- calls["crypto/md5"] = []string{"New", "Sum"}
- calls["crypto/sha1"] = []string{"New", "Sum"}
- rule := &usesWeakCryptographyHash{
- blocklist: calls,
- MetaData: issue.MetaData{
- ID: id,
- Severity: issue.Medium,
- Confidence: issue.High,
- What: "Use of weak cryptographic primitive",
- },
- }
- return rule, []ast.Node{(*ast.CallExpr)(nil)}
-}
diff --git a/vendor/github.com/securego/gosec/v2/rules/weakdepricatedcryptohash.go b/vendor/github.com/securego/gosec/v2/rules/weakdepricatedcryptohash.go
deleted file mode 100644
index 68297355c..000000000
--- a/vendor/github.com/securego/gosec/v2/rules/weakdepricatedcryptohash.go
+++ /dev/null
@@ -1,57 +0,0 @@
-// (c) Copyright 2024 Mercedes-Benz Tech Innovation GmbH
-//
-// 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 rules
-
-import (
- "go/ast"
-
- "github.com/securego/gosec/v2"
- "github.com/securego/gosec/v2/issue"
-)
-
-type usesWeakDeprecatedCryptographyHash struct {
- issue.MetaData
- blocklist map[string][]string
-}
-
-func (r *usesWeakDeprecatedCryptographyHash) ID() string {
- return r.MetaData.ID
-}
-
-func (r *usesWeakDeprecatedCryptographyHash) Match(n ast.Node, c *gosec.Context) (*issue.Issue, error) {
- for pkg, funcs := range r.blocklist {
- if _, matched := gosec.MatchCallByPackage(n, c, pkg, funcs...); matched {
- return c.NewIssue(n, r.ID(), r.What, r.Severity, r.Confidence), nil
- }
- }
- return nil, nil
-}
-
-// NewUsesWeakCryptographyHash detects uses of md4.New, ripemd160.New
-func NewUsesWeakDeprecatedCryptographyHash(id string, _ gosec.Config) (gosec.Rule, []ast.Node) {
- calls := make(map[string][]string)
- calls["golang.org/x/crypto/md4"] = []string{"New"}
- calls["golang.org/x/crypto/ripemd160"] = []string{"New"}
- rule := &usesWeakDeprecatedCryptographyHash{
- blocklist: calls,
- MetaData: issue.MetaData{
- ID: id,
- Severity: issue.Medium,
- Confidence: issue.High,
- What: "Use of deprecated weak cryptographic primitive",
- },
- }
- return rule, []ast.Node{(*ast.CallExpr)(nil)}
-}
diff --git a/vendor/github.com/securego/gosec/v2/taint/analyzer.go b/vendor/github.com/securego/gosec/v2/taint/analyzer.go
new file mode 100644
index 000000000..63640177b
--- /dev/null
+++ b/vendor/github.com/securego/gosec/v2/taint/analyzer.go
@@ -0,0 +1,147 @@
+package taint
+
+import (
+ "fmt"
+ "go/token"
+ "os"
+ "strconv"
+
+ "golang.org/x/tools/go/analysis"
+ "golang.org/x/tools/go/analysis/passes/buildssa"
+ "golang.org/x/tools/go/ssa"
+
+ "github.com/securego/gosec/v2/internal/ssautil"
+ "github.com/securego/gosec/v2/issue"
+)
+
+// RuleInfo holds metadata about a taint analysis rule.
+type RuleInfo struct {
+ ID string
+ Description string
+ Severity string
+ CWE string
+}
+
+// NewGosecAnalyzer creates a golang.org/x/tools/go/analysis.Analyzer
+// compatible with gosec's analyzer framework.
+func NewGosecAnalyzer(rule *RuleInfo, config *Config) *analysis.Analyzer {
+ return &analysis.Analyzer{
+ Name: rule.ID,
+ Doc: rule.Description,
+ Run: makeAnalyzerRunner(rule, config),
+ Requires: []*analysis.Analyzer{buildssa.Analyzer},
+ }
+}
+
+// makeAnalyzerRunner creates the run function for an analyzer.
+func makeAnalyzerRunner(rule *RuleInfo, config *Config) func(*analysis.Pass) (interface{}, error) {
+ return func(pass *analysis.Pass) (interface{}, error) {
+ // Get SSA result using shared helper (same as G602, G115, G407)
+ ssaResult, err := ssautil.GetSSAResult(pass)
+ if err != nil {
+ return nil, fmt.Errorf("taint analysis %s: failed to get SSA result: %w", rule.ID, err)
+ }
+
+ // Collect source functions (filter out nil)
+ var srcFuncs []*ssa.Function
+ for _, fn := range ssaResult.SSA.SrcFuncs {
+ if fn != nil {
+ srcFuncs = append(srcFuncs, fn)
+ }
+ }
+
+ if len(srcFuncs) == 0 {
+ return nil, nil // No functions to analyze - this is OK
+ }
+
+ // Run taint analysis
+ analyzer := New(config)
+ if ssaResult.Shared != nil {
+ analyzer.SetCallGraph(ssaResult.Shared.CallGraph())
+ }
+ results := analyzer.Analyze(srcFuncs[0].Prog, srcFuncs)
+
+ // Convert results to gosec issues
+ var issues []*issue.Issue
+ for _, result := range results {
+ // Map severity string to issue.Score
+ var severity issue.Score
+ switch rule.Severity {
+ case "LOW":
+ severity = issue.Low
+ case "MEDIUM":
+ severity = issue.Medium
+ case "HIGH":
+ severity = issue.High
+ case "CRITICAL":
+ severity = issue.High // gosec uses High for critical
+ default:
+ severity = issue.Medium
+ }
+
+ // Create gosec issue using the standard helper
+ newIssue := newIssue(
+ rule.ID,
+ rule.Description,
+ pass.Fset,
+ result.SinkPos,
+ severity,
+ issue.High, // confidence
+ )
+
+ issues = append(issues, newIssue)
+
+ // Report to analysis pass (for use with go vet style tools)
+ pass.Reportf(result.SinkPos, "%s: %s", rule.ID, rule.Description)
+ }
+
+ if len(issues) > 0 {
+ return issues, nil
+ }
+ return nil, nil
+ }
+}
+
+// newIssue creates a new gosec issue
+func newIssue(analyzerID string, desc string, fileSet *token.FileSet,
+ pos token.Pos, severity, confidence issue.Score,
+) *issue.Issue {
+ file := fileSet.File(pos)
+ if file == nil {
+ return &issue.Issue{}
+ }
+ line := file.Line(pos)
+ col := file.Position(pos).Column
+
+ return &issue.Issue{
+ RuleID: analyzerID,
+ File: file.Name(),
+ Line: strconv.Itoa(line),
+ Col: strconv.Itoa(col),
+ Severity: severity,
+ Confidence: confidence,
+ What: desc,
+ Cwe: issue.GetCweByRule(analyzerID),
+ Code: issueCodeSnippet(fileSet, pos),
+ }
+}
+
+func issueCodeSnippet(fileSet *token.FileSet, pos token.Pos) string {
+ file := fileSet.File(pos)
+ start := (int64)(file.Line(pos))
+ if start-issue.SnippetOffset > 0 {
+ start = start - issue.SnippetOffset
+ }
+ end := (int64)(file.Line(pos))
+ end = end + issue.SnippetOffset
+
+ var code string
+ if f, err := os.Open(file.Name()); err == nil {
+ defer f.Close() // #nosec
+ code, err = issue.CodeSnippet(f, start, end)
+ if err != nil {
+ return err.Error()
+ }
+ }
+ return code
+}
diff --git a/vendor/github.com/securego/gosec/v2/taint/taint.go b/vendor/github.com/securego/gosec/v2/taint/taint.go
new file mode 100644
index 000000000..fab64ccc4
--- /dev/null
+++ b/vendor/github.com/securego/gosec/v2/taint/taint.go
@@ -0,0 +1,1545 @@
+// Package taint provides a minimal taint analysis engine for gosec.
+// It tracks data flow from sources (user input) to sinks (dangerous functions)
+// using SSA form and call graph analysis.
+//
+// This implementation uses only golang.org/x/tools packages which gosec
+// already depends on - no external dependencies required.
+//
+// Inspired by:
+// - github.com/google/capslock (call graph traversal pattern)
+// - gosec issue #1160 (requirements)
+package taint
+
+import (
+ "go/token"
+ "go/types"
+ "strings"
+
+ "golang.org/x/tools/go/callgraph"
+ "golang.org/x/tools/go/callgraph/cha"
+ "golang.org/x/tools/go/ssa"
+)
+
+// maxTaintDepth limits recursion depth to prevent stack overflow on large codebases
+const maxTaintDepth = 50
+
+// maxCallerEdges caps the number of incoming call graph edges examined per function
+// in isParameterTainted. CHA over-approximates call graphs (every interface method
+// call fans out to ALL implementations), so a function can have thousands of callers.
+// Real taint flows come from direct/nearby callers, not the 33rd+ CHA-generated edge.
+const maxCallerEdges = 32
+
+// isContextType checks if a type is context.Context.
+// context.Context is a control-flow mechanism (deadlines, cancellation, request-scoped values)
+// that does not carry user-controlled data relevant to taint sinks like XSS.
+// Tainted context arguments (e.g., request.Context()) should not propagate taint
+// to function return values, as the context doesn't flow as data to the output.
+func isContextType(t types.Type) bool {
+ // Unwrap pointer layers (e.g., *context.Context) to reach the named type.
+ for {
+ ptr, ok := t.(*types.Pointer)
+ if !ok {
+ break
+ }
+ t = ptr.Elem()
+ }
+ named, ok := t.(*types.Named)
+ if !ok {
+ return false
+ }
+ obj := named.Obj()
+ return obj != nil && obj.Pkg() != nil && obj.Pkg().Path() == "context" && obj.Name() == "Context"
+}
+
+// Source defines where tainted data originates.
+// Format: "package/path.TypeOrFunc" or "*package/path.Type" for pointer types.
+type Source struct {
+ // Package is the import path of the package containing the source (e.g., "net/http")
+ Package string
+ // Name is the type or function name that produces tainted data (e.g., "Request" for type, "Get" for function)
+ Name string
+ // Pointer indicates whether the source is a pointer type (true for *Type)
+ Pointer bool
+ // IsFunc marks this source as a function/method that returns tainted data
+ // (e.g., os.Getenv, os.ReadFile). When false, Source is treated as a type
+ // that is only tainted when received as a function parameter from external callers.
+ IsFunc bool
+}
+
+// Sink defines a dangerous function that should not receive tainted data.
+// Format: "(*package/path.Type).Method" or "package/path.Func"
+type Sink struct {
+ // Package is the import path of the package containing the sink (e.g., "database/sql")
+ Package string
+ // Receiver is the type name for methods (e.g., "DB"), or empty for package-level functions
+ Receiver string
+ // Method is the function or method name that represents the sink (e.g., "Query")
+ Method string
+ // Pointer indicates whether the receiver is a pointer type (true for *Type methods)
+ Pointer bool
+ // CheckArgs specifies which argument positions to check for taint (0-indexed).
+ // For method calls, Args[0] is the receiver.
+ // If nil or empty, all arguments are checked.
+ // Examples:
+ // - SQL methods: [1] - only check query string (Args[1]), skip receiver
+ // - fmt.Fprintf: [1,2,3,...] - skip writer (Args[0]), check format and data
+ CheckArgs []int
+
+ // ArgTypeGuards constrains argument types before treating a call as a sink.
+ // Key is the zero-based argument index; value is the required type expressed
+ // as "import/path.TypeName" (e.g. "net/http.ResponseWriter").
+ // The sink only fires when every guarded argument's type implements (or equals)
+ // the named interface/type. When empty, no type constraint is applied.
+ ArgTypeGuards map[int]string
+}
+
+// resolveOriginalType traces back through SSA interface-conversion instructions
+// (ChangeInterface, MakeInterface) to recover the original value's type before
+// any implicit widening to a broader interface (e.g. http.ResponseWriter → io.Writer).
+func resolveOriginalType(v ssa.Value) types.Type {
+ switch val := v.(type) {
+ case *ssa.ChangeInterface:
+ // ChangeInterface converts one interface type to another; trace through.
+ return resolveOriginalType(val.X)
+ case *ssa.MakeInterface:
+ // MakeInterface boxes a concrete value into an interface; return the
+ // concrete type (val.X.Type()), not the interface type.
+ return val.X.Type()
+ }
+ return v.Type()
+}
+
+// guardsSatisfied returns true when every ArgTypeGuard declared in sink is
+// satisfied by the concrete SSA argument types present in args.
+//
+// Interface guards are checked with types.Implements (handles pointer receivers
+// and embedding). Concrete-type guards require exact types.Identical match.
+// When sink.ArgTypeGuards is nil or empty the function always returns true.
+//
+// Argument types are resolved through ChangeInterface/MakeInterface so that
+// an http.ResponseWriter passed where io.Writer is expected is still recognised
+// as implementing http.ResponseWriter.
+func guardsSatisfied(args []ssa.Value, sink Sink, prog *ssa.Program) bool {
+ if len(sink.ArgTypeGuards) == 0 {
+ return true
+ }
+ if prog == nil {
+ return true // no program to resolve types against; skip guard
+ }
+ for argIdx, requiredTypePath := range sink.ArgTypeGuards {
+ if argIdx >= len(args) {
+ return false
+ }
+ // Resolve back through implicit interface conversions.
+ argType := resolveOriginalType(args[argIdx])
+ required := lookupNamedType(requiredTypePath, prog)
+ if required == nil {
+ // Type not found in the program — the guard cannot be satisfied.
+ return false
+ }
+ iface, isIface := required.Underlying().(*types.Interface)
+ if isIface {
+ // Interface guard: accept if argType or *argType implements iface.
+ if !types.Implements(argType, iface) &&
+ !types.Implements(types.NewPointer(argType), iface) {
+ return false
+ }
+ } else {
+ // Concrete-type guard: require exact named-type identity.
+ if !types.Identical(argType, required) &&
+ !types.Identical(argType, types.NewPointer(required)) {
+ return false
+ }
+ }
+ }
+ return true
+}
+
+// lookupNamedType resolves a fully-qualified type string of the form
+// "import/path.TypeName" to a types.Type using the SSA program's package set.
+// Returns nil when the package or type name is not found.
+func lookupNamedType(typePath string, prog *ssa.Program) types.Type {
+ lastDot := strings.LastIndex(typePath, ".")
+ if lastDot < 0 {
+ return nil
+ }
+ pkgPath := typePath[:lastDot]
+ typeName := typePath[lastDot+1:]
+
+ for _, pkg := range prog.AllPackages() {
+ if pkg.Pkg == nil || pkg.Pkg.Path() != pkgPath {
+ continue
+ }
+ member := pkg.Pkg.Scope().Lookup(typeName)
+ if member == nil {
+ continue
+ }
+ if tn, ok := member.(*types.TypeName); ok {
+ return tn.Type()
+ }
+ }
+ return nil
+}
+
+// Sanitizer defines a function that neutralizes taint.
+// When tainted data passes through a sanitizer, it is no longer considered tainted.
+type Sanitizer struct {
+ // Package is the import path (e.g., "path/filepath")
+ Package string
+ // Receiver is the type name for methods, or empty for package-level functions
+ Receiver string
+ // Method is the function or method name (e.g., "Clean")
+ Method string
+ // Pointer indicates whether the receiver is a pointer type
+ Pointer bool
+}
+
+// Result represents a detected taint flow from source to sink.
+type Result struct {
+ // Source is the origin of the tainted data
+ Source Source
+ // Sink is the dangerous function that receives the tainted data
+ Sink Sink
+ // SinkPos is the source code position of the sink call
+ SinkPos token.Pos
+ // Path is the sequence of functions from entry point to the sink
+ Path []*ssa.Function
+}
+
+// Config holds taint analysis configuration.
+type Config struct {
+ // Sources is the list of data origins that produce tainted values
+ Sources []Source
+ // Sinks is the list of dangerous functions that should not receive tainted data
+ Sinks []Sink
+ // Sanitizers is the list of functions that neutralize taint (optional)
+ Sanitizers []Sanitizer
+}
+
+// Analyzer performs taint analysis on SSA programs.
+// paramKey identifies a specific parameter of a function for memoization.
+type paramKey struct {
+ fn *ssa.Function
+ paramIdx int
+}
+
+type Analyzer struct {
+ config *Config
+ sources map[string]Source // keyed by full type string
+ funcSrcs map[string]Source // function sources keyed by "pkg.Func"
+ sinks map[string]Sink // keyed by full function string
+ sanitizers map[string]struct{} // keyed by full function string
+ callGraph *callgraph.Graph
+ prog *ssa.Program // set at Analyze time for ArgTypeGuards resolution
+ paramTaintCache map[paramKey]bool // caches true results from isParameterTainted
+}
+
+// SetCallGraph injects a precomputed call graph.
+func (a *Analyzer) SetCallGraph(cg *callgraph.Graph) {
+ a.callGraph = cg
+}
+
+// New creates a new taint analyzer with the given configuration.
+func New(config *Config) *Analyzer {
+ a := &Analyzer{
+ config: config,
+ sources: make(map[string]Source),
+ funcSrcs: make(map[string]Source),
+ sinks: make(map[string]Sink),
+ sanitizers: make(map[string]struct{}),
+ }
+
+ // Index sources for fast lookup, separating type sources from function sources
+ for _, src := range config.Sources {
+ key := formatSourceKey(src)
+ a.sources[key] = src
+ if src.IsFunc {
+ a.funcSrcs[key] = src
+ }
+ }
+
+ // Index sinks for fast lookup
+ for _, sink := range config.Sinks {
+ key := formatSinkKey(sink)
+ a.sinks[key] = sink
+ }
+
+ // Index sanitizers for fast lookup
+ for _, san := range config.Sanitizers {
+ key := formatSanitizerKey(san)
+ a.sanitizers[key] = struct{}{}
+ }
+
+ return a
+}
+
+// formatSourceKey creates a lookup key for a source.
+func formatSourceKey(src Source) string {
+ key := src.Package + "." + src.Name
+ if src.Pointer {
+ key = "*" + key
+ }
+ return key
+}
+
+// formatSinkKey creates a lookup key for a sink.
+func formatSinkKey(sink Sink) string {
+ if sink.Receiver == "" {
+ return sink.Package + "." + sink.Method
+ }
+ recv := sink.Package + "." + sink.Receiver
+ if sink.Pointer {
+ recv = "*" + recv
+ }
+ return "(" + recv + ")." + sink.Method
+}
+
+// formatSanitizerKey creates a lookup key for a sanitizer.
+func formatSanitizerKey(san Sanitizer) string {
+ if san.Receiver == "" {
+ return san.Package + "." + san.Method
+ }
+ recv := san.Package + "." + san.Receiver
+ if san.Pointer {
+ recv = "*" + recv
+ }
+ return "(" + recv + ")." + san.Method
+}
+
+// Analyze performs taint analysis on the given SSA program.
+// It returns all detected taint flows from sources to sinks.
+func (a *Analyzer) Analyze(prog *ssa.Program, srcFuncs []*ssa.Function) []Result {
+ if len(srcFuncs) == 0 {
+ return nil
+ }
+
+ a.prog = prog
+
+ if a.callGraph == nil {
+ // Build call graph using Class Hierarchy Analysis (CHA).
+ // CHA is fast and sound (no false negatives) but may have false positives.
+ // For more precision, use VTA (Variable Type Analysis) instead.
+ a.callGraph = cha.CallGraph(prog)
+ }
+
+ a.paramTaintCache = make(map[paramKey]bool)
+
+ var results []Result
+
+ // Find all sink calls in the program
+ for _, fn := range srcFuncs {
+ results = append(results, a.analyzeFunctionSinks(fn)...)
+ }
+
+ a.paramTaintCache = nil
+
+ return results
+}
+
+// analyzeFunctionSinks finds sink calls in a function and traces taint.
+func (a *Analyzer) analyzeFunctionSinks(fn *ssa.Function) []Result {
+ if fn == nil || fn.Blocks == nil {
+ return nil
+ }
+
+ var results []Result
+
+ for _, block := range fn.Blocks {
+ for _, instr := range block.Instrs {
+ call, ok := instr.(*ssa.Call)
+ if !ok {
+ continue
+ }
+
+ // Check if this call is a sink
+ sink, isSink := a.isSinkCall(call)
+ if !isSink {
+ continue
+ }
+
+ // Apply ArgTypeGuards: skip this sink if argument type constraints
+ // are not satisfied (e.g. writer is not http.ResponseWriter).
+ if !guardsSatisfied(call.Call.Args, sink, a.prog) {
+ continue
+ }
+
+ // Determine which arguments to check for taint
+ var argsToCheck []ssa.Value
+
+ if len(sink.CheckArgs) > 0 {
+ // Sink specifies which argument positions to check
+ for _, idx := range sink.CheckArgs {
+ if idx < len(call.Call.Args) {
+ argsToCheck = append(argsToCheck, call.Call.Args[idx])
+ }
+ }
+ } else {
+ // No CheckArgs specified: check all arguments
+ argsToCheck = call.Call.Args
+ }
+
+ // Check if any of the specified arguments are tainted
+ for _, arg := range argsToCheck {
+ if a.isTainted(arg, fn, make(map[ssa.Value]bool), 0) {
+ results = append(results, Result{
+ Sink: sink,
+ SinkPos: call.Pos(),
+ Path: a.buildPath(fn),
+ })
+ break
+ }
+ }
+ }
+ }
+
+ return results
+}
+
+// isSinkCall checks if a call instruction is a sink and returns the sink info.
+func (a *Analyzer) isSinkCall(call *ssa.Call) (Sink, bool) {
+ // Try to get receiver info first (works for both concrete and interface calls)
+ var pkg, receiverName, methodName string
+ var isPointer bool
+
+ // Check for method call (invoke or static with receiver)
+ if call.Call.IsInvoke() {
+ // Interface method call - receiver is in Call.Value, not Args
+ if call.Call.Value != nil {
+ recvType := call.Call.Value.Type()
+ methodName = call.Call.Method.Name()
+
+ // For interface calls, the type is usually a Named type pointing to the interface
+ if named, ok := recvType.(*types.Named); ok {
+ receiverName = named.Obj().Name()
+ if pkgObj := named.Obj(); pkgObj != nil && pkgObj.Pkg() != nil {
+ pkg = pkgObj.Pkg().Path()
+ }
+ }
+
+ // Match against sinks (interface methods don't have Pointer field usually)
+ for _, sink := range a.sinks {
+ if sink.Package == pkg && sink.Receiver == receiverName && sink.Method == methodName {
+ return sink, true
+ }
+ }
+ }
+ }
+
+ // Try static callee (for non-interface method calls and functions)
+ callee := call.Call.StaticCallee()
+ if callee != nil {
+ if callee.Pkg != nil && callee.Pkg.Pkg != nil {
+ pkg = callee.Pkg.Pkg.Path()
+ }
+ methodName = callee.Name()
+
+ // Check if it has a receiver (method call)
+ if recv := callee.Signature.Recv(); recv != nil {
+ recvType := recv.Type()
+ if named, ok := recvType.(*types.Named); ok {
+ receiverName = named.Obj().Name()
+ }
+ if ptr, ok := recvType.(*types.Pointer); ok {
+ isPointer = true
+ if named, ok := ptr.Elem().(*types.Named); ok {
+ receiverName = named.Obj().Name()
+ }
+ }
+ }
+ }
+
+ // Match against configured sinks
+ for _, sink := range a.sinks {
+ // Package must match
+ if sink.Package != pkg {
+ continue
+ }
+
+ // For method sinks (with receiver)
+ if sink.Receiver != "" {
+ if sink.Receiver == receiverName && sink.Method == methodName && sink.Pointer == isPointer {
+ return sink, true
+ }
+ } else {
+ // For function sinks (no receiver)
+ if sink.Method == methodName && receiverName == "" {
+ return sink, true
+ }
+ }
+ }
+
+ return Sink{}, false
+}
+
+// isSanitizerCall checks if a call instruction is a sanitizer.
+func (a *Analyzer) isSanitizerCall(call *ssa.Call) bool {
+ if len(a.sanitizers) == 0 {
+ return false
+ }
+
+ callee := call.Call.StaticCallee()
+ if callee == nil {
+ return false
+ }
+
+ var pkg, receiverName, methodName string
+ var isPointer bool
+
+ if callee.Pkg != nil && callee.Pkg.Pkg != nil {
+ pkg = callee.Pkg.Pkg.Path()
+ }
+ methodName = callee.Name()
+
+ if recv := callee.Signature.Recv(); recv != nil {
+ recvType := recv.Type()
+ if named, ok := recvType.(*types.Named); ok {
+ receiverName = named.Obj().Name()
+ }
+ if ptr, ok := recvType.(*types.Pointer); ok {
+ isPointer = true
+ if named, ok := ptr.Elem().(*types.Named); ok {
+ receiverName = named.Obj().Name()
+ }
+ }
+ }
+
+ // Build key and check
+ key := formatSanitizerKey(Sanitizer{
+ Package: pkg,
+ Receiver: receiverName,
+ Method: methodName,
+ Pointer: isPointer,
+ })
+ _, found := a.sanitizers[key]
+ return found
+}
+
+// isTainted recursively checks if a value is tainted (originates from a source).
+//
+// KEY DESIGN PRINCIPLE: Type-based source matching is ONLY applied to function
+// parameters received from external callers and global variables. Locally
+// constructed values of source types (e.g., http.NewRequest with a hardcoded
+// URL) are NOT automatically considered tainted — their taintedness depends
+// on whether the data flowing into them is tainted.
+func (a *Analyzer) isTainted(v ssa.Value, fn *ssa.Function, visited map[ssa.Value]bool, depth int) bool {
+ if v == nil {
+ return false
+ }
+
+ // Prevent stack overflow on large codebases
+ if depth > maxTaintDepth {
+ return false
+ }
+
+ // Prevent infinite recursion
+ if visited[v] {
+ return false
+ }
+ visited[v] = true
+
+ // Constants are compile-time literals and can never carry attacker-controlled
+ // data. Short-circuit immediately — no taint possible.
+ if _, ok := v.(*ssa.Const); ok {
+ return false
+ }
+
+ // Trace back through SSA instructions
+ switch val := v.(type) {
+ case *ssa.Parameter:
+ // Parameters are tainted if:
+ // 1. Their type matches a source type AND they come from an external caller
+ // 2. A caller passes tainted data to this parameter position
+ return a.isParameterTainted(val, fn, visited, depth+1)
+
+ case *ssa.Call:
+ // FIRST: Check if this call is a sanitizer — sanitizers break the taint chain
+ if a.isSanitizerCall(val) {
+ return false
+ }
+
+ // Check if this is a known source function (e.g., os.Getenv, os.ReadFile)
+ if a.isSourceFuncCall(val) {
+ return true
+ }
+
+ // For method calls, check if the receiver carries taint.
+ // This handles patterns like: req.URL.Query().Get("param")
+ // where req is a tainted *http.Request parameter.
+ if val.Call.IsInvoke() {
+ // Interface method call — receiver is Call.Value
+ if val.Call.Value != nil && a.isTainted(val.Call.Value, fn, visited, depth+1) {
+ return true
+ }
+ // Also check non-receiver args for interface method calls.
+ // Skip context.Context args — they don't carry user data to outputs.
+ for _, arg := range val.Call.Args {
+ if isContextType(arg.Type()) {
+ continue
+ }
+ if a.isTainted(arg, fn, visited, depth+1) {
+ return true
+ }
+ }
+ } else if callee := val.Call.StaticCallee(); callee != nil && callee.Signature.Recv() != nil {
+ // Static method call — receiver is Args[0]
+ if len(val.Call.Args) > 0 && a.isTainted(val.Call.Args[0], fn, visited, depth+1) {
+ return true
+ }
+ // Also check non-receiver arguments (Args[1:]) for methods.
+ // For internal methods with bodies, use interprocedural analysis.
+ // For external methods, conservatively propagate any tainted arg.
+ if len(callee.Blocks) > 0 {
+ if a.doTaintedArgsFlowToReturn(val, callee, fn, visited, depth+1) {
+ return true
+ }
+ } else if len(val.Call.Args) > 1 {
+ // Skip context.Context args — they don't carry user data to outputs.
+ for _, arg := range val.Call.Args[1:] {
+ if isContextType(arg.Type()) {
+ continue
+ }
+ if a.isTainted(arg, fn, visited, depth+1) {
+ return true
+ }
+ }
+ }
+ }
+
+ // For non-method calls (plain functions), check if data-carrying arguments
+ // are tainted AND actually flow to the return value.
+ if callee := val.Call.StaticCallee(); callee != nil {
+ if callee.Signature.Recv() == nil {
+ if len(callee.Blocks) > 0 {
+ // Internal function with available body — use interprocedural
+ // analysis to check if tainted args actually influence the return.
+ if a.doTaintedArgsFlowToReturn(val, callee, fn, visited, depth+1) {
+ return true
+ }
+ } else {
+ // External function (no body) — conservatively assume any
+ // tainted arg taints the return. This is correct for stdlib
+ // data-transformation functions (string ops, fmt, etc.).
+ // Skip context.Context args — they don't carry user data to outputs.
+ for _, arg := range val.Call.Args {
+ if isContextType(arg.Type()) {
+ continue
+ }
+ if a.isTainted(arg, fn, visited, depth+1) {
+ return true
+ }
+ }
+ }
+ }
+ }
+
+ // Check for builtin calls (append, copy, string conversion, etc.)
+ if _, ok := val.Call.Value.(*ssa.Builtin); ok {
+ for _, arg := range val.Call.Args {
+ if a.isTainted(arg, fn, visited, depth+1) {
+ return true
+ }
+ }
+ }
+
+ case *ssa.FieldAddr:
+ // Field access on a struct — use field-sensitive analysis.
+ // Instead of blindly propagating taint from the parent struct, we
+ // check whether this specific field carries tainted data.
+ return a.isFieldAccessTainted(val, fn, visited, depth+1)
+
+ case *ssa.IndexAddr:
+ // Index into a tainted slice/array
+ return a.isTainted(val.X, fn, visited, depth+1)
+
+ case *ssa.UnOp:
+ // Unary operation (like pointer dereference)
+ return a.isTainted(val.X, fn, visited, depth+1)
+
+ case *ssa.BinOp:
+ // Binary operation - tainted if either operand is tainted
+ return a.isTainted(val.X, fn, visited, depth+1) || a.isTainted(val.Y, fn, visited, depth+1)
+
+ case *ssa.Phi:
+ // Phi node - tainted if any edge is tainted
+ for _, edge := range val.Edges {
+ if a.isTainted(edge, fn, visited, depth+1) {
+ return true
+ }
+ }
+
+ case *ssa.Extract:
+ // Extract from tuple - check the tuple
+ return a.isTainted(val.Tuple, fn, visited, depth+1)
+
+ case *ssa.TypeAssert:
+ // Type assertion - check the underlying value
+ return a.isTainted(val.X, fn, visited, depth+1)
+
+ case *ssa.MakeInterface:
+ // Interface creation - check the underlying value
+ return a.isTainted(val.X, fn, visited, depth+1)
+
+ case *ssa.Slice:
+ // Slice operation - check the sliced value
+ return a.isTainted(val.X, fn, visited, depth+1)
+
+ case *ssa.Convert:
+ // Type conversion - check the converted value
+ return a.isTainted(val.X, fn, visited, depth+1)
+
+ case *ssa.ChangeType:
+ // Type change - check the underlying value
+ return a.isTainted(val.X, fn, visited, depth+1)
+
+ case *ssa.Alloc:
+ // Allocation - check referrers for assignments
+ for _, ref := range *val.Referrers() {
+ // Direct stores to the allocation
+ if store, ok := ref.(*ssa.Store); ok {
+ if a.isTainted(store.Val, fn, visited, depth+1) {
+ return true
+ }
+ }
+ // For arrays/slices, check stores to indexed addresses (e.g., varargs)
+ if indexAddr, ok := ref.(*ssa.IndexAddr); ok {
+ if indexRefs := indexAddr.Referrers(); indexRefs != nil {
+ for _, indexRef := range *indexRefs {
+ if store, ok := indexRef.(*ssa.Store); ok {
+ if a.isTainted(store.Val, fn, visited, depth+1) {
+ return true
+ }
+ }
+ }
+ }
+ }
+ }
+
+ case *ssa.Lookup:
+ // Map/string lookup - check the map/string
+ return a.isTainted(val.X, fn, visited, depth+1)
+
+ case *ssa.MakeSlice:
+ // MakeSlice - check if it's being populated with tainted data
+ if refs := val.Referrers(); refs != nil {
+ for _, ref := range *refs {
+ if store, ok := ref.(*ssa.Store); ok {
+ if a.isTainted(store.Val, fn, visited, depth+1) {
+ return true
+ }
+ }
+ if call, ok := ref.(*ssa.Call); ok {
+ for _, arg := range call.Call.Args {
+ if arg == val {
+ continue // Skip the slice itself
+ }
+ if a.isTainted(arg, fn, visited, depth+1) {
+ return true
+ }
+ }
+ }
+ }
+ }
+ return false
+
+ case *ssa.MakeMap, *ssa.MakeChan:
+ // New maps/channels are not tainted by default
+ return false
+
+ case *ssa.Const:
+ // Constants are never tainted
+ return false
+
+ case *ssa.Global:
+ // Global variables - check if configured as a known source (e.g., os.Args)
+ if val.Pkg != nil && val.Pkg.Pkg != nil {
+ globalKey := val.Pkg.Pkg.Path() + "." + val.Name()
+ if _, ok := a.sources[globalKey]; ok {
+ return true
+ }
+ }
+ return false
+
+ case *ssa.FreeVar:
+ // Free variables in closures - trace to the enclosing scope's binding.
+ // This handles closures like filepath.WalkDir callbacks where a variable
+ // from the outer scope is captured.
+ return a.isFreeVarTainted(val, fn, visited, depth+1)
+
+ default:
+ // Unhandled SSA instruction type - be conservative and don't propagate taint
+ // to avoid false positives, but this might cause false negatives
+ return false
+ }
+
+ return false
+}
+
+// isSourceType checks if a type matches any configured source type.
+// This is used specifically for parameter checking, NOT for general value checking.
+func (a *Analyzer) isSourceType(t types.Type) bool {
+ if t == nil {
+ return false
+ }
+
+ typeStr := t.String()
+
+ // Direct match
+ if _, ok := a.sources[typeStr]; ok {
+ return true
+ }
+
+ // Check underlying type for named types
+ if named, ok := t.(*types.Named); ok {
+ obj := named.Obj()
+ if obj != nil && obj.Pkg() != nil {
+ key := obj.Pkg().Path() + "." + obj.Name()
+ if _, ok := a.sources[key]; ok {
+ return true
+ }
+ // Check pointer variant
+ if _, ok := a.sources["*"+key]; ok {
+ return true
+ }
+ }
+ }
+
+ // Check pointer types
+ if ptr, ok := t.(*types.Pointer); ok {
+ return a.isSourceType(ptr.Elem())
+ }
+
+ return false
+}
+
+// mayHaveExternalCallers reports whether fn could be invoked by code outside
+// the analyzed package — code that is invisible to the call graph.
+//
+// Exported bare functions (non-methods) are the primary case: frameworks
+// register them via dynamic dispatch that CHA cannot resolve, so the call
+// graph may lack edges even though the function IS called at runtime.
+//
+// Methods with a receiver are excluded because CHA resolves interface dispatch
+// to concrete methods, so their callers are generally visible in the graph.
+// Unexported functions are only callable within the package, and the call graph
+// covers intra-package calls comprehensively.
+func mayHaveExternalCallers(fn *ssa.Function) bool {
+ if fn.Signature == nil {
+ return false
+ }
+ // Methods — CHA handles interface dispatch; callers are visible.
+ if fn.Signature.Recv() != nil {
+ return false
+ }
+ // Closures / anonymous functions are never exported.
+ if fn.Parent() != nil {
+ return false
+ }
+ // Exported bare function — may be called by external frameworks.
+ return token.IsExported(fn.Name())
+}
+
+// isSourceFuncCall checks if a call invokes a known source function
+// (a function explicitly configured as producing tainted data, e.g., os.Getenv).
+func (a *Analyzer) isSourceFuncCall(call *ssa.Call) bool {
+ callee := call.Call.StaticCallee()
+ if callee == nil {
+ return false
+ }
+
+ if callee.Pkg != nil && callee.Pkg.Pkg != nil {
+ pkg := callee.Pkg.Pkg.Path()
+ funcKey := pkg + "." + callee.Name()
+ if src, ok := a.sources[funcKey]; ok && src.IsFunc {
+ return true
+ }
+ }
+
+ return false
+}
+
+// isParameterTainted checks if a function parameter receives tainted data.
+//
+// A parameter is tainted if:
+// 1. Its type matches a configured source type (e.g., *http.Request in a handler)
+// 2. Any caller passes tainted data to the corresponding argument position
+func (a *Analyzer) isParameterTainted(param *ssa.Parameter, fn *ssa.Function, visited map[ssa.Value]bool, depth int) bool {
+ // Prevent stack overflow
+ if depth > maxTaintDepth {
+ return false
+ }
+
+ // Resolve paramIdx early so we can use it for cache lookups.
+ paramIdx := -1
+ for i, p := range fn.Params {
+ if p == param {
+ paramIdx = i
+ break
+ }
+ }
+
+ // Check memoization cache (only true results are cached).
+ if paramIdx >= 0 && a.paramTaintCache != nil {
+ key := paramKey{fn: fn, paramIdx: paramIdx}
+ if a.paramTaintCache[key] {
+ return true
+ }
+ }
+
+ // Use call graph to find callers and check their arguments
+ if a.callGraph == nil {
+ // No call graph: fall back to type-based auto-taint for source-typed params
+ // (conservative — may produce false positives, but we have no callee info).
+ if a.isSourceType(param.Type()) {
+ if paramIdx >= 0 && a.paramTaintCache != nil {
+ a.paramTaintCache[paramKey{fn: fn, paramIdx: paramIdx}] = true
+ }
+ return true
+ }
+ return false
+ }
+
+ node := a.callGraph.Nodes[fn]
+
+ // Check if parameter type is a configured source type.
+ //
+ // Strategy:
+ // 1. No callers in call graph → definite entry point → auto-taint.
+ // 2. Exported bare function → may have invisible external callers
+ // (framework dispatch) → auto-taint to avoid false negatives.
+ // 3. Has callers, not exported bare func → fall through to caller check.
+ //
+ // Case 2 addresses a class of false negatives where an internal caller
+ // with safe args suppresses taint for an exported entry point that is
+ // also called externally by a framework (issue #1629 + Barry review).
+ // Methods are excluded because CHA resolves interface dispatch, making
+ // their callers visible in the call graph.
+ if a.isSourceType(param.Type()) {
+ isEntryPoint := (node == nil || len(node.In) == 0)
+ if isEntryPoint || mayHaveExternalCallers(fn) {
+ if paramIdx >= 0 && a.paramTaintCache != nil {
+ a.paramTaintCache[paramKey{fn: fn, paramIdx: paramIdx}] = true
+ }
+ return true
+ }
+ // Has known callers and is not a handler — fall through to verify
+ // taint via those callers.
+ }
+
+ if node == nil {
+ return false
+ }
+
+ if paramIdx < 0 {
+ return false
+ }
+
+ // Compute the adjusted index ONCE outside the loop.
+ adjustedIdx := paramIdx
+ if fn.Signature.Recv() != nil {
+ // In SSA, method parameters include the receiver at index 0.
+ // fn.Params already includes the receiver, so paramIdx is correct
+ // relative to fn.Params. But call site Args also include the receiver
+ // at index 0 for bound methods. So we don't need to adjust—the
+ // indices are already aligned.
+ // However, for interface method invocations (IsInvoke), the receiver
+ // is in Call.Value, not Args. We handle that separately below.
+ adjustedIdx = paramIdx
+ }
+
+ // Check each caller, capping at maxCallerEdges to avoid combinatorial
+ // explosion from CHA over-approximation of interface method calls.
+ edgesChecked := 0
+ for _, inEdge := range node.In {
+ if edgesChecked >= maxCallerEdges {
+ break
+ }
+
+ site := inEdge.Site
+ if site == nil {
+ continue
+ }
+
+ callArgs := site.Common().Args
+
+ if adjustedIdx < len(callArgs) {
+ edgesChecked++
+ if a.isTainted(callArgs[adjustedIdx], inEdge.Caller.Func, visited, depth+1) {
+ if a.paramTaintCache != nil {
+ a.paramTaintCache[paramKey{fn: fn, paramIdx: paramIdx}] = true
+ }
+ return true
+ }
+ }
+ }
+
+ return false
+}
+
+// isFreeVarTainted checks if a closure's free variable is tainted.
+// Free variables are captured from the enclosing function's scope.
+func (a *Analyzer) isFreeVarTainted(fv *ssa.FreeVar, fn *ssa.Function, visited map[ssa.Value]bool, depth int) bool {
+ if depth > maxTaintDepth {
+ return false
+ }
+
+ // Find the enclosing function that creates this closure
+ parent := fn.Parent()
+ if parent == nil {
+ return false
+ }
+
+ // Find the MakeClosure instruction in the parent that creates fn
+ for _, block := range parent.Blocks {
+ for _, instr := range block.Instrs {
+ mc, ok := instr.(*ssa.MakeClosure)
+ if !ok {
+ continue
+ }
+ // Check if this MakeClosure creates our function
+ if mc.Fn != fn {
+ continue
+ }
+ // mc.Bindings correspond to fn.FreeVars in the same order
+ for i, binding := range mc.Bindings {
+ if i < len(fn.FreeVars) && fn.FreeVars[i] == fv {
+ return a.isTainted(binding, parent, visited, depth+1)
+ }
+ }
+ }
+ }
+
+ return false
+}
+
+// isFieldAccessTainted checks whether a specific field of a struct carries tainted data.
+//
+// This is the core of field-sensitive taint tracking. Rather than treating
+// the entire struct as tainted when any field is tainted, we trace the
+// specific field to see if IT was assigned tainted data.
+func (a *Analyzer) isFieldAccessTainted(fa *ssa.FieldAddr, fn *ssa.Function, visited map[ssa.Value]bool, depth int) bool {
+ if depth > maxTaintDepth {
+ return false
+ }
+
+ // CASE 1: The struct is a parameter of a known source type (e.g., *http.Request).
+ // ALL fields of externally-supplied source types are considered tainted.
+ if a.isSourceType(fa.X.Type()) {
+ if _, ok := fa.X.(*ssa.Parameter); ok {
+ return true
+ }
+ // If not a parameter but still a source type, trace the struct origin
+ if a.isTainted(fa.X, fn, visited, depth) {
+ return true
+ }
+ return false
+ }
+
+ // CASE 2: The struct was returned by a function call.
+ // Use interprocedural analysis: look inside the callee to see if this
+ // specific field index was assigned tainted data.
+ if call, ok := fa.X.(*ssa.Call); ok {
+ if callee := call.Call.StaticCallee(); callee != nil && callee.Blocks != nil {
+ return a.isFieldTaintedViaCall(call, fa.Field, callee, fn, visited, depth)
+ }
+ // External function — fall back to checking if the call result is tainted
+ return a.isTainted(fa.X, fn, visited, depth)
+ }
+
+ // CASE 3: The struct is from an Extract (multi-return call, e.g., job, err := NewJob(...)).
+ if extract, ok := fa.X.(*ssa.Extract); ok {
+ if call, ok := extract.Tuple.(*ssa.Call); ok {
+ if callee := call.Call.StaticCallee(); callee != nil && callee.Blocks != nil {
+ return a.isFieldTaintedViaCall(call, fa.Field, callee, fn, visited, depth)
+ }
+ }
+ // Fall back
+ return a.isTainted(fa.X, fn, visited, depth)
+ }
+
+ // CASE 4: The struct is a local Alloc. Check stores to this specific field.
+ if alloc, ok := fa.X.(*ssa.Alloc); ok {
+ return a.isFieldOfAllocTainted(alloc, fa.Field, fn, visited, depth)
+ }
+
+ // CASE 5: Pointer dereference (load) — trace through the pointer.
+ if unop, ok := fa.X.(*ssa.UnOp); ok {
+ return a.isFieldAccessOnPointerTainted(unop, fa.Field, fn, visited, depth)
+ }
+
+ // CASE 6: Phi node — field is tainted if tainted on any incoming edge.
+ if phi, ok := fa.X.(*ssa.Phi); ok {
+ for _, edge := range phi.Edges {
+ if a.isFieldTaintedOnValue(edge, fa.Field, fn, visited, depth+1) {
+ return true
+ }
+ }
+ return false
+ }
+
+ // CASE 7: Nested field access — e.g., job.Rinse.Something
+ if innerFA, ok := fa.X.(*ssa.FieldAddr); ok {
+ return a.isFieldAccessTainted(innerFA, fn, visited, depth)
+ }
+
+ // Default: fall back to checking if the parent struct value is tainted.
+ return a.isTainted(fa.X, fn, visited, depth)
+}
+
+// isFieldTaintedOnValue checks if a specific field of a value is tainted.
+func (a *Analyzer) isFieldTaintedOnValue(v ssa.Value, fieldIdx int, fn *ssa.Function, visited map[ssa.Value]bool, depth int) bool {
+ if v == nil || depth > maxTaintDepth {
+ return false
+ }
+
+ switch val := v.(type) {
+ case *ssa.Call:
+ if callee := val.Call.StaticCallee(); callee != nil && callee.Blocks != nil {
+ return a.isFieldTaintedViaCall(val, fieldIdx, callee, fn, visited, depth)
+ }
+ return a.isTainted(v, fn, visited, depth)
+ case *ssa.Extract:
+ if call, ok := val.Tuple.(*ssa.Call); ok {
+ if callee := call.Call.StaticCallee(); callee != nil && callee.Blocks != nil {
+ return a.isFieldTaintedViaCall(call, fieldIdx, callee, fn, visited, depth)
+ }
+ }
+ return a.isTainted(v, fn, visited, depth)
+ case *ssa.Alloc:
+ return a.isFieldOfAllocTainted(val, fieldIdx, fn, visited, depth)
+ case *ssa.Phi:
+ if visited[v] {
+ return false
+ }
+ visited[v] = true
+ for _, edge := range val.Edges {
+ if a.isFieldTaintedOnValue(edge, fieldIdx, fn, visited, depth+1) {
+ return true
+ }
+ }
+ return false
+ default:
+ return a.isTainted(v, fn, visited, depth)
+ }
+}
+
+// isFieldOfAllocTainted checks if a specific field of a locally-allocated struct
+// has been assigned tainted data.
+func (a *Analyzer) isFieldOfAllocTainted(alloc *ssa.Alloc, fieldIdx int, fn *ssa.Function, visited map[ssa.Value]bool, depth int) bool {
+ if alloc.Referrers() == nil {
+ return false
+ }
+ for _, ref := range *alloc.Referrers() {
+ fa, ok := ref.(*ssa.FieldAddr)
+ if !ok || fa.Field != fieldIdx {
+ continue
+ }
+
+ if fa.Referrers() == nil {
+ continue
+ }
+ for _, faRef := range *fa.Referrers() {
+ store, ok := faRef.(*ssa.Store)
+ if !ok || store.Addr != fa {
+ continue
+ }
+ if a.isTainted(store.Val, fn, visited, depth+1) {
+ return true
+ }
+ }
+ }
+ return false
+}
+
+// isFieldAccessOnPointerTainted handles field access through a pointer dereference.
+func (a *Analyzer) isFieldAccessOnPointerTainted(unop *ssa.UnOp, fieldIdx int, fn *ssa.Function, visited map[ssa.Value]bool, depth int) bool {
+ // Trace through the pointer to find the underlying value
+ return a.isFieldTaintedOnValue(unop.X, fieldIdx, fn, visited, depth)
+}
+
+// isFieldTaintedViaCall performs interprocedural analysis to check if a specific
+// field of the struct returned by a function call is tainted.
+//
+// It looks inside the callee to find the returned struct allocation and checks
+// whether the specific field was assigned data derived from tainted arguments.
+func (a *Analyzer) isFieldTaintedViaCall(call *ssa.Call, fieldIdx int, callee *ssa.Function, callerFn *ssa.Function, visited map[ssa.Value]bool, depth int) bool {
+ if depth > maxTaintDepth || callee == nil {
+ return false
+ }
+
+ // Prevent re-analyzing the same call site
+ if visited[call] {
+ return false
+ }
+ visited[call] = true
+
+ // If we don't have SSA blocks (external function or no body), use fallback logic:
+ // Assume the field is tainted if any argument to the constructor is tainted.
+ if callee.Blocks == nil {
+ for _, arg := range call.Call.Args {
+ if a.isTainted(arg, callerFn, visited, depth) {
+ return true
+ }
+ }
+ return false
+ }
+
+ // Find all Return instructions in the callee
+ for _, block := range callee.Blocks {
+ for _, instr := range block.Instrs {
+ ret, ok := instr.(*ssa.Return)
+ if !ok {
+ continue
+ }
+ // Check each return value for our struct
+ for _, retVal := range ret.Results {
+ alloc := traceToAlloc(retVal)
+ if alloc == nil {
+ continue
+ }
+ // Check stores to this alloc's field at fieldIdx
+ if a.isFieldOfAllocTaintedInCallee(alloc, fieldIdx, callee, call, callerFn, visited, depth+1) {
+ return true
+ }
+ }
+ }
+ }
+
+ return false
+}
+
+// isFieldOfAllocTaintedInCallee checks if a specific field of an allocated struct
+// (inside a callee function) receives tainted data from the caller's arguments.
+func (a *Analyzer) isFieldOfAllocTaintedInCallee(alloc *ssa.Alloc, fieldIdx int, callee *ssa.Function, call *ssa.Call, callerFn *ssa.Function, visited map[ssa.Value]bool, depth int) bool {
+ if alloc.Referrers() == nil || depth > maxTaintDepth {
+ return false
+ }
+
+ if visited[alloc] {
+ return false
+ }
+ visited[alloc] = true
+ for _, ref := range *alloc.Referrers() {
+ fa, ok := ref.(*ssa.FieldAddr)
+ if !ok || fa.Field != fieldIdx {
+ continue
+ }
+ if fa.Referrers() == nil {
+ continue
+ }
+ for _, faRef := range *fa.Referrers() {
+ store, ok := faRef.(*ssa.Store)
+ if !ok || store.Addr != fa {
+ continue
+ }
+ // Check if the stored value traces back to a tainted caller argument.
+ // Map callee parameters back to caller arguments.
+ if a.isCalleValueTainted(store.Val, callee, call, callerFn, visited, depth+1) {
+ return true
+ }
+ }
+ }
+ return false
+}
+
+// isCalleValueTainted checks if a value inside a callee is tainted, mapping
+// callee parameters back to the actual caller arguments for interprocedural analysis.
+func (a *Analyzer) isCalleValueTainted(v ssa.Value, callee *ssa.Function, call *ssa.Call, callerFn *ssa.Function, visited map[ssa.Value]bool, depth int) bool {
+ if v == nil || depth > maxTaintDepth {
+ return false
+ }
+
+ // Prevent infinite recursion on cyclic SSA value graphs
+ if visited[v] {
+ return false
+ }
+ visited[v] = true
+
+ // If the value is a callee parameter, map it to the caller's argument
+ if param, ok := v.(*ssa.Parameter); ok {
+ for i, p := range callee.Params {
+ if p == param && i < len(call.Call.Args) {
+ return a.isTainted(call.Call.Args[i], callerFn, visited, depth)
+ }
+ }
+ return false
+ }
+
+ // For constants, never tainted
+ if _, ok := v.(*ssa.Const); ok {
+ return false
+ }
+
+ // For calls within the callee, check if any tainted param flows in
+ if innerCall, ok := v.(*ssa.Call); ok {
+ // Check if it's a sanitizer
+ if a.isSanitizerCall(innerCall) {
+ return false
+ }
+ if a.isSourceFuncCall(innerCall) {
+ return true
+ }
+ for _, arg := range innerCall.Call.Args {
+ if a.isCalleValueTainted(arg, callee, call, callerFn, visited, depth+1) {
+ return true
+ }
+ }
+ return false
+ }
+
+ // For Extract (tuple unpacking), trace the tuple
+ if extract, ok := v.(*ssa.Extract); ok {
+ return a.isCalleValueTainted(extract.Tuple, callee, call, callerFn, visited, depth+1)
+ }
+
+ // For Phi, check all edges
+ if phi, ok := v.(*ssa.Phi); ok {
+ for _, edge := range phi.Edges {
+ if a.isCalleValueTainted(edge, callee, call, callerFn, visited, depth+1) {
+ return true
+ }
+ }
+ return false
+ }
+
+ // For BinOp, check both sides
+ if binop, ok := v.(*ssa.BinOp); ok {
+ return a.isCalleValueTainted(binop.X, callee, call, callerFn, visited, depth+1) ||
+ a.isCalleValueTainted(binop.Y, callee, call, callerFn, visited, depth+1)
+ }
+
+ // For Convert/ChangeType, trace through
+ if conv, ok := v.(*ssa.Convert); ok {
+ return a.isCalleValueTainted(conv.X, callee, call, callerFn, visited, depth+1)
+ }
+ if ct, ok := v.(*ssa.ChangeType); ok {
+ return a.isCalleValueTainted(ct.X, callee, call, callerFn, visited, depth+1)
+ }
+
+ // For FieldAddr on a callee parameter (e.g., accessing a field of an arg struct)
+ if fa, ok := v.(*ssa.FieldAddr); ok {
+ return a.isCalleValueTainted(fa.X, callee, call, callerFn, visited, depth+1)
+ }
+
+ // For UnOp (pointer deref), trace through
+ if unop, ok := v.(*ssa.UnOp); ok {
+ return a.isCalleValueTainted(unop.X, callee, call, callerFn, visited, depth+1)
+ }
+
+ // For other SSA values, fall back to the callee-local taint check
+ return a.isTainted(v, callee, visited, depth)
+}
+
+// doTaintedArgsFlowToReturn checks if any tainted argument to an internal function
+// call actually influences the function's return value(s).
+//
+// This prevents false positives from constructor-like functions (e.g., NewJob)
+// where only some arguments flow into the return struct, while others are stored
+// in fields that don't affect the data being tracked.
+func (a *Analyzer) doTaintedArgsFlowToReturn(call *ssa.Call, callee *ssa.Function, callerFn *ssa.Function, visited map[ssa.Value]bool, depth int) bool {
+ if depth > maxTaintDepth {
+ return false
+ }
+
+ // Identify which args are tainted.
+ // Skip context.Context args — they don't carry user data to outputs.
+ var taintedArgIndices []int
+ for i, arg := range call.Call.Args {
+ if isContextType(arg.Type()) {
+ continue
+ }
+ if a.isTainted(arg, callerFn, visited, depth) {
+ taintedArgIndices = append(taintedArgIndices, i)
+ }
+ }
+ if len(taintedArgIndices) == 0 {
+ return false
+ }
+
+ // Build a set of callee parameters that correspond to tainted caller args
+ taintedParams := make(map[*ssa.Parameter]bool)
+ for _, idx := range taintedArgIndices {
+ if idx < len(callee.Params) {
+ taintedParams[callee.Params[idx]] = true
+ }
+ }
+
+ // Check if any tainted parameter flows to a Return instruction
+ for _, block := range callee.Blocks {
+ for _, instr := range block.Instrs {
+ ret, ok := instr.(*ssa.Return)
+ if !ok {
+ continue
+ }
+ for _, retVal := range ret.Results {
+ if a.valueReachableFromParams(retVal, taintedParams, make(map[ssa.Value]bool), 0) {
+ return true
+ }
+ }
+ }
+ }
+
+ return false
+}
+
+// valueReachableFromParams checks if a value in a function is data-derived from
+// any of the specified parameters. This is a lightweight reachability check
+// within a single function body.
+func (a *Analyzer) valueReachableFromParams(v ssa.Value, taintedParams map[*ssa.Parameter]bool, visited map[ssa.Value]bool, depth int) bool {
+ if v == nil || depth > 30 || visited[v] {
+ return false
+ }
+ visited[v] = true
+
+ switch val := v.(type) {
+ case *ssa.Parameter:
+ return taintedParams[val]
+ case *ssa.Const:
+ return false
+ case *ssa.Global:
+ return false
+ case *ssa.Alloc:
+ // Check if any store to this alloc uses tainted data
+ if val.Referrers() == nil {
+ return false
+ }
+ for _, ref := range *val.Referrers() {
+ if store, ok := ref.(*ssa.Store); ok && store.Addr == val {
+ if a.valueReachableFromParams(store.Val, taintedParams, visited, depth+1) {
+ return true
+ }
+ }
+ // Also check FieldAddr stores (for struct allocs)
+ if fa, ok := ref.(*ssa.FieldAddr); ok {
+ if fa.Referrers() != nil {
+ for _, faRef := range *fa.Referrers() {
+ if store, ok := faRef.(*ssa.Store); ok && store.Addr == fa {
+ if a.valueReachableFromParams(store.Val, taintedParams, visited, depth+1) {
+ return true
+ }
+ }
+ }
+ }
+ }
+ }
+ return false
+ case *ssa.Call:
+ // Check if any arg to this call comes from tainted params
+ for _, arg := range val.Call.Args {
+ if a.valueReachableFromParams(arg, taintedParams, visited, depth+1) {
+ return true
+ }
+ }
+ if val.Call.Value != nil {
+ if a.valueReachableFromParams(val.Call.Value, taintedParams, visited, depth+1) {
+ return true
+ }
+ }
+ return false
+ case *ssa.Phi:
+ for _, edge := range val.Edges {
+ if a.valueReachableFromParams(edge, taintedParams, visited, depth+1) {
+ return true
+ }
+ }
+ return false
+ case *ssa.UnOp:
+ return a.valueReachableFromParams(val.X, taintedParams, visited, depth+1)
+ case *ssa.BinOp:
+ return a.valueReachableFromParams(val.X, taintedParams, visited, depth+1) ||
+ a.valueReachableFromParams(val.Y, taintedParams, visited, depth+1)
+ case *ssa.Convert:
+ return a.valueReachableFromParams(val.X, taintedParams, visited, depth+1)
+ case *ssa.ChangeType:
+ return a.valueReachableFromParams(val.X, taintedParams, visited, depth+1)
+ case *ssa.MakeInterface:
+ return a.valueReachableFromParams(val.X, taintedParams, visited, depth+1)
+ case *ssa.TypeAssert:
+ return a.valueReachableFromParams(val.X, taintedParams, visited, depth+1)
+ case *ssa.Slice:
+ return a.valueReachableFromParams(val.X, taintedParams, visited, depth+1)
+ case *ssa.FieldAddr:
+ return a.valueReachableFromParams(val.X, taintedParams, visited, depth+1)
+ case *ssa.IndexAddr:
+ return a.valueReachableFromParams(val.X, taintedParams, visited, depth+1)
+ case *ssa.Extract:
+ return a.valueReachableFromParams(val.Tuple, taintedParams, visited, depth+1)
+ case *ssa.FreeVar:
+ return false // Conservative: closures don't flow from params
+ case *ssa.Lookup:
+ return a.valueReachableFromParams(val.X, taintedParams, visited, depth+1)
+ default:
+ return false // Unknown SSA type — conservative, don't propagate
+ }
+}
+
+// traceToAlloc follows a value back through SSA instructions to find
+// the underlying Alloc instruction (struct allocation), if any.
+func traceToAlloc(v ssa.Value) *ssa.Alloc {
+ seen := make(map[ssa.Value]bool)
+ return traceToAllocImpl(v, seen)
+}
+
+func traceToAllocImpl(v ssa.Value, seen map[ssa.Value]bool) *ssa.Alloc {
+ if v == nil || seen[v] {
+ return nil
+ }
+ seen[v] = true
+
+ switch val := v.(type) {
+ case *ssa.Alloc:
+ return val
+ case *ssa.Phi:
+ for _, e := range val.Edges {
+ if a := traceToAllocImpl(e, seen); a != nil {
+ return a
+ }
+ }
+ return nil
+ case *ssa.MakeInterface:
+ return traceToAllocImpl(val.X, seen)
+ case *ssa.ChangeType:
+ return traceToAllocImpl(val.X, seen)
+ case *ssa.Convert:
+ return traceToAllocImpl(val.X, seen)
+ case *ssa.UnOp:
+ return traceToAllocImpl(val.X, seen)
+ default:
+ return nil
+ }
+}
+
+// buildPath constructs the call path from entry point to the sink.
+func (a *Analyzer) buildPath(fn *ssa.Function) []*ssa.Function {
+ if a.callGraph == nil {
+ return []*ssa.Function{fn}
+ }
+
+ // BFS to find path from root to this function
+ path := []*ssa.Function{fn}
+
+ node := a.callGraph.Nodes[fn]
+ if node == nil {
+ return path
+ }
+
+ // Simple path: just trace callers up
+ visited := make(map[*ssa.Function]bool)
+ current := node
+
+ for current != nil && len(current.In) > 0 {
+ if visited[current.Func] {
+ break
+ }
+ visited[current.Func] = true
+
+ caller := current.In[0].Caller
+ if caller == nil || caller.Func == nil {
+ break
+ }
+
+ path = append([]*ssa.Function{caller.Func}, path...)
+ current = caller
+ }
+
+ return path
+}
diff --git a/vendor/github.com/sergi/go-diff/diffmatchpatch/diff.go b/vendor/github.com/sergi/go-diff/diffmatchpatch/diff.go
index 2a9f2dc3b..08c36e74f 100644
--- a/vendor/github.com/sergi/go-diff/diffmatchpatch/diff.go
+++ b/vendor/github.com/sergi/go-diff/diffmatchpatch/diff.go
@@ -34,8 +34,6 @@ const (
DiffInsert Operation = 1
// DiffEqual item represents an equal diff.
DiffEqual Operation = 0
- //IndexSeparator is used to seperate the array indexes in an index string
- IndexSeparator = ","
)
// Diff represents one diff operation
@@ -406,14 +404,11 @@ func (dmp *DiffMatchPatch) DiffLinesToRunes(text1, text2 string) ([]rune, []rune
func (dmp *DiffMatchPatch) DiffCharsToLines(diffs []Diff, lineArray []string) []Diff {
hydrated := make([]Diff, 0, len(diffs))
for _, aDiff := range diffs {
- chars := strings.Split(aDiff.Text, IndexSeparator)
- text := make([]string, len(chars))
+ runes := []rune(aDiff.Text)
+ text := make([]string, len(runes))
- for i, r := range chars {
- i1, err := strconv.Atoi(r)
- if err == nil {
- text[i] = lineArray[i1]
- }
+ for i, r := range runes {
+ text[i] = lineArray[runeToInt(r)]
}
aDiff.Text = strings.Join(text, "")
@@ -1151,13 +1146,28 @@ func (dmp *DiffMatchPatch) DiffPrettyText(diffs []Diff) string {
switch diff.Type {
case DiffInsert:
- _, _ = buff.WriteString("\x1b[32m")
- _, _ = buff.WriteString(text)
- _, _ = buff.WriteString("\x1b[0m")
+ lines := strings.Split(text, "\n")
+ for i, line := range lines {
+ _, _ = buff.WriteString("\x1b[32m")
+ _, _ = buff.WriteString(line)
+ if i < len(lines)-1 {
+ _, _ = buff.WriteString("\x1b[0m\n")
+ } else {
+ _, _ = buff.WriteString("\x1b[0m")
+ }
+ }
+
case DiffDelete:
- _, _ = buff.WriteString("\x1b[31m")
- _, _ = buff.WriteString(text)
- _, _ = buff.WriteString("\x1b[0m")
+ lines := strings.Split(text, "\n")
+ for i, line := range lines {
+ _, _ = buff.WriteString("\x1b[31m")
+ _, _ = buff.WriteString(line)
+ if i < len(lines)-1 {
+ _, _ = buff.WriteString("\x1b[0m\n")
+ } else {
+ _, _ = buff.WriteString("\x1b[0m")
+ }
+ }
case DiffEqual:
_, _ = buff.WriteString(text)
}
@@ -1310,23 +1320,21 @@ func (dmp *DiffMatchPatch) DiffFromDelta(text1 string, delta string) (diffs []Di
// diffLinesToStrings splits two texts into a list of strings. Each string represents one line.
func (dmp *DiffMatchPatch) diffLinesToStrings(text1, text2 string) (string, string, []string) {
- // '\x00' is a valid character, but various debuggers don't like it. So we'll insert a junk entry to avoid generating a null character.
lineArray := []string{""} // e.g. lineArray[4] == 'Hello\n'
+ lineHash := make(map[string]int)
//Each string has the index of lineArray which it points to
- strIndexArray1 := dmp.diffLinesToStringsMunge(text1, &lineArray)
- strIndexArray2 := dmp.diffLinesToStringsMunge(text2, &lineArray)
+ strIndexArray1 := dmp.diffLinesToStringsMunge(text1, &lineArray, lineHash)
+ strIndexArray2 := dmp.diffLinesToStringsMunge(text2, &lineArray, lineHash)
return intArrayToString(strIndexArray1), intArrayToString(strIndexArray2), lineArray
}
-// diffLinesToStringsMunge splits a text into an array of strings, and reduces the texts to a []string.
-func (dmp *DiffMatchPatch) diffLinesToStringsMunge(text string, lineArray *[]string) []uint32 {
- // Walk the text, pulling out a substring for each line. text.split('\n') would would temporarily double our memory footprint. Modifying text would create many large strings to garbage collect.
- lineHash := map[string]int{} // e.g. lineHash['Hello\n'] == 4
+// diffLinesToStringsMunge splits a text into an array of strings, and reduces the texts to a []index.
+func (dmp *DiffMatchPatch) diffLinesToStringsMunge(text string, lineArray *[]string, lineHash map[string]int) []index {
lineStart := 0
lineEnd := -1
- strs := []uint32{}
+ strs := []index{}
for lineEnd < len(text)-1 {
lineEnd = indexOf(text, "\n", lineStart)
@@ -1340,11 +1348,11 @@ func (dmp *DiffMatchPatch) diffLinesToStringsMunge(text string, lineArray *[]str
lineValue, ok := lineHash[line]
if ok {
- strs = append(strs, uint32(lineValue))
+ strs = append(strs, index(lineValue))
} else {
*lineArray = append(*lineArray, line)
lineHash[line] = len(*lineArray) - 1
- strs = append(strs, uint32(len(*lineArray)-1))
+ strs = append(strs, index(len(*lineArray)-1))
}
}
diff --git a/vendor/github.com/sergi/go-diff/diffmatchpatch/index.go b/vendor/github.com/sergi/go-diff/diffmatchpatch/index.go
new file mode 100644
index 000000000..965a1c64b
--- /dev/null
+++ b/vendor/github.com/sergi/go-diff/diffmatchpatch/index.go
@@ -0,0 +1,32 @@
+package diffmatchpatch
+
+type index uint32
+
+const runeSkipStart = 0xd800
+const runeSkipEnd = 0xdfff + 1
+const runeMax = 0x110000 // next invalid code point
+
+func stringToIndex(text string) []index {
+ runes := []rune(text)
+ indexes := make([]index, len(runes))
+ for i, r := range runes {
+ if r < runeSkipEnd {
+ indexes[i] = index(r)
+ } else {
+ indexes[i] = index(r) - (runeSkipEnd - runeSkipStart)
+ }
+ }
+ return indexes
+}
+
+func indexesToString(indexes []index) string {
+ runes := make([]rune, len(indexes))
+ for i, index := range indexes {
+ if index < runeSkipStart {
+ runes[i] = rune(index)
+ } else {
+ runes[i] = rune(index + (runeSkipEnd - runeSkipStart))
+ }
+ }
+ return string(runes)
+}
diff --git a/vendor/github.com/sergi/go-diff/diffmatchpatch/stringutil.go b/vendor/github.com/sergi/go-diff/diffmatchpatch/stringutil.go
index 44c435954..573b6bf75 100644
--- a/vendor/github.com/sergi/go-diff/diffmatchpatch/stringutil.go
+++ b/vendor/github.com/sergi/go-diff/diffmatchpatch/stringutil.go
@@ -9,11 +9,16 @@
package diffmatchpatch
import (
- "strconv"
+ "fmt"
"strings"
"unicode/utf8"
)
+const UNICODE_INVALID_RANGE_START = 0xD800
+const UNICODE_INVALID_RANGE_END = 0xDFFF
+const UNICODE_INVALID_RANGE_DELTA = UNICODE_INVALID_RANGE_END - UNICODE_INVALID_RANGE_START + 1
+const UNICODE_RANGE_MAX = 0x10FFFF
+
// unescaper unescapes selected chars for compatibility with JavaScript's encodeURI.
// In speed critical applications this could be dropped since the receiving application will certainly decode these fine. Note that this function is case-sensitive. Thus "%3F" would not be unescaped. But this is ok because it is only called with the output of HttpUtility.UrlEncode which returns lowercase hex. Example: "%3f" -> "?", "%24" -> "$", etc.
var unescaper = strings.NewReplacer(
@@ -88,19 +93,98 @@ func runesIndex(r1, r2 []rune) int {
return -1
}
-func intArrayToString(ns []uint32) string {
+func intArrayToString(ns []index) string {
if len(ns) == 0 {
return ""
}
- indexSeparator := IndexSeparator[0]
-
- // Appr. 3 chars per num plus the comma.
- b := []byte{}
+ b := []rune{}
for _, n := range ns {
- b = strconv.AppendInt(b, int64(n), 10)
- b = append(b, indexSeparator)
+ b = append(b, intToRune(uint32(n)))
}
- b = b[:len(b)-1]
return string(b)
}
+
+// These constants define the number of bits representable
+// in 1,2,3,4 byte utf8 sequences, respectively.
+const ONE_BYTE_BITS = 7
+const TWO_BYTE_BITS = 11
+const THREE_BYTE_BITS = 16
+const FOUR_BYTE_BITS = 21
+
+// Helper for getting a sequence of bits from an integer.
+func getBits(i uint32, cnt byte, from byte) byte {
+ return byte((i >> from) & ((1 << cnt) - 1))
+}
+
+// Converts an integer in the range 0~1112060 into a rune.
+// Based on the ranges table in https://en.wikipedia.org/wiki/UTF-8
+func intToRune(i uint32) rune {
+ if i < (1 << ONE_BYTE_BITS) {
+ return rune(i)
+ }
+
+ if i < (1 << TWO_BYTE_BITS) {
+ r, size := utf8.DecodeRune([]byte{0b11000000 | getBits(i, 5, 6), 0b10000000 | getBits(i, 6, 0)})
+ if size != 2 || r == utf8.RuneError {
+ panic(fmt.Sprintf("Error encoding an int %d with size 2, got rune %v and size %d", size, r, i))
+ }
+ return r
+ }
+
+ // Last -3 here needed because for some reason 3rd to last codepoint 65533 in this range
+ // was returning utf8.RuneError during encoding.
+ if i < ((1 << THREE_BYTE_BITS) - UNICODE_INVALID_RANGE_DELTA - 3) {
+ if i >= UNICODE_INVALID_RANGE_START {
+ i += UNICODE_INVALID_RANGE_DELTA
+ }
+
+ r, size := utf8.DecodeRune([]byte{0b11100000 | getBits(i, 4, 12), 0b10000000 | getBits(i, 6, 6), 0b10000000 | getBits(i, 6, 0)})
+ if size != 3 || r == utf8.RuneError {
+ panic(fmt.Sprintf("Error encoding an int %d with size 3, got rune %v and size %d", size, r, i))
+ }
+ return r
+ }
+
+ if i < (1<= UNICODE_INVALID_RANGE_END {
+ return result - UNICODE_INVALID_RANGE_DELTA
+ }
+
+ return result
+ }
+
+ if size == 4 {
+ result := uint32(bytes[0]&0b111)<<18 | uint32(bytes[1]&0b111111)<<12 | uint32(bytes[2]&0b111111)<<6 | uint32(bytes[3]&0b111111)
+ return result - UNICODE_INVALID_RANGE_DELTA - 3
+ }
+
+ panic(fmt.Sprintf("Unexpected state decoding rune=%v size=%d", r, size))
+}
diff --git a/vendor/github.com/shopspring/decimal/.gitignore b/vendor/github.com/shopspring/decimal/.gitignore
new file mode 100644
index 000000000..ff36b987f
--- /dev/null
+++ b/vendor/github.com/shopspring/decimal/.gitignore
@@ -0,0 +1,9 @@
+.git
+*.swp
+
+# IntelliJ
+.idea/
+*.iml
+
+# VS code
+*.code-workspace
diff --git a/vendor/github.com/shopspring/decimal/CHANGELOG.md b/vendor/github.com/shopspring/decimal/CHANGELOG.md
new file mode 100644
index 000000000..432d0fd4e
--- /dev/null
+++ b/vendor/github.com/shopspring/decimal/CHANGELOG.md
@@ -0,0 +1,76 @@
+## Decimal v1.4.0
+#### BREAKING
+- Drop support for Go version older than 1.10 [#361](https://github.com/shopspring/decimal/pull/361)
+
+#### FEATURES
+- Add implementation of natural logarithm [#339](https://github.com/shopspring/decimal/pull/339) [#357](https://github.com/shopspring/decimal/pull/357)
+- Add improved implementation of power operation [#358](https://github.com/shopspring/decimal/pull/358)
+- Add Compare method which forwards calls to Cmp [#346](https://github.com/shopspring/decimal/pull/346)
+- Add NewFromBigRat constructor [#288](https://github.com/shopspring/decimal/pull/288)
+- Add NewFromUint64 constructor [#352](https://github.com/shopspring/decimal/pull/352)
+
+#### ENHANCEMENTS
+- Migrate to Github Actions [#245](https://github.com/shopspring/decimal/pull/245) [#340](https://github.com/shopspring/decimal/pull/340)
+- Fix examples for RoundDown, RoundFloor, RoundUp, and RoundCeil [#285](https://github.com/shopspring/decimal/pull/285) [#328](https://github.com/shopspring/decimal/pull/328) [#341](https://github.com/shopspring/decimal/pull/341)
+- Use Godoc standard to mark deprecated Equals and StringScaled methods [#342](https://github.com/shopspring/decimal/pull/342)
+- Removed unnecessary min function for RescalePair method [#265](https://github.com/shopspring/decimal/pull/265)
+- Avoid reallocation of initial slice in MarshalBinary (GobEncode) [#355](https://github.com/shopspring/decimal/pull/355)
+- Optimize NumDigits method [#301](https://github.com/shopspring/decimal/pull/301) [#356](https://github.com/shopspring/decimal/pull/356)
+- Optimize BigInt method [#359](https://github.com/shopspring/decimal/pull/359)
+- Support scanning uint64 [#131](https://github.com/shopspring/decimal/pull/131) [#364](https://github.com/shopspring/decimal/pull/364)
+- Add docs section with alternative libraries [#363](https://github.com/shopspring/decimal/pull/363)
+
+#### BUGFIXES
+- Fix incorrect calculation of decimal modulo [#258](https://github.com/shopspring/decimal/pull/258) [#317](https://github.com/shopspring/decimal/pull/317)
+- Allocate new(big.Int) in Copy method to deeply clone it [#278](https://github.com/shopspring/decimal/pull/278)
+- Fix overflow edge case in QuoRem method [#322](https://github.com/shopspring/decimal/pull/322)
+
+## Decimal v1.3.1
+
+#### ENHANCEMENTS
+- Reduce memory allocation in case of initialization from big.Int [#252](https://github.com/shopspring/decimal/pull/252)
+
+#### BUGFIXES
+- Fix binary marshalling of decimal zero value [#253](https://github.com/shopspring/decimal/pull/253)
+
+## Decimal v1.3.0
+
+#### FEATURES
+- Add NewFromFormattedString initializer [#184](https://github.com/shopspring/decimal/pull/184)
+- Add NewNullDecimal initializer [#234](https://github.com/shopspring/decimal/pull/234)
+- Add implementation of natural exponent function (Taylor, Hull-Abraham) [#229](https://github.com/shopspring/decimal/pull/229)
+- Add RoundUp, RoundDown, RoundCeil, RoundFloor methods [#196](https://github.com/shopspring/decimal/pull/196) [#202](https://github.com/shopspring/decimal/pull/202) [#220](https://github.com/shopspring/decimal/pull/220)
+- Add XML support for NullDecimal [#192](https://github.com/shopspring/decimal/pull/192)
+- Add IsInteger method [#179](https://github.com/shopspring/decimal/pull/179)
+- Add Copy helper method [#123](https://github.com/shopspring/decimal/pull/123)
+- Add InexactFloat64 helper method [#205](https://github.com/shopspring/decimal/pull/205)
+- Add CoefficientInt64 helper method [#244](https://github.com/shopspring/decimal/pull/244)
+
+#### ENHANCEMENTS
+- Performance optimization of NewFromString init method [#198](https://github.com/shopspring/decimal/pull/198)
+- Performance optimization of Abs and Round methods [#240](https://github.com/shopspring/decimal/pull/240)
+- Additional tests (CI) for ppc64le architecture [#188](https://github.com/shopspring/decimal/pull/188)
+
+#### BUGFIXES
+- Fix rounding in FormatFloat fallback path (roundShortest method, fix taken from Go main repository) [#161](https://github.com/shopspring/decimal/pull/161)
+- Add slice range checks to UnmarshalBinary method [#232](https://github.com/shopspring/decimal/pull/232)
+
+## Decimal v1.2.0
+
+#### BREAKING
+- Drop support for Go version older than 1.7 [#172](https://github.com/shopspring/decimal/pull/172)
+
+#### FEATURES
+- Add NewFromInt and NewFromInt32 initializers [#72](https://github.com/shopspring/decimal/pull/72)
+- Add support for Go modules [#157](https://github.com/shopspring/decimal/pull/157)
+- Add BigInt, BigFloat helper methods [#171](https://github.com/shopspring/decimal/pull/171)
+
+#### ENHANCEMENTS
+- Memory usage optimization [#160](https://github.com/shopspring/decimal/pull/160)
+- Updated travis CI golang versions [#156](https://github.com/shopspring/decimal/pull/156)
+- Update documentation [#173](https://github.com/shopspring/decimal/pull/173)
+- Improve code quality [#174](https://github.com/shopspring/decimal/pull/174)
+
+#### BUGFIXES
+- Revert remove insignificant digits [#159](https://github.com/shopspring/decimal/pull/159)
+- Remove 15 interval for RoundCash [#166](https://github.com/shopspring/decimal/pull/166)
diff --git a/vendor/github.com/shopspring/decimal/LICENSE b/vendor/github.com/shopspring/decimal/LICENSE
new file mode 100644
index 000000000..ad2148aaf
--- /dev/null
+++ b/vendor/github.com/shopspring/decimal/LICENSE
@@ -0,0 +1,45 @@
+The MIT License (MIT)
+
+Copyright (c) 2015 Spring, Inc.
+
+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.
+
+- Based on https://github.com/oguzbilgic/fpd, which has the following license:
+"""
+The MIT License (MIT)
+
+Copyright (c) 2013 Oguz Bilgic
+
+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.
+"""
diff --git a/vendor/github.com/shopspring/decimal/README.md b/vendor/github.com/shopspring/decimal/README.md
new file mode 100644
index 000000000..318c9df58
--- /dev/null
+++ b/vendor/github.com/shopspring/decimal/README.md
@@ -0,0 +1,139 @@
+# decimal
+
+[](https://github.com/shopspring/decimal/actions/workflows/ci.yml)
+[](https://godoc.org/github.com/shopspring/decimal)
+[](https://goreportcard.com/report/github.com/shopspring/decimal)
+
+Arbitrary-precision fixed-point decimal numbers in go.
+
+_Note:_ Decimal library can "only" represent numbers with a maximum of 2^31 digits after the decimal point.
+
+## Features
+
+ * The zero-value is 0, and is safe to use without initialization
+ * Addition, subtraction, multiplication with no loss of precision
+ * Division with specified precision
+ * Database/sql serialization/deserialization
+ * JSON and XML serialization/deserialization
+
+## Install
+
+Run `go get github.com/shopspring/decimal`
+
+## Requirements
+
+Decimal library requires Go version `>=1.10`
+
+## Documentation
+
+http://godoc.org/github.com/shopspring/decimal
+
+
+## Usage
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/shopspring/decimal"
+)
+
+func main() {
+ price, err := decimal.NewFromString("136.02")
+ if err != nil {
+ panic(err)
+ }
+
+ quantity := decimal.NewFromInt(3)
+
+ fee, _ := decimal.NewFromString(".035")
+ taxRate, _ := decimal.NewFromString(".08875")
+
+ subtotal := price.Mul(quantity)
+
+ preTax := subtotal.Mul(fee.Add(decimal.NewFromFloat(1)))
+
+ total := preTax.Mul(taxRate.Add(decimal.NewFromFloat(1)))
+
+ fmt.Println("Subtotal:", subtotal) // Subtotal: 408.06
+ fmt.Println("Pre-tax:", preTax) // Pre-tax: 422.3421
+ fmt.Println("Taxes:", total.Sub(preTax)) // Taxes: 37.482861375
+ fmt.Println("Total:", total) // Total: 459.824961375
+ fmt.Println("Tax rate:", total.Sub(preTax).Div(preTax)) // Tax rate: 0.08875
+}
+```
+
+## Alternative libraries
+
+When working with decimal numbers, you might face problems this library is not perfectly suited for.
+Fortunately, thanks to the wonderful community we have a dozen other libraries that you can choose from.
+Explore other alternatives to find the one that best fits your needs :)
+
+* [cockroachdb/apd](https://github.com/cockroachdb/apd) - arbitrary precision, mutable and rich API similar to `big.Int`, more performant than this library
+* [alpacahq/alpacadecimal](https://github.com/alpacahq/alpacadecimal) - high performance, low precision (12 digits), fully compatible API with this library
+* [govalues/decimal](https://github.com/govalues/decimal) - high performance, zero-allocation, low precision (19 digits)
+* [greatcloak/decimal](https://github.com/greatcloak/decimal) - fork focusing on billing and e-commerce web application related use cases, includes out-of-the-box BSON marshaling support
+
+## FAQ
+
+#### Why don't you just use float64?
+
+Because float64 (or any binary floating point type, actually) can't represent
+numbers such as `0.1` exactly.
+
+Consider this code: http://play.golang.org/p/TQBd4yJe6B You might expect that
+it prints out `10`, but it actually prints `9.999999999999831`. Over time,
+these small errors can really add up!
+
+#### Why don't you just use big.Rat?
+
+big.Rat is fine for representing rational numbers, but Decimal is better for
+representing money. Why? Here's a (contrived) example:
+
+Let's say you use big.Rat, and you have two numbers, x and y, both
+representing 1/3, and you have `z = 1 - x - y = 1/3`. If you print each one
+out, the string output has to stop somewhere (let's say it stops at 3 decimal
+digits, for simplicity), so you'll get 0.333, 0.333, and 0.333. But where did
+the other 0.001 go?
+
+Here's the above example as code: http://play.golang.org/p/lCZZs0w9KE
+
+With Decimal, the strings being printed out represent the number exactly. So,
+if you have `x = y = 1/3` (with precision 3), they will actually be equal to
+0.333, and when you do `z = 1 - x - y`, `z` will be equal to .334. No money is
+unaccounted for!
+
+You still have to be careful. If you want to split a number `N` 3 ways, you
+can't just send `N/3` to three different people. You have to pick one to send
+`N - (2/3*N)` to. That person will receive the fraction of a penny remainder.
+
+But, it is much easier to be careful with Decimal than with big.Rat.
+
+#### Why isn't the API similar to big.Int's?
+
+big.Int's API is built to reduce the number of memory allocations for maximal
+performance. This makes sense for its use-case, but the trade-off is that the
+API is awkward and easy to misuse.
+
+For example, to add two big.Ints, you do: `z := new(big.Int).Add(x, y)`. A
+developer unfamiliar with this API might try to do `z := a.Add(a, b)`. This
+modifies `a` and sets `z` as an alias for `a`, which they might not expect. It
+also modifies any other aliases to `a`.
+
+Here's an example of the subtle bugs you can introduce with big.Int's API:
+https://play.golang.org/p/x2R_78pa8r
+
+In contrast, it's difficult to make such mistakes with decimal. Decimals
+behave like other go numbers types: even though `a = b` will not deep copy
+`b` into `a`, it is impossible to modify a Decimal, since all Decimal methods
+return new Decimals and do not modify the originals. The downside is that
+this causes extra allocations, so Decimal is less performant. My assumption
+is that if you're using Decimals, you probably care more about correctness
+than performance.
+
+## License
+
+The MIT License (MIT)
+
+This is a heavily modified fork of [fpd.Decimal](https://github.com/oguzbilgic/fpd), which was also released under the MIT License.
diff --git a/vendor/github.com/shopspring/decimal/const.go b/vendor/github.com/shopspring/decimal/const.go
new file mode 100644
index 000000000..e5d6fa87e
--- /dev/null
+++ b/vendor/github.com/shopspring/decimal/const.go
@@ -0,0 +1,63 @@
+package decimal
+
+import (
+ "strings"
+)
+
+const (
+ strLn10 = "2.302585092994045684017991454684364207601101488628772976033327900967572609677352480235997205089598298341967784042286248633409525465082806756666287369098781689482907208325554680843799894826233198528393505308965377732628846163366222287698219886746543667474404243274365155048934314939391479619404400222105101714174800368808401264708068556774321622835522011480466371565912137345074785694768346361679210180644507064800027750268491674655058685693567342067058113642922455440575892572420824131469568901675894025677631135691929203337658714166023010570308963457207544037084746994016826928280848118428931484852494864487192780967627127577539702766860595249671667418348570442250719796500471495105049221477656763693866297697952211071826454973477266242570942932258279850258550978526538320760672631716430950599508780752371033310119785754733154142180842754386359177811705430982748238504564801909561029929182431823752535770975053956518769751037497088869218020518933950723853920514463419726528728696511086257149219884997874887377134568620916705849807828059751193854445009978131146915934666241071846692310107598438319191292230792503747298650929009880391941702654416816335727555703151596113564846546190897042819763365836983716328982174407366009162177850541779276367731145041782137660111010731042397832521894898817597921798666394319523936855916447118246753245630912528778330963604262982153040874560927760726641354787576616262926568298704957954913954918049209069438580790032763017941503117866862092408537949861264933479354871737451675809537088281067452440105892444976479686075120275724181874989395971643105518848195288330746699317814634930000321200327765654130472621883970596794457943468343218395304414844803701305753674262153675579814770458031413637793236291560128185336498466942261465206459942072917119370602444929358037007718981097362533224548366988505528285966192805098447175198503666680874970496982273220244823343097169111136813588418696549323714996941979687803008850408979618598756579894836445212043698216415292987811742973332588607915912510967187510929248475023930572665446276200923068791518135803477701295593646298412366497023355174586195564772461857717369368404676577047874319780573853271810933883496338813069945569399346101090745616033312247949360455361849123333063704751724871276379140924398331810164737823379692265637682071706935846394531616949411701841938119405416449466111274712819705817783293841742231409930022911502362192186723337268385688273533371925103412930705632544426611429765388301822384091026198582888433587455960453004548370789052578473166283701953392231047527564998119228742789713715713228319641003422124210082180679525276689858180956119208391760721080919923461516952599099473782780648128058792731993893453415320185969711021407542282796298237068941764740642225757212455392526179373652434440560595336591539160312524480149313234572453879524389036839236450507881731359711238145323701508413491122324390927681724749607955799151363982881058285740538000653371655553014196332241918087621018204919492651483892"
+)
+
+var (
+ ln10 = newConstApproximation(strLn10)
+)
+
+type constApproximation struct {
+ exact Decimal
+ approximations []Decimal
+}
+
+func newConstApproximation(value string) constApproximation {
+ parts := strings.Split(value, ".")
+ coeff, fractional := parts[0], parts[1]
+
+ coeffLen := len(coeff)
+ maxPrecision := len(fractional)
+
+ var approximations []Decimal
+ for p := 1; p < maxPrecision; p *= 2 {
+ r := RequireFromString(value[:coeffLen+p])
+ approximations = append(approximations, r)
+ }
+
+ return constApproximation{
+ RequireFromString(value),
+ approximations,
+ }
+}
+
+// Returns the smallest approximation available that's at least as precise
+// as the passed precision (places after decimal point), i.e. Floor[ log2(precision) ] + 1
+func (c constApproximation) withPrecision(precision int32) Decimal {
+ i := 0
+
+ if precision >= 1 {
+ i++
+ }
+
+ for precision >= 16 {
+ precision /= 16
+ i += 4
+ }
+
+ for precision >= 2 {
+ precision /= 2
+ i++
+ }
+
+ if i >= len(c.approximations) {
+ return c.exact
+ }
+
+ return c.approximations[i]
+}
diff --git a/vendor/github.com/shopspring/decimal/decimal-go.go b/vendor/github.com/shopspring/decimal/decimal-go.go
new file mode 100644
index 000000000..9958d6902
--- /dev/null
+++ b/vendor/github.com/shopspring/decimal/decimal-go.go
@@ -0,0 +1,415 @@
+// Copyright 2009 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.
+
+// Multiprecision decimal numbers.
+// For floating-point formatting only; not general purpose.
+// Only operations are assign and (binary) left/right shift.
+// Can do binary floating point in multiprecision decimal precisely
+// because 2 divides 10; cannot do decimal floating point
+// in multiprecision binary precisely.
+
+package decimal
+
+type decimal struct {
+ d [800]byte // digits, big-endian representation
+ nd int // number of digits used
+ dp int // decimal point
+ neg bool // negative flag
+ trunc bool // discarded nonzero digits beyond d[:nd]
+}
+
+func (a *decimal) String() string {
+ n := 10 + a.nd
+ if a.dp > 0 {
+ n += a.dp
+ }
+ if a.dp < 0 {
+ n += -a.dp
+ }
+
+ buf := make([]byte, n)
+ w := 0
+ switch {
+ case a.nd == 0:
+ return "0"
+
+ case a.dp <= 0:
+ // zeros fill space between decimal point and digits
+ buf[w] = '0'
+ w++
+ buf[w] = '.'
+ w++
+ w += digitZero(buf[w : w+-a.dp])
+ w += copy(buf[w:], a.d[0:a.nd])
+
+ case a.dp < a.nd:
+ // decimal point in middle of digits
+ w += copy(buf[w:], a.d[0:a.dp])
+ buf[w] = '.'
+ w++
+ w += copy(buf[w:], a.d[a.dp:a.nd])
+
+ default:
+ // zeros fill space between digits and decimal point
+ w += copy(buf[w:], a.d[0:a.nd])
+ w += digitZero(buf[w : w+a.dp-a.nd])
+ }
+ return string(buf[0:w])
+}
+
+func digitZero(dst []byte) int {
+ for i := range dst {
+ dst[i] = '0'
+ }
+ return len(dst)
+}
+
+// trim trailing zeros from number.
+// (They are meaningless; the decimal point is tracked
+// independent of the number of digits.)
+func trim(a *decimal) {
+ for a.nd > 0 && a.d[a.nd-1] == '0' {
+ a.nd--
+ }
+ if a.nd == 0 {
+ a.dp = 0
+ }
+}
+
+// Assign v to a.
+func (a *decimal) Assign(v uint64) {
+ var buf [24]byte
+
+ // Write reversed decimal in buf.
+ n := 0
+ for v > 0 {
+ v1 := v / 10
+ v -= 10 * v1
+ buf[n] = byte(v + '0')
+ n++
+ v = v1
+ }
+
+ // Reverse again to produce forward decimal in a.d.
+ a.nd = 0
+ for n--; n >= 0; n-- {
+ a.d[a.nd] = buf[n]
+ a.nd++
+ }
+ a.dp = a.nd
+ trim(a)
+}
+
+// Maximum shift that we can do in one pass without overflow.
+// A uint has 32 or 64 bits, and we have to be able to accommodate 9<> 63)
+const maxShift = uintSize - 4
+
+// Binary shift right (/ 2) by k bits. k <= maxShift to avoid overflow.
+func rightShift(a *decimal, k uint) {
+ r := 0 // read pointer
+ w := 0 // write pointer
+
+ // Pick up enough leading digits to cover first shift.
+ var n uint
+ for ; n>>k == 0; r++ {
+ if r >= a.nd {
+ if n == 0 {
+ // a == 0; shouldn't get here, but handle anyway.
+ a.nd = 0
+ return
+ }
+ for n>>k == 0 {
+ n = n * 10
+ r++
+ }
+ break
+ }
+ c := uint(a.d[r])
+ n = n*10 + c - '0'
+ }
+ a.dp -= r - 1
+
+ var mask uint = (1 << k) - 1
+
+ // Pick up a digit, put down a digit.
+ for ; r < a.nd; r++ {
+ c := uint(a.d[r])
+ dig := n >> k
+ n &= mask
+ a.d[w] = byte(dig + '0')
+ w++
+ n = n*10 + c - '0'
+ }
+
+ // Put down extra digits.
+ for n > 0 {
+ dig := n >> k
+ n &= mask
+ if w < len(a.d) {
+ a.d[w] = byte(dig + '0')
+ w++
+ } else if dig > 0 {
+ a.trunc = true
+ }
+ n = n * 10
+ }
+
+ a.nd = w
+ trim(a)
+}
+
+// Cheat sheet for left shift: table indexed by shift count giving
+// number of new digits that will be introduced by that shift.
+//
+// For example, leftcheats[4] = {2, "625"}. That means that
+// if we are shifting by 4 (multiplying by 16), it will add 2 digits
+// when the string prefix is "625" through "999", and one fewer digit
+// if the string prefix is "000" through "624".
+//
+// Credit for this trick goes to Ken.
+
+type leftCheat struct {
+ delta int // number of new digits
+ cutoff string // minus one digit if original < a.
+}
+
+var leftcheats = []leftCheat{
+ // Leading digits of 1/2^i = 5^i.
+ // 5^23 is not an exact 64-bit floating point number,
+ // so have to use bc for the math.
+ // Go up to 60 to be large enough for 32bit and 64bit platforms.
+ /*
+ seq 60 | sed 's/^/5^/' | bc |
+ awk 'BEGIN{ print "\t{ 0, \"\" }," }
+ {
+ log2 = log(2)/log(10)
+ printf("\t{ %d, \"%s\" },\t// * %d\n",
+ int(log2*NR+1), $0, 2**NR)
+ }'
+ */
+ {0, ""},
+ {1, "5"}, // * 2
+ {1, "25"}, // * 4
+ {1, "125"}, // * 8
+ {2, "625"}, // * 16
+ {2, "3125"}, // * 32
+ {2, "15625"}, // * 64
+ {3, "78125"}, // * 128
+ {3, "390625"}, // * 256
+ {3, "1953125"}, // * 512
+ {4, "9765625"}, // * 1024
+ {4, "48828125"}, // * 2048
+ {4, "244140625"}, // * 4096
+ {4, "1220703125"}, // * 8192
+ {5, "6103515625"}, // * 16384
+ {5, "30517578125"}, // * 32768
+ {5, "152587890625"}, // * 65536
+ {6, "762939453125"}, // * 131072
+ {6, "3814697265625"}, // * 262144
+ {6, "19073486328125"}, // * 524288
+ {7, "95367431640625"}, // * 1048576
+ {7, "476837158203125"}, // * 2097152
+ {7, "2384185791015625"}, // * 4194304
+ {7, "11920928955078125"}, // * 8388608
+ {8, "59604644775390625"}, // * 16777216
+ {8, "298023223876953125"}, // * 33554432
+ {8, "1490116119384765625"}, // * 67108864
+ {9, "7450580596923828125"}, // * 134217728
+ {9, "37252902984619140625"}, // * 268435456
+ {9, "186264514923095703125"}, // * 536870912
+ {10, "931322574615478515625"}, // * 1073741824
+ {10, "4656612873077392578125"}, // * 2147483648
+ {10, "23283064365386962890625"}, // * 4294967296
+ {10, "116415321826934814453125"}, // * 8589934592
+ {11, "582076609134674072265625"}, // * 17179869184
+ {11, "2910383045673370361328125"}, // * 34359738368
+ {11, "14551915228366851806640625"}, // * 68719476736
+ {12, "72759576141834259033203125"}, // * 137438953472
+ {12, "363797880709171295166015625"}, // * 274877906944
+ {12, "1818989403545856475830078125"}, // * 549755813888
+ {13, "9094947017729282379150390625"}, // * 1099511627776
+ {13, "45474735088646411895751953125"}, // * 2199023255552
+ {13, "227373675443232059478759765625"}, // * 4398046511104
+ {13, "1136868377216160297393798828125"}, // * 8796093022208
+ {14, "5684341886080801486968994140625"}, // * 17592186044416
+ {14, "28421709430404007434844970703125"}, // * 35184372088832
+ {14, "142108547152020037174224853515625"}, // * 70368744177664
+ {15, "710542735760100185871124267578125"}, // * 140737488355328
+ {15, "3552713678800500929355621337890625"}, // * 281474976710656
+ {15, "17763568394002504646778106689453125"}, // * 562949953421312
+ {16, "88817841970012523233890533447265625"}, // * 1125899906842624
+ {16, "444089209850062616169452667236328125"}, // * 2251799813685248
+ {16, "2220446049250313080847263336181640625"}, // * 4503599627370496
+ {16, "11102230246251565404236316680908203125"}, // * 9007199254740992
+ {17, "55511151231257827021181583404541015625"}, // * 18014398509481984
+ {17, "277555756156289135105907917022705078125"}, // * 36028797018963968
+ {17, "1387778780781445675529539585113525390625"}, // * 72057594037927936
+ {18, "6938893903907228377647697925567626953125"}, // * 144115188075855872
+ {18, "34694469519536141888238489627838134765625"}, // * 288230376151711744
+ {18, "173472347597680709441192448139190673828125"}, // * 576460752303423488
+ {19, "867361737988403547205962240695953369140625"}, // * 1152921504606846976
+}
+
+// Is the leading prefix of b lexicographically less than s?
+func prefixIsLessThan(b []byte, s string) bool {
+ for i := 0; i < len(s); i++ {
+ if i >= len(b) {
+ return true
+ }
+ if b[i] != s[i] {
+ return b[i] < s[i]
+ }
+ }
+ return false
+}
+
+// Binary shift left (* 2) by k bits. k <= maxShift to avoid overflow.
+func leftShift(a *decimal, k uint) {
+ delta := leftcheats[k].delta
+ if prefixIsLessThan(a.d[0:a.nd], leftcheats[k].cutoff) {
+ delta--
+ }
+
+ r := a.nd // read index
+ w := a.nd + delta // write index
+
+ // Pick up a digit, put down a digit.
+ var n uint
+ for r--; r >= 0; r-- {
+ n += (uint(a.d[r]) - '0') << k
+ quo := n / 10
+ rem := n - 10*quo
+ w--
+ if w < len(a.d) {
+ a.d[w] = byte(rem + '0')
+ } else if rem != 0 {
+ a.trunc = true
+ }
+ n = quo
+ }
+
+ // Put down extra digits.
+ for n > 0 {
+ quo := n / 10
+ rem := n - 10*quo
+ w--
+ if w < len(a.d) {
+ a.d[w] = byte(rem + '0')
+ } else if rem != 0 {
+ a.trunc = true
+ }
+ n = quo
+ }
+
+ a.nd += delta
+ if a.nd >= len(a.d) {
+ a.nd = len(a.d)
+ }
+ a.dp += delta
+ trim(a)
+}
+
+// Binary shift left (k > 0) or right (k < 0).
+func (a *decimal) Shift(k int) {
+ switch {
+ case a.nd == 0:
+ // nothing to do: a == 0
+ case k > 0:
+ for k > maxShift {
+ leftShift(a, maxShift)
+ k -= maxShift
+ }
+ leftShift(a, uint(k))
+ case k < 0:
+ for k < -maxShift {
+ rightShift(a, maxShift)
+ k += maxShift
+ }
+ rightShift(a, uint(-k))
+ }
+}
+
+// If we chop a at nd digits, should we round up?
+func shouldRoundUp(a *decimal, nd int) bool {
+ if nd < 0 || nd >= a.nd {
+ return false
+ }
+ if a.d[nd] == '5' && nd+1 == a.nd { // exactly halfway - round to even
+ // if we truncated, a little higher than what's recorded - always round up
+ if a.trunc {
+ return true
+ }
+ return nd > 0 && (a.d[nd-1]-'0')%2 != 0
+ }
+ // not halfway - digit tells all
+ return a.d[nd] >= '5'
+}
+
+// Round a to nd digits (or fewer).
+// If nd is zero, it means we're rounding
+// just to the left of the digits, as in
+// 0.09 -> 0.1.
+func (a *decimal) Round(nd int) {
+ if nd < 0 || nd >= a.nd {
+ return
+ }
+ if shouldRoundUp(a, nd) {
+ a.RoundUp(nd)
+ } else {
+ a.RoundDown(nd)
+ }
+}
+
+// Round a down to nd digits (or fewer).
+func (a *decimal) RoundDown(nd int) {
+ if nd < 0 || nd >= a.nd {
+ return
+ }
+ a.nd = nd
+ trim(a)
+}
+
+// Round a up to nd digits (or fewer).
+func (a *decimal) RoundUp(nd int) {
+ if nd < 0 || nd >= a.nd {
+ return
+ }
+
+ // round up
+ for i := nd - 1; i >= 0; i-- {
+ c := a.d[i]
+ if c < '9' { // can stop after this digit
+ a.d[i]++
+ a.nd = i + 1
+ return
+ }
+ }
+
+ // Number is all 9s.
+ // Change to single 1 with adjusted decimal point.
+ a.d[0] = '1'
+ a.nd = 1
+ a.dp++
+}
+
+// Extract integer part, rounded appropriately.
+// No guarantees about overflow.
+func (a *decimal) RoundedInteger() uint64 {
+ if a.dp > 20 {
+ return 0xFFFFFFFFFFFFFFFF
+ }
+ var i int
+ n := uint64(0)
+ for i = 0; i < a.dp && i < a.nd; i++ {
+ n = n*10 + uint64(a.d[i]-'0')
+ }
+ for ; i < a.dp; i++ {
+ n *= 10
+ }
+ if shouldRoundUp(a, a.dp) {
+ n++
+ }
+ return n
+}
diff --git a/vendor/github.com/shopspring/decimal/decimal.go b/vendor/github.com/shopspring/decimal/decimal.go
new file mode 100644
index 000000000..a37a2301e
--- /dev/null
+++ b/vendor/github.com/shopspring/decimal/decimal.go
@@ -0,0 +1,2339 @@
+// Package decimal implements an arbitrary precision fixed-point decimal.
+//
+// The zero-value of a Decimal is 0, as you would expect.
+//
+// The best way to create a new Decimal is to use decimal.NewFromString, ex:
+//
+// n, err := decimal.NewFromString("-123.4567")
+// n.String() // output: "-123.4567"
+//
+// To use Decimal as part of a struct:
+//
+// type StructName struct {
+// Number Decimal
+// }
+//
+// Note: This can "only" represent numbers with a maximum of 2^31 digits after the decimal point.
+package decimal
+
+import (
+ "database/sql/driver"
+ "encoding/binary"
+ "fmt"
+ "math"
+ "math/big"
+ "regexp"
+ "strconv"
+ "strings"
+)
+
+// DivisionPrecision is the number of decimal places in the result when it
+// doesn't divide exactly.
+//
+// Example:
+//
+// d1 := decimal.NewFromFloat(2).Div(decimal.NewFromFloat(3))
+// d1.String() // output: "0.6666666666666667"
+// d2 := decimal.NewFromFloat(2).Div(decimal.NewFromFloat(30000))
+// d2.String() // output: "0.0000666666666667"
+// d3 := decimal.NewFromFloat(20000).Div(decimal.NewFromFloat(3))
+// d3.String() // output: "6666.6666666666666667"
+// decimal.DivisionPrecision = 3
+// d4 := decimal.NewFromFloat(2).Div(decimal.NewFromFloat(3))
+// d4.String() // output: "0.667"
+var DivisionPrecision = 16
+
+// PowPrecisionNegativeExponent specifies the maximum precision of the result (digits after decimal point)
+// when calculating decimal power. Only used for cases where the exponent is a negative number.
+// This constant applies to Pow, PowInt32 and PowBigInt methods, PowWithPrecision method is not constrained by it.
+//
+// Example:
+//
+// d1, err := decimal.NewFromFloat(15.2).PowInt32(-2)
+// d1.String() // output: "0.0043282548476454"
+//
+// decimal.PowPrecisionNegativeExponent = 24
+// d2, err := decimal.NewFromFloat(15.2).PowInt32(-2)
+// d2.String() // output: "0.004328254847645429362881"
+var PowPrecisionNegativeExponent = 16
+
+// MarshalJSONWithoutQuotes should be set to true if you want the decimal to
+// be JSON marshaled as a number, instead of as a string.
+// WARNING: this is dangerous for decimals with many digits, since many JSON
+// unmarshallers (ex: Javascript's) will unmarshal JSON numbers to IEEE 754
+// double-precision floating point numbers, which means you can potentially
+// silently lose precision.
+var MarshalJSONWithoutQuotes = false
+
+// ExpMaxIterations specifies the maximum number of iterations needed to calculate
+// precise natural exponent value using ExpHullAbrham method.
+var ExpMaxIterations = 1000
+
+// Zero constant, to make computations faster.
+// Zero should never be compared with == or != directly, please use decimal.Equal or decimal.Cmp instead.
+var Zero = New(0, 1)
+
+var zeroInt = big.NewInt(0)
+var oneInt = big.NewInt(1)
+var twoInt = big.NewInt(2)
+var fourInt = big.NewInt(4)
+var fiveInt = big.NewInt(5)
+var tenInt = big.NewInt(10)
+var twentyInt = big.NewInt(20)
+
+var factorials = []Decimal{New(1, 0)}
+
+// Decimal represents a fixed-point decimal. It is immutable.
+// number = value * 10 ^ exp
+type Decimal struct {
+ value *big.Int
+
+ // NOTE(vadim): this must be an int32, because we cast it to float64 during
+ // calculations. If exp is 64 bit, we might lose precision.
+ // If we cared about being able to represent every possible decimal, we
+ // could make exp a *big.Int but it would hurt performance and numbers
+ // like that are unrealistic.
+ exp int32
+}
+
+// New returns a new fixed-point decimal, value * 10 ^ exp.
+func New(value int64, exp int32) Decimal {
+ return Decimal{
+ value: big.NewInt(value),
+ exp: exp,
+ }
+}
+
+// NewFromInt converts an int64 to Decimal.
+//
+// Example:
+//
+// NewFromInt(123).String() // output: "123"
+// NewFromInt(-10).String() // output: "-10"
+func NewFromInt(value int64) Decimal {
+ return Decimal{
+ value: big.NewInt(value),
+ exp: 0,
+ }
+}
+
+// NewFromInt32 converts an int32 to Decimal.
+//
+// Example:
+//
+// NewFromInt(123).String() // output: "123"
+// NewFromInt(-10).String() // output: "-10"
+func NewFromInt32(value int32) Decimal {
+ return Decimal{
+ value: big.NewInt(int64(value)),
+ exp: 0,
+ }
+}
+
+// NewFromUint64 converts an uint64 to Decimal.
+//
+// Example:
+//
+// NewFromUint64(123).String() // output: "123"
+func NewFromUint64(value uint64) Decimal {
+ return Decimal{
+ value: new(big.Int).SetUint64(value),
+ exp: 0,
+ }
+}
+
+// NewFromBigInt returns a new Decimal from a big.Int, value * 10 ^ exp
+func NewFromBigInt(value *big.Int, exp int32) Decimal {
+ return Decimal{
+ value: new(big.Int).Set(value),
+ exp: exp,
+ }
+}
+
+// NewFromBigRat returns a new Decimal from a big.Rat. The numerator and
+// denominator are divided and rounded to the given precision.
+//
+// Example:
+//
+// d1 := NewFromBigRat(big.NewRat(0, 1), 0) // output: "0"
+// d2 := NewFromBigRat(big.NewRat(4, 5), 1) // output: "0.8"
+// d3 := NewFromBigRat(big.NewRat(1000, 3), 3) // output: "333.333"
+// d4 := NewFromBigRat(big.NewRat(2, 7), 4) // output: "0.2857"
+func NewFromBigRat(value *big.Rat, precision int32) Decimal {
+ return Decimal{
+ value: new(big.Int).Set(value.Num()),
+ exp: 0,
+ }.DivRound(Decimal{
+ value: new(big.Int).Set(value.Denom()),
+ exp: 0,
+ }, precision)
+}
+
+// NewFromString returns a new Decimal from a string representation.
+// Trailing zeroes are not trimmed.
+//
+// Example:
+//
+// d, err := NewFromString("-123.45")
+// d2, err := NewFromString(".0001")
+// d3, err := NewFromString("1.47000")
+func NewFromString(value string) (Decimal, error) {
+ originalInput := value
+ var intString string
+ var exp int64
+
+ // Check if number is using scientific notation
+ eIndex := strings.IndexAny(value, "Ee")
+ if eIndex != -1 {
+ expInt, err := strconv.ParseInt(value[eIndex+1:], 10, 32)
+ if err != nil {
+ if e, ok := err.(*strconv.NumError); ok && e.Err == strconv.ErrRange {
+ return Decimal{}, fmt.Errorf("can't convert %s to decimal: fractional part too long", value)
+ }
+ return Decimal{}, fmt.Errorf("can't convert %s to decimal: exponent is not numeric", value)
+ }
+ value = value[:eIndex]
+ exp = expInt
+ }
+
+ pIndex := -1
+ vLen := len(value)
+ for i := 0; i < vLen; i++ {
+ if value[i] == '.' {
+ if pIndex > -1 {
+ return Decimal{}, fmt.Errorf("can't convert %s to decimal: too many .s", value)
+ }
+ pIndex = i
+ }
+ }
+
+ if pIndex == -1 {
+ // There is no decimal point, we can just parse the original string as
+ // an int
+ intString = value
+ } else {
+ if pIndex+1 < vLen {
+ intString = value[:pIndex] + value[pIndex+1:]
+ } else {
+ intString = value[:pIndex]
+ }
+ expInt := -len(value[pIndex+1:])
+ exp += int64(expInt)
+ }
+
+ var dValue *big.Int
+ // strconv.ParseInt is faster than new(big.Int).SetString so this is just a shortcut for strings we know won't overflow
+ if len(intString) <= 18 {
+ parsed64, err := strconv.ParseInt(intString, 10, 64)
+ if err != nil {
+ return Decimal{}, fmt.Errorf("can't convert %s to decimal", value)
+ }
+ dValue = big.NewInt(parsed64)
+ } else {
+ dValue = new(big.Int)
+ _, ok := dValue.SetString(intString, 10)
+ if !ok {
+ return Decimal{}, fmt.Errorf("can't convert %s to decimal", value)
+ }
+ }
+
+ if exp < math.MinInt32 || exp > math.MaxInt32 {
+ // NOTE(vadim): I doubt a string could realistically be this long
+ return Decimal{}, fmt.Errorf("can't convert %s to decimal: fractional part too long", originalInput)
+ }
+
+ return Decimal{
+ value: dValue,
+ exp: int32(exp),
+ }, nil
+}
+
+// NewFromFormattedString returns a new Decimal from a formatted string representation.
+// The second argument - replRegexp, is a regular expression that is used to find characters that should be
+// removed from given decimal string representation. All matched characters will be replaced with an empty string.
+//
+// Example:
+//
+// r := regexp.MustCompile("[$,]")
+// d1, err := NewFromFormattedString("$5,125.99", r)
+//
+// r2 := regexp.MustCompile("[_]")
+// d2, err := NewFromFormattedString("1_000_000", r2)
+//
+// r3 := regexp.MustCompile("[USD\\s]")
+// d3, err := NewFromFormattedString("5000 USD", r3)
+func NewFromFormattedString(value string, replRegexp *regexp.Regexp) (Decimal, error) {
+ parsedValue := replRegexp.ReplaceAllString(value, "")
+ d, err := NewFromString(parsedValue)
+ if err != nil {
+ return Decimal{}, err
+ }
+ return d, nil
+}
+
+// RequireFromString returns a new Decimal from a string representation
+// or panics if NewFromString had returned an error.
+//
+// Example:
+//
+// d := RequireFromString("-123.45")
+// d2 := RequireFromString(".0001")
+func RequireFromString(value string) Decimal {
+ dec, err := NewFromString(value)
+ if err != nil {
+ panic(err)
+ }
+ return dec
+}
+
+// NewFromFloat converts a float64 to Decimal.
+//
+// The converted number will contain the number of significant digits that can be
+// represented in a float with reliable roundtrip.
+// This is typically 15 digits, but may be more in some cases.
+// See https://www.exploringbinary.com/decimal-precision-of-binary-floating-point-numbers/ for more information.
+//
+// For slightly faster conversion, use NewFromFloatWithExponent where you can specify the precision in absolute terms.
+//
+// NOTE: this will panic on NaN, +/-inf
+func NewFromFloat(value float64) Decimal {
+ if value == 0 {
+ return New(0, 0)
+ }
+ return newFromFloat(value, math.Float64bits(value), &float64info)
+}
+
+// NewFromFloat32 converts a float32 to Decimal.
+//
+// The converted number will contain the number of significant digits that can be
+// represented in a float with reliable roundtrip.
+// This is typically 6-8 digits depending on the input.
+// See https://www.exploringbinary.com/decimal-precision-of-binary-floating-point-numbers/ for more information.
+//
+// For slightly faster conversion, use NewFromFloatWithExponent where you can specify the precision in absolute terms.
+//
+// NOTE: this will panic on NaN, +/-inf
+func NewFromFloat32(value float32) Decimal {
+ if value == 0 {
+ return New(0, 0)
+ }
+ // XOR is workaround for https://github.com/golang/go/issues/26285
+ a := math.Float32bits(value) ^ 0x80808080
+ return newFromFloat(float64(value), uint64(a)^0x80808080, &float32info)
+}
+
+func newFromFloat(val float64, bits uint64, flt *floatInfo) Decimal {
+ if math.IsNaN(val) || math.IsInf(val, 0) {
+ panic(fmt.Sprintf("Cannot create a Decimal from %v", val))
+ }
+ exp := int(bits>>flt.mantbits) & (1<>(flt.expbits+flt.mantbits) != 0
+
+ roundShortest(&d, mant, exp, flt)
+ // If less than 19 digits, we can do calculation in an int64.
+ if d.nd < 19 {
+ tmp := int64(0)
+ m := int64(1)
+ for i := d.nd - 1; i >= 0; i-- {
+ tmp += m * int64(d.d[i]-'0')
+ m *= 10
+ }
+ if d.neg {
+ tmp *= -1
+ }
+ return Decimal{value: big.NewInt(tmp), exp: int32(d.dp) - int32(d.nd)}
+ }
+ dValue := new(big.Int)
+ dValue, ok := dValue.SetString(string(d.d[:d.nd]), 10)
+ if ok {
+ return Decimal{value: dValue, exp: int32(d.dp) - int32(d.nd)}
+ }
+
+ return NewFromFloatWithExponent(val, int32(d.dp)-int32(d.nd))
+}
+
+// NewFromFloatWithExponent converts a float64 to Decimal, with an arbitrary
+// number of fractional digits.
+//
+// Example:
+//
+// NewFromFloatWithExponent(123.456, -2).String() // output: "123.46"
+func NewFromFloatWithExponent(value float64, exp int32) Decimal {
+ if math.IsNaN(value) || math.IsInf(value, 0) {
+ panic(fmt.Sprintf("Cannot create a Decimal from %v", value))
+ }
+
+ bits := math.Float64bits(value)
+ mant := bits & (1<<52 - 1)
+ exp2 := int32((bits >> 52) & (1<<11 - 1))
+ sign := bits >> 63
+
+ if exp2 == 0 {
+ // specials
+ if mant == 0 {
+ return Decimal{}
+ }
+ // subnormal
+ exp2++
+ } else {
+ // normal
+ mant |= 1 << 52
+ }
+
+ exp2 -= 1023 + 52
+
+ // normalizing base-2 values
+ for mant&1 == 0 {
+ mant = mant >> 1
+ exp2++
+ }
+
+ // maximum number of fractional base-10 digits to represent 2^N exactly cannot be more than -N if N<0
+ if exp < 0 && exp < exp2 {
+ if exp2 < 0 {
+ exp = exp2
+ } else {
+ exp = 0
+ }
+ }
+
+ // representing 10^M * 2^N as 5^M * 2^(M+N)
+ exp2 -= exp
+
+ temp := big.NewInt(1)
+ dMant := big.NewInt(int64(mant))
+
+ // applying 5^M
+ if exp > 0 {
+ temp = temp.SetInt64(int64(exp))
+ temp = temp.Exp(fiveInt, temp, nil)
+ } else if exp < 0 {
+ temp = temp.SetInt64(-int64(exp))
+ temp = temp.Exp(fiveInt, temp, nil)
+ dMant = dMant.Mul(dMant, temp)
+ temp = temp.SetUint64(1)
+ }
+
+ // applying 2^(M+N)
+ if exp2 > 0 {
+ dMant = dMant.Lsh(dMant, uint(exp2))
+ } else if exp2 < 0 {
+ temp = temp.Lsh(temp, uint(-exp2))
+ }
+
+ // rounding and downscaling
+ if exp > 0 || exp2 < 0 {
+ halfDown := new(big.Int).Rsh(temp, 1)
+ dMant = dMant.Add(dMant, halfDown)
+ dMant = dMant.Quo(dMant, temp)
+ }
+
+ if sign == 1 {
+ dMant = dMant.Neg(dMant)
+ }
+
+ return Decimal{
+ value: dMant,
+ exp: exp,
+ }
+}
+
+// Copy returns a copy of decimal with the same value and exponent, but a different pointer to value.
+func (d Decimal) Copy() Decimal {
+ d.ensureInitialized()
+ return Decimal{
+ value: new(big.Int).Set(d.value),
+ exp: d.exp,
+ }
+}
+
+// rescale returns a rescaled version of the decimal. Returned
+// decimal may be less precise if the given exponent is bigger
+// than the initial exponent of the Decimal.
+// NOTE: this will truncate, NOT round
+//
+// Example:
+//
+// d := New(12345, -4)
+// d2 := d.rescale(-1)
+// d3 := d2.rescale(-4)
+// println(d1)
+// println(d2)
+// println(d3)
+//
+// Output:
+//
+// 1.2345
+// 1.2
+// 1.2000
+func (d Decimal) rescale(exp int32) Decimal {
+ d.ensureInitialized()
+
+ if d.exp == exp {
+ return Decimal{
+ new(big.Int).Set(d.value),
+ d.exp,
+ }
+ }
+
+ // NOTE(vadim): must convert exps to float64 before - to prevent overflow
+ diff := math.Abs(float64(exp) - float64(d.exp))
+ value := new(big.Int).Set(d.value)
+
+ expScale := new(big.Int).Exp(tenInt, big.NewInt(int64(diff)), nil)
+ if exp > d.exp {
+ value = value.Quo(value, expScale)
+ } else if exp < d.exp {
+ value = value.Mul(value, expScale)
+ }
+
+ return Decimal{
+ value: value,
+ exp: exp,
+ }
+}
+
+// Abs returns the absolute value of the decimal.
+func (d Decimal) Abs() Decimal {
+ if !d.IsNegative() {
+ return d
+ }
+ d.ensureInitialized()
+ d2Value := new(big.Int).Abs(d.value)
+ return Decimal{
+ value: d2Value,
+ exp: d.exp,
+ }
+}
+
+// Add returns d + d2.
+func (d Decimal) Add(d2 Decimal) Decimal {
+ rd, rd2 := RescalePair(d, d2)
+
+ d3Value := new(big.Int).Add(rd.value, rd2.value)
+ return Decimal{
+ value: d3Value,
+ exp: rd.exp,
+ }
+}
+
+// Sub returns d - d2.
+func (d Decimal) Sub(d2 Decimal) Decimal {
+ rd, rd2 := RescalePair(d, d2)
+
+ d3Value := new(big.Int).Sub(rd.value, rd2.value)
+ return Decimal{
+ value: d3Value,
+ exp: rd.exp,
+ }
+}
+
+// Neg returns -d.
+func (d Decimal) Neg() Decimal {
+ d.ensureInitialized()
+ val := new(big.Int).Neg(d.value)
+ return Decimal{
+ value: val,
+ exp: d.exp,
+ }
+}
+
+// Mul returns d * d2.
+func (d Decimal) Mul(d2 Decimal) Decimal {
+ d.ensureInitialized()
+ d2.ensureInitialized()
+
+ expInt64 := int64(d.exp) + int64(d2.exp)
+ if expInt64 > math.MaxInt32 || expInt64 < math.MinInt32 {
+ // NOTE(vadim): better to panic than give incorrect results, as
+ // Decimals are usually used for money
+ panic(fmt.Sprintf("exponent %v overflows an int32!", expInt64))
+ }
+
+ d3Value := new(big.Int).Mul(d.value, d2.value)
+ return Decimal{
+ value: d3Value,
+ exp: int32(expInt64),
+ }
+}
+
+// Shift shifts the decimal in base 10.
+// It shifts left when shift is positive and right if shift is negative.
+// In simpler terms, the given value for shift is added to the exponent
+// of the decimal.
+func (d Decimal) Shift(shift int32) Decimal {
+ d.ensureInitialized()
+ return Decimal{
+ value: new(big.Int).Set(d.value),
+ exp: d.exp + shift,
+ }
+}
+
+// Div returns d / d2. If it doesn't divide exactly, the result will have
+// DivisionPrecision digits after the decimal point.
+func (d Decimal) Div(d2 Decimal) Decimal {
+ return d.DivRound(d2, int32(DivisionPrecision))
+}
+
+// QuoRem does division with remainder
+// d.QuoRem(d2,precision) returns quotient q and remainder r such that
+//
+// d = d2 * q + r, q an integer multiple of 10^(-precision)
+// 0 <= r < abs(d2) * 10 ^(-precision) if d>=0
+// 0 >= r > -abs(d2) * 10 ^(-precision) if d<0
+//
+// Note that precision<0 is allowed as input.
+func (d Decimal) QuoRem(d2 Decimal, precision int32) (Decimal, Decimal) {
+ d.ensureInitialized()
+ d2.ensureInitialized()
+ if d2.value.Sign() == 0 {
+ panic("decimal division by 0")
+ }
+ scale := -precision
+ e := int64(d.exp) - int64(d2.exp) - int64(scale)
+ if e > math.MaxInt32 || e < math.MinInt32 {
+ panic("overflow in decimal QuoRem")
+ }
+ var aa, bb, expo big.Int
+ var scalerest int32
+ // d = a 10^ea
+ // d2 = b 10^eb
+ if e < 0 {
+ aa = *d.value
+ expo.SetInt64(-e)
+ bb.Exp(tenInt, &expo, nil)
+ bb.Mul(d2.value, &bb)
+ scalerest = d.exp
+ // now aa = a
+ // bb = b 10^(scale + eb - ea)
+ } else {
+ expo.SetInt64(e)
+ aa.Exp(tenInt, &expo, nil)
+ aa.Mul(d.value, &aa)
+ bb = *d2.value
+ scalerest = scale + d2.exp
+ // now aa = a ^ (ea - eb - scale)
+ // bb = b
+ }
+ var q, r big.Int
+ q.QuoRem(&aa, &bb, &r)
+ dq := Decimal{value: &q, exp: scale}
+ dr := Decimal{value: &r, exp: scalerest}
+ return dq, dr
+}
+
+// DivRound divides and rounds to a given precision
+// i.e. to an integer multiple of 10^(-precision)
+//
+// for a positive quotient digit 5 is rounded up, away from 0
+// if the quotient is negative then digit 5 is rounded down, away from 0
+//
+// Note that precision<0 is allowed as input.
+func (d Decimal) DivRound(d2 Decimal, precision int32) Decimal {
+ // QuoRem already checks initialization
+ q, r := d.QuoRem(d2, precision)
+ // the actual rounding decision is based on comparing r*10^precision and d2/2
+ // instead compare 2 r 10 ^precision and d2
+ var rv2 big.Int
+ rv2.Abs(r.value)
+ rv2.Lsh(&rv2, 1)
+ // now rv2 = abs(r.value) * 2
+ r2 := Decimal{value: &rv2, exp: r.exp + precision}
+ // r2 is now 2 * r * 10 ^ precision
+ var c = r2.Cmp(d2.Abs())
+
+ if c < 0 {
+ return q
+ }
+
+ if d.value.Sign()*d2.value.Sign() < 0 {
+ return q.Sub(New(1, -precision))
+ }
+
+ return q.Add(New(1, -precision))
+}
+
+// Mod returns d % d2.
+func (d Decimal) Mod(d2 Decimal) Decimal {
+ _, r := d.QuoRem(d2, 0)
+ return r
+}
+
+// Pow returns d to the power of d2.
+// When exponent is negative the returned decimal will have maximum precision of PowPrecisionNegativeExponent places after decimal point.
+//
+// Pow returns 0 (zero-value of Decimal) instead of error for power operation edge cases, to handle those edge cases use PowWithPrecision
+// Edge cases not handled by Pow:
+// - 0 ** 0 => undefined value
+// - 0 ** y, where y < 0 => infinity
+// - x ** y, where x < 0 and y is non-integer decimal => imaginary value
+//
+// Example:
+//
+// d1 := decimal.NewFromFloat(4.0)
+// d2 := decimal.NewFromFloat(4.0)
+// res1 := d1.Pow(d2)
+// res1.String() // output: "256"
+//
+// d3 := decimal.NewFromFloat(5.0)
+// d4 := decimal.NewFromFloat(5.73)
+// res2 := d3.Pow(d4)
+// res2.String() // output: "10118.08037125"
+func (d Decimal) Pow(d2 Decimal) Decimal {
+ baseSign := d.Sign()
+ expSign := d2.Sign()
+
+ if baseSign == 0 {
+ if expSign == 0 {
+ return Decimal{}
+ }
+ if expSign == 1 {
+ return Decimal{zeroInt, 0}
+ }
+ if expSign == -1 {
+ return Decimal{}
+ }
+ }
+
+ if expSign == 0 {
+ return Decimal{oneInt, 0}
+ }
+
+ // TODO: optimize extraction of fractional part
+ one := Decimal{oneInt, 0}
+ expIntPart, expFracPart := d2.QuoRem(one, 0)
+
+ if baseSign == -1 && !expFracPart.IsZero() {
+ return Decimal{}
+ }
+
+ intPartPow, _ := d.PowBigInt(expIntPart.value)
+
+ // if exponent is an integer we don't need to calculate d1**frac(d2)
+ if expFracPart.value.Sign() == 0 {
+ return intPartPow
+ }
+
+ // TODO: optimize NumDigits for more performant precision adjustment
+ digitsBase := d.NumDigits()
+ digitsExponent := d2.NumDigits()
+
+ precision := digitsBase
+
+ if digitsExponent > precision {
+ precision += digitsExponent
+ }
+
+ precision += 6
+
+ // Calculate x ** frac(y), where
+ // x ** frac(y) = exp(ln(x ** frac(y)) = exp(ln(x) * frac(y))
+ fracPartPow, err := d.Abs().Ln(-d.exp + int32(precision))
+ if err != nil {
+ return Decimal{}
+ }
+
+ fracPartPow = fracPartPow.Mul(expFracPart)
+
+ fracPartPow, err = fracPartPow.ExpTaylor(-d.exp + int32(precision))
+ if err != nil {
+ return Decimal{}
+ }
+
+ // Join integer and fractional part,
+ // base ** (expBase + expFrac) = base ** expBase * base ** expFrac
+ res := intPartPow.Mul(fracPartPow)
+
+ return res
+}
+
+// PowWithPrecision returns d to the power of d2.
+// Precision parameter specifies minimum precision of the result (digits after decimal point).
+// Returned decimal is not rounded to 'precision' places after decimal point.
+//
+// PowWithPrecision returns error when:
+// - 0 ** 0 => undefined value
+// - 0 ** y, where y < 0 => infinity
+// - x ** y, where x < 0 and y is non-integer decimal => imaginary value
+//
+// Example:
+//
+// d1 := decimal.NewFromFloat(4.0)
+// d2 := decimal.NewFromFloat(4.0)
+// res1, err := d1.PowWithPrecision(d2, 2)
+// res1.String() // output: "256"
+//
+// d3 := decimal.NewFromFloat(5.0)
+// d4 := decimal.NewFromFloat(5.73)
+// res2, err := d3.PowWithPrecision(d4, 5)
+// res2.String() // output: "10118.080371595015625"
+//
+// d5 := decimal.NewFromFloat(-3.0)
+// d6 := decimal.NewFromFloat(-6.0)
+// res3, err := d5.PowWithPrecision(d6, 10)
+// res3.String() // output: "0.0013717421"
+func (d Decimal) PowWithPrecision(d2 Decimal, precision int32) (Decimal, error) {
+ baseSign := d.Sign()
+ expSign := d2.Sign()
+
+ if baseSign == 0 {
+ if expSign == 0 {
+ return Decimal{}, fmt.Errorf("cannot represent undefined value of 0**0")
+ }
+ if expSign == 1 {
+ return Decimal{zeroInt, 0}, nil
+ }
+ if expSign == -1 {
+ return Decimal{}, fmt.Errorf("cannot represent infinity value of 0 ** y, where y < 0")
+ }
+ }
+
+ if expSign == 0 {
+ return Decimal{oneInt, 0}, nil
+ }
+
+ // TODO: optimize extraction of fractional part
+ one := Decimal{oneInt, 0}
+ expIntPart, expFracPart := d2.QuoRem(one, 0)
+
+ if baseSign == -1 && !expFracPart.IsZero() {
+ return Decimal{}, fmt.Errorf("cannot represent imaginary value of x ** y, where x < 0 and y is non-integer decimal")
+ }
+
+ intPartPow, _ := d.powBigIntWithPrecision(expIntPart.value, precision)
+
+ // if exponent is an integer we don't need to calculate d1**frac(d2)
+ if expFracPart.value.Sign() == 0 {
+ return intPartPow, nil
+ }
+
+ // TODO: optimize NumDigits for more performant precision adjustment
+ digitsBase := d.NumDigits()
+ digitsExponent := d2.NumDigits()
+
+ if int32(digitsBase) > precision {
+ precision = int32(digitsBase)
+ }
+ if int32(digitsExponent) > precision {
+ precision += int32(digitsExponent)
+ }
+ // increase precision by 10 to compensate for errors in further calculations
+ precision += 10
+
+ // Calculate x ** frac(y), where
+ // x ** frac(y) = exp(ln(x ** frac(y)) = exp(ln(x) * frac(y))
+ fracPartPow, err := d.Abs().Ln(precision)
+ if err != nil {
+ return Decimal{}, err
+ }
+
+ fracPartPow = fracPartPow.Mul(expFracPart)
+
+ fracPartPow, err = fracPartPow.ExpTaylor(precision)
+ if err != nil {
+ return Decimal{}, err
+ }
+
+ // Join integer and fractional part,
+ // base ** (expBase + expFrac) = base ** expBase * base ** expFrac
+ res := intPartPow.Mul(fracPartPow)
+
+ return res, nil
+}
+
+// PowInt32 returns d to the power of exp, where exp is int32.
+// Only returns error when d and exp is 0, thus result is undefined.
+//
+// When exponent is negative the returned decimal will have maximum precision of PowPrecisionNegativeExponent places after decimal point.
+//
+// Example:
+//
+// d1, err := decimal.NewFromFloat(4.0).PowInt32(4)
+// d1.String() // output: "256"
+//
+// d2, err := decimal.NewFromFloat(3.13).PowInt32(5)
+// d2.String() // output: "300.4150512793"
+func (d Decimal) PowInt32(exp int32) (Decimal, error) {
+ if d.IsZero() && exp == 0 {
+ return Decimal{}, fmt.Errorf("cannot represent undefined value of 0**0")
+ }
+
+ isExpNeg := exp < 0
+ exp = abs(exp)
+
+ n, result := d, New(1, 0)
+
+ for exp > 0 {
+ if exp%2 == 1 {
+ result = result.Mul(n)
+ }
+ exp /= 2
+
+ if exp > 0 {
+ n = n.Mul(n)
+ }
+ }
+
+ if isExpNeg {
+ return New(1, 0).DivRound(result, int32(PowPrecisionNegativeExponent)), nil
+ }
+
+ return result, nil
+}
+
+// PowBigInt returns d to the power of exp, where exp is big.Int.
+// Only returns error when d and exp is 0, thus result is undefined.
+//
+// When exponent is negative the returned decimal will have maximum precision of PowPrecisionNegativeExponent places after decimal point.
+//
+// Example:
+//
+// d1, err := decimal.NewFromFloat(3.0).PowBigInt(big.NewInt(3))
+// d1.String() // output: "27"
+//
+// d2, err := decimal.NewFromFloat(629.25).PowBigInt(big.NewInt(5))
+// d2.String() // output: "98654323103449.5673828125"
+func (d Decimal) PowBigInt(exp *big.Int) (Decimal, error) {
+ return d.powBigIntWithPrecision(exp, int32(PowPrecisionNegativeExponent))
+}
+
+func (d Decimal) powBigIntWithPrecision(exp *big.Int, precision int32) (Decimal, error) {
+ if d.IsZero() && exp.Sign() == 0 {
+ return Decimal{}, fmt.Errorf("cannot represent undefined value of 0**0")
+ }
+
+ tmpExp := new(big.Int).Set(exp)
+ isExpNeg := exp.Sign() < 0
+
+ if isExpNeg {
+ tmpExp.Abs(tmpExp)
+ }
+
+ n, result := d, New(1, 0)
+
+ for tmpExp.Sign() > 0 {
+ if tmpExp.Bit(0) == 1 {
+ result = result.Mul(n)
+ }
+ tmpExp.Rsh(tmpExp, 1)
+
+ if tmpExp.Sign() > 0 {
+ n = n.Mul(n)
+ }
+ }
+
+ if isExpNeg {
+ return New(1, 0).DivRound(result, precision), nil
+ }
+
+ return result, nil
+}
+
+// ExpHullAbrham calculates the natural exponent of decimal (e to the power of d) using Hull-Abraham algorithm.
+// OverallPrecision argument specifies the overall precision of the result (integer part + decimal part).
+//
+// ExpHullAbrham is faster than ExpTaylor for small precision values, but it is much slower for large precision values.
+//
+// Example:
+//
+// NewFromFloat(26.1).ExpHullAbrham(2).String() // output: "220000000000"
+// NewFromFloat(26.1).ExpHullAbrham(20).String() // output: "216314672147.05767284"
+func (d Decimal) ExpHullAbrham(overallPrecision uint32) (Decimal, error) {
+ // Algorithm based on Variable precision exponential function.
+ // ACM Transactions on Mathematical Software by T. E. Hull & A. Abrham.
+ if d.IsZero() {
+ return Decimal{oneInt, 0}, nil
+ }
+
+ currentPrecision := overallPrecision
+
+ // Algorithm does not work if currentPrecision * 23 < |x|.
+ // Precision is automatically increased in such cases, so the value can be calculated precisely.
+ // If newly calculated precision is higher than ExpMaxIterations the currentPrecision will not be changed.
+ f := d.Abs().InexactFloat64()
+ if ncp := f / 23; ncp > float64(currentPrecision) && ncp < float64(ExpMaxIterations) {
+ currentPrecision = uint32(math.Ceil(ncp))
+ }
+
+ // fail if abs(d) beyond an over/underflow threshold
+ overflowThreshold := New(23*int64(currentPrecision), 0)
+ if d.Abs().Cmp(overflowThreshold) > 0 {
+ return Decimal{}, fmt.Errorf("over/underflow threshold, exp(x) cannot be calculated precisely")
+ }
+
+ // Return 1 if abs(d) small enough; this also avoids later over/underflow
+ overflowThreshold2 := New(9, -int32(currentPrecision)-1)
+ if d.Abs().Cmp(overflowThreshold2) <= 0 {
+ return Decimal{oneInt, d.exp}, nil
+ }
+
+ // t is the smallest integer >= 0 such that the corresponding abs(d/k) < 1
+ t := d.exp + int32(d.NumDigits()) // Add d.NumDigits because the paper assumes that d.value [0.1, 1)
+
+ if t < 0 {
+ t = 0
+ }
+
+ k := New(1, t) // reduction factor
+ r := Decimal{new(big.Int).Set(d.value), d.exp - t} // reduced argument
+ p := int32(currentPrecision) + t + 2 // precision for calculating the sum
+
+ // Determine n, the number of therms for calculating sum
+ // use first Newton step (1.435p - 1.182) / log10(p/abs(r))
+ // for solving appropriate equation, along with directed
+ // roundings and simple rational bound for log10(p/abs(r))
+ rf := r.Abs().InexactFloat64()
+ pf := float64(p)
+ nf := math.Ceil((1.453*pf - 1.182) / math.Log10(pf/rf))
+ if nf > float64(ExpMaxIterations) || math.IsNaN(nf) {
+ return Decimal{}, fmt.Errorf("exact value cannot be calculated in <=ExpMaxIterations iterations")
+ }
+ n := int64(nf)
+
+ tmp := New(0, 0)
+ sum := New(1, 0)
+ one := New(1, 0)
+ for i := n - 1; i > 0; i-- {
+ tmp.value.SetInt64(i)
+ sum = sum.Mul(r.DivRound(tmp, p))
+ sum = sum.Add(one)
+ }
+
+ ki := k.IntPart()
+ res := New(1, 0)
+ for i := ki; i > 0; i-- {
+ res = res.Mul(sum)
+ }
+
+ resNumDigits := int32(res.NumDigits())
+
+ var roundDigits int32
+ if resNumDigits > abs(res.exp) {
+ roundDigits = int32(currentPrecision) - resNumDigits - res.exp
+ } else {
+ roundDigits = int32(currentPrecision)
+ }
+
+ res = res.Round(roundDigits)
+
+ return res, nil
+}
+
+// ExpTaylor calculates the natural exponent of decimal (e to the power of d) using Taylor series expansion.
+// Precision argument specifies how precise the result must be (number of digits after decimal point).
+// Negative precision is allowed.
+//
+// ExpTaylor is much faster for large precision values than ExpHullAbrham.
+//
+// Example:
+//
+// d, err := NewFromFloat(26.1).ExpTaylor(2).String()
+// d.String() // output: "216314672147.06"
+//
+// NewFromFloat(26.1).ExpTaylor(20).String()
+// d.String() // output: "216314672147.05767284062928674083"
+//
+// NewFromFloat(26.1).ExpTaylor(-10).String()
+// d.String() // output: "220000000000"
+func (d Decimal) ExpTaylor(precision int32) (Decimal, error) {
+ // Note(mwoss): Implementation can be optimized by exclusively using big.Int API only
+ if d.IsZero() {
+ return Decimal{oneInt, 0}.Round(precision), nil
+ }
+
+ var epsilon Decimal
+ var divPrecision int32
+ if precision < 0 {
+ epsilon = New(1, -1)
+ divPrecision = 8
+ } else {
+ epsilon = New(1, -precision-1)
+ divPrecision = precision + 1
+ }
+
+ decAbs := d.Abs()
+ pow := d.Abs()
+ factorial := New(1, 0)
+
+ result := New(1, 0)
+
+ for i := int64(1); ; {
+ step := pow.DivRound(factorial, divPrecision)
+ result = result.Add(step)
+
+ // Stop Taylor series when current step is smaller than epsilon
+ if step.Cmp(epsilon) < 0 {
+ break
+ }
+
+ pow = pow.Mul(decAbs)
+
+ i++
+
+ // Calculate next factorial number or retrieve cached value
+ if len(factorials) >= int(i) && !factorials[i-1].IsZero() {
+ factorial = factorials[i-1]
+ } else {
+ // To avoid any race conditions, firstly the zero value is appended to a slice to create
+ // a spot for newly calculated factorial. After that, the zero value is replaced by calculated
+ // factorial using the index notation.
+ factorial = factorials[i-2].Mul(New(i, 0))
+ factorials = append(factorials, Zero)
+ factorials[i-1] = factorial
+ }
+ }
+
+ if d.Sign() < 0 {
+ result = New(1, 0).DivRound(result, precision+1)
+ }
+
+ result = result.Round(precision)
+ return result, nil
+}
+
+// Ln calculates natural logarithm of d.
+// Precision argument specifies how precise the result must be (number of digits after decimal point).
+// Negative precision is allowed.
+//
+// Example:
+//
+// d1, err := NewFromFloat(13.3).Ln(2)
+// d1.String() // output: "2.59"
+//
+// d2, err := NewFromFloat(579.161).Ln(10)
+// d2.String() // output: "6.3615805046"
+func (d Decimal) Ln(precision int32) (Decimal, error) {
+ // Algorithm based on The Use of Iteration Methods for Approximating the Natural Logarithm,
+ // James F. Epperson, The American Mathematical Monthly, Vol. 96, No. 9, November 1989, pp. 831-835.
+ if d.IsNegative() {
+ return Decimal{}, fmt.Errorf("cannot calculate natural logarithm for negative decimals")
+ }
+
+ if d.IsZero() {
+ return Decimal{}, fmt.Errorf("cannot represent natural logarithm of 0, result: -infinity")
+ }
+
+ calcPrecision := precision + 2
+ z := d.Copy()
+
+ var comp1, comp3, comp2, comp4, reduceAdjust Decimal
+ comp1 = z.Sub(Decimal{oneInt, 0})
+ comp3 = Decimal{oneInt, -1}
+
+ // for decimal in range [0.9, 1.1] where ln(d) is close to 0
+ usePowerSeries := false
+
+ if comp1.Abs().Cmp(comp3) <= 0 {
+ usePowerSeries = true
+ } else {
+ // reduce input decimal to range [0.1, 1)
+ expDelta := int32(z.NumDigits()) + z.exp
+ z.exp -= expDelta
+
+ // Input decimal was reduced by factor of 10^expDelta, thus we will need to add
+ // ln(10^expDelta) = expDelta * ln(10)
+ // to the result to compensate that
+ ln10 := ln10.withPrecision(calcPrecision)
+ reduceAdjust = NewFromInt32(expDelta)
+ reduceAdjust = reduceAdjust.Mul(ln10)
+
+ comp1 = z.Sub(Decimal{oneInt, 0})
+
+ if comp1.Abs().Cmp(comp3) <= 0 {
+ usePowerSeries = true
+ } else {
+ // initial estimate using floats
+ zFloat := z.InexactFloat64()
+ comp1 = NewFromFloat(math.Log(zFloat))
+ }
+ }
+
+ epsilon := Decimal{oneInt, -calcPrecision}
+
+ if usePowerSeries {
+ // Power Series - https://en.wikipedia.org/wiki/Logarithm#Power_series
+ // Calculating n-th term of formula: ln(z+1) = 2 sum [ 1 / (2n+1) * (z / (z+2))^(2n+1) ]
+ // until the difference between current and next term is smaller than epsilon.
+ // Coverage quite fast for decimals close to 1.0
+
+ // z + 2
+ comp2 = comp1.Add(Decimal{twoInt, 0})
+ // z / (z + 2)
+ comp3 = comp1.DivRound(comp2, calcPrecision)
+ // 2 * (z / (z + 2))
+ comp1 = comp3.Add(comp3)
+ comp2 = comp1.Copy()
+
+ for n := 1; ; n++ {
+ // 2 * (z / (z+2))^(2n+1)
+ comp2 = comp2.Mul(comp3).Mul(comp3)
+
+ // 1 / (2n+1) * 2 * (z / (z+2))^(2n+1)
+ comp4 = NewFromInt(int64(2*n + 1))
+ comp4 = comp2.DivRound(comp4, calcPrecision)
+
+ // comp1 = 2 sum [ 1 / (2n+1) * (z / (z+2))^(2n+1) ]
+ comp1 = comp1.Add(comp4)
+
+ if comp4.Abs().Cmp(epsilon) <= 0 {
+ break
+ }
+ }
+ } else {
+ // Halley's Iteration.
+ // Calculating n-th term of formula: a_(n+1) = a_n - 2 * (exp(a_n) - z) / (exp(a_n) + z),
+ // until the difference between current and next term is smaller than epsilon
+ var prevStep Decimal
+ maxIters := calcPrecision*2 + 10
+
+ for i := int32(0); i < maxIters; i++ {
+ // exp(a_n)
+ comp3, _ = comp1.ExpTaylor(calcPrecision)
+ // exp(a_n) - z
+ comp2 = comp3.Sub(z)
+ // 2 * (exp(a_n) - z)
+ comp2 = comp2.Add(comp2)
+ // exp(a_n) + z
+ comp4 = comp3.Add(z)
+ // 2 * (exp(a_n) - z) / (exp(a_n) + z)
+ comp3 = comp2.DivRound(comp4, calcPrecision)
+ // comp1 = a_(n+1) = a_n - 2 * (exp(a_n) - z) / (exp(a_n) + z)
+ comp1 = comp1.Sub(comp3)
+
+ if prevStep.Add(comp3).IsZero() {
+ // If iteration steps oscillate we should return early and prevent an infinity loop
+ // NOTE(mwoss): This should be quite a rare case, returning error is not necessary
+ break
+ }
+
+ if comp3.Abs().Cmp(epsilon) <= 0 {
+ break
+ }
+
+ prevStep = comp3
+ }
+ }
+
+ comp1 = comp1.Add(reduceAdjust)
+
+ return comp1.Round(precision), nil
+}
+
+// NumDigits returns the number of digits of the decimal coefficient (d.Value)
+func (d Decimal) NumDigits() int {
+ if d.value == nil {
+ return 1
+ }
+
+ if d.value.IsInt64() {
+ i64 := d.value.Int64()
+ // restrict fast path to integers with exact conversion to float64
+ if i64 <= (1<<53) && i64 >= -(1<<53) {
+ if i64 == 0 {
+ return 1
+ }
+ return int(math.Log10(math.Abs(float64(i64)))) + 1
+ }
+ }
+
+ estimatedNumDigits := int(float64(d.value.BitLen()) / math.Log2(10))
+
+ // estimatedNumDigits (lg10) may be off by 1, need to verify
+ digitsBigInt := big.NewInt(int64(estimatedNumDigits))
+ errorCorrectionUnit := digitsBigInt.Exp(tenInt, digitsBigInt, nil)
+
+ if d.value.CmpAbs(errorCorrectionUnit) >= 0 {
+ return estimatedNumDigits + 1
+ }
+
+ return estimatedNumDigits
+}
+
+// IsInteger returns true when decimal can be represented as an integer value, otherwise, it returns false.
+func (d Decimal) IsInteger() bool {
+ // The most typical case, all decimal with exponent higher or equal 0 can be represented as integer
+ if d.exp >= 0 {
+ return true
+ }
+ // When the exponent is negative we have to check every number after the decimal place
+ // If all of them are zeroes, we are sure that given decimal can be represented as an integer
+ var r big.Int
+ q := new(big.Int).Set(d.value)
+ for z := abs(d.exp); z > 0; z-- {
+ q.QuoRem(q, tenInt, &r)
+ if r.Cmp(zeroInt) != 0 {
+ return false
+ }
+ }
+ return true
+}
+
+// Abs calculates absolute value of any int32. Used for calculating absolute value of decimal's exponent.
+func abs(n int32) int32 {
+ if n < 0 {
+ return -n
+ }
+ return n
+}
+
+// Cmp compares the numbers represented by d and d2 and returns:
+//
+// -1 if d < d2
+// 0 if d == d2
+// +1 if d > d2
+func (d Decimal) Cmp(d2 Decimal) int {
+ d.ensureInitialized()
+ d2.ensureInitialized()
+
+ if d.exp == d2.exp {
+ return d.value.Cmp(d2.value)
+ }
+
+ rd, rd2 := RescalePair(d, d2)
+
+ return rd.value.Cmp(rd2.value)
+}
+
+// Compare compares the numbers represented by d and d2 and returns:
+//
+// -1 if d < d2
+// 0 if d == d2
+// +1 if d > d2
+func (d Decimal) Compare(d2 Decimal) int {
+ return d.Cmp(d2)
+}
+
+// Equal returns whether the numbers represented by d and d2 are equal.
+func (d Decimal) Equal(d2 Decimal) bool {
+ return d.Cmp(d2) == 0
+}
+
+// Deprecated: Equals is deprecated, please use Equal method instead.
+func (d Decimal) Equals(d2 Decimal) bool {
+ return d.Equal(d2)
+}
+
+// GreaterThan (GT) returns true when d is greater than d2.
+func (d Decimal) GreaterThan(d2 Decimal) bool {
+ return d.Cmp(d2) == 1
+}
+
+// GreaterThanOrEqual (GTE) returns true when d is greater than or equal to d2.
+func (d Decimal) GreaterThanOrEqual(d2 Decimal) bool {
+ cmp := d.Cmp(d2)
+ return cmp == 1 || cmp == 0
+}
+
+// LessThan (LT) returns true when d is less than d2.
+func (d Decimal) LessThan(d2 Decimal) bool {
+ return d.Cmp(d2) == -1
+}
+
+// LessThanOrEqual (LTE) returns true when d is less than or equal to d2.
+func (d Decimal) LessThanOrEqual(d2 Decimal) bool {
+ cmp := d.Cmp(d2)
+ return cmp == -1 || cmp == 0
+}
+
+// Sign returns:
+//
+// -1 if d < 0
+// 0 if d == 0
+// +1 if d > 0
+func (d Decimal) Sign() int {
+ if d.value == nil {
+ return 0
+ }
+ return d.value.Sign()
+}
+
+// IsPositive return
+//
+// true if d > 0
+// false if d == 0
+// false if d < 0
+func (d Decimal) IsPositive() bool {
+ return d.Sign() == 1
+}
+
+// IsNegative return
+//
+// true if d < 0
+// false if d == 0
+// false if d > 0
+func (d Decimal) IsNegative() bool {
+ return d.Sign() == -1
+}
+
+// IsZero return
+//
+// true if d == 0
+// false if d > 0
+// false if d < 0
+func (d Decimal) IsZero() bool {
+ return d.Sign() == 0
+}
+
+// Exponent returns the exponent, or scale component of the decimal.
+func (d Decimal) Exponent() int32 {
+ return d.exp
+}
+
+// Coefficient returns the coefficient of the decimal. It is scaled by 10^Exponent()
+func (d Decimal) Coefficient() *big.Int {
+ d.ensureInitialized()
+ // we copy the coefficient so that mutating the result does not mutate the Decimal.
+ return new(big.Int).Set(d.value)
+}
+
+// CoefficientInt64 returns the coefficient of the decimal as int64. It is scaled by 10^Exponent()
+// If coefficient cannot be represented in an int64, the result will be undefined.
+func (d Decimal) CoefficientInt64() int64 {
+ d.ensureInitialized()
+ return d.value.Int64()
+}
+
+// IntPart returns the integer component of the decimal.
+func (d Decimal) IntPart() int64 {
+ scaledD := d.rescale(0)
+ return scaledD.value.Int64()
+}
+
+// BigInt returns integer component of the decimal as a BigInt.
+func (d Decimal) BigInt() *big.Int {
+ scaledD := d.rescale(0)
+ return scaledD.value
+}
+
+// BigFloat returns decimal as BigFloat.
+// Be aware that casting decimal to BigFloat might cause a loss of precision.
+func (d Decimal) BigFloat() *big.Float {
+ f := &big.Float{}
+ f.SetString(d.String())
+ return f
+}
+
+// Rat returns a rational number representation of the decimal.
+func (d Decimal) Rat() *big.Rat {
+ d.ensureInitialized()
+ if d.exp <= 0 {
+ // NOTE(vadim): must negate after casting to prevent int32 overflow
+ denom := new(big.Int).Exp(tenInt, big.NewInt(-int64(d.exp)), nil)
+ return new(big.Rat).SetFrac(d.value, denom)
+ }
+
+ mul := new(big.Int).Exp(tenInt, big.NewInt(int64(d.exp)), nil)
+ num := new(big.Int).Mul(d.value, mul)
+ return new(big.Rat).SetFrac(num, oneInt)
+}
+
+// Float64 returns the nearest float64 value for d and a bool indicating
+// whether f represents d exactly.
+// For more details, see the documentation for big.Rat.Float64
+func (d Decimal) Float64() (f float64, exact bool) {
+ return d.Rat().Float64()
+}
+
+// InexactFloat64 returns the nearest float64 value for d.
+// It doesn't indicate if the returned value represents d exactly.
+func (d Decimal) InexactFloat64() float64 {
+ f, _ := d.Float64()
+ return f
+}
+
+// String returns the string representation of the decimal
+// with the fixed point.
+//
+// Example:
+//
+// d := New(-12345, -3)
+// println(d.String())
+//
+// Output:
+//
+// -12.345
+func (d Decimal) String() string {
+ return d.string(true)
+}
+
+// StringFixed returns a rounded fixed-point string with places digits after
+// the decimal point.
+//
+// Example:
+//
+// NewFromFloat(0).StringFixed(2) // output: "0.00"
+// NewFromFloat(0).StringFixed(0) // output: "0"
+// NewFromFloat(5.45).StringFixed(0) // output: "5"
+// NewFromFloat(5.45).StringFixed(1) // output: "5.5"
+// NewFromFloat(5.45).StringFixed(2) // output: "5.45"
+// NewFromFloat(5.45).StringFixed(3) // output: "5.450"
+// NewFromFloat(545).StringFixed(-1) // output: "550"
+func (d Decimal) StringFixed(places int32) string {
+ rounded := d.Round(places)
+ return rounded.string(false)
+}
+
+// StringFixedBank returns a banker rounded fixed-point string with places digits
+// after the decimal point.
+//
+// Example:
+//
+// NewFromFloat(0).StringFixedBank(2) // output: "0.00"
+// NewFromFloat(0).StringFixedBank(0) // output: "0"
+// NewFromFloat(5.45).StringFixedBank(0) // output: "5"
+// NewFromFloat(5.45).StringFixedBank(1) // output: "5.4"
+// NewFromFloat(5.45).StringFixedBank(2) // output: "5.45"
+// NewFromFloat(5.45).StringFixedBank(3) // output: "5.450"
+// NewFromFloat(545).StringFixedBank(-1) // output: "540"
+func (d Decimal) StringFixedBank(places int32) string {
+ rounded := d.RoundBank(places)
+ return rounded.string(false)
+}
+
+// StringFixedCash returns a Swedish/Cash rounded fixed-point string. For
+// more details see the documentation at function RoundCash.
+func (d Decimal) StringFixedCash(interval uint8) string {
+ rounded := d.RoundCash(interval)
+ return rounded.string(false)
+}
+
+// Round rounds the decimal to places decimal places.
+// If places < 0, it will round the integer part to the nearest 10^(-places).
+//
+// Example:
+//
+// NewFromFloat(5.45).Round(1).String() // output: "5.5"
+// NewFromFloat(545).Round(-1).String() // output: "550"
+func (d Decimal) Round(places int32) Decimal {
+ if d.exp == -places {
+ return d
+ }
+ // truncate to places + 1
+ ret := d.rescale(-places - 1)
+
+ // add sign(d) * 0.5
+ if ret.value.Sign() < 0 {
+ ret.value.Sub(ret.value, fiveInt)
+ } else {
+ ret.value.Add(ret.value, fiveInt)
+ }
+
+ // floor for positive numbers, ceil for negative numbers
+ _, m := ret.value.DivMod(ret.value, tenInt, new(big.Int))
+ ret.exp++
+ if ret.value.Sign() < 0 && m.Cmp(zeroInt) != 0 {
+ ret.value.Add(ret.value, oneInt)
+ }
+
+ return ret
+}
+
+// RoundCeil rounds the decimal towards +infinity.
+//
+// Example:
+//
+// NewFromFloat(545).RoundCeil(-2).String() // output: "600"
+// NewFromFloat(500).RoundCeil(-2).String() // output: "500"
+// NewFromFloat(1.1001).RoundCeil(2).String() // output: "1.11"
+// NewFromFloat(-1.454).RoundCeil(1).String() // output: "-1.4"
+func (d Decimal) RoundCeil(places int32) Decimal {
+ if d.exp >= -places {
+ return d
+ }
+
+ rescaled := d.rescale(-places)
+ if d.Equal(rescaled) {
+ return d
+ }
+
+ if d.value.Sign() > 0 {
+ rescaled.value.Add(rescaled.value, oneInt)
+ }
+
+ return rescaled
+}
+
+// RoundFloor rounds the decimal towards -infinity.
+//
+// Example:
+//
+// NewFromFloat(545).RoundFloor(-2).String() // output: "500"
+// NewFromFloat(-500).RoundFloor(-2).String() // output: "-500"
+// NewFromFloat(1.1001).RoundFloor(2).String() // output: "1.1"
+// NewFromFloat(-1.454).RoundFloor(1).String() // output: "-1.5"
+func (d Decimal) RoundFloor(places int32) Decimal {
+ if d.exp >= -places {
+ return d
+ }
+
+ rescaled := d.rescale(-places)
+ if d.Equal(rescaled) {
+ return d
+ }
+
+ if d.value.Sign() < 0 {
+ rescaled.value.Sub(rescaled.value, oneInt)
+ }
+
+ return rescaled
+}
+
+// RoundUp rounds the decimal away from zero.
+//
+// Example:
+//
+// NewFromFloat(545).RoundUp(-2).String() // output: "600"
+// NewFromFloat(500).RoundUp(-2).String() // output: "500"
+// NewFromFloat(1.1001).RoundUp(2).String() // output: "1.11"
+// NewFromFloat(-1.454).RoundUp(1).String() // output: "-1.5"
+func (d Decimal) RoundUp(places int32) Decimal {
+ if d.exp >= -places {
+ return d
+ }
+
+ rescaled := d.rescale(-places)
+ if d.Equal(rescaled) {
+ return d
+ }
+
+ if d.value.Sign() > 0 {
+ rescaled.value.Add(rescaled.value, oneInt)
+ } else if d.value.Sign() < 0 {
+ rescaled.value.Sub(rescaled.value, oneInt)
+ }
+
+ return rescaled
+}
+
+// RoundDown rounds the decimal towards zero.
+//
+// Example:
+//
+// NewFromFloat(545).RoundDown(-2).String() // output: "500"
+// NewFromFloat(-500).RoundDown(-2).String() // output: "-500"
+// NewFromFloat(1.1001).RoundDown(2).String() // output: "1.1"
+// NewFromFloat(-1.454).RoundDown(1).String() // output: "-1.4"
+func (d Decimal) RoundDown(places int32) Decimal {
+ if d.exp >= -places {
+ return d
+ }
+
+ rescaled := d.rescale(-places)
+ if d.Equal(rescaled) {
+ return d
+ }
+ return rescaled
+}
+
+// RoundBank rounds the decimal to places decimal places.
+// If the final digit to round is equidistant from the nearest two integers the
+// rounded value is taken as the even number
+//
+// If places < 0, it will round the integer part to the nearest 10^(-places).
+//
+// Examples:
+//
+// NewFromFloat(5.45).RoundBank(1).String() // output: "5.4"
+// NewFromFloat(545).RoundBank(-1).String() // output: "540"
+// NewFromFloat(5.46).RoundBank(1).String() // output: "5.5"
+// NewFromFloat(546).RoundBank(-1).String() // output: "550"
+// NewFromFloat(5.55).RoundBank(1).String() // output: "5.6"
+// NewFromFloat(555).RoundBank(-1).String() // output: "560"
+func (d Decimal) RoundBank(places int32) Decimal {
+
+ round := d.Round(places)
+ remainder := d.Sub(round).Abs()
+
+ half := New(5, -places-1)
+ if remainder.Cmp(half) == 0 && round.value.Bit(0) != 0 {
+ if round.value.Sign() < 0 {
+ round.value.Add(round.value, oneInt)
+ } else {
+ round.value.Sub(round.value, oneInt)
+ }
+ }
+
+ return round
+}
+
+// RoundCash aka Cash/Penny/öre rounding rounds decimal to a specific
+// interval. The amount payable for a cash transaction is rounded to the nearest
+// multiple of the minimum currency unit available. The following intervals are
+// available: 5, 10, 25, 50 and 100; any other number throws a panic.
+//
+// 5: 5 cent rounding 3.43 => 3.45
+// 10: 10 cent rounding 3.45 => 3.50 (5 gets rounded up)
+// 25: 25 cent rounding 3.41 => 3.50
+// 50: 50 cent rounding 3.75 => 4.00
+// 100: 100 cent rounding 3.50 => 4.00
+//
+// For more details: https://en.wikipedia.org/wiki/Cash_rounding
+func (d Decimal) RoundCash(interval uint8) Decimal {
+ var iVal *big.Int
+ switch interval {
+ case 5:
+ iVal = twentyInt
+ case 10:
+ iVal = tenInt
+ case 25:
+ iVal = fourInt
+ case 50:
+ iVal = twoInt
+ case 100:
+ iVal = oneInt
+ default:
+ panic(fmt.Sprintf("Decimal does not support this Cash rounding interval `%d`. Supported: 5, 10, 25, 50, 100", interval))
+ }
+ dVal := Decimal{
+ value: iVal,
+ }
+
+ // TODO: optimize those calculations to reduce the high allocations (~29 allocs).
+ return d.Mul(dVal).Round(0).Div(dVal).Truncate(2)
+}
+
+// Floor returns the nearest integer value less than or equal to d.
+func (d Decimal) Floor() Decimal {
+ d.ensureInitialized()
+
+ if d.exp >= 0 {
+ return d
+ }
+
+ exp := big.NewInt(10)
+
+ // NOTE(vadim): must negate after casting to prevent int32 overflow
+ exp.Exp(exp, big.NewInt(-int64(d.exp)), nil)
+
+ z := new(big.Int).Div(d.value, exp)
+ return Decimal{value: z, exp: 0}
+}
+
+// Ceil returns the nearest integer value greater than or equal to d.
+func (d Decimal) Ceil() Decimal {
+ d.ensureInitialized()
+
+ if d.exp >= 0 {
+ return d
+ }
+
+ exp := big.NewInt(10)
+
+ // NOTE(vadim): must negate after casting to prevent int32 overflow
+ exp.Exp(exp, big.NewInt(-int64(d.exp)), nil)
+
+ z, m := new(big.Int).DivMod(d.value, exp, new(big.Int))
+ if m.Cmp(zeroInt) != 0 {
+ z.Add(z, oneInt)
+ }
+ return Decimal{value: z, exp: 0}
+}
+
+// Truncate truncates off digits from the number, without rounding.
+//
+// NOTE: precision is the last digit that will not be truncated (must be >= 0).
+//
+// Example:
+//
+// decimal.NewFromString("123.456").Truncate(2).String() // "123.45"
+func (d Decimal) Truncate(precision int32) Decimal {
+ d.ensureInitialized()
+ if precision >= 0 && -precision > d.exp {
+ return d.rescale(-precision)
+ }
+ return d
+}
+
+// UnmarshalJSON implements the json.Unmarshaler interface.
+func (d *Decimal) UnmarshalJSON(decimalBytes []byte) error {
+ if string(decimalBytes) == "null" {
+ return nil
+ }
+
+ str, err := unquoteIfQuoted(decimalBytes)
+ if err != nil {
+ return fmt.Errorf("error decoding string '%s': %s", decimalBytes, err)
+ }
+
+ decimal, err := NewFromString(str)
+ *d = decimal
+ if err != nil {
+ return fmt.Errorf("error decoding string '%s': %s", str, err)
+ }
+ return nil
+}
+
+// MarshalJSON implements the json.Marshaler interface.
+func (d Decimal) MarshalJSON() ([]byte, error) {
+ var str string
+ if MarshalJSONWithoutQuotes {
+ str = d.String()
+ } else {
+ str = "\"" + d.String() + "\""
+ }
+ return []byte(str), nil
+}
+
+// UnmarshalBinary implements the encoding.BinaryUnmarshaler interface. As a string representation
+// is already used when encoding to text, this method stores that string as []byte
+func (d *Decimal) UnmarshalBinary(data []byte) error {
+ // Verify we have at least 4 bytes for the exponent. The GOB encoded value
+ // may be empty.
+ if len(data) < 4 {
+ return fmt.Errorf("error decoding binary %v: expected at least 4 bytes, got %d", data, len(data))
+ }
+
+ // Extract the exponent
+ d.exp = int32(binary.BigEndian.Uint32(data[:4]))
+
+ // Extract the value
+ d.value = new(big.Int)
+ if err := d.value.GobDecode(data[4:]); err != nil {
+ return fmt.Errorf("error decoding binary %v: %s", data, err)
+ }
+
+ return nil
+}
+
+// MarshalBinary implements the encoding.BinaryMarshaler interface.
+func (d Decimal) MarshalBinary() (data []byte, err error) {
+ // exp is written first, but encode value first to know output size
+ var valueData []byte
+ if valueData, err = d.value.GobEncode(); err != nil {
+ return nil, err
+ }
+
+ // Write the exponent in front, since it's a fixed size
+ expData := make([]byte, 4, len(valueData)+4)
+ binary.BigEndian.PutUint32(expData, uint32(d.exp))
+
+ // Return the byte array
+ return append(expData, valueData...), nil
+}
+
+// Scan implements the sql.Scanner interface for database deserialization.
+func (d *Decimal) Scan(value interface{}) error {
+ // first try to see if the data is stored in database as a Numeric datatype
+ switch v := value.(type) {
+
+ case float32:
+ *d = NewFromFloat(float64(v))
+ return nil
+
+ case float64:
+ // numeric in sqlite3 sends us float64
+ *d = NewFromFloat(v)
+ return nil
+
+ case int64:
+ // at least in sqlite3 when the value is 0 in db, the data is sent
+ // to us as an int64 instead of a float64 ...
+ *d = New(v, 0)
+ return nil
+
+ case uint64:
+ // while clickhouse may send 0 in db as uint64
+ *d = NewFromUint64(v)
+ return nil
+
+ default:
+ // default is trying to interpret value stored as string
+ str, err := unquoteIfQuoted(v)
+ if err != nil {
+ return err
+ }
+ *d, err = NewFromString(str)
+ return err
+ }
+}
+
+// Value implements the driver.Valuer interface for database serialization.
+func (d Decimal) Value() (driver.Value, error) {
+ return d.String(), nil
+}
+
+// UnmarshalText implements the encoding.TextUnmarshaler interface for XML
+// deserialization.
+func (d *Decimal) UnmarshalText(text []byte) error {
+ str := string(text)
+
+ dec, err := NewFromString(str)
+ *d = dec
+ if err != nil {
+ return fmt.Errorf("error decoding string '%s': %s", str, err)
+ }
+
+ return nil
+}
+
+// MarshalText implements the encoding.TextMarshaler interface for XML
+// serialization.
+func (d Decimal) MarshalText() (text []byte, err error) {
+ return []byte(d.String()), nil
+}
+
+// GobEncode implements the gob.GobEncoder interface for gob serialization.
+func (d Decimal) GobEncode() ([]byte, error) {
+ return d.MarshalBinary()
+}
+
+// GobDecode implements the gob.GobDecoder interface for gob serialization.
+func (d *Decimal) GobDecode(data []byte) error {
+ return d.UnmarshalBinary(data)
+}
+
+// StringScaled first scales the decimal then calls .String() on it.
+//
+// Deprecated: buggy and unintuitive. Use StringFixed instead.
+func (d Decimal) StringScaled(exp int32) string {
+ return d.rescale(exp).String()
+}
+
+func (d Decimal) string(trimTrailingZeros bool) string {
+ if d.exp >= 0 {
+ return d.rescale(0).value.String()
+ }
+
+ abs := new(big.Int).Abs(d.value)
+ str := abs.String()
+
+ var intPart, fractionalPart string
+
+ // NOTE(vadim): this cast to int will cause bugs if d.exp == INT_MIN
+ // and you are on a 32-bit machine. Won't fix this super-edge case.
+ dExpInt := int(d.exp)
+ if len(str) > -dExpInt {
+ intPart = str[:len(str)+dExpInt]
+ fractionalPart = str[len(str)+dExpInt:]
+ } else {
+ intPart = "0"
+
+ num0s := -dExpInt - len(str)
+ fractionalPart = strings.Repeat("0", num0s) + str
+ }
+
+ if trimTrailingZeros {
+ i := len(fractionalPart) - 1
+ for ; i >= 0; i-- {
+ if fractionalPart[i] != '0' {
+ break
+ }
+ }
+ fractionalPart = fractionalPart[:i+1]
+ }
+
+ number := intPart
+ if len(fractionalPart) > 0 {
+ number += "." + fractionalPart
+ }
+
+ if d.value.Sign() < 0 {
+ return "-" + number
+ }
+
+ return number
+}
+
+func (d *Decimal) ensureInitialized() {
+ if d.value == nil {
+ d.value = new(big.Int)
+ }
+}
+
+// Min returns the smallest Decimal that was passed in the arguments.
+//
+// To call this function with an array, you must do:
+//
+// Min(arr[0], arr[1:]...)
+//
+// This makes it harder to accidentally call Min with 0 arguments.
+func Min(first Decimal, rest ...Decimal) Decimal {
+ ans := first
+ for _, item := range rest {
+ if item.Cmp(ans) < 0 {
+ ans = item
+ }
+ }
+ return ans
+}
+
+// Max returns the largest Decimal that was passed in the arguments.
+//
+// To call this function with an array, you must do:
+//
+// Max(arr[0], arr[1:]...)
+//
+// This makes it harder to accidentally call Max with 0 arguments.
+func Max(first Decimal, rest ...Decimal) Decimal {
+ ans := first
+ for _, item := range rest {
+ if item.Cmp(ans) > 0 {
+ ans = item
+ }
+ }
+ return ans
+}
+
+// Sum returns the combined total of the provided first and rest Decimals
+func Sum(first Decimal, rest ...Decimal) Decimal {
+ total := first
+ for _, item := range rest {
+ total = total.Add(item)
+ }
+
+ return total
+}
+
+// Avg returns the average value of the provided first and rest Decimals
+func Avg(first Decimal, rest ...Decimal) Decimal {
+ count := New(int64(len(rest)+1), 0)
+ sum := Sum(first, rest...)
+ return sum.Div(count)
+}
+
+// RescalePair rescales two decimals to common exponential value (minimal exp of both decimals)
+func RescalePair(d1 Decimal, d2 Decimal) (Decimal, Decimal) {
+ d1.ensureInitialized()
+ d2.ensureInitialized()
+
+ if d1.exp < d2.exp {
+ return d1, d2.rescale(d1.exp)
+ } else if d1.exp > d2.exp {
+ return d1.rescale(d2.exp), d2
+ }
+
+ return d1, d2
+}
+
+func unquoteIfQuoted(value interface{}) (string, error) {
+ var bytes []byte
+
+ switch v := value.(type) {
+ case string:
+ bytes = []byte(v)
+ case []byte:
+ bytes = v
+ default:
+ return "", fmt.Errorf("could not convert value '%+v' to byte array of type '%T'", value, value)
+ }
+
+ // If the amount is quoted, strip the quotes
+ if len(bytes) > 2 && bytes[0] == '"' && bytes[len(bytes)-1] == '"' {
+ bytes = bytes[1 : len(bytes)-1]
+ }
+ return string(bytes), nil
+}
+
+// NullDecimal represents a nullable decimal with compatibility for
+// scanning null values from the database.
+type NullDecimal struct {
+ Decimal Decimal
+ Valid bool
+}
+
+func NewNullDecimal(d Decimal) NullDecimal {
+ return NullDecimal{
+ Decimal: d,
+ Valid: true,
+ }
+}
+
+// Scan implements the sql.Scanner interface for database deserialization.
+func (d *NullDecimal) Scan(value interface{}) error {
+ if value == nil {
+ d.Valid = false
+ return nil
+ }
+ d.Valid = true
+ return d.Decimal.Scan(value)
+}
+
+// Value implements the driver.Valuer interface for database serialization.
+func (d NullDecimal) Value() (driver.Value, error) {
+ if !d.Valid {
+ return nil, nil
+ }
+ return d.Decimal.Value()
+}
+
+// UnmarshalJSON implements the json.Unmarshaler interface.
+func (d *NullDecimal) UnmarshalJSON(decimalBytes []byte) error {
+ if string(decimalBytes) == "null" {
+ d.Valid = false
+ return nil
+ }
+ d.Valid = true
+ return d.Decimal.UnmarshalJSON(decimalBytes)
+}
+
+// MarshalJSON implements the json.Marshaler interface.
+func (d NullDecimal) MarshalJSON() ([]byte, error) {
+ if !d.Valid {
+ return []byte("null"), nil
+ }
+ return d.Decimal.MarshalJSON()
+}
+
+// UnmarshalText implements the encoding.TextUnmarshaler interface for XML
+// deserialization
+func (d *NullDecimal) UnmarshalText(text []byte) error {
+ str := string(text)
+
+ // check for empty XML or XML without body e.g.,
+ if str == "" {
+ d.Valid = false
+ return nil
+ }
+ if err := d.Decimal.UnmarshalText(text); err != nil {
+ d.Valid = false
+ return err
+ }
+ d.Valid = true
+ return nil
+}
+
+// MarshalText implements the encoding.TextMarshaler interface for XML
+// serialization.
+func (d NullDecimal) MarshalText() (text []byte, err error) {
+ if !d.Valid {
+ return []byte{}, nil
+ }
+ return d.Decimal.MarshalText()
+}
+
+// Trig functions
+
+// Atan returns the arctangent, in radians, of x.
+func (d Decimal) Atan() Decimal {
+ if d.Equal(NewFromFloat(0.0)) {
+ return d
+ }
+ if d.GreaterThan(NewFromFloat(0.0)) {
+ return d.satan()
+ }
+ return d.Neg().satan().Neg()
+}
+
+func (d Decimal) xatan() Decimal {
+ P0 := NewFromFloat(-8.750608600031904122785e-01)
+ P1 := NewFromFloat(-1.615753718733365076637e+01)
+ P2 := NewFromFloat(-7.500855792314704667340e+01)
+ P3 := NewFromFloat(-1.228866684490136173410e+02)
+ P4 := NewFromFloat(-6.485021904942025371773e+01)
+ Q0 := NewFromFloat(2.485846490142306297962e+01)
+ Q1 := NewFromFloat(1.650270098316988542046e+02)
+ Q2 := NewFromFloat(4.328810604912902668951e+02)
+ Q3 := NewFromFloat(4.853903996359136964868e+02)
+ Q4 := NewFromFloat(1.945506571482613964425e+02)
+ z := d.Mul(d)
+ b1 := P0.Mul(z).Add(P1).Mul(z).Add(P2).Mul(z).Add(P3).Mul(z).Add(P4).Mul(z)
+ b2 := z.Add(Q0).Mul(z).Add(Q1).Mul(z).Add(Q2).Mul(z).Add(Q3).Mul(z).Add(Q4)
+ z = b1.Div(b2)
+ z = d.Mul(z).Add(d)
+ return z
+}
+
+// satan reduces its argument (known to be positive)
+// to the range [0, 0.66] and calls xatan.
+func (d Decimal) satan() Decimal {
+ Morebits := NewFromFloat(6.123233995736765886130e-17) // pi/2 = PIO2 + Morebits
+ Tan3pio8 := NewFromFloat(2.41421356237309504880) // tan(3*pi/8)
+ pi := NewFromFloat(3.14159265358979323846264338327950288419716939937510582097494459)
+
+ if d.LessThanOrEqual(NewFromFloat(0.66)) {
+ return d.xatan()
+ }
+ if d.GreaterThan(Tan3pio8) {
+ return pi.Div(NewFromFloat(2.0)).Sub(NewFromFloat(1.0).Div(d).xatan()).Add(Morebits)
+ }
+ return pi.Div(NewFromFloat(4.0)).Add((d.Sub(NewFromFloat(1.0)).Div(d.Add(NewFromFloat(1.0)))).xatan()).Add(NewFromFloat(0.5).Mul(Morebits))
+}
+
+// sin coefficients
+var _sin = [...]Decimal{
+ NewFromFloat(1.58962301576546568060e-10), // 0x3de5d8fd1fd19ccd
+ NewFromFloat(-2.50507477628578072866e-8), // 0xbe5ae5e5a9291f5d
+ NewFromFloat(2.75573136213857245213e-6), // 0x3ec71de3567d48a1
+ NewFromFloat(-1.98412698295895385996e-4), // 0xbf2a01a019bfdf03
+ NewFromFloat(8.33333333332211858878e-3), // 0x3f8111111110f7d0
+ NewFromFloat(-1.66666666666666307295e-1), // 0xbfc5555555555548
+}
+
+// Sin returns the sine of the radian argument x.
+func (d Decimal) Sin() Decimal {
+ PI4A := NewFromFloat(7.85398125648498535156e-1) // 0x3fe921fb40000000, Pi/4 split into three parts
+ PI4B := NewFromFloat(3.77489470793079817668e-8) // 0x3e64442d00000000,
+ PI4C := NewFromFloat(2.69515142907905952645e-15) // 0x3ce8469898cc5170,
+ M4PI := NewFromFloat(1.273239544735162542821171882678754627704620361328125) // 4/pi
+
+ if d.Equal(NewFromFloat(0.0)) {
+ return d
+ }
+ // make argument positive but save the sign
+ sign := false
+ if d.LessThan(NewFromFloat(0.0)) {
+ d = d.Neg()
+ sign = true
+ }
+
+ j := d.Mul(M4PI).IntPart() // integer part of x/(Pi/4), as integer for tests on the phase angle
+ y := NewFromFloat(float64(j)) // integer part of x/(Pi/4), as float
+
+ // map zeros to origin
+ if j&1 == 1 {
+ j++
+ y = y.Add(NewFromFloat(1.0))
+ }
+ j &= 7 // octant modulo 2Pi radians (360 degrees)
+ // reflect in x axis
+ if j > 3 {
+ sign = !sign
+ j -= 4
+ }
+ z := d.Sub(y.Mul(PI4A)).Sub(y.Mul(PI4B)).Sub(y.Mul(PI4C)) // Extended precision modular arithmetic
+ zz := z.Mul(z)
+
+ if j == 1 || j == 2 {
+ w := zz.Mul(zz).Mul(_cos[0].Mul(zz).Add(_cos[1]).Mul(zz).Add(_cos[2]).Mul(zz).Add(_cos[3]).Mul(zz).Add(_cos[4]).Mul(zz).Add(_cos[5]))
+ y = NewFromFloat(1.0).Sub(NewFromFloat(0.5).Mul(zz)).Add(w)
+ } else {
+ y = z.Add(z.Mul(zz).Mul(_sin[0].Mul(zz).Add(_sin[1]).Mul(zz).Add(_sin[2]).Mul(zz).Add(_sin[3]).Mul(zz).Add(_sin[4]).Mul(zz).Add(_sin[5])))
+ }
+ if sign {
+ y = y.Neg()
+ }
+ return y
+}
+
+// cos coefficients
+var _cos = [...]Decimal{
+ NewFromFloat(-1.13585365213876817300e-11), // 0xbda8fa49a0861a9b
+ NewFromFloat(2.08757008419747316778e-9), // 0x3e21ee9d7b4e3f05
+ NewFromFloat(-2.75573141792967388112e-7), // 0xbe927e4f7eac4bc6
+ NewFromFloat(2.48015872888517045348e-5), // 0x3efa01a019c844f5
+ NewFromFloat(-1.38888888888730564116e-3), // 0xbf56c16c16c14f91
+ NewFromFloat(4.16666666666665929218e-2), // 0x3fa555555555554b
+}
+
+// Cos returns the cosine of the radian argument x.
+func (d Decimal) Cos() Decimal {
+
+ PI4A := NewFromFloat(7.85398125648498535156e-1) // 0x3fe921fb40000000, Pi/4 split into three parts
+ PI4B := NewFromFloat(3.77489470793079817668e-8) // 0x3e64442d00000000,
+ PI4C := NewFromFloat(2.69515142907905952645e-15) // 0x3ce8469898cc5170,
+ M4PI := NewFromFloat(1.273239544735162542821171882678754627704620361328125) // 4/pi
+
+ // make argument positive
+ sign := false
+ if d.LessThan(NewFromFloat(0.0)) {
+ d = d.Neg()
+ }
+
+ j := d.Mul(M4PI).IntPart() // integer part of x/(Pi/4), as integer for tests on the phase angle
+ y := NewFromFloat(float64(j)) // integer part of x/(Pi/4), as float
+
+ // map zeros to origin
+ if j&1 == 1 {
+ j++
+ y = y.Add(NewFromFloat(1.0))
+ }
+ j &= 7 // octant modulo 2Pi radians (360 degrees)
+ // reflect in x axis
+ if j > 3 {
+ sign = !sign
+ j -= 4
+ }
+ if j > 1 {
+ sign = !sign
+ }
+
+ z := d.Sub(y.Mul(PI4A)).Sub(y.Mul(PI4B)).Sub(y.Mul(PI4C)) // Extended precision modular arithmetic
+ zz := z.Mul(z)
+
+ if j == 1 || j == 2 {
+ y = z.Add(z.Mul(zz).Mul(_sin[0].Mul(zz).Add(_sin[1]).Mul(zz).Add(_sin[2]).Mul(zz).Add(_sin[3]).Mul(zz).Add(_sin[4]).Mul(zz).Add(_sin[5])))
+ } else {
+ w := zz.Mul(zz).Mul(_cos[0].Mul(zz).Add(_cos[1]).Mul(zz).Add(_cos[2]).Mul(zz).Add(_cos[3]).Mul(zz).Add(_cos[4]).Mul(zz).Add(_cos[5]))
+ y = NewFromFloat(1.0).Sub(NewFromFloat(0.5).Mul(zz)).Add(w)
+ }
+ if sign {
+ y = y.Neg()
+ }
+ return y
+}
+
+var _tanP = [...]Decimal{
+ NewFromFloat(-1.30936939181383777646e+4), // 0xc0c992d8d24f3f38
+ NewFromFloat(1.15351664838587416140e+6), // 0x413199eca5fc9ddd
+ NewFromFloat(-1.79565251976484877988e+7), // 0xc1711fead3299176
+}
+var _tanQ = [...]Decimal{
+ NewFromFloat(1.00000000000000000000e+0),
+ NewFromFloat(1.36812963470692954678e+4), //0x40cab8a5eeb36572
+ NewFromFloat(-1.32089234440210967447e+6), //0xc13427bc582abc96
+ NewFromFloat(2.50083801823357915839e+7), //0x4177d98fc2ead8ef
+ NewFromFloat(-5.38695755929454629881e+7), //0xc189afe03cbe5a31
+}
+
+// Tan returns the tangent of the radian argument x.
+func (d Decimal) Tan() Decimal {
+
+ PI4A := NewFromFloat(7.85398125648498535156e-1) // 0x3fe921fb40000000, Pi/4 split into three parts
+ PI4B := NewFromFloat(3.77489470793079817668e-8) // 0x3e64442d00000000,
+ PI4C := NewFromFloat(2.69515142907905952645e-15) // 0x3ce8469898cc5170,
+ M4PI := NewFromFloat(1.273239544735162542821171882678754627704620361328125) // 4/pi
+
+ if d.Equal(NewFromFloat(0.0)) {
+ return d
+ }
+
+ // make argument positive but save the sign
+ sign := false
+ if d.LessThan(NewFromFloat(0.0)) {
+ d = d.Neg()
+ sign = true
+ }
+
+ j := d.Mul(M4PI).IntPart() // integer part of x/(Pi/4), as integer for tests on the phase angle
+ y := NewFromFloat(float64(j)) // integer part of x/(Pi/4), as float
+
+ // map zeros to origin
+ if j&1 == 1 {
+ j++
+ y = y.Add(NewFromFloat(1.0))
+ }
+
+ z := d.Sub(y.Mul(PI4A)).Sub(y.Mul(PI4B)).Sub(y.Mul(PI4C)) // Extended precision modular arithmetic
+ zz := z.Mul(z)
+
+ if zz.GreaterThan(NewFromFloat(1e-14)) {
+ w := zz.Mul(_tanP[0].Mul(zz).Add(_tanP[1]).Mul(zz).Add(_tanP[2]))
+ x := zz.Add(_tanQ[1]).Mul(zz).Add(_tanQ[2]).Mul(zz).Add(_tanQ[3]).Mul(zz).Add(_tanQ[4])
+ y = z.Add(z.Mul(w.Div(x)))
+ } else {
+ y = z
+ }
+ if j&2 == 2 {
+ y = NewFromFloat(-1.0).Div(y)
+ }
+ if sign {
+ y = y.Neg()
+ }
+ return y
+}
diff --git a/vendor/github.com/shopspring/decimal/rounding.go b/vendor/github.com/shopspring/decimal/rounding.go
new file mode 100644
index 000000000..d4b0cd007
--- /dev/null
+++ b/vendor/github.com/shopspring/decimal/rounding.go
@@ -0,0 +1,160 @@
+// Copyright 2009 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.
+
+// Multiprecision decimal numbers.
+// For floating-point formatting only; not general purpose.
+// Only operations are assign and (binary) left/right shift.
+// Can do binary floating point in multiprecision decimal precisely
+// because 2 divides 10; cannot do decimal floating point
+// in multiprecision binary precisely.
+
+package decimal
+
+type floatInfo struct {
+ mantbits uint
+ expbits uint
+ bias int
+}
+
+var float32info = floatInfo{23, 8, -127}
+var float64info = floatInfo{52, 11, -1023}
+
+// roundShortest rounds d (= mant * 2^exp) to the shortest number of digits
+// that will let the original floating point value be precisely reconstructed.
+func roundShortest(d *decimal, mant uint64, exp int, flt *floatInfo) {
+ // If mantissa is zero, the number is zero; stop now.
+ if mant == 0 {
+ d.nd = 0
+ return
+ }
+
+ // Compute upper and lower such that any decimal number
+ // between upper and lower (possibly inclusive)
+ // will round to the original floating point number.
+
+ // We may see at once that the number is already shortest.
+ //
+ // Suppose d is not denormal, so that 2^exp <= d < 10^dp.
+ // The closest shorter number is at least 10^(dp-nd) away.
+ // The lower/upper bounds computed below are at distance
+ // at most 2^(exp-mantbits).
+ //
+ // So the number is already shortest if 10^(dp-nd) > 2^(exp-mantbits),
+ // or equivalently log2(10)*(dp-nd) > exp-mantbits.
+ // It is true if 332/100*(dp-nd) >= exp-mantbits (log2(10) > 3.32).
+ minexp := flt.bias + 1 // minimum possible exponent
+ if exp > minexp && 332*(d.dp-d.nd) >= 100*(exp-int(flt.mantbits)) {
+ // The number is already shortest.
+ return
+ }
+
+ // d = mant << (exp - mantbits)
+ // Next highest floating point number is mant+1 << exp-mantbits.
+ // Our upper bound is halfway between, mant*2+1 << exp-mantbits-1.
+ upper := new(decimal)
+ upper.Assign(mant*2 + 1)
+ upper.Shift(exp - int(flt.mantbits) - 1)
+
+ // d = mant << (exp - mantbits)
+ // Next lowest floating point number is mant-1 << exp-mantbits,
+ // unless mant-1 drops the significant bit and exp is not the minimum exp,
+ // in which case the next lowest is mant*2-1 << exp-mantbits-1.
+ // Either way, call it mantlo << explo-mantbits.
+ // Our lower bound is halfway between, mantlo*2+1 << explo-mantbits-1.
+ var mantlo uint64
+ var explo int
+ if mant > 1<= d.nd {
+ break
+ }
+ li := ui - upper.dp + lower.dp
+ l := byte('0') // lower digit
+ if li >= 0 && li < lower.nd {
+ l = lower.d[li]
+ }
+ m := byte('0') // middle digit
+ if mi >= 0 {
+ m = d.d[mi]
+ }
+ u := byte('0') // upper digit
+ if ui < upper.nd {
+ u = upper.d[ui]
+ }
+
+ // Okay to round down (truncate) if lower has a different digit
+ // or if lower is inclusive and is exactly the result of rounding
+ // down (i.e., and we have reached the final digit of lower).
+ okdown := l != m || inclusive && li+1 == lower.nd
+
+ switch {
+ case upperdelta == 0 && m+1 < u:
+ // Example:
+ // m = 12345xxx
+ // u = 12347xxx
+ upperdelta = 2
+ case upperdelta == 0 && m != u:
+ // Example:
+ // m = 12345xxx
+ // u = 12346xxx
+ upperdelta = 1
+ case upperdelta == 1 && (m != '9' || u != '0'):
+ // Example:
+ // m = 1234598x
+ // u = 1234600x
+ upperdelta = 2
+ }
+ // Okay to round up if upper has a different digit and either upper
+ // is inclusive or upper is bigger than the result of rounding up.
+ okup := upperdelta > 0 && (inclusive || upperdelta > 1 || ui+1 < upper.nd)
+
+ // If it's okay to do either, then round to the nearest one.
+ // If it's okay to do only one, do it.
+ switch {
+ case okdown && okup:
+ d.Round(mi + 1)
+ return
+ case okdown:
+ d.RoundDown(mi + 1)
+ return
+ case okup:
+ d.RoundUp(mi + 1)
+ return
+ }
+ }
+}
diff --git a/vendor/github.com/sonatard/noctx/.goreleaser.yml b/vendor/github.com/sonatard/noctx/.goreleaser.yml
index 2e3653cde..04f6a0da0 100644
--- a/vendor/github.com/sonatard/noctx/.goreleaser.yml
+++ b/vendor/github.com/sonatard/noctx/.goreleaser.yml
@@ -25,6 +25,8 @@ builds:
ignore:
- goos: darwin
goarch: 386
+ - goos: windows
+ goarch: arm
archives:
- id: noctx
diff --git a/vendor/github.com/sonatard/noctx/README.md b/vendor/github.com/sonatard/noctx/README.md
index 912aa050d..c62d86792 100644
--- a/vendor/github.com/sonatard/noctx/README.md
+++ b/vendor/github.com/sonatard/noctx/README.md
@@ -67,6 +67,7 @@ https://github.com/sonatard/noctx/blob/b768dab1764733f7f69c5075b7497eff4c58f260/
- [net/http - NewRequest](https://pkg.go.dev/net/http#NewRequest)
- [net/http - NewRequestWithContext](https://pkg.go.dev/net/http#NewRequestWithContext)
- [net/http - Request.WithContext](https://pkg.go.dev/net/http#Request.WithContext)
+- [net/http/httptest - NewRequest](https://pkg.go.dev/net/http/httptest#NewRequest)
## net package
diff --git a/vendor/github.com/sonatard/noctx/noctx.go b/vendor/github.com/sonatard/noctx/noctx.go
index 8d79fbad1..2683824aa 100644
--- a/vendor/github.com/sonatard/noctx/noctx.go
+++ b/vendor/github.com/sonatard/noctx/noctx.go
@@ -39,15 +39,16 @@ var ngFuncMessages = map[string]string{
"net.LookupAddr": "must not be called. use (*net.Resolver).LookupAddr with a context",
// net/http
- "net/http.Get": "must not be called. use net/http.NewRequestWithContext and (*net/http.Client).Do(*http.Request)",
- "net/http.Head": "must not be called. use net/http.NewRequestWithContext and (*net/http.Client).Do(*http.Request)",
- "net/http.Post": "must not be called. use net/http.NewRequestWithContext and (*net/http.Client).Do(*http.Request)",
- "net/http.PostForm": "must not be called. use net/http.NewRequestWithContext and (*net/http.Client).Do(*http.Request)",
- "(*net/http.Client).Get": "must not be called. use (*net/http.Client).Do(*http.Request)",
- "(*net/http.Client).Head": "must not be called. use (*net/http.Client).Do(*http.Request)",
- "(*net/http.Client).Post": "must not be called. use (*net/http.Client).Do(*http.Request)",
- "(*net/http.Client).PostForm": "must not be called. use (*net/http.Client).Do(*http.Request)",
- "net/http.NewRequest": "must not be called. use net/http.NewRequestWithContext",
+ "net/http.Get": "must not be called. use net/http.NewRequestWithContext and (*net/http.Client).Do(*http.Request)",
+ "net/http.Head": "must not be called. use net/http.NewRequestWithContext and (*net/http.Client).Do(*http.Request)",
+ "net/http.Post": "must not be called. use net/http.NewRequestWithContext and (*net/http.Client).Do(*http.Request)",
+ "net/http.PostForm": "must not be called. use net/http.NewRequestWithContext and (*net/http.Client).Do(*http.Request)",
+ "(*net/http.Client).Get": "must not be called. use (*net/http.Client).Do(*http.Request)",
+ "(*net/http.Client).Head": "must not be called. use (*net/http.Client).Do(*http.Request)",
+ "(*net/http.Client).Post": "must not be called. use (*net/http.Client).Do(*http.Request)",
+ "(*net/http.Client).PostForm": "must not be called. use (*net/http.Client).Do(*http.Request)",
+ "net/http.NewRequest": "must not be called. use net/http.NewRequestWithContext",
+ "net/http/httptest.NewRequest": "must not be called. use net/http/httptest.NewRequestWithContext",
// database/sql
"(*database/sql.DB).Begin": "must not be called. use (*database/sql.DB).BeginTx",
diff --git a/vendor/github.com/sourcegraph/go-diff/diff/diff.go b/vendor/github.com/sourcegraph/go-diff/diff/diff.go
index 81aa65570..cc19fe522 100644
--- a/vendor/github.com/sourcegraph/go-diff/diff/diff.go
+++ b/vendor/github.com/sourcegraph/go-diff/diff/diff.go
@@ -5,12 +5,18 @@ import (
"time"
)
+// ParseOptions specifies options for parsing diffs.
+type ParseOptions struct {
+ // KeepCR specifies whether to keep trailing carriage return characters (\r) in lines.
+ KeepCR bool
+}
+
// A FileDiff represents a unified diff for a single file.
//
// A file unified diff has a header that resembles the following:
//
-// --- oldname 2009-10-11 15:12:20.000000000 -0700
-// +++ newname 2009-10-11 15:12:30.000000000 -0700
+// --- oldname 2009-10-11 15:12:20.000000000 -0700
+// +++ newname 2009-10-11 15:12:30.000000000 -0700
type FileDiff struct {
// the original name of the file
OrigName string
diff --git a/vendor/github.com/sourcegraph/go-diff/diff/parse.go b/vendor/github.com/sourcegraph/go-diff/diff/parse.go
index 48eeb9670..b73e2301f 100644
--- a/vendor/github.com/sourcegraph/go-diff/diff/parse.go
+++ b/vendor/github.com/sourcegraph/go-diff/diff/parse.go
@@ -1,7 +1,6 @@
package diff
import (
- "bufio"
"bytes"
"errors"
"fmt"
@@ -17,13 +16,24 @@ import (
// case of per-file errors. If it cannot detect when the diff of the next file
// begins, the hunks are added to the FileDiff of the previous file.
func ParseMultiFileDiff(diff []byte) ([]*FileDiff, error) {
- return NewMultiFileDiffReader(bytes.NewReader(diff)).ReadAllFiles()
+ return ParseMultiFileDiffOptions(diff, ParseOptions{})
+}
+
+// ParseMultiFileDiffOptions parses a multi-file unified diff with the given options.
+func ParseMultiFileDiffOptions(diff []byte, opts ParseOptions) ([]*FileDiff, error) {
+ return NewMultiFileDiffReaderOptions(bytes.NewReader(diff), opts).ReadAllFiles()
}
// NewMultiFileDiffReader returns a new MultiFileDiffReader that reads
// a multi-file unified diff from r.
func NewMultiFileDiffReader(r io.Reader) *MultiFileDiffReader {
- return &MultiFileDiffReader{reader: newLineReader(r)}
+ return NewMultiFileDiffReaderOptions(r, ParseOptions{})
+}
+
+// NewMultiFileDiffReaderOptions returns a new MultiFileDiffReader that reads
+// a multi-file unified diff from r with the given options.
+func NewMultiFileDiffReaderOptions(r io.Reader, opts ParseOptions) *MultiFileDiffReader {
+ return &MultiFileDiffReader{reader: newLineReaderOptions(r, opts)}
}
// MultiFileDiffReader reads a multi-file unified diff.
@@ -153,13 +163,24 @@ func (r *MultiFileDiffReader) ReadAllFiles() ([]*FileDiff, error) {
// ParseFileDiff parses a file unified diff.
func ParseFileDiff(diff []byte) (*FileDiff, error) {
- return NewFileDiffReader(bytes.NewReader(diff)).Read()
+ return ParseFileDiffOptions(diff, ParseOptions{})
+}
+
+// ParseFileDiffOptions parses a file unified diff with the given options.
+func ParseFileDiffOptions(diff []byte, opts ParseOptions) (*FileDiff, error) {
+ return NewFileDiffReaderOptions(bytes.NewReader(diff), opts).Read()
}
// NewFileDiffReader returns a new FileDiffReader that reads a file
// unified diff.
func NewFileDiffReader(r io.Reader) *FileDiffReader {
- return &FileDiffReader{reader: &lineReader{reader: bufio.NewReader(r)}}
+ return NewFileDiffReaderOptions(r, ParseOptions{})
+}
+
+// NewFileDiffReaderOptions returns a new FileDiffReader that reads a file
+// unified diff with the given options.
+func NewFileDiffReaderOptions(r io.Reader, opts ParseOptions) *FileDiffReader {
+ return &FileDiffReader{reader: newLineReaderOptions(r, opts)}
}
// FileDiffReader reads a unified file diff.
@@ -405,6 +426,7 @@ func readQuotedFilename(text string) (value string, remainder string, err error)
// valid syntax, it may be impossible to extract filenames; if so, the
// function returns ("", "", true).
func parseDiffGitArgs(diffArgs string) (string, string, bool) {
+ diffArgs = strings.TrimSuffix(diffArgs, "\r")
length := len(diffArgs)
if length < 3 {
return "", "", false
@@ -540,6 +562,7 @@ func handleEmpty(fd *FileDiff) (wasEmpty bool) {
return
}
rawFilename := header[len(prefix):]
+ rawFilename = strings.TrimSuffix(rawFilename, "\r")
// extract the filename prefix (e.g. "a/") from the 'diff --git' line.
var prefixLetterIndex int
@@ -586,7 +609,12 @@ var (
// only of hunks and not include a file header; if it has a file
// header, use ParseFileDiff.
func ParseHunks(diff []byte) ([]*Hunk, error) {
- r := NewHunksReader(bytes.NewReader(diff))
+ return ParseHunksOptions(diff, ParseOptions{})
+}
+
+// ParseHunksOptions parses hunks from a unified diff with the given options.
+func ParseHunksOptions(diff []byte, opts ParseOptions) ([]*Hunk, error) {
+ r := NewHunksReaderOptions(bytes.NewReader(diff), opts)
hunks, err := r.ReadAllHunks()
if err != nil {
return nil, err
@@ -597,7 +625,13 @@ func ParseHunks(diff []byte) ([]*Hunk, error) {
// NewHunksReader returns a new HunksReader that reads unified diff hunks
// from r.
func NewHunksReader(r io.Reader) *HunksReader {
- return &HunksReader{reader: &lineReader{reader: bufio.NewReader(r)}}
+ return NewHunksReaderOptions(r, ParseOptions{})
+}
+
+// NewHunksReaderOptions returns a new HunksReader that reads unified diff hunks
+// from r with the given options.
+func NewHunksReaderOptions(r io.Reader, opts ParseOptions) *HunksReader {
+ return &HunksReader{reader: newLineReaderOptions(r, opts)}
}
// A HunksReader reads hunks from a unified diff.
@@ -701,7 +735,7 @@ func (r *HunksReader) ReadHunk() (*Hunk, error) {
// handle that case.
return r.hunk, &ParseError{r.line, r.offset, &ErrBadHunkLine{Line: line}}
}
- if bytes.Equal(line, []byte(noNewlineMessage)) {
+ if bytes.Equal(bytes.TrimSuffix(line, []byte("\r")), []byte(noNewlineMessage)) {
if lastLineFromOrig {
// Retain the newline in the body (otherwise the
// diff line would be like "-a+b", where "+b" is
@@ -755,6 +789,7 @@ func linePrefix(c byte) bool {
// if its value is 1. normalizeHeader returns an error if the header
// is not in the correct format.
func normalizeHeader(header string) (string, string, error) {
+ header = strings.TrimSuffix(header, "\r")
// Split the header into five parts: the first '@@', the two
// ranges, the last '@@', and the optional section.
pieces := strings.SplitN(header, " ", 5)
@@ -815,7 +850,8 @@ func parseOnlyInMessage(line []byte) (bool, []byte, []byte) {
if idx < 0 {
return false, nil, nil
}
- return true, line[:idx], line[idx+2:]
+ filename := bytes.TrimSuffix(line[idx+2:], []byte("\r"))
+ return true, line[:idx], filename
}
// A ParseError is a description of a unified diff syntax error.
diff --git a/vendor/github.com/sourcegraph/go-diff/diff/reader_util.go b/vendor/github.com/sourcegraph/go-diff/diff/reader_util.go
index 45300252b..3356283d6 100644
--- a/vendor/github.com/sourcegraph/go-diff/diff/reader_util.go
+++ b/vendor/github.com/sourcegraph/go-diff/diff/reader_util.go
@@ -13,6 +13,13 @@ func newLineReader(r io.Reader) *lineReader {
return &lineReader{reader: bufio.NewReader(r)}
}
+func newLineReaderOptions(r io.Reader, opts ParseOptions) *lineReader {
+ return &lineReader{
+ reader: bufio.NewReader(r),
+ keepCR: opts.KeepCR,
+ }
+}
+
// lineReader is a wrapper around a bufio.Reader that caches the next line to
// provide lookahead functionality for the next two lines.
type lineReader struct {
@@ -20,14 +27,20 @@ type lineReader struct {
cachedNextLine []byte
cachedNextLineErr error
+
+ keepCR bool
+}
+
+func (l *lineReader) ensureCachedNextLine() {
+ if l.cachedNextLine == nil && l.cachedNextLineErr == nil {
+ l.cachedNextLine, l.cachedNextLineErr = readLine(l.reader, l.keepCR)
+ }
}
// readLine returns the next unconsumed line and advances the internal cache of
// the lineReader.
func (l *lineReader) readLine() ([]byte, error) {
- if l.cachedNextLine == nil && l.cachedNextLineErr == nil {
- l.cachedNextLine, l.cachedNextLineErr = readLine(l.reader)
- }
+ l.ensureCachedNextLine()
if l.cachedNextLineErr != nil {
return nil, l.cachedNextLineErr
@@ -35,7 +48,7 @@ func (l *lineReader) readLine() ([]byte, error) {
next := l.cachedNextLine
- l.cachedNextLine, l.cachedNextLineErr = readLine(l.reader)
+ l.cachedNextLine, l.cachedNextLineErr = readLine(l.reader, l.keepCR)
return next, nil
}
@@ -46,9 +59,7 @@ func (l *lineReader) readLine() ([]byte, error) {
// io.EOF and bufio.ErrBufferFull errors are ignored so that the function can
// be used when at the end of the file.
func (l *lineReader) nextLineStartsWith(prefix string) (bool, error) {
- if l.cachedNextLine == nil && l.cachedNextLineErr == nil {
- l.cachedNextLine, l.cachedNextLineErr = readLine(l.reader)
- }
+ l.ensureCachedNextLine()
return l.lineHasPrefix(l.cachedNextLine, prefix, l.cachedNextLineErr)
}
@@ -58,14 +69,8 @@ func (l *lineReader) nextLineStartsWith(prefix string) (bool, error) {
//
// io.EOF and bufio.ErrBufferFull errors are ignored so that the function can
// be used when at the end of the file.
-//
-// The lineReader MUST be initialized by calling readLine at least once before
-// calling nextLineStartsWith. Otherwise ErrLineReaderUninitialized will be
-// returned.
func (l *lineReader) nextNextLineStartsWith(prefix string) (bool, error) {
- if l.cachedNextLine == nil && l.cachedNextLineErr == nil {
- l.cachedNextLine, l.cachedNextLineErr = readLine(l.reader)
- }
+ l.ensureCachedNextLine()
next, err := l.reader.Peek(len(prefix))
return l.lineHasPrefix(next, prefix, err)
@@ -93,22 +98,21 @@ func (l *lineReader) lineHasPrefix(line []byte, prefix string, readErr error) (b
// the next line in the Reader with the trailing newline stripped. It will return an
// io.EOF error when there is nothing left to read (at the start of the function call). It
// will return any other errors it receives from the underlying call to ReadBytes.
-func readLine(r *bufio.Reader) ([]byte, error) {
- line_, err := r.ReadBytes('\n')
- if err == io.EOF {
- if len(line_) == 0 {
- return nil, io.EOF
- }
-
- // ReadBytes returned io.EOF, because it didn't find another newline, but there is
- // still the remainder of the file to return as a line.
- line := line_
- return line, nil
- } else if err != nil {
+func readLine(r *bufio.Reader, keepCR bool) ([]byte, error) {
+ line, err := r.ReadBytes('\n')
+ if err == io.EOF && len(line) == 0 {
+ return nil, io.EOF
+ }
+ if err != nil && err != io.EOF {
return nil, err
}
- line := line_[0 : len(line_)-1]
- return dropCR(line), nil
+ if line[len(line)-1] == '\n' {
+ line = line[:len(line)-1]
+ }
+ if !keepCR {
+ return dropCR(line), nil
+ }
+ return line, nil
}
// dropCR drops a terminal \r from the data.
diff --git a/vendor/github.com/sourcegraph/go-diff/diff/reverse.go b/vendor/github.com/sourcegraph/go-diff/diff/reverse.go
new file mode 100644
index 000000000..87715efb9
--- /dev/null
+++ b/vendor/github.com/sourcegraph/go-diff/diff/reverse.go
@@ -0,0 +1,192 @@
+package diff
+
+import (
+ "bytes"
+ "errors"
+ "fmt"
+)
+
+// ReverseFileDiff takes a diff.FileDiff, and returns the reverse operation.
+// This is a FileDiff that undoes the edit of the original.
+func ReverseFileDiff(fd *FileDiff) (*FileDiff, error) {
+ reverse := FileDiff{
+ OrigName: fd.NewName,
+ OrigTime: fd.NewTime,
+ NewName: fd.OrigName,
+ NewTime: fd.OrigTime,
+ Extended: fd.Extended,
+ }
+ for _, hunk := range fd.Hunks {
+ invHunk, err := reverseHunk(hunk)
+ if err != nil {
+ return nil, err
+ }
+ reverse.Hunks = append(reverse.Hunks, invHunk)
+ }
+ return &reverse, nil
+}
+
+// ReverseMultiFileDiff reverses a series of FileDiffs.
+func ReverseMultiFileDiff(fds []*FileDiff) ([]*FileDiff, error) {
+ var reverse []*FileDiff
+ for _, fd := range fds {
+ r, err := ReverseFileDiff(fd)
+ if err != nil {
+ return nil, err
+ }
+ reverse = append(reverse, r)
+ }
+ return reverse, nil
+}
+
+// A subhunk represents a portion of a Hunk.Body, split into three sections.
+// It consists of zero or more context lines, followed by zero or more orig
+// lines and then zero or more new lines.
+//
+// Each line is stored WITHOUT its starting character, but with the newlines
+// included. The final entry in a section may be missing a trailing newline.
+//
+// A missing newline in orig is represented in a Hunk by OrigNoNewlineAt,
+// but is represented here as a missing newline.
+type contextLine struct {
+ body []byte
+ bare bool
+}
+
+type subhunk struct {
+ context []contextLine
+ orig [][]byte
+ new [][]byte
+}
+
+// reverseHunk converts a Hunk into its reverse operation.
+func reverseHunk(forward *Hunk) (*Hunk, error) {
+ reverse := Hunk{
+ OrigStartLine: forward.NewStartLine,
+ OrigLines: forward.NewLines,
+ OrigNoNewlineAt: 0, // we may change this below
+ NewStartLine: forward.OrigStartLine,
+ NewLines: forward.OrigLines,
+ Section: forward.Section,
+ StartPosition: forward.StartPosition,
+ }
+ subs, err := toSubhunks(forward)
+ if err != nil {
+ return nil, err
+ }
+ for _, sub := range subs {
+ invSub := subhunk{
+ context: sub.context,
+ orig: sub.new,
+ new: sub.orig,
+ }
+ for _, line := range invSub.context {
+ if line.bare {
+ reverse.Body = append(reverse.Body, line.body...)
+ continue
+ }
+ reverse.Body = append(reverse.Body, ' ')
+ reverse.Body = append(reverse.Body, line.body...)
+ }
+ for _, line := range invSub.orig {
+ reverse.Body = append(reverse.Body, '-')
+ reverse.Body = append(reverse.Body, line...)
+ }
+ if len(invSub.orig) > 0 && reverse.Body[len(reverse.Body)-1] != '\n' {
+ // There was a missing newline in `orig`, which we encode in a
+ // hunk with an offset.
+ reverse.Body = append(reverse.Body, '\n')
+ reverse.OrigNoNewlineAt = int32(len(reverse.Body))
+ }
+ for _, line := range invSub.new {
+ reverse.Body = append(reverse.Body, '+')
+ reverse.Body = append(reverse.Body, line...)
+ }
+ }
+ return &reverse, nil
+}
+
+func extractContextLines(from *[]byte) []contextLine {
+ var lines []contextLine
+ for len(*from) > 0 {
+ if (*from)[0] == '\n' {
+ lines = append(lines, contextLine{body: []byte{'\n'}, bare: true})
+ *from = (*from)[1:]
+ continue
+ }
+ if (*from)[0] != ' ' {
+ break
+ }
+
+ newline := bytes.IndexByte(*from, '\n')
+ if newline < 0 {
+ lines = append(lines, contextLine{body: (*from)[1:]})
+ *from = nil
+ continue
+ }
+
+ lines = append(lines, contextLine{body: (*from)[1 : newline+1]})
+ *from = (*from)[newline+1:]
+ }
+ return lines
+}
+
+func extractLinesStartingWith(from *[]byte, startingWith byte) [][]byte {
+ var lines [][]byte
+ for len(*from) > 0 {
+ if (*from)[0] != startingWith {
+ break
+ }
+
+ newline := bytes.IndexByte(*from, '\n')
+ if newline < 0 {
+ lines = append(lines, (*from)[1:])
+ *from = nil
+ continue
+ }
+
+ lines = append(lines, (*from)[1:newline+1])
+ *from = (*from)[newline+1:]
+ }
+ return lines
+}
+
+// Extracts the subhunks from a diff.Hunk.
+//
+// This groups a Hunk's buffer into one or more subhunks, matching the conditions
+// of `subhunk` above. This function groups, strips prefix characters, and strips
+// a newline for `OrigNoNewlineAt` if necessary.
+func toSubhunks(hunk *Hunk) ([]subhunk, error) {
+ var body []byte = hunk.Body
+ var subhunks []subhunk
+ if len(body) == 0 {
+ return nil, nil
+ }
+ for len(body) > 0 {
+ sh := subhunk{
+ context: extractContextLines(&body),
+ orig: extractLinesStartingWith(&body, '-'),
+ new: extractLinesStartingWith(&body, '+'),
+ }
+ if len(sh.context) == 0 && len(sh.orig) == 0 && len(sh.new) == 0 {
+ // The first line didn't start with any expected prefix.
+ return nil, fmt.Errorf("unexpected character %q at start of line", body[0])
+ }
+ subhunks = append(subhunks, sh)
+ }
+ if hunk.OrigNoNewlineAt > 0 {
+ // The Hunk represents a missing newline at the end of an "orig" line with a
+ // OrigNoNewlineAt index. We represent it here as an actual missing newline.
+ var lastSubhunk *subhunk = &subhunks[len(subhunks)-1]
+ s := len(lastSubhunk.orig)
+ if s == 0 {
+ return nil, errors.New("inconsistent OrigNoNewlineAt in input")
+ }
+ var cut bool
+ lastSubhunk.orig[s-1], cut = bytes.CutSuffix(lastSubhunk.orig[s-1], []byte("\n"))
+ if !cut {
+ return nil, errors.New("missing newline in input")
+ }
+ }
+ return subhunks, nil
+}
diff --git a/vendor/github.com/spf13/cast/.editorconfig b/vendor/github.com/spf13/cast/.editorconfig
new file mode 100644
index 000000000..a85749f19
--- /dev/null
+++ b/vendor/github.com/spf13/cast/.editorconfig
@@ -0,0 +1,15 @@
+root = true
+
+[*]
+charset = utf-8
+end_of_line = lf
+indent_size = 4
+indent_style = space
+insert_final_newline = true
+trim_trailing_whitespace = true
+
+[*.go]
+indent_style = tab
+
+[{*.yml,*.yaml}]
+indent_size = 2
diff --git a/vendor/github.com/spf13/cast/.golangci.yaml b/vendor/github.com/spf13/cast/.golangci.yaml
new file mode 100644
index 000000000..e00fd47aa
--- /dev/null
+++ b/vendor/github.com/spf13/cast/.golangci.yaml
@@ -0,0 +1,39 @@
+version: "2"
+
+run:
+ timeout: 10m
+
+linters:
+ enable:
+ - errcheck
+ - govet
+ - ineffassign
+ - misspell
+ - nolintlint
+ # - revive
+ - unused
+
+ disable:
+ - staticcheck
+
+ settings:
+ misspell:
+ locale: US
+ nolintlint:
+ allow-unused: false # report any unused nolint directives
+ require-specific: false # don't require nolint directives to be specific about which linter is being skipped
+
+formatters:
+ enable:
+ - gci
+ - gofmt
+ # - gofumpt
+ - goimports
+ # - golines
+
+ settings:
+ gci:
+ sections:
+ - standard
+ - default
+ - localmodule
diff --git a/vendor/github.com/spf13/cast/README.md b/vendor/github.com/spf13/cast/README.md
index 120a57342..c58eccb3f 100644
--- a/vendor/github.com/spf13/cast/README.md
+++ b/vendor/github.com/spf13/cast/README.md
@@ -1,8 +1,9 @@
-cast
-====
-[](https://godoc.org/github.com/spf13/cast)
-[](https://github.com/spf13/cast/actions/workflows/go.yml)
-[](https://goreportcard.com/report/github.com/spf13/cast)
+# cast
+
+[](https://github.com/spf13/cast/actions/workflows/ci.yaml)
+[](https://pkg.go.dev/mod/github.com/spf13/cast)
+
+[](https://deps.dev/go/github.com%252Fspf13%252Fcast)
Easy and safe casting from one type to another in Go
@@ -17,7 +18,7 @@ interface into a bool, etc. Cast does this intelligently when an obvious
conversion is possible. It doesn’t make any attempts to guess what you meant,
for example you can only convert a string to an int when it is a string
representation of an int such as “8”. Cast was developed for use in
-[Hugo](http://hugo.spf13.com), a website engine which uses YAML, TOML or JSON
+[Hugo](https://gohugo.io), a website engine which uses YAML, TOML or JSON
for meta data.
## Why use Cast?
@@ -73,3 +74,6 @@ the code for a complete set.
cast.ToInt(eight) // 8
cast.ToInt(nil) // 0
+## License
+
+The project is licensed under the [MIT License](LICENSE).
diff --git a/vendor/github.com/spf13/cast/alias.go b/vendor/github.com/spf13/cast/alias.go
new file mode 100644
index 000000000..855d60005
--- /dev/null
+++ b/vendor/github.com/spf13/cast/alias.go
@@ -0,0 +1,69 @@
+// Copyright © 2014 Steve Francia .
+//
+// Use of this source code is governed by an MIT-style
+// license that can be found in the LICENSE file.
+package cast
+
+import (
+ "reflect"
+ "slices"
+)
+
+var kindNames = []string{
+ reflect.String: "string",
+ reflect.Bool: "bool",
+ reflect.Int: "int",
+ reflect.Int8: "int8",
+ reflect.Int16: "int16",
+ reflect.Int32: "int32",
+ reflect.Int64: "int64",
+ reflect.Uint: "uint",
+ reflect.Uint8: "uint8",
+ reflect.Uint16: "uint16",
+ reflect.Uint32: "uint32",
+ reflect.Uint64: "uint64",
+ reflect.Float32: "float32",
+ reflect.Float64: "float64",
+}
+
+var kinds = map[reflect.Kind]func(reflect.Value) any{
+ reflect.String: func(v reflect.Value) any { return v.String() },
+ reflect.Bool: func(v reflect.Value) any { return v.Bool() },
+ reflect.Int: func(v reflect.Value) any { return int(v.Int()) },
+ reflect.Int8: func(v reflect.Value) any { return int8(v.Int()) },
+ reflect.Int16: func(v reflect.Value) any { return int16(v.Int()) },
+ reflect.Int32: func(v reflect.Value) any { return int32(v.Int()) },
+ reflect.Int64: func(v reflect.Value) any { return v.Int() },
+ reflect.Uint: func(v reflect.Value) any { return uint(v.Uint()) },
+ reflect.Uint8: func(v reflect.Value) any { return uint8(v.Uint()) },
+ reflect.Uint16: func(v reflect.Value) any { return uint16(v.Uint()) },
+ reflect.Uint32: func(v reflect.Value) any { return uint32(v.Uint()) },
+ reflect.Uint64: func(v reflect.Value) any { return v.Uint() },
+ reflect.Float32: func(v reflect.Value) any { return float32(v.Float()) },
+ reflect.Float64: func(v reflect.Value) any { return v.Float() },
+}
+
+// resolveAlias attempts to resolve a named type to its underlying basic type (if possible).
+//
+// Pointers are expected to be indirected by this point.
+func resolveAlias(i any) (any, bool) {
+ if i == nil {
+ return nil, false
+ }
+
+ t := reflect.TypeOf(i)
+
+ // Not a named type
+ if t.Name() == "" || slices.Contains(kindNames, t.Name()) {
+ return i, false
+ }
+
+ resolve, ok := kinds[t.Kind()]
+ if !ok { // Not a supported kind
+ return i, false
+ }
+
+ v := reflect.ValueOf(i)
+
+ return resolve(v), true
+}
diff --git a/vendor/github.com/spf13/cast/basic.go b/vendor/github.com/spf13/cast/basic.go
new file mode 100644
index 000000000..fa330e207
--- /dev/null
+++ b/vendor/github.com/spf13/cast/basic.go
@@ -0,0 +1,131 @@
+// Copyright © 2014 Steve Francia .
+//
+// Use of this source code is governed by an MIT-style
+// license that can be found in the LICENSE file.
+
+package cast
+
+import (
+ "encoding/json"
+ "fmt"
+ "html/template"
+ "strconv"
+ "time"
+)
+
+// ToBoolE casts any value to a bool type.
+func ToBoolE(i any) (bool, error) {
+ i, _ = indirect(i)
+
+ switch b := i.(type) {
+ case bool:
+ return b, nil
+ case nil:
+ return false, nil
+ case int:
+ return b != 0, nil
+ case int8:
+ return b != 0, nil
+ case int16:
+ return b != 0, nil
+ case int32:
+ return b != 0, nil
+ case int64:
+ return b != 0, nil
+ case uint:
+ return b != 0, nil
+ case uint8:
+ return b != 0, nil
+ case uint16:
+ return b != 0, nil
+ case uint32:
+ return b != 0, nil
+ case uint64:
+ return b != 0, nil
+ case float32:
+ return b != 0, nil
+ case float64:
+ return b != 0, nil
+ case time.Duration:
+ return b != 0, nil
+ case string:
+ return strconv.ParseBool(b)
+ case json.Number:
+ v, err := ToInt64E(b)
+ if err == nil {
+ return v != 0, nil
+ }
+
+ return false, fmt.Errorf(errorMsg, i, i, false)
+ default:
+ if i, ok := resolveAlias(i); ok {
+ return ToBoolE(i)
+ }
+
+ return false, fmt.Errorf(errorMsg, i, i, false)
+ }
+}
+
+// ToStringE casts any value to a string type.
+func ToStringE(i any) (string, error) {
+ switch s := i.(type) {
+ case string:
+ return s, nil
+ case bool:
+ return strconv.FormatBool(s), nil
+ case float64:
+ return strconv.FormatFloat(s, 'f', -1, 64), nil
+ case float32:
+ return strconv.FormatFloat(float64(s), 'f', -1, 32), nil
+ case int:
+ return strconv.Itoa(s), nil
+ case int8:
+ return strconv.FormatInt(int64(s), 10), nil
+ case int16:
+ return strconv.FormatInt(int64(s), 10), nil
+ case int32:
+ return strconv.FormatInt(int64(s), 10), nil
+ case int64:
+ return strconv.FormatInt(s, 10), nil
+ case uint:
+ return strconv.FormatUint(uint64(s), 10), nil
+ case uint8:
+ return strconv.FormatUint(uint64(s), 10), nil
+ case uint16:
+ return strconv.FormatUint(uint64(s), 10), nil
+ case uint32:
+ return strconv.FormatUint(uint64(s), 10), nil
+ case uint64:
+ return strconv.FormatUint(s, 10), nil
+ case json.Number:
+ return s.String(), nil
+ case []byte:
+ return string(s), nil
+ case template.HTML:
+ return string(s), nil
+ case template.URL:
+ return string(s), nil
+ case template.JS:
+ return string(s), nil
+ case template.CSS:
+ return string(s), nil
+ case template.HTMLAttr:
+ return string(s), nil
+ case nil:
+ return "", nil
+ case fmt.Stringer:
+ return s.String(), nil
+ case error:
+ return s.Error(), nil
+ default:
+ if i, ok := indirect(i); ok {
+ return ToStringE(i)
+ }
+
+ if i, ok := resolveAlias(i); ok {
+ return ToStringE(i)
+ }
+
+ return "", fmt.Errorf(errorMsg, i, i, "")
+ }
+}
diff --git a/vendor/github.com/spf13/cast/cast.go b/vendor/github.com/spf13/cast/cast.go
index 0cfe9418d..8d85539b3 100644
--- a/vendor/github.com/spf13/cast/cast.go
+++ b/vendor/github.com/spf13/cast/cast.go
@@ -8,169 +8,77 @@ package cast
import "time"
-// ToBool casts an interface to a bool type.
-func ToBool(i interface{}) bool {
- v, _ := ToBoolE(i)
- return v
-}
-
-// ToTime casts an interface to a time.Time type.
-func ToTime(i interface{}) time.Time {
- v, _ := ToTimeE(i)
- return v
-}
-
-func ToTimeInDefaultLocation(i interface{}, location *time.Location) time.Time {
- v, _ := ToTimeInDefaultLocationE(i, location)
- return v
-}
-
-// ToDuration casts an interface to a time.Duration type.
-func ToDuration(i interface{}) time.Duration {
- v, _ := ToDurationE(i)
- return v
-}
-
-// ToFloat64 casts an interface to a float64 type.
-func ToFloat64(i interface{}) float64 {
- v, _ := ToFloat64E(i)
- return v
-}
-
-// ToFloat32 casts an interface to a float32 type.
-func ToFloat32(i interface{}) float32 {
- v, _ := ToFloat32E(i)
- return v
-}
-
-// ToInt64 casts an interface to an int64 type.
-func ToInt64(i interface{}) int64 {
- v, _ := ToInt64E(i)
- return v
-}
-
-// ToInt32 casts an interface to an int32 type.
-func ToInt32(i interface{}) int32 {
- v, _ := ToInt32E(i)
- return v
-}
-
-// ToInt16 casts an interface to an int16 type.
-func ToInt16(i interface{}) int16 {
- v, _ := ToInt16E(i)
- return v
-}
-
-// ToInt8 casts an interface to an int8 type.
-func ToInt8(i interface{}) int8 {
- v, _ := ToInt8E(i)
- return v
-}
-
-// ToInt casts an interface to an int type.
-func ToInt(i interface{}) int {
- v, _ := ToIntE(i)
- return v
-}
-
-// ToUint casts an interface to a uint type.
-func ToUint(i interface{}) uint {
- v, _ := ToUintE(i)
- return v
-}
-
-// ToUint64 casts an interface to a uint64 type.
-func ToUint64(i interface{}) uint64 {
- v, _ := ToUint64E(i)
- return v
-}
-
-// ToUint32 casts an interface to a uint32 type.
-func ToUint32(i interface{}) uint32 {
- v, _ := ToUint32E(i)
- return v
-}
-
-// ToUint16 casts an interface to a uint16 type.
-func ToUint16(i interface{}) uint16 {
- v, _ := ToUint16E(i)
- return v
-}
-
-// ToUint8 casts an interface to a uint8 type.
-func ToUint8(i interface{}) uint8 {
- v, _ := ToUint8E(i)
- return v
-}
-
-// ToString casts an interface to a string type.
-func ToString(i interface{}) string {
- v, _ := ToStringE(i)
- return v
-}
-
-// ToStringMapString casts an interface to a map[string]string type.
-func ToStringMapString(i interface{}) map[string]string {
- v, _ := ToStringMapStringE(i)
- return v
-}
-
-// ToStringMapStringSlice casts an interface to a map[string][]string type.
-func ToStringMapStringSlice(i interface{}) map[string][]string {
- v, _ := ToStringMapStringSliceE(i)
- return v
-}
-
-// ToStringMapBool casts an interface to a map[string]bool type.
-func ToStringMapBool(i interface{}) map[string]bool {
- v, _ := ToStringMapBoolE(i)
- return v
-}
-
-// ToStringMapInt casts an interface to a map[string]int type.
-func ToStringMapInt(i interface{}) map[string]int {
- v, _ := ToStringMapIntE(i)
- return v
-}
-
-// ToStringMapInt64 casts an interface to a map[string]int64 type.
-func ToStringMapInt64(i interface{}) map[string]int64 {
- v, _ := ToStringMapInt64E(i)
- return v
-}
-
-// ToStringMap casts an interface to a map[string]interface{} type.
-func ToStringMap(i interface{}) map[string]interface{} {
- v, _ := ToStringMapE(i)
- return v
-}
-
-// ToSlice casts an interface to a []interface{} type.
-func ToSlice(i interface{}) []interface{} {
- v, _ := ToSliceE(i)
- return v
-}
-
-// ToBoolSlice casts an interface to a []bool type.
-func ToBoolSlice(i interface{}) []bool {
- v, _ := ToBoolSliceE(i)
- return v
-}
-
-// ToStringSlice casts an interface to a []string type.
-func ToStringSlice(i interface{}) []string {
- v, _ := ToStringSliceE(i)
- return v
-}
+const errorMsg = "unable to cast %#v of type %T to %T"
+const errorMsgWith = "unable to cast %#v of type %T to %T: %w"
-// ToIntSlice casts an interface to a []int type.
-func ToIntSlice(i interface{}) []int {
- v, _ := ToIntSliceE(i)
- return v
-}
+// Basic is a type parameter constraint for functions accepting basic types.
+//
+// It represents the supported basic types this package can cast to.
+type Basic interface {
+ string | bool | Number | time.Time | time.Duration
+}
+
+// ToE casts any value to a [Basic] type.
+func ToE[T Basic](i any) (T, error) {
+ var t T
+
+ var v any
+ var err error
+
+ switch any(t).(type) {
+ case string:
+ v, err = ToStringE(i)
+ case bool:
+ v, err = ToBoolE(i)
+ case int:
+ v, err = toNumberE[int](i, parseInt[int])
+ case int8:
+ v, err = toNumberE[int8](i, parseInt[int8])
+ case int16:
+ v, err = toNumberE[int16](i, parseInt[int16])
+ case int32:
+ v, err = toNumberE[int32](i, parseInt[int32])
+ case int64:
+ v, err = toNumberE[int64](i, parseInt[int64])
+ case uint:
+ v, err = toUnsignedNumberE[uint](i, parseUint[uint])
+ case uint8:
+ v, err = toUnsignedNumberE[uint8](i, parseUint[uint8])
+ case uint16:
+ v, err = toUnsignedNumberE[uint16](i, parseUint[uint16])
+ case uint32:
+ v, err = toUnsignedNumberE[uint32](i, parseUint[uint32])
+ case uint64:
+ v, err = toUnsignedNumberE[uint64](i, parseUint[uint64])
+ case float32:
+ v, err = toNumberE[float32](i, parseFloat[float32])
+ case float64:
+ v, err = toNumberE[float64](i, parseFloat[float64])
+ case time.Time:
+ v, err = ToTimeE(i)
+ case time.Duration:
+ v, err = ToDurationE(i)
+ }
+
+ if err != nil {
+ return t, err
+ }
+
+ return v.(T), nil
+}
+
+// Must is a helper that wraps a call to a cast function and panics if the error is non-nil.
+func Must[T any](i any, err error) T {
+ if err != nil {
+ panic(err)
+ }
+
+ return i.(T)
+}
+
+// To casts any value to a [Basic] type.
+func To[T Basic](i any) T {
+ v, _ := ToE[T](i)
-// ToDurationSlice casts an interface to a []time.Duration type.
-func ToDurationSlice(i interface{}) []time.Duration {
- v, _ := ToDurationSliceE(i)
return v
}
diff --git a/vendor/github.com/spf13/cast/caste.go b/vendor/github.com/spf13/cast/caste.go
deleted file mode 100644
index 514d759bf..000000000
--- a/vendor/github.com/spf13/cast/caste.go
+++ /dev/null
@@ -1,1476 +0,0 @@
-// Copyright © 2014 Steve Francia .
-//
-// Use of this source code is governed by an MIT-style
-// license that can be found in the LICENSE file.
-
-package cast
-
-import (
- "encoding/json"
- "errors"
- "fmt"
- "html/template"
- "reflect"
- "strconv"
- "strings"
- "time"
-)
-
-var errNegativeNotAllowed = errors.New("unable to cast negative value")
-
-// ToTimeE casts an interface to a time.Time type.
-func ToTimeE(i interface{}) (tim time.Time, err error) {
- return ToTimeInDefaultLocationE(i, time.UTC)
-}
-
-// ToTimeInDefaultLocationE casts an empty interface to time.Time,
-// interpreting inputs without a timezone to be in the given location,
-// or the local timezone if nil.
-func ToTimeInDefaultLocationE(i interface{}, location *time.Location) (tim time.Time, err error) {
- i = indirect(i)
-
- switch v := i.(type) {
- case time.Time:
- return v, nil
- case string:
- return StringToDateInDefaultLocation(v, location)
- case json.Number:
- s, err1 := ToInt64E(v)
- if err1 != nil {
- return time.Time{}, fmt.Errorf("unable to cast %#v of type %T to Time", i, i)
- }
- return time.Unix(s, 0), nil
- case int:
- return time.Unix(int64(v), 0), nil
- case int64:
- return time.Unix(v, 0), nil
- case int32:
- return time.Unix(int64(v), 0), nil
- case uint:
- return time.Unix(int64(v), 0), nil
- case uint64:
- return time.Unix(int64(v), 0), nil
- case uint32:
- return time.Unix(int64(v), 0), nil
- default:
- return time.Time{}, fmt.Errorf("unable to cast %#v of type %T to Time", i, i)
- }
-}
-
-// ToDurationE casts an interface to a time.Duration type.
-func ToDurationE(i interface{}) (d time.Duration, err error) {
- i = indirect(i)
-
- switch s := i.(type) {
- case time.Duration:
- return s, nil
- case int, int64, int32, int16, int8, uint, uint64, uint32, uint16, uint8:
- d = time.Duration(ToInt64(s))
- return
- case float32, float64:
- d = time.Duration(ToFloat64(s))
- return
- case string:
- if strings.ContainsAny(s, "nsuµmh") {
- d, err = time.ParseDuration(s)
- } else {
- d, err = time.ParseDuration(s + "ns")
- }
- return
- case json.Number:
- var v float64
- v, err = s.Float64()
- d = time.Duration(v)
- return
- default:
- err = fmt.Errorf("unable to cast %#v of type %T to Duration", i, i)
- return
- }
-}
-
-// ToBoolE casts an interface to a bool type.
-func ToBoolE(i interface{}) (bool, error) {
- i = indirect(i)
-
- switch b := i.(type) {
- case bool:
- return b, nil
- case nil:
- return false, nil
- case int:
- if i.(int) != 0 {
- return true, nil
- }
- return false, nil
- case string:
- return strconv.ParseBool(i.(string))
- case json.Number:
- v, err := ToInt64E(b)
- if err == nil {
- return v != 0, nil
- }
- return false, fmt.Errorf("unable to cast %#v of type %T to bool", i, i)
- default:
- return false, fmt.Errorf("unable to cast %#v of type %T to bool", i, i)
- }
-}
-
-// ToFloat64E casts an interface to a float64 type.
-func ToFloat64E(i interface{}) (float64, error) {
- i = indirect(i)
-
- intv, ok := toInt(i)
- if ok {
- return float64(intv), nil
- }
-
- switch s := i.(type) {
- case float64:
- return s, nil
- case float32:
- return float64(s), nil
- case int64:
- return float64(s), nil
- case int32:
- return float64(s), nil
- case int16:
- return float64(s), nil
- case int8:
- return float64(s), nil
- case uint:
- return float64(s), nil
- case uint64:
- return float64(s), nil
- case uint32:
- return float64(s), nil
- case uint16:
- return float64(s), nil
- case uint8:
- return float64(s), nil
- case string:
- v, err := strconv.ParseFloat(s, 64)
- if err == nil {
- return v, nil
- }
- return 0, fmt.Errorf("unable to cast %#v of type %T to float64", i, i)
- case json.Number:
- v, err := s.Float64()
- if err == nil {
- return v, nil
- }
- return 0, fmt.Errorf("unable to cast %#v of type %T to float64", i, i)
- case bool:
- if s {
- return 1, nil
- }
- return 0, nil
- case nil:
- return 0, nil
- default:
- return 0, fmt.Errorf("unable to cast %#v of type %T to float64", i, i)
- }
-}
-
-// ToFloat32E casts an interface to a float32 type.
-func ToFloat32E(i interface{}) (float32, error) {
- i = indirect(i)
-
- intv, ok := toInt(i)
- if ok {
- return float32(intv), nil
- }
-
- switch s := i.(type) {
- case float64:
- return float32(s), nil
- case float32:
- return s, nil
- case int64:
- return float32(s), nil
- case int32:
- return float32(s), nil
- case int16:
- return float32(s), nil
- case int8:
- return float32(s), nil
- case uint:
- return float32(s), nil
- case uint64:
- return float32(s), nil
- case uint32:
- return float32(s), nil
- case uint16:
- return float32(s), nil
- case uint8:
- return float32(s), nil
- case string:
- v, err := strconv.ParseFloat(s, 32)
- if err == nil {
- return float32(v), nil
- }
- return 0, fmt.Errorf("unable to cast %#v of type %T to float32", i, i)
- case json.Number:
- v, err := s.Float64()
- if err == nil {
- return float32(v), nil
- }
- return 0, fmt.Errorf("unable to cast %#v of type %T to float32", i, i)
- case bool:
- if s {
- return 1, nil
- }
- return 0, nil
- case nil:
- return 0, nil
- default:
- return 0, fmt.Errorf("unable to cast %#v of type %T to float32", i, i)
- }
-}
-
-// ToInt64E casts an interface to an int64 type.
-func ToInt64E(i interface{}) (int64, error) {
- i = indirect(i)
-
- intv, ok := toInt(i)
- if ok {
- return int64(intv), nil
- }
-
- switch s := i.(type) {
- case int64:
- return s, nil
- case int32:
- return int64(s), nil
- case int16:
- return int64(s), nil
- case int8:
- return int64(s), nil
- case uint:
- return int64(s), nil
- case uint64:
- return int64(s), nil
- case uint32:
- return int64(s), nil
- case uint16:
- return int64(s), nil
- case uint8:
- return int64(s), nil
- case float64:
- return int64(s), nil
- case float32:
- return int64(s), nil
- case string:
- v, err := strconv.ParseInt(trimZeroDecimal(s), 0, 0)
- if err == nil {
- return v, nil
- }
- return 0, fmt.Errorf("unable to cast %#v of type %T to int64", i, i)
- case json.Number:
- return ToInt64E(string(s))
- case bool:
- if s {
- return 1, nil
- }
- return 0, nil
- case nil:
- return 0, nil
- default:
- return 0, fmt.Errorf("unable to cast %#v of type %T to int64", i, i)
- }
-}
-
-// ToInt32E casts an interface to an int32 type.
-func ToInt32E(i interface{}) (int32, error) {
- i = indirect(i)
-
- intv, ok := toInt(i)
- if ok {
- return int32(intv), nil
- }
-
- switch s := i.(type) {
- case int64:
- return int32(s), nil
- case int32:
- return s, nil
- case int16:
- return int32(s), nil
- case int8:
- return int32(s), nil
- case uint:
- return int32(s), nil
- case uint64:
- return int32(s), nil
- case uint32:
- return int32(s), nil
- case uint16:
- return int32(s), nil
- case uint8:
- return int32(s), nil
- case float64:
- return int32(s), nil
- case float32:
- return int32(s), nil
- case string:
- v, err := strconv.ParseInt(trimZeroDecimal(s), 0, 0)
- if err == nil {
- return int32(v), nil
- }
- return 0, fmt.Errorf("unable to cast %#v of type %T to int32", i, i)
- case json.Number:
- return ToInt32E(string(s))
- case bool:
- if s {
- return 1, nil
- }
- return 0, nil
- case nil:
- return 0, nil
- default:
- return 0, fmt.Errorf("unable to cast %#v of type %T to int32", i, i)
- }
-}
-
-// ToInt16E casts an interface to an int16 type.
-func ToInt16E(i interface{}) (int16, error) {
- i = indirect(i)
-
- intv, ok := toInt(i)
- if ok {
- return int16(intv), nil
- }
-
- switch s := i.(type) {
- case int64:
- return int16(s), nil
- case int32:
- return int16(s), nil
- case int16:
- return s, nil
- case int8:
- return int16(s), nil
- case uint:
- return int16(s), nil
- case uint64:
- return int16(s), nil
- case uint32:
- return int16(s), nil
- case uint16:
- return int16(s), nil
- case uint8:
- return int16(s), nil
- case float64:
- return int16(s), nil
- case float32:
- return int16(s), nil
- case string:
- v, err := strconv.ParseInt(trimZeroDecimal(s), 0, 0)
- if err == nil {
- return int16(v), nil
- }
- return 0, fmt.Errorf("unable to cast %#v of type %T to int16", i, i)
- case json.Number:
- return ToInt16E(string(s))
- case bool:
- if s {
- return 1, nil
- }
- return 0, nil
- case nil:
- return 0, nil
- default:
- return 0, fmt.Errorf("unable to cast %#v of type %T to int16", i, i)
- }
-}
-
-// ToInt8E casts an interface to an int8 type.
-func ToInt8E(i interface{}) (int8, error) {
- i = indirect(i)
-
- intv, ok := toInt(i)
- if ok {
- return int8(intv), nil
- }
-
- switch s := i.(type) {
- case int64:
- return int8(s), nil
- case int32:
- return int8(s), nil
- case int16:
- return int8(s), nil
- case int8:
- return s, nil
- case uint:
- return int8(s), nil
- case uint64:
- return int8(s), nil
- case uint32:
- return int8(s), nil
- case uint16:
- return int8(s), nil
- case uint8:
- return int8(s), nil
- case float64:
- return int8(s), nil
- case float32:
- return int8(s), nil
- case string:
- v, err := strconv.ParseInt(trimZeroDecimal(s), 0, 0)
- if err == nil {
- return int8(v), nil
- }
- return 0, fmt.Errorf("unable to cast %#v of type %T to int8", i, i)
- case json.Number:
- return ToInt8E(string(s))
- case bool:
- if s {
- return 1, nil
- }
- return 0, nil
- case nil:
- return 0, nil
- default:
- return 0, fmt.Errorf("unable to cast %#v of type %T to int8", i, i)
- }
-}
-
-// ToIntE casts an interface to an int type.
-func ToIntE(i interface{}) (int, error) {
- i = indirect(i)
-
- intv, ok := toInt(i)
- if ok {
- return intv, nil
- }
-
- switch s := i.(type) {
- case int64:
- return int(s), nil
- case int32:
- return int(s), nil
- case int16:
- return int(s), nil
- case int8:
- return int(s), nil
- case uint:
- return int(s), nil
- case uint64:
- return int(s), nil
- case uint32:
- return int(s), nil
- case uint16:
- return int(s), nil
- case uint8:
- return int(s), nil
- case float64:
- return int(s), nil
- case float32:
- return int(s), nil
- case string:
- v, err := strconv.ParseInt(trimZeroDecimal(s), 0, 0)
- if err == nil {
- return int(v), nil
- }
- return 0, fmt.Errorf("unable to cast %#v of type %T to int64", i, i)
- case json.Number:
- return ToIntE(string(s))
- case bool:
- if s {
- return 1, nil
- }
- return 0, nil
- case nil:
- return 0, nil
- default:
- return 0, fmt.Errorf("unable to cast %#v of type %T to int", i, i)
- }
-}
-
-// ToUintE casts an interface to a uint type.
-func ToUintE(i interface{}) (uint, error) {
- i = indirect(i)
-
- intv, ok := toInt(i)
- if ok {
- if intv < 0 {
- return 0, errNegativeNotAllowed
- }
- return uint(intv), nil
- }
-
- switch s := i.(type) {
- case string:
- v, err := strconv.ParseInt(trimZeroDecimal(s), 0, 0)
- if err == nil {
- if v < 0 {
- return 0, errNegativeNotAllowed
- }
- return uint(v), nil
- }
- return 0, fmt.Errorf("unable to cast %#v of type %T to uint", i, i)
- case json.Number:
- return ToUintE(string(s))
- case int64:
- if s < 0 {
- return 0, errNegativeNotAllowed
- }
- return uint(s), nil
- case int32:
- if s < 0 {
- return 0, errNegativeNotAllowed
- }
- return uint(s), nil
- case int16:
- if s < 0 {
- return 0, errNegativeNotAllowed
- }
- return uint(s), nil
- case int8:
- if s < 0 {
- return 0, errNegativeNotAllowed
- }
- return uint(s), nil
- case uint:
- return s, nil
- case uint64:
- return uint(s), nil
- case uint32:
- return uint(s), nil
- case uint16:
- return uint(s), nil
- case uint8:
- return uint(s), nil
- case float64:
- if s < 0 {
- return 0, errNegativeNotAllowed
- }
- return uint(s), nil
- case float32:
- if s < 0 {
- return 0, errNegativeNotAllowed
- }
- return uint(s), nil
- case bool:
- if s {
- return 1, nil
- }
- return 0, nil
- case nil:
- return 0, nil
- default:
- return 0, fmt.Errorf("unable to cast %#v of type %T to uint", i, i)
- }
-}
-
-// ToUint64E casts an interface to a uint64 type.
-func ToUint64E(i interface{}) (uint64, error) {
- i = indirect(i)
-
- intv, ok := toInt(i)
- if ok {
- if intv < 0 {
- return 0, errNegativeNotAllowed
- }
- return uint64(intv), nil
- }
-
- switch s := i.(type) {
- case string:
- v, err := strconv.ParseInt(trimZeroDecimal(s), 0, 0)
- if err == nil {
- if v < 0 {
- return 0, errNegativeNotAllowed
- }
- return uint64(v), nil
- }
- return 0, fmt.Errorf("unable to cast %#v of type %T to uint64", i, i)
- case json.Number:
- return ToUint64E(string(s))
- case int64:
- if s < 0 {
- return 0, errNegativeNotAllowed
- }
- return uint64(s), nil
- case int32:
- if s < 0 {
- return 0, errNegativeNotAllowed
- }
- return uint64(s), nil
- case int16:
- if s < 0 {
- return 0, errNegativeNotAllowed
- }
- return uint64(s), nil
- case int8:
- if s < 0 {
- return 0, errNegativeNotAllowed
- }
- return uint64(s), nil
- case uint:
- return uint64(s), nil
- case uint64:
- return s, nil
- case uint32:
- return uint64(s), nil
- case uint16:
- return uint64(s), nil
- case uint8:
- return uint64(s), nil
- case float32:
- if s < 0 {
- return 0, errNegativeNotAllowed
- }
- return uint64(s), nil
- case float64:
- if s < 0 {
- return 0, errNegativeNotAllowed
- }
- return uint64(s), nil
- case bool:
- if s {
- return 1, nil
- }
- return 0, nil
- case nil:
- return 0, nil
- default:
- return 0, fmt.Errorf("unable to cast %#v of type %T to uint64", i, i)
- }
-}
-
-// ToUint32E casts an interface to a uint32 type.
-func ToUint32E(i interface{}) (uint32, error) {
- i = indirect(i)
-
- intv, ok := toInt(i)
- if ok {
- if intv < 0 {
- return 0, errNegativeNotAllowed
- }
- return uint32(intv), nil
- }
-
- switch s := i.(type) {
- case string:
- v, err := strconv.ParseInt(trimZeroDecimal(s), 0, 0)
- if err == nil {
- if v < 0 {
- return 0, errNegativeNotAllowed
- }
- return uint32(v), nil
- }
- return 0, fmt.Errorf("unable to cast %#v of type %T to uint32", i, i)
- case json.Number:
- return ToUint32E(string(s))
- case int64:
- if s < 0 {
- return 0, errNegativeNotAllowed
- }
- return uint32(s), nil
- case int32:
- if s < 0 {
- return 0, errNegativeNotAllowed
- }
- return uint32(s), nil
- case int16:
- if s < 0 {
- return 0, errNegativeNotAllowed
- }
- return uint32(s), nil
- case int8:
- if s < 0 {
- return 0, errNegativeNotAllowed
- }
- return uint32(s), nil
- case uint:
- return uint32(s), nil
- case uint64:
- return uint32(s), nil
- case uint32:
- return s, nil
- case uint16:
- return uint32(s), nil
- case uint8:
- return uint32(s), nil
- case float64:
- if s < 0 {
- return 0, errNegativeNotAllowed
- }
- return uint32(s), nil
- case float32:
- if s < 0 {
- return 0, errNegativeNotAllowed
- }
- return uint32(s), nil
- case bool:
- if s {
- return 1, nil
- }
- return 0, nil
- case nil:
- return 0, nil
- default:
- return 0, fmt.Errorf("unable to cast %#v of type %T to uint32", i, i)
- }
-}
-
-// ToUint16E casts an interface to a uint16 type.
-func ToUint16E(i interface{}) (uint16, error) {
- i = indirect(i)
-
- intv, ok := toInt(i)
- if ok {
- if intv < 0 {
- return 0, errNegativeNotAllowed
- }
- return uint16(intv), nil
- }
-
- switch s := i.(type) {
- case string:
- v, err := strconv.ParseInt(trimZeroDecimal(s), 0, 0)
- if err == nil {
- if v < 0 {
- return 0, errNegativeNotAllowed
- }
- return uint16(v), nil
- }
- return 0, fmt.Errorf("unable to cast %#v of type %T to uint16", i, i)
- case json.Number:
- return ToUint16E(string(s))
- case int64:
- if s < 0 {
- return 0, errNegativeNotAllowed
- }
- return uint16(s), nil
- case int32:
- if s < 0 {
- return 0, errNegativeNotAllowed
- }
- return uint16(s), nil
- case int16:
- if s < 0 {
- return 0, errNegativeNotAllowed
- }
- return uint16(s), nil
- case int8:
- if s < 0 {
- return 0, errNegativeNotAllowed
- }
- return uint16(s), nil
- case uint:
- return uint16(s), nil
- case uint64:
- return uint16(s), nil
- case uint32:
- return uint16(s), nil
- case uint16:
- return s, nil
- case uint8:
- return uint16(s), nil
- case float64:
- if s < 0 {
- return 0, errNegativeNotAllowed
- }
- return uint16(s), nil
- case float32:
- if s < 0 {
- return 0, errNegativeNotAllowed
- }
- return uint16(s), nil
- case bool:
- if s {
- return 1, nil
- }
- return 0, nil
- case nil:
- return 0, nil
- default:
- return 0, fmt.Errorf("unable to cast %#v of type %T to uint16", i, i)
- }
-}
-
-// ToUint8E casts an interface to a uint type.
-func ToUint8E(i interface{}) (uint8, error) {
- i = indirect(i)
-
- intv, ok := toInt(i)
- if ok {
- if intv < 0 {
- return 0, errNegativeNotAllowed
- }
- return uint8(intv), nil
- }
-
- switch s := i.(type) {
- case string:
- v, err := strconv.ParseInt(trimZeroDecimal(s), 0, 0)
- if err == nil {
- if v < 0 {
- return 0, errNegativeNotAllowed
- }
- return uint8(v), nil
- }
- return 0, fmt.Errorf("unable to cast %#v of type %T to uint8", i, i)
- case json.Number:
- return ToUint8E(string(s))
- case int64:
- if s < 0 {
- return 0, errNegativeNotAllowed
- }
- return uint8(s), nil
- case int32:
- if s < 0 {
- return 0, errNegativeNotAllowed
- }
- return uint8(s), nil
- case int16:
- if s < 0 {
- return 0, errNegativeNotAllowed
- }
- return uint8(s), nil
- case int8:
- if s < 0 {
- return 0, errNegativeNotAllowed
- }
- return uint8(s), nil
- case uint:
- return uint8(s), nil
- case uint64:
- return uint8(s), nil
- case uint32:
- return uint8(s), nil
- case uint16:
- return uint8(s), nil
- case uint8:
- return s, nil
- case float64:
- if s < 0 {
- return 0, errNegativeNotAllowed
- }
- return uint8(s), nil
- case float32:
- if s < 0 {
- return 0, errNegativeNotAllowed
- }
- return uint8(s), nil
- case bool:
- if s {
- return 1, nil
- }
- return 0, nil
- case nil:
- return 0, nil
- default:
- return 0, fmt.Errorf("unable to cast %#v of type %T to uint8", i, i)
- }
-}
-
-// From html/template/content.go
-// Copyright 2011 The Go Authors. All rights reserved.
-// indirect returns the value, after dereferencing as many times
-// as necessary to reach the base type (or nil).
-func indirect(a interface{}) interface{} {
- if a == nil {
- return nil
- }
- if t := reflect.TypeOf(a); t.Kind() != reflect.Ptr {
- // Avoid creating a reflect.Value if it's not a pointer.
- return a
- }
- v := reflect.ValueOf(a)
- for v.Kind() == reflect.Ptr && !v.IsNil() {
- v = v.Elem()
- }
- return v.Interface()
-}
-
-// From html/template/content.go
-// Copyright 2011 The Go Authors. All rights reserved.
-// indirectToStringerOrError returns the value, after dereferencing as many times
-// as necessary to reach the base type (or nil) or an implementation of fmt.Stringer
-// or error,
-func indirectToStringerOrError(a interface{}) interface{} {
- if a == nil {
- return nil
- }
-
- var errorType = reflect.TypeOf((*error)(nil)).Elem()
- var fmtStringerType = reflect.TypeOf((*fmt.Stringer)(nil)).Elem()
-
- v := reflect.ValueOf(a)
- for !v.Type().Implements(fmtStringerType) && !v.Type().Implements(errorType) && v.Kind() == reflect.Ptr && !v.IsNil() {
- v = v.Elem()
- }
- return v.Interface()
-}
-
-// ToStringE casts an interface to a string type.
-func ToStringE(i interface{}) (string, error) {
- i = indirectToStringerOrError(i)
-
- switch s := i.(type) {
- case string:
- return s, nil
- case bool:
- return strconv.FormatBool(s), nil
- case float64:
- return strconv.FormatFloat(s, 'f', -1, 64), nil
- case float32:
- return strconv.FormatFloat(float64(s), 'f', -1, 32), nil
- case int:
- return strconv.Itoa(s), nil
- case int64:
- return strconv.FormatInt(s, 10), nil
- case int32:
- return strconv.Itoa(int(s)), nil
- case int16:
- return strconv.FormatInt(int64(s), 10), nil
- case int8:
- return strconv.FormatInt(int64(s), 10), nil
- case uint:
- return strconv.FormatUint(uint64(s), 10), nil
- case uint64:
- return strconv.FormatUint(uint64(s), 10), nil
- case uint32:
- return strconv.FormatUint(uint64(s), 10), nil
- case uint16:
- return strconv.FormatUint(uint64(s), 10), nil
- case uint8:
- return strconv.FormatUint(uint64(s), 10), nil
- case json.Number:
- return s.String(), nil
- case []byte:
- return string(s), nil
- case template.HTML:
- return string(s), nil
- case template.URL:
- return string(s), nil
- case template.JS:
- return string(s), nil
- case template.CSS:
- return string(s), nil
- case template.HTMLAttr:
- return string(s), nil
- case nil:
- return "", nil
- case fmt.Stringer:
- return s.String(), nil
- case error:
- return s.Error(), nil
- default:
- return "", fmt.Errorf("unable to cast %#v of type %T to string", i, i)
- }
-}
-
-// ToStringMapStringE casts an interface to a map[string]string type.
-func ToStringMapStringE(i interface{}) (map[string]string, error) {
- var m = map[string]string{}
-
- switch v := i.(type) {
- case map[string]string:
- return v, nil
- case map[string]interface{}:
- for k, val := range v {
- m[ToString(k)] = ToString(val)
- }
- return m, nil
- case map[interface{}]string:
- for k, val := range v {
- m[ToString(k)] = ToString(val)
- }
- return m, nil
- case map[interface{}]interface{}:
- for k, val := range v {
- m[ToString(k)] = ToString(val)
- }
- return m, nil
- case string:
- err := jsonStringToObject(v, &m)
- return m, err
- default:
- return m, fmt.Errorf("unable to cast %#v of type %T to map[string]string", i, i)
- }
-}
-
-// ToStringMapStringSliceE casts an interface to a map[string][]string type.
-func ToStringMapStringSliceE(i interface{}) (map[string][]string, error) {
- var m = map[string][]string{}
-
- switch v := i.(type) {
- case map[string][]string:
- return v, nil
- case map[string][]interface{}:
- for k, val := range v {
- m[ToString(k)] = ToStringSlice(val)
- }
- return m, nil
- case map[string]string:
- for k, val := range v {
- m[ToString(k)] = []string{val}
- }
- case map[string]interface{}:
- for k, val := range v {
- switch vt := val.(type) {
- case []interface{}:
- m[ToString(k)] = ToStringSlice(vt)
- case []string:
- m[ToString(k)] = vt
- default:
- m[ToString(k)] = []string{ToString(val)}
- }
- }
- return m, nil
- case map[interface{}][]string:
- for k, val := range v {
- m[ToString(k)] = ToStringSlice(val)
- }
- return m, nil
- case map[interface{}]string:
- for k, val := range v {
- m[ToString(k)] = ToStringSlice(val)
- }
- return m, nil
- case map[interface{}][]interface{}:
- for k, val := range v {
- m[ToString(k)] = ToStringSlice(val)
- }
- return m, nil
- case map[interface{}]interface{}:
- for k, val := range v {
- key, err := ToStringE(k)
- if err != nil {
- return m, fmt.Errorf("unable to cast %#v of type %T to map[string][]string", i, i)
- }
- value, err := ToStringSliceE(val)
- if err != nil {
- return m, fmt.Errorf("unable to cast %#v of type %T to map[string][]string", i, i)
- }
- m[key] = value
- }
- case string:
- err := jsonStringToObject(v, &m)
- return m, err
- default:
- return m, fmt.Errorf("unable to cast %#v of type %T to map[string][]string", i, i)
- }
- return m, nil
-}
-
-// ToStringMapBoolE casts an interface to a map[string]bool type.
-func ToStringMapBoolE(i interface{}) (map[string]bool, error) {
- var m = map[string]bool{}
-
- switch v := i.(type) {
- case map[interface{}]interface{}:
- for k, val := range v {
- m[ToString(k)] = ToBool(val)
- }
- return m, nil
- case map[string]interface{}:
- for k, val := range v {
- m[ToString(k)] = ToBool(val)
- }
- return m, nil
- case map[string]bool:
- return v, nil
- case string:
- err := jsonStringToObject(v, &m)
- return m, err
- default:
- return m, fmt.Errorf("unable to cast %#v of type %T to map[string]bool", i, i)
- }
-}
-
-// ToStringMapE casts an interface to a map[string]interface{} type.
-func ToStringMapE(i interface{}) (map[string]interface{}, error) {
- var m = map[string]interface{}{}
-
- switch v := i.(type) {
- case map[interface{}]interface{}:
- for k, val := range v {
- m[ToString(k)] = val
- }
- return m, nil
- case map[string]interface{}:
- return v, nil
- case string:
- err := jsonStringToObject(v, &m)
- return m, err
- default:
- return m, fmt.Errorf("unable to cast %#v of type %T to map[string]interface{}", i, i)
- }
-}
-
-// ToStringMapIntE casts an interface to a map[string]int{} type.
-func ToStringMapIntE(i interface{}) (map[string]int, error) {
- var m = map[string]int{}
- if i == nil {
- return m, fmt.Errorf("unable to cast %#v of type %T to map[string]int", i, i)
- }
-
- switch v := i.(type) {
- case map[interface{}]interface{}:
- for k, val := range v {
- m[ToString(k)] = ToInt(val)
- }
- return m, nil
- case map[string]interface{}:
- for k, val := range v {
- m[k] = ToInt(val)
- }
- return m, nil
- case map[string]int:
- return v, nil
- case string:
- err := jsonStringToObject(v, &m)
- return m, err
- }
-
- if reflect.TypeOf(i).Kind() != reflect.Map {
- return m, fmt.Errorf("unable to cast %#v of type %T to map[string]int", i, i)
- }
-
- mVal := reflect.ValueOf(m)
- v := reflect.ValueOf(i)
- for _, keyVal := range v.MapKeys() {
- val, err := ToIntE(v.MapIndex(keyVal).Interface())
- if err != nil {
- return m, fmt.Errorf("unable to cast %#v of type %T to map[string]int", i, i)
- }
- mVal.SetMapIndex(keyVal, reflect.ValueOf(val))
- }
- return m, nil
-}
-
-// ToStringMapInt64E casts an interface to a map[string]int64{} type.
-func ToStringMapInt64E(i interface{}) (map[string]int64, error) {
- var m = map[string]int64{}
- if i == nil {
- return m, fmt.Errorf("unable to cast %#v of type %T to map[string]int64", i, i)
- }
-
- switch v := i.(type) {
- case map[interface{}]interface{}:
- for k, val := range v {
- m[ToString(k)] = ToInt64(val)
- }
- return m, nil
- case map[string]interface{}:
- for k, val := range v {
- m[k] = ToInt64(val)
- }
- return m, nil
- case map[string]int64:
- return v, nil
- case string:
- err := jsonStringToObject(v, &m)
- return m, err
- }
-
- if reflect.TypeOf(i).Kind() != reflect.Map {
- return m, fmt.Errorf("unable to cast %#v of type %T to map[string]int64", i, i)
- }
- mVal := reflect.ValueOf(m)
- v := reflect.ValueOf(i)
- for _, keyVal := range v.MapKeys() {
- val, err := ToInt64E(v.MapIndex(keyVal).Interface())
- if err != nil {
- return m, fmt.Errorf("unable to cast %#v of type %T to map[string]int64", i, i)
- }
- mVal.SetMapIndex(keyVal, reflect.ValueOf(val))
- }
- return m, nil
-}
-
-// ToSliceE casts an interface to a []interface{} type.
-func ToSliceE(i interface{}) ([]interface{}, error) {
- var s []interface{}
-
- switch v := i.(type) {
- case []interface{}:
- return append(s, v...), nil
- case []map[string]interface{}:
- for _, u := range v {
- s = append(s, u)
- }
- return s, nil
- default:
- return s, fmt.Errorf("unable to cast %#v of type %T to []interface{}", i, i)
- }
-}
-
-// ToBoolSliceE casts an interface to a []bool type.
-func ToBoolSliceE(i interface{}) ([]bool, error) {
- if i == nil {
- return []bool{}, fmt.Errorf("unable to cast %#v of type %T to []bool", i, i)
- }
-
- switch v := i.(type) {
- case []bool:
- return v, nil
- }
-
- kind := reflect.TypeOf(i).Kind()
- switch kind {
- case reflect.Slice, reflect.Array:
- s := reflect.ValueOf(i)
- a := make([]bool, s.Len())
- for j := 0; j < s.Len(); j++ {
- val, err := ToBoolE(s.Index(j).Interface())
- if err != nil {
- return []bool{}, fmt.Errorf("unable to cast %#v of type %T to []bool", i, i)
- }
- a[j] = val
- }
- return a, nil
- default:
- return []bool{}, fmt.Errorf("unable to cast %#v of type %T to []bool", i, i)
- }
-}
-
-// ToStringSliceE casts an interface to a []string type.
-func ToStringSliceE(i interface{}) ([]string, error) {
- var a []string
-
- switch v := i.(type) {
- case []interface{}:
- for _, u := range v {
- a = append(a, ToString(u))
- }
- return a, nil
- case []string:
- return v, nil
- case []int8:
- for _, u := range v {
- a = append(a, ToString(u))
- }
- return a, nil
- case []int:
- for _, u := range v {
- a = append(a, ToString(u))
- }
- return a, nil
- case []int32:
- for _, u := range v {
- a = append(a, ToString(u))
- }
- return a, nil
- case []int64:
- for _, u := range v {
- a = append(a, ToString(u))
- }
- return a, nil
- case []float32:
- for _, u := range v {
- a = append(a, ToString(u))
- }
- return a, nil
- case []float64:
- for _, u := range v {
- a = append(a, ToString(u))
- }
- return a, nil
- case string:
- return strings.Fields(v), nil
- case []error:
- for _, err := range i.([]error) {
- a = append(a, err.Error())
- }
- return a, nil
- case interface{}:
- str, err := ToStringE(v)
- if err != nil {
- return a, fmt.Errorf("unable to cast %#v of type %T to []string", i, i)
- }
- return []string{str}, nil
- default:
- return a, fmt.Errorf("unable to cast %#v of type %T to []string", i, i)
- }
-}
-
-// ToIntSliceE casts an interface to a []int type.
-func ToIntSliceE(i interface{}) ([]int, error) {
- if i == nil {
- return []int{}, fmt.Errorf("unable to cast %#v of type %T to []int", i, i)
- }
-
- switch v := i.(type) {
- case []int:
- return v, nil
- }
-
- kind := reflect.TypeOf(i).Kind()
- switch kind {
- case reflect.Slice, reflect.Array:
- s := reflect.ValueOf(i)
- a := make([]int, s.Len())
- for j := 0; j < s.Len(); j++ {
- val, err := ToIntE(s.Index(j).Interface())
- if err != nil {
- return []int{}, fmt.Errorf("unable to cast %#v of type %T to []int", i, i)
- }
- a[j] = val
- }
- return a, nil
- default:
- return []int{}, fmt.Errorf("unable to cast %#v of type %T to []int", i, i)
- }
-}
-
-// ToDurationSliceE casts an interface to a []time.Duration type.
-func ToDurationSliceE(i interface{}) ([]time.Duration, error) {
- if i == nil {
- return []time.Duration{}, fmt.Errorf("unable to cast %#v of type %T to []time.Duration", i, i)
- }
-
- switch v := i.(type) {
- case []time.Duration:
- return v, nil
- }
-
- kind := reflect.TypeOf(i).Kind()
- switch kind {
- case reflect.Slice, reflect.Array:
- s := reflect.ValueOf(i)
- a := make([]time.Duration, s.Len())
- for j := 0; j < s.Len(); j++ {
- val, err := ToDurationE(s.Index(j).Interface())
- if err != nil {
- return []time.Duration{}, fmt.Errorf("unable to cast %#v of type %T to []time.Duration", i, i)
- }
- a[j] = val
- }
- return a, nil
- default:
- return []time.Duration{}, fmt.Errorf("unable to cast %#v of type %T to []time.Duration", i, i)
- }
-}
-
-// StringToDate attempts to parse a string into a time.Time type using a
-// predefined list of formats. If no suitable format is found, an error is
-// returned.
-func StringToDate(s string) (time.Time, error) {
- return parseDateWith(s, time.UTC, timeFormats)
-}
-
-// StringToDateInDefaultLocation casts an empty interface to a time.Time,
-// interpreting inputs without a timezone to be in the given location,
-// or the local timezone if nil.
-func StringToDateInDefaultLocation(s string, location *time.Location) (time.Time, error) {
- return parseDateWith(s, location, timeFormats)
-}
-
-type timeFormatType int
-
-const (
- timeFormatNoTimezone timeFormatType = iota
- timeFormatNamedTimezone
- timeFormatNumericTimezone
- timeFormatNumericAndNamedTimezone
- timeFormatTimeOnly
-)
-
-type timeFormat struct {
- format string
- typ timeFormatType
-}
-
-func (f timeFormat) hasTimezone() bool {
- // We don't include the formats with only named timezones, see
- // https://github.com/golang/go/issues/19694#issuecomment-289103522
- return f.typ >= timeFormatNumericTimezone && f.typ <= timeFormatNumericAndNamedTimezone
-}
-
-var (
- timeFormats = []timeFormat{
- {time.RFC3339, timeFormatNumericTimezone},
- {"2006-01-02T15:04:05", timeFormatNoTimezone}, // iso8601 without timezone
- {time.RFC1123Z, timeFormatNumericTimezone},
- {time.RFC1123, timeFormatNamedTimezone},
- {time.RFC822Z, timeFormatNumericTimezone},
- {time.RFC822, timeFormatNamedTimezone},
- {time.RFC850, timeFormatNamedTimezone},
- {"2006-01-02 15:04:05.999999999 -0700 MST", timeFormatNumericAndNamedTimezone}, // Time.String()
- {"2006-01-02T15:04:05-0700", timeFormatNumericTimezone}, // RFC3339 without timezone hh:mm colon
- {"2006-01-02 15:04:05Z0700", timeFormatNumericTimezone}, // RFC3339 without T or timezone hh:mm colon
- {"2006-01-02 15:04:05", timeFormatNoTimezone},
- {time.ANSIC, timeFormatNoTimezone},
- {time.UnixDate, timeFormatNamedTimezone},
- {time.RubyDate, timeFormatNumericTimezone},
- {"2006-01-02 15:04:05Z07:00", timeFormatNumericTimezone},
- {"2006-01-02", timeFormatNoTimezone},
- {"02 Jan 2006", timeFormatNoTimezone},
- {"2006-01-02 15:04:05 -07:00", timeFormatNumericTimezone},
- {"2006-01-02 15:04:05 -0700", timeFormatNumericTimezone},
- {time.Kitchen, timeFormatTimeOnly},
- {time.Stamp, timeFormatTimeOnly},
- {time.StampMilli, timeFormatTimeOnly},
- {time.StampMicro, timeFormatTimeOnly},
- {time.StampNano, timeFormatTimeOnly},
- }
-)
-
-func parseDateWith(s string, location *time.Location, formats []timeFormat) (d time.Time, e error) {
-
- for _, format := range formats {
- if d, e = time.Parse(format.format, s); e == nil {
-
- // Some time formats have a zone name, but no offset, so it gets
- // put in that zone name (not the default one passed in to us), but
- // without that zone's offset. So set the location manually.
- if format.typ <= timeFormatNamedTimezone {
- if location == nil {
- location = time.Local
- }
- year, month, day := d.Date()
- hour, min, sec := d.Clock()
- d = time.Date(year, month, day, hour, min, sec, d.Nanosecond(), location)
- }
-
- return
- }
- }
- return d, fmt.Errorf("unable to parse date: %s", s)
-}
-
-// jsonStringToObject attempts to unmarshall a string as JSON into
-// the object passed as pointer.
-func jsonStringToObject(s string, v interface{}) error {
- data := []byte(s)
- return json.Unmarshal(data, v)
-}
-
-// toInt returns the int value of v if v or v's underlying type
-// is an int.
-// Note that this will return false for int64 etc. types.
-func toInt(v interface{}) (int, bool) {
- switch v := v.(type) {
- case int:
- return v, true
- case time.Weekday:
- return int(v), true
- case time.Month:
- return int(v), true
- default:
- return 0, false
- }
-}
-
-func trimZeroDecimal(s string) string {
- var foundZero bool
- for i := len(s); i > 0; i-- {
- switch s[i-1] {
- case '.':
- if foundZero {
- return s[:i-1]
- }
- case '0':
- foundZero = true
- default:
- return s
- }
- }
- return s
-}
diff --git a/vendor/github.com/spf13/cast/indirect.go b/vendor/github.com/spf13/cast/indirect.go
new file mode 100644
index 000000000..093345f73
--- /dev/null
+++ b/vendor/github.com/spf13/cast/indirect.go
@@ -0,0 +1,37 @@
+// Copyright © 2014 Steve Francia .
+//
+// Use of this source code is governed by an MIT-style
+// license that can be found in the LICENSE file.
+
+package cast
+
+import (
+ "reflect"
+)
+
+// From html/template/content.go
+// Copyright 2011 The Go Authors. All rights reserved.
+// indirect returns the value, after dereferencing as many times
+// as necessary to reach the base type (or nil).
+func indirect(i any) (any, bool) {
+ if i == nil {
+ return nil, false
+ }
+
+ if t := reflect.TypeOf(i); t.Kind() != reflect.Ptr {
+ // Avoid creating a reflect.Value if it's not a pointer.
+ return i, false
+ }
+
+ v := reflect.ValueOf(i)
+
+ for v.Kind() == reflect.Ptr || (v.Kind() == reflect.Interface && v.Elem().Kind() == reflect.Ptr) {
+ if v.IsNil() {
+ return nil, true
+ }
+
+ v = v.Elem()
+ }
+
+ return v.Interface(), true
+}
diff --git a/vendor/github.com/spf13/cast/internal/time.go b/vendor/github.com/spf13/cast/internal/time.go
new file mode 100644
index 000000000..906e9aece
--- /dev/null
+++ b/vendor/github.com/spf13/cast/internal/time.go
@@ -0,0 +1,79 @@
+package internal
+
+import (
+ "fmt"
+ "time"
+)
+
+//go:generate stringer -type=TimeFormatType
+
+type TimeFormatType int
+
+const (
+ TimeFormatNoTimezone TimeFormatType = iota
+ TimeFormatNamedTimezone
+ TimeFormatNumericTimezone
+ TimeFormatNumericAndNamedTimezone
+ TimeFormatTimeOnly
+)
+
+type TimeFormat struct {
+ Format string
+ Typ TimeFormatType
+}
+
+func (f TimeFormat) HasTimezone() bool {
+ // We don't include the formats with only named timezones, see
+ // https://github.com/golang/go/issues/19694#issuecomment-289103522
+ return f.Typ >= TimeFormatNumericTimezone && f.Typ <= TimeFormatNumericAndNamedTimezone
+}
+
+var TimeFormats = []TimeFormat{
+ // Keep common formats at the top.
+ {"2006-01-02", TimeFormatNoTimezone},
+ {time.RFC3339, TimeFormatNumericTimezone},
+ {"2006-01-02T15:04:05", TimeFormatNoTimezone}, // iso8601 without timezone
+ {time.RFC1123Z, TimeFormatNumericTimezone},
+ {time.RFC1123, TimeFormatNamedTimezone},
+ {time.RFC822Z, TimeFormatNumericTimezone},
+ {time.RFC822, TimeFormatNamedTimezone},
+ {time.RFC850, TimeFormatNamedTimezone},
+ {"2006-01-02 15:04:05.999999999 -0700 MST", TimeFormatNumericAndNamedTimezone}, // Time.String()
+ {"2006-01-02T15:04:05-0700", TimeFormatNumericTimezone}, // RFC3339 without timezone hh:mm colon
+ {"2006-01-02 15:04:05Z0700", TimeFormatNumericTimezone}, // RFC3339 without T or timezone hh:mm colon
+ {"2006-01-02 15:04:05", TimeFormatNoTimezone},
+ {time.ANSIC, TimeFormatNoTimezone},
+ {time.UnixDate, TimeFormatNamedTimezone},
+ {time.RubyDate, TimeFormatNumericTimezone},
+ {"2006-01-02 15:04:05Z07:00", TimeFormatNumericTimezone},
+ {"02 Jan 2006", TimeFormatNoTimezone},
+ {"2006-01-02 15:04:05 -07:00", TimeFormatNumericTimezone},
+ {"2006-01-02 15:04:05 -0700", TimeFormatNumericTimezone},
+ {time.Kitchen, TimeFormatTimeOnly},
+ {time.Stamp, TimeFormatTimeOnly},
+ {time.StampMilli, TimeFormatTimeOnly},
+ {time.StampMicro, TimeFormatTimeOnly},
+ {time.StampNano, TimeFormatTimeOnly},
+}
+
+func ParseDateWith(s string, location *time.Location, formats []TimeFormat) (d time.Time, e error) {
+ for _, format := range formats {
+ if d, e = time.Parse(format.Format, s); e == nil {
+
+ // Some time formats have a zone name, but no offset, so it gets
+ // put in that zone name (not the default one passed in to us), but
+ // without that zone's offset. So set the location manually.
+ if format.Typ <= TimeFormatNamedTimezone {
+ if location == nil {
+ location = time.Local
+ }
+ year, month, day := d.Date()
+ hour, min, sec := d.Clock()
+ d = time.Date(year, month, day, hour, min, sec, d.Nanosecond(), location)
+ }
+
+ return
+ }
+ }
+ return d, fmt.Errorf("unable to parse date: %s", s)
+}
diff --git a/vendor/github.com/spf13/cast/internal/timeformattype_string.go b/vendor/github.com/spf13/cast/internal/timeformattype_string.go
new file mode 100644
index 000000000..60a29a862
--- /dev/null
+++ b/vendor/github.com/spf13/cast/internal/timeformattype_string.go
@@ -0,0 +1,27 @@
+// Code generated by "stringer -type=TimeFormatType"; DO NOT EDIT.
+
+package internal
+
+import "strconv"
+
+func _() {
+ // An "invalid array index" compiler error signifies that the constant values have changed.
+ // Re-run the stringer command to generate them again.
+ var x [1]struct{}
+ _ = x[TimeFormatNoTimezone-0]
+ _ = x[TimeFormatNamedTimezone-1]
+ _ = x[TimeFormatNumericTimezone-2]
+ _ = x[TimeFormatNumericAndNamedTimezone-3]
+ _ = x[TimeFormatTimeOnly-4]
+}
+
+const _TimeFormatType_name = "TimeFormatNoTimezoneTimeFormatNamedTimezoneTimeFormatNumericTimezoneTimeFormatNumericAndNamedTimezoneTimeFormatTimeOnly"
+
+var _TimeFormatType_index = [...]uint8{0, 20, 43, 68, 101, 119}
+
+func (i TimeFormatType) String() string {
+ if i < 0 || i >= TimeFormatType(len(_TimeFormatType_index)-1) {
+ return "TimeFormatType(" + strconv.FormatInt(int64(i), 10) + ")"
+ }
+ return _TimeFormatType_name[_TimeFormatType_index[i]:_TimeFormatType_index[i+1]]
+}
diff --git a/vendor/github.com/spf13/cast/map.go b/vendor/github.com/spf13/cast/map.go
new file mode 100644
index 000000000..858d4ee43
--- /dev/null
+++ b/vendor/github.com/spf13/cast/map.go
@@ -0,0 +1,212 @@
+// Copyright © 2014 Steve Francia .
+//
+// Use of this source code is governed by an MIT-style
+// license that can be found in the LICENSE file.
+
+package cast
+
+import (
+ "encoding/json"
+ "fmt"
+ "reflect"
+)
+
+func toMapE[K comparable, V any](i any, keyFn func(any) K, valFn func(any) V) (map[K]V, error) {
+ m := map[K]V{}
+
+ if i == nil {
+ return m, fmt.Errorf(errorMsg, i, i, m)
+ }
+
+ switch v := i.(type) {
+ case map[K]V:
+ return v, nil
+
+ case map[K]any:
+ for k, val := range v {
+ m[k] = valFn(val)
+ }
+
+ return m, nil
+
+ case map[any]V:
+ for k, val := range v {
+ m[keyFn(k)] = val
+ }
+
+ return m, nil
+
+ case map[any]any:
+ for k, val := range v {
+ m[keyFn(k)] = valFn(val)
+ }
+
+ return m, nil
+
+ case string:
+ err := jsonStringToObject(v, &m)
+ return m, err
+
+ default:
+ return m, fmt.Errorf(errorMsg, i, i, m)
+ }
+}
+
+func toStringMapE[T any](i any, fn func(any) T) (map[string]T, error) {
+ return toMapE(i, ToString, fn)
+}
+
+// ToStringMapStringE casts any value to a map[string]string type.
+func ToStringMapStringE(i any) (map[string]string, error) {
+ return toStringMapE(i, ToString)
+}
+
+// ToStringMapStringSliceE casts any value to a map[string][]string type.
+func ToStringMapStringSliceE(i any) (map[string][]string, error) {
+ m := map[string][]string{}
+
+ switch v := i.(type) {
+ case map[string][]string:
+ return v, nil
+ case map[string][]any:
+ for k, val := range v {
+ m[ToString(k)] = ToStringSlice(val)
+ }
+ return m, nil
+ case map[string]string:
+ for k, val := range v {
+ m[ToString(k)] = []string{val}
+ }
+ case map[string]any:
+ for k, val := range v {
+ switch vt := val.(type) {
+ case []any:
+ m[ToString(k)] = ToStringSlice(vt)
+ case []string:
+ m[ToString(k)] = vt
+ default:
+ m[ToString(k)] = []string{ToString(val)}
+ }
+ }
+ return m, nil
+ case map[any][]string:
+ for k, val := range v {
+ m[ToString(k)] = ToStringSlice(val)
+ }
+ return m, nil
+ case map[any]string:
+ for k, val := range v {
+ m[ToString(k)] = ToStringSlice(val)
+ }
+ return m, nil
+ case map[any][]any:
+ for k, val := range v {
+ m[ToString(k)] = ToStringSlice(val)
+ }
+ return m, nil
+ case map[any]any:
+ for k, val := range v {
+ key, err := ToStringE(k)
+ if err != nil {
+ return m, fmt.Errorf(errorMsg, i, i, m)
+ }
+ value, err := ToStringSliceE(val)
+ if err != nil {
+ return m, fmt.Errorf(errorMsg, i, i, m)
+ }
+ m[key] = value
+ }
+ case string:
+ err := jsonStringToObject(v, &m)
+ return m, err
+ default:
+ return m, fmt.Errorf(errorMsg, i, i, m)
+ }
+
+ return m, nil
+}
+
+// ToStringMapBoolE casts any value to a map[string]bool type.
+func ToStringMapBoolE(i any) (map[string]bool, error) {
+ return toStringMapE(i, ToBool)
+}
+
+// ToStringMapE casts any value to a map[string]any type.
+func ToStringMapE(i any) (map[string]any, error) {
+ fn := func(i any) any { return i }
+
+ return toStringMapE(i, fn)
+}
+
+func toStringMapIntE[T int | int64](i any, fn func(any) T, fnE func(any) (T, error)) (map[string]T, error) {
+ m := map[string]T{}
+
+ if i == nil {
+ return nil, fmt.Errorf(errorMsg, i, i, m)
+ }
+
+ switch v := i.(type) {
+ case map[string]T:
+ return v, nil
+
+ case map[string]any:
+ for k, val := range v {
+ m[k] = fn(val)
+ }
+
+ return m, nil
+
+ case map[any]T:
+ for k, val := range v {
+ m[ToString(k)] = val
+ }
+
+ return m, nil
+
+ case map[any]any:
+ for k, val := range v {
+ m[ToString(k)] = fn(val)
+ }
+
+ return m, nil
+
+ case string:
+ err := jsonStringToObject(v, &m)
+ return m, err
+ }
+
+ if reflect.TypeOf(i).Kind() != reflect.Map {
+ return m, fmt.Errorf(errorMsg, i, i, m)
+ }
+
+ mVal := reflect.ValueOf(m)
+ v := reflect.ValueOf(i)
+
+ for _, keyVal := range v.MapKeys() {
+ val, err := fnE(v.MapIndex(keyVal).Interface())
+ if err != nil {
+ return m, fmt.Errorf(errorMsg, i, i, m)
+ }
+
+ mVal.SetMapIndex(keyVal, reflect.ValueOf(val))
+ }
+
+ return m, nil
+}
+
+// ToStringMapIntE casts any value to a map[string]int type.
+func ToStringMapIntE(i any) (map[string]int, error) {
+ return toStringMapIntE(i, ToInt, ToIntE)
+}
+
+// ToStringMapInt64E casts any value to a map[string]int64 type.
+func ToStringMapInt64E(i any) (map[string]int64, error) {
+ return toStringMapIntE(i, ToInt64, ToInt64E)
+}
+
+// jsonStringToObject attempts to unmarshall a string as JSON into
+// the object passed as pointer.
+func jsonStringToObject(s string, v any) error {
+ data := []byte(s)
+ return json.Unmarshal(data, v)
+}
diff --git a/vendor/github.com/spf13/cast/number.go b/vendor/github.com/spf13/cast/number.go
new file mode 100644
index 000000000..a58dc4d1e
--- /dev/null
+++ b/vendor/github.com/spf13/cast/number.go
@@ -0,0 +1,549 @@
+// Copyright © 2014 Steve Francia .
+//
+// Use of this source code is governed by an MIT-style
+// license that can be found in the LICENSE file.
+
+package cast
+
+import (
+ "encoding/json"
+ "errors"
+ "fmt"
+ "regexp"
+ "strconv"
+ "strings"
+ "time"
+)
+
+var errNegativeNotAllowed = errors.New("unable to cast negative value")
+
+type float64EProvider interface {
+ Float64() (float64, error)
+}
+
+type float64Provider interface {
+ Float64() float64
+}
+
+// Number is a type parameter constraint for functions accepting number types.
+//
+// It represents the supported number types this package can cast to.
+type Number interface {
+ int | int8 | int16 | int32 | int64 | uint | uint8 | uint16 | uint32 | uint64 | float32 | float64
+}
+
+type integer interface {
+ int | int8 | int16 | int32 | int64
+}
+
+type unsigned interface {
+ uint | uint8 | uint16 | uint32 | uint64
+}
+
+type float interface {
+ float32 | float64
+}
+
+// ToNumberE casts any value to a [Number] type.
+func ToNumberE[T Number](i any) (T, error) {
+ var t T
+
+ switch any(t).(type) {
+ case int:
+ return toNumberE[T](i, parseNumber[T])
+ case int8:
+ return toNumberE[T](i, parseNumber[T])
+ case int16:
+ return toNumberE[T](i, parseNumber[T])
+ case int32:
+ return toNumberE[T](i, parseNumber[T])
+ case int64:
+ return toNumberE[T](i, parseNumber[T])
+ case uint:
+ return toUnsignedNumberE[T](i, parseNumber[T])
+ case uint8:
+ return toUnsignedNumberE[T](i, parseNumber[T])
+ case uint16:
+ return toUnsignedNumberE[T](i, parseNumber[T])
+ case uint32:
+ return toUnsignedNumberE[T](i, parseNumber[T])
+ case uint64:
+ return toUnsignedNumberE[T](i, parseNumber[T])
+ case float32:
+ return toNumberE[T](i, parseNumber[T])
+ case float64:
+ return toNumberE[T](i, parseNumber[T])
+ default:
+ return 0, fmt.Errorf("unknown number type: %T", t)
+ }
+}
+
+// ToNumber casts any value to a [Number] type.
+func ToNumber[T Number](i any) T {
+ v, _ := ToNumberE[T](i)
+
+ return v
+}
+
+// toNumber's semantics differ from other "to" functions.
+// It returns false as the second parameter if the conversion fails.
+// This is to signal other callers that they should proceed with their own conversions.
+func toNumber[T Number](i any) (T, bool) {
+ i, _ = indirect(i)
+
+ switch s := i.(type) {
+ case T:
+ return s, true
+ case int:
+ return T(s), true
+ case int8:
+ return T(s), true
+ case int16:
+ return T(s), true
+ case int32:
+ return T(s), true
+ case int64:
+ return T(s), true
+ case uint:
+ return T(s), true
+ case uint8:
+ return T(s), true
+ case uint16:
+ return T(s), true
+ case uint32:
+ return T(s), true
+ case uint64:
+ return T(s), true
+ case float32:
+ return T(s), true
+ case float64:
+ return T(s), true
+ case bool:
+ if s {
+ return 1, true
+ }
+
+ return 0, true
+ case nil:
+ return 0, true
+ case time.Weekday:
+ return T(s), true
+ case time.Month:
+ return T(s), true
+ }
+
+ return 0, false
+}
+
+func toNumberE[T Number](i any, parseFn func(string) (T, error)) (T, error) {
+ n, ok := toNumber[T](i)
+ if ok {
+ return n, nil
+ }
+
+ i, _ = indirect(i)
+
+ switch s := i.(type) {
+ case string:
+ if s == "" {
+ return 0, nil
+ }
+
+ v, err := parseFn(s)
+ if err != nil {
+ return 0, fmt.Errorf(errorMsgWith, i, i, n, err)
+ }
+
+ return v, nil
+ case json.Number:
+ if s == "" {
+ return 0, nil
+ }
+
+ v, err := parseFn(string(s))
+ if err != nil {
+ return 0, fmt.Errorf(errorMsgWith, i, i, n, err)
+ }
+
+ return v, nil
+ case float64EProvider:
+ if _, ok := any(n).(float64); !ok {
+ return 0, fmt.Errorf(errorMsg, i, i, n)
+ }
+
+ v, err := s.Float64()
+ if err != nil {
+ return 0, fmt.Errorf(errorMsg, i, i, n)
+ }
+
+ return T(v), nil
+ case float64Provider:
+ if _, ok := any(n).(float64); !ok {
+ return 0, fmt.Errorf(errorMsg, i, i, n)
+ }
+
+ return T(s.Float64()), nil
+ default:
+ if i, ok := resolveAlias(i); ok {
+ return toNumberE(i, parseFn)
+ }
+
+ return 0, fmt.Errorf(errorMsg, i, i, n)
+ }
+}
+
+func toUnsignedNumber[T Number](i any) (T, bool, bool) {
+ i, _ = indirect(i)
+
+ switch s := i.(type) {
+ case T:
+ return s, true, true
+ case int:
+ if s < 0 {
+ return 0, false, false
+ }
+
+ return T(s), true, true
+ case int8:
+ if s < 0 {
+ return 0, false, false
+ }
+
+ return T(s), true, true
+ case int16:
+ if s < 0 {
+ return 0, false, false
+ }
+
+ return T(s), true, true
+ case int32:
+ if s < 0 {
+ return 0, false, false
+ }
+
+ return T(s), true, true
+ case int64:
+ if s < 0 {
+ return 0, false, false
+ }
+
+ return T(s), true, true
+ case uint:
+ return T(s), true, true
+ case uint8:
+ return T(s), true, true
+ case uint16:
+ return T(s), true, true
+ case uint32:
+ return T(s), true, true
+ case uint64:
+ return T(s), true, true
+ case float32:
+ if s < 0 {
+ return 0, false, false
+ }
+
+ return T(s), true, true
+ case float64:
+ if s < 0 {
+ return 0, false, false
+ }
+
+ return T(s), true, true
+ case bool:
+ if s {
+ return 1, true, true
+ }
+
+ return 0, true, true
+ case nil:
+ return 0, true, true
+ case time.Weekday:
+ if s < 0 {
+ return 0, false, false
+ }
+
+ return T(s), true, true
+ case time.Month:
+ if s < 0 {
+ return 0, false, false
+ }
+
+ return T(s), true, true
+ }
+
+ return 0, true, false
+}
+
+func toUnsignedNumberE[T Number](i any, parseFn func(string) (T, error)) (T, error) {
+ n, valid, ok := toUnsignedNumber[T](i)
+ if ok {
+ return n, nil
+ }
+
+ i, _ = indirect(i)
+
+ if !valid {
+ return 0, errNegativeNotAllowed
+ }
+
+ switch s := i.(type) {
+ case string:
+ if s == "" {
+ return 0, nil
+ }
+
+ v, err := parseFn(s)
+ if err != nil {
+ return 0, fmt.Errorf(errorMsgWith, i, i, n, err)
+ }
+
+ return v, nil
+ case json.Number:
+ if s == "" {
+ return 0, nil
+ }
+
+ v, err := parseFn(string(s))
+ if err != nil {
+ return 0, fmt.Errorf(errorMsgWith, i, i, n, err)
+ }
+
+ return v, nil
+ case float64EProvider:
+ if _, ok := any(n).(float64); !ok {
+ return 0, fmt.Errorf(errorMsg, i, i, n)
+ }
+
+ v, err := s.Float64()
+ if err != nil {
+ return 0, fmt.Errorf(errorMsg, i, i, n)
+ }
+
+ if v < 0 {
+ return 0, errNegativeNotAllowed
+ }
+
+ return T(v), nil
+ case float64Provider:
+ if _, ok := any(n).(float64); !ok {
+ return 0, fmt.Errorf(errorMsg, i, i, n)
+ }
+
+ v := s.Float64()
+
+ if v < 0 {
+ return 0, errNegativeNotAllowed
+ }
+
+ return T(v), nil
+ default:
+ if i, ok := resolveAlias(i); ok {
+ return toUnsignedNumberE(i, parseFn)
+ }
+
+ return 0, fmt.Errorf(errorMsg, i, i, n)
+ }
+}
+
+func parseNumber[T Number](s string) (T, error) {
+ var t T
+
+ switch any(t).(type) {
+ case int:
+ v, err := parseInt[int](s)
+
+ return T(v), err
+ case int8:
+ v, err := parseInt[int8](s)
+
+ return T(v), err
+ case int16:
+ v, err := parseInt[int16](s)
+
+ return T(v), err
+ case int32:
+ v, err := parseInt[int32](s)
+
+ return T(v), err
+ case int64:
+ v, err := parseInt[int64](s)
+
+ return T(v), err
+ case uint:
+ v, err := parseUint[uint](s)
+
+ return T(v), err
+ case uint8:
+ v, err := parseUint[uint8](s)
+
+ return T(v), err
+ case uint16:
+ v, err := parseUint[uint16](s)
+
+ return T(v), err
+ case uint32:
+ v, err := parseUint[uint32](s)
+
+ return T(v), err
+ case uint64:
+ v, err := parseUint[uint64](s)
+
+ return T(v), err
+ case float32:
+ v, err := strconv.ParseFloat(s, 32)
+
+ return T(v), err
+ case float64:
+ v, err := strconv.ParseFloat(s, 64)
+
+ return T(v), err
+
+ default:
+ return 0, fmt.Errorf("unknown number type: %T", t)
+ }
+}
+
+func parseInt[T integer](s string) (T, error) {
+ v, err := strconv.ParseInt(trimDecimal(s), 0, 0)
+ if err != nil {
+ return 0, err
+ }
+
+ return T(v), nil
+}
+
+func parseUint[T unsigned](s string) (T, error) {
+ v, err := strconv.ParseUint(strings.TrimLeft(trimDecimal(s), "+"), 0, 0)
+ if err != nil {
+ return 0, err
+ }
+
+ return T(v), nil
+}
+
+func parseFloat[T float](s string) (T, error) {
+ var t T
+
+ var v any
+ var err error
+
+ switch any(t).(type) {
+ case float32:
+ n, e := strconv.ParseFloat(s, 32)
+
+ v = float32(n)
+ err = e
+ case float64:
+ n, e := strconv.ParseFloat(s, 64)
+
+ v = float64(n)
+ err = e
+ }
+
+ return v.(T), err
+}
+
+// ToFloat64E casts an interface to a float64 type.
+func ToFloat64E(i any) (float64, error) {
+ return toNumberE[float64](i, parseFloat[float64])
+}
+
+// ToFloat32E casts an interface to a float32 type.
+func ToFloat32E(i any) (float32, error) {
+ return toNumberE[float32](i, parseFloat[float32])
+}
+
+// ToInt64E casts an interface to an int64 type.
+func ToInt64E(i any) (int64, error) {
+ return toNumberE[int64](i, parseInt[int64])
+}
+
+// ToInt32E casts an interface to an int32 type.
+func ToInt32E(i any) (int32, error) {
+ return toNumberE[int32](i, parseInt[int32])
+}
+
+// ToInt16E casts an interface to an int16 type.
+func ToInt16E(i any) (int16, error) {
+ return toNumberE[int16](i, parseInt[int16])
+}
+
+// ToInt8E casts an interface to an int8 type.
+func ToInt8E(i any) (int8, error) {
+ return toNumberE[int8](i, parseInt[int8])
+}
+
+// ToIntE casts an interface to an int type.
+func ToIntE(i any) (int, error) {
+ return toNumberE[int](i, parseInt[int])
+}
+
+// ToUintE casts an interface to a uint type.
+func ToUintE(i any) (uint, error) {
+ return toUnsignedNumberE[uint](i, parseUint[uint])
+}
+
+// ToUint64E casts an interface to a uint64 type.
+func ToUint64E(i any) (uint64, error) {
+ return toUnsignedNumberE[uint64](i, parseUint[uint64])
+}
+
+// ToUint32E casts an interface to a uint32 type.
+func ToUint32E(i any) (uint32, error) {
+ return toUnsignedNumberE[uint32](i, parseUint[uint32])
+}
+
+// ToUint16E casts an interface to a uint16 type.
+func ToUint16E(i any) (uint16, error) {
+ return toUnsignedNumberE[uint16](i, parseUint[uint16])
+}
+
+// ToUint8E casts an interface to a uint type.
+func ToUint8E(i any) (uint8, error) {
+ return toUnsignedNumberE[uint8](i, parseUint[uint8])
+}
+
+func trimZeroDecimal(s string) string {
+ var foundZero bool
+ for i := len(s); i > 0; i-- {
+ switch s[i-1] {
+ case '.':
+ if foundZero {
+ return s[:i-1]
+ }
+ case '0':
+ foundZero = true
+ default:
+ return s
+ }
+ }
+ return s
+}
+
+var stringNumberRe = regexp.MustCompile(`^([-+]?\d*)(\.\d*)?$`)
+
+// see [BenchmarkDecimal] for details about the implementation
+func trimDecimal(s string) string {
+ if !strings.Contains(s, ".") {
+ return s
+ }
+
+ matches := stringNumberRe.FindStringSubmatch(s)
+ if matches != nil {
+ // matches[1] is the captured integer part with sign
+ s = matches[1]
+
+ // handle special cases
+ switch s {
+ case "-", "+":
+ s += "0"
+ case "":
+ s = "0"
+ }
+
+ return s
+ }
+
+ return s
+}
diff --git a/vendor/github.com/spf13/cast/slice.go b/vendor/github.com/spf13/cast/slice.go
new file mode 100644
index 000000000..e6a8328c6
--- /dev/null
+++ b/vendor/github.com/spf13/cast/slice.go
@@ -0,0 +1,106 @@
+// Copyright © 2014 Steve Francia .
+//
+// Use of this source code is governed by an MIT-style
+// license that can be found in the LICENSE file.
+
+package cast
+
+import (
+ "fmt"
+ "reflect"
+ "strings"
+)
+
+// ToSliceE casts any value to a []any type.
+func ToSliceE(i any) ([]any, error) {
+ i, _ = indirect(i)
+
+ var s []any
+
+ switch v := i.(type) {
+ case []any:
+ // TODO: use slices.Clone
+ return append(s, v...), nil
+ case []map[string]any:
+ for _, u := range v {
+ s = append(s, u)
+ }
+
+ return s, nil
+ default:
+ return s, fmt.Errorf(errorMsg, i, i, s)
+ }
+}
+
+func toSliceE[T Basic](i any) ([]T, error) {
+ v, ok, err := toSliceEOk[T](i)
+ if err != nil {
+ return nil, err
+ }
+
+ if !ok {
+ return nil, fmt.Errorf(errorMsg, i, i, []T{})
+ }
+
+ return v, nil
+}
+
+func toSliceEOk[T Basic](i any) ([]T, bool, error) {
+ i, _ = indirect(i)
+ if i == nil {
+ return nil, true, fmt.Errorf(errorMsg, i, i, []T{})
+ }
+
+ switch v := i.(type) {
+ case []T:
+ // TODO: clone slice
+ return v, true, nil
+ }
+
+ kind := reflect.TypeOf(i).Kind()
+ switch kind {
+ case reflect.Slice, reflect.Array:
+ s := reflect.ValueOf(i)
+ a := make([]T, s.Len())
+
+ for j := 0; j < s.Len(); j++ {
+ val, err := ToE[T](s.Index(j).Interface())
+ if err != nil {
+ return nil, true, fmt.Errorf(errorMsg, i, i, []T{})
+ }
+
+ a[j] = val
+ }
+
+ return a, true, nil
+ default:
+ return nil, false, nil
+ }
+}
+
+// ToStringSliceE casts any value to a []string type.
+func ToStringSliceE(i any) ([]string, error) {
+ if a, ok, err := toSliceEOk[string](i); ok {
+ if err != nil {
+ return nil, err
+ }
+
+ return a, nil
+ }
+
+ var a []string
+
+ switch v := i.(type) {
+ case string:
+ return strings.Fields(v), nil
+ case any:
+ str, err := ToStringE(v)
+ if err != nil {
+ return nil, fmt.Errorf(errorMsg, i, i, a)
+ }
+
+ return []string{str}, nil
+ default:
+ return nil, fmt.Errorf(errorMsg, i, i, a)
+ }
+}
diff --git a/vendor/github.com/spf13/cast/time.go b/vendor/github.com/spf13/cast/time.go
new file mode 100644
index 000000000..744cd5acc
--- /dev/null
+++ b/vendor/github.com/spf13/cast/time.go
@@ -0,0 +1,116 @@
+// Copyright © 2014 Steve Francia .
+//
+// Use of this source code is governed by an MIT-style
+// license that can be found in the LICENSE file.
+
+package cast
+
+import (
+ "encoding/json"
+ "errors"
+ "fmt"
+ "strings"
+ "time"
+
+ "github.com/spf13/cast/internal"
+)
+
+// ToTimeE any value to a [time.Time] type.
+func ToTimeE(i any) (time.Time, error) {
+ return ToTimeInDefaultLocationE(i, time.UTC)
+}
+
+// ToTimeInDefaultLocationE casts an empty interface to [time.Time],
+// interpreting inputs without a timezone to be in the given location,
+// or the local timezone if nil.
+func ToTimeInDefaultLocationE(i any, location *time.Location) (tim time.Time, err error) {
+ i, _ = indirect(i)
+
+ switch v := i.(type) {
+ case time.Time:
+ return v, nil
+ case string:
+ return StringToDateInDefaultLocation(v, location)
+ case json.Number:
+ // Originally this used ToInt64E, but adding string float conversion broke ToTime.
+ // the behavior of ToTime would have changed if we continued using it.
+ // For now, using json.Number's own Int64 method should be good enough to preserve backwards compatibility.
+ v = json.Number(trimZeroDecimal(string(v)))
+ s, err1 := v.Int64()
+ if err1 != nil {
+ return time.Time{}, fmt.Errorf(errorMsg, i, i, time.Time{})
+ }
+ return time.Unix(s, 0), nil
+ case int:
+ return time.Unix(int64(v), 0), nil
+ case int32:
+ return time.Unix(int64(v), 0), nil
+ case int64:
+ return time.Unix(v, 0), nil
+ case uint:
+ return time.Unix(int64(v), 0), nil
+ case uint32:
+ return time.Unix(int64(v), 0), nil
+ case uint64:
+ return time.Unix(int64(v), 0), nil
+ case nil:
+ return time.Time{}, nil
+ default:
+ return time.Time{}, fmt.Errorf(errorMsg, i, i, time.Time{})
+ }
+}
+
+// ToDurationE casts any value to a [time.Duration] type.
+func ToDurationE(i any) (time.Duration, error) {
+ i, _ = indirect(i)
+
+ switch s := i.(type) {
+ case time.Duration:
+ return s, nil
+ case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64:
+ v, err := ToInt64E(s)
+ if err != nil {
+ // TODO: once there is better error handling, this should be easier
+ return 0, errors.New(strings.ReplaceAll(err.Error(), " int64", "time.Duration"))
+ }
+
+ return time.Duration(v), nil
+ case float32, float64, float64EProvider, float64Provider:
+ v, err := ToFloat64E(s)
+ if err != nil {
+ // TODO: once there is better error handling, this should be easier
+ return 0, errors.New(strings.ReplaceAll(err.Error(), " float64", "time.Duration"))
+ }
+
+ return time.Duration(v), nil
+ case string:
+ if !strings.ContainsAny(s, "nsuµmh") {
+ return time.ParseDuration(s + "ns")
+ }
+
+ return time.ParseDuration(s)
+ case nil:
+ return time.Duration(0), nil
+ default:
+ if i, ok := resolveAlias(i); ok {
+ return ToDurationE(i)
+ }
+
+ return 0, fmt.Errorf(errorMsg, i, i, time.Duration(0))
+ }
+}
+
+// StringToDate attempts to parse a string into a [time.Time] type using a
+// predefined list of formats.
+//
+// If no suitable format is found, an error is returned.
+func StringToDate(s string) (time.Time, error) {
+ return internal.ParseDateWith(s, time.UTC, internal.TimeFormats)
+}
+
+// StringToDateInDefaultLocation casts an empty interface to a [time.Time],
+// interpreting inputs without a timezone to be in the given location,
+// or the local timezone if nil.
+func StringToDateInDefaultLocation(s string, location *time.Location) (time.Time, error) {
+ return internal.ParseDateWith(s, location, internal.TimeFormats)
+}
diff --git a/vendor/github.com/spf13/cast/timeformattype_string.go b/vendor/github.com/spf13/cast/timeformattype_string.go
deleted file mode 100644
index 1524fc82c..000000000
--- a/vendor/github.com/spf13/cast/timeformattype_string.go
+++ /dev/null
@@ -1,27 +0,0 @@
-// Code generated by "stringer -type timeFormatType"; DO NOT EDIT.
-
-package cast
-
-import "strconv"
-
-func _() {
- // An "invalid array index" compiler error signifies that the constant values have changed.
- // Re-run the stringer command to generate them again.
- var x [1]struct{}
- _ = x[timeFormatNoTimezone-0]
- _ = x[timeFormatNamedTimezone-1]
- _ = x[timeFormatNumericTimezone-2]
- _ = x[timeFormatNumericAndNamedTimezone-3]
- _ = x[timeFormatTimeOnly-4]
-}
-
-const _timeFormatType_name = "timeFormatNoTimezonetimeFormatNamedTimezonetimeFormatNumericTimezonetimeFormatNumericAndNamedTimezonetimeFormatTimeOnly"
-
-var _timeFormatType_index = [...]uint8{0, 20, 43, 68, 101, 119}
-
-func (i timeFormatType) String() string {
- if i < 0 || i >= timeFormatType(len(_timeFormatType_index)-1) {
- return "timeFormatType(" + strconv.FormatInt(int64(i), 10) + ")"
- }
- return _timeFormatType_name[_timeFormatType_index[i]:_timeFormatType_index[i+1]]
-}
diff --git a/vendor/github.com/spf13/cast/zz_generated.go b/vendor/github.com/spf13/cast/zz_generated.go
new file mode 100644
index 000000000..ce3ec0f78
--- /dev/null
+++ b/vendor/github.com/spf13/cast/zz_generated.go
@@ -0,0 +1,261 @@
+// Code generated by cast generator. DO NOT EDIT.
+
+package cast
+
+import "time"
+
+// ToBool casts any value to a(n) bool type.
+func ToBool(i any) bool {
+ v, _ := ToBoolE(i)
+ return v
+}
+
+// ToString casts any value to a(n) string type.
+func ToString(i any) string {
+ v, _ := ToStringE(i)
+ return v
+}
+
+// ToTime casts any value to a(n) time.Time type.
+func ToTime(i any) time.Time {
+ v, _ := ToTimeE(i)
+ return v
+}
+
+// ToTimeInDefaultLocation casts any value to a(n) time.Time type.
+func ToTimeInDefaultLocation(i any, location *time.Location) time.Time {
+ v, _ := ToTimeInDefaultLocationE(i, location)
+ return v
+}
+
+// ToDuration casts any value to a(n) time.Duration type.
+func ToDuration(i any) time.Duration {
+ v, _ := ToDurationE(i)
+ return v
+}
+
+// ToInt casts any value to a(n) int type.
+func ToInt(i any) int {
+ v, _ := ToIntE(i)
+ return v
+}
+
+// ToInt8 casts any value to a(n) int8 type.
+func ToInt8(i any) int8 {
+ v, _ := ToInt8E(i)
+ return v
+}
+
+// ToInt16 casts any value to a(n) int16 type.
+func ToInt16(i any) int16 {
+ v, _ := ToInt16E(i)
+ return v
+}
+
+// ToInt32 casts any value to a(n) int32 type.
+func ToInt32(i any) int32 {
+ v, _ := ToInt32E(i)
+ return v
+}
+
+// ToInt64 casts any value to a(n) int64 type.
+func ToInt64(i any) int64 {
+ v, _ := ToInt64E(i)
+ return v
+}
+
+// ToUint casts any value to a(n) uint type.
+func ToUint(i any) uint {
+ v, _ := ToUintE(i)
+ return v
+}
+
+// ToUint8 casts any value to a(n) uint8 type.
+func ToUint8(i any) uint8 {
+ v, _ := ToUint8E(i)
+ return v
+}
+
+// ToUint16 casts any value to a(n) uint16 type.
+func ToUint16(i any) uint16 {
+ v, _ := ToUint16E(i)
+ return v
+}
+
+// ToUint32 casts any value to a(n) uint32 type.
+func ToUint32(i any) uint32 {
+ v, _ := ToUint32E(i)
+ return v
+}
+
+// ToUint64 casts any value to a(n) uint64 type.
+func ToUint64(i any) uint64 {
+ v, _ := ToUint64E(i)
+ return v
+}
+
+// ToFloat32 casts any value to a(n) float32 type.
+func ToFloat32(i any) float32 {
+ v, _ := ToFloat32E(i)
+ return v
+}
+
+// ToFloat64 casts any value to a(n) float64 type.
+func ToFloat64(i any) float64 {
+ v, _ := ToFloat64E(i)
+ return v
+}
+
+// ToStringMapString casts any value to a(n) map[string]string type.
+func ToStringMapString(i any) map[string]string {
+ v, _ := ToStringMapStringE(i)
+ return v
+}
+
+// ToStringMapStringSlice casts any value to a(n) map[string][]string type.
+func ToStringMapStringSlice(i any) map[string][]string {
+ v, _ := ToStringMapStringSliceE(i)
+ return v
+}
+
+// ToStringMapBool casts any value to a(n) map[string]bool type.
+func ToStringMapBool(i any) map[string]bool {
+ v, _ := ToStringMapBoolE(i)
+ return v
+}
+
+// ToStringMapInt casts any value to a(n) map[string]int type.
+func ToStringMapInt(i any) map[string]int {
+ v, _ := ToStringMapIntE(i)
+ return v
+}
+
+// ToStringMapInt64 casts any value to a(n) map[string]int64 type.
+func ToStringMapInt64(i any) map[string]int64 {
+ v, _ := ToStringMapInt64E(i)
+ return v
+}
+
+// ToStringMap casts any value to a(n) map[string]any type.
+func ToStringMap(i any) map[string]any {
+ v, _ := ToStringMapE(i)
+ return v
+}
+
+// ToSlice casts any value to a(n) []any type.
+func ToSlice(i any) []any {
+ v, _ := ToSliceE(i)
+ return v
+}
+
+// ToBoolSlice casts any value to a(n) []bool type.
+func ToBoolSlice(i any) []bool {
+ v, _ := ToBoolSliceE(i)
+ return v
+}
+
+// ToStringSlice casts any value to a(n) []string type.
+func ToStringSlice(i any) []string {
+ v, _ := ToStringSliceE(i)
+ return v
+}
+
+// ToIntSlice casts any value to a(n) []int type.
+func ToIntSlice(i any) []int {
+ v, _ := ToIntSliceE(i)
+ return v
+}
+
+// ToInt64Slice casts any value to a(n) []int64 type.
+func ToInt64Slice(i any) []int64 {
+ v, _ := ToInt64SliceE(i)
+ return v
+}
+
+// ToUintSlice casts any value to a(n) []uint type.
+func ToUintSlice(i any) []uint {
+ v, _ := ToUintSliceE(i)
+ return v
+}
+
+// ToFloat64Slice casts any value to a(n) []float64 type.
+func ToFloat64Slice(i any) []float64 {
+ v, _ := ToFloat64SliceE(i)
+ return v
+}
+
+// ToDurationSlice casts any value to a(n) []time.Duration type.
+func ToDurationSlice(i any) []time.Duration {
+ v, _ := ToDurationSliceE(i)
+ return v
+}
+
+// ToBoolSliceE casts any value to a(n) []bool type.
+func ToBoolSliceE(i any) ([]bool, error) {
+ return toSliceE[bool](i)
+}
+
+// ToDurationSliceE casts any value to a(n) []time.Duration type.
+func ToDurationSliceE(i any) ([]time.Duration, error) {
+ return toSliceE[time.Duration](i)
+}
+
+// ToIntSliceE casts any value to a(n) []int type.
+func ToIntSliceE(i any) ([]int, error) {
+ return toSliceE[int](i)
+}
+
+// ToInt8SliceE casts any value to a(n) []int8 type.
+func ToInt8SliceE(i any) ([]int8, error) {
+ return toSliceE[int8](i)
+}
+
+// ToInt16SliceE casts any value to a(n) []int16 type.
+func ToInt16SliceE(i any) ([]int16, error) {
+ return toSliceE[int16](i)
+}
+
+// ToInt32SliceE casts any value to a(n) []int32 type.
+func ToInt32SliceE(i any) ([]int32, error) {
+ return toSliceE[int32](i)
+}
+
+// ToInt64SliceE casts any value to a(n) []int64 type.
+func ToInt64SliceE(i any) ([]int64, error) {
+ return toSliceE[int64](i)
+}
+
+// ToUintSliceE casts any value to a(n) []uint type.
+func ToUintSliceE(i any) ([]uint, error) {
+ return toSliceE[uint](i)
+}
+
+// ToUint8SliceE casts any value to a(n) []uint8 type.
+func ToUint8SliceE(i any) ([]uint8, error) {
+ return toSliceE[uint8](i)
+}
+
+// ToUint16SliceE casts any value to a(n) []uint16 type.
+func ToUint16SliceE(i any) ([]uint16, error) {
+ return toSliceE[uint16](i)
+}
+
+// ToUint32SliceE casts any value to a(n) []uint32 type.
+func ToUint32SliceE(i any) ([]uint32, error) {
+ return toSliceE[uint32](i)
+}
+
+// ToUint64SliceE casts any value to a(n) []uint64 type.
+func ToUint64SliceE(i any) ([]uint64, error) {
+ return toSliceE[uint64](i)
+}
+
+// ToFloat32SliceE casts any value to a(n) []float32 type.
+func ToFloat32SliceE(i any) ([]float32, error) {
+ return toSliceE[float32](i)
+}
+
+// ToFloat64SliceE casts any value to a(n) []float64 type.
+func ToFloat64SliceE(i any) ([]float64, error) {
+ return toSliceE[float64](i)
+}
diff --git a/vendor/github.com/tetafro/godot/.golangci.yml b/vendor/github.com/tetafro/godot/.golangci.yml
index 2b6261868..9679efa79 100644
--- a/vendor/github.com/tetafro/godot/.golangci.yml
+++ b/vendor/github.com/tetafro/godot/.golangci.yml
@@ -1,9 +1,8 @@
+version: "2"
run:
concurrency: 2
- timeout: 5m
-
linters:
- disable-all: true
+ default: none
enable:
- asciicheck
- bodyclose
@@ -22,12 +21,8 @@ linters:
- gocritic
- gocyclo
- godot
- - gofmt
- - gofumpt
- - goimports
- goprintffuncname
- gosec
- - gosimple
- govet
- importas
- ineffassign
@@ -41,38 +36,39 @@ linters:
- revive
- rowserrcheck
- sqlclosecheck
- - sqlclosecheck
- staticcheck
- - stylecheck
- - typecheck
- unconvert
- unparam
- unused
- wastedassign
- whitespace
- wrapcheck
-
-linters-settings:
- godot:
- scope: toplevel
-
-issues:
- exclude-use-default: false
- exclude:
- - "do not define dynamic errors, use wrapped static errors instead"
- exclude-files:
- - ./testdata/
- exclude-rules:
- - path: _test\.go
- linters:
- - dupl
- - errcheck
- - funlen
- - gocognit
- - cyclop
- - gosec
- - noctx
- - path: main\.go
- linters:
- - cyclop
- - gomnd
+ exclusions:
+ rules:
+ - path: _test\.go
+ linters:
+ - cyclop
+ - dupl
+ - errcheck
+ - gocognit
+ - goconst
+ - gocyclo
+ - gosec
+ - noctx
+ - path: main\.go
+ linters:
+ - cyclop
+ - gocognit
+ - path: main\.go
+ text: '`defer cancel\(\)` will not run'
+ - path: (.+)\.go$
+ text: 'G404: Use of weak random number generator'
+ - path: (.+)\.go$
+ text: do not define dynamic errors, use wrapped static errors instead
+ - path: (.+)\.go$
+ text: Error return value of `.*.Body.Close` is not checked
+formatters:
+ enable:
+ - gofmt
+ - gofumpt
+ - goimports
diff --git a/vendor/github.com/tetafro/godot/.goreleaser.yml b/vendor/github.com/tetafro/godot/.goreleaser.yml
index 2f0c2466a..ff5992025 100644
--- a/vendor/github.com/tetafro/godot/.goreleaser.yml
+++ b/vendor/github.com/tetafro/godot/.goreleaser.yml
@@ -5,7 +5,7 @@ builds:
checksum:
name_template: checksums.txt
snapshot:
- name_template: "{{ .Tag }}"
+ version_template: "{{ .Tag }}"
changelog:
sort: asc
filters:
diff --git a/vendor/github.com/tetafro/godot/checks.go b/vendor/github.com/tetafro/godot/checks.go
index 0301fa93c..13e867fb5 100644
--- a/vendor/github.com/tetafro/godot/checks.go
+++ b/vendor/github.com/tetafro/godot/checks.go
@@ -111,7 +111,9 @@ func checkPeriod(c comment) *Issue {
// Get the offset of the first symbol in the last line of the comment.
// This value is used only in golangci-lint to point to the problem,
// and to replace the line when running in auto-fix mode.
- offset := c.start.Offset
+ // For inline comments, the line starts before the comment, so we
+ // subtract the column offset to get the line start.
+ offset := c.start.Offset - (c.start.Column - 1)
for i := 0; i < pos.line-1; i++ {
offset += len(c.lines[i]) + 1
}
@@ -218,7 +220,9 @@ func checkCapital(c comment) []Issue {
// Get the offset of the first symbol in the current issue's line.
// This value is used only in golangci-lint to point to the problem,
// and to replace the line when running in auto-fix mode.
- offset := c.start.Offset
+ // For inline comments, the line starts before the comment, so we
+ // subtract the column offset to get the line start.
+ offset := c.start.Offset - (c.start.Column - 1)
for i := 0; i < pos.line-1; i++ {
offset += len(c.lines[i]) + 1
}
diff --git a/vendor/github.com/tetafro/godot/file.go b/vendor/github.com/tetafro/godot/file.go
index 19b0ebe92..7b878c293 100644
--- a/vendor/github.com/tetafro/godot/file.go
+++ b/vendor/github.com/tetafro/godot/file.go
@@ -87,6 +87,8 @@ func (pf *parsedFile) getComments(scope Scope, exclude []*regexp.Regexp) []comme
// getBlockComments gets comments from the inside of top level blocks:
// var (...), const (...).
+//
+//nolint:cyclop
func (pf *parsedFile) getBlockComments(exclude []*regexp.Regexp) []comment {
var comments []comment
for _, decl := range pf.file.Decls {
@@ -109,12 +111,14 @@ func (pf *parsedFile) getBlockComments(exclude []*regexp.Regexp) []comment {
// Skip comments that are not top-level for this block
// (the block itself is top level, so comments inside this block
// would be on column 2)
- //nolint:gomnd
if pf.fset.Position(c.Pos()).Column != 2 {
continue
}
firstLine := pf.fset.Position(c.Pos()).Line
lastLine := pf.fset.Position(c.End()).Line
+ if firstLine < 1 || lastLine < firstLine || lastLine > len(pf.lines) {
+ continue // broken consistency, probably by the `//line` directive
+ }
comments = append(comments, comment{
lines: pf.lines[firstLine-1 : lastLine],
text: getText(c, exclude),
@@ -127,7 +131,7 @@ func (pf *parsedFile) getBlockComments(exclude []*regexp.Regexp) []comment {
// getTopLevelComments gets all top level comments.
func (pf *parsedFile) getTopLevelComments(exclude []*regexp.Regexp) []comment {
- var comments []comment //nolint:prealloc
+ var comments []comment
for _, c := range pf.file.Comments {
if c == nil || len(c.List) == 0 {
continue
@@ -137,6 +141,9 @@ func (pf *parsedFile) getTopLevelComments(exclude []*regexp.Regexp) []comment {
}
firstLine := pf.fset.Position(c.Pos()).Line
lastLine := pf.fset.Position(c.End()).Line
+ if firstLine < 1 || lastLine < firstLine || lastLine > len(pf.lines) {
+ continue // broken consistency, probably by the `//line` directive
+ }
comments = append(comments, comment{
lines: pf.lines[firstLine-1 : lastLine],
text: getText(c, exclude),
@@ -148,7 +155,7 @@ func (pf *parsedFile) getTopLevelComments(exclude []*regexp.Regexp) []comment {
// getDeclarationComments gets top level declaration comments.
func (pf *parsedFile) getDeclarationComments(exclude []*regexp.Regexp) []comment {
- var comments []comment //nolint:prealloc
+ var comments []comment
for _, decl := range pf.file.Decls {
var cg *ast.CommentGroup
switch d := decl.(type) {
@@ -164,6 +171,9 @@ func (pf *parsedFile) getDeclarationComments(exclude []*regexp.Regexp) []comment
firstLine := pf.fset.Position(cg.Pos()).Line
lastLine := pf.fset.Position(cg.End()).Line
+ if firstLine < 1 || lastLine < firstLine || lastLine > len(pf.lines) {
+ continue // broken consistency, probably by the `//line` directive
+ }
comments = append(comments, comment{
lines: pf.lines[firstLine-1 : lastLine],
text: getText(cg, exclude),
@@ -175,13 +185,16 @@ func (pf *parsedFile) getDeclarationComments(exclude []*regexp.Regexp) []comment
// getNoInlineComments gets all except inline comments.
func (pf *parsedFile) getNoInlineComments(exclude []*regexp.Regexp) []comment {
- var comments []comment //nolint:prealloc
+ var comments []comment
for _, c := range pf.file.Comments {
if c == nil || len(c.List) == 0 {
continue
}
firstLine := pf.fset.Position(c.Pos()).Line
lastLine := pf.fset.Position(c.End()).Line
+ if firstLine < 1 || lastLine < firstLine || lastLine > len(pf.lines) {
+ continue // broken consistency, probably by the `//line` directive
+ }
c := comment{
lines: pf.lines[firstLine-1 : lastLine],
@@ -203,13 +216,16 @@ func (pf *parsedFile) getNoInlineComments(exclude []*regexp.Regexp) []comment {
// getAllComments gets every single comment from the file.
func (pf *parsedFile) getAllComments(exclude []*regexp.Regexp) []comment {
- var comments []comment //nolint:prealloc
+ var comments []comment
for _, c := range pf.file.Comments {
if c == nil || len(c.List) == 0 {
continue
}
firstLine := pf.fset.Position(c.Pos()).Line
lastLine := pf.fset.Position(c.End()).Line
+ if firstLine < 1 || lastLine < firstLine || lastLine > len(pf.lines) {
+ continue // broken consistency, probably by the `//line` directive
+ }
comments = append(comments, comment{
lines: pf.lines[firstLine-1 : lastLine],
start: pf.fset.Position(c.List[0].Slash),
diff --git a/vendor/github.com/timakin/bodyclose/passes/bodyclose/bodyclose.go b/vendor/github.com/timakin/bodyclose/passes/bodyclose/bodyclose.go
index ae860d728..4a862521f 100644
--- a/vendor/github.com/timakin/bodyclose/passes/bodyclose/bodyclose.go
+++ b/vendor/github.com/timakin/bodyclose/passes/bodyclose/bodyclose.go
@@ -16,12 +16,18 @@ import (
var Analyzer = &analysis.Analyzer{
Name: "bodyclose",
Doc: Doc,
- Run: new(runner).run,
+ Run: run,
Requires: []*analysis.Analyzer{
buildssa.Analyzer,
},
}
+func init() {
+ Analyzer.Flags.BoolVar(&checkConsumptionFlag, "check-consumption", false, "also check that response body is consumed")
+}
+
+var checkConsumptionFlag bool
+
const (
Doc = "checks whether HTTP response body is closed successfully"
@@ -30,18 +36,21 @@ const (
)
type runner struct {
- pass *analysis.Pass
- resObj types.Object
- resTyp *types.Pointer
- bodyObj types.Object
- closeMthd *types.Func
- skipFile map[*ast.File]bool
+ pass *analysis.Pass
+ resObj types.Object
+ resTyp *types.Pointer
+ bodyObj types.Object
+ closeMthd *types.Func
+ skipFile map[*ast.File]bool
+ checkConsumption bool
}
-// run executes an analysis for the pass. The receiver is passed
-// by value because this func is called in parallel for different passes.
-func (r runner) run(pass *analysis.Pass) (interface{}, error) {
- r.pass = pass
+// run executes an analysis for the pass
+func run(pass *analysis.Pass) (interface{}, error) {
+ r := runner{
+ pass: pass,
+ checkConsumption: checkConsumptionFlag,
+ }
funcs := pass.ResultOf[buildssa.Analyzer].(*buildssa.SSA).SrcFuncs
r.resObj = analysisutil.LookupFromImports(pass.Pkg.Imports(), nethttpPath, "Response")
@@ -96,7 +105,11 @@ FuncLoop:
for i := range b.Instrs {
pos := b.Instrs[i].Pos()
if r.isopen(b, i) {
- pass.Reportf(pos, "response body must be closed")
+ if r.checkConsumption {
+ pass.Reportf(pos, "response body must be closed and consumed")
+ } else {
+ pass.Reportf(pos, "response body must be closed")
+ }
}
}
}
@@ -216,11 +229,8 @@ func (r *runner) isopen(b *ssa.BasicBlock, i int) bool {
if len(*bOp.Referrers()) == 0 {
return true
}
- ccalls := *bOp.Referrers()
- for _, ccall := range ccalls {
- if r.isCloseCall(ccall) {
- return false
- }
+ if r.isBodyProperlyHandled(bOp) {
+ return false
}
}
case *ssa.Phi: // Called in the higher-level block
@@ -242,11 +252,8 @@ func (r *runner) isopen(b *ssa.BasicBlock, i int) bool {
if len(*bOp.Referrers()) == 0 {
return true
}
- ccalls := *bOp.Referrers()
- for _, ccall := range ccalls {
- if r.isCloseCall(ccall) {
- return false
- }
+ if r.isBodyProperlyHandled(bOp) {
+ return false
}
}
}
@@ -268,6 +275,7 @@ func (r *runner) getReqCall(instr ssa.Instruction) (*ssa.Call, bool) {
strings.Contains(callType, "net/http.ResponseController") {
return nil, false
}
+
return call, true
}
@@ -300,6 +308,102 @@ func (r *runner) getBodyOp(instr ssa.Instruction) (*ssa.UnOp, bool) {
return op, true
}
+// isBodyProperlyHandled checks if response body is properly handled (closed and optionally consumed based on flag)
+func (r *runner) isBodyProperlyHandled(bOp *ssa.UnOp) bool {
+ ccalls := *bOp.Referrers()
+
+ for _, ccall := range ccalls {
+ if r.isCloseCall(ccall) {
+ // Early return if consumption checking is disabled
+ if !r.checkConsumption {
+ return true
+ }
+ // Close found and consumption checking enabled - check consumption
+ return r.hasConsumptionForBody(bOp)
+ }
+ }
+
+ // No close call found
+ return false
+}
+
+// hasConsumptionForBody searches the function for consumption calls that use the specific response body
+func (r *runner) hasConsumptionForBody(bodyOp *ssa.UnOp) bool {
+ fn := bodyOp.Block().Parent()
+
+ // Search for consumption functions that specifically consume this response body
+ for _, block := range fn.Blocks {
+ for _, blockInstr := range block.Instrs {
+ if call, ok := blockInstr.(*ssa.Call); ok {
+ if r.isConsumptionFunction(call) && r.isCallUsingBody(call, bodyOp) {
+ return true
+ }
+ }
+ }
+ }
+
+ return false
+}
+
+// isCallUsingBody checks if a consumption function call uses the specific response body
+func (r *runner) isCallUsingBody(call *ssa.Call, responseBodyOp *ssa.UnOp) bool {
+ // Get the FieldAddr of the response body we're checking
+ responseBodyFieldAddr, ok := responseBodyOp.X.(*ssa.FieldAddr)
+ if !ok {
+ return false
+ }
+
+ // Check if any argument to the call refers to this specific response body
+ for _, arg := range call.Call.Args {
+ if r.isArgumentMatchingBody(arg, responseBodyFieldAddr) {
+ return true
+ }
+ }
+
+ return false
+}
+
+// isArgumentMatchingBody checks if a function argument refers to the same response body instance
+func (r *runner) isArgumentMatchingBody(arg ssa.Value, responseBodyFieldAddr *ssa.FieldAddr) bool {
+ switch v := arg.(type) {
+ case *ssa.FieldAddr:
+ // Direct field access - check if it's accessing Body field of same response
+ return v.X == responseBodyFieldAddr.X && v.Field == responseBodyFieldAddr.Field
+ case *ssa.UnOp:
+ // Dereference of field access - check if it's dereferencing the same response body field
+ if fieldAddr, ok := v.X.(*ssa.FieldAddr); ok {
+ return fieldAddr.X == responseBodyFieldAddr.X && fieldAddr.Field == responseBodyFieldAddr.Field
+ }
+ case *ssa.ChangeInterface:
+ // Type conversion - check if it converts the response body
+ if unOp, ok := v.X.(*ssa.UnOp); ok {
+ if fieldAddr, ok := unOp.X.(*ssa.FieldAddr); ok {
+ return fieldAddr.X == responseBodyFieldAddr.X && fieldAddr.Field == responseBodyFieldAddr.Field
+ }
+ }
+ }
+ return false
+}
+
+func (r *runner) isConsumptionFunction(call *ssa.Call) bool {
+ if call.Call.StaticCallee() != nil {
+ callee := call.Call.StaticCallee()
+ if callee.Pkg != nil {
+ pkg := callee.Pkg.Pkg.Path()
+ name := callee.Name()
+
+ // Check for known consumption functions
+ if (pkg == "io" && (name == "Copy" || name == "ReadAll")) ||
+ (pkg == "io/ioutil" && name == "ReadAll") ||
+ (pkg == "encoding/json" && name == "NewDecoder") ||
+ (pkg == "bufio" && (name == "NewScanner" || name == "NewReader")) {
+ return true
+ }
+ }
+ }
+ return false
+}
+
func (r *runner) isCloseCall(ccall ssa.Instruction) bool {
switch ccall := ccall.(type) {
case *ssa.Defer:
diff --git a/vendor/github.com/uudashr/gocognit/rangeiter.go b/vendor/github.com/uudashr/gocognit/rangeiter.go
new file mode 100644
index 000000000..f4bdac498
--- /dev/null
+++ b/vendor/github.com/uudashr/gocognit/rangeiter.go
@@ -0,0 +1,47 @@
+package gocognit
+
+import (
+ "fmt"
+ "iter"
+)
+
+func ForRangeIter(all iter.Seq[int]) {
+ for v := range all {
+ fmt.Println(v)
+ }
+}
+
+func CountDown(start int) iter.Seq[int] {
+ return func(yield func(int) bool) {
+ for i := start; i > 0; i-- {
+ if !yield(i) {
+ return
+ }
+ }
+ }
+}
+
+func DoCount() {
+ for n := range CountDown(5) {
+ fmt.Println(n)
+ }
+}
+
+func FilteredMap(m map[string]int, threshold int) iter.Seq2[string, int] {
+ return func(yield func(string, int) bool) {
+ for k, v := range m {
+ if v > threshold {
+ if !yield(k, v) {
+ return
+ }
+ }
+ }
+ }
+}
+func DoFilter() {
+ scores := map[string]int{"Alice": 50, "Bob": 90, "Charlie": 85}
+
+ for name, score := range FilteredMap(scores, 80) {
+ fmt.Printf("%s: %d\n", name, score)
+ }
+}
diff --git a/vendor/github.com/uudashr/iface/identical/identical.go b/vendor/github.com/uudashr/iface/identical/identical.go
index 0f470e547..18c3ff060 100644
--- a/vendor/github.com/uudashr/iface/identical/identical.go
+++ b/vendor/github.com/uudashr/iface/identical/identical.go
@@ -55,27 +55,31 @@ func (r *runner) run(pass *analysis.Pass) (interface{}, error) {
return
}
- if r.debug {
- fmt.Printf("GenDecl: %v specs=%d\n", decl.Tok, len(decl.Specs))
- }
+ r.debugf("GenDecl: %v specs=%d\n", decl.Tok, len(decl.Specs))
if decl.Tok != token.TYPE {
return
}
+ blockDir := directive.ParseIgnore(decl.Doc)
+ if blockDir != nil && blockDir.ShouldIgnore(pass.Analyzer.Name) {
+ return
+ }
+
for i, spec := range decl.Specs {
- if r.debug {
- fmt.Printf(" spec[%d]: %v %v\n", i, spec, reflect.TypeOf(spec))
- }
+ r.debugf(" spec[%d]: %v %T\n", i, spec, spec)
ts, ok := spec.(*ast.TypeSpec)
if !ok {
- return
+ // this code is unreachable since we already have guard the token type
+ continue
}
+ r.debugf(" -> ts.Type %T\n", ts.Type)
+
ifaceType, ok := ts.Type.(*ast.InterfaceType)
if !ok {
- return
+ continue
}
if r.debug {
@@ -93,9 +97,12 @@ func (r *runner) run(pass *analysis.Pass) (interface{}, error) {
}
}
- dir := directive.ParseIgnore(decl.Doc)
+ dir := directive.ParseIgnore(ts.Doc)
+ if dir == nil {
+ dir = blockDir
+ }
+
if dir != nil && dir.ShouldIgnore(pass.Analyzer.Name) {
- // skip due to ignore directive
continue
}
@@ -103,12 +110,12 @@ func (r *runner) run(pass *analysis.Pass) (interface{}, error) {
obj := pass.TypesInfo.Defs[ts.Name]
if obj == nil {
- return
+ continue
}
iface, ok := obj.Type().Underlying().(*types.Interface)
if !ok {
- return
+ continue
}
ifaceTypes[ts.Name.Name] = iface
@@ -147,3 +154,9 @@ func (r *runner) debugln(a ...any) {
fmt.Println(a...)
}
}
+
+func (r *runner) debugf(format string, a ...any) {
+ if r.debug {
+ fmt.Printf(format, a...)
+ }
+}
diff --git a/vendor/github.com/uudashr/iface/unexported/unexported.go b/vendor/github.com/uudashr/iface/unexported/unexported.go
index 27a31ff1b..55bb7ab8a 100644
--- a/vendor/github.com/uudashr/iface/unexported/unexported.go
+++ b/vendor/github.com/uudashr/iface/unexported/unexported.go
@@ -4,7 +4,6 @@ import (
"fmt"
"go/ast"
"go/types"
- "reflect"
"github.com/uudashr/iface/internal/directive"
"golang.org/x/tools/go/analysis"
@@ -21,7 +20,7 @@ func newAnalyzer() *analysis.Analyzer {
analyzer := &analysis.Analyzer{
Name: "unexported",
Doc: "Detects interfaces which are not exported but are used as parameters or return values in exported functions or methods.",
- URL: "https://pkg.go.dev/github.com/uudashr/iface/visibility",
+ URL: "https://pkg.go.dev/github.com/uudashr/iface/unexported",
Requires: []*analysis.Analyzer{inspect.Analyzer},
Run: r.run,
}
@@ -50,7 +49,7 @@ func (r *runner) run(pass *analysis.Pass) (any, error) {
dir := directive.ParseIgnore(funcDecl.Doc)
if dir != nil && dir.ShouldIgnore(pass.Analyzer.Name) {
// skip ignored function
- r.debugln(" skip ignored")
+ r.debugln(" skip ignored")
return
}
@@ -62,36 +61,36 @@ func (r *runner) run(pass *analysis.Pass) (any, error) {
if r.debug {
infoType := pass.TypesInfo.TypeOf(recvType)
- fmt.Println(" recvType:", recvType, "infoType:", infoType, "reflectType:", reflect.TypeOf(recvType))
+ fmt.Printf(" recvType: %v infoType: %v reflectType: %T\n", recvType, infoType, recvType)
}
switch typ := recvType.(type) {
case *ast.Ident:
- r.debugln(" recvIdent:", typ.Name)
+ r.debugln(" recvIdent:", typ.Name)
recvName = typ.Name
case *ast.StarExpr:
- r.debugln(" recvStarExpr:", typ.X)
+ r.debugln(" recvStarExpr:", typ.X)
if ident, ok := typ.X.(*ast.Ident); ok {
- r.debugln(" recvIdent:", ident.Name)
+ r.debugln(" recvIdent:", ident.Name)
recvName = ident.Name
} else {
- r.debugln(" unhandled")
+ r.debugln(" unhandled")
}
default:
- r.debugln(" unhandled")
+ r.debugln(" unhandled")
}
}
if !funcDecl.Name.IsExported() {
// skip unexported functions
- r.debugln(" skip non-exported")
+ r.debugln(" skip non-exported")
return
}
- r.debugln(" params:")
+ r.debugln(" params:")
params := funcDecl.Type.Params
@@ -99,25 +98,25 @@ func (r *runner) run(pass *analysis.Pass) (any, error) {
paramType := param.Type
infoType := pass.TypesInfo.TypeOf(paramType)
- r.debugln(" paramType:", paramType, "infoType:", infoType, "reflectType:", reflect.TypeOf(paramType))
+ r.debugf(" paramType: %v infoType: %v reflectType: %T\n", paramType, infoType, paramType)
if !types.IsInterface(infoType) {
// skip non-interface
- r.debugln(" skip non-interface")
+ r.debugln(" skip non-interface")
continue
}
if infoType.String() == "error" {
// skip error interface
- r.debugln(" skip error interface")
+ r.debugln(" skip error interface")
continue
}
if infoType.String() == "any" {
// skip any interface
- r.debugln(" skip any interface")
+ r.debugln(" skip any interface")
continue
}
@@ -125,7 +124,7 @@ func (r *runner) run(pass *analysis.Pass) (any, error) {
switch typ := paramType.(type) {
case *ast.Ident:
if !typ.IsExported() {
- r.debugln(" unexported")
+ r.debugln(" unexported")
funcMethod := "function"
funcMethodName := funcDecl.Name.Name
@@ -141,15 +140,15 @@ func (r *runner) run(pass *analysis.Pass) (any, error) {
})
}
default:
- r.debugln(" unhandled")
+ r.debugln(" unhandled")
}
}
- r.debugln(" results:")
+ r.debugln(" results:")
results := funcDecl.Type.Results
if results == nil {
- r.debugln(" no results")
+ r.debugln(" no results")
return
}
@@ -158,24 +157,24 @@ func (r *runner) run(pass *analysis.Pass) (any, error) {
resultType := result.Type
infoType := pass.TypesInfo.TypeOf(resultType)
- r.debugln(" resultType:", resultType, "infoType:", infoType, "reflectType:", reflect.TypeOf(resultType))
+ r.debugf(" resultType: %v infoType: %v reflectType: %T\n", resultType, infoType, resultType)
if !types.IsInterface(infoType) {
- r.debugln(" skip non-interface")
+ r.debugln(" skip non-interface")
continue
}
if infoType.String() == "error" {
// skip error interface
- r.debugln(" skip error interface")
+ r.debugln(" skip error interface")
continue
}
if infoType.String() == "any" {
// skip any interface
- r.debugln(" skip any interface")
+ r.debugln(" skip any interface")
continue
}
@@ -183,7 +182,7 @@ func (r *runner) run(pass *analysis.Pass) (any, error) {
switch typ := resultType.(type) {
case *ast.Ident:
if !typ.IsExported() {
- r.debugln(" unexported")
+ r.debugln(" unexported")
funcMethod := "function"
funcMethodName := funcDecl.Name.Name
@@ -199,7 +198,7 @@ func (r *runner) run(pass *analysis.Pass) (any, error) {
})
}
default:
- r.debugln(" unhandled")
+ r.debugln(" unhandled")
}
}
})
@@ -212,3 +211,9 @@ func (r *runner) debugln(a ...any) {
fmt.Println(a...)
}
}
+
+func (r *runner) debugf(format string, a ...any) {
+ if r.debug {
+ fmt.Printf(format, a...)
+ }
+}
diff --git a/vendor/go-simpler.org/sloglint/.golangci.yaml b/vendor/go-simpler.org/sloglint/.golangci.yaml
index cbac91508..526e368d4 100644
--- a/vendor/go-simpler.org/sloglint/.golangci.yaml
+++ b/vendor/go-simpler.org/sloglint/.golangci.yaml
@@ -1,10 +1,10 @@
-# https://golangci-lint.run/usage/configuration
+# https://golangci-lint.run/docs/configuration/file
version: "2"
linters:
- default: standard
enable:
- gocritic
+ - modernize
settings:
gocritic:
enable-all: true
@@ -16,3 +16,6 @@ formatters:
enable:
- gofumpt
- goimports
+ settings:
+ gofumpt:
+ extra-rules: true
diff --git a/vendor/go-simpler.org/sloglint/.goreleaser.yaml b/vendor/go-simpler.org/sloglint/.goreleaser.yaml
new file mode 100644
index 000000000..a8fa6bbfd
--- /dev/null
+++ b/vendor/go-simpler.org/sloglint/.goreleaser.yaml
@@ -0,0 +1,12 @@
+# https://goreleaser.com/customization/builds/go
+
+builds:
+ - main: ./cmd/{{.ProjectName}}
+ flags:
+ - -trimpath
+ ldflags:
+ - -s -w -X main.version={{.Version}}
+ env:
+ - CGO_ENABLED=0
+ targets:
+ - go_first_class # https://go.dev/wiki/PortingPolicy#first-class-ports
diff --git a/vendor/go-simpler.org/sloglint/.goreleaser.yml b/vendor/go-simpler.org/sloglint/.goreleaser.yml
deleted file mode 100644
index d31ea11d3..000000000
--- a/vendor/go-simpler.org/sloglint/.goreleaser.yml
+++ /dev/null
@@ -1,18 +0,0 @@
-builds:
- - main: ./cmd/sloglint
- env:
- - CGO_ENABLED=0
- flags:
- - -trimpath
- ldflags:
- - -s -w -X main.version={{.Version}}
- targets:
- - darwin_amd64
- - darwin_arm64
- - linux_amd64
- - windows_amd64
-
-archives:
- - format_overrides:
- - goos: windows
- format: zip
diff --git a/vendor/go-simpler.org/sloglint/Makefile b/vendor/go-simpler.org/sloglint/Makefile
index 6165b16f4..cf5eb9d10 100644
--- a/vendor/go-simpler.org/sloglint/Makefile
+++ b/vendor/go-simpler.org/sloglint/Makefile
@@ -1,28 +1,25 @@
.POSIX:
.SUFFIXES:
-all: test lint
+help:
+ @echo 'Available commands:'
+ @echo ' build Build the project'
+ @echo ' fmt Run formatters'
+ @echo ' lint Run linters'
+ @echo ' test Run tests'
+ @echo ' test/cover Run tests and open coverage report'
-test:
- go test -race -shuffle=on -cover ./...
+build:
+ @go build -o /dev/null ./...
-test/cover:
- go test -race -shuffle=on -coverprofile=coverage.out ./...
- go tool cover -html=coverage.out
+fmt:
+ @golangci-lint fmt
lint:
- golangci-lint run
-
-tidy:
- go mod tidy
+ @golangci-lint run --fix
-generate:
- go generate ./...
-
-# run `make pre-commit` once to install the hook.
-pre-commit: .git/hooks/pre-commit test lint tidy generate
- git diff --exit-code
+test:
+ @go test -race -shuffle=on -coverprofile=coverage.out ./...
-.git/hooks/pre-commit:
- echo "make pre-commit" > .git/hooks/pre-commit
- chmod +x .git/hooks/pre-commit
+test/cover: test
+ @go tool cover -html=coverage.out
diff --git a/vendor/go-simpler.org/sloglint/README.md b/vendor/go-simpler.org/sloglint/README.md
index e75fd0215..9653bd154 100644
--- a/vendor/go-simpler.org/sloglint/README.md
+++ b/vendor/go-simpler.org/sloglint/README.md
@@ -1,205 +1,296 @@
# sloglint
-[](https://github.com/go-simpler/sloglint/actions/workflows/checks.yml)
-[](https://pkg.go.dev/go-simpler.org/sloglint)
-[](https://goreportcard.com/report/go-simpler.org/sloglint)
+[](https://github.com/go-simpler/sloglint/actions/workflows/checks.yaml)
+[](https://pkg.go.dev/go-simpler.org/sloglint)
[](https://codecov.io/gh/go-simpler/sloglint)
A Go linter that ensures consistent code style when using `log/slog`.
-## 📌 About
+## Install
-The `log/slog` API allows two different types of arguments: key-value pairs and attributes.
-While people may have different opinions about which one is better, most seem to agree on one thing: it should be consistent.
-With `sloglint` you can enforce various rules for `log/slog` based on your preferred code style.
-
-## 🚀 Features
-
-* Enforce not mixing key-value pairs and attributes (default)
-* Enforce using either key-value pairs only or attributes only (optional)
-* Enforce not using global loggers (optional)
-* Enforce using methods that accept a context (optional)
-* Enforce using static messages (optional)
-* Enforce message style (optional)
-* Enforce using constants instead of raw keys (optional)
-* Enforce key naming convention (optional)
-* Enforce not using specific keys (optional)
-* Enforce putting arguments on separate lines (optional)
-
-## 📦 Install
-
-`sloglint` is integrated into [`golangci-lint`][1], and this is the recommended way to use it.
-
-To enable the linter, add the following lines to `.golangci.yml`:
+`sloglint` is part of [golangci-lint](https://golangci-lint.run), and this is the recommended way to use it.
```yaml
+# .golangci.yaml
linters:
enable:
- sloglint
```
-Alternatively, you can download a prebuilt binary from the [Releases][2] page to use `sloglint` standalone.
+Alternatively, you can download a prebuilt binary from the [Releases](https://github.com/go-simpler/sloglint/releases) page to use `sloglint` standalone.
-## 📋 Usage
+## Supported checks
-Run `golangci-lint` with `sloglint` enabled.
-See the list of [available options][3] to configure the linter.
+For `log/slog` functions:
+- [No global logger](#no-global-logger)
+- [Context only](#context-only)
+- [Discard handler](#discard-handler)
-When using `sloglint` standalone, pass the options as flags of the same name.
+For log messages:
+- [Static message](#static-message)
+- [Message style](#message-style)
-### No mixed arguments
+For log arguments:
+- [No mixed arguments](#no-mixed-arguments)
+- [Key-value pairs only](#key-value-pairs-only)
+- [Attributes only](#attributes-only)
+- [Arguments on separate lines](#arguments-on-separate-lines)
-The `no-mixed-args` option causes `sloglint` to report mixing key-values pairs and attributes within a single function call:
+For log keys:
+- [Constant keys](#constant-keys)
+- [Allowed keys](#allowed-keys)
+- [Forbidden keys](#forbidden-keys)
+- [Key naming case](#key-naming-case)
-```go
-slog.Info("a user has logged in", "user_id", 42, slog.String("ip_address", "192.0.2.0")) // sloglint: key-value pairs and attributes should not be mixed
-```
+The checks for log messages, arguments, and keys can also be used to analyze [custom functions](#custom-function-analysis).
-It is enabled by default.
-
-### Key-value pairs only
+### No global logger
-The `kv-only` option causes `sloglint` to report any use of attributes:
+Report the use of global loggers.
+Alternatively, only report the use of the `slog.Default()` logger.
```go
-slog.Info("a user has logged in", slog.Int("user_id", 42)) // sloglint: attributes should not be used
+slog.Info("a user has logged in")
+// sloglint: global logger should not be used
```
-### Attributes only
-
-In contrast, the `attr-only` option causes `sloglint` to report any use of key-value pairs:
-
-```go
-slog.Info("a user has logged in", "user_id", 42) // sloglint: key-value pairs should not be used
+```yaml
+# .golangci.yaml
+linters:
+ settings:
+ sloglint:
+ no-global: "all" # Or "default".
```
-### No global
+### Context only
-Some projects prefer to pass loggers as explicit dependencies.
-The `no-global` option causes `sloglint` to report the use of global loggers.
+Report the use of functions without a `context.Context`.
+Alternatively, only report their use if a context exists within the scope of the outermost function.
```go
-slog.Info("a user has logged in", "user_id", 42) // sloglint: global logger should not be used
+slog.Info("a user has logged in")
+// sloglint: InfoContext should be used instead
+```
+
+```yaml
+# .golangci.yaml
+linters:
+ settings:
+ sloglint:
+ context: "all" # Or "scope".
```
-Possible values are `all` (report all global loggers) and `default` (report only the default `slog` logger).
+This check partially supports autofix.
-### Context only
+### Discard handler
-Some `slog.Handler` implementations make use of the given `context.Context` (e.g. to access context values).
-For them to work properly, you need to pass a context to all logger calls.
-The `context-only` option causes `sloglint` to report the use of methods without a context:
+Suggest using `slog.DiscardHandler` when possible.
```go
-slog.Info("a user has logged in") // sloglint: InfoContext should be used instead
+slog.NewJSONHandler(io.Discard, nil)
+// sloglint: use slog.DiscardHandler instead
```
-Possible values are `all` (report all contextless calls) and `scope` (report only if a context exists in the scope of the outermost function).
+This check is enabled by default and supports autofix.
-### Static messages
+### Static message
-To get the most out of structured logging, you may want to require log messages to be static.
-The `static-msg` option causes `sloglint` to report non-static messages:
+Report dynamic log messages, such as those that are built with `fmt.Sprintf`.
```go
-slog.Info(fmt.Sprintf("a user with id %d has logged in", 42)) // sloglint: message should be a string literal or a constant
+slog.Info(fmt.Sprintf("a user with id %d has logged in", 42))
+// sloglint: message should be a string literal or a constant
+```
+
+```yaml
+# .golangci.yaml
+linters:
+ settings:
+ sloglint:
+ static-msg: true
```
-The report can be fixed by moving dynamic values to arguments:
+### Message style
+
+Report log messages that do not match a particular style.
+The supported styles are `lowercased` (the first letter is lowercase) and `capitalized` (the first letter is uppercase).
```go
-slog.Info("a user has logged in", "user_id", 42)
+slog.Info("A user has logged in")
+// sloglint: message should be lowercased
```
-### Message style
+```yaml
+# .golangci.yaml
+linters:
+ settings:
+ sloglint:
+ msg-style: "lowercased" # Or "capitalized".
+```
-The `msg-style` option causes `sloglint` to check log messages for a particular style.
+### No mixed arguments
-Possible values are `lowercased` (report messages that begin with an uppercase letter)...
+Report the use of both key-value pairs and attributes within a single function call.
```go
-slog.Info("Msg") // sloglint: message should be lowercased
+slog.Info("a user has logged in", "user_id", 42, slog.String("ip_address", "192.0.2.0"))
+// sloglint: key-value pairs and attributes should not be mixed
```
-...and `capitalized` (report messages that begin with a lowercase letter):
+This check is enabled by default.
+
+### Key-value pairs only
+
+Report any use of attributes as function call arguments.
```go
-slog.Info("msg") // sloglint: message should be capitalized
+slog.Info("a user has logged in", slog.Int("user_id", 42))
+// sloglint: attributes should not be used
```
-Special cases such as acronyms (e.g. `HTTP`, `U.S.`) are ignored.
+```yaml
+# .golangci.yaml
+linters:
+ settings:
+ sloglint:
+ kv-only: true
+```
-### No raw keys
+### Attributes only
-To prevent typos, you may want to forbid the use of raw keys altogether.
-The `no-raw-keys` option causes `sloglint` to report the use of strings as keys
-(including `slog.Attr` calls, e.g. `slog.Int("user_id", 42)`):
+Report any use of key-value pairs as function call arguments.
```go
-slog.Info("a user has logged in", "user_id", 42) // sloglint: raw keys should not be used
+slog.Info("a user has logged in", "user_id", 42)
+// sloglint: key-value pairs should not be used
+```
+
+```yaml
+# .golangci.yaml
+linters:
+ settings:
+ sloglint:
+ attr-only: true
```
-This report can be fixed by using either constants...
+### Arguments on separate lines
+
+Report two or more arguments on the same line.
+A key-value pair is considered a single argument.
```go
-const UserId = "user_id"
+slog.Info("a user has logged in", "user_id", 42, "ip_address", "192.0.2.0")
+// sloglint: arguments should be put on separate lines
+```
-slog.Info("a user has logged in", UserId, 42)
+```yaml
+# .golangci.yaml
+linters:
+ settings:
+ sloglint:
+ args-on-sep-lines: true
```
-...or custom `slog.Attr` constructors:
+### Constant keys
-```go
-func UserId(value int) slog.Attr { return slog.Int("user_id", value) }
+Report the use of string literals as log keys.
-slog.Info("a user has logged in", UserId(42))
+```go
+slog.Info("a user has logged in", "user_id", 42)
+// sloglint: the "user_id" key should be a constant
```
-> [!TIP]
-> Such helpers can be automatically generated for you by the [`sloggen`][4] tool. Give it a try too!
+```yaml
+# .golangci.yaml
+linters:
+ settings:
+ sloglint:
+ no-raw-keys: true
+```
-### Key naming convention
+### Allowed keys
-To ensure consistency in logs, you may want to enforce a single key naming convention.
-The `key-naming-case` option causes `sloglint` to report keys written in a case other than the given one:
+Report the use of log keys that are not explicitly allowed.
```go
-slog.Info("a user has logged in", "user-id", 42) // sloglint: keys should be written in snake_case
+slog.Info("a user has logged in", "id", 42)
+// sloglint: the "id" key is not allowed and should not be used
```
-Possible values are `snake`, `kebab`, `camel`, or `pascal`.
+```yaml
+# .golangci.yaml
+linters:
+ settings:
+ sloglint:
+ allowed-keys:
+ - user_id
+```
### Forbidden keys
-To prevent accidental use of reserved log keys, you may want to forbid specific keys altogether.
-The `forbidden-keys` option causes `sloglint` to report the use of forbidden keys:
+Report the use of forbidden log keys.
+When using the standard `slog.JSONHandler` or `slog.TextHandler`,
+you may want to forbid the `time`, `level`, `msg`, and `source` keys,
+as these will be written by the handler.
```go
-slog.Info("a user has logged in", "reserved", 42) // sloglint: "reserved" key is forbidden and should not be used
+slog.Info("a user has logged in", "time", time.Now())
+// sloglint: the "time" key is forbidden and should not be used
```
-For example, when using the standard `slog.JSONHandler` and `slog.TextHandler`,
-you may want to forbid the `time`, `level`, `msg`, and `source` keys, as these are used by the handlers.
+```yaml
+# .golangci.yaml
+linters:
+ settings:
+ sloglint:
+ forbidden-keys:
+ - time
+ - level
+ - msg
+ - source
+```
-### Arguments on separate lines
+### Key naming case
-To improve code readability, you may want to put arguments on separate lines, especially when using key-value pairs.
-The `args-on-sep-lines` option causes `sloglint` to report 2+ arguments on the same line:
+Report log keys that do not match a particular naming case.
+The supported cases are `snake_case`, `kebab-case`, `camelCase`, and `PascalCase`.
```go
-slog.Info("a user has logged in", "user_id", 42, "ip_address", "192.0.2.0") // sloglint: arguments should be put on separate lines
+slog.Info("a user has logged in", "user-id", 42)
+// sloglint: keys should be written in snake_case
```
-This report can be fixed by reformatting the code:
-
-```go
-slog.Info("a user has logged in",
- "user_id", 42,
- "ip_address", "192.0.2.0",
-)
+```yaml
+# .golangci.yaml
+linters:
+ settings:
+ sloglint:
+ key-naming-case: "snake" # Or "kebab", "camel", "pascal".
```
-[1]: https://golangci-lint.run
-[2]: https://github.com/go-simpler/sloglint/releases
-[3]: https://golangci-lint.run/usage/linters/#sloglint
-[4]: https://github.com/go-simpler/sloggen
+This check supports autofix.
+
+## Custom function analysis
+
+Analyze custom functions in addition to the standard `log/slog` functions.
+
+The following function properties must be specified:
+1. The full name of the function, including the package, e.g. `log/slog.Info`.
+If the function is a method, the receiver type must be wrapped in parentheses, e.g. `(*log/slog.Logger).Info`.
+2. The position of the `msg string` argument in the function signature, starting from 0.
+If there is no message in the function, a negative value must be passed.
+3. The position of the `args ...any` argument in the function signature, starting from 0.
+If there are no arguments in the function, a negative value must be passed.
+
+Here's an example for the [exp/slog](https://pkg.go.dev/golang.org/x/exp/slog) package, the predecessor of `log/slog`.
+
+```yaml
+# .golangci.yaml
+linters:
+ settings:
+ sloglint:
+ custom-funcs:
+ - name: "(*golang.org/x/exp/slog.Logger).InfoContext"
+ msg-pos: 1
+ args-pos: 2
+```
diff --git a/vendor/go-simpler.org/sloglint/analyzer.go b/vendor/go-simpler.org/sloglint/analyzer.go
new file mode 100644
index 000000000..03e43e02c
--- /dev/null
+++ b/vendor/go-simpler.org/sloglint/analyzer.go
@@ -0,0 +1,209 @@
+// Package sloglint implements the sloglint analyzer.
+package sloglint
+
+import (
+ "go/ast"
+ "go/version"
+ "slices"
+
+ "golang.org/x/tools/go/analysis"
+ "golang.org/x/tools/go/analysis/passes/inspect"
+ "golang.org/x/tools/go/ast/inspector"
+ "golang.org/x/tools/go/types/typeutil"
+)
+
+// New creates a new sloglint analyzer.
+func New(opts *Options) *analysis.Analyzer {
+ if opts == nil {
+ opts = &Options{NoMixedArguments: true}
+ }
+
+ return &analysis.Analyzer{
+ Name: "sloglint",
+ Doc: "Ensures consistent code style when using log/slog.",
+ URL: "https://go-simpler.org/sloglint",
+ Flags: flags(opts),
+ Requires: []*analysis.Analyzer{inspect.Analyzer},
+ Run: func(pass *analysis.Pass) (any, error) {
+ if err := opts.validate(); err != nil {
+ return nil, err
+ }
+
+ root := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector).Root()
+ for cursor := range root.Preorder(new(ast.CallExpr), new(ast.CompositeLit)) {
+ analyzeNode(pass, opts, cursor)
+ }
+
+ return nil, nil
+ },
+ }
+}
+
+var slogFuncs = []Func{
+ {"log/slog.Log", 2, 3},
+ {"log/slog.LogAttrs", 2, 3},
+ {"log/slog.Debug", 0, 1},
+ {"log/slog.Info", 0, 1},
+ {"log/slog.Warn", 0, 1},
+ {"log/slog.Error", 0, 1},
+ {"log/slog.DebugContext", 1, 2},
+ {"log/slog.InfoContext", 1, 2},
+ {"log/slog.WarnContext", 1, 2},
+ {"log/slog.ErrorContext", 1, 2},
+ {"log/slog.With", -1, 0},
+ {"log/slog.Group", -1, 1},
+ {"log/slog.NewTextHandler", -1, -1},
+ {"log/slog.NewJSONHandler", -1, -1},
+ {"(*log/slog.Logger).Log", 2, 3},
+ {"(*log/slog.Logger).LogAttrs", 2, 3},
+ {"(*log/slog.Logger).Debug", 0, 1},
+ {"(*log/slog.Logger).Info", 0, 1},
+ {"(*log/slog.Logger).Warn", 0, 1},
+ {"(*log/slog.Logger).Error", 0, 1},
+ {"(*log/slog.Logger).DebugContext", 1, 2},
+ {"(*log/slog.Logger).InfoContext", 1, 2},
+ {"(*log/slog.Logger).WarnContext", 1, 2},
+ {"(*log/slog.Logger).ErrorContext", 1, 2},
+ {"(*log/slog.Logger).With", -1, 0},
+}
+
+func analyzeNode(pass *analysis.Pass, opts *Options, cursor inspector.Cursor) {
+ node := cursor.Node()
+ if cl, ok := node.(*ast.CompositeLit); ok && typeName(pass.TypesInfo, cl) == "log/slog.Attr" {
+ analyzeAttrKey(pass, opts, cl)
+ return
+ }
+
+ call, ok := node.(*ast.CallExpr)
+ if !ok {
+ return
+ }
+
+ fn := typeutil.StaticCallee(pass.TypesInfo, call)
+ if fn == nil {
+ return
+ }
+
+ switch fn.FullName() {
+ case "log/slog.Int",
+ "log/slog.Int64",
+ "log/slog.Uint64",
+ "log/slog.Float64",
+ "log/slog.String",
+ "log/slog.Bool",
+ "log/slog.Time",
+ "log/slog.Duration",
+ "log/slog.Any":
+ analyzeKey(pass, opts, call.Args[0])
+ return
+ case "log/slog.Group":
+ analyzeKey(pass, opts, call.Args[0])
+ // Special case: don't return here, we also need to analyze the group's arguments.
+ }
+
+ funcs := slices.Concat(slogFuncs, opts.CustomFuncs)
+ idx := slices.IndexFunc(funcs, func(f Func) bool {
+ return f.FullName == fn.FullName()
+ })
+ if idx == -1 {
+ return
+ }
+
+ if idx < len(slogFuncs) {
+ analyzeFunction(pass, opts, call, cursor)
+ }
+ if pos := funcs[idx].MessagePos; pos >= 0 && len(call.Args) > pos {
+ analyzeMessage(pass, opts, call.Args[pos])
+ }
+ if pos := funcs[idx].ArgumentsPos; pos >= 0 && len(call.Args) > pos {
+ analyzeArguments(pass, opts, call.Args[pos:])
+ }
+}
+
+func analyzeFunction(pass *analysis.Pass, opts *Options, call *ast.CallExpr, cursor inspector.Cursor) {
+ if opts.NoGlobalLogger != "" {
+ noGlobalLogger(pass, call, opts.NoGlobalLogger == noGlobalLoggerDefault)
+ }
+ if opts.ContextOnly != "" {
+ contextOnly(pass, call, cursor, opts.ContextOnly == contextOnlyScope)
+ }
+ v := pass.Module.GoVersion // Empty in test runs.
+ if v == "" || version.Compare("go"+v, "go1.24") >= 0 {
+ discardHandler(pass, call)
+ }
+}
+
+func analyzeMessage(pass *analysis.Pass, opts *Options, msg ast.Expr) {
+ if opts.StaticMessage {
+ staticMessage(pass, msg)
+ }
+ if opts.MessageStyle != "" {
+ messageStyle(pass, msg, opts.MessageStyle)
+ }
+}
+
+func analyzeArguments(pass *analysis.Pass, opts *Options, args []ast.Expr) {
+ var keys, attrs []ast.Expr
+
+ for i := 0; i < len(args); i++ {
+ typ := pass.TypesInfo.TypeOf(args[i])
+ if typ == nil {
+ continue
+ }
+ switch typ.String() {
+ case "string":
+ keys = append(keys, args[i])
+ analyzeKey(pass, opts, args[i])
+ i++ // Skip the value.
+ case "log/slog.Attr":
+ attrs = append(attrs, args[i])
+ case "[]any", "[]log/slog.Attr":
+ continue // The last argument may be an unpacked slice, skip it.
+ }
+ }
+
+ if opts.NoMixedArguments {
+ noMixedArguments(pass, keys, attrs)
+ }
+ if opts.KeyValuePairsOnly {
+ keyValuePairsOnly(pass, attrs)
+ }
+ if opts.AttributesOnly {
+ attributesOnly(pass, keys)
+ }
+ if opts.ArgumentsOnSeparateLines {
+ argumentsOnSeparateLines(pass, keys, attrs)
+ }
+}
+
+func analyzeKey(pass *analysis.Pass, opts *Options, key ast.Expr) {
+ if opts.ConstantKeys {
+ constantKeys(pass, key)
+ }
+ if opts.KeyNamingCase != "" {
+ keyNamingCase(pass, key, opts.KeyNamingCase)
+ }
+ if len(opts.AllowedKeys) > 0 {
+ allowedKeys(pass, key, opts.AllowedKeys)
+ }
+ if len(opts.ForbiddenKeys) > 0 {
+ forbiddenKeys(pass, key, opts.ForbiddenKeys)
+ }
+}
+
+func analyzeAttrKey(pass *analysis.Pass, opts *Options, attr *ast.CompositeLit) {
+ switch len(attr.Elts) {
+ case 1:
+ if kv := attr.Elts[0].(*ast.KeyValueExpr); kv.Key.(*ast.Ident).Name == "Key" {
+ analyzeKey(pass, opts, kv.Value) // slog.Attr{Key: ...}
+ }
+ case 2:
+ if kv, ok := attr.Elts[0].(*ast.KeyValueExpr); ok && kv.Key.(*ast.Ident).Name == "Key" {
+ analyzeKey(pass, opts, kv.Value) // slog.Attr{Key: ..., Value: ...}
+ } else if kv, ok := attr.Elts[1].(*ast.KeyValueExpr); ok && kv.Key.(*ast.Ident).Name == "Key" {
+ analyzeKey(pass, opts, kv.Value) // slog.Attr{Value: ..., Key: ...}
+ } else {
+ analyzeKey(pass, opts, attr.Elts[0]) // slog.Attr{..., ...}
+ }
+ }
+}
diff --git a/vendor/go-simpler.org/sloglint/argument_checks.go b/vendor/go-simpler.org/sloglint/argument_checks.go
new file mode 100644
index 000000000..17590d7e7
--- /dev/null
+++ b/vendor/go-simpler.org/sloglint/argument_checks.go
@@ -0,0 +1,55 @@
+package sloglint
+
+import (
+ "go/ast"
+ "slices"
+
+ "golang.org/x/tools/go/analysis"
+)
+
+func noMixedArguments(pass *analysis.Pass, keys, attrs []ast.Expr) {
+ if len(keys) == 0 {
+ return
+ }
+ for _, attr := range attrs {
+ if call, ok := attr.(*ast.CallExpr); ok && funcName(pass.TypesInfo, call) == "log/slog.Group" {
+ continue // Special case: slog.Group() should always be allowed.
+ }
+ pass.ReportRangef(attr, "key-value pairs and attributes should not be mixed")
+ return
+ }
+}
+
+func keyValuePairsOnly(pass *analysis.Pass, attrs []ast.Expr) {
+ for _, attr := range attrs {
+ if call, ok := attr.(*ast.CallExpr); ok && funcName(pass.TypesInfo, call) == "log/slog.Group" {
+ continue // Special case: slog.Group() should always be allowed.
+ }
+ pass.ReportRangef(attr, "attributes should not be used")
+ return
+ }
+}
+
+func attributesOnly(pass *analysis.Pass, keys []ast.Expr) {
+ for _, key := range keys {
+ pass.ReportRangef(key, "key-value pairs should not be used")
+ return
+ }
+}
+
+func argumentsOnSeparateLines(pass *analysis.Pass, keys, attrs []ast.Expr) {
+ args := slices.Concat(keys, attrs)
+ if len(args) <= 1 {
+ return // Special case: slog.Info("msg", "key", "value") is fine.
+ }
+
+ prevLine := pass.Fset.Position(args[0].Pos()).Line
+ for _, arg := range args[1:] {
+ currLine := pass.Fset.Position(arg.Pos()).Line
+ if currLine == prevLine {
+ pass.Reportf(arg.Pos(), "arguments should be put on separate lines")
+ return
+ }
+ prevLine = currLine
+ }
+}
diff --git a/vendor/go-simpler.org/sloglint/function_checks.go b/vendor/go-simpler.org/sloglint/function_checks.go
new file mode 100644
index 000000000..7781aba6a
--- /dev/null
+++ b/vendor/go-simpler.org/sloglint/function_checks.go
@@ -0,0 +1,144 @@
+package sloglint
+
+import (
+ "fmt"
+ "go/ast"
+
+ "golang.org/x/tools/go/analysis"
+ "golang.org/x/tools/go/ast/inspector"
+ "golang.org/x/tools/go/types/typeutil"
+)
+
+func noGlobalLogger(pass *analysis.Pass, call *ast.CallExpr, defaultOnly bool) {
+ fn := typeutil.StaticCallee(pass.TypesInfo, call)
+
+ switch fn.Name() {
+ case "Log", "LogAttrs",
+ "Debug", "Info", "Warn", "Error",
+ "DebugContext", "InfoContext", "WarnContext", "ErrorContext",
+ "With":
+ default:
+ return
+ }
+
+ sel, ok := call.Fun.(*ast.SelectorExpr)
+ if !ok {
+ return
+ }
+
+ ident, ok := sel.X.(*ast.Ident)
+ if !ok {
+ return
+ }
+
+ if ident.Name == "slog" {
+ pass.ReportRangef(sel.X, "default logger should not be used")
+ return
+ }
+
+ if defaultOnly {
+ return
+ }
+
+ if obj := pass.TypesInfo.ObjectOf(ident); obj != nil && obj.Parent() == obj.Pkg().Scope() {
+ pass.ReportRangef(sel.X, "global logger should not be used")
+ }
+}
+
+func contextOnly(pass *analysis.Pass, call *ast.CallExpr, cursor inspector.Cursor, scopeOnly bool) {
+ fn := typeutil.StaticCallee(pass.TypesInfo, call)
+
+ switch fn.Name() {
+ case "Debug", "Info", "Warn", "Error":
+ default:
+ return
+ }
+
+ sel, ok := call.Fun.(*ast.SelectorExpr)
+ if !ok {
+ return
+ }
+
+ if !scopeOnly {
+ // Don't suggest fixes here, we don't know whether there is a context in the scope.
+ pass.ReportRangef(sel.Sel, "%sContext should be used instead", fn.Name())
+ return
+ }
+
+ for cursor := range cursor.Enclosing(new(ast.FuncDecl), new(ast.FuncLit)) {
+ var params []*ast.Field
+ switch fn := cursor.Node().(type) {
+ case *ast.FuncDecl:
+ params = fn.Type.Params.List
+ case *ast.FuncLit:
+ params = fn.Type.Params.List
+ }
+
+ if len(params) == 0 {
+ continue
+ }
+
+ for _, param := range params {
+ if len(param.Names) == 0 {
+ continue
+ }
+
+ var ctxArg string
+ switch name := param.Names[0]; typeName(pass.TypesInfo, name) {
+ case "context.Context":
+ ctxArg = name.Name
+ case "*net/http.Request":
+ ctxArg = name.Name + ".Context()"
+ default:
+ continue
+ }
+
+ pass.Report(analysis.Diagnostic{
+ Pos: sel.Sel.Pos(),
+ End: sel.Sel.End(),
+ Message: fmt.Sprintf("%sContext should be used instead", fn.Name()),
+ SuggestedFixes: []analysis.SuggestedFix{{
+ TextEdits: []analysis.TextEdit{{
+ Pos: sel.Sel.Pos(),
+ End: call.Lparen + 1,
+ NewText: fmt.Appendf(nil, "%sContext(%s, ", fn.Name(), ctxArg),
+ }},
+ }},
+ })
+ return
+ }
+ }
+}
+
+func discardHandler(pass *analysis.Pass, call *ast.CallExpr) {
+ if len(call.Args) == 0 {
+ return
+ }
+
+ sel, ok := call.Args[0].(*ast.SelectorExpr)
+ if !ok {
+ return
+ }
+
+ obj := pass.TypesInfo.ObjectOf(sel.Sel)
+ if obj == nil {
+ return
+ }
+
+ if obj.Pkg().Name() != "io" || obj.Name() != "Discard" {
+ return
+ }
+
+ pass.Report(analysis.Diagnostic{
+ Pos: call.Pos(),
+ End: call.Pos(),
+ Message: "use slog.DiscardHandler instead",
+ SuggestedFixes: []analysis.SuggestedFix{{
+ TextEdits: []analysis.TextEdit{{
+ Pos: call.Pos(),
+ End: call.End(),
+ NewText: []byte("slog.DiscardHandler"),
+ }},
+ }},
+ })
+}
diff --git a/vendor/go-simpler.org/sloglint/key_checks.go b/vendor/go-simpler.org/sloglint/key_checks.go
new file mode 100644
index 000000000..c664a8424
--- /dev/null
+++ b/vendor/go-simpler.org/sloglint/key_checks.go
@@ -0,0 +1,73 @@
+package sloglint
+
+import (
+ "fmt"
+ "go/ast"
+ "go/types"
+ "slices"
+ "strconv"
+
+ "github.com/ettle/strcase"
+ "golang.org/x/tools/go/analysis"
+)
+
+func constantKeys(pass *analysis.Pass, key ast.Expr) {
+ if sel, ok := key.(*ast.SelectorExpr); ok {
+ key = sel.Sel // The key is defined in another package, e.g. pkg.ConstKey.
+ }
+ if ident, ok := key.(*ast.Ident); ok {
+ if _, ok := pass.TypesInfo.ObjectOf(ident).(*types.Const); ok {
+ return
+ }
+ }
+ name, _ := keyName(key)
+ pass.ReportRangef(key, "the %q key should be a constant", name)
+}
+
+func allowedKeys(pass *analysis.Pass, key ast.Expr, allowed []string) {
+ if name, ok := keyName(key); ok && !slices.Contains(allowed, name) {
+ pass.ReportRangef(key, "the %q key is not allowed and should not be used", name)
+ }
+}
+
+func forbiddenKeys(pass *analysis.Pass, key ast.Expr, forbidden []string) {
+ if name, ok := keyName(key); ok && slices.Contains(forbidden, name) {
+ pass.ReportRangef(key, "the %q key is forbidden and should not be used", name)
+ }
+}
+
+func keyNamingCase(pass *analysis.Pass, key ast.Expr, caseName string) {
+ name, ok := keyName(key)
+ if !ok {
+ return
+ }
+
+ var caseFn func(string) string
+ switch caseName {
+ case keyNamingCaseSnake:
+ caseFn = strcase.ToSnake
+ case keyNamingCaseKebab:
+ caseFn = strcase.ToKebab
+ case keyNamingCaseCamel:
+ caseFn = strcase.ToCamel
+ case keyNamingCasePascal:
+ caseFn = strcase.ToPascal
+ }
+
+ if name == caseFn(name) {
+ return
+ }
+
+ pass.Report(analysis.Diagnostic{
+ Pos: key.Pos(),
+ End: key.End(),
+ Message: fmt.Sprintf("keys should be written in %s", caseFn(caseName+" case")),
+ SuggestedFixes: []analysis.SuggestedFix{{
+ TextEdits: []analysis.TextEdit{{
+ Pos: key.Pos(),
+ End: key.End(),
+ NewText: strconv.AppendQuote(nil, caseFn(name)),
+ }},
+ }},
+ })
+}
diff --git a/vendor/go-simpler.org/sloglint/message_checks.go b/vendor/go-simpler.org/sloglint/message_checks.go
new file mode 100644
index 000000000..746745f0f
--- /dev/null
+++ b/vendor/go-simpler.org/sloglint/message_checks.go
@@ -0,0 +1,81 @@
+package sloglint
+
+import (
+ "go/ast"
+ "go/token"
+ "go/types"
+ "strconv"
+ "strings"
+ "unicode"
+
+ "golang.org/x/tools/go/analysis"
+)
+
+func staticMessage(pass *analysis.Pass, msg ast.Expr) {
+ var isStatic func(msg ast.Expr) bool
+ isStatic = func(msg ast.Expr) bool {
+ switch msg := msg.(type) {
+ case *ast.BasicLit: // e.g. slog.Info("msg")
+ return msg.Kind == token.STRING
+ case *ast.Ident: // e.g. slog.Info(constMsg)
+ _, isConst := pass.TypesInfo.ObjectOf(msg).(*types.Const)
+ return isConst
+ case *ast.BinaryExpr: // e.g. slog.Info("x" + "y")
+ if msg.Op != token.ADD {
+ panic("unreachable") // Only "+" can be applied to strings.
+ }
+ return isStatic(msg.X) && isStatic(msg.Y)
+ default:
+ return false
+ }
+ }
+
+ if !isStatic(msg) {
+ pass.ReportRangef(msg, "message should be a string literal or a constant")
+ }
+}
+
+func messageStyle(pass *analysis.Pass, msg ast.Expr, style string) {
+ lit, ok := msg.(*ast.BasicLit)
+ if !ok || lit.Kind != token.STRING {
+ return
+ }
+
+ s, err := strconv.Unquote(lit.Value)
+ if err != nil {
+ panic("unreachable") // String literals are always quoted.
+ }
+
+ runes := []rune(strings.TrimSpace(s))
+ if len(runes) < 2 {
+ return
+ }
+
+ first, second := runes[0], runes[1]
+
+ if !unicode.IsLetter(first) {
+ return // e.g. "200 OK"
+ }
+
+ switch style {
+ case messageStyleLowercased:
+ if unicode.IsLower(first) {
+ return
+ }
+ if unicode.IsPunct(second) {
+ return // e.g. "U.S."
+ }
+ if unicode.IsUpper(second) {
+ return // e.g. "HTTP"
+ }
+ case messageStyleCapitalized:
+ if unicode.IsUpper(first) {
+ return
+ }
+ if unicode.IsUpper(second) {
+ return // e.g. "iPhone"
+ }
+ }
+
+ pass.ReportRangef(msg, "message should be %s", style)
+}
diff --git a/vendor/go-simpler.org/sloglint/options.go b/vendor/go-simpler.org/sloglint/options.go
new file mode 100644
index 000000000..361eb5933
--- /dev/null
+++ b/vendor/go-simpler.org/sloglint/options.go
@@ -0,0 +1,152 @@
+package sloglint
+
+import (
+ "errors"
+ "flag"
+ "fmt"
+ "strings"
+)
+
+// Func describes a function to analyze, e.g. [slog.Info].
+type Func struct {
+ // The full name of the function, including the package, e.g. "log/slog.Info".
+ // If the function is a method, the receiver type must be wrapped in parentheses, e.g. "(*log/slog.Logger).Info".
+ FullName string
+ // The position of the "msg string" argument in the function signature, starting from 0.
+ // If there is no message in the function, a negative value must be passed.
+ MessagePos int
+ // The position of the "args ...any" argument in the function signature, starting from 0.
+ // If there are no arguments in the function, a negative value must be passed.
+ ArgumentsPos int
+}
+
+// Options contains options for the sloglint analyzer.
+type Options struct {
+ // Report the use of global loggers ("all" or "default").
+ NoGlobalLogger string
+ // Report the use of functions without a [context.Context] ("all" or "scope").
+ ContextOnly string
+
+ // Report dynamic log messages, such as those that are built with [fmt.Sprintf].
+ StaticMessage bool
+ // Report log messages that do not match a particular style ("lowercased" or "capitalized").
+ MessageStyle string
+
+ // Report the use of both key-value pairs and attributes within a single function call (default true).
+ NoMixedArguments bool
+ // Report any use of attributes as function call arguments.
+ KeyValuePairsOnly bool
+ // Report any use of key-value pairs as function call arguments.
+ AttributesOnly bool
+ // Report two or more arguments on the same line.
+ ArgumentsOnSeparateLines bool
+
+ // Report the use of string literals as log keys.
+ ConstantKeys bool
+ // Report the use of log keys that are not explicitly allowed.
+ AllowedKeys []string
+ // Report the use of forbidden log keys.
+ ForbiddenKeys []string
+ // Report log keys that do not match a particular naming case ("snake", "kebab", "camel", or "pascal").
+ KeyNamingCase string
+
+ // Analyze custom functions in addition to the standard [log/slog] functions.
+ CustomFuncs []Func
+}
+
+// Possible values for [Options.NoGlobalLogger].
+const (
+ noGlobalLoggerAll = "all"
+ noGlobalLoggerDefault = "default"
+)
+
+// Possible values for [Options.ContextOnly].
+const (
+ contextOnlyAll = "all"
+ contextOnlyScope = "scope"
+)
+
+// Possible values for [Options.MessageStyle].
+const (
+ messageStyleLowercased = "lowercased"
+ messageStyleCapitalized = "capitalized"
+)
+
+// Possible values for [Options.KeyNamingCase].
+const (
+ keyNamingCaseSnake = "snake"
+ keyNamingCaseKebab = "kebab"
+ keyNamingCaseCamel = "camel"
+ keyNamingCasePascal = "pascal"
+)
+
+var (
+ errIncompatible = errors.New("incompatible")
+ errInvalidValue = errors.New("invalid value")
+)
+
+func (opts *Options) validate() error {
+ switch opts.NoGlobalLogger {
+ case "", noGlobalLoggerAll, noGlobalLoggerDefault:
+ default:
+ return fmt.Errorf("sloglint: Options.NoGlobalLogger has an %w %q", errInvalidValue, opts.NoGlobalLogger)
+ }
+
+ switch opts.ContextOnly {
+ case "", contextOnlyAll, contextOnlyScope:
+ default:
+ return fmt.Errorf("sloglint: Options.ContextOnly has an %w %q", errInvalidValue, opts.ContextOnly)
+ }
+
+ switch opts.MessageStyle {
+ case "", messageStyleLowercased, messageStyleCapitalized:
+ default:
+ return fmt.Errorf("sloglint: Options.MessageStyle has an %w %q", errInvalidValue, opts.MessageStyle)
+ }
+
+ if opts.KeyValuePairsOnly && opts.AttributesOnly {
+ return fmt.Errorf("sloglint: Options.KeyValuePairsOnly and Options.AttributesOnly are %w", errIncompatible)
+ }
+
+ switch opts.KeyNamingCase {
+ case "", keyNamingCaseSnake, keyNamingCaseKebab, keyNamingCaseCamel, keyNamingCasePascal:
+ default:
+ return fmt.Errorf("sloglint: Options.KeyNamingCase has an %w %q", errInvalidValue, opts.KeyNamingCase)
+ }
+
+ return nil
+}
+
+func flags(opts *Options) flag.FlagSet {
+ fs := flag.NewFlagSet("sloglint", flag.ContinueOnError)
+
+ listVar := func(p *[]string, name, usage string) {
+ fs.Func(name, usage+" (comma-separated)", func(s string) error {
+ *p = append(*p, strings.Split(s, ",")...)
+ return nil
+ })
+ }
+
+ fs.StringVar(&opts.NoGlobalLogger, "no-global", opts.NoGlobalLogger, `report the use of global loggers ("all" or "default")`)
+ fs.StringVar(&opts.ContextOnly, "ctx-only", opts.ContextOnly, `report the use of functions without a context.Context ("all" or "scope")`)
+ fs.BoolVar(&opts.StaticMessage, "static-msg", opts.StaticMessage, `report dynamic log messages, such as those that are built with fmt.Sprintf`)
+ fs.StringVar(&opts.MessageStyle, "msg-style", opts.MessageStyle, `report log messages that do not match a particular style ("lowercased" or "capitalized")`)
+ fs.BoolVar(&opts.NoMixedArguments, "no-mixed-args", opts.NoMixedArguments, `report the use of both key-value pairs and attributes within a single function call (default true)`)
+ fs.BoolVar(&opts.KeyValuePairsOnly, "kv-only", opts.KeyValuePairsOnly, `report any use of attributes as function call arguments`)
+ fs.BoolVar(&opts.AttributesOnly, "attr-only", opts.AttributesOnly, `report any use of key-value pairs as function call arguments`)
+ fs.BoolVar(&opts.ArgumentsOnSeparateLines, "args-on-sep-lines", opts.ArgumentsOnSeparateLines, `report two or more arguments on the same line`)
+ fs.BoolVar(&opts.ConstantKeys, "const-keys", opts.ConstantKeys, `report the use of string literal as log keys`)
+ listVar(&opts.AllowedKeys, "allowed-keys", `report the use of log keys that are not explicitly allowed`)
+ listVar(&opts.ForbiddenKeys, "forbidden-keys", `report the use of forbidden log keys`)
+ fs.StringVar(&opts.KeyNamingCase, "key-naming-case", opts.KeyNamingCase, `report log keys that do not match a particular naming case ("snake", "kebab", "camel", or "pascal")`)
+
+ fs.Func("fn", `analyze a custom function (format: "full-name:msg-pos:args-pos")`, func(s string) error {
+ name, rest, _ := strings.Cut(s, ":")
+ fn := Func{FullName: name}
+ _, err := fmt.Sscanf(rest, "%d:%d", &fn.MessagePos, &fn.ArgumentsPos)
+ opts.CustomFuncs = append(opts.CustomFuncs, fn)
+ return err
+ })
+
+ return *fs
+}
diff --git a/vendor/go-simpler.org/sloglint/sloglint.go b/vendor/go-simpler.org/sloglint/sloglint.go
deleted file mode 100644
index ff5d1f80c..000000000
--- a/vendor/go-simpler.org/sloglint/sloglint.go
+++ /dev/null
@@ -1,576 +0,0 @@
-// Package sloglint implements the sloglint analyzer.
-package sloglint
-
-import (
- "errors"
- "flag"
- "fmt"
- "go/ast"
- "go/token"
- "go/types"
- "go/version"
- "iter"
- "slices"
- "strconv"
- "strings"
- "unicode"
-
- "github.com/ettle/strcase"
- "golang.org/x/tools/go/analysis"
- "golang.org/x/tools/go/analysis/passes/inspect"
- "golang.org/x/tools/go/ast/inspector"
- "golang.org/x/tools/go/types/typeutil"
-)
-
-// Options are options for the sloglint analyzer.
-type Options struct {
- NoMixedArgs bool // Enforce not mixing key-value pairs and attributes (default true).
- KVOnly bool // Enforce using key-value pairs only (overrides NoMixedArgs, incompatible with AttrOnly).
- AttrOnly bool // Enforce using attributes only (overrides NoMixedArgs, incompatible with KVOnly).
- NoGlobal string // Enforce not using global loggers ("all" or "default").
- ContextOnly string // Enforce using methods that accept a context ("all" or "scope").
- StaticMsg bool // Enforce using static messages.
- MsgStyle string // Enforce message style ("lowercased" or "capitalized").
- NoRawKeys bool // Enforce using constants instead of raw keys.
- KeyNamingCase string // Enforce key naming convention ("snake", "kebab", "camel", or "pascal").
- ForbiddenKeys []string // Enforce not using specific keys.
- ArgsOnSepLines bool // Enforce putting arguments on separate lines.
-
- go124 bool
-}
-
-// New creates a new sloglint analyzer.
-func New(opts *Options) *analysis.Analyzer {
- if opts == nil {
- opts = &Options{NoMixedArgs: true}
- }
-
- return &analysis.Analyzer{
- Name: "sloglint",
- Doc: "ensure consistent code style when using log/slog",
- Flags: flags(opts),
- Requires: []*analysis.Analyzer{inspect.Analyzer},
- Run: func(pass *analysis.Pass) (any, error) {
- if opts.KVOnly && opts.AttrOnly {
- return nil, fmt.Errorf("sloglint: Options.KVOnly and Options.AttrOnly: %w", errIncompatible)
- }
-
- switch opts.NoGlobal {
- case "", "all", "default":
- default:
- return nil, fmt.Errorf("sloglint: Options.NoGlobal=%s: %w", opts.NoGlobal, errInvalidValue)
- }
-
- switch opts.ContextOnly {
- case "", "all", "scope":
- default:
- return nil, fmt.Errorf("sloglint: Options.ContextOnly=%s: %w", opts.ContextOnly, errInvalidValue)
- }
-
- switch opts.MsgStyle {
- case "", styleLowercased, styleCapitalized:
- default:
- return nil, fmt.Errorf("sloglint: Options.MsgStyle=%s: %w", opts.MsgStyle, errInvalidValue)
- }
-
- switch opts.KeyNamingCase {
- case "", snakeCase, kebabCase, camelCase, pascalCase:
- default:
- return nil, fmt.Errorf("sloglint: Options.KeyNamingCase=%s: %w", opts.KeyNamingCase, errInvalidValue)
- }
-
- if version.Compare("go"+pass.Module.GoVersion, "go1.24") >= 0 {
- opts.go124 = true
- }
-
- run(pass, opts)
- return nil, nil
- },
- }
-}
-
-var (
- errIncompatible = errors.New("incompatible options")
- errInvalidValue = errors.New("invalid value")
-)
-
-func flags(opts *Options) flag.FlagSet {
- fset := flag.NewFlagSet("sloglint", flag.ContinueOnError)
-
- boolVar := func(value *bool, name, usage string) {
- fset.Func(name, usage, func(s string) error {
- v, err := strconv.ParseBool(s)
- *value = v
- return err
- })
- }
-
- strVar := func(value *string, name, usage string) {
- fset.Func(name, usage, func(s string) error {
- *value = s
- return nil
- })
- }
-
- boolVar(&opts.NoMixedArgs, "no-mixed-args", "enforce not mixing key-value pairs and attributes (default true)")
- boolVar(&opts.KVOnly, "kv-only", "enforce using key-value pairs only (overrides -no-mixed-args, incompatible with -attr-only)")
- boolVar(&opts.AttrOnly, "attr-only", "enforce using attributes only (overrides -no-mixed-args, incompatible with -kv-only)")
- strVar(&opts.NoGlobal, "no-global", "enforce not using global loggers (all|default)")
- strVar(&opts.ContextOnly, "context-only", "enforce using methods that accept a context (all|scope)")
- boolVar(&opts.StaticMsg, "static-msg", "enforce using static messages")
- strVar(&opts.MsgStyle, "msg-style", "enforce message style (lowercased|capitalized)")
- boolVar(&opts.NoRawKeys, "no-raw-keys", "enforce using constants instead of raw keys")
- strVar(&opts.KeyNamingCase, "key-naming-case", "enforce key naming convention (snake|kebab|camel|pascal)")
- boolVar(&opts.ArgsOnSepLines, "args-on-sep-lines", "enforce putting arguments on separate lines")
-
- fset.Func("forbidden-keys", "enforce not using specific keys (comma-separated)", func(s string) error {
- opts.ForbiddenKeys = append(opts.ForbiddenKeys, strings.Split(s, ",")...)
- return nil
- })
-
- return *fset
-}
-
-var slogFuncs = map[string]struct {
- argsPos int
- skipContextCheck bool
-}{
- "log/slog.With": {argsPos: 0, skipContextCheck: true},
- "log/slog.Log": {argsPos: 3},
- "log/slog.LogAttrs": {argsPos: 3},
- "log/slog.Debug": {argsPos: 1},
- "log/slog.Info": {argsPos: 1},
- "log/slog.Warn": {argsPos: 1},
- "log/slog.Error": {argsPos: 1},
- "log/slog.DebugContext": {argsPos: 2},
- "log/slog.InfoContext": {argsPos: 2},
- "log/slog.WarnContext": {argsPos: 2},
- "log/slog.ErrorContext": {argsPos: 2},
- "(*log/slog.Logger).With": {argsPos: 0, skipContextCheck: true},
- "(*log/slog.Logger).Log": {argsPos: 3},
- "(*log/slog.Logger).LogAttrs": {argsPos: 3},
- "(*log/slog.Logger).Debug": {argsPos: 1},
- "(*log/slog.Logger).Info": {argsPos: 1},
- "(*log/slog.Logger).Warn": {argsPos: 1},
- "(*log/slog.Logger).Error": {argsPos: 1},
- "(*log/slog.Logger).DebugContext": {argsPos: 2},
- "(*log/slog.Logger).InfoContext": {argsPos: 2},
- "(*log/slog.Logger).WarnContext": {argsPos: 2},
- "(*log/slog.Logger).ErrorContext": {argsPos: 2},
-}
-
-var attrFuncs = map[string]struct{}{
- "log/slog.String": {},
- "log/slog.Int64": {},
- "log/slog.Int": {},
- "log/slog.Uint64": {},
- "log/slog.Float64": {},
- "log/slog.Bool": {},
- "log/slog.Time": {},
- "log/slog.Duration": {},
- "log/slog.Group": {},
- "log/slog.Any": {},
-}
-
-// message styles.
-const (
- styleLowercased = "lowercased"
- styleCapitalized = "capitalized"
-)
-
-// key naming conventions.
-const (
- snakeCase = "snake"
- kebabCase = "kebab"
- camelCase = "camel"
- pascalCase = "pascal"
-)
-
-func run(pass *analysis.Pass, opts *Options) {
- visitor := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector)
- filter := []ast.Node{(*ast.CallExpr)(nil)}
-
- // WithStack is ~2x slower than Preorder, use it only when stack is needed.
- if opts.ContextOnly == "scope" {
- visitor.WithStack(filter, func(node ast.Node, _ bool, stack []ast.Node) bool {
- visit(pass, opts, node, stack)
- return false
- })
- return
- }
-
- visitor.Preorder(filter, func(node ast.Node) {
- visit(pass, opts, node, nil)
- })
-}
-
-// NOTE: stack is nil if Preorder is used.
-func visit(pass *analysis.Pass, opts *Options, node ast.Node, stack []ast.Node) {
- call := node.(*ast.CallExpr)
-
- fn := typeutil.StaticCallee(pass.TypesInfo, call)
- if fn == nil {
- return
- }
-
- name := fn.FullName()
-
- checkDiscardHandler(opts, pass, name, call)
-
- funcInfo, ok := slogFuncs[name]
- if !ok {
- return
- }
-
- switch opts.NoGlobal {
- case "all":
- if strings.HasPrefix(name, "log/slog.") || isGlobalLoggerUsed(pass.TypesInfo, call.Fun) {
- pass.Reportf(call.Pos(), "global logger should not be used")
- }
- case "default":
- if strings.HasPrefix(name, "log/slog.") {
- pass.Reportf(call.Pos(), "default logger should not be used")
- }
- }
-
- // NOTE: "With" functions are not checked for context.Context.
- if !funcInfo.skipContextCheck {
- switch opts.ContextOnly {
- case "all":
- typ := pass.TypesInfo.TypeOf(call.Args[0])
- if typ != nil && typ.String() != "context.Context" {
- pass.Reportf(call.Pos(), "%sContext should be used instead", fn.Name())
- }
- case "scope":
- typ := pass.TypesInfo.TypeOf(call.Args[0])
- if typ != nil && typ.String() != "context.Context" && isContextInScope(pass.TypesInfo, stack) {
- pass.Reportf(call.Pos(), "%sContext should be used instead", fn.Name())
- }
- }
- }
-
- msgPos := funcInfo.argsPos - 1
-
- // NOTE: "With" functions have no message argument and must be skipped.
- if opts.StaticMsg && msgPos >= 0 && !isStaticMsg(pass.TypesInfo, call.Args[msgPos]) {
- pass.Reportf(call.Args[msgPos].Pos(), "message should be a string literal or a constant")
- }
-
- if opts.MsgStyle != "" && msgPos >= 0 {
- if lit, ok := call.Args[msgPos].(*ast.BasicLit); ok && lit.Kind == token.STRING {
- value, err := strconv.Unquote(lit.Value)
- if err != nil {
- panic("unreachable") // string literals are always quoted.
- }
- if ok := isValidMsgStyle(value, opts.MsgStyle); !ok {
- pass.Reportf(call.Args[msgPos].Pos(), "message should be %s", opts.MsgStyle)
- }
- }
- }
-
- // NOTE: we assume that the arguments have already been validated by govet.
- args := call.Args[funcInfo.argsPos:]
- if len(args) == 0 {
- return
- }
-
- var keys []ast.Expr
- var attrs []ast.Expr
-
- for i := 0; i < len(args); i++ {
- typ := pass.TypesInfo.TypeOf(args[i])
- if typ == nil {
- continue
- }
- switch typ.String() {
- case "string":
- keys = append(keys, args[i])
- i++ // skip the value.
- case "log/slog.Attr":
- attrs = append(attrs, args[i])
- case "[]any", "[]log/slog.Attr":
- continue // the last argument may be an unpacked slice, skip it.
- }
- }
-
- switch {
- case opts.KVOnly && len(attrs) > 0:
- pass.Reportf(call.Pos(), "attributes should not be used")
- case opts.AttrOnly && len(keys) > 0:
- pass.Reportf(call.Pos(), "key-value pairs should not be used")
- case opts.NoMixedArgs && len(attrs) > 0 && len(keys) > 0:
- pass.Reportf(call.Pos(), "key-value pairs and attributes should not be mixed")
- }
-
- if opts.NoRawKeys {
- for key := range AllKeys(pass.TypesInfo, keys, attrs) {
- if sel, ok := key.(*ast.SelectorExpr); ok {
- key = sel.Sel // the key is defined in another package, e.g. pkg.ConstKey.
- }
-
- isConst := false
-
- if ident, ok := key.(*ast.Ident); ok {
- if obj := pass.TypesInfo.ObjectOf(ident); obj != nil {
- if _, ok := obj.(*types.Const); ok {
- isConst = true
- }
- }
- }
-
- if !isConst {
- pass.Reportf(key.Pos(), "raw keys should not be used")
- }
- }
- }
-
- checkKeysNaming(opts, pass, keys, attrs)
-
- if len(opts.ForbiddenKeys) > 0 {
- for key := range AllKeys(pass.TypesInfo, keys, attrs) {
- if name, ok := getKeyName(key); ok && slices.Contains(opts.ForbiddenKeys, name) {
- pass.Reportf(key.Pos(), "%q key is forbidden and should not be used", name)
- }
- }
- }
-
- if opts.ArgsOnSepLines && areArgsOnSameLine(pass.Fset, call, keys, attrs) {
- pass.Reportf(call.Pos(), "arguments should be put on separate lines")
- }
-}
-
-func checkKeysNaming(opts *Options, pass *analysis.Pass, keys, attrs []ast.Expr) {
- checkKeyNamingCase := func(caseFn func(string) string, caseName string) {
- for key := range AllKeys(pass.TypesInfo, keys, attrs) {
- name, ok := getKeyName(key)
- if !ok || name == caseFn(name) {
- return
- }
-
- pass.Report(analysis.Diagnostic{
- Pos: key.Pos(),
- Message: fmt.Sprintf("keys should be written in %s", caseName),
- SuggestedFixes: []analysis.SuggestedFix{{
- TextEdits: []analysis.TextEdit{{
- Pos: key.Pos(),
- End: key.End(),
- NewText: []byte(strconv.Quote(caseFn(name))),
- }},
- }},
- })
- }
- }
-
- switch opts.KeyNamingCase {
- case snakeCase:
- checkKeyNamingCase(strcase.ToSnake, "snake_case")
- case kebabCase:
- checkKeyNamingCase(strcase.ToKebab, "kebab-case")
- case camelCase:
- checkKeyNamingCase(strcase.ToCamel, "camelCase")
- case pascalCase:
- checkKeyNamingCase(strcase.ToPascal, "PascalCase")
- }
-}
-
-func checkDiscardHandler(opts *Options, pass *analysis.Pass, name string, call *ast.CallExpr) {
- if !opts.go124 {
- return
- }
-
- if name != "log/slog.NewTextHandler" && name != "log/slog.NewJSONHandler" {
- return
- }
-
- sel, ok := call.Args[0].(*ast.SelectorExpr)
- if !ok {
- return
- }
-
- obj := pass.TypesInfo.ObjectOf(sel.Sel)
- if obj == nil {
- return
- }
-
- if obj.Pkg().Name() != "io" || obj.Name() != "Discard" {
- return
- }
-
- pass.Report(analysis.Diagnostic{
- Pos: call.Pos(),
- Message: "use slog.DiscardHandler instead",
- SuggestedFixes: []analysis.SuggestedFix{{
- TextEdits: []analysis.TextEdit{{
- Pos: call.Pos(),
- End: call.End(),
- NewText: []byte("slog.DiscardHandler"),
- }},
- }},
- })
-}
-
-func isGlobalLoggerUsed(info *types.Info, call ast.Expr) bool {
- sel, ok := call.(*ast.SelectorExpr)
- if !ok {
- return false
- }
- ident, ok := sel.X.(*ast.Ident)
- if !ok {
- return false
- }
- obj := info.ObjectOf(ident)
- return obj.Parent() == obj.Pkg().Scope()
-}
-
-func isContextInScope(info *types.Info, stack []ast.Node) bool {
- for i := len(stack) - 1; i >= 0; i-- {
- decl, ok := stack[i].(*ast.FuncDecl)
- if !ok {
- continue
- }
- params := decl.Type.Params
- if len(params.List) == 0 || len(params.List[0].Names) == 0 {
- continue
- }
- typ := info.TypeOf(params.List[0].Names[0])
- if typ != nil && typ.String() == "context.Context" {
- return true
- }
- }
- return false
-}
-
-func isStaticMsg(info *types.Info, msg ast.Expr) bool {
- switch msg := msg.(type) {
- case *ast.BasicLit: // e.g. slog.Info("msg")
- return msg.Kind == token.STRING
- case *ast.Ident: // e.g. const msg = "msg"; slog.Info(msg)
- _, isConst := info.ObjectOf(msg).(*types.Const)
- return isConst
- case *ast.BinaryExpr: // e.g. slog.Info("x" + "y")
- if msg.Op != token.ADD {
- panic("unreachable") // only + can be applied to strings.
- }
- return isStaticMsg(info, msg.X) && isStaticMsg(info, msg.Y)
- default:
- return false
- }
-}
-
-func isValidMsgStyle(msg, style string) bool {
- runes := []rune(msg)
- if len(runes) < 2 {
- return true
- }
-
- first, second := runes[0], runes[1]
-
- switch style {
- case styleLowercased:
- if unicode.IsLower(first) {
- return true
- }
- if unicode.IsPunct(second) {
- return true // e.g. "U.S.A."
- }
- return unicode.IsUpper(second) // e.g. "HTTP"
- case styleCapitalized:
- if unicode.IsUpper(first) {
- return true
- }
- return unicode.IsUpper(second) // e.g. "iPhone"
- default:
- panic("unreachable")
- }
-}
-
-func AllKeys(info *types.Info, keys, attrs []ast.Expr) iter.Seq[ast.Expr] {
- return func(yield func(key ast.Expr) bool) {
- for _, key := range keys {
- if !yield(key) {
- return
- }
- }
-
- for _, attr := range attrs {
- switch attr := attr.(type) {
- case *ast.CallExpr: // e.g. slog.Int()
- callee := typeutil.StaticCallee(info, attr)
- if callee == nil {
- continue
- }
- if _, ok := attrFuncs[callee.FullName()]; !ok {
- continue
- }
-
- if !yield(attr.Args[0]) {
- return
- }
-
- case *ast.CompositeLit: // slog.Attr{}
- switch len(attr.Elts) {
- case 1: // slog.Attr{Key: ...} | slog.Attr{Value: ...}
- if kv := attr.Elts[0].(*ast.KeyValueExpr); kv.Key.(*ast.Ident).Name == "Key" {
- if !yield(kv.Value) {
- return
- }
- }
-
- case 2: // slog.Attr{Key: ..., Value: ...} | slog.Attr{Value: ..., Key: ...} | slog.Attr{..., ...}
- if kv, ok := attr.Elts[0].(*ast.KeyValueExpr); ok && kv.Key.(*ast.Ident).Name == "Key" {
- if !yield(kv.Value) {
- return
- }
- } else if kv, ok := attr.Elts[1].(*ast.KeyValueExpr); ok && kv.Key.(*ast.Ident).Name == "Key" {
- if !yield(kv.Value) {
- return
- }
- } else {
- if !yield(attr.Elts[0]) {
- return
- }
- }
- }
- }
- }
- }
-}
-
-func getKeyName(key ast.Expr) (string, bool) {
- if ident, ok := key.(*ast.Ident); ok {
- if ident.Obj == nil || ident.Obj.Decl == nil || ident.Obj.Kind != ast.Con {
- return "", false
- }
- if spec, ok := ident.Obj.Decl.(*ast.ValueSpec); ok && len(spec.Values) > 0 {
- // TODO: support len(spec.Values) > 1; e.g. const foo, bar = 1, 2
- key = spec.Values[0]
- }
- }
- if lit, ok := key.(*ast.BasicLit); ok && lit.Kind == token.STRING {
- value, err := strconv.Unquote(lit.Value)
- if err != nil {
- panic("unreachable") // string literals are always quoted.
- }
- return value, true
- }
- return "", false
-}
-
-func areArgsOnSameLine(fset *token.FileSet, call ast.Expr, keys, attrs []ast.Expr) bool {
- if len(keys)+len(attrs) <= 1 {
- return false // special case: slog.Info("msg", "key", "value") is ok.
- }
-
- args := slices.Concat([]ast.Expr{call}, keys, attrs)
-
- lines := make(map[int]struct{}, len(args))
- for _, arg := range args {
- line := fset.Position(arg.Pos()).Line
- if _, ok := lines[line]; ok {
- return true
- }
- lines[line] = struct{}{}
- }
-
- return false
-}
diff --git a/vendor/go-simpler.org/sloglint/utils.go b/vendor/go-simpler.org/sloglint/utils.go
new file mode 100644
index 000000000..7e86e7726
--- /dev/null
+++ b/vendor/go-simpler.org/sloglint/utils.go
@@ -0,0 +1,47 @@
+package sloglint
+
+import (
+ "go/ast"
+ "go/token"
+ "go/types"
+ "strconv"
+
+ "golang.org/x/tools/go/types/typeutil"
+)
+
+func typeName(info *types.Info, expr ast.Expr) string {
+ if typ := info.TypeOf(expr); typ != nil {
+ return typ.String()
+ }
+ return ""
+}
+
+func funcName(info *types.Info, call *ast.CallExpr) string {
+ if fn := typeutil.StaticCallee(info, call); fn != nil {
+ return fn.FullName()
+ }
+ return ""
+}
+
+func keyName(key ast.Expr) (string, bool) {
+ if ident, ok := key.(*ast.Ident); ok {
+ if ident.Obj == nil || ident.Obj.Decl == nil || ident.Obj.Kind != ast.Con {
+ return "", false
+ }
+ if spec, ok := ident.Obj.Decl.(*ast.ValueSpec); ok && len(spec.Values) > 0 {
+ key = spec.Values[0] // TODO: Support len(spec.Values) > 1; e.g. const foo, bar = 1, 2.
+ }
+ }
+
+ lit, ok := key.(*ast.BasicLit)
+ if !ok || lit.Kind != token.STRING {
+ return "", false
+ }
+
+ name, err := strconv.Unquote(lit.Value)
+ if err != nil {
+ panic("unreachable") // String literals are always quoted.
+ }
+
+ return name, true
+}
diff --git a/vendor/go.augendre.info/arangolint/pkg/analyzer/analyzer.go b/vendor/go.augendre.info/arangolint/pkg/analyzer/analyzer.go
index 53f19e2e6..6eebe4880 100644
--- a/vendor/go.augendre.info/arangolint/pkg/analyzer/analyzer.go
+++ b/vendor/go.augendre.info/arangolint/pkg/analyzer/analyzer.go
@@ -23,12 +23,19 @@ import (
)
const (
- allowImplicitFieldName = "AllowImplicit"
- msgMissingAllowImplicit = "missing AllowImplicit option"
- methodBeginTransaction = "BeginTransaction"
- expectedBeginTxnArgs = 3
- arangoDatabaseTypeSuffix = "github.com/arangodb/go-driver/v2/arangodb.Database"
- arangoPackageSuffix = "github.com/arangodb/go-driver/v2/arangodb"
+ allowImplicitFieldName = "AllowImplicit"
+ msgMissingAllowImplicit = "missing AllowImplicit option"
+ msgQueryConcatenation = "query string uses concatenation instead of bind variables"
+ methodBeginTransaction = "BeginTransaction"
+ methodQuery = "Query"
+ methodQueryBatch = "QueryBatch"
+ methodValidateQuery = "ValidateQuery"
+ methodExplainQuery = "ExplainQuery"
+ expectedBeginTxnArgs = 3
+ arangoDatabaseTypeSuffix = "github.com/arangodb/go-driver/v2/arangodb.Database"
+ arangoTransactionTypeSuffix = "github.com/arangodb/go-driver/v2/arangodb.Transaction"
+ arangoPackageSuffix = "github.com/arangodb/go-driver/v2/arangodb"
+ fmtPackagePath = "fmt"
)
var errInvalidAnalysis = errors.New("invalid analysis")
@@ -59,6 +66,7 @@ func run(pass *analysis.Pass) (interface{}, error) {
// node is guaranteed to be *ast.CallExpr due to the filter above.
call := node.(*ast.CallExpr) //nolint:forcetypeassert
handleBeginTransactionCall(call, pass, stack)
+ handleQueryCall(call, pass, stack)
return true
})
@@ -90,6 +98,124 @@ func handleBeginTransactionCall(call *ast.CallExpr, pass *analysis.Pass, stack [
}
}
+// handleQueryCall validates Query/QueryBatch/ValidateQuery/ExplainQuery call sites
+// to detect AQL injection vulnerabilities via string concatenation.
+func handleQueryCall(call *ast.CallExpr, pass *analysis.Pass, stack []ast.Node) {
+ methodName, queryArgIndex := identifyQueryMethod(call, pass)
+ if methodName == "" {
+ return
+ }
+
+ // Ensure the call has enough arguments
+ if len(call.Args) <= queryArgIndex {
+ return
+ }
+
+ queryArg := unwrapParens(call.Args[queryArgIndex])
+
+ if shouldReportQueryConcatenation(queryArg, pass, stack, call.Pos()) {
+ diag := analysis.Diagnostic{
+ Pos: queryArg.Pos(),
+ Message: msgQueryConcatenation,
+ }
+ pass.Report(diag)
+ }
+}
+
+// identifyQueryMethod checks if the call is to a Database or Transaction query method
+// and returns the method name and the index of the query string argument.
+// Returns empty string if not a query method.
+func identifyQueryMethod(
+ call *ast.CallExpr,
+ pass *analysis.Pass,
+) (methodName string, queryArgIndex int) {
+ selExpr, isSelector := call.Fun.(*ast.SelectorExpr)
+ if !isSelector || selExpr.Sel == nil {
+ return "", 0
+ }
+
+ methodName = selExpr.Sel.Name
+
+ queryArgIndex = getQueryArgIndex(methodName)
+ if queryArgIndex == -1 {
+ return "", 0
+ }
+
+ // Verify it's called on a Database or Transaction type
+ xType := pass.TypesInfo.TypeOf(selExpr.X)
+ if xType == nil {
+ return "", 0
+ }
+
+ if isQueryReceiverType(xType, pass) {
+ return methodName, queryArgIndex
+ }
+
+ return "", 0
+}
+
+// getQueryArgIndex returns the index of the query argument for a given method name,
+// or -1 if the method is not a query method.
+func getQueryArgIndex(methodName string) int {
+ switch methodName {
+ case methodQuery, methodQueryBatch, methodValidateQuery, methodExplainQuery:
+ return 1
+ default:
+ return -1
+ }
+}
+
+// isQueryReceiverType checks if the given type is a Database or Transaction type.
+func isQueryReceiverType(xType types.Type, pass *analysis.Pass) bool {
+ // Try to find the arangodb package and get Database and Transaction types
+ dbType, trxType := getArangoDBTypes(pass)
+
+ if dbType != nil && types.AssignableTo(xType, dbType) {
+ return true
+ }
+
+ if trxType != nil && types.AssignableTo(xType, trxType) {
+ return true
+ }
+
+ // Fallback: direct receiver type match
+ receiverTypeStr := xType.String()
+
+ return strings.HasSuffix(receiverTypeStr, arangoDatabaseTypeSuffix) ||
+ strings.HasSuffix(receiverTypeStr, arangoTransactionTypeSuffix)
+}
+
+// getArangoDBTypes retrieves the Database and Transaction types from the arangodb package.
+func getArangoDBTypes(pass *analysis.Pass) (dbType, trxType types.Type) {
+ for _, imp := range pass.Pkg.Imports() {
+ if !strings.HasSuffix(imp.Path(), arangoPackageSuffix) {
+ continue
+ }
+
+ dbType = lookupType(imp, "Database")
+ trxType = lookupType(imp, "Transaction")
+
+ break
+ }
+
+ return dbType, trxType
+}
+
+// lookupType looks up a type by name in a package scope.
+func lookupType(pkg *types.Package, name string) types.Type {
+ obj := pkg.Scope().Lookup(name)
+ if obj == nil {
+ return nil
+ }
+
+ tn, typeOK := obj.(*types.TypeName)
+ if !typeOK {
+ return nil
+ }
+
+ return tn.Type()
+}
+
// shouldReportMissingAllowImplicit returns true when the provided 3rd argument
// expression should trigger the "missing AllowImplicit" diagnostic, and false
// when the argument is known to have AllowImplicit set (or when we must stay
@@ -169,6 +295,398 @@ func isAllowImplicitSelector(s *ast.SelectorExpr) bool {
return s != nil && s.Sel != nil && s.Sel.Name == allowImplicitFieldName
}
+// shouldReportQueryConcatenation returns true when the query string argument
+// appears to be built using concatenation or fmt.Sprintf, which could lead to
+// SQL injection vulnerabilities. Returns false when the query is a static string
+// or we cannot determine its construction (conservative approach).
+func shouldReportQueryConcatenation(
+ arg ast.Expr,
+ pass *analysis.Pass,
+ stack []ast.Node,
+ callPos token.Pos,
+) bool {
+ // Direct concatenation: "query" + var
+ if isConcatenatedString(arg) {
+ return true
+ }
+
+ // fmt.Sprintf call
+ if isFmtSprintfCall(arg, pass) {
+ return true
+ }
+
+ // Variable that was assigned a concatenated string
+ if ident, ok := arg.(*ast.Ident); ok {
+ return wasBuiltWithConcatenation(ident, pass, stack, callPos)
+ }
+
+ // Conservative: unknown expression shape, don't report
+ return false
+}
+
+// isConcatenatedString checks if expr is a binary expression using + operator
+// that involves at least one non-literal operand (indicating variable interpolation).
+func isConcatenatedString(expr ast.Expr) bool {
+ expr = unwrapParens(expr)
+
+ binExpr, ok := expr.(*ast.BinaryExpr)
+ if !ok {
+ return false
+ }
+
+ if binExpr.Op != token.ADD {
+ return false
+ }
+
+ // Recursively check both sides
+ leftIsAllLiteral := isAllStringLiterals(binExpr.X)
+ rightIsAllLiteral := isAllStringLiterals(binExpr.Y)
+
+ // If both sides are only string literals (recursively), this is safe static concatenation
+ if leftIsAllLiteral && rightIsAllLiteral {
+ return false
+ }
+
+ // At least one side involves non-literal content, so it's unsafe
+ return true
+}
+
+// isAllStringLiterals recursively checks if expr consists only of string literals
+// (including nested concatenations of string literals).
+func isAllStringLiterals(expr ast.Expr) bool {
+ expr = unwrapParens(expr)
+
+ // Base case: string literal
+ if isStringLiteral(expr) {
+ return true
+ }
+
+ // Recursive case: binary expression with +
+ if binExpr, ok := expr.(*ast.BinaryExpr); ok && binExpr.Op == token.ADD {
+ return isAllStringLiterals(binExpr.X) && isAllStringLiterals(binExpr.Y)
+ }
+
+ // Anything else (ident, call, etc.) is not a literal
+ return false
+}
+
+// isStringLiteral checks if expr is a basic string literal (unwrapping parens).
+func isStringLiteral(expr ast.Expr) bool {
+ expr = unwrapParens(expr)
+ lit, ok := expr.(*ast.BasicLit)
+
+ return ok && lit.Kind == token.STRING
+}
+
+// isFmtSprintfCall checks if expr is a call to fmt.Sprintf or similar formatting function.
+func isFmtSprintfCall(expr ast.Expr, pass *analysis.Pass) bool {
+ expr = unwrapParens(expr)
+
+ call, isCallExpr := expr.(*ast.CallExpr)
+ if !isCallExpr {
+ return false
+ }
+
+ selExpr, isSelectorExpr := call.Fun.(*ast.SelectorExpr)
+ if !isSelectorExpr {
+ return false
+ }
+
+ // Check if it's a Sprintf-like method
+ methodName := selExpr.Sel.Name
+ if methodName != "Sprintf" {
+ return false
+ }
+
+ // Check if the receiver is from the fmt package
+ if ident, isIdent := selExpr.X.(*ast.Ident); isIdent {
+ if obj := pass.TypesInfo.ObjectOf(ident); obj != nil {
+ if pkgName, isPkgName := obj.(*types.PkgName); isPkgName {
+ return pkgName.Imported().Path() == fmtPackagePath
+ }
+ }
+ }
+
+ return false
+}
+
+// wasBuiltWithConcatenation checks if an identifier was assigned a value
+// that involves string concatenation or fmt.Sprintf.
+func wasBuiltWithConcatenation(
+ id *ast.Ident,
+ pass *analysis.Pass,
+ stack []ast.Node,
+ callPos token.Pos,
+) bool {
+ obj := pass.TypesInfo.ObjectOf(id)
+ if obj == nil {
+ return false
+ }
+
+ blocks := ancestorBlocks(stack)
+
+ // Scan prior statements for assignments to this identifier
+ found := scanPriorStatements(blocks, callPos, func(stmt ast.Stmt) bool {
+ return stmtAssignsConcatenation(stmt, obj, pass)
+ })
+
+ if found {
+ return true
+ }
+
+ // Check package-level variable declarations
+ return packageVarHasConcatenation(pass, obj)
+}
+
+// stmtAssignsConcatenation checks if stmt assigns a concatenated string to the given object.
+func stmtAssignsConcatenation(stmt ast.Stmt, obj types.Object, pass *analysis.Pass) bool {
+ // Handle regular assignment statements
+ if assign, isAssign := stmt.(*ast.AssignStmt); isAssign {
+ return assignStmtAssignsConcatenation(assign, obj, pass)
+ }
+
+ // Handle var declarations with initialization
+ if declStmt, isDeclStmt := stmt.(*ast.DeclStmt); isDeclStmt {
+ return declStmtAssignsConcatenation(declStmt, obj, pass)
+ }
+
+ // Handle control flow structures
+ switch stmtTyped := stmt.(type) {
+ case *ast.IfStmt:
+ return ifStmtAssignsConcatenation(stmtTyped, obj, pass)
+ case *ast.ForStmt:
+ return forStmtAssignsConcatenation(stmtTyped, obj, pass)
+ case *ast.RangeStmt:
+ return rangeStmtAssignsConcatenation(stmtTyped, obj, pass)
+ case *ast.SwitchStmt:
+ return switchStmtAssignsConcatenation(stmtTyped, obj, pass)
+ }
+
+ return false
+}
+
+// assignStmtAssignsConcatenation checks if an assignment statement assigns concatenation to obj.
+func assignStmtAssignsConcatenation(
+ assign *ast.AssignStmt,
+ obj types.Object,
+ pass *analysis.Pass,
+) bool {
+ for lhsIndex, lhs := range assign.Lhs {
+ lhsIdent, isIdent := lhs.(*ast.Ident)
+ if !isIdent {
+ continue
+ }
+
+ if pass.TypesInfo.ObjectOf(lhsIdent) != obj {
+ continue
+ }
+
+ // Find corresponding RHS
+ rhs := getRHSForLHS(assign, lhsIndex)
+ if rhs == nil {
+ continue
+ }
+
+ // Check if RHS involves concatenation
+ if isConcatenatedString(rhs) || isFmtSprintfCall(rhs, pass) {
+ return true
+ }
+
+ // Check for compound assignment (+=)
+ // Only flag if RHS is not a static string literal
+ if assign.Tok == token.ADD_ASSIGN {
+ // Safe if adding only static string literals
+ if !isStringLiteral(rhs) {
+ return true
+ }
+ }
+ }
+
+ return false
+}
+
+// getRHSForLHS returns the RHS expression corresponding to the LHS at the given index.
+func getRHSForLHS(assign *ast.AssignStmt, lhsIndex int) ast.Expr {
+ switch {
+ case len(assign.Rhs) == len(assign.Lhs):
+ return assign.Rhs[lhsIndex]
+ case len(assign.Rhs) == 1:
+ return assign.Rhs[0]
+ default:
+ return nil
+ }
+}
+
+// declStmtAssignsConcatenation checks if a declaration statement initializes obj with concatenation.
+func declStmtAssignsConcatenation(
+ declStmt *ast.DeclStmt,
+ obj types.Object,
+ pass *analysis.Pass,
+) bool {
+ genDecl, isGenDecl := declStmt.Decl.(*ast.GenDecl)
+ if !isGenDecl || genDecl.Tok != token.VAR {
+ return false
+ }
+
+ for _, spec := range genDecl.Specs {
+ valueSpec, isValueSpec := spec.(*ast.ValueSpec)
+ if !isValueSpec {
+ continue
+ }
+
+ if varDeclHasConcatenation(valueSpec, obj, pass) {
+ return true
+ }
+ }
+
+ return false
+}
+
+// varDeclHasConcatenation checks if a variable declaration initializes with concatenation.
+func varDeclHasConcatenation(valueSpec *ast.ValueSpec, obj types.Object, pass *analysis.Pass) bool {
+ targetIndex := -1
+
+ for nameIndex, name := range valueSpec.Names {
+ if pass.TypesInfo.ObjectOf(name) == obj {
+ targetIndex = nameIndex
+
+ break
+ }
+ }
+
+ if targetIndex == -1 {
+ return false
+ }
+
+ rhsValue := getRHSValueForIndex(valueSpec, targetIndex)
+ if rhsValue == nil {
+ return false
+ }
+
+ return isConcatenatedString(rhsValue) || isFmtSprintfCall(rhsValue, pass)
+}
+
+// getRHSValueForIndex returns the RHS value for a given index in a value spec.
+func getRHSValueForIndex(valueSpec *ast.ValueSpec, targetIndex int) ast.Expr {
+ switch {
+ case targetIndex < len(valueSpec.Values):
+ return valueSpec.Values[targetIndex]
+ case len(valueSpec.Values) == 1:
+ return valueSpec.Values[0]
+ default:
+ return nil
+ }
+}
+
+// packageVarHasConcatenation checks if a package-level variable is initialized with concatenation.
+func packageVarHasConcatenation(pass *analysis.Pass, obj types.Object) bool {
+ for _, f := range pass.Files {
+ for _, decl := range f.Decls {
+ genDecl, ok := decl.(*ast.GenDecl)
+ if !ok || genDecl.Tok != token.VAR {
+ continue
+ }
+
+ for _, spec := range genDecl.Specs {
+ valueSpec, ok := spec.(*ast.ValueSpec)
+ if !ok {
+ continue
+ }
+
+ if varDeclHasConcatenation(valueSpec, obj, pass) {
+ return true
+ }
+ }
+ }
+ }
+
+ return false
+}
+
+// Control flow helpers for concatenation detection.
+func ifStmtAssignsConcatenation(stmt *ast.IfStmt, obj types.Object, pass *analysis.Pass) bool {
+ for _, s := range stmt.Body.List {
+ if stmtAssignsConcatenation(s, obj, pass) {
+ return true
+ }
+ }
+
+ if stmt.Else != nil {
+ switch elseNode := stmt.Else.(type) {
+ case *ast.BlockStmt:
+ for _, s := range elseNode.List {
+ if stmtAssignsConcatenation(s, obj, pass) {
+ return true
+ }
+ }
+ case *ast.IfStmt:
+ if stmtAssignsConcatenation(elseNode, obj, pass) {
+ return true
+ }
+ }
+ }
+
+ return false
+}
+
+func forStmtAssignsConcatenation(stmt *ast.ForStmt, obj types.Object, pass *analysis.Pass) bool {
+ if assign, ok := stmt.Init.(*ast.AssignStmt); ok {
+ if stmtAssignsConcatenation(assign, obj, pass) {
+ return true
+ }
+ }
+
+ for _, s := range stmt.Body.List {
+ if stmtAssignsConcatenation(s, obj, pass) {
+ return true
+ }
+ }
+
+ return false
+}
+
+func rangeStmtAssignsConcatenation(
+ stmt *ast.RangeStmt,
+ obj types.Object,
+ pass *analysis.Pass,
+) bool {
+ if stmt == nil || stmt.Body == nil {
+ return false
+ }
+
+ for _, s := range stmt.Body.List {
+ if stmtAssignsConcatenation(s, obj, pass) {
+ return true
+ }
+ }
+
+ return false
+}
+
+func switchStmtAssignsConcatenation(
+ stmt *ast.SwitchStmt,
+ obj types.Object,
+ pass *analysis.Pass,
+) bool {
+ if assign, ok := stmt.Init.(*ast.AssignStmt); ok {
+ if stmtAssignsConcatenation(assign, obj, pass) {
+ return true
+ }
+ }
+
+ for _, cc := range stmt.Body.List {
+ if clause, ok := cc.(*ast.CaseClause); ok {
+ for _, s := range clause.Body {
+ if stmtAssignsConcatenation(s, obj, pass) {
+ return true
+ }
+ }
+ }
+ }
+
+ return false
+}
+
// isBeginTransaction reports whether call is a call to arangodb.Database.BeginTransaction.
// It prefers selection-based detection via TypesInfo.Selections to support wrappers or
// types that embed arangodb.Database. If selection info is unavailable, it falls back
diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/config.go b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/config.go
index f7338b7e5..a7d4b2a81 100644
--- a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/config.go
+++ b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/config.go
@@ -194,6 +194,9 @@ func WithServerName(server string) Option {
// WithMetricAttributesFn returns an Option to set a function that maps an HTTP request to a slice of attribute.KeyValue.
// These attributes will be included in metrics for every request.
+//
+// Deprecated: WithMetricAttributesFn is deprecated and will be removed in a
+// future release. Use [Labeler] instead.
func WithMetricAttributesFn(metricAttributesFn func(r *http.Request) []attribute.KeyValue) Option {
return optionFunc(func(c *config) {
c.MetricAttributesFn = metricAttributesFn
diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/handler.go b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/handler.go
index 1ecd4be2d..a269fce0f 100644
--- a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/handler.go
+++ b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/handler.go
@@ -184,30 +184,26 @@ func (h *middleware) serveHTTP(w http.ResponseWriter, r *http.Request, next http
statusCode := rww.StatusCode()
bytesWritten := rww.BytesWritten()
span.SetStatus(h.semconv.Status(statusCode))
+ bytesRead := bw.BytesRead()
span.SetAttributes(h.semconv.ResponseTraceAttrs(semconv.ResponseTelemetry{
StatusCode: statusCode,
- ReadBytes: bw.BytesRead(),
+ ReadBytes: bytesRead,
ReadError: bw.Error(),
WriteBytes: bytesWritten,
WriteError: rww.Error(),
})...)
- // Use floating point division here for higher precision (instead of Millisecond method).
- elapsedTime := float64(time.Since(requestStartTime)) / float64(time.Millisecond)
-
- metricAttributes := semconv.MetricAttributes{
- Req: r,
- StatusCode: statusCode,
- AdditionalAttributes: append(labeler.Get(), h.metricAttributesFromRequest(r)...),
- }
-
h.semconv.RecordMetrics(ctx, semconv.ServerMetricData{
- ServerName: h.server,
- ResponseSize: bytesWritten,
- MetricAttributes: metricAttributes,
+ ServerName: h.server,
+ ResponseSize: bytesWritten,
+ MetricAttributes: semconv.MetricAttributes{
+ Req: r,
+ StatusCode: statusCode,
+ AdditionalAttributes: append(labeler.Get(), h.metricAttributesFromRequest(r)...),
+ },
MetricData: semconv.MetricData{
- RequestSize: bw.BytesRead(),
- ElapsedTime: elapsedTime,
+ RequestSize: bytesRead,
+ RequestDuration: time.Since(requestStartTime),
},
})
}
diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/request/resp_writer_wrapper.go b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/request/resp_writer_wrapper.go
index ca2e4c14c..f29f9b7c9 100644
--- a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/request/resp_writer_wrapper.go
+++ b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/request/resp_writer_wrapper.go
@@ -61,7 +61,7 @@ func (w *RespWriterWrapper) Write(p []byte) (int, error) {
// WriteHeader persists initial statusCode for span attribution.
// All calls to WriteHeader will be propagated to the underlying ResponseWriter
-// and will persist the statusCode from the first call.
+// and will persist the statusCode from the first call (except for informational response status codes).
// Blocking consecutive calls to WriteHeader alters expected behavior and will
// remove warning logs from net/http where developers will notice incorrect handler implementations.
func (w *RespWriterWrapper) WriteHeader(statusCode int) {
@@ -77,6 +77,13 @@ func (w *RespWriterWrapper) WriteHeader(statusCode int) {
// parent method.
func (w *RespWriterWrapper) writeHeader(statusCode int) {
if !w.wroteHeader {
+ // Ignore informational response status codes.
+ // Based on https://github.com/golang/go/blob/go1.24.1/src/net/http/server.go#L1216
+ if statusCode >= 100 && statusCode <= 199 && statusCode != http.StatusSwitchingProtocols {
+ w.ResponseWriter.WriteHeader(statusCode)
+ return
+ }
+
w.wroteHeader = true
w.statusCode = statusCode
}
diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/client.go b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/client.go
index 29d6f508c..1398d85c2 100644
--- a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/client.go
+++ b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/client.go
@@ -19,11 +19,11 @@ import (
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/codes"
"go.opentelemetry.io/otel/metric"
- "go.opentelemetry.io/otel/semconv/v1.39.0"
- "go.opentelemetry.io/otel/semconv/v1.39.0/httpconv"
+ "go.opentelemetry.io/otel/semconv/v1.40.0"
+ "go.opentelemetry.io/otel/semconv/v1.40.0/httpconv"
)
-type HTTPClient struct{
+type HTTPClient struct {
requestBodySize httpconv.ClientRequestBodySize
requestDuration httpconv.ClientRequestDuration
}
@@ -57,14 +57,14 @@ func (n HTTPClient) Status(code int) (codes.Code, string) {
// RequestTraceAttrs returns trace attributes for an HTTP request made by a client.
func (n HTTPClient) RequestTraceAttrs(req *http.Request) []attribute.KeyValue {
/*
- below attributes are returned:
- - http.request.method
- - http.request.method.original
- - url.full
- - server.address
- - server.port
- - network.protocol.name
- - network.protocol.version
+ below attributes are returned:
+ - http.request.method
+ - http.request.method.original
+ - url.full
+ - server.address
+ - server.port
+ - network.protocol.name
+ - network.protocol.version
*/
numOfAttributes := 3 // URL, server address, proto, and method.
@@ -139,9 +139,9 @@ func (n HTTPClient) RequestTraceAttrs(req *http.Request) []attribute.KeyValue {
// ResponseTraceAttrs returns trace attributes for an HTTP response made by a client.
func (n HTTPClient) ResponseTraceAttrs(resp *http.Response) []attribute.KeyValue {
/*
- below attributes are returned:
- - http.response.status_code
- - error.type
+ below attributes are returned:
+ - http.response.status_code
+ - error.type
*/
var count int
if resp.StatusCode > 0 {
@@ -247,22 +247,26 @@ func (o MetricOpts) AddOptions() metric.AddOption {
return o.addOptions
}
-func (n HTTPClient) MetricOptions(ma MetricAttributes) map[string]MetricOpts {
- opts := map[string]MetricOpts{}
-
+func (n HTTPClient) MetricOptions(ma MetricAttributes) MetricOpts {
attributes := n.MetricAttributes(ma.Req, ma.StatusCode, ma.AdditionalAttributes)
set := metric.WithAttributeSet(attribute.NewSet(attributes...))
- opts["new"] = MetricOpts{
+
+ return MetricOpts{
measurement: set,
addOptions: set,
}
-
- return opts
}
-func (n HTTPClient) RecordMetrics(ctx context.Context, md MetricData, opts map[string]MetricOpts) {
- n.requestBodySize.Inst().Record(ctx, md.RequestSize, opts["new"].MeasurementOption())
- n.requestDuration.Inst().Record(ctx, md.ElapsedTime/1000, opts["new"].MeasurementOption())
+func (n HTTPClient) RecordMetrics(ctx context.Context, md MetricData, opts MetricOpts) {
+ recordOpts := metricRecordOptionPool.Get().(*[]metric.RecordOption)
+ defer func() {
+ *recordOpts = (*recordOpts)[:0]
+ metricRecordOptionPool.Put(recordOpts)
+ }()
+ *recordOpts = append(*recordOpts, opts.MeasurementOption())
+
+ n.requestBodySize.Inst().Record(ctx, md.RequestSize, *recordOpts...)
+ n.requestDuration.Inst().Record(ctx, durationToSeconds(md.RequestDuration), *recordOpts...)
}
// TraceAttributes returns attributes for httptrace.
diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/server.go b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/server.go
index e0e9ebc05..6dcf1b5b5 100644
--- a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/server.go
+++ b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/server.go
@@ -15,12 +15,13 @@ import (
"slices"
"strings"
"sync"
+ "time"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/codes"
"go.opentelemetry.io/otel/metric"
- "go.opentelemetry.io/otel/semconv/v1.39.0"
- "go.opentelemetry.io/otel/semconv/v1.39.0/httpconv"
+ "go.opentelemetry.io/otel/semconv/v1.40.0"
+ "go.opentelemetry.io/otel/semconv/v1.40.0/httpconv"
)
type RequestTraceAttrsOpts struct {
@@ -36,7 +37,7 @@ type ResponseTelemetry struct {
WriteError error
}
-type HTTPServer struct{
+type HTTPServer struct {
requestBodySizeHistogram httpconv.ServerRequestBodySize
responseBodySizeHistogram httpconv.ServerResponseBodySize
requestDurationHistogram httpconv.ServerRequestDuration
@@ -245,19 +246,11 @@ type MetricAttributes struct {
}
type MetricData struct {
- RequestSize int64
-
- // The request duration, in milliseconds
- ElapsedTime float64
+ RequestSize int64
+ RequestDuration time.Duration
}
var (
- metricAddOptionPool = &sync.Pool{
- New: func() any {
- return &[]metric.AddOption{}
- },
- }
-
metricRecordOptionPool = &sync.Pool{
New: func() any {
return &[]metric.RecordOption{}
@@ -272,7 +265,7 @@ func (n HTTPServer) RecordMetrics(ctx context.Context, md ServerMetricData) {
*recordOpts = append(*recordOpts, o)
n.requestBodySizeHistogram.Inst().Record(ctx, md.RequestSize, *recordOpts...)
n.responseBodySizeHistogram.Inst().Record(ctx, md.ResponseSize, *recordOpts...)
- n.requestDurationHistogram.Inst().Record(ctx, md.ElapsedTime/1000.0, o)
+ n.requestDurationHistogram.Inst().Record(ctx, durationToSeconds(md.RequestDuration), o)
*recordOpts = (*recordOpts)[:0]
metricRecordOptionPool.Put(recordOpts)
}
@@ -373,8 +366,8 @@ func (n HTTPServer) MetricAttributes(server string, req *http.Request, statusCod
}
if route != "" {
- num++
- }
+ num++
+ }
attributes := slices.Grow(additionalAttributes, num)
attributes = append(attributes,
@@ -397,7 +390,7 @@ func (n HTTPServer) MetricAttributes(server string, req *http.Request, statusCod
}
if route != "" {
- attributes = append(attributes, semconv.HTTPRoute(route))
- }
+ attributes = append(attributes, semconv.HTTPRoute(route))
+ }
return attributes
}
diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/util.go b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/util.go
index 131fda489..2eab2ecab 100644
--- a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/util.go
+++ b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/util.go
@@ -11,10 +11,11 @@ import (
"net/http"
"strconv"
"strings"
+ "time"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/attribute"
- semconvNew "go.opentelemetry.io/otel/semconv/v1.39.0"
+ semconvNew "go.opentelemetry.io/otel/semconv/v1.40.0"
)
// SplitHostPort splits a network address hostport of the form "host",
@@ -125,3 +126,8 @@ func standardizeHTTPMethod(method string) string {
}
return method
}
+
+func durationToSeconds(d time.Duration) float64 {
+ // Use floating point division here for higher precision (instead of Seconds method).
+ return float64(d) / float64(time.Second)
+}
diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/transport.go b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/transport.go
index 59b6c5498..d8d204d1f 100644
--- a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/transport.go
+++ b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/transport.go
@@ -5,7 +5,6 @@ package otelhttp // import "go.opentelemetry.io/contrib/instrumentation/net/http
import (
"context"
- "fmt"
"io"
"net/http"
"net/http/httptrace"
@@ -16,7 +15,7 @@ import (
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/codes"
"go.opentelemetry.io/otel/propagation"
- otelsemconv "go.opentelemetry.io/otel/semconv/v1.39.0"
+ otelsemconv "go.opentelemetry.io/otel/semconv/v1.40.0"
"go.opentelemetry.io/otel/trace"
"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/request"
@@ -85,8 +84,6 @@ func defaultTransportFormatter(_ string, r *http.Request) string {
// RoundTrip creates a Span and propagates its context via the provided request's headers
// before handing the request to the configured base RoundTripper. The created span will
// end when the response body is closed or when a read from the body returns io.EOF.
-// If GetBody returns an error, the error is reported via otel.Handle and the request
-// continues with the original Body.
func (t *Transport) RoundTrip(r *http.Request) (*http.Response, error) {
requestStartTime := time.Now()
for _, f := range t.filters {
@@ -106,9 +103,7 @@ func (t *Transport) RoundTrip(r *http.Request) (*http.Response, error) {
}
}
- opts := append([]trace.SpanStartOption{}, t.spanStartOptions...) // start with the configured options
-
- ctx, span := tracer.Start(r.Context(), t.spanNameFormatter("", r), opts...)
+ ctx, span := tracer.Start(r.Context(), t.spanNameFormatter("", r), t.spanStartOptions...)
if t.clientTrace != nil {
ctx = httptrace.WithClientTrace(ctx, t.clientTrace(ctx))
@@ -121,23 +116,26 @@ func (t *Transport) RoundTrip(r *http.Request) (*http.Response, error) {
r = r.Clone(ctx) // According to RoundTripper spec, we shouldn't modify the origin request.
- // GetBody is preferred over direct access to Body if the function is set.
- // If the resulting body is nil or is NoBody, we don't want to mutate the body as it
- // will affect the identity of it in an unforeseeable way because we assert
- // ReadCloser fulfills a certain interface and it is indeed nil or NoBody.
- body := r.Body
- if r.GetBody != nil {
- b, err := r.GetBody()
- if err != nil {
- otel.Handle(fmt.Errorf("http.Request GetBody returned an error: %w", err))
- } else {
- body = b
+ var lastBW *request.BodyWrapper // Records the last body wrapper. Can be nil.
+ maybeWrapBody := func(body io.ReadCloser) io.ReadCloser {
+ if body == nil || body == http.NoBody {
+ return body
}
+ bw := request.NewBodyWrapper(body, func(int64) {})
+ lastBW = bw
+ return bw
}
-
- bw := request.NewBodyWrapper(body, func(int64) {})
- if body != nil && body != http.NoBody {
- r.Body = bw
+ r.Body = maybeWrapBody(r.Body)
+ if r.GetBody != nil {
+ originalGetBody := r.GetBody
+ r.GetBody = func() (io.ReadCloser, error) {
+ b, err := originalGetBody()
+ if err != nil {
+ lastBW = nil // The underlying transport will fail to make a retry request, hence, record no data.
+ return nil, err
+ }
+ return maybeWrapBody(b), nil
+ }
}
span.SetAttributes(t.semconv.RequestTraceAttrs(r)...)
@@ -145,35 +143,27 @@ func (t *Transport) RoundTrip(r *http.Request) (*http.Response, error) {
res, err := t.rt.RoundTrip(r)
- // Defer metrics recording function to record the metrics on error or no error.
- defer func() {
- metricAttributes := semconv.MetricAttributes{
+ // Record the metrics on error or no error.
+ statusCode := 0
+ if err == nil {
+ statusCode = res.StatusCode
+ }
+ var requestSize int64
+ if lastBW != nil {
+ requestSize = lastBW.BytesRead()
+ }
+ t.semconv.RecordMetrics(
+ ctx,
+ semconv.MetricData{
+ RequestSize: requestSize,
+ RequestDuration: time.Since(requestStartTime),
+ },
+ t.semconv.MetricOptions(semconv.MetricAttributes{
Req: r,
+ StatusCode: statusCode,
AdditionalAttributes: append(labeler.Get(), t.metricAttributesFromRequest(r)...),
- }
-
- if err == nil {
- metricAttributes.StatusCode = res.StatusCode
- }
-
- metricOpts := t.semconv.MetricOptions(metricAttributes)
-
- metricData := semconv.MetricData{
- RequestSize: bw.BytesRead(),
- }
-
- if err == nil {
- readRecordFunc := func(int64) {}
- res.Body = newWrappedBody(span, readRecordFunc, res.Body)
- }
-
- // Use floating point division here for higher precision (instead of Millisecond method).
- elapsedTime := float64(time.Since(requestStartTime)) / float64(time.Millisecond)
-
- metricData.ElapsedTime = elapsedTime
-
- t.semconv.RecordMetrics(ctx, metricData, metricOpts)
- }()
+ }),
+ )
if err != nil {
span.SetAttributes(otelsemconv.ErrorType(err))
@@ -183,6 +173,8 @@ func (t *Transport) RoundTrip(r *http.Request) (*http.Response, error) {
return res, err
}
+ readRecordFunc := func(int64) {}
+ res.Body = newWrappedBody(span, readRecordFunc, res.Body)
// traces
span.SetAttributes(t.semconv.ResponseTraceAttrs(res)...)
span.SetStatus(t.semconv.Status(res.StatusCode))
diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/version.go b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/version.go
index d0107952e..1d90fc264 100644
--- a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/version.go
+++ b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/version.go
@@ -4,4 +4,4 @@
package otelhttp // import "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
// Version is the current release version of the otelhttp instrumentation.
-const Version = "0.65.0"
+const Version = "0.67.0"
diff --git a/vendor/go.opentelemetry.io/otel/.golangci.yml b/vendor/go.opentelemetry.io/otel/.golangci.yml
index d12c8920a..645c7e6af 100644
--- a/vendor/go.opentelemetry.io/otel/.golangci.yml
+++ b/vendor/go.opentelemetry.io/otel/.golangci.yml
@@ -17,6 +17,7 @@ linters:
- ineffassign
- misspell
- modernize
+ - noctx
- perfsprint
- revive
- staticcheck
@@ -88,6 +89,16 @@ linters:
deny:
- pkg: go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal
desc: Do not use cross-module internal packages.
+ semconv:
+ list-mode: lax
+ files:
+ - "!**/semconv/**"
+ - "!**/exporters/zipkin/**"
+ deny:
+ - pkg: go.opentelemetry.io/otel/semconv
+ desc: "Use go.opentelemetry.io/otel/semconv/v1.41.0 instead. If a newer semconv version has been released, update the depguard rule."
+ allow:
+ - go.opentelemetry.io/otel/semconv/v1.41.0
gocritic:
disabled-checks:
- appendAssign
@@ -123,13 +134,16 @@ linters:
strconcat: true
revive:
confidence: 0.01
+ enable-all-rules: false
+ enable-default-rules: true
+ max-open-files: 2048
rules:
- name: blank-imports
- name: bool-literal-in-expr
- name: constant-logical-expr
- name: context-as-argument
arguments:
- - allowTypesBefore: '*testing.T'
+ - allow-types-before: '*testing.T'
disabled: true
- name: context-keys-type
- name: deep-exit
@@ -141,7 +155,7 @@ linters:
- name: duplicated-imports
- name: early-return
arguments:
- - preserveScope
+ - preserve-scope
- name: empty-block
- name: empty-lines
- name: error-naming
@@ -150,7 +164,7 @@ linters:
- name: errorf
- name: exported
arguments:
- - sayRepetitiveInsteadOfStutters
+ - say-repetitive-instead-of-stutters
- name: flag-parameter
- name: identical-branches
- name: if-return
@@ -158,11 +172,12 @@ linters:
- name: increment-decrement
- name: indent-error-flow
arguments:
- - preserveScope
+ - preserve-scope
- name: package-comments
- name: range
- name: range-val-in-closure
- name: range-val-address
+ - name: receiver-naming
- name: redefines-builtin-id
- name: string-format
arguments:
@@ -172,7 +187,7 @@ linters:
- name: struct-tag
- name: superfluous-else
arguments:
- - preserveScope
+ - preserve-scope
- name: time-equal
- name: unconditional-recursion
- name: unexported-return
diff --git a/vendor/go.opentelemetry.io/otel/AGENTS.md b/vendor/go.opentelemetry.io/otel/AGENTS.md
new file mode 100644
index 000000000..26c0fc4dd
--- /dev/null
+++ b/vendor/go.opentelemetry.io/otel/AGENTS.md
@@ -0,0 +1,109 @@
+# Agent Guide for opentelemetry-go
+
+This file contains active, task-oriented instructions for autonomous and semi-autonomous coding agents working in this repository.
+
+Before starting any task, read `.github/copilot-instructions.md`, `CONTRIBUTING.md`, and this file.
+Treat `.github/copilot-instructions.md` as global passive guidance for every task, including docs-only and review-only work.
+
+## Core expectations
+
+- Preserve OpenTelemetry specification compliance, API stability, and idiomatic Go.
+- Prefer minimal, surgical changes over broad refactors or speculative cleanup.
+- Read the package you are editing and match its existing naming, option types, error handling, comments, tests, and concurrency patterns.
+- Keep public APIs backward compatible unless the task explicitly requires a breaking change.
+- Keep telemetry resilient and loosely coupled. Do not introduce behavior that can unexpectedly interfere with host applications.
+- Inspect boundaries carefully: input validation, resource limits, cancellation, shutdown, error propagation, concurrency, and memory growth.
+- Prefer fail-safe behavior and explicit invariants over implicit assumptions.
+- Keep dependencies minimal and justified.
+- Preserve host-application safety: telemetry should not panic, block indefinitely, or amplify attacker-controlled input.
+- Be conservative on hot paths. Avoid unnecessary allocations, reflection, interface churn, blocking, global state, and high-cardinality telemetry.
+- Write comments only for intent, invariants, and non-obvious constraints. Do not add comments that restate the code.
+
+## Default workflow
+
+For new features and behavior changes, use this order unless the task explicitly says otherwise:
+
+1. Read the relevant package, its tests, and any package docs or `README.md`.
+2. Add or update a failing unit test that captures the required behavior or regression.
+3. Implement the smallest change that makes the test pass.
+4. Refactor only after the behavior is locked in, and only if the refactor keeps the diff focused.
+5. If the changed code is on a hot path or performance-sensitive, inspect existing benchmarks and run them. Add a benchmark if coverage is missing.
+6. Update documentation artifacts as needed while the context is fresh. Follow the documentation and changelog conventions below for the specific updates required.
+7. Run `make precommit` each time before considering the work complete.
+
+For docs-only, test-only, or review-only tasks, still start with the required repository guidance above, then skip the workflow steps that do not apply while keeping the same discipline around scope, verification, and repository conventions.
+
+## Verification
+
+- Use `make` as the canonical repository verification command. The default target is `precommit`.
+- `make precommit` is the expected final verification step for linting, generation, README checks, module checks, and tests.
+- During iteration, targeted commands are fine for fast feedback, but do not stop there if the task changes code.
+- If you touch performance-sensitive code, run focused benchmarks and compare the results using `benchstat` in addition to `make`.
+
+## Documentation and changelog
+
+- Non-internal, non-test packages should have Go doc comments, usually in `doc.go`.
+- Non-internal, non-test, non-documentation packages should also have a `README.md` with at least a title and a `pkg.go.dev` badge.
+- Prefer examples over long code snippets in GoDoc when practical.
+- Keep docs aligned with actual behavior. Do not leave stale comments, stale examples, or stale package documentation behind.
+- For user-visible changes, update `CHANGELOG.md` under the appropriate `Added`, `Changed`, `Deprecated`, `Fixed`, or `Removed` section within `## [Unreleased]`.
+
+## Repository habits
+
+- Prefer focused diffs. Avoid drive-by cleanup.
+- Follow existing option patterns and exported API conventions instead of inventing new abstractions.
+- Generated files are checked in. If your change affects generation, keep generated output up to date.
+- Prefer fast local search tools such as `rg` when exploring the repository.
+- When changing behavior, make the invariants explicit in tests.
+
+## Personas
+
+### Feature Agent
+
+Use this persona for new behavior, new API surface, or spec-driven feature work.
+
+- Start with a failing unit test.
+- Confirm the expected behavior against the spec, existing package behavior, and public API compatibility.
+- Implement the smallest viable change.
+- Update GoDoc, examples, `README.md`, and `CHANGELOG.md` when the change is user-visible.
+- If the feature touches a hot path, check benchmarks and add one if the coverage is missing.
+
+### Refactoring Agent
+
+Use this persona when improving structure without intentionally changing behavior.
+
+- Treat behavior preservation as the default contract.
+- Add or tighten tests before moving code if current behavior is not already pinned down.
+- Avoid broad rewrites, clever abstractions, or package-wide cleanup unless explicitly requested.
+- If a refactor touches a hot path, benchmark before and after.
+- Keep API shape, semantics, concurrency guarantees, and failure modes unchanged unless the task says otherwise.
+
+### Test Agent
+
+Use this persona when adding missing coverage, reproducing bugs, or hardening regressions.
+
+- Reproduce the bug or missing behavior with the smallest failing test you can.
+- Prefer testing public behavior and externally visible invariants.
+- Add targeted regression tests before changing production code.
+- Only change production code when it is required to make the tested behavior correct or testable.
+- Keep tests deterministic, readable, and aligned with package patterns.
+
+### Performance Agent
+
+Use this persona for hot-path work, allocation reduction, or throughput and latency improvements.
+
+- Benchmark first to establish a baseline.
+- Prefer changes that reduce allocations, copying, interface churn, and unnecessary synchronization.
+- Do not trade away correctness, spec compliance, or API stability for micro-optimizations.
+- Add or update benchmarks when performance-sensitive coverage is missing.
+- If you materially change a hot path, capture before-and-after results, preferably with `benchstat`.
+
+### Review Agent
+
+Use this persona when asked to review code, patches, or pull requests.
+
+- Lead with findings, not summaries.
+- Order findings by severity and include precise file and line references when available.
+- Focus on correctness, spec compliance, API compatibility, concurrency safety, resilience, performance regressions, missing tests, missing benchmarks, documentation gaps, and changelog gaps.
+- Call out when a diff is broader than necessary.
+- If you find no issues, say that explicitly and note any residual risks or verification gaps.
diff --git a/vendor/go.opentelemetry.io/otel/CHANGELOG.md b/vendor/go.opentelemetry.io/otel/CHANGELOG.md
index f0595b5e5..6a90451f5 100644
--- a/vendor/go.opentelemetry.io/otel/CHANGELOG.md
+++ b/vendor/go.opentelemetry.io/otel/CHANGELOG.md
@@ -8,6 +8,169 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
## [Unreleased]
+
+
+
+## [1.44.0/0.66.0/0.20.0/0.0.17] 2026-05-27
+
+### Added
+
+- Add `ByteSlice` and `ByteSliceValue` functions for new `BYTESLICE` attribute type in `go.opentelemetry.io/otel/attribute`. (#7948)
+- Apply attribute value limit to the `KindBytes` attribute type in `go.opentelemetry.io/otel/sdk/log`. (#7990)
+- Apply attribute value limit to the `BYTESLICE` attribute type in `go.opentelemetry.io/otel/sdk/trace`. (#7990)
+- Support `BYTESLICE` attributes in `go.opentelemetry.io/otel/trace`. (#8153)
+- Support `BYTESLICE` attributes in `go.opentelemetry.io/otel/exporters/otlp/otlptrace`. (#8153)
+- Support `BYTESLICE` attributes in `go.opentelemetry.io/otel/exporters/otlp/otlplog`. (#8153)
+- Support `BYTESLICE` attributes in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric`. (#8153)
+- Support `BYTESLICE` attributes in `go.opentelemetry.io/otel/exporters/zipkin`. (#8153)
+- Add `String` method for `Value` type in `go.opentelemetry.io/otel/attribute`. (#8142)
+- Add `Slice` and `SliceValue` functions for new `SLICE` attribute type in `go.opentelemetry.io/otel/attribute`. (#8166)
+- Support `SLICE` attributes in `go.opentelemetry.io/otel/exporters/otlp/otlptrace`. (#8216)
+- Support `SLICE` attributes in `go.opentelemetry.io/otel/exporters/otlp/otlplog`. (#8216)
+- Support `SLICE` attributes in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric`. (#8216)
+- Support `SLICE` attributes in `go.opentelemetry.io/otel/exporters/zipkin`. (#8216)
+- Apply `AttributeValueLengthLimit` to `attribute.SLICE` type attribute values in `go.opentelemetry.io/otel/sdk/trace`, recursively truncating contained string values. (#8217)
+- Add `Error` field on `Record` type in `go.opentelemetry.io/otel/log/logtest`. (#8148)
+- Add `WithMaxRequestSize` option in `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc`. (#8157)
+- Add `WithMaxRequestSize` option in `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp`. (#8157)
+- Add `WithMaxRequestSize` option in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc`. (#8157)
+- Add `WithMaxRequestSize` option in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp`. (#8157)
+- Add `WithMaxRequestSize` option in `go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc`. (#8157)
+- Add `WithMaxRequestSize` option in `go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp`. (#8157)
+- Add `Settable` to `go.opentelemetry.io/otel/metric/x` to allow reusing attribute options. (#8178)
+- Add experimental support for splitting metric data across multiple batches in `go.opentelemetry.io/otel/sdk/metric`.
+ Set `OTEL_GO_X_METRIC_EXPORT_BATCH_SIZE=` to enable for all periodic readers.
+ See `go.opentelemetry.io/otel/sdk/metric/internal/x` for feature documentation. (#8071)
+- Add experimental self-observability metrics in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc`.
+ Enable with `OTEL_GO_X_SELF_OBSERVABILITY=true` environment variable.
+ See `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/x` for feature documentation. (#8192)
+- Add experimental self-observability metrics in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp`.
+ Enable with `OTEL_GO_X_SELF_OBSERVABILITY=true` environment variable.
+ See `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal/x` for feature documentation. (#8194)
+- Add experimental self-observability metrics in `go.opentelemetry.io/otel/exporters/stdout/stdoutlog`.
+ Enable with `OTEL_GO_X_SELF_OBSERVABILITY=true` environment variable.
+ See `go.opentelemetry.io/otel/stdout/stdoutlog/internal/x` for feature documentation. (#8263)
+- Add `WithDefaultAttributes` to `go.opentelemetry.io/otel/metric/x` to support setting default attributes on instruments. (#8135)
+- Add `go.opentelemetry.io/otel/semconv/v1.41.0` package.
+ The package contains semantic conventions from the `v1.41.0` version of the OpenTelemetry Semantic Conventions.
+ See the [migration documentation](./semconv/v1.41.0/MIGRATION.md) for information on how to upgrade from `go.opentelemetry.io/otel/semconv/v1.40.0`. (#8324)
+- Add Observable variants of instruments to `go.opentelemetry.io/otel/semconv/v1.41.0` package. (#8350)
+- Generate explicit histogram bucket boundaries from weaver configuration for HTTP and RPC duration instruments in `go.opentelemetry.io/otel/semconv/v1.41.0`. (#8002)
+
+### Changed
+
+- ⚠️ **Breaking Change:** `go.opentelemetry.io/otel/sdk/metric` now applies a default cardinality limit of 2000 to comply with the Metrics SDK specification recommendation.
+ New attribute sets are dropped when the cardinality limit is reached. The measurement of these sets are aggregated into a special attribute set containing `attribute.Bool("otel.metric.overflow", true)`.
+ This can break users who relied on the previous unlimited default.
+ Set `WithCardinalityLimit(0)` or the deprecated `OTEL_GO_X_CARDINALITY_LIMIT=0` environment variable to preserve unlimited cardinality.
+ Note that support for `OTEL_GO_X_CARDINALITY_LIMIT` may be removed in a future release. (#8247)
+- `ErrorType` in `go.opentelemetry.io/otel/semconv` now unwraps errors created with `fmt.Errorf` when deriving the `error.type` attribute. (#8133)
+- `go.opentelemetry.io/otel/sdk/log` now unwraps error chains created with `fmt.Errorf` when deriving the `error.type` attribute from errors on log records. (#8133)
+- `Set.MarshalLog` method in `go.opentelemetry.io/otel/attribute` now uses `Value.String` formatting following the [OpenTelemetry AnyValue representation for non-OTLP protocols](https://opentelemetry.io/docs/specs/otel/common/#anyvalue). (#8169)
+- Optimize `go.opentelemetry.io/otel/sdk/metric` to return a drop reservoir and short-circuit `Offer` calls to the exemplar reservoir when `exemplar.AlwaysOffFilter` is configured. (#8211) (#8267)
+- Optimize `go.opentelemetry.io/otel/sdk/metric` to return a drop reservoir for asynchronous instruments when `exemplar.TraceBasedFilter` is configured. (#8286)
+
+### Deprecated
+
+- Deprecate `Value.Emit` method in `go.opentelemetry.io/otel/attribute`.
+ Use `Value.String` instead. (#8176)
+
+### Fixed
+
+- Limit OTLP request size to 64 MiB by default in `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc`.
+ The limit applies before compression, oversized requests are treated as non-retryable errors, and the limit can be configured with the new `WithMaxRequestSize` option. (#8157, #8365)
+- Limit OTLP request size to 64 MiB by default in `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp`.
+ The limit applies before compression, oversized requests are treated as non-retryable errors, and the limit can be configured with the new `WithMaxRequestSize` option. (#8157, #8365)
+- Limit OTLP request size to 64 MiB by default in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc`.
+ The limit applies before compression, oversized requests are treated as non-retryable errors, and the limit can be configured with the new `WithMaxRequestSize` option. (#8157, #8365)
+- Limit OTLP request size to 64 MiB by default in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp`.
+ The limit applies before compression, oversized requests are treated as non-retryable errors, and the limit can be configured with the new `WithMaxRequestSize` option. (#8157, #8365)
+- Limit OTLP request size to 64 MiB by default in `go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc`.
+ The limit applies before compression, oversized requests are treated as non-retryable errors, and the limit can be configured with the new `WithMaxRequestSize` option. (#8157, #8365)
+- Limit OTLP request size to 64 MiB by default in `go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp`.
+ The limit applies before compression, oversized requests are treated as non-retryable errors, and the limit can be configured with the new `WithMaxRequestSize` option. (#8157, #8365)
+- Fix gzipped request body replay on redirect in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp`. (#8135)
+- Fix gzipped request body replay on redirect in `go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp`. (#8152)
+- `go.opentelemetry.io/otel/exporters/prometheus` now uses `Value.String` formatting for label values following the [OpenTelemetry AnyValue representation for non-OTLP protocols](https://opentelemetry.io/docs/specs/otel/common/#anyvalue). (#8170)
+- Propagate errors from the exporter when calling `Shutdown` on `BatchSpanProcessor` in `go.opentelemetry.io/otel/sdk/trace`. (#8197)
+- Fix stale status code reporting on self-observability metrics in `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp` and `go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp`. (#8226)
+- Fix a concurrent `Collect` data race and potential panic in `go.opentelemetry.io/otel/exporters/prometheus` when `WithResourceAsConstantLabels` option is used. (#8227)
+- Fix race condition in `FixedSizeReservoir` in `go.opentelemetry.io/otel/sdk/metric/exemplar` by reverting #7447. (#8249)
+- Fix `FixedSizeReservoir` in `go.opentelemetry.io/otel/sdk/metric/exemplar` to safely handle zero size.
+ A capacity check in the constructor initializes the reservoir safely and skips initialization for zero-cap; early returns in `Offer()` and `Collect()` ensure no-op behavior. (#8295)
+- Fix counting of spans and logs in self-observability metrics in `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc`, `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp`, `go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc`, and `go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp`. (#8254)
+- Drop conflicting scope attributes named `name`, `version`, or `schema_url` from metric labels in `go.opentelemetry.io/otel/exporters/prometheus`, preserving the dedicated `otel_scope_name`, `otel_scope_version`, and `otel_scope_schema_url` labels. (#8264)
+- Close schema files opened by `ParseFile` in `go.opentelemetry.io/otel/schema/v1.0` and `go.opentelemetry.io/otel/schema/v1.1`. ([GHSA-995v-fvrw-c78m](https://github.com/open-telemetry/opentelemetry-go/security/advisories/GHSA-995v-fvrw-c78m))
+- Enforce the 8192-byte baggage size limit during extraction/parsing, changing behavior when the limit is exceeded in `go.opentelemetry.io/otel/baggage` and `go.opentelemetry.io/otel/propagation`. (#8222)
+- Fix `go.opentelemetry.io/otel/semconv/v1.41.0` to include `Attr*` helper methods for required attributes on observable instruments. (#8361)
+- Limit baggage extraction error reporting in `go.opentelemetry.io/otel/propagation` to prevent malformed or oversized baggage headers from flooding logs. ([GHSA-5wrp-cwcj-q835](https://github.com/open-telemetry/opentelemetry-go/security/advisories/GHSA-5wrp-cwcj-q835))
+
+## [1.43.0/0.65.0/0.19.0] 2026-04-02
+
+### Added
+
+- Add `IsRandom` and `WithRandom` on `TraceFlags`, and `IsRandom` on `SpanContext` in `go.opentelemetry.io/otel/trace` for [W3C Trace Context Level 2 Random Trace ID Flag](https://www.w3.org/TR/trace-context-2/#random-trace-id-flag) support. (#8012)
+- Add service detection with `WithService` in `go.opentelemetry.io/otel/sdk/resource`. (#7642)
+- Add `DefaultWithContext` and `EnvironmentWithContext` in `go.opentelemetry.io/otel/sdk/resource` to support plumbing `context.Context` through default and environment detectors. (#8051)
+- Support attributes with empty value (`attribute.EMPTY`) in `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc`. (#8038)
+- Support attributes with empty value (`attribute.EMPTY`) in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc`. (#8038)
+- Support attributes with empty value (`attribute.EMPTY`) in `go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc`. (#8038)
+- Support attributes with empty value (`attribute.EMPTY`) in `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp`. (#8038)
+- Support attributes with empty value (`attribute.EMPTY`) in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp`. (#8038)
+- Support attributes with empty value (`attribute.EMPTY`) in `go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp`. (#8038)
+- Support attributes with empty value (`attribute.EMPTY`) in `go.opentelemetry.io/otel/sdk/metric/metricdata/metricdatatest`. (#8038)
+- Add support for per-series start time tracking for cumulative metrics in `go.opentelemetry.io/otel/sdk/metric`.
+ Set `OTEL_GO_X_PER_SERIES_START_TIMESTAMPS=true` to enable. (#8060)
+- Add `WithCardinalityLimitSelector` for metric reader for configuring cardinality limits specific to the instrument kind. (#7855)
+
+### Changed
+
+- Introduce the `EMPTY` Type in `go.opentelemetry.io/otel/attribute` to reflect that an empty value is now a valid value, with `INVALID` remaining as a deprecated alias of `EMPTY`. (#8038)
+- Improve slice handling in `go.opentelemetry.io/otel/attribute` to optimize short slice values with fixed-size fast paths. (#8039)
+- Improve performance of span metric recording in `go.opentelemetry.io/otel/sdk/trace` by returning early if self-observability is not enabled. (#8067)
+- Improve formatting of metric data diffs in `go.opentelemetry.io/otel/sdk/metric/metricdata/metricdatatest`. (#8073)
+
+### Deprecated
+
+- Deprecate `INVALID` in `go.opentelemetry.io/otel/attribute`. Use `EMPTY` instead. (#8038)
+
+### Fixed
+
+- Return spec-compliant `TraceIdRatioBased` description. This is a breaking behavioral change, but it is necessary to
+ make the implementation [spec-compliant](https://opentelemetry.io/docs/specs/otel/trace/sdk/#traceidratiobased). (#8027)
+- Fix a race condition in `go.opentelemetry.io/otel/sdk/metric` where the lastvalue aggregation could collect the value 0 even when no zero-value measurements were recorded. (#8056)
+- Limit HTTP response body to 4 MiB in `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp` to mitigate excessive memory usage caused by a misconfigured or malicious server.
+ Responses exceeding the limit are treated as non-retryable errors. (#8108)
+- Limit HTTP response body to 4 MiB in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp` to mitigate excessive memory usage caused by a misconfigured or malicious server.
+ Responses exceeding the limit are treated as non-retryable errors. (#8108)
+- Limit HTTP response body to 4 MiB in `go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp` to mitigate excessive memory usage caused by a misconfigured or malicious server.
+ Responses exceeding the limit are treated as non-retryable errors. (#8108)
+- `WithHostID` detector in `go.opentelemetry.io/otel/sdk/resource` to use full path for `kenv` command on BSD. (#8113)
+- Fix missing `request.GetBody` in `go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp` to correctly handle HTTP2 GOAWAY frame. (#8096)
+
+## [1.42.0/0.64.0/0.18.0/0.0.16] 2026-03-06
+
+### Added
+
+- Add `go.opentelemetry.io/otel/semconv/v1.40.0` package.
+ The package contains semantic conventions from the `v1.40.0` version of the OpenTelemetry Semantic Conventions.
+ See the [migration documentation](./semconv/v1.40.0/MIGRATION.md) for information on how to upgrade from `go.opentelemetry.io/otel/semconv/v1.39.0`. (#7985)
+- Add `Err` and `SetErr` on `Record` in `go.opentelemetry.io/otel/log` to attach an error and set record exception attributes in `go.opentelemetry.io/otel/log/sdk`. (#7924)
+
+### Changed
+
+- `TracerProvider.ForceFlush` in `go.opentelemetry.io/otel/sdk/trace` joins errors together and continues iteration through SpanProcessors as opposed to returning the first encountered error without attempting exports on subsequent SpanProcessors. (#7856)
+
+### Fixed
+
+- Fix missing `request.GetBody` in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp` to correctly handle HTTP2 GOAWAY frame. (#7931)
+- Fix semconv v1.39.0 generated metric helpers skipping required attributes when extra attributes were empty. (#7964)
+- Preserve W3C TraceFlags bitmask (including the random Trace ID flag) during trace context extraction and injection in `go.opentelemetry.io/otel/propagation`. (#7834)
+
+### Removed
+
+- Drop support for [Go 1.24]. (#7984)
+
## [1.41.0/0.63.0/0.17.0/0.0.15] 2026-03-02
This release is the last to support [Go 1.24].
@@ -26,9 +189,6 @@ The next release will require at least [Go 1.25].
- Return an error when the endpoint is configured as insecure and with TLS configuration in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp`. (#7914)
- Return an error when the endpoint is configured as insecure and with TLS configuration in `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp`. (#7914)
-
-
-
## [1.40.0/0.62.0/0.16.0] 2026-02-02
### Added
@@ -3553,7 +3713,10 @@ It contains api and sdk for trace and meter.
- CircleCI build CI manifest files.
- CODEOWNERS file to track owners of this project.
-[Unreleased]: https://github.com/open-telemetry/opentelemetry-go/compare/v1.41.0...HEAD
+[Unreleased]: https://github.com/open-telemetry/opentelemetry-go/compare/v1.44.0...HEAD
+[1.44.0/0.66.0/0.20.0/0.0.17]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.44.0
+[1.43.0/0.65.0/0.19.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.43.0
+[1.42.0/0.64.0/0.18.0/0.0.16]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.42.0
[1.41.0/0.63.0/0.17.0/0.0.15]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.41.0
[1.40.0/0.62.0/0.16.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.40.0
[1.39.0/0.61.0/0.15.0/0.0.14]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.39.0
diff --git a/vendor/go.opentelemetry.io/otel/CLAUDE.md b/vendor/go.opentelemetry.io/otel/CLAUDE.md
new file mode 100644
index 000000000..dd3c4594f
--- /dev/null
+++ b/vendor/go.opentelemetry.io/otel/CLAUDE.md
@@ -0,0 +1,3 @@
+# Instructions for Claude Code
+
+@AGENTS.md
diff --git a/vendor/go.opentelemetry.io/otel/CONTRIBUTING.md b/vendor/go.opentelemetry.io/otel/CONTRIBUTING.md
index 38dede932..3ec17d683 100644
--- a/vendor/go.opentelemetry.io/otel/CONTRIBUTING.md
+++ b/vendor/go.opentelemetry.io/otel/CONTRIBUTING.md
@@ -11,6 +11,12 @@ for a summary description of past meetings. To request edit access,
join the meeting or get in touch on
[Slack](https://cloud-native.slack.com/archives/C01NPAXACKT).
+The meeting is open for all to join. We invite everyone to join our
+meeting, regardless of your experience level. Whether you're a
+seasoned OpenTelemetry developer, just starting your journey, or
+simply curious about the work we do, you're more than welcome to
+participate!
+
## Development
You can view and edit the source code by cloning this repository:
@@ -746,8 +752,8 @@ Encapsulate setup in constructor functions, ensuring clear ownership and scope:
import (
"errors"
- semconv "go.opentelemetry.io/otel/semconv/v1.39.0"
- "go.opentelemetry.io/otel/semconv/v1.39.0/otelconv"
+ semconv "go.opentelemetry.io/otel/semconv/v1.41.0"
+ "go.opentelemetry.io/otel/semconv/v1.41.0/otelconv"
)
type SDKComponent struct {
@@ -808,11 +814,11 @@ func (c *Component) initObservability() {
#### Performance
-When observability is disabled there should be little to no overhead.
+When observability is disabled or the instrument is not `Enabled`, there should be little to no overhead.
```go
func (e *Exporter) ExportSpans(ctx context.Context, spans []trace.ReadOnlySpan) error {
- if e.inst != nil {
+ if e.inst != nil && e.inst.Enabled(ctx) {
attrs := expensiveOperation()
e.inst.recordSpanInflight(ctx, int64(len(spans)), attrs...)
}
@@ -829,7 +835,7 @@ func (e *Exporter) ExportSpans(ctx context.Context, spans []trace.ReadOnlySpan)
}
func (i *instrumentation) recordSpanInflight(ctx context.Context, count int64, attrs ...attribute.KeyValue) {
- if i == nil || i.inflight == nil {
+ if i == nil || i.inflight == nil || !i.inflight.Enabled(ctx) {
return
}
i.inflight.Add(ctx, count, metric.WithAttributes(attrs...))
@@ -865,8 +871,12 @@ var (
)
func (i *instrumentation) record(ctx context.Context, value int64, baseAttrs ...attribute.KeyValue) {
+ if !i.counter.Enabled(ctx) {
+ return
+ }
attrs := attrPool.Get().(*[]attribute.KeyValue)
defer func() {
+ clear(*attrs) // Clear references to strings/etc to let GC collect them.
*attrs = (*attrs)[:0] // Reset.
attrPool.Put(attrs)
}()
@@ -877,6 +887,7 @@ func (i *instrumentation) record(ctx context.Context, value int64, baseAttrs ...
addOpt := addOptPool.Get().(*[]metric.AddOption)
defer func() {
+ clear(*addOpt)
*addOpt = (*addOpt)[:0]
addOptPool.Put(addOpt)
}()
@@ -1007,16 +1018,20 @@ Ensure observability measurements receive the correct context, especially for tr
```go
func (e *Exporter) ExportSpans(ctx context.Context, spans []trace.ReadOnlySpan) error {
// Use the provided context for observability measurements
- e.inst.recordSpanExportStarted(ctx, len(spans))
+ if e.inst.Enabled(ctx) {
+ e.inst.recordSpanExportStarted(ctx, len(spans))
+ }
err := e.doExport(ctx, spans)
- if err != nil {
- e.inst.recordSpanExportFailed(ctx, len(spans), err)
- } else {
- e.inst.recordSpanExportSucceeded(ctx, len(spans))
+ if e.inst.Enabled(ctx) {
+ if err != nil {
+ e.inst.recordSpanExportFailed(ctx, len(spans), err)
+ } else {
+ e.inst.recordSpanExportSucceeded(ctx, len(spans))
+ }
}
-
+
return err
}
```
@@ -1039,7 +1054,7 @@ func (e *Exporter) ExportSpans(ctx context.Context, spans []trace.ReadOnlySpan)
All observability metrics should follow the [OpenTelemetry Semantic Conventions for SDK metrics](https://github.com/open-telemetry/semantic-conventions/blob/1cf2476ae5e518225a766990a28a6d5602bd5a30/docs/otel/sdk-metrics.md).
-Use the metric semantic conventions convenience package [otelconv](./semconv/v1.39.0/otelconv/metric.go).
+Use the metric semantic conventions convenience package [otelconv](./semconv/v1.41.0/otelconv/metric.go).
##### Component Identification
@@ -1109,6 +1124,68 @@ func TestObservability(t *testing.T) {
Test order should not affect results.
Ensure that any global state (e.g. component ID counters) is reset between tests.
+### Experimental Features
+
+To support the development of new features in the specification, we use the following patterns to implement in-development features without adding new public artifacts in stable modules.
+
+#### Experimental behavior with no API artifacts
+
+Features that change behavior without changing the API (e.g., exemplar collection, auto-generation of identifiers) are implemented behind a feature gate.
+The implementation resides in an `/internal/x` package and is activated through environment variables with the `OTEL_GO_X_` prefix (e.g., `OTEL_GO_X_OBSERVABILITY`).
+The feature must be documented in a `README.md` file in the `/internal/x` package.
+
+#### Experimental methods on SDK-only interfaces
+
+Features that require new methods on SDK interfaces are defined as a new interface in an experimental module (e.g., `go.opentelemetry.io/otel/sdk/x`).
+The SDK uses type assertions (without importing the unstable package) to check if passing types implement these experimental interfaces.
+The SDK must not depend on the experimental module.
+
+#### Experimental structs, functions, or interfaces
+
+Features that don't need any changes to the existing stable package are implemented in an experimental module (e.g., `go.opentelemetry.io/otel/sdk/x`).
+
+#### Experimental signals and components
+
+New telemetry signals (e.g., Logs before stabilization) and components (e.g. bridges) are hosted in new, unstable modules (e.g., `go.opentelemetry.io/otel/log` before 1.0.0).
+The package should have the final name it will use once stabilized (i.e. not `/x`), and is released at a v0.x.y version to indicate it is not stable.
+Most new components are hosted in [opentelemetry-go-contrib](https://github.com/open-telemetry/opentelemetry-go-contrib).
+
+#### Experimental options for API or SDK functions
+
+Experimental Options functions are implemented in an experimental module (e.g., `go.opentelemetry.io/otel/sdk/x`).
+The return type of the Option function must embed the option's type (e.g. `metric.InstrumentOption`), and have an `Experimental()` method to prevent the API from panicking when the option is used.
+The SDK uses type assertions (without importing the unstable package) to check if passing types implement these experimental interfaces.
+The SDK must not depend on the experimental module.
+
+For example:
+
+```go
+type myOption struct {
+ // Embed the stable option type.
+ metric.InstrumentOption
+ value string
+}
+
+// Experimental prevents the API from panicking when the option is used.
+func (o myOption) Experimental() {}
+
+// The SDK can use type assertions to use this function.
+func (o myOption) Value() string { return o.value }
+
+func WithMyOption(value string) metric.InstrumentOption {
+ return myOption{value: value}
+}
+```
+
+#### Not Supported
+
+The following kinds of experimental features are **not currently supported** on stable interfaces:
+
+- Experimental methods on API interfaces
+- Experimental fields for API or SDK exported structs
+
+In some cases forks or long-lived branches may be used for prototyping these features.
+
## Approvers and Maintainers
### Maintainers
diff --git a/vendor/go.opentelemetry.io/otel/Makefile b/vendor/go.opentelemetry.io/otel/Makefile
index fc4befb22..de63a5e9b 100644
--- a/vendor/go.opentelemetry.io/otel/Makefile
+++ b/vendor/go.opentelemetry.io/otel/Makefile
@@ -38,10 +38,14 @@ CROSSLINK = $(TOOLS)/crosslink
$(TOOLS)/crosslink: PACKAGE=go.opentelemetry.io/build-tools/crosslink
SEMCONVKIT = $(TOOLS)/semconvkit
+SEMCONVKIT_FILES := $(sort $(shell find $(TOOLS_MOD_DIR)/semconvkit -type f))
$(TOOLS)/semconvkit: PACKAGE=go.opentelemetry.io/otel/$(TOOLS_MOD_DIR)/semconvkit
+$(TOOLS)/semconvkit: $(SEMCONVKIT_FILES)
VERIFYREADMES = $(TOOLS)/verifyreadmes
+VERIFYREADMES_FILES := $(sort $(shell find $(TOOLS_MOD_DIR)/verifyreadmes -type f))
$(TOOLS)/verifyreadmes: PACKAGE=go.opentelemetry.io/otel/$(TOOLS_MOD_DIR)/verifyreadmes
+$(TOOLS)/verifyreadmes: $(VERIFYREADMES_FILES)
GOLANGCI_LINT = $(TOOLS)/golangci-lint
$(TOOLS)/golangci-lint: PACKAGE=github.com/golangci/golangci-lint/v2/cmd/golangci-lint
@@ -185,11 +189,18 @@ test-coverage: $(GOCOVMERGE)
.PHONY: benchmark
benchmark: $(OTEL_GO_MOD_DIRS:%=benchmark/%)
benchmark/%:
- @echo "$(GO) test -run=xxxxxMatchNothingxxxxx -bench=. $*..." \
- && cd $* \
- && $(GO) list ./... \
- | grep -v third_party \
- | xargs $(GO) test -run=xxxxxMatchNothingxxxxx -bench=.
+ cd $* && $(GO) test -run='^$$' -bench=. $(ARGS) ./...
+
+# sdk/metric is split into two shards to work around CodSpeed limitations.
+# See https://github.com/CodSpeedHQ/codspeed-go/issues/56
+BENCHMARK_SHARDS := $(filter-out ./sdk/metric,$(OTEL_GO_MOD_DIRS)) ./sdk/metric/root ./sdk/metric/internal
+benchmark/./sdk/metric/root:
+ cd ./sdk/metric && $(GO) test -run='^$$' -bench=. $(ARGS) . ./exemplar/...
+benchmark/./sdk/metric/internal:
+ cd ./sdk/metric && $(GO) test -run='^$$' -bench=. $(ARGS) ./internal/...
+
+print-sharded-benchmarks:
+ @echo $(BENCHMARK_SHARDS) | jq -cR 'split(" ")'
.PHONY: golangci-lint golangci-lint-fix
golangci-lint-fix: ARGS=--fix
diff --git a/vendor/go.opentelemetry.io/otel/README.md b/vendor/go.opentelemetry.io/otel/README.md
index 6b1e170c4..16a72004c 100644
--- a/vendor/go.opentelemetry.io/otel/README.md
+++ b/vendor/go.opentelemetry.io/otel/README.md
@@ -55,25 +55,18 @@ Currently, this project supports the following environments.
|----------|------------|--------------|
| Ubuntu | 1.26 | amd64 |
| Ubuntu | 1.25 | amd64 |
-| Ubuntu | 1.24 | amd64 |
| Ubuntu | 1.26 | 386 |
| Ubuntu | 1.25 | 386 |
-| Ubuntu | 1.24 | 386 |
| Ubuntu | 1.26 | arm64 |
| Ubuntu | 1.25 | arm64 |
-| Ubuntu | 1.24 | arm64 |
| macOS | 1.26 | amd64 |
| macOS | 1.25 | amd64 |
-| macOS | 1.24 | amd64 |
| macOS | 1.26 | arm64 |
| macOS | 1.25 | arm64 |
-| macOS | 1.24 | arm64 |
| Windows | 1.26 | amd64 |
| Windows | 1.25 | amd64 |
-| Windows | 1.24 | amd64 |
| Windows | 1.26 | 386 |
| Windows | 1.25 | 386 |
-| Windows | 1.24 | 386 |
While this project should work for other systems, no compatibility guarantees
are made for those systems currently.
diff --git a/vendor/go.opentelemetry.io/otel/RELEASING.md b/vendor/go.opentelemetry.io/otel/RELEASING.md
index 861756fd7..6aff7548c 100644
--- a/vendor/go.opentelemetry.io/otel/RELEASING.md
+++ b/vendor/go.opentelemetry.io/otel/RELEASING.md
@@ -4,7 +4,9 @@
Create a `Version Release` issue to track the release process.
-## Semantic Convention Generation
+## Semantic Convention Upgrade
+
+### Semantic Convention Generation
New versions of the [OpenTelemetry Semantic Conventions] mean new versions of the `semconv` package need to be generated.
The `semconv-generate` make target is used for this.
@@ -22,6 +24,43 @@ make semconv-generate # Uses the exported TAG.
This should create a new sub-package of [`semconv`](./semconv).
Ensure things look correct before submitting a pull request to include the addition.
+The `CHANGELOG.md` should also be updated to reflect the new changes:
+
+```md
+- The `go.opentelemetry.io/otel/semconv/` package. The package contains semantic conventions from the `` version of the OpenTelemetry Semantic Conventions. See the [migration documentation](./semconv//MIGRATION.md) for information on how to upgrade from `go.opentelemetry.io/otel/semconv/`. (#PR_NUMBER)
+```
+
+> **Tip:** Change to the release and prior version to match the changes
+
+### Update semconv imports
+
+Once the new semconv module has been generated, update all semconv imports throughout the codebase to reference the new version:
+
+```go
+// Before
+semconv "go.opentelemetry.io/otel/semconv/v1.37.0"
+"go.opentelemetry.io/otel/semconv/v1.37.0/otelconv"
+
+
+// After
+semconv "go.opentelemetry.io/otel/semconv/v1.39.0"
+"go.opentelemetry.io/otel/semconv/v1.39.0/otelconv"
+```
+
+Once complete, run `make` to check for any compilation or test failures.
+
+#### Handling attribute changes
+
+Some semconv releases might add new attributes or impact attributes that are currently being used. Changes could stem from a simple renaming, to more complex changes like merging attributes and property values being changed.
+
+One should update the code to the new attributes that supersede the impacted ones, hence sticking to the semantic conventions. However, legacy attributes might still be emitted in accordance to the `OTEL_SEMCONV_STABILITY_OPT_IN` environment variable.
+
+For an example on how such migration might have to be tracked and performed, see issue [#7806](https://github.com/open-telemetry/opentelemetry-go/issues/7806).
+
+### Go contrib linter update
+
+Update [.golangci.yml](https://github.com/open-telemetry/opentelemetry-go-contrib/blob/main/.golangci.yml) in [opentelemetry-go-contrib](https://github.com/open-telemetry/opentelemetry-go-contrib/) to mandate the new semconv version.
+
## Breaking changes validation
You can run `make gorelease` which runs [gorelease](https://pkg.go.dev/golang.org/x/exp/cmd/gorelease) to ensure that there are no unwanted changes made in the public API.
diff --git a/vendor/go.opentelemetry.io/otel/attribute/encoder.go b/vendor/go.opentelemetry.io/otel/attribute/encoder.go
index 6cc1a1655..ca186d8ac 100644
--- a/vendor/go.opentelemetry.io/otel/attribute/encoder.go
+++ b/vendor/go.opentelemetry.io/otel/attribute/encoder.go
@@ -53,7 +53,7 @@ var (
_ Encoder = &defaultAttrEncoder{}
// encoderIDCounter is for generating IDs for other attribute encoders.
- encoderIDCounter uint64
+ encoderIDCounter atomic.Uint64
defaultEncoderOnce sync.Once
defaultEncoderID = NewEncoderID()
@@ -64,7 +64,7 @@ var (
// once per each type of attribute encoder. Preferably in init() or in var
// definition.
func NewEncoderID() EncoderID {
- return EncoderID{value: atomic.AddUint64(&encoderIDCounter, 1)}
+ return EncoderID{value: encoderIDCounter.Add(1)}
}
// DefaultEncoder returns an attribute encoder that encodes attributes in such
@@ -105,7 +105,9 @@ func (d *defaultAttrEncoder) Encode(iter Iterator) string {
if keyValue.Value.Type() == STRING {
copyAndEscape(buf, keyValue.Value.AsString())
} else {
- _, _ = buf.WriteString(keyValue.Value.Emit())
+ _, _ = buf.WriteString(
+ keyValue.Value.Emit(),
+ ) //nolint:staticcheck // Preserve the existing default encoder output.
}
}
return buf.String()
diff --git a/vendor/go.opentelemetry.io/otel/attribute/hash.go b/vendor/go.opentelemetry.io/otel/attribute/hash.go
index 6aa69aeae..92f39ffe7 100644
--- a/vendor/go.opentelemetry.io/otel/attribute/hash.go
+++ b/vendor/go.opentelemetry.io/otel/attribute/hash.go
@@ -27,6 +27,9 @@ const (
int64SliceID uint64 = 3762322556277578591 // "_[]int64" (little endian)
float64SliceID uint64 = 7308324551835016539 // "[]double" (little endian)
stringSliceID uint64 = 7453010373645655387 // "[]string" (little endian)
+ byteSliceID uint64 = 6874028470941080415 // "_[]byte_" (little endian)
+ sliceID uint64 = 7883494272577650031 // "__slice_" (little endian)
+ emptyID uint64 = 7305809155345288421 // "__empty_" (little endian)
)
// hashKVs returns a new xxHash64 hash of kvs.
@@ -41,52 +44,87 @@ func hashKVs(kvs []KeyValue) uint64 {
// hashKV returns the xxHash64 hash of kv with h as the base.
func hashKV(h xxhash.Hash, kv KeyValue) xxhash.Hash {
h = h.String(string(kv.Key))
+ return hashValue(h, kv.Value)
+}
- switch kv.Value.Type() {
+func hashValue(h xxhash.Hash, v Value) xxhash.Hash {
+ switch v.Type() {
case BOOL:
h = h.Uint64(boolID)
- h = h.Uint64(kv.Value.numeric)
+ h = h.Uint64(v.numeric)
case INT64:
h = h.Uint64(int64ID)
- h = h.Uint64(kv.Value.numeric)
+ h = h.Uint64(v.numeric)
case FLOAT64:
h = h.Uint64(float64ID)
// Assumes numeric stored with math.Float64bits.
- h = h.Uint64(kv.Value.numeric)
+ h = h.Uint64(v.numeric)
case STRING:
h = h.Uint64(stringID)
- h = h.String(kv.Value.stringly)
+ h = h.String(v.stringly)
case BOOLSLICE:
h = h.Uint64(boolSliceID)
- rv := reflect.ValueOf(kv.Value.slice)
+ rv := reflect.ValueOf(v.slice)
for i := 0; i < rv.Len(); i++ {
h = h.Bool(rv.Index(i).Bool())
}
case INT64SLICE:
h = h.Uint64(int64SliceID)
- rv := reflect.ValueOf(kv.Value.slice)
+ rv := reflect.ValueOf(v.slice)
for i := 0; i < rv.Len(); i++ {
h = h.Int64(rv.Index(i).Int())
}
case FLOAT64SLICE:
h = h.Uint64(float64SliceID)
- rv := reflect.ValueOf(kv.Value.slice)
+ rv := reflect.ValueOf(v.slice)
for i := 0; i < rv.Len(); i++ {
h = h.Float64(rv.Index(i).Float())
}
case STRINGSLICE:
h = h.Uint64(stringSliceID)
- rv := reflect.ValueOf(kv.Value.slice)
+ rv := reflect.ValueOf(v.slice)
for i := 0; i < rv.Len(); i++ {
h = h.String(rv.Index(i).String())
}
- case INVALID:
+ case BYTESLICE:
+ h = h.Uint64(byteSliceID)
+ h = h.String(v.stringly)
+ case SLICE:
+ h = h.Uint64(sliceID)
+ switch vals := v.slice.(type) {
+ case [0]Value:
+ // No values to hash, but the type identifier is still hashed above.
+ case [1]Value:
+ h = hashValueSlice(h, vals[:])
+ case [2]Value:
+ h = hashValueSlice(h, vals[:])
+ case [3]Value:
+ h = hashValueSlice(h, vals[:])
+ case [4]Value:
+ h = hashValueSlice(h, vals[:])
+ case [5]Value:
+ h = hashValueSlice(h, vals[:])
+ default:
+ rv := reflect.ValueOf(v.slice)
+ for i := 0; i < rv.Len(); i++ {
+ h = hashValue(h, rv.Index(i).Interface().(Value))
+ }
+ }
+ case EMPTY:
+ h = h.Uint64(emptyID)
default:
// Logging is an alternative, but using the internal logger here
// causes an import cycle so it is not done.
- v := kv.Value.AsInterface()
- msg := fmt.Sprintf("unknown value type: %[1]v (%[1]T)", v)
+ val := v.AsInterface()
+ msg := fmt.Sprintf("unknown value type: %[1]v (%[1]T)", val)
panic(msg)
}
return h
}
+
+func hashValueSlice(h xxhash.Hash, vals []Value) xxhash.Hash {
+ for _, v := range vals {
+ h = hashValue(h, v)
+ }
+ return h
+}
diff --git a/vendor/go.opentelemetry.io/otel/attribute/internal/attribute.go b/vendor/go.opentelemetry.io/otel/attribute/internal/attribute.go
index 7f5eae877..d9f51fa2d 100644
--- a/vendor/go.opentelemetry.io/otel/attribute/internal/attribute.go
+++ b/vendor/go.opentelemetry.io/otel/attribute/internal/attribute.go
@@ -11,80 +11,63 @@ import (
"reflect"
)
-// BoolSliceValue converts a bool slice into an array with same elements as slice.
-func BoolSliceValue(v []bool) any {
- cp := reflect.New(reflect.ArrayOf(len(v), reflect.TypeFor[bool]())).Elem()
- reflect.Copy(cp, reflect.ValueOf(v))
- return cp.Interface()
+// sliceElem is the exact set of element types stored in attribute slice values.
+// Using a closed set prevents accidental instantiations for unsupported types.
+type sliceElem interface {
+ bool | int64 | float64 | string
}
-// Int64SliceValue converts an int64 slice into an array with same elements as slice.
-func Int64SliceValue(v []int64) any {
- cp := reflect.New(reflect.ArrayOf(len(v), reflect.TypeFor[int64]())).Elem()
- reflect.Copy(cp, reflect.ValueOf(v))
- return cp.Interface()
-}
-
-// Float64SliceValue converts a float64 slice into an array with same elements as slice.
-func Float64SliceValue(v []float64) any {
- cp := reflect.New(reflect.ArrayOf(len(v), reflect.TypeFor[float64]())).Elem()
- reflect.Copy(cp, reflect.ValueOf(v))
- return cp.Interface()
-}
+// SliceValue converts a slice into an array with the same elements.
+func SliceValue[T sliceElem](v []T) any {
+ // Keep only the common tiny-slice cases out of reflection. Extending this
+ // much further increases code size for diminishing benefit while larger
+ // slices still need the generic reflective path to preserve comparability.
+ // This matches the short lengths that show up most often in local
+ // benchmarks and semantic convention examples while leaving larger, less
+ // predictable slices on the generic reflective path.
+ switch len(v) {
+ case 0:
+ return [0]T{}
+ case 1:
+ return [1]T{v[0]}
+ case 2:
+ return [2]T{v[0], v[1]}
+ case 3:
+ return [3]T{v[0], v[1], v[2]}
+ }
-// StringSliceValue converts a string slice into an array with same elements as slice.
-func StringSliceValue(v []string) any {
- cp := reflect.New(reflect.ArrayOf(len(v), reflect.TypeFor[string]())).Elem()
- reflect.Copy(cp, reflect.ValueOf(v))
- return cp.Interface()
+ return sliceValueReflect(v)
}
-// AsBoolSlice converts a bool array into a slice into with same elements as array.
-func AsBoolSlice(v any) []bool {
- rv := reflect.ValueOf(v)
- if rv.Type().Kind() != reflect.Array {
- return nil
+// AsSlice converts an array into a slice with the same elements.
+func AsSlice[T sliceElem](v any) []T {
+ // Mirror the small fixed-array fast path used by SliceValue.
+ switch a := v.(type) {
+ case [0]T:
+ return []T{}
+ case [1]T:
+ return []T{a[0]}
+ case [2]T:
+ return []T{a[0], a[1]}
+ case [3]T:
+ return []T{a[0], a[1], a[2]}
}
- cpy := make([]bool, rv.Len())
- if len(cpy) > 0 {
- _ = reflect.Copy(reflect.ValueOf(cpy), rv)
- }
- return cpy
-}
-// AsInt64Slice converts an int64 array into a slice into with same elements as array.
-func AsInt64Slice(v any) []int64 {
- rv := reflect.ValueOf(v)
- if rv.Type().Kind() != reflect.Array {
- return nil
- }
- cpy := make([]int64, rv.Len())
- if len(cpy) > 0 {
- _ = reflect.Copy(reflect.ValueOf(cpy), rv)
- }
- return cpy
+ return asSliceReflect[T](v)
}
-// AsFloat64Slice converts a float64 array into a slice into with same elements as array.
-func AsFloat64Slice(v any) []float64 {
- rv := reflect.ValueOf(v)
- if rv.Type().Kind() != reflect.Array {
- return nil
- }
- cpy := make([]float64, rv.Len())
- if len(cpy) > 0 {
- _ = reflect.Copy(reflect.ValueOf(cpy), rv)
- }
- return cpy
+func sliceValueReflect[T sliceElem](v []T) any {
+ cp := reflect.New(reflect.ArrayOf(len(v), reflect.TypeFor[T]())).Elem()
+ reflect.Copy(cp, reflect.ValueOf(v))
+ return cp.Interface()
}
-// AsStringSlice converts a string array into a slice into with same elements as array.
-func AsStringSlice(v any) []string {
+func asSliceReflect[T sliceElem](v any) []T {
rv := reflect.ValueOf(v)
- if rv.Type().Kind() != reflect.Array {
+ if !rv.IsValid() || rv.Kind() != reflect.Array || rv.Type().Elem() != reflect.TypeFor[T]() {
return nil
}
- cpy := make([]string, rv.Len())
+ cpy := make([]T, rv.Len())
if len(cpy) > 0 {
_ = reflect.Copy(reflect.ValueOf(cpy), rv)
}
diff --git a/vendor/go.opentelemetry.io/otel/attribute/key.go b/vendor/go.opentelemetry.io/otel/attribute/key.go
index 80a9e5643..cdc7089e8 100644
--- a/vendor/go.opentelemetry.io/otel/attribute/key.go
+++ b/vendor/go.opentelemetry.io/otel/attribute/key.go
@@ -117,6 +117,28 @@ func (k Key) StringSlice(v []string) KeyValue {
}
}
+// ByteSlice creates a KeyValue instance with a BYTESLICE Value.
+//
+// If creating both a key and value at the same time, use the provided
+// convenience function instead -- ByteSlice(name, value).
+func (k Key) ByteSlice(v []byte) KeyValue {
+ return KeyValue{
+ Key: k,
+ Value: ByteSliceValue(v),
+ }
+}
+
+// Slice creates a KeyValue instance with a SLICE Value.
+//
+// If creating both a key and value at the same time, use the provided
+// convenience function instead -- Slice(name, values...).
+func (k Key) Slice(v ...Value) KeyValue {
+ return KeyValue{
+ Key: k,
+ Value: SliceValue(v...),
+ }
+}
+
// Defined reports whether the key is not empty.
func (k Key) Defined() bool {
return len(k) != 0
diff --git a/vendor/go.opentelemetry.io/otel/attribute/kv.go b/vendor/go.opentelemetry.io/otel/attribute/kv.go
index 8c6928ca7..eeb76a134 100644
--- a/vendor/go.opentelemetry.io/otel/attribute/kv.go
+++ b/vendor/go.opentelemetry.io/otel/attribute/kv.go
@@ -15,7 +15,7 @@ type KeyValue struct {
// Valid reports whether kv is a valid OpenTelemetry attribute.
func (kv KeyValue) Valid() bool {
- return kv.Key.Defined() && kv.Value.Type() != INVALID
+ return kv.Key.Defined()
}
// Bool creates a KeyValue with a BOOL Value type.
@@ -68,6 +68,16 @@ func StringSlice(k string, v []string) KeyValue {
return Key(k).StringSlice(v)
}
+// ByteSlice creates a KeyValue with a BYTESLICE Value type.
+func ByteSlice(k string, v []byte) KeyValue {
+ return Key(k).ByteSlice(v)
+}
+
+// Slice creates a KeyValue with a SLICE Value type.
+func Slice(k string, v ...Value) KeyValue {
+ return Key(k).Slice(v...)
+}
+
// Stringer creates a new key-value pair with a passed name and a string
// value generated by the passed Stringer interface.
func Stringer(k string, v fmt.Stringer) KeyValue {
diff --git a/vendor/go.opentelemetry.io/otel/attribute/set.go b/vendor/go.opentelemetry.io/otel/attribute/set.go
index 6572c98b1..a4b6ce81d 100644
--- a/vendor/go.opentelemetry.io/otel/attribute/set.go
+++ b/vendor/go.opentelemetry.io/otel/attribute/set.go
@@ -401,7 +401,7 @@ func computeDataFixed(kvs []KeyValue) any {
func computeDataReflect(kvs []KeyValue) any {
at := reflect.New(reflect.ArrayOf(len(kvs), keyValueType)).Elem()
for i, keyValue := range kvs {
- *(at.Index(i).Addr().Interface().(*KeyValue)) = keyValue
+ *at.Index(i).Addr().Interface().(*KeyValue) = keyValue
}
return at.Interface()
}
@@ -415,7 +415,7 @@ func (l *Set) MarshalJSON() ([]byte, error) {
func (l Set) MarshalLog() any {
kvs := make(map[string]string)
for _, kv := range l.ToSlice() {
- kvs[string(kv.Key)] = kv.Value.Emit()
+ kvs[string(kv.Key)] = kv.Value.String()
}
return kvs
}
diff --git a/vendor/go.opentelemetry.io/otel/attribute/type_string.go b/vendor/go.opentelemetry.io/otel/attribute/type_string.go
index 24f1fa37d..dbc01d324 100644
--- a/vendor/go.opentelemetry.io/otel/attribute/type_string.go
+++ b/vendor/go.opentelemetry.io/otel/attribute/type_string.go
@@ -8,7 +8,7 @@ func _() {
// An "invalid array index" compiler error signifies that the constant values have changed.
// Re-run the stringer command to generate them again.
var x [1]struct{}
- _ = x[INVALID-0]
+ _ = x[EMPTY-0]
_ = x[BOOL-1]
_ = x[INT64-2]
_ = x[FLOAT64-3]
@@ -17,11 +17,13 @@ func _() {
_ = x[INT64SLICE-6]
_ = x[FLOAT64SLICE-7]
_ = x[STRINGSLICE-8]
+ _ = x[BYTESLICE-9]
+ _ = x[SLICE-10]
}
-const _Type_name = "INVALIDBOOLINT64FLOAT64STRINGBOOLSLICEINT64SLICEFLOAT64SLICESTRINGSLICE"
+const _Type_name = "EMPTYBOOLINT64FLOAT64STRINGBOOLSLICEINT64SLICEFLOAT64SLICESTRINGSLICEBYTESLICESLICE"
-var _Type_index = [...]uint8{0, 7, 11, 16, 23, 29, 38, 48, 60, 71}
+var _Type_index = [...]uint8{0, 5, 9, 14, 21, 27, 36, 46, 58, 69, 78, 83}
func (i Type) String() string {
idx := int(i) - 0
diff --git a/vendor/go.opentelemetry.io/otel/attribute/value.go b/vendor/go.opentelemetry.io/otel/attribute/value.go
index 5931e7129..0529fefae 100644
--- a/vendor/go.opentelemetry.io/otel/attribute/value.go
+++ b/vendor/go.opentelemetry.io/otel/attribute/value.go
@@ -4,10 +4,14 @@
package attribute // import "go.opentelemetry.io/otel/attribute"
import (
+ "encoding/base64"
"encoding/json"
"fmt"
+ "math"
"reflect"
"strconv"
+ "strings"
+ "unicode/utf8"
attribute "go.opentelemetry.io/otel/attribute/internal"
)
@@ -18,6 +22,8 @@ import (
type Type int // nolint: revive // redefines builtin Type.
// Value represents the value part in key-value pairs.
+//
+// Note that the zero value is a valid empty value.
type Value struct {
vtype Type
numeric uint64
@@ -26,8 +32,8 @@ type Value struct {
}
const (
- // INVALID is used for a Value with no value set.
- INVALID Type = iota
+ // EMPTY is used for a Value with no value set.
+ EMPTY Type = iota
// BOOL is a boolean Type Value.
BOOL
// INT64 is a 64-bit signed integral Type Value.
@@ -44,6 +50,14 @@ const (
FLOAT64SLICE
// STRINGSLICE is a slice of strings Type Value.
STRINGSLICE
+ // BYTESLICE is a slice of bytes Type Value.
+ BYTESLICE
+ // SLICE is a slice of Value Type values.
+ SLICE
+ // INVALID is used for a Value with no value set.
+ //
+ // Deprecated: Use EMPTY instead as an empty value is a valid value.
+ INVALID = EMPTY
)
// BoolValue creates a BOOL Value.
@@ -56,7 +70,7 @@ func BoolValue(v bool) Value {
// BoolSliceValue creates a BOOLSLICE Value.
func BoolSliceValue(v []bool) Value {
- return Value{vtype: BOOLSLICE, slice: attribute.BoolSliceValue(v)}
+ return Value{vtype: BOOLSLICE, slice: attribute.SliceValue(v)}
}
// IntValue creates an INT64 Value.
@@ -64,16 +78,30 @@ func IntValue(v int) Value {
return Int64Value(int64(v))
}
-// IntSliceValue creates an INTSLICE Value.
+// IntSliceValue creates an INT64SLICE Value.
func IntSliceValue(v []int) Value {
- cp := reflect.New(reflect.ArrayOf(len(v), reflect.TypeFor[int64]()))
- for i, val := range v {
- cp.Elem().Index(i).SetInt(int64(val))
- }
- return Value{
- vtype: INT64SLICE,
- slice: cp.Elem().Interface(),
+ val := Value{vtype: INT64SLICE}
+
+ // Avoid the common tiny-slice cases from allocating a new slice.
+ switch len(v) {
+ case 0:
+ val.slice = [0]int64{}
+ case 1:
+ val.slice = [1]int64{int64(v[0])}
+ case 2:
+ val.slice = [2]int64{int64(v[0]), int64(v[1])}
+ case 3:
+ val.slice = [3]int64{int64(v[0]), int64(v[1]), int64(v[2])}
+ default:
+ // Fallback to a new slice for larger slices.
+ cp := make([]int64, len(v))
+ for i, val := range v {
+ cp[i] = int64(val)
+ }
+ val.slice = attribute.SliceValue(cp)
}
+
+ return val
}
// Int64Value creates an INT64 Value.
@@ -86,7 +114,7 @@ func Int64Value(v int64) Value {
// Int64SliceValue creates an INT64SLICE Value.
func Int64SliceValue(v []int64) Value {
- return Value{vtype: INT64SLICE, slice: attribute.Int64SliceValue(v)}
+ return Value{vtype: INT64SLICE, slice: attribute.SliceValue(v)}
}
// Float64Value creates a FLOAT64 Value.
@@ -99,7 +127,7 @@ func Float64Value(v float64) Value {
// Float64SliceValue creates a FLOAT64SLICE Value.
func Float64SliceValue(v []float64) Value {
- return Value{vtype: FLOAT64SLICE, slice: attribute.Float64SliceValue(v)}
+ return Value{vtype: FLOAT64SLICE, slice: attribute.SliceValue(v)}
}
// StringValue creates a STRING Value.
@@ -112,7 +140,20 @@ func StringValue(v string) Value {
// StringSliceValue creates a STRINGSLICE Value.
func StringSliceValue(v []string) Value {
- return Value{vtype: STRINGSLICE, slice: attribute.StringSliceValue(v)}
+ return Value{vtype: STRINGSLICE, slice: attribute.SliceValue(v)}
+}
+
+// ByteSliceValue creates a BYTESLICE Value.
+func ByteSliceValue(v []byte) Value {
+ return Value{
+ vtype: BYTESLICE,
+ stringly: string(v),
+ }
+}
+
+// SliceValue creates a SLICE Value.
+func SliceValue(v ...Value) Value {
+ return Value{vtype: SLICE, slice: sliceValue(v)}
}
// Type returns a type of the Value.
@@ -136,7 +177,7 @@ func (v Value) AsBoolSlice() []bool {
}
func (v Value) asBoolSlice() []bool {
- return attribute.AsBoolSlice(v.slice)
+ return attribute.AsSlice[bool](v.slice)
}
// AsInt64 returns the int64 value. Make sure that the Value's type is
@@ -155,7 +196,7 @@ func (v Value) AsInt64Slice() []int64 {
}
func (v Value) asInt64Slice() []int64 {
- return attribute.AsInt64Slice(v.slice)
+ return attribute.AsSlice[int64](v.slice)
}
// AsFloat64 returns the float64 value. Make sure that the Value's
@@ -174,7 +215,7 @@ func (v Value) AsFloat64Slice() []float64 {
}
func (v Value) asFloat64Slice() []float64 {
- return attribute.AsFloat64Slice(v.slice)
+ return attribute.AsSlice[float64](v.slice)
}
// AsString returns the string value. Make sure that the Value's type
@@ -193,7 +234,60 @@ func (v Value) AsStringSlice() []string {
}
func (v Value) asStringSlice() []string {
- return attribute.AsStringSlice(v.slice)
+ return attribute.AsSlice[string](v.slice)
+}
+
+// AsSlice returns the []Value value. Make sure that the Value's type is
+// SLICE.
+func (v Value) AsSlice() []Value {
+ if v.vtype != SLICE {
+ return nil
+ }
+ return v.asSlice()
+}
+
+func (v Value) asSlice() []Value {
+ switch vals := v.slice.(type) {
+ case [0]Value:
+ return []Value{}
+ case [1]Value:
+ return []Value{vals[0]}
+ case [2]Value:
+ return []Value{vals[0], vals[1]}
+ case [3]Value:
+ return []Value{vals[0], vals[1], vals[2]}
+ case [4]Value:
+ return []Value{vals[0], vals[1], vals[2], vals[3]}
+ case [5]Value:
+ return []Value{vals[0], vals[1], vals[2], vals[3], vals[4]}
+ default:
+ return asValueSliceReflect(v.slice)
+ }
+}
+
+func asValueSliceReflect(v any) []Value {
+ rv := reflect.ValueOf(v)
+ if !rv.IsValid() || rv.Kind() != reflect.Array || rv.Type().Elem() != reflect.TypeFor[Value]() {
+ return nil
+ }
+ cpy := make([]Value, rv.Len())
+ if len(cpy) > 0 {
+ _ = reflect.Copy(reflect.ValueOf(cpy), rv)
+ }
+ return cpy
+}
+
+// AsByteSlice returns the bytes value. Make sure that the Value's type
+// is BYTESLICE.
+func (v Value) AsByteSlice() []byte {
+ if v.vtype != BYTESLICE {
+ return nil
+ }
+ return v.asByteSlice()
+}
+
+func (v Value) asByteSlice() []byte {
+ return []byte(v.stringly)
}
type unknownValueType struct{}
@@ -217,11 +311,60 @@ func (v Value) AsInterface() any {
return v.stringly
case STRINGSLICE:
return v.asStringSlice()
+ case BYTESLICE:
+ return v.asByteSlice()
+ case SLICE:
+ return v.asSlice()
+ case EMPTY:
+ return nil
}
return unknownValueType{}
}
+// String returns a string representation of Value using the
+// [OpenTelemetry AnyValue representation for non-OTLP protocols] rules.
+//
+// Strings are returned as-is without JSON quoting, booleans and integers use
+// JSON literals, floating-point values use JSON numbers except that NaN and
+// ±Inf are rendered as NaN, Infinity, and -Infinity, byte slices are
+// base64-encoded, empty values are the empty string, and slices are encoded as
+// JSON arrays. String, byte, and special floating-point values inside arrays
+// are encoded as JSON strings, and empty values inside arrays are encoded as
+// null.
+//
+// [OpenTelemetry AnyValue representation for non-OTLP protocols]: https://opentelemetry.io/docs/specs/otel/common/#anyvalue-representation-for-non-otlp-protocols
+func (v Value) String() string {
+ switch v.Type() {
+ case BOOL:
+ return strconv.FormatBool(v.AsBool())
+ case BOOLSLICE:
+ return formatBoolSliceValue(v.slice)
+ case INT64:
+ return strconv.FormatInt(v.AsInt64(), 10)
+ case INT64SLICE:
+ return formatInt64SliceValue(v.slice)
+ case FLOAT64:
+ return formatFloat64(v.AsFloat64())
+ case FLOAT64SLICE:
+ return formatFloat64SliceValue(v.slice)
+ case STRING:
+ return v.stringly
+ case STRINGSLICE:
+ return formatStringSliceValue(v.slice)
+ case BYTESLICE:
+ return formatByteSlice(v.stringly)
+ case SLICE:
+ return formatValueSliceValue(v.slice)
+ case EMPTY:
+ return ""
+ default:
+ return "unknown"
+ }
+}
+
// Emit returns a string representation of Value's data.
+//
+// Deprecated: Use [Value.String] instead.
func (v Value) Emit() string {
switch v.Type() {
case BOOLSLICE:
@@ -252,11 +395,633 @@ func (v Value) Emit() string {
return string(j)
case STRING:
return v.stringly
+ case BYTESLICE:
+ return formatByteSlice(v.stringly)
+ case SLICE:
+ return formatValueSliceValue(v.slice)
+ case EMPTY:
+ return ""
default:
return "unknown"
}
}
+const (
+ jsonArrayBracketsLen = len("[]")
+ boolArrayElemMaxLen = len("false")
+ int64ArrayElemMaxLen = len("-9223372036854775808")
+ float64ArrayElemMaxLen = len("-1.7976931348623157e+308")
+ commaLen = len(",")
+)
+
+func sliceValue(v []Value) any {
+ switch len(v) {
+ case 0:
+ return [0]Value{}
+ case 1:
+ return [1]Value{v[0]}
+ case 2:
+ return [2]Value{v[0], v[1]}
+ case 3:
+ return [3]Value{v[0], v[1], v[2]}
+ case 4:
+ return [4]Value{v[0], v[1], v[2], v[3]}
+ case 5:
+ return [5]Value{v[0], v[1], v[2], v[3], v[4]}
+ default:
+ return sliceValueReflect(v)
+ }
+}
+
+func sliceValueReflect(v []Value) any {
+ cp := reflect.New(reflect.ArrayOf(len(v), reflect.TypeFor[Value]())).Elem()
+ reflect.Copy(cp, reflect.ValueOf(v))
+ return cp.Interface()
+}
+
+func formatBoolSliceValue(v any) string {
+ switch vals := v.(type) {
+ case [0]bool:
+ return "[]"
+ case [1]bool:
+ return formatBoolSlice(vals[:])
+ case [2]bool:
+ return formatBoolSlice(vals[:])
+ case [3]bool:
+ return formatBoolSlice(vals[:])
+ default:
+ return formatBoolSliceReflect(v)
+ }
+}
+
+func formatBoolSlice(vals []bool) string {
+ var b strings.Builder
+ appendBoolSlice(&b, vals)
+ return b.String()
+}
+
+func formatBoolSliceReflect(v any) string {
+ var b strings.Builder
+ appendBoolSliceReflect(&b, reflect.ValueOf(v))
+ return b.String()
+}
+
+func appendBoolSliceValue(dst *strings.Builder, v any) {
+ switch vals := v.(type) {
+ case [0]bool:
+ _, _ = dst.WriteString("[]")
+ case [1]bool:
+ appendBoolSlice(dst, vals[:])
+ case [2]bool:
+ appendBoolSlice(dst, vals[:])
+ case [3]bool:
+ appendBoolSlice(dst, vals[:])
+ default:
+ appendBoolSliceReflect(dst, reflect.ValueOf(v))
+ }
+}
+
+func appendBoolSlice(dst *strings.Builder, vals []bool) {
+ dst.Grow(jsonArrayBracketsLen + len(vals)*(boolArrayElemMaxLen+commaLen))
+ _ = dst.WriteByte('[')
+ for i, val := range vals {
+ if i > 0 {
+ _ = dst.WriteByte(',')
+ }
+ if val {
+ _, _ = dst.WriteString("true")
+ } else {
+ _, _ = dst.WriteString("false")
+ }
+ }
+ _ = dst.WriteByte(']')
+}
+
+func appendBoolSliceReflect(dst *strings.Builder, rv reflect.Value) {
+ dst.Grow(jsonArrayBracketsLen + rv.Len()*(boolArrayElemMaxLen+commaLen))
+ _ = dst.WriteByte('[')
+ for i := 0; i < rv.Len(); i++ {
+ if i > 0 {
+ _ = dst.WriteByte(',')
+ }
+ if rv.Index(i).Bool() {
+ _, _ = dst.WriteString("true")
+ } else {
+ _, _ = dst.WriteString("false")
+ }
+ }
+ _ = dst.WriteByte(']')
+}
+
+func formatInt64SliceValue(v any) string {
+ switch vals := v.(type) {
+ case [0]int64:
+ return "[]"
+ case [1]int64:
+ return formatInt64Slice(vals[:])
+ case [2]int64:
+ return formatInt64Slice(vals[:])
+ case [3]int64:
+ return formatInt64Slice(vals[:])
+ default:
+ return formatInt64SliceReflect(v)
+ }
+}
+
+func formatInt64Slice(vals []int64) string {
+ var b strings.Builder
+ appendInt64Slice(&b, vals)
+ return b.String()
+}
+
+func formatInt64SliceReflect(v any) string {
+ var b strings.Builder
+ appendInt64SliceReflect(&b, reflect.ValueOf(v))
+ return b.String()
+}
+
+func appendInt64SliceValue(dst *strings.Builder, v any) {
+ switch vals := v.(type) {
+ case [0]int64:
+ _, _ = dst.WriteString("[]")
+ case [1]int64:
+ appendInt64Slice(dst, vals[:])
+ case [2]int64:
+ appendInt64Slice(dst, vals[:])
+ case [3]int64:
+ appendInt64Slice(dst, vals[:])
+ default:
+ appendInt64SliceReflect(dst, reflect.ValueOf(v))
+ }
+}
+
+func appendInt64Slice(dst *strings.Builder, vals []int64) {
+ dst.Grow(jsonArrayBracketsLen + len(vals)*(int64ArrayElemMaxLen+commaLen))
+ _ = dst.WriteByte('[')
+
+ var buf [int64ArrayElemMaxLen]byte
+ for i, val := range vals {
+ if i > 0 {
+ _ = dst.WriteByte(',')
+ }
+ out := strconv.AppendInt(buf[:0], val, 10)
+ _, _ = dst.Write(out)
+ }
+
+ _ = dst.WriteByte(']')
+}
+
+func appendInt64SliceReflect(dst *strings.Builder, rv reflect.Value) {
+ dst.Grow(jsonArrayBracketsLen + rv.Len()*(int64ArrayElemMaxLen+commaLen))
+ _ = dst.WriteByte('[')
+
+ var scratch [int64ArrayElemMaxLen]byte
+ for i := 0; i < rv.Len(); i++ {
+ if i > 0 {
+ _ = dst.WriteByte(',')
+ }
+ out := strconv.AppendInt(scratch[:0], rv.Index(i).Int(), 10)
+ _, _ = dst.Write(out)
+ }
+
+ _ = dst.WriteByte(']')
+}
+
+func formatFloat64(v float64) string {
+ switch {
+ case math.IsNaN(v):
+ return "NaN"
+ case math.IsInf(v, 1):
+ return "Infinity"
+ case math.IsInf(v, -1):
+ return "-Infinity"
+ default:
+ return strconv.FormatFloat(v, 'g', -1, 64)
+ }
+}
+
+func formatFloat64SliceValue(v any) string {
+ switch vals := v.(type) {
+ case [0]float64:
+ return "[]"
+ case [1]float64:
+ return formatFloat64Slice(vals[:])
+ case [2]float64:
+ return formatFloat64Slice(vals[:])
+ case [3]float64:
+ return formatFloat64Slice(vals[:])
+ default:
+ return formatFloat64SliceReflect(v)
+ }
+}
+
+func formatFloat64Slice(vals []float64) string {
+ var b strings.Builder
+ appendFloat64Slice(&b, vals)
+ return b.String()
+}
+
+func formatFloat64SliceReflect(v any) string {
+ var b strings.Builder
+ appendFloat64SliceReflect(&b, reflect.ValueOf(v))
+ return b.String()
+}
+
+func appendFloat64SliceValue(dst *strings.Builder, v any) {
+ switch vals := v.(type) {
+ case [0]float64:
+ _, _ = dst.WriteString("[]")
+ case [1]float64:
+ appendFloat64Slice(dst, vals[:])
+ case [2]float64:
+ appendFloat64Slice(dst, vals[:])
+ case [3]float64:
+ appendFloat64Slice(dst, vals[:])
+ default:
+ appendFloat64SliceReflect(dst, reflect.ValueOf(v))
+ }
+}
+
+func appendFloat64Slice(dst *strings.Builder, vals []float64) {
+ dst.Grow(jsonArrayBracketsLen + len(vals)*(float64ArrayElemMaxLen+commaLen))
+ _ = dst.WriteByte('[')
+
+ var buf [float64ArrayElemMaxLen]byte
+ for i, val := range vals {
+ if i > 0 {
+ _ = dst.WriteByte(',')
+ }
+
+ switch {
+ case math.IsNaN(val):
+ _, _ = dst.WriteString(`"NaN"`)
+ case math.IsInf(val, 1):
+ _, _ = dst.WriteString(`"Infinity"`)
+ case math.IsInf(val, -1):
+ _, _ = dst.WriteString(`"-Infinity"`)
+ default:
+ out := strconv.AppendFloat(buf[:0], val, 'g', -1, 64)
+ _, _ = dst.Write(out)
+ }
+ }
+
+ _ = dst.WriteByte(']')
+}
+
+func appendFloat64SliceReflect(dst *strings.Builder, rv reflect.Value) {
+ dst.Grow(jsonArrayBracketsLen + rv.Len()*(float64ArrayElemMaxLen+commaLen))
+ _ = dst.WriteByte('[')
+
+ var scratch [float64ArrayElemMaxLen]byte
+ for i := 0; i < rv.Len(); i++ {
+ if i > 0 {
+ _ = dst.WriteByte(',')
+ }
+ val := rv.Index(i).Float()
+ switch {
+ case math.IsNaN(val):
+ _, _ = dst.WriteString(`"NaN"`)
+ case math.IsInf(val, 1):
+ _, _ = dst.WriteString(`"Infinity"`)
+ case math.IsInf(val, -1):
+ _, _ = dst.WriteString(`"-Infinity"`)
+ default:
+ out := strconv.AppendFloat(scratch[:0], val, 'g', -1, 64)
+ _, _ = dst.Write(out)
+ }
+ }
+
+ _ = dst.WriteByte(']')
+}
+
+func formatStringSliceValue(v any) string {
+ switch vals := v.(type) {
+ case [0]string:
+ return "[]"
+ case [1]string:
+ return formatStringSlice(vals[:])
+ case [2]string:
+ return formatStringSlice(vals[:])
+ case [3]string:
+ return formatStringSlice(vals[:])
+ default:
+ return formatStringSliceReflect(v)
+ }
+}
+
+func formatStringSlice(vals []string) string {
+ var b strings.Builder
+ appendStringSlice(&b, vals)
+ return b.String()
+}
+
+func formatStringSliceReflect(v any) string {
+ var b strings.Builder
+ appendStringSliceReflect(&b, reflect.ValueOf(v))
+ return b.String()
+}
+
+func appendStringSliceValue(dst *strings.Builder, v any) {
+ switch vals := v.(type) {
+ case [0]string:
+ _, _ = dst.WriteString("[]")
+ case [1]string:
+ appendStringSlice(dst, vals[:])
+ case [2]string:
+ appendStringSlice(dst, vals[:])
+ case [3]string:
+ appendStringSlice(dst, vals[:])
+ default:
+ appendStringSliceReflect(dst, reflect.ValueOf(v))
+ }
+}
+
+func appendStringSlice(dst *strings.Builder, vals []string) {
+ size := jsonArrayBracketsLen
+ for _, val := range vals {
+ size += len(val) + commaLen + 2 // Account for JSON string quotes and comma.
+ }
+
+ dst.Grow(size)
+ _ = dst.WriteByte('[')
+ for i, val := range vals {
+ if i > 0 {
+ _ = dst.WriteByte(',')
+ }
+ appendJSONString(dst, val)
+ }
+ _ = dst.WriteByte(']')
+}
+
+func appendStringSliceReflect(dst *strings.Builder, rv reflect.Value) {
+ size := jsonArrayBracketsLen
+ for i := 0; i < rv.Len(); i++ {
+ size += len(rv.Index(i).String()) + commaLen + 2 // Account for JSON string quotes and comma.
+ }
+
+ dst.Grow(size)
+ _ = dst.WriteByte('[')
+ for i := 0; i < rv.Len(); i++ {
+ if i > 0 {
+ _ = dst.WriteByte(',')
+ }
+ appendJSONString(dst, rv.Index(i).String())
+ }
+ _ = dst.WriteByte(']')
+}
+
+func formatByteSlice(v string) string {
+ var b strings.Builder
+ appendBase64(&b, v)
+ return b.String()
+}
+
+func formatValueSliceValue(v any) string {
+ switch vals := v.(type) {
+ case [0]Value:
+ return "[]"
+ case [1]Value:
+ return formatValueSlice(vals[:])
+ case [2]Value:
+ return formatValueSlice(vals[:])
+ case [3]Value:
+ return formatValueSlice(vals[:])
+ case [4]Value:
+ return formatValueSlice(vals[:])
+ case [5]Value:
+ return formatValueSlice(vals[:])
+ default:
+ return formatValueSliceReflect(v)
+ }
+}
+
+func formatValueSlice(vals []Value) string {
+ var b strings.Builder
+ appendValueSlice(&b, vals)
+ return b.String()
+}
+
+func formatValueSliceReflect(v any) string {
+ var b strings.Builder
+ appendValueSliceReflect(&b, reflect.ValueOf(v))
+ return b.String()
+}
+
+func appendValueSliceValue(dst *strings.Builder, v any) {
+ switch vals := v.(type) {
+ case [0]Value:
+ _, _ = dst.WriteString("[]")
+ case [1]Value:
+ appendValueSlice(dst, vals[:])
+ case [2]Value:
+ appendValueSlice(dst, vals[:])
+ case [3]Value:
+ appendValueSlice(dst, vals[:])
+ case [4]Value:
+ appendValueSlice(dst, vals[:])
+ case [5]Value:
+ appendValueSlice(dst, vals[:])
+ default:
+ appendValueSliceReflect(dst, reflect.ValueOf(v))
+ }
+}
+
+func appendValueSlice(dst *strings.Builder, vals []Value) {
+ // Estimate 10 bytes per value for small values and commas.
+ dst.Grow(jsonArrayBracketsLen + len(vals)*commaLen + len(vals)*10)
+ _ = dst.WriteByte('[')
+ for i, val := range vals {
+ if i > 0 {
+ _ = dst.WriteByte(',')
+ }
+ appendJSONValue(dst, val)
+ }
+ _ = dst.WriteByte(']')
+}
+
+func appendValueSliceReflect(dst *strings.Builder, rv reflect.Value) {
+ // Estimate 10 bytes per value for small values and commas.
+ dst.Grow(jsonArrayBracketsLen + rv.Len()*commaLen + rv.Len()*10)
+ _ = dst.WriteByte('[')
+ for i := 0; i < rv.Len(); i++ {
+ if i > 0 {
+ _ = dst.WriteByte(',')
+ }
+ appendJSONValue(dst, rv.Index(i).Interface().(Value))
+ }
+ _ = dst.WriteByte(']')
+}
+
+func appendJSONValue(dst *strings.Builder, v Value) {
+ switch v.Type() {
+ case BOOL:
+ if v.AsBool() {
+ _, _ = dst.WriteString("true")
+ } else {
+ _, _ = dst.WriteString("false")
+ }
+ case BOOLSLICE:
+ appendBoolSliceValue(dst, v.slice)
+ case INT64:
+ var buf [int64ArrayElemMaxLen]byte
+ out := strconv.AppendInt(buf[:0], v.AsInt64(), 10)
+ _, _ = dst.Write(out)
+ case INT64SLICE:
+ appendInt64SliceValue(dst, v.slice)
+ case FLOAT64:
+ val := v.AsFloat64()
+ switch {
+ case math.IsNaN(val):
+ appendJSONString(dst, "NaN")
+ case math.IsInf(val, 1):
+ appendJSONString(dst, "Infinity")
+ case math.IsInf(val, -1):
+ appendJSONString(dst, "-Infinity")
+ default:
+ var buf [float64ArrayElemMaxLen]byte
+ out := strconv.AppendFloat(buf[:0], val, 'g', -1, 64)
+ _, _ = dst.Write(out)
+ }
+ case FLOAT64SLICE:
+ appendFloat64SliceValue(dst, v.slice)
+ case STRING:
+ appendJSONString(dst, v.stringly)
+ case STRINGSLICE:
+ appendStringSliceValue(dst, v.slice)
+ case BYTESLICE:
+ _ = dst.WriteByte('"')
+ appendBase64(dst, v.stringly)
+ _ = dst.WriteByte('"')
+ case SLICE:
+ appendValueSliceValue(dst, v.slice)
+ case EMPTY:
+ _, _ = dst.WriteString("null")
+ default:
+ appendJSONString(dst, "unknown")
+ }
+}
+
+// appendJSONString appends s to dst as a JSON string literal.
+//
+// This is adapted from the Go standard library's encoding/json
+// [appendString implementation]. It keeps the same escaping behavior we need
+// here, but writes directly into a strings.Builder and intentionally does not
+// apply HTML escaping because the OpenTelemetry non-OTLP AnyValue representation
+// only requires JSON array string encoding. We inline this instead of using
+// encoding/json so slice formatting avoids allocations and reflection.
+//
+// [appendString implementation]: https://github.com/golang/go/blob/3b5954c6349d31465dca409b45ab6597e0942d9f/src/encoding/json/encode.go#L998-L1064
+func appendJSONString(dst *strings.Builder, s string) {
+ const hex = "0123456789abcdef" // For escaping bytes to hex.
+
+ _ = dst.WriteByte('"')
+ start := 0
+
+ for i := 0; i < len(s); {
+ if c := s[i]; c < utf8.RuneSelf {
+ if c >= 0x20 && c != '\\' && c != '"' {
+ i++
+ continue
+ }
+
+ if start < i {
+ _, _ = dst.WriteString(s[start:i])
+ }
+
+ switch c {
+ case '\\', '"':
+ _ = dst.WriteByte('\\')
+ _ = dst.WriteByte(c)
+ case '\b':
+ _, _ = dst.WriteString(`\b`)
+ case '\f':
+ _, _ = dst.WriteString(`\f`)
+ case '\n':
+ _, _ = dst.WriteString(`\n`)
+ case '\r':
+ _, _ = dst.WriteString(`\r`)
+ case '\t':
+ _, _ = dst.WriteString(`\t`)
+ default:
+ _, _ = dst.WriteString(`\u00`)
+ _ = dst.WriteByte(hex[c>>4])
+ _ = dst.WriteByte(hex[c&0x0f])
+ }
+
+ i++
+ start = i
+ continue
+ }
+
+ r, size := utf8.DecodeRuneInString(s[i:])
+ if r == utf8.RuneError && size == 1 {
+ if start < i {
+ _, _ = dst.WriteString(s[start:i])
+ }
+ // Match encoding/json by replacing invalid UTF-8 with U+FFFD.
+ _, _ = dst.WriteString(`\ufffd`)
+ i++
+ start = i
+ continue
+ }
+
+ if r == '\u2028' || r == '\u2029' {
+ if start < i {
+ _, _ = dst.WriteString(s[start:i])
+ }
+ // Escape JSONP-sensitive separators unconditionally, like encoding/json.
+ _, _ = dst.WriteString(`\u202`)
+ _ = dst.WriteByte(hex[r&0x0f])
+ i += size
+ start = i
+ continue
+ }
+
+ i += size
+ }
+
+ if start < len(s) {
+ _, _ = dst.WriteString(s[start:])
+ }
+ _ = dst.WriteByte('"')
+}
+
+// This is adapted from the Go standard library's encoding/base64
+// [Encoding.Encode implementation]. It keeps the same encoding behavior we need
+// here, but writes directly into a strings.Builder. We inline this instead of using
+// encoding/base64 to avoid allocations.
+//
+// [Encoding.Encode implementation]: https://github.com/golang/go/blob/3b5954c6349d31465dca409b45ab6597e0942d9f/src/encoding/base64/base64.go#L139-L189
+func appendBase64(dst *strings.Builder, s string) {
+ const encode = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
+
+ dst.Grow(base64.StdEncoding.EncodedLen(len(s)))
+
+ i := 0
+ for ; i+2 < len(s); i += 3 {
+ n := uint32(s[i])<<16 | uint32(s[i+1])<<8 | uint32(s[i+2])
+ _ = dst.WriteByte(encode[n>>18&0x3f])
+ _ = dst.WriteByte(encode[n>>12&0x3f])
+ _ = dst.WriteByte(encode[n>>6&0x3f])
+ _ = dst.WriteByte(encode[n&0x3f])
+ }
+
+ switch len(s) - i {
+ case 1:
+ n := uint32(s[i]) << 16
+ _ = dst.WriteByte(encode[n>>18&0x3f])
+ _ = dst.WriteByte(encode[n>>12&0x3f])
+ _ = dst.WriteByte('=')
+ _ = dst.WriteByte('=')
+ case 2:
+ n := uint32(s[i])<<16 | uint32(s[i+1])<<8
+ _ = dst.WriteByte(encode[n>>18&0x3f])
+ _ = dst.WriteByte(encode[n>>12&0x3f])
+ _ = dst.WriteByte(encode[n>>6&0x3f])
+ _ = dst.WriteByte('=')
+ }
+}
+
// MarshalJSON returns the JSON encoding of the Value.
func (v Value) MarshalJSON() ([]byte, error) {
var jsonVal struct {
diff --git a/vendor/go.opentelemetry.io/otel/baggage/baggage.go b/vendor/go.opentelemetry.io/otel/baggage/baggage.go
index 878ffbe43..b290c6d6c 100644
--- a/vendor/go.opentelemetry.io/otel/baggage/baggage.go
+++ b/vendor/go.opentelemetry.io/otel/baggage/baggage.go
@@ -14,6 +14,10 @@ import (
)
const (
+ maxParseErrors = 5
+
+ // W3C Baggage specification limits.
+ // https://www.w3.org/TR/baggage/#limits
maxMembers = 64
maxBytesPerBaggageString = 8192
@@ -493,9 +497,15 @@ func New(members ...Member) (Baggage, error) {
// from the W3C Baggage specification which allows duplicate list-members, but
// conforms to the OpenTelemetry Baggage specification.
//
-// If the baggage-string exceeds the maximum allowed members (64) or bytes
-// (8192), members are dropped until the limits are satisfied and an error is
-// returned along with the partial result.
+// If the raw baggage-string exceeds the maximum allowed bytes (8192), an
+// empty Baggage and an error are returned.
+//
+// Otherwise, members are parsed left-to-right and accumulated until one of
+// the following conditions is reached, at which point parsing stops and an
+// error is returned alongside the partial result:
+// - accepting the next member would cause the encoded baggage to exceed
+// 8192 bytes, or
+// - the baggage already contains 64 distinct keys.
//
// Invalid members are skipped and the error is returned along with the
// partial result containing the valid members.
@@ -504,9 +514,14 @@ func Parse(bStr string) (Baggage, error) {
return Baggage{}, nil
}
+ if n := len(bStr); n > maxBytesPerBaggageString {
+ return Baggage{}, fmt.Errorf("%w: %d", errBaggageBytes, n)
+ }
+
b := make(baggage.List)
sizes := make(map[string]int) // Track per-key byte sizes
var totalBytes int
+ var parseErrors int
var truncateErr error
for memberStr := range strings.SplitSeq(bStr, listDelimiter) {
// Check member count limit.
@@ -517,7 +532,10 @@ func Parse(bStr string) (Baggage, error) {
m, err := parseMember(memberStr)
if err != nil {
- truncateErr = errors.Join(truncateErr, err)
+ parseErrors++
+ if parseErrors <= maxParseErrors {
+ truncateErr = errors.Join(truncateErr, err)
+ }
continue // skip invalid member, keep processing
}
@@ -553,6 +571,10 @@ func Parse(bStr string) (Baggage, error) {
totalBytes = newTotalBytes
}
+ if dropped := parseErrors - maxParseErrors; dropped > 0 {
+ truncateErr = errors.Join(truncateErr, fmt.Errorf("and %d more invalid member(s)", dropped))
+ }
+
if len(b) == 0 {
return Baggage{}, truncateErr
}
diff --git a/vendor/go.opentelemetry.io/otel/dependencies.Dockerfile b/vendor/go.opentelemetry.io/otel/dependencies.Dockerfile
index f0cc942ba..74fa510bc 100644
--- a/vendor/go.opentelemetry.io/otel/dependencies.Dockerfile
+++ b/vendor/go.opentelemetry.io/otel/dependencies.Dockerfile
@@ -1,4 +1,4 @@
# This is a renovate-friendly source of Docker images.
FROM python:3.13.6-slim-bullseye@sha256:e98b521460ee75bca92175c16247bdf7275637a8faaeb2bcfa19d879ae5c4b9a AS python
-FROM otel/weaver:v0.21.2@sha256:2401de985c38bdb98b43918e2f43aa36b2afed4aa5669ac1c1de0a17301cd36d AS weaver
+FROM otel/weaver:v0.23.0@sha256:7984ecb55b859eb3034ae9d836c4eeda137e2bdd0873b7ba2bb6c3d24d6ff457 AS weaver
FROM avtodev/markdown-lint:v1@sha256:6aeedc2f49138ce7a1cd0adffc1b1c0321b841dc2102408967d9301c031949ee AS markdown
diff --git a/vendor/go.opentelemetry.io/otel/metric/asyncfloat64.go b/vendor/go.opentelemetry.io/otel/metric/asyncfloat64.go
index 466812d34..1d21e2eb7 100644
--- a/vendor/go.opentelemetry.io/otel/metric/asyncfloat64.go
+++ b/vendor/go.opentelemetry.io/otel/metric/asyncfloat64.go
@@ -51,6 +51,9 @@ type Float64ObservableCounterConfig struct {
func NewFloat64ObservableCounterConfig(opts ...Float64ObservableCounterOption) Float64ObservableCounterConfig {
var config Float64ObservableCounterConfig
for _, o := range opts {
+ if _, ok := o.(experimentalOption); ok {
+ continue
+ }
config = o.applyFloat64ObservableCounter(config)
}
return config
@@ -111,6 +114,9 @@ func NewFloat64ObservableUpDownCounterConfig(
) Float64ObservableUpDownCounterConfig {
var config Float64ObservableUpDownCounterConfig
for _, o := range opts {
+ if _, ok := o.(experimentalOption); ok {
+ continue
+ }
config = o.applyFloat64ObservableUpDownCounter(config)
}
return config
@@ -168,6 +174,9 @@ type Float64ObservableGaugeConfig struct {
func NewFloat64ObservableGaugeConfig(opts ...Float64ObservableGaugeOption) Float64ObservableGaugeConfig {
var config Float64ObservableGaugeConfig
for _, o := range opts {
+ if _, ok := o.(experimentalOption); ok {
+ continue
+ }
config = o.applyFloat64ObservableGauge(config)
}
return config
diff --git a/vendor/go.opentelemetry.io/otel/metric/asyncint64.go b/vendor/go.opentelemetry.io/otel/metric/asyncint64.go
index 66c971bd8..9d45a4d41 100644
--- a/vendor/go.opentelemetry.io/otel/metric/asyncint64.go
+++ b/vendor/go.opentelemetry.io/otel/metric/asyncint64.go
@@ -50,6 +50,9 @@ type Int64ObservableCounterConfig struct {
func NewInt64ObservableCounterConfig(opts ...Int64ObservableCounterOption) Int64ObservableCounterConfig {
var config Int64ObservableCounterConfig
for _, o := range opts {
+ if _, ok := o.(experimentalOption); ok {
+ continue
+ }
config = o.applyInt64ObservableCounter(config)
}
return config
@@ -110,6 +113,9 @@ func NewInt64ObservableUpDownCounterConfig(
) Int64ObservableUpDownCounterConfig {
var config Int64ObservableUpDownCounterConfig
for _, o := range opts {
+ if _, ok := o.(experimentalOption); ok {
+ continue
+ }
config = o.applyInt64ObservableUpDownCounter(config)
}
return config
@@ -167,6 +173,9 @@ type Int64ObservableGaugeConfig struct {
func NewInt64ObservableGaugeConfig(opts ...Int64ObservableGaugeOption) Int64ObservableGaugeConfig {
var config Int64ObservableGaugeConfig
for _, o := range opts {
+ if _, ok := o.(experimentalOption); ok {
+ continue
+ }
config = o.applyInt64ObservableGauge(config)
}
return config
diff --git a/vendor/go.opentelemetry.io/otel/metric/config.go b/vendor/go.opentelemetry.io/otel/metric/config.go
index e42dd6e70..889545e23 100644
--- a/vendor/go.opentelemetry.io/otel/metric/config.go
+++ b/vendor/go.opentelemetry.io/otel/metric/config.go
@@ -42,11 +42,18 @@ type MeterOption interface {
applyMeter(MeterConfig) MeterConfig
}
+type experimentalOption interface {
+ Experimental()
+}
+
// NewMeterConfig creates a new MeterConfig and applies
// all the given options.
func NewMeterConfig(opts ...MeterOption) MeterConfig {
var config MeterConfig
for _, o := range opts {
+ if _, ok := o.(experimentalOption); ok {
+ continue
+ }
config = o.applyMeter(config)
}
return config
diff --git a/vendor/go.opentelemetry.io/otel/metric/doc.go b/vendor/go.opentelemetry.io/otel/metric/doc.go
index f153745b0..794e1a8ba 100644
--- a/vendor/go.opentelemetry.io/otel/metric/doc.go
+++ b/vendor/go.opentelemetry.io/otel/metric/doc.go
@@ -24,10 +24,10 @@ all instruments fall into two overlapping logical categories: asynchronous or
synchronous, and int64 or float64.
All synchronous instruments ([Int64Counter], [Int64UpDownCounter],
-[Int64Histogram], [Float64Counter], [Float64UpDownCounter], and
-[Float64Histogram]) are used to measure the operation and performance of source
-code during the source code execution. These instruments only make measurements
-when the source code they instrument is run.
+[Int64Histogram], [Int64Gauge], [Float64Counter], [Float64UpDownCounter],
+[Float64Histogram], and [Float64Gauge]) are used to measure the operation and
+performance of source code during the source code execution. These instruments
+only make measurements when the source code they instrument is run.
All asynchronous instruments ([Int64ObservableCounter],
[Int64ObservableUpDownCounter], [Int64ObservableGauge],
@@ -50,9 +50,11 @@ incrementally increase in value. UpDownCounters ([Int64UpDownCounter],
values that can increase and decrease. When more information needs to be
conveyed about all the synchronous measurements made during a collection cycle,
a Histogram ([Int64Histogram] and [Float64Histogram]) should be used. Finally,
-when just the most recent measurement needs to be conveyed about an
-asynchronous measurement, a Gauge ([Int64ObservableGauge] and
-[Float64ObservableGauge]) should be used.
+when just the most recent measurement needs to be conveyed, a Gauge
+([Int64Gauge], [Float64Gauge], [Int64ObservableGauge], and
+[Float64ObservableGauge]) should be used: the synchronous variants record an
+instantaneous value at a specific point in code, while the observable variants
+sample the value via a callback once per collection cycle.
See the [OpenTelemetry documentation] for more information about instruments
and their intended use.
@@ -80,11 +82,11 @@ Measurements are made by recording values and information about the values with
an instrument. How these measurements are recorded depends on the instrument.
Measurements for synchronous instruments ([Int64Counter], [Int64UpDownCounter],
-[Int64Histogram], [Float64Counter], [Float64UpDownCounter], and
-[Float64Histogram]) are recorded using the instrument methods directly. All
-counter instruments have an Add method that is used to measure an increment
-value, and all histogram instruments have a Record method to measure a data
-point.
+[Int64Histogram], [Int64Gauge], [Float64Counter], [Float64UpDownCounter],
+[Float64Histogram], and [Float64Gauge]) are recorded using the instrument
+methods directly. All counter instruments have an Add method that is used to
+measure an increment value, and all histogram and synchronous gauge
+instruments have a Record method to measure a data point.
Asynchronous instruments ([Int64ObservableCounter],
[Int64ObservableUpDownCounter], [Int64ObservableGauge],
@@ -107,6 +109,31 @@ respectively):
If the criteria are not met, use the RegisterCallback method of the [Meter] that
created the instrument to register a [Callback].
+# Avoiding Expensive Computations
+
+All synchronous instruments provide an Enabled method that reports whether the
+instrument will process measurements for the given context. When no SDK is
+registered or the instrument is otherwise disabled, Enabled returns false. This
+can be used to avoid expensive measurement work when a measurement will not be
+recorded:
+
+ if counter.Enabled(ctx) {
+ counter.Add(ctx, 1, metric.WithAttributes(expensiveAttributes()...))
+ }
+
+This is especially valuable when computing attributes is expensive.
+[WithAttributes] performs non-trivial work on every call to build an
+[attribute.Set] from the provided attributes, and that work is wasted if the
+measurement is not recorded.
+
+For performance sensitive code where the same attribute set is used repeatedly,
+prefer [WithAttributeSet]. It accepts a pre-built [attribute.Set], letting you
+pay the construction cost once and reuse it across many measurements:
+
+ attrs := attribute.NewSet(attribute.String("key", "val"))
+ // ... later, on each call:
+ counter.Add(ctx, 1, metric.WithAttributeSet(attrs))
+
# API Implementations
This package does not conform to the standard Go versioning policy, all of its
diff --git a/vendor/go.opentelemetry.io/otel/metric/instrument.go b/vendor/go.opentelemetry.io/otel/metric/instrument.go
index 9f48d5f11..2e79ab568 100644
--- a/vendor/go.opentelemetry.io/otel/metric/instrument.go
+++ b/vendor/go.opentelemetry.io/otel/metric/instrument.go
@@ -3,7 +3,9 @@
package metric // import "go.opentelemetry.io/otel/metric"
-import "go.opentelemetry.io/otel/attribute"
+import (
+ "go.opentelemetry.io/otel/attribute"
+)
// Observable is used as a grouping mechanism for all instruments that are
// updated within a Callback.
@@ -228,6 +230,9 @@ type AddConfig struct {
func NewAddConfig(opts []AddOption) AddConfig {
config := AddConfig{attrs: *attribute.EmptySet()}
for _, o := range opts {
+ if _, ok := o.(experimentalOption); ok {
+ continue
+ }
config = o.applyAdd(config)
}
return config
@@ -253,6 +258,9 @@ type RecordConfig struct {
func NewRecordConfig(opts []RecordOption) RecordConfig {
config := RecordConfig{attrs: *attribute.EmptySet()}
for _, o := range opts {
+ if _, ok := o.(experimentalOption); ok {
+ continue
+ }
config = o.applyRecord(config)
}
return config
@@ -278,6 +286,9 @@ type ObserveConfig struct {
func NewObserveConfig(opts []ObserveOption) ObserveConfig {
config := ObserveConfig{attrs: *attribute.EmptySet()}
for _, o := range opts {
+ if _, ok := o.(experimentalOption); ok {
+ continue
+ }
config = o.applyObserve(config)
}
return config
@@ -299,6 +310,10 @@ type attrOpt struct {
set attribute.Set
}
+func (o *attrOpt) Set(set attribute.Set) {
+ o.set = set
+}
+
// mergeSets returns the union of keys between a and b. Any duplicate keys will
// use the value associated with b.
func mergeSets(a, b attribute.Set) attribute.Set {
@@ -311,7 +326,7 @@ func mergeSets(a, b attribute.Set) attribute.Set {
return attribute.NewSet(merged...)
}
-func (o attrOpt) applyAdd(c AddConfig) AddConfig {
+func (o *attrOpt) applyAdd(c AddConfig) AddConfig {
switch {
case o.set.Len() == 0:
case c.attrs.Len() == 0:
@@ -322,7 +337,7 @@ func (o attrOpt) applyAdd(c AddConfig) AddConfig {
return c
}
-func (o attrOpt) applyRecord(c RecordConfig) RecordConfig {
+func (o *attrOpt) applyRecord(c RecordConfig) RecordConfig {
switch {
case o.set.Len() == 0:
case c.attrs.Len() == 0:
@@ -333,7 +348,7 @@ func (o attrOpt) applyRecord(c RecordConfig) RecordConfig {
return c
}
-func (o attrOpt) applyObserve(c ObserveConfig) ObserveConfig {
+func (o *attrOpt) applyObserve(c ObserveConfig) ObserveConfig {
switch {
case o.set.Len() == 0:
case c.attrs.Len() == 0:
@@ -350,8 +365,14 @@ func (o attrOpt) applyObserve(c ObserveConfig) ObserveConfig {
// If multiple WithAttributeSet or WithAttributes options are passed the
// attributes will be merged together in the order they are passed. Attributes
// with duplicate keys will use the last value passed.
+//
+// Experimental: The returned option may implement
+// [go.opentelemetry.io/otel/metric/x.Settable][attribute.Set], which can be
+// used to replace the option's attribute set and reuse the option without
+// additional allocations. This behavior is experimental and may be changed or
+// removed in a future release without notice.
func WithAttributeSet(attributes attribute.Set) MeasurementOption {
- return attrOpt{set: attributes}
+ return &attrOpt{set: attributes}
}
// WithAttributes converts attributes into an attribute Set and sets the Set to
@@ -369,8 +390,14 @@ func WithAttributeSet(attributes attribute.Set) MeasurementOption {
//
// See [WithAttributeSet] for information about how multiple WithAttributes are
// merged.
+//
+// Experimental: The returned option may implement
+// [go.opentelemetry.io/otel/metric/x.Settable][[]attribute.KeyValue], which can be
+// used to replace the option's attributes and reuse the option without
+// additional allocations. This behavior is experimental and may be changed or
+// removed in a future release without notice.
func WithAttributes(attributes ...attribute.KeyValue) MeasurementOption {
cp := make([]attribute.KeyValue, len(attributes))
copy(cp, attributes)
- return attrOpt{set: attribute.NewSet(cp...)}
+ return &attrOpt{set: attribute.NewSet(cp...)}
}
diff --git a/vendor/go.opentelemetry.io/otel/metric/syncfloat64.go b/vendor/go.opentelemetry.io/otel/metric/syncfloat64.go
index abb3051d7..2101f686a 100644
--- a/vendor/go.opentelemetry.io/otel/metric/syncfloat64.go
+++ b/vendor/go.opentelemetry.io/otel/metric/syncfloat64.go
@@ -51,6 +51,9 @@ type Float64CounterConfig struct {
func NewFloat64CounterConfig(opts ...Float64CounterOption) Float64CounterConfig {
var config Float64CounterConfig
for _, o := range opts {
+ if _, ok := o.(experimentalOption); ok {
+ continue
+ }
config = o.applyFloat64Counter(config)
}
return config
@@ -116,6 +119,9 @@ type Float64UpDownCounterConfig struct {
func NewFloat64UpDownCounterConfig(opts ...Float64UpDownCounterOption) Float64UpDownCounterConfig {
var config Float64UpDownCounterConfig
for _, o := range opts {
+ if _, ok := o.(experimentalOption); ok {
+ continue
+ }
config = o.applyFloat64UpDownCounter(config)
}
return config
@@ -182,6 +188,9 @@ type Float64HistogramConfig struct {
func NewFloat64HistogramConfig(opts ...Float64HistogramOption) Float64HistogramConfig {
var config Float64HistogramConfig
for _, o := range opts {
+ if _, ok := o.(experimentalOption); ok {
+ continue
+ }
config = o.applyFloat64Histogram(config)
}
return config
@@ -251,6 +260,9 @@ type Float64GaugeConfig struct {
func NewFloat64GaugeConfig(opts ...Float64GaugeOption) Float64GaugeConfig {
var config Float64GaugeConfig
for _, o := range opts {
+ if _, ok := o.(experimentalOption); ok {
+ continue
+ }
config = o.applyFloat64Gauge(config)
}
return config
diff --git a/vendor/go.opentelemetry.io/otel/metric/syncint64.go b/vendor/go.opentelemetry.io/otel/metric/syncint64.go
index 5bbfaf039..425c1a0d5 100644
--- a/vendor/go.opentelemetry.io/otel/metric/syncint64.go
+++ b/vendor/go.opentelemetry.io/otel/metric/syncint64.go
@@ -51,6 +51,9 @@ type Int64CounterConfig struct {
func NewInt64CounterConfig(opts ...Int64CounterOption) Int64CounterConfig {
var config Int64CounterConfig
for _, o := range opts {
+ if _, ok := o.(experimentalOption); ok {
+ continue
+ }
config = o.applyInt64Counter(config)
}
return config
@@ -116,6 +119,9 @@ type Int64UpDownCounterConfig struct {
func NewInt64UpDownCounterConfig(opts ...Int64UpDownCounterOption) Int64UpDownCounterConfig {
var config Int64UpDownCounterConfig
for _, o := range opts {
+ if _, ok := o.(experimentalOption); ok {
+ continue
+ }
config = o.applyInt64UpDownCounter(config)
}
return config
@@ -182,6 +188,9 @@ type Int64HistogramConfig struct {
func NewInt64HistogramConfig(opts ...Int64HistogramOption) Int64HistogramConfig {
var config Int64HistogramConfig
for _, o := range opts {
+ if _, ok := o.(experimentalOption); ok {
+ continue
+ }
config = o.applyInt64Histogram(config)
}
return config
@@ -251,6 +260,9 @@ type Int64GaugeConfig struct {
func NewInt64GaugeConfig(opts ...Int64GaugeOption) Int64GaugeConfig {
var config Int64GaugeConfig
for _, o := range opts {
+ if _, ok := o.(experimentalOption); ok {
+ continue
+ }
config = o.applyInt64Gauge(config)
}
return config
diff --git a/vendor/go.opentelemetry.io/otel/propagation/baggage.go b/vendor/go.opentelemetry.io/otel/propagation/baggage.go
index 2ecca3fed..d81b709a2 100644
--- a/vendor/go.opentelemetry.io/otel/propagation/baggage.go
+++ b/vendor/go.opentelemetry.io/otel/propagation/baggage.go
@@ -5,6 +5,9 @@ package propagation // import "go.opentelemetry.io/otel/propagation"
import (
"context"
+ "errors"
+ "fmt"
+ "sync"
"go.opentelemetry.io/otel/baggage"
"go.opentelemetry.io/otel/internal/errorhandler"
@@ -13,11 +16,18 @@ import (
const (
baggageHeader = "baggage"
+ maxParseErrors = 5
+
// W3C Baggage specification limits.
// https://www.w3.org/TR/baggage/#limits
- maxMembers = 64
+ maxMembers = 64
+ maxBytesPerBaggageString = 8192
)
+// handleExtractErrOnce limits error reporting for attacker-controlled baggage headers
+// to one process-wide emission, preventing repeated extraction from flooding logs.
+var handleExtractErrOnce sync.Once
+
// Baggage is a propagator that supports the W3C Baggage format.
//
// This propagates user-defined baggage associated with a trace. The complete
@@ -57,7 +67,9 @@ func extractSingleBaggage(parent context.Context, carrier TextMapCarrier) contex
bag, err := baggage.Parse(bStr)
if err != nil {
- errorhandler.GetErrorHandler().Handle(err)
+ handleExtractErrOnce.Do(func() {
+ errorhandler.GetErrorHandler().Handle(err)
+ })
}
if bag.Len() == 0 {
return parent
@@ -72,24 +84,60 @@ func extractMultiBaggage(parent context.Context, carrier ValuesGetter) context.C
}
var members []baggage.Member
- for _, bStr := range bVals {
- currBag, err := baggage.Parse(bStr)
- if err != nil {
- errorhandler.GetErrorHandler().Handle(err)
+ var totalBytes int
+ var parseErrors int
+ var truncateErr error
+ for i, bStr := range bVals {
+ if i > 0 {
+ totalBytes++ // comma separator between combined header values
}
- if currBag.Len() == 0 {
- continue
+ totalBytes += len(bStr)
+ if totalBytes > maxBytesPerBaggageString {
+ // Per the W3C Baggage spec, the byte limit applies to the
+ // combination of all baggage headers, not each header
+ // individually. Mirror the single-header behavior of
+ // reporting the error and returning the parent context
+ // with no baggage attached.
+ handleExtractErrOnce.Do(func() {
+ errorhandler.GetErrorHandler().Handle(fmt.Errorf(
+ "baggage: aggregate header size %d exceeds %d byte limit",
+ totalBytes,
+ maxBytesPerBaggageString,
+ ))
+ })
+ return parent
}
- members = append(members, currBag.Members()...)
- if len(members) >= maxMembers {
- break
+
+ // If members exceed the limit, stop parsing baggage.
+ if len(members) <= maxMembers {
+ currBag, err := baggage.Parse(bStr)
+ if err != nil {
+ parseErrors++
+ if parseErrors <= maxParseErrors {
+ truncateErr = errors.Join(truncateErr, err)
+ }
+ }
+ if currBag.Len() == 0 {
+ continue
+ }
+ members = append(members, currBag.Members()...)
}
}
+ if dropped := parseErrors - maxParseErrors; dropped > 0 {
+ truncateErr = errors.Join(truncateErr, fmt.Errorf("and %d more error(s)", dropped))
+ }
+
b, err := baggage.New(members...)
if err != nil {
- errorhandler.GetErrorHandler().Handle(err)
+ truncateErr = errors.Join(truncateErr, err)
}
+ if truncateErr != nil {
+ handleExtractErrOnce.Do(func() {
+ errorhandler.GetErrorHandler().Handle(truncateErr)
+ })
+ }
+
if b.Len() == 0 {
return parent
}
diff --git a/vendor/go.opentelemetry.io/otel/propagation/trace_context.go b/vendor/go.opentelemetry.io/otel/propagation/trace_context.go
index 271ab71f1..11f404deb 100644
--- a/vendor/go.opentelemetry.io/otel/propagation/trace_context.go
+++ b/vendor/go.opentelemetry.io/otel/propagation/trace_context.go
@@ -46,8 +46,8 @@ func (TraceContext) Inject(ctx context.Context, carrier TextMapCarrier) {
carrier.Set(tracestateHeader, ts)
}
- // Clear all flags other than the trace-context supported sampling bit.
- flags := sc.TraceFlags() & trace.FlagsSampled
+ // Preserve only the spec-defined flags: sampled (0x01) and random (0x02).
+ flags := sc.TraceFlags() & (trace.FlagsSampled | trace.FlagsRandom)
var sb strings.Builder
sb.Grow(2 + 32 + 16 + 2 + 3)
@@ -104,14 +104,13 @@ func (TraceContext) extract(carrier TextMapCarrier) trace.SpanContext {
if !extractPart(opts[:], &h, 2) {
return trace.SpanContext{}
}
- if version == 0 && (h != "" || opts[0] > 2) {
- // version 0 not allow extra
- // version 0 not allow other flag
+ if version == 0 && (h != "" || opts[0] > 3) {
+ // version 0 does not allow extra fields or reserved flag bits.
return trace.SpanContext{}
}
- // Clear all flags other than the trace-context supported sampling bit.
- scc.TraceFlags = trace.TraceFlags(opts[0]) & trace.FlagsSampled // nolint:gosec // slice size already checked.
+ scc.TraceFlags = trace.TraceFlags(opts[0]) & //nolint:gosec // slice size already checked.
+ (trace.FlagsSampled | trace.FlagsRandom)
// Ignore the error returned here. Failure to parse tracestate MUST NOT
// affect the parsing of traceparent according to the W3C tracecontext
diff --git a/vendor/go.opentelemetry.io/otel/requirements.txt b/vendor/go.opentelemetry.io/otel/requirements.txt
index 1bb55fb1c..7c541dee7 100644
--- a/vendor/go.opentelemetry.io/otel/requirements.txt
+++ b/vendor/go.opentelemetry.io/otel/requirements.txt
@@ -1 +1 @@
-codespell==2.4.1
+codespell==2.4.2
diff --git a/vendor/go.opentelemetry.io/otel/sdk/internal/x/features.go b/vendor/go.opentelemetry.io/otel/sdk/internal/x/features.go
index bfeb73e81..694b64a31 100644
--- a/vendor/go.opentelemetry.io/otel/sdk/internal/x/features.go
+++ b/vendor/go.opentelemetry.io/otel/sdk/internal/x/features.go
@@ -37,3 +37,18 @@ var Observability = newFeature(
return "", false
},
)
+
+// PerSeriesStartTimestamps is an experimental feature flag that determines if the SDK
+// uses the new Start Timestamps specification.
+//
+// To enable this feature set the OTEL_GO_X_PER_SERIES_START_TIMESTAMPS environment variable
+// to the case-insensitive string value of "true".
+var PerSeriesStartTimestamps = newFeature(
+ []string{"PER_SERIES_START_TIMESTAMPS"},
+ func(v string) (bool, bool) {
+ if strings.EqualFold(v, "true") {
+ return true, true
+ }
+ return false, false
+ },
+)
diff --git a/vendor/go.opentelemetry.io/otel/sdk/resource/builtin.go b/vendor/go.opentelemetry.io/otel/sdk/resource/builtin.go
index 8a7bb330b..04f15fcd2 100644
--- a/vendor/go.opentelemetry.io/otel/sdk/resource/builtin.go
+++ b/vendor/go.opentelemetry.io/otel/sdk/resource/builtin.go
@@ -13,7 +13,7 @@ import (
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/sdk"
- semconv "go.opentelemetry.io/otel/semconv/v1.39.0"
+ semconv "go.opentelemetry.io/otel/semconv/v1.40.0"
)
type (
diff --git a/vendor/go.opentelemetry.io/otel/sdk/resource/config.go b/vendor/go.opentelemetry.io/otel/sdk/resource/config.go
index 0d6e213d9..a3d647d92 100644
--- a/vendor/go.opentelemetry.io/otel/sdk/resource/config.go
+++ b/vendor/go.opentelemetry.io/otel/sdk/resource/config.go
@@ -193,3 +193,11 @@ func WithContainer() Option {
func WithContainerID() Option {
return WithDetectors(cgroupContainerIDDetector{})
}
+
+// WithService adds all the Service attributes to the configured Resource.
+func WithService() Option {
+ return WithDetectors(
+ defaultServiceInstanceIDDetector{},
+ defaultServiceNameDetector{},
+ )
+}
diff --git a/vendor/go.opentelemetry.io/otel/sdk/resource/container.go b/vendor/go.opentelemetry.io/otel/sdk/resource/container.go
index a19b39def..e977ff1c4 100644
--- a/vendor/go.opentelemetry.io/otel/sdk/resource/container.go
+++ b/vendor/go.opentelemetry.io/otel/sdk/resource/container.go
@@ -11,7 +11,7 @@ import (
"os"
"regexp"
- semconv "go.opentelemetry.io/otel/semconv/v1.39.0"
+ semconv "go.opentelemetry.io/otel/semconv/v1.40.0"
)
type containerIDProvider func() (string, error)
diff --git a/vendor/go.opentelemetry.io/otel/sdk/resource/env.go b/vendor/go.opentelemetry.io/otel/sdk/resource/env.go
index c49157224..bc0e5c19e 100644
--- a/vendor/go.opentelemetry.io/otel/sdk/resource/env.go
+++ b/vendor/go.opentelemetry.io/otel/sdk/resource/env.go
@@ -12,7 +12,7 @@ import (
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/attribute"
- semconv "go.opentelemetry.io/otel/semconv/v1.39.0"
+ semconv "go.opentelemetry.io/otel/semconv/v1.40.0"
)
const (
diff --git a/vendor/go.opentelemetry.io/otel/sdk/resource/host_id.go b/vendor/go.opentelemetry.io/otel/sdk/resource/host_id.go
index 023621ba7..755c08242 100644
--- a/vendor/go.opentelemetry.io/otel/sdk/resource/host_id.go
+++ b/vendor/go.opentelemetry.io/otel/sdk/resource/host_id.go
@@ -8,7 +8,7 @@ import (
"errors"
"strings"
- semconv "go.opentelemetry.io/otel/semconv/v1.39.0"
+ semconv "go.opentelemetry.io/otel/semconv/v1.40.0"
)
type hostIDProvider func() (string, error)
@@ -31,19 +31,19 @@ type hostIDReaderBSD struct {
readFile fileReader
}
-// read attempts to read the machine-id from /etc/hostid. If not found it will
-// execute `kenv -q smbios.system.uuid`. If neither location yields an id an
-// error will be returned.
+// read attempts to read the machine-id from /etc/hostid.
+// If not found it will execute: /bin/kenv -q smbios.system.uuid.
+// If neither location yields an id an error will be returned.
func (r *hostIDReaderBSD) read() (string, error) {
if result, err := r.readFile("/etc/hostid"); err == nil {
return strings.TrimSpace(result), nil
}
- if result, err := r.execCommand("kenv", "-q", "smbios.system.uuid"); err == nil {
+ if result, err := r.execCommand("/bin/kenv", "-q", "smbios.system.uuid"); err == nil {
return strings.TrimSpace(result), nil
}
- return "", errors.New("host id not found in: /etc/hostid or kenv")
+ return "", errors.New("host id not found in: /etc/hostid or /bin/kenv")
}
// hostIDReaderDarwin implements hostIDReader.
diff --git a/vendor/go.opentelemetry.io/otel/sdk/resource/host_id_readfile.go b/vendor/go.opentelemetry.io/otel/sdk/resource/host_id_readfile.go
index 6354b3560..c95d87685 100644
--- a/vendor/go.opentelemetry.io/otel/sdk/resource/host_id_readfile.go
+++ b/vendor/go.opentelemetry.io/otel/sdk/resource/host_id_readfile.go
@@ -8,7 +8,7 @@ package resource // import "go.opentelemetry.io/otel/sdk/resource"
import "os"
func readFile(filename string) (string, error) {
- b, err := os.ReadFile(filename)
+ b, err := os.ReadFile(filename) // nolint:gosec // false positive
if err != nil {
return "", err
}
diff --git a/vendor/go.opentelemetry.io/otel/sdk/resource/os.go b/vendor/go.opentelemetry.io/otel/sdk/resource/os.go
index 534809e21..f5682cad4 100644
--- a/vendor/go.opentelemetry.io/otel/sdk/resource/os.go
+++ b/vendor/go.opentelemetry.io/otel/sdk/resource/os.go
@@ -8,7 +8,7 @@ import (
"strings"
"go.opentelemetry.io/otel/attribute"
- semconv "go.opentelemetry.io/otel/semconv/v1.39.0"
+ semconv "go.opentelemetry.io/otel/semconv/v1.40.0"
)
type osDescriptionProvider func() (string, error)
diff --git a/vendor/go.opentelemetry.io/otel/sdk/resource/process.go b/vendor/go.opentelemetry.io/otel/sdk/resource/process.go
index a1189553c..99dce64f6 100644
--- a/vendor/go.opentelemetry.io/otel/sdk/resource/process.go
+++ b/vendor/go.opentelemetry.io/otel/sdk/resource/process.go
@@ -11,7 +11,7 @@ import (
"path/filepath"
"runtime"
- semconv "go.opentelemetry.io/otel/semconv/v1.39.0"
+ semconv "go.opentelemetry.io/otel/semconv/v1.40.0"
)
type (
diff --git a/vendor/go.opentelemetry.io/otel/sdk/resource/resource.go b/vendor/go.opentelemetry.io/otel/sdk/resource/resource.go
index 28e1e4f7e..f715be53e 100644
--- a/vendor/go.opentelemetry.io/otel/sdk/resource/resource.go
+++ b/vendor/go.opentelemetry.io/otel/sdk/resource/resource.go
@@ -232,6 +232,15 @@ func Empty() *Resource {
// Default returns an instance of Resource with a default
// "service.name" and OpenTelemetrySDK attributes.
func Default() *Resource {
+ return DefaultWithContext(context.Background())
+}
+
+// DefaultWithContext returns an instance of Resource with a default
+// "service.name" and OpenTelemetrySDK attributes.
+//
+// If the default resource has already been initialized, the provided ctx
+// is ignored and the cached resource is returned.
+func DefaultWithContext(ctx context.Context) *Resource {
defaultResourceOnce.Do(func() {
var err error
defaultDetectors := []Detector{
@@ -243,7 +252,7 @@ func Default() *Resource {
defaultDetectors = append([]Detector{defaultServiceInstanceIDDetector{}}, defaultDetectors...)
}
defaultResource, err = Detect(
- context.Background(),
+ ctx,
defaultDetectors...,
)
if err != nil {
@@ -260,8 +269,14 @@ func Default() *Resource {
// Environment returns an instance of Resource with attributes
// extracted from the OTEL_RESOURCE_ATTRIBUTES environment variable.
func Environment() *Resource {
+ return EnvironmentWithContext(context.Background())
+}
+
+// EnvironmentWithContext returns an instance of Resource with attributes
+// extracted from the OTEL_RESOURCE_ATTRIBUTES environment variable.
+func EnvironmentWithContext(ctx context.Context) *Resource {
detector := &fromEnv{}
- resource, err := detector.Detect(context.Background())
+ resource, err := detector.Detect(ctx)
if err != nil {
otel.Handle(err)
}
diff --git a/vendor/go.opentelemetry.io/otel/sdk/trace/batch_span_processor.go b/vendor/go.opentelemetry.io/otel/sdk/trace/batch_span_processor.go
index 7d15cbb9c..32854b14a 100644
--- a/vendor/go.opentelemetry.io/otel/sdk/trace/batch_span_processor.go
+++ b/vendor/go.opentelemetry.io/otel/sdk/trace/batch_span_processor.go
@@ -68,7 +68,7 @@ type batchSpanProcessor struct {
o BatchSpanProcessorOptions
queue chan ReadOnlySpan
- dropped uint32
+ dropped atomic.Uint32
inst *observ.BSP
@@ -123,12 +123,10 @@ func NewBatchSpanProcessor(exporter SpanExporter, options ...BatchSpanProcessorO
otel.Handle(err)
}
- bsp.stopWait.Add(1)
- go func() {
- defer bsp.stopWait.Done()
+ bsp.stopWait.Go(func() {
bsp.processQueue()
bsp.drainQueue()
- }()
+ })
return bsp
}
@@ -295,7 +293,7 @@ func (bsp *batchSpanProcessor) exportSpans(ctx context.Context) error {
}
if l := len(bsp.batch); l > 0 {
- global.Debug("exporting spans", "count", len(bsp.batch), "total_dropped", atomic.LoadUint32(&bsp.dropped))
+ global.Debug("exporting spans", "count", len(bsp.batch), "total_dropped", bsp.dropped.Load())
if bsp.inst != nil {
bsp.inst.Processed(ctx, int64(l))
}
@@ -423,7 +421,7 @@ func (bsp *batchSpanProcessor) enqueueDrop(ctx context.Context, sd ReadOnlySpan)
case bsp.queue <- sd:
return true
default:
- atomic.AddUint32(&bsp.dropped, 1)
+ bsp.dropped.Add(1)
if bsp.inst != nil {
bsp.inst.ProcessedQueueFull(ctx, 1)
}
diff --git a/vendor/go.opentelemetry.io/otel/sdk/trace/internal/observ/batch_span_processor.go b/vendor/go.opentelemetry.io/otel/sdk/trace/internal/observ/batch_span_processor.go
index d9cfba0b4..c31e03aa0 100644
--- a/vendor/go.opentelemetry.io/otel/sdk/trace/internal/observ/batch_span_processor.go
+++ b/vendor/go.opentelemetry.io/otel/sdk/trace/internal/observ/batch_span_processor.go
@@ -13,8 +13,8 @@ import (
"go.opentelemetry.io/otel/metric"
"go.opentelemetry.io/otel/sdk"
"go.opentelemetry.io/otel/sdk/internal/x"
- semconv "go.opentelemetry.io/otel/semconv/v1.39.0"
- "go.opentelemetry.io/otel/semconv/v1.39.0/otelconv"
+ semconv "go.opentelemetry.io/otel/semconv/v1.40.0"
+ "go.opentelemetry.io/otel/semconv/v1.40.0/otelconv"
)
const (
diff --git a/vendor/go.opentelemetry.io/otel/sdk/trace/internal/observ/simple_span_processor.go b/vendor/go.opentelemetry.io/otel/sdk/trace/internal/observ/simple_span_processor.go
index 8afd05267..0e77cd953 100644
--- a/vendor/go.opentelemetry.io/otel/sdk/trace/internal/observ/simple_span_processor.go
+++ b/vendor/go.opentelemetry.io/otel/sdk/trace/internal/observ/simple_span_processor.go
@@ -13,8 +13,8 @@ import (
"go.opentelemetry.io/otel/metric"
"go.opentelemetry.io/otel/sdk"
"go.opentelemetry.io/otel/sdk/internal/x"
- semconv "go.opentelemetry.io/otel/semconv/v1.39.0"
- "go.opentelemetry.io/otel/semconv/v1.39.0/otelconv"
+ semconv "go.opentelemetry.io/otel/semconv/v1.40.0"
+ "go.opentelemetry.io/otel/semconv/v1.40.0/otelconv"
)
var measureAttrsPool = sync.Pool{
diff --git a/vendor/go.opentelemetry.io/otel/sdk/trace/internal/observ/tracer.go b/vendor/go.opentelemetry.io/otel/sdk/trace/internal/observ/tracer.go
index 13a2db296..560d316f2 100644
--- a/vendor/go.opentelemetry.io/otel/sdk/trace/internal/observ/tracer.go
+++ b/vendor/go.opentelemetry.io/otel/sdk/trace/internal/observ/tracer.go
@@ -13,7 +13,7 @@ import (
"go.opentelemetry.io/otel/metric"
"go.opentelemetry.io/otel/sdk"
"go.opentelemetry.io/otel/sdk/internal/x"
- "go.opentelemetry.io/otel/semconv/v1.39.0/otelconv"
+ "go.opentelemetry.io/otel/semconv/v1.40.0/otelconv"
"go.opentelemetry.io/otel/trace"
)
@@ -55,6 +55,10 @@ func NewTracer() (Tracer, error) {
func (t Tracer) Enabled() bool { return t.enabled }
func (t Tracer) SpanStarted(ctx context.Context, psc trace.SpanContext, span trace.Span) {
+ if !t.started.Enabled(ctx) {
+ return
+ }
+
key := spanStartedKey{
parent: parentStateNoParent,
sampling: samplingStateDrop,
@@ -89,6 +93,10 @@ func (t Tracer) SpanEnded(ctx context.Context, span trace.Span) {
}
func (t Tracer) spanLive(ctx context.Context, value int64, span trace.Span) {
+ if !t.live.Enabled(ctx) {
+ return
+ }
+
key := spanLiveKey{sampled: span.SpanContext().IsSampled()}
opts := spanLiveOpts[key]
t.live.Add(ctx, value, opts...)
diff --git a/vendor/go.opentelemetry.io/otel/sdk/trace/provider.go b/vendor/go.opentelemetry.io/otel/sdk/trace/provider.go
index d2cf4ebd3..cd40d299d 100644
--- a/vendor/go.opentelemetry.io/otel/sdk/trace/provider.go
+++ b/vendor/go.opentelemetry.io/otel/sdk/trace/provider.go
@@ -5,6 +5,7 @@ package trace // import "go.opentelemetry.io/otel/sdk/trace"
import (
"context"
+ "errors"
"fmt"
"sync"
"sync/atomic"
@@ -262,6 +263,7 @@ func (p *TracerProvider) ForceFlush(ctx context.Context) error {
return nil
}
+ var err error
for _, sps := range spss {
select {
case <-ctx.Done():
@@ -269,11 +271,9 @@ func (p *TracerProvider) ForceFlush(ctx context.Context) error {
default:
}
- if err := sps.sp.ForceFlush(ctx); err != nil {
- return err
- }
+ err = errors.Join(err, sps.sp.ForceFlush(ctx))
}
- return nil
+ return err
}
// Shutdown shuts down TracerProvider. All registered span processors are shut down
@@ -303,14 +303,7 @@ func (p *TracerProvider) Shutdown(ctx context.Context) error {
sps.state.Do(func() {
err = sps.sp.Shutdown(ctx)
})
- if err != nil {
- if retErr == nil {
- retErr = err
- } else {
- // Poor man's list of errors
- retErr = fmt.Errorf("%w; %w", retErr, err)
- }
- }
+ retErr = errors.Join(retErr, err)
}
p.spanProcessors.Store(&spanProcessorStates{})
return retErr
diff --git a/vendor/go.opentelemetry.io/otel/sdk/trace/sampling.go b/vendor/go.opentelemetry.io/otel/sdk/trace/sampling.go
index 81c5060ad..845e292c2 100644
--- a/vendor/go.opentelemetry.io/otel/sdk/trace/sampling.go
+++ b/vendor/go.opentelemetry.io/otel/sdk/trace/sampling.go
@@ -69,17 +69,17 @@ type traceIDRatioSampler struct {
}
func (ts traceIDRatioSampler) ShouldSample(p SamplingParameters) SamplingResult {
- psc := trace.SpanContextFromContext(p.ParentContext)
+ state := trace.SpanContextFromContext(p.ParentContext).TraceState()
x := binary.BigEndian.Uint64(p.TraceID[8:16]) >> 1
if x < ts.traceIDUpperBound {
return SamplingResult{
Decision: RecordAndSample,
- Tracestate: psc.TraceState(),
+ Tracestate: state,
}
}
return SamplingResult{
Decision: Drop,
- Tracestate: psc.TraceState(),
+ Tracestate: state,
}
}
@@ -94,12 +94,20 @@ func (ts traceIDRatioSampler) Description() string {
//
//nolint:revive // revive complains about stutter of `trace.TraceIDRatioBased`
func TraceIDRatioBased(fraction float64) Sampler {
+ // Cannot use AlwaysSample() and NeverSample(), must return spec-compliant descriptions.
+ // See https://opentelemetry.io/docs/specs/otel/trace/sdk/#traceidratiobased.
if fraction >= 1 {
- return AlwaysSample()
+ return predeterminedSampler{
+ description: "TraceIDRatioBased{1}",
+ decision: RecordAndSample,
+ }
}
if fraction <= 0 {
- fraction = 0
+ return predeterminedSampler{
+ description: "TraceIDRatioBased{0}",
+ decision: Drop,
+ }
}
return &traceIDRatioSampler{
@@ -118,6 +126,7 @@ func (alwaysOnSampler) ShouldSample(p SamplingParameters) SamplingResult {
}
func (alwaysOnSampler) Description() string {
+ // https://opentelemetry.io/docs/specs/otel/trace/sdk/#alwayson
return "AlwaysOnSampler"
}
@@ -139,6 +148,7 @@ func (alwaysOffSampler) ShouldSample(p SamplingParameters) SamplingResult {
}
func (alwaysOffSampler) Description() string {
+ // https://opentelemetry.io/docs/specs/otel/trace/sdk/#alwaysoff
return "AlwaysOffSampler"
}
@@ -147,6 +157,22 @@ func NeverSample() Sampler {
return alwaysOffSampler{}
}
+type predeterminedSampler struct {
+ description string
+ decision SamplingDecision
+}
+
+func (s predeterminedSampler) ShouldSample(p SamplingParameters) SamplingResult {
+ return SamplingResult{
+ Decision: s.decision,
+ Tracestate: trace.SpanContextFromContext(p.ParentContext).TraceState(),
+ }
+}
+
+func (s predeterminedSampler) Description() string {
+ return s.description
+}
+
// ParentBased returns a sampler decorator which behaves differently,
// based on the parent of the span. If the span has no parent,
// the decorated sampler is used to make sampling decision. If the span has
diff --git a/vendor/go.opentelemetry.io/otel/sdk/trace/span.go b/vendor/go.opentelemetry.io/otel/sdk/trace/span.go
index d46661059..7d55ce1dc 100644
--- a/vendor/go.opentelemetry.io/otel/sdk/trace/span.go
+++ b/vendor/go.opentelemetry.io/otel/sdk/trace/span.go
@@ -20,7 +20,7 @@ import (
"go.opentelemetry.io/otel/internal/global"
"go.opentelemetry.io/otel/sdk/instrumentation"
"go.opentelemetry.io/otel/sdk/resource"
- semconv "go.opentelemetry.io/otel/semconv/v1.39.0"
+ semconv "go.opentelemetry.io/otel/semconv/v1.40.0"
"go.opentelemetry.io/otel/trace"
"go.opentelemetry.io/otel/trace/embedded"
)
diff --git a/vendor/go.opentelemetry.io/otel/sdk/version.go b/vendor/go.opentelemetry.io/otel/sdk/version.go
index b5497c281..766731dd2 100644
--- a/vendor/go.opentelemetry.io/otel/sdk/version.go
+++ b/vendor/go.opentelemetry.io/otel/sdk/version.go
@@ -6,5 +6,5 @@ package sdk // import "go.opentelemetry.io/otel/sdk"
// Version is the current release version of the OpenTelemetry SDK in use.
func Version() string {
- return "1.40.0"
+ return "1.43.0"
}
diff --git a/vendor/go.opentelemetry.io/otel/semconv/v1.37.0/attribute_group.go b/vendor/go.opentelemetry.io/otel/semconv/v1.37.0/attribute_group.go
index b6b27498f..2fcab2435 100644
--- a/vendor/go.opentelemetry.io/otel/semconv/v1.37.0/attribute_group.go
+++ b/vendor/go.opentelemetry.io/otel/semconv/v1.37.0/attribute_group.go
@@ -1447,9 +1447,11 @@ func AWSExtendedRequestID(val string) attribute.KeyValue {
// AWSKinesisStreamName returns an attribute KeyValue conforming to the
// "aws.kinesis.stream_name" semantic conventions. It represents the name of the
// AWS Kinesis [stream] the request refers to. Corresponds to the `--stream-name`
-// parameter of the Kinesis [describe-stream] operation.
+//
+// parameter of the Kinesis [describe-stream] operation.
//
// [stream]: https://docs.aws.amazon.com/streams/latest/dev/introduction.html
+//
// [describe-stream]: https://docs.aws.amazon.com/cli/latest/reference/kinesis/describe-stream.html
func AWSKinesisStreamName(val string) attribute.KeyValue {
return AWSKinesisStreamNameKey.String(val)
@@ -1459,7 +1461,8 @@ func AWSKinesisStreamName(val string) attribute.KeyValue {
// "aws.lambda.invoked_arn" semantic conventions. It represents the full invoked
// ARN as provided on the `Context` passed to the function (
// `Lambda-Runtime-Invoked-Function-Arn` header on the `/runtime/invocation/next`
-// applicable).
+//
+// applicable).
func AWSLambdaInvokedARN(val string) attribute.KeyValue {
return AWSLambdaInvokedARNKey.String(val)
}
@@ -2635,7 +2638,8 @@ func CloudRegion(val string) attribute.KeyValue {
// "cloud.resource_id" semantic conventions. It represents the cloud
// provider-specific native identifier of the monitored cloud resource (e.g. an
// [ARN] on AWS, a [fully qualified resource ID] on Azure, a [full resource name]
-// on GCP).
+//
+// on GCP).
//
// [ARN]: https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html
// [fully qualified resource ID]: https://learn.microsoft.com/rest/api/resources/resources/get-by-id
@@ -15190,4 +15194,4 @@ func ZOSSmfID(val string) attribute.KeyValue {
// to which the z/OS system belongs too.
func ZOSSysplexName(val string) attribute.KeyValue {
return ZOSSysplexNameKey.String(val)
-}
\ No newline at end of file
+}
diff --git a/vendor/go.opentelemetry.io/otel/semconv/v1.39.0/attribute_group.go b/vendor/go.opentelemetry.io/otel/semconv/v1.39.0/attribute_group.go
index 080365fc1..dfcee964a 100644
--- a/vendor/go.opentelemetry.io/otel/semconv/v1.39.0/attribute_group.go
+++ b/vendor/go.opentelemetry.io/otel/semconv/v1.39.0/attribute_group.go
@@ -1493,9 +1493,11 @@ func AWSExtendedRequestID(val string) attribute.KeyValue {
// AWSKinesisStreamName returns an attribute KeyValue conforming to the
// "aws.kinesis.stream_name" semantic conventions. It represents the name of the
// AWS Kinesis [stream] the request refers to. Corresponds to the `--stream-name`
-// parameter of the Kinesis [describe-stream] operation.
+//
+// parameter of the Kinesis [describe-stream] operation.
//
// [stream]: https://docs.aws.amazon.com/streams/latest/dev/introduction.html
+//
// [describe-stream]: https://docs.aws.amazon.com/cli/latest/reference/kinesis/describe-stream.html
func AWSKinesisStreamName(val string) attribute.KeyValue {
return AWSKinesisStreamNameKey.String(val)
@@ -1505,7 +1507,8 @@ func AWSKinesisStreamName(val string) attribute.KeyValue {
// "aws.lambda.invoked_arn" semantic conventions. It represents the full invoked
// ARN as provided on the `Context` passed to the function (
// `Lambda-Runtime-Invoked-Function-Arn` header on the `/runtime/invocation/next`
-// applicable).
+//
+// applicable).
func AWSLambdaInvokedARN(val string) attribute.KeyValue {
return AWSLambdaInvokedARNKey.String(val)
}
@@ -2681,7 +2684,8 @@ func CloudRegion(val string) attribute.KeyValue {
// "cloud.resource_id" semantic conventions. It represents the cloud
// provider-specific native identifier of the monitored cloud resource (e.g. an
// [ARN] on AWS, a [fully qualified resource ID] on Azure, a [full resource name]
-// on GCP).
+//
+// on GCP).
//
// [ARN]: https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html
// [fully qualified resource ID]: https://learn.microsoft.com/rest/api/resources/resources/get-by-id
@@ -16236,4 +16240,4 @@ func ZOSSmfID(val string) attribute.KeyValue {
// to which the z/OS system belongs too.
func ZOSSysplexName(val string) attribute.KeyValue {
return ZOSSysplexNameKey.String(val)
-}
\ No newline at end of file
+}
diff --git a/vendor/go.opentelemetry.io/otel/semconv/v1.39.0/httpconv/metric.go b/vendor/go.opentelemetry.io/otel/semconv/v1.39.0/httpconv/metric.go
deleted file mode 100644
index cb993812a..000000000
--- a/vendor/go.opentelemetry.io/otel/semconv/v1.39.0/httpconv/metric.go
+++ /dev/null
@@ -1,1733 +0,0 @@
-// Code generated from semantic convention specification. DO NOT EDIT.
-
-// Copyright The OpenTelemetry Authors
-// SPDX-License-Identifier: Apache-2.0
-
-// Package httpconv provides types and functionality for OpenTelemetry semantic
-// conventions in the "http" namespace.
-package httpconv
-
-import (
- "context"
- "sync"
-
- "go.opentelemetry.io/otel/attribute"
- "go.opentelemetry.io/otel/metric"
- "go.opentelemetry.io/otel/metric/noop"
-)
-
-var (
- addOptPool = &sync.Pool{New: func() any { return &[]metric.AddOption{} }}
- recOptPool = &sync.Pool{New: func() any { return &[]metric.RecordOption{} }}
-)
-
-// ErrorTypeAttr is an attribute conforming to the error.type semantic
-// conventions. It represents the describes a class of error the operation ended
-// with.
-type ErrorTypeAttr string
-
-var (
- // ErrorTypeOther is a fallback error value to be used when the instrumentation
- // doesn't define a custom value.
- ErrorTypeOther ErrorTypeAttr = "_OTHER"
-)
-
-// ConnectionStateAttr is an attribute conforming to the http.connection.state
-// semantic conventions. It represents the state of the HTTP connection in the
-// HTTP connection pool.
-type ConnectionStateAttr string
-
-var (
- // ConnectionStateActive is the active state.
- ConnectionStateActive ConnectionStateAttr = "active"
- // ConnectionStateIdle is the idle state.
- ConnectionStateIdle ConnectionStateAttr = "idle"
-)
-
-// RequestMethodAttr is an attribute conforming to the http.request.method
-// semantic conventions. It represents the HTTP request method.
-type RequestMethodAttr string
-
-var (
- // RequestMethodConnect is the CONNECT method.
- RequestMethodConnect RequestMethodAttr = "CONNECT"
- // RequestMethodDelete is the DELETE method.
- RequestMethodDelete RequestMethodAttr = "DELETE"
- // RequestMethodGet is the GET method.
- RequestMethodGet RequestMethodAttr = "GET"
- // RequestMethodHead is the HEAD method.
- RequestMethodHead RequestMethodAttr = "HEAD"
- // RequestMethodOptions is the OPTIONS method.
- RequestMethodOptions RequestMethodAttr = "OPTIONS"
- // RequestMethodPatch is the PATCH method.
- RequestMethodPatch RequestMethodAttr = "PATCH"
- // RequestMethodPost is the POST method.
- RequestMethodPost RequestMethodAttr = "POST"
- // RequestMethodPut is the PUT method.
- RequestMethodPut RequestMethodAttr = "PUT"
- // RequestMethodTrace is the TRACE method.
- RequestMethodTrace RequestMethodAttr = "TRACE"
- // RequestMethodQuery is the QUERY method.
- RequestMethodQuery RequestMethodAttr = "QUERY"
- // RequestMethodOther is the any HTTP method that the instrumentation has no
- // prior knowledge of.
- RequestMethodOther RequestMethodAttr = "_OTHER"
-)
-
-// UserAgentSyntheticTypeAttr is an attribute conforming to the
-// user_agent.synthetic.type semantic conventions. It represents the specifies
-// the category of synthetic traffic, such as tests or bots.
-type UserAgentSyntheticTypeAttr string
-
-var (
- // UserAgentSyntheticTypeBot is the bot source.
- UserAgentSyntheticTypeBot UserAgentSyntheticTypeAttr = "bot"
- // UserAgentSyntheticTypeTest is the synthetic test source.
- UserAgentSyntheticTypeTest UserAgentSyntheticTypeAttr = "test"
-)
-
-// ClientActiveRequests is an instrument used to record metric values conforming
-// to the "http.client.active_requests" semantic conventions. It represents the
-// number of active HTTP requests.
-type ClientActiveRequests struct {
- metric.Int64UpDownCounter
-}
-
-var newClientActiveRequestsOpts = []metric.Int64UpDownCounterOption{
- metric.WithDescription("Number of active HTTP requests."),
- metric.WithUnit("{request}"),
-}
-
-// NewClientActiveRequests returns a new ClientActiveRequests instrument.
-func NewClientActiveRequests(
- m metric.Meter,
- opt ...metric.Int64UpDownCounterOption,
-) (ClientActiveRequests, error) {
- // Check if the meter is nil.
- if m == nil {
- return ClientActiveRequests{noop.Int64UpDownCounter{}}, nil
- }
-
- if len(opt) == 0 {
- opt = newClientActiveRequestsOpts
- } else {
- opt = append(opt, newClientActiveRequestsOpts...)
- }
-
- i, err := m.Int64UpDownCounter(
- "http.client.active_requests",
- opt...,
- )
- if err != nil {
- return ClientActiveRequests{noop.Int64UpDownCounter{}}, err
- }
- return ClientActiveRequests{i}, nil
-}
-
-// Inst returns the underlying metric instrument.
-func (m ClientActiveRequests) Inst() metric.Int64UpDownCounter {
- return m.Int64UpDownCounter
-}
-
-// Name returns the semantic convention name of the instrument.
-func (ClientActiveRequests) Name() string {
- return "http.client.active_requests"
-}
-
-// Unit returns the semantic convention unit of the instrument
-func (ClientActiveRequests) Unit() string {
- return "{request}"
-}
-
-// Description returns the semantic convention description of the instrument
-func (ClientActiveRequests) Description() string {
- return "Number of active HTTP requests."
-}
-
-// Add adds incr to the existing count for attrs.
-//
-// The serverAddress is the server domain name if available without reverse DNS
-// lookup; otherwise, IP address or Unix domain socket name.
-//
-// The serverPort is the server port number.
-//
-// All additional attrs passed are included in the recorded value.
-func (m ClientActiveRequests) Add(
- ctx context.Context,
- incr int64,
- serverAddress string,
- serverPort int,
- attrs ...attribute.KeyValue,
-) {
- if len(attrs) == 0 {
- m.Int64UpDownCounter.Add(ctx, incr)
- return
- }
-
- o := addOptPool.Get().(*[]metric.AddOption)
- defer func() {
- *o = (*o)[:0]
- addOptPool.Put(o)
- }()
-
- *o = append(
- *o,
- metric.WithAttributes(
- append(
- attrs,
- attribute.String("server.address", serverAddress),
- attribute.Int("server.port", serverPort),
- )...,
- ),
- )
-
- m.Int64UpDownCounter.Add(ctx, incr, *o...)
-}
-
-// AddSet adds incr to the existing count for set.
-func (m ClientActiveRequests) AddSet(ctx context.Context, incr int64, set attribute.Set) {
- if set.Len() == 0 {
- m.Int64UpDownCounter.Add(ctx, incr)
- return
- }
-
- o := addOptPool.Get().(*[]metric.AddOption)
- defer func() {
- *o = (*o)[:0]
- addOptPool.Put(o)
- }()
-
- *o = append(*o, metric.WithAttributeSet(set))
- m.Int64UpDownCounter.Add(ctx, incr, *o...)
-}
-
-// AttrURLTemplate returns an optional attribute for the "url.template" semantic
-// convention. It represents the low-cardinality template of an
-// [absolute path reference].
-//
-// [absolute path reference]: https://www.rfc-editor.org/rfc/rfc3986#section-4.2
-func (ClientActiveRequests) AttrURLTemplate(val string) attribute.KeyValue {
- return attribute.String("url.template", val)
-}
-
-// AttrRequestMethod returns an optional attribute for the "http.request.method"
-// semantic convention. It represents the HTTP request method.
-func (ClientActiveRequests) AttrRequestMethod(val RequestMethodAttr) attribute.KeyValue {
- return attribute.String("http.request.method", string(val))
-}
-
-// AttrURLScheme returns an optional attribute for the "url.scheme" semantic
-// convention. It represents the [URI scheme] component identifying the used
-// protocol.
-//
-// [URI scheme]: https://www.rfc-editor.org/rfc/rfc3986#section-3.1
-func (ClientActiveRequests) AttrURLScheme(val string) attribute.KeyValue {
- return attribute.String("url.scheme", val)
-}
-
-// ClientConnectionDuration is an instrument used to record metric values
-// conforming to the "http.client.connection.duration" semantic conventions. It
-// represents the duration of the successfully established outbound HTTP
-// connections.
-type ClientConnectionDuration struct {
- metric.Float64Histogram
-}
-
-var newClientConnectionDurationOpts = []metric.Float64HistogramOption{
- metric.WithDescription("The duration of the successfully established outbound HTTP connections."),
- metric.WithUnit("s"),
-}
-
-// NewClientConnectionDuration returns a new ClientConnectionDuration instrument.
-func NewClientConnectionDuration(
- m metric.Meter,
- opt ...metric.Float64HistogramOption,
-) (ClientConnectionDuration, error) {
- // Check if the meter is nil.
- if m == nil {
- return ClientConnectionDuration{noop.Float64Histogram{}}, nil
- }
-
- if len(opt) == 0 {
- opt = newClientConnectionDurationOpts
- } else {
- opt = append(opt, newClientConnectionDurationOpts...)
- }
-
- i, err := m.Float64Histogram(
- "http.client.connection.duration",
- opt...,
- )
- if err != nil {
- return ClientConnectionDuration{noop.Float64Histogram{}}, err
- }
- return ClientConnectionDuration{i}, nil
-}
-
-// Inst returns the underlying metric instrument.
-func (m ClientConnectionDuration) Inst() metric.Float64Histogram {
- return m.Float64Histogram
-}
-
-// Name returns the semantic convention name of the instrument.
-func (ClientConnectionDuration) Name() string {
- return "http.client.connection.duration"
-}
-
-// Unit returns the semantic convention unit of the instrument
-func (ClientConnectionDuration) Unit() string {
- return "s"
-}
-
-// Description returns the semantic convention description of the instrument
-func (ClientConnectionDuration) Description() string {
- return "The duration of the successfully established outbound HTTP connections."
-}
-
-// Record records val to the current distribution for attrs.
-//
-// The serverAddress is the server domain name if available without reverse DNS
-// lookup; otherwise, IP address or Unix domain socket name.
-//
-// The serverPort is the server port number.
-//
-// All additional attrs passed are included in the recorded value.
-func (m ClientConnectionDuration) Record(
- ctx context.Context,
- val float64,
- serverAddress string,
- serverPort int,
- attrs ...attribute.KeyValue,
-) {
- if len(attrs) == 0 {
- m.Float64Histogram.Record(ctx, val)
- return
- }
-
- o := recOptPool.Get().(*[]metric.RecordOption)
- defer func() {
- *o = (*o)[:0]
- recOptPool.Put(o)
- }()
-
- *o = append(
- *o,
- metric.WithAttributes(
- append(
- attrs,
- attribute.String("server.address", serverAddress),
- attribute.Int("server.port", serverPort),
- )...,
- ),
- )
-
- m.Float64Histogram.Record(ctx, val, *o...)
-}
-
-// RecordSet records val to the current distribution for set.
-func (m ClientConnectionDuration) RecordSet(ctx context.Context, val float64, set attribute.Set) {
- if set.Len() == 0 {
- m.Float64Histogram.Record(ctx, val)
- return
- }
-
- o := recOptPool.Get().(*[]metric.RecordOption)
- defer func() {
- *o = (*o)[:0]
- recOptPool.Put(o)
- }()
-
- *o = append(*o, metric.WithAttributeSet(set))
- m.Float64Histogram.Record(ctx, val, *o...)
-}
-
-// AttrNetworkPeerAddress returns an optional attribute for the
-// "network.peer.address" semantic convention. It represents the peer address of
-// the network connection - IP address or Unix domain socket name.
-func (ClientConnectionDuration) AttrNetworkPeerAddress(val string) attribute.KeyValue {
- return attribute.String("network.peer.address", val)
-}
-
-// AttrNetworkProtocolVersion returns an optional attribute for the
-// "network.protocol.version" semantic convention. It represents the actual
-// version of the protocol used for network communication.
-func (ClientConnectionDuration) AttrNetworkProtocolVersion(val string) attribute.KeyValue {
- return attribute.String("network.protocol.version", val)
-}
-
-// AttrURLScheme returns an optional attribute for the "url.scheme" semantic
-// convention. It represents the [URI scheme] component identifying the used
-// protocol.
-//
-// [URI scheme]: https://www.rfc-editor.org/rfc/rfc3986#section-3.1
-func (ClientConnectionDuration) AttrURLScheme(val string) attribute.KeyValue {
- return attribute.String("url.scheme", val)
-}
-
-// ClientOpenConnections is an instrument used to record metric values conforming
-// to the "http.client.open_connections" semantic conventions. It represents the
-// number of outbound HTTP connections that are currently active or idle on the
-// client.
-type ClientOpenConnections struct {
- metric.Int64UpDownCounter
-}
-
-var newClientOpenConnectionsOpts = []metric.Int64UpDownCounterOption{
- metric.WithDescription("Number of outbound HTTP connections that are currently active or idle on the client."),
- metric.WithUnit("{connection}"),
-}
-
-// NewClientOpenConnections returns a new ClientOpenConnections instrument.
-func NewClientOpenConnections(
- m metric.Meter,
- opt ...metric.Int64UpDownCounterOption,
-) (ClientOpenConnections, error) {
- // Check if the meter is nil.
- if m == nil {
- return ClientOpenConnections{noop.Int64UpDownCounter{}}, nil
- }
-
- if len(opt) == 0 {
- opt = newClientOpenConnectionsOpts
- } else {
- opt = append(opt, newClientOpenConnectionsOpts...)
- }
-
- i, err := m.Int64UpDownCounter(
- "http.client.open_connections",
- opt...,
- )
- if err != nil {
- return ClientOpenConnections{noop.Int64UpDownCounter{}}, err
- }
- return ClientOpenConnections{i}, nil
-}
-
-// Inst returns the underlying metric instrument.
-func (m ClientOpenConnections) Inst() metric.Int64UpDownCounter {
- return m.Int64UpDownCounter
-}
-
-// Name returns the semantic convention name of the instrument.
-func (ClientOpenConnections) Name() string {
- return "http.client.open_connections"
-}
-
-// Unit returns the semantic convention unit of the instrument
-func (ClientOpenConnections) Unit() string {
- return "{connection}"
-}
-
-// Description returns the semantic convention description of the instrument
-func (ClientOpenConnections) Description() string {
- return "Number of outbound HTTP connections that are currently active or idle on the client."
-}
-
-// Add adds incr to the existing count for attrs.
-//
-// The connectionState is the state of the HTTP connection in the HTTP connection
-// pool.
-//
-// The serverAddress is the server domain name if available without reverse DNS
-// lookup; otherwise, IP address or Unix domain socket name.
-//
-// The serverPort is the server port number.
-//
-// All additional attrs passed are included in the recorded value.
-func (m ClientOpenConnections) Add(
- ctx context.Context,
- incr int64,
- connectionState ConnectionStateAttr,
- serverAddress string,
- serverPort int,
- attrs ...attribute.KeyValue,
-) {
- if len(attrs) == 0 {
- m.Int64UpDownCounter.Add(ctx, incr)
- return
- }
-
- o := addOptPool.Get().(*[]metric.AddOption)
- defer func() {
- *o = (*o)[:0]
- addOptPool.Put(o)
- }()
-
- *o = append(
- *o,
- metric.WithAttributes(
- append(
- attrs,
- attribute.String("http.connection.state", string(connectionState)),
- attribute.String("server.address", serverAddress),
- attribute.Int("server.port", serverPort),
- )...,
- ),
- )
-
- m.Int64UpDownCounter.Add(ctx, incr, *o...)
-}
-
-// AddSet adds incr to the existing count for set.
-func (m ClientOpenConnections) AddSet(ctx context.Context, incr int64, set attribute.Set) {
- if set.Len() == 0 {
- m.Int64UpDownCounter.Add(ctx, incr)
- return
- }
-
- o := addOptPool.Get().(*[]metric.AddOption)
- defer func() {
- *o = (*o)[:0]
- addOptPool.Put(o)
- }()
-
- *o = append(*o, metric.WithAttributeSet(set))
- m.Int64UpDownCounter.Add(ctx, incr, *o...)
-}
-
-// AttrNetworkPeerAddress returns an optional attribute for the
-// "network.peer.address" semantic convention. It represents the peer address of
-// the network connection - IP address or Unix domain socket name.
-func (ClientOpenConnections) AttrNetworkPeerAddress(val string) attribute.KeyValue {
- return attribute.String("network.peer.address", val)
-}
-
-// AttrNetworkProtocolVersion returns an optional attribute for the
-// "network.protocol.version" semantic convention. It represents the actual
-// version of the protocol used for network communication.
-func (ClientOpenConnections) AttrNetworkProtocolVersion(val string) attribute.KeyValue {
- return attribute.String("network.protocol.version", val)
-}
-
-// AttrURLScheme returns an optional attribute for the "url.scheme" semantic
-// convention. It represents the [URI scheme] component identifying the used
-// protocol.
-//
-// [URI scheme]: https://www.rfc-editor.org/rfc/rfc3986#section-3.1
-func (ClientOpenConnections) AttrURLScheme(val string) attribute.KeyValue {
- return attribute.String("url.scheme", val)
-}
-
-// ClientRequestBodySize is an instrument used to record metric values conforming
-// to the "http.client.request.body.size" semantic conventions. It represents the
-// size of HTTP client request bodies.
-type ClientRequestBodySize struct {
- metric.Int64Histogram
-}
-
-var newClientRequestBodySizeOpts = []metric.Int64HistogramOption{
- metric.WithDescription("Size of HTTP client request bodies."),
- metric.WithUnit("By"),
-}
-
-// NewClientRequestBodySize returns a new ClientRequestBodySize instrument.
-func NewClientRequestBodySize(
- m metric.Meter,
- opt ...metric.Int64HistogramOption,
-) (ClientRequestBodySize, error) {
- // Check if the meter is nil.
- if m == nil {
- return ClientRequestBodySize{noop.Int64Histogram{}}, nil
- }
-
- if len(opt) == 0 {
- opt = newClientRequestBodySizeOpts
- } else {
- opt = append(opt, newClientRequestBodySizeOpts...)
- }
-
- i, err := m.Int64Histogram(
- "http.client.request.body.size",
- opt...,
- )
- if err != nil {
- return ClientRequestBodySize{noop.Int64Histogram{}}, err
- }
- return ClientRequestBodySize{i}, nil
-}
-
-// Inst returns the underlying metric instrument.
-func (m ClientRequestBodySize) Inst() metric.Int64Histogram {
- return m.Int64Histogram
-}
-
-// Name returns the semantic convention name of the instrument.
-func (ClientRequestBodySize) Name() string {
- return "http.client.request.body.size"
-}
-
-// Unit returns the semantic convention unit of the instrument
-func (ClientRequestBodySize) Unit() string {
- return "By"
-}
-
-// Description returns the semantic convention description of the instrument
-func (ClientRequestBodySize) Description() string {
- return "Size of HTTP client request bodies."
-}
-
-// Record records val to the current distribution for attrs.
-//
-// The requestMethod is the HTTP request method.
-//
-// The serverAddress is the server domain name if available without reverse DNS
-// lookup; otherwise, IP address or Unix domain socket name.
-//
-// The serverPort is the server port number.
-//
-// All additional attrs passed are included in the recorded value.
-//
-// The size of the request payload body in bytes. This is the number of bytes
-// transferred excluding headers and is often, but not always, present as the
-// [Content-Length] header. For requests using transport encoding, this should be
-// the compressed size.
-//
-// [Content-Length]: https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length
-func (m ClientRequestBodySize) Record(
- ctx context.Context,
- val int64,
- requestMethod RequestMethodAttr,
- serverAddress string,
- serverPort int,
- attrs ...attribute.KeyValue,
-) {
- if len(attrs) == 0 {
- m.Int64Histogram.Record(ctx, val)
- return
- }
-
- o := recOptPool.Get().(*[]metric.RecordOption)
- defer func() {
- *o = (*o)[:0]
- recOptPool.Put(o)
- }()
-
- *o = append(
- *o,
- metric.WithAttributes(
- append(
- attrs,
- attribute.String("http.request.method", string(requestMethod)),
- attribute.String("server.address", serverAddress),
- attribute.Int("server.port", serverPort),
- )...,
- ),
- )
-
- m.Int64Histogram.Record(ctx, val, *o...)
-}
-
-// RecordSet records val to the current distribution for set.
-//
-// The size of the request payload body in bytes. This is the number of bytes
-// transferred excluding headers and is often, but not always, present as the
-// [Content-Length] header. For requests using transport encoding, this should be
-// the compressed size.
-//
-// [Content-Length]: https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length
-func (m ClientRequestBodySize) RecordSet(ctx context.Context, val int64, set attribute.Set) {
- if set.Len() == 0 {
- m.Int64Histogram.Record(ctx, val)
- return
- }
-
- o := recOptPool.Get().(*[]metric.RecordOption)
- defer func() {
- *o = (*o)[:0]
- recOptPool.Put(o)
- }()
-
- *o = append(*o, metric.WithAttributeSet(set))
- m.Int64Histogram.Record(ctx, val, *o...)
-}
-
-// AttrErrorType returns an optional attribute for the "error.type" semantic
-// convention. It represents the describes a class of error the operation ended
-// with.
-func (ClientRequestBodySize) AttrErrorType(val ErrorTypeAttr) attribute.KeyValue {
- return attribute.String("error.type", string(val))
-}
-
-// AttrResponseStatusCode returns an optional attribute for the
-// "http.response.status_code" semantic convention. It represents the
-// [HTTP response status code].
-//
-// [HTTP response status code]: https://tools.ietf.org/html/rfc7231#section-6
-func (ClientRequestBodySize) AttrResponseStatusCode(val int) attribute.KeyValue {
- return attribute.Int("http.response.status_code", val)
-}
-
-// AttrNetworkProtocolName returns an optional attribute for the
-// "network.protocol.name" semantic convention. It represents the
-// [OSI application layer] or non-OSI equivalent.
-//
-// [OSI application layer]: https://wikipedia.org/wiki/Application_layer
-func (ClientRequestBodySize) AttrNetworkProtocolName(val string) attribute.KeyValue {
- return attribute.String("network.protocol.name", val)
-}
-
-// AttrURLTemplate returns an optional attribute for the "url.template" semantic
-// convention. It represents the low-cardinality template of an
-// [absolute path reference].
-//
-// [absolute path reference]: https://www.rfc-editor.org/rfc/rfc3986#section-4.2
-func (ClientRequestBodySize) AttrURLTemplate(val string) attribute.KeyValue {
- return attribute.String("url.template", val)
-}
-
-// AttrNetworkProtocolVersion returns an optional attribute for the
-// "network.protocol.version" semantic convention. It represents the actual
-// version of the protocol used for network communication.
-func (ClientRequestBodySize) AttrNetworkProtocolVersion(val string) attribute.KeyValue {
- return attribute.String("network.protocol.version", val)
-}
-
-// AttrURLScheme returns an optional attribute for the "url.scheme" semantic
-// convention. It represents the [URI scheme] component identifying the used
-// protocol.
-//
-// [URI scheme]: https://www.rfc-editor.org/rfc/rfc3986#section-3.1
-func (ClientRequestBodySize) AttrURLScheme(val string) attribute.KeyValue {
- return attribute.String("url.scheme", val)
-}
-
-// ClientRequestDuration is an instrument used to record metric values conforming
-// to the "http.client.request.duration" semantic conventions. It represents the
-// duration of HTTP client requests.
-type ClientRequestDuration struct {
- metric.Float64Histogram
-}
-
-var newClientRequestDurationOpts = []metric.Float64HistogramOption{
- metric.WithDescription("Duration of HTTP client requests."),
- metric.WithUnit("s"),
-}
-
-// NewClientRequestDuration returns a new ClientRequestDuration instrument.
-func NewClientRequestDuration(
- m metric.Meter,
- opt ...metric.Float64HistogramOption,
-) (ClientRequestDuration, error) {
- // Check if the meter is nil.
- if m == nil {
- return ClientRequestDuration{noop.Float64Histogram{}}, nil
- }
-
- if len(opt) == 0 {
- opt = newClientRequestDurationOpts
- } else {
- opt = append(opt, newClientRequestDurationOpts...)
- }
-
- i, err := m.Float64Histogram(
- "http.client.request.duration",
- opt...,
- )
- if err != nil {
- return ClientRequestDuration{noop.Float64Histogram{}}, err
- }
- return ClientRequestDuration{i}, nil
-}
-
-// Inst returns the underlying metric instrument.
-func (m ClientRequestDuration) Inst() metric.Float64Histogram {
- return m.Float64Histogram
-}
-
-// Name returns the semantic convention name of the instrument.
-func (ClientRequestDuration) Name() string {
- return "http.client.request.duration"
-}
-
-// Unit returns the semantic convention unit of the instrument
-func (ClientRequestDuration) Unit() string {
- return "s"
-}
-
-// Description returns the semantic convention description of the instrument
-func (ClientRequestDuration) Description() string {
- return "Duration of HTTP client requests."
-}
-
-// Record records val to the current distribution for attrs.
-//
-// The requestMethod is the HTTP request method.
-//
-// The serverAddress is the server domain name if available without reverse DNS
-// lookup; otherwise, IP address or Unix domain socket name.
-//
-// The serverPort is the server port number.
-//
-// All additional attrs passed are included in the recorded value.
-func (m ClientRequestDuration) Record(
- ctx context.Context,
- val float64,
- requestMethod RequestMethodAttr,
- serverAddress string,
- serverPort int,
- attrs ...attribute.KeyValue,
-) {
- if len(attrs) == 0 {
- m.Float64Histogram.Record(ctx, val)
- return
- }
-
- o := recOptPool.Get().(*[]metric.RecordOption)
- defer func() {
- *o = (*o)[:0]
- recOptPool.Put(o)
- }()
-
- *o = append(
- *o,
- metric.WithAttributes(
- append(
- attrs,
- attribute.String("http.request.method", string(requestMethod)),
- attribute.String("server.address", serverAddress),
- attribute.Int("server.port", serverPort),
- )...,
- ),
- )
-
- m.Float64Histogram.Record(ctx, val, *o...)
-}
-
-// RecordSet records val to the current distribution for set.
-func (m ClientRequestDuration) RecordSet(ctx context.Context, val float64, set attribute.Set) {
- if set.Len() == 0 {
- m.Float64Histogram.Record(ctx, val)
- return
- }
-
- o := recOptPool.Get().(*[]metric.RecordOption)
- defer func() {
- *o = (*o)[:0]
- recOptPool.Put(o)
- }()
-
- *o = append(*o, metric.WithAttributeSet(set))
- m.Float64Histogram.Record(ctx, val, *o...)
-}
-
-// AttrErrorType returns an optional attribute for the "error.type" semantic
-// convention. It represents the describes a class of error the operation ended
-// with.
-func (ClientRequestDuration) AttrErrorType(val ErrorTypeAttr) attribute.KeyValue {
- return attribute.String("error.type", string(val))
-}
-
-// AttrResponseStatusCode returns an optional attribute for the
-// "http.response.status_code" semantic convention. It represents the
-// [HTTP response status code].
-//
-// [HTTP response status code]: https://tools.ietf.org/html/rfc7231#section-6
-func (ClientRequestDuration) AttrResponseStatusCode(val int) attribute.KeyValue {
- return attribute.Int("http.response.status_code", val)
-}
-
-// AttrNetworkProtocolName returns an optional attribute for the
-// "network.protocol.name" semantic convention. It represents the
-// [OSI application layer] or non-OSI equivalent.
-//
-// [OSI application layer]: https://wikipedia.org/wiki/Application_layer
-func (ClientRequestDuration) AttrNetworkProtocolName(val string) attribute.KeyValue {
- return attribute.String("network.protocol.name", val)
-}
-
-// AttrNetworkProtocolVersion returns an optional attribute for the
-// "network.protocol.version" semantic convention. It represents the actual
-// version of the protocol used for network communication.
-func (ClientRequestDuration) AttrNetworkProtocolVersion(val string) attribute.KeyValue {
- return attribute.String("network.protocol.version", val)
-}
-
-// AttrURLScheme returns an optional attribute for the "url.scheme" semantic
-// convention. It represents the [URI scheme] component identifying the used
-// protocol.
-//
-// [URI scheme]: https://www.rfc-editor.org/rfc/rfc3986#section-3.1
-func (ClientRequestDuration) AttrURLScheme(val string) attribute.KeyValue {
- return attribute.String("url.scheme", val)
-}
-
-// AttrURLTemplate returns an optional attribute for the "url.template" semantic
-// convention. It represents the low-cardinality template of an
-// [absolute path reference].
-//
-// [absolute path reference]: https://www.rfc-editor.org/rfc/rfc3986#section-4.2
-func (ClientRequestDuration) AttrURLTemplate(val string) attribute.KeyValue {
- return attribute.String("url.template", val)
-}
-
-// ClientResponseBodySize is an instrument used to record metric values
-// conforming to the "http.client.response.body.size" semantic conventions. It
-// represents the size of HTTP client response bodies.
-type ClientResponseBodySize struct {
- metric.Int64Histogram
-}
-
-var newClientResponseBodySizeOpts = []metric.Int64HistogramOption{
- metric.WithDescription("Size of HTTP client response bodies."),
- metric.WithUnit("By"),
-}
-
-// NewClientResponseBodySize returns a new ClientResponseBodySize instrument.
-func NewClientResponseBodySize(
- m metric.Meter,
- opt ...metric.Int64HistogramOption,
-) (ClientResponseBodySize, error) {
- // Check if the meter is nil.
- if m == nil {
- return ClientResponseBodySize{noop.Int64Histogram{}}, nil
- }
-
- if len(opt) == 0 {
- opt = newClientResponseBodySizeOpts
- } else {
- opt = append(opt, newClientResponseBodySizeOpts...)
- }
-
- i, err := m.Int64Histogram(
- "http.client.response.body.size",
- opt...,
- )
- if err != nil {
- return ClientResponseBodySize{noop.Int64Histogram{}}, err
- }
- return ClientResponseBodySize{i}, nil
-}
-
-// Inst returns the underlying metric instrument.
-func (m ClientResponseBodySize) Inst() metric.Int64Histogram {
- return m.Int64Histogram
-}
-
-// Name returns the semantic convention name of the instrument.
-func (ClientResponseBodySize) Name() string {
- return "http.client.response.body.size"
-}
-
-// Unit returns the semantic convention unit of the instrument
-func (ClientResponseBodySize) Unit() string {
- return "By"
-}
-
-// Description returns the semantic convention description of the instrument
-func (ClientResponseBodySize) Description() string {
- return "Size of HTTP client response bodies."
-}
-
-// Record records val to the current distribution for attrs.
-//
-// The requestMethod is the HTTP request method.
-//
-// The serverAddress is the server domain name if available without reverse DNS
-// lookup; otherwise, IP address or Unix domain socket name.
-//
-// The serverPort is the server port number.
-//
-// All additional attrs passed are included in the recorded value.
-//
-// The size of the response payload body in bytes. This is the number of bytes
-// transferred excluding headers and is often, but not always, present as the
-// [Content-Length] header. For requests using transport encoding, this should be
-// the compressed size.
-//
-// [Content-Length]: https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length
-func (m ClientResponseBodySize) Record(
- ctx context.Context,
- val int64,
- requestMethod RequestMethodAttr,
- serverAddress string,
- serverPort int,
- attrs ...attribute.KeyValue,
-) {
- if len(attrs) == 0 {
- m.Int64Histogram.Record(ctx, val)
- return
- }
-
- o := recOptPool.Get().(*[]metric.RecordOption)
- defer func() {
- *o = (*o)[:0]
- recOptPool.Put(o)
- }()
-
- *o = append(
- *o,
- metric.WithAttributes(
- append(
- attrs,
- attribute.String("http.request.method", string(requestMethod)),
- attribute.String("server.address", serverAddress),
- attribute.Int("server.port", serverPort),
- )...,
- ),
- )
-
- m.Int64Histogram.Record(ctx, val, *o...)
-}
-
-// RecordSet records val to the current distribution for set.
-//
-// The size of the response payload body in bytes. This is the number of bytes
-// transferred excluding headers and is often, but not always, present as the
-// [Content-Length] header. For requests using transport encoding, this should be
-// the compressed size.
-//
-// [Content-Length]: https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length
-func (m ClientResponseBodySize) RecordSet(ctx context.Context, val int64, set attribute.Set) {
- if set.Len() == 0 {
- m.Int64Histogram.Record(ctx, val)
- return
- }
-
- o := recOptPool.Get().(*[]metric.RecordOption)
- defer func() {
- *o = (*o)[:0]
- recOptPool.Put(o)
- }()
-
- *o = append(*o, metric.WithAttributeSet(set))
- m.Int64Histogram.Record(ctx, val, *o...)
-}
-
-// AttrErrorType returns an optional attribute for the "error.type" semantic
-// convention. It represents the describes a class of error the operation ended
-// with.
-func (ClientResponseBodySize) AttrErrorType(val ErrorTypeAttr) attribute.KeyValue {
- return attribute.String("error.type", string(val))
-}
-
-// AttrResponseStatusCode returns an optional attribute for the
-// "http.response.status_code" semantic convention. It represents the
-// [HTTP response status code].
-//
-// [HTTP response status code]: https://tools.ietf.org/html/rfc7231#section-6
-func (ClientResponseBodySize) AttrResponseStatusCode(val int) attribute.KeyValue {
- return attribute.Int("http.response.status_code", val)
-}
-
-// AttrNetworkProtocolName returns an optional attribute for the
-// "network.protocol.name" semantic convention. It represents the
-// [OSI application layer] or non-OSI equivalent.
-//
-// [OSI application layer]: https://wikipedia.org/wiki/Application_layer
-func (ClientResponseBodySize) AttrNetworkProtocolName(val string) attribute.KeyValue {
- return attribute.String("network.protocol.name", val)
-}
-
-// AttrURLTemplate returns an optional attribute for the "url.template" semantic
-// convention. It represents the low-cardinality template of an
-// [absolute path reference].
-//
-// [absolute path reference]: https://www.rfc-editor.org/rfc/rfc3986#section-4.2
-func (ClientResponseBodySize) AttrURLTemplate(val string) attribute.KeyValue {
- return attribute.String("url.template", val)
-}
-
-// AttrNetworkProtocolVersion returns an optional attribute for the
-// "network.protocol.version" semantic convention. It represents the actual
-// version of the protocol used for network communication.
-func (ClientResponseBodySize) AttrNetworkProtocolVersion(val string) attribute.KeyValue {
- return attribute.String("network.protocol.version", val)
-}
-
-// AttrURLScheme returns an optional attribute for the "url.scheme" semantic
-// convention. It represents the [URI scheme] component identifying the used
-// protocol.
-//
-// [URI scheme]: https://www.rfc-editor.org/rfc/rfc3986#section-3.1
-func (ClientResponseBodySize) AttrURLScheme(val string) attribute.KeyValue {
- return attribute.String("url.scheme", val)
-}
-
-// ServerActiveRequests is an instrument used to record metric values conforming
-// to the "http.server.active_requests" semantic conventions. It represents the
-// number of active HTTP server requests.
-type ServerActiveRequests struct {
- metric.Int64UpDownCounter
-}
-
-var newServerActiveRequestsOpts = []metric.Int64UpDownCounterOption{
- metric.WithDescription("Number of active HTTP server requests."),
- metric.WithUnit("{request}"),
-}
-
-// NewServerActiveRequests returns a new ServerActiveRequests instrument.
-func NewServerActiveRequests(
- m metric.Meter,
- opt ...metric.Int64UpDownCounterOption,
-) (ServerActiveRequests, error) {
- // Check if the meter is nil.
- if m == nil {
- return ServerActiveRequests{noop.Int64UpDownCounter{}}, nil
- }
-
- if len(opt) == 0 {
- opt = newServerActiveRequestsOpts
- } else {
- opt = append(opt, newServerActiveRequestsOpts...)
- }
-
- i, err := m.Int64UpDownCounter(
- "http.server.active_requests",
- opt...,
- )
- if err != nil {
- return ServerActiveRequests{noop.Int64UpDownCounter{}}, err
- }
- return ServerActiveRequests{i}, nil
-}
-
-// Inst returns the underlying metric instrument.
-func (m ServerActiveRequests) Inst() metric.Int64UpDownCounter {
- return m.Int64UpDownCounter
-}
-
-// Name returns the semantic convention name of the instrument.
-func (ServerActiveRequests) Name() string {
- return "http.server.active_requests"
-}
-
-// Unit returns the semantic convention unit of the instrument
-func (ServerActiveRequests) Unit() string {
- return "{request}"
-}
-
-// Description returns the semantic convention description of the instrument
-func (ServerActiveRequests) Description() string {
- return "Number of active HTTP server requests."
-}
-
-// Add adds incr to the existing count for attrs.
-//
-// The requestMethod is the HTTP request method.
-//
-// The urlScheme is the the [URI scheme] component identifying the used protocol.
-//
-// All additional attrs passed are included in the recorded value.
-//
-// [URI scheme]: https://www.rfc-editor.org/rfc/rfc3986#section-3.1
-func (m ServerActiveRequests) Add(
- ctx context.Context,
- incr int64,
- requestMethod RequestMethodAttr,
- urlScheme string,
- attrs ...attribute.KeyValue,
-) {
- if len(attrs) == 0 {
- m.Int64UpDownCounter.Add(ctx, incr)
- return
- }
-
- o := addOptPool.Get().(*[]metric.AddOption)
- defer func() {
- *o = (*o)[:0]
- addOptPool.Put(o)
- }()
-
- *o = append(
- *o,
- metric.WithAttributes(
- append(
- attrs,
- attribute.String("http.request.method", string(requestMethod)),
- attribute.String("url.scheme", urlScheme),
- )...,
- ),
- )
-
- m.Int64UpDownCounter.Add(ctx, incr, *o...)
-}
-
-// AddSet adds incr to the existing count for set.
-func (m ServerActiveRequests) AddSet(ctx context.Context, incr int64, set attribute.Set) {
- if set.Len() == 0 {
- m.Int64UpDownCounter.Add(ctx, incr)
- return
- }
-
- o := addOptPool.Get().(*[]metric.AddOption)
- defer func() {
- *o = (*o)[:0]
- addOptPool.Put(o)
- }()
-
- *o = append(*o, metric.WithAttributeSet(set))
- m.Int64UpDownCounter.Add(ctx, incr, *o...)
-}
-
-// AttrServerAddress returns an optional attribute for the "server.address"
-// semantic convention. It represents the name of the local HTTP server that
-// received the request.
-func (ServerActiveRequests) AttrServerAddress(val string) attribute.KeyValue {
- return attribute.String("server.address", val)
-}
-
-// AttrServerPort returns an optional attribute for the "server.port" semantic
-// convention. It represents the port of the local HTTP server that received the
-// request.
-func (ServerActiveRequests) AttrServerPort(val int) attribute.KeyValue {
- return attribute.Int("server.port", val)
-}
-
-// ServerRequestBodySize is an instrument used to record metric values conforming
-// to the "http.server.request.body.size" semantic conventions. It represents the
-// size of HTTP server request bodies.
-type ServerRequestBodySize struct {
- metric.Int64Histogram
-}
-
-var newServerRequestBodySizeOpts = []metric.Int64HistogramOption{
- metric.WithDescription("Size of HTTP server request bodies."),
- metric.WithUnit("By"),
-}
-
-// NewServerRequestBodySize returns a new ServerRequestBodySize instrument.
-func NewServerRequestBodySize(
- m metric.Meter,
- opt ...metric.Int64HistogramOption,
-) (ServerRequestBodySize, error) {
- // Check if the meter is nil.
- if m == nil {
- return ServerRequestBodySize{noop.Int64Histogram{}}, nil
- }
-
- if len(opt) == 0 {
- opt = newServerRequestBodySizeOpts
- } else {
- opt = append(opt, newServerRequestBodySizeOpts...)
- }
-
- i, err := m.Int64Histogram(
- "http.server.request.body.size",
- opt...,
- )
- if err != nil {
- return ServerRequestBodySize{noop.Int64Histogram{}}, err
- }
- return ServerRequestBodySize{i}, nil
-}
-
-// Inst returns the underlying metric instrument.
-func (m ServerRequestBodySize) Inst() metric.Int64Histogram {
- return m.Int64Histogram
-}
-
-// Name returns the semantic convention name of the instrument.
-func (ServerRequestBodySize) Name() string {
- return "http.server.request.body.size"
-}
-
-// Unit returns the semantic convention unit of the instrument
-func (ServerRequestBodySize) Unit() string {
- return "By"
-}
-
-// Description returns the semantic convention description of the instrument
-func (ServerRequestBodySize) Description() string {
- return "Size of HTTP server request bodies."
-}
-
-// Record records val to the current distribution for attrs.
-//
-// The requestMethod is the HTTP request method.
-//
-// The urlScheme is the the [URI scheme] component identifying the used protocol.
-//
-// All additional attrs passed are included in the recorded value.
-//
-// [URI scheme]: https://www.rfc-editor.org/rfc/rfc3986#section-3.1
-//
-// The size of the request payload body in bytes. This is the number of bytes
-// transferred excluding headers and is often, but not always, present as the
-// [Content-Length] header. For requests using transport encoding, this should be
-// the compressed size.
-//
-// [Content-Length]: https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length
-func (m ServerRequestBodySize) Record(
- ctx context.Context,
- val int64,
- requestMethod RequestMethodAttr,
- urlScheme string,
- attrs ...attribute.KeyValue,
-) {
- if len(attrs) == 0 {
- m.Int64Histogram.Record(ctx, val)
- return
- }
-
- o := recOptPool.Get().(*[]metric.RecordOption)
- defer func() {
- *o = (*o)[:0]
- recOptPool.Put(o)
- }()
-
- *o = append(
- *o,
- metric.WithAttributes(
- append(
- attrs,
- attribute.String("http.request.method", string(requestMethod)),
- attribute.String("url.scheme", urlScheme),
- )...,
- ),
- )
-
- m.Int64Histogram.Record(ctx, val, *o...)
-}
-
-// RecordSet records val to the current distribution for set.
-//
-// The size of the request payload body in bytes. This is the number of bytes
-// transferred excluding headers and is often, but not always, present as the
-// [Content-Length] header. For requests using transport encoding, this should be
-// the compressed size.
-//
-// [Content-Length]: https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length
-func (m ServerRequestBodySize) RecordSet(ctx context.Context, val int64, set attribute.Set) {
- if set.Len() == 0 {
- m.Int64Histogram.Record(ctx, val)
- return
- }
-
- o := recOptPool.Get().(*[]metric.RecordOption)
- defer func() {
- *o = (*o)[:0]
- recOptPool.Put(o)
- }()
-
- *o = append(*o, metric.WithAttributeSet(set))
- m.Int64Histogram.Record(ctx, val, *o...)
-}
-
-// AttrErrorType returns an optional attribute for the "error.type" semantic
-// convention. It represents the describes a class of error the operation ended
-// with.
-func (ServerRequestBodySize) AttrErrorType(val ErrorTypeAttr) attribute.KeyValue {
- return attribute.String("error.type", string(val))
-}
-
-// AttrResponseStatusCode returns an optional attribute for the
-// "http.response.status_code" semantic convention. It represents the
-// [HTTP response status code].
-//
-// [HTTP response status code]: https://tools.ietf.org/html/rfc7231#section-6
-func (ServerRequestBodySize) AttrResponseStatusCode(val int) attribute.KeyValue {
- return attribute.Int("http.response.status_code", val)
-}
-
-// AttrRoute returns an optional attribute for the "http.route" semantic
-// convention. It represents the matched route template for the request. This
-// MUST be low-cardinality and include all static path segments, with dynamic
-// path segments represented with placeholders.
-func (ServerRequestBodySize) AttrRoute(val string) attribute.KeyValue {
- return attribute.String("http.route", val)
-}
-
-// AttrNetworkProtocolName returns an optional attribute for the
-// "network.protocol.name" semantic convention. It represents the
-// [OSI application layer] or non-OSI equivalent.
-//
-// [OSI application layer]: https://wikipedia.org/wiki/Application_layer
-func (ServerRequestBodySize) AttrNetworkProtocolName(val string) attribute.KeyValue {
- return attribute.String("network.protocol.name", val)
-}
-
-// AttrNetworkProtocolVersion returns an optional attribute for the
-// "network.protocol.version" semantic convention. It represents the actual
-// version of the protocol used for network communication.
-func (ServerRequestBodySize) AttrNetworkProtocolVersion(val string) attribute.KeyValue {
- return attribute.String("network.protocol.version", val)
-}
-
-// AttrServerAddress returns an optional attribute for the "server.address"
-// semantic convention. It represents the name of the local HTTP server that
-// received the request.
-func (ServerRequestBodySize) AttrServerAddress(val string) attribute.KeyValue {
- return attribute.String("server.address", val)
-}
-
-// AttrServerPort returns an optional attribute for the "server.port" semantic
-// convention. It represents the port of the local HTTP server that received the
-// request.
-func (ServerRequestBodySize) AttrServerPort(val int) attribute.KeyValue {
- return attribute.Int("server.port", val)
-}
-
-// AttrUserAgentSyntheticType returns an optional attribute for the
-// "user_agent.synthetic.type" semantic convention. It represents the specifies
-// the category of synthetic traffic, such as tests or bots.
-func (ServerRequestBodySize) AttrUserAgentSyntheticType(val UserAgentSyntheticTypeAttr) attribute.KeyValue {
- return attribute.String("user_agent.synthetic.type", string(val))
-}
-
-// ServerRequestDuration is an instrument used to record metric values conforming
-// to the "http.server.request.duration" semantic conventions. It represents the
-// duration of HTTP server requests.
-type ServerRequestDuration struct {
- metric.Float64Histogram
-}
-
-var newServerRequestDurationOpts = []metric.Float64HistogramOption{
- metric.WithDescription("Duration of HTTP server requests."),
- metric.WithUnit("s"),
-}
-
-// NewServerRequestDuration returns a new ServerRequestDuration instrument.
-func NewServerRequestDuration(
- m metric.Meter,
- opt ...metric.Float64HistogramOption,
-) (ServerRequestDuration, error) {
- // Check if the meter is nil.
- if m == nil {
- return ServerRequestDuration{noop.Float64Histogram{}}, nil
- }
-
- if len(opt) == 0 {
- opt = newServerRequestDurationOpts
- } else {
- opt = append(opt, newServerRequestDurationOpts...)
- }
-
- i, err := m.Float64Histogram(
- "http.server.request.duration",
- opt...,
- )
- if err != nil {
- return ServerRequestDuration{noop.Float64Histogram{}}, err
- }
- return ServerRequestDuration{i}, nil
-}
-
-// Inst returns the underlying metric instrument.
-func (m ServerRequestDuration) Inst() metric.Float64Histogram {
- return m.Float64Histogram
-}
-
-// Name returns the semantic convention name of the instrument.
-func (ServerRequestDuration) Name() string {
- return "http.server.request.duration"
-}
-
-// Unit returns the semantic convention unit of the instrument
-func (ServerRequestDuration) Unit() string {
- return "s"
-}
-
-// Description returns the semantic convention description of the instrument
-func (ServerRequestDuration) Description() string {
- return "Duration of HTTP server requests."
-}
-
-// Record records val to the current distribution for attrs.
-//
-// The requestMethod is the HTTP request method.
-//
-// The urlScheme is the the [URI scheme] component identifying the used protocol.
-//
-// All additional attrs passed are included in the recorded value.
-//
-// [URI scheme]: https://www.rfc-editor.org/rfc/rfc3986#section-3.1
-func (m ServerRequestDuration) Record(
- ctx context.Context,
- val float64,
- requestMethod RequestMethodAttr,
- urlScheme string,
- attrs ...attribute.KeyValue,
-) {
- if len(attrs) == 0 {
- m.Float64Histogram.Record(ctx, val)
- return
- }
-
- o := recOptPool.Get().(*[]metric.RecordOption)
- defer func() {
- *o = (*o)[:0]
- recOptPool.Put(o)
- }()
-
- *o = append(
- *o,
- metric.WithAttributes(
- append(
- attrs,
- attribute.String("http.request.method", string(requestMethod)),
- attribute.String("url.scheme", urlScheme),
- )...,
- ),
- )
-
- m.Float64Histogram.Record(ctx, val, *o...)
-}
-
-// RecordSet records val to the current distribution for set.
-func (m ServerRequestDuration) RecordSet(ctx context.Context, val float64, set attribute.Set) {
- if set.Len() == 0 {
- m.Float64Histogram.Record(ctx, val)
- return
- }
-
- o := recOptPool.Get().(*[]metric.RecordOption)
- defer func() {
- *o = (*o)[:0]
- recOptPool.Put(o)
- }()
-
- *o = append(*o, metric.WithAttributeSet(set))
- m.Float64Histogram.Record(ctx, val, *o...)
-}
-
-// AttrErrorType returns an optional attribute for the "error.type" semantic
-// convention. It represents the describes a class of error the operation ended
-// with.
-func (ServerRequestDuration) AttrErrorType(val ErrorTypeAttr) attribute.KeyValue {
- return attribute.String("error.type", string(val))
-}
-
-// AttrResponseStatusCode returns an optional attribute for the
-// "http.response.status_code" semantic convention. It represents the
-// [HTTP response status code].
-//
-// [HTTP response status code]: https://tools.ietf.org/html/rfc7231#section-6
-func (ServerRequestDuration) AttrResponseStatusCode(val int) attribute.KeyValue {
- return attribute.Int("http.response.status_code", val)
-}
-
-// AttrRoute returns an optional attribute for the "http.route" semantic
-// convention. It represents the matched route template for the request. This
-// MUST be low-cardinality and include all static path segments, with dynamic
-// path segments represented with placeholders.
-func (ServerRequestDuration) AttrRoute(val string) attribute.KeyValue {
- return attribute.String("http.route", val)
-}
-
-// AttrNetworkProtocolName returns an optional attribute for the
-// "network.protocol.name" semantic convention. It represents the
-// [OSI application layer] or non-OSI equivalent.
-//
-// [OSI application layer]: https://wikipedia.org/wiki/Application_layer
-func (ServerRequestDuration) AttrNetworkProtocolName(val string) attribute.KeyValue {
- return attribute.String("network.protocol.name", val)
-}
-
-// AttrNetworkProtocolVersion returns an optional attribute for the
-// "network.protocol.version" semantic convention. It represents the actual
-// version of the protocol used for network communication.
-func (ServerRequestDuration) AttrNetworkProtocolVersion(val string) attribute.KeyValue {
- return attribute.String("network.protocol.version", val)
-}
-
-// AttrServerAddress returns an optional attribute for the "server.address"
-// semantic convention. It represents the name of the local HTTP server that
-// received the request.
-func (ServerRequestDuration) AttrServerAddress(val string) attribute.KeyValue {
- return attribute.String("server.address", val)
-}
-
-// AttrServerPort returns an optional attribute for the "server.port" semantic
-// convention. It represents the port of the local HTTP server that received the
-// request.
-func (ServerRequestDuration) AttrServerPort(val int) attribute.KeyValue {
- return attribute.Int("server.port", val)
-}
-
-// AttrUserAgentSyntheticType returns an optional attribute for the
-// "user_agent.synthetic.type" semantic convention. It represents the specifies
-// the category of synthetic traffic, such as tests or bots.
-func (ServerRequestDuration) AttrUserAgentSyntheticType(val UserAgentSyntheticTypeAttr) attribute.KeyValue {
- return attribute.String("user_agent.synthetic.type", string(val))
-}
-
-// ServerResponseBodySize is an instrument used to record metric values
-// conforming to the "http.server.response.body.size" semantic conventions. It
-// represents the size of HTTP server response bodies.
-type ServerResponseBodySize struct {
- metric.Int64Histogram
-}
-
-var newServerResponseBodySizeOpts = []metric.Int64HistogramOption{
- metric.WithDescription("Size of HTTP server response bodies."),
- metric.WithUnit("By"),
-}
-
-// NewServerResponseBodySize returns a new ServerResponseBodySize instrument.
-func NewServerResponseBodySize(
- m metric.Meter,
- opt ...metric.Int64HistogramOption,
-) (ServerResponseBodySize, error) {
- // Check if the meter is nil.
- if m == nil {
- return ServerResponseBodySize{noop.Int64Histogram{}}, nil
- }
-
- if len(opt) == 0 {
- opt = newServerResponseBodySizeOpts
- } else {
- opt = append(opt, newServerResponseBodySizeOpts...)
- }
-
- i, err := m.Int64Histogram(
- "http.server.response.body.size",
- opt...,
- )
- if err != nil {
- return ServerResponseBodySize{noop.Int64Histogram{}}, err
- }
- return ServerResponseBodySize{i}, nil
-}
-
-// Inst returns the underlying metric instrument.
-func (m ServerResponseBodySize) Inst() metric.Int64Histogram {
- return m.Int64Histogram
-}
-
-// Name returns the semantic convention name of the instrument.
-func (ServerResponseBodySize) Name() string {
- return "http.server.response.body.size"
-}
-
-// Unit returns the semantic convention unit of the instrument
-func (ServerResponseBodySize) Unit() string {
- return "By"
-}
-
-// Description returns the semantic convention description of the instrument
-func (ServerResponseBodySize) Description() string {
- return "Size of HTTP server response bodies."
-}
-
-// Record records val to the current distribution for attrs.
-//
-// The requestMethod is the HTTP request method.
-//
-// The urlScheme is the the [URI scheme] component identifying the used protocol.
-//
-// All additional attrs passed are included in the recorded value.
-//
-// [URI scheme]: https://www.rfc-editor.org/rfc/rfc3986#section-3.1
-//
-// The size of the response payload body in bytes. This is the number of bytes
-// transferred excluding headers and is often, but not always, present as the
-// [Content-Length] header. For requests using transport encoding, this should be
-// the compressed size.
-//
-// [Content-Length]: https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length
-func (m ServerResponseBodySize) Record(
- ctx context.Context,
- val int64,
- requestMethod RequestMethodAttr,
- urlScheme string,
- attrs ...attribute.KeyValue,
-) {
- if len(attrs) == 0 {
- m.Int64Histogram.Record(ctx, val)
- return
- }
-
- o := recOptPool.Get().(*[]metric.RecordOption)
- defer func() {
- *o = (*o)[:0]
- recOptPool.Put(o)
- }()
-
- *o = append(
- *o,
- metric.WithAttributes(
- append(
- attrs,
- attribute.String("http.request.method", string(requestMethod)),
- attribute.String("url.scheme", urlScheme),
- )...,
- ),
- )
-
- m.Int64Histogram.Record(ctx, val, *o...)
-}
-
-// RecordSet records val to the current distribution for set.
-//
-// The size of the response payload body in bytes. This is the number of bytes
-// transferred excluding headers and is often, but not always, present as the
-// [Content-Length] header. For requests using transport encoding, this should be
-// the compressed size.
-//
-// [Content-Length]: https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length
-func (m ServerResponseBodySize) RecordSet(ctx context.Context, val int64, set attribute.Set) {
- if set.Len() == 0 {
- m.Int64Histogram.Record(ctx, val)
- return
- }
-
- o := recOptPool.Get().(*[]metric.RecordOption)
- defer func() {
- *o = (*o)[:0]
- recOptPool.Put(o)
- }()
-
- *o = append(*o, metric.WithAttributeSet(set))
- m.Int64Histogram.Record(ctx, val, *o...)
-}
-
-// AttrErrorType returns an optional attribute for the "error.type" semantic
-// convention. It represents the describes a class of error the operation ended
-// with.
-func (ServerResponseBodySize) AttrErrorType(val ErrorTypeAttr) attribute.KeyValue {
- return attribute.String("error.type", string(val))
-}
-
-// AttrResponseStatusCode returns an optional attribute for the
-// "http.response.status_code" semantic convention. It represents the
-// [HTTP response status code].
-//
-// [HTTP response status code]: https://tools.ietf.org/html/rfc7231#section-6
-func (ServerResponseBodySize) AttrResponseStatusCode(val int) attribute.KeyValue {
- return attribute.Int("http.response.status_code", val)
-}
-
-// AttrRoute returns an optional attribute for the "http.route" semantic
-// convention. It represents the matched route template for the request. This
-// MUST be low-cardinality and include all static path segments, with dynamic
-// path segments represented with placeholders.
-func (ServerResponseBodySize) AttrRoute(val string) attribute.KeyValue {
- return attribute.String("http.route", val)
-}
-
-// AttrNetworkProtocolName returns an optional attribute for the
-// "network.protocol.name" semantic convention. It represents the
-// [OSI application layer] or non-OSI equivalent.
-//
-// [OSI application layer]: https://wikipedia.org/wiki/Application_layer
-func (ServerResponseBodySize) AttrNetworkProtocolName(val string) attribute.KeyValue {
- return attribute.String("network.protocol.name", val)
-}
-
-// AttrNetworkProtocolVersion returns an optional attribute for the
-// "network.protocol.version" semantic convention. It represents the actual
-// version of the protocol used for network communication.
-func (ServerResponseBodySize) AttrNetworkProtocolVersion(val string) attribute.KeyValue {
- return attribute.String("network.protocol.version", val)
-}
-
-// AttrServerAddress returns an optional attribute for the "server.address"
-// semantic convention. It represents the name of the local HTTP server that
-// received the request.
-func (ServerResponseBodySize) AttrServerAddress(val string) attribute.KeyValue {
- return attribute.String("server.address", val)
-}
-
-// AttrServerPort returns an optional attribute for the "server.port" semantic
-// convention. It represents the port of the local HTTP server that received the
-// request.
-func (ServerResponseBodySize) AttrServerPort(val int) attribute.KeyValue {
- return attribute.Int("server.port", val)
-}
-
-// AttrUserAgentSyntheticType returns an optional attribute for the
-// "user_agent.synthetic.type" semantic convention. It represents the specifies
-// the category of synthetic traffic, such as tests or bots.
-func (ServerResponseBodySize) AttrUserAgentSyntheticType(val UserAgentSyntheticTypeAttr) attribute.KeyValue {
- return attribute.String("user_agent.synthetic.type", string(val))
-}
diff --git a/vendor/go.opentelemetry.io/otel/semconv/v1.39.0/otelconv/metric.go b/vendor/go.opentelemetry.io/otel/semconv/v1.39.0/otelconv/metric.go
index 901da8698..2ec60d9cb 100644
--- a/vendor/go.opentelemetry.io/otel/semconv/v1.39.0/otelconv/metric.go
+++ b/vendor/go.opentelemetry.io/otel/semconv/v1.39.0/otelconv/metric.go
@@ -26,11 +26,9 @@ var (
// with.
type ErrorTypeAttr string
-var (
- // ErrorTypeOther is a fallback error value to be used when the instrumentation
- // doesn't define a custom value.
- ErrorTypeOther ErrorTypeAttr = "_OTHER"
-)
+// ErrorTypeOther is a fallback error value to be used when the instrumentation
+// doesn't define a custom value.
+var ErrorTypeOther ErrorTypeAttr = "_OTHER"
// ComponentTypeAttr is an attribute conforming to the otel.component.type
// semantic conventions. It represents a name identifying the type of the
diff --git a/vendor/go.opentelemetry.io/otel/semconv/v1.40.0/MIGRATION.md b/vendor/go.opentelemetry.io/otel/semconv/v1.40.0/MIGRATION.md
new file mode 100644
index 000000000..e246b1692
--- /dev/null
+++ b/vendor/go.opentelemetry.io/otel/semconv/v1.40.0/MIGRATION.md
@@ -0,0 +1,27 @@
+
+# Migration from v1.39.0 to v1.40.0
+
+The `go.opentelemetry.io/otel/semconv/v1.40.0` package should be a drop-in replacement for `go.opentelemetry.io/otel/semconv/v1.39.0` with the following exceptions.
+
+## Removed
+
+The following declarations have been removed.
+Refer to the [OpenTelemetry Semantic Conventions documentation] for deprecation instructions.
+
+If the type is not listed in the documentation as deprecated, it has been removed in this version due to lack of applicability or use.
+If you use any of these non-deprecated declarations in your Go application, please [open an issue] describing your use-case.
+
+- `ErrorMessage`
+- `ErrorMessageKey`
+- `RPCMessageCompressedSize`
+- `RPCMessageCompressedSizeKey`
+- `RPCMessageID`
+- `RPCMessageIDKey`
+- `RPCMessageTypeKey`
+- `RPCMessageTypeReceived`
+- `RPCMessageTypeSent`
+- `RPCMessageUncompressedSize`
+- `RPCMessageUncompressedSizeKey`
+
+[OpenTelemetry Semantic Conventions documentation]: https://github.com/open-telemetry/semantic-conventions
+[open an issue]: https://github.com/open-telemetry/opentelemetry-go/issues/new?template=Blank+issue
diff --git a/vendor/go.opentelemetry.io/otel/semconv/v1.40.0/README.md b/vendor/go.opentelemetry.io/otel/semconv/v1.40.0/README.md
new file mode 100644
index 000000000..c51b7fb7b
--- /dev/null
+++ b/vendor/go.opentelemetry.io/otel/semconv/v1.40.0/README.md
@@ -0,0 +1,3 @@
+# Semconv v1.40.0
+
+[](https://pkg.go.dev/go.opentelemetry.io/otel/semconv/v1.40.0)
diff --git a/vendor/go.opentelemetry.io/otel/semconv/v1.40.0/attribute_group.go b/vendor/go.opentelemetry.io/otel/semconv/v1.40.0/attribute_group.go
new file mode 100644
index 000000000..c5d40e518
--- /dev/null
+++ b/vendor/go.opentelemetry.io/otel/semconv/v1.40.0/attribute_group.go
@@ -0,0 +1,16865 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+// Code generated from semantic convention specification. DO NOT EDIT.
+
+package semconv // import "go.opentelemetry.io/otel/semconv/v1.40.0"
+
+import "go.opentelemetry.io/otel/attribute"
+
+// Namespace: android
+const (
+ // AndroidAppStateKey is the attribute Key conforming to the "android.app.state"
+ // semantic conventions. It represents the this attribute represents the state
+ // of the application.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "created"
+ // Note: The Android lifecycle states are defined in
+ // [Activity lifecycle callbacks], and from which the `OS identifiers` are
+ // derived.
+ //
+ // [Activity lifecycle callbacks]: https://developer.android.com/guide/components/activities/activity-lifecycle#lc
+ AndroidAppStateKey = attribute.Key("android.app.state")
+
+ // AndroidOSAPILevelKey is the attribute Key conforming to the
+ // "android.os.api_level" semantic conventions. It represents the uniquely
+ // identifies the framework API revision offered by a version (`os.version`) of
+ // the android operating system. More information can be found in the
+ // [Android API levels documentation].
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "33", "32"
+ //
+ // [Android API levels documentation]: https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels
+ AndroidOSAPILevelKey = attribute.Key("android.os.api_level")
+)
+
+// AndroidOSAPILevel returns an attribute KeyValue conforming to the
+// "android.os.api_level" semantic conventions. It represents the uniquely
+// identifies the framework API revision offered by a version (`os.version`) of
+// the android operating system. More information can be found in the
+// [Android API levels documentation].
+//
+// [Android API levels documentation]: https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels
+func AndroidOSAPILevel(val string) attribute.KeyValue {
+ return AndroidOSAPILevelKey.String(val)
+}
+
+// Enum values for android.app.state
+var (
+ // Any time before Activity.onResume() or, if the app has no Activity,
+ // Context.startService() has been called in the app for the first time.
+ //
+ // Stability: development
+ AndroidAppStateCreated = AndroidAppStateKey.String("created")
+ // Any time after Activity.onPause() or, if the app has no Activity,
+ // Context.stopService() has been called when the app was in the foreground
+ // state.
+ //
+ // Stability: development
+ AndroidAppStateBackground = AndroidAppStateKey.String("background")
+ // Any time after Activity.onResume() or, if the app has no Activity,
+ // Context.startService() has been called when the app was in either the created
+ // or background states.
+ //
+ // Stability: development
+ AndroidAppStateForeground = AndroidAppStateKey.String("foreground")
+)
+
+// Namespace: app
+const (
+ // AppBuildIDKey is the attribute Key conforming to the "app.build_id" semantic
+ // conventions. It represents the unique identifier for a particular build or
+ // compilation of the application.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "6cff0a7e-cefc-4668-96f5-1273d8b334d0",
+ // "9f2b833506aa6973a92fde9733e6271f", "my-app-1.0.0-code-123"
+ AppBuildIDKey = attribute.Key("app.build_id")
+
+ // AppInstallationIDKey is the attribute Key conforming to the
+ // "app.installation.id" semantic conventions. It represents a unique identifier
+ // representing the installation of an application on a specific device.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "2ab2916d-a51f-4ac8-80ee-45ac31a28092"
+ // Note: Its value SHOULD persist across launches of the same application
+ // installation, including through application upgrades.
+ // It SHOULD change if the application is uninstalled or if all applications of
+ // the vendor are uninstalled.
+ // Additionally, users might be able to reset this value (e.g. by clearing
+ // application data).
+ // If an app is installed multiple times on the same device (e.g. in different
+ // accounts on Android), each `app.installation.id` SHOULD have a different
+ // value.
+ // If multiple OpenTelemetry SDKs are used within the same application, they
+ // SHOULD use the same value for `app.installation.id`.
+ // Hardware IDs (e.g. serial number, IMEI, MAC address) MUST NOT be used as the
+ // `app.installation.id`.
+ //
+ // For iOS, this value SHOULD be equal to the [vendor identifier].
+ //
+ // For Android, examples of `app.installation.id` implementations include:
+ //
+ // - [Firebase Installation ID].
+ // - A globally unique UUID which is persisted across sessions in your
+ // application.
+ // - [App set ID].
+ // - [`Settings.getString(Settings.Secure.ANDROID_ID)`].
+ //
+ // More information about Android identifier best practices can be found in the
+ // [Android user data IDs guide].
+ //
+ // [vendor identifier]: https://developer.apple.com/documentation/uikit/uidevice/identifierforvendor
+ // [Firebase Installation ID]: https://firebase.google.com/docs/projects/manage-installations
+ // [App set ID]: https://developer.android.com/identity/app-set-id
+ // [`Settings.getString(Settings.Secure.ANDROID_ID)`]: https://developer.android.com/reference/android/provider/Settings.Secure#ANDROID_ID
+ // [Android user data IDs guide]: https://developer.android.com/training/articles/user-data-ids
+ AppInstallationIDKey = attribute.Key("app.installation.id")
+
+ // AppJankFrameCountKey is the attribute Key conforming to the
+ // "app.jank.frame_count" semantic conventions. It represents a number of frame
+ // renders that experienced jank.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 9, 42
+ // Note: Depending on platform limitations, the value provided MAY be
+ // approximation.
+ AppJankFrameCountKey = attribute.Key("app.jank.frame_count")
+
+ // AppJankPeriodKey is the attribute Key conforming to the "app.jank.period"
+ // semantic conventions. It represents the time period, in seconds, for which
+ // this jank is being reported.
+ //
+ // Type: double
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 1.0, 5.0, 10.24
+ AppJankPeriodKey = attribute.Key("app.jank.period")
+
+ // AppJankThresholdKey is the attribute Key conforming to the
+ // "app.jank.threshold" semantic conventions. It represents the minimum
+ // rendering threshold for this jank, in seconds.
+ //
+ // Type: double
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 0.016, 0.7, 1.024
+ AppJankThresholdKey = attribute.Key("app.jank.threshold")
+
+ // AppScreenCoordinateXKey is the attribute Key conforming to the
+ // "app.screen.coordinate.x" semantic conventions. It represents the x
+ // (horizontal) coordinate of a screen coordinate, in screen pixels.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 0, 131
+ AppScreenCoordinateXKey = attribute.Key("app.screen.coordinate.x")
+
+ // AppScreenCoordinateYKey is the attribute Key conforming to the
+ // "app.screen.coordinate.y" semantic conventions. It represents the y
+ // (vertical) component of a screen coordinate, in screen pixels.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 12, 99
+ AppScreenCoordinateYKey = attribute.Key("app.screen.coordinate.y")
+
+ // AppScreenIDKey is the attribute Key conforming to the "app.screen.id"
+ // semantic conventions. It represents an identifier that uniquely
+ // differentiates this screen from other screens in the same application.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "f9bc787d-ff05-48ad-90e1-fca1d46130b3",
+ // "com.example.app.MainActivity", "com.example.shop.ProductDetailFragment",
+ // "MyApp.ProfileView", "MyApp.ProfileViewController"
+ // Note: A screen represents only the part of the device display drawn by the
+ // app. It typically contains multiple widgets or UI components and is larger in
+ // scope than individual widgets. Multiple screens can coexist on the same
+ // display simultaneously (e.g., split view on tablets).
+ AppScreenIDKey = attribute.Key("app.screen.id")
+
+ // AppScreenNameKey is the attribute Key conforming to the "app.screen.name"
+ // semantic conventions. It represents the name of an application screen.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "MainActivity", "ProductDetailFragment", "ProfileView",
+ // "ProfileViewController"
+ // Note: A screen represents only the part of the device display drawn by the
+ // app. It typically contains multiple widgets or UI components and is larger in
+ // scope than individual widgets. Multiple screens can coexist on the same
+ // display simultaneously (e.g., split view on tablets).
+ AppScreenNameKey = attribute.Key("app.screen.name")
+
+ // AppWidgetIDKey is the attribute Key conforming to the "app.widget.id"
+ // semantic conventions. It represents an identifier that uniquely
+ // differentiates this widget from other widgets in the same application.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "f9bc787d-ff05-48ad-90e1-fca1d46130b3", "submit_order_1829"
+ // Note: A widget is an application component, typically an on-screen visual GUI
+ // element.
+ AppWidgetIDKey = attribute.Key("app.widget.id")
+
+ // AppWidgetNameKey is the attribute Key conforming to the "app.widget.name"
+ // semantic conventions. It represents the name of an application widget.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "submit", "attack", "Clear Cart"
+ // Note: A widget is an application component, typically an on-screen visual GUI
+ // element.
+ AppWidgetNameKey = attribute.Key("app.widget.name")
+)
+
+// AppBuildID returns an attribute KeyValue conforming to the "app.build_id"
+// semantic conventions. It represents the unique identifier for a particular
+// build or compilation of the application.
+func AppBuildID(val string) attribute.KeyValue {
+ return AppBuildIDKey.String(val)
+}
+
+// AppInstallationID returns an attribute KeyValue conforming to the
+// "app.installation.id" semantic conventions. It represents a unique identifier
+// representing the installation of an application on a specific device.
+func AppInstallationID(val string) attribute.KeyValue {
+ return AppInstallationIDKey.String(val)
+}
+
+// AppJankFrameCount returns an attribute KeyValue conforming to the
+// "app.jank.frame_count" semantic conventions. It represents a number of frame
+// renders that experienced jank.
+func AppJankFrameCount(val int) attribute.KeyValue {
+ return AppJankFrameCountKey.Int(val)
+}
+
+// AppJankPeriod returns an attribute KeyValue conforming to the
+// "app.jank.period" semantic conventions. It represents the time period, in
+// seconds, for which this jank is being reported.
+func AppJankPeriod(val float64) attribute.KeyValue {
+ return AppJankPeriodKey.Float64(val)
+}
+
+// AppJankThreshold returns an attribute KeyValue conforming to the
+// "app.jank.threshold" semantic conventions. It represents the minimum rendering
+// threshold for this jank, in seconds.
+func AppJankThreshold(val float64) attribute.KeyValue {
+ return AppJankThresholdKey.Float64(val)
+}
+
+// AppScreenCoordinateX returns an attribute KeyValue conforming to the
+// "app.screen.coordinate.x" semantic conventions. It represents the x
+// (horizontal) coordinate of a screen coordinate, in screen pixels.
+func AppScreenCoordinateX(val int) attribute.KeyValue {
+ return AppScreenCoordinateXKey.Int(val)
+}
+
+// AppScreenCoordinateY returns an attribute KeyValue conforming to the
+// "app.screen.coordinate.y" semantic conventions. It represents the y (vertical)
+// component of a screen coordinate, in screen pixels.
+func AppScreenCoordinateY(val int) attribute.KeyValue {
+ return AppScreenCoordinateYKey.Int(val)
+}
+
+// AppScreenID returns an attribute KeyValue conforming to the "app.screen.id"
+// semantic conventions. It represents an identifier that uniquely differentiates
+// this screen from other screens in the same application.
+func AppScreenID(val string) attribute.KeyValue {
+ return AppScreenIDKey.String(val)
+}
+
+// AppScreenName returns an attribute KeyValue conforming to the
+// "app.screen.name" semantic conventions. It represents the name of an
+// application screen.
+func AppScreenName(val string) attribute.KeyValue {
+ return AppScreenNameKey.String(val)
+}
+
+// AppWidgetID returns an attribute KeyValue conforming to the "app.widget.id"
+// semantic conventions. It represents an identifier that uniquely differentiates
+// this widget from other widgets in the same application.
+func AppWidgetID(val string) attribute.KeyValue {
+ return AppWidgetIDKey.String(val)
+}
+
+// AppWidgetName returns an attribute KeyValue conforming to the
+// "app.widget.name" semantic conventions. It represents the name of an
+// application widget.
+func AppWidgetName(val string) attribute.KeyValue {
+ return AppWidgetNameKey.String(val)
+}
+
+// Namespace: artifact
+const (
+ // ArtifactAttestationFilenameKey is the attribute Key conforming to the
+ // "artifact.attestation.filename" semantic conventions. It represents the
+ // provenance filename of the built attestation which directly relates to the
+ // build artifact filename. This filename SHOULD accompany the artifact at
+ // publish time. See the [SLSA Relationship] specification for more information.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "golang-binary-amd64-v0.1.0.attestation",
+ // "docker-image-amd64-v0.1.0.intoto.json1", "release-1.tar.gz.attestation",
+ // "file-name-package.tar.gz.intoto.json1"
+ //
+ // [SLSA Relationship]: https://slsa.dev/spec/v1.0/distributing-provenance#relationship-between-artifacts-and-attestations
+ ArtifactAttestationFilenameKey = attribute.Key("artifact.attestation.filename")
+
+ // ArtifactAttestationHashKey is the attribute Key conforming to the
+ // "artifact.attestation.hash" semantic conventions. It represents the full
+ // [hash value (see glossary)], of the built attestation. Some envelopes in the
+ // [software attestation space] also refer to this as the **digest**.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "1b31dfcd5b7f9267bf2ff47651df1cfb9147b9e4df1f335accf65b4cda498408"
+ //
+ // [hash value (see glossary)]: https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-5.pdf
+ // [software attestation space]: https://github.com/in-toto/attestation/tree/main/spec
+ ArtifactAttestationHashKey = attribute.Key("artifact.attestation.hash")
+
+ // ArtifactAttestationIDKey is the attribute Key conforming to the
+ // "artifact.attestation.id" semantic conventions. It represents the id of the
+ // build [software attestation].
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "123"
+ //
+ // [software attestation]: https://slsa.dev/attestation-model
+ ArtifactAttestationIDKey = attribute.Key("artifact.attestation.id")
+
+ // ArtifactFilenameKey is the attribute Key conforming to the
+ // "artifact.filename" semantic conventions. It represents the human readable
+ // file name of the artifact, typically generated during build and release
+ // processes. Often includes the package name and version in the file name.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "golang-binary-amd64-v0.1.0", "docker-image-amd64-v0.1.0",
+ // "release-1.tar.gz", "file-name-package.tar.gz"
+ // Note: This file name can also act as the [Package Name]
+ // in cases where the package ecosystem maps accordingly.
+ // Additionally, the artifact [can be published]
+ // for others, but that is not a guarantee.
+ //
+ // [Package Name]: https://slsa.dev/spec/v1.0/terminology#package-model
+ // [can be published]: https://slsa.dev/spec/v1.0/terminology#software-supply-chain
+ ArtifactFilenameKey = attribute.Key("artifact.filename")
+
+ // ArtifactHashKey is the attribute Key conforming to the "artifact.hash"
+ // semantic conventions. It represents the full [hash value (see glossary)],
+ // often found in checksum.txt on a release of the artifact and used to verify
+ // package integrity.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "9ff4c52759e2c4ac70b7d517bc7fcdc1cda631ca0045271ddd1b192544f8a3e9"
+ // Note: The specific algorithm used to create the cryptographic hash value is
+ // not defined. In situations where an artifact has multiple
+ // cryptographic hashes, it is up to the implementer to choose which
+ // hash value to set here; this should be the most secure hash algorithm
+ // that is suitable for the situation and consistent with the
+ // corresponding attestation. The implementer can then provide the other
+ // hash values through an additional set of attribute extensions as they
+ // deem necessary.
+ //
+ // [hash value (see glossary)]: https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-5.pdf
+ ArtifactHashKey = attribute.Key("artifact.hash")
+
+ // ArtifactPurlKey is the attribute Key conforming to the "artifact.purl"
+ // semantic conventions. It represents the [Package URL] of the
+ // [package artifact] provides a standard way to identify and locate the
+ // packaged artifact.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "pkg:github/package-url/purl-spec@1209109710924",
+ // "pkg:npm/foo@12.12.3"
+ //
+ // [Package URL]: https://github.com/package-url/purl-spec
+ // [package artifact]: https://slsa.dev/spec/v1.0/terminology#package-model
+ ArtifactPurlKey = attribute.Key("artifact.purl")
+
+ // ArtifactVersionKey is the attribute Key conforming to the "artifact.version"
+ // semantic conventions. It represents the version of the artifact.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "v0.1.0", "1.2.1", "122691-build"
+ ArtifactVersionKey = attribute.Key("artifact.version")
+)
+
+// ArtifactAttestationFilename returns an attribute KeyValue conforming to the
+// "artifact.attestation.filename" semantic conventions. It represents the
+// provenance filename of the built attestation which directly relates to the
+// build artifact filename. This filename SHOULD accompany the artifact at
+// publish time. See the [SLSA Relationship] specification for more information.
+//
+// [SLSA Relationship]: https://slsa.dev/spec/v1.0/distributing-provenance#relationship-between-artifacts-and-attestations
+func ArtifactAttestationFilename(val string) attribute.KeyValue {
+ return ArtifactAttestationFilenameKey.String(val)
+}
+
+// ArtifactAttestationHash returns an attribute KeyValue conforming to the
+// "artifact.attestation.hash" semantic conventions. It represents the full
+// [hash value (see glossary)], of the built attestation. Some envelopes in the
+// [software attestation space] also refer to this as the **digest**.
+//
+// [hash value (see glossary)]: https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-5.pdf
+// [software attestation space]: https://github.com/in-toto/attestation/tree/main/spec
+func ArtifactAttestationHash(val string) attribute.KeyValue {
+ return ArtifactAttestationHashKey.String(val)
+}
+
+// ArtifactAttestationID returns an attribute KeyValue conforming to the
+// "artifact.attestation.id" semantic conventions. It represents the id of the
+// build [software attestation].
+//
+// [software attestation]: https://slsa.dev/attestation-model
+func ArtifactAttestationID(val string) attribute.KeyValue {
+ return ArtifactAttestationIDKey.String(val)
+}
+
+// ArtifactFilename returns an attribute KeyValue conforming to the
+// "artifact.filename" semantic conventions. It represents the human readable
+// file name of the artifact, typically generated during build and release
+// processes. Often includes the package name and version in the file name.
+func ArtifactFilename(val string) attribute.KeyValue {
+ return ArtifactFilenameKey.String(val)
+}
+
+// ArtifactHash returns an attribute KeyValue conforming to the "artifact.hash"
+// semantic conventions. It represents the full [hash value (see glossary)],
+// often found in checksum.txt on a release of the artifact and used to verify
+// package integrity.
+//
+// [hash value (see glossary)]: https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-5.pdf
+func ArtifactHash(val string) attribute.KeyValue {
+ return ArtifactHashKey.String(val)
+}
+
+// ArtifactPurl returns an attribute KeyValue conforming to the "artifact.purl"
+// semantic conventions. It represents the [Package URL] of the
+// [package artifact] provides a standard way to identify and locate the packaged
+// artifact.
+//
+// [Package URL]: https://github.com/package-url/purl-spec
+// [package artifact]: https://slsa.dev/spec/v1.0/terminology#package-model
+func ArtifactPurl(val string) attribute.KeyValue {
+ return ArtifactPurlKey.String(val)
+}
+
+// ArtifactVersion returns an attribute KeyValue conforming to the
+// "artifact.version" semantic conventions. It represents the version of the
+// artifact.
+func ArtifactVersion(val string) attribute.KeyValue {
+ return ArtifactVersionKey.String(val)
+}
+
+// Namespace: aws
+const (
+ // AWSBedrockGuardrailIDKey is the attribute Key conforming to the
+ // "aws.bedrock.guardrail.id" semantic conventions. It represents the unique
+ // identifier of the AWS Bedrock Guardrail. A [guardrail] helps safeguard and
+ // prevent unwanted behavior from model responses or user messages.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "sgi5gkybzqak"
+ //
+ // [guardrail]: https://docs.aws.amazon.com/bedrock/latest/userguide/guardrails.html
+ AWSBedrockGuardrailIDKey = attribute.Key("aws.bedrock.guardrail.id")
+
+ // AWSBedrockKnowledgeBaseIDKey is the attribute Key conforming to the
+ // "aws.bedrock.knowledge_base.id" semantic conventions. It represents the
+ // unique identifier of the AWS Bedrock Knowledge base. A [knowledge base] is a
+ // bank of information that can be queried by models to generate more relevant
+ // responses and augment prompts.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "XFWUPB9PAW"
+ //
+ // [knowledge base]: https://docs.aws.amazon.com/bedrock/latest/userguide/knowledge-base.html
+ AWSBedrockKnowledgeBaseIDKey = attribute.Key("aws.bedrock.knowledge_base.id")
+
+ // AWSDynamoDBAttributeDefinitionsKey is the attribute Key conforming to the
+ // "aws.dynamodb.attribute_definitions" semantic conventions. It represents the
+ // JSON-serialized value of each item in the `AttributeDefinitions` request
+ // field.
+ //
+ // Type: string[]
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "{ "AttributeName": "string", "AttributeType": "string" }"
+ AWSDynamoDBAttributeDefinitionsKey = attribute.Key("aws.dynamodb.attribute_definitions")
+
+ // AWSDynamoDBAttributesToGetKey is the attribute Key conforming to the
+ // "aws.dynamodb.attributes_to_get" semantic conventions. It represents the
+ // value of the `AttributesToGet` request parameter.
+ //
+ // Type: string[]
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "lives", "id"
+ AWSDynamoDBAttributesToGetKey = attribute.Key("aws.dynamodb.attributes_to_get")
+
+ // AWSDynamoDBConsistentReadKey is the attribute Key conforming to the
+ // "aws.dynamodb.consistent_read" semantic conventions. It represents the value
+ // of the `ConsistentRead` request parameter.
+ //
+ // Type: boolean
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ AWSDynamoDBConsistentReadKey = attribute.Key("aws.dynamodb.consistent_read")
+
+ // AWSDynamoDBConsumedCapacityKey is the attribute Key conforming to the
+ // "aws.dynamodb.consumed_capacity" semantic conventions. It represents the
+ // JSON-serialized value of each item in the `ConsumedCapacity` response field.
+ //
+ // Type: string[]
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "{ "CapacityUnits": number, "GlobalSecondaryIndexes": { "string" :
+ // { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits":
+ // number } }, "LocalSecondaryIndexes": { "string" : { "CapacityUnits": number,
+ // "ReadCapacityUnits": number, "WriteCapacityUnits": number } },
+ // "ReadCapacityUnits": number, "Table": { "CapacityUnits": number,
+ // "ReadCapacityUnits": number, "WriteCapacityUnits": number }, "TableName":
+ // "string", "WriteCapacityUnits": number }"
+ AWSDynamoDBConsumedCapacityKey = attribute.Key("aws.dynamodb.consumed_capacity")
+
+ // AWSDynamoDBCountKey is the attribute Key conforming to the
+ // "aws.dynamodb.count" semantic conventions. It represents the value of the
+ // `Count` response parameter.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 10
+ AWSDynamoDBCountKey = attribute.Key("aws.dynamodb.count")
+
+ // AWSDynamoDBExclusiveStartTableKey is the attribute Key conforming to the
+ // "aws.dynamodb.exclusive_start_table" semantic conventions. It represents the
+ // value of the `ExclusiveStartTableName` request parameter.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "Users", "CatsTable"
+ AWSDynamoDBExclusiveStartTableKey = attribute.Key("aws.dynamodb.exclusive_start_table")
+
+ // AWSDynamoDBGlobalSecondaryIndexUpdatesKey is the attribute Key conforming to
+ // the "aws.dynamodb.global_secondary_index_updates" semantic conventions. It
+ // represents the JSON-serialized value of each item in the
+ // `GlobalSecondaryIndexUpdates` request field.
+ //
+ // Type: string[]
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "{ "Create": { "IndexName": "string", "KeySchema": [ {
+ // "AttributeName": "string", "KeyType": "string" } ], "Projection": {
+ // "NonKeyAttributes": [ "string" ], "ProjectionType": "string" },
+ // "ProvisionedThroughput": { "ReadCapacityUnits": number, "WriteCapacityUnits":
+ // number } }"
+ AWSDynamoDBGlobalSecondaryIndexUpdatesKey = attribute.Key("aws.dynamodb.global_secondary_index_updates")
+
+ // AWSDynamoDBGlobalSecondaryIndexesKey is the attribute Key conforming to the
+ // "aws.dynamodb.global_secondary_indexes" semantic conventions. It represents
+ // the JSON-serialized value of each item of the `GlobalSecondaryIndexes`
+ // request field.
+ //
+ // Type: string[]
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "{ "IndexName": "string", "KeySchema": [ { "AttributeName":
+ // "string", "KeyType": "string" } ], "Projection": { "NonKeyAttributes": [
+ // "string" ], "ProjectionType": "string" }, "ProvisionedThroughput": {
+ // "ReadCapacityUnits": number, "WriteCapacityUnits": number } }"
+ AWSDynamoDBGlobalSecondaryIndexesKey = attribute.Key("aws.dynamodb.global_secondary_indexes")
+
+ // AWSDynamoDBIndexNameKey is the attribute Key conforming to the
+ // "aws.dynamodb.index_name" semantic conventions. It represents the value of
+ // the `IndexName` request parameter.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "name_to_group"
+ AWSDynamoDBIndexNameKey = attribute.Key("aws.dynamodb.index_name")
+
+ // AWSDynamoDBItemCollectionMetricsKey is the attribute Key conforming to the
+ // "aws.dynamodb.item_collection_metrics" semantic conventions. It represents
+ // the JSON-serialized value of the `ItemCollectionMetrics` response field.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "{ "string" : [ { "ItemCollectionKey": { "string" : { "B": blob,
+ // "BOOL": boolean, "BS": [ blob ], "L": [ "AttributeValue" ], "M": { "string" :
+ // "AttributeValue" }, "N": "string", "NS": [ "string" ], "NULL": boolean, "S":
+ // "string", "SS": [ "string" ] } }, "SizeEstimateRangeGB": [ number ] } ] }"
+ AWSDynamoDBItemCollectionMetricsKey = attribute.Key("aws.dynamodb.item_collection_metrics")
+
+ // AWSDynamoDBLimitKey is the attribute Key conforming to the
+ // "aws.dynamodb.limit" semantic conventions. It represents the value of the
+ // `Limit` request parameter.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 10
+ AWSDynamoDBLimitKey = attribute.Key("aws.dynamodb.limit")
+
+ // AWSDynamoDBLocalSecondaryIndexesKey is the attribute Key conforming to the
+ // "aws.dynamodb.local_secondary_indexes" semantic conventions. It represents
+ // the JSON-serialized value of each item of the `LocalSecondaryIndexes` request
+ // field.
+ //
+ // Type: string[]
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "{ "IndexArn": "string", "IndexName": "string", "IndexSizeBytes":
+ // number, "ItemCount": number, "KeySchema": [ { "AttributeName": "string",
+ // "KeyType": "string" } ], "Projection": { "NonKeyAttributes": [ "string" ],
+ // "ProjectionType": "string" } }"
+ AWSDynamoDBLocalSecondaryIndexesKey = attribute.Key("aws.dynamodb.local_secondary_indexes")
+
+ // AWSDynamoDBProjectionKey is the attribute Key conforming to the
+ // "aws.dynamodb.projection" semantic conventions. It represents the value of
+ // the `ProjectionExpression` request parameter.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "Title", "Title, Price, Color", "Title, Description, RelatedItems,
+ // ProductReviews"
+ AWSDynamoDBProjectionKey = attribute.Key("aws.dynamodb.projection")
+
+ // AWSDynamoDBProvisionedReadCapacityKey is the attribute Key conforming to the
+ // "aws.dynamodb.provisioned_read_capacity" semantic conventions. It represents
+ // the value of the `ProvisionedThroughput.ReadCapacityUnits` request parameter.
+ //
+ // Type: double
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 1.0, 2.0
+ AWSDynamoDBProvisionedReadCapacityKey = attribute.Key("aws.dynamodb.provisioned_read_capacity")
+
+ // AWSDynamoDBProvisionedWriteCapacityKey is the attribute Key conforming to the
+ // "aws.dynamodb.provisioned_write_capacity" semantic conventions. It represents
+ // the value of the `ProvisionedThroughput.WriteCapacityUnits` request
+ // parameter.
+ //
+ // Type: double
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 1.0, 2.0
+ AWSDynamoDBProvisionedWriteCapacityKey = attribute.Key("aws.dynamodb.provisioned_write_capacity")
+
+ // AWSDynamoDBScanForwardKey is the attribute Key conforming to the
+ // "aws.dynamodb.scan_forward" semantic conventions. It represents the value of
+ // the `ScanIndexForward` request parameter.
+ //
+ // Type: boolean
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ AWSDynamoDBScanForwardKey = attribute.Key("aws.dynamodb.scan_forward")
+
+ // AWSDynamoDBScannedCountKey is the attribute Key conforming to the
+ // "aws.dynamodb.scanned_count" semantic conventions. It represents the value of
+ // the `ScannedCount` response parameter.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 50
+ AWSDynamoDBScannedCountKey = attribute.Key("aws.dynamodb.scanned_count")
+
+ // AWSDynamoDBSegmentKey is the attribute Key conforming to the
+ // "aws.dynamodb.segment" semantic conventions. It represents the value of the
+ // `Segment` request parameter.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 10
+ AWSDynamoDBSegmentKey = attribute.Key("aws.dynamodb.segment")
+
+ // AWSDynamoDBSelectKey is the attribute Key conforming to the
+ // "aws.dynamodb.select" semantic conventions. It represents the value of the
+ // `Select` request parameter.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "ALL_ATTRIBUTES", "COUNT"
+ AWSDynamoDBSelectKey = attribute.Key("aws.dynamodb.select")
+
+ // AWSDynamoDBTableCountKey is the attribute Key conforming to the
+ // "aws.dynamodb.table_count" semantic conventions. It represents the number of
+ // items in the `TableNames` response parameter.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 20
+ AWSDynamoDBTableCountKey = attribute.Key("aws.dynamodb.table_count")
+
+ // AWSDynamoDBTableNamesKey is the attribute Key conforming to the
+ // "aws.dynamodb.table_names" semantic conventions. It represents the keys in
+ // the `RequestItems` object field.
+ //
+ // Type: string[]
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "Users", "Cats"
+ AWSDynamoDBTableNamesKey = attribute.Key("aws.dynamodb.table_names")
+
+ // AWSDynamoDBTotalSegmentsKey is the attribute Key conforming to the
+ // "aws.dynamodb.total_segments" semantic conventions. It represents the value
+ // of the `TotalSegments` request parameter.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 100
+ AWSDynamoDBTotalSegmentsKey = attribute.Key("aws.dynamodb.total_segments")
+
+ // AWSECSClusterARNKey is the attribute Key conforming to the
+ // "aws.ecs.cluster.arn" semantic conventions. It represents the ARN of an
+ // [ECS cluster].
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "arn:aws:ecs:us-west-2:123456789123:cluster/my-cluster"
+ //
+ // [ECS cluster]: https://docs.aws.amazon.com/AmazonECS/latest/developerguide/clusters.html
+ AWSECSClusterARNKey = attribute.Key("aws.ecs.cluster.arn")
+
+ // AWSECSContainerARNKey is the attribute Key conforming to the
+ // "aws.ecs.container.arn" semantic conventions. It represents the Amazon
+ // Resource Name (ARN) of an [ECS container instance].
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ // "arn:aws:ecs:us-west-1:123456789123:container/32624152-9086-4f0e-acae-1a75b14fe4d9"
+ //
+ // [ECS container instance]: https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ECS_instances.html
+ AWSECSContainerARNKey = attribute.Key("aws.ecs.container.arn")
+
+ // AWSECSLaunchtypeKey is the attribute Key conforming to the
+ // "aws.ecs.launchtype" semantic conventions. It represents the [launch type]
+ // for an ECS task.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ //
+ // [launch type]: https://docs.aws.amazon.com/AmazonECS/latest/developerguide/launch_types.html
+ AWSECSLaunchtypeKey = attribute.Key("aws.ecs.launchtype")
+
+ // AWSECSTaskARNKey is the attribute Key conforming to the "aws.ecs.task.arn"
+ // semantic conventions. It represents the ARN of a running [ECS task].
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ // "arn:aws:ecs:us-west-1:123456789123:task/10838bed-421f-43ef-870a-f43feacbbb5b",
+ // "arn:aws:ecs:us-west-1:123456789123:task/my-cluster/task-id/23ebb8ac-c18f-46c6-8bbe-d55d0e37cfbd"
+ //
+ // [ECS task]: https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs-account-settings.html#ecs-resource-ids
+ AWSECSTaskARNKey = attribute.Key("aws.ecs.task.arn")
+
+ // AWSECSTaskFamilyKey is the attribute Key conforming to the
+ // "aws.ecs.task.family" semantic conventions. It represents the family name of
+ // the [ECS task definition] used to create the ECS task.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "opentelemetry-family"
+ //
+ // [ECS task definition]: https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definitions.html
+ AWSECSTaskFamilyKey = attribute.Key("aws.ecs.task.family")
+
+ // AWSECSTaskIDKey is the attribute Key conforming to the "aws.ecs.task.id"
+ // semantic conventions. It represents the ID of a running ECS task. The ID MUST
+ // be extracted from `task.arn`.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "10838bed-421f-43ef-870a-f43feacbbb5b",
+ // "23ebb8ac-c18f-46c6-8bbe-d55d0e37cfbd"
+ AWSECSTaskIDKey = attribute.Key("aws.ecs.task.id")
+
+ // AWSECSTaskRevisionKey is the attribute Key conforming to the
+ // "aws.ecs.task.revision" semantic conventions. It represents the revision for
+ // the task definition used to create the ECS task.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "8", "26"
+ AWSECSTaskRevisionKey = attribute.Key("aws.ecs.task.revision")
+
+ // AWSEKSClusterARNKey is the attribute Key conforming to the
+ // "aws.eks.cluster.arn" semantic conventions. It represents the ARN of an EKS
+ // cluster.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "arn:aws:ecs:us-west-2:123456789123:cluster/my-cluster"
+ AWSEKSClusterARNKey = attribute.Key("aws.eks.cluster.arn")
+
+ // AWSExtendedRequestIDKey is the attribute Key conforming to the
+ // "aws.extended_request_id" semantic conventions. It represents the AWS
+ // extended request ID as returned in the response header `x-amz-id-2`.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ // "wzHcyEWfmOGDIE5QOhTAqFDoDWP3y8IUvpNINCwL9N4TEHbUw0/gZJ+VZTmCNCWR7fezEN3eCiQ="
+ AWSExtendedRequestIDKey = attribute.Key("aws.extended_request_id")
+
+ // AWSKinesisStreamNameKey is the attribute Key conforming to the
+ // "aws.kinesis.stream_name" semantic conventions. It represents the name of the
+ // AWS Kinesis [stream] the request refers to. Corresponds to the
+ // `--stream-name` parameter of the Kinesis [describe-stream] operation.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "some-stream-name"
+ //
+ // [stream]: https://docs.aws.amazon.com/streams/latest/dev/introduction.html
+ // [describe-stream]: https://docs.aws.amazon.com/cli/latest/reference/kinesis/describe-stream.html
+ AWSKinesisStreamNameKey = attribute.Key("aws.kinesis.stream_name")
+
+ // AWSLambdaInvokedARNKey is the attribute Key conforming to the
+ // "aws.lambda.invoked_arn" semantic conventions. It represents the full invoked
+ // ARN as provided on the `Context` passed to the function (
+ // `Lambda-Runtime-Invoked-Function-Arn` header on the
+ // `/runtime/invocation/next` applicable).
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "arn:aws:lambda:us-east-1:123456:function:myfunction:myalias"
+ // Note: This may be different from `cloud.resource_id` if an alias is involved.
+ AWSLambdaInvokedARNKey = attribute.Key("aws.lambda.invoked_arn")
+
+ // AWSLambdaResourceMappingIDKey is the attribute Key conforming to the
+ // "aws.lambda.resource_mapping.id" semantic conventions. It represents the UUID
+ // of the [AWS Lambda EvenSource Mapping]. An event source is mapped to a lambda
+ // function. It's contents are read by Lambda and used to trigger a function.
+ // This isn't available in the lambda execution context or the lambda runtime
+ // environtment. This is going to be populated by the AWS SDK for each language
+ // when that UUID is present. Some of these operations are
+ // Create/Delete/Get/List/Update EventSourceMapping.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "587ad24b-03b9-4413-8202-bbd56b36e5b7"
+ //
+ // [AWS Lambda EvenSource Mapping]: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-eventsourcemapping.html
+ AWSLambdaResourceMappingIDKey = attribute.Key("aws.lambda.resource_mapping.id")
+
+ // AWSLogGroupARNsKey is the attribute Key conforming to the
+ // "aws.log.group.arns" semantic conventions. It represents the Amazon Resource
+ // Name(s) (ARN) of the AWS log group(s).
+ //
+ // Type: string[]
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "arn:aws:logs:us-west-1:123456789012:log-group:/aws/my/group:*"
+ // Note: See the [log group ARN format documentation].
+ //
+ // [log group ARN format documentation]: https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/iam-access-control-overview-cwl.html#CWL_ARN_Format
+ AWSLogGroupARNsKey = attribute.Key("aws.log.group.arns")
+
+ // AWSLogGroupNamesKey is the attribute Key conforming to the
+ // "aws.log.group.names" semantic conventions. It represents the name(s) of the
+ // AWS log group(s) an application is writing to.
+ //
+ // Type: string[]
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "/aws/lambda/my-function", "opentelemetry-service"
+ // Note: Multiple log groups must be supported for cases like multi-container
+ // applications, where a single application has sidecar containers, and each
+ // write to their own log group.
+ AWSLogGroupNamesKey = attribute.Key("aws.log.group.names")
+
+ // AWSLogStreamARNsKey is the attribute Key conforming to the
+ // "aws.log.stream.arns" semantic conventions. It represents the ARN(s) of the
+ // AWS log stream(s).
+ //
+ // Type: string[]
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ // "arn:aws:logs:us-west-1:123456789012:log-group:/aws/my/group:log-stream:logs/main/10838bed-421f-43ef-870a-f43feacbbb5b"
+ // Note: See the [log stream ARN format documentation]. One log group can
+ // contain several log streams, so these ARNs necessarily identify both a log
+ // group and a log stream.
+ //
+ // [log stream ARN format documentation]: https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/iam-access-control-overview-cwl.html#CWL_ARN_Format
+ AWSLogStreamARNsKey = attribute.Key("aws.log.stream.arns")
+
+ // AWSLogStreamNamesKey is the attribute Key conforming to the
+ // "aws.log.stream.names" semantic conventions. It represents the name(s) of the
+ // AWS log stream(s) an application is writing to.
+ //
+ // Type: string[]
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "logs/main/10838bed-421f-43ef-870a-f43feacbbb5b"
+ AWSLogStreamNamesKey = attribute.Key("aws.log.stream.names")
+
+ // AWSRequestIDKey is the attribute Key conforming to the "aws.request_id"
+ // semantic conventions. It represents the AWS request ID as returned in the
+ // response headers `x-amzn-requestid`, `x-amzn-request-id` or
+ // `x-amz-request-id`.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "79b9da39-b7ae-508a-a6bc-864b2829c622", "C9ER4AJX75574TDJ"
+ AWSRequestIDKey = attribute.Key("aws.request_id")
+
+ // AWSS3BucketKey is the attribute Key conforming to the "aws.s3.bucket"
+ // semantic conventions. It represents the S3 bucket name the request refers to.
+ // Corresponds to the `--bucket` parameter of the [S3 API] operations.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "some-bucket-name"
+ // Note: The `bucket` attribute is applicable to all S3 operations that
+ // reference a bucket, i.e. that require the bucket name as a mandatory
+ // parameter.
+ // This applies to almost all S3 operations except `list-buckets`.
+ //
+ // [S3 API]: https://docs.aws.amazon.com/cli/latest/reference/s3api/index.html
+ AWSS3BucketKey = attribute.Key("aws.s3.bucket")
+
+ // AWSS3CopySourceKey is the attribute Key conforming to the
+ // "aws.s3.copy_source" semantic conventions. It represents the source object
+ // (in the form `bucket`/`key`) for the copy operation.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "someFile.yml"
+ // Note: The `copy_source` attribute applies to S3 copy operations and
+ // corresponds to the `--copy-source` parameter
+ // of the [copy-object operation within the S3 API].
+ // This applies in particular to the following operations:
+ //
+ // - [copy-object]
+ // - [upload-part-copy]
+ //
+ //
+ // [copy-object operation within the S3 API]: https://docs.aws.amazon.com/cli/latest/reference/s3api/copy-object.html
+ // [copy-object]: https://docs.aws.amazon.com/cli/latest/reference/s3api/copy-object.html
+ // [upload-part-copy]: https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part-copy.html
+ AWSS3CopySourceKey = attribute.Key("aws.s3.copy_source")
+
+ // AWSS3DeleteKey is the attribute Key conforming to the "aws.s3.delete"
+ // semantic conventions. It represents the delete request container that
+ // specifies the objects to be deleted.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ // "Objects=[{Key=string,VersionId=string},{Key=string,VersionId=string}],Quiet=boolean"
+ // Note: The `delete` attribute is only applicable to the [delete-object]
+ // operation.
+ // The `delete` attribute corresponds to the `--delete` parameter of the
+ // [delete-objects operation within the S3 API].
+ //
+ // [delete-object]: https://docs.aws.amazon.com/cli/latest/reference/s3api/delete-object.html
+ // [delete-objects operation within the S3 API]: https://docs.aws.amazon.com/cli/latest/reference/s3api/delete-objects.html
+ AWSS3DeleteKey = attribute.Key("aws.s3.delete")
+
+ // AWSS3KeyKey is the attribute Key conforming to the "aws.s3.key" semantic
+ // conventions. It represents the S3 object key the request refers to.
+ // Corresponds to the `--key` parameter of the [S3 API] operations.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "someFile.yml"
+ // Note: The `key` attribute is applicable to all object-related S3 operations,
+ // i.e. that require the object key as a mandatory parameter.
+ // This applies in particular to the following operations:
+ //
+ // - [copy-object]
+ // - [delete-object]
+ // - [get-object]
+ // - [head-object]
+ // - [put-object]
+ // - [restore-object]
+ // - [select-object-content]
+ // - [abort-multipart-upload]
+ // - [complete-multipart-upload]
+ // - [create-multipart-upload]
+ // - [list-parts]
+ // - [upload-part]
+ // - [upload-part-copy]
+ //
+ //
+ // [S3 API]: https://docs.aws.amazon.com/cli/latest/reference/s3api/index.html
+ // [copy-object]: https://docs.aws.amazon.com/cli/latest/reference/s3api/copy-object.html
+ // [delete-object]: https://docs.aws.amazon.com/cli/latest/reference/s3api/delete-object.html
+ // [get-object]: https://docs.aws.amazon.com/cli/latest/reference/s3api/get-object.html
+ // [head-object]: https://docs.aws.amazon.com/cli/latest/reference/s3api/head-object.html
+ // [put-object]: https://docs.aws.amazon.com/cli/latest/reference/s3api/put-object.html
+ // [restore-object]: https://docs.aws.amazon.com/cli/latest/reference/s3api/restore-object.html
+ // [select-object-content]: https://docs.aws.amazon.com/cli/latest/reference/s3api/select-object-content.html
+ // [abort-multipart-upload]: https://docs.aws.amazon.com/cli/latest/reference/s3api/abort-multipart-upload.html
+ // [complete-multipart-upload]: https://docs.aws.amazon.com/cli/latest/reference/s3api/complete-multipart-upload.html
+ // [create-multipart-upload]: https://docs.aws.amazon.com/cli/latest/reference/s3api/create-multipart-upload.html
+ // [list-parts]: https://docs.aws.amazon.com/cli/latest/reference/s3api/list-parts.html
+ // [upload-part]: https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part.html
+ // [upload-part-copy]: https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part-copy.html
+ AWSS3KeyKey = attribute.Key("aws.s3.key")
+
+ // AWSS3PartNumberKey is the attribute Key conforming to the
+ // "aws.s3.part_number" semantic conventions. It represents the part number of
+ // the part being uploaded in a multipart-upload operation. This is a positive
+ // integer between 1 and 10,000.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 3456
+ // Note: The `part_number` attribute is only applicable to the [upload-part]
+ // and [upload-part-copy] operations.
+ // The `part_number` attribute corresponds to the `--part-number` parameter of
+ // the
+ // [upload-part operation within the S3 API].
+ //
+ // [upload-part]: https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part.html
+ // [upload-part-copy]: https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part-copy.html
+ // [upload-part operation within the S3 API]: https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part.html
+ AWSS3PartNumberKey = attribute.Key("aws.s3.part_number")
+
+ // AWSS3UploadIDKey is the attribute Key conforming to the "aws.s3.upload_id"
+ // semantic conventions. It represents the upload ID that identifies the
+ // multipart upload.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "dfRtDYWFbkRONycy.Yxwh66Yjlx.cph0gtNBtJ"
+ // Note: The `upload_id` attribute applies to S3 multipart-upload operations and
+ // corresponds to the `--upload-id` parameter
+ // of the [S3 API] multipart operations.
+ // This applies in particular to the following operations:
+ //
+ // - [abort-multipart-upload]
+ // - [complete-multipart-upload]
+ // - [list-parts]
+ // - [upload-part]
+ // - [upload-part-copy]
+ //
+ //
+ // [S3 API]: https://docs.aws.amazon.com/cli/latest/reference/s3api/index.html
+ // [abort-multipart-upload]: https://docs.aws.amazon.com/cli/latest/reference/s3api/abort-multipart-upload.html
+ // [complete-multipart-upload]: https://docs.aws.amazon.com/cli/latest/reference/s3api/complete-multipart-upload.html
+ // [list-parts]: https://docs.aws.amazon.com/cli/latest/reference/s3api/list-parts.html
+ // [upload-part]: https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part.html
+ // [upload-part-copy]: https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part-copy.html
+ AWSS3UploadIDKey = attribute.Key("aws.s3.upload_id")
+
+ // AWSSecretsmanagerSecretARNKey is the attribute Key conforming to the
+ // "aws.secretsmanager.secret.arn" semantic conventions. It represents the ARN
+ // of the Secret stored in the Secrets Mangger.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ // "arn:aws:secretsmanager:us-east-1:123456789012:secret:SecretName-6RandomCharacters"
+ AWSSecretsmanagerSecretARNKey = attribute.Key("aws.secretsmanager.secret.arn")
+
+ // AWSSNSTopicARNKey is the attribute Key conforming to the "aws.sns.topic.arn"
+ // semantic conventions. It represents the ARN of the AWS SNS Topic. An Amazon
+ // SNS [topic] is a logical access point that acts as a communication channel.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "arn:aws:sns:us-east-1:123456789012:mystack-mytopic-NZJ5JSMVGFIE"
+ //
+ // [topic]: https://docs.aws.amazon.com/sns/latest/dg/sns-create-topic.html
+ AWSSNSTopicARNKey = attribute.Key("aws.sns.topic.arn")
+
+ // AWSSQSQueueURLKey is the attribute Key conforming to the "aws.sqs.queue.url"
+ // semantic conventions. It represents the URL of the AWS SQS Queue. It's a
+ // unique identifier for a queue in Amazon Simple Queue Service (SQS) and is
+ // used to access the queue and perform actions on it.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "https://sqs.us-east-1.amazonaws.com/123456789012/MyQueue"
+ AWSSQSQueueURLKey = attribute.Key("aws.sqs.queue.url")
+
+ // AWSStepFunctionsActivityARNKey is the attribute Key conforming to the
+ // "aws.step_functions.activity.arn" semantic conventions. It represents the ARN
+ // of the AWS Step Functions Activity.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "arn:aws:states:us-east-1:123456789012:activity:get-greeting"
+ AWSStepFunctionsActivityARNKey = attribute.Key("aws.step_functions.activity.arn")
+
+ // AWSStepFunctionsStateMachineARNKey is the attribute Key conforming to the
+ // "aws.step_functions.state_machine.arn" semantic conventions. It represents
+ // the ARN of the AWS Step Functions State Machine.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ // "arn:aws:states:us-east-1:123456789012:stateMachine:myStateMachine:1"
+ AWSStepFunctionsStateMachineARNKey = attribute.Key("aws.step_functions.state_machine.arn")
+)
+
+// AWSBedrockGuardrailID returns an attribute KeyValue conforming to the
+// "aws.bedrock.guardrail.id" semantic conventions. It represents the unique
+// identifier of the AWS Bedrock Guardrail. A [guardrail] helps safeguard and
+// prevent unwanted behavior from model responses or user messages.
+//
+// [guardrail]: https://docs.aws.amazon.com/bedrock/latest/userguide/guardrails.html
+func AWSBedrockGuardrailID(val string) attribute.KeyValue {
+ return AWSBedrockGuardrailIDKey.String(val)
+}
+
+// AWSBedrockKnowledgeBaseID returns an attribute KeyValue conforming to the
+// "aws.bedrock.knowledge_base.id" semantic conventions. It represents the unique
+// identifier of the AWS Bedrock Knowledge base. A [knowledge base] is a bank of
+// information that can be queried by models to generate more relevant responses
+// and augment prompts.
+//
+// [knowledge base]: https://docs.aws.amazon.com/bedrock/latest/userguide/knowledge-base.html
+func AWSBedrockKnowledgeBaseID(val string) attribute.KeyValue {
+ return AWSBedrockKnowledgeBaseIDKey.String(val)
+}
+
+// AWSDynamoDBAttributeDefinitions returns an attribute KeyValue conforming to
+// the "aws.dynamodb.attribute_definitions" semantic conventions. It represents
+// the JSON-serialized value of each item in the `AttributeDefinitions` request
+// field.
+func AWSDynamoDBAttributeDefinitions(val ...string) attribute.KeyValue {
+ return AWSDynamoDBAttributeDefinitionsKey.StringSlice(val)
+}
+
+// AWSDynamoDBAttributesToGet returns an attribute KeyValue conforming to the
+// "aws.dynamodb.attributes_to_get" semantic conventions. It represents the value
+// of the `AttributesToGet` request parameter.
+func AWSDynamoDBAttributesToGet(val ...string) attribute.KeyValue {
+ return AWSDynamoDBAttributesToGetKey.StringSlice(val)
+}
+
+// AWSDynamoDBConsistentRead returns an attribute KeyValue conforming to the
+// "aws.dynamodb.consistent_read" semantic conventions. It represents the value
+// of the `ConsistentRead` request parameter.
+func AWSDynamoDBConsistentRead(val bool) attribute.KeyValue {
+ return AWSDynamoDBConsistentReadKey.Bool(val)
+}
+
+// AWSDynamoDBConsumedCapacity returns an attribute KeyValue conforming to the
+// "aws.dynamodb.consumed_capacity" semantic conventions. It represents the
+// JSON-serialized value of each item in the `ConsumedCapacity` response field.
+func AWSDynamoDBConsumedCapacity(val ...string) attribute.KeyValue {
+ return AWSDynamoDBConsumedCapacityKey.StringSlice(val)
+}
+
+// AWSDynamoDBCount returns an attribute KeyValue conforming to the
+// "aws.dynamodb.count" semantic conventions. It represents the value of the
+// `Count` response parameter.
+func AWSDynamoDBCount(val int) attribute.KeyValue {
+ return AWSDynamoDBCountKey.Int(val)
+}
+
+// AWSDynamoDBExclusiveStartTable returns an attribute KeyValue conforming to the
+// "aws.dynamodb.exclusive_start_table" semantic conventions. It represents the
+// value of the `ExclusiveStartTableName` request parameter.
+func AWSDynamoDBExclusiveStartTable(val string) attribute.KeyValue {
+ return AWSDynamoDBExclusiveStartTableKey.String(val)
+}
+
+// AWSDynamoDBGlobalSecondaryIndexUpdates returns an attribute KeyValue
+// conforming to the "aws.dynamodb.global_secondary_index_updates" semantic
+// conventions. It represents the JSON-serialized value of each item in the
+// `GlobalSecondaryIndexUpdates` request field.
+func AWSDynamoDBGlobalSecondaryIndexUpdates(val ...string) attribute.KeyValue {
+ return AWSDynamoDBGlobalSecondaryIndexUpdatesKey.StringSlice(val)
+}
+
+// AWSDynamoDBGlobalSecondaryIndexes returns an attribute KeyValue conforming to
+// the "aws.dynamodb.global_secondary_indexes" semantic conventions. It
+// represents the JSON-serialized value of each item of the
+// `GlobalSecondaryIndexes` request field.
+func AWSDynamoDBGlobalSecondaryIndexes(val ...string) attribute.KeyValue {
+ return AWSDynamoDBGlobalSecondaryIndexesKey.StringSlice(val)
+}
+
+// AWSDynamoDBIndexName returns an attribute KeyValue conforming to the
+// "aws.dynamodb.index_name" semantic conventions. It represents the value of the
+// `IndexName` request parameter.
+func AWSDynamoDBIndexName(val string) attribute.KeyValue {
+ return AWSDynamoDBIndexNameKey.String(val)
+}
+
+// AWSDynamoDBItemCollectionMetrics returns an attribute KeyValue conforming to
+// the "aws.dynamodb.item_collection_metrics" semantic conventions. It represents
+// the JSON-serialized value of the `ItemCollectionMetrics` response field.
+func AWSDynamoDBItemCollectionMetrics(val string) attribute.KeyValue {
+ return AWSDynamoDBItemCollectionMetricsKey.String(val)
+}
+
+// AWSDynamoDBLimit returns an attribute KeyValue conforming to the
+// "aws.dynamodb.limit" semantic conventions. It represents the value of the
+// `Limit` request parameter.
+func AWSDynamoDBLimit(val int) attribute.KeyValue {
+ return AWSDynamoDBLimitKey.Int(val)
+}
+
+// AWSDynamoDBLocalSecondaryIndexes returns an attribute KeyValue conforming to
+// the "aws.dynamodb.local_secondary_indexes" semantic conventions. It represents
+// the JSON-serialized value of each item of the `LocalSecondaryIndexes` request
+// field.
+func AWSDynamoDBLocalSecondaryIndexes(val ...string) attribute.KeyValue {
+ return AWSDynamoDBLocalSecondaryIndexesKey.StringSlice(val)
+}
+
+// AWSDynamoDBProjection returns an attribute KeyValue conforming to the
+// "aws.dynamodb.projection" semantic conventions. It represents the value of the
+// `ProjectionExpression` request parameter.
+func AWSDynamoDBProjection(val string) attribute.KeyValue {
+ return AWSDynamoDBProjectionKey.String(val)
+}
+
+// AWSDynamoDBProvisionedReadCapacity returns an attribute KeyValue conforming to
+// the "aws.dynamodb.provisioned_read_capacity" semantic conventions. It
+// represents the value of the `ProvisionedThroughput.ReadCapacityUnits` request
+// parameter.
+func AWSDynamoDBProvisionedReadCapacity(val float64) attribute.KeyValue {
+ return AWSDynamoDBProvisionedReadCapacityKey.Float64(val)
+}
+
+// AWSDynamoDBProvisionedWriteCapacity returns an attribute KeyValue conforming
+// to the "aws.dynamodb.provisioned_write_capacity" semantic conventions. It
+// represents the value of the `ProvisionedThroughput.WriteCapacityUnits` request
+// parameter.
+func AWSDynamoDBProvisionedWriteCapacity(val float64) attribute.KeyValue {
+ return AWSDynamoDBProvisionedWriteCapacityKey.Float64(val)
+}
+
+// AWSDynamoDBScanForward returns an attribute KeyValue conforming to the
+// "aws.dynamodb.scan_forward" semantic conventions. It represents the value of
+// the `ScanIndexForward` request parameter.
+func AWSDynamoDBScanForward(val bool) attribute.KeyValue {
+ return AWSDynamoDBScanForwardKey.Bool(val)
+}
+
+// AWSDynamoDBScannedCount returns an attribute KeyValue conforming to the
+// "aws.dynamodb.scanned_count" semantic conventions. It represents the value of
+// the `ScannedCount` response parameter.
+func AWSDynamoDBScannedCount(val int) attribute.KeyValue {
+ return AWSDynamoDBScannedCountKey.Int(val)
+}
+
+// AWSDynamoDBSegment returns an attribute KeyValue conforming to the
+// "aws.dynamodb.segment" semantic conventions. It represents the value of the
+// `Segment` request parameter.
+func AWSDynamoDBSegment(val int) attribute.KeyValue {
+ return AWSDynamoDBSegmentKey.Int(val)
+}
+
+// AWSDynamoDBSelect returns an attribute KeyValue conforming to the
+// "aws.dynamodb.select" semantic conventions. It represents the value of the
+// `Select` request parameter.
+func AWSDynamoDBSelect(val string) attribute.KeyValue {
+ return AWSDynamoDBSelectKey.String(val)
+}
+
+// AWSDynamoDBTableCount returns an attribute KeyValue conforming to the
+// "aws.dynamodb.table_count" semantic conventions. It represents the number of
+// items in the `TableNames` response parameter.
+func AWSDynamoDBTableCount(val int) attribute.KeyValue {
+ return AWSDynamoDBTableCountKey.Int(val)
+}
+
+// AWSDynamoDBTableNames returns an attribute KeyValue conforming to the
+// "aws.dynamodb.table_names" semantic conventions. It represents the keys in the
+// `RequestItems` object field.
+func AWSDynamoDBTableNames(val ...string) attribute.KeyValue {
+ return AWSDynamoDBTableNamesKey.StringSlice(val)
+}
+
+// AWSDynamoDBTotalSegments returns an attribute KeyValue conforming to the
+// "aws.dynamodb.total_segments" semantic conventions. It represents the value of
+// the `TotalSegments` request parameter.
+func AWSDynamoDBTotalSegments(val int) attribute.KeyValue {
+ return AWSDynamoDBTotalSegmentsKey.Int(val)
+}
+
+// AWSECSClusterARN returns an attribute KeyValue conforming to the
+// "aws.ecs.cluster.arn" semantic conventions. It represents the ARN of an
+// [ECS cluster].
+//
+// [ECS cluster]: https://docs.aws.amazon.com/AmazonECS/latest/developerguide/clusters.html
+func AWSECSClusterARN(val string) attribute.KeyValue {
+ return AWSECSClusterARNKey.String(val)
+}
+
+// AWSECSContainerARN returns an attribute KeyValue conforming to the
+// "aws.ecs.container.arn" semantic conventions. It represents the Amazon
+// Resource Name (ARN) of an [ECS container instance].
+//
+// [ECS container instance]: https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ECS_instances.html
+func AWSECSContainerARN(val string) attribute.KeyValue {
+ return AWSECSContainerARNKey.String(val)
+}
+
+// AWSECSTaskARN returns an attribute KeyValue conforming to the
+// "aws.ecs.task.arn" semantic conventions. It represents the ARN of a running
+// [ECS task].
+//
+// [ECS task]: https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs-account-settings.html#ecs-resource-ids
+func AWSECSTaskARN(val string) attribute.KeyValue {
+ return AWSECSTaskARNKey.String(val)
+}
+
+// AWSECSTaskFamily returns an attribute KeyValue conforming to the
+// "aws.ecs.task.family" semantic conventions. It represents the family name of
+// the [ECS task definition] used to create the ECS task.
+//
+// [ECS task definition]: https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definitions.html
+func AWSECSTaskFamily(val string) attribute.KeyValue {
+ return AWSECSTaskFamilyKey.String(val)
+}
+
+// AWSECSTaskID returns an attribute KeyValue conforming to the "aws.ecs.task.id"
+// semantic conventions. It represents the ID of a running ECS task. The ID MUST
+// be extracted from `task.arn`.
+func AWSECSTaskID(val string) attribute.KeyValue {
+ return AWSECSTaskIDKey.String(val)
+}
+
+// AWSECSTaskRevision returns an attribute KeyValue conforming to the
+// "aws.ecs.task.revision" semantic conventions. It represents the revision for
+// the task definition used to create the ECS task.
+func AWSECSTaskRevision(val string) attribute.KeyValue {
+ return AWSECSTaskRevisionKey.String(val)
+}
+
+// AWSEKSClusterARN returns an attribute KeyValue conforming to the
+// "aws.eks.cluster.arn" semantic conventions. It represents the ARN of an EKS
+// cluster.
+func AWSEKSClusterARN(val string) attribute.KeyValue {
+ return AWSEKSClusterARNKey.String(val)
+}
+
+// AWSExtendedRequestID returns an attribute KeyValue conforming to the
+// "aws.extended_request_id" semantic conventions. It represents the AWS extended
+// request ID as returned in the response header `x-amz-id-2`.
+func AWSExtendedRequestID(val string) attribute.KeyValue {
+ return AWSExtendedRequestIDKey.String(val)
+}
+
+// AWSKinesisStreamName returns an attribute KeyValue conforming to the
+// "aws.kinesis.stream_name" semantic conventions. It represents the name of the
+// AWS Kinesis [stream] the request refers to. Corresponds to the `--stream-name`
+//
+// parameter of the Kinesis [describe-stream] operation.
+//
+// [stream]: https://docs.aws.amazon.com/streams/latest/dev/introduction.html
+//
+// [describe-stream]: https://docs.aws.amazon.com/cli/latest/reference/kinesis/describe-stream.html
+func AWSKinesisStreamName(val string) attribute.KeyValue {
+ return AWSKinesisStreamNameKey.String(val)
+}
+
+// AWSLambdaInvokedARN returns an attribute KeyValue conforming to the
+// "aws.lambda.invoked_arn" semantic conventions. It represents the full invoked
+// ARN as provided on the `Context` passed to the function (
+// `Lambda-Runtime-Invoked-Function-Arn` header on the `/runtime/invocation/next`
+//
+// applicable).
+func AWSLambdaInvokedARN(val string) attribute.KeyValue {
+ return AWSLambdaInvokedARNKey.String(val)
+}
+
+// AWSLambdaResourceMappingID returns an attribute KeyValue conforming to the
+// "aws.lambda.resource_mapping.id" semantic conventions. It represents the UUID
+// of the [AWS Lambda EvenSource Mapping]. An event source is mapped to a lambda
+// function. It's contents are read by Lambda and used to trigger a function.
+// This isn't available in the lambda execution context or the lambda runtime
+// environtment. This is going to be populated by the AWS SDK for each language
+// when that UUID is present. Some of these operations are
+// Create/Delete/Get/List/Update EventSourceMapping.
+//
+// [AWS Lambda EvenSource Mapping]: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-eventsourcemapping.html
+func AWSLambdaResourceMappingID(val string) attribute.KeyValue {
+ return AWSLambdaResourceMappingIDKey.String(val)
+}
+
+// AWSLogGroupARNs returns an attribute KeyValue conforming to the
+// "aws.log.group.arns" semantic conventions. It represents the Amazon Resource
+// Name(s) (ARN) of the AWS log group(s).
+func AWSLogGroupARNs(val ...string) attribute.KeyValue {
+ return AWSLogGroupARNsKey.StringSlice(val)
+}
+
+// AWSLogGroupNames returns an attribute KeyValue conforming to the
+// "aws.log.group.names" semantic conventions. It represents the name(s) of the
+// AWS log group(s) an application is writing to.
+func AWSLogGroupNames(val ...string) attribute.KeyValue {
+ return AWSLogGroupNamesKey.StringSlice(val)
+}
+
+// AWSLogStreamARNs returns an attribute KeyValue conforming to the
+// "aws.log.stream.arns" semantic conventions. It represents the ARN(s) of the
+// AWS log stream(s).
+func AWSLogStreamARNs(val ...string) attribute.KeyValue {
+ return AWSLogStreamARNsKey.StringSlice(val)
+}
+
+// AWSLogStreamNames returns an attribute KeyValue conforming to the
+// "aws.log.stream.names" semantic conventions. It represents the name(s) of the
+// AWS log stream(s) an application is writing to.
+func AWSLogStreamNames(val ...string) attribute.KeyValue {
+ return AWSLogStreamNamesKey.StringSlice(val)
+}
+
+// AWSRequestID returns an attribute KeyValue conforming to the "aws.request_id"
+// semantic conventions. It represents the AWS request ID as returned in the
+// response headers `x-amzn-requestid`, `x-amzn-request-id` or `x-amz-request-id`
+// .
+func AWSRequestID(val string) attribute.KeyValue {
+ return AWSRequestIDKey.String(val)
+}
+
+// AWSS3Bucket returns an attribute KeyValue conforming to the "aws.s3.bucket"
+// semantic conventions. It represents the S3 bucket name the request refers to.
+// Corresponds to the `--bucket` parameter of the [S3 API] operations.
+//
+// [S3 API]: https://docs.aws.amazon.com/cli/latest/reference/s3api/index.html
+func AWSS3Bucket(val string) attribute.KeyValue {
+ return AWSS3BucketKey.String(val)
+}
+
+// AWSS3CopySource returns an attribute KeyValue conforming to the
+// "aws.s3.copy_source" semantic conventions. It represents the source object (in
+// the form `bucket`/`key`) for the copy operation.
+func AWSS3CopySource(val string) attribute.KeyValue {
+ return AWSS3CopySourceKey.String(val)
+}
+
+// AWSS3Delete returns an attribute KeyValue conforming to the "aws.s3.delete"
+// semantic conventions. It represents the delete request container that
+// specifies the objects to be deleted.
+func AWSS3Delete(val string) attribute.KeyValue {
+ return AWSS3DeleteKey.String(val)
+}
+
+// AWSS3Key returns an attribute KeyValue conforming to the "aws.s3.key" semantic
+// conventions. It represents the S3 object key the request refers to.
+// Corresponds to the `--key` parameter of the [S3 API] operations.
+//
+// [S3 API]: https://docs.aws.amazon.com/cli/latest/reference/s3api/index.html
+func AWSS3Key(val string) attribute.KeyValue {
+ return AWSS3KeyKey.String(val)
+}
+
+// AWSS3PartNumber returns an attribute KeyValue conforming to the
+// "aws.s3.part_number" semantic conventions. It represents the part number of
+// the part being uploaded in a multipart-upload operation. This is a positive
+// integer between 1 and 10,000.
+func AWSS3PartNumber(val int) attribute.KeyValue {
+ return AWSS3PartNumberKey.Int(val)
+}
+
+// AWSS3UploadID returns an attribute KeyValue conforming to the
+// "aws.s3.upload_id" semantic conventions. It represents the upload ID that
+// identifies the multipart upload.
+func AWSS3UploadID(val string) attribute.KeyValue {
+ return AWSS3UploadIDKey.String(val)
+}
+
+// AWSSecretsmanagerSecretARN returns an attribute KeyValue conforming to the
+// "aws.secretsmanager.secret.arn" semantic conventions. It represents the ARN of
+// the Secret stored in the Secrets Mangger.
+func AWSSecretsmanagerSecretARN(val string) attribute.KeyValue {
+ return AWSSecretsmanagerSecretARNKey.String(val)
+}
+
+// AWSSNSTopicARN returns an attribute KeyValue conforming to the
+// "aws.sns.topic.arn" semantic conventions. It represents the ARN of the AWS SNS
+// Topic. An Amazon SNS [topic] is a logical access point that acts as a
+// communication channel.
+//
+// [topic]: https://docs.aws.amazon.com/sns/latest/dg/sns-create-topic.html
+func AWSSNSTopicARN(val string) attribute.KeyValue {
+ return AWSSNSTopicARNKey.String(val)
+}
+
+// AWSSQSQueueURL returns an attribute KeyValue conforming to the
+// "aws.sqs.queue.url" semantic conventions. It represents the URL of the AWS SQS
+// Queue. It's a unique identifier for a queue in Amazon Simple Queue Service
+// (SQS) and is used to access the queue and perform actions on it.
+func AWSSQSQueueURL(val string) attribute.KeyValue {
+ return AWSSQSQueueURLKey.String(val)
+}
+
+// AWSStepFunctionsActivityARN returns an attribute KeyValue conforming to the
+// "aws.step_functions.activity.arn" semantic conventions. It represents the ARN
+// of the AWS Step Functions Activity.
+func AWSStepFunctionsActivityARN(val string) attribute.KeyValue {
+ return AWSStepFunctionsActivityARNKey.String(val)
+}
+
+// AWSStepFunctionsStateMachineARN returns an attribute KeyValue conforming to
+// the "aws.step_functions.state_machine.arn" semantic conventions. It represents
+// the ARN of the AWS Step Functions State Machine.
+func AWSStepFunctionsStateMachineARN(val string) attribute.KeyValue {
+ return AWSStepFunctionsStateMachineARNKey.String(val)
+}
+
+// Enum values for aws.ecs.launchtype
+var (
+ // Amazon EC2
+ // Stability: development
+ AWSECSLaunchtypeEC2 = AWSECSLaunchtypeKey.String("ec2")
+ // Amazon Fargate
+ // Stability: development
+ AWSECSLaunchtypeFargate = AWSECSLaunchtypeKey.String("fargate")
+)
+
+// Namespace: azure
+const (
+ // AzureClientIDKey is the attribute Key conforming to the "azure.client.id"
+ // semantic conventions. It represents the unique identifier of the client
+ // instance.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "3ba4827d-4422-483f-b59f-85b74211c11d", "storage-client-1"
+ AzureClientIDKey = attribute.Key("azure.client.id")
+
+ // AzureCosmosDBConnectionModeKey is the attribute Key conforming to the
+ // "azure.cosmosdb.connection.mode" semantic conventions. It represents the
+ // cosmos client connection mode.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ AzureCosmosDBConnectionModeKey = attribute.Key("azure.cosmosdb.connection.mode")
+
+ // AzureCosmosDBConsistencyLevelKey is the attribute Key conforming to the
+ // "azure.cosmosdb.consistency.level" semantic conventions. It represents the
+ // account or request [consistency level].
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "Eventual", "ConsistentPrefix", "BoundedStaleness", "Strong",
+ // "Session"
+ //
+ // [consistency level]: https://learn.microsoft.com/azure/cosmos-db/consistency-levels
+ AzureCosmosDBConsistencyLevelKey = attribute.Key("azure.cosmosdb.consistency.level")
+
+ // AzureCosmosDBOperationContactedRegionsKey is the attribute Key conforming to
+ // the "azure.cosmosdb.operation.contacted_regions" semantic conventions. It
+ // represents the list of regions contacted during operation in the order that
+ // they were contacted. If there is more than one region listed, it indicates
+ // that the operation was performed on multiple regions i.e. cross-regional
+ // call.
+ //
+ // Type: string[]
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "North Central US", "Australia East", "Australia Southeast"
+ // Note: Region name matches the format of `displayName` in [Azure Location API]
+ //
+ // [Azure Location API]: https://learn.microsoft.com/rest/api/resources/subscriptions/list-locations
+ AzureCosmosDBOperationContactedRegionsKey = attribute.Key("azure.cosmosdb.operation.contacted_regions")
+
+ // AzureCosmosDBOperationRequestChargeKey is the attribute Key conforming to the
+ // "azure.cosmosdb.operation.request_charge" semantic conventions. It represents
+ // the number of request units consumed by the operation.
+ //
+ // Type: double
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 46.18, 1.0
+ AzureCosmosDBOperationRequestChargeKey = attribute.Key("azure.cosmosdb.operation.request_charge")
+
+ // AzureCosmosDBRequestBodySizeKey is the attribute Key conforming to the
+ // "azure.cosmosdb.request.body.size" semantic conventions. It represents the
+ // request payload size in bytes.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ AzureCosmosDBRequestBodySizeKey = attribute.Key("azure.cosmosdb.request.body.size")
+
+ // AzureCosmosDBResponseSubStatusCodeKey is the attribute Key conforming to the
+ // "azure.cosmosdb.response.sub_status_code" semantic conventions. It represents
+ // the cosmos DB sub status code.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 1000, 1002
+ AzureCosmosDBResponseSubStatusCodeKey = attribute.Key("azure.cosmosdb.response.sub_status_code")
+
+ // AzureResourceProviderNamespaceKey is the attribute Key conforming to the
+ // "azure.resource_provider.namespace" semantic conventions. It represents the
+ // [Azure Resource Provider Namespace] as recognized by the client.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "Microsoft.Storage", "Microsoft.KeyVault", "Microsoft.ServiceBus"
+ //
+ // [Azure Resource Provider Namespace]: https://learn.microsoft.com/azure/azure-resource-manager/management/azure-services-resource-providers
+ AzureResourceProviderNamespaceKey = attribute.Key("azure.resource_provider.namespace")
+
+ // AzureServiceRequestIDKey is the attribute Key conforming to the
+ // "azure.service.request.id" semantic conventions. It represents the unique
+ // identifier of the service request. It's generated by the Azure service and
+ // returned with the response.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "00000000-0000-0000-0000-000000000000"
+ AzureServiceRequestIDKey = attribute.Key("azure.service.request.id")
+)
+
+// AzureClientID returns an attribute KeyValue conforming to the
+// "azure.client.id" semantic conventions. It represents the unique identifier of
+// the client instance.
+func AzureClientID(val string) attribute.KeyValue {
+ return AzureClientIDKey.String(val)
+}
+
+// AzureCosmosDBOperationContactedRegions returns an attribute KeyValue
+// conforming to the "azure.cosmosdb.operation.contacted_regions" semantic
+// conventions. It represents the list of regions contacted during operation in
+// the order that they were contacted. If there is more than one region listed,
+// it indicates that the operation was performed on multiple regions i.e.
+// cross-regional call.
+func AzureCosmosDBOperationContactedRegions(val ...string) attribute.KeyValue {
+ return AzureCosmosDBOperationContactedRegionsKey.StringSlice(val)
+}
+
+// AzureCosmosDBOperationRequestCharge returns an attribute KeyValue conforming
+// to the "azure.cosmosdb.operation.request_charge" semantic conventions. It
+// represents the number of request units consumed by the operation.
+func AzureCosmosDBOperationRequestCharge(val float64) attribute.KeyValue {
+ return AzureCosmosDBOperationRequestChargeKey.Float64(val)
+}
+
+// AzureCosmosDBRequestBodySize returns an attribute KeyValue conforming to the
+// "azure.cosmosdb.request.body.size" semantic conventions. It represents the
+// request payload size in bytes.
+func AzureCosmosDBRequestBodySize(val int) attribute.KeyValue {
+ return AzureCosmosDBRequestBodySizeKey.Int(val)
+}
+
+// AzureCosmosDBResponseSubStatusCode returns an attribute KeyValue conforming to
+// the "azure.cosmosdb.response.sub_status_code" semantic conventions. It
+// represents the cosmos DB sub status code.
+func AzureCosmosDBResponseSubStatusCode(val int) attribute.KeyValue {
+ return AzureCosmosDBResponseSubStatusCodeKey.Int(val)
+}
+
+// AzureResourceProviderNamespace returns an attribute KeyValue conforming to the
+// "azure.resource_provider.namespace" semantic conventions. It represents the
+// [Azure Resource Provider Namespace] as recognized by the client.
+//
+// [Azure Resource Provider Namespace]: https://learn.microsoft.com/azure/azure-resource-manager/management/azure-services-resource-providers
+func AzureResourceProviderNamespace(val string) attribute.KeyValue {
+ return AzureResourceProviderNamespaceKey.String(val)
+}
+
+// AzureServiceRequestID returns an attribute KeyValue conforming to the
+// "azure.service.request.id" semantic conventions. It represents the unique
+// identifier of the service request. It's generated by the Azure service and
+// returned with the response.
+func AzureServiceRequestID(val string) attribute.KeyValue {
+ return AzureServiceRequestIDKey.String(val)
+}
+
+// Enum values for azure.cosmosdb.connection.mode
+var (
+ // Gateway (HTTP) connection.
+ // Stability: development
+ AzureCosmosDBConnectionModeGateway = AzureCosmosDBConnectionModeKey.String("gateway")
+ // Direct connection.
+ // Stability: development
+ AzureCosmosDBConnectionModeDirect = AzureCosmosDBConnectionModeKey.String("direct")
+)
+
+// Enum values for azure.cosmosdb.consistency.level
+var (
+ // Strong
+ // Stability: development
+ AzureCosmosDBConsistencyLevelStrong = AzureCosmosDBConsistencyLevelKey.String("Strong")
+ // Bounded Staleness
+ // Stability: development
+ AzureCosmosDBConsistencyLevelBoundedStaleness = AzureCosmosDBConsistencyLevelKey.String("BoundedStaleness")
+ // Session
+ // Stability: development
+ AzureCosmosDBConsistencyLevelSession = AzureCosmosDBConsistencyLevelKey.String("Session")
+ // Eventual
+ // Stability: development
+ AzureCosmosDBConsistencyLevelEventual = AzureCosmosDBConsistencyLevelKey.String("Eventual")
+ // Consistent Prefix
+ // Stability: development
+ AzureCosmosDBConsistencyLevelConsistentPrefix = AzureCosmosDBConsistencyLevelKey.String("ConsistentPrefix")
+)
+
+// Namespace: browser
+const (
+ // BrowserBrandsKey is the attribute Key conforming to the "browser.brands"
+ // semantic conventions. It represents the array of brand name and version
+ // separated by a space.
+ //
+ // Type: string[]
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: " Not A;Brand 99", "Chromium 99", "Chrome 99"
+ // Note: This value is intended to be taken from the [UA client hints API] (
+ // `navigator.userAgentData.brands`).
+ //
+ // [UA client hints API]: https://wicg.github.io/ua-client-hints/#interface
+ BrowserBrandsKey = attribute.Key("browser.brands")
+
+ // BrowserLanguageKey is the attribute Key conforming to the "browser.language"
+ // semantic conventions. It represents the preferred language of the user using
+ // the browser.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "en", "en-US", "fr", "fr-FR"
+ // Note: This value is intended to be taken from the Navigator API
+ // `navigator.language`.
+ BrowserLanguageKey = attribute.Key("browser.language")
+
+ // BrowserMobileKey is the attribute Key conforming to the "browser.mobile"
+ // semantic conventions. It represents a boolean that is true if the browser is
+ // running on a mobile device.
+ //
+ // Type: boolean
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ // Note: This value is intended to be taken from the [UA client hints API] (
+ // `navigator.userAgentData.mobile`). If unavailable, this attribute SHOULD be
+ // left unset.
+ //
+ // [UA client hints API]: https://wicg.github.io/ua-client-hints/#interface
+ BrowserMobileKey = attribute.Key("browser.mobile")
+
+ // BrowserPlatformKey is the attribute Key conforming to the "browser.platform"
+ // semantic conventions. It represents the platform on which the browser is
+ // running.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "Windows", "macOS", "Android"
+ // Note: This value is intended to be taken from the [UA client hints API] (
+ // `navigator.userAgentData.platform`). If unavailable, the legacy
+ // `navigator.platform` API SHOULD NOT be used instead and this attribute SHOULD
+ // be left unset in order for the values to be consistent.
+ // The list of possible values is defined in the
+ // [W3C User-Agent Client Hints specification]. Note that some (but not all) of
+ // these values can overlap with values in the
+ // [`os.type` and `os.name` attributes]. However, for consistency, the values in
+ // the `browser.platform` attribute should capture the exact value that the user
+ // agent provides.
+ //
+ // [UA client hints API]: https://wicg.github.io/ua-client-hints/#interface
+ // [W3C User-Agent Client Hints specification]: https://wicg.github.io/ua-client-hints/#sec-ch-ua-platform
+ // [`os.type` and `os.name` attributes]: ./os.md
+ BrowserPlatformKey = attribute.Key("browser.platform")
+)
+
+// BrowserBrands returns an attribute KeyValue conforming to the "browser.brands"
+// semantic conventions. It represents the array of brand name and version
+// separated by a space.
+func BrowserBrands(val ...string) attribute.KeyValue {
+ return BrowserBrandsKey.StringSlice(val)
+}
+
+// BrowserLanguage returns an attribute KeyValue conforming to the
+// "browser.language" semantic conventions. It represents the preferred language
+// of the user using the browser.
+func BrowserLanguage(val string) attribute.KeyValue {
+ return BrowserLanguageKey.String(val)
+}
+
+// BrowserMobile returns an attribute KeyValue conforming to the "browser.mobile"
+// semantic conventions. It represents a boolean that is true if the browser is
+// running on a mobile device.
+func BrowserMobile(val bool) attribute.KeyValue {
+ return BrowserMobileKey.Bool(val)
+}
+
+// BrowserPlatform returns an attribute KeyValue conforming to the
+// "browser.platform" semantic conventions. It represents the platform on which
+// the browser is running.
+func BrowserPlatform(val string) attribute.KeyValue {
+ return BrowserPlatformKey.String(val)
+}
+
+// Namespace: cassandra
+const (
+ // CassandraConsistencyLevelKey is the attribute Key conforming to the
+ // "cassandra.consistency.level" semantic conventions. It represents the
+ // consistency level of the query. Based on consistency values from [CQL].
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ //
+ // [CQL]: https://docs.datastax.com/en/cassandra-oss/3.0/cassandra/dml/dmlConfigConsistency.html
+ CassandraConsistencyLevelKey = attribute.Key("cassandra.consistency.level")
+
+ // CassandraCoordinatorDCKey is the attribute Key conforming to the
+ // "cassandra.coordinator.dc" semantic conventions. It represents the data
+ // center of the coordinating node for a query.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: us-west-2
+ CassandraCoordinatorDCKey = attribute.Key("cassandra.coordinator.dc")
+
+ // CassandraCoordinatorIDKey is the attribute Key conforming to the
+ // "cassandra.coordinator.id" semantic conventions. It represents the ID of the
+ // coordinating node for a query.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: be13faa2-8574-4d71-926d-27f16cf8a7af
+ CassandraCoordinatorIDKey = attribute.Key("cassandra.coordinator.id")
+
+ // CassandraPageSizeKey is the attribute Key conforming to the
+ // "cassandra.page.size" semantic conventions. It represents the fetch size used
+ // for paging, i.e. how many rows will be returned at once.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 5000
+ CassandraPageSizeKey = attribute.Key("cassandra.page.size")
+
+ // CassandraQueryIdempotentKey is the attribute Key conforming to the
+ // "cassandra.query.idempotent" semantic conventions. It represents the whether
+ // or not the query is idempotent.
+ //
+ // Type: boolean
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ CassandraQueryIdempotentKey = attribute.Key("cassandra.query.idempotent")
+
+ // CassandraSpeculativeExecutionCountKey is the attribute Key conforming to the
+ // "cassandra.speculative_execution.count" semantic conventions. It represents
+ // the number of times a query was speculatively executed. Not set or `0` if the
+ // query was not executed speculatively.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 0, 2
+ CassandraSpeculativeExecutionCountKey = attribute.Key("cassandra.speculative_execution.count")
+)
+
+// CassandraCoordinatorDC returns an attribute KeyValue conforming to the
+// "cassandra.coordinator.dc" semantic conventions. It represents the data center
+// of the coordinating node for a query.
+func CassandraCoordinatorDC(val string) attribute.KeyValue {
+ return CassandraCoordinatorDCKey.String(val)
+}
+
+// CassandraCoordinatorID returns an attribute KeyValue conforming to the
+// "cassandra.coordinator.id" semantic conventions. It represents the ID of the
+// coordinating node for a query.
+func CassandraCoordinatorID(val string) attribute.KeyValue {
+ return CassandraCoordinatorIDKey.String(val)
+}
+
+// CassandraPageSize returns an attribute KeyValue conforming to the
+// "cassandra.page.size" semantic conventions. It represents the fetch size used
+// for paging, i.e. how many rows will be returned at once.
+func CassandraPageSize(val int) attribute.KeyValue {
+ return CassandraPageSizeKey.Int(val)
+}
+
+// CassandraQueryIdempotent returns an attribute KeyValue conforming to the
+// "cassandra.query.idempotent" semantic conventions. It represents the whether
+// or not the query is idempotent.
+func CassandraQueryIdempotent(val bool) attribute.KeyValue {
+ return CassandraQueryIdempotentKey.Bool(val)
+}
+
+// CassandraSpeculativeExecutionCount returns an attribute KeyValue conforming to
+// the "cassandra.speculative_execution.count" semantic conventions. It
+// represents the number of times a query was speculatively executed. Not set or
+// `0` if the query was not executed speculatively.
+func CassandraSpeculativeExecutionCount(val int) attribute.KeyValue {
+ return CassandraSpeculativeExecutionCountKey.Int(val)
+}
+
+// Enum values for cassandra.consistency.level
+var (
+ // All
+ // Stability: development
+ CassandraConsistencyLevelAll = CassandraConsistencyLevelKey.String("all")
+ // Each Quorum
+ // Stability: development
+ CassandraConsistencyLevelEachQuorum = CassandraConsistencyLevelKey.String("each_quorum")
+ // Quorum
+ // Stability: development
+ CassandraConsistencyLevelQuorum = CassandraConsistencyLevelKey.String("quorum")
+ // Local Quorum
+ // Stability: development
+ CassandraConsistencyLevelLocalQuorum = CassandraConsistencyLevelKey.String("local_quorum")
+ // One
+ // Stability: development
+ CassandraConsistencyLevelOne = CassandraConsistencyLevelKey.String("one")
+ // Two
+ // Stability: development
+ CassandraConsistencyLevelTwo = CassandraConsistencyLevelKey.String("two")
+ // Three
+ // Stability: development
+ CassandraConsistencyLevelThree = CassandraConsistencyLevelKey.String("three")
+ // Local One
+ // Stability: development
+ CassandraConsistencyLevelLocalOne = CassandraConsistencyLevelKey.String("local_one")
+ // Any
+ // Stability: development
+ CassandraConsistencyLevelAny = CassandraConsistencyLevelKey.String("any")
+ // Serial
+ // Stability: development
+ CassandraConsistencyLevelSerial = CassandraConsistencyLevelKey.String("serial")
+ // Local Serial
+ // Stability: development
+ CassandraConsistencyLevelLocalSerial = CassandraConsistencyLevelKey.String("local_serial")
+)
+
+// Namespace: cicd
+const (
+ // CICDPipelineActionNameKey is the attribute Key conforming to the
+ // "cicd.pipeline.action.name" semantic conventions. It represents the kind of
+ // action a pipeline run is performing.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "BUILD", "RUN", "SYNC"
+ CICDPipelineActionNameKey = attribute.Key("cicd.pipeline.action.name")
+
+ // CICDPipelineNameKey is the attribute Key conforming to the
+ // "cicd.pipeline.name" semantic conventions. It represents the human readable
+ // name of the pipeline within a CI/CD system.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "Build and Test", "Lint", "Deploy Go Project",
+ // "deploy_to_environment"
+ CICDPipelineNameKey = attribute.Key("cicd.pipeline.name")
+
+ // CICDPipelineResultKey is the attribute Key conforming to the
+ // "cicd.pipeline.result" semantic conventions. It represents the result of a
+ // pipeline run.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "success", "failure", "timeout", "skipped"
+ CICDPipelineResultKey = attribute.Key("cicd.pipeline.result")
+
+ // CICDPipelineRunIDKey is the attribute Key conforming to the
+ // "cicd.pipeline.run.id" semantic conventions. It represents the unique
+ // identifier of a pipeline run within a CI/CD system.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "120912"
+ CICDPipelineRunIDKey = attribute.Key("cicd.pipeline.run.id")
+
+ // CICDPipelineRunStateKey is the attribute Key conforming to the
+ // "cicd.pipeline.run.state" semantic conventions. It represents the pipeline
+ // run goes through these states during its lifecycle.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "pending", "executing", "finalizing"
+ CICDPipelineRunStateKey = attribute.Key("cicd.pipeline.run.state")
+
+ // CICDPipelineRunURLFullKey is the attribute Key conforming to the
+ // "cicd.pipeline.run.url.full" semantic conventions. It represents the [URL] of
+ // the pipeline run, providing the complete address in order to locate and
+ // identify the pipeline run.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ // "https://github.com/open-telemetry/semantic-conventions/actions/runs/9753949763?pr=1075"
+ //
+ // [URL]: https://wikipedia.org/wiki/URL
+ CICDPipelineRunURLFullKey = attribute.Key("cicd.pipeline.run.url.full")
+
+ // CICDPipelineTaskNameKey is the attribute Key conforming to the
+ // "cicd.pipeline.task.name" semantic conventions. It represents the human
+ // readable name of a task within a pipeline. Task here most closely aligns with
+ // a [computing process] in a pipeline. Other terms for tasks include commands,
+ // steps, and procedures.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "Run GoLang Linter", "Go Build", "go-test", "deploy_binary"
+ //
+ // [computing process]: https://wikipedia.org/wiki/Pipeline_(computing)
+ CICDPipelineTaskNameKey = attribute.Key("cicd.pipeline.task.name")
+
+ // CICDPipelineTaskRunIDKey is the attribute Key conforming to the
+ // "cicd.pipeline.task.run.id" semantic conventions. It represents the unique
+ // identifier of a task run within a pipeline.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "12097"
+ CICDPipelineTaskRunIDKey = attribute.Key("cicd.pipeline.task.run.id")
+
+ // CICDPipelineTaskRunResultKey is the attribute Key conforming to the
+ // "cicd.pipeline.task.run.result" semantic conventions. It represents the
+ // result of a task run.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "success", "failure", "timeout", "skipped"
+ CICDPipelineTaskRunResultKey = attribute.Key("cicd.pipeline.task.run.result")
+
+ // CICDPipelineTaskRunURLFullKey is the attribute Key conforming to the
+ // "cicd.pipeline.task.run.url.full" semantic conventions. It represents the
+ // [URL] of the pipeline task run, providing the complete address in order to
+ // locate and identify the pipeline task run.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ // "https://github.com/open-telemetry/semantic-conventions/actions/runs/9753949763/job/26920038674?pr=1075"
+ //
+ // [URL]: https://wikipedia.org/wiki/URL
+ CICDPipelineTaskRunURLFullKey = attribute.Key("cicd.pipeline.task.run.url.full")
+
+ // CICDPipelineTaskTypeKey is the attribute Key conforming to the
+ // "cicd.pipeline.task.type" semantic conventions. It represents the type of the
+ // task within a pipeline.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "build", "test", "deploy"
+ CICDPipelineTaskTypeKey = attribute.Key("cicd.pipeline.task.type")
+
+ // CICDSystemComponentKey is the attribute Key conforming to the
+ // "cicd.system.component" semantic conventions. It represents the name of a
+ // component of the CICD system.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "controller", "scheduler", "agent"
+ CICDSystemComponentKey = attribute.Key("cicd.system.component")
+
+ // CICDWorkerIDKey is the attribute Key conforming to the "cicd.worker.id"
+ // semantic conventions. It represents the unique identifier of a worker within
+ // a CICD system.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "abc123", "10.0.1.2", "controller"
+ CICDWorkerIDKey = attribute.Key("cicd.worker.id")
+
+ // CICDWorkerNameKey is the attribute Key conforming to the "cicd.worker.name"
+ // semantic conventions. It represents the name of a worker within a CICD
+ // system.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "agent-abc", "controller", "Ubuntu LTS"
+ CICDWorkerNameKey = attribute.Key("cicd.worker.name")
+
+ // CICDWorkerStateKey is the attribute Key conforming to the "cicd.worker.state"
+ // semantic conventions. It represents the state of a CICD worker / agent.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "idle", "busy", "down"
+ CICDWorkerStateKey = attribute.Key("cicd.worker.state")
+
+ // CICDWorkerURLFullKey is the attribute Key conforming to the
+ // "cicd.worker.url.full" semantic conventions. It represents the [URL] of the
+ // worker, providing the complete address in order to locate and identify the
+ // worker.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "https://cicd.example.org/worker/abc123"
+ //
+ // [URL]: https://wikipedia.org/wiki/URL
+ CICDWorkerURLFullKey = attribute.Key("cicd.worker.url.full")
+)
+
+// CICDPipelineName returns an attribute KeyValue conforming to the
+// "cicd.pipeline.name" semantic conventions. It represents the human readable
+// name of the pipeline within a CI/CD system.
+func CICDPipelineName(val string) attribute.KeyValue {
+ return CICDPipelineNameKey.String(val)
+}
+
+// CICDPipelineRunID returns an attribute KeyValue conforming to the
+// "cicd.pipeline.run.id" semantic conventions. It represents the unique
+// identifier of a pipeline run within a CI/CD system.
+func CICDPipelineRunID(val string) attribute.KeyValue {
+ return CICDPipelineRunIDKey.String(val)
+}
+
+// CICDPipelineRunURLFull returns an attribute KeyValue conforming to the
+// "cicd.pipeline.run.url.full" semantic conventions. It represents the [URL] of
+// the pipeline run, providing the complete address in order to locate and
+// identify the pipeline run.
+//
+// [URL]: https://wikipedia.org/wiki/URL
+func CICDPipelineRunURLFull(val string) attribute.KeyValue {
+ return CICDPipelineRunURLFullKey.String(val)
+}
+
+// CICDPipelineTaskName returns an attribute KeyValue conforming to the
+// "cicd.pipeline.task.name" semantic conventions. It represents the human
+// readable name of a task within a pipeline. Task here most closely aligns with
+// a [computing process] in a pipeline. Other terms for tasks include commands,
+// steps, and procedures.
+//
+// [computing process]: https://wikipedia.org/wiki/Pipeline_(computing)
+func CICDPipelineTaskName(val string) attribute.KeyValue {
+ return CICDPipelineTaskNameKey.String(val)
+}
+
+// CICDPipelineTaskRunID returns an attribute KeyValue conforming to the
+// "cicd.pipeline.task.run.id" semantic conventions. It represents the unique
+// identifier of a task run within a pipeline.
+func CICDPipelineTaskRunID(val string) attribute.KeyValue {
+ return CICDPipelineTaskRunIDKey.String(val)
+}
+
+// CICDPipelineTaskRunURLFull returns an attribute KeyValue conforming to the
+// "cicd.pipeline.task.run.url.full" semantic conventions. It represents the
+// [URL] of the pipeline task run, providing the complete address in order to
+// locate and identify the pipeline task run.
+//
+// [URL]: https://wikipedia.org/wiki/URL
+func CICDPipelineTaskRunURLFull(val string) attribute.KeyValue {
+ return CICDPipelineTaskRunURLFullKey.String(val)
+}
+
+// CICDSystemComponent returns an attribute KeyValue conforming to the
+// "cicd.system.component" semantic conventions. It represents the name of a
+// component of the CICD system.
+func CICDSystemComponent(val string) attribute.KeyValue {
+ return CICDSystemComponentKey.String(val)
+}
+
+// CICDWorkerID returns an attribute KeyValue conforming to the "cicd.worker.id"
+// semantic conventions. It represents the unique identifier of a worker within a
+// CICD system.
+func CICDWorkerID(val string) attribute.KeyValue {
+ return CICDWorkerIDKey.String(val)
+}
+
+// CICDWorkerName returns an attribute KeyValue conforming to the
+// "cicd.worker.name" semantic conventions. It represents the name of a worker
+// within a CICD system.
+func CICDWorkerName(val string) attribute.KeyValue {
+ return CICDWorkerNameKey.String(val)
+}
+
+// CICDWorkerURLFull returns an attribute KeyValue conforming to the
+// "cicd.worker.url.full" semantic conventions. It represents the [URL] of the
+// worker, providing the complete address in order to locate and identify the
+// worker.
+//
+// [URL]: https://wikipedia.org/wiki/URL
+func CICDWorkerURLFull(val string) attribute.KeyValue {
+ return CICDWorkerURLFullKey.String(val)
+}
+
+// Enum values for cicd.pipeline.action.name
+var (
+ // The pipeline run is executing a build.
+ // Stability: development
+ CICDPipelineActionNameBuild = CICDPipelineActionNameKey.String("BUILD")
+ // The pipeline run is executing.
+ // Stability: development
+ CICDPipelineActionNameRun = CICDPipelineActionNameKey.String("RUN")
+ // The pipeline run is executing a sync.
+ // Stability: development
+ CICDPipelineActionNameSync = CICDPipelineActionNameKey.String("SYNC")
+)
+
+// Enum values for cicd.pipeline.result
+var (
+ // The pipeline run finished successfully.
+ // Stability: development
+ CICDPipelineResultSuccess = CICDPipelineResultKey.String("success")
+ // The pipeline run did not finish successfully, eg. due to a compile error or a
+ // failing test. Such failures are usually detected by non-zero exit codes of
+ // the tools executed in the pipeline run.
+ // Stability: development
+ CICDPipelineResultFailure = CICDPipelineResultKey.String("failure")
+ // The pipeline run failed due to an error in the CICD system, eg. due to the
+ // worker being killed.
+ // Stability: development
+ CICDPipelineResultError = CICDPipelineResultKey.String("error")
+ // A timeout caused the pipeline run to be interrupted.
+ // Stability: development
+ CICDPipelineResultTimeout = CICDPipelineResultKey.String("timeout")
+ // The pipeline run was cancelled, eg. by a user manually cancelling the
+ // pipeline run.
+ // Stability: development
+ CICDPipelineResultCancellation = CICDPipelineResultKey.String("cancellation")
+ // The pipeline run was skipped, eg. due to a precondition not being met.
+ // Stability: development
+ CICDPipelineResultSkip = CICDPipelineResultKey.String("skip")
+)
+
+// Enum values for cicd.pipeline.run.state
+var (
+ // The run pending state spans from the event triggering the pipeline run until
+ // the execution of the run starts (eg. time spent in a queue, provisioning
+ // agents, creating run resources).
+ //
+ // Stability: development
+ CICDPipelineRunStatePending = CICDPipelineRunStateKey.String("pending")
+ // The executing state spans the execution of any run tasks (eg. build, test).
+ // Stability: development
+ CICDPipelineRunStateExecuting = CICDPipelineRunStateKey.String("executing")
+ // The finalizing state spans from when the run has finished executing (eg.
+ // cleanup of run resources).
+ // Stability: development
+ CICDPipelineRunStateFinalizing = CICDPipelineRunStateKey.String("finalizing")
+)
+
+// Enum values for cicd.pipeline.task.run.result
+var (
+ // The task run finished successfully.
+ // Stability: development
+ CICDPipelineTaskRunResultSuccess = CICDPipelineTaskRunResultKey.String("success")
+ // The task run did not finish successfully, eg. due to a compile error or a
+ // failing test. Such failures are usually detected by non-zero exit codes of
+ // the tools executed in the task run.
+ // Stability: development
+ CICDPipelineTaskRunResultFailure = CICDPipelineTaskRunResultKey.String("failure")
+ // The task run failed due to an error in the CICD system, eg. due to the worker
+ // being killed.
+ // Stability: development
+ CICDPipelineTaskRunResultError = CICDPipelineTaskRunResultKey.String("error")
+ // A timeout caused the task run to be interrupted.
+ // Stability: development
+ CICDPipelineTaskRunResultTimeout = CICDPipelineTaskRunResultKey.String("timeout")
+ // The task run was cancelled, eg. by a user manually cancelling the task run.
+ // Stability: development
+ CICDPipelineTaskRunResultCancellation = CICDPipelineTaskRunResultKey.String("cancellation")
+ // The task run was skipped, eg. due to a precondition not being met.
+ // Stability: development
+ CICDPipelineTaskRunResultSkip = CICDPipelineTaskRunResultKey.String("skip")
+)
+
+// Enum values for cicd.pipeline.task.type
+var (
+ // build
+ // Stability: development
+ CICDPipelineTaskTypeBuild = CICDPipelineTaskTypeKey.String("build")
+ // test
+ // Stability: development
+ CICDPipelineTaskTypeTest = CICDPipelineTaskTypeKey.String("test")
+ // deploy
+ // Stability: development
+ CICDPipelineTaskTypeDeploy = CICDPipelineTaskTypeKey.String("deploy")
+)
+
+// Enum values for cicd.worker.state
+var (
+ // The worker is not performing work for the CICD system. It is available to the
+ // CICD system to perform work on (online / idle).
+ // Stability: development
+ CICDWorkerStateAvailable = CICDWorkerStateKey.String("available")
+ // The worker is performing work for the CICD system.
+ // Stability: development
+ CICDWorkerStateBusy = CICDWorkerStateKey.String("busy")
+ // The worker is not available to the CICD system (disconnected / down).
+ // Stability: development
+ CICDWorkerStateOffline = CICDWorkerStateKey.String("offline")
+)
+
+// Namespace: client
+const (
+ // ClientAddressKey is the attribute Key conforming to the "client.address"
+ // semantic conventions. It represents the client address - domain name if
+ // available without reverse DNS lookup; otherwise, IP address or Unix domain
+ // socket name.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ //
+ // Examples: "client.example.com", "10.1.2.80", "/tmp/my.sock"
+ // Note: When observed from the server side, and when communicating through an
+ // intermediary, `client.address` SHOULD represent the client address behind any
+ // intermediaries, for example proxies, if it's available.
+ ClientAddressKey = attribute.Key("client.address")
+
+ // ClientPortKey is the attribute Key conforming to the "client.port" semantic
+ // conventions. It represents the client port number.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ //
+ // Examples: 65123
+ // Note: When observed from the server side, and when communicating through an
+ // intermediary, `client.port` SHOULD represent the client port behind any
+ // intermediaries, for example proxies, if it's available.
+ ClientPortKey = attribute.Key("client.port")
+)
+
+// ClientAddress returns an attribute KeyValue conforming to the "client.address"
+// semantic conventions. It represents the client address - domain name if
+// available without reverse DNS lookup; otherwise, IP address or Unix domain
+// socket name.
+func ClientAddress(val string) attribute.KeyValue {
+ return ClientAddressKey.String(val)
+}
+
+// ClientPort returns an attribute KeyValue conforming to the "client.port"
+// semantic conventions. It represents the client port number.
+func ClientPort(val int) attribute.KeyValue {
+ return ClientPortKey.Int(val)
+}
+
+// Namespace: cloud
+const (
+ // CloudAccountIDKey is the attribute Key conforming to the "cloud.account.id"
+ // semantic conventions. It represents the cloud account ID the resource is
+ // assigned to.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "111111111111", "opentelemetry"
+ CloudAccountIDKey = attribute.Key("cloud.account.id")
+
+ // CloudAvailabilityZoneKey is the attribute Key conforming to the
+ // "cloud.availability_zone" semantic conventions. It represents the cloud
+ // regions often have multiple, isolated locations known as zones to increase
+ // availability. Availability zone represents the zone where the resource is
+ // running.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "us-east-1c"
+ // Note: Availability zones are called "zones" on Alibaba Cloud and Google
+ // Cloud.
+ CloudAvailabilityZoneKey = attribute.Key("cloud.availability_zone")
+
+ // CloudPlatformKey is the attribute Key conforming to the "cloud.platform"
+ // semantic conventions. It represents the cloud platform in use.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ // Note: The prefix of the service SHOULD match the one specified in
+ // `cloud.provider`.
+ CloudPlatformKey = attribute.Key("cloud.platform")
+
+ // CloudProviderKey is the attribute Key conforming to the "cloud.provider"
+ // semantic conventions. It represents the name of the cloud provider.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ CloudProviderKey = attribute.Key("cloud.provider")
+
+ // CloudRegionKey is the attribute Key conforming to the "cloud.region" semantic
+ // conventions. It represents the geographical region within a cloud provider.
+ // When associated with a resource, this attribute specifies the region where
+ // the resource operates. When calling services or APIs deployed on a cloud,
+ // this attribute identifies the region where the called destination is
+ // deployed.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "us-central1", "us-east-1"
+ // Note: Refer to your provider's docs to see the available regions, for example
+ // [Alibaba Cloud regions], [AWS regions], [Azure regions],
+ // [Google Cloud regions], or [Tencent Cloud regions].
+ //
+ // [Alibaba Cloud regions]: https://www.alibabacloud.com/help/doc-detail/40654.htm
+ // [AWS regions]: https://aws.amazon.com/about-aws/global-infrastructure/regions_az/
+ // [Azure regions]: https://azure.microsoft.com/global-infrastructure/geographies/
+ // [Google Cloud regions]: https://cloud.google.com/about/locations
+ // [Tencent Cloud regions]: https://www.tencentcloud.com/document/product/213/6091
+ CloudRegionKey = attribute.Key("cloud.region")
+
+ // CloudResourceIDKey is the attribute Key conforming to the "cloud.resource_id"
+ // semantic conventions. It represents the cloud provider-specific native
+ // identifier of the monitored cloud resource (e.g. an [ARN] on AWS, a
+ // [fully qualified resource ID] on Azure, a [full resource name] on GCP).
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "arn:aws:lambda:REGION:ACCOUNT_ID:function:my-function",
+ // "//run.googleapis.com/projects/PROJECT_ID/locations/LOCATION_ID/services/SERVICE_ID",
+ // "/subscriptions//resourceGroups/
+ // /providers/Microsoft.Web/sites//functions/"
+ // Note: On some cloud providers, it may not be possible to determine the full
+ // ID at startup,
+ // so it may be necessary to set `cloud.resource_id` as a span attribute
+ // instead.
+ //
+ // The exact value to use for `cloud.resource_id` depends on the cloud provider.
+ // The following well-known definitions MUST be used if you set this attribute
+ // and they apply:
+ //
+ // - **AWS Lambda:** The function [ARN].
+ // Take care not to use the "invoked ARN" directly but replace any
+ // [alias suffix]
+ // with the resolved function version, as the same runtime instance may be
+ // invocable with
+ // multiple different aliases.
+ // - **GCP:** The [URI of the resource]
+ // - **Azure:** The [Fully Qualified Resource ID] of the invoked function,
+ // *not* the function app, having the form
+ //
+ // `/subscriptions//resourceGroups//providers/Microsoft.Web/sites//functions/`
+ // .
+ // This means that a span attribute MUST be used, as an Azure function app
+ // can host multiple functions that would usually share
+ // a TracerProvider.
+ //
+ //
+ // [ARN]: https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html
+ // [fully qualified resource ID]: https://learn.microsoft.com/rest/api/resources/resources/get-by-id
+ // [full resource name]: https://google.aip.dev/122#full-resource-names
+ // [ARN]: https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html
+ // [alias suffix]: https://docs.aws.amazon.com/lambda/latest/dg/configuration-aliases.html
+ // [URI of the resource]: https://cloud.google.com/iam/docs/full-resource-names
+ // [Fully Qualified Resource ID]: https://learn.microsoft.com/rest/api/resources/resources/get-by-id
+ CloudResourceIDKey = attribute.Key("cloud.resource_id")
+)
+
+// CloudAccountID returns an attribute KeyValue conforming to the
+// "cloud.account.id" semantic conventions. It represents the cloud account ID
+// the resource is assigned to.
+func CloudAccountID(val string) attribute.KeyValue {
+ return CloudAccountIDKey.String(val)
+}
+
+// CloudAvailabilityZone returns an attribute KeyValue conforming to the
+// "cloud.availability_zone" semantic conventions. It represents the cloud
+// regions often have multiple, isolated locations known as zones to increase
+// availability. Availability zone represents the zone where the resource is
+// running.
+func CloudAvailabilityZone(val string) attribute.KeyValue {
+ return CloudAvailabilityZoneKey.String(val)
+}
+
+// CloudRegion returns an attribute KeyValue conforming to the "cloud.region"
+// semantic conventions. It represents the geographical region within a cloud
+// provider. When associated with a resource, this attribute specifies the region
+// where the resource operates. When calling services or APIs deployed on a
+// cloud, this attribute identifies the region where the called destination is
+// deployed.
+func CloudRegion(val string) attribute.KeyValue {
+ return CloudRegionKey.String(val)
+}
+
+// CloudResourceID returns an attribute KeyValue conforming to the
+// "cloud.resource_id" semantic conventions. It represents the cloud
+// provider-specific native identifier of the monitored cloud resource (e.g. an
+// [ARN] on AWS, a [fully qualified resource ID] on Azure, a [full resource name]
+//
+// on GCP).
+//
+// [ARN]: https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html
+// [fully qualified resource ID]: https://learn.microsoft.com/rest/api/resources/resources/get-by-id
+// [full resource name]: https://google.aip.dev/122#full-resource-names
+func CloudResourceID(val string) attribute.KeyValue {
+ return CloudResourceIDKey.String(val)
+}
+
+// Enum values for cloud.platform
+var (
+ // Akamai Cloud Compute
+ // Stability: development
+ CloudPlatformAkamaiCloudCompute = CloudPlatformKey.String("akamai_cloud.compute")
+ // Alibaba Cloud Elastic Compute Service
+ // Stability: development
+ CloudPlatformAlibabaCloudECS = CloudPlatformKey.String("alibaba_cloud_ecs")
+ // Alibaba Cloud Function Compute
+ // Stability: development
+ CloudPlatformAlibabaCloudFC = CloudPlatformKey.String("alibaba_cloud_fc")
+ // Red Hat OpenShift on Alibaba Cloud
+ // Stability: development
+ CloudPlatformAlibabaCloudOpenShift = CloudPlatformKey.String("alibaba_cloud_openshift")
+ // AWS Elastic Compute Cloud
+ // Stability: development
+ CloudPlatformAWSEC2 = CloudPlatformKey.String("aws_ec2")
+ // AWS Elastic Container Service
+ // Stability: development
+ CloudPlatformAWSECS = CloudPlatformKey.String("aws_ecs")
+ // AWS Elastic Kubernetes Service
+ // Stability: development
+ CloudPlatformAWSEKS = CloudPlatformKey.String("aws_eks")
+ // AWS Lambda
+ // Stability: development
+ CloudPlatformAWSLambda = CloudPlatformKey.String("aws_lambda")
+ // AWS Elastic Beanstalk
+ // Stability: development
+ CloudPlatformAWSElasticBeanstalk = CloudPlatformKey.String("aws_elastic_beanstalk")
+ // AWS App Runner
+ // Stability: development
+ CloudPlatformAWSAppRunner = CloudPlatformKey.String("aws_app_runner")
+ // Red Hat OpenShift on AWS (ROSA)
+ // Stability: development
+ CloudPlatformAWSOpenShift = CloudPlatformKey.String("aws_openshift")
+ // Azure Virtual Machines
+ // Stability: development
+ CloudPlatformAzureVM = CloudPlatformKey.String("azure.vm")
+ // Azure Container Apps
+ // Stability: development
+ CloudPlatformAzureContainerApps = CloudPlatformKey.String("azure.container_apps")
+ // Azure Container Instances
+ // Stability: development
+ CloudPlatformAzureContainerInstances = CloudPlatformKey.String("azure.container_instances")
+ // Azure Kubernetes Service
+ // Stability: development
+ CloudPlatformAzureAKS = CloudPlatformKey.String("azure.aks")
+ // Azure Functions
+ // Stability: development
+ CloudPlatformAzureFunctions = CloudPlatformKey.String("azure.functions")
+ // Azure App Service
+ // Stability: development
+ CloudPlatformAzureAppService = CloudPlatformKey.String("azure.app_service")
+ // Azure Red Hat OpenShift
+ // Stability: development
+ CloudPlatformAzureOpenShift = CloudPlatformKey.String("azure.openshift")
+ // Google Vertex AI Agent Engine
+ // Stability: development
+ CloudPlatformGCPAgentEngine = CloudPlatformKey.String("gcp.agent_engine")
+ // Google Bare Metal Solution (BMS)
+ // Stability: development
+ CloudPlatformGCPBareMetalSolution = CloudPlatformKey.String("gcp_bare_metal_solution")
+ // Google Cloud Compute Engine (GCE)
+ // Stability: development
+ CloudPlatformGCPComputeEngine = CloudPlatformKey.String("gcp_compute_engine")
+ // Google Cloud Run
+ // Stability: development
+ CloudPlatformGCPCloudRun = CloudPlatformKey.String("gcp_cloud_run")
+ // Google Cloud Kubernetes Engine (GKE)
+ // Stability: development
+ CloudPlatformGCPKubernetesEngine = CloudPlatformKey.String("gcp_kubernetes_engine")
+ // Google Cloud Functions (GCF)
+ // Stability: development
+ CloudPlatformGCPCloudFunctions = CloudPlatformKey.String("gcp_cloud_functions")
+ // Google Cloud App Engine (GAE)
+ // Stability: development
+ CloudPlatformGCPAppEngine = CloudPlatformKey.String("gcp_app_engine")
+ // Red Hat OpenShift on Google Cloud
+ // Stability: development
+ CloudPlatformGCPOpenShift = CloudPlatformKey.String("gcp_openshift")
+ // Server on Hetzner Cloud
+ // Stability: development
+ CloudPlatformHetznerCloudServer = CloudPlatformKey.String("hetzner.cloud_server")
+ // Red Hat OpenShift on IBM Cloud
+ // Stability: development
+ CloudPlatformIBMCloudOpenShift = CloudPlatformKey.String("ibm_cloud_openshift")
+ // Compute on Oracle Cloud Infrastructure (OCI)
+ // Stability: development
+ CloudPlatformOracleCloudCompute = CloudPlatformKey.String("oracle_cloud_compute")
+ // Kubernetes Engine (OKE) on Oracle Cloud Infrastructure (OCI)
+ // Stability: development
+ CloudPlatformOracleCloudOKE = CloudPlatformKey.String("oracle_cloud_oke")
+ // Tencent Cloud Cloud Virtual Machine (CVM)
+ // Stability: development
+ CloudPlatformTencentCloudCVM = CloudPlatformKey.String("tencent_cloud_cvm")
+ // Tencent Cloud Elastic Kubernetes Service (EKS)
+ // Stability: development
+ CloudPlatformTencentCloudEKS = CloudPlatformKey.String("tencent_cloud_eks")
+ // Tencent Cloud Serverless Cloud Function (SCF)
+ // Stability: development
+ CloudPlatformTencentCloudSCF = CloudPlatformKey.String("tencent_cloud_scf")
+ // Vultr Cloud Compute
+ // Stability: development
+ CloudPlatformVultrCloudCompute = CloudPlatformKey.String("vultr.cloud_compute")
+)
+
+// Enum values for cloud.provider
+var (
+ // Akamai Cloud
+ // Stability: development
+ CloudProviderAkamaiCloud = CloudProviderKey.String("akamai_cloud")
+ // Alibaba Cloud
+ // Stability: development
+ CloudProviderAlibabaCloud = CloudProviderKey.String("alibaba_cloud")
+ // Amazon Web Services
+ // Stability: development
+ CloudProviderAWS = CloudProviderKey.String("aws")
+ // Microsoft Azure
+ // Stability: development
+ CloudProviderAzure = CloudProviderKey.String("azure")
+ // Google Cloud Platform
+ // Stability: development
+ CloudProviderGCP = CloudProviderKey.String("gcp")
+ // Heroku Platform as a Service
+ // Stability: development
+ CloudProviderHeroku = CloudProviderKey.String("heroku")
+ // Hetzner
+ // Stability: development
+ CloudProviderHetzner = CloudProviderKey.String("hetzner")
+ // IBM Cloud
+ // Stability: development
+ CloudProviderIBMCloud = CloudProviderKey.String("ibm_cloud")
+ // Oracle Cloud Infrastructure (OCI)
+ // Stability: development
+ CloudProviderOracleCloud = CloudProviderKey.String("oracle_cloud")
+ // Tencent Cloud
+ // Stability: development
+ CloudProviderTencentCloud = CloudProviderKey.String("tencent_cloud")
+ // Vultr
+ // Stability: development
+ CloudProviderVultr = CloudProviderKey.String("vultr")
+)
+
+// Namespace: cloudevents
+const (
+ // CloudEventsEventIDKey is the attribute Key conforming to the
+ // "cloudevents.event_id" semantic conventions. It represents the [event_id]
+ // uniquely identifies the event.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "123e4567-e89b-12d3-a456-426614174000", "0001"
+ //
+ // [event_id]: https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#id
+ CloudEventsEventIDKey = attribute.Key("cloudevents.event_id")
+
+ // CloudEventsEventSourceKey is the attribute Key conforming to the
+ // "cloudevents.event_source" semantic conventions. It represents the [source]
+ // identifies the context in which an event happened.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "https://github.com/cloudevents", "/cloudevents/spec/pull/123",
+ // "my-service"
+ //
+ // [source]: https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#source-1
+ CloudEventsEventSourceKey = attribute.Key("cloudevents.event_source")
+
+ // CloudEventsEventSpecVersionKey is the attribute Key conforming to the
+ // "cloudevents.event_spec_version" semantic conventions. It represents the
+ // [version of the CloudEvents specification] which the event uses.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 1.0
+ //
+ // [version of the CloudEvents specification]: https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#specversion
+ CloudEventsEventSpecVersionKey = attribute.Key("cloudevents.event_spec_version")
+
+ // CloudEventsEventSubjectKey is the attribute Key conforming to the
+ // "cloudevents.event_subject" semantic conventions. It represents the [subject]
+ // of the event in the context of the event producer (identified by source).
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: mynewfile.jpg
+ //
+ // [subject]: https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#subject
+ CloudEventsEventSubjectKey = attribute.Key("cloudevents.event_subject")
+
+ // CloudEventsEventTypeKey is the attribute Key conforming to the
+ // "cloudevents.event_type" semantic conventions. It represents the [event_type]
+ // contains a value describing the type of event related to the originating
+ // occurrence.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "com.github.pull_request.opened", "com.example.object.deleted.v2"
+ //
+ // [event_type]: https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#type
+ CloudEventsEventTypeKey = attribute.Key("cloudevents.event_type")
+)
+
+// CloudEventsEventID returns an attribute KeyValue conforming to the
+// "cloudevents.event_id" semantic conventions. It represents the [event_id]
+// uniquely identifies the event.
+//
+// [event_id]: https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#id
+func CloudEventsEventID(val string) attribute.KeyValue {
+ return CloudEventsEventIDKey.String(val)
+}
+
+// CloudEventsEventSource returns an attribute KeyValue conforming to the
+// "cloudevents.event_source" semantic conventions. It represents the [source]
+// identifies the context in which an event happened.
+//
+// [source]: https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#source-1
+func CloudEventsEventSource(val string) attribute.KeyValue {
+ return CloudEventsEventSourceKey.String(val)
+}
+
+// CloudEventsEventSpecVersion returns an attribute KeyValue conforming to the
+// "cloudevents.event_spec_version" semantic conventions. It represents the
+// [version of the CloudEvents specification] which the event uses.
+//
+// [version of the CloudEvents specification]: https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#specversion
+func CloudEventsEventSpecVersion(val string) attribute.KeyValue {
+ return CloudEventsEventSpecVersionKey.String(val)
+}
+
+// CloudEventsEventSubject returns an attribute KeyValue conforming to the
+// "cloudevents.event_subject" semantic conventions. It represents the [subject]
+// of the event in the context of the event producer (identified by source).
+//
+// [subject]: https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#subject
+func CloudEventsEventSubject(val string) attribute.KeyValue {
+ return CloudEventsEventSubjectKey.String(val)
+}
+
+// CloudEventsEventType returns an attribute KeyValue conforming to the
+// "cloudevents.event_type" semantic conventions. It represents the [event_type]
+// contains a value describing the type of event related to the originating
+// occurrence.
+//
+// [event_type]: https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#type
+func CloudEventsEventType(val string) attribute.KeyValue {
+ return CloudEventsEventTypeKey.String(val)
+}
+
+// Namespace: cloudfoundry
+const (
+ // CloudFoundryAppIDKey is the attribute Key conforming to the
+ // "cloudfoundry.app.id" semantic conventions. It represents the guid of the
+ // application.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "218fc5a9-a5f1-4b54-aa05-46717d0ab26d"
+ // Note: Application instrumentation should use the value from environment
+ // variable `VCAP_APPLICATION.application_id`. This is the same value as
+ // reported by `cf app --guid`.
+ CloudFoundryAppIDKey = attribute.Key("cloudfoundry.app.id")
+
+ // CloudFoundryAppInstanceIDKey is the attribute Key conforming to the
+ // "cloudfoundry.app.instance.id" semantic conventions. It represents the index
+ // of the application instance. 0 when just one instance is active.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "0", "1"
+ // Note: CloudFoundry defines the `instance_id` in the [Loggregator v2 envelope]
+ // .
+ // It is used for logs and metrics emitted by CloudFoundry. It is
+ // supposed to contain the application instance index for applications
+ // deployed on the runtime.
+ //
+ // Application instrumentation should use the value from environment
+ // variable `CF_INSTANCE_INDEX`.
+ //
+ // [Loggregator v2 envelope]: https://github.com/cloudfoundry/loggregator-api#v2-envelope
+ CloudFoundryAppInstanceIDKey = attribute.Key("cloudfoundry.app.instance.id")
+
+ // CloudFoundryAppNameKey is the attribute Key conforming to the
+ // "cloudfoundry.app.name" semantic conventions. It represents the name of the
+ // application.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "my-app-name"
+ // Note: Application instrumentation should use the value from environment
+ // variable `VCAP_APPLICATION.application_name`. This is the same value
+ // as reported by `cf apps`.
+ CloudFoundryAppNameKey = attribute.Key("cloudfoundry.app.name")
+
+ // CloudFoundryOrgIDKey is the attribute Key conforming to the
+ // "cloudfoundry.org.id" semantic conventions. It represents the guid of the
+ // CloudFoundry org the application is running in.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "218fc5a9-a5f1-4b54-aa05-46717d0ab26d"
+ // Note: Application instrumentation should use the value from environment
+ // variable `VCAP_APPLICATION.org_id`. This is the same value as
+ // reported by `cf org --guid`.
+ CloudFoundryOrgIDKey = attribute.Key("cloudfoundry.org.id")
+
+ // CloudFoundryOrgNameKey is the attribute Key conforming to the
+ // "cloudfoundry.org.name" semantic conventions. It represents the name of the
+ // CloudFoundry organization the app is running in.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "my-org-name"
+ // Note: Application instrumentation should use the value from environment
+ // variable `VCAP_APPLICATION.org_name`. This is the same value as
+ // reported by `cf orgs`.
+ CloudFoundryOrgNameKey = attribute.Key("cloudfoundry.org.name")
+
+ // CloudFoundryProcessIDKey is the attribute Key conforming to the
+ // "cloudfoundry.process.id" semantic conventions. It represents the UID
+ // identifying the process.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "218fc5a9-a5f1-4b54-aa05-46717d0ab26d"
+ // Note: Application instrumentation should use the value from environment
+ // variable `VCAP_APPLICATION.process_id`. It is supposed to be equal to
+ // `VCAP_APPLICATION.app_id` for applications deployed to the runtime.
+ // For system components, this could be the actual PID.
+ CloudFoundryProcessIDKey = attribute.Key("cloudfoundry.process.id")
+
+ // CloudFoundryProcessTypeKey is the attribute Key conforming to the
+ // "cloudfoundry.process.type" semantic conventions. It represents the type of
+ // process.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "web"
+ // Note: CloudFoundry applications can consist of multiple jobs. Usually the
+ // main process will be of type `web`. There can be additional background
+ // tasks or side-cars with different process types.
+ CloudFoundryProcessTypeKey = attribute.Key("cloudfoundry.process.type")
+
+ // CloudFoundrySpaceIDKey is the attribute Key conforming to the
+ // "cloudfoundry.space.id" semantic conventions. It represents the guid of the
+ // CloudFoundry space the application is running in.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "218fc5a9-a5f1-4b54-aa05-46717d0ab26d"
+ // Note: Application instrumentation should use the value from environment
+ // variable `VCAP_APPLICATION.space_id`. This is the same value as
+ // reported by `cf space --guid`.
+ CloudFoundrySpaceIDKey = attribute.Key("cloudfoundry.space.id")
+
+ // CloudFoundrySpaceNameKey is the attribute Key conforming to the
+ // "cloudfoundry.space.name" semantic conventions. It represents the name of the
+ // CloudFoundry space the application is running in.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "my-space-name"
+ // Note: Application instrumentation should use the value from environment
+ // variable `VCAP_APPLICATION.space_name`. This is the same value as
+ // reported by `cf spaces`.
+ CloudFoundrySpaceNameKey = attribute.Key("cloudfoundry.space.name")
+
+ // CloudFoundrySystemIDKey is the attribute Key conforming to the
+ // "cloudfoundry.system.id" semantic conventions. It represents a guid or
+ // another name describing the event source.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "cf/gorouter"
+ // Note: CloudFoundry defines the `source_id` in the [Loggregator v2 envelope].
+ // It is used for logs and metrics emitted by CloudFoundry. It is
+ // supposed to contain the component name, e.g. "gorouter", for
+ // CloudFoundry components.
+ //
+ // When system components are instrumented, values from the
+ // [Bosh spec]
+ // should be used. The `system.id` should be set to
+ // `spec.deployment/spec.name`.
+ //
+ // [Loggregator v2 envelope]: https://github.com/cloudfoundry/loggregator-api#v2-envelope
+ // [Bosh spec]: https://bosh.io/docs/jobs/#properties-spec
+ CloudFoundrySystemIDKey = attribute.Key("cloudfoundry.system.id")
+
+ // CloudFoundrySystemInstanceIDKey is the attribute Key conforming to the
+ // "cloudfoundry.system.instance.id" semantic conventions. It represents a guid
+ // describing the concrete instance of the event source.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "218fc5a9-a5f1-4b54-aa05-46717d0ab26d"
+ // Note: CloudFoundry defines the `instance_id` in the [Loggregator v2 envelope]
+ // .
+ // It is used for logs and metrics emitted by CloudFoundry. It is
+ // supposed to contain the vm id for CloudFoundry components.
+ //
+ // When system components are instrumented, values from the
+ // [Bosh spec]
+ // should be used. The `system.instance.id` should be set to `spec.id`.
+ //
+ // [Loggregator v2 envelope]: https://github.com/cloudfoundry/loggregator-api#v2-envelope
+ // [Bosh spec]: https://bosh.io/docs/jobs/#properties-spec
+ CloudFoundrySystemInstanceIDKey = attribute.Key("cloudfoundry.system.instance.id")
+)
+
+// CloudFoundryAppID returns an attribute KeyValue conforming to the
+// "cloudfoundry.app.id" semantic conventions. It represents the guid of the
+// application.
+func CloudFoundryAppID(val string) attribute.KeyValue {
+ return CloudFoundryAppIDKey.String(val)
+}
+
+// CloudFoundryAppInstanceID returns an attribute KeyValue conforming to the
+// "cloudfoundry.app.instance.id" semantic conventions. It represents the index
+// of the application instance. 0 when just one instance is active.
+func CloudFoundryAppInstanceID(val string) attribute.KeyValue {
+ return CloudFoundryAppInstanceIDKey.String(val)
+}
+
+// CloudFoundryAppName returns an attribute KeyValue conforming to the
+// "cloudfoundry.app.name" semantic conventions. It represents the name of the
+// application.
+func CloudFoundryAppName(val string) attribute.KeyValue {
+ return CloudFoundryAppNameKey.String(val)
+}
+
+// CloudFoundryOrgID returns an attribute KeyValue conforming to the
+// "cloudfoundry.org.id" semantic conventions. It represents the guid of the
+// CloudFoundry org the application is running in.
+func CloudFoundryOrgID(val string) attribute.KeyValue {
+ return CloudFoundryOrgIDKey.String(val)
+}
+
+// CloudFoundryOrgName returns an attribute KeyValue conforming to the
+// "cloudfoundry.org.name" semantic conventions. It represents the name of the
+// CloudFoundry organization the app is running in.
+func CloudFoundryOrgName(val string) attribute.KeyValue {
+ return CloudFoundryOrgNameKey.String(val)
+}
+
+// CloudFoundryProcessID returns an attribute KeyValue conforming to the
+// "cloudfoundry.process.id" semantic conventions. It represents the UID
+// identifying the process.
+func CloudFoundryProcessID(val string) attribute.KeyValue {
+ return CloudFoundryProcessIDKey.String(val)
+}
+
+// CloudFoundryProcessType returns an attribute KeyValue conforming to the
+// "cloudfoundry.process.type" semantic conventions. It represents the type of
+// process.
+func CloudFoundryProcessType(val string) attribute.KeyValue {
+ return CloudFoundryProcessTypeKey.String(val)
+}
+
+// CloudFoundrySpaceID returns an attribute KeyValue conforming to the
+// "cloudfoundry.space.id" semantic conventions. It represents the guid of the
+// CloudFoundry space the application is running in.
+func CloudFoundrySpaceID(val string) attribute.KeyValue {
+ return CloudFoundrySpaceIDKey.String(val)
+}
+
+// CloudFoundrySpaceName returns an attribute KeyValue conforming to the
+// "cloudfoundry.space.name" semantic conventions. It represents the name of the
+// CloudFoundry space the application is running in.
+func CloudFoundrySpaceName(val string) attribute.KeyValue {
+ return CloudFoundrySpaceNameKey.String(val)
+}
+
+// CloudFoundrySystemID returns an attribute KeyValue conforming to the
+// "cloudfoundry.system.id" semantic conventions. It represents a guid or another
+// name describing the event source.
+func CloudFoundrySystemID(val string) attribute.KeyValue {
+ return CloudFoundrySystemIDKey.String(val)
+}
+
+// CloudFoundrySystemInstanceID returns an attribute KeyValue conforming to the
+// "cloudfoundry.system.instance.id" semantic conventions. It represents a guid
+// describing the concrete instance of the event source.
+func CloudFoundrySystemInstanceID(val string) attribute.KeyValue {
+ return CloudFoundrySystemInstanceIDKey.String(val)
+}
+
+// Namespace: code
+const (
+ // CodeColumnNumberKey is the attribute Key conforming to the
+ // "code.column.number" semantic conventions. It represents the column number in
+ // `code.file.path` best representing the operation. It SHOULD point within the
+ // code unit named in `code.function.name`. This attribute MUST NOT be used on
+ // the Profile signal since the data is already captured in 'message Line'. This
+ // constraint is imposed to prevent redundancy and maintain data integrity.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ CodeColumnNumberKey = attribute.Key("code.column.number")
+
+ // CodeFilePathKey is the attribute Key conforming to the "code.file.path"
+ // semantic conventions. It represents the source code file name that identifies
+ // the code unit as uniquely as possible (preferably an absolute file path).
+ // This attribute MUST NOT be used on the Profile signal since the data is
+ // already captured in 'message Function'. This constraint is imposed to prevent
+ // redundancy and maintain data integrity.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ //
+ // Examples: /usr/local/MyApplication/content_root/app/index.php
+ CodeFilePathKey = attribute.Key("code.file.path")
+
+ // CodeFunctionNameKey is the attribute Key conforming to the
+ // "code.function.name" semantic conventions. It represents the method or
+ // function fully-qualified name without arguments. The value should fit the
+ // natural representation of the language runtime, which is also likely the same
+ // used within `code.stacktrace` attribute value. This attribute MUST NOT be
+ // used on the Profile signal since the data is already captured in 'message
+ // Function'. This constraint is imposed to prevent redundancy and maintain data
+ // integrity.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ //
+ // Examples: "com.example.MyHttpService.serveRequest",
+ // "GuzzleHttp\Client::transfer", "fopen"
+ // Note: Values and format depends on each language runtime, thus it is
+ // impossible to provide an exhaustive list of examples.
+ // The values are usually the same (or prefixes of) the ones found in native
+ // stack trace representation stored in
+ // `code.stacktrace` without information on arguments.
+ //
+ // Examples:
+ //
+ // - Java method: `com.example.MyHttpService.serveRequest`
+ // - Java anonymous class method: `com.mycompany.Main$1.myMethod`
+ // - Java lambda method:
+ // `com.mycompany.Main$$Lambda/0x0000748ae4149c00.myMethod`
+ // - PHP function: `GuzzleHttp\Client::transfer`
+ // - Go function: `github.com/my/repo/pkg.foo.func5`
+ // - Elixir: `OpenTelemetry.Ctx.new`
+ // - Erlang: `opentelemetry_ctx:new`
+ // - Rust: `playground::my_module::my_cool_func`
+ // - C function: `fopen`
+ CodeFunctionNameKey = attribute.Key("code.function.name")
+
+ // CodeLineNumberKey is the attribute Key conforming to the "code.line.number"
+ // semantic conventions. It represents the line number in `code.file.path` best
+ // representing the operation. It SHOULD point within the code unit named in
+ // `code.function.name`. This attribute MUST NOT be used on the Profile signal
+ // since the data is already captured in 'message Line'. This constraint is
+ // imposed to prevent redundancy and maintain data integrity.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ CodeLineNumberKey = attribute.Key("code.line.number")
+
+ // CodeStacktraceKey is the attribute Key conforming to the "code.stacktrace"
+ // semantic conventions. It represents a stacktrace as a string in the natural
+ // representation for the language runtime. The representation is identical to
+ // [`exception.stacktrace`]. This attribute MUST NOT be used on the Profile
+ // signal since the data is already captured in 'message Location'. This
+ // constraint is imposed to prevent redundancy and maintain data integrity.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ //
+ // Examples: at com.example.GenerateTrace.methodB(GenerateTrace.java:13)\n at
+ // com.example.GenerateTrace.methodA(GenerateTrace.java:9)\n at
+ // com.example.GenerateTrace.main(GenerateTrace.java:5)
+ //
+ // [`exception.stacktrace`]: /docs/exceptions/exceptions-spans.md#stacktrace-representation
+ CodeStacktraceKey = attribute.Key("code.stacktrace")
+)
+
+// CodeColumnNumber returns an attribute KeyValue conforming to the
+// "code.column.number" semantic conventions. It represents the column number in
+// `code.file.path` best representing the operation. It SHOULD point within the
+// code unit named in `code.function.name`. This attribute MUST NOT be used on
+// the Profile signal since the data is already captured in 'message Line'. This
+// constraint is imposed to prevent redundancy and maintain data integrity.
+func CodeColumnNumber(val int) attribute.KeyValue {
+ return CodeColumnNumberKey.Int(val)
+}
+
+// CodeFilePath returns an attribute KeyValue conforming to the "code.file.path"
+// semantic conventions. It represents the source code file name that identifies
+// the code unit as uniquely as possible (preferably an absolute file path). This
+// attribute MUST NOT be used on the Profile signal since the data is already
+// captured in 'message Function'. This constraint is imposed to prevent
+// redundancy and maintain data integrity.
+func CodeFilePath(val string) attribute.KeyValue {
+ return CodeFilePathKey.String(val)
+}
+
+// CodeFunctionName returns an attribute KeyValue conforming to the
+// "code.function.name" semantic conventions. It represents the method or
+// function fully-qualified name without arguments. The value should fit the
+// natural representation of the language runtime, which is also likely the same
+// used within `code.stacktrace` attribute value. This attribute MUST NOT be used
+// on the Profile signal since the data is already captured in 'message
+// Function'. This constraint is imposed to prevent redundancy and maintain data
+// integrity.
+func CodeFunctionName(val string) attribute.KeyValue {
+ return CodeFunctionNameKey.String(val)
+}
+
+// CodeLineNumber returns an attribute KeyValue conforming to the
+// "code.line.number" semantic conventions. It represents the line number in
+// `code.file.path` best representing the operation. It SHOULD point within the
+// code unit named in `code.function.name`. This attribute MUST NOT be used on
+// the Profile signal since the data is already captured in 'message Line'. This
+// constraint is imposed to prevent redundancy and maintain data integrity.
+func CodeLineNumber(val int) attribute.KeyValue {
+ return CodeLineNumberKey.Int(val)
+}
+
+// CodeStacktrace returns an attribute KeyValue conforming to the
+// "code.stacktrace" semantic conventions. It represents a stacktrace as a string
+// in the natural representation for the language runtime. The representation is
+// identical to [`exception.stacktrace`]. This attribute MUST NOT be used on the
+// Profile signal since the data is already captured in 'message Location'. This
+// constraint is imposed to prevent redundancy and maintain data integrity.
+//
+// [`exception.stacktrace`]: /docs/exceptions/exceptions-spans.md#stacktrace-representation
+func CodeStacktrace(val string) attribute.KeyValue {
+ return CodeStacktraceKey.String(val)
+}
+
+// Namespace: container
+const (
+ // ContainerCommandKey is the attribute Key conforming to the
+ // "container.command" semantic conventions. It represents the command used to
+ // run the container (i.e. the command name).
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "otelcontribcol"
+ // Note: If using embedded credentials or sensitive data, it is recommended to
+ // remove them to prevent potential leakage.
+ ContainerCommandKey = attribute.Key("container.command")
+
+ // ContainerCommandArgsKey is the attribute Key conforming to the
+ // "container.command_args" semantic conventions. It represents the all the
+ // command arguments (including the command/executable itself) run by the
+ // container.
+ //
+ // Type: string[]
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "otelcontribcol", "--config", "config.yaml"
+ ContainerCommandArgsKey = attribute.Key("container.command_args")
+
+ // ContainerCommandLineKey is the attribute Key conforming to the
+ // "container.command_line" semantic conventions. It represents the full command
+ // run by the container as a single string representing the full command.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "otelcontribcol --config config.yaml"
+ ContainerCommandLineKey = attribute.Key("container.command_line")
+
+ // ContainerCSIPluginNameKey is the attribute Key conforming to the
+ // "container.csi.plugin.name" semantic conventions. It represents the name of
+ // the CSI ([Container Storage Interface]) plugin used by the volume.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "pd.csi.storage.gke.io"
+ // Note: This can sometimes be referred to as a "driver" in CSI implementations.
+ // This should represent the `name` field of the GetPluginInfo RPC.
+ //
+ // [Container Storage Interface]: https://github.com/container-storage-interface/spec
+ ContainerCSIPluginNameKey = attribute.Key("container.csi.plugin.name")
+
+ // ContainerCSIVolumeIDKey is the attribute Key conforming to the
+ // "container.csi.volume.id" semantic conventions. It represents the unique
+ // volume ID returned by the CSI ([Container Storage Interface]) plugin.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "projects/my-gcp-project/zones/my-gcp-zone/disks/my-gcp-disk"
+ // Note: This can sometimes be referred to as a "volume handle" in CSI
+ // implementations. This should represent the `Volume.volume_id` field in CSI
+ // spec.
+ //
+ // [Container Storage Interface]: https://github.com/container-storage-interface/spec
+ ContainerCSIVolumeIDKey = attribute.Key("container.csi.volume.id")
+
+ // ContainerIDKey is the attribute Key conforming to the "container.id" semantic
+ // conventions. It represents the container ID. Usually a UUID, as for example
+ // used to [identify Docker containers]. The UUID might be abbreviated.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Beta
+ //
+ // Examples: "a3bf90e006b2"
+ //
+ // [identify Docker containers]: https://docs.docker.com/engine/containers/run/#container-identification
+ ContainerIDKey = attribute.Key("container.id")
+
+ // ContainerImageIDKey is the attribute Key conforming to the
+ // "container.image.id" semantic conventions. It represents the runtime specific
+ // image identifier. Usually a hash algorithm followed by a UUID.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ // "sha256:19c92d0a00d1b66d897bceaa7319bee0dd38a10a851c60bcec9474aa3f01e50f"
+ // Note: Docker defines a sha256 of the image id; `container.image.id`
+ // corresponds to the `Image` field from the Docker container inspect [API]
+ // endpoint.
+ // K8s defines a link to the container registry repository with digest
+ // `"imageID": "registry.azurecr.io /namespace/service/dockerfile@sha256:bdeabd40c3a8a492eaf9e8e44d0ebbb84bac7ee25ac0cf8a7159d25f62555625"`
+ // .
+ // The ID is assigned by the container runtime and can vary in different
+ // environments. Consider using `oci.manifest.digest` if it is important to
+ // identify the same image in different environments/runtimes.
+ //
+ // [API]: https://docs.docker.com/reference/api/engine/version/v1.52/#tag/Container/operation/ContainerInspect
+ ContainerImageIDKey = attribute.Key("container.image.id")
+
+ // ContainerImageNameKey is the attribute Key conforming to the
+ // "container.image.name" semantic conventions. It represents the name of the
+ // image the container was built on.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Beta
+ //
+ // Examples: "gcr.io/opentelemetry/operator"
+ ContainerImageNameKey = attribute.Key("container.image.name")
+
+ // ContainerImageRepoDigestsKey is the attribute Key conforming to the
+ // "container.image.repo_digests" semantic conventions. It represents the repo
+ // digests of the container image as provided by the container runtime.
+ //
+ // Type: string[]
+ // RequirementLevel: Recommended
+ // Stability: Beta
+ //
+ // Examples:
+ // "example@sha256:afcc7f1ac1b49db317a7196c902e61c6c3c4607d63599ee1a82d702d249a0ccb",
+ // "internal.registry.example.com:5000/example@sha256:b69959407d21e8a062e0416bf13405bb2b71ed7a84dde4158ebafacfa06f5578"
+ // Note: [Docker] and [CRI] report those under the `RepoDigests` field.
+ //
+ // [Docker]: https://docs.docker.com/reference/api/engine/version/v1.52/#tag/Image/operation/ImageInspect
+ // [CRI]: https://github.com/kubernetes/cri-api/blob/c75ef5b473bbe2d0a4fc92f82235efd665ea8e9f/pkg/apis/runtime/v1/api.proto#L1237-L1238
+ ContainerImageRepoDigestsKey = attribute.Key("container.image.repo_digests")
+
+ // ContainerImageTagsKey is the attribute Key conforming to the
+ // "container.image.tags" semantic conventions. It represents the container
+ // image tags. An example can be found in [Docker Image Inspect]. Should be only
+ // the `` section of the full name for example from
+ // `registry.example.com/my-org/my-image:`.
+ //
+ // Type: string[]
+ // RequirementLevel: Recommended
+ // Stability: Beta
+ //
+ // Examples: "v1.27.1", "3.5.7-0"
+ //
+ // [Docker Image Inspect]: https://docs.docker.com/reference/api/engine/version/v1.52/#tag/Image/operation/ImageInspect
+ ContainerImageTagsKey = attribute.Key("container.image.tags")
+
+ // ContainerNameKey is the attribute Key conforming to the "container.name"
+ // semantic conventions. It represents the container name used by container
+ // runtime.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "opentelemetry-autoconf"
+ ContainerNameKey = attribute.Key("container.name")
+
+ // ContainerRuntimeDescriptionKey is the attribute Key conforming to the
+ // "container.runtime.description" semantic conventions. It represents a
+ // description about the runtime which could include, for example details about
+ // the CRI/API version being used or other customisations.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "docker://19.3.1 - CRI: 1.22.0"
+ ContainerRuntimeDescriptionKey = attribute.Key("container.runtime.description")
+
+ // ContainerRuntimeNameKey is the attribute Key conforming to the
+ // "container.runtime.name" semantic conventions. It represents the container
+ // runtime managing this container.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "docker", "containerd", "rkt"
+ ContainerRuntimeNameKey = attribute.Key("container.runtime.name")
+
+ // ContainerRuntimeVersionKey is the attribute Key conforming to the
+ // "container.runtime.version" semantic conventions. It represents the version
+ // of the runtime of this process, as returned by the runtime without
+ // modification.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 1.0.0
+ ContainerRuntimeVersionKey = attribute.Key("container.runtime.version")
+)
+
+// ContainerCommand returns an attribute KeyValue conforming to the
+// "container.command" semantic conventions. It represents the command used to
+// run the container (i.e. the command name).
+func ContainerCommand(val string) attribute.KeyValue {
+ return ContainerCommandKey.String(val)
+}
+
+// ContainerCommandArgs returns an attribute KeyValue conforming to the
+// "container.command_args" semantic conventions. It represents the all the
+// command arguments (including the command/executable itself) run by the
+// container.
+func ContainerCommandArgs(val ...string) attribute.KeyValue {
+ return ContainerCommandArgsKey.StringSlice(val)
+}
+
+// ContainerCommandLine returns an attribute KeyValue conforming to the
+// "container.command_line" semantic conventions. It represents the full command
+// run by the container as a single string representing the full command.
+func ContainerCommandLine(val string) attribute.KeyValue {
+ return ContainerCommandLineKey.String(val)
+}
+
+// ContainerCSIPluginName returns an attribute KeyValue conforming to the
+// "container.csi.plugin.name" semantic conventions. It represents the name of
+// the CSI ([Container Storage Interface]) plugin used by the volume.
+//
+// [Container Storage Interface]: https://github.com/container-storage-interface/spec
+func ContainerCSIPluginName(val string) attribute.KeyValue {
+ return ContainerCSIPluginNameKey.String(val)
+}
+
+// ContainerCSIVolumeID returns an attribute KeyValue conforming to the
+// "container.csi.volume.id" semantic conventions. It represents the unique
+// volume ID returned by the CSI ([Container Storage Interface]) plugin.
+//
+// [Container Storage Interface]: https://github.com/container-storage-interface/spec
+func ContainerCSIVolumeID(val string) attribute.KeyValue {
+ return ContainerCSIVolumeIDKey.String(val)
+}
+
+// ContainerID returns an attribute KeyValue conforming to the "container.id"
+// semantic conventions. It represents the container ID. Usually a UUID, as for
+// example used to [identify Docker containers]. The UUID might be abbreviated.
+//
+// [identify Docker containers]: https://docs.docker.com/engine/containers/run/#container-identification
+func ContainerID(val string) attribute.KeyValue {
+ return ContainerIDKey.String(val)
+}
+
+// ContainerImageID returns an attribute KeyValue conforming to the
+// "container.image.id" semantic conventions. It represents the runtime specific
+// image identifier. Usually a hash algorithm followed by a UUID.
+func ContainerImageID(val string) attribute.KeyValue {
+ return ContainerImageIDKey.String(val)
+}
+
+// ContainerImageName returns an attribute KeyValue conforming to the
+// "container.image.name" semantic conventions. It represents the name of the
+// image the container was built on.
+func ContainerImageName(val string) attribute.KeyValue {
+ return ContainerImageNameKey.String(val)
+}
+
+// ContainerImageRepoDigests returns an attribute KeyValue conforming to the
+// "container.image.repo_digests" semantic conventions. It represents the repo
+// digests of the container image as provided by the container runtime.
+func ContainerImageRepoDigests(val ...string) attribute.KeyValue {
+ return ContainerImageRepoDigestsKey.StringSlice(val)
+}
+
+// ContainerImageTags returns an attribute KeyValue conforming to the
+// "container.image.tags" semantic conventions. It represents the container image
+// tags. An example can be found in [Docker Image Inspect]. Should be only the
+// `` section of the full name for example from
+// `registry.example.com/my-org/my-image:`.
+//
+// [Docker Image Inspect]: https://docs.docker.com/reference/api/engine/version/v1.52/#tag/Image/operation/ImageInspect
+func ContainerImageTags(val ...string) attribute.KeyValue {
+ return ContainerImageTagsKey.StringSlice(val)
+}
+
+// ContainerLabel returns an attribute KeyValue conforming to the
+// "container.label" semantic conventions. It represents the container labels,
+// `` being the label name, the value being the label value.
+func ContainerLabel(key string, val string) attribute.KeyValue {
+ return attribute.String("container.label."+key, val)
+}
+
+// ContainerName returns an attribute KeyValue conforming to the "container.name"
+// semantic conventions. It represents the container name used by container
+// runtime.
+func ContainerName(val string) attribute.KeyValue {
+ return ContainerNameKey.String(val)
+}
+
+// ContainerRuntimeDescription returns an attribute KeyValue conforming to the
+// "container.runtime.description" semantic conventions. It represents a
+// description about the runtime which could include, for example details about
+// the CRI/API version being used or other customisations.
+func ContainerRuntimeDescription(val string) attribute.KeyValue {
+ return ContainerRuntimeDescriptionKey.String(val)
+}
+
+// ContainerRuntimeName returns an attribute KeyValue conforming to the
+// "container.runtime.name" semantic conventions. It represents the container
+// runtime managing this container.
+func ContainerRuntimeName(val string) attribute.KeyValue {
+ return ContainerRuntimeNameKey.String(val)
+}
+
+// ContainerRuntimeVersion returns an attribute KeyValue conforming to the
+// "container.runtime.version" semantic conventions. It represents the version of
+// the runtime of this process, as returned by the runtime without modification.
+func ContainerRuntimeVersion(val string) attribute.KeyValue {
+ return ContainerRuntimeVersionKey.String(val)
+}
+
+// Namespace: cpu
+const (
+ // CPULogicalNumberKey is the attribute Key conforming to the
+ // "cpu.logical_number" semantic conventions. It represents the logical CPU
+ // number [0..n-1].
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 1
+ CPULogicalNumberKey = attribute.Key("cpu.logical_number")
+
+ // CPUModeKey is the attribute Key conforming to the "cpu.mode" semantic
+ // conventions. It represents the mode of the CPU.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "user", "system"
+ CPUModeKey = attribute.Key("cpu.mode")
+)
+
+// CPULogicalNumber returns an attribute KeyValue conforming to the
+// "cpu.logical_number" semantic conventions. It represents the logical CPU
+// number [0..n-1].
+func CPULogicalNumber(val int) attribute.KeyValue {
+ return CPULogicalNumberKey.Int(val)
+}
+
+// Enum values for cpu.mode
+var (
+ // User
+ // Stability: development
+ CPUModeUser = CPUModeKey.String("user")
+ // System
+ // Stability: development
+ CPUModeSystem = CPUModeKey.String("system")
+ // Nice
+ // Stability: development
+ CPUModeNice = CPUModeKey.String("nice")
+ // Idle
+ // Stability: development
+ CPUModeIdle = CPUModeKey.String("idle")
+ // IO Wait
+ // Stability: development
+ CPUModeIOWait = CPUModeKey.String("iowait")
+ // Interrupt
+ // Stability: development
+ CPUModeInterrupt = CPUModeKey.String("interrupt")
+ // Steal
+ // Stability: development
+ CPUModeSteal = CPUModeKey.String("steal")
+ // Kernel
+ // Stability: development
+ CPUModeKernel = CPUModeKey.String("kernel")
+)
+
+// Namespace: db
+const (
+ // DBClientConnectionPoolNameKey is the attribute Key conforming to the
+ // "db.client.connection.pool.name" semantic conventions. It represents the name
+ // of the connection pool; unique within the instrumented application. In case
+ // the connection pool implementation doesn't provide a name, instrumentation
+ // SHOULD use a combination of parameters that would make the name unique, for
+ // example, combining attributes `server.address`, `server.port`, and
+ // `db.namespace`, formatted as `server.address:server.port/db.namespace`.
+ // Instrumentations that generate connection pool name following different
+ // patterns SHOULD document it.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "myDataSource"
+ DBClientConnectionPoolNameKey = attribute.Key("db.client.connection.pool.name")
+
+ // DBClientConnectionStateKey is the attribute Key conforming to the
+ // "db.client.connection.state" semantic conventions. It represents the state of
+ // a connection in the pool.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "idle"
+ DBClientConnectionStateKey = attribute.Key("db.client.connection.state")
+
+ // DBCollectionNameKey is the attribute Key conforming to the
+ // "db.collection.name" semantic conventions. It represents the name of a
+ // collection (table, container) within the database.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ //
+ // Examples: "public.users", "customers"
+ // Note: It is RECOMMENDED to capture the value as provided by the application
+ // without attempting to do any case normalization.
+ //
+ // The collection name SHOULD NOT be extracted from `db.query.text`,
+ // when the database system supports query text with multiple collections
+ // in non-batch operations.
+ //
+ // For batch operations, if the individual operations are known to have the same
+ // collection name then that collection name SHOULD be used.
+ DBCollectionNameKey = attribute.Key("db.collection.name")
+
+ // DBNamespaceKey is the attribute Key conforming to the "db.namespace" semantic
+ // conventions. It represents the name of the database, fully qualified within
+ // the server address and port.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ //
+ // Examples: "customers", "test.users"
+ // Note: If a database system has multiple namespace components, they SHOULD be
+ // concatenated from the most general to the most specific namespace component,
+ // using `|` as a separator between the components. Any missing components (and
+ // their associated separators) SHOULD be omitted.
+ // Semantic conventions for individual database systems SHOULD document what
+ // `db.namespace` means in the context of that system.
+ // It is RECOMMENDED to capture the value as provided by the application without
+ // attempting to do any case normalization.
+ DBNamespaceKey = attribute.Key("db.namespace")
+
+ // DBOperationBatchSizeKey is the attribute Key conforming to the
+ // "db.operation.batch.size" semantic conventions. It represents the number of
+ // queries included in a batch operation.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ //
+ // Examples: 2, 3, 4
+ // Note: Operations are only considered batches when they contain two or more
+ // operations, and so `db.operation.batch.size` SHOULD never be `1`.
+ DBOperationBatchSizeKey = attribute.Key("db.operation.batch.size")
+
+ // DBOperationNameKey is the attribute Key conforming to the "db.operation.name"
+ // semantic conventions. It represents the name of the operation or command
+ // being executed.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ //
+ // Examples: "findAndModify", "HMSET", "SELECT"
+ // Note: It is RECOMMENDED to capture the value as provided by the application
+ // without attempting to do any case normalization.
+ //
+ // The operation name SHOULD NOT be extracted from `db.query.text`,
+ // when the database system supports query text with multiple operations
+ // in non-batch operations.
+ //
+ // If spaces can occur in the operation name, multiple consecutive spaces
+ // SHOULD be normalized to a single space.
+ //
+ // For batch operations, if the individual operations are known to have the same
+ // operation name
+ // then that operation name SHOULD be used prepended by `BATCH `,
+ // otherwise `db.operation.name` SHOULD be `BATCH` or some other database
+ // system specific term if more applicable.
+ DBOperationNameKey = attribute.Key("db.operation.name")
+
+ // DBQuerySummaryKey is the attribute Key conforming to the "db.query.summary"
+ // semantic conventions. It represents the low cardinality summary of a database
+ // query.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ //
+ // Examples: "SELECT wuser_table", "INSERT shipping_details SELECT orders", "get
+ // user by id"
+ // Note: The query summary describes a class of database queries and is useful
+ // as a grouping key, especially when analyzing telemetry for database
+ // calls involving complex queries.
+ //
+ // Summary may be available to the instrumentation through
+ // instrumentation hooks or other means. If it is not available,
+ // instrumentations
+ // that support query parsing SHOULD generate a summary following
+ // [Generating query summary]
+ // section.
+ //
+ // For batch operations, if the individual operations are known to have the same
+ // query summary
+ // then that query summary SHOULD be used prepended by `BATCH `,
+ // otherwise `db.query.summary` SHOULD be `BATCH` or some other database
+ // system specific term if more applicable.
+ //
+ // [Generating query summary]: /docs/db/database-spans.md#generating-a-summary-of-the-query
+ DBQuerySummaryKey = attribute.Key("db.query.summary")
+
+ // DBQueryTextKey is the attribute Key conforming to the "db.query.text"
+ // semantic conventions. It represents the database query being executed.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ //
+ // Examples: "SELECT * FROM wuser_table where username = ?", "SET mykey ?"
+ // Note: For sanitization see [Sanitization of `db.query.text`].
+ // For batch operations, if the individual operations are known to have the same
+ // query text then that query text SHOULD be used, otherwise all of the
+ // individual query texts SHOULD be concatenated with separator `; ` or some
+ // other database system specific separator if more applicable.
+ // Parameterized query text SHOULD NOT be sanitized. Even though parameterized
+ // query text can potentially have sensitive data, by using a parameterized
+ // query the user is giving a strong signal that any sensitive data will be
+ // passed as parameter values, and the benefit to observability of capturing the
+ // static part of the query text by default outweighs the risk.
+ //
+ // [Sanitization of `db.query.text`]: /docs/db/database-spans.md#sanitization-of-dbquerytext
+ DBQueryTextKey = attribute.Key("db.query.text")
+
+ // DBResponseReturnedRowsKey is the attribute Key conforming to the
+ // "db.response.returned_rows" semantic conventions. It represents the number of
+ // rows returned by the operation.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 10, 30, 1000
+ DBResponseReturnedRowsKey = attribute.Key("db.response.returned_rows")
+
+ // DBResponseStatusCodeKey is the attribute Key conforming to the
+ // "db.response.status_code" semantic conventions. It represents the database
+ // response status code.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ //
+ // Examples: "102", "ORA-17002", "08P01", "404"
+ // Note: The status code returned by the database. Usually it represents an
+ // error code, but may also represent partial success, warning, or differentiate
+ // between various types of successful outcomes.
+ // Semantic conventions for individual database systems SHOULD document what
+ // `db.response.status_code` means in the context of that system.
+ DBResponseStatusCodeKey = attribute.Key("db.response.status_code")
+
+ // DBStoredProcedureNameKey is the attribute Key conforming to the
+ // "db.stored_procedure.name" semantic conventions. It represents the name of a
+ // stored procedure within the database.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ //
+ // Examples: "GetCustomer"
+ // Note: It is RECOMMENDED to capture the value as provided by the application
+ // without attempting to do any case normalization.
+ //
+ // For batch operations, if the individual operations are known to have the same
+ // stored procedure name then that stored procedure name SHOULD be used.
+ DBStoredProcedureNameKey = attribute.Key("db.stored_procedure.name")
+
+ // DBSystemNameKey is the attribute Key conforming to the "db.system.name"
+ // semantic conventions. It represents the database management system (DBMS)
+ // product as identified by the client instrumentation.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ //
+ // Examples:
+ // Note: The actual DBMS may differ from the one identified by the client. For
+ // example, when using PostgreSQL client libraries to connect to a CockroachDB,
+ // the `db.system.name` is set to `postgresql` based on the instrumentation's
+ // best knowledge.
+ DBSystemNameKey = attribute.Key("db.system.name")
+)
+
+// DBClientConnectionPoolName returns an attribute KeyValue conforming to the
+// "db.client.connection.pool.name" semantic conventions. It represents the name
+// of the connection pool; unique within the instrumented application. In case
+// the connection pool implementation doesn't provide a name, instrumentation
+// SHOULD use a combination of parameters that would make the name unique, for
+// example, combining attributes `server.address`, `server.port`, and
+// `db.namespace`, formatted as `server.address:server.port/db.namespace`.
+// Instrumentations that generate connection pool name following different
+// patterns SHOULD document it.
+func DBClientConnectionPoolName(val string) attribute.KeyValue {
+ return DBClientConnectionPoolNameKey.String(val)
+}
+
+// DBCollectionName returns an attribute KeyValue conforming to the
+// "db.collection.name" semantic conventions. It represents the name of a
+// collection (table, container) within the database.
+func DBCollectionName(val string) attribute.KeyValue {
+ return DBCollectionNameKey.String(val)
+}
+
+// DBNamespace returns an attribute KeyValue conforming to the "db.namespace"
+// semantic conventions. It represents the name of the database, fully qualified
+// within the server address and port.
+func DBNamespace(val string) attribute.KeyValue {
+ return DBNamespaceKey.String(val)
+}
+
+// DBOperationBatchSize returns an attribute KeyValue conforming to the
+// "db.operation.batch.size" semantic conventions. It represents the number of
+// queries included in a batch operation.
+func DBOperationBatchSize(val int) attribute.KeyValue {
+ return DBOperationBatchSizeKey.Int(val)
+}
+
+// DBOperationName returns an attribute KeyValue conforming to the
+// "db.operation.name" semantic conventions. It represents the name of the
+// operation or command being executed.
+func DBOperationName(val string) attribute.KeyValue {
+ return DBOperationNameKey.String(val)
+}
+
+// DBOperationParameter returns an attribute KeyValue conforming to the
+// "db.operation.parameter" semantic conventions. It represents a database
+// operation parameter, with `` being the parameter name, and the attribute
+// value being a string representation of the parameter value.
+func DBOperationParameter(key string, val string) attribute.KeyValue {
+ return attribute.String("db.operation.parameter."+key, val)
+}
+
+// DBQueryParameter returns an attribute KeyValue conforming to the
+// "db.query.parameter" semantic conventions. It represents a database query
+// parameter, with `` being the parameter name, and the attribute value
+// being a string representation of the parameter value.
+func DBQueryParameter(key string, val string) attribute.KeyValue {
+ return attribute.String("db.query.parameter."+key, val)
+}
+
+// DBQuerySummary returns an attribute KeyValue conforming to the
+// "db.query.summary" semantic conventions. It represents the low cardinality
+// summary of a database query.
+func DBQuerySummary(val string) attribute.KeyValue {
+ return DBQuerySummaryKey.String(val)
+}
+
+// DBQueryText returns an attribute KeyValue conforming to the "db.query.text"
+// semantic conventions. It represents the database query being executed.
+func DBQueryText(val string) attribute.KeyValue {
+ return DBQueryTextKey.String(val)
+}
+
+// DBResponseReturnedRows returns an attribute KeyValue conforming to the
+// "db.response.returned_rows" semantic conventions. It represents the number of
+// rows returned by the operation.
+func DBResponseReturnedRows(val int) attribute.KeyValue {
+ return DBResponseReturnedRowsKey.Int(val)
+}
+
+// DBResponseStatusCode returns an attribute KeyValue conforming to the
+// "db.response.status_code" semantic conventions. It represents the database
+// response status code.
+func DBResponseStatusCode(val string) attribute.KeyValue {
+ return DBResponseStatusCodeKey.String(val)
+}
+
+// DBStoredProcedureName returns an attribute KeyValue conforming to the
+// "db.stored_procedure.name" semantic conventions. It represents the name of a
+// stored procedure within the database.
+func DBStoredProcedureName(val string) attribute.KeyValue {
+ return DBStoredProcedureNameKey.String(val)
+}
+
+// Enum values for db.client.connection.state
+var (
+ // idle
+ // Stability: development
+ DBClientConnectionStateIdle = DBClientConnectionStateKey.String("idle")
+ // used
+ // Stability: development
+ DBClientConnectionStateUsed = DBClientConnectionStateKey.String("used")
+)
+
+// Enum values for db.system.name
+var (
+ // Some other SQL database. Fallback only.
+ // Stability: development
+ DBSystemNameOtherSQL = DBSystemNameKey.String("other_sql")
+ // [Adabas (Adaptable Database System)]
+ // Stability: development
+ //
+ // [Adabas (Adaptable Database System)]: https://documentation.softwareag.com/?pf=adabas
+ DBSystemNameSoftwareagAdabas = DBSystemNameKey.String("softwareag.adabas")
+ // [Actian Ingres]
+ // Stability: development
+ //
+ // [Actian Ingres]: https://www.actian.com/databases/ingres/
+ DBSystemNameActianIngres = DBSystemNameKey.String("actian.ingres")
+ // [Amazon DynamoDB]
+ // Stability: development
+ //
+ // [Amazon DynamoDB]: https://aws.amazon.com/pm/dynamodb/
+ DBSystemNameAWSDynamoDB = DBSystemNameKey.String("aws.dynamodb")
+ // [Amazon Redshift]
+ // Stability: development
+ //
+ // [Amazon Redshift]: https://aws.amazon.com/redshift/
+ DBSystemNameAWSRedshift = DBSystemNameKey.String("aws.redshift")
+ // [Azure Cosmos DB]
+ // Stability: development
+ //
+ // [Azure Cosmos DB]: https://learn.microsoft.com/azure/cosmos-db
+ DBSystemNameAzureCosmosDB = DBSystemNameKey.String("azure.cosmosdb")
+ // [InterSystems Caché]
+ // Stability: development
+ //
+ // [InterSystems Caché]: https://www.intersystems.com/products/cache/
+ DBSystemNameIntersystemsCache = DBSystemNameKey.String("intersystems.cache")
+ // [Apache Cassandra]
+ // Stability: development
+ //
+ // [Apache Cassandra]: https://cassandra.apache.org/
+ DBSystemNameCassandra = DBSystemNameKey.String("cassandra")
+ // [ClickHouse]
+ // Stability: development
+ //
+ // [ClickHouse]: https://clickhouse.com/
+ DBSystemNameClickHouse = DBSystemNameKey.String("clickhouse")
+ // [CockroachDB]
+ // Stability: development
+ //
+ // [CockroachDB]: https://www.cockroachlabs.com/
+ DBSystemNameCockroachDB = DBSystemNameKey.String("cockroachdb")
+ // [Couchbase]
+ // Stability: development
+ //
+ // [Couchbase]: https://www.couchbase.com/
+ DBSystemNameCouchbase = DBSystemNameKey.String("couchbase")
+ // [Apache CouchDB]
+ // Stability: development
+ //
+ // [Apache CouchDB]: https://couchdb.apache.org/
+ DBSystemNameCouchDB = DBSystemNameKey.String("couchdb")
+ // [Apache Derby]
+ // Stability: development
+ //
+ // [Apache Derby]: https://db.apache.org/derby/
+ DBSystemNameDerby = DBSystemNameKey.String("derby")
+ // [Elasticsearch]
+ // Stability: development
+ //
+ // [Elasticsearch]: https://www.elastic.co/elasticsearch
+ DBSystemNameElasticsearch = DBSystemNameKey.String("elasticsearch")
+ // [Firebird]
+ // Stability: development
+ //
+ // [Firebird]: https://www.firebirdsql.org/
+ DBSystemNameFirebirdSQL = DBSystemNameKey.String("firebirdsql")
+ // [Google Cloud Spanner]
+ // Stability: development
+ //
+ // [Google Cloud Spanner]: https://cloud.google.com/spanner
+ DBSystemNameGCPSpanner = DBSystemNameKey.String("gcp.spanner")
+ // [Apache Geode]
+ // Stability: development
+ //
+ // [Apache Geode]: https://geode.apache.org/
+ DBSystemNameGeode = DBSystemNameKey.String("geode")
+ // [H2 Database]
+ // Stability: development
+ //
+ // [H2 Database]: https://h2database.com/
+ DBSystemNameH2database = DBSystemNameKey.String("h2database")
+ // [Apache HBase]
+ // Stability: development
+ //
+ // [Apache HBase]: https://hbase.apache.org/
+ DBSystemNameHBase = DBSystemNameKey.String("hbase")
+ // [Apache Hive]
+ // Stability: development
+ //
+ // [Apache Hive]: https://hive.apache.org/
+ DBSystemNameHive = DBSystemNameKey.String("hive")
+ // [HyperSQL Database]
+ // Stability: development
+ //
+ // [HyperSQL Database]: https://hsqldb.org/
+ DBSystemNameHSQLDB = DBSystemNameKey.String("hsqldb")
+ // [IBM Db2]
+ // Stability: development
+ //
+ // [IBM Db2]: https://www.ibm.com/db2
+ DBSystemNameIBMDB2 = DBSystemNameKey.String("ibm.db2")
+ // [IBM Informix]
+ // Stability: development
+ //
+ // [IBM Informix]: https://www.ibm.com/products/informix
+ DBSystemNameIBMInformix = DBSystemNameKey.String("ibm.informix")
+ // [IBM Netezza]
+ // Stability: development
+ //
+ // [IBM Netezza]: https://www.ibm.com/products/netezza
+ DBSystemNameIBMNetezza = DBSystemNameKey.String("ibm.netezza")
+ // [InfluxDB]
+ // Stability: development
+ //
+ // [InfluxDB]: https://www.influxdata.com/
+ DBSystemNameInfluxDB = DBSystemNameKey.String("influxdb")
+ // [Instant]
+ // Stability: development
+ //
+ // [Instant]: https://www.instantdb.com/
+ DBSystemNameInstantDB = DBSystemNameKey.String("instantdb")
+ // [MariaDB]
+ // Stability: stable
+ //
+ // [MariaDB]: https://mariadb.org/
+ DBSystemNameMariaDB = DBSystemNameKey.String("mariadb")
+ // [Memcached]
+ // Stability: development
+ //
+ // [Memcached]: https://memcached.org/
+ DBSystemNameMemcached = DBSystemNameKey.String("memcached")
+ // [MongoDB]
+ // Stability: development
+ //
+ // [MongoDB]: https://www.mongodb.com/
+ DBSystemNameMongoDB = DBSystemNameKey.String("mongodb")
+ // [Microsoft SQL Server]
+ // Stability: stable
+ //
+ // [Microsoft SQL Server]: https://www.microsoft.com/sql-server
+ DBSystemNameMicrosoftSQLServer = DBSystemNameKey.String("microsoft.sql_server")
+ // [MySQL]
+ // Stability: stable
+ //
+ // [MySQL]: https://www.mysql.com/
+ DBSystemNameMySQL = DBSystemNameKey.String("mysql")
+ // [Neo4j]
+ // Stability: development
+ //
+ // [Neo4j]: https://neo4j.com/
+ DBSystemNameNeo4j = DBSystemNameKey.String("neo4j")
+ // [OpenSearch]
+ // Stability: development
+ //
+ // [OpenSearch]: https://opensearch.org/
+ DBSystemNameOpenSearch = DBSystemNameKey.String("opensearch")
+ // [Oracle Database]
+ // Stability: development
+ //
+ // [Oracle Database]: https://www.oracle.com/database/
+ DBSystemNameOracleDB = DBSystemNameKey.String("oracle.db")
+ // [PostgreSQL]
+ // Stability: stable
+ //
+ // [PostgreSQL]: https://www.postgresql.org/
+ DBSystemNamePostgreSQL = DBSystemNameKey.String("postgresql")
+ // [Redis]
+ // Stability: development
+ //
+ // [Redis]: https://redis.io/
+ DBSystemNameRedis = DBSystemNameKey.String("redis")
+ // [SAP HANA]
+ // Stability: development
+ //
+ // [SAP HANA]: https://www.sap.com/products/technology-platform/hana/what-is-sap-hana.html
+ DBSystemNameSAPHANA = DBSystemNameKey.String("sap.hana")
+ // [SAP MaxDB]
+ // Stability: development
+ //
+ // [SAP MaxDB]: https://maxdb.sap.com/
+ DBSystemNameSAPMaxDB = DBSystemNameKey.String("sap.maxdb")
+ // [SQLite]
+ // Stability: development
+ //
+ // [SQLite]: https://www.sqlite.org/
+ DBSystemNameSQLite = DBSystemNameKey.String("sqlite")
+ // [Teradata]
+ // Stability: development
+ //
+ // [Teradata]: https://www.teradata.com/
+ DBSystemNameTeradata = DBSystemNameKey.String("teradata")
+ // [Trino]
+ // Stability: development
+ //
+ // [Trino]: https://trino.io/
+ DBSystemNameTrino = DBSystemNameKey.String("trino")
+)
+
+// Namespace: deployment
+const (
+ // DeploymentEnvironmentNameKey is the attribute Key conforming to the
+ // "deployment.environment.name" semantic conventions. It represents the name of
+ // the [deployment environment] (aka deployment tier).
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "staging", "production"
+ // Note: `deployment.environment.name` does not affect the uniqueness
+ // constraints defined through
+ // the `service.namespace`, `service.name` and `service.instance.id` resource
+ // attributes.
+ // This implies that resources carrying the following attribute combinations
+ // MUST be
+ // considered to be identifying the same service:
+ //
+ // - `service.name=frontend`, `deployment.environment.name=production`
+ // - `service.name=frontend`, `deployment.environment.name=staging`.
+ //
+ //
+ // [deployment environment]: https://wikipedia.org/wiki/Deployment_environment
+ DeploymentEnvironmentNameKey = attribute.Key("deployment.environment.name")
+
+ // DeploymentIDKey is the attribute Key conforming to the "deployment.id"
+ // semantic conventions. It represents the id of the deployment.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "1208"
+ DeploymentIDKey = attribute.Key("deployment.id")
+
+ // DeploymentNameKey is the attribute Key conforming to the "deployment.name"
+ // semantic conventions. It represents the name of the deployment.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "deploy my app", "deploy-frontend"
+ DeploymentNameKey = attribute.Key("deployment.name")
+
+ // DeploymentStatusKey is the attribute Key conforming to the
+ // "deployment.status" semantic conventions. It represents the status of the
+ // deployment.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ DeploymentStatusKey = attribute.Key("deployment.status")
+)
+
+// DeploymentEnvironmentName returns an attribute KeyValue conforming to the
+// "deployment.environment.name" semantic conventions. It represents the name of
+// the [deployment environment] (aka deployment tier).
+//
+// [deployment environment]: https://wikipedia.org/wiki/Deployment_environment
+func DeploymentEnvironmentName(val string) attribute.KeyValue {
+ return DeploymentEnvironmentNameKey.String(val)
+}
+
+// DeploymentID returns an attribute KeyValue conforming to the "deployment.id"
+// semantic conventions. It represents the id of the deployment.
+func DeploymentID(val string) attribute.KeyValue {
+ return DeploymentIDKey.String(val)
+}
+
+// DeploymentName returns an attribute KeyValue conforming to the
+// "deployment.name" semantic conventions. It represents the name of the
+// deployment.
+func DeploymentName(val string) attribute.KeyValue {
+ return DeploymentNameKey.String(val)
+}
+
+// Enum values for deployment.status
+var (
+ // failed
+ // Stability: development
+ DeploymentStatusFailed = DeploymentStatusKey.String("failed")
+ // succeeded
+ // Stability: development
+ DeploymentStatusSucceeded = DeploymentStatusKey.String("succeeded")
+)
+
+// Namespace: destination
+const (
+ // DestinationAddressKey is the attribute Key conforming to the
+ // "destination.address" semantic conventions. It represents the destination
+ // address - domain name if available without reverse DNS lookup; otherwise, IP
+ // address or Unix domain socket name.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "destination.example.com", "10.1.2.80", "/tmp/my.sock"
+ // Note: When observed from the source side, and when communicating through an
+ // intermediary, `destination.address` SHOULD represent the destination address
+ // behind any intermediaries, for example proxies, if it's available.
+ DestinationAddressKey = attribute.Key("destination.address")
+
+ // DestinationPortKey is the attribute Key conforming to the "destination.port"
+ // semantic conventions. It represents the destination port number.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 3389, 2888
+ DestinationPortKey = attribute.Key("destination.port")
+)
+
+// DestinationAddress returns an attribute KeyValue conforming to the
+// "destination.address" semantic conventions. It represents the destination
+// address - domain name if available without reverse DNS lookup; otherwise, IP
+// address or Unix domain socket name.
+func DestinationAddress(val string) attribute.KeyValue {
+ return DestinationAddressKey.String(val)
+}
+
+// DestinationPort returns an attribute KeyValue conforming to the
+// "destination.port" semantic conventions. It represents the destination port
+// number.
+func DestinationPort(val int) attribute.KeyValue {
+ return DestinationPortKey.Int(val)
+}
+
+// Namespace: device
+const (
+ // DeviceIDKey is the attribute Key conforming to the "device.id" semantic
+ // conventions. It represents a unique identifier representing the device.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "123456789012345", "01:23:45:67:89:AB"
+ // Note: Its value SHOULD be identical for all apps on a device and it SHOULD
+ // NOT change if an app is uninstalled and re-installed.
+ // However, it might be resettable by the user for all apps on a device.
+ // Hardware IDs (e.g. vendor-specific serial number, IMEI or MAC address) MAY be
+ // used as values.
+ //
+ // More information about Android identifier best practices can be found in the
+ // [Android user data IDs guide].
+ //
+ // > [!WARNING]> This attribute may contain sensitive (PII) information. Caution
+ // > should be taken when storing personal data or anything which can identify a
+ // > user. GDPR and data protection laws may apply,
+ // > ensure you do your own due diligence.> Due to these reasons, this
+ // > identifier is not recommended for consumer applications and will likely
+ // > result in rejection from both Google Play and App Store.
+ // > However, it may be appropriate for specific enterprise scenarios, such as
+ // > kiosk devices or enterprise-managed devices, with appropriate compliance
+ // > clearance.
+ // > Any instrumentation providing this identifier MUST implement it as an
+ // > opt-in feature.> See [`app.installation.id`]> for a more
+ // > privacy-preserving alternative.
+ //
+ // [Android user data IDs guide]: https://developer.android.com/training/articles/user-data-ids
+ // [`app.installation.id`]: /docs/registry/attributes/app.md#app-installation-id
+ DeviceIDKey = attribute.Key("device.id")
+
+ // DeviceManufacturerKey is the attribute Key conforming to the
+ // "device.manufacturer" semantic conventions. It represents the name of the
+ // device manufacturer.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "Apple", "Samsung"
+ // Note: The Android OS provides this field via [Build]. iOS apps SHOULD
+ // hardcode the value `Apple`.
+ //
+ // [Build]: https://developer.android.com/reference/android/os/Build#MANUFACTURER
+ DeviceManufacturerKey = attribute.Key("device.manufacturer")
+
+ // DeviceModelIdentifierKey is the attribute Key conforming to the
+ // "device.model.identifier" semantic conventions. It represents the model
+ // identifier for the device.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "iPhone3,4", "SM-G920F"
+ // Note: It's recommended this value represents a machine-readable version of
+ // the model identifier rather than the market or consumer-friendly name of the
+ // device.
+ DeviceModelIdentifierKey = attribute.Key("device.model.identifier")
+
+ // DeviceModelNameKey is the attribute Key conforming to the "device.model.name"
+ // semantic conventions. It represents the marketing name for the device model.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "iPhone 6s Plus", "Samsung Galaxy S6"
+ // Note: It's recommended this value represents a human-readable version of the
+ // device model rather than a machine-readable alternative.
+ DeviceModelNameKey = attribute.Key("device.model.name")
+)
+
+// DeviceID returns an attribute KeyValue conforming to the "device.id" semantic
+// conventions. It represents a unique identifier representing the device.
+func DeviceID(val string) attribute.KeyValue {
+ return DeviceIDKey.String(val)
+}
+
+// DeviceManufacturer returns an attribute KeyValue conforming to the
+// "device.manufacturer" semantic conventions. It represents the name of the
+// device manufacturer.
+func DeviceManufacturer(val string) attribute.KeyValue {
+ return DeviceManufacturerKey.String(val)
+}
+
+// DeviceModelIdentifier returns an attribute KeyValue conforming to the
+// "device.model.identifier" semantic conventions. It represents the model
+// identifier for the device.
+func DeviceModelIdentifier(val string) attribute.KeyValue {
+ return DeviceModelIdentifierKey.String(val)
+}
+
+// DeviceModelName returns an attribute KeyValue conforming to the
+// "device.model.name" semantic conventions. It represents the marketing name for
+// the device model.
+func DeviceModelName(val string) attribute.KeyValue {
+ return DeviceModelNameKey.String(val)
+}
+
+// Namespace: disk
+const (
+ // DiskIODirectionKey is the attribute Key conforming to the "disk.io.direction"
+ // semantic conventions. It represents the disk IO operation direction.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "read"
+ DiskIODirectionKey = attribute.Key("disk.io.direction")
+)
+
+// Enum values for disk.io.direction
+var (
+ // read
+ // Stability: development
+ DiskIODirectionRead = DiskIODirectionKey.String("read")
+ // write
+ // Stability: development
+ DiskIODirectionWrite = DiskIODirectionKey.String("write")
+)
+
+// Namespace: dns
+const (
+ // DNSAnswersKey is the attribute Key conforming to the "dns.answers" semantic
+ // conventions. It represents the list of IPv4 or IPv6 addresses resolved during
+ // DNS lookup.
+ //
+ // Type: string[]
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "10.0.0.1", "2001:0db8:85a3:0000:0000:8a2e:0370:7334"
+ DNSAnswersKey = attribute.Key("dns.answers")
+
+ // DNSQuestionNameKey is the attribute Key conforming to the "dns.question.name"
+ // semantic conventions. It represents the name being queried.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "www.example.com", "opentelemetry.io"
+ // Note: The name represents the queried domain name as it appears in the DNS
+ // query without any additional normalization.
+ DNSQuestionNameKey = attribute.Key("dns.question.name")
+)
+
+// DNSAnswers returns an attribute KeyValue conforming to the "dns.answers"
+// semantic conventions. It represents the list of IPv4 or IPv6 addresses
+// resolved during DNS lookup.
+func DNSAnswers(val ...string) attribute.KeyValue {
+ return DNSAnswersKey.StringSlice(val)
+}
+
+// DNSQuestionName returns an attribute KeyValue conforming to the
+// "dns.question.name" semantic conventions. It represents the name being
+// queried.
+func DNSQuestionName(val string) attribute.KeyValue {
+ return DNSQuestionNameKey.String(val)
+}
+
+// Namespace: elasticsearch
+const (
+ // ElasticsearchNodeNameKey is the attribute Key conforming to the
+ // "elasticsearch.node.name" semantic conventions. It represents the represents
+ // the human-readable identifier of the node/instance to which a request was
+ // routed.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "instance-0000000001"
+ ElasticsearchNodeNameKey = attribute.Key("elasticsearch.node.name")
+)
+
+// ElasticsearchNodeName returns an attribute KeyValue conforming to the
+// "elasticsearch.node.name" semantic conventions. It represents the represents
+// the human-readable identifier of the node/instance to which a request was
+// routed.
+func ElasticsearchNodeName(val string) attribute.KeyValue {
+ return ElasticsearchNodeNameKey.String(val)
+}
+
+// Namespace: enduser
+const (
+ // EnduserIDKey is the attribute Key conforming to the "enduser.id" semantic
+ // conventions. It represents the unique identifier of an end user in the
+ // system. It maybe a username, email address, or other identifier.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "username"
+ // Note: Unique identifier of an end user in the system.
+ //
+ // > [!Warning]
+ // > This field contains sensitive (PII) information.
+ EnduserIDKey = attribute.Key("enduser.id")
+
+ // EnduserPseudoIDKey is the attribute Key conforming to the "enduser.pseudo.id"
+ // semantic conventions. It represents the pseudonymous identifier of an end
+ // user. This identifier should be a random value that is not directly linked or
+ // associated with the end user's actual identity.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "QdH5CAWJgqVT4rOr0qtumf"
+ // Note: Pseudonymous identifier of an end user.
+ //
+ // > [!Warning]
+ // > This field contains sensitive (linkable PII) information.
+ EnduserPseudoIDKey = attribute.Key("enduser.pseudo.id")
+)
+
+// EnduserID returns an attribute KeyValue conforming to the "enduser.id"
+// semantic conventions. It represents the unique identifier of an end user in
+// the system. It maybe a username, email address, or other identifier.
+func EnduserID(val string) attribute.KeyValue {
+ return EnduserIDKey.String(val)
+}
+
+// EnduserPseudoID returns an attribute KeyValue conforming to the
+// "enduser.pseudo.id" semantic conventions. It represents the pseudonymous
+// identifier of an end user. This identifier should be a random value that is
+// not directly linked or associated with the end user's actual identity.
+func EnduserPseudoID(val string) attribute.KeyValue {
+ return EnduserPseudoIDKey.String(val)
+}
+
+// Namespace: error
+const (
+ // ErrorTypeKey is the attribute Key conforming to the "error.type" semantic
+ // conventions. It represents the describes a class of error the operation ended
+ // with.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ //
+ // Examples: "timeout", "java.net.UnknownHostException",
+ // "server_certificate_invalid", "500"
+ // Note: The `error.type` SHOULD be predictable, and SHOULD have low
+ // cardinality.
+ //
+ // When `error.type` is set to a type (e.g., an exception type), its
+ // canonical class name identifying the type within the artifact SHOULD be used.
+ //
+ // Instrumentations SHOULD document the list of errors they report.
+ //
+ // The cardinality of `error.type` within one instrumentation library SHOULD be
+ // low.
+ // Telemetry consumers that aggregate data from multiple instrumentation
+ // libraries and applications
+ // should be prepared for `error.type` to have high cardinality at query time
+ // when no
+ // additional filters are applied.
+ //
+ // If the operation has completed successfully, instrumentations SHOULD NOT set
+ // `error.type`.
+ //
+ // If a specific domain defines its own set of error identifiers (such as HTTP
+ // or RPC status codes),
+ // it's RECOMMENDED to:
+ //
+ // - Use a domain-specific attribute
+ // - Set `error.type` to capture all errors, regardless of whether they are
+ // defined within the domain-specific set or not.
+ ErrorTypeKey = attribute.Key("error.type")
+)
+
+// Enum values for error.type
+var (
+ // A fallback error value to be used when the instrumentation doesn't define a
+ // custom value.
+ //
+ // Stability: stable
+ ErrorTypeOther = ErrorTypeKey.String("_OTHER")
+)
+
+// Namespace: exception
+const (
+ // ExceptionMessageKey is the attribute Key conforming to the
+ // "exception.message" semantic conventions. It represents the exception
+ // message.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ //
+ // Examples: "Division by zero", "Can't convert 'int' object to str implicitly"
+ // Note: > [!WARNING]
+ //
+ // > This attribute may contain sensitive information.
+ ExceptionMessageKey = attribute.Key("exception.message")
+
+ // ExceptionStacktraceKey is the attribute Key conforming to the
+ // "exception.stacktrace" semantic conventions. It represents a stacktrace as a
+ // string in the natural representation for the language runtime. The
+ // representation is to be determined and documented by each language SIG.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ //
+ // Examples: Exception in thread "main" java.lang.RuntimeException: Test
+ // exception\n at com.example.GenerateTrace.methodB(GenerateTrace.java:13)\n at
+ // com.example.GenerateTrace.methodA(GenerateTrace.java:9)\n at
+ // com.example.GenerateTrace.main(GenerateTrace.java:5)
+ ExceptionStacktraceKey = attribute.Key("exception.stacktrace")
+
+ // ExceptionTypeKey is the attribute Key conforming to the "exception.type"
+ // semantic conventions. It represents the type of the exception (its
+ // fully-qualified class name, if applicable). The dynamic type of the exception
+ // should be preferred over the static type in languages that support it.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ //
+ // Examples: "java.net.ConnectException", "OSError"
+ ExceptionTypeKey = attribute.Key("exception.type")
+)
+
+// ExceptionMessage returns an attribute KeyValue conforming to the
+// "exception.message" semantic conventions. It represents the exception message.
+func ExceptionMessage(val string) attribute.KeyValue {
+ return ExceptionMessageKey.String(val)
+}
+
+// ExceptionStacktrace returns an attribute KeyValue conforming to the
+// "exception.stacktrace" semantic conventions. It represents a stacktrace as a
+// string in the natural representation for the language runtime. The
+// representation is to be determined and documented by each language SIG.
+func ExceptionStacktrace(val string) attribute.KeyValue {
+ return ExceptionStacktraceKey.String(val)
+}
+
+// ExceptionType returns an attribute KeyValue conforming to the "exception.type"
+// semantic conventions. It represents the type of the exception (its
+// fully-qualified class name, if applicable). The dynamic type of the exception
+// should be preferred over the static type in languages that support it.
+func ExceptionType(val string) attribute.KeyValue {
+ return ExceptionTypeKey.String(val)
+}
+
+// Namespace: faas
+const (
+ // FaaSColdstartKey is the attribute Key conforming to the "faas.coldstart"
+ // semantic conventions. It represents a boolean that is true if the serverless
+ // function is executed for the first time (aka cold-start).
+ //
+ // Type: boolean
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ FaaSColdstartKey = attribute.Key("faas.coldstart")
+
+ // FaaSCronKey is the attribute Key conforming to the "faas.cron" semantic
+ // conventions. It represents a string containing the schedule period as
+ // [Cron Expression].
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 0/5 * * * ? *
+ //
+ // [Cron Expression]: https://docs.oracle.com/cd/E12058_01/doc/doc.1014/e12030/cron_expressions.htm
+ FaaSCronKey = attribute.Key("faas.cron")
+
+ // FaaSDocumentCollectionKey is the attribute Key conforming to the
+ // "faas.document.collection" semantic conventions. It represents the name of
+ // the source on which the triggering operation was performed. For example, in
+ // Cloud Storage or S3 corresponds to the bucket name, and in Cosmos DB to the
+ // database name.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "myBucketName", "myDbName"
+ FaaSDocumentCollectionKey = attribute.Key("faas.document.collection")
+
+ // FaaSDocumentNameKey is the attribute Key conforming to the
+ // "faas.document.name" semantic conventions. It represents the document
+ // name/table subjected to the operation. For example, in Cloud Storage or S3 is
+ // the name of the file, and in Cosmos DB the table name.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "myFile.txt", "myTableName"
+ FaaSDocumentNameKey = attribute.Key("faas.document.name")
+
+ // FaaSDocumentOperationKey is the attribute Key conforming to the
+ // "faas.document.operation" semantic conventions. It represents the describes
+ // the type of the operation that was performed on the data.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ FaaSDocumentOperationKey = attribute.Key("faas.document.operation")
+
+ // FaaSDocumentTimeKey is the attribute Key conforming to the
+ // "faas.document.time" semantic conventions. It represents a string containing
+ // the time when the data was accessed in the [ISO 8601] format expressed in
+ // [UTC].
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 2020-01-23T13:47:06Z
+ //
+ // [ISO 8601]: https://www.iso.org/iso-8601-date-and-time-format.html
+ // [UTC]: https://www.w3.org/TR/NOTE-datetime
+ FaaSDocumentTimeKey = attribute.Key("faas.document.time")
+
+ // FaaSInstanceKey is the attribute Key conforming to the "faas.instance"
+ // semantic conventions. It represents the execution environment ID as a string,
+ // that will be potentially reused for other invocations to the same
+ // function/function version.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "2021/06/28/[$LATEST]2f399eb14537447da05ab2a2e39309de"
+ // Note: - **AWS Lambda:** Use the (full) log stream name.
+ FaaSInstanceKey = attribute.Key("faas.instance")
+
+ // FaaSInvocationIDKey is the attribute Key conforming to the
+ // "faas.invocation_id" semantic conventions. It represents the invocation ID of
+ // the current function invocation.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: af9d5aa4-a685-4c5f-a22b-444f80b3cc28
+ FaaSInvocationIDKey = attribute.Key("faas.invocation_id")
+
+ // FaaSInvokedNameKey is the attribute Key conforming to the "faas.invoked_name"
+ // semantic conventions. It represents the name of the invoked function.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: my-function
+ // Note: SHOULD be equal to the `faas.name` resource attribute of the invoked
+ // function.
+ FaaSInvokedNameKey = attribute.Key("faas.invoked_name")
+
+ // FaaSInvokedProviderKey is the attribute Key conforming to the
+ // "faas.invoked_provider" semantic conventions. It represents the cloud
+ // provider of the invoked function.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ // Note: SHOULD be equal to the `cloud.provider` resource attribute of the
+ // invoked function.
+ FaaSInvokedProviderKey = attribute.Key("faas.invoked_provider")
+
+ // FaaSInvokedRegionKey is the attribute Key conforming to the
+ // "faas.invoked_region" semantic conventions. It represents the cloud region of
+ // the invoked function.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: eu-central-1
+ // Note: SHOULD be equal to the `cloud.region` resource attribute of the invoked
+ // function.
+ FaaSInvokedRegionKey = attribute.Key("faas.invoked_region")
+
+ // FaaSMaxMemoryKey is the attribute Key conforming to the "faas.max_memory"
+ // semantic conventions. It represents the amount of memory available to the
+ // serverless function converted to Bytes.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Note: It's recommended to set this attribute since e.g. too little memory can
+ // easily stop a Java AWS Lambda function from working correctly. On AWS Lambda,
+ // the environment variable `AWS_LAMBDA_FUNCTION_MEMORY_SIZE` provides this
+ // information (which must be multiplied by 1,048,576).
+ FaaSMaxMemoryKey = attribute.Key("faas.max_memory")
+
+ // FaaSNameKey is the attribute Key conforming to the "faas.name" semantic
+ // conventions. It represents the name of the single function that this runtime
+ // instance executes.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "my-function", "myazurefunctionapp/some-function-name"
+ // Note: This is the name of the function as configured/deployed on the FaaS
+ // platform and is usually different from the name of the callback
+ // function (which may be stored in the
+ // [`code.namespace`/`code.function.name`]
+ // span attributes).
+ //
+ // For some cloud providers, the above definition is ambiguous. The following
+ // definition of function name MUST be used for this attribute
+ // (and consequently the span name) for the listed cloud providers/products:
+ //
+ // - **Azure:** The full name `/`, i.e., function app name
+ // followed by a forward slash followed by the function name (this form
+ // can also be seen in the resource JSON for the function).
+ // This means that a span attribute MUST be used, as an Azure function
+ // app can host multiple functions that would usually share
+ // a TracerProvider (see also the `cloud.resource_id` attribute).
+ //
+ //
+ // [`code.namespace`/`code.function.name`]: /docs/general/attributes.md#source-code-attributes
+ FaaSNameKey = attribute.Key("faas.name")
+
+ // FaaSTimeKey is the attribute Key conforming to the "faas.time" semantic
+ // conventions. It represents a string containing the function invocation time
+ // in the [ISO 8601] format expressed in [UTC].
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 2020-01-23T13:47:06Z
+ //
+ // [ISO 8601]: https://www.iso.org/iso-8601-date-and-time-format.html
+ // [UTC]: https://www.w3.org/TR/NOTE-datetime
+ FaaSTimeKey = attribute.Key("faas.time")
+
+ // FaaSTriggerKey is the attribute Key conforming to the "faas.trigger" semantic
+ // conventions. It represents the type of the trigger which caused this function
+ // invocation.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ FaaSTriggerKey = attribute.Key("faas.trigger")
+
+ // FaaSVersionKey is the attribute Key conforming to the "faas.version" semantic
+ // conventions. It represents the immutable version of the function being
+ // executed.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "26", "pinkfroid-00002"
+ // Note: Depending on the cloud provider and platform, use:
+ //
+ // - **AWS Lambda:** The [function version]
+ // (an integer represented as a decimal string).
+ // - **Google Cloud Run (Services):** The [revision]
+ // (i.e., the function name plus the revision suffix).
+ // - **Google Cloud Functions:** The value of the
+ // [`K_REVISION` environment variable].
+ // - **Azure Functions:** Not applicable. Do not set this attribute.
+ //
+ //
+ // [function version]: https://docs.aws.amazon.com/lambda/latest/dg/configuration-versions.html
+ // [revision]: https://cloud.google.com/run/docs/managing/revisions
+ // [`K_REVISION` environment variable]: https://cloud.google.com/run/docs/container-contract#services-env-vars
+ FaaSVersionKey = attribute.Key("faas.version")
+)
+
+// FaaSColdstart returns an attribute KeyValue conforming to the "faas.coldstart"
+// semantic conventions. It represents a boolean that is true if the serverless
+// function is executed for the first time (aka cold-start).
+func FaaSColdstart(val bool) attribute.KeyValue {
+ return FaaSColdstartKey.Bool(val)
+}
+
+// FaaSCron returns an attribute KeyValue conforming to the "faas.cron" semantic
+// conventions. It represents a string containing the schedule period as
+// [Cron Expression].
+//
+// [Cron Expression]: https://docs.oracle.com/cd/E12058_01/doc/doc.1014/e12030/cron_expressions.htm
+func FaaSCron(val string) attribute.KeyValue {
+ return FaaSCronKey.String(val)
+}
+
+// FaaSDocumentCollection returns an attribute KeyValue conforming to the
+// "faas.document.collection" semantic conventions. It represents the name of the
+// source on which the triggering operation was performed. For example, in Cloud
+// Storage or S3 corresponds to the bucket name, and in Cosmos DB to the database
+// name.
+func FaaSDocumentCollection(val string) attribute.KeyValue {
+ return FaaSDocumentCollectionKey.String(val)
+}
+
+// FaaSDocumentName returns an attribute KeyValue conforming to the
+// "faas.document.name" semantic conventions. It represents the document
+// name/table subjected to the operation. For example, in Cloud Storage or S3 is
+// the name of the file, and in Cosmos DB the table name.
+func FaaSDocumentName(val string) attribute.KeyValue {
+ return FaaSDocumentNameKey.String(val)
+}
+
+// FaaSDocumentTime returns an attribute KeyValue conforming to the
+// "faas.document.time" semantic conventions. It represents a string containing
+// the time when the data was accessed in the [ISO 8601] format expressed in
+// [UTC].
+//
+// [ISO 8601]: https://www.iso.org/iso-8601-date-and-time-format.html
+// [UTC]: https://www.w3.org/TR/NOTE-datetime
+func FaaSDocumentTime(val string) attribute.KeyValue {
+ return FaaSDocumentTimeKey.String(val)
+}
+
+// FaaSInstance returns an attribute KeyValue conforming to the "faas.instance"
+// semantic conventions. It represents the execution environment ID as a string,
+// that will be potentially reused for other invocations to the same
+// function/function version.
+func FaaSInstance(val string) attribute.KeyValue {
+ return FaaSInstanceKey.String(val)
+}
+
+// FaaSInvocationID returns an attribute KeyValue conforming to the
+// "faas.invocation_id" semantic conventions. It represents the invocation ID of
+// the current function invocation.
+func FaaSInvocationID(val string) attribute.KeyValue {
+ return FaaSInvocationIDKey.String(val)
+}
+
+// FaaSInvokedName returns an attribute KeyValue conforming to the
+// "faas.invoked_name" semantic conventions. It represents the name of the
+// invoked function.
+func FaaSInvokedName(val string) attribute.KeyValue {
+ return FaaSInvokedNameKey.String(val)
+}
+
+// FaaSInvokedRegion returns an attribute KeyValue conforming to the
+// "faas.invoked_region" semantic conventions. It represents the cloud region of
+// the invoked function.
+func FaaSInvokedRegion(val string) attribute.KeyValue {
+ return FaaSInvokedRegionKey.String(val)
+}
+
+// FaaSMaxMemory returns an attribute KeyValue conforming to the
+// "faas.max_memory" semantic conventions. It represents the amount of memory
+// available to the serverless function converted to Bytes.
+func FaaSMaxMemory(val int) attribute.KeyValue {
+ return FaaSMaxMemoryKey.Int(val)
+}
+
+// FaaSName returns an attribute KeyValue conforming to the "faas.name" semantic
+// conventions. It represents the name of the single function that this runtime
+// instance executes.
+func FaaSName(val string) attribute.KeyValue {
+ return FaaSNameKey.String(val)
+}
+
+// FaaSTime returns an attribute KeyValue conforming to the "faas.time" semantic
+// conventions. It represents a string containing the function invocation time in
+// the [ISO 8601] format expressed in [UTC].
+//
+// [ISO 8601]: https://www.iso.org/iso-8601-date-and-time-format.html
+// [UTC]: https://www.w3.org/TR/NOTE-datetime
+func FaaSTime(val string) attribute.KeyValue {
+ return FaaSTimeKey.String(val)
+}
+
+// FaaSVersion returns an attribute KeyValue conforming to the "faas.version"
+// semantic conventions. It represents the immutable version of the function
+// being executed.
+func FaaSVersion(val string) attribute.KeyValue {
+ return FaaSVersionKey.String(val)
+}
+
+// Enum values for faas.document.operation
+var (
+ // When a new object is created.
+ // Stability: development
+ FaaSDocumentOperationInsert = FaaSDocumentOperationKey.String("insert")
+ // When an object is modified.
+ // Stability: development
+ FaaSDocumentOperationEdit = FaaSDocumentOperationKey.String("edit")
+ // When an object is deleted.
+ // Stability: development
+ FaaSDocumentOperationDelete = FaaSDocumentOperationKey.String("delete")
+)
+
+// Enum values for faas.invoked_provider
+var (
+ // Alibaba Cloud
+ // Stability: development
+ FaaSInvokedProviderAlibabaCloud = FaaSInvokedProviderKey.String("alibaba_cloud")
+ // Amazon Web Services
+ // Stability: development
+ FaaSInvokedProviderAWS = FaaSInvokedProviderKey.String("aws")
+ // Microsoft Azure
+ // Stability: development
+ FaaSInvokedProviderAzure = FaaSInvokedProviderKey.String("azure")
+ // Google Cloud Platform
+ // Stability: development
+ FaaSInvokedProviderGCP = FaaSInvokedProviderKey.String("gcp")
+ // Tencent Cloud
+ // Stability: development
+ FaaSInvokedProviderTencentCloud = FaaSInvokedProviderKey.String("tencent_cloud")
+)
+
+// Enum values for faas.trigger
+var (
+ // A response to some data source operation such as a database or filesystem
+ // read/write
+ // Stability: development
+ FaaSTriggerDatasource = FaaSTriggerKey.String("datasource")
+ // To provide an answer to an inbound HTTP request
+ // Stability: development
+ FaaSTriggerHTTP = FaaSTriggerKey.String("http")
+ // A function is set to be executed when messages are sent to a messaging system
+ // Stability: development
+ FaaSTriggerPubSub = FaaSTriggerKey.String("pubsub")
+ // A function is scheduled to be executed regularly
+ // Stability: development
+ FaaSTriggerTimer = FaaSTriggerKey.String("timer")
+ // If none of the others apply
+ // Stability: development
+ FaaSTriggerOther = FaaSTriggerKey.String("other")
+)
+
+// Namespace: feature_flag
+const (
+ // FeatureFlagContextIDKey is the attribute Key conforming to the
+ // "feature_flag.context.id" semantic conventions. It represents the unique
+ // identifier for the flag evaluation context. For example, the targeting key.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Release_Candidate
+ //
+ // Examples: "5157782b-2203-4c80-a857-dbbd5e7761db"
+ FeatureFlagContextIDKey = attribute.Key("feature_flag.context.id")
+
+ // FeatureFlagErrorMessageKey is the attribute Key conforming to the
+ // "feature_flag.error.message" semantic conventions. It represents a message
+ // providing more detail about an error that occurred during feature flag
+ // evaluation in human-readable form.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Release_Candidate
+ //
+ // Examples: "Unexpected input type: string", "The user has exceeded their
+ // storage quota"
+ FeatureFlagErrorMessageKey = attribute.Key("feature_flag.error.message")
+
+ // FeatureFlagKeyKey is the attribute Key conforming to the "feature_flag.key"
+ // semantic conventions. It represents the lookup key of the feature flag.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Release_Candidate
+ //
+ // Examples: "logo-color"
+ FeatureFlagKeyKey = attribute.Key("feature_flag.key")
+
+ // FeatureFlagProviderNameKey is the attribute Key conforming to the
+ // "feature_flag.provider.name" semantic conventions. It represents the
+ // identifies the feature flag provider.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Release_Candidate
+ //
+ // Examples: "Flag Manager"
+ FeatureFlagProviderNameKey = attribute.Key("feature_flag.provider.name")
+
+ // FeatureFlagResultReasonKey is the attribute Key conforming to the
+ // "feature_flag.result.reason" semantic conventions. It represents the reason
+ // code which shows how a feature flag value was determined.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Release_Candidate
+ //
+ // Examples: "static", "targeting_match", "error", "default"
+ FeatureFlagResultReasonKey = attribute.Key("feature_flag.result.reason")
+
+ // FeatureFlagResultValueKey is the attribute Key conforming to the
+ // "feature_flag.result.value" semantic conventions. It represents the evaluated
+ // value of the feature flag.
+ //
+ // Type: any
+ // RequirementLevel: Recommended
+ // Stability: Release_Candidate
+ //
+ // Examples: "#ff0000", true, 3
+ // Note: With some feature flag providers, feature flag results can be quite
+ // large or contain private or sensitive details.
+ // Because of this, `feature_flag.result.variant` is often the preferred
+ // attribute if it is available.
+ //
+ // It may be desirable to redact or otherwise limit the size and scope of
+ // `feature_flag.result.value` if possible.
+ // Because the evaluated flag value is unstructured and may be any type, it is
+ // left to the instrumentation author to determine how best to achieve this.
+ FeatureFlagResultValueKey = attribute.Key("feature_flag.result.value")
+
+ // FeatureFlagResultVariantKey is the attribute Key conforming to the
+ // "feature_flag.result.variant" semantic conventions. It represents a semantic
+ // identifier for an evaluated flag value.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Release_Candidate
+ //
+ // Examples: "red", "true", "on"
+ // Note: A semantic identifier, commonly referred to as a variant, provides a
+ // means
+ // for referring to a value without including the value itself. This can
+ // provide additional context for understanding the meaning behind a value.
+ // For example, the variant `red` maybe be used for the value `#c05543`.
+ FeatureFlagResultVariantKey = attribute.Key("feature_flag.result.variant")
+
+ // FeatureFlagSetIDKey is the attribute Key conforming to the
+ // "feature_flag.set.id" semantic conventions. It represents the identifier of
+ // the [flag set] to which the feature flag belongs.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Release_Candidate
+ //
+ // Examples: "proj-1", "ab98sgs", "service1/dev"
+ //
+ // [flag set]: https://openfeature.dev/specification/glossary/#flag-set
+ FeatureFlagSetIDKey = attribute.Key("feature_flag.set.id")
+
+ // FeatureFlagVersionKey is the attribute Key conforming to the
+ // "feature_flag.version" semantic conventions. It represents the version of the
+ // ruleset used during the evaluation. This may be any stable value which
+ // uniquely identifies the ruleset.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Release_Candidate
+ //
+ // Examples: "1", "01ABCDEF"
+ FeatureFlagVersionKey = attribute.Key("feature_flag.version")
+)
+
+// FeatureFlagContextID returns an attribute KeyValue conforming to the
+// "feature_flag.context.id" semantic conventions. It represents the unique
+// identifier for the flag evaluation context. For example, the targeting key.
+func FeatureFlagContextID(val string) attribute.KeyValue {
+ return FeatureFlagContextIDKey.String(val)
+}
+
+// FeatureFlagErrorMessage returns an attribute KeyValue conforming to the
+// "feature_flag.error.message" semantic conventions. It represents a message
+// providing more detail about an error that occurred during feature flag
+// evaluation in human-readable form.
+func FeatureFlagErrorMessage(val string) attribute.KeyValue {
+ return FeatureFlagErrorMessageKey.String(val)
+}
+
+// FeatureFlagKey returns an attribute KeyValue conforming to the
+// "feature_flag.key" semantic conventions. It represents the lookup key of the
+// feature flag.
+func FeatureFlagKey(val string) attribute.KeyValue {
+ return FeatureFlagKeyKey.String(val)
+}
+
+// FeatureFlagProviderName returns an attribute KeyValue conforming to the
+// "feature_flag.provider.name" semantic conventions. It represents the
+// identifies the feature flag provider.
+func FeatureFlagProviderName(val string) attribute.KeyValue {
+ return FeatureFlagProviderNameKey.String(val)
+}
+
+// FeatureFlagResultVariant returns an attribute KeyValue conforming to the
+// "feature_flag.result.variant" semantic conventions. It represents a semantic
+// identifier for an evaluated flag value.
+func FeatureFlagResultVariant(val string) attribute.KeyValue {
+ return FeatureFlagResultVariantKey.String(val)
+}
+
+// FeatureFlagSetID returns an attribute KeyValue conforming to the
+// "feature_flag.set.id" semantic conventions. It represents the identifier of
+// the [flag set] to which the feature flag belongs.
+//
+// [flag set]: https://openfeature.dev/specification/glossary/#flag-set
+func FeatureFlagSetID(val string) attribute.KeyValue {
+ return FeatureFlagSetIDKey.String(val)
+}
+
+// FeatureFlagVersion returns an attribute KeyValue conforming to the
+// "feature_flag.version" semantic conventions. It represents the version of the
+// ruleset used during the evaluation. This may be any stable value which
+// uniquely identifies the ruleset.
+func FeatureFlagVersion(val string) attribute.KeyValue {
+ return FeatureFlagVersionKey.String(val)
+}
+
+// Enum values for feature_flag.result.reason
+var (
+ // The resolved value is static (no dynamic evaluation).
+ // Stability: release_candidate
+ FeatureFlagResultReasonStatic = FeatureFlagResultReasonKey.String("static")
+ // The resolved value fell back to a pre-configured value (no dynamic evaluation
+ // occurred or dynamic evaluation yielded no result).
+ // Stability: release_candidate
+ FeatureFlagResultReasonDefault = FeatureFlagResultReasonKey.String("default")
+ // The resolved value was the result of a dynamic evaluation, such as a rule or
+ // specific user-targeting.
+ // Stability: release_candidate
+ FeatureFlagResultReasonTargetingMatch = FeatureFlagResultReasonKey.String("targeting_match")
+ // The resolved value was the result of pseudorandom assignment.
+ // Stability: release_candidate
+ FeatureFlagResultReasonSplit = FeatureFlagResultReasonKey.String("split")
+ // The resolved value was retrieved from cache.
+ // Stability: release_candidate
+ FeatureFlagResultReasonCached = FeatureFlagResultReasonKey.String("cached")
+ // The resolved value was the result of the flag being disabled in the
+ // management system.
+ // Stability: release_candidate
+ FeatureFlagResultReasonDisabled = FeatureFlagResultReasonKey.String("disabled")
+ // The reason for the resolved value could not be determined.
+ // Stability: release_candidate
+ FeatureFlagResultReasonUnknown = FeatureFlagResultReasonKey.String("unknown")
+ // The resolved value is non-authoritative or possibly out of date
+ // Stability: release_candidate
+ FeatureFlagResultReasonStale = FeatureFlagResultReasonKey.String("stale")
+ // The resolved value was the result of an error.
+ // Stability: release_candidate
+ FeatureFlagResultReasonError = FeatureFlagResultReasonKey.String("error")
+)
+
+// Namespace: file
+const (
+ // FileAccessedKey is the attribute Key conforming to the "file.accessed"
+ // semantic conventions. It represents the time when the file was last accessed,
+ // in ISO 8601 format.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "2021-01-01T12:00:00Z"
+ // Note: This attribute might not be supported by some file systems — NFS,
+ // FAT32, in embedded OS, etc.
+ FileAccessedKey = attribute.Key("file.accessed")
+
+ // FileAttributesKey is the attribute Key conforming to the "file.attributes"
+ // semantic conventions. It represents the array of file attributes.
+ //
+ // Type: string[]
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "readonly", "hidden"
+ // Note: Attributes names depend on the OS or file system. Here’s a
+ // non-exhaustive list of values expected for this attribute: `archive`,
+ // `compressed`, `directory`, `encrypted`, `execute`, `hidden`, `immutable`,
+ // `journaled`, `read`, `readonly`, `symbolic link`, `system`, `temporary`,
+ // `write`.
+ FileAttributesKey = attribute.Key("file.attributes")
+
+ // FileChangedKey is the attribute Key conforming to the "file.changed" semantic
+ // conventions. It represents the time when the file attributes or metadata was
+ // last changed, in ISO 8601 format.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "2021-01-01T12:00:00Z"
+ // Note: `file.changed` captures the time when any of the file's properties or
+ // attributes (including the content) are changed, while `file.modified`
+ // captures the timestamp when the file content is modified.
+ FileChangedKey = attribute.Key("file.changed")
+
+ // FileCreatedKey is the attribute Key conforming to the "file.created" semantic
+ // conventions. It represents the time when the file was created, in ISO 8601
+ // format.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "2021-01-01T12:00:00Z"
+ // Note: This attribute might not be supported by some file systems — NFS,
+ // FAT32, in embedded OS, etc.
+ FileCreatedKey = attribute.Key("file.created")
+
+ // FileDirectoryKey is the attribute Key conforming to the "file.directory"
+ // semantic conventions. It represents the directory where the file is located.
+ // It should include the drive letter, when appropriate.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "/home/user", "C:\Program Files\MyApp"
+ FileDirectoryKey = attribute.Key("file.directory")
+
+ // FileExtensionKey is the attribute Key conforming to the "file.extension"
+ // semantic conventions. It represents the file extension, excluding the leading
+ // dot.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "png", "gz"
+ // Note: When the file name has multiple extensions (example.tar.gz), only the
+ // last one should be captured ("gz", not "tar.gz").
+ FileExtensionKey = attribute.Key("file.extension")
+
+ // FileForkNameKey is the attribute Key conforming to the "file.fork_name"
+ // semantic conventions. It represents the name of the fork. A fork is
+ // additional data associated with a filesystem object.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "Zone.Identifier"
+ // Note: On Linux, a resource fork is used to store additional data with a
+ // filesystem object. A file always has at least one fork for the data portion,
+ // and additional forks may exist.
+ // On NTFS, this is analogous to an Alternate Data Stream (ADS), and the default
+ // data stream for a file is just called $DATA. Zone.Identifier is commonly used
+ // by Windows to track contents downloaded from the Internet. An ADS is
+ // typically of the form: C:\path\to\filename.extension:some_fork_name, and
+ // some_fork_name is the value that should populate `fork_name`.
+ // `filename.extension` should populate `file.name`, and `extension` should
+ // populate `file.extension`. The full path, `file.path`, will include the fork
+ // name.
+ FileForkNameKey = attribute.Key("file.fork_name")
+
+ // FileGroupIDKey is the attribute Key conforming to the "file.group.id"
+ // semantic conventions. It represents the primary Group ID (GID) of the file.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "1000"
+ FileGroupIDKey = attribute.Key("file.group.id")
+
+ // FileGroupNameKey is the attribute Key conforming to the "file.group.name"
+ // semantic conventions. It represents the primary group name of the file.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "users"
+ FileGroupNameKey = attribute.Key("file.group.name")
+
+ // FileInodeKey is the attribute Key conforming to the "file.inode" semantic
+ // conventions. It represents the inode representing the file in the filesystem.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "256383"
+ FileInodeKey = attribute.Key("file.inode")
+
+ // FileModeKey is the attribute Key conforming to the "file.mode" semantic
+ // conventions. It represents the mode of the file in octal representation.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "0640"
+ FileModeKey = attribute.Key("file.mode")
+
+ // FileModifiedKey is the attribute Key conforming to the "file.modified"
+ // semantic conventions. It represents the time when the file content was last
+ // modified, in ISO 8601 format.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "2021-01-01T12:00:00Z"
+ FileModifiedKey = attribute.Key("file.modified")
+
+ // FileNameKey is the attribute Key conforming to the "file.name" semantic
+ // conventions. It represents the name of the file including the extension,
+ // without the directory.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "example.png"
+ FileNameKey = attribute.Key("file.name")
+
+ // FileOwnerIDKey is the attribute Key conforming to the "file.owner.id"
+ // semantic conventions. It represents the user ID (UID) or security identifier
+ // (SID) of the file owner.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "1000"
+ FileOwnerIDKey = attribute.Key("file.owner.id")
+
+ // FileOwnerNameKey is the attribute Key conforming to the "file.owner.name"
+ // semantic conventions. It represents the username of the file owner.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "root"
+ FileOwnerNameKey = attribute.Key("file.owner.name")
+
+ // FilePathKey is the attribute Key conforming to the "file.path" semantic
+ // conventions. It represents the full path to the file, including the file
+ // name. It should include the drive letter, when appropriate.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "/home/alice/example.png", "C:\Program Files\MyApp\myapp.exe"
+ FilePathKey = attribute.Key("file.path")
+
+ // FileSizeKey is the attribute Key conforming to the "file.size" semantic
+ // conventions. It represents the file size in bytes.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ FileSizeKey = attribute.Key("file.size")
+
+ // FileSymbolicLinkTargetPathKey is the attribute Key conforming to the
+ // "file.symbolic_link.target_path" semantic conventions. It represents the path
+ // to the target of a symbolic link.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "/usr/bin/python3"
+ // Note: This attribute is only applicable to symbolic links.
+ FileSymbolicLinkTargetPathKey = attribute.Key("file.symbolic_link.target_path")
+)
+
+// FileAccessed returns an attribute KeyValue conforming to the "file.accessed"
+// semantic conventions. It represents the time when the file was last accessed,
+// in ISO 8601 format.
+func FileAccessed(val string) attribute.KeyValue {
+ return FileAccessedKey.String(val)
+}
+
+// FileAttributes returns an attribute KeyValue conforming to the
+// "file.attributes" semantic conventions. It represents the array of file
+// attributes.
+func FileAttributes(val ...string) attribute.KeyValue {
+ return FileAttributesKey.StringSlice(val)
+}
+
+// FileChanged returns an attribute KeyValue conforming to the "file.changed"
+// semantic conventions. It represents the time when the file attributes or
+// metadata was last changed, in ISO 8601 format.
+func FileChanged(val string) attribute.KeyValue {
+ return FileChangedKey.String(val)
+}
+
+// FileCreated returns an attribute KeyValue conforming to the "file.created"
+// semantic conventions. It represents the time when the file was created, in ISO
+// 8601 format.
+func FileCreated(val string) attribute.KeyValue {
+ return FileCreatedKey.String(val)
+}
+
+// FileDirectory returns an attribute KeyValue conforming to the "file.directory"
+// semantic conventions. It represents the directory where the file is located.
+// It should include the drive letter, when appropriate.
+func FileDirectory(val string) attribute.KeyValue {
+ return FileDirectoryKey.String(val)
+}
+
+// FileExtension returns an attribute KeyValue conforming to the "file.extension"
+// semantic conventions. It represents the file extension, excluding the leading
+// dot.
+func FileExtension(val string) attribute.KeyValue {
+ return FileExtensionKey.String(val)
+}
+
+// FileForkName returns an attribute KeyValue conforming to the "file.fork_name"
+// semantic conventions. It represents the name of the fork. A fork is additional
+// data associated with a filesystem object.
+func FileForkName(val string) attribute.KeyValue {
+ return FileForkNameKey.String(val)
+}
+
+// FileGroupID returns an attribute KeyValue conforming to the "file.group.id"
+// semantic conventions. It represents the primary Group ID (GID) of the file.
+func FileGroupID(val string) attribute.KeyValue {
+ return FileGroupIDKey.String(val)
+}
+
+// FileGroupName returns an attribute KeyValue conforming to the
+// "file.group.name" semantic conventions. It represents the primary group name
+// of the file.
+func FileGroupName(val string) attribute.KeyValue {
+ return FileGroupNameKey.String(val)
+}
+
+// FileInode returns an attribute KeyValue conforming to the "file.inode"
+// semantic conventions. It represents the inode representing the file in the
+// filesystem.
+func FileInode(val string) attribute.KeyValue {
+ return FileInodeKey.String(val)
+}
+
+// FileMode returns an attribute KeyValue conforming to the "file.mode" semantic
+// conventions. It represents the mode of the file in octal representation.
+func FileMode(val string) attribute.KeyValue {
+ return FileModeKey.String(val)
+}
+
+// FileModified returns an attribute KeyValue conforming to the "file.modified"
+// semantic conventions. It represents the time when the file content was last
+// modified, in ISO 8601 format.
+func FileModified(val string) attribute.KeyValue {
+ return FileModifiedKey.String(val)
+}
+
+// FileName returns an attribute KeyValue conforming to the "file.name" semantic
+// conventions. It represents the name of the file including the extension,
+// without the directory.
+func FileName(val string) attribute.KeyValue {
+ return FileNameKey.String(val)
+}
+
+// FileOwnerID returns an attribute KeyValue conforming to the "file.owner.id"
+// semantic conventions. It represents the user ID (UID) or security identifier
+// (SID) of the file owner.
+func FileOwnerID(val string) attribute.KeyValue {
+ return FileOwnerIDKey.String(val)
+}
+
+// FileOwnerName returns an attribute KeyValue conforming to the
+// "file.owner.name" semantic conventions. It represents the username of the file
+// owner.
+func FileOwnerName(val string) attribute.KeyValue {
+ return FileOwnerNameKey.String(val)
+}
+
+// FilePath returns an attribute KeyValue conforming to the "file.path" semantic
+// conventions. It represents the full path to the file, including the file name.
+// It should include the drive letter, when appropriate.
+func FilePath(val string) attribute.KeyValue {
+ return FilePathKey.String(val)
+}
+
+// FileSize returns an attribute KeyValue conforming to the "file.size" semantic
+// conventions. It represents the file size in bytes.
+func FileSize(val int) attribute.KeyValue {
+ return FileSizeKey.Int(val)
+}
+
+// FileSymbolicLinkTargetPath returns an attribute KeyValue conforming to the
+// "file.symbolic_link.target_path" semantic conventions. It represents the path
+// to the target of a symbolic link.
+func FileSymbolicLinkTargetPath(val string) attribute.KeyValue {
+ return FileSymbolicLinkTargetPathKey.String(val)
+}
+
+// Namespace: gcp
+const (
+ // GCPAppHubApplicationContainerKey is the attribute Key conforming to the
+ // "gcp.apphub.application.container" semantic conventions. It represents the
+ // container within GCP where the AppHub application is defined.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "projects/my-container-project"
+ GCPAppHubApplicationContainerKey = attribute.Key("gcp.apphub.application.container")
+
+ // GCPAppHubApplicationIDKey is the attribute Key conforming to the
+ // "gcp.apphub.application.id" semantic conventions. It represents the name of
+ // the application as configured in AppHub.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "my-application"
+ GCPAppHubApplicationIDKey = attribute.Key("gcp.apphub.application.id")
+
+ // GCPAppHubApplicationLocationKey is the attribute Key conforming to the
+ // "gcp.apphub.application.location" semantic conventions. It represents the GCP
+ // zone or region where the application is defined.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "us-central1"
+ GCPAppHubApplicationLocationKey = attribute.Key("gcp.apphub.application.location")
+
+ // GCPAppHubServiceCriticalityTypeKey is the attribute Key conforming to the
+ // "gcp.apphub.service.criticality_type" semantic conventions. It represents the
+ // criticality of a service indicates its importance to the business.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ // Note: [See AppHub type enum]
+ //
+ // [See AppHub type enum]: https://cloud.google.com/app-hub/docs/reference/rest/v1/Attributes#type
+ GCPAppHubServiceCriticalityTypeKey = attribute.Key("gcp.apphub.service.criticality_type")
+
+ // GCPAppHubServiceEnvironmentTypeKey is the attribute Key conforming to the
+ // "gcp.apphub.service.environment_type" semantic conventions. It represents the
+ // environment of a service is the stage of a software lifecycle.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ // Note: [See AppHub environment type]
+ //
+ // [See AppHub environment type]: https://cloud.google.com/app-hub/docs/reference/rest/v1/Attributes#type_1
+ GCPAppHubServiceEnvironmentTypeKey = attribute.Key("gcp.apphub.service.environment_type")
+
+ // GCPAppHubServiceIDKey is the attribute Key conforming to the
+ // "gcp.apphub.service.id" semantic conventions. It represents the name of the
+ // service as configured in AppHub.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "my-service"
+ GCPAppHubServiceIDKey = attribute.Key("gcp.apphub.service.id")
+
+ // GCPAppHubWorkloadCriticalityTypeKey is the attribute Key conforming to the
+ // "gcp.apphub.workload.criticality_type" semantic conventions. It represents
+ // the criticality of a workload indicates its importance to the business.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ // Note: [See AppHub type enum]
+ //
+ // [See AppHub type enum]: https://cloud.google.com/app-hub/docs/reference/rest/v1/Attributes#type
+ GCPAppHubWorkloadCriticalityTypeKey = attribute.Key("gcp.apphub.workload.criticality_type")
+
+ // GCPAppHubWorkloadEnvironmentTypeKey is the attribute Key conforming to the
+ // "gcp.apphub.workload.environment_type" semantic conventions. It represents
+ // the environment of a workload is the stage of a software lifecycle.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ // Note: [See AppHub environment type]
+ //
+ // [See AppHub environment type]: https://cloud.google.com/app-hub/docs/reference/rest/v1/Attributes#type_1
+ GCPAppHubWorkloadEnvironmentTypeKey = attribute.Key("gcp.apphub.workload.environment_type")
+
+ // GCPAppHubWorkloadIDKey is the attribute Key conforming to the
+ // "gcp.apphub.workload.id" semantic conventions. It represents the name of the
+ // workload as configured in AppHub.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "my-workload"
+ GCPAppHubWorkloadIDKey = attribute.Key("gcp.apphub.workload.id")
+
+ // GCPAppHubDestinationApplicationContainerKey is the attribute Key conforming
+ // to the "gcp.apphub_destination.application.container" semantic conventions.
+ // It represents the container within GCP where the AppHub destination
+ // application is defined.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "projects/my-container-project"
+ GCPAppHubDestinationApplicationContainerKey = attribute.Key("gcp.apphub_destination.application.container")
+
+ // GCPAppHubDestinationApplicationIDKey is the attribute Key conforming to the
+ // "gcp.apphub_destination.application.id" semantic conventions. It represents
+ // the name of the destination application as configured in AppHub.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "my-application"
+ GCPAppHubDestinationApplicationIDKey = attribute.Key("gcp.apphub_destination.application.id")
+
+ // GCPAppHubDestinationApplicationLocationKey is the attribute Key conforming to
+ // the "gcp.apphub_destination.application.location" semantic conventions. It
+ // represents the GCP zone or region where the destination application is
+ // defined.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "us-central1"
+ GCPAppHubDestinationApplicationLocationKey = attribute.Key("gcp.apphub_destination.application.location")
+
+ // GCPAppHubDestinationServiceCriticalityTypeKey is the attribute Key conforming
+ // to the "gcp.apphub_destination.service.criticality_type" semantic
+ // conventions. It represents the criticality of a destination workload
+ // indicates its importance to the business as specified in [AppHub type enum].
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ //
+ // [AppHub type enum]: https://cloud.google.com/app-hub/docs/reference/rest/v1/Attributes#type
+ GCPAppHubDestinationServiceCriticalityTypeKey = attribute.Key("gcp.apphub_destination.service.criticality_type")
+
+ // GCPAppHubDestinationServiceEnvironmentTypeKey is the attribute Key conforming
+ // to the "gcp.apphub_destination.service.environment_type" semantic
+ // conventions. It represents the software lifecycle stage of a destination
+ // service as defined [AppHub environment type].
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ //
+ // [AppHub environment type]: https://cloud.google.com/app-hub/docs/reference/rest/v1/Attributes#type_1
+ GCPAppHubDestinationServiceEnvironmentTypeKey = attribute.Key("gcp.apphub_destination.service.environment_type")
+
+ // GCPAppHubDestinationServiceIDKey is the attribute Key conforming to the
+ // "gcp.apphub_destination.service.id" semantic conventions. It represents the
+ // name of the destination service as configured in AppHub.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "my-service"
+ GCPAppHubDestinationServiceIDKey = attribute.Key("gcp.apphub_destination.service.id")
+
+ // GCPAppHubDestinationWorkloadCriticalityTypeKey is the attribute Key
+ // conforming to the "gcp.apphub_destination.workload.criticality_type" semantic
+ // conventions. It represents the criticality of a destination workload
+ // indicates its importance to the business as specified in [AppHub type enum].
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ //
+ // [AppHub type enum]: https://cloud.google.com/app-hub/docs/reference/rest/v1/Attributes#type
+ GCPAppHubDestinationWorkloadCriticalityTypeKey = attribute.Key("gcp.apphub_destination.workload.criticality_type")
+
+ // GCPAppHubDestinationWorkloadEnvironmentTypeKey is the attribute Key
+ // conforming to the "gcp.apphub_destination.workload.environment_type" semantic
+ // conventions. It represents the environment of a destination workload is the
+ // stage of a software lifecycle as provided in the [AppHub environment type].
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ //
+ // [AppHub environment type]: https://cloud.google.com/app-hub/docs/reference/rest/v1/Attributes#type_1
+ GCPAppHubDestinationWorkloadEnvironmentTypeKey = attribute.Key("gcp.apphub_destination.workload.environment_type")
+
+ // GCPAppHubDestinationWorkloadIDKey is the attribute Key conforming to the
+ // "gcp.apphub_destination.workload.id" semantic conventions. It represents the
+ // name of the destination workload as configured in AppHub.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "my-workload"
+ GCPAppHubDestinationWorkloadIDKey = attribute.Key("gcp.apphub_destination.workload.id")
+
+ // GCPClientServiceKey is the attribute Key conforming to the
+ // "gcp.client.service" semantic conventions. It represents the identifies the
+ // Google Cloud service for which the official client library is intended.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "appengine", "run", "firestore", "alloydb", "spanner"
+ // Note: Intended to be a stable identifier for Google Cloud client libraries
+ // that is uniform across implementation languages. The value should be derived
+ // from the canonical service domain for the service; for example,
+ // 'foo.googleapis.com' should result in a value of 'foo'.
+ GCPClientServiceKey = attribute.Key("gcp.client.service")
+
+ // GCPCloudRunJobExecutionKey is the attribute Key conforming to the
+ // "gcp.cloud_run.job.execution" semantic conventions. It represents the name of
+ // the Cloud Run [execution] being run for the Job, as set by the
+ // [`CLOUD_RUN_EXECUTION`] environment variable.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "job-name-xxxx", "sample-job-mdw84"
+ //
+ // [execution]: https://cloud.google.com/run/docs/managing/job-executions
+ // [`CLOUD_RUN_EXECUTION`]: https://cloud.google.com/run/docs/container-contract#jobs-env-vars
+ GCPCloudRunJobExecutionKey = attribute.Key("gcp.cloud_run.job.execution")
+
+ // GCPCloudRunJobTaskIndexKey is the attribute Key conforming to the
+ // "gcp.cloud_run.job.task_index" semantic conventions. It represents the index
+ // for a task within an execution as provided by the [`CLOUD_RUN_TASK_INDEX`]
+ // environment variable.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 0, 1
+ //
+ // [`CLOUD_RUN_TASK_INDEX`]: https://cloud.google.com/run/docs/container-contract#jobs-env-vars
+ GCPCloudRunJobTaskIndexKey = attribute.Key("gcp.cloud_run.job.task_index")
+
+ // GCPGCEInstanceHostnameKey is the attribute Key conforming to the
+ // "gcp.gce.instance.hostname" semantic conventions. It represents the hostname
+ // of a GCE instance. This is the full value of the default or [custom hostname]
+ // .
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "my-host1234.example.com",
+ // "sample-vm.us-west1-b.c.my-project.internal"
+ //
+ // [custom hostname]: https://cloud.google.com/compute/docs/instances/custom-hostname-vm
+ GCPGCEInstanceHostnameKey = attribute.Key("gcp.gce.instance.hostname")
+
+ // GCPGCEInstanceNameKey is the attribute Key conforming to the
+ // "gcp.gce.instance.name" semantic conventions. It represents the instance name
+ // of a GCE instance. This is the value provided by `host.name`, the visible
+ // name of the instance in the Cloud Console UI, and the prefix for the default
+ // hostname of the instance as defined by the [default internal DNS name].
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "instance-1", "my-vm-name"
+ //
+ // [default internal DNS name]: https://cloud.google.com/compute/docs/internal-dns#instance-fully-qualified-domain-names
+ GCPGCEInstanceNameKey = attribute.Key("gcp.gce.instance.name")
+
+ // GCPGCEInstanceGroupManagerNameKey is the attribute Key conforming to the
+ // "gcp.gce.instance_group_manager.name" semantic conventions. It represents the
+ // name of the Instance Group Manager (IGM) that manages this VM, if any.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "web-igm", "my-managed-group"
+ GCPGCEInstanceGroupManagerNameKey = attribute.Key("gcp.gce.instance_group_manager.name")
+
+ // GCPGCEInstanceGroupManagerRegionKey is the attribute Key conforming to the
+ // "gcp.gce.instance_group_manager.region" semantic conventions. It represents
+ // the region of a **regional** Instance Group Manager (e.g., `us-central1`).
+ // Set this **only** when the IGM is regional.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "us-central1", "europe-west1"
+ GCPGCEInstanceGroupManagerRegionKey = attribute.Key("gcp.gce.instance_group_manager.region")
+
+ // GCPGCEInstanceGroupManagerZoneKey is the attribute Key conforming to the
+ // "gcp.gce.instance_group_manager.zone" semantic conventions. It represents the
+ // zone of a **zonal** Instance Group Manager (e.g., `us-central1-a`). Set this
+ // **only** when the IGM is zonal.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "us-central1-a", "europe-west1-b"
+ GCPGCEInstanceGroupManagerZoneKey = attribute.Key("gcp.gce.instance_group_manager.zone")
+)
+
+// GCPAppHubApplicationContainer returns an attribute KeyValue conforming to the
+// "gcp.apphub.application.container" semantic conventions. It represents the
+// container within GCP where the AppHub application is defined.
+func GCPAppHubApplicationContainer(val string) attribute.KeyValue {
+ return GCPAppHubApplicationContainerKey.String(val)
+}
+
+// GCPAppHubApplicationID returns an attribute KeyValue conforming to the
+// "gcp.apphub.application.id" semantic conventions. It represents the name of
+// the application as configured in AppHub.
+func GCPAppHubApplicationID(val string) attribute.KeyValue {
+ return GCPAppHubApplicationIDKey.String(val)
+}
+
+// GCPAppHubApplicationLocation returns an attribute KeyValue conforming to the
+// "gcp.apphub.application.location" semantic conventions. It represents the GCP
+// zone or region where the application is defined.
+func GCPAppHubApplicationLocation(val string) attribute.KeyValue {
+ return GCPAppHubApplicationLocationKey.String(val)
+}
+
+// GCPAppHubServiceID returns an attribute KeyValue conforming to the
+// "gcp.apphub.service.id" semantic conventions. It represents the name of the
+// service as configured in AppHub.
+func GCPAppHubServiceID(val string) attribute.KeyValue {
+ return GCPAppHubServiceIDKey.String(val)
+}
+
+// GCPAppHubWorkloadID returns an attribute KeyValue conforming to the
+// "gcp.apphub.workload.id" semantic conventions. It represents the name of the
+// workload as configured in AppHub.
+func GCPAppHubWorkloadID(val string) attribute.KeyValue {
+ return GCPAppHubWorkloadIDKey.String(val)
+}
+
+// GCPAppHubDestinationApplicationContainer returns an attribute KeyValue
+// conforming to the "gcp.apphub_destination.application.container" semantic
+// conventions. It represents the container within GCP where the AppHub
+// destination application is defined.
+func GCPAppHubDestinationApplicationContainer(val string) attribute.KeyValue {
+ return GCPAppHubDestinationApplicationContainerKey.String(val)
+}
+
+// GCPAppHubDestinationApplicationID returns an attribute KeyValue conforming to
+// the "gcp.apphub_destination.application.id" semantic conventions. It
+// represents the name of the destination application as configured in AppHub.
+func GCPAppHubDestinationApplicationID(val string) attribute.KeyValue {
+ return GCPAppHubDestinationApplicationIDKey.String(val)
+}
+
+// GCPAppHubDestinationApplicationLocation returns an attribute KeyValue
+// conforming to the "gcp.apphub_destination.application.location" semantic
+// conventions. It represents the GCP zone or region where the destination
+// application is defined.
+func GCPAppHubDestinationApplicationLocation(val string) attribute.KeyValue {
+ return GCPAppHubDestinationApplicationLocationKey.String(val)
+}
+
+// GCPAppHubDestinationServiceID returns an attribute KeyValue conforming to the
+// "gcp.apphub_destination.service.id" semantic conventions. It represents the
+// name of the destination service as configured in AppHub.
+func GCPAppHubDestinationServiceID(val string) attribute.KeyValue {
+ return GCPAppHubDestinationServiceIDKey.String(val)
+}
+
+// GCPAppHubDestinationWorkloadID returns an attribute KeyValue conforming to the
+// "gcp.apphub_destination.workload.id" semantic conventions. It represents the
+// name of the destination workload as configured in AppHub.
+func GCPAppHubDestinationWorkloadID(val string) attribute.KeyValue {
+ return GCPAppHubDestinationWorkloadIDKey.String(val)
+}
+
+// GCPClientService returns an attribute KeyValue conforming to the
+// "gcp.client.service" semantic conventions. It represents the identifies the
+// Google Cloud service for which the official client library is intended.
+func GCPClientService(val string) attribute.KeyValue {
+ return GCPClientServiceKey.String(val)
+}
+
+// GCPCloudRunJobExecution returns an attribute KeyValue conforming to the
+// "gcp.cloud_run.job.execution" semantic conventions. It represents the name of
+// the Cloud Run [execution] being run for the Job, as set by the
+// [`CLOUD_RUN_EXECUTION`] environment variable.
+//
+// [execution]: https://cloud.google.com/run/docs/managing/job-executions
+// [`CLOUD_RUN_EXECUTION`]: https://cloud.google.com/run/docs/container-contract#jobs-env-vars
+func GCPCloudRunJobExecution(val string) attribute.KeyValue {
+ return GCPCloudRunJobExecutionKey.String(val)
+}
+
+// GCPCloudRunJobTaskIndex returns an attribute KeyValue conforming to the
+// "gcp.cloud_run.job.task_index" semantic conventions. It represents the index
+// for a task within an execution as provided by the [`CLOUD_RUN_TASK_INDEX`]
+// environment variable.
+//
+// [`CLOUD_RUN_TASK_INDEX`]: https://cloud.google.com/run/docs/container-contract#jobs-env-vars
+func GCPCloudRunJobTaskIndex(val int) attribute.KeyValue {
+ return GCPCloudRunJobTaskIndexKey.Int(val)
+}
+
+// GCPGCEInstanceHostname returns an attribute KeyValue conforming to the
+// "gcp.gce.instance.hostname" semantic conventions. It represents the hostname
+// of a GCE instance. This is the full value of the default or [custom hostname]
+// .
+//
+// [custom hostname]: https://cloud.google.com/compute/docs/instances/custom-hostname-vm
+func GCPGCEInstanceHostname(val string) attribute.KeyValue {
+ return GCPGCEInstanceHostnameKey.String(val)
+}
+
+// GCPGCEInstanceName returns an attribute KeyValue conforming to the
+// "gcp.gce.instance.name" semantic conventions. It represents the instance name
+// of a GCE instance. This is the value provided by `host.name`, the visible name
+// of the instance in the Cloud Console UI, and the prefix for the default
+// hostname of the instance as defined by the [default internal DNS name].
+//
+// [default internal DNS name]: https://cloud.google.com/compute/docs/internal-dns#instance-fully-qualified-domain-names
+func GCPGCEInstanceName(val string) attribute.KeyValue {
+ return GCPGCEInstanceNameKey.String(val)
+}
+
+// GCPGCEInstanceGroupManagerName returns an attribute KeyValue conforming to the
+// "gcp.gce.instance_group_manager.name" semantic conventions. It represents the
+// name of the Instance Group Manager (IGM) that manages this VM, if any.
+func GCPGCEInstanceGroupManagerName(val string) attribute.KeyValue {
+ return GCPGCEInstanceGroupManagerNameKey.String(val)
+}
+
+// GCPGCEInstanceGroupManagerRegion returns an attribute KeyValue conforming to
+// the "gcp.gce.instance_group_manager.region" semantic conventions. It
+// represents the region of a **regional** Instance Group Manager (e.g.,
+// `us-central1`). Set this **only** when the IGM is regional.
+func GCPGCEInstanceGroupManagerRegion(val string) attribute.KeyValue {
+ return GCPGCEInstanceGroupManagerRegionKey.String(val)
+}
+
+// GCPGCEInstanceGroupManagerZone returns an attribute KeyValue conforming to the
+// "gcp.gce.instance_group_manager.zone" semantic conventions. It represents the
+// zone of a **zonal** Instance Group Manager (e.g., `us-central1-a`). Set this
+// **only** when the IGM is zonal.
+func GCPGCEInstanceGroupManagerZone(val string) attribute.KeyValue {
+ return GCPGCEInstanceGroupManagerZoneKey.String(val)
+}
+
+// Enum values for gcp.apphub.service.criticality_type
+var (
+ // Mission critical service.
+ // Stability: development
+ GCPAppHubServiceCriticalityTypeMissionCritical = GCPAppHubServiceCriticalityTypeKey.String("MISSION_CRITICAL")
+ // High impact.
+ // Stability: development
+ GCPAppHubServiceCriticalityTypeHigh = GCPAppHubServiceCriticalityTypeKey.String("HIGH")
+ // Medium impact.
+ // Stability: development
+ GCPAppHubServiceCriticalityTypeMedium = GCPAppHubServiceCriticalityTypeKey.String("MEDIUM")
+ // Low impact.
+ // Stability: development
+ GCPAppHubServiceCriticalityTypeLow = GCPAppHubServiceCriticalityTypeKey.String("LOW")
+)
+
+// Enum values for gcp.apphub.service.environment_type
+var (
+ // Production environment.
+ // Stability: development
+ GCPAppHubServiceEnvironmentTypeProduction = GCPAppHubServiceEnvironmentTypeKey.String("PRODUCTION")
+ // Staging environment.
+ // Stability: development
+ GCPAppHubServiceEnvironmentTypeStaging = GCPAppHubServiceEnvironmentTypeKey.String("STAGING")
+ // Test environment.
+ // Stability: development
+ GCPAppHubServiceEnvironmentTypeTest = GCPAppHubServiceEnvironmentTypeKey.String("TEST")
+ // Development environment.
+ // Stability: development
+ GCPAppHubServiceEnvironmentTypeDevelopment = GCPAppHubServiceEnvironmentTypeKey.String("DEVELOPMENT")
+)
+
+// Enum values for gcp.apphub.workload.criticality_type
+var (
+ // Mission critical service.
+ // Stability: development
+ GCPAppHubWorkloadCriticalityTypeMissionCritical = GCPAppHubWorkloadCriticalityTypeKey.String("MISSION_CRITICAL")
+ // High impact.
+ // Stability: development
+ GCPAppHubWorkloadCriticalityTypeHigh = GCPAppHubWorkloadCriticalityTypeKey.String("HIGH")
+ // Medium impact.
+ // Stability: development
+ GCPAppHubWorkloadCriticalityTypeMedium = GCPAppHubWorkloadCriticalityTypeKey.String("MEDIUM")
+ // Low impact.
+ // Stability: development
+ GCPAppHubWorkloadCriticalityTypeLow = GCPAppHubWorkloadCriticalityTypeKey.String("LOW")
+)
+
+// Enum values for gcp.apphub.workload.environment_type
+var (
+ // Production environment.
+ // Stability: development
+ GCPAppHubWorkloadEnvironmentTypeProduction = GCPAppHubWorkloadEnvironmentTypeKey.String("PRODUCTION")
+ // Staging environment.
+ // Stability: development
+ GCPAppHubWorkloadEnvironmentTypeStaging = GCPAppHubWorkloadEnvironmentTypeKey.String("STAGING")
+ // Test environment.
+ // Stability: development
+ GCPAppHubWorkloadEnvironmentTypeTest = GCPAppHubWorkloadEnvironmentTypeKey.String("TEST")
+ // Development environment.
+ // Stability: development
+ GCPAppHubWorkloadEnvironmentTypeDevelopment = GCPAppHubWorkloadEnvironmentTypeKey.String("DEVELOPMENT")
+)
+
+// Enum values for gcp.apphub_destination.service.criticality_type
+var (
+ // Mission critical service.
+ // Stability: development
+ GCPAppHubDestinationServiceCriticalityTypeMissionCritical = GCPAppHubDestinationServiceCriticalityTypeKey.String("MISSION_CRITICAL")
+ // High impact.
+ // Stability: development
+ GCPAppHubDestinationServiceCriticalityTypeHigh = GCPAppHubDestinationServiceCriticalityTypeKey.String("HIGH")
+ // Medium impact.
+ // Stability: development
+ GCPAppHubDestinationServiceCriticalityTypeMedium = GCPAppHubDestinationServiceCriticalityTypeKey.String("MEDIUM")
+ // Low impact.
+ // Stability: development
+ GCPAppHubDestinationServiceCriticalityTypeLow = GCPAppHubDestinationServiceCriticalityTypeKey.String("LOW")
+)
+
+// Enum values for gcp.apphub_destination.service.environment_type
+var (
+ // Production environment.
+ // Stability: development
+ GCPAppHubDestinationServiceEnvironmentTypeProduction = GCPAppHubDestinationServiceEnvironmentTypeKey.String("PRODUCTION")
+ // Staging environment.
+ // Stability: development
+ GCPAppHubDestinationServiceEnvironmentTypeStaging = GCPAppHubDestinationServiceEnvironmentTypeKey.String("STAGING")
+ // Test environment.
+ // Stability: development
+ GCPAppHubDestinationServiceEnvironmentTypeTest = GCPAppHubDestinationServiceEnvironmentTypeKey.String("TEST")
+ // Development environment.
+ // Stability: development
+ GCPAppHubDestinationServiceEnvironmentTypeDevelopment = GCPAppHubDestinationServiceEnvironmentTypeKey.String("DEVELOPMENT")
+)
+
+// Enum values for gcp.apphub_destination.workload.criticality_type
+var (
+ // Mission critical service.
+ // Stability: development
+ GCPAppHubDestinationWorkloadCriticalityTypeMissionCritical = GCPAppHubDestinationWorkloadCriticalityTypeKey.String("MISSION_CRITICAL")
+ // High impact.
+ // Stability: development
+ GCPAppHubDestinationWorkloadCriticalityTypeHigh = GCPAppHubDestinationWorkloadCriticalityTypeKey.String("HIGH")
+ // Medium impact.
+ // Stability: development
+ GCPAppHubDestinationWorkloadCriticalityTypeMedium = GCPAppHubDestinationWorkloadCriticalityTypeKey.String("MEDIUM")
+ // Low impact.
+ // Stability: development
+ GCPAppHubDestinationWorkloadCriticalityTypeLow = GCPAppHubDestinationWorkloadCriticalityTypeKey.String("LOW")
+)
+
+// Enum values for gcp.apphub_destination.workload.environment_type
+var (
+ // Production environment.
+ // Stability: development
+ GCPAppHubDestinationWorkloadEnvironmentTypeProduction = GCPAppHubDestinationWorkloadEnvironmentTypeKey.String("PRODUCTION")
+ // Staging environment.
+ // Stability: development
+ GCPAppHubDestinationWorkloadEnvironmentTypeStaging = GCPAppHubDestinationWorkloadEnvironmentTypeKey.String("STAGING")
+ // Test environment.
+ // Stability: development
+ GCPAppHubDestinationWorkloadEnvironmentTypeTest = GCPAppHubDestinationWorkloadEnvironmentTypeKey.String("TEST")
+ // Development environment.
+ // Stability: development
+ GCPAppHubDestinationWorkloadEnvironmentTypeDevelopment = GCPAppHubDestinationWorkloadEnvironmentTypeKey.String("DEVELOPMENT")
+)
+
+// Namespace: gen_ai
+const (
+ // GenAIAgentDescriptionKey is the attribute Key conforming to the
+ // "gen_ai.agent.description" semantic conventions. It represents the free-form
+ // description of the GenAI agent provided by the application.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "Helps with math problems", "Generates fiction stories"
+ GenAIAgentDescriptionKey = attribute.Key("gen_ai.agent.description")
+
+ // GenAIAgentIDKey is the attribute Key conforming to the "gen_ai.agent.id"
+ // semantic conventions. It represents the unique identifier of the GenAI agent.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "asst_5j66UpCpwteGg4YSxUnt7lPY"
+ GenAIAgentIDKey = attribute.Key("gen_ai.agent.id")
+
+ // GenAIAgentNameKey is the attribute Key conforming to the "gen_ai.agent.name"
+ // semantic conventions. It represents the human-readable name of the GenAI
+ // agent provided by the application.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "Math Tutor", "Fiction Writer"
+ GenAIAgentNameKey = attribute.Key("gen_ai.agent.name")
+
+ // GenAIAgentVersionKey is the attribute Key conforming to the
+ // "gen_ai.agent.version" semantic conventions. It represents the version of the
+ // GenAI agent.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "1.0.0", "2025-05-01"
+ GenAIAgentVersionKey = attribute.Key("gen_ai.agent.version")
+
+ // GenAIConversationIDKey is the attribute Key conforming to the
+ // "gen_ai.conversation.id" semantic conventions. It represents the unique
+ // identifier for a conversation (session, thread), used to store and correlate
+ // messages within this conversation.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "conv_5j66UpCpwteGg4YSxUnt7lPY"
+ GenAIConversationIDKey = attribute.Key("gen_ai.conversation.id")
+
+ // GenAIDataSourceIDKey is the attribute Key conforming to the
+ // "gen_ai.data_source.id" semantic conventions. It represents the data source
+ // identifier.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "H7STPQYOND"
+ // Note: Data sources are used by AI agents and RAG applications to store
+ // grounding data. A data source may be an external database, object store,
+ // document collection, website, or any other storage system used by the GenAI
+ // agent or application. The `gen_ai.data_source.id` SHOULD match the identifier
+ // used by the GenAI system rather than a name specific to the external storage,
+ // such as a database or object store. Semantic conventions referencing
+ // `gen_ai.data_source.id` MAY also leverage additional attributes, such as
+ // `db.*`, to further identify and describe the data source.
+ GenAIDataSourceIDKey = attribute.Key("gen_ai.data_source.id")
+
+ // GenAIEmbeddingsDimensionCountKey is the attribute Key conforming to the
+ // "gen_ai.embeddings.dimension.count" semantic conventions. It represents the
+ // number of dimensions the resulting output embeddings should have.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 512, 1024
+ GenAIEmbeddingsDimensionCountKey = attribute.Key("gen_ai.embeddings.dimension.count")
+
+ // GenAIEvaluationExplanationKey is the attribute Key conforming to the
+ // "gen_ai.evaluation.explanation" semantic conventions. It represents a
+ // free-form explanation for the assigned score provided by the evaluator.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "The response is factually accurate but lacks sufficient detail to
+ // fully address the question."
+ GenAIEvaluationExplanationKey = attribute.Key("gen_ai.evaluation.explanation")
+
+ // GenAIEvaluationNameKey is the attribute Key conforming to the
+ // "gen_ai.evaluation.name" semantic conventions. It represents the name of the
+ // evaluation metric used for the GenAI response.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "Relevance", "IntentResolution"
+ GenAIEvaluationNameKey = attribute.Key("gen_ai.evaluation.name")
+
+ // GenAIEvaluationScoreLabelKey is the attribute Key conforming to the
+ // "gen_ai.evaluation.score.label" semantic conventions. It represents the human
+ // readable label for evaluation.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "relevant", "not_relevant", "correct", "incorrect", "pass", "fail"
+ // Note: This attribute provides a human-readable interpretation of the
+ // evaluation score produced by an evaluator. For example, a score value of 1
+ // could mean "relevant" in one evaluation system and "not relevant" in another,
+ // depending on the scoring range and evaluator. The label SHOULD have low
+ // cardinality. Possible values depend on the evaluation metric and evaluator
+ // used; implementations SHOULD document the possible values.
+ GenAIEvaluationScoreLabelKey = attribute.Key("gen_ai.evaluation.score.label")
+
+ // GenAIEvaluationScoreValueKey is the attribute Key conforming to the
+ // "gen_ai.evaluation.score.value" semantic conventions. It represents the
+ // evaluation score returned by the evaluator.
+ //
+ // Type: double
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 4.0
+ GenAIEvaluationScoreValueKey = attribute.Key("gen_ai.evaluation.score.value")
+
+ // GenAIInputMessagesKey is the attribute Key conforming to the
+ // "gen_ai.input.messages" semantic conventions. It represents the chat history
+ // provided to the model as an input.
+ //
+ // Type: any
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "[\n {\n "role": "user",\n "parts": [\n {\n "type": "text",\n
+ // "content": "Weather in Paris?"\n }\n ]\n },\n {\n "role": "assistant",\n
+ // "parts": [\n {\n "type": "tool_call",\n "id":
+ // "call_VSPygqKTWdrhaFErNvMV18Yl",\n "name": "get_weather",\n "arguments": {\n
+ // "location": "Paris"\n }\n }\n ]\n },\n {\n "role": "tool",\n "parts": [\n {\n
+ // "type": "tool_call_response",\n "id": " call_VSPygqKTWdrhaFErNvMV18Yl",\n
+ // "result": "rainy, 57°F"\n }\n ]\n }\n]\n"
+ // Note: Instrumentations MUST follow [Input messages JSON schema].
+ // When the attribute is recorded on events, it MUST be recorded in structured
+ // form. When recorded on spans, it MAY be recorded as a JSON string if
+ // structured
+ // format is not supported and SHOULD be recorded in structured form otherwise.
+ //
+ // Messages MUST be provided in the order they were sent to the model.
+ // Instrumentations MAY provide a way for users to filter or truncate
+ // input messages.
+ //
+ // > [!Warning]
+ // > This attribute is likely to contain sensitive information including
+ // > user/PII data.
+ //
+ // See [Recording content on attributes]
+ // section for more details.
+ //
+ // [Input messages JSON schema]: /docs/gen-ai/gen-ai-input-messages.json
+ // [Recording content on attributes]: /docs/gen-ai/gen-ai-spans.md#recording-content-on-attributes
+ GenAIInputMessagesKey = attribute.Key("gen_ai.input.messages")
+
+ // GenAIOperationNameKey is the attribute Key conforming to the
+ // "gen_ai.operation.name" semantic conventions. It represents the name of the
+ // operation being performed.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ // Note: If one of the predefined values applies, but specific system uses a
+ // different name it's RECOMMENDED to document it in the semantic conventions
+ // for specific GenAI system and use system-specific name in the
+ // instrumentation. If a different name is not documented, instrumentation
+ // libraries SHOULD use applicable predefined value.
+ GenAIOperationNameKey = attribute.Key("gen_ai.operation.name")
+
+ // GenAIOutputMessagesKey is the attribute Key conforming to the
+ // "gen_ai.output.messages" semantic conventions. It represents the messages
+ // returned by the model where each message represents a specific model response
+ // (choice, candidate).
+ //
+ // Type: any
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "[\n {\n "role": "assistant",\n "parts": [\n {\n "type": "text",\n
+ // "content": "The weather in Paris is currently rainy with a temperature of
+ // 57°F."\n }\n ],\n "finish_reason": "stop"\n }\n]\n"
+ // Note: Instrumentations MUST follow [Output messages JSON schema]
+ //
+ // Each message represents a single output choice/candidate generated by
+ // the model. Each message corresponds to exactly one generation
+ // (choice/candidate) and vice versa - one choice cannot be split across
+ // multiple messages or one message cannot contain parts from multiple choices.
+ //
+ // When the attribute is recorded on events, it MUST be recorded in structured
+ // form. When recorded on spans, it MAY be recorded as a JSON string if
+ // structured
+ // format is not supported and SHOULD be recorded in structured form otherwise.
+ //
+ // Instrumentations MAY provide a way for users to filter or truncate
+ // output messages.
+ //
+ // > [!Warning]
+ // > This attribute is likely to contain sensitive information including
+ // > user/PII data.
+ //
+ // See [Recording content on attributes]
+ // section for more details.
+ //
+ // [Output messages JSON schema]: /docs/gen-ai/gen-ai-output-messages.json
+ // [Recording content on attributes]: /docs/gen-ai/gen-ai-spans.md#recording-content-on-attributes
+ GenAIOutputMessagesKey = attribute.Key("gen_ai.output.messages")
+
+ // GenAIOutputTypeKey is the attribute Key conforming to the
+ // "gen_ai.output.type" semantic conventions. It represents the represents the
+ // content type requested by the client.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ // Note: This attribute SHOULD be used when the client requests output of a
+ // specific type. The model may return zero or more outputs of this type.
+ // This attribute specifies the output modality and not the actual output
+ // format. For example, if an image is requested, the actual output could be a
+ // URL pointing to an image file.
+ // Additional output format details may be recorded in the future in the
+ // `gen_ai.output.{type}.*` attributes.
+ GenAIOutputTypeKey = attribute.Key("gen_ai.output.type")
+
+ // GenAIPromptNameKey is the attribute Key conforming to the
+ // "gen_ai.prompt.name" semantic conventions. It represents the name of the
+ // prompt that uniquely identifies it.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "analyze-code"
+ GenAIPromptNameKey = attribute.Key("gen_ai.prompt.name")
+
+ // GenAIProviderNameKey is the attribute Key conforming to the
+ // "gen_ai.provider.name" semantic conventions. It represents the Generative AI
+ // provider as identified by the client or server instrumentation.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ // Note: The attribute SHOULD be set based on the instrumentation's best
+ // knowledge and may differ from the actual model provider.
+ //
+ // Multiple providers, including Azure OpenAI, Gemini, and AI hosting platforms
+ // are accessible using the OpenAI REST API and corresponding client libraries,
+ // but may proxy or host models from different providers.
+ //
+ // The `gen_ai.request.model`, `gen_ai.response.model`, and `server.address`
+ // attributes may help identify the actual system in use.
+ //
+ // The `gen_ai.provider.name` attribute acts as a discriminator that
+ // identifies the GenAI telemetry format flavor specific to that provider
+ // within GenAI semantic conventions.
+ // It SHOULD be set consistently with provider-specific attributes and signals.
+ // For example, GenAI spans, metrics, and events related to AWS Bedrock
+ // should have the `gen_ai.provider.name` set to `aws.bedrock` and include
+ // applicable `aws.bedrock.*` attributes and are not expected to include
+ // `openai.*` attributes.
+ GenAIProviderNameKey = attribute.Key("gen_ai.provider.name")
+
+ // GenAIRequestChoiceCountKey is the attribute Key conforming to the
+ // "gen_ai.request.choice.count" semantic conventions. It represents the target
+ // number of candidate completions to return.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 3
+ GenAIRequestChoiceCountKey = attribute.Key("gen_ai.request.choice.count")
+
+ // GenAIRequestEncodingFormatsKey is the attribute Key conforming to the
+ // "gen_ai.request.encoding_formats" semantic conventions. It represents the
+ // encoding formats requested in an embeddings operation, if specified.
+ //
+ // Type: string[]
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "base64"], ["float", "binary"
+ // Note: In some GenAI systems the encoding formats are called embedding types.
+ // Also, some GenAI systems only accept a single format per request.
+ GenAIRequestEncodingFormatsKey = attribute.Key("gen_ai.request.encoding_formats")
+
+ // GenAIRequestFrequencyPenaltyKey is the attribute Key conforming to the
+ // "gen_ai.request.frequency_penalty" semantic conventions. It represents the
+ // frequency penalty setting for the GenAI request.
+ //
+ // Type: double
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 0.1
+ GenAIRequestFrequencyPenaltyKey = attribute.Key("gen_ai.request.frequency_penalty")
+
+ // GenAIRequestMaxTokensKey is the attribute Key conforming to the
+ // "gen_ai.request.max_tokens" semantic conventions. It represents the maximum
+ // number of tokens the model generates for a request.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 100
+ GenAIRequestMaxTokensKey = attribute.Key("gen_ai.request.max_tokens")
+
+ // GenAIRequestModelKey is the attribute Key conforming to the
+ // "gen_ai.request.model" semantic conventions. It represents the name of the
+ // GenAI model a request is being made to.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: gpt-4
+ GenAIRequestModelKey = attribute.Key("gen_ai.request.model")
+
+ // GenAIRequestPresencePenaltyKey is the attribute Key conforming to the
+ // "gen_ai.request.presence_penalty" semantic conventions. It represents the
+ // presence penalty setting for the GenAI request.
+ //
+ // Type: double
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 0.1
+ GenAIRequestPresencePenaltyKey = attribute.Key("gen_ai.request.presence_penalty")
+
+ // GenAIRequestSeedKey is the attribute Key conforming to the
+ // "gen_ai.request.seed" semantic conventions. It represents the requests with
+ // same seed value more likely to return same result.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 100
+ GenAIRequestSeedKey = attribute.Key("gen_ai.request.seed")
+
+ // GenAIRequestStopSequencesKey is the attribute Key conforming to the
+ // "gen_ai.request.stop_sequences" semantic conventions. It represents the list
+ // of sequences that the model will use to stop generating further tokens.
+ //
+ // Type: string[]
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "forest", "lived"
+ GenAIRequestStopSequencesKey = attribute.Key("gen_ai.request.stop_sequences")
+
+ // GenAIRequestTemperatureKey is the attribute Key conforming to the
+ // "gen_ai.request.temperature" semantic conventions. It represents the
+ // temperature setting for the GenAI request.
+ //
+ // Type: double
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 0.0
+ GenAIRequestTemperatureKey = attribute.Key("gen_ai.request.temperature")
+
+ // GenAIRequestTopKKey is the attribute Key conforming to the
+ // "gen_ai.request.top_k" semantic conventions. It represents the top_k sampling
+ // setting for the GenAI request.
+ //
+ // Type: double
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 1.0
+ GenAIRequestTopKKey = attribute.Key("gen_ai.request.top_k")
+
+ // GenAIRequestTopPKey is the attribute Key conforming to the
+ // "gen_ai.request.top_p" semantic conventions. It represents the top_p sampling
+ // setting for the GenAI request.
+ //
+ // Type: double
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 1.0
+ GenAIRequestTopPKey = attribute.Key("gen_ai.request.top_p")
+
+ // GenAIResponseFinishReasonsKey is the attribute Key conforming to the
+ // "gen_ai.response.finish_reasons" semantic conventions. It represents the
+ // array of reasons the model stopped generating tokens, corresponding to each
+ // generation received.
+ //
+ // Type: string[]
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "stop"], ["stop", "length"
+ GenAIResponseFinishReasonsKey = attribute.Key("gen_ai.response.finish_reasons")
+
+ // GenAIResponseIDKey is the attribute Key conforming to the
+ // "gen_ai.response.id" semantic conventions. It represents the unique
+ // identifier for the completion.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "chatcmpl-123"
+ GenAIResponseIDKey = attribute.Key("gen_ai.response.id")
+
+ // GenAIResponseModelKey is the attribute Key conforming to the
+ // "gen_ai.response.model" semantic conventions. It represents the name of the
+ // model that generated the response.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "gpt-4-0613"
+ GenAIResponseModelKey = attribute.Key("gen_ai.response.model")
+
+ // GenAIRetrievalDocumentsKey is the attribute Key conforming to the
+ // "gen_ai.retrieval.documents" semantic conventions. It represents the
+ // documents retrieved.
+ //
+ // Type: any
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "[\n {\n "id": "doc_123",\n "score": 0.95\n },\n {\n "id":
+ // "doc_456",\n "score": 0.87\n },\n {\n "id": "doc_789",\n "score": 0.82\n
+ // }\n]\n"
+ // Note: Instrumentations MUST follow [Retrieval documents JSON schema].
+ // When the attribute is recorded on events, it MUST be recorded in structured
+ // form. When recorded on spans, it MAY be recorded as a JSON string if
+ // structured
+ // format is not supported and SHOULD be recorded in structured form otherwise.
+ //
+ // Each document object SHOULD contain at least the following properties:
+ // `id` (string): A unique identifier for the document, `score` (double): The
+ // relevance score of the document
+ //
+ // [Retrieval documents JSON schema]: /docs/gen-ai/gen-ai-retrieval-documents.json
+ GenAIRetrievalDocumentsKey = attribute.Key("gen_ai.retrieval.documents")
+
+ // GenAIRetrievalQueryTextKey is the attribute Key conforming to the
+ // "gen_ai.retrieval.query.text" semantic conventions. It represents the query
+ // text used for retrieval.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "What is the capital of France?", "weather in Paris"
+ // Note: > [!Warning]
+ //
+ // > This attribute may contain sensitive information.
+ GenAIRetrievalQueryTextKey = attribute.Key("gen_ai.retrieval.query.text")
+
+ // GenAISystemInstructionsKey is the attribute Key conforming to the
+ // "gen_ai.system_instructions" semantic conventions. It represents the system
+ // message or instructions provided to the GenAI model separately from the chat
+ // history.
+ //
+ // Type: any
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "[\n {\n "type": "text",\n "content": "You are an Agent that greet
+ // users, always use greetings tool to respond"\n }\n]\n", "[\n {\n "type":
+ // "text",\n "content": "You are a language translator."\n },\n {\n "type":
+ // "text",\n "content": "Your mission is to translate text in English to
+ // French."\n }\n]\n"
+ // Note: This attribute SHOULD be used when the corresponding provider or API
+ // allows to provide system instructions or messages separately from the
+ // chat history.
+ //
+ // Instructions that are part of the chat history SHOULD be recorded in
+ // `gen_ai.input.messages` attribute instead.
+ //
+ // Instrumentations MUST follow [System instructions JSON schema].
+ //
+ // When recorded on spans, it MAY be recorded as a JSON string if structured
+ // format is not supported and SHOULD be recorded in structured form otherwise.
+ //
+ // Instrumentations MAY provide a way for users to filter or truncate
+ // system instructions.
+ //
+ // > [!Warning]
+ // > This attribute may contain sensitive information.
+ //
+ // See [Recording content on attributes]
+ // section for more details.
+ //
+ // [System instructions JSON schema]: /docs/gen-ai/gen-ai-system-instructions.json
+ // [Recording content on attributes]: /docs/gen-ai/gen-ai-spans.md#recording-content-on-attributes
+ GenAISystemInstructionsKey = attribute.Key("gen_ai.system_instructions")
+
+ // GenAITokenTypeKey is the attribute Key conforming to the "gen_ai.token.type"
+ // semantic conventions. It represents the type of token being counted.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "input", "output"
+ GenAITokenTypeKey = attribute.Key("gen_ai.token.type")
+
+ // GenAIToolCallArgumentsKey is the attribute Key conforming to the
+ // "gen_ai.tool.call.arguments" semantic conventions. It represents the
+ // parameters passed to the tool call.
+ //
+ // Type: any
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "{\n "location": "San Francisco?",\n "date": "2025-10-01"\n}\n"
+ // Note: > [!WARNING]
+ //
+ // > This attribute may contain sensitive information.
+ //
+ // It's expected to be an object - in case a serialized string is available
+ // to the instrumentation, the instrumentation SHOULD do the best effort to
+ // deserialize it to an object. When recorded on spans, it MAY be recorded as a
+ // JSON string if structured format is not supported and SHOULD be recorded in
+ // structured form otherwise.
+ GenAIToolCallArgumentsKey = attribute.Key("gen_ai.tool.call.arguments")
+
+ // GenAIToolCallIDKey is the attribute Key conforming to the
+ // "gen_ai.tool.call.id" semantic conventions. It represents the tool call
+ // identifier.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "call_mszuSIzqtI65i1wAUOE8w5H4"
+ GenAIToolCallIDKey = attribute.Key("gen_ai.tool.call.id")
+
+ // GenAIToolCallResultKey is the attribute Key conforming to the
+ // "gen_ai.tool.call.result" semantic conventions. It represents the result
+ // returned by the tool call (if any and if execution was successful).
+ //
+ // Type: any
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "{\n "temperature_range": {\n "high": 75,\n "low": 60\n },\n
+ // "conditions": "sunny"\n}\n"
+ // Note: > [!WARNING]
+ //
+ // > This attribute may contain sensitive information.
+ //
+ // It's expected to be an object - in case a serialized string is available
+ // to the instrumentation, the instrumentation SHOULD do the best effort to
+ // deserialize it to an object. When recorded on spans, it MAY be recorded as a
+ // JSON string if structured format is not supported and SHOULD be recorded in
+ // structured form otherwise.
+ GenAIToolCallResultKey = attribute.Key("gen_ai.tool.call.result")
+
+ // GenAIToolDefinitionsKey is the attribute Key conforming to the
+ // "gen_ai.tool.definitions" semantic conventions. It represents the list of
+ // source system tool definitions available to the GenAI agent or model.
+ //
+ // Type: any
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "[\n {\n "type": "function",\n "name": "get_current_weather",\n
+ // "description": "Get the current weather in a given location",\n "parameters":
+ // {\n "type": "object",\n "properties": {\n "location": {\n "type": "string",\n
+ // "description": "The city and state, e.g. San Francisco, CA"\n },\n "unit":
+ // {\n "type": "string",\n "enum": [\n "celsius",\n "fahrenheit"\n ]\n }\n },\n
+ // "required": [\n "location",\n "unit"\n ]\n }\n }\n]\n"
+ // Note: The value of this attribute matches source system tool definition
+ // format.
+ //
+ // It's expected to be an array of objects where each object represents a tool
+ // definition. In case a serialized string is available
+ // to the instrumentation, the instrumentation SHOULD do the best effort to
+ // deserialize it to an array. When recorded on spans, it MAY be recorded as a
+ // JSON string if structured format is not supported and SHOULD be recorded in
+ // structured form otherwise.
+ //
+ // Since this attribute could be large, it's NOT RECOMMENDED to populate
+ // it by default. Instrumentations MAY provide a way to enable
+ // populating this attribute.
+ GenAIToolDefinitionsKey = attribute.Key("gen_ai.tool.definitions")
+
+ // GenAIToolDescriptionKey is the attribute Key conforming to the
+ // "gen_ai.tool.description" semantic conventions. It represents the tool
+ // description.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "Multiply two numbers"
+ GenAIToolDescriptionKey = attribute.Key("gen_ai.tool.description")
+
+ // GenAIToolNameKey is the attribute Key conforming to the "gen_ai.tool.name"
+ // semantic conventions. It represents the name of the tool utilized by the
+ // agent.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "Flights"
+ GenAIToolNameKey = attribute.Key("gen_ai.tool.name")
+
+ // GenAIToolTypeKey is the attribute Key conforming to the "gen_ai.tool.type"
+ // semantic conventions. It represents the type of the tool utilized by the
+ // agent.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "function", "extension", "datastore"
+ // Note: Extension: A tool executed on the agent-side to directly call external
+ // APIs, bridging the gap between the agent and real-world systems.
+ // Agent-side operations involve actions that are performed by the agent on the
+ // server or within the agent's controlled environment.
+ // Function: A tool executed on the client-side, where the agent generates
+ // parameters for a predefined function, and the client executes the logic.
+ // Client-side operations are actions taken on the user's end or within the
+ // client application.
+ // Datastore: A tool used by the agent to access and query structured or
+ // unstructured external data for retrieval-augmented tasks or knowledge
+ // updates.
+ GenAIToolTypeKey = attribute.Key("gen_ai.tool.type")
+
+ // GenAIUsageCacheCreationInputTokensKey is the attribute Key conforming to the
+ // "gen_ai.usage.cache_creation.input_tokens" semantic conventions. It
+ // represents the number of input tokens written to a provider-managed cache.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 25
+ // Note: The value SHOULD be included in `gen_ai.usage.input_tokens`.
+ GenAIUsageCacheCreationInputTokensKey = attribute.Key("gen_ai.usage.cache_creation.input_tokens")
+
+ // GenAIUsageCacheReadInputTokensKey is the attribute Key conforming to the
+ // "gen_ai.usage.cache_read.input_tokens" semantic conventions. It represents
+ // the number of input tokens served from a provider-managed cache.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 50
+ // Note: The value SHOULD be included in `gen_ai.usage.input_tokens`.
+ GenAIUsageCacheReadInputTokensKey = attribute.Key("gen_ai.usage.cache_read.input_tokens")
+
+ // GenAIUsageInputTokensKey is the attribute Key conforming to the
+ // "gen_ai.usage.input_tokens" semantic conventions. It represents the number of
+ // tokens used in the GenAI input (prompt).
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 100
+ // Note: This value SHOULD include all types of input tokens, including cached
+ // tokens.
+ // Instrumentations SHOULD make a best effort to populate this value, using a
+ // total
+ // provided by the provider when available or, depending on the provider API,
+ // by summing different token types parsed from the provider output.
+ GenAIUsageInputTokensKey = attribute.Key("gen_ai.usage.input_tokens")
+
+ // GenAIUsageOutputTokensKey is the attribute Key conforming to the
+ // "gen_ai.usage.output_tokens" semantic conventions. It represents the number
+ // of tokens used in the GenAI response (completion).
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 180
+ GenAIUsageOutputTokensKey = attribute.Key("gen_ai.usage.output_tokens")
+)
+
+// GenAIAgentDescription returns an attribute KeyValue conforming to the
+// "gen_ai.agent.description" semantic conventions. It represents the free-form
+// description of the GenAI agent provided by the application.
+func GenAIAgentDescription(val string) attribute.KeyValue {
+ return GenAIAgentDescriptionKey.String(val)
+}
+
+// GenAIAgentID returns an attribute KeyValue conforming to the "gen_ai.agent.id"
+// semantic conventions. It represents the unique identifier of the GenAI agent.
+func GenAIAgentID(val string) attribute.KeyValue {
+ return GenAIAgentIDKey.String(val)
+}
+
+// GenAIAgentName returns an attribute KeyValue conforming to the
+// "gen_ai.agent.name" semantic conventions. It represents the human-readable
+// name of the GenAI agent provided by the application.
+func GenAIAgentName(val string) attribute.KeyValue {
+ return GenAIAgentNameKey.String(val)
+}
+
+// GenAIAgentVersion returns an attribute KeyValue conforming to the
+// "gen_ai.agent.version" semantic conventions. It represents the version of the
+// GenAI agent.
+func GenAIAgentVersion(val string) attribute.KeyValue {
+ return GenAIAgentVersionKey.String(val)
+}
+
+// GenAIConversationID returns an attribute KeyValue conforming to the
+// "gen_ai.conversation.id" semantic conventions. It represents the unique
+// identifier for a conversation (session, thread), used to store and correlate
+// messages within this conversation.
+func GenAIConversationID(val string) attribute.KeyValue {
+ return GenAIConversationIDKey.String(val)
+}
+
+// GenAIDataSourceID returns an attribute KeyValue conforming to the
+// "gen_ai.data_source.id" semantic conventions. It represents the data source
+// identifier.
+func GenAIDataSourceID(val string) attribute.KeyValue {
+ return GenAIDataSourceIDKey.String(val)
+}
+
+// GenAIEmbeddingsDimensionCount returns an attribute KeyValue conforming to the
+// "gen_ai.embeddings.dimension.count" semantic conventions. It represents the
+// number of dimensions the resulting output embeddings should have.
+func GenAIEmbeddingsDimensionCount(val int) attribute.KeyValue {
+ return GenAIEmbeddingsDimensionCountKey.Int(val)
+}
+
+// GenAIEvaluationExplanation returns an attribute KeyValue conforming to the
+// "gen_ai.evaluation.explanation" semantic conventions. It represents a
+// free-form explanation for the assigned score provided by the evaluator.
+func GenAIEvaluationExplanation(val string) attribute.KeyValue {
+ return GenAIEvaluationExplanationKey.String(val)
+}
+
+// GenAIEvaluationName returns an attribute KeyValue conforming to the
+// "gen_ai.evaluation.name" semantic conventions. It represents the name of the
+// evaluation metric used for the GenAI response.
+func GenAIEvaluationName(val string) attribute.KeyValue {
+ return GenAIEvaluationNameKey.String(val)
+}
+
+// GenAIEvaluationScoreLabel returns an attribute KeyValue conforming to the
+// "gen_ai.evaluation.score.label" semantic conventions. It represents the human
+// readable label for evaluation.
+func GenAIEvaluationScoreLabel(val string) attribute.KeyValue {
+ return GenAIEvaluationScoreLabelKey.String(val)
+}
+
+// GenAIEvaluationScoreValue returns an attribute KeyValue conforming to the
+// "gen_ai.evaluation.score.value" semantic conventions. It represents the
+// evaluation score returned by the evaluator.
+func GenAIEvaluationScoreValue(val float64) attribute.KeyValue {
+ return GenAIEvaluationScoreValueKey.Float64(val)
+}
+
+// GenAIPromptName returns an attribute KeyValue conforming to the
+// "gen_ai.prompt.name" semantic conventions. It represents the name of the
+// prompt that uniquely identifies it.
+func GenAIPromptName(val string) attribute.KeyValue {
+ return GenAIPromptNameKey.String(val)
+}
+
+// GenAIRequestChoiceCount returns an attribute KeyValue conforming to the
+// "gen_ai.request.choice.count" semantic conventions. It represents the target
+// number of candidate completions to return.
+func GenAIRequestChoiceCount(val int) attribute.KeyValue {
+ return GenAIRequestChoiceCountKey.Int(val)
+}
+
+// GenAIRequestEncodingFormats returns an attribute KeyValue conforming to the
+// "gen_ai.request.encoding_formats" semantic conventions. It represents the
+// encoding formats requested in an embeddings operation, if specified.
+func GenAIRequestEncodingFormats(val ...string) attribute.KeyValue {
+ return GenAIRequestEncodingFormatsKey.StringSlice(val)
+}
+
+// GenAIRequestFrequencyPenalty returns an attribute KeyValue conforming to the
+// "gen_ai.request.frequency_penalty" semantic conventions. It represents the
+// frequency penalty setting for the GenAI request.
+func GenAIRequestFrequencyPenalty(val float64) attribute.KeyValue {
+ return GenAIRequestFrequencyPenaltyKey.Float64(val)
+}
+
+// GenAIRequestMaxTokens returns an attribute KeyValue conforming to the
+// "gen_ai.request.max_tokens" semantic conventions. It represents the maximum
+// number of tokens the model generates for a request.
+func GenAIRequestMaxTokens(val int) attribute.KeyValue {
+ return GenAIRequestMaxTokensKey.Int(val)
+}
+
+// GenAIRequestModel returns an attribute KeyValue conforming to the
+// "gen_ai.request.model" semantic conventions. It represents the name of the
+// GenAI model a request is being made to.
+func GenAIRequestModel(val string) attribute.KeyValue {
+ return GenAIRequestModelKey.String(val)
+}
+
+// GenAIRequestPresencePenalty returns an attribute KeyValue conforming to the
+// "gen_ai.request.presence_penalty" semantic conventions. It represents the
+// presence penalty setting for the GenAI request.
+func GenAIRequestPresencePenalty(val float64) attribute.KeyValue {
+ return GenAIRequestPresencePenaltyKey.Float64(val)
+}
+
+// GenAIRequestSeed returns an attribute KeyValue conforming to the
+// "gen_ai.request.seed" semantic conventions. It represents the requests with
+// same seed value more likely to return same result.
+func GenAIRequestSeed(val int) attribute.KeyValue {
+ return GenAIRequestSeedKey.Int(val)
+}
+
+// GenAIRequestStopSequences returns an attribute KeyValue conforming to the
+// "gen_ai.request.stop_sequences" semantic conventions. It represents the list
+// of sequences that the model will use to stop generating further tokens.
+func GenAIRequestStopSequences(val ...string) attribute.KeyValue {
+ return GenAIRequestStopSequencesKey.StringSlice(val)
+}
+
+// GenAIRequestTemperature returns an attribute KeyValue conforming to the
+// "gen_ai.request.temperature" semantic conventions. It represents the
+// temperature setting for the GenAI request.
+func GenAIRequestTemperature(val float64) attribute.KeyValue {
+ return GenAIRequestTemperatureKey.Float64(val)
+}
+
+// GenAIRequestTopK returns an attribute KeyValue conforming to the
+// "gen_ai.request.top_k" semantic conventions. It represents the top_k sampling
+// setting for the GenAI request.
+func GenAIRequestTopK(val float64) attribute.KeyValue {
+ return GenAIRequestTopKKey.Float64(val)
+}
+
+// GenAIRequestTopP returns an attribute KeyValue conforming to the
+// "gen_ai.request.top_p" semantic conventions. It represents the top_p sampling
+// setting for the GenAI request.
+func GenAIRequestTopP(val float64) attribute.KeyValue {
+ return GenAIRequestTopPKey.Float64(val)
+}
+
+// GenAIResponseFinishReasons returns an attribute KeyValue conforming to the
+// "gen_ai.response.finish_reasons" semantic conventions. It represents the array
+// of reasons the model stopped generating tokens, corresponding to each
+// generation received.
+func GenAIResponseFinishReasons(val ...string) attribute.KeyValue {
+ return GenAIResponseFinishReasonsKey.StringSlice(val)
+}
+
+// GenAIResponseID returns an attribute KeyValue conforming to the
+// "gen_ai.response.id" semantic conventions. It represents the unique identifier
+// for the completion.
+func GenAIResponseID(val string) attribute.KeyValue {
+ return GenAIResponseIDKey.String(val)
+}
+
+// GenAIResponseModel returns an attribute KeyValue conforming to the
+// "gen_ai.response.model" semantic conventions. It represents the name of the
+// model that generated the response.
+func GenAIResponseModel(val string) attribute.KeyValue {
+ return GenAIResponseModelKey.String(val)
+}
+
+// GenAIRetrievalQueryText returns an attribute KeyValue conforming to the
+// "gen_ai.retrieval.query.text" semantic conventions. It represents the query
+// text used for retrieval.
+func GenAIRetrievalQueryText(val string) attribute.KeyValue {
+ return GenAIRetrievalQueryTextKey.String(val)
+}
+
+// GenAIToolCallID returns an attribute KeyValue conforming to the
+// "gen_ai.tool.call.id" semantic conventions. It represents the tool call
+// identifier.
+func GenAIToolCallID(val string) attribute.KeyValue {
+ return GenAIToolCallIDKey.String(val)
+}
+
+// GenAIToolDescription returns an attribute KeyValue conforming to the
+// "gen_ai.tool.description" semantic conventions. It represents the tool
+// description.
+func GenAIToolDescription(val string) attribute.KeyValue {
+ return GenAIToolDescriptionKey.String(val)
+}
+
+// GenAIToolName returns an attribute KeyValue conforming to the
+// "gen_ai.tool.name" semantic conventions. It represents the name of the tool
+// utilized by the agent.
+func GenAIToolName(val string) attribute.KeyValue {
+ return GenAIToolNameKey.String(val)
+}
+
+// GenAIToolType returns an attribute KeyValue conforming to the
+// "gen_ai.tool.type" semantic conventions. It represents the type of the tool
+// utilized by the agent.
+func GenAIToolType(val string) attribute.KeyValue {
+ return GenAIToolTypeKey.String(val)
+}
+
+// GenAIUsageCacheCreationInputTokens returns an attribute KeyValue conforming to
+// the "gen_ai.usage.cache_creation.input_tokens" semantic conventions. It
+// represents the number of input tokens written to a provider-managed cache.
+func GenAIUsageCacheCreationInputTokens(val int) attribute.KeyValue {
+ return GenAIUsageCacheCreationInputTokensKey.Int(val)
+}
+
+// GenAIUsageCacheReadInputTokens returns an attribute KeyValue conforming to the
+// "gen_ai.usage.cache_read.input_tokens" semantic conventions. It represents the
+// number of input tokens served from a provider-managed cache.
+func GenAIUsageCacheReadInputTokens(val int) attribute.KeyValue {
+ return GenAIUsageCacheReadInputTokensKey.Int(val)
+}
+
+// GenAIUsageInputTokens returns an attribute KeyValue conforming to the
+// "gen_ai.usage.input_tokens" semantic conventions. It represents the number of
+// tokens used in the GenAI input (prompt).
+func GenAIUsageInputTokens(val int) attribute.KeyValue {
+ return GenAIUsageInputTokensKey.Int(val)
+}
+
+// GenAIUsageOutputTokens returns an attribute KeyValue conforming to the
+// "gen_ai.usage.output_tokens" semantic conventions. It represents the number of
+// tokens used in the GenAI response (completion).
+func GenAIUsageOutputTokens(val int) attribute.KeyValue {
+ return GenAIUsageOutputTokensKey.Int(val)
+}
+
+// Enum values for gen_ai.operation.name
+var (
+ // Chat completion operation such as [OpenAI Chat API]
+ // Stability: development
+ //
+ // [OpenAI Chat API]: https://platform.openai.com/docs/api-reference/chat
+ GenAIOperationNameChat = GenAIOperationNameKey.String("chat")
+ // Multimodal content generation operation such as [Gemini Generate Content]
+ // Stability: development
+ //
+ // [Gemini Generate Content]: https://ai.google.dev/api/generate-content
+ GenAIOperationNameGenerateContent = GenAIOperationNameKey.String("generate_content")
+ // Text completions operation such as [OpenAI Completions API (Legacy)]
+ // Stability: development
+ //
+ // [OpenAI Completions API (Legacy)]: https://platform.openai.com/docs/api-reference/completions
+ GenAIOperationNameTextCompletion = GenAIOperationNameKey.String("text_completion")
+ // Embeddings operation such as [OpenAI Create embeddings API]
+ // Stability: development
+ //
+ // [OpenAI Create embeddings API]: https://platform.openai.com/docs/api-reference/embeddings/create
+ GenAIOperationNameEmbeddings = GenAIOperationNameKey.String("embeddings")
+ // Retrieval operation such as [OpenAI Search Vector Store API]
+ // Stability: development
+ //
+ // [OpenAI Search Vector Store API]: https://platform.openai.com/docs/api-reference/vector-stores/search
+ GenAIOperationNameRetrieval = GenAIOperationNameKey.String("retrieval")
+ // Create GenAI agent
+ // Stability: development
+ GenAIOperationNameCreateAgent = GenAIOperationNameKey.String("create_agent")
+ // Invoke GenAI agent
+ // Stability: development
+ GenAIOperationNameInvokeAgent = GenAIOperationNameKey.String("invoke_agent")
+ // Execute a tool
+ // Stability: development
+ GenAIOperationNameExecuteTool = GenAIOperationNameKey.String("execute_tool")
+)
+
+// Enum values for gen_ai.output.type
+var (
+ // Plain text
+ // Stability: development
+ GenAIOutputTypeText = GenAIOutputTypeKey.String("text")
+ // JSON object with known or unknown schema
+ // Stability: development
+ GenAIOutputTypeJSON = GenAIOutputTypeKey.String("json")
+ // Image
+ // Stability: development
+ GenAIOutputTypeImage = GenAIOutputTypeKey.String("image")
+ // Speech
+ // Stability: development
+ GenAIOutputTypeSpeech = GenAIOutputTypeKey.String("speech")
+)
+
+// Enum values for gen_ai.provider.name
+var (
+ // [OpenAI]
+ // Stability: development
+ //
+ // [OpenAI]: https://openai.com/
+ GenAIProviderNameOpenAI = GenAIProviderNameKey.String("openai")
+ // Any Google generative AI endpoint
+ // Stability: development
+ GenAIProviderNameGCPGenAI = GenAIProviderNameKey.String("gcp.gen_ai")
+ // [Vertex AI]
+ // Stability: development
+ //
+ // [Vertex AI]: https://cloud.google.com/vertex-ai
+ GenAIProviderNameGCPVertexAI = GenAIProviderNameKey.String("gcp.vertex_ai")
+ // [Gemini]
+ // Stability: development
+ //
+ // [Gemini]: https://cloud.google.com/products/gemini
+ GenAIProviderNameGCPGemini = GenAIProviderNameKey.String("gcp.gemini")
+ // [Anthropic]
+ // Stability: development
+ //
+ // [Anthropic]: https://www.anthropic.com/
+ GenAIProviderNameAnthropic = GenAIProviderNameKey.String("anthropic")
+ // [Cohere]
+ // Stability: development
+ //
+ // [Cohere]: https://cohere.com/
+ GenAIProviderNameCohere = GenAIProviderNameKey.String("cohere")
+ // Azure AI Inference
+ // Stability: development
+ GenAIProviderNameAzureAIInference = GenAIProviderNameKey.String("azure.ai.inference")
+ // [Azure OpenAI]
+ // Stability: development
+ //
+ // [Azure OpenAI]: https://azure.microsoft.com/products/ai-services/openai-service/
+ GenAIProviderNameAzureAIOpenAI = GenAIProviderNameKey.String("azure.ai.openai")
+ // [IBM Watsonx AI]
+ // Stability: development
+ //
+ // [IBM Watsonx AI]: https://www.ibm.com/products/watsonx-ai
+ GenAIProviderNameIBMWatsonxAI = GenAIProviderNameKey.String("ibm.watsonx.ai")
+ // [AWS Bedrock]
+ // Stability: development
+ //
+ // [AWS Bedrock]: https://aws.amazon.com/bedrock
+ GenAIProviderNameAWSBedrock = GenAIProviderNameKey.String("aws.bedrock")
+ // [Perplexity]
+ // Stability: development
+ //
+ // [Perplexity]: https://www.perplexity.ai/
+ GenAIProviderNamePerplexity = GenAIProviderNameKey.String("perplexity")
+ // [xAI]
+ // Stability: development
+ //
+ // [xAI]: https://x.ai/
+ GenAIProviderNameXAI = GenAIProviderNameKey.String("x_ai")
+ // [DeepSeek]
+ // Stability: development
+ //
+ // [DeepSeek]: https://www.deepseek.com/
+ GenAIProviderNameDeepseek = GenAIProviderNameKey.String("deepseek")
+ // [Groq]
+ // Stability: development
+ //
+ // [Groq]: https://groq.com/
+ GenAIProviderNameGroq = GenAIProviderNameKey.String("groq")
+ // [Mistral AI]
+ // Stability: development
+ //
+ // [Mistral AI]: https://mistral.ai/
+ GenAIProviderNameMistralAI = GenAIProviderNameKey.String("mistral_ai")
+)
+
+// Enum values for gen_ai.token.type
+var (
+ // Input tokens (prompt, input, etc.)
+ // Stability: development
+ GenAITokenTypeInput = GenAITokenTypeKey.String("input")
+ // Output tokens (completion, response, etc.)
+ // Stability: development
+ GenAITokenTypeOutput = GenAITokenTypeKey.String("output")
+)
+
+// Namespace: geo
+const (
+ // GeoContinentCodeKey is the attribute Key conforming to the
+ // "geo.continent.code" semantic conventions. It represents the two-letter code
+ // representing continent’s name.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ GeoContinentCodeKey = attribute.Key("geo.continent.code")
+
+ // GeoCountryISOCodeKey is the attribute Key conforming to the
+ // "geo.country.iso_code" semantic conventions. It represents the two-letter ISO
+ // Country Code ([ISO 3166-1 alpha2]).
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "CA"
+ //
+ // [ISO 3166-1 alpha2]: https://wikipedia.org/wiki/ISO_3166-1#Codes
+ GeoCountryISOCodeKey = attribute.Key("geo.country.iso_code")
+
+ // GeoLocalityNameKey is the attribute Key conforming to the "geo.locality.name"
+ // semantic conventions. It represents the locality name. Represents the name of
+ // a city, town, village, or similar populated place.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "Montreal", "Berlin"
+ GeoLocalityNameKey = attribute.Key("geo.locality.name")
+
+ // GeoLocationLatKey is the attribute Key conforming to the "geo.location.lat"
+ // semantic conventions. It represents the latitude of the geo location in
+ // [WGS84].
+ //
+ // Type: double
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 45.505918
+ //
+ // [WGS84]: https://wikipedia.org/wiki/World_Geodetic_System#WGS84
+ GeoLocationLatKey = attribute.Key("geo.location.lat")
+
+ // GeoLocationLonKey is the attribute Key conforming to the "geo.location.lon"
+ // semantic conventions. It represents the longitude of the geo location in
+ // [WGS84].
+ //
+ // Type: double
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: -73.61483
+ //
+ // [WGS84]: https://wikipedia.org/wiki/World_Geodetic_System#WGS84
+ GeoLocationLonKey = attribute.Key("geo.location.lon")
+
+ // GeoPostalCodeKey is the attribute Key conforming to the "geo.postal_code"
+ // semantic conventions. It represents the postal code associated with the
+ // location. Values appropriate for this field may also be known as a postcode
+ // or ZIP code and will vary widely from country to country.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "94040"
+ GeoPostalCodeKey = attribute.Key("geo.postal_code")
+
+ // GeoRegionISOCodeKey is the attribute Key conforming to the
+ // "geo.region.iso_code" semantic conventions. It represents the region ISO code
+ // ([ISO 3166-2]).
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "CA-QC"
+ //
+ // [ISO 3166-2]: https://wikipedia.org/wiki/ISO_3166-2
+ GeoRegionISOCodeKey = attribute.Key("geo.region.iso_code")
+)
+
+// GeoCountryISOCode returns an attribute KeyValue conforming to the
+// "geo.country.iso_code" semantic conventions. It represents the two-letter ISO
+// Country Code ([ISO 3166-1 alpha2]).
+//
+// [ISO 3166-1 alpha2]: https://wikipedia.org/wiki/ISO_3166-1#Codes
+func GeoCountryISOCode(val string) attribute.KeyValue {
+ return GeoCountryISOCodeKey.String(val)
+}
+
+// GeoLocalityName returns an attribute KeyValue conforming to the
+// "geo.locality.name" semantic conventions. It represents the locality name.
+// Represents the name of a city, town, village, or similar populated place.
+func GeoLocalityName(val string) attribute.KeyValue {
+ return GeoLocalityNameKey.String(val)
+}
+
+// GeoLocationLat returns an attribute KeyValue conforming to the
+// "geo.location.lat" semantic conventions. It represents the latitude of the geo
+// location in [WGS84].
+//
+// [WGS84]: https://wikipedia.org/wiki/World_Geodetic_System#WGS84
+func GeoLocationLat(val float64) attribute.KeyValue {
+ return GeoLocationLatKey.Float64(val)
+}
+
+// GeoLocationLon returns an attribute KeyValue conforming to the
+// "geo.location.lon" semantic conventions. It represents the longitude of the
+// geo location in [WGS84].
+//
+// [WGS84]: https://wikipedia.org/wiki/World_Geodetic_System#WGS84
+func GeoLocationLon(val float64) attribute.KeyValue {
+ return GeoLocationLonKey.Float64(val)
+}
+
+// GeoPostalCode returns an attribute KeyValue conforming to the
+// "geo.postal_code" semantic conventions. It represents the postal code
+// associated with the location. Values appropriate for this field may also be
+// known as a postcode or ZIP code and will vary widely from country to country.
+func GeoPostalCode(val string) attribute.KeyValue {
+ return GeoPostalCodeKey.String(val)
+}
+
+// GeoRegionISOCode returns an attribute KeyValue conforming to the
+// "geo.region.iso_code" semantic conventions. It represents the region ISO code
+// ([ISO 3166-2]).
+//
+// [ISO 3166-2]: https://wikipedia.org/wiki/ISO_3166-2
+func GeoRegionISOCode(val string) attribute.KeyValue {
+ return GeoRegionISOCodeKey.String(val)
+}
+
+// Enum values for geo.continent.code
+var (
+ // Africa
+ // Stability: development
+ GeoContinentCodeAf = GeoContinentCodeKey.String("AF")
+ // Antarctica
+ // Stability: development
+ GeoContinentCodeAn = GeoContinentCodeKey.String("AN")
+ // Asia
+ // Stability: development
+ GeoContinentCodeAs = GeoContinentCodeKey.String("AS")
+ // Europe
+ // Stability: development
+ GeoContinentCodeEu = GeoContinentCodeKey.String("EU")
+ // North America
+ // Stability: development
+ GeoContinentCodeNa = GeoContinentCodeKey.String("NA")
+ // Oceania
+ // Stability: development
+ GeoContinentCodeOc = GeoContinentCodeKey.String("OC")
+ // South America
+ // Stability: development
+ GeoContinentCodeSa = GeoContinentCodeKey.String("SA")
+)
+
+// Namespace: go
+const (
+ // GoMemoryTypeKey is the attribute Key conforming to the "go.memory.type"
+ // semantic conventions. It represents the type of memory.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "other", "stack"
+ GoMemoryTypeKey = attribute.Key("go.memory.type")
+)
+
+// Enum values for go.memory.type
+var (
+ // Memory allocated from the heap that is reserved for stack space, whether or
+ // not it is currently in-use.
+ // Stability: development
+ GoMemoryTypeStack = GoMemoryTypeKey.String("stack")
+ // Memory used by the Go runtime, excluding other categories of memory usage
+ // described in this enumeration.
+ // Stability: development
+ GoMemoryTypeOther = GoMemoryTypeKey.String("other")
+)
+
+// Namespace: graphql
+const (
+ // GraphQLDocumentKey is the attribute Key conforming to the "graphql.document"
+ // semantic conventions. It represents the GraphQL document being executed.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: query findBookById { bookById(id: ?) { name } }
+ // Note: The value may be sanitized to exclude sensitive information.
+ GraphQLDocumentKey = attribute.Key("graphql.document")
+
+ // GraphQLOperationNameKey is the attribute Key conforming to the
+ // "graphql.operation.name" semantic conventions. It represents the name of the
+ // operation being executed.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: findBookById
+ GraphQLOperationNameKey = attribute.Key("graphql.operation.name")
+
+ // GraphQLOperationTypeKey is the attribute Key conforming to the
+ // "graphql.operation.type" semantic conventions. It represents the type of the
+ // operation being executed.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "query", "mutation", "subscription"
+ GraphQLOperationTypeKey = attribute.Key("graphql.operation.type")
+)
+
+// GraphQLDocument returns an attribute KeyValue conforming to the
+// "graphql.document" semantic conventions. It represents the GraphQL document
+// being executed.
+func GraphQLDocument(val string) attribute.KeyValue {
+ return GraphQLDocumentKey.String(val)
+}
+
+// GraphQLOperationName returns an attribute KeyValue conforming to the
+// "graphql.operation.name" semantic conventions. It represents the name of the
+// operation being executed.
+func GraphQLOperationName(val string) attribute.KeyValue {
+ return GraphQLOperationNameKey.String(val)
+}
+
+// Enum values for graphql.operation.type
+var (
+ // GraphQL query
+ // Stability: development
+ GraphQLOperationTypeQuery = GraphQLOperationTypeKey.String("query")
+ // GraphQL mutation
+ // Stability: development
+ GraphQLOperationTypeMutation = GraphQLOperationTypeKey.String("mutation")
+ // GraphQL subscription
+ // Stability: development
+ GraphQLOperationTypeSubscription = GraphQLOperationTypeKey.String("subscription")
+)
+
+// Namespace: heroku
+const (
+ // HerokuAppIDKey is the attribute Key conforming to the "heroku.app.id"
+ // semantic conventions. It represents the unique identifier for the
+ // application.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "2daa2797-e42b-4624-9322-ec3f968df4da"
+ HerokuAppIDKey = attribute.Key("heroku.app.id")
+
+ // HerokuReleaseCommitKey is the attribute Key conforming to the
+ // "heroku.release.commit" semantic conventions. It represents the commit hash
+ // for the current release.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "e6134959463efd8966b20e75b913cafe3f5ec"
+ HerokuReleaseCommitKey = attribute.Key("heroku.release.commit")
+
+ // HerokuReleaseCreationTimestampKey is the attribute Key conforming to the
+ // "heroku.release.creation_timestamp" semantic conventions. It represents the
+ // time and date the release was created.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "2022-10-23T18:00:42Z"
+ HerokuReleaseCreationTimestampKey = attribute.Key("heroku.release.creation_timestamp")
+)
+
+// HerokuAppID returns an attribute KeyValue conforming to the "heroku.app.id"
+// semantic conventions. It represents the unique identifier for the application.
+func HerokuAppID(val string) attribute.KeyValue {
+ return HerokuAppIDKey.String(val)
+}
+
+// HerokuReleaseCommit returns an attribute KeyValue conforming to the
+// "heroku.release.commit" semantic conventions. It represents the commit hash
+// for the current release.
+func HerokuReleaseCommit(val string) attribute.KeyValue {
+ return HerokuReleaseCommitKey.String(val)
+}
+
+// HerokuReleaseCreationTimestamp returns an attribute KeyValue conforming to the
+// "heroku.release.creation_timestamp" semantic conventions. It represents the
+// time and date the release was created.
+func HerokuReleaseCreationTimestamp(val string) attribute.KeyValue {
+ return HerokuReleaseCreationTimestampKey.String(val)
+}
+
+// Namespace: host
+const (
+ // HostArchKey is the attribute Key conforming to the "host.arch" semantic
+ // conventions. It represents the CPU architecture the host system is running
+ // on.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ HostArchKey = attribute.Key("host.arch")
+
+ // HostCPUCacheL2SizeKey is the attribute Key conforming to the
+ // "host.cpu.cache.l2.size" semantic conventions. It represents the amount of
+ // level 2 memory cache available to the processor (in Bytes).
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 12288000
+ HostCPUCacheL2SizeKey = attribute.Key("host.cpu.cache.l2.size")
+
+ // HostCPUFamilyKey is the attribute Key conforming to the "host.cpu.family"
+ // semantic conventions. It represents the family or generation of the CPU.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "6", "PA-RISC 1.1e"
+ HostCPUFamilyKey = attribute.Key("host.cpu.family")
+
+ // HostCPUModelIDKey is the attribute Key conforming to the "host.cpu.model.id"
+ // semantic conventions. It represents the model identifier. It provides more
+ // granular information about the CPU, distinguishing it from other CPUs within
+ // the same family.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "6", "9000/778/B180L"
+ HostCPUModelIDKey = attribute.Key("host.cpu.model.id")
+
+ // HostCPUModelNameKey is the attribute Key conforming to the
+ // "host.cpu.model.name" semantic conventions. It represents the model
+ // designation of the processor.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "11th Gen Intel(R) Core(TM) i7-1185G7 @ 3.00GHz"
+ HostCPUModelNameKey = attribute.Key("host.cpu.model.name")
+
+ // HostCPUSteppingKey is the attribute Key conforming to the "host.cpu.stepping"
+ // semantic conventions. It represents the stepping or core revisions.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "1", "r1p1"
+ HostCPUSteppingKey = attribute.Key("host.cpu.stepping")
+
+ // HostCPUVendorIDKey is the attribute Key conforming to the
+ // "host.cpu.vendor.id" semantic conventions. It represents the processor
+ // manufacturer identifier. A maximum 12-character string.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "GenuineIntel"
+ // Note: [CPUID] command returns the vendor ID string in EBX, EDX and ECX
+ // registers. Writing these to memory in this order results in a 12-character
+ // string.
+ //
+ // [CPUID]: https://wiki.osdev.org/CPUID
+ HostCPUVendorIDKey = attribute.Key("host.cpu.vendor.id")
+
+ // HostIDKey is the attribute Key conforming to the "host.id" semantic
+ // conventions. It represents the unique host ID. For Cloud, this must be the
+ // instance_id assigned by the cloud provider. For non-containerized systems,
+ // this should be the `machine-id`. See the table below for the sources to use
+ // to determine the `machine-id` based on operating system.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "fdbf79e8af94cb7f9e8df36789187052"
+ HostIDKey = attribute.Key("host.id")
+
+ // HostImageIDKey is the attribute Key conforming to the "host.image.id"
+ // semantic conventions. It represents the VM image ID or host OS image ID. For
+ // Cloud, this value is from the provider.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "ami-07b06b442921831e5"
+ HostImageIDKey = attribute.Key("host.image.id")
+
+ // HostImageNameKey is the attribute Key conforming to the "host.image.name"
+ // semantic conventions. It represents the name of the VM image or OS install
+ // the host was instantiated from.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "infra-ami-eks-worker-node-7d4ec78312", "CentOS-8-x86_64-1905"
+ HostImageNameKey = attribute.Key("host.image.name")
+
+ // HostImageVersionKey is the attribute Key conforming to the
+ // "host.image.version" semantic conventions. It represents the version string
+ // of the VM image or host OS as defined in [Version Attributes].
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "0.1"
+ //
+ // [Version Attributes]: /docs/resource/README.md#version-attributes
+ HostImageVersionKey = attribute.Key("host.image.version")
+
+ // HostIPKey is the attribute Key conforming to the "host.ip" semantic
+ // conventions. It represents the available IP addresses of the host, excluding
+ // loopback interfaces.
+ //
+ // Type: string[]
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "192.168.1.140", "fe80::abc2:4a28:737a:609e"
+ // Note: IPv4 Addresses MUST be specified in dotted-quad notation. IPv6
+ // addresses MUST be specified in the [RFC 5952] format.
+ //
+ // [RFC 5952]: https://www.rfc-editor.org/rfc/rfc5952.html
+ HostIPKey = attribute.Key("host.ip")
+
+ // HostMacKey is the attribute Key conforming to the "host.mac" semantic
+ // conventions. It represents the available MAC addresses of the host, excluding
+ // loopback interfaces.
+ //
+ // Type: string[]
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "AC-DE-48-23-45-67", "AC-DE-48-23-45-67-01-9F"
+ // Note: MAC Addresses MUST be represented in [IEEE RA hexadecimal form]: as
+ // hyphen-separated octets in uppercase hexadecimal form from most to least
+ // significant.
+ //
+ // [IEEE RA hexadecimal form]: https://standards.ieee.org/wp-content/uploads/import/documents/tutorials/eui.pdf
+ HostMacKey = attribute.Key("host.mac")
+
+ // HostNameKey is the attribute Key conforming to the "host.name" semantic
+ // conventions. It represents the name of the host. On Unix systems, it may
+ // contain what the hostname command returns, or the fully qualified hostname,
+ // or another name specified by the user.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "opentelemetry-test"
+ HostNameKey = attribute.Key("host.name")
+
+ // HostTypeKey is the attribute Key conforming to the "host.type" semantic
+ // conventions. It represents the type of host. For Cloud, this must be the
+ // machine type.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "n1-standard-1"
+ HostTypeKey = attribute.Key("host.type")
+)
+
+// HostCPUCacheL2Size returns an attribute KeyValue conforming to the
+// "host.cpu.cache.l2.size" semantic conventions. It represents the amount of
+// level 2 memory cache available to the processor (in Bytes).
+func HostCPUCacheL2Size(val int) attribute.KeyValue {
+ return HostCPUCacheL2SizeKey.Int(val)
+}
+
+// HostCPUFamily returns an attribute KeyValue conforming to the
+// "host.cpu.family" semantic conventions. It represents the family or generation
+// of the CPU.
+func HostCPUFamily(val string) attribute.KeyValue {
+ return HostCPUFamilyKey.String(val)
+}
+
+// HostCPUModelID returns an attribute KeyValue conforming to the
+// "host.cpu.model.id" semantic conventions. It represents the model identifier.
+// It provides more granular information about the CPU, distinguishing it from
+// other CPUs within the same family.
+func HostCPUModelID(val string) attribute.KeyValue {
+ return HostCPUModelIDKey.String(val)
+}
+
+// HostCPUModelName returns an attribute KeyValue conforming to the
+// "host.cpu.model.name" semantic conventions. It represents the model
+// designation of the processor.
+func HostCPUModelName(val string) attribute.KeyValue {
+ return HostCPUModelNameKey.String(val)
+}
+
+// HostCPUStepping returns an attribute KeyValue conforming to the
+// "host.cpu.stepping" semantic conventions. It represents the stepping or core
+// revisions.
+func HostCPUStepping(val string) attribute.KeyValue {
+ return HostCPUSteppingKey.String(val)
+}
+
+// HostCPUVendorID returns an attribute KeyValue conforming to the
+// "host.cpu.vendor.id" semantic conventions. It represents the processor
+// manufacturer identifier. A maximum 12-character string.
+func HostCPUVendorID(val string) attribute.KeyValue {
+ return HostCPUVendorIDKey.String(val)
+}
+
+// HostID returns an attribute KeyValue conforming to the "host.id" semantic
+// conventions. It represents the unique host ID. For Cloud, this must be the
+// instance_id assigned by the cloud provider. For non-containerized systems,
+// this should be the `machine-id`. See the table below for the sources to use to
+// determine the `machine-id` based on operating system.
+func HostID(val string) attribute.KeyValue {
+ return HostIDKey.String(val)
+}
+
+// HostImageID returns an attribute KeyValue conforming to the "host.image.id"
+// semantic conventions. It represents the VM image ID or host OS image ID. For
+// Cloud, this value is from the provider.
+func HostImageID(val string) attribute.KeyValue {
+ return HostImageIDKey.String(val)
+}
+
+// HostImageName returns an attribute KeyValue conforming to the
+// "host.image.name" semantic conventions. It represents the name of the VM image
+// or OS install the host was instantiated from.
+func HostImageName(val string) attribute.KeyValue {
+ return HostImageNameKey.String(val)
+}
+
+// HostImageVersion returns an attribute KeyValue conforming to the
+// "host.image.version" semantic conventions. It represents the version string of
+// the VM image or host OS as defined in [Version Attributes].
+//
+// [Version Attributes]: /docs/resource/README.md#version-attributes
+func HostImageVersion(val string) attribute.KeyValue {
+ return HostImageVersionKey.String(val)
+}
+
+// HostIP returns an attribute KeyValue conforming to the "host.ip" semantic
+// conventions. It represents the available IP addresses of the host, excluding
+// loopback interfaces.
+func HostIP(val ...string) attribute.KeyValue {
+ return HostIPKey.StringSlice(val)
+}
+
+// HostMac returns an attribute KeyValue conforming to the "host.mac" semantic
+// conventions. It represents the available MAC addresses of the host, excluding
+// loopback interfaces.
+func HostMac(val ...string) attribute.KeyValue {
+ return HostMacKey.StringSlice(val)
+}
+
+// HostName returns an attribute KeyValue conforming to the "host.name" semantic
+// conventions. It represents the name of the host. On Unix systems, it may
+// contain what the hostname command returns, or the fully qualified hostname, or
+// another name specified by the user.
+func HostName(val string) attribute.KeyValue {
+ return HostNameKey.String(val)
+}
+
+// HostType returns an attribute KeyValue conforming to the "host.type" semantic
+// conventions. It represents the type of host. For Cloud, this must be the
+// machine type.
+func HostType(val string) attribute.KeyValue {
+ return HostTypeKey.String(val)
+}
+
+// Enum values for host.arch
+var (
+ // AMD64
+ // Stability: development
+ HostArchAMD64 = HostArchKey.String("amd64")
+ // ARM32
+ // Stability: development
+ HostArchARM32 = HostArchKey.String("arm32")
+ // ARM64
+ // Stability: development
+ HostArchARM64 = HostArchKey.String("arm64")
+ // Itanium
+ // Stability: development
+ HostArchIA64 = HostArchKey.String("ia64")
+ // 32-bit PowerPC
+ // Stability: development
+ HostArchPPC32 = HostArchKey.String("ppc32")
+ // 64-bit PowerPC
+ // Stability: development
+ HostArchPPC64 = HostArchKey.String("ppc64")
+ // IBM z/Architecture
+ // Stability: development
+ HostArchS390x = HostArchKey.String("s390x")
+ // 32-bit x86
+ // Stability: development
+ HostArchX86 = HostArchKey.String("x86")
+)
+
+// Namespace: http
+const (
+ // HTTPConnectionStateKey is the attribute Key conforming to the
+ // "http.connection.state" semantic conventions. It represents the state of the
+ // HTTP connection in the HTTP connection pool.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "active", "idle"
+ HTTPConnectionStateKey = attribute.Key("http.connection.state")
+
+ // HTTPRequestBodySizeKey is the attribute Key conforming to the
+ // "http.request.body.size" semantic conventions. It represents the size of the
+ // request payload body in bytes. This is the number of bytes transferred
+ // excluding headers and is often, but not always, present as the
+ // [Content-Length] header. For requests using transport encoding, this should
+ // be the compressed size.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // [Content-Length]: https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length
+ HTTPRequestBodySizeKey = attribute.Key("http.request.body.size")
+
+ // HTTPRequestMethodKey is the attribute Key conforming to the
+ // "http.request.method" semantic conventions. It represents the HTTP request
+ // method.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ //
+ // Examples: "GET", "POST", "HEAD"
+ // Note: HTTP request method value SHOULD be "known" to the instrumentation.
+ // By default, this convention defines "known" methods as the ones listed in
+ // [RFC9110],
+ // the PATCH method defined in [RFC5789]
+ // and the QUERY method defined in [httpbis-safe-method-w-body].
+ //
+ // If the HTTP request method is not known to instrumentation, it MUST set the
+ // `http.request.method` attribute to `_OTHER`.
+ //
+ // If the HTTP instrumentation could end up converting valid HTTP request
+ // methods to `_OTHER`, then it MUST provide a way to override
+ // the list of known HTTP methods. If this override is done via environment
+ // variable, then the environment variable MUST be named
+ // OTEL_INSTRUMENTATION_HTTP_KNOWN_METHODS and support a comma-separated list of
+ // case-sensitive known HTTP methods.
+ //
+ //
+ // If this override is done via declarative configuration, then the list MUST be
+ // configurable via the `known_methods` property
+ // (an array of case-sensitive strings with minimum items 0) under
+ // `.instrumentation/development.general.http.client` and/or
+ // `.instrumentation/development.general.http.server`.
+ //
+ // In either case, this list MUST be a full override of the default known
+ // methods,
+ // it is not a list of known methods in addition to the defaults.
+ //
+ // HTTP method names are case-sensitive and `http.request.method` attribute
+ // value MUST match a known HTTP method name exactly.
+ // Instrumentations for specific web frameworks that consider HTTP methods to be
+ // case insensitive, SHOULD populate a canonical equivalent.
+ // Tracing instrumentations that do so, MUST also set
+ // `http.request.method_original` to the original value.
+ //
+ // [RFC9110]: https://www.rfc-editor.org/rfc/rfc9110.html#name-methods
+ // [RFC5789]: https://www.rfc-editor.org/rfc/rfc5789.html
+ // [httpbis-safe-method-w-body]: https://datatracker.ietf.org/doc/draft-ietf-httpbis-safe-method-w-body/?include_text=1
+ HTTPRequestMethodKey = attribute.Key("http.request.method")
+
+ // HTTPRequestMethodOriginalKey is the attribute Key conforming to the
+ // "http.request.method_original" semantic conventions. It represents the
+ // original HTTP method sent by the client in the request line.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ //
+ // Examples: "GeT", "ACL", "foo"
+ HTTPRequestMethodOriginalKey = attribute.Key("http.request.method_original")
+
+ // HTTPRequestResendCountKey is the attribute Key conforming to the
+ // "http.request.resend_count" semantic conventions. It represents the ordinal
+ // number of request resending attempt (for any reason, including redirects).
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ //
+ // Note: The resend count SHOULD be updated each time an HTTP request gets
+ // resent by the client, regardless of what was the cause of the resending (e.g.
+ // redirection, authorization failure, 503 Server Unavailable, network issues,
+ // or any other).
+ HTTPRequestResendCountKey = attribute.Key("http.request.resend_count")
+
+ // HTTPRequestSizeKey is the attribute Key conforming to the "http.request.size"
+ // semantic conventions. It represents the total size of the request in bytes.
+ // This should be the total number of bytes sent over the wire, including the
+ // request line (HTTP/1.1), framing (HTTP/2 and HTTP/3), headers, and request
+ // body if any.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ HTTPRequestSizeKey = attribute.Key("http.request.size")
+
+ // HTTPResponseBodySizeKey is the attribute Key conforming to the
+ // "http.response.body.size" semantic conventions. It represents the size of the
+ // response payload body in bytes. This is the number of bytes transferred
+ // excluding headers and is often, but not always, present as the
+ // [Content-Length] header. For requests using transport encoding, this should
+ // be the compressed size.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // [Content-Length]: https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length
+ HTTPResponseBodySizeKey = attribute.Key("http.response.body.size")
+
+ // HTTPResponseSizeKey is the attribute Key conforming to the
+ // "http.response.size" semantic conventions. It represents the total size of
+ // the response in bytes. This should be the total number of bytes sent over the
+ // wire, including the status line (HTTP/1.1), framing (HTTP/2 and HTTP/3),
+ // headers, and response body and trailers if any.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ HTTPResponseSizeKey = attribute.Key("http.response.size")
+
+ // HTTPResponseStatusCodeKey is the attribute Key conforming to the
+ // "http.response.status_code" semantic conventions. It represents the
+ // [HTTP response status code].
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ //
+ // Examples: 200
+ //
+ // [HTTP response status code]: https://tools.ietf.org/html/rfc7231#section-6
+ HTTPResponseStatusCodeKey = attribute.Key("http.response.status_code")
+
+ // HTTPRouteKey is the attribute Key conforming to the "http.route" semantic
+ // conventions. It represents the matched route template for the request. This
+ // MUST be low-cardinality and include all static path segments, with dynamic
+ // path segments represented with placeholders.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ //
+ // Examples: "/users/:userID?", "my-controller/my-action/{id?}"
+ // Note: MUST NOT be populated when this is not supported by the HTTP server
+ // framework as the route attribute should have low-cardinality and the URI path
+ // can NOT substitute it.
+ // SHOULD include the [application root] if there is one.
+ //
+ // A static path segment is a part of the route template with a fixed,
+ // low-cardinality value. This includes literal strings like `/users/` and
+ // placeholders that
+ // are constrained to a finite, predefined set of values, e.g. `{controller}` or
+ // `{action}`.
+ //
+ // A dynamic path segment is a placeholder for a value that can have high
+ // cardinality and is not constrained to a predefined list like static path
+ // segments.
+ //
+ // Instrumentations SHOULD use routing information provided by the corresponding
+ // web framework. They SHOULD pick the most precise source of routing
+ // information and MAY
+ // support custom route formatting. Instrumentations SHOULD document the format
+ // and the API used to obtain the route string.
+ //
+ // [application root]: /docs/http/http-spans.md#http-server-definitions
+ HTTPRouteKey = attribute.Key("http.route")
+)
+
+// HTTPRequestBodySize returns an attribute KeyValue conforming to the
+// "http.request.body.size" semantic conventions. It represents the size of the
+// request payload body in bytes. This is the number of bytes transferred
+// excluding headers and is often, but not always, present as the
+// [Content-Length] header. For requests using transport encoding, this should be
+// the compressed size.
+//
+// [Content-Length]: https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length
+func HTTPRequestBodySize(val int) attribute.KeyValue {
+ return HTTPRequestBodySizeKey.Int(val)
+}
+
+// HTTPRequestHeader returns an attribute KeyValue conforming to the
+// "http.request.header" semantic conventions. It represents the HTTP request
+// headers, `` being the normalized HTTP Header name (lowercase), the value
+// being the header values.
+func HTTPRequestHeader(key string, val ...string) attribute.KeyValue {
+ return attribute.StringSlice("http.request.header."+key, val)
+}
+
+// HTTPRequestMethodOriginal returns an attribute KeyValue conforming to the
+// "http.request.method_original" semantic conventions. It represents the
+// original HTTP method sent by the client in the request line.
+func HTTPRequestMethodOriginal(val string) attribute.KeyValue {
+ return HTTPRequestMethodOriginalKey.String(val)
+}
+
+// HTTPRequestResendCount returns an attribute KeyValue conforming to the
+// "http.request.resend_count" semantic conventions. It represents the ordinal
+// number of request resending attempt (for any reason, including redirects).
+func HTTPRequestResendCount(val int) attribute.KeyValue {
+ return HTTPRequestResendCountKey.Int(val)
+}
+
+// HTTPRequestSize returns an attribute KeyValue conforming to the
+// "http.request.size" semantic conventions. It represents the total size of the
+// request in bytes. This should be the total number of bytes sent over the wire,
+// including the request line (HTTP/1.1), framing (HTTP/2 and HTTP/3), headers,
+// and request body if any.
+func HTTPRequestSize(val int) attribute.KeyValue {
+ return HTTPRequestSizeKey.Int(val)
+}
+
+// HTTPResponseBodySize returns an attribute KeyValue conforming to the
+// "http.response.body.size" semantic conventions. It represents the size of the
+// response payload body in bytes. This is the number of bytes transferred
+// excluding headers and is often, but not always, present as the
+// [Content-Length] header. For requests using transport encoding, this should be
+// the compressed size.
+//
+// [Content-Length]: https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length
+func HTTPResponseBodySize(val int) attribute.KeyValue {
+ return HTTPResponseBodySizeKey.Int(val)
+}
+
+// HTTPResponseHeader returns an attribute KeyValue conforming to the
+// "http.response.header" semantic conventions. It represents the HTTP response
+// headers, `` being the normalized HTTP Header name (lowercase), the value
+// being the header values.
+func HTTPResponseHeader(key string, val ...string) attribute.KeyValue {
+ return attribute.StringSlice("http.response.header."+key, val)
+}
+
+// HTTPResponseSize returns an attribute KeyValue conforming to the
+// "http.response.size" semantic conventions. It represents the total size of the
+// response in bytes. This should be the total number of bytes sent over the
+// wire, including the status line (HTTP/1.1), framing (HTTP/2 and HTTP/3),
+// headers, and response body and trailers if any.
+func HTTPResponseSize(val int) attribute.KeyValue {
+ return HTTPResponseSizeKey.Int(val)
+}
+
+// HTTPResponseStatusCode returns an attribute KeyValue conforming to the
+// "http.response.status_code" semantic conventions. It represents the
+// [HTTP response status code].
+//
+// [HTTP response status code]: https://tools.ietf.org/html/rfc7231#section-6
+func HTTPResponseStatusCode(val int) attribute.KeyValue {
+ return HTTPResponseStatusCodeKey.Int(val)
+}
+
+// HTTPRoute returns an attribute KeyValue conforming to the "http.route"
+// semantic conventions. It represents the matched route template for the
+// request. This MUST be low-cardinality and include all static path segments,
+// with dynamic path segments represented with placeholders.
+func HTTPRoute(val string) attribute.KeyValue {
+ return HTTPRouteKey.String(val)
+}
+
+// Enum values for http.connection.state
+var (
+ // active state.
+ // Stability: development
+ HTTPConnectionStateActive = HTTPConnectionStateKey.String("active")
+ // idle state.
+ // Stability: development
+ HTTPConnectionStateIdle = HTTPConnectionStateKey.String("idle")
+)
+
+// Enum values for http.request.method
+var (
+ // CONNECT method.
+ // Stability: stable
+ HTTPRequestMethodConnect = HTTPRequestMethodKey.String("CONNECT")
+ // DELETE method.
+ // Stability: stable
+ HTTPRequestMethodDelete = HTTPRequestMethodKey.String("DELETE")
+ // GET method.
+ // Stability: stable
+ HTTPRequestMethodGet = HTTPRequestMethodKey.String("GET")
+ // HEAD method.
+ // Stability: stable
+ HTTPRequestMethodHead = HTTPRequestMethodKey.String("HEAD")
+ // OPTIONS method.
+ // Stability: stable
+ HTTPRequestMethodOptions = HTTPRequestMethodKey.String("OPTIONS")
+ // PATCH method.
+ // Stability: stable
+ HTTPRequestMethodPatch = HTTPRequestMethodKey.String("PATCH")
+ // POST method.
+ // Stability: stable
+ HTTPRequestMethodPost = HTTPRequestMethodKey.String("POST")
+ // PUT method.
+ // Stability: stable
+ HTTPRequestMethodPut = HTTPRequestMethodKey.String("PUT")
+ // TRACE method.
+ // Stability: stable
+ HTTPRequestMethodTrace = HTTPRequestMethodKey.String("TRACE")
+ // QUERY method.
+ // Stability: development
+ HTTPRequestMethodQuery = HTTPRequestMethodKey.String("QUERY")
+ // Any HTTP method that the instrumentation has no prior knowledge of.
+ // Stability: stable
+ HTTPRequestMethodOther = HTTPRequestMethodKey.String("_OTHER")
+)
+
+// Namespace: hw
+const (
+ // HwBatteryCapacityKey is the attribute Key conforming to the
+ // "hw.battery.capacity" semantic conventions. It represents the design capacity
+ // in Watts-hours or Amper-hours.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "9.3Ah", "50Wh"
+ HwBatteryCapacityKey = attribute.Key("hw.battery.capacity")
+
+ // HwBatteryChemistryKey is the attribute Key conforming to the
+ // "hw.battery.chemistry" semantic conventions. It represents the battery
+ // [chemistry], e.g. Lithium-Ion, Nickel-Cadmium, etc.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "Li-ion", "NiMH"
+ //
+ // [chemistry]: https://schemas.dmtf.org/wbem/cim-html/2.31.0/CIM_Battery.html
+ HwBatteryChemistryKey = attribute.Key("hw.battery.chemistry")
+
+ // HwBatteryStateKey is the attribute Key conforming to the "hw.battery.state"
+ // semantic conventions. It represents the current state of the battery.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ HwBatteryStateKey = attribute.Key("hw.battery.state")
+
+ // HwBiosVersionKey is the attribute Key conforming to the "hw.bios_version"
+ // semantic conventions. It represents the BIOS version of the hardware
+ // component.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "1.2.3"
+ HwBiosVersionKey = attribute.Key("hw.bios_version")
+
+ // HwDriverVersionKey is the attribute Key conforming to the "hw.driver_version"
+ // semantic conventions. It represents the driver version for the hardware
+ // component.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "10.2.1-3"
+ HwDriverVersionKey = attribute.Key("hw.driver_version")
+
+ // HwEnclosureTypeKey is the attribute Key conforming to the "hw.enclosure.type"
+ // semantic conventions. It represents the type of the enclosure (useful for
+ // modular systems).
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "Computer", "Storage", "Switch"
+ HwEnclosureTypeKey = attribute.Key("hw.enclosure.type")
+
+ // HwFirmwareVersionKey is the attribute Key conforming to the
+ // "hw.firmware_version" semantic conventions. It represents the firmware
+ // version of the hardware component.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "2.0.1"
+ HwFirmwareVersionKey = attribute.Key("hw.firmware_version")
+
+ // HwGpuTaskKey is the attribute Key conforming to the "hw.gpu.task" semantic
+ // conventions. It represents the type of task the GPU is performing.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ HwGpuTaskKey = attribute.Key("hw.gpu.task")
+
+ // HwIDKey is the attribute Key conforming to the "hw.id" semantic conventions.
+ // It represents an identifier for the hardware component, unique within the
+ // monitored host.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "win32battery_battery_testsysa33_1"
+ HwIDKey = attribute.Key("hw.id")
+
+ // HwLimitTypeKey is the attribute Key conforming to the "hw.limit_type"
+ // semantic conventions. It represents the type of limit for hardware
+ // components.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ HwLimitTypeKey = attribute.Key("hw.limit_type")
+
+ // HwLogicalDiskRaidLevelKey is the attribute Key conforming to the
+ // "hw.logical_disk.raid_level" semantic conventions. It represents the RAID
+ // Level of the logical disk.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "RAID0+1", "RAID5", "RAID10"
+ HwLogicalDiskRaidLevelKey = attribute.Key("hw.logical_disk.raid_level")
+
+ // HwLogicalDiskStateKey is the attribute Key conforming to the
+ // "hw.logical_disk.state" semantic conventions. It represents the state of the
+ // logical disk space usage.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ HwLogicalDiskStateKey = attribute.Key("hw.logical_disk.state")
+
+ // HwMemoryTypeKey is the attribute Key conforming to the "hw.memory.type"
+ // semantic conventions. It represents the type of the memory module.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "DDR4", "DDR5", "LPDDR5"
+ HwMemoryTypeKey = attribute.Key("hw.memory.type")
+
+ // HwModelKey is the attribute Key conforming to the "hw.model" semantic
+ // conventions. It represents the descriptive model name of the hardware
+ // component.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "PERC H740P", "Intel(R) Core(TM) i7-10700K", "Dell XPS 15 Battery"
+ HwModelKey = attribute.Key("hw.model")
+
+ // HwNameKey is the attribute Key conforming to the "hw.name" semantic
+ // conventions. It represents an easily-recognizable name for the hardware
+ // component.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "eth0"
+ HwNameKey = attribute.Key("hw.name")
+
+ // HwNetworkLogicalAddressesKey is the attribute Key conforming to the
+ // "hw.network.logical_addresses" semantic conventions. It represents the
+ // logical addresses of the adapter (e.g. IP address, or WWPN).
+ //
+ // Type: string[]
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "172.16.8.21", "57.11.193.42"
+ HwNetworkLogicalAddressesKey = attribute.Key("hw.network.logical_addresses")
+
+ // HwNetworkPhysicalAddressKey is the attribute Key conforming to the
+ // "hw.network.physical_address" semantic conventions. It represents the
+ // physical address of the adapter (e.g. MAC address, or WWNN).
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "00-90-F5-E9-7B-36"
+ HwNetworkPhysicalAddressKey = attribute.Key("hw.network.physical_address")
+
+ // HwParentKey is the attribute Key conforming to the "hw.parent" semantic
+ // conventions. It represents the unique identifier of the parent component
+ // (typically the `hw.id` attribute of the enclosure, or disk controller).
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "dellStorage_perc_0"
+ HwParentKey = attribute.Key("hw.parent")
+
+ // HwPhysicalDiskSmartAttributeKey is the attribute Key conforming to the
+ // "hw.physical_disk.smart_attribute" semantic conventions. It represents the
+ // [S.M.A.R.T.] (Self-Monitoring, Analysis, and Reporting Technology) attribute
+ // of the physical disk.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "Spin Retry Count", "Seek Error Rate", "Raw Read Error Rate"
+ //
+ // [S.M.A.R.T.]: https://wikipedia.org/wiki/S.M.A.R.T.
+ HwPhysicalDiskSmartAttributeKey = attribute.Key("hw.physical_disk.smart_attribute")
+
+ // HwPhysicalDiskStateKey is the attribute Key conforming to the
+ // "hw.physical_disk.state" semantic conventions. It represents the state of the
+ // physical disk endurance utilization.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ HwPhysicalDiskStateKey = attribute.Key("hw.physical_disk.state")
+
+ // HwPhysicalDiskTypeKey is the attribute Key conforming to the
+ // "hw.physical_disk.type" semantic conventions. It represents the type of the
+ // physical disk.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "HDD", "SSD", "10K"
+ HwPhysicalDiskTypeKey = attribute.Key("hw.physical_disk.type")
+
+ // HwSensorLocationKey is the attribute Key conforming to the
+ // "hw.sensor_location" semantic conventions. It represents the location of the
+ // sensor.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "cpu0", "ps1", "INLET", "CPU0_DIE", "AMBIENT", "MOTHERBOARD", "PS0
+ // V3_3", "MAIN_12V", "CPU_VCORE"
+ HwSensorLocationKey = attribute.Key("hw.sensor_location")
+
+ // HwSerialNumberKey is the attribute Key conforming to the "hw.serial_number"
+ // semantic conventions. It represents the serial number of the hardware
+ // component.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "CNFCP0123456789"
+ HwSerialNumberKey = attribute.Key("hw.serial_number")
+
+ // HwStateKey is the attribute Key conforming to the "hw.state" semantic
+ // conventions. It represents the current state of the component.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ HwStateKey = attribute.Key("hw.state")
+
+ // HwTapeDriveOperationTypeKey is the attribute Key conforming to the
+ // "hw.tape_drive.operation_type" semantic conventions. It represents the type
+ // of tape drive operation.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ HwTapeDriveOperationTypeKey = attribute.Key("hw.tape_drive.operation_type")
+
+ // HwTypeKey is the attribute Key conforming to the "hw.type" semantic
+ // conventions. It represents the type of the component.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ // Note: Describes the category of the hardware component for which `hw.state`
+ // is being reported. For example, `hw.type=temperature` along with
+ // `hw.state=degraded` would indicate that the temperature of the hardware
+ // component has been reported as `degraded`.
+ HwTypeKey = attribute.Key("hw.type")
+
+ // HwVendorKey is the attribute Key conforming to the "hw.vendor" semantic
+ // conventions. It represents the vendor name of the hardware component.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "Dell", "HP", "Intel", "AMD", "LSI", "Lenovo"
+ HwVendorKey = attribute.Key("hw.vendor")
+)
+
+// HwBatteryCapacity returns an attribute KeyValue conforming to the
+// "hw.battery.capacity" semantic conventions. It represents the design capacity
+// in Watts-hours or Amper-hours.
+func HwBatteryCapacity(val string) attribute.KeyValue {
+ return HwBatteryCapacityKey.String(val)
+}
+
+// HwBatteryChemistry returns an attribute KeyValue conforming to the
+// "hw.battery.chemistry" semantic conventions. It represents the battery
+// [chemistry], e.g. Lithium-Ion, Nickel-Cadmium, etc.
+//
+// [chemistry]: https://schemas.dmtf.org/wbem/cim-html/2.31.0/CIM_Battery.html
+func HwBatteryChemistry(val string) attribute.KeyValue {
+ return HwBatteryChemistryKey.String(val)
+}
+
+// HwBiosVersion returns an attribute KeyValue conforming to the
+// "hw.bios_version" semantic conventions. It represents the BIOS version of the
+// hardware component.
+func HwBiosVersion(val string) attribute.KeyValue {
+ return HwBiosVersionKey.String(val)
+}
+
+// HwDriverVersion returns an attribute KeyValue conforming to the
+// "hw.driver_version" semantic conventions. It represents the driver version for
+// the hardware component.
+func HwDriverVersion(val string) attribute.KeyValue {
+ return HwDriverVersionKey.String(val)
+}
+
+// HwEnclosureType returns an attribute KeyValue conforming to the
+// "hw.enclosure.type" semantic conventions. It represents the type of the
+// enclosure (useful for modular systems).
+func HwEnclosureType(val string) attribute.KeyValue {
+ return HwEnclosureTypeKey.String(val)
+}
+
+// HwFirmwareVersion returns an attribute KeyValue conforming to the
+// "hw.firmware_version" semantic conventions. It represents the firmware version
+// of the hardware component.
+func HwFirmwareVersion(val string) attribute.KeyValue {
+ return HwFirmwareVersionKey.String(val)
+}
+
+// HwID returns an attribute KeyValue conforming to the "hw.id" semantic
+// conventions. It represents an identifier for the hardware component, unique
+// within the monitored host.
+func HwID(val string) attribute.KeyValue {
+ return HwIDKey.String(val)
+}
+
+// HwLogicalDiskRaidLevel returns an attribute KeyValue conforming to the
+// "hw.logical_disk.raid_level" semantic conventions. It represents the RAID
+// Level of the logical disk.
+func HwLogicalDiskRaidLevel(val string) attribute.KeyValue {
+ return HwLogicalDiskRaidLevelKey.String(val)
+}
+
+// HwMemoryType returns an attribute KeyValue conforming to the "hw.memory.type"
+// semantic conventions. It represents the type of the memory module.
+func HwMemoryType(val string) attribute.KeyValue {
+ return HwMemoryTypeKey.String(val)
+}
+
+// HwModel returns an attribute KeyValue conforming to the "hw.model" semantic
+// conventions. It represents the descriptive model name of the hardware
+// component.
+func HwModel(val string) attribute.KeyValue {
+ return HwModelKey.String(val)
+}
+
+// HwName returns an attribute KeyValue conforming to the "hw.name" semantic
+// conventions. It represents an easily-recognizable name for the hardware
+// component.
+func HwName(val string) attribute.KeyValue {
+ return HwNameKey.String(val)
+}
+
+// HwNetworkLogicalAddresses returns an attribute KeyValue conforming to the
+// "hw.network.logical_addresses" semantic conventions. It represents the logical
+// addresses of the adapter (e.g. IP address, or WWPN).
+func HwNetworkLogicalAddresses(val ...string) attribute.KeyValue {
+ return HwNetworkLogicalAddressesKey.StringSlice(val)
+}
+
+// HwNetworkPhysicalAddress returns an attribute KeyValue conforming to the
+// "hw.network.physical_address" semantic conventions. It represents the physical
+// address of the adapter (e.g. MAC address, or WWNN).
+func HwNetworkPhysicalAddress(val string) attribute.KeyValue {
+ return HwNetworkPhysicalAddressKey.String(val)
+}
+
+// HwParent returns an attribute KeyValue conforming to the "hw.parent" semantic
+// conventions. It represents the unique identifier of the parent component
+// (typically the `hw.id` attribute of the enclosure, or disk controller).
+func HwParent(val string) attribute.KeyValue {
+ return HwParentKey.String(val)
+}
+
+// HwPhysicalDiskSmartAttribute returns an attribute KeyValue conforming to the
+// "hw.physical_disk.smart_attribute" semantic conventions. It represents the
+// [S.M.A.R.T.] (Self-Monitoring, Analysis, and Reporting Technology) attribute
+// of the physical disk.
+//
+// [S.M.A.R.T.]: https://wikipedia.org/wiki/S.M.A.R.T.
+func HwPhysicalDiskSmartAttribute(val string) attribute.KeyValue {
+ return HwPhysicalDiskSmartAttributeKey.String(val)
+}
+
+// HwPhysicalDiskType returns an attribute KeyValue conforming to the
+// "hw.physical_disk.type" semantic conventions. It represents the type of the
+// physical disk.
+func HwPhysicalDiskType(val string) attribute.KeyValue {
+ return HwPhysicalDiskTypeKey.String(val)
+}
+
+// HwSensorLocation returns an attribute KeyValue conforming to the
+// "hw.sensor_location" semantic conventions. It represents the location of the
+// sensor.
+func HwSensorLocation(val string) attribute.KeyValue {
+ return HwSensorLocationKey.String(val)
+}
+
+// HwSerialNumber returns an attribute KeyValue conforming to the
+// "hw.serial_number" semantic conventions. It represents the serial number of
+// the hardware component.
+func HwSerialNumber(val string) attribute.KeyValue {
+ return HwSerialNumberKey.String(val)
+}
+
+// HwVendor returns an attribute KeyValue conforming to the "hw.vendor" semantic
+// conventions. It represents the vendor name of the hardware component.
+func HwVendor(val string) attribute.KeyValue {
+ return HwVendorKey.String(val)
+}
+
+// Enum values for hw.battery.state
+var (
+ // Charging
+ // Stability: development
+ HwBatteryStateCharging = HwBatteryStateKey.String("charging")
+ // Discharging
+ // Stability: development
+ HwBatteryStateDischarging = HwBatteryStateKey.String("discharging")
+)
+
+// Enum values for hw.gpu.task
+var (
+ // Decoder
+ // Stability: development
+ HwGpuTaskDecoder = HwGpuTaskKey.String("decoder")
+ // Encoder
+ // Stability: development
+ HwGpuTaskEncoder = HwGpuTaskKey.String("encoder")
+ // General
+ // Stability: development
+ HwGpuTaskGeneral = HwGpuTaskKey.String("general")
+)
+
+// Enum values for hw.limit_type
+var (
+ // Critical
+ // Stability: development
+ HwLimitTypeCritical = HwLimitTypeKey.String("critical")
+ // Degraded
+ // Stability: development
+ HwLimitTypeDegraded = HwLimitTypeKey.String("degraded")
+ // High Critical
+ // Stability: development
+ HwLimitTypeHighCritical = HwLimitTypeKey.String("high.critical")
+ // High Degraded
+ // Stability: development
+ HwLimitTypeHighDegraded = HwLimitTypeKey.String("high.degraded")
+ // Low Critical
+ // Stability: development
+ HwLimitTypeLowCritical = HwLimitTypeKey.String("low.critical")
+ // Low Degraded
+ // Stability: development
+ HwLimitTypeLowDegraded = HwLimitTypeKey.String("low.degraded")
+ // Maximum
+ // Stability: development
+ HwLimitTypeMax = HwLimitTypeKey.String("max")
+ // Throttled
+ // Stability: development
+ HwLimitTypeThrottled = HwLimitTypeKey.String("throttled")
+ // Turbo
+ // Stability: development
+ HwLimitTypeTurbo = HwLimitTypeKey.String("turbo")
+)
+
+// Enum values for hw.logical_disk.state
+var (
+ // Used
+ // Stability: development
+ HwLogicalDiskStateUsed = HwLogicalDiskStateKey.String("used")
+ // Free
+ // Stability: development
+ HwLogicalDiskStateFree = HwLogicalDiskStateKey.String("free")
+)
+
+// Enum values for hw.physical_disk.state
+var (
+ // Remaining
+ // Stability: development
+ HwPhysicalDiskStateRemaining = HwPhysicalDiskStateKey.String("remaining")
+)
+
+// Enum values for hw.state
+var (
+ // Degraded
+ // Stability: development
+ HwStateDegraded = HwStateKey.String("degraded")
+ // Failed
+ // Stability: development
+ HwStateFailed = HwStateKey.String("failed")
+ // Needs Cleaning
+ // Stability: development
+ HwStateNeedsCleaning = HwStateKey.String("needs_cleaning")
+ // OK
+ // Stability: development
+ HwStateOk = HwStateKey.String("ok")
+ // Predicted Failure
+ // Stability: development
+ HwStatePredictedFailure = HwStateKey.String("predicted_failure")
+)
+
+// Enum values for hw.tape_drive.operation_type
+var (
+ // Mount
+ // Stability: development
+ HwTapeDriveOperationTypeMount = HwTapeDriveOperationTypeKey.String("mount")
+ // Unmount
+ // Stability: development
+ HwTapeDriveOperationTypeUnmount = HwTapeDriveOperationTypeKey.String("unmount")
+ // Clean
+ // Stability: development
+ HwTapeDriveOperationTypeClean = HwTapeDriveOperationTypeKey.String("clean")
+)
+
+// Enum values for hw.type
+var (
+ // Battery
+ // Stability: development
+ HwTypeBattery = HwTypeKey.String("battery")
+ // CPU
+ // Stability: development
+ HwTypeCPU = HwTypeKey.String("cpu")
+ // Disk controller
+ // Stability: development
+ HwTypeDiskController = HwTypeKey.String("disk_controller")
+ // Enclosure
+ // Stability: development
+ HwTypeEnclosure = HwTypeKey.String("enclosure")
+ // Fan
+ // Stability: development
+ HwTypeFan = HwTypeKey.String("fan")
+ // GPU
+ // Stability: development
+ HwTypeGpu = HwTypeKey.String("gpu")
+ // Logical disk
+ // Stability: development
+ HwTypeLogicalDisk = HwTypeKey.String("logical_disk")
+ // Memory
+ // Stability: development
+ HwTypeMemory = HwTypeKey.String("memory")
+ // Network
+ // Stability: development
+ HwTypeNetwork = HwTypeKey.String("network")
+ // Physical disk
+ // Stability: development
+ HwTypePhysicalDisk = HwTypeKey.String("physical_disk")
+ // Power supply
+ // Stability: development
+ HwTypePowerSupply = HwTypeKey.String("power_supply")
+ // Tape drive
+ // Stability: development
+ HwTypeTapeDrive = HwTypeKey.String("tape_drive")
+ // Temperature
+ // Stability: development
+ HwTypeTemperature = HwTypeKey.String("temperature")
+ // Voltage
+ // Stability: development
+ HwTypeVoltage = HwTypeKey.String("voltage")
+)
+
+// Namespace: ios
+const (
+ // IOSAppStateKey is the attribute Key conforming to the "ios.app.state"
+ // semantic conventions. It represents the this attribute represents the state
+ // of the application.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ // Note: The iOS lifecycle states are defined in the
+ // [UIApplicationDelegate documentation], and from which the `OS terminology`
+ // column values are derived.
+ //
+ // [UIApplicationDelegate documentation]: https://developer.apple.com/documentation/uikit/uiapplicationdelegate
+ IOSAppStateKey = attribute.Key("ios.app.state")
+)
+
+// Enum values for ios.app.state
+var (
+ // The app has become `active`. Associated with UIKit notification
+ // `applicationDidBecomeActive`.
+ //
+ // Stability: development
+ IOSAppStateActive = IOSAppStateKey.String("active")
+ // The app is now `inactive`. Associated with UIKit notification
+ // `applicationWillResignActive`.
+ //
+ // Stability: development
+ IOSAppStateInactive = IOSAppStateKey.String("inactive")
+ // The app is now in the background. This value is associated with UIKit
+ // notification `applicationDidEnterBackground`.
+ //
+ // Stability: development
+ IOSAppStateBackground = IOSAppStateKey.String("background")
+ // The app is now in the foreground. This value is associated with UIKit
+ // notification `applicationWillEnterForeground`.
+ //
+ // Stability: development
+ IOSAppStateForeground = IOSAppStateKey.String("foreground")
+ // The app is about to terminate. Associated with UIKit notification
+ // `applicationWillTerminate`.
+ //
+ // Stability: development
+ IOSAppStateTerminate = IOSAppStateKey.String("terminate")
+)
+
+// Namespace: jsonrpc
+const (
+ // JSONRPCProtocolVersionKey is the attribute Key conforming to the
+ // "jsonrpc.protocol.version" semantic conventions. It represents the protocol
+ // version, as specified in the `jsonrpc` property of the request and its
+ // corresponding response.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "2.0", "1.0"
+ JSONRPCProtocolVersionKey = attribute.Key("jsonrpc.protocol.version")
+
+ // JSONRPCRequestIDKey is the attribute Key conforming to the
+ // "jsonrpc.request.id" semantic conventions. It represents a string
+ // representation of the `id` property of the request and its corresponding
+ // response.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "10", "request-7"
+ // Note: Under the [JSON-RPC specification], the `id` property may be a string,
+ // number, null, or omitted entirely. When omitted, the request is treated as a
+ // notification. Using `null` is not equivalent to omitting the `id`, but it is
+ // discouraged.
+ // Instrumentations SHOULD NOT capture this attribute when the `id` is `null` or
+ // omitted.
+ //
+ // [JSON-RPC specification]: https://www.jsonrpc.org/specification
+ JSONRPCRequestIDKey = attribute.Key("jsonrpc.request.id")
+)
+
+// JSONRPCProtocolVersion returns an attribute KeyValue conforming to the
+// "jsonrpc.protocol.version" semantic conventions. It represents the protocol
+// version, as specified in the `jsonrpc` property of the request and its
+// corresponding response.
+func JSONRPCProtocolVersion(val string) attribute.KeyValue {
+ return JSONRPCProtocolVersionKey.String(val)
+}
+
+// JSONRPCRequestID returns an attribute KeyValue conforming to the
+// "jsonrpc.request.id" semantic conventions. It represents a string
+// representation of the `id` property of the request and its corresponding
+// response.
+func JSONRPCRequestID(val string) attribute.KeyValue {
+ return JSONRPCRequestIDKey.String(val)
+}
+
+// Namespace: k8s
+const (
+ // K8SClusterNameKey is the attribute Key conforming to the "k8s.cluster.name"
+ // semantic conventions. It represents the name of the cluster.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Beta
+ //
+ // Examples: "opentelemetry-cluster"
+ K8SClusterNameKey = attribute.Key("k8s.cluster.name")
+
+ // K8SClusterUIDKey is the attribute Key conforming to the "k8s.cluster.uid"
+ // semantic conventions. It represents a pseudo-ID for the cluster, set to the
+ // UID of the `kube-system` namespace.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Beta
+ //
+ // Examples: "218fc5a9-a5f1-4b54-aa05-46717d0ab26d"
+ // Note: K8s doesn't have support for obtaining a cluster ID. If this is ever
+ // added, we will recommend collecting the `k8s.cluster.uid` through the
+ // official APIs. In the meantime, we are able to use the `uid` of the
+ // `kube-system` namespace as a proxy for cluster ID. Read on for the
+ // rationale.
+ //
+ // Every object created in a K8s cluster is assigned a distinct UID. The
+ // `kube-system` namespace is used by Kubernetes itself and will exist
+ // for the lifetime of the cluster. Using the `uid` of the `kube-system`
+ // namespace is a reasonable proxy for the K8s ClusterID as it will only
+ // change if the cluster is rebuilt. Furthermore, Kubernetes UIDs are
+ // UUIDs as standardized by
+ // [ISO/IEC 9834-8 and ITU-T X.667].
+ // Which states:
+ //
+ // > If generated according to one of the mechanisms defined in Rec.
+ // > ITU-T X.667 | ISO/IEC 9834-8, a UUID is either guaranteed to be
+ // > different from all other UUIDs generated before 3603 A.D., or is
+ // > extremely likely to be different (depending on the mechanism chosen).
+ //
+ // Therefore, UIDs between clusters should be extremely unlikely to
+ // conflict.
+ //
+ // [ISO/IEC 9834-8 and ITU-T X.667]: https://www.itu.int/ITU-T/studygroups/com17/oid.html
+ K8SClusterUIDKey = attribute.Key("k8s.cluster.uid")
+
+ // K8SContainerNameKey is the attribute Key conforming to the
+ // "k8s.container.name" semantic conventions. It represents the name of the
+ // Container from Pod specification, must be unique within a Pod. Container
+ // runtime usually uses different globally unique name (`container.name`).
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Beta
+ //
+ // Examples: "redis"
+ K8SContainerNameKey = attribute.Key("k8s.container.name")
+
+ // K8SContainerRestartCountKey is the attribute Key conforming to the
+ // "k8s.container.restart_count" semantic conventions. It represents the number
+ // of times the container was restarted. This attribute can be used to identify
+ // a particular container (running or stopped) within a container spec.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Beta
+ //
+ // Examples:
+ K8SContainerRestartCountKey = attribute.Key("k8s.container.restart_count")
+
+ // K8SContainerStatusLastTerminatedReasonKey is the attribute Key conforming to
+ // the "k8s.container.status.last_terminated_reason" semantic conventions. It
+ // represents the last terminated reason of the Container.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "Evicted", "Error"
+ K8SContainerStatusLastTerminatedReasonKey = attribute.Key("k8s.container.status.last_terminated_reason")
+
+ // K8SContainerStatusReasonKey is the attribute Key conforming to the
+ // "k8s.container.status.reason" semantic conventions. It represents the reason
+ // for the container state. Corresponds to the `reason` field of the:
+ // [K8s ContainerStateWaiting] or [K8s ContainerStateTerminated].
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "ContainerCreating", "CrashLoopBackOff",
+ // "CreateContainerConfigError", "ErrImagePull", "ImagePullBackOff",
+ // "OOMKilled", "Completed", "Error", "ContainerCannotRun"
+ //
+ // [K8s ContainerStateWaiting]: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#containerstatewaiting-v1-core
+ // [K8s ContainerStateTerminated]: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#containerstateterminated-v1-core
+ K8SContainerStatusReasonKey = attribute.Key("k8s.container.status.reason")
+
+ // K8SContainerStatusStateKey is the attribute Key conforming to the
+ // "k8s.container.status.state" semantic conventions. It represents the state of
+ // the container. [K8s ContainerState].
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "terminated", "running", "waiting"
+ //
+ // [K8s ContainerState]: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#containerstate-v1-core
+ K8SContainerStatusStateKey = attribute.Key("k8s.container.status.state")
+
+ // K8SCronJobNameKey is the attribute Key conforming to the "k8s.cronjob.name"
+ // semantic conventions. It represents the name of the CronJob.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Beta
+ //
+ // Examples: "opentelemetry"
+ K8SCronJobNameKey = attribute.Key("k8s.cronjob.name")
+
+ // K8SCronJobUIDKey is the attribute Key conforming to the "k8s.cronjob.uid"
+ // semantic conventions. It represents the UID of the CronJob.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Beta
+ //
+ // Examples: "275ecb36-5aa8-4c2a-9c47-d8bb681b9aff"
+ K8SCronJobUIDKey = attribute.Key("k8s.cronjob.uid")
+
+ // K8SDaemonSetNameKey is the attribute Key conforming to the
+ // "k8s.daemonset.name" semantic conventions. It represents the name of the
+ // DaemonSet.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Beta
+ //
+ // Examples: "opentelemetry"
+ K8SDaemonSetNameKey = attribute.Key("k8s.daemonset.name")
+
+ // K8SDaemonSetUIDKey is the attribute Key conforming to the "k8s.daemonset.uid"
+ // semantic conventions. It represents the UID of the DaemonSet.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Beta
+ //
+ // Examples: "275ecb36-5aa8-4c2a-9c47-d8bb681b9aff"
+ K8SDaemonSetUIDKey = attribute.Key("k8s.daemonset.uid")
+
+ // K8SDeploymentNameKey is the attribute Key conforming to the
+ // "k8s.deployment.name" semantic conventions. It represents the name of the
+ // Deployment.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Beta
+ //
+ // Examples: "opentelemetry"
+ K8SDeploymentNameKey = attribute.Key("k8s.deployment.name")
+
+ // K8SDeploymentUIDKey is the attribute Key conforming to the
+ // "k8s.deployment.uid" semantic conventions. It represents the UID of the
+ // Deployment.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Beta
+ //
+ // Examples: "275ecb36-5aa8-4c2a-9c47-d8bb681b9aff"
+ K8SDeploymentUIDKey = attribute.Key("k8s.deployment.uid")
+
+ // K8SHPAMetricTypeKey is the attribute Key conforming to the
+ // "k8s.hpa.metric.type" semantic conventions. It represents the type of metric
+ // source for the horizontal pod autoscaler.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "Resource", "ContainerResource"
+ // Note: This attribute reflects the `type` field of spec.metrics[] in the HPA.
+ K8SHPAMetricTypeKey = attribute.Key("k8s.hpa.metric.type")
+
+ // K8SHPANameKey is the attribute Key conforming to the "k8s.hpa.name" semantic
+ // conventions. It represents the name of the horizontal pod autoscaler.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "opentelemetry"
+ K8SHPANameKey = attribute.Key("k8s.hpa.name")
+
+ // K8SHPAScaletargetrefAPIVersionKey is the attribute Key conforming to the
+ // "k8s.hpa.scaletargetref.api_version" semantic conventions. It represents the
+ // API version of the target resource to scale for the HorizontalPodAutoscaler.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "apps/v1", "autoscaling/v2"
+ // Note: This maps to the `apiVersion` field in the `scaleTargetRef` of the HPA
+ // spec.
+ K8SHPAScaletargetrefAPIVersionKey = attribute.Key("k8s.hpa.scaletargetref.api_version")
+
+ // K8SHPAScaletargetrefKindKey is the attribute Key conforming to the
+ // "k8s.hpa.scaletargetref.kind" semantic conventions. It represents the kind of
+ // the target resource to scale for the HorizontalPodAutoscaler.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "Deployment", "StatefulSet"
+ // Note: This maps to the `kind` field in the `scaleTargetRef` of the HPA spec.
+ K8SHPAScaletargetrefKindKey = attribute.Key("k8s.hpa.scaletargetref.kind")
+
+ // K8SHPAScaletargetrefNameKey is the attribute Key conforming to the
+ // "k8s.hpa.scaletargetref.name" semantic conventions. It represents the name of
+ // the target resource to scale for the HorizontalPodAutoscaler.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "my-deployment", "my-statefulset"
+ // Note: This maps to the `name` field in the `scaleTargetRef` of the HPA spec.
+ K8SHPAScaletargetrefNameKey = attribute.Key("k8s.hpa.scaletargetref.name")
+
+ // K8SHPAUIDKey is the attribute Key conforming to the "k8s.hpa.uid" semantic
+ // conventions. It represents the UID of the horizontal pod autoscaler.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "275ecb36-5aa8-4c2a-9c47-d8bb681b9aff"
+ K8SHPAUIDKey = attribute.Key("k8s.hpa.uid")
+
+ // K8SHugepageSizeKey is the attribute Key conforming to the "k8s.hugepage.size"
+ // semantic conventions. It represents the size (identifier) of the K8s huge
+ // page.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "2Mi"
+ K8SHugepageSizeKey = attribute.Key("k8s.hugepage.size")
+
+ // K8SJobNameKey is the attribute Key conforming to the "k8s.job.name" semantic
+ // conventions. It represents the name of the Job.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Beta
+ //
+ // Examples: "opentelemetry"
+ K8SJobNameKey = attribute.Key("k8s.job.name")
+
+ // K8SJobUIDKey is the attribute Key conforming to the "k8s.job.uid" semantic
+ // conventions. It represents the UID of the Job.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Beta
+ //
+ // Examples: "275ecb36-5aa8-4c2a-9c47-d8bb681b9aff"
+ K8SJobUIDKey = attribute.Key("k8s.job.uid")
+
+ // K8SNamespaceNameKey is the attribute Key conforming to the
+ // "k8s.namespace.name" semantic conventions. It represents the name of the
+ // namespace that the pod is running in.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Beta
+ //
+ // Examples: "default"
+ K8SNamespaceNameKey = attribute.Key("k8s.namespace.name")
+
+ // K8SNamespacePhaseKey is the attribute Key conforming to the
+ // "k8s.namespace.phase" semantic conventions. It represents the phase of the
+ // K8s namespace.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "active", "terminating"
+ // Note: This attribute aligns with the `phase` field of the
+ // [K8s NamespaceStatus]
+ //
+ // [K8s NamespaceStatus]: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#namespacestatus-v1-core
+ K8SNamespacePhaseKey = attribute.Key("k8s.namespace.phase")
+
+ // K8SNodeConditionStatusKey is the attribute Key conforming to the
+ // "k8s.node.condition.status" semantic conventions. It represents the status of
+ // the condition, one of True, False, Unknown.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "true", "false", "unknown"
+ // Note: This attribute aligns with the `status` field of the
+ // [NodeCondition]
+ //
+ // [NodeCondition]: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#nodecondition-v1-core
+ K8SNodeConditionStatusKey = attribute.Key("k8s.node.condition.status")
+
+ // K8SNodeConditionTypeKey is the attribute Key conforming to the
+ // "k8s.node.condition.type" semantic conventions. It represents the condition
+ // type of a K8s Node.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "Ready", "DiskPressure"
+ // Note: K8s Node conditions as described
+ // by [K8s documentation].
+ //
+ // This attribute aligns with the `type` field of the
+ // [NodeCondition]
+ //
+ // The set of possible values is not limited to those listed here. Managed
+ // Kubernetes environments,
+ // or custom controllers MAY introduce additional node condition types.
+ // When this occurs, the exact value as reported by the Kubernetes API SHOULD be
+ // used.
+ //
+ // [K8s documentation]: https://v1-32.docs.kubernetes.io/docs/reference/node/node-status/#condition
+ // [NodeCondition]: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#nodecondition-v1-core
+ K8SNodeConditionTypeKey = attribute.Key("k8s.node.condition.type")
+
+ // K8SNodeNameKey is the attribute Key conforming to the "k8s.node.name"
+ // semantic conventions. It represents the name of the Node.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Beta
+ //
+ // Examples: "node-1"
+ K8SNodeNameKey = attribute.Key("k8s.node.name")
+
+ // K8SNodeUIDKey is the attribute Key conforming to the "k8s.node.uid" semantic
+ // conventions. It represents the UID of the Node.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Beta
+ //
+ // Examples: "1eb3a0c6-0477-4080-a9cb-0cb7db65c6a2"
+ K8SNodeUIDKey = attribute.Key("k8s.node.uid")
+
+ // K8SPodHostnameKey is the attribute Key conforming to the "k8s.pod.hostname"
+ // semantic conventions. It represents the specifies the hostname of the Pod.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Beta
+ //
+ // Examples: "collector-gateway"
+ // Note: The K8s Pod spec has an optional hostname field, which can be used to
+ // specify a hostname.
+ // Refer to [K8s docs]
+ // for more information about this field.
+ //
+ // This attribute aligns with the `hostname` field of the
+ // [K8s PodSpec].
+ //
+ // [K8s docs]: https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/#pod-hostname-and-subdomain-field
+ // [K8s PodSpec]: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#podspec-v1-core
+ K8SPodHostnameKey = attribute.Key("k8s.pod.hostname")
+
+ // K8SPodIPKey is the attribute Key conforming to the "k8s.pod.ip" semantic
+ // conventions. It represents the IP address allocated to the Pod.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Beta
+ //
+ // Examples: "172.18.0.2"
+ // Note: This attribute aligns with the `podIP` field of the
+ // [K8s PodStatus].
+ //
+ // [K8s PodStatus]: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#podstatus-v1-core
+ K8SPodIPKey = attribute.Key("k8s.pod.ip")
+
+ // K8SPodNameKey is the attribute Key conforming to the "k8s.pod.name" semantic
+ // conventions. It represents the name of the Pod.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Beta
+ //
+ // Examples: "opentelemetry-pod-autoconf"
+ K8SPodNameKey = attribute.Key("k8s.pod.name")
+
+ // K8SPodStartTimeKey is the attribute Key conforming to the
+ // "k8s.pod.start_time" semantic conventions. It represents the start timestamp
+ // of the Pod.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Beta
+ //
+ // Examples: "2025-12-04T08:41:03Z"
+ // Note: Date and time at which the object was acknowledged by the Kubelet.
+ // This is before the Kubelet pulled the container image(s) for the pod.
+ //
+ // This attribute aligns with the `startTime` field of the
+ // [K8s PodStatus],
+ // in ISO 8601 (RFC 3339 compatible) format.
+ //
+ // [K8s PodStatus]: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#podstatus-v1-core
+ K8SPodStartTimeKey = attribute.Key("k8s.pod.start_time")
+
+ // K8SPodStatusPhaseKey is the attribute Key conforming to the
+ // "k8s.pod.status.phase" semantic conventions. It represents the phase for the
+ // pod. Corresponds to the `phase` field of the: [K8s PodStatus].
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "Pending", "Running"
+ //
+ // [K8s PodStatus]: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.33/#podstatus-v1-core
+ K8SPodStatusPhaseKey = attribute.Key("k8s.pod.status.phase")
+
+ // K8SPodStatusReasonKey is the attribute Key conforming to the
+ // "k8s.pod.status.reason" semantic conventions. It represents the reason for
+ // the pod state. Corresponds to the `reason` field of the: [K8s PodStatus].
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "Evicted", "NodeAffinity"
+ //
+ // [K8s PodStatus]: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.33/#podstatus-v1-core
+ K8SPodStatusReasonKey = attribute.Key("k8s.pod.status.reason")
+
+ // K8SPodUIDKey is the attribute Key conforming to the "k8s.pod.uid" semantic
+ // conventions. It represents the UID of the Pod.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Beta
+ //
+ // Examples: "275ecb36-5aa8-4c2a-9c47-d8bb681b9aff"
+ K8SPodUIDKey = attribute.Key("k8s.pod.uid")
+
+ // K8SReplicaSetNameKey is the attribute Key conforming to the
+ // "k8s.replicaset.name" semantic conventions. It represents the name of the
+ // ReplicaSet.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Beta
+ //
+ // Examples: "opentelemetry"
+ K8SReplicaSetNameKey = attribute.Key("k8s.replicaset.name")
+
+ // K8SReplicaSetUIDKey is the attribute Key conforming to the
+ // "k8s.replicaset.uid" semantic conventions. It represents the UID of the
+ // ReplicaSet.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Beta
+ //
+ // Examples: "275ecb36-5aa8-4c2a-9c47-d8bb681b9aff"
+ K8SReplicaSetUIDKey = attribute.Key("k8s.replicaset.uid")
+
+ // K8SReplicationControllerNameKey is the attribute Key conforming to the
+ // "k8s.replicationcontroller.name" semantic conventions. It represents the name
+ // of the replication controller.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "opentelemetry"
+ K8SReplicationControllerNameKey = attribute.Key("k8s.replicationcontroller.name")
+
+ // K8SReplicationControllerUIDKey is the attribute Key conforming to the
+ // "k8s.replicationcontroller.uid" semantic conventions. It represents the UID
+ // of the replication controller.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "275ecb36-5aa8-4c2a-9c47-d8bb681b9aff"
+ K8SReplicationControllerUIDKey = attribute.Key("k8s.replicationcontroller.uid")
+
+ // K8SResourceQuotaNameKey is the attribute Key conforming to the
+ // "k8s.resourcequota.name" semantic conventions. It represents the name of the
+ // resource quota.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "opentelemetry"
+ K8SResourceQuotaNameKey = attribute.Key("k8s.resourcequota.name")
+
+ // K8SResourceQuotaResourceNameKey is the attribute Key conforming to the
+ // "k8s.resourcequota.resource_name" semantic conventions. It represents the
+ // name of the K8s resource a resource quota defines.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "count/replicationcontrollers"
+ // Note: The value for this attribute can be either the full
+ // `count/[.]` string (e.g., count/deployments.apps,
+ // count/pods), or, for certain core Kubernetes resources, just the resource
+ // name (e.g., pods, services, configmaps). Both forms are supported by
+ // Kubernetes for object count quotas. See
+ // [Kubernetes Resource Quotas documentation] for more details.
+ //
+ // [Kubernetes Resource Quotas documentation]: https://kubernetes.io/docs/concepts/policy/resource-quotas/#quota-on-object-count
+ K8SResourceQuotaResourceNameKey = attribute.Key("k8s.resourcequota.resource_name")
+
+ // K8SResourceQuotaUIDKey is the attribute Key conforming to the
+ // "k8s.resourcequota.uid" semantic conventions. It represents the UID of the
+ // resource quota.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "275ecb36-5aa8-4c2a-9c47-d8bb681b9aff"
+ K8SResourceQuotaUIDKey = attribute.Key("k8s.resourcequota.uid")
+
+ // K8SServiceEndpointAddressTypeKey is the attribute Key conforming to the
+ // "k8s.service.endpoint.address_type" semantic conventions. It represents the
+ // address type of the service endpoint.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "IPv4", "IPv6"
+ // Note: The network address family or type of the endpoint.
+ // This attribute aligns with the `addressType` field of the
+ // [K8s EndpointSlice].
+ // It is used to differentiate metrics when a Service is backed by multiple
+ // address types
+ // (e.g., in dual-stack clusters).
+ //
+ // [K8s EndpointSlice]: https://kubernetes.io/docs/reference/kubernetes-api/service-resources/endpoint-slice-v1/
+ K8SServiceEndpointAddressTypeKey = attribute.Key("k8s.service.endpoint.address_type")
+
+ // K8SServiceEndpointConditionKey is the attribute Key conforming to the
+ // "k8s.service.endpoint.condition" semantic conventions. It represents the
+ // condition of the service endpoint.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "ready", "serving", "terminating"
+ // Note: The current operational condition of the service endpoint.
+ // An endpoint can have multiple conditions set at once (e.g., both `serving`
+ // and `terminating` during rollout).
+ // This attribute aligns with the condition fields in the [K8s EndpointSlice].
+ //
+ // [K8s EndpointSlice]: https://kubernetes.io/docs/reference/kubernetes-api/service-resources/endpoint-slice-v1/
+ K8SServiceEndpointConditionKey = attribute.Key("k8s.service.endpoint.condition")
+
+ // K8SServiceEndpointZoneKey is the attribute Key conforming to the
+ // "k8s.service.endpoint.zone" semantic conventions. It represents the zone of
+ // the service endpoint.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "us-east-1a", "us-west-2b", "zone-a", ""
+ // Note: The zone where the endpoint is located, typically corresponding to a
+ // failure domain.
+ // This attribute aligns with the `zone` field of endpoints in the
+ // [K8s EndpointSlice].
+ // It enables zone-aware monitoring of service endpoint distribution and
+ // supports
+ // features like [Topology Aware Routing].
+ //
+ // If the zone is not populated (e.g., nodes without the
+ // `topology.kubernetes.io/zone` label),
+ // the attribute value will be an empty string.
+ //
+ // [K8s EndpointSlice]: https://kubernetes.io/docs/reference/kubernetes-api/service-resources/endpoint-slice-v1/
+ // [Topology Aware Routing]: https://kubernetes.io/docs/concepts/services-networking/topology-aware-routing/
+ K8SServiceEndpointZoneKey = attribute.Key("k8s.service.endpoint.zone")
+
+ // K8SServiceNameKey is the attribute Key conforming to the "k8s.service.name"
+ // semantic conventions. It represents the name of the Service.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "my-service"
+ K8SServiceNameKey = attribute.Key("k8s.service.name")
+
+ // K8SServicePublishNotReadyAddressesKey is the attribute Key conforming to the
+ // "k8s.service.publish_not_ready_addresses" semantic conventions. It represents
+ // the whether the Service publishes not-ready endpoints.
+ //
+ // Type: boolean
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: true, false
+ // Note: Whether the Service is configured to publish endpoints before the pods
+ // are ready.
+ // This attribute is typically used to indicate that a Service (such as a
+ // headless
+ // Service for a StatefulSet) allows peer discovery before pods pass their
+ // readiness probes.
+ // It aligns with the `publishNotReadyAddresses` field of the
+ // [K8s ServiceSpec].
+ //
+ // [K8s ServiceSpec]: https://kubernetes.io/docs/reference/kubernetes-api/service-resources/service-v1/#ServiceSpec
+ K8SServicePublishNotReadyAddressesKey = attribute.Key("k8s.service.publish_not_ready_addresses")
+
+ // K8SServiceTrafficDistributionKey is the attribute Key conforming to the
+ // "k8s.service.traffic_distribution" semantic conventions. It represents the
+ // traffic distribution policy for the Service.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "PreferSameZone", "PreferSameNode"
+ // Note: Specifies how traffic is distributed to endpoints for this Service.
+ // This attribute aligns with the `trafficDistribution` field of the
+ // [K8s ServiceSpec].
+ // Known values include `PreferSameZone` (prefer endpoints in the same zone as
+ // the client) and
+ // `PreferSameNode` (prefer endpoints on the same node, fallback to same zone,
+ // then cluster-wide).
+ // If this field is not set on the Service, the attribute SHOULD NOT be emitted.
+ // When not set, Kubernetes distributes traffic evenly across all endpoints
+ // cluster-wide.
+ //
+ // [K8s ServiceSpec]: https://kubernetes.io/docs/reference/networking/virtual-ips/#traffic-distribution
+ K8SServiceTrafficDistributionKey = attribute.Key("k8s.service.traffic_distribution")
+
+ // K8SServiceTypeKey is the attribute Key conforming to the "k8s.service.type"
+ // semantic conventions. It represents the type of the Kubernetes Service.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "ClusterIP", "NodePort", "LoadBalancer"
+ // Note: This attribute aligns with the `type` field of the
+ // [K8s ServiceSpec].
+ //
+ // [K8s ServiceSpec]: https://kubernetes.io/docs/reference/kubernetes-api/service-resources/service-v1/#ServiceSpec
+ K8SServiceTypeKey = attribute.Key("k8s.service.type")
+
+ // K8SServiceUIDKey is the attribute Key conforming to the "k8s.service.uid"
+ // semantic conventions. It represents the UID of the Service.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "275ecb36-5aa8-4c2a-9c47-d8bb681b9aff"
+ K8SServiceUIDKey = attribute.Key("k8s.service.uid")
+
+ // K8SStatefulSetNameKey is the attribute Key conforming to the
+ // "k8s.statefulset.name" semantic conventions. It represents the name of the
+ // StatefulSet.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Beta
+ //
+ // Examples: "opentelemetry"
+ K8SStatefulSetNameKey = attribute.Key("k8s.statefulset.name")
+
+ // K8SStatefulSetUIDKey is the attribute Key conforming to the
+ // "k8s.statefulset.uid" semantic conventions. It represents the UID of the
+ // StatefulSet.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Beta
+ //
+ // Examples: "275ecb36-5aa8-4c2a-9c47-d8bb681b9aff"
+ K8SStatefulSetUIDKey = attribute.Key("k8s.statefulset.uid")
+
+ // K8SStorageclassNameKey is the attribute Key conforming to the
+ // "k8s.storageclass.name" semantic conventions. It represents the name of K8s
+ // [StorageClass] object.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "gold.storageclass.storage.k8s.io"
+ //
+ // [StorageClass]: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#storageclass-v1-storage-k8s-io
+ K8SStorageclassNameKey = attribute.Key("k8s.storageclass.name")
+
+ // K8SVolumeNameKey is the attribute Key conforming to the "k8s.volume.name"
+ // semantic conventions. It represents the name of the K8s volume.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "volume0"
+ K8SVolumeNameKey = attribute.Key("k8s.volume.name")
+
+ // K8SVolumeTypeKey is the attribute Key conforming to the "k8s.volume.type"
+ // semantic conventions. It represents the type of the K8s volume.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "emptyDir", "persistentVolumeClaim"
+ K8SVolumeTypeKey = attribute.Key("k8s.volume.type")
+)
+
+// K8SClusterName returns an attribute KeyValue conforming to the
+// "k8s.cluster.name" semantic conventions. It represents the name of the
+// cluster.
+func K8SClusterName(val string) attribute.KeyValue {
+ return K8SClusterNameKey.String(val)
+}
+
+// K8SClusterUID returns an attribute KeyValue conforming to the
+// "k8s.cluster.uid" semantic conventions. It represents a pseudo-ID for the
+// cluster, set to the UID of the `kube-system` namespace.
+func K8SClusterUID(val string) attribute.KeyValue {
+ return K8SClusterUIDKey.String(val)
+}
+
+// K8SContainerName returns an attribute KeyValue conforming to the
+// "k8s.container.name" semantic conventions. It represents the name of the
+// Container from Pod specification, must be unique within a Pod. Container
+// runtime usually uses different globally unique name (`container.name`).
+func K8SContainerName(val string) attribute.KeyValue {
+ return K8SContainerNameKey.String(val)
+}
+
+// K8SContainerRestartCount returns an attribute KeyValue conforming to the
+// "k8s.container.restart_count" semantic conventions. It represents the number
+// of times the container was restarted. This attribute can be used to identify a
+// particular container (running or stopped) within a container spec.
+func K8SContainerRestartCount(val int) attribute.KeyValue {
+ return K8SContainerRestartCountKey.Int(val)
+}
+
+// K8SContainerStatusLastTerminatedReason returns an attribute KeyValue
+// conforming to the "k8s.container.status.last_terminated_reason" semantic
+// conventions. It represents the last terminated reason of the Container.
+func K8SContainerStatusLastTerminatedReason(val string) attribute.KeyValue {
+ return K8SContainerStatusLastTerminatedReasonKey.String(val)
+}
+
+// K8SCronJobAnnotation returns an attribute KeyValue conforming to the
+// "k8s.cronjob.annotation" semantic conventions. It represents the cronjob
+// annotation placed on the CronJob, the `` being the annotation name, the
+// value being the annotation value.
+func K8SCronJobAnnotation(key string, val string) attribute.KeyValue {
+ return attribute.String("k8s.cronjob.annotation."+key, val)
+}
+
+// K8SCronJobLabel returns an attribute KeyValue conforming to the
+// "k8s.cronjob.label" semantic conventions. It represents the label placed on
+// the CronJob, the `` being the label name, the value being the label
+// value.
+func K8SCronJobLabel(key string, val string) attribute.KeyValue {
+ return attribute.String("k8s.cronjob.label."+key, val)
+}
+
+// K8SCronJobName returns an attribute KeyValue conforming to the
+// "k8s.cronjob.name" semantic conventions. It represents the name of the
+// CronJob.
+func K8SCronJobName(val string) attribute.KeyValue {
+ return K8SCronJobNameKey.String(val)
+}
+
+// K8SCronJobUID returns an attribute KeyValue conforming to the
+// "k8s.cronjob.uid" semantic conventions. It represents the UID of the CronJob.
+func K8SCronJobUID(val string) attribute.KeyValue {
+ return K8SCronJobUIDKey.String(val)
+}
+
+// K8SDaemonSetAnnotation returns an attribute KeyValue conforming to the
+// "k8s.daemonset.annotation" semantic conventions. It represents the annotation
+// placed on the DaemonSet, the `` being the annotation name, the value
+// being the annotation value, even if the value is empty.
+func K8SDaemonSetAnnotation(key string, val string) attribute.KeyValue {
+ return attribute.String("k8s.daemonset.annotation."+key, val)
+}
+
+// K8SDaemonSetLabel returns an attribute KeyValue conforming to the
+// "k8s.daemonset.label" semantic conventions. It represents the label placed on
+// the DaemonSet, the `` being the label name, the value being the label
+// value, even if the value is empty.
+func K8SDaemonSetLabel(key string, val string) attribute.KeyValue {
+ return attribute.String("k8s.daemonset.label."+key, val)
+}
+
+// K8SDaemonSetName returns an attribute KeyValue conforming to the
+// "k8s.daemonset.name" semantic conventions. It represents the name of the
+// DaemonSet.
+func K8SDaemonSetName(val string) attribute.KeyValue {
+ return K8SDaemonSetNameKey.String(val)
+}
+
+// K8SDaemonSetUID returns an attribute KeyValue conforming to the
+// "k8s.daemonset.uid" semantic conventions. It represents the UID of the
+// DaemonSet.
+func K8SDaemonSetUID(val string) attribute.KeyValue {
+ return K8SDaemonSetUIDKey.String(val)
+}
+
+// K8SDeploymentAnnotation returns an attribute KeyValue conforming to the
+// "k8s.deployment.annotation" semantic conventions. It represents the annotation
+// placed on the Deployment, the `` being the annotation name, the value
+// being the annotation value, even if the value is empty.
+func K8SDeploymentAnnotation(key string, val string) attribute.KeyValue {
+ return attribute.String("k8s.deployment.annotation."+key, val)
+}
+
+// K8SDeploymentLabel returns an attribute KeyValue conforming to the
+// "k8s.deployment.label" semantic conventions. It represents the label placed on
+// the Deployment, the `` being the label name, the value being the label
+// value, even if the value is empty.
+func K8SDeploymentLabel(key string, val string) attribute.KeyValue {
+ return attribute.String("k8s.deployment.label."+key, val)
+}
+
+// K8SDeploymentName returns an attribute KeyValue conforming to the
+// "k8s.deployment.name" semantic conventions. It represents the name of the
+// Deployment.
+func K8SDeploymentName(val string) attribute.KeyValue {
+ return K8SDeploymentNameKey.String(val)
+}
+
+// K8SDeploymentUID returns an attribute KeyValue conforming to the
+// "k8s.deployment.uid" semantic conventions. It represents the UID of the
+// Deployment.
+func K8SDeploymentUID(val string) attribute.KeyValue {
+ return K8SDeploymentUIDKey.String(val)
+}
+
+// K8SHPAMetricType returns an attribute KeyValue conforming to the
+// "k8s.hpa.metric.type" semantic conventions. It represents the type of metric
+// source for the horizontal pod autoscaler.
+func K8SHPAMetricType(val string) attribute.KeyValue {
+ return K8SHPAMetricTypeKey.String(val)
+}
+
+// K8SHPAName returns an attribute KeyValue conforming to the "k8s.hpa.name"
+// semantic conventions. It represents the name of the horizontal pod autoscaler.
+func K8SHPAName(val string) attribute.KeyValue {
+ return K8SHPANameKey.String(val)
+}
+
+// K8SHPAScaletargetrefAPIVersion returns an attribute KeyValue conforming to the
+// "k8s.hpa.scaletargetref.api_version" semantic conventions. It represents the
+// API version of the target resource to scale for the HorizontalPodAutoscaler.
+func K8SHPAScaletargetrefAPIVersion(val string) attribute.KeyValue {
+ return K8SHPAScaletargetrefAPIVersionKey.String(val)
+}
+
+// K8SHPAScaletargetrefKind returns an attribute KeyValue conforming to the
+// "k8s.hpa.scaletargetref.kind" semantic conventions. It represents the kind of
+// the target resource to scale for the HorizontalPodAutoscaler.
+func K8SHPAScaletargetrefKind(val string) attribute.KeyValue {
+ return K8SHPAScaletargetrefKindKey.String(val)
+}
+
+// K8SHPAScaletargetrefName returns an attribute KeyValue conforming to the
+// "k8s.hpa.scaletargetref.name" semantic conventions. It represents the name of
+// the target resource to scale for the HorizontalPodAutoscaler.
+func K8SHPAScaletargetrefName(val string) attribute.KeyValue {
+ return K8SHPAScaletargetrefNameKey.String(val)
+}
+
+// K8SHPAUID returns an attribute KeyValue conforming to the "k8s.hpa.uid"
+// semantic conventions. It represents the UID of the horizontal pod autoscaler.
+func K8SHPAUID(val string) attribute.KeyValue {
+ return K8SHPAUIDKey.String(val)
+}
+
+// K8SHugepageSize returns an attribute KeyValue conforming to the
+// "k8s.hugepage.size" semantic conventions. It represents the size (identifier)
+// of the K8s huge page.
+func K8SHugepageSize(val string) attribute.KeyValue {
+ return K8SHugepageSizeKey.String(val)
+}
+
+// K8SJobAnnotation returns an attribute KeyValue conforming to the
+// "k8s.job.annotation" semantic conventions. It represents the annotation placed
+// on the Job, the `` being the annotation name, the value being the
+// annotation value, even if the value is empty.
+func K8SJobAnnotation(key string, val string) attribute.KeyValue {
+ return attribute.String("k8s.job.annotation."+key, val)
+}
+
+// K8SJobLabel returns an attribute KeyValue conforming to the "k8s.job.label"
+// semantic conventions. It represents the label placed on the Job, the ``
+// being the label name, the value being the label value, even if the value is
+// empty.
+func K8SJobLabel(key string, val string) attribute.KeyValue {
+ return attribute.String("k8s.job.label."+key, val)
+}
+
+// K8SJobName returns an attribute KeyValue conforming to the "k8s.job.name"
+// semantic conventions. It represents the name of the Job.
+func K8SJobName(val string) attribute.KeyValue {
+ return K8SJobNameKey.String(val)
+}
+
+// K8SJobUID returns an attribute KeyValue conforming to the "k8s.job.uid"
+// semantic conventions. It represents the UID of the Job.
+func K8SJobUID(val string) attribute.KeyValue {
+ return K8SJobUIDKey.String(val)
+}
+
+// K8SNamespaceAnnotation returns an attribute KeyValue conforming to the
+// "k8s.namespace.annotation" semantic conventions. It represents the annotation
+// placed on the Namespace, the `` being the annotation name, the value
+// being the annotation value, even if the value is empty.
+func K8SNamespaceAnnotation(key string, val string) attribute.KeyValue {
+ return attribute.String("k8s.namespace.annotation."+key, val)
+}
+
+// K8SNamespaceLabel returns an attribute KeyValue conforming to the
+// "k8s.namespace.label" semantic conventions. It represents the label placed on
+// the Namespace, the `` being the label name, the value being the label
+// value, even if the value is empty.
+func K8SNamespaceLabel(key string, val string) attribute.KeyValue {
+ return attribute.String("k8s.namespace.label."+key, val)
+}
+
+// K8SNamespaceName returns an attribute KeyValue conforming to the
+// "k8s.namespace.name" semantic conventions. It represents the name of the
+// namespace that the pod is running in.
+func K8SNamespaceName(val string) attribute.KeyValue {
+ return K8SNamespaceNameKey.String(val)
+}
+
+// K8SNodeAnnotation returns an attribute KeyValue conforming to the
+// "k8s.node.annotation" semantic conventions. It represents the annotation
+// placed on the Node, the `` being the annotation name, the value being the
+// annotation value, even if the value is empty.
+func K8SNodeAnnotation(key string, val string) attribute.KeyValue {
+ return attribute.String("k8s.node.annotation."+key, val)
+}
+
+// K8SNodeLabel returns an attribute KeyValue conforming to the "k8s.node.label"
+// semantic conventions. It represents the label placed on the Node, the ``
+// being the label name, the value being the label value, even if the value is
+// empty.
+func K8SNodeLabel(key string, val string) attribute.KeyValue {
+ return attribute.String("k8s.node.label."+key, val)
+}
+
+// K8SNodeName returns an attribute KeyValue conforming to the "k8s.node.name"
+// semantic conventions. It represents the name of the Node.
+func K8SNodeName(val string) attribute.KeyValue {
+ return K8SNodeNameKey.String(val)
+}
+
+// K8SNodeUID returns an attribute KeyValue conforming to the "k8s.node.uid"
+// semantic conventions. It represents the UID of the Node.
+func K8SNodeUID(val string) attribute.KeyValue {
+ return K8SNodeUIDKey.String(val)
+}
+
+// K8SPodAnnotation returns an attribute KeyValue conforming to the
+// "k8s.pod.annotation" semantic conventions. It represents the annotation placed
+// on the Pod, the `` being the annotation name, the value being the
+// annotation value.
+func K8SPodAnnotation(key string, val string) attribute.KeyValue {
+ return attribute.String("k8s.pod.annotation."+key, val)
+}
+
+// K8SPodHostname returns an attribute KeyValue conforming to the
+// "k8s.pod.hostname" semantic conventions. It represents the specifies the
+// hostname of the Pod.
+func K8SPodHostname(val string) attribute.KeyValue {
+ return K8SPodHostnameKey.String(val)
+}
+
+// K8SPodIP returns an attribute KeyValue conforming to the "k8s.pod.ip" semantic
+// conventions. It represents the IP address allocated to the Pod.
+func K8SPodIP(val string) attribute.KeyValue {
+ return K8SPodIPKey.String(val)
+}
+
+// K8SPodLabel returns an attribute KeyValue conforming to the "k8s.pod.label"
+// semantic conventions. It represents the label placed on the Pod, the ``
+// being the label name, the value being the label value.
+func K8SPodLabel(key string, val string) attribute.KeyValue {
+ return attribute.String("k8s.pod.label."+key, val)
+}
+
+// K8SPodName returns an attribute KeyValue conforming to the "k8s.pod.name"
+// semantic conventions. It represents the name of the Pod.
+func K8SPodName(val string) attribute.KeyValue {
+ return K8SPodNameKey.String(val)
+}
+
+// K8SPodStartTime returns an attribute KeyValue conforming to the
+// "k8s.pod.start_time" semantic conventions. It represents the start timestamp
+// of the Pod.
+func K8SPodStartTime(val string) attribute.KeyValue {
+ return K8SPodStartTimeKey.String(val)
+}
+
+// K8SPodUID returns an attribute KeyValue conforming to the "k8s.pod.uid"
+// semantic conventions. It represents the UID of the Pod.
+func K8SPodUID(val string) attribute.KeyValue {
+ return K8SPodUIDKey.String(val)
+}
+
+// K8SReplicaSetAnnotation returns an attribute KeyValue conforming to the
+// "k8s.replicaset.annotation" semantic conventions. It represents the annotation
+// placed on the ReplicaSet, the `` being the annotation name, the value
+// being the annotation value, even if the value is empty.
+func K8SReplicaSetAnnotation(key string, val string) attribute.KeyValue {
+ return attribute.String("k8s.replicaset.annotation."+key, val)
+}
+
+// K8SReplicaSetLabel returns an attribute KeyValue conforming to the
+// "k8s.replicaset.label" semantic conventions. It represents the label placed on
+// the ReplicaSet, the `` being the label name, the value being the label
+// value, even if the value is empty.
+func K8SReplicaSetLabel(key string, val string) attribute.KeyValue {
+ return attribute.String("k8s.replicaset.label."+key, val)
+}
+
+// K8SReplicaSetName returns an attribute KeyValue conforming to the
+// "k8s.replicaset.name" semantic conventions. It represents the name of the
+// ReplicaSet.
+func K8SReplicaSetName(val string) attribute.KeyValue {
+ return K8SReplicaSetNameKey.String(val)
+}
+
+// K8SReplicaSetUID returns an attribute KeyValue conforming to the
+// "k8s.replicaset.uid" semantic conventions. It represents the UID of the
+// ReplicaSet.
+func K8SReplicaSetUID(val string) attribute.KeyValue {
+ return K8SReplicaSetUIDKey.String(val)
+}
+
+// K8SReplicationControllerName returns an attribute KeyValue conforming to the
+// "k8s.replicationcontroller.name" semantic conventions. It represents the name
+// of the replication controller.
+func K8SReplicationControllerName(val string) attribute.KeyValue {
+ return K8SReplicationControllerNameKey.String(val)
+}
+
+// K8SReplicationControllerUID returns an attribute KeyValue conforming to the
+// "k8s.replicationcontroller.uid" semantic conventions. It represents the UID of
+// the replication controller.
+func K8SReplicationControllerUID(val string) attribute.KeyValue {
+ return K8SReplicationControllerUIDKey.String(val)
+}
+
+// K8SResourceQuotaName returns an attribute KeyValue conforming to the
+// "k8s.resourcequota.name" semantic conventions. It represents the name of the
+// resource quota.
+func K8SResourceQuotaName(val string) attribute.KeyValue {
+ return K8SResourceQuotaNameKey.String(val)
+}
+
+// K8SResourceQuotaResourceName returns an attribute KeyValue conforming to the
+// "k8s.resourcequota.resource_name" semantic conventions. It represents the name
+// of the K8s resource a resource quota defines.
+func K8SResourceQuotaResourceName(val string) attribute.KeyValue {
+ return K8SResourceQuotaResourceNameKey.String(val)
+}
+
+// K8SResourceQuotaUID returns an attribute KeyValue conforming to the
+// "k8s.resourcequota.uid" semantic conventions. It represents the UID of the
+// resource quota.
+func K8SResourceQuotaUID(val string) attribute.KeyValue {
+ return K8SResourceQuotaUIDKey.String(val)
+}
+
+// K8SServiceAnnotation returns an attribute KeyValue conforming to the
+// "k8s.service.annotation" semantic conventions. It represents the annotation
+// placed on the Service, the `` being the annotation name, the value being
+// the annotation value, even if the value is empty.
+func K8SServiceAnnotation(key string, val string) attribute.KeyValue {
+ return attribute.String("k8s.service.annotation."+key, val)
+}
+
+// K8SServiceEndpointZone returns an attribute KeyValue conforming to the
+// "k8s.service.endpoint.zone" semantic conventions. It represents the zone of
+// the service endpoint.
+func K8SServiceEndpointZone(val string) attribute.KeyValue {
+ return K8SServiceEndpointZoneKey.String(val)
+}
+
+// K8SServiceLabel returns an attribute KeyValue conforming to the
+// "k8s.service.label" semantic conventions. It represents the label placed on
+// the Service, the `` being the label name, the value being the label
+// value, even if the value is empty.
+func K8SServiceLabel(key string, val string) attribute.KeyValue {
+ return attribute.String("k8s.service.label."+key, val)
+}
+
+// K8SServiceName returns an attribute KeyValue conforming to the
+// "k8s.service.name" semantic conventions. It represents the name of the
+// Service.
+func K8SServiceName(val string) attribute.KeyValue {
+ return K8SServiceNameKey.String(val)
+}
+
+// K8SServicePublishNotReadyAddresses returns an attribute KeyValue conforming to
+// the "k8s.service.publish_not_ready_addresses" semantic conventions. It
+// represents the whether the Service publishes not-ready endpoints.
+func K8SServicePublishNotReadyAddresses(val bool) attribute.KeyValue {
+ return K8SServicePublishNotReadyAddressesKey.Bool(val)
+}
+
+// K8SServiceSelector returns an attribute KeyValue conforming to the
+// "k8s.service.selector" semantic conventions. It represents the selector
+// key-value pair placed on the Service, the `` being the selector key, the
+// value being the selector value.
+func K8SServiceSelector(key string, val string) attribute.KeyValue {
+ return attribute.String("k8s.service.selector."+key, val)
+}
+
+// K8SServiceTrafficDistribution returns an attribute KeyValue conforming to the
+// "k8s.service.traffic_distribution" semantic conventions. It represents the
+// traffic distribution policy for the Service.
+func K8SServiceTrafficDistribution(val string) attribute.KeyValue {
+ return K8SServiceTrafficDistributionKey.String(val)
+}
+
+// K8SServiceUID returns an attribute KeyValue conforming to the
+// "k8s.service.uid" semantic conventions. It represents the UID of the Service.
+func K8SServiceUID(val string) attribute.KeyValue {
+ return K8SServiceUIDKey.String(val)
+}
+
+// K8SStatefulSetAnnotation returns an attribute KeyValue conforming to the
+// "k8s.statefulset.annotation" semantic conventions. It represents the
+// annotation placed on the StatefulSet, the `` being the annotation name,
+// the value being the annotation value, even if the value is empty.
+func K8SStatefulSetAnnotation(key string, val string) attribute.KeyValue {
+ return attribute.String("k8s.statefulset.annotation."+key, val)
+}
+
+// K8SStatefulSetLabel returns an attribute KeyValue conforming to the
+// "k8s.statefulset.label" semantic conventions. It represents the label placed
+// on the StatefulSet, the `` being the label name, the value being the
+// label value, even if the value is empty.
+func K8SStatefulSetLabel(key string, val string) attribute.KeyValue {
+ return attribute.String("k8s.statefulset.label."+key, val)
+}
+
+// K8SStatefulSetName returns an attribute KeyValue conforming to the
+// "k8s.statefulset.name" semantic conventions. It represents the name of the
+// StatefulSet.
+func K8SStatefulSetName(val string) attribute.KeyValue {
+ return K8SStatefulSetNameKey.String(val)
+}
+
+// K8SStatefulSetUID returns an attribute KeyValue conforming to the
+// "k8s.statefulset.uid" semantic conventions. It represents the UID of the
+// StatefulSet.
+func K8SStatefulSetUID(val string) attribute.KeyValue {
+ return K8SStatefulSetUIDKey.String(val)
+}
+
+// K8SStorageclassName returns an attribute KeyValue conforming to the
+// "k8s.storageclass.name" semantic conventions. It represents the name of K8s
+// [StorageClass] object.
+//
+// [StorageClass]: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#storageclass-v1-storage-k8s-io
+func K8SStorageclassName(val string) attribute.KeyValue {
+ return K8SStorageclassNameKey.String(val)
+}
+
+// K8SVolumeName returns an attribute KeyValue conforming to the
+// "k8s.volume.name" semantic conventions. It represents the name of the K8s
+// volume.
+func K8SVolumeName(val string) attribute.KeyValue {
+ return K8SVolumeNameKey.String(val)
+}
+
+// Enum values for k8s.container.status.reason
+var (
+ // The container is being created.
+ // Stability: development
+ K8SContainerStatusReasonContainerCreating = K8SContainerStatusReasonKey.String("ContainerCreating")
+ // The container is in a crash loop back off state.
+ // Stability: development
+ K8SContainerStatusReasonCrashLoopBackOff = K8SContainerStatusReasonKey.String("CrashLoopBackOff")
+ // There was an error creating the container configuration.
+ // Stability: development
+ K8SContainerStatusReasonCreateContainerConfigError = K8SContainerStatusReasonKey.String("CreateContainerConfigError")
+ // There was an error pulling the container image.
+ // Stability: development
+ K8SContainerStatusReasonErrImagePull = K8SContainerStatusReasonKey.String("ErrImagePull")
+ // The container image pull is in back off state.
+ // Stability: development
+ K8SContainerStatusReasonImagePullBackOff = K8SContainerStatusReasonKey.String("ImagePullBackOff")
+ // The container was killed due to out of memory.
+ // Stability: development
+ K8SContainerStatusReasonOomKilled = K8SContainerStatusReasonKey.String("OOMKilled")
+ // The container has completed execution.
+ // Stability: development
+ K8SContainerStatusReasonCompleted = K8SContainerStatusReasonKey.String("Completed")
+ // There was an error with the container.
+ // Stability: development
+ K8SContainerStatusReasonError = K8SContainerStatusReasonKey.String("Error")
+ // The container cannot run.
+ // Stability: development
+ K8SContainerStatusReasonContainerCannotRun = K8SContainerStatusReasonKey.String("ContainerCannotRun")
+)
+
+// Enum values for k8s.container.status.state
+var (
+ // The container has terminated.
+ // Stability: development
+ K8SContainerStatusStateTerminated = K8SContainerStatusStateKey.String("terminated")
+ // The container is running.
+ // Stability: development
+ K8SContainerStatusStateRunning = K8SContainerStatusStateKey.String("running")
+ // The container is waiting.
+ // Stability: development
+ K8SContainerStatusStateWaiting = K8SContainerStatusStateKey.String("waiting")
+)
+
+// Enum values for k8s.namespace.phase
+var (
+ // Active namespace phase as described by [K8s API]
+ // Stability: development
+ //
+ // [K8s API]: https://pkg.go.dev/k8s.io/api@v0.31.3/core/v1#NamespacePhase
+ K8SNamespacePhaseActive = K8SNamespacePhaseKey.String("active")
+ // Terminating namespace phase as described by [K8s API]
+ // Stability: development
+ //
+ // [K8s API]: https://pkg.go.dev/k8s.io/api@v0.31.3/core/v1#NamespacePhase
+ K8SNamespacePhaseTerminating = K8SNamespacePhaseKey.String("terminating")
+)
+
+// Enum values for k8s.node.condition.status
+var (
+ // condition_true
+ // Stability: development
+ K8SNodeConditionStatusConditionTrue = K8SNodeConditionStatusKey.String("true")
+ // condition_false
+ // Stability: development
+ K8SNodeConditionStatusConditionFalse = K8SNodeConditionStatusKey.String("false")
+ // condition_unknown
+ // Stability: development
+ K8SNodeConditionStatusConditionUnknown = K8SNodeConditionStatusKey.String("unknown")
+)
+
+// Enum values for k8s.node.condition.type
+var (
+ // The node is healthy and ready to accept pods
+ // Stability: development
+ K8SNodeConditionTypeReady = K8SNodeConditionTypeKey.String("Ready")
+ // Pressure exists on the disk size—that is, if the disk capacity is low
+ // Stability: development
+ K8SNodeConditionTypeDiskPressure = K8SNodeConditionTypeKey.String("DiskPressure")
+ // Pressure exists on the node memory—that is, if the node memory is low
+ // Stability: development
+ K8SNodeConditionTypeMemoryPressure = K8SNodeConditionTypeKey.String("MemoryPressure")
+ // Pressure exists on the processes—that is, if there are too many processes
+ // on the node
+ // Stability: development
+ K8SNodeConditionTypePIDPressure = K8SNodeConditionTypeKey.String("PIDPressure")
+ // The network for the node is not correctly configured
+ // Stability: development
+ K8SNodeConditionTypeNetworkUnavailable = K8SNodeConditionTypeKey.String("NetworkUnavailable")
+)
+
+// Enum values for k8s.pod.status.phase
+var (
+ // The pod has been accepted by the system, but one or more of the containers
+ // has not been started. This includes time before being bound to a node, as
+ // well as time spent pulling images onto the host.
+ //
+ // Stability: development
+ K8SPodStatusPhasePending = K8SPodStatusPhaseKey.String("Pending")
+ // The pod has been bound to a node and all of the containers have been started.
+ // At least one container is still running or is in the process of being
+ // restarted.
+ //
+ // Stability: development
+ K8SPodStatusPhaseRunning = K8SPodStatusPhaseKey.String("Running")
+ // All containers in the pod have voluntarily terminated with a container exit
+ // code of 0, and the system is not going to restart any of these containers.
+ //
+ // Stability: development
+ K8SPodStatusPhaseSucceeded = K8SPodStatusPhaseKey.String("Succeeded")
+ // All containers in the pod have terminated, and at least one container has
+ // terminated in a failure (exited with a non-zero exit code or was stopped by
+ // the system).
+ //
+ // Stability: development
+ K8SPodStatusPhaseFailed = K8SPodStatusPhaseKey.String("Failed")
+ // For some reason the state of the pod could not be obtained, typically due to
+ // an error in communicating with the host of the pod.
+ //
+ // Stability: development
+ K8SPodStatusPhaseUnknown = K8SPodStatusPhaseKey.String("Unknown")
+)
+
+// Enum values for k8s.pod.status.reason
+var (
+ // The pod is evicted.
+ // Stability: development
+ K8SPodStatusReasonEvicted = K8SPodStatusReasonKey.String("Evicted")
+ // The pod is in a status because of its node affinity
+ // Stability: development
+ K8SPodStatusReasonNodeAffinity = K8SPodStatusReasonKey.String("NodeAffinity")
+ // The reason on a pod when its state cannot be confirmed as kubelet is
+ // unresponsive on the node it is (was) running.
+ //
+ // Stability: development
+ K8SPodStatusReasonNodeLost = K8SPodStatusReasonKey.String("NodeLost")
+ // The node is shutdown
+ // Stability: development
+ K8SPodStatusReasonShutdown = K8SPodStatusReasonKey.String("Shutdown")
+ // The pod was rejected admission to the node because of an error during
+ // admission that could not be categorized.
+ //
+ // Stability: development
+ K8SPodStatusReasonUnexpectedAdmissionError = K8SPodStatusReasonKey.String("UnexpectedAdmissionError")
+)
+
+// Enum values for k8s.service.endpoint.address_type
+var (
+ // IPv4 address type
+ // Stability: development
+ K8SServiceEndpointAddressTypeIPv4 = K8SServiceEndpointAddressTypeKey.String("IPv4")
+ // IPv6 address type
+ // Stability: development
+ K8SServiceEndpointAddressTypeIPv6 = K8SServiceEndpointAddressTypeKey.String("IPv6")
+ // FQDN address type
+ // Stability: development
+ K8SServiceEndpointAddressTypeFqdn = K8SServiceEndpointAddressTypeKey.String("FQDN")
+)
+
+// Enum values for k8s.service.endpoint.condition
+var (
+ // The endpoint is ready to receive new connections.
+ // Stability: development
+ K8SServiceEndpointConditionReady = K8SServiceEndpointConditionKey.String("ready")
+ // The endpoint is currently handling traffic.
+ // Stability: development
+ K8SServiceEndpointConditionServing = K8SServiceEndpointConditionKey.String("serving")
+ // The endpoint is in the process of shutting down.
+ // Stability: development
+ K8SServiceEndpointConditionTerminating = K8SServiceEndpointConditionKey.String("terminating")
+)
+
+// Enum values for k8s.service.type
+var (
+ // ClusterIP service type
+ // Stability: development
+ K8SServiceTypeClusterIP = K8SServiceTypeKey.String("ClusterIP")
+ // NodePort service type
+ // Stability: development
+ K8SServiceTypeNodePort = K8SServiceTypeKey.String("NodePort")
+ // LoadBalancer service type
+ // Stability: development
+ K8SServiceTypeLoadBalancer = K8SServiceTypeKey.String("LoadBalancer")
+ // ExternalName service type
+ // Stability: development
+ K8SServiceTypeExternalName = K8SServiceTypeKey.String("ExternalName")
+)
+
+// Enum values for k8s.volume.type
+var (
+ // A [persistentVolumeClaim] volume
+ // Stability: development
+ //
+ // [persistentVolumeClaim]: https://v1-30.docs.kubernetes.io/docs/concepts/storage/volumes/#persistentvolumeclaim
+ K8SVolumeTypePersistentVolumeClaim = K8SVolumeTypeKey.String("persistentVolumeClaim")
+ // A [configMap] volume
+ // Stability: development
+ //
+ // [configMap]: https://v1-30.docs.kubernetes.io/docs/concepts/storage/volumes/#configmap
+ K8SVolumeTypeConfigMap = K8SVolumeTypeKey.String("configMap")
+ // A [downwardAPI] volume
+ // Stability: development
+ //
+ // [downwardAPI]: https://v1-30.docs.kubernetes.io/docs/concepts/storage/volumes/#downwardapi
+ K8SVolumeTypeDownwardAPI = K8SVolumeTypeKey.String("downwardAPI")
+ // An [emptyDir] volume
+ // Stability: development
+ //
+ // [emptyDir]: https://v1-30.docs.kubernetes.io/docs/concepts/storage/volumes/#emptydir
+ K8SVolumeTypeEmptyDir = K8SVolumeTypeKey.String("emptyDir")
+ // A [secret] volume
+ // Stability: development
+ //
+ // [secret]: https://v1-30.docs.kubernetes.io/docs/concepts/storage/volumes/#secret
+ K8SVolumeTypeSecret = K8SVolumeTypeKey.String("secret")
+ // A [local] volume
+ // Stability: development
+ //
+ // [local]: https://v1-30.docs.kubernetes.io/docs/concepts/storage/volumes/#local
+ K8SVolumeTypeLocal = K8SVolumeTypeKey.String("local")
+)
+
+// Namespace: log
+const (
+ // LogFileNameKey is the attribute Key conforming to the "log.file.name"
+ // semantic conventions. It represents the basename of the file.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "audit.log"
+ LogFileNameKey = attribute.Key("log.file.name")
+
+ // LogFileNameResolvedKey is the attribute Key conforming to the
+ // "log.file.name_resolved" semantic conventions. It represents the basename of
+ // the file, with symlinks resolved.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "uuid.log"
+ LogFileNameResolvedKey = attribute.Key("log.file.name_resolved")
+
+ // LogFilePathKey is the attribute Key conforming to the "log.file.path"
+ // semantic conventions. It represents the full path to the file.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "/var/log/mysql/audit.log"
+ LogFilePathKey = attribute.Key("log.file.path")
+
+ // LogFilePathResolvedKey is the attribute Key conforming to the
+ // "log.file.path_resolved" semantic conventions. It represents the full path to
+ // the file, with symlinks resolved.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "/var/lib/docker/uuid.log"
+ LogFilePathResolvedKey = attribute.Key("log.file.path_resolved")
+
+ // LogIostreamKey is the attribute Key conforming to the "log.iostream" semantic
+ // conventions. It represents the stream associated with the log. See below for
+ // a list of well-known values.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ LogIostreamKey = attribute.Key("log.iostream")
+
+ // LogRecordOriginalKey is the attribute Key conforming to the
+ // "log.record.original" semantic conventions. It represents the complete
+ // original Log Record.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "77 <86>1 2015-08-06T21:58:59.694Z 192.168.2.133 inactive - - -
+ // Something happened", "[INFO] 8/3/24 12:34:56 Something happened"
+ // Note: This value MAY be added when processing a Log Record which was
+ // originally transmitted as a string or equivalent data type AND the Body field
+ // of the Log Record does not contain the same value. (e.g. a syslog or a log
+ // record read from a file.)
+ LogRecordOriginalKey = attribute.Key("log.record.original")
+
+ // LogRecordUIDKey is the attribute Key conforming to the "log.record.uid"
+ // semantic conventions. It represents a unique identifier for the Log Record.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "01ARZ3NDEKTSV4RRFFQ69G5FAV"
+ // Note: If an id is provided, other log records with the same id will be
+ // considered duplicates and can be removed safely. This means, that two
+ // distinguishable log records MUST have different values.
+ // The id MAY be an
+ // [Universally Unique Lexicographically Sortable Identifier (ULID)], but other
+ // identifiers (e.g. UUID) may be used as needed.
+ //
+ // [Universally Unique Lexicographically Sortable Identifier (ULID)]: https://github.com/ulid/spec
+ LogRecordUIDKey = attribute.Key("log.record.uid")
+)
+
+// LogFileName returns an attribute KeyValue conforming to the "log.file.name"
+// semantic conventions. It represents the basename of the file.
+func LogFileName(val string) attribute.KeyValue {
+ return LogFileNameKey.String(val)
+}
+
+// LogFileNameResolved returns an attribute KeyValue conforming to the
+// "log.file.name_resolved" semantic conventions. It represents the basename of
+// the file, with symlinks resolved.
+func LogFileNameResolved(val string) attribute.KeyValue {
+ return LogFileNameResolvedKey.String(val)
+}
+
+// LogFilePath returns an attribute KeyValue conforming to the "log.file.path"
+// semantic conventions. It represents the full path to the file.
+func LogFilePath(val string) attribute.KeyValue {
+ return LogFilePathKey.String(val)
+}
+
+// LogFilePathResolved returns an attribute KeyValue conforming to the
+// "log.file.path_resolved" semantic conventions. It represents the full path to
+// the file, with symlinks resolved.
+func LogFilePathResolved(val string) attribute.KeyValue {
+ return LogFilePathResolvedKey.String(val)
+}
+
+// LogRecordOriginal returns an attribute KeyValue conforming to the
+// "log.record.original" semantic conventions. It represents the complete
+// original Log Record.
+func LogRecordOriginal(val string) attribute.KeyValue {
+ return LogRecordOriginalKey.String(val)
+}
+
+// LogRecordUID returns an attribute KeyValue conforming to the "log.record.uid"
+// semantic conventions. It represents a unique identifier for the Log Record.
+func LogRecordUID(val string) attribute.KeyValue {
+ return LogRecordUIDKey.String(val)
+}
+
+// Enum values for log.iostream
+var (
+ // Logs from stdout stream
+ // Stability: development
+ LogIostreamStdout = LogIostreamKey.String("stdout")
+ // Events from stderr stream
+ // Stability: development
+ LogIostreamStderr = LogIostreamKey.String("stderr")
+)
+
+// Namespace: mainframe
+const (
+ // MainframeLparNameKey is the attribute Key conforming to the
+ // "mainframe.lpar.name" semantic conventions. It represents the name of the
+ // logical partition that hosts a systems with a mainframe operating system.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "LPAR01"
+ MainframeLparNameKey = attribute.Key("mainframe.lpar.name")
+)
+
+// MainframeLparName returns an attribute KeyValue conforming to the
+// "mainframe.lpar.name" semantic conventions. It represents the name of the
+// logical partition that hosts a systems with a mainframe operating system.
+func MainframeLparName(val string) attribute.KeyValue {
+ return MainframeLparNameKey.String(val)
+}
+
+// Namespace: mcp
+const (
+ // McpMethodNameKey is the attribute Key conforming to the "mcp.method.name"
+ // semantic conventions. It represents the name of the request or notification
+ // method.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ McpMethodNameKey = attribute.Key("mcp.method.name")
+
+ // McpProtocolVersionKey is the attribute Key conforming to the
+ // "mcp.protocol.version" semantic conventions. It represents the [version] of
+ // the Model Context Protocol used.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "2025-06-18"
+ //
+ // [version]: https://modelcontextprotocol.io/specification/versioning
+ McpProtocolVersionKey = attribute.Key("mcp.protocol.version")
+
+ // McpResourceURIKey is the attribute Key conforming to the "mcp.resource.uri"
+ // semantic conventions. It represents the value of the resource uri.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "postgres://database/customers/schema",
+ // "file:///home/user/documents/report.pdf"
+ // Note: This is a URI of the resource provided in the following requests or
+ // notifications: `resources/read`, `resources/subscribe`,
+ // `resources/unsubscribe`, or `notifications/resources/updated`.
+ McpResourceURIKey = attribute.Key("mcp.resource.uri")
+
+ // McpSessionIDKey is the attribute Key conforming to the "mcp.session.id"
+ // semantic conventions. It represents the identifies [MCP session].
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "191c4850af6c49e08843a3f6c80e5046"
+ //
+ // [MCP session]: https://modelcontextprotocol.io/specification/2025-06-18/basic/transports#session-management
+ McpSessionIDKey = attribute.Key("mcp.session.id")
+)
+
+// McpProtocolVersion returns an attribute KeyValue conforming to the
+// "mcp.protocol.version" semantic conventions. It represents the [version] of
+// the Model Context Protocol used.
+//
+// [version]: https://modelcontextprotocol.io/specification/versioning
+func McpProtocolVersion(val string) attribute.KeyValue {
+ return McpProtocolVersionKey.String(val)
+}
+
+// McpResourceURI returns an attribute KeyValue conforming to the
+// "mcp.resource.uri" semantic conventions. It represents the value of the
+// resource uri.
+func McpResourceURI(val string) attribute.KeyValue {
+ return McpResourceURIKey.String(val)
+}
+
+// McpSessionID returns an attribute KeyValue conforming to the "mcp.session.id"
+// semantic conventions. It represents the identifies [MCP session].
+//
+// [MCP session]: https://modelcontextprotocol.io/specification/2025-06-18/basic/transports#session-management
+func McpSessionID(val string) attribute.KeyValue {
+ return McpSessionIDKey.String(val)
+}
+
+// Enum values for mcp.method.name
+var (
+ // Notification cancelling a previously-issued request.
+ //
+ // Stability: development
+ McpMethodNameNotificationsCancelled = McpMethodNameKey.String("notifications/cancelled")
+ // Request to initialize the MCP client.
+ //
+ // Stability: development
+ McpMethodNameInitialize = McpMethodNameKey.String("initialize")
+ // Notification indicating that the MCP client has been initialized.
+ //
+ // Stability: development
+ McpMethodNameNotificationsInitialized = McpMethodNameKey.String("notifications/initialized")
+ // Notification indicating the progress for a long-running operation.
+ //
+ // Stability: development
+ McpMethodNameNotificationsProgress = McpMethodNameKey.String("notifications/progress")
+ // Request to check that the other party is still alive.
+ //
+ // Stability: development
+ McpMethodNamePing = McpMethodNameKey.String("ping")
+ // Request to list resources available on server.
+ //
+ // Stability: development
+ McpMethodNameResourcesList = McpMethodNameKey.String("resources/list")
+ // Request to list resource templates available on server.
+ //
+ // Stability: development
+ McpMethodNameResourcesTemplatesList = McpMethodNameKey.String("resources/templates/list")
+ // Request to read a resource.
+ //
+ // Stability: development
+ McpMethodNameResourcesRead = McpMethodNameKey.String("resources/read")
+ // Notification indicating that the list of resources has changed.
+ //
+ // Stability: development
+ McpMethodNameNotificationsResourcesListChanged = McpMethodNameKey.String("notifications/resources/list_changed")
+ // Request to subscribe to a resource.
+ //
+ // Stability: development
+ McpMethodNameResourcesSubscribe = McpMethodNameKey.String("resources/subscribe")
+ // Request to unsubscribe from resource updates.
+ //
+ // Stability: development
+ McpMethodNameResourcesUnsubscribe = McpMethodNameKey.String("resources/unsubscribe")
+ // Notification indicating that a resource has been updated.
+ //
+ // Stability: development
+ McpMethodNameNotificationsResourcesUpdated = McpMethodNameKey.String("notifications/resources/updated")
+ // Request to list prompts available on server.
+ //
+ // Stability: development
+ McpMethodNamePromptsList = McpMethodNameKey.String("prompts/list")
+ // Request to get a prompt.
+ //
+ // Stability: development
+ McpMethodNamePromptsGet = McpMethodNameKey.String("prompts/get")
+ // Notification indicating that the list of prompts has changed.
+ //
+ // Stability: development
+ McpMethodNameNotificationsPromptsListChanged = McpMethodNameKey.String("notifications/prompts/list_changed")
+ // Request to list tools available on server.
+ //
+ // Stability: development
+ McpMethodNameToolsList = McpMethodNameKey.String("tools/list")
+ // Request to call a tool.
+ //
+ // Stability: development
+ McpMethodNameToolsCall = McpMethodNameKey.String("tools/call")
+ // Notification indicating that the list of tools has changed.
+ //
+ // Stability: development
+ McpMethodNameNotificationsToolsListChanged = McpMethodNameKey.String("notifications/tools/list_changed")
+ // Request to set the logging level.
+ //
+ // Stability: development
+ McpMethodNameLoggingSetLevel = McpMethodNameKey.String("logging/setLevel")
+ // Notification indicating that a message has been received.
+ //
+ // Stability: development
+ McpMethodNameNotificationsMessage = McpMethodNameKey.String("notifications/message")
+ // Request to create a sampling message.
+ //
+ // Stability: development
+ McpMethodNameSamplingCreateMessage = McpMethodNameKey.String("sampling/createMessage")
+ // Request to complete a prompt.
+ //
+ // Stability: development
+ McpMethodNameCompletionComplete = McpMethodNameKey.String("completion/complete")
+ // Request to list roots available on server.
+ //
+ // Stability: development
+ McpMethodNameRootsList = McpMethodNameKey.String("roots/list")
+ // Notification indicating that the list of roots has changed.
+ //
+ // Stability: development
+ McpMethodNameNotificationsRootsListChanged = McpMethodNameKey.String("notifications/roots/list_changed")
+ // Request from the server to elicit additional information from the user via
+ // the client
+ //
+ // Stability: development
+ McpMethodNameElicitationCreate = McpMethodNameKey.String("elicitation/create")
+)
+
+// Namespace: messaging
+const (
+ // MessagingBatchMessageCountKey is the attribute Key conforming to the
+ // "messaging.batch.message_count" semantic conventions. It represents the
+ // number of messages sent, received, or processed in the scope of the batching
+ // operation.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 0, 1, 2
+ // Note: Instrumentations SHOULD NOT set `messaging.batch.message_count` on
+ // spans that operate with a single message. When a messaging client library
+ // supports both batch and single-message API for the same operation,
+ // instrumentations SHOULD use `messaging.batch.message_count` for batching APIs
+ // and SHOULD NOT use it for single-message APIs.
+ MessagingBatchMessageCountKey = attribute.Key("messaging.batch.message_count")
+
+ // MessagingClientIDKey is the attribute Key conforming to the
+ // "messaging.client.id" semantic conventions. It represents a unique identifier
+ // for the client that consumes or produces a message.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "client-5", "myhost@8742@s8083jm"
+ MessagingClientIDKey = attribute.Key("messaging.client.id")
+
+ // MessagingConsumerGroupNameKey is the attribute Key conforming to the
+ // "messaging.consumer.group.name" semantic conventions. It represents the name
+ // of the consumer group with which a consumer is associated.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "my-group", "indexer"
+ // Note: Semantic conventions for individual messaging systems SHOULD document
+ // whether `messaging.consumer.group.name` is applicable and what it means in
+ // the context of that system.
+ MessagingConsumerGroupNameKey = attribute.Key("messaging.consumer.group.name")
+
+ // MessagingDestinationAnonymousKey is the attribute Key conforming to the
+ // "messaging.destination.anonymous" semantic conventions. It represents a
+ // boolean that is true if the message destination is anonymous (could be
+ // unnamed or have auto-generated name).
+ //
+ // Type: boolean
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ MessagingDestinationAnonymousKey = attribute.Key("messaging.destination.anonymous")
+
+ // MessagingDestinationNameKey is the attribute Key conforming to the
+ // "messaging.destination.name" semantic conventions. It represents the message
+ // destination name.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "MyQueue", "MyTopic"
+ // Note: Destination name SHOULD uniquely identify a specific queue, topic or
+ // other entity within the broker. If
+ // the broker doesn't have such notion, the destination name SHOULD uniquely
+ // identify the broker.
+ MessagingDestinationNameKey = attribute.Key("messaging.destination.name")
+
+ // MessagingDestinationPartitionIDKey is the attribute Key conforming to the
+ // "messaging.destination.partition.id" semantic conventions. It represents the
+ // identifier of the partition messages are sent to or received from, unique
+ // within the `messaging.destination.name`.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 1
+ MessagingDestinationPartitionIDKey = attribute.Key("messaging.destination.partition.id")
+
+ // MessagingDestinationSubscriptionNameKey is the attribute Key conforming to
+ // the "messaging.destination.subscription.name" semantic conventions. It
+ // represents the name of the destination subscription from which a message is
+ // consumed.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "subscription-a"
+ // Note: Semantic conventions for individual messaging systems SHOULD document
+ // whether `messaging.destination.subscription.name` is applicable and what it
+ // means in the context of that system.
+ MessagingDestinationSubscriptionNameKey = attribute.Key("messaging.destination.subscription.name")
+
+ // MessagingDestinationTemplateKey is the attribute Key conforming to the
+ // "messaging.destination.template" semantic conventions. It represents the low
+ // cardinality representation of the messaging destination name.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "/customers/{customerId}"
+ // Note: Destination names could be constructed from templates. An example would
+ // be a destination name involving a user name or product id. Although the
+ // destination name in this case is of high cardinality, the underlying template
+ // is of low cardinality and can be effectively used for grouping and
+ // aggregation.
+ MessagingDestinationTemplateKey = attribute.Key("messaging.destination.template")
+
+ // MessagingDestinationTemporaryKey is the attribute Key conforming to the
+ // "messaging.destination.temporary" semantic conventions. It represents a
+ // boolean that is true if the message destination is temporary and might not
+ // exist anymore after messages are processed.
+ //
+ // Type: boolean
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ MessagingDestinationTemporaryKey = attribute.Key("messaging.destination.temporary")
+
+ // MessagingEventHubsMessageEnqueuedTimeKey is the attribute Key conforming to
+ // the "messaging.eventhubs.message.enqueued_time" semantic conventions. It
+ // represents the UTC epoch seconds at which the message has been accepted and
+ // stored in the entity.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ MessagingEventHubsMessageEnqueuedTimeKey = attribute.Key("messaging.eventhubs.message.enqueued_time")
+
+ // MessagingGCPPubSubMessageAckDeadlineKey is the attribute Key conforming to
+ // the "messaging.gcp_pubsub.message.ack_deadline" semantic conventions. It
+ // represents the ack deadline in seconds set for the modify ack deadline
+ // request.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ MessagingGCPPubSubMessageAckDeadlineKey = attribute.Key("messaging.gcp_pubsub.message.ack_deadline")
+
+ // MessagingGCPPubSubMessageAckIDKey is the attribute Key conforming to the
+ // "messaging.gcp_pubsub.message.ack_id" semantic conventions. It represents the
+ // ack id for a given message.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: ack_id
+ MessagingGCPPubSubMessageAckIDKey = attribute.Key("messaging.gcp_pubsub.message.ack_id")
+
+ // MessagingGCPPubSubMessageDeliveryAttemptKey is the attribute Key conforming
+ // to the "messaging.gcp_pubsub.message.delivery_attempt" semantic conventions.
+ // It represents the delivery attempt for a given message.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ MessagingGCPPubSubMessageDeliveryAttemptKey = attribute.Key("messaging.gcp_pubsub.message.delivery_attempt")
+
+ // MessagingGCPPubSubMessageOrderingKeyKey is the attribute Key conforming to
+ // the "messaging.gcp_pubsub.message.ordering_key" semantic conventions. It
+ // represents the ordering key for a given message. If the attribute is not
+ // present, the message does not have an ordering key.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: ordering_key
+ MessagingGCPPubSubMessageOrderingKeyKey = attribute.Key("messaging.gcp_pubsub.message.ordering_key")
+
+ // MessagingKafkaMessageKeyKey is the attribute Key conforming to the
+ // "messaging.kafka.message.key" semantic conventions. It represents the message
+ // keys in Kafka are used for grouping alike messages to ensure they're
+ // processed on the same partition. They differ from `messaging.message.id` in
+ // that they're not unique. If the key is `null`, the attribute MUST NOT be set.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: myKey
+ // Note: If the key type is not string, it's string representation has to be
+ // supplied for the attribute. If the key has no unambiguous, canonical string
+ // form, don't include its value.
+ MessagingKafkaMessageKeyKey = attribute.Key("messaging.kafka.message.key")
+
+ // MessagingKafkaMessageTombstoneKey is the attribute Key conforming to the
+ // "messaging.kafka.message.tombstone" semantic conventions. It represents a
+ // boolean that is true if the message is a tombstone.
+ //
+ // Type: boolean
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ MessagingKafkaMessageTombstoneKey = attribute.Key("messaging.kafka.message.tombstone")
+
+ // MessagingKafkaOffsetKey is the attribute Key conforming to the
+ // "messaging.kafka.offset" semantic conventions. It represents the offset of a
+ // record in the corresponding Kafka partition.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ MessagingKafkaOffsetKey = attribute.Key("messaging.kafka.offset")
+
+ // MessagingMessageBodySizeKey is the attribute Key conforming to the
+ // "messaging.message.body.size" semantic conventions. It represents the size of
+ // the message body in bytes.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Note: This can refer to both the compressed or uncompressed body size. If
+ // both sizes are known, the uncompressed
+ // body size should be used.
+ MessagingMessageBodySizeKey = attribute.Key("messaging.message.body.size")
+
+ // MessagingMessageConversationIDKey is the attribute Key conforming to the
+ // "messaging.message.conversation_id" semantic conventions. It represents the
+ // conversation ID identifying the conversation to which the message belongs,
+ // represented as a string. Sometimes called "Correlation ID".
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: MyConversationId
+ MessagingMessageConversationIDKey = attribute.Key("messaging.message.conversation_id")
+
+ // MessagingMessageEnvelopeSizeKey is the attribute Key conforming to the
+ // "messaging.message.envelope.size" semantic conventions. It represents the
+ // size of the message body and metadata in bytes.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Note: This can refer to both the compressed or uncompressed size. If both
+ // sizes are known, the uncompressed
+ // size should be used.
+ MessagingMessageEnvelopeSizeKey = attribute.Key("messaging.message.envelope.size")
+
+ // MessagingMessageIDKey is the attribute Key conforming to the
+ // "messaging.message.id" semantic conventions. It represents a value used by
+ // the messaging system as an identifier for the message, represented as a
+ // string.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 452a7c7c7c7048c2f887f61572b18fc2
+ MessagingMessageIDKey = attribute.Key("messaging.message.id")
+
+ // MessagingOperationNameKey is the attribute Key conforming to the
+ // "messaging.operation.name" semantic conventions. It represents the
+ // system-specific name of the messaging operation.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "ack", "nack", "send"
+ MessagingOperationNameKey = attribute.Key("messaging.operation.name")
+
+ // MessagingOperationTypeKey is the attribute Key conforming to the
+ // "messaging.operation.type" semantic conventions. It represents a string
+ // identifying the type of the messaging operation.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ // Note: If a custom value is used, it MUST be of low cardinality.
+ MessagingOperationTypeKey = attribute.Key("messaging.operation.type")
+
+ // MessagingRabbitMQDestinationRoutingKeyKey is the attribute Key conforming to
+ // the "messaging.rabbitmq.destination.routing_key" semantic conventions. It
+ // represents the rabbitMQ message routing key.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: myKey
+ MessagingRabbitMQDestinationRoutingKeyKey = attribute.Key("messaging.rabbitmq.destination.routing_key")
+
+ // MessagingRabbitMQMessageDeliveryTagKey is the attribute Key conforming to the
+ // "messaging.rabbitmq.message.delivery_tag" semantic conventions. It represents
+ // the rabbitMQ message delivery tag.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ MessagingRabbitMQMessageDeliveryTagKey = attribute.Key("messaging.rabbitmq.message.delivery_tag")
+
+ // MessagingRocketMQConsumptionModelKey is the attribute Key conforming to the
+ // "messaging.rocketmq.consumption_model" semantic conventions. It represents
+ // the model of message consumption. This only applies to consumer spans.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ MessagingRocketMQConsumptionModelKey = attribute.Key("messaging.rocketmq.consumption_model")
+
+ // MessagingRocketMQMessageDelayTimeLevelKey is the attribute Key conforming to
+ // the "messaging.rocketmq.message.delay_time_level" semantic conventions. It
+ // represents the delay time level for delay message, which determines the
+ // message delay time.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ MessagingRocketMQMessageDelayTimeLevelKey = attribute.Key("messaging.rocketmq.message.delay_time_level")
+
+ // MessagingRocketMQMessageDeliveryTimestampKey is the attribute Key conforming
+ // to the "messaging.rocketmq.message.delivery_timestamp" semantic conventions.
+ // It represents the timestamp in milliseconds that the delay message is
+ // expected to be delivered to consumer.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ MessagingRocketMQMessageDeliveryTimestampKey = attribute.Key("messaging.rocketmq.message.delivery_timestamp")
+
+ // MessagingRocketMQMessageGroupKey is the attribute Key conforming to the
+ // "messaging.rocketmq.message.group" semantic conventions. It represents the it
+ // is essential for FIFO message. Messages that belong to the same message group
+ // are always processed one by one within the same consumer group.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: myMessageGroup
+ MessagingRocketMQMessageGroupKey = attribute.Key("messaging.rocketmq.message.group")
+
+ // MessagingRocketMQMessageKeysKey is the attribute Key conforming to the
+ // "messaging.rocketmq.message.keys" semantic conventions. It represents the
+ // key(s) of message, another way to mark message besides message id.
+ //
+ // Type: string[]
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "keyA", "keyB"
+ MessagingRocketMQMessageKeysKey = attribute.Key("messaging.rocketmq.message.keys")
+
+ // MessagingRocketMQMessageTagKey is the attribute Key conforming to the
+ // "messaging.rocketmq.message.tag" semantic conventions. It represents the
+ // secondary classifier of message besides topic.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: tagA
+ MessagingRocketMQMessageTagKey = attribute.Key("messaging.rocketmq.message.tag")
+
+ // MessagingRocketMQMessageTypeKey is the attribute Key conforming to the
+ // "messaging.rocketmq.message.type" semantic conventions. It represents the
+ // type of message.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ MessagingRocketMQMessageTypeKey = attribute.Key("messaging.rocketmq.message.type")
+
+ // MessagingRocketMQNamespaceKey is the attribute Key conforming to the
+ // "messaging.rocketmq.namespace" semantic conventions. It represents the
+ // namespace of RocketMQ resources, resources in different namespaces are
+ // individual.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: myNamespace
+ MessagingRocketMQNamespaceKey = attribute.Key("messaging.rocketmq.namespace")
+
+ // MessagingServiceBusDispositionStatusKey is the attribute Key conforming to
+ // the "messaging.servicebus.disposition_status" semantic conventions. It
+ // represents the describes the [settlement type].
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ //
+ // [settlement type]: https://learn.microsoft.com/azure/service-bus-messaging/message-transfers-locks-settlement#peeklock
+ MessagingServiceBusDispositionStatusKey = attribute.Key("messaging.servicebus.disposition_status")
+
+ // MessagingServiceBusMessageDeliveryCountKey is the attribute Key conforming to
+ // the "messaging.servicebus.message.delivery_count" semantic conventions. It
+ // represents the number of deliveries that have been attempted for this
+ // message.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ MessagingServiceBusMessageDeliveryCountKey = attribute.Key("messaging.servicebus.message.delivery_count")
+
+ // MessagingServiceBusMessageEnqueuedTimeKey is the attribute Key conforming to
+ // the "messaging.servicebus.message.enqueued_time" semantic conventions. It
+ // represents the UTC epoch seconds at which the message has been accepted and
+ // stored in the entity.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ MessagingServiceBusMessageEnqueuedTimeKey = attribute.Key("messaging.servicebus.message.enqueued_time")
+
+ // MessagingSystemKey is the attribute Key conforming to the "messaging.system"
+ // semantic conventions. It represents the messaging system as identified by the
+ // client instrumentation.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ // Note: The actual messaging system may differ from the one known by the
+ // client. For example, when using Kafka client libraries to communicate with
+ // Azure Event Hubs, the `messaging.system` is set to `kafka` based on the
+ // instrumentation's best knowledge.
+ MessagingSystemKey = attribute.Key("messaging.system")
+)
+
+// MessagingBatchMessageCount returns an attribute KeyValue conforming to the
+// "messaging.batch.message_count" semantic conventions. It represents the number
+// of messages sent, received, or processed in the scope of the batching
+// operation.
+func MessagingBatchMessageCount(val int) attribute.KeyValue {
+ return MessagingBatchMessageCountKey.Int(val)
+}
+
+// MessagingClientID returns an attribute KeyValue conforming to the
+// "messaging.client.id" semantic conventions. It represents a unique identifier
+// for the client that consumes or produces a message.
+func MessagingClientID(val string) attribute.KeyValue {
+ return MessagingClientIDKey.String(val)
+}
+
+// MessagingConsumerGroupName returns an attribute KeyValue conforming to the
+// "messaging.consumer.group.name" semantic conventions. It represents the name
+// of the consumer group with which a consumer is associated.
+func MessagingConsumerGroupName(val string) attribute.KeyValue {
+ return MessagingConsumerGroupNameKey.String(val)
+}
+
+// MessagingDestinationAnonymous returns an attribute KeyValue conforming to the
+// "messaging.destination.anonymous" semantic conventions. It represents a
+// boolean that is true if the message destination is anonymous (could be unnamed
+// or have auto-generated name).
+func MessagingDestinationAnonymous(val bool) attribute.KeyValue {
+ return MessagingDestinationAnonymousKey.Bool(val)
+}
+
+// MessagingDestinationName returns an attribute KeyValue conforming to the
+// "messaging.destination.name" semantic conventions. It represents the message
+// destination name.
+func MessagingDestinationName(val string) attribute.KeyValue {
+ return MessagingDestinationNameKey.String(val)
+}
+
+// MessagingDestinationPartitionID returns an attribute KeyValue conforming to
+// the "messaging.destination.partition.id" semantic conventions. It represents
+// the identifier of the partition messages are sent to or received from, unique
+// within the `messaging.destination.name`.
+func MessagingDestinationPartitionID(val string) attribute.KeyValue {
+ return MessagingDestinationPartitionIDKey.String(val)
+}
+
+// MessagingDestinationSubscriptionName returns an attribute KeyValue conforming
+// to the "messaging.destination.subscription.name" semantic conventions. It
+// represents the name of the destination subscription from which a message is
+// consumed.
+func MessagingDestinationSubscriptionName(val string) attribute.KeyValue {
+ return MessagingDestinationSubscriptionNameKey.String(val)
+}
+
+// MessagingDestinationTemplate returns an attribute KeyValue conforming to the
+// "messaging.destination.template" semantic conventions. It represents the low
+// cardinality representation of the messaging destination name.
+func MessagingDestinationTemplate(val string) attribute.KeyValue {
+ return MessagingDestinationTemplateKey.String(val)
+}
+
+// MessagingDestinationTemporary returns an attribute KeyValue conforming to the
+// "messaging.destination.temporary" semantic conventions. It represents a
+// boolean that is true if the message destination is temporary and might not
+// exist anymore after messages are processed.
+func MessagingDestinationTemporary(val bool) attribute.KeyValue {
+ return MessagingDestinationTemporaryKey.Bool(val)
+}
+
+// MessagingEventHubsMessageEnqueuedTime returns an attribute KeyValue conforming
+// to the "messaging.eventhubs.message.enqueued_time" semantic conventions. It
+// represents the UTC epoch seconds at which the message has been accepted and
+// stored in the entity.
+func MessagingEventHubsMessageEnqueuedTime(val int) attribute.KeyValue {
+ return MessagingEventHubsMessageEnqueuedTimeKey.Int(val)
+}
+
+// MessagingGCPPubSubMessageAckDeadline returns an attribute KeyValue conforming
+// to the "messaging.gcp_pubsub.message.ack_deadline" semantic conventions. It
+// represents the ack deadline in seconds set for the modify ack deadline
+// request.
+func MessagingGCPPubSubMessageAckDeadline(val int) attribute.KeyValue {
+ return MessagingGCPPubSubMessageAckDeadlineKey.Int(val)
+}
+
+// MessagingGCPPubSubMessageAckID returns an attribute KeyValue conforming to the
+// "messaging.gcp_pubsub.message.ack_id" semantic conventions. It represents the
+// ack id for a given message.
+func MessagingGCPPubSubMessageAckID(val string) attribute.KeyValue {
+ return MessagingGCPPubSubMessageAckIDKey.String(val)
+}
+
+// MessagingGCPPubSubMessageDeliveryAttempt returns an attribute KeyValue
+// conforming to the "messaging.gcp_pubsub.message.delivery_attempt" semantic
+// conventions. It represents the delivery attempt for a given message.
+func MessagingGCPPubSubMessageDeliveryAttempt(val int) attribute.KeyValue {
+ return MessagingGCPPubSubMessageDeliveryAttemptKey.Int(val)
+}
+
+// MessagingGCPPubSubMessageOrderingKey returns an attribute KeyValue conforming
+// to the "messaging.gcp_pubsub.message.ordering_key" semantic conventions. It
+// represents the ordering key for a given message. If the attribute is not
+// present, the message does not have an ordering key.
+func MessagingGCPPubSubMessageOrderingKey(val string) attribute.KeyValue {
+ return MessagingGCPPubSubMessageOrderingKeyKey.String(val)
+}
+
+// MessagingKafkaMessageKey returns an attribute KeyValue conforming to the
+// "messaging.kafka.message.key" semantic conventions. It represents the message
+// keys in Kafka are used for grouping alike messages to ensure they're processed
+// on the same partition. They differ from `messaging.message.id` in that they're
+// not unique. If the key is `null`, the attribute MUST NOT be set.
+func MessagingKafkaMessageKey(val string) attribute.KeyValue {
+ return MessagingKafkaMessageKeyKey.String(val)
+}
+
+// MessagingKafkaMessageTombstone returns an attribute KeyValue conforming to the
+// "messaging.kafka.message.tombstone" semantic conventions. It represents a
+// boolean that is true if the message is a tombstone.
+func MessagingKafkaMessageTombstone(val bool) attribute.KeyValue {
+ return MessagingKafkaMessageTombstoneKey.Bool(val)
+}
+
+// MessagingKafkaOffset returns an attribute KeyValue conforming to the
+// "messaging.kafka.offset" semantic conventions. It represents the offset of a
+// record in the corresponding Kafka partition.
+func MessagingKafkaOffset(val int) attribute.KeyValue {
+ return MessagingKafkaOffsetKey.Int(val)
+}
+
+// MessagingMessageBodySize returns an attribute KeyValue conforming to the
+// "messaging.message.body.size" semantic conventions. It represents the size of
+// the message body in bytes.
+func MessagingMessageBodySize(val int) attribute.KeyValue {
+ return MessagingMessageBodySizeKey.Int(val)
+}
+
+// MessagingMessageConversationID returns an attribute KeyValue conforming to the
+// "messaging.message.conversation_id" semantic conventions. It represents the
+// conversation ID identifying the conversation to which the message belongs,
+// represented as a string. Sometimes called "Correlation ID".
+func MessagingMessageConversationID(val string) attribute.KeyValue {
+ return MessagingMessageConversationIDKey.String(val)
+}
+
+// MessagingMessageEnvelopeSize returns an attribute KeyValue conforming to the
+// "messaging.message.envelope.size" semantic conventions. It represents the size
+// of the message body and metadata in bytes.
+func MessagingMessageEnvelopeSize(val int) attribute.KeyValue {
+ return MessagingMessageEnvelopeSizeKey.Int(val)
+}
+
+// MessagingMessageID returns an attribute KeyValue conforming to the
+// "messaging.message.id" semantic conventions. It represents a value used by the
+// messaging system as an identifier for the message, represented as a string.
+func MessagingMessageID(val string) attribute.KeyValue {
+ return MessagingMessageIDKey.String(val)
+}
+
+// MessagingOperationName returns an attribute KeyValue conforming to the
+// "messaging.operation.name" semantic conventions. It represents the
+// system-specific name of the messaging operation.
+func MessagingOperationName(val string) attribute.KeyValue {
+ return MessagingOperationNameKey.String(val)
+}
+
+// MessagingRabbitMQDestinationRoutingKey returns an attribute KeyValue
+// conforming to the "messaging.rabbitmq.destination.routing_key" semantic
+// conventions. It represents the rabbitMQ message routing key.
+func MessagingRabbitMQDestinationRoutingKey(val string) attribute.KeyValue {
+ return MessagingRabbitMQDestinationRoutingKeyKey.String(val)
+}
+
+// MessagingRabbitMQMessageDeliveryTag returns an attribute KeyValue conforming
+// to the "messaging.rabbitmq.message.delivery_tag" semantic conventions. It
+// represents the rabbitMQ message delivery tag.
+func MessagingRabbitMQMessageDeliveryTag(val int) attribute.KeyValue {
+ return MessagingRabbitMQMessageDeliveryTagKey.Int(val)
+}
+
+// MessagingRocketMQMessageDelayTimeLevel returns an attribute KeyValue
+// conforming to the "messaging.rocketmq.message.delay_time_level" semantic
+// conventions. It represents the delay time level for delay message, which
+// determines the message delay time.
+func MessagingRocketMQMessageDelayTimeLevel(val int) attribute.KeyValue {
+ return MessagingRocketMQMessageDelayTimeLevelKey.Int(val)
+}
+
+// MessagingRocketMQMessageDeliveryTimestamp returns an attribute KeyValue
+// conforming to the "messaging.rocketmq.message.delivery_timestamp" semantic
+// conventions. It represents the timestamp in milliseconds that the delay
+// message is expected to be delivered to consumer.
+func MessagingRocketMQMessageDeliveryTimestamp(val int) attribute.KeyValue {
+ return MessagingRocketMQMessageDeliveryTimestampKey.Int(val)
+}
+
+// MessagingRocketMQMessageGroup returns an attribute KeyValue conforming to the
+// "messaging.rocketmq.message.group" semantic conventions. It represents the it
+// is essential for FIFO message. Messages that belong to the same message group
+// are always processed one by one within the same consumer group.
+func MessagingRocketMQMessageGroup(val string) attribute.KeyValue {
+ return MessagingRocketMQMessageGroupKey.String(val)
+}
+
+// MessagingRocketMQMessageKeys returns an attribute KeyValue conforming to the
+// "messaging.rocketmq.message.keys" semantic conventions. It represents the
+// key(s) of message, another way to mark message besides message id.
+func MessagingRocketMQMessageKeys(val ...string) attribute.KeyValue {
+ return MessagingRocketMQMessageKeysKey.StringSlice(val)
+}
+
+// MessagingRocketMQMessageTag returns an attribute KeyValue conforming to the
+// "messaging.rocketmq.message.tag" semantic conventions. It represents the
+// secondary classifier of message besides topic.
+func MessagingRocketMQMessageTag(val string) attribute.KeyValue {
+ return MessagingRocketMQMessageTagKey.String(val)
+}
+
+// MessagingRocketMQNamespace returns an attribute KeyValue conforming to the
+// "messaging.rocketmq.namespace" semantic conventions. It represents the
+// namespace of RocketMQ resources, resources in different namespaces are
+// individual.
+func MessagingRocketMQNamespace(val string) attribute.KeyValue {
+ return MessagingRocketMQNamespaceKey.String(val)
+}
+
+// MessagingServiceBusMessageDeliveryCount returns an attribute KeyValue
+// conforming to the "messaging.servicebus.message.delivery_count" semantic
+// conventions. It represents the number of deliveries that have been attempted
+// for this message.
+func MessagingServiceBusMessageDeliveryCount(val int) attribute.KeyValue {
+ return MessagingServiceBusMessageDeliveryCountKey.Int(val)
+}
+
+// MessagingServiceBusMessageEnqueuedTime returns an attribute KeyValue
+// conforming to the "messaging.servicebus.message.enqueued_time" semantic
+// conventions. It represents the UTC epoch seconds at which the message has been
+// accepted and stored in the entity.
+func MessagingServiceBusMessageEnqueuedTime(val int) attribute.KeyValue {
+ return MessagingServiceBusMessageEnqueuedTimeKey.Int(val)
+}
+
+// Enum values for messaging.operation.type
+var (
+ // A message is created. "Create" spans always refer to a single message and are
+ // used to provide a unique creation context for messages in batch sending
+ // scenarios.
+ //
+ // Stability: development
+ MessagingOperationTypeCreate = MessagingOperationTypeKey.String("create")
+ // One or more messages are provided for sending to an intermediary. If a single
+ // message is sent, the context of the "Send" span can be used as the creation
+ // context and no "Create" span needs to be created.
+ //
+ // Stability: development
+ MessagingOperationTypeSend = MessagingOperationTypeKey.String("send")
+ // One or more messages are requested by a consumer. This operation refers to
+ // pull-based scenarios, where consumers explicitly call methods of messaging
+ // SDKs to receive messages.
+ //
+ // Stability: development
+ MessagingOperationTypeReceive = MessagingOperationTypeKey.String("receive")
+ // One or more messages are processed by a consumer.
+ //
+ // Stability: development
+ MessagingOperationTypeProcess = MessagingOperationTypeKey.String("process")
+ // One or more messages are settled.
+ //
+ // Stability: development
+ MessagingOperationTypeSettle = MessagingOperationTypeKey.String("settle")
+)
+
+// Enum values for messaging.rocketmq.consumption_model
+var (
+ // Clustering consumption model
+ // Stability: development
+ MessagingRocketMQConsumptionModelClustering = MessagingRocketMQConsumptionModelKey.String("clustering")
+ // Broadcasting consumption model
+ // Stability: development
+ MessagingRocketMQConsumptionModelBroadcasting = MessagingRocketMQConsumptionModelKey.String("broadcasting")
+)
+
+// Enum values for messaging.rocketmq.message.type
+var (
+ // Normal message
+ // Stability: development
+ MessagingRocketMQMessageTypeNormal = MessagingRocketMQMessageTypeKey.String("normal")
+ // FIFO message
+ // Stability: development
+ MessagingRocketMQMessageTypeFifo = MessagingRocketMQMessageTypeKey.String("fifo")
+ // Delay message
+ // Stability: development
+ MessagingRocketMQMessageTypeDelay = MessagingRocketMQMessageTypeKey.String("delay")
+ // Transaction message
+ // Stability: development
+ MessagingRocketMQMessageTypeTransaction = MessagingRocketMQMessageTypeKey.String("transaction")
+)
+
+// Enum values for messaging.servicebus.disposition_status
+var (
+ // Message is completed
+ // Stability: development
+ MessagingServiceBusDispositionStatusComplete = MessagingServiceBusDispositionStatusKey.String("complete")
+ // Message is abandoned
+ // Stability: development
+ MessagingServiceBusDispositionStatusAbandon = MessagingServiceBusDispositionStatusKey.String("abandon")
+ // Message is sent to dead letter queue
+ // Stability: development
+ MessagingServiceBusDispositionStatusDeadLetter = MessagingServiceBusDispositionStatusKey.String("dead_letter")
+ // Message is deferred
+ // Stability: development
+ MessagingServiceBusDispositionStatusDefer = MessagingServiceBusDispositionStatusKey.String("defer")
+)
+
+// Enum values for messaging.system
+var (
+ // Apache ActiveMQ
+ // Stability: development
+ MessagingSystemActiveMQ = MessagingSystemKey.String("activemq")
+ // Amazon Simple Notification Service (SNS)
+ // Stability: development
+ MessagingSystemAWSSNS = MessagingSystemKey.String("aws.sns")
+ // Amazon Simple Queue Service (SQS)
+ // Stability: development
+ MessagingSystemAWSSQS = MessagingSystemKey.String("aws_sqs")
+ // Azure Event Grid
+ // Stability: development
+ MessagingSystemEventGrid = MessagingSystemKey.String("eventgrid")
+ // Azure Event Hubs
+ // Stability: development
+ MessagingSystemEventHubs = MessagingSystemKey.String("eventhubs")
+ // Azure Service Bus
+ // Stability: development
+ MessagingSystemServiceBus = MessagingSystemKey.String("servicebus")
+ // Google Cloud Pub/Sub
+ // Stability: development
+ MessagingSystemGCPPubSub = MessagingSystemKey.String("gcp_pubsub")
+ // Java Message Service
+ // Stability: development
+ MessagingSystemJMS = MessagingSystemKey.String("jms")
+ // Apache Kafka
+ // Stability: development
+ MessagingSystemKafka = MessagingSystemKey.String("kafka")
+ // RabbitMQ
+ // Stability: development
+ MessagingSystemRabbitMQ = MessagingSystemKey.String("rabbitmq")
+ // Apache RocketMQ
+ // Stability: development
+ MessagingSystemRocketMQ = MessagingSystemKey.String("rocketmq")
+ // Apache Pulsar
+ // Stability: development
+ MessagingSystemPulsar = MessagingSystemKey.String("pulsar")
+)
+
+// Namespace: network
+const (
+ // NetworkCarrierICCKey is the attribute Key conforming to the
+ // "network.carrier.icc" semantic conventions. It represents the ISO 3166-1
+ // alpha-2 2-character country code associated with the mobile carrier network.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: DE
+ NetworkCarrierICCKey = attribute.Key("network.carrier.icc")
+
+ // NetworkCarrierMCCKey is the attribute Key conforming to the
+ // "network.carrier.mcc" semantic conventions. It represents the mobile carrier
+ // country code.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 310
+ NetworkCarrierMCCKey = attribute.Key("network.carrier.mcc")
+
+ // NetworkCarrierMNCKey is the attribute Key conforming to the
+ // "network.carrier.mnc" semantic conventions. It represents the mobile carrier
+ // network code.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 001
+ NetworkCarrierMNCKey = attribute.Key("network.carrier.mnc")
+
+ // NetworkCarrierNameKey is the attribute Key conforming to the
+ // "network.carrier.name" semantic conventions. It represents the name of the
+ // mobile carrier.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: sprint
+ NetworkCarrierNameKey = attribute.Key("network.carrier.name")
+
+ // NetworkConnectionStateKey is the attribute Key conforming to the
+ // "network.connection.state" semantic conventions. It represents the state of
+ // network connection.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "close_wait"
+ // Note: Connection states are defined as part of the [rfc9293]
+ //
+ // [rfc9293]: https://datatracker.ietf.org/doc/html/rfc9293#section-3.3.2
+ NetworkConnectionStateKey = attribute.Key("network.connection.state")
+
+ // NetworkConnectionSubtypeKey is the attribute Key conforming to the
+ // "network.connection.subtype" semantic conventions. It represents the this
+ // describes more details regarding the connection.type. It may be the type of
+ // cell technology connection, but it could be used for describing details about
+ // a wifi connection.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: LTE
+ NetworkConnectionSubtypeKey = attribute.Key("network.connection.subtype")
+
+ // NetworkConnectionTypeKey is the attribute Key conforming to the
+ // "network.connection.type" semantic conventions. It represents the internet
+ // connection type.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: wifi
+ NetworkConnectionTypeKey = attribute.Key("network.connection.type")
+
+ // NetworkInterfaceNameKey is the attribute Key conforming to the
+ // "network.interface.name" semantic conventions. It represents the network
+ // interface name.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "lo", "eth0"
+ NetworkInterfaceNameKey = attribute.Key("network.interface.name")
+
+ // NetworkIODirectionKey is the attribute Key conforming to the
+ // "network.io.direction" semantic conventions. It represents the network IO
+ // operation direction.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "transmit"
+ NetworkIODirectionKey = attribute.Key("network.io.direction")
+
+ // NetworkLocalAddressKey is the attribute Key conforming to the
+ // "network.local.address" semantic conventions. It represents the local address
+ // of the network connection - IP address or Unix domain socket name.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ //
+ // Examples: "10.1.2.80", "/tmp/my.sock"
+ NetworkLocalAddressKey = attribute.Key("network.local.address")
+
+ // NetworkLocalPortKey is the attribute Key conforming to the
+ // "network.local.port" semantic conventions. It represents the local port
+ // number of the network connection.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ //
+ // Examples: 65123
+ NetworkLocalPortKey = attribute.Key("network.local.port")
+
+ // NetworkPeerAddressKey is the attribute Key conforming to the
+ // "network.peer.address" semantic conventions. It represents the peer address
+ // of the network connection - IP address or Unix domain socket name.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ //
+ // Examples: "10.1.2.80", "/tmp/my.sock"
+ NetworkPeerAddressKey = attribute.Key("network.peer.address")
+
+ // NetworkPeerPortKey is the attribute Key conforming to the "network.peer.port"
+ // semantic conventions. It represents the peer port number of the network
+ // connection.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ //
+ // Examples: 65123
+ NetworkPeerPortKey = attribute.Key("network.peer.port")
+
+ // NetworkProtocolNameKey is the attribute Key conforming to the
+ // "network.protocol.name" semantic conventions. It represents the
+ // [OSI application layer] or non-OSI equivalent.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ //
+ // Examples: "amqp", "http", "mqtt"
+ // Note: The value SHOULD be normalized to lowercase.
+ //
+ // [OSI application layer]: https://wikipedia.org/wiki/Application_layer
+ NetworkProtocolNameKey = attribute.Key("network.protocol.name")
+
+ // NetworkProtocolVersionKey is the attribute Key conforming to the
+ // "network.protocol.version" semantic conventions. It represents the actual
+ // version of the protocol used for network communication.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ //
+ // Examples: "1.1", "2"
+ // Note: If protocol version is subject to negotiation (for example using [ALPN]
+ // ), this attribute SHOULD be set to the negotiated version. If the actual
+ // protocol version is not known, this attribute SHOULD NOT be set.
+ //
+ // [ALPN]: https://www.rfc-editor.org/rfc/rfc7301.html
+ NetworkProtocolVersionKey = attribute.Key("network.protocol.version")
+
+ // NetworkTransportKey is the attribute Key conforming to the
+ // "network.transport" semantic conventions. It represents the
+ // [OSI transport layer] or [inter-process communication method].
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ //
+ // Examples: "tcp", "udp"
+ // Note: The value SHOULD be normalized to lowercase.
+ //
+ // Consider always setting the transport when setting a port number, since
+ // a port number is ambiguous without knowing the transport. For example
+ // different processes could be listening on TCP port 12345 and UDP port 12345.
+ //
+ // [OSI transport layer]: https://wikipedia.org/wiki/Transport_layer
+ // [inter-process communication method]: https://wikipedia.org/wiki/Inter-process_communication
+ NetworkTransportKey = attribute.Key("network.transport")
+
+ // NetworkTypeKey is the attribute Key conforming to the "network.type" semantic
+ // conventions. It represents the [OSI network layer] or non-OSI equivalent.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ //
+ // Examples: "ipv4", "ipv6"
+ // Note: The value SHOULD be normalized to lowercase.
+ //
+ // [OSI network layer]: https://wikipedia.org/wiki/Network_layer
+ NetworkTypeKey = attribute.Key("network.type")
+)
+
+// NetworkCarrierICC returns an attribute KeyValue conforming to the
+// "network.carrier.icc" semantic conventions. It represents the ISO 3166-1
+// alpha-2 2-character country code associated with the mobile carrier network.
+func NetworkCarrierICC(val string) attribute.KeyValue {
+ return NetworkCarrierICCKey.String(val)
+}
+
+// NetworkCarrierMCC returns an attribute KeyValue conforming to the
+// "network.carrier.mcc" semantic conventions. It represents the mobile carrier
+// country code.
+func NetworkCarrierMCC(val string) attribute.KeyValue {
+ return NetworkCarrierMCCKey.String(val)
+}
+
+// NetworkCarrierMNC returns an attribute KeyValue conforming to the
+// "network.carrier.mnc" semantic conventions. It represents the mobile carrier
+// network code.
+func NetworkCarrierMNC(val string) attribute.KeyValue {
+ return NetworkCarrierMNCKey.String(val)
+}
+
+// NetworkCarrierName returns an attribute KeyValue conforming to the
+// "network.carrier.name" semantic conventions. It represents the name of the
+// mobile carrier.
+func NetworkCarrierName(val string) attribute.KeyValue {
+ return NetworkCarrierNameKey.String(val)
+}
+
+// NetworkInterfaceName returns an attribute KeyValue conforming to the
+// "network.interface.name" semantic conventions. It represents the network
+// interface name.
+func NetworkInterfaceName(val string) attribute.KeyValue {
+ return NetworkInterfaceNameKey.String(val)
+}
+
+// NetworkLocalAddress returns an attribute KeyValue conforming to the
+// "network.local.address" semantic conventions. It represents the local address
+// of the network connection - IP address or Unix domain socket name.
+func NetworkLocalAddress(val string) attribute.KeyValue {
+ return NetworkLocalAddressKey.String(val)
+}
+
+// NetworkLocalPort returns an attribute KeyValue conforming to the
+// "network.local.port" semantic conventions. It represents the local port number
+// of the network connection.
+func NetworkLocalPort(val int) attribute.KeyValue {
+ return NetworkLocalPortKey.Int(val)
+}
+
+// NetworkPeerAddress returns an attribute KeyValue conforming to the
+// "network.peer.address" semantic conventions. It represents the peer address of
+// the network connection - IP address or Unix domain socket name.
+func NetworkPeerAddress(val string) attribute.KeyValue {
+ return NetworkPeerAddressKey.String(val)
+}
+
+// NetworkPeerPort returns an attribute KeyValue conforming to the
+// "network.peer.port" semantic conventions. It represents the peer port number
+// of the network connection.
+func NetworkPeerPort(val int) attribute.KeyValue {
+ return NetworkPeerPortKey.Int(val)
+}
+
+// NetworkProtocolName returns an attribute KeyValue conforming to the
+// "network.protocol.name" semantic conventions. It represents the
+// [OSI application layer] or non-OSI equivalent.
+//
+// [OSI application layer]: https://wikipedia.org/wiki/Application_layer
+func NetworkProtocolName(val string) attribute.KeyValue {
+ return NetworkProtocolNameKey.String(val)
+}
+
+// NetworkProtocolVersion returns an attribute KeyValue conforming to the
+// "network.protocol.version" semantic conventions. It represents the actual
+// version of the protocol used for network communication.
+func NetworkProtocolVersion(val string) attribute.KeyValue {
+ return NetworkProtocolVersionKey.String(val)
+}
+
+// Enum values for network.connection.state
+var (
+ // closed
+ // Stability: development
+ NetworkConnectionStateClosed = NetworkConnectionStateKey.String("closed")
+ // close_wait
+ // Stability: development
+ NetworkConnectionStateCloseWait = NetworkConnectionStateKey.String("close_wait")
+ // closing
+ // Stability: development
+ NetworkConnectionStateClosing = NetworkConnectionStateKey.String("closing")
+ // established
+ // Stability: development
+ NetworkConnectionStateEstablished = NetworkConnectionStateKey.String("established")
+ // fin_wait_1
+ // Stability: development
+ NetworkConnectionStateFinWait1 = NetworkConnectionStateKey.String("fin_wait_1")
+ // fin_wait_2
+ // Stability: development
+ NetworkConnectionStateFinWait2 = NetworkConnectionStateKey.String("fin_wait_2")
+ // last_ack
+ // Stability: development
+ NetworkConnectionStateLastAck = NetworkConnectionStateKey.String("last_ack")
+ // listen
+ // Stability: development
+ NetworkConnectionStateListen = NetworkConnectionStateKey.String("listen")
+ // syn_received
+ // Stability: development
+ NetworkConnectionStateSynReceived = NetworkConnectionStateKey.String("syn_received")
+ // syn_sent
+ // Stability: development
+ NetworkConnectionStateSynSent = NetworkConnectionStateKey.String("syn_sent")
+ // time_wait
+ // Stability: development
+ NetworkConnectionStateTimeWait = NetworkConnectionStateKey.String("time_wait")
+)
+
+// Enum values for network.connection.subtype
+var (
+ // GPRS
+ // Stability: development
+ NetworkConnectionSubtypeGprs = NetworkConnectionSubtypeKey.String("gprs")
+ // EDGE
+ // Stability: development
+ NetworkConnectionSubtypeEdge = NetworkConnectionSubtypeKey.String("edge")
+ // UMTS
+ // Stability: development
+ NetworkConnectionSubtypeUmts = NetworkConnectionSubtypeKey.String("umts")
+ // CDMA
+ // Stability: development
+ NetworkConnectionSubtypeCdma = NetworkConnectionSubtypeKey.String("cdma")
+ // EVDO Rel. 0
+ // Stability: development
+ NetworkConnectionSubtypeEvdo0 = NetworkConnectionSubtypeKey.String("evdo_0")
+ // EVDO Rev. A
+ // Stability: development
+ NetworkConnectionSubtypeEvdoA = NetworkConnectionSubtypeKey.String("evdo_a")
+ // CDMA2000 1XRTT
+ // Stability: development
+ NetworkConnectionSubtypeCdma20001xrtt = NetworkConnectionSubtypeKey.String("cdma2000_1xrtt")
+ // HSDPA
+ // Stability: development
+ NetworkConnectionSubtypeHsdpa = NetworkConnectionSubtypeKey.String("hsdpa")
+ // HSUPA
+ // Stability: development
+ NetworkConnectionSubtypeHsupa = NetworkConnectionSubtypeKey.String("hsupa")
+ // HSPA
+ // Stability: development
+ NetworkConnectionSubtypeHspa = NetworkConnectionSubtypeKey.String("hspa")
+ // IDEN
+ // Stability: development
+ NetworkConnectionSubtypeIden = NetworkConnectionSubtypeKey.String("iden")
+ // EVDO Rev. B
+ // Stability: development
+ NetworkConnectionSubtypeEvdoB = NetworkConnectionSubtypeKey.String("evdo_b")
+ // LTE
+ // Stability: development
+ NetworkConnectionSubtypeLte = NetworkConnectionSubtypeKey.String("lte")
+ // EHRPD
+ // Stability: development
+ NetworkConnectionSubtypeEhrpd = NetworkConnectionSubtypeKey.String("ehrpd")
+ // HSPAP
+ // Stability: development
+ NetworkConnectionSubtypeHspap = NetworkConnectionSubtypeKey.String("hspap")
+ // GSM
+ // Stability: development
+ NetworkConnectionSubtypeGsm = NetworkConnectionSubtypeKey.String("gsm")
+ // TD-SCDMA
+ // Stability: development
+ NetworkConnectionSubtypeTdScdma = NetworkConnectionSubtypeKey.String("td_scdma")
+ // IWLAN
+ // Stability: development
+ NetworkConnectionSubtypeIwlan = NetworkConnectionSubtypeKey.String("iwlan")
+ // 5G NR (New Radio)
+ // Stability: development
+ NetworkConnectionSubtypeNr = NetworkConnectionSubtypeKey.String("nr")
+ // 5G NRNSA (New Radio Non-Standalone)
+ // Stability: development
+ NetworkConnectionSubtypeNrnsa = NetworkConnectionSubtypeKey.String("nrnsa")
+ // LTE CA
+ // Stability: development
+ NetworkConnectionSubtypeLteCa = NetworkConnectionSubtypeKey.String("lte_ca")
+)
+
+// Enum values for network.connection.type
+var (
+ // wifi
+ // Stability: development
+ NetworkConnectionTypeWifi = NetworkConnectionTypeKey.String("wifi")
+ // wired
+ // Stability: development
+ NetworkConnectionTypeWired = NetworkConnectionTypeKey.String("wired")
+ // cell
+ // Stability: development
+ NetworkConnectionTypeCell = NetworkConnectionTypeKey.String("cell")
+ // unavailable
+ // Stability: development
+ NetworkConnectionTypeUnavailable = NetworkConnectionTypeKey.String("unavailable")
+ // unknown
+ // Stability: development
+ NetworkConnectionTypeUnknown = NetworkConnectionTypeKey.String("unknown")
+)
+
+// Enum values for network.io.direction
+var (
+ // transmit
+ // Stability: development
+ NetworkIODirectionTransmit = NetworkIODirectionKey.String("transmit")
+ // receive
+ // Stability: development
+ NetworkIODirectionReceive = NetworkIODirectionKey.String("receive")
+)
+
+// Enum values for network.transport
+var (
+ // TCP
+ // Stability: stable
+ NetworkTransportTCP = NetworkTransportKey.String("tcp")
+ // UDP
+ // Stability: stable
+ NetworkTransportUDP = NetworkTransportKey.String("udp")
+ // Named or anonymous pipe.
+ // Stability: stable
+ NetworkTransportPipe = NetworkTransportKey.String("pipe")
+ // Unix domain socket
+ // Stability: stable
+ NetworkTransportUnix = NetworkTransportKey.String("unix")
+ // QUIC
+ // Stability: stable
+ NetworkTransportQUIC = NetworkTransportKey.String("quic")
+)
+
+// Enum values for network.type
+var (
+ // IPv4
+ // Stability: stable
+ NetworkTypeIPv4 = NetworkTypeKey.String("ipv4")
+ // IPv6
+ // Stability: stable
+ NetworkTypeIPv6 = NetworkTypeKey.String("ipv6")
+)
+
+// Namespace: nfs
+const (
+ // NfsOperationNameKey is the attribute Key conforming to the
+ // "nfs.operation.name" semantic conventions. It represents the NFSv4+ operation
+ // name.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "OPEN", "READ", "GETATTR"
+ NfsOperationNameKey = attribute.Key("nfs.operation.name")
+
+ // NfsServerRepcacheStatusKey is the attribute Key conforming to the
+ // "nfs.server.repcache.status" semantic conventions. It represents the linux:
+ // one of "hit" (NFSD_STATS_RC_HITS), "miss" (NFSD_STATS_RC_MISSES), or
+ // "nocache" (NFSD_STATS_RC_NOCACHE -- uncacheable).
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: hit
+ NfsServerRepcacheStatusKey = attribute.Key("nfs.server.repcache.status")
+)
+
+// NfsOperationName returns an attribute KeyValue conforming to the
+// "nfs.operation.name" semantic conventions. It represents the NFSv4+ operation
+// name.
+func NfsOperationName(val string) attribute.KeyValue {
+ return NfsOperationNameKey.String(val)
+}
+
+// NfsServerRepcacheStatus returns an attribute KeyValue conforming to the
+// "nfs.server.repcache.status" semantic conventions. It represents the linux:
+// one of "hit" (NFSD_STATS_RC_HITS), "miss" (NFSD_STATS_RC_MISSES), or "nocache"
+// (NFSD_STATS_RC_NOCACHE -- uncacheable).
+func NfsServerRepcacheStatus(val string) attribute.KeyValue {
+ return NfsServerRepcacheStatusKey.String(val)
+}
+
+// Namespace: oci
+const (
+ // OCIManifestDigestKey is the attribute Key conforming to the
+ // "oci.manifest.digest" semantic conventions. It represents the digest of the
+ // OCI image manifest. For container images specifically is the digest by which
+ // the container image is known.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ // "sha256:e4ca62c0d62f3e886e684806dfe9d4e0cda60d54986898173c1083856cfda0f4"
+ // Note: Follows [OCI Image Manifest Specification], and specifically the
+ // [Digest property].
+ // An example can be found in [Example Image Manifest].
+ //
+ // [OCI Image Manifest Specification]: https://github.com/opencontainers/image-spec/blob/main/manifest.md
+ // [Digest property]: https://github.com/opencontainers/image-spec/blob/main/descriptor.md#digests
+ // [Example Image Manifest]: https://github.com/opencontainers/image-spec/blob/main/manifest.md#example-image-manifest
+ OCIManifestDigestKey = attribute.Key("oci.manifest.digest")
+)
+
+// OCIManifestDigest returns an attribute KeyValue conforming to the
+// "oci.manifest.digest" semantic conventions. It represents the digest of the
+// OCI image manifest. For container images specifically is the digest by which
+// the container image is known.
+func OCIManifestDigest(val string) attribute.KeyValue {
+ return OCIManifestDigestKey.String(val)
+}
+
+// Namespace: onc_rpc
+const (
+ // OncRPCProcedureNameKey is the attribute Key conforming to the
+ // "onc_rpc.procedure.name" semantic conventions. It represents the ONC/Sun RPC
+ // procedure name.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "OPEN", "READ", "GETATTR"
+ OncRPCProcedureNameKey = attribute.Key("onc_rpc.procedure.name")
+
+ // OncRPCProcedureNumberKey is the attribute Key conforming to the
+ // "onc_rpc.procedure.number" semantic conventions. It represents the ONC/Sun
+ // RPC procedure number.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ OncRPCProcedureNumberKey = attribute.Key("onc_rpc.procedure.number")
+
+ // OncRPCProgramNameKey is the attribute Key conforming to the
+ // "onc_rpc.program.name" semantic conventions. It represents the ONC/Sun RPC
+ // program name.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "portmapper", "nfs"
+ OncRPCProgramNameKey = attribute.Key("onc_rpc.program.name")
+
+ // OncRPCVersionKey is the attribute Key conforming to the "onc_rpc.version"
+ // semantic conventions. It represents the ONC/Sun RPC program version.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ OncRPCVersionKey = attribute.Key("onc_rpc.version")
+)
+
+// OncRPCProcedureName returns an attribute KeyValue conforming to the
+// "onc_rpc.procedure.name" semantic conventions. It represents the ONC/Sun RPC
+// procedure name.
+func OncRPCProcedureName(val string) attribute.KeyValue {
+ return OncRPCProcedureNameKey.String(val)
+}
+
+// OncRPCProcedureNumber returns an attribute KeyValue conforming to the
+// "onc_rpc.procedure.number" semantic conventions. It represents the ONC/Sun RPC
+// procedure number.
+func OncRPCProcedureNumber(val int) attribute.KeyValue {
+ return OncRPCProcedureNumberKey.Int(val)
+}
+
+// OncRPCProgramName returns an attribute KeyValue conforming to the
+// "onc_rpc.program.name" semantic conventions. It represents the ONC/Sun RPC
+// program name.
+func OncRPCProgramName(val string) attribute.KeyValue {
+ return OncRPCProgramNameKey.String(val)
+}
+
+// OncRPCVersion returns an attribute KeyValue conforming to the
+// "onc_rpc.version" semantic conventions. It represents the ONC/Sun RPC program
+// version.
+func OncRPCVersion(val int) attribute.KeyValue {
+ return OncRPCVersionKey.Int(val)
+}
+
+// Namespace: openai
+const (
+ // OpenAIAPITypeKey is the attribute Key conforming to the "openai.api.type"
+ // semantic conventions. It represents the type of OpenAI API being used.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ OpenAIAPITypeKey = attribute.Key("openai.api.type")
+
+ // OpenAIRequestServiceTierKey is the attribute Key conforming to the
+ // "openai.request.service_tier" semantic conventions. It represents the service
+ // tier requested. May be a specific tier, default, or auto.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "auto", "default"
+ OpenAIRequestServiceTierKey = attribute.Key("openai.request.service_tier")
+
+ // OpenAIResponseServiceTierKey is the attribute Key conforming to the
+ // "openai.response.service_tier" semantic conventions. It represents the
+ // service tier used for the response.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "scale", "default"
+ OpenAIResponseServiceTierKey = attribute.Key("openai.response.service_tier")
+
+ // OpenAIResponseSystemFingerprintKey is the attribute Key conforming to the
+ // "openai.response.system_fingerprint" semantic conventions. It represents a
+ // fingerprint to track any eventual change in the Generative AI environment.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "fp_44709d6fcb"
+ OpenAIResponseSystemFingerprintKey = attribute.Key("openai.response.system_fingerprint")
+)
+
+// OpenAIResponseServiceTier returns an attribute KeyValue conforming to the
+// "openai.response.service_tier" semantic conventions. It represents the service
+// tier used for the response.
+func OpenAIResponseServiceTier(val string) attribute.KeyValue {
+ return OpenAIResponseServiceTierKey.String(val)
+}
+
+// OpenAIResponseSystemFingerprint returns an attribute KeyValue conforming to
+// the "openai.response.system_fingerprint" semantic conventions. It represents a
+// fingerprint to track any eventual change in the Generative AI environment.
+func OpenAIResponseSystemFingerprint(val string) attribute.KeyValue {
+ return OpenAIResponseSystemFingerprintKey.String(val)
+}
+
+// Enum values for openai.api.type
+var (
+ // The OpenAI [Chat Completions API].
+ // Stability: development
+ //
+ // [Chat Completions API]: https://developers.openai.com/api/reference/chat-completions/overview
+ OpenAIAPITypeChatCompletions = OpenAIAPITypeKey.String("chat_completions")
+ // The OpenAI [Responses API].
+ // Stability: development
+ //
+ // [Responses API]: https://developers.openai.com/api/reference/responses/overview
+ OpenAIAPITypeResponses = OpenAIAPITypeKey.String("responses")
+)
+
+// Enum values for openai.request.service_tier
+var (
+ // The system will utilize scale tier credits until they are exhausted.
+ // Stability: development
+ OpenAIRequestServiceTierAuto = OpenAIRequestServiceTierKey.String("auto")
+ // The system will utilize the default scale tier.
+ // Stability: development
+ OpenAIRequestServiceTierDefault = OpenAIRequestServiceTierKey.String("default")
+)
+
+// Namespace: openshift
+const (
+ // OpenShiftClusterquotaNameKey is the attribute Key conforming to the
+ // "openshift.clusterquota.name" semantic conventions. It represents the name of
+ // the cluster quota.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "opentelemetry"
+ OpenShiftClusterquotaNameKey = attribute.Key("openshift.clusterquota.name")
+
+ // OpenShiftClusterquotaUIDKey is the attribute Key conforming to the
+ // "openshift.clusterquota.uid" semantic conventions. It represents the UID of
+ // the cluster quota.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "275ecb36-5aa8-4c2a-9c47-d8bb681b9aff"
+ OpenShiftClusterquotaUIDKey = attribute.Key("openshift.clusterquota.uid")
+)
+
+// OpenShiftClusterquotaName returns an attribute KeyValue conforming to the
+// "openshift.clusterquota.name" semantic conventions. It represents the name of
+// the cluster quota.
+func OpenShiftClusterquotaName(val string) attribute.KeyValue {
+ return OpenShiftClusterquotaNameKey.String(val)
+}
+
+// OpenShiftClusterquotaUID returns an attribute KeyValue conforming to the
+// "openshift.clusterquota.uid" semantic conventions. It represents the UID of
+// the cluster quota.
+func OpenShiftClusterquotaUID(val string) attribute.KeyValue {
+ return OpenShiftClusterquotaUIDKey.String(val)
+}
+
+// Namespace: opentracing
+const (
+ // OpenTracingRefTypeKey is the attribute Key conforming to the
+ // "opentracing.ref_type" semantic conventions. It represents the parent-child
+ // Reference type.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ // Note: The causal relationship between a child Span and a parent Span.
+ OpenTracingRefTypeKey = attribute.Key("opentracing.ref_type")
+)
+
+// Enum values for opentracing.ref_type
+var (
+ // The parent Span depends on the child Span in some capacity
+ // Stability: development
+ OpenTracingRefTypeChildOf = OpenTracingRefTypeKey.String("child_of")
+ // The parent Span doesn't depend in any way on the result of the child Span
+ // Stability: development
+ OpenTracingRefTypeFollowsFrom = OpenTracingRefTypeKey.String("follows_from")
+)
+
+// Namespace: oracle
+const (
+ // OracleDBDomainKey is the attribute Key conforming to the "oracle.db.domain"
+ // semantic conventions. It represents the database domain associated with the
+ // connection.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "example.com", "corp.internal", "prod.db.local"
+ // Note: This attribute SHOULD be set to the value of the `DB_DOMAIN`
+ // initialization parameter,
+ // as exposed in `v$parameter`. `DB_DOMAIN` defines the domain portion of the
+ // global
+ // database name and SHOULD be configured when a database is, or may become,
+ // part of a
+ // distributed environment. Its value consists of one or more valid identifiers
+ // (alphanumeric ASCII characters) separated by periods.
+ OracleDBDomainKey = attribute.Key("oracle.db.domain")
+
+ // OracleDBInstanceNameKey is the attribute Key conforming to the
+ // "oracle.db.instance.name" semantic conventions. It represents the instance
+ // name associated with the connection in an Oracle Real Application Clusters
+ // environment.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "ORCL1", "ORCL2", "ORCL3"
+ // Note: There can be multiple instances associated with a single database
+ // service. It indicates the
+ // unique instance name to which the connection is currently bound. For non-RAC
+ // databases, this value
+ // defaults to the `oracle.db.name`.
+ OracleDBInstanceNameKey = attribute.Key("oracle.db.instance.name")
+
+ // OracleDBNameKey is the attribute Key conforming to the "oracle.db.name"
+ // semantic conventions. It represents the database name associated with the
+ // connection.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "ORCL1", "FREE"
+ // Note: This attribute SHOULD be set to the value of the parameter `DB_NAME`
+ // exposed in `v$parameter`.
+ OracleDBNameKey = attribute.Key("oracle.db.name")
+
+ // OracleDBPdbKey is the attribute Key conforming to the "oracle.db.pdb"
+ // semantic conventions. It represents the pluggable database (PDB) name
+ // associated with the connection.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "PDB1", "FREEPDB"
+ // Note: This attribute SHOULD reflect the PDB that the session is currently
+ // connected to.
+ // If instrumentation cannot reliably obtain the active PDB name for each
+ // operation
+ // without issuing an additional query (such as `SELECT SYS_CONTEXT`), it is
+ // RECOMMENDED to fall back to the PDB name specified at connection
+ // establishment.
+ OracleDBPdbKey = attribute.Key("oracle.db.pdb")
+
+ // OracleDBServiceKey is the attribute Key conforming to the "oracle.db.service"
+ // semantic conventions. It represents the service name currently associated
+ // with the database connection.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "order-processing-service", "db_low.adb.oraclecloud.com",
+ // "db_high.adb.oraclecloud.com"
+ // Note: The effective service name for a connection can change during its
+ // lifetime,
+ // for example after executing sql, `ALTER SESSION`. If an instrumentation
+ // cannot reliably
+ // obtain the current service name for each operation without issuing an
+ // additional
+ // query (such as `SELECT SYS_CONTEXT`), it is RECOMMENDED to fall back to the
+ // service name originally provided at connection establishment.
+ OracleDBServiceKey = attribute.Key("oracle.db.service")
+)
+
+// OracleDBDomain returns an attribute KeyValue conforming to the
+// "oracle.db.domain" semantic conventions. It represents the database domain
+// associated with the connection.
+func OracleDBDomain(val string) attribute.KeyValue {
+ return OracleDBDomainKey.String(val)
+}
+
+// OracleDBInstanceName returns an attribute KeyValue conforming to the
+// "oracle.db.instance.name" semantic conventions. It represents the instance
+// name associated with the connection in an Oracle Real Application Clusters
+// environment.
+func OracleDBInstanceName(val string) attribute.KeyValue {
+ return OracleDBInstanceNameKey.String(val)
+}
+
+// OracleDBName returns an attribute KeyValue conforming to the "oracle.db.name"
+// semantic conventions. It represents the database name associated with the
+// connection.
+func OracleDBName(val string) attribute.KeyValue {
+ return OracleDBNameKey.String(val)
+}
+
+// OracleDBPdb returns an attribute KeyValue conforming to the "oracle.db.pdb"
+// semantic conventions. It represents the pluggable database (PDB) name
+// associated with the connection.
+func OracleDBPdb(val string) attribute.KeyValue {
+ return OracleDBPdbKey.String(val)
+}
+
+// OracleDBService returns an attribute KeyValue conforming to the
+// "oracle.db.service" semantic conventions. It represents the service name
+// currently associated with the database connection.
+func OracleDBService(val string) attribute.KeyValue {
+ return OracleDBServiceKey.String(val)
+}
+
+// Namespace: oracle_cloud
+const (
+ // OracleCloudRealmKey is the attribute Key conforming to the
+ // "oracle_cloud.realm" semantic conventions. It represents the OCI realm
+ // identifier that indicates the isolated partition in which the tenancy and its
+ // resources reside.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "oc1", "oc2"
+ // Note: See [OCI documentation on realms]
+ //
+ // [OCI documentation on realms]: https://docs.oracle.com/iaas/Content/General/Concepts/regions.htm
+ OracleCloudRealmKey = attribute.Key("oracle_cloud.realm")
+)
+
+// OracleCloudRealm returns an attribute KeyValue conforming to the
+// "oracle_cloud.realm" semantic conventions. It represents the OCI realm
+// identifier that indicates the isolated partition in which the tenancy and its
+// resources reside.
+func OracleCloudRealm(val string) attribute.KeyValue {
+ return OracleCloudRealmKey.String(val)
+}
+
+// Namespace: os
+const (
+ // OSBuildIDKey is the attribute Key conforming to the "os.build_id" semantic
+ // conventions. It represents the unique identifier for a particular build or
+ // compilation of the operating system.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "TQ3C.230805.001.B2", "20E247", "22621"
+ OSBuildIDKey = attribute.Key("os.build_id")
+
+ // OSDescriptionKey is the attribute Key conforming to the "os.description"
+ // semantic conventions. It represents the human readable (not intended to be
+ // parsed) OS version information, like e.g. reported by `ver` or
+ // `lsb_release -a` commands.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "Microsoft Windows [Version 10.0.18363.778]", "Ubuntu 18.04.1 LTS"
+ OSDescriptionKey = attribute.Key("os.description")
+
+ // OSNameKey is the attribute Key conforming to the "os.name" semantic
+ // conventions. It represents the human readable operating system name.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "iOS", "Android", "Ubuntu"
+ OSNameKey = attribute.Key("os.name")
+
+ // OSTypeKey is the attribute Key conforming to the "os.type" semantic
+ // conventions. It represents the operating system type.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ OSTypeKey = attribute.Key("os.type")
+
+ // OSVersionKey is the attribute Key conforming to the "os.version" semantic
+ // conventions. It represents the version string of the operating system as
+ // defined in [Version Attributes].
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "14.2.1", "18.04.1"
+ //
+ // [Version Attributes]: /docs/resource/README.md#version-attributes
+ OSVersionKey = attribute.Key("os.version")
+)
+
+// OSBuildID returns an attribute KeyValue conforming to the "os.build_id"
+// semantic conventions. It represents the unique identifier for a particular
+// build or compilation of the operating system.
+func OSBuildID(val string) attribute.KeyValue {
+ return OSBuildIDKey.String(val)
+}
+
+// OSDescription returns an attribute KeyValue conforming to the "os.description"
+// semantic conventions. It represents the human readable (not intended to be
+// parsed) OS version information, like e.g. reported by `ver` or
+// `lsb_release -a` commands.
+func OSDescription(val string) attribute.KeyValue {
+ return OSDescriptionKey.String(val)
+}
+
+// OSName returns an attribute KeyValue conforming to the "os.name" semantic
+// conventions. It represents the human readable operating system name.
+func OSName(val string) attribute.KeyValue {
+ return OSNameKey.String(val)
+}
+
+// OSVersion returns an attribute KeyValue conforming to the "os.version"
+// semantic conventions. It represents the version string of the operating system
+// as defined in [Version Attributes].
+//
+// [Version Attributes]: /docs/resource/README.md#version-attributes
+func OSVersion(val string) attribute.KeyValue {
+ return OSVersionKey.String(val)
+}
+
+// Enum values for os.type
+var (
+ // Microsoft Windows
+ // Stability: development
+ OSTypeWindows = OSTypeKey.String("windows")
+ // Linux
+ // Stability: development
+ OSTypeLinux = OSTypeKey.String("linux")
+ // Apple Darwin
+ // Stability: development
+ OSTypeDarwin = OSTypeKey.String("darwin")
+ // FreeBSD
+ // Stability: development
+ OSTypeFreeBSD = OSTypeKey.String("freebsd")
+ // NetBSD
+ // Stability: development
+ OSTypeNetBSD = OSTypeKey.String("netbsd")
+ // OpenBSD
+ // Stability: development
+ OSTypeOpenBSD = OSTypeKey.String("openbsd")
+ // DragonFly BSD
+ // Stability: development
+ OSTypeDragonflyBSD = OSTypeKey.String("dragonflybsd")
+ // HP-UX (Hewlett Packard Unix)
+ // Stability: development
+ OSTypeHPUX = OSTypeKey.String("hpux")
+ // AIX (Advanced Interactive eXecutive)
+ // Stability: development
+ OSTypeAIX = OSTypeKey.String("aix")
+ // SunOS, Oracle Solaris
+ // Stability: development
+ OSTypeSolaris = OSTypeKey.String("solaris")
+ // IBM z/OS
+ // Stability: development
+ OSTypeZOS = OSTypeKey.String("zos")
+)
+
+// Namespace: otel
+const (
+ // OTelComponentNameKey is the attribute Key conforming to the
+ // "otel.component.name" semantic conventions. It represents a name uniquely
+ // identifying the instance of the OpenTelemetry component within its containing
+ // SDK instance.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "otlp_grpc_span_exporter/0", "custom-name"
+ // Note: Implementations SHOULD ensure a low cardinality for this attribute,
+ // even across application or SDK restarts.
+ // E.g. implementations MUST NOT use UUIDs as values for this attribute.
+ //
+ // Implementations MAY achieve these goals by following a
+ // `/` pattern, e.g.
+ // `batching_span_processor/0`.
+ // Hereby `otel.component.type` refers to the corresponding attribute value of
+ // the component.
+ //
+ // The value of `instance-counter` MAY be automatically assigned by the
+ // component and uniqueness within the enclosing SDK instance MUST be
+ // guaranteed.
+ // For example, `` MAY be implemented by using a monotonically
+ // increasing counter (starting with `0`), which is incremented every time an
+ // instance of the given component type is started.
+ //
+ // With this implementation, for example the first Batching Span Processor would
+ // have `batching_span_processor/0`
+ // as `otel.component.name`, the second one `batching_span_processor/1` and so
+ // on.
+ // These values will therefore be reused in the case of an application restart.
+ OTelComponentNameKey = attribute.Key("otel.component.name")
+
+ // OTelComponentTypeKey is the attribute Key conforming to the
+ // "otel.component.type" semantic conventions. It represents a name identifying
+ // the type of the OpenTelemetry component.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "batching_span_processor", "com.example.MySpanExporter"
+ // Note: If none of the standardized values apply, implementations SHOULD use
+ // the language-defined name of the type.
+ // E.g. for Java the fully qualified classname SHOULD be used in this case.
+ OTelComponentTypeKey = attribute.Key("otel.component.type")
+
+ // OTelEventNameKey is the attribute Key conforming to the "otel.event.name"
+ // semantic conventions. It represents the identifies the class / type of event.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "browser.mouse.click", "device.app.lifecycle"
+ // Note: This attribute SHOULD be used by non-OTLP exporters when destination
+ // does not support `EventName` or equivalent field. This attribute MAY be used
+ // by applications using existing logging libraries so that it can be used to
+ // set the `EventName` field by Collector or SDK components.
+ OTelEventNameKey = attribute.Key("otel.event.name")
+
+ // OTelScopeNameKey is the attribute Key conforming to the "otel.scope.name"
+ // semantic conventions. It represents the name of the instrumentation scope - (
+ // `InstrumentationScope.Name` in OTLP).
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ //
+ // Examples: "io.opentelemetry.contrib.mongodb"
+ OTelScopeNameKey = attribute.Key("otel.scope.name")
+
+ // OTelScopeSchemaURLKey is the attribute Key conforming to the
+ // "otel.scope.schema_url" semantic conventions. It represents the schema URL of
+ // the instrumentation scope.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "https://opentelemetry.io/schemas/1.31.0"
+ OTelScopeSchemaURLKey = attribute.Key("otel.scope.schema_url")
+
+ // OTelScopeVersionKey is the attribute Key conforming to the
+ // "otel.scope.version" semantic conventions. It represents the version of the
+ // instrumentation scope - (`InstrumentationScope.Version` in OTLP).
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ //
+ // Examples: "1.0.0"
+ OTelScopeVersionKey = attribute.Key("otel.scope.version")
+
+ // OTelSpanParentOriginKey is the attribute Key conforming to the
+ // "otel.span.parent.origin" semantic conventions. It represents the determines
+ // whether the span has a parent span, and if so,
+ // [whether it is a remote parent].
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ //
+ // [whether it is a remote parent]: https://opentelemetry.io/docs/specs/otel/trace/api/#isremote
+ OTelSpanParentOriginKey = attribute.Key("otel.span.parent.origin")
+
+ // OTelSpanSamplingResultKey is the attribute Key conforming to the
+ // "otel.span.sampling_result" semantic conventions. It represents the result
+ // value of the sampler for this span.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ OTelSpanSamplingResultKey = attribute.Key("otel.span.sampling_result")
+
+ // OTelStatusCodeKey is the attribute Key conforming to the "otel.status_code"
+ // semantic conventions. It represents the name of the code, either "OK" or
+ // "ERROR". MUST NOT be set if the status code is UNSET.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ //
+ // Examples:
+ OTelStatusCodeKey = attribute.Key("otel.status_code")
+
+ // OTelStatusDescriptionKey is the attribute Key conforming to the
+ // "otel.status_description" semantic conventions. It represents the description
+ // of the Status if it has a value, otherwise not set.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ //
+ // Examples: "resource not found"
+ OTelStatusDescriptionKey = attribute.Key("otel.status_description")
+)
+
+// OTelComponentName returns an attribute KeyValue conforming to the
+// "otel.component.name" semantic conventions. It represents a name uniquely
+// identifying the instance of the OpenTelemetry component within its containing
+// SDK instance.
+func OTelComponentName(val string) attribute.KeyValue {
+ return OTelComponentNameKey.String(val)
+}
+
+// OTelEventName returns an attribute KeyValue conforming to the
+// "otel.event.name" semantic conventions. It represents the identifies the class
+// / type of event.
+func OTelEventName(val string) attribute.KeyValue {
+ return OTelEventNameKey.String(val)
+}
+
+// OTelScopeName returns an attribute KeyValue conforming to the
+// "otel.scope.name" semantic conventions. It represents the name of the
+// instrumentation scope - (`InstrumentationScope.Name` in OTLP).
+func OTelScopeName(val string) attribute.KeyValue {
+ return OTelScopeNameKey.String(val)
+}
+
+// OTelScopeSchemaURL returns an attribute KeyValue conforming to the
+// "otel.scope.schema_url" semantic conventions. It represents the schema URL of
+// the instrumentation scope.
+func OTelScopeSchemaURL(val string) attribute.KeyValue {
+ return OTelScopeSchemaURLKey.String(val)
+}
+
+// OTelScopeVersion returns an attribute KeyValue conforming to the
+// "otel.scope.version" semantic conventions. It represents the version of the
+// instrumentation scope - (`InstrumentationScope.Version` in OTLP).
+func OTelScopeVersion(val string) attribute.KeyValue {
+ return OTelScopeVersionKey.String(val)
+}
+
+// OTelStatusDescription returns an attribute KeyValue conforming to the
+// "otel.status_description" semantic conventions. It represents the description
+// of the Status if it has a value, otherwise not set.
+func OTelStatusDescription(val string) attribute.KeyValue {
+ return OTelStatusDescriptionKey.String(val)
+}
+
+// Enum values for otel.component.type
+var (
+ // The builtin SDK batching span processor
+ //
+ // Stability: development
+ OTelComponentTypeBatchingSpanProcessor = OTelComponentTypeKey.String("batching_span_processor")
+ // The builtin SDK simple span processor
+ //
+ // Stability: development
+ OTelComponentTypeSimpleSpanProcessor = OTelComponentTypeKey.String("simple_span_processor")
+ // The builtin SDK batching log record processor
+ //
+ // Stability: development
+ OTelComponentTypeBatchingLogProcessor = OTelComponentTypeKey.String("batching_log_processor")
+ // The builtin SDK simple log record processor
+ //
+ // Stability: development
+ OTelComponentTypeSimpleLogProcessor = OTelComponentTypeKey.String("simple_log_processor")
+ // OTLP span exporter over gRPC with protobuf serialization
+ //
+ // Stability: development
+ OTelComponentTypeOtlpGRPCSpanExporter = OTelComponentTypeKey.String("otlp_grpc_span_exporter")
+ // OTLP span exporter over HTTP with protobuf serialization
+ //
+ // Stability: development
+ OTelComponentTypeOtlpHTTPSpanExporter = OTelComponentTypeKey.String("otlp_http_span_exporter")
+ // OTLP span exporter over HTTP with JSON serialization
+ //
+ // Stability: development
+ OTelComponentTypeOtlpHTTPJSONSpanExporter = OTelComponentTypeKey.String("otlp_http_json_span_exporter")
+ // Zipkin span exporter over HTTP
+ //
+ // Stability: development
+ OTelComponentTypeZipkinHTTPSpanExporter = OTelComponentTypeKey.String("zipkin_http_span_exporter")
+ // OTLP log record exporter over gRPC with protobuf serialization
+ //
+ // Stability: development
+ OTelComponentTypeOtlpGRPCLogExporter = OTelComponentTypeKey.String("otlp_grpc_log_exporter")
+ // OTLP log record exporter over HTTP with protobuf serialization
+ //
+ // Stability: development
+ OTelComponentTypeOtlpHTTPLogExporter = OTelComponentTypeKey.String("otlp_http_log_exporter")
+ // OTLP log record exporter over HTTP with JSON serialization
+ //
+ // Stability: development
+ OTelComponentTypeOtlpHTTPJSONLogExporter = OTelComponentTypeKey.String("otlp_http_json_log_exporter")
+ // The builtin SDK periodically exporting metric reader
+ //
+ // Stability: development
+ OTelComponentTypePeriodicMetricReader = OTelComponentTypeKey.String("periodic_metric_reader")
+ // OTLP metric exporter over gRPC with protobuf serialization
+ //
+ // Stability: development
+ OTelComponentTypeOtlpGRPCMetricExporter = OTelComponentTypeKey.String("otlp_grpc_metric_exporter")
+ // OTLP metric exporter over HTTP with protobuf serialization
+ //
+ // Stability: development
+ OTelComponentTypeOtlpHTTPMetricExporter = OTelComponentTypeKey.String("otlp_http_metric_exporter")
+ // OTLP metric exporter over HTTP with JSON serialization
+ //
+ // Stability: development
+ OTelComponentTypeOtlpHTTPJSONMetricExporter = OTelComponentTypeKey.String("otlp_http_json_metric_exporter")
+ // Prometheus metric exporter over HTTP with the default text-based format
+ //
+ // Stability: development
+ OTelComponentTypePrometheusHTTPTextMetricExporter = OTelComponentTypeKey.String("prometheus_http_text_metric_exporter")
+)
+
+// Enum values for otel.span.parent.origin
+var (
+ // The span does not have a parent, it is a root span
+ // Stability: development
+ OTelSpanParentOriginNone = OTelSpanParentOriginKey.String("none")
+ // The span has a parent and the parent's span context [isRemote()] is false
+ // Stability: development
+ //
+ // [isRemote()]: https://opentelemetry.io/docs/specs/otel/trace/api/#isremote
+ OTelSpanParentOriginLocal = OTelSpanParentOriginKey.String("local")
+ // The span has a parent and the parent's span context [isRemote()] is true
+ // Stability: development
+ //
+ // [isRemote()]: https://opentelemetry.io/docs/specs/otel/trace/api/#isremote
+ OTelSpanParentOriginRemote = OTelSpanParentOriginKey.String("remote")
+)
+
+// Enum values for otel.span.sampling_result
+var (
+ // The span is not sampled and not recording
+ // Stability: development
+ OTelSpanSamplingResultDrop = OTelSpanSamplingResultKey.String("DROP")
+ // The span is not sampled, but recording
+ // Stability: development
+ OTelSpanSamplingResultRecordOnly = OTelSpanSamplingResultKey.String("RECORD_ONLY")
+ // The span is sampled and recording
+ // Stability: development
+ OTelSpanSamplingResultRecordAndSample = OTelSpanSamplingResultKey.String("RECORD_AND_SAMPLE")
+)
+
+// Enum values for otel.status_code
+var (
+ // The operation has been validated by an Application developer or Operator to
+ // have completed successfully.
+ // Stability: stable
+ OTelStatusCodeOk = OTelStatusCodeKey.String("OK")
+ // The operation contains an error.
+ // Stability: stable
+ OTelStatusCodeError = OTelStatusCodeKey.String("ERROR")
+)
+
+// Namespace: pprof
+const (
+ // PprofLocationIsFoldedKey is the attribute Key conforming to the
+ // "pprof.location.is_folded" semantic conventions. It represents the provides
+ // an indication that multiple symbols map to this location's address, for
+ // example due to identical code folding by the linker. In that case the line
+ // information represents one of the multiple symbols. This field must be
+ // recomputed when the symbolization state of the profile changes.
+ //
+ // Type: boolean
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ PprofLocationIsFoldedKey = attribute.Key("pprof.location.is_folded")
+
+ // PprofMappingHasFilenamesKey is the attribute Key conforming to the
+ // "pprof.mapping.has_filenames" semantic conventions. It represents the
+ // indicates that there are filenames related to this mapping.
+ //
+ // Type: boolean
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ PprofMappingHasFilenamesKey = attribute.Key("pprof.mapping.has_filenames")
+
+ // PprofMappingHasFunctionsKey is the attribute Key conforming to the
+ // "pprof.mapping.has_functions" semantic conventions. It represents the
+ // indicates that there are functions related to this mapping.
+ //
+ // Type: boolean
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ PprofMappingHasFunctionsKey = attribute.Key("pprof.mapping.has_functions")
+
+ // PprofMappingHasInlineFramesKey is the attribute Key conforming to the
+ // "pprof.mapping.has_inline_frames" semantic conventions. It represents the
+ // indicates that there are inline frames related to this mapping.
+ //
+ // Type: boolean
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ PprofMappingHasInlineFramesKey = attribute.Key("pprof.mapping.has_inline_frames")
+
+ // PprofMappingHasLineNumbersKey is the attribute Key conforming to the
+ // "pprof.mapping.has_line_numbers" semantic conventions. It represents the
+ // indicates that there are line numbers related to this mapping.
+ //
+ // Type: boolean
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ PprofMappingHasLineNumbersKey = attribute.Key("pprof.mapping.has_line_numbers")
+
+ // PprofProfileCommentKey is the attribute Key conforming to the
+ // "pprof.profile.comment" semantic conventions. It represents the free-form
+ // text associated with the profile. This field should not be used to store any
+ // machine-readable information, it is only for human-friendly content.
+ //
+ // Type: string[]
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "hello world", "bazinga"
+ PprofProfileCommentKey = attribute.Key("pprof.profile.comment")
+
+ // PprofProfileDocURLKey is the attribute Key conforming to the
+ // "pprof.profile.doc_url" semantic conventions. It represents the documentation
+ // link for this profile type.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "http://pprof.example.com/cpu-profile.html"
+ // Note: The URL must be absolute and may be missing if the profile was
+ // generated by code that did not supply a link
+ PprofProfileDocURLKey = attribute.Key("pprof.profile.doc_url")
+
+ // PprofProfileDropFramesKey is the attribute Key conforming to the
+ // "pprof.profile.drop_frames" semantic conventions. It represents the frames
+ // with Function.function_name fully matching the regexp will be dropped from
+ // the samples, along with their successors.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "/foobar/"
+ PprofProfileDropFramesKey = attribute.Key("pprof.profile.drop_frames")
+
+ // PprofProfileKeepFramesKey is the attribute Key conforming to the
+ // "pprof.profile.keep_frames" semantic conventions. It represents the frames
+ // with Function.function_name fully matching the regexp will be kept, even if
+ // it matches drop_frames.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "/bazinga/"
+ PprofProfileKeepFramesKey = attribute.Key("pprof.profile.keep_frames")
+
+ // PprofScopeDefaultSampleTypeKey is the attribute Key conforming to the
+ // "pprof.scope.default_sample_type" semantic conventions. It represents the
+ // records the pprof's default_sample_type in the original profile. Not set if
+ // the default sample type was missing.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "cpu"
+ // Note: This attribute, if present, MUST be set at the scope level
+ // (resource_profiles[].scope_profiles[].scope.attributes[]).
+ PprofScopeDefaultSampleTypeKey = attribute.Key("pprof.scope.default_sample_type")
+
+ // PprofScopeSampleTypeOrderKey is the attribute Key conforming to the
+ // "pprof.scope.sample_type_order" semantic conventions. It represents the
+ // records the indexes of the sample types in the original profile.
+ //
+ // Type: int[]
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 3, 0, 1, 2
+ // Note: This attribute, if present, MUST be set at the scope level
+ // (resource_profiles[].scope_profiles[].scope.attributes[]).
+ PprofScopeSampleTypeOrderKey = attribute.Key("pprof.scope.sample_type_order")
+)
+
+// PprofLocationIsFolded returns an attribute KeyValue conforming to the
+// "pprof.location.is_folded" semantic conventions. It represents the provides an
+// indication that multiple symbols map to this location's address, for example
+// due to identical code folding by the linker. In that case the line information
+// represents one of the multiple symbols. This field must be recomputed when the
+// symbolization state of the profile changes.
+func PprofLocationIsFolded(val bool) attribute.KeyValue {
+ return PprofLocationIsFoldedKey.Bool(val)
+}
+
+// PprofMappingHasFilenames returns an attribute KeyValue conforming to the
+// "pprof.mapping.has_filenames" semantic conventions. It represents the
+// indicates that there are filenames related to this mapping.
+func PprofMappingHasFilenames(val bool) attribute.KeyValue {
+ return PprofMappingHasFilenamesKey.Bool(val)
+}
+
+// PprofMappingHasFunctions returns an attribute KeyValue conforming to the
+// "pprof.mapping.has_functions" semantic conventions. It represents the
+// indicates that there are functions related to this mapping.
+func PprofMappingHasFunctions(val bool) attribute.KeyValue {
+ return PprofMappingHasFunctionsKey.Bool(val)
+}
+
+// PprofMappingHasInlineFrames returns an attribute KeyValue conforming to the
+// "pprof.mapping.has_inline_frames" semantic conventions. It represents the
+// indicates that there are inline frames related to this mapping.
+func PprofMappingHasInlineFrames(val bool) attribute.KeyValue {
+ return PprofMappingHasInlineFramesKey.Bool(val)
+}
+
+// PprofMappingHasLineNumbers returns an attribute KeyValue conforming to the
+// "pprof.mapping.has_line_numbers" semantic conventions. It represents the
+// indicates that there are line numbers related to this mapping.
+func PprofMappingHasLineNumbers(val bool) attribute.KeyValue {
+ return PprofMappingHasLineNumbersKey.Bool(val)
+}
+
+// PprofProfileComment returns an attribute KeyValue conforming to the
+// "pprof.profile.comment" semantic conventions. It represents the free-form text
+// associated with the profile. This field should not be used to store any
+// machine-readable information, it is only for human-friendly content.
+func PprofProfileComment(val ...string) attribute.KeyValue {
+ return PprofProfileCommentKey.StringSlice(val)
+}
+
+// PprofProfileDocURL returns an attribute KeyValue conforming to the
+// "pprof.profile.doc_url" semantic conventions. It represents the documentation
+// link for this profile type.
+func PprofProfileDocURL(val string) attribute.KeyValue {
+ return PprofProfileDocURLKey.String(val)
+}
+
+// PprofProfileDropFrames returns an attribute KeyValue conforming to the
+// "pprof.profile.drop_frames" semantic conventions. It represents the frames
+// with Function.function_name fully matching the regexp will be dropped from the
+// samples, along with their successors.
+func PprofProfileDropFrames(val string) attribute.KeyValue {
+ return PprofProfileDropFramesKey.String(val)
+}
+
+// PprofProfileKeepFrames returns an attribute KeyValue conforming to the
+// "pprof.profile.keep_frames" semantic conventions. It represents the frames
+// with Function.function_name fully matching the regexp will be kept, even if it
+// matches drop_frames.
+func PprofProfileKeepFrames(val string) attribute.KeyValue {
+ return PprofProfileKeepFramesKey.String(val)
+}
+
+// PprofScopeDefaultSampleType returns an attribute KeyValue conforming to the
+// "pprof.scope.default_sample_type" semantic conventions. It represents the
+// records the pprof's default_sample_type in the original profile. Not set if
+// the default sample type was missing.
+func PprofScopeDefaultSampleType(val string) attribute.KeyValue {
+ return PprofScopeDefaultSampleTypeKey.String(val)
+}
+
+// PprofScopeSampleTypeOrder returns an attribute KeyValue conforming to the
+// "pprof.scope.sample_type_order" semantic conventions. It represents the
+// records the indexes of the sample types in the original profile.
+func PprofScopeSampleTypeOrder(val ...int) attribute.KeyValue {
+ return PprofScopeSampleTypeOrderKey.IntSlice(val)
+}
+
+// Namespace: process
+const (
+ // ProcessArgsCountKey is the attribute Key conforming to the
+ // "process.args_count" semantic conventions. It represents the length of the
+ // process.command_args array.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 4
+ // Note: This field can be useful for querying or performing bucket analysis on
+ // how many arguments were provided to start a process. More arguments may be an
+ // indication of suspicious activity.
+ ProcessArgsCountKey = attribute.Key("process.args_count")
+
+ // ProcessCommandKey is the attribute Key conforming to the "process.command"
+ // semantic conventions. It represents the command used to launch the process
+ // (i.e. the command name). On Linux based systems, can be set to the zeroth
+ // string in `proc/[pid]/cmdline`. On Windows, can be set to the first parameter
+ // extracted from `GetCommandLineW`.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "cmd/otelcol"
+ ProcessCommandKey = attribute.Key("process.command")
+
+ // ProcessCommandArgsKey is the attribute Key conforming to the
+ // "process.command_args" semantic conventions. It represents the all the
+ // command arguments (including the command/executable itself) as received by
+ // the process. On Linux-based systems (and some other Unixoid systems
+ // supporting procfs), can be set according to the list of null-delimited
+ // strings extracted from `proc/[pid]/cmdline`. For libc-based executables, this
+ // would be the full argv vector passed to `main`. SHOULD NOT be collected by
+ // default unless there is sanitization that excludes sensitive data.
+ //
+ // Type: string[]
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "cmd/otecol", "--config=config.yaml"
+ ProcessCommandArgsKey = attribute.Key("process.command_args")
+
+ // ProcessCommandLineKey is the attribute Key conforming to the
+ // "process.command_line" semantic conventions. It represents the full command
+ // used to launch the process as a single string representing the full command.
+ // On Windows, can be set to the result of `GetCommandLineW`. Do not set this if
+ // you have to assemble it just for monitoring; use `process.command_args`
+ // instead. SHOULD NOT be collected by default unless there is sanitization that
+ // excludes sensitive data.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "C:\cmd\otecol --config="my directory\config.yaml""
+ ProcessCommandLineKey = attribute.Key("process.command_line")
+
+ // ProcessContextSwitchTypeKey is the attribute Key conforming to the
+ // "process.context_switch.type" semantic conventions. It represents the
+ // specifies whether the context switches for this data point were voluntary or
+ // involuntary.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ ProcessContextSwitchTypeKey = attribute.Key("process.context_switch.type")
+
+ // ProcessCreationTimeKey is the attribute Key conforming to the
+ // "process.creation.time" semantic conventions. It represents the date and time
+ // the process was created, in ISO 8601 format.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "2023-11-21T09:25:34.853Z"
+ ProcessCreationTimeKey = attribute.Key("process.creation.time")
+
+ // ProcessExecutableBuildIDGNUKey is the attribute Key conforming to the
+ // "process.executable.build_id.gnu" semantic conventions. It represents the GNU
+ // build ID as found in the `.note.gnu.build-id` ELF section (hex string).
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "c89b11207f6479603b0d49bf291c092c2b719293"
+ ProcessExecutableBuildIDGNUKey = attribute.Key("process.executable.build_id.gnu")
+
+ // ProcessExecutableBuildIDGoKey is the attribute Key conforming to the
+ // "process.executable.build_id.go" semantic conventions. It represents the Go
+ // build ID as retrieved by `go tool buildid `.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ // "foh3mEXu7BLZjsN9pOwG/kATcXlYVCDEFouRMQed_/WwRFB1hPo9LBkekthSPG/x8hMC8emW2cCjXD0_1aY"
+ ProcessExecutableBuildIDGoKey = attribute.Key("process.executable.build_id.go")
+
+ // ProcessExecutableBuildIDHtlhashKey is the attribute Key conforming to the
+ // "process.executable.build_id.htlhash" semantic conventions. It represents the
+ // profiling specific build ID for executables. See the OTel specification for
+ // Profiles for more information.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "600DCAFE4A110000F2BF38C493F5FB92"
+ ProcessExecutableBuildIDHtlhashKey = attribute.Key("process.executable.build_id.htlhash")
+
+ // ProcessExecutableNameKey is the attribute Key conforming to the
+ // "process.executable.name" semantic conventions. It represents the name of the
+ // process executable. On Linux based systems, this SHOULD be set to the base
+ // name of the target of `/proc/[pid]/exe`. On Windows, this SHOULD be set to
+ // the base name of `GetProcessImageFileNameW`.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "otelcol"
+ ProcessExecutableNameKey = attribute.Key("process.executable.name")
+
+ // ProcessExecutablePathKey is the attribute Key conforming to the
+ // "process.executable.path" semantic conventions. It represents the full path
+ // to the process executable. On Linux based systems, can be set to the target
+ // of `proc/[pid]/exe`. On Windows, can be set to the result of
+ // `GetProcessImageFileNameW`.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "/usr/bin/cmd/otelcol"
+ ProcessExecutablePathKey = attribute.Key("process.executable.path")
+
+ // ProcessExitCodeKey is the attribute Key conforming to the "process.exit.code"
+ // semantic conventions. It represents the exit code of the process.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 127
+ ProcessExitCodeKey = attribute.Key("process.exit.code")
+
+ // ProcessExitTimeKey is the attribute Key conforming to the "process.exit.time"
+ // semantic conventions. It represents the date and time the process exited, in
+ // ISO 8601 format.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "2023-11-21T09:26:12.315Z"
+ ProcessExitTimeKey = attribute.Key("process.exit.time")
+
+ // ProcessGroupLeaderPIDKey is the attribute Key conforming to the
+ // "process.group_leader.pid" semantic conventions. It represents the PID of the
+ // process's group leader. This is also the process group ID (PGID) of the
+ // process.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 23
+ ProcessGroupLeaderPIDKey = attribute.Key("process.group_leader.pid")
+
+ // ProcessInteractiveKey is the attribute Key conforming to the
+ // "process.interactive" semantic conventions. It represents the whether the
+ // process is connected to an interactive shell.
+ //
+ // Type: boolean
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ ProcessInteractiveKey = attribute.Key("process.interactive")
+
+ // ProcessLinuxCgroupKey is the attribute Key conforming to the
+ // "process.linux.cgroup" semantic conventions. It represents the control group
+ // associated with the process.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "1:name=systemd:/user.slice/user-1000.slice/session-3.scope",
+ // "0::/user.slice/user-1000.slice/user@1000.service/tmux-spawn-0267755b-4639-4a27-90ed-f19f88e53748.scope"
+ // Note: Control groups (cgroups) are a kernel feature used to organize and
+ // manage process resources. This attribute provides the path(s) to the
+ // cgroup(s) associated with the process, which should match the contents of the
+ // [/proc/[PID]/cgroup] file.
+ //
+ // [/proc/[PID]/cgroup]: https://man7.org/linux/man-pages/man7/cgroups.7.html
+ ProcessLinuxCgroupKey = attribute.Key("process.linux.cgroup")
+
+ // ProcessOwnerKey is the attribute Key conforming to the "process.owner"
+ // semantic conventions. It represents the username of the user that owns the
+ // process.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "root"
+ ProcessOwnerKey = attribute.Key("process.owner")
+
+ // ProcessParentPIDKey is the attribute Key conforming to the
+ // "process.parent_pid" semantic conventions. It represents the parent Process
+ // identifier (PPID).
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 111
+ ProcessParentPIDKey = attribute.Key("process.parent_pid")
+
+ // ProcessPIDKey is the attribute Key conforming to the "process.pid" semantic
+ // conventions. It represents the process identifier (PID).
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 1234
+ ProcessPIDKey = attribute.Key("process.pid")
+
+ // ProcessRealUserIDKey is the attribute Key conforming to the
+ // "process.real_user.id" semantic conventions. It represents the real user ID
+ // (RUID) of the process.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 1000
+ ProcessRealUserIDKey = attribute.Key("process.real_user.id")
+
+ // ProcessRealUserNameKey is the attribute Key conforming to the
+ // "process.real_user.name" semantic conventions. It represents the username of
+ // the real user of the process.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "operator"
+ ProcessRealUserNameKey = attribute.Key("process.real_user.name")
+
+ // ProcessRuntimeDescriptionKey is the attribute Key conforming to the
+ // "process.runtime.description" semantic conventions. It represents an
+ // additional description about the runtime of the process, for example a
+ // specific vendor customization of the runtime environment.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: Eclipse OpenJ9 Eclipse OpenJ9 VM openj9-0.21.0
+ ProcessRuntimeDescriptionKey = attribute.Key("process.runtime.description")
+
+ // ProcessRuntimeNameKey is the attribute Key conforming to the
+ // "process.runtime.name" semantic conventions. It represents the name of the
+ // runtime of this process.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "OpenJDK Runtime Environment"
+ ProcessRuntimeNameKey = attribute.Key("process.runtime.name")
+
+ // ProcessRuntimeVersionKey is the attribute Key conforming to the
+ // "process.runtime.version" semantic conventions. It represents the version of
+ // the runtime of this process, as returned by the runtime without modification.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 14.0.2
+ ProcessRuntimeVersionKey = attribute.Key("process.runtime.version")
+
+ // ProcessSavedUserIDKey is the attribute Key conforming to the
+ // "process.saved_user.id" semantic conventions. It represents the saved user ID
+ // (SUID) of the process.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 1002
+ ProcessSavedUserIDKey = attribute.Key("process.saved_user.id")
+
+ // ProcessSavedUserNameKey is the attribute Key conforming to the
+ // "process.saved_user.name" semantic conventions. It represents the username of
+ // the saved user.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "operator"
+ ProcessSavedUserNameKey = attribute.Key("process.saved_user.name")
+
+ // ProcessSessionLeaderPIDKey is the attribute Key conforming to the
+ // "process.session_leader.pid" semantic conventions. It represents the PID of
+ // the process's session leader. This is also the session ID (SID) of the
+ // process.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 14
+ ProcessSessionLeaderPIDKey = attribute.Key("process.session_leader.pid")
+
+ // ProcessStateKey is the attribute Key conforming to the "process.state"
+ // semantic conventions. It represents the process state, e.g.,
+ // [Linux Process State Codes].
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "running"
+ //
+ // [Linux Process State Codes]: https://man7.org/linux/man-pages/man1/ps.1.html#PROCESS_STATE_CODES
+ ProcessStateKey = attribute.Key("process.state")
+
+ // ProcessTitleKey is the attribute Key conforming to the "process.title"
+ // semantic conventions. It represents the process title (proctitle).
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "cat /etc/hostname", "xfce4-session", "bash"
+ // Note: In many Unix-like systems, process title (proctitle), is the string
+ // that represents the name or command line of a running process, displayed by
+ // system monitoring tools like ps, top, and htop.
+ ProcessTitleKey = attribute.Key("process.title")
+
+ // ProcessUserIDKey is the attribute Key conforming to the "process.user.id"
+ // semantic conventions. It represents the effective user ID (EUID) of the
+ // process.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 1001
+ ProcessUserIDKey = attribute.Key("process.user.id")
+
+ // ProcessUserNameKey is the attribute Key conforming to the "process.user.name"
+ // semantic conventions. It represents the username of the effective user of the
+ // process.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "root"
+ ProcessUserNameKey = attribute.Key("process.user.name")
+
+ // ProcessVpidKey is the attribute Key conforming to the "process.vpid" semantic
+ // conventions. It represents the virtual process identifier.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 12
+ // Note: The process ID within a PID namespace. This is not necessarily unique
+ // across all processes on the host but it is unique within the process
+ // namespace that the process exists within.
+ ProcessVpidKey = attribute.Key("process.vpid")
+
+ // ProcessWorkingDirectoryKey is the attribute Key conforming to the
+ // "process.working_directory" semantic conventions. It represents the working
+ // directory of the process.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "/root"
+ ProcessWorkingDirectoryKey = attribute.Key("process.working_directory")
+)
+
+// ProcessArgsCount returns an attribute KeyValue conforming to the
+// "process.args_count" semantic conventions. It represents the length of the
+// process.command_args array.
+func ProcessArgsCount(val int) attribute.KeyValue {
+ return ProcessArgsCountKey.Int(val)
+}
+
+// ProcessCommand returns an attribute KeyValue conforming to the
+// "process.command" semantic conventions. It represents the command used to
+// launch the process (i.e. the command name). On Linux based systems, can be set
+// to the zeroth string in `proc/[pid]/cmdline`. On Windows, can be set to the
+// first parameter extracted from `GetCommandLineW`.
+func ProcessCommand(val string) attribute.KeyValue {
+ return ProcessCommandKey.String(val)
+}
+
+// ProcessCommandArgs returns an attribute KeyValue conforming to the
+// "process.command_args" semantic conventions. It represents the all the command
+// arguments (including the command/executable itself) as received by the
+// process. On Linux-based systems (and some other Unixoid systems supporting
+// procfs), can be set according to the list of null-delimited strings extracted
+// from `proc/[pid]/cmdline`. For libc-based executables, this would be the full
+// argv vector passed to `main`. SHOULD NOT be collected by default unless there
+// is sanitization that excludes sensitive data.
+func ProcessCommandArgs(val ...string) attribute.KeyValue {
+ return ProcessCommandArgsKey.StringSlice(val)
+}
+
+// ProcessCommandLine returns an attribute KeyValue conforming to the
+// "process.command_line" semantic conventions. It represents the full command
+// used to launch the process as a single string representing the full command.
+// On Windows, can be set to the result of `GetCommandLineW`. Do not set this if
+// you have to assemble it just for monitoring; use `process.command_args`
+// instead. SHOULD NOT be collected by default unless there is sanitization that
+// excludes sensitive data.
+func ProcessCommandLine(val string) attribute.KeyValue {
+ return ProcessCommandLineKey.String(val)
+}
+
+// ProcessCreationTime returns an attribute KeyValue conforming to the
+// "process.creation.time" semantic conventions. It represents the date and time
+// the process was created, in ISO 8601 format.
+func ProcessCreationTime(val string) attribute.KeyValue {
+ return ProcessCreationTimeKey.String(val)
+}
+
+// ProcessEnvironmentVariable returns an attribute KeyValue conforming to the
+// "process.environment_variable" semantic conventions. It represents the process
+// environment variables, `` being the environment variable name, the value
+// being the environment variable value.
+func ProcessEnvironmentVariable(key string, val string) attribute.KeyValue {
+ return attribute.String("process.environment_variable."+key, val)
+}
+
+// ProcessExecutableBuildIDGNU returns an attribute KeyValue conforming to the
+// "process.executable.build_id.gnu" semantic conventions. It represents the GNU
+// build ID as found in the `.note.gnu.build-id` ELF section (hex string).
+func ProcessExecutableBuildIDGNU(val string) attribute.KeyValue {
+ return ProcessExecutableBuildIDGNUKey.String(val)
+}
+
+// ProcessExecutableBuildIDGo returns an attribute KeyValue conforming to the
+// "process.executable.build_id.go" semantic conventions. It represents the Go
+// build ID as retrieved by `go tool buildid `.
+func ProcessExecutableBuildIDGo(val string) attribute.KeyValue {
+ return ProcessExecutableBuildIDGoKey.String(val)
+}
+
+// ProcessExecutableBuildIDHtlhash returns an attribute KeyValue conforming to
+// the "process.executable.build_id.htlhash" semantic conventions. It represents
+// the profiling specific build ID for executables. See the OTel specification
+// for Profiles for more information.
+func ProcessExecutableBuildIDHtlhash(val string) attribute.KeyValue {
+ return ProcessExecutableBuildIDHtlhashKey.String(val)
+}
+
+// ProcessExecutableName returns an attribute KeyValue conforming to the
+// "process.executable.name" semantic conventions. It represents the name of the
+// process executable. On Linux based systems, this SHOULD be set to the base
+// name of the target of `/proc/[pid]/exe`. On Windows, this SHOULD be set to the
+// base name of `GetProcessImageFileNameW`.
+func ProcessExecutableName(val string) attribute.KeyValue {
+ return ProcessExecutableNameKey.String(val)
+}
+
+// ProcessExecutablePath returns an attribute KeyValue conforming to the
+// "process.executable.path" semantic conventions. It represents the full path to
+// the process executable. On Linux based systems, can be set to the target of
+// `proc/[pid]/exe`. On Windows, can be set to the result of
+// `GetProcessImageFileNameW`.
+func ProcessExecutablePath(val string) attribute.KeyValue {
+ return ProcessExecutablePathKey.String(val)
+}
+
+// ProcessExitCode returns an attribute KeyValue conforming to the
+// "process.exit.code" semantic conventions. It represents the exit code of the
+// process.
+func ProcessExitCode(val int) attribute.KeyValue {
+ return ProcessExitCodeKey.Int(val)
+}
+
+// ProcessExitTime returns an attribute KeyValue conforming to the
+// "process.exit.time" semantic conventions. It represents the date and time the
+// process exited, in ISO 8601 format.
+func ProcessExitTime(val string) attribute.KeyValue {
+ return ProcessExitTimeKey.String(val)
+}
+
+// ProcessGroupLeaderPID returns an attribute KeyValue conforming to the
+// "process.group_leader.pid" semantic conventions. It represents the PID of the
+// process's group leader. This is also the process group ID (PGID) of the
+// process.
+func ProcessGroupLeaderPID(val int) attribute.KeyValue {
+ return ProcessGroupLeaderPIDKey.Int(val)
+}
+
+// ProcessInteractive returns an attribute KeyValue conforming to the
+// "process.interactive" semantic conventions. It represents the whether the
+// process is connected to an interactive shell.
+func ProcessInteractive(val bool) attribute.KeyValue {
+ return ProcessInteractiveKey.Bool(val)
+}
+
+// ProcessLinuxCgroup returns an attribute KeyValue conforming to the
+// "process.linux.cgroup" semantic conventions. It represents the control group
+// associated with the process.
+func ProcessLinuxCgroup(val string) attribute.KeyValue {
+ return ProcessLinuxCgroupKey.String(val)
+}
+
+// ProcessOwner returns an attribute KeyValue conforming to the "process.owner"
+// semantic conventions. It represents the username of the user that owns the
+// process.
+func ProcessOwner(val string) attribute.KeyValue {
+ return ProcessOwnerKey.String(val)
+}
+
+// ProcessParentPID returns an attribute KeyValue conforming to the
+// "process.parent_pid" semantic conventions. It represents the parent Process
+// identifier (PPID).
+func ProcessParentPID(val int) attribute.KeyValue {
+ return ProcessParentPIDKey.Int(val)
+}
+
+// ProcessPID returns an attribute KeyValue conforming to the "process.pid"
+// semantic conventions. It represents the process identifier (PID).
+func ProcessPID(val int) attribute.KeyValue {
+ return ProcessPIDKey.Int(val)
+}
+
+// ProcessRealUserID returns an attribute KeyValue conforming to the
+// "process.real_user.id" semantic conventions. It represents the real user ID
+// (RUID) of the process.
+func ProcessRealUserID(val int) attribute.KeyValue {
+ return ProcessRealUserIDKey.Int(val)
+}
+
+// ProcessRealUserName returns an attribute KeyValue conforming to the
+// "process.real_user.name" semantic conventions. It represents the username of
+// the real user of the process.
+func ProcessRealUserName(val string) attribute.KeyValue {
+ return ProcessRealUserNameKey.String(val)
+}
+
+// ProcessRuntimeDescription returns an attribute KeyValue conforming to the
+// "process.runtime.description" semantic conventions. It represents an
+// additional description about the runtime of the process, for example a
+// specific vendor customization of the runtime environment.
+func ProcessRuntimeDescription(val string) attribute.KeyValue {
+ return ProcessRuntimeDescriptionKey.String(val)
+}
+
+// ProcessRuntimeName returns an attribute KeyValue conforming to the
+// "process.runtime.name" semantic conventions. It represents the name of the
+// runtime of this process.
+func ProcessRuntimeName(val string) attribute.KeyValue {
+ return ProcessRuntimeNameKey.String(val)
+}
+
+// ProcessRuntimeVersion returns an attribute KeyValue conforming to the
+// "process.runtime.version" semantic conventions. It represents the version of
+// the runtime of this process, as returned by the runtime without modification.
+func ProcessRuntimeVersion(val string) attribute.KeyValue {
+ return ProcessRuntimeVersionKey.String(val)
+}
+
+// ProcessSavedUserID returns an attribute KeyValue conforming to the
+// "process.saved_user.id" semantic conventions. It represents the saved user ID
+// (SUID) of the process.
+func ProcessSavedUserID(val int) attribute.KeyValue {
+ return ProcessSavedUserIDKey.Int(val)
+}
+
+// ProcessSavedUserName returns an attribute KeyValue conforming to the
+// "process.saved_user.name" semantic conventions. It represents the username of
+// the saved user.
+func ProcessSavedUserName(val string) attribute.KeyValue {
+ return ProcessSavedUserNameKey.String(val)
+}
+
+// ProcessSessionLeaderPID returns an attribute KeyValue conforming to the
+// "process.session_leader.pid" semantic conventions. It represents the PID of
+// the process's session leader. This is also the session ID (SID) of the
+// process.
+func ProcessSessionLeaderPID(val int) attribute.KeyValue {
+ return ProcessSessionLeaderPIDKey.Int(val)
+}
+
+// ProcessTitle returns an attribute KeyValue conforming to the "process.title"
+// semantic conventions. It represents the process title (proctitle).
+func ProcessTitle(val string) attribute.KeyValue {
+ return ProcessTitleKey.String(val)
+}
+
+// ProcessUserID returns an attribute KeyValue conforming to the
+// "process.user.id" semantic conventions. It represents the effective user ID
+// (EUID) of the process.
+func ProcessUserID(val int) attribute.KeyValue {
+ return ProcessUserIDKey.Int(val)
+}
+
+// ProcessUserName returns an attribute KeyValue conforming to the
+// "process.user.name" semantic conventions. It represents the username of the
+// effective user of the process.
+func ProcessUserName(val string) attribute.KeyValue {
+ return ProcessUserNameKey.String(val)
+}
+
+// ProcessVpid returns an attribute KeyValue conforming to the "process.vpid"
+// semantic conventions. It represents the virtual process identifier.
+func ProcessVpid(val int) attribute.KeyValue {
+ return ProcessVpidKey.Int(val)
+}
+
+// ProcessWorkingDirectory returns an attribute KeyValue conforming to the
+// "process.working_directory" semantic conventions. It represents the working
+// directory of the process.
+func ProcessWorkingDirectory(val string) attribute.KeyValue {
+ return ProcessWorkingDirectoryKey.String(val)
+}
+
+// Enum values for process.context_switch.type
+var (
+ // voluntary
+ // Stability: development
+ ProcessContextSwitchTypeVoluntary = ProcessContextSwitchTypeKey.String("voluntary")
+ // involuntary
+ // Stability: development
+ ProcessContextSwitchTypeInvoluntary = ProcessContextSwitchTypeKey.String("involuntary")
+)
+
+// Enum values for process.state
+var (
+ // running
+ // Stability: development
+ ProcessStateRunning = ProcessStateKey.String("running")
+ // sleeping
+ // Stability: development
+ ProcessStateSleeping = ProcessStateKey.String("sleeping")
+ // stopped
+ // Stability: development
+ ProcessStateStopped = ProcessStateKey.String("stopped")
+ // defunct
+ // Stability: development
+ ProcessStateDefunct = ProcessStateKey.String("defunct")
+)
+
+// Namespace: profile
+const (
+ // ProfileFrameTypeKey is the attribute Key conforming to the
+ // "profile.frame.type" semantic conventions. It represents the describes the
+ // interpreter or compiler of a single frame.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "cpython"
+ ProfileFrameTypeKey = attribute.Key("profile.frame.type")
+)
+
+// Enum values for profile.frame.type
+var (
+ // [.NET]
+ //
+ // Stability: development
+ //
+ // [.NET]: https://wikipedia.org/wiki/.NET
+ ProfileFrameTypeDotnet = ProfileFrameTypeKey.String("dotnet")
+ // [JVM]
+ //
+ // Stability: development
+ //
+ // [JVM]: https://wikipedia.org/wiki/Java_virtual_machine
+ ProfileFrameTypeJVM = ProfileFrameTypeKey.String("jvm")
+ // [Kernel]
+ //
+ // Stability: development
+ //
+ // [Kernel]: https://wikipedia.org/wiki/Kernel_(operating_system)
+ ProfileFrameTypeKernel = ProfileFrameTypeKey.String("kernel")
+ // Can be one of but not limited to [C], [C++], [Go] or [Rust]. If possible, a
+ // more precise value MUST be used.
+ //
+ // Stability: development
+ //
+ // [C]: https://wikipedia.org/wiki/C_(programming_language)
+ // [C++]: https://wikipedia.org/wiki/C%2B%2B
+ // [Go]: https://wikipedia.org/wiki/Go_(programming_language)
+ // [Rust]: https://wikipedia.org/wiki/Rust_(programming_language)
+ ProfileFrameTypeNative = ProfileFrameTypeKey.String("native")
+ // [Perl]
+ //
+ // Stability: development
+ //
+ // [Perl]: https://wikipedia.org/wiki/Perl
+ ProfileFrameTypePerl = ProfileFrameTypeKey.String("perl")
+ // [PHP]
+ //
+ // Stability: development
+ //
+ // [PHP]: https://wikipedia.org/wiki/PHP
+ ProfileFrameTypePHP = ProfileFrameTypeKey.String("php")
+ // [Python]
+ //
+ // Stability: development
+ //
+ // [Python]: https://wikipedia.org/wiki/Python_(programming_language)
+ ProfileFrameTypeCpython = ProfileFrameTypeKey.String("cpython")
+ // [Ruby]
+ //
+ // Stability: development
+ //
+ // [Ruby]: https://wikipedia.org/wiki/Ruby_(programming_language)
+ ProfileFrameTypeRuby = ProfileFrameTypeKey.String("ruby")
+ // [V8JS]
+ //
+ // Stability: development
+ //
+ // [V8JS]: https://wikipedia.org/wiki/V8_(JavaScript_engine)
+ ProfileFrameTypeV8JS = ProfileFrameTypeKey.String("v8js")
+ // [Erlang]
+ //
+ // Stability: development
+ //
+ // [Erlang]: https://en.wikipedia.org/wiki/BEAM_(Erlang_virtual_machine)
+ ProfileFrameTypeBeam = ProfileFrameTypeKey.String("beam")
+ // [Go],
+ //
+ // Stability: development
+ //
+ // [Go]: https://wikipedia.org/wiki/Go_(programming_language)
+ ProfileFrameTypeGo = ProfileFrameTypeKey.String("go")
+ // [Rust]
+ //
+ // Stability: development
+ //
+ // [Rust]: https://wikipedia.org/wiki/Rust_(programming_language)
+ ProfileFrameTypeRust = ProfileFrameTypeKey.String("rust")
+)
+
+// Namespace: rpc
+const (
+ // RPCMethodKey is the attribute Key conforming to the "rpc.method" semantic
+ // conventions. It represents the fully-qualified logical name of the method
+ // from the RPC interface perspective.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Release_Candidate
+ //
+ // Examples: "com.example.ExampleService/exampleMethod", "EchoService/Echo",
+ // "_OTHER"
+ // Note: The method name MAY have unbounded cardinality in edge or error cases.
+ //
+ // Some RPC frameworks or libraries provide a fixed set of recognized methods
+ // for client stubs and server implementations. Instrumentations for such
+ // frameworks MUST set this attribute to the original method name only
+ // when the method is recognized by the framework or library.
+ //
+ // When the method is not recognized, for example, when the server receives
+ // a request for a method that is not predefined on the server, or when
+ // instrumentation is not able to reliably detect if the method is predefined,
+ // the attribute MUST be set to `_OTHER`. In such cases, tracing
+ // instrumentations MUST also set `rpc.method_original` attribute to
+ // the original method value.
+ //
+ // If the RPC instrumentation could end up converting valid RPC methods to
+ // `_OTHER`, then it SHOULD provide a way to configure the list of recognized
+ // RPC methods.
+ //
+ // The `rpc.method` can be different from the name of any implementing
+ // method/function.
+ // The `code.function.name` attribute may be used to record the fully-qualified
+ // method actually executing the call on the server side, or the
+ // RPC client stub method on the client side.
+ RPCMethodKey = attribute.Key("rpc.method")
+
+ // RPCMethodOriginalKey is the attribute Key conforming to the
+ // "rpc.method_original" semantic conventions. It represents the original name
+ // of the method used by the client.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Release_Candidate
+ //
+ // Examples: "com.myservice.EchoService/catchAll",
+ // "com.myservice.EchoService/unknownMethod", "InvalidMethod"
+ RPCMethodOriginalKey = attribute.Key("rpc.method_original")
+
+ // RPCResponseStatusCodeKey is the attribute Key conforming to the
+ // "rpc.response.status_code" semantic conventions. It represents the status
+ // code of the RPC returned by the RPC server or generated by the client.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Release_Candidate
+ //
+ // Examples: "OK", "DEADLINE_EXCEEDED", "-32602"
+ // Note: Usually it represents an error code, but may also represent partial
+ // success, warning, or differentiate between various types of successful
+ // outcomes.
+ // Semantic conventions for individual RPC frameworks SHOULD document what
+ // `rpc.response.status_code` means in the context of that system and which
+ // values are considered to represent errors.
+ RPCResponseStatusCodeKey = attribute.Key("rpc.response.status_code")
+
+ // RPCSystemNameKey is the attribute Key conforming to the "rpc.system.name"
+ // semantic conventions. It represents the Remote Procedure Call (RPC) system.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Release_Candidate
+ //
+ // Examples:
+ // Note: The client and server RPC systems may differ for the same RPC
+ // interaction. For example, a client may use Apache Dubbo or Connect RPC to
+ // communicate with a server that uses gRPC since both protocols provide
+ // compatibility with gRPC.
+ RPCSystemNameKey = attribute.Key("rpc.system.name")
+)
+
+// RPCMethod returns an attribute KeyValue conforming to the "rpc.method"
+// semantic conventions. It represents the fully-qualified logical name of the
+// method from the RPC interface perspective.
+func RPCMethod(val string) attribute.KeyValue {
+ return RPCMethodKey.String(val)
+}
+
+// RPCMethodOriginal returns an attribute KeyValue conforming to the
+// "rpc.method_original" semantic conventions. It represents the original name of
+// the method used by the client.
+func RPCMethodOriginal(val string) attribute.KeyValue {
+ return RPCMethodOriginalKey.String(val)
+}
+
+// RPCRequestMetadata returns an attribute KeyValue conforming to the
+// "rpc.request.metadata" semantic conventions. It represents the RPC request
+// metadata, `` being the normalized RPC metadata key (lowercase), the value
+// being the metadata values.
+func RPCRequestMetadata(key string, val ...string) attribute.KeyValue {
+ return attribute.StringSlice("rpc.request.metadata."+key, val)
+}
+
+// RPCResponseMetadata returns an attribute KeyValue conforming to the
+// "rpc.response.metadata" semantic conventions. It represents the RPC response
+// metadata, `` being the normalized RPC metadata key (lowercase), the value
+// being the metadata values.
+func RPCResponseMetadata(key string, val ...string) attribute.KeyValue {
+ return attribute.StringSlice("rpc.response.metadata."+key, val)
+}
+
+// RPCResponseStatusCode returns an attribute KeyValue conforming to the
+// "rpc.response.status_code" semantic conventions. It represents the status code
+// of the RPC returned by the RPC server or generated by the client.
+func RPCResponseStatusCode(val string) attribute.KeyValue {
+ return RPCResponseStatusCodeKey.String(val)
+}
+
+// Enum values for rpc.system.name
+var (
+ // [gRPC]
+ // Stability: release_candidate
+ //
+ // [gRPC]: https://grpc.io/
+ RPCSystemNameGRPC = RPCSystemNameKey.String("grpc")
+ // [Apache Dubbo]
+ // Stability: release_candidate
+ //
+ // [Apache Dubbo]: https://dubbo.apache.org/
+ RPCSystemNameDubbo = RPCSystemNameKey.String("dubbo")
+ // [Connect RPC]
+ // Stability: development
+ //
+ // [Connect RPC]: https://connectrpc.com/
+ RPCSystemNameConnectrpc = RPCSystemNameKey.String("connectrpc")
+ // [JSON-RPC]
+ // Stability: development
+ //
+ // [JSON-RPC]: https://www.jsonrpc.org/
+ RPCSystemNameJSONRPC = RPCSystemNameKey.String("jsonrpc")
+)
+
+// Namespace: security_rule
+const (
+ // SecurityRuleCategoryKey is the attribute Key conforming to the
+ // "security_rule.category" semantic conventions. It represents a categorization
+ // value keyword used by the entity using the rule for detection of this event.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "Attempted Information Leak"
+ SecurityRuleCategoryKey = attribute.Key("security_rule.category")
+
+ // SecurityRuleDescriptionKey is the attribute Key conforming to the
+ // "security_rule.description" semantic conventions. It represents the
+ // description of the rule generating the event.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "Block requests to public DNS over HTTPS / TLS protocols"
+ SecurityRuleDescriptionKey = attribute.Key("security_rule.description")
+
+ // SecurityRuleLicenseKey is the attribute Key conforming to the
+ // "security_rule.license" semantic conventions. It represents the name of the
+ // license under which the rule used to generate this event is made available.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "Apache 2.0"
+ SecurityRuleLicenseKey = attribute.Key("security_rule.license")
+
+ // SecurityRuleNameKey is the attribute Key conforming to the
+ // "security_rule.name" semantic conventions. It represents the name of the rule
+ // or signature generating the event.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "BLOCK_DNS_over_TLS"
+ SecurityRuleNameKey = attribute.Key("security_rule.name")
+
+ // SecurityRuleReferenceKey is the attribute Key conforming to the
+ // "security_rule.reference" semantic conventions. It represents the reference
+ // URL to additional information about the rule used to generate this event.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "https://en.wikipedia.org/wiki/DNS_over_TLS"
+ // Note: The URL can point to the vendor’s documentation about the rule. If
+ // that’s not available, it can also be a link to a more general page
+ // describing this type of alert.
+ SecurityRuleReferenceKey = attribute.Key("security_rule.reference")
+
+ // SecurityRuleRulesetNameKey is the attribute Key conforming to the
+ // "security_rule.ruleset.name" semantic conventions. It represents the name of
+ // the ruleset, policy, group, or parent category in which the rule used to
+ // generate this event is a member.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "Standard_Protocol_Filters"
+ SecurityRuleRulesetNameKey = attribute.Key("security_rule.ruleset.name")
+
+ // SecurityRuleUUIDKey is the attribute Key conforming to the
+ // "security_rule.uuid" semantic conventions. It represents a rule ID that is
+ // unique within the scope of a set or group of agents, observers, or other
+ // entities using the rule for detection of this event.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "550e8400-e29b-41d4-a716-446655440000", "1100110011"
+ SecurityRuleUUIDKey = attribute.Key("security_rule.uuid")
+
+ // SecurityRuleVersionKey is the attribute Key conforming to the
+ // "security_rule.version" semantic conventions. It represents the version /
+ // revision of the rule being used for analysis.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "1.0.0"
+ SecurityRuleVersionKey = attribute.Key("security_rule.version")
+)
+
+// SecurityRuleCategory returns an attribute KeyValue conforming to the
+// "security_rule.category" semantic conventions. It represents a categorization
+// value keyword used by the entity using the rule for detection of this event.
+func SecurityRuleCategory(val string) attribute.KeyValue {
+ return SecurityRuleCategoryKey.String(val)
+}
+
+// SecurityRuleDescription returns an attribute KeyValue conforming to the
+// "security_rule.description" semantic conventions. It represents the
+// description of the rule generating the event.
+func SecurityRuleDescription(val string) attribute.KeyValue {
+ return SecurityRuleDescriptionKey.String(val)
+}
+
+// SecurityRuleLicense returns an attribute KeyValue conforming to the
+// "security_rule.license" semantic conventions. It represents the name of the
+// license under which the rule used to generate this event is made available.
+func SecurityRuleLicense(val string) attribute.KeyValue {
+ return SecurityRuleLicenseKey.String(val)
+}
+
+// SecurityRuleName returns an attribute KeyValue conforming to the
+// "security_rule.name" semantic conventions. It represents the name of the rule
+// or signature generating the event.
+func SecurityRuleName(val string) attribute.KeyValue {
+ return SecurityRuleNameKey.String(val)
+}
+
+// SecurityRuleReference returns an attribute KeyValue conforming to the
+// "security_rule.reference" semantic conventions. It represents the reference
+// URL to additional information about the rule used to generate this event.
+func SecurityRuleReference(val string) attribute.KeyValue {
+ return SecurityRuleReferenceKey.String(val)
+}
+
+// SecurityRuleRulesetName returns an attribute KeyValue conforming to the
+// "security_rule.ruleset.name" semantic conventions. It represents the name of
+// the ruleset, policy, group, or parent category in which the rule used to
+// generate this event is a member.
+func SecurityRuleRulesetName(val string) attribute.KeyValue {
+ return SecurityRuleRulesetNameKey.String(val)
+}
+
+// SecurityRuleUUID returns an attribute KeyValue conforming to the
+// "security_rule.uuid" semantic conventions. It represents a rule ID that is
+// unique within the scope of a set or group of agents, observers, or other
+// entities using the rule for detection of this event.
+func SecurityRuleUUID(val string) attribute.KeyValue {
+ return SecurityRuleUUIDKey.String(val)
+}
+
+// SecurityRuleVersion returns an attribute KeyValue conforming to the
+// "security_rule.version" semantic conventions. It represents the version /
+// revision of the rule being used for analysis.
+func SecurityRuleVersion(val string) attribute.KeyValue {
+ return SecurityRuleVersionKey.String(val)
+}
+
+// Namespace: server
+const (
+ // ServerAddressKey is the attribute Key conforming to the "server.address"
+ // semantic conventions. It represents the server domain name if available
+ // without reverse DNS lookup; otherwise, IP address or Unix domain socket name.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ //
+ // Examples: "example.com", "10.1.2.80", "/tmp/my.sock"
+ // Note: When observed from the client side, and when communicating through an
+ // intermediary, `server.address` SHOULD represent the server address behind any
+ // intermediaries, for example proxies, if it's available.
+ ServerAddressKey = attribute.Key("server.address")
+
+ // ServerPortKey is the attribute Key conforming to the "server.port" semantic
+ // conventions. It represents the server port number.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ //
+ // Examples: 80, 8080, 443
+ // Note: When observed from the client side, and when communicating through an
+ // intermediary, `server.port` SHOULD represent the server port behind any
+ // intermediaries, for example proxies, if it's available.
+ ServerPortKey = attribute.Key("server.port")
+)
+
+// ServerAddress returns an attribute KeyValue conforming to the "server.address"
+// semantic conventions. It represents the server domain name if available
+// without reverse DNS lookup; otherwise, IP address or Unix domain socket name.
+func ServerAddress(val string) attribute.KeyValue {
+ return ServerAddressKey.String(val)
+}
+
+// ServerPort returns an attribute KeyValue conforming to the "server.port"
+// semantic conventions. It represents the server port number.
+func ServerPort(val int) attribute.KeyValue {
+ return ServerPortKey.Int(val)
+}
+
+// Namespace: service
+const (
+ // ServiceCriticalityKey is the attribute Key conforming to the
+ // "service.criticality" semantic conventions. It represents the operational
+ // criticality of the service.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "critical", "high", "medium", "low"
+ // Note: Application developers are encouraged to set `service.criticality` to
+ // express the operational importance of their services. Telemetry consumers MAY
+ // use this attribute to optimize telemetry collection or improve user
+ // experience.
+ ServiceCriticalityKey = attribute.Key("service.criticality")
+
+ // ServiceInstanceIDKey is the attribute Key conforming to the
+ // "service.instance.id" semantic conventions. It represents the string ID of
+ // the service instance.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ //
+ // Examples: "627cc493-f310-47de-96bd-71410b7dec09"
+ // Note: MUST be unique for each instance of the same
+ // `service.namespace,service.name` pair (in other words
+ // `service.namespace,service.name,service.instance.id` triplet MUST be globally
+ // unique). The ID helps to
+ // distinguish instances of the same service that exist at the same time (e.g.
+ // instances of a horizontally scaled
+ // service).
+ //
+ // Implementations, such as SDKs, are recommended to generate a random Version 1
+ // or Version 4 [RFC
+ // 4122] UUID, but are free to use an inherent unique ID as
+ // the source of
+ // this value if stability is desirable. In that case, the ID SHOULD be used as
+ // source of a UUID Version 5 and
+ // SHOULD use the following UUID as the namespace:
+ // `4d63009a-8d0f-11ee-aad7-4c796ed8e320`.
+ //
+ // UUIDs are typically recommended, as only an opaque value for the purposes of
+ // identifying a service instance is
+ // needed. Similar to what can be seen in the man page for the
+ // [`/etc/machine-id`] file, the underlying
+ // data, such as pod name and namespace should be treated as confidential, being
+ // the user's choice to expose it
+ // or not via another resource attribute.
+ //
+ // For applications running behind an application server (like unicorn), we do
+ // not recommend using one identifier
+ // for all processes participating in the application. Instead, it's recommended
+ // each division (e.g. a worker
+ // thread in unicorn) to have its own instance.id.
+ //
+ // It's not recommended for a Collector to set `service.instance.id` if it can't
+ // unambiguously determine the
+ // service instance that is generating that telemetry. For instance, creating an
+ // UUID based on `pod.name` will
+ // likely be wrong, as the Collector might not know from which container within
+ // that pod the telemetry originated.
+ // However, Collectors can set the `service.instance.id` if they can
+ // unambiguously determine the service instance
+ // for that telemetry. This is typically the case for scraping receivers, as
+ // they know the target address and
+ // port.
+ //
+ // [RFC
+ // 4122]: https://www.ietf.org/rfc/rfc4122.txt
+ // [`/etc/machine-id`]: https://www.freedesktop.org/software/systemd/man/latest/machine-id.html
+ ServiceInstanceIDKey = attribute.Key("service.instance.id")
+
+ // ServiceNameKey is the attribute Key conforming to the "service.name" semantic
+ // conventions. It represents the logical name of the service.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ //
+ // Examples: "shoppingcart"
+ // Note: MUST be the same for all instances of horizontally scaled services. If
+ // the value was not specified, SDKs MUST fallback to `unknown_service:`
+ // concatenated with [`process.executable.name`], e.g. `unknown_service:bash`.
+ // If `process.executable.name` is not available, the value MUST be set to
+ // `unknown_service`.
+ //
+ // [`process.executable.name`]: process.md
+ ServiceNameKey = attribute.Key("service.name")
+
+ // ServiceNamespaceKey is the attribute Key conforming to the
+ // "service.namespace" semantic conventions. It represents a namespace for
+ // `service.name`.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ //
+ // Examples: "Shop"
+ // Note: A string value having a meaning that helps to distinguish a group of
+ // services, for example the team name that owns a group of services.
+ // `service.name` is expected to be unique within the same namespace. If
+ // `service.namespace` is not specified in the Resource then `service.name` is
+ // expected to be unique for all services that have no explicit namespace
+ // defined (so the empty/unspecified namespace is simply one more valid
+ // namespace). Zero-length namespace string is assumed equal to unspecified
+ // namespace.
+ ServiceNamespaceKey = attribute.Key("service.namespace")
+
+ // ServicePeerNameKey is the attribute Key conforming to the "service.peer.name"
+ // semantic conventions. It represents the logical name of the service on the
+ // other side of the connection. SHOULD be equal to the actual [`service.name`]
+ // resource attribute of the remote service if any.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "shoppingcart"
+ //
+ // [`service.name`]: /docs/resource/README.md#service
+ ServicePeerNameKey = attribute.Key("service.peer.name")
+
+ // ServicePeerNamespaceKey is the attribute Key conforming to the
+ // "service.peer.namespace" semantic conventions. It represents the logical
+ // namespace of the service on the other side of the connection. SHOULD be equal
+ // to the actual [`service.namespace`] resource attribute of the remote service
+ // if any.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "Shop"
+ //
+ // [`service.namespace`]: /docs/resource/README.md#service
+ ServicePeerNamespaceKey = attribute.Key("service.peer.namespace")
+
+ // ServiceVersionKey is the attribute Key conforming to the "service.version"
+ // semantic conventions. It represents the version string of the service
+ // component. The format is not defined by these conventions.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ //
+ // Examples: "2.0.0", "a01dbef8a"
+ ServiceVersionKey = attribute.Key("service.version")
+)
+
+// ServiceInstanceID returns an attribute KeyValue conforming to the
+// "service.instance.id" semantic conventions. It represents the string ID of the
+// service instance.
+func ServiceInstanceID(val string) attribute.KeyValue {
+ return ServiceInstanceIDKey.String(val)
+}
+
+// ServiceName returns an attribute KeyValue conforming to the "service.name"
+// semantic conventions. It represents the logical name of the service.
+func ServiceName(val string) attribute.KeyValue {
+ return ServiceNameKey.String(val)
+}
+
+// ServiceNamespace returns an attribute KeyValue conforming to the
+// "service.namespace" semantic conventions. It represents a namespace for
+// `service.name`.
+func ServiceNamespace(val string) attribute.KeyValue {
+ return ServiceNamespaceKey.String(val)
+}
+
+// ServicePeerName returns an attribute KeyValue conforming to the
+// "service.peer.name" semantic conventions. It represents the logical name of
+// the service on the other side of the connection. SHOULD be equal to the actual
+// [`service.name`] resource attribute of the remote service if any.
+//
+// [`service.name`]: /docs/resource/README.md#service
+func ServicePeerName(val string) attribute.KeyValue {
+ return ServicePeerNameKey.String(val)
+}
+
+// ServicePeerNamespace returns an attribute KeyValue conforming to the
+// "service.peer.namespace" semantic conventions. It represents the logical
+// namespace of the service on the other side of the connection. SHOULD be equal
+// to the actual [`service.namespace`] resource attribute of the remote service
+// if any.
+//
+// [`service.namespace`]: /docs/resource/README.md#service
+func ServicePeerNamespace(val string) attribute.KeyValue {
+ return ServicePeerNamespaceKey.String(val)
+}
+
+// ServiceVersion returns an attribute KeyValue conforming to the
+// "service.version" semantic conventions. It represents the version string of
+// the service component. The format is not defined by these conventions.
+func ServiceVersion(val string) attribute.KeyValue {
+ return ServiceVersionKey.String(val)
+}
+
+// Enum values for service.criticality
+var (
+ // Service is business-critical; downtime directly impacts revenue, user
+ // experience, or core functionality.
+ //
+ // Stability: development
+ ServiceCriticalityCritical = ServiceCriticalityKey.String("critical")
+ // Service is important but has degradation tolerance or fallback mechanisms.
+ //
+ // Stability: development
+ ServiceCriticalityHigh = ServiceCriticalityKey.String("high")
+ // Service provides supplementary functionality; degradation has limited user
+ // impact.
+ //
+ // Stability: development
+ ServiceCriticalityMedium = ServiceCriticalityKey.String("medium")
+ // Service is non-essential to core operations; used for background tasks or
+ // internal tools.
+ //
+ // Stability: development
+ ServiceCriticalityLow = ServiceCriticalityKey.String("low")
+)
+
+// Namespace: session
+const (
+ // SessionIDKey is the attribute Key conforming to the "session.id" semantic
+ // conventions. It represents a unique id to identify a session.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 00112233-4455-6677-8899-aabbccddeeff
+ SessionIDKey = attribute.Key("session.id")
+
+ // SessionPreviousIDKey is the attribute Key conforming to the
+ // "session.previous_id" semantic conventions. It represents the previous
+ // `session.id` for this user, when known.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 00112233-4455-6677-8899-aabbccddeeff
+ SessionPreviousIDKey = attribute.Key("session.previous_id")
+)
+
+// SessionID returns an attribute KeyValue conforming to the "session.id"
+// semantic conventions. It represents a unique id to identify a session.
+func SessionID(val string) attribute.KeyValue {
+ return SessionIDKey.String(val)
+}
+
+// SessionPreviousID returns an attribute KeyValue conforming to the
+// "session.previous_id" semantic conventions. It represents the previous
+// `session.id` for this user, when known.
+func SessionPreviousID(val string) attribute.KeyValue {
+ return SessionPreviousIDKey.String(val)
+}
+
+// Namespace: signalr
+const (
+ // SignalRConnectionStatusKey is the attribute Key conforming to the
+ // "signalr.connection.status" semantic conventions. It represents the signalR
+ // HTTP connection closure status.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ //
+ // Examples: "app_shutdown", "timeout"
+ SignalRConnectionStatusKey = attribute.Key("signalr.connection.status")
+
+ // SignalRTransportKey is the attribute Key conforming to the
+ // "signalr.transport" semantic conventions. It represents the
+ // [SignalR transport type].
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ //
+ // Examples: "web_sockets", "long_polling"
+ //
+ // [SignalR transport type]: https://github.com/dotnet/aspnetcore/blob/main/src/SignalR/docs/specs/TransportProtocols.md
+ SignalRTransportKey = attribute.Key("signalr.transport")
+)
+
+// Enum values for signalr.connection.status
+var (
+ // The connection was closed normally.
+ // Stability: stable
+ SignalRConnectionStatusNormalClosure = SignalRConnectionStatusKey.String("normal_closure")
+ // The connection was closed due to a timeout.
+ // Stability: stable
+ SignalRConnectionStatusTimeout = SignalRConnectionStatusKey.String("timeout")
+ // The connection was closed because the app is shutting down.
+ // Stability: stable
+ SignalRConnectionStatusAppShutdown = SignalRConnectionStatusKey.String("app_shutdown")
+)
+
+// Enum values for signalr.transport
+var (
+ // ServerSentEvents protocol
+ // Stability: stable
+ SignalRTransportServerSentEvents = SignalRTransportKey.String("server_sent_events")
+ // LongPolling protocol
+ // Stability: stable
+ SignalRTransportLongPolling = SignalRTransportKey.String("long_polling")
+ // WebSockets protocol
+ // Stability: stable
+ SignalRTransportWebSockets = SignalRTransportKey.String("web_sockets")
+)
+
+// Namespace: source
+const (
+ // SourceAddressKey is the attribute Key conforming to the "source.address"
+ // semantic conventions. It represents the source address - domain name if
+ // available without reverse DNS lookup; otherwise, IP address or Unix domain
+ // socket name.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "source.example.com", "10.1.2.80", "/tmp/my.sock"
+ // Note: When observed from the destination side, and when communicating through
+ // an intermediary, `source.address` SHOULD represent the source address behind
+ // any intermediaries, for example proxies, if it's available.
+ SourceAddressKey = attribute.Key("source.address")
+
+ // SourcePortKey is the attribute Key conforming to the "source.port" semantic
+ // conventions. It represents the source port number.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 3389, 2888
+ SourcePortKey = attribute.Key("source.port")
+)
+
+// SourceAddress returns an attribute KeyValue conforming to the "source.address"
+// semantic conventions. It represents the source address - domain name if
+// available without reverse DNS lookup; otherwise, IP address or Unix domain
+// socket name.
+func SourceAddress(val string) attribute.KeyValue {
+ return SourceAddressKey.String(val)
+}
+
+// SourcePort returns an attribute KeyValue conforming to the "source.port"
+// semantic conventions. It represents the source port number.
+func SourcePort(val int) attribute.KeyValue {
+ return SourcePortKey.Int(val)
+}
+
+// Namespace: system
+const (
+ // SystemDeviceKey is the attribute Key conforming to the "system.device"
+ // semantic conventions. It represents the device identifier.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "(identifier)"
+ SystemDeviceKey = attribute.Key("system.device")
+
+ // SystemFilesystemModeKey is the attribute Key conforming to the
+ // "system.filesystem.mode" semantic conventions. It represents the filesystem
+ // mode.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "rw, ro"
+ SystemFilesystemModeKey = attribute.Key("system.filesystem.mode")
+
+ // SystemFilesystemMountpointKey is the attribute Key conforming to the
+ // "system.filesystem.mountpoint" semantic conventions. It represents the
+ // filesystem mount path.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "/mnt/data"
+ SystemFilesystemMountpointKey = attribute.Key("system.filesystem.mountpoint")
+
+ // SystemFilesystemStateKey is the attribute Key conforming to the
+ // "system.filesystem.state" semantic conventions. It represents the filesystem
+ // state.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "used"
+ SystemFilesystemStateKey = attribute.Key("system.filesystem.state")
+
+ // SystemFilesystemTypeKey is the attribute Key conforming to the
+ // "system.filesystem.type" semantic conventions. It represents the filesystem
+ // type.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "ext4"
+ SystemFilesystemTypeKey = attribute.Key("system.filesystem.type")
+
+ // SystemMemoryLinuxSlabStateKey is the attribute Key conforming to the
+ // "system.memory.linux.slab.state" semantic conventions. It represents the
+ // Linux Slab memory state.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "reclaimable", "unreclaimable"
+ SystemMemoryLinuxSlabStateKey = attribute.Key("system.memory.linux.slab.state")
+
+ // SystemMemoryStateKey is the attribute Key conforming to the
+ // "system.memory.state" semantic conventions. It represents the memory state.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "free", "cached"
+ SystemMemoryStateKey = attribute.Key("system.memory.state")
+
+ // SystemPagingDirectionKey is the attribute Key conforming to the
+ // "system.paging.direction" semantic conventions. It represents the paging
+ // access direction.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "in"
+ SystemPagingDirectionKey = attribute.Key("system.paging.direction")
+
+ // SystemPagingFaultTypeKey is the attribute Key conforming to the
+ // "system.paging.fault.type" semantic conventions. It represents the paging
+ // fault type.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "minor"
+ SystemPagingFaultTypeKey = attribute.Key("system.paging.fault.type")
+
+ // SystemPagingStateKey is the attribute Key conforming to the
+ // "system.paging.state" semantic conventions. It represents the memory paging
+ // state.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "free"
+ SystemPagingStateKey = attribute.Key("system.paging.state")
+)
+
+// SystemDevice returns an attribute KeyValue conforming to the "system.device"
+// semantic conventions. It represents the device identifier.
+func SystemDevice(val string) attribute.KeyValue {
+ return SystemDeviceKey.String(val)
+}
+
+// SystemFilesystemMode returns an attribute KeyValue conforming to the
+// "system.filesystem.mode" semantic conventions. It represents the filesystem
+// mode.
+func SystemFilesystemMode(val string) attribute.KeyValue {
+ return SystemFilesystemModeKey.String(val)
+}
+
+// SystemFilesystemMountpoint returns an attribute KeyValue conforming to the
+// "system.filesystem.mountpoint" semantic conventions. It represents the
+// filesystem mount path.
+func SystemFilesystemMountpoint(val string) attribute.KeyValue {
+ return SystemFilesystemMountpointKey.String(val)
+}
+
+// Enum values for system.filesystem.state
+var (
+ // used
+ // Stability: development
+ SystemFilesystemStateUsed = SystemFilesystemStateKey.String("used")
+ // free
+ // Stability: development
+ SystemFilesystemStateFree = SystemFilesystemStateKey.String("free")
+ // reserved
+ // Stability: development
+ SystemFilesystemStateReserved = SystemFilesystemStateKey.String("reserved")
+)
+
+// Enum values for system.filesystem.type
+var (
+ // fat32
+ // Stability: development
+ SystemFilesystemTypeFat32 = SystemFilesystemTypeKey.String("fat32")
+ // exfat
+ // Stability: development
+ SystemFilesystemTypeExfat = SystemFilesystemTypeKey.String("exfat")
+ // ntfs
+ // Stability: development
+ SystemFilesystemTypeNtfs = SystemFilesystemTypeKey.String("ntfs")
+ // refs
+ // Stability: development
+ SystemFilesystemTypeRefs = SystemFilesystemTypeKey.String("refs")
+ // hfsplus
+ // Stability: development
+ SystemFilesystemTypeHfsplus = SystemFilesystemTypeKey.String("hfsplus")
+ // ext4
+ // Stability: development
+ SystemFilesystemTypeExt4 = SystemFilesystemTypeKey.String("ext4")
+)
+
+// Enum values for system.memory.linux.slab.state
+var (
+ // reclaimable
+ // Stability: development
+ SystemMemoryLinuxSlabStateReclaimable = SystemMemoryLinuxSlabStateKey.String("reclaimable")
+ // unreclaimable
+ // Stability: development
+ SystemMemoryLinuxSlabStateUnreclaimable = SystemMemoryLinuxSlabStateKey.String("unreclaimable")
+)
+
+// Enum values for system.memory.state
+var (
+ // Actual used virtual memory in bytes.
+ // Stability: development
+ SystemMemoryStateUsed = SystemMemoryStateKey.String("used")
+ // free
+ // Stability: development
+ SystemMemoryStateFree = SystemMemoryStateKey.String("free")
+ // buffers
+ // Stability: development
+ SystemMemoryStateBuffers = SystemMemoryStateKey.String("buffers")
+ // cached
+ // Stability: development
+ SystemMemoryStateCached = SystemMemoryStateKey.String("cached")
+)
+
+// Enum values for system.paging.direction
+var (
+ // in
+ // Stability: development
+ SystemPagingDirectionIn = SystemPagingDirectionKey.String("in")
+ // out
+ // Stability: development
+ SystemPagingDirectionOut = SystemPagingDirectionKey.String("out")
+)
+
+// Enum values for system.paging.fault.type
+var (
+ // major
+ // Stability: development
+ SystemPagingFaultTypeMajor = SystemPagingFaultTypeKey.String("major")
+ // minor
+ // Stability: development
+ SystemPagingFaultTypeMinor = SystemPagingFaultTypeKey.String("minor")
+)
+
+// Enum values for system.paging.state
+var (
+ // used
+ // Stability: development
+ SystemPagingStateUsed = SystemPagingStateKey.String("used")
+ // free
+ // Stability: development
+ SystemPagingStateFree = SystemPagingStateKey.String("free")
+)
+
+// Namespace: telemetry
+const (
+ // TelemetryDistroNameKey is the attribute Key conforming to the
+ // "telemetry.distro.name" semantic conventions. It represents the name of the
+ // auto instrumentation agent or distribution, if used.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "parts-unlimited-java"
+ // Note: Official auto instrumentation agents and distributions SHOULD set the
+ // `telemetry.distro.name` attribute to
+ // a string starting with `opentelemetry-`, e.g.
+ // `opentelemetry-java-instrumentation`.
+ TelemetryDistroNameKey = attribute.Key("telemetry.distro.name")
+
+ // TelemetryDistroVersionKey is the attribute Key conforming to the
+ // "telemetry.distro.version" semantic conventions. It represents the version
+ // string of the auto instrumentation agent or distribution, if used.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "1.2.3"
+ TelemetryDistroVersionKey = attribute.Key("telemetry.distro.version")
+
+ // TelemetrySDKLanguageKey is the attribute Key conforming to the
+ // "telemetry.sdk.language" semantic conventions. It represents the language of
+ // the telemetry SDK.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ //
+ // Examples:
+ TelemetrySDKLanguageKey = attribute.Key("telemetry.sdk.language")
+
+ // TelemetrySDKNameKey is the attribute Key conforming to the
+ // "telemetry.sdk.name" semantic conventions. It represents the name of the
+ // telemetry SDK as defined above.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ //
+ // Examples: "opentelemetry"
+ // Note: The OpenTelemetry SDK MUST set the `telemetry.sdk.name` attribute to
+ // `opentelemetry`.
+ // If another SDK, like a fork or a vendor-provided implementation, is used,
+ // this SDK MUST set the
+ // `telemetry.sdk.name` attribute to the fully-qualified class or module name of
+ // this SDK's main entry point
+ // or another suitable identifier depending on the language.
+ // The identifier `opentelemetry` is reserved and MUST NOT be used in this case.
+ // All custom identifiers SHOULD be stable across different versions of an
+ // implementation.
+ TelemetrySDKNameKey = attribute.Key("telemetry.sdk.name")
+
+ // TelemetrySDKVersionKey is the attribute Key conforming to the
+ // "telemetry.sdk.version" semantic conventions. It represents the version
+ // string of the telemetry SDK.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ //
+ // Examples: "1.2.3"
+ TelemetrySDKVersionKey = attribute.Key("telemetry.sdk.version")
+)
+
+// TelemetryDistroName returns an attribute KeyValue conforming to the
+// "telemetry.distro.name" semantic conventions. It represents the name of the
+// auto instrumentation agent or distribution, if used.
+func TelemetryDistroName(val string) attribute.KeyValue {
+ return TelemetryDistroNameKey.String(val)
+}
+
+// TelemetryDistroVersion returns an attribute KeyValue conforming to the
+// "telemetry.distro.version" semantic conventions. It represents the version
+// string of the auto instrumentation agent or distribution, if used.
+func TelemetryDistroVersion(val string) attribute.KeyValue {
+ return TelemetryDistroVersionKey.String(val)
+}
+
+// TelemetrySDKName returns an attribute KeyValue conforming to the
+// "telemetry.sdk.name" semantic conventions. It represents the name of the
+// telemetry SDK as defined above.
+func TelemetrySDKName(val string) attribute.KeyValue {
+ return TelemetrySDKNameKey.String(val)
+}
+
+// TelemetrySDKVersion returns an attribute KeyValue conforming to the
+// "telemetry.sdk.version" semantic conventions. It represents the version string
+// of the telemetry SDK.
+func TelemetrySDKVersion(val string) attribute.KeyValue {
+ return TelemetrySDKVersionKey.String(val)
+}
+
+// Enum values for telemetry.sdk.language
+var (
+ // cpp
+ // Stability: stable
+ TelemetrySDKLanguageCPP = TelemetrySDKLanguageKey.String("cpp")
+ // dotnet
+ // Stability: stable
+ TelemetrySDKLanguageDotnet = TelemetrySDKLanguageKey.String("dotnet")
+ // erlang
+ // Stability: stable
+ TelemetrySDKLanguageErlang = TelemetrySDKLanguageKey.String("erlang")
+ // go
+ // Stability: stable
+ TelemetrySDKLanguageGo = TelemetrySDKLanguageKey.String("go")
+ // java
+ // Stability: stable
+ TelemetrySDKLanguageJava = TelemetrySDKLanguageKey.String("java")
+ // nodejs
+ // Stability: stable
+ TelemetrySDKLanguageNodejs = TelemetrySDKLanguageKey.String("nodejs")
+ // php
+ // Stability: stable
+ TelemetrySDKLanguagePHP = TelemetrySDKLanguageKey.String("php")
+ // python
+ // Stability: stable
+ TelemetrySDKLanguagePython = TelemetrySDKLanguageKey.String("python")
+ // ruby
+ // Stability: stable
+ TelemetrySDKLanguageRuby = TelemetrySDKLanguageKey.String("ruby")
+ // rust
+ // Stability: stable
+ TelemetrySDKLanguageRust = TelemetrySDKLanguageKey.String("rust")
+ // swift
+ // Stability: stable
+ TelemetrySDKLanguageSwift = TelemetrySDKLanguageKey.String("swift")
+ // webjs
+ // Stability: stable
+ TelemetrySDKLanguageWebJS = TelemetrySDKLanguageKey.String("webjs")
+)
+
+// Namespace: test
+const (
+ // TestCaseNameKey is the attribute Key conforming to the "test.case.name"
+ // semantic conventions. It represents the fully qualified human readable name
+ // of the [test case].
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "org.example.TestCase1.test1", "example/tests/TestCase1.test1",
+ // "ExampleTestCase1_test1"
+ //
+ // [test case]: https://wikipedia.org/wiki/Test_case
+ TestCaseNameKey = attribute.Key("test.case.name")
+
+ // TestCaseResultStatusKey is the attribute Key conforming to the
+ // "test.case.result.status" semantic conventions. It represents the status of
+ // the actual test case result from test execution.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "pass", "fail"
+ TestCaseResultStatusKey = attribute.Key("test.case.result.status")
+
+ // TestSuiteNameKey is the attribute Key conforming to the "test.suite.name"
+ // semantic conventions. It represents the human readable name of a [test suite]
+ // .
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "TestSuite1"
+ //
+ // [test suite]: https://wikipedia.org/wiki/Test_suite
+ TestSuiteNameKey = attribute.Key("test.suite.name")
+
+ // TestSuiteRunStatusKey is the attribute Key conforming to the
+ // "test.suite.run.status" semantic conventions. It represents the status of the
+ // test suite run.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "success", "failure", "skipped", "aborted", "timed_out",
+ // "in_progress"
+ TestSuiteRunStatusKey = attribute.Key("test.suite.run.status")
+)
+
+// TestCaseName returns an attribute KeyValue conforming to the "test.case.name"
+// semantic conventions. It represents the fully qualified human readable name of
+// the [test case].
+//
+// [test case]: https://wikipedia.org/wiki/Test_case
+func TestCaseName(val string) attribute.KeyValue {
+ return TestCaseNameKey.String(val)
+}
+
+// TestSuiteName returns an attribute KeyValue conforming to the
+// "test.suite.name" semantic conventions. It represents the human readable name
+// of a [test suite].
+//
+// [test suite]: https://wikipedia.org/wiki/Test_suite
+func TestSuiteName(val string) attribute.KeyValue {
+ return TestSuiteNameKey.String(val)
+}
+
+// Enum values for test.case.result.status
+var (
+ // pass
+ // Stability: development
+ TestCaseResultStatusPass = TestCaseResultStatusKey.String("pass")
+ // fail
+ // Stability: development
+ TestCaseResultStatusFail = TestCaseResultStatusKey.String("fail")
+)
+
+// Enum values for test.suite.run.status
+var (
+ // success
+ // Stability: development
+ TestSuiteRunStatusSuccess = TestSuiteRunStatusKey.String("success")
+ // failure
+ // Stability: development
+ TestSuiteRunStatusFailure = TestSuiteRunStatusKey.String("failure")
+ // skipped
+ // Stability: development
+ TestSuiteRunStatusSkipped = TestSuiteRunStatusKey.String("skipped")
+ // aborted
+ // Stability: development
+ TestSuiteRunStatusAborted = TestSuiteRunStatusKey.String("aborted")
+ // timed_out
+ // Stability: development
+ TestSuiteRunStatusTimedOut = TestSuiteRunStatusKey.String("timed_out")
+ // in_progress
+ // Stability: development
+ TestSuiteRunStatusInProgress = TestSuiteRunStatusKey.String("in_progress")
+)
+
+// Namespace: thread
+const (
+ // ThreadIDKey is the attribute Key conforming to the "thread.id" semantic
+ // conventions. It represents the current "managed" thread ID (as opposed to OS
+ // thread ID).
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Note:
+ // Examples of where the value can be extracted from:
+ //
+ // | Language or platform | Source |
+ // | --- | --- |
+ // | JVM | `Thread.currentThread().threadId()` |
+ // | .NET | `Thread.CurrentThread.ManagedThreadId` |
+ // | Python | `threading.current_thread().ident` |
+ // | Ruby | `Thread.current.object_id` |
+ // | C++ | `std::this_thread::get_id()` |
+ // | Erlang | `erlang:self()` |
+ ThreadIDKey = attribute.Key("thread.id")
+
+ // ThreadNameKey is the attribute Key conforming to the "thread.name" semantic
+ // conventions. It represents the current thread name.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: main
+ // Note:
+ // Examples of where the value can be extracted from:
+ //
+ // | Language or platform | Source |
+ // | --- | --- |
+ // | JVM | `Thread.currentThread().getName()` |
+ // | .NET | `Thread.CurrentThread.Name` |
+ // | Python | `threading.current_thread().name` |
+ // | Ruby | `Thread.current.name` |
+ // | Erlang | `erlang:process_info(self(), registered_name)` |
+ ThreadNameKey = attribute.Key("thread.name")
+)
+
+// ThreadID returns an attribute KeyValue conforming to the "thread.id" semantic
+// conventions. It represents the current "managed" thread ID (as opposed to OS
+// thread ID).
+func ThreadID(val int) attribute.KeyValue {
+ return ThreadIDKey.Int(val)
+}
+
+// ThreadName returns an attribute KeyValue conforming to the "thread.name"
+// semantic conventions. It represents the current thread name.
+func ThreadName(val string) attribute.KeyValue {
+ return ThreadNameKey.String(val)
+}
+
+// Namespace: tls
+const (
+ // TLSCipherKey is the attribute Key conforming to the "tls.cipher" semantic
+ // conventions. It represents the string indicating the [cipher] used during the
+ // current connection.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "TLS_RSA_WITH_3DES_EDE_CBC_SHA",
+ // "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256"
+ // Note: The values allowed for `tls.cipher` MUST be one of the `Descriptions`
+ // of the [registered TLS Cipher Suits].
+ //
+ // [cipher]: https://datatracker.ietf.org/doc/html/rfc5246#appendix-A.5
+ // [registered TLS Cipher Suits]: https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#table-tls-parameters-4
+ TLSCipherKey = attribute.Key("tls.cipher")
+
+ // TLSClientCertificateKey is the attribute Key conforming to the
+ // "tls.client.certificate" semantic conventions. It represents the PEM-encoded
+ // stand-alone certificate offered by the client. This is usually
+ // mutually-exclusive of `client.certificate_chain` since this value also exists
+ // in that list.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "MII..."
+ TLSClientCertificateKey = attribute.Key("tls.client.certificate")
+
+ // TLSClientCertificateChainKey is the attribute Key conforming to the
+ // "tls.client.certificate_chain" semantic conventions. It represents the array
+ // of PEM-encoded certificates that make up the certificate chain offered by the
+ // client. This is usually mutually-exclusive of `client.certificate` since that
+ // value should be the first certificate in the chain.
+ //
+ // Type: string[]
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "MII...", "MI..."
+ TLSClientCertificateChainKey = attribute.Key("tls.client.certificate_chain")
+
+ // TLSClientHashMd5Key is the attribute Key conforming to the
+ // "tls.client.hash.md5" semantic conventions. It represents the certificate
+ // fingerprint using the MD5 digest of DER-encoded version of certificate
+ // offered by the client. For consistency with other hash values, this value
+ // should be formatted as an uppercase hash.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "0F76C7F2C55BFD7D8E8B8F4BFBF0C9EC"
+ TLSClientHashMd5Key = attribute.Key("tls.client.hash.md5")
+
+ // TLSClientHashSha1Key is the attribute Key conforming to the
+ // "tls.client.hash.sha1" semantic conventions. It represents the certificate
+ // fingerprint using the SHA1 digest of DER-encoded version of certificate
+ // offered by the client. For consistency with other hash values, this value
+ // should be formatted as an uppercase hash.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "9E393D93138888D288266C2D915214D1D1CCEB2A"
+ TLSClientHashSha1Key = attribute.Key("tls.client.hash.sha1")
+
+ // TLSClientHashSha256Key is the attribute Key conforming to the
+ // "tls.client.hash.sha256" semantic conventions. It represents the certificate
+ // fingerprint using the SHA256 digest of DER-encoded version of certificate
+ // offered by the client. For consistency with other hash values, this value
+ // should be formatted as an uppercase hash.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "0687F666A054EF17A08E2F2162EAB4CBC0D265E1D7875BE74BF3C712CA92DAF0"
+ TLSClientHashSha256Key = attribute.Key("tls.client.hash.sha256")
+
+ // TLSClientIssuerKey is the attribute Key conforming to the "tls.client.issuer"
+ // semantic conventions. It represents the distinguished name of [subject] of
+ // the issuer of the x.509 certificate presented by the client.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "CN=Example Root CA, OU=Infrastructure Team, DC=example, DC=com"
+ //
+ // [subject]: https://datatracker.ietf.org/doc/html/rfc5280#section-4.1.2.6
+ TLSClientIssuerKey = attribute.Key("tls.client.issuer")
+
+ // TLSClientJa3Key is the attribute Key conforming to the "tls.client.ja3"
+ // semantic conventions. It represents a hash that identifies clients based on
+ // how they perform an SSL/TLS handshake.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "d4e5b18d6b55c71272893221c96ba240"
+ TLSClientJa3Key = attribute.Key("tls.client.ja3")
+
+ // TLSClientNotAfterKey is the attribute Key conforming to the
+ // "tls.client.not_after" semantic conventions. It represents the date/Time
+ // indicating when client certificate is no longer considered valid.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "2021-01-01T00:00:00.000Z"
+ TLSClientNotAfterKey = attribute.Key("tls.client.not_after")
+
+ // TLSClientNotBeforeKey is the attribute Key conforming to the
+ // "tls.client.not_before" semantic conventions. It represents the date/Time
+ // indicating when client certificate is first considered valid.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "1970-01-01T00:00:00.000Z"
+ TLSClientNotBeforeKey = attribute.Key("tls.client.not_before")
+
+ // TLSClientSubjectKey is the attribute Key conforming to the
+ // "tls.client.subject" semantic conventions. It represents the distinguished
+ // name of subject of the x.509 certificate presented by the client.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "CN=myclient, OU=Documentation Team, DC=example, DC=com"
+ TLSClientSubjectKey = attribute.Key("tls.client.subject")
+
+ // TLSClientSupportedCiphersKey is the attribute Key conforming to the
+ // "tls.client.supported_ciphers" semantic conventions. It represents the array
+ // of ciphers offered by the client during the client hello.
+ //
+ // Type: string[]
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
+ // "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384"
+ TLSClientSupportedCiphersKey = attribute.Key("tls.client.supported_ciphers")
+
+ // TLSCurveKey is the attribute Key conforming to the "tls.curve" semantic
+ // conventions. It represents the string indicating the curve used for the given
+ // cipher, when applicable.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "secp256r1"
+ TLSCurveKey = attribute.Key("tls.curve")
+
+ // TLSEstablishedKey is the attribute Key conforming to the "tls.established"
+ // semantic conventions. It represents the boolean flag indicating if the TLS
+ // negotiation was successful and transitioned to an encrypted tunnel.
+ //
+ // Type: boolean
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: true
+ TLSEstablishedKey = attribute.Key("tls.established")
+
+ // TLSNextProtocolKey is the attribute Key conforming to the "tls.next_protocol"
+ // semantic conventions. It represents the string indicating the protocol being
+ // tunneled. Per the values in the [IANA registry], this string should be lower
+ // case.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "http/1.1"
+ //
+ // [IANA registry]: https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#alpn-protocol-ids
+ TLSNextProtocolKey = attribute.Key("tls.next_protocol")
+
+ // TLSProtocolNameKey is the attribute Key conforming to the "tls.protocol.name"
+ // semantic conventions. It represents the normalized lowercase protocol name
+ // parsed from original string of the negotiated [SSL/TLS protocol version].
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ //
+ // [SSL/TLS protocol version]: https://docs.openssl.org/1.1.1/man3/SSL_get_version/#return-values
+ TLSProtocolNameKey = attribute.Key("tls.protocol.name")
+
+ // TLSProtocolVersionKey is the attribute Key conforming to the
+ // "tls.protocol.version" semantic conventions. It represents the numeric part
+ // of the version parsed from the original string of the negotiated
+ // [SSL/TLS protocol version].
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "1.2", "3"
+ //
+ // [SSL/TLS protocol version]: https://docs.openssl.org/1.1.1/man3/SSL_get_version/#return-values
+ TLSProtocolVersionKey = attribute.Key("tls.protocol.version")
+
+ // TLSResumedKey is the attribute Key conforming to the "tls.resumed" semantic
+ // conventions. It represents the boolean flag indicating if this TLS connection
+ // was resumed from an existing TLS negotiation.
+ //
+ // Type: boolean
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: true
+ TLSResumedKey = attribute.Key("tls.resumed")
+
+ // TLSServerCertificateKey is the attribute Key conforming to the
+ // "tls.server.certificate" semantic conventions. It represents the PEM-encoded
+ // stand-alone certificate offered by the server. This is usually
+ // mutually-exclusive of `server.certificate_chain` since this value also exists
+ // in that list.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "MII..."
+ TLSServerCertificateKey = attribute.Key("tls.server.certificate")
+
+ // TLSServerCertificateChainKey is the attribute Key conforming to the
+ // "tls.server.certificate_chain" semantic conventions. It represents the array
+ // of PEM-encoded certificates that make up the certificate chain offered by the
+ // server. This is usually mutually-exclusive of `server.certificate` since that
+ // value should be the first certificate in the chain.
+ //
+ // Type: string[]
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "MII...", "MI..."
+ TLSServerCertificateChainKey = attribute.Key("tls.server.certificate_chain")
+
+ // TLSServerHashMd5Key is the attribute Key conforming to the
+ // "tls.server.hash.md5" semantic conventions. It represents the certificate
+ // fingerprint using the MD5 digest of DER-encoded version of certificate
+ // offered by the server. For consistency with other hash values, this value
+ // should be formatted as an uppercase hash.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "0F76C7F2C55BFD7D8E8B8F4BFBF0C9EC"
+ TLSServerHashMd5Key = attribute.Key("tls.server.hash.md5")
+
+ // TLSServerHashSha1Key is the attribute Key conforming to the
+ // "tls.server.hash.sha1" semantic conventions. It represents the certificate
+ // fingerprint using the SHA1 digest of DER-encoded version of certificate
+ // offered by the server. For consistency with other hash values, this value
+ // should be formatted as an uppercase hash.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "9E393D93138888D288266C2D915214D1D1CCEB2A"
+ TLSServerHashSha1Key = attribute.Key("tls.server.hash.sha1")
+
+ // TLSServerHashSha256Key is the attribute Key conforming to the
+ // "tls.server.hash.sha256" semantic conventions. It represents the certificate
+ // fingerprint using the SHA256 digest of DER-encoded version of certificate
+ // offered by the server. For consistency with other hash values, this value
+ // should be formatted as an uppercase hash.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "0687F666A054EF17A08E2F2162EAB4CBC0D265E1D7875BE74BF3C712CA92DAF0"
+ TLSServerHashSha256Key = attribute.Key("tls.server.hash.sha256")
+
+ // TLSServerIssuerKey is the attribute Key conforming to the "tls.server.issuer"
+ // semantic conventions. It represents the distinguished name of [subject] of
+ // the issuer of the x.509 certificate presented by the client.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "CN=Example Root CA, OU=Infrastructure Team, DC=example, DC=com"
+ //
+ // [subject]: https://datatracker.ietf.org/doc/html/rfc5280#section-4.1.2.6
+ TLSServerIssuerKey = attribute.Key("tls.server.issuer")
+
+ // TLSServerJa3sKey is the attribute Key conforming to the "tls.server.ja3s"
+ // semantic conventions. It represents a hash that identifies servers based on
+ // how they perform an SSL/TLS handshake.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "d4e5b18d6b55c71272893221c96ba240"
+ TLSServerJa3sKey = attribute.Key("tls.server.ja3s")
+
+ // TLSServerNotAfterKey is the attribute Key conforming to the
+ // "tls.server.not_after" semantic conventions. It represents the date/Time
+ // indicating when server certificate is no longer considered valid.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "2021-01-01T00:00:00.000Z"
+ TLSServerNotAfterKey = attribute.Key("tls.server.not_after")
+
+ // TLSServerNotBeforeKey is the attribute Key conforming to the
+ // "tls.server.not_before" semantic conventions. It represents the date/Time
+ // indicating when server certificate is first considered valid.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "1970-01-01T00:00:00.000Z"
+ TLSServerNotBeforeKey = attribute.Key("tls.server.not_before")
+
+ // TLSServerSubjectKey is the attribute Key conforming to the
+ // "tls.server.subject" semantic conventions. It represents the distinguished
+ // name of subject of the x.509 certificate presented by the server.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "CN=myserver, OU=Documentation Team, DC=example, DC=com"
+ TLSServerSubjectKey = attribute.Key("tls.server.subject")
+)
+
+// TLSCipher returns an attribute KeyValue conforming to the "tls.cipher"
+// semantic conventions. It represents the string indicating the [cipher] used
+// during the current connection.
+//
+// [cipher]: https://datatracker.ietf.org/doc/html/rfc5246#appendix-A.5
+func TLSCipher(val string) attribute.KeyValue {
+ return TLSCipherKey.String(val)
+}
+
+// TLSClientCertificate returns an attribute KeyValue conforming to the
+// "tls.client.certificate" semantic conventions. It represents the PEM-encoded
+// stand-alone certificate offered by the client. This is usually
+// mutually-exclusive of `client.certificate_chain` since this value also exists
+// in that list.
+func TLSClientCertificate(val string) attribute.KeyValue {
+ return TLSClientCertificateKey.String(val)
+}
+
+// TLSClientCertificateChain returns an attribute KeyValue conforming to the
+// "tls.client.certificate_chain" semantic conventions. It represents the array
+// of PEM-encoded certificates that make up the certificate chain offered by the
+// client. This is usually mutually-exclusive of `client.certificate` since that
+// value should be the first certificate in the chain.
+func TLSClientCertificateChain(val ...string) attribute.KeyValue {
+ return TLSClientCertificateChainKey.StringSlice(val)
+}
+
+// TLSClientHashMd5 returns an attribute KeyValue conforming to the
+// "tls.client.hash.md5" semantic conventions. It represents the certificate
+// fingerprint using the MD5 digest of DER-encoded version of certificate offered
+// by the client. For consistency with other hash values, this value should be
+// formatted as an uppercase hash.
+func TLSClientHashMd5(val string) attribute.KeyValue {
+ return TLSClientHashMd5Key.String(val)
+}
+
+// TLSClientHashSha1 returns an attribute KeyValue conforming to the
+// "tls.client.hash.sha1" semantic conventions. It represents the certificate
+// fingerprint using the SHA1 digest of DER-encoded version of certificate
+// offered by the client. For consistency with other hash values, this value
+// should be formatted as an uppercase hash.
+func TLSClientHashSha1(val string) attribute.KeyValue {
+ return TLSClientHashSha1Key.String(val)
+}
+
+// TLSClientHashSha256 returns an attribute KeyValue conforming to the
+// "tls.client.hash.sha256" semantic conventions. It represents the certificate
+// fingerprint using the SHA256 digest of DER-encoded version of certificate
+// offered by the client. For consistency with other hash values, this value
+// should be formatted as an uppercase hash.
+func TLSClientHashSha256(val string) attribute.KeyValue {
+ return TLSClientHashSha256Key.String(val)
+}
+
+// TLSClientIssuer returns an attribute KeyValue conforming to the
+// "tls.client.issuer" semantic conventions. It represents the distinguished name
+// of [subject] of the issuer of the x.509 certificate presented by the client.
+//
+// [subject]: https://datatracker.ietf.org/doc/html/rfc5280#section-4.1.2.6
+func TLSClientIssuer(val string) attribute.KeyValue {
+ return TLSClientIssuerKey.String(val)
+}
+
+// TLSClientJa3 returns an attribute KeyValue conforming to the "tls.client.ja3"
+// semantic conventions. It represents a hash that identifies clients based on
+// how they perform an SSL/TLS handshake.
+func TLSClientJa3(val string) attribute.KeyValue {
+ return TLSClientJa3Key.String(val)
+}
+
+// TLSClientNotAfter returns an attribute KeyValue conforming to the
+// "tls.client.not_after" semantic conventions. It represents the date/Time
+// indicating when client certificate is no longer considered valid.
+func TLSClientNotAfter(val string) attribute.KeyValue {
+ return TLSClientNotAfterKey.String(val)
+}
+
+// TLSClientNotBefore returns an attribute KeyValue conforming to the
+// "tls.client.not_before" semantic conventions. It represents the date/Time
+// indicating when client certificate is first considered valid.
+func TLSClientNotBefore(val string) attribute.KeyValue {
+ return TLSClientNotBeforeKey.String(val)
+}
+
+// TLSClientSubject returns an attribute KeyValue conforming to the
+// "tls.client.subject" semantic conventions. It represents the distinguished
+// name of subject of the x.509 certificate presented by the client.
+func TLSClientSubject(val string) attribute.KeyValue {
+ return TLSClientSubjectKey.String(val)
+}
+
+// TLSClientSupportedCiphers returns an attribute KeyValue conforming to the
+// "tls.client.supported_ciphers" semantic conventions. It represents the array
+// of ciphers offered by the client during the client hello.
+func TLSClientSupportedCiphers(val ...string) attribute.KeyValue {
+ return TLSClientSupportedCiphersKey.StringSlice(val)
+}
+
+// TLSCurve returns an attribute KeyValue conforming to the "tls.curve" semantic
+// conventions. It represents the string indicating the curve used for the given
+// cipher, when applicable.
+func TLSCurve(val string) attribute.KeyValue {
+ return TLSCurveKey.String(val)
+}
+
+// TLSEstablished returns an attribute KeyValue conforming to the
+// "tls.established" semantic conventions. It represents the boolean flag
+// indicating if the TLS negotiation was successful and transitioned to an
+// encrypted tunnel.
+func TLSEstablished(val bool) attribute.KeyValue {
+ return TLSEstablishedKey.Bool(val)
+}
+
+// TLSNextProtocol returns an attribute KeyValue conforming to the
+// "tls.next_protocol" semantic conventions. It represents the string indicating
+// the protocol being tunneled. Per the values in the [IANA registry], this
+// string should be lower case.
+//
+// [IANA registry]: https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#alpn-protocol-ids
+func TLSNextProtocol(val string) attribute.KeyValue {
+ return TLSNextProtocolKey.String(val)
+}
+
+// TLSProtocolVersion returns an attribute KeyValue conforming to the
+// "tls.protocol.version" semantic conventions. It represents the numeric part of
+// the version parsed from the original string of the negotiated
+// [SSL/TLS protocol version].
+//
+// [SSL/TLS protocol version]: https://docs.openssl.org/1.1.1/man3/SSL_get_version/#return-values
+func TLSProtocolVersion(val string) attribute.KeyValue {
+ return TLSProtocolVersionKey.String(val)
+}
+
+// TLSResumed returns an attribute KeyValue conforming to the "tls.resumed"
+// semantic conventions. It represents the boolean flag indicating if this TLS
+// connection was resumed from an existing TLS negotiation.
+func TLSResumed(val bool) attribute.KeyValue {
+ return TLSResumedKey.Bool(val)
+}
+
+// TLSServerCertificate returns an attribute KeyValue conforming to the
+// "tls.server.certificate" semantic conventions. It represents the PEM-encoded
+// stand-alone certificate offered by the server. This is usually
+// mutually-exclusive of `server.certificate_chain` since this value also exists
+// in that list.
+func TLSServerCertificate(val string) attribute.KeyValue {
+ return TLSServerCertificateKey.String(val)
+}
+
+// TLSServerCertificateChain returns an attribute KeyValue conforming to the
+// "tls.server.certificate_chain" semantic conventions. It represents the array
+// of PEM-encoded certificates that make up the certificate chain offered by the
+// server. This is usually mutually-exclusive of `server.certificate` since that
+// value should be the first certificate in the chain.
+func TLSServerCertificateChain(val ...string) attribute.KeyValue {
+ return TLSServerCertificateChainKey.StringSlice(val)
+}
+
+// TLSServerHashMd5 returns an attribute KeyValue conforming to the
+// "tls.server.hash.md5" semantic conventions. It represents the certificate
+// fingerprint using the MD5 digest of DER-encoded version of certificate offered
+// by the server. For consistency with other hash values, this value should be
+// formatted as an uppercase hash.
+func TLSServerHashMd5(val string) attribute.KeyValue {
+ return TLSServerHashMd5Key.String(val)
+}
+
+// TLSServerHashSha1 returns an attribute KeyValue conforming to the
+// "tls.server.hash.sha1" semantic conventions. It represents the certificate
+// fingerprint using the SHA1 digest of DER-encoded version of certificate
+// offered by the server. For consistency with other hash values, this value
+// should be formatted as an uppercase hash.
+func TLSServerHashSha1(val string) attribute.KeyValue {
+ return TLSServerHashSha1Key.String(val)
+}
+
+// TLSServerHashSha256 returns an attribute KeyValue conforming to the
+// "tls.server.hash.sha256" semantic conventions. It represents the certificate
+// fingerprint using the SHA256 digest of DER-encoded version of certificate
+// offered by the server. For consistency with other hash values, this value
+// should be formatted as an uppercase hash.
+func TLSServerHashSha256(val string) attribute.KeyValue {
+ return TLSServerHashSha256Key.String(val)
+}
+
+// TLSServerIssuer returns an attribute KeyValue conforming to the
+// "tls.server.issuer" semantic conventions. It represents the distinguished name
+// of [subject] of the issuer of the x.509 certificate presented by the client.
+//
+// [subject]: https://datatracker.ietf.org/doc/html/rfc5280#section-4.1.2.6
+func TLSServerIssuer(val string) attribute.KeyValue {
+ return TLSServerIssuerKey.String(val)
+}
+
+// TLSServerJa3s returns an attribute KeyValue conforming to the
+// "tls.server.ja3s" semantic conventions. It represents a hash that identifies
+// servers based on how they perform an SSL/TLS handshake.
+func TLSServerJa3s(val string) attribute.KeyValue {
+ return TLSServerJa3sKey.String(val)
+}
+
+// TLSServerNotAfter returns an attribute KeyValue conforming to the
+// "tls.server.not_after" semantic conventions. It represents the date/Time
+// indicating when server certificate is no longer considered valid.
+func TLSServerNotAfter(val string) attribute.KeyValue {
+ return TLSServerNotAfterKey.String(val)
+}
+
+// TLSServerNotBefore returns an attribute KeyValue conforming to the
+// "tls.server.not_before" semantic conventions. It represents the date/Time
+// indicating when server certificate is first considered valid.
+func TLSServerNotBefore(val string) attribute.KeyValue {
+ return TLSServerNotBeforeKey.String(val)
+}
+
+// TLSServerSubject returns an attribute KeyValue conforming to the
+// "tls.server.subject" semantic conventions. It represents the distinguished
+// name of subject of the x.509 certificate presented by the server.
+func TLSServerSubject(val string) attribute.KeyValue {
+ return TLSServerSubjectKey.String(val)
+}
+
+// Enum values for tls.protocol.name
+var (
+ // ssl
+ // Stability: development
+ TLSProtocolNameSsl = TLSProtocolNameKey.String("ssl")
+ // tls
+ // Stability: development
+ TLSProtocolNameTLS = TLSProtocolNameKey.String("tls")
+)
+
+// Namespace: url
+const (
+ // URLDomainKey is the attribute Key conforming to the "url.domain" semantic
+ // conventions. It represents the domain extracted from the `url.full`, such as
+ // "opentelemetry.io".
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "www.foo.bar", "opentelemetry.io", "3.12.167.2",
+ // "[1080:0:0:0:8:800:200C:417A]"
+ // Note: In some cases a URL may refer to an IP and/or port directly, without a
+ // domain name. In this case, the IP address would go to the domain field. If
+ // the URL contains a [literal IPv6 address] enclosed by `[` and `]`, the `[`
+ // and `]` characters should also be captured in the domain field.
+ //
+ // [literal IPv6 address]: https://www.rfc-editor.org/rfc/rfc2732#section-2
+ URLDomainKey = attribute.Key("url.domain")
+
+ // URLExtensionKey is the attribute Key conforming to the "url.extension"
+ // semantic conventions. It represents the file extension extracted from the
+ // `url.full`, excluding the leading dot.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "png", "gz"
+ // Note: The file extension is only set if it exists, as not every url has a
+ // file extension. When the file name has multiple extensions `example.tar.gz`,
+ // only the last one should be captured `gz`, not `tar.gz`.
+ URLExtensionKey = attribute.Key("url.extension")
+
+ // URLFragmentKey is the attribute Key conforming to the "url.fragment" semantic
+ // conventions. It represents the [URI fragment] component.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ //
+ // Examples: "SemConv"
+ //
+ // [URI fragment]: https://www.rfc-editor.org/rfc/rfc3986#section-3.5
+ URLFragmentKey = attribute.Key("url.fragment")
+
+ // URLFullKey is the attribute Key conforming to the "url.full" semantic
+ // conventions. It represents the absolute URL describing a network resource
+ // according to [RFC3986].
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ //
+ // Examples: "https://www.foo.bar/search?q=OpenTelemetry#SemConv", "//localhost"
+ // Note: For network calls, URL usually has
+ // `scheme://host[:port][path][?query][#fragment]` format, where the fragment
+ // is not transmitted over HTTP, but if it is known, it SHOULD be included
+ // nevertheless.
+ //
+ // `url.full` MUST NOT contain credentials passed via URL in form of
+ // `https://username:password@www.example.com/`.
+ // In such case username and password SHOULD be redacted and attribute's value
+ // SHOULD be `https://REDACTED:REDACTED@www.example.com/`.
+ //
+ // `url.full` SHOULD capture the absolute URL when it is available (or can be
+ // reconstructed).
+ //
+ // Sensitive content provided in `url.full` SHOULD be scrubbed when
+ // instrumentations can identify it.
+ //
+ //
+ // Query string values for the following keys SHOULD be redacted by default and
+ // replaced by the
+ // value `REDACTED`:
+ //
+ // - [`AWSAccessKeyId`]
+ // - [`Signature`]
+ // - [`sig`]
+ // - [`X-Goog-Signature`]
+ //
+ // This list is subject to change over time.
+ //
+ // Matching of query parameter keys against the sensitive list SHOULD be
+ // case-sensitive.
+ //
+ //
+ // Instrumentation MAY provide a way to override this list via declarative
+ // configuration.
+ // If so, it SHOULD use the `sensitive_query_parameters` property
+ // (an array of case-sensitive strings with minimum items 0) under
+ // `.instrumentation/development.general.sanitization.url`.
+ // This list is a full override of the default sensitive query parameter keys,
+ // it is not a list of keys in addition to the defaults.
+ //
+ // When a query string value is redacted, the query string key SHOULD still be
+ // preserved, e.g.
+ // `https://www.example.com/path?color=blue&sig=REDACTED`.
+ //
+ // [RFC3986]: https://www.rfc-editor.org/rfc/rfc3986
+ // [`AWSAccessKeyId`]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/RESTAuthentication.html#RESTAuthenticationQueryStringAuth
+ // [`Signature`]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/RESTAuthentication.html#RESTAuthenticationQueryStringAuth
+ // [`sig`]: https://learn.microsoft.com/azure/storage/common/storage-sas-overview#sas-token
+ // [`X-Goog-Signature`]: https://cloud.google.com/storage/docs/access-control/signed-urls
+ URLFullKey = attribute.Key("url.full")
+
+ // URLOriginalKey is the attribute Key conforming to the "url.original" semantic
+ // conventions. It represents the unmodified original URL as seen in the event
+ // source.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "https://www.foo.bar/search?q=OpenTelemetry#SemConv",
+ // "search?q=OpenTelemetry"
+ // Note: In network monitoring, the observed URL may be a full URL, whereas in
+ // access logs, the URL is often just represented as a path. This field is meant
+ // to represent the URL as it was observed, complete or not.
+ // `url.original` might contain credentials passed via URL in form of
+ // `https://username:password@www.example.com/`. In such case password and
+ // username SHOULD NOT be redacted and attribute's value SHOULD remain the same.
+ URLOriginalKey = attribute.Key("url.original")
+
+ // URLPathKey is the attribute Key conforming to the "url.path" semantic
+ // conventions. It represents the [URI path] component.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ //
+ // Examples: "/search"
+ // Note: Sensitive content provided in `url.path` SHOULD be scrubbed when
+ // instrumentations can identify it.
+ //
+ // [URI path]: https://www.rfc-editor.org/rfc/rfc3986#section-3.3
+ URLPathKey = attribute.Key("url.path")
+
+ // URLPortKey is the attribute Key conforming to the "url.port" semantic
+ // conventions. It represents the port extracted from the `url.full`.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 443
+ URLPortKey = attribute.Key("url.port")
+
+ // URLQueryKey is the attribute Key conforming to the "url.query" semantic
+ // conventions. It represents the [URI query] component.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ //
+ // Examples: "q=OpenTelemetry"
+ // Note: Sensitive content provided in `url.query` SHOULD be scrubbed when
+ // instrumentations can identify it.
+ //
+ //
+ // Query string values for the following keys SHOULD be redacted by default and
+ // replaced by the value `REDACTED`:
+ //
+ // - [`AWSAccessKeyId`]
+ // - [`Signature`]
+ // - [`sig`]
+ // - [`X-Goog-Signature`]
+ //
+ // This list is subject to change over time.
+ //
+ // Matching of query parameter keys against the sensitive list SHOULD be
+ // case-sensitive.
+ //
+ // Instrumentation MAY provide a way to override this list via declarative
+ // configuration.
+ // If so, it SHOULD use the `sensitive_query_parameters` property
+ // (an array of case-sensitive strings with minimum items 0) under
+ // `.instrumentation/development.general.sanitization.url`.
+ // This list is a full override of the default sensitive query parameter keys,
+ // it is not a list of keys in addition to the defaults.
+ //
+ // When a query string value is redacted, the query string key SHOULD still be
+ // preserved, e.g.
+ // `q=OpenTelemetry&sig=REDACTED`.
+ //
+ // [URI query]: https://www.rfc-editor.org/rfc/rfc3986#section-3.4
+ // [`AWSAccessKeyId`]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/RESTAuthentication.html#RESTAuthenticationQueryStringAuth
+ // [`Signature`]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/RESTAuthentication.html#RESTAuthenticationQueryStringAuth
+ // [`sig`]: https://learn.microsoft.com/azure/storage/common/storage-sas-overview#sas-token
+ // [`X-Goog-Signature`]: https://cloud.google.com/storage/docs/access-control/signed-urls
+ URLQueryKey = attribute.Key("url.query")
+
+ // URLRegisteredDomainKey is the attribute Key conforming to the
+ // "url.registered_domain" semantic conventions. It represents the highest
+ // registered url domain, stripped of the subdomain.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "example.com", "foo.co.uk"
+ // Note: This value can be determined precisely with the [public suffix list].
+ // For example, the registered domain for `foo.example.com` is `example.com`.
+ // Trying to approximate this by simply taking the last two labels will not work
+ // well for TLDs such as `co.uk`.
+ //
+ // [public suffix list]: https://publicsuffix.org/
+ URLRegisteredDomainKey = attribute.Key("url.registered_domain")
+
+ // URLSchemeKey is the attribute Key conforming to the "url.scheme" semantic
+ // conventions. It represents the [URI scheme] component identifying the used
+ // protocol.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ //
+ // Examples: "https", "ftp", "telnet"
+ //
+ // [URI scheme]: https://www.rfc-editor.org/rfc/rfc3986#section-3.1
+ URLSchemeKey = attribute.Key("url.scheme")
+
+ // URLSubdomainKey is the attribute Key conforming to the "url.subdomain"
+ // semantic conventions. It represents the subdomain portion of a fully
+ // qualified domain name includes all of the names except the host name under
+ // the registered_domain. In a partially qualified domain, or if the
+ // qualification level of the full name cannot be determined, subdomain contains
+ // all of the names below the registered domain.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "east", "sub2.sub1"
+ // Note: The subdomain portion of `www.east.mydomain.co.uk` is `east`. If the
+ // domain has multiple levels of subdomain, such as `sub2.sub1.example.com`, the
+ // subdomain field should contain `sub2.sub1`, with no trailing period.
+ URLSubdomainKey = attribute.Key("url.subdomain")
+
+ // URLTemplateKey is the attribute Key conforming to the "url.template" semantic
+ // conventions. It represents the low-cardinality template of an
+ // [absolute path reference].
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "/users/{id}", "/users/:id", "/users?id={id}"
+ //
+ // [absolute path reference]: https://www.rfc-editor.org/rfc/rfc3986#section-4.2
+ URLTemplateKey = attribute.Key("url.template")
+
+ // URLTopLevelDomainKey is the attribute Key conforming to the
+ // "url.top_level_domain" semantic conventions. It represents the effective top
+ // level domain (eTLD), also known as the domain suffix, is the last part of the
+ // domain name. For example, the top level domain for example.com is `com`.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "com", "co.uk"
+ // Note: This value can be determined precisely with the [public suffix list].
+ //
+ // [public suffix list]: https://publicsuffix.org/
+ URLTopLevelDomainKey = attribute.Key("url.top_level_domain")
+)
+
+// URLDomain returns an attribute KeyValue conforming to the "url.domain"
+// semantic conventions. It represents the domain extracted from the `url.full`,
+// such as "opentelemetry.io".
+func URLDomain(val string) attribute.KeyValue {
+ return URLDomainKey.String(val)
+}
+
+// URLExtension returns an attribute KeyValue conforming to the "url.extension"
+// semantic conventions. It represents the file extension extracted from the
+// `url.full`, excluding the leading dot.
+func URLExtension(val string) attribute.KeyValue {
+ return URLExtensionKey.String(val)
+}
+
+// URLFragment returns an attribute KeyValue conforming to the "url.fragment"
+// semantic conventions. It represents the [URI fragment] component.
+//
+// [URI fragment]: https://www.rfc-editor.org/rfc/rfc3986#section-3.5
+func URLFragment(val string) attribute.KeyValue {
+ return URLFragmentKey.String(val)
+}
+
+// URLFull returns an attribute KeyValue conforming to the "url.full" semantic
+// conventions. It represents the absolute URL describing a network resource
+// according to [RFC3986].
+//
+// [RFC3986]: https://www.rfc-editor.org/rfc/rfc3986
+func URLFull(val string) attribute.KeyValue {
+ return URLFullKey.String(val)
+}
+
+// URLOriginal returns an attribute KeyValue conforming to the "url.original"
+// semantic conventions. It represents the unmodified original URL as seen in the
+// event source.
+func URLOriginal(val string) attribute.KeyValue {
+ return URLOriginalKey.String(val)
+}
+
+// URLPath returns an attribute KeyValue conforming to the "url.path" semantic
+// conventions. It represents the [URI path] component.
+//
+// [URI path]: https://www.rfc-editor.org/rfc/rfc3986#section-3.3
+func URLPath(val string) attribute.KeyValue {
+ return URLPathKey.String(val)
+}
+
+// URLPort returns an attribute KeyValue conforming to the "url.port" semantic
+// conventions. It represents the port extracted from the `url.full`.
+func URLPort(val int) attribute.KeyValue {
+ return URLPortKey.Int(val)
+}
+
+// URLQuery returns an attribute KeyValue conforming to the "url.query" semantic
+// conventions. It represents the [URI query] component.
+//
+// [URI query]: https://www.rfc-editor.org/rfc/rfc3986#section-3.4
+func URLQuery(val string) attribute.KeyValue {
+ return URLQueryKey.String(val)
+}
+
+// URLRegisteredDomain returns an attribute KeyValue conforming to the
+// "url.registered_domain" semantic conventions. It represents the highest
+// registered url domain, stripped of the subdomain.
+func URLRegisteredDomain(val string) attribute.KeyValue {
+ return URLRegisteredDomainKey.String(val)
+}
+
+// URLScheme returns an attribute KeyValue conforming to the "url.scheme"
+// semantic conventions. It represents the [URI scheme] component identifying the
+// used protocol.
+//
+// [URI scheme]: https://www.rfc-editor.org/rfc/rfc3986#section-3.1
+func URLScheme(val string) attribute.KeyValue {
+ return URLSchemeKey.String(val)
+}
+
+// URLSubdomain returns an attribute KeyValue conforming to the "url.subdomain"
+// semantic conventions. It represents the subdomain portion of a fully qualified
+// domain name includes all of the names except the host name under the
+// registered_domain. In a partially qualified domain, or if the qualification
+// level of the full name cannot be determined, subdomain contains all of the
+// names below the registered domain.
+func URLSubdomain(val string) attribute.KeyValue {
+ return URLSubdomainKey.String(val)
+}
+
+// URLTemplate returns an attribute KeyValue conforming to the "url.template"
+// semantic conventions. It represents the low-cardinality template of an
+// [absolute path reference].
+//
+// [absolute path reference]: https://www.rfc-editor.org/rfc/rfc3986#section-4.2
+func URLTemplate(val string) attribute.KeyValue {
+ return URLTemplateKey.String(val)
+}
+
+// URLTopLevelDomain returns an attribute KeyValue conforming to the
+// "url.top_level_domain" semantic conventions. It represents the effective top
+// level domain (eTLD), also known as the domain suffix, is the last part of the
+// domain name. For example, the top level domain for example.com is `com`.
+func URLTopLevelDomain(val string) attribute.KeyValue {
+ return URLTopLevelDomainKey.String(val)
+}
+
+// Namespace: user
+const (
+ // UserEmailKey is the attribute Key conforming to the "user.email" semantic
+ // conventions. It represents the user email address.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "a.einstein@example.com"
+ UserEmailKey = attribute.Key("user.email")
+
+ // UserFullNameKey is the attribute Key conforming to the "user.full_name"
+ // semantic conventions. It represents the user's full name.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "Albert Einstein"
+ UserFullNameKey = attribute.Key("user.full_name")
+
+ // UserHashKey is the attribute Key conforming to the "user.hash" semantic
+ // conventions. It represents the unique user hash to correlate information for
+ // a user in anonymized form.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "364fc68eaf4c8acec74a4e52d7d1feaa"
+ // Note: Useful if `user.id` or `user.name` contain confidential information and
+ // cannot be used.
+ UserHashKey = attribute.Key("user.hash")
+
+ // UserIDKey is the attribute Key conforming to the "user.id" semantic
+ // conventions. It represents the unique identifier of the user.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "S-1-5-21-202424912787-2692429404-2351956786-1000"
+ UserIDKey = attribute.Key("user.id")
+
+ // UserNameKey is the attribute Key conforming to the "user.name" semantic
+ // conventions. It represents the short name or login/username of the user.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "a.einstein"
+ UserNameKey = attribute.Key("user.name")
+
+ // UserRolesKey is the attribute Key conforming to the "user.roles" semantic
+ // conventions. It represents the array of user roles at the time of the event.
+ //
+ // Type: string[]
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "admin", "reporting_user"
+ UserRolesKey = attribute.Key("user.roles")
+)
+
+// UserEmail returns an attribute KeyValue conforming to the "user.email"
+// semantic conventions. It represents the user email address.
+func UserEmail(val string) attribute.KeyValue {
+ return UserEmailKey.String(val)
+}
+
+// UserFullName returns an attribute KeyValue conforming to the "user.full_name"
+// semantic conventions. It represents the user's full name.
+func UserFullName(val string) attribute.KeyValue {
+ return UserFullNameKey.String(val)
+}
+
+// UserHash returns an attribute KeyValue conforming to the "user.hash" semantic
+// conventions. It represents the unique user hash to correlate information for a
+// user in anonymized form.
+func UserHash(val string) attribute.KeyValue {
+ return UserHashKey.String(val)
+}
+
+// UserID returns an attribute KeyValue conforming to the "user.id" semantic
+// conventions. It represents the unique identifier of the user.
+func UserID(val string) attribute.KeyValue {
+ return UserIDKey.String(val)
+}
+
+// UserName returns an attribute KeyValue conforming to the "user.name" semantic
+// conventions. It represents the short name or login/username of the user.
+func UserName(val string) attribute.KeyValue {
+ return UserNameKey.String(val)
+}
+
+// UserRoles returns an attribute KeyValue conforming to the "user.roles"
+// semantic conventions. It represents the array of user roles at the time of the
+// event.
+func UserRoles(val ...string) attribute.KeyValue {
+ return UserRolesKey.StringSlice(val)
+}
+
+// Namespace: user_agent
+const (
+ // UserAgentNameKey is the attribute Key conforming to the "user_agent.name"
+ // semantic conventions. It represents the name of the user-agent extracted from
+ // original. Usually refers to the browser's name.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "Safari", "YourApp"
+ // Note: [Example] of extracting browser's name from original string. In the
+ // case of using a user-agent for non-browser products, such as microservices
+ // with multiple names/versions inside the `user_agent.original`, the most
+ // significant name SHOULD be selected. In such a scenario it should align with
+ // `user_agent.version`
+ //
+ // [Example]: https://uaparser.dev/#demo
+ UserAgentNameKey = attribute.Key("user_agent.name")
+
+ // UserAgentOriginalKey is the attribute Key conforming to the
+ // "user_agent.original" semantic conventions. It represents the value of the
+ // [HTTP User-Agent] header sent by the client.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ //
+ // Examples: "CERN-LineMode/2.15 libwww/2.17b3", "Mozilla/5.0 (iPhone; CPU
+ // iPhone OS 14_7_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko)
+ // Version/14.1.2 Mobile/15E148 Safari/604.1", "YourApp/1.0.0
+ // grpc-java-okhttp/1.27.2"
+ //
+ // [HTTP User-Agent]: https://www.rfc-editor.org/rfc/rfc9110.html#field.user-agent
+ UserAgentOriginalKey = attribute.Key("user_agent.original")
+
+ // UserAgentOSNameKey is the attribute Key conforming to the
+ // "user_agent.os.name" semantic conventions. It represents the human readable
+ // operating system name.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "iOS", "Android", "Ubuntu"
+ // Note: For mapping user agent strings to OS names, libraries such as
+ // [ua-parser] can be utilized.
+ //
+ // [ua-parser]: https://github.com/ua-parser
+ UserAgentOSNameKey = attribute.Key("user_agent.os.name")
+
+ // UserAgentOSVersionKey is the attribute Key conforming to the
+ // "user_agent.os.version" semantic conventions. It represents the version
+ // string of the operating system as defined in [Version Attributes].
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "14.2.1", "18.04.1"
+ // Note: For mapping user agent strings to OS versions, libraries such as
+ // [ua-parser] can be utilized.
+ //
+ // [Version Attributes]: /docs/resource/README.md#version-attributes
+ // [ua-parser]: https://github.com/ua-parser
+ UserAgentOSVersionKey = attribute.Key("user_agent.os.version")
+
+ // UserAgentSyntheticTypeKey is the attribute Key conforming to the
+ // "user_agent.synthetic.type" semantic conventions. It represents the specifies
+ // the category of synthetic traffic, such as tests or bots.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ // Note: This attribute MAY be derived from the contents of the
+ // `user_agent.original` attribute. Components that populate the attribute are
+ // responsible for determining what they consider to be synthetic bot or test
+ // traffic. This attribute can either be set for self-identification purposes,
+ // or on telemetry detected to be generated as a result of a synthetic request.
+ // This attribute is useful for distinguishing between genuine client traffic
+ // and synthetic traffic generated by bots or tests.
+ UserAgentSyntheticTypeKey = attribute.Key("user_agent.synthetic.type")
+
+ // UserAgentVersionKey is the attribute Key conforming to the
+ // "user_agent.version" semantic conventions. It represents the version of the
+ // user-agent extracted from original. Usually refers to the browser's version.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "14.1.2", "1.0.0"
+ // Note: [Example] of extracting browser's version from original string. In the
+ // case of using a user-agent for non-browser products, such as microservices
+ // with multiple names/versions inside the `user_agent.original`, the most
+ // significant version SHOULD be selected. In such a scenario it should align
+ // with `user_agent.name`
+ //
+ // [Example]: https://uaparser.dev/#demo
+ UserAgentVersionKey = attribute.Key("user_agent.version")
+)
+
+// UserAgentName returns an attribute KeyValue conforming to the
+// "user_agent.name" semantic conventions. It represents the name of the
+// user-agent extracted from original. Usually refers to the browser's name.
+func UserAgentName(val string) attribute.KeyValue {
+ return UserAgentNameKey.String(val)
+}
+
+// UserAgentOriginal returns an attribute KeyValue conforming to the
+// "user_agent.original" semantic conventions. It represents the value of the
+// [HTTP User-Agent] header sent by the client.
+//
+// [HTTP User-Agent]: https://www.rfc-editor.org/rfc/rfc9110.html#field.user-agent
+func UserAgentOriginal(val string) attribute.KeyValue {
+ return UserAgentOriginalKey.String(val)
+}
+
+// UserAgentOSName returns an attribute KeyValue conforming to the
+// "user_agent.os.name" semantic conventions. It represents the human readable
+// operating system name.
+func UserAgentOSName(val string) attribute.KeyValue {
+ return UserAgentOSNameKey.String(val)
+}
+
+// UserAgentOSVersion returns an attribute KeyValue conforming to the
+// "user_agent.os.version" semantic conventions. It represents the version string
+// of the operating system as defined in [Version Attributes].
+//
+// [Version Attributes]: /docs/resource/README.md#version-attributes
+func UserAgentOSVersion(val string) attribute.KeyValue {
+ return UserAgentOSVersionKey.String(val)
+}
+
+// UserAgentVersion returns an attribute KeyValue conforming to the
+// "user_agent.version" semantic conventions. It represents the version of the
+// user-agent extracted from original. Usually refers to the browser's version.
+func UserAgentVersion(val string) attribute.KeyValue {
+ return UserAgentVersionKey.String(val)
+}
+
+// Enum values for user_agent.synthetic.type
+var (
+ // Bot source.
+ // Stability: development
+ UserAgentSyntheticTypeBot = UserAgentSyntheticTypeKey.String("bot")
+ // Synthetic test source.
+ // Stability: development
+ UserAgentSyntheticTypeTest = UserAgentSyntheticTypeKey.String("test")
+)
+
+// Namespace: vcs
+const (
+ // VCSChangeIDKey is the attribute Key conforming to the "vcs.change.id"
+ // semantic conventions. It represents the ID of the change (pull request/merge
+ // request/changelist) if applicable. This is usually a unique (within
+ // repository) identifier generated by the VCS system.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "123"
+ VCSChangeIDKey = attribute.Key("vcs.change.id")
+
+ // VCSChangeStateKey is the attribute Key conforming to the "vcs.change.state"
+ // semantic conventions. It represents the state of the change (pull
+ // request/merge request/changelist).
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "open", "closed", "merged"
+ VCSChangeStateKey = attribute.Key("vcs.change.state")
+
+ // VCSChangeTitleKey is the attribute Key conforming to the "vcs.change.title"
+ // semantic conventions. It represents the human readable title of the change
+ // (pull request/merge request/changelist). This title is often a brief summary
+ // of the change and may get merged in to a ref as the commit summary.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "Fixes broken thing", "feat: add my new feature", "[chore] update
+ // dependency"
+ VCSChangeTitleKey = attribute.Key("vcs.change.title")
+
+ // VCSLineChangeTypeKey is the attribute Key conforming to the
+ // "vcs.line_change.type" semantic conventions. It represents the type of line
+ // change being measured on a branch or change.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "added", "removed"
+ VCSLineChangeTypeKey = attribute.Key("vcs.line_change.type")
+
+ // VCSOwnerNameKey is the attribute Key conforming to the "vcs.owner.name"
+ // semantic conventions. It represents the group owner within the version
+ // control system.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "my-org", "myteam", "business-unit"
+ VCSOwnerNameKey = attribute.Key("vcs.owner.name")
+
+ // VCSProviderNameKey is the attribute Key conforming to the "vcs.provider.name"
+ // semantic conventions. It represents the name of the version control system
+ // provider.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "github", "gitlab", "gitea", "bitbucket"
+ VCSProviderNameKey = attribute.Key("vcs.provider.name")
+
+ // VCSRefBaseNameKey is the attribute Key conforming to the "vcs.ref.base.name"
+ // semantic conventions. It represents the name of the [reference] such as
+ // **branch** or **tag** in the repository.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "my-feature-branch", "tag-1-test"
+ // Note: `base` refers to the starting point of a change. For example, `main`
+ // would be the base reference of type branch if you've created a new
+ // reference of type branch from it and created new commits.
+ //
+ // [reference]: https://git-scm.com/docs/gitglossary#def_ref
+ VCSRefBaseNameKey = attribute.Key("vcs.ref.base.name")
+
+ // VCSRefBaseRevisionKey is the attribute Key conforming to the
+ // "vcs.ref.base.revision" semantic conventions. It represents the revision,
+ // literally [revised version], The revision most often refers to a commit
+ // object in Git, or a revision number in SVN.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "9d59409acf479dfa0df1aa568182e43e43df8bbe28d60fcf2bc52e30068802cc",
+ // "main", "123", "HEAD"
+ // Note: `base` refers to the starting point of a change. For example, `main`
+ // would be the base reference of type branch if you've created a new
+ // reference of type branch from it and created new commits. The
+ // revision can be a full [hash value (see
+ // glossary)],
+ // of the recorded change to a ref within a repository pointing to a
+ // commit [commit] object. It does
+ // not necessarily have to be a hash; it can simply define a [revision
+ // number]
+ // which is an integer that is monotonically increasing. In cases where
+ // it is identical to the `ref.base.name`, it SHOULD still be included.
+ // It is up to the implementer to decide which value to set as the
+ // revision based on the VCS system and situational context.
+ //
+ // [revised version]: https://www.merriam-webster.com/dictionary/revision
+ // [hash value (see
+ // glossary)]: https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-5.pdf
+ // [commit]: https://git-scm.com/docs/git-commit
+ // [revision
+ // number]: https://svnbook.red-bean.com/en/1.7/svn.tour.revs.specifiers.html
+ VCSRefBaseRevisionKey = attribute.Key("vcs.ref.base.revision")
+
+ // VCSRefBaseTypeKey is the attribute Key conforming to the "vcs.ref.base.type"
+ // semantic conventions. It represents the type of the [reference] in the
+ // repository.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "branch", "tag"
+ // Note: `base` refers to the starting point of a change. For example, `main`
+ // would be the base reference of type branch if you've created a new
+ // reference of type branch from it and created new commits.
+ //
+ // [reference]: https://git-scm.com/docs/gitglossary#def_ref
+ VCSRefBaseTypeKey = attribute.Key("vcs.ref.base.type")
+
+ // VCSRefHeadNameKey is the attribute Key conforming to the "vcs.ref.head.name"
+ // semantic conventions. It represents the name of the [reference] such as
+ // **branch** or **tag** in the repository.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "my-feature-branch", "tag-1-test"
+ // Note: `head` refers to where you are right now; the current reference at a
+ // given time.
+ //
+ // [reference]: https://git-scm.com/docs/gitglossary#def_ref
+ VCSRefHeadNameKey = attribute.Key("vcs.ref.head.name")
+
+ // VCSRefHeadRevisionKey is the attribute Key conforming to the
+ // "vcs.ref.head.revision" semantic conventions. It represents the revision,
+ // literally [revised version], The revision most often refers to a commit
+ // object in Git, or a revision number in SVN.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "9d59409acf479dfa0df1aa568182e43e43df8bbe28d60fcf2bc52e30068802cc",
+ // "main", "123", "HEAD"
+ // Note: `head` refers to where you are right now; the current reference at a
+ // given time.The revision can be a full [hash value (see
+ // glossary)],
+ // of the recorded change to a ref within a repository pointing to a
+ // commit [commit] object. It does
+ // not necessarily have to be a hash; it can simply define a [revision
+ // number]
+ // which is an integer that is monotonically increasing. In cases where
+ // it is identical to the `ref.head.name`, it SHOULD still be included.
+ // It is up to the implementer to decide which value to set as the
+ // revision based on the VCS system and situational context.
+ //
+ // [revised version]: https://www.merriam-webster.com/dictionary/revision
+ // [hash value (see
+ // glossary)]: https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-5.pdf
+ // [commit]: https://git-scm.com/docs/git-commit
+ // [revision
+ // number]: https://svnbook.red-bean.com/en/1.7/svn.tour.revs.specifiers.html
+ VCSRefHeadRevisionKey = attribute.Key("vcs.ref.head.revision")
+
+ // VCSRefHeadTypeKey is the attribute Key conforming to the "vcs.ref.head.type"
+ // semantic conventions. It represents the type of the [reference] in the
+ // repository.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "branch", "tag"
+ // Note: `head` refers to where you are right now; the current reference at a
+ // given time.
+ //
+ // [reference]: https://git-scm.com/docs/gitglossary#def_ref
+ VCSRefHeadTypeKey = attribute.Key("vcs.ref.head.type")
+
+ // VCSRefTypeKey is the attribute Key conforming to the "vcs.ref.type" semantic
+ // conventions. It represents the type of the [reference] in the repository.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "branch", "tag"
+ //
+ // [reference]: https://git-scm.com/docs/gitglossary#def_ref
+ VCSRefTypeKey = attribute.Key("vcs.ref.type")
+
+ // VCSRepositoryNameKey is the attribute Key conforming to the
+ // "vcs.repository.name" semantic conventions. It represents the human readable
+ // name of the repository. It SHOULD NOT include any additional identifier like
+ // Group/SubGroup in GitLab or organization in GitHub.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "semantic-conventions", "my-cool-repo"
+ // Note: Due to it only being the name, it can clash with forks of the same
+ // repository if collecting telemetry across multiple orgs or groups in
+ // the same backends.
+ VCSRepositoryNameKey = attribute.Key("vcs.repository.name")
+
+ // VCSRepositoryURLFullKey is the attribute Key conforming to the
+ // "vcs.repository.url.full" semantic conventions. It represents the
+ // [canonical URL] of the repository providing the complete HTTP(S) address in
+ // order to locate and identify the repository through a browser.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ // "https://github.com/opentelemetry/open-telemetry-collector-contrib",
+ // "https://gitlab.com/my-org/my-project/my-projects-project/repo"
+ // Note: In Git Version Control Systems, the canonical URL SHOULD NOT include
+ // the `.git` extension.
+ //
+ // [canonical URL]: https://support.google.com/webmasters/answer/10347851
+ VCSRepositoryURLFullKey = attribute.Key("vcs.repository.url.full")
+
+ // VCSRevisionDeltaDirectionKey is the attribute Key conforming to the
+ // "vcs.revision_delta.direction" semantic conventions. It represents the type
+ // of revision comparison.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "ahead", "behind"
+ VCSRevisionDeltaDirectionKey = attribute.Key("vcs.revision_delta.direction")
+)
+
+// VCSChangeID returns an attribute KeyValue conforming to the "vcs.change.id"
+// semantic conventions. It represents the ID of the change (pull request/merge
+// request/changelist) if applicable. This is usually a unique (within
+// repository) identifier generated by the VCS system.
+func VCSChangeID(val string) attribute.KeyValue {
+ return VCSChangeIDKey.String(val)
+}
+
+// VCSChangeTitle returns an attribute KeyValue conforming to the
+// "vcs.change.title" semantic conventions. It represents the human readable
+// title of the change (pull request/merge request/changelist). This title is
+// often a brief summary of the change and may get merged in to a ref as the
+// commit summary.
+func VCSChangeTitle(val string) attribute.KeyValue {
+ return VCSChangeTitleKey.String(val)
+}
+
+// VCSOwnerName returns an attribute KeyValue conforming to the "vcs.owner.name"
+// semantic conventions. It represents the group owner within the version control
+// system.
+func VCSOwnerName(val string) attribute.KeyValue {
+ return VCSOwnerNameKey.String(val)
+}
+
+// VCSRefBaseName returns an attribute KeyValue conforming to the
+// "vcs.ref.base.name" semantic conventions. It represents the name of the
+// [reference] such as **branch** or **tag** in the repository.
+//
+// [reference]: https://git-scm.com/docs/gitglossary#def_ref
+func VCSRefBaseName(val string) attribute.KeyValue {
+ return VCSRefBaseNameKey.String(val)
+}
+
+// VCSRefBaseRevision returns an attribute KeyValue conforming to the
+// "vcs.ref.base.revision" semantic conventions. It represents the revision,
+// literally [revised version], The revision most often refers to a commit object
+// in Git, or a revision number in SVN.
+//
+// [revised version]: https://www.merriam-webster.com/dictionary/revision
+func VCSRefBaseRevision(val string) attribute.KeyValue {
+ return VCSRefBaseRevisionKey.String(val)
+}
+
+// VCSRefHeadName returns an attribute KeyValue conforming to the
+// "vcs.ref.head.name" semantic conventions. It represents the name of the
+// [reference] such as **branch** or **tag** in the repository.
+//
+// [reference]: https://git-scm.com/docs/gitglossary#def_ref
+func VCSRefHeadName(val string) attribute.KeyValue {
+ return VCSRefHeadNameKey.String(val)
+}
+
+// VCSRefHeadRevision returns an attribute KeyValue conforming to the
+// "vcs.ref.head.revision" semantic conventions. It represents the revision,
+// literally [revised version], The revision most often refers to a commit object
+// in Git, or a revision number in SVN.
+//
+// [revised version]: https://www.merriam-webster.com/dictionary/revision
+func VCSRefHeadRevision(val string) attribute.KeyValue {
+ return VCSRefHeadRevisionKey.String(val)
+}
+
+// VCSRepositoryName returns an attribute KeyValue conforming to the
+// "vcs.repository.name" semantic conventions. It represents the human readable
+// name of the repository. It SHOULD NOT include any additional identifier like
+// Group/SubGroup in GitLab or organization in GitHub.
+func VCSRepositoryName(val string) attribute.KeyValue {
+ return VCSRepositoryNameKey.String(val)
+}
+
+// VCSRepositoryURLFull returns an attribute KeyValue conforming to the
+// "vcs.repository.url.full" semantic conventions. It represents the
+// [canonical URL] of the repository providing the complete HTTP(S) address in
+// order to locate and identify the repository through a browser.
+//
+// [canonical URL]: https://support.google.com/webmasters/answer/10347851
+func VCSRepositoryURLFull(val string) attribute.KeyValue {
+ return VCSRepositoryURLFullKey.String(val)
+}
+
+// Enum values for vcs.change.state
+var (
+ // Open means the change is currently active and under review. It hasn't been
+ // merged into the target branch yet, and it's still possible to make changes or
+ // add comments.
+ // Stability: development
+ VCSChangeStateOpen = VCSChangeStateKey.String("open")
+ // WIP (work-in-progress, draft) means the change is still in progress and not
+ // yet ready for a full review. It might still undergo significant changes.
+ // Stability: development
+ VCSChangeStateWip = VCSChangeStateKey.String("wip")
+ // Closed means the merge request has been closed without merging. This can
+ // happen for various reasons, such as the changes being deemed unnecessary, the
+ // issue being resolved in another way, or the author deciding to withdraw the
+ // request.
+ // Stability: development
+ VCSChangeStateClosed = VCSChangeStateKey.String("closed")
+ // Merged indicates that the change has been successfully integrated into the
+ // target codebase.
+ // Stability: development
+ VCSChangeStateMerged = VCSChangeStateKey.String("merged")
+)
+
+// Enum values for vcs.line_change.type
+var (
+ // How many lines were added.
+ // Stability: development
+ VCSLineChangeTypeAdded = VCSLineChangeTypeKey.String("added")
+ // How many lines were removed.
+ // Stability: development
+ VCSLineChangeTypeRemoved = VCSLineChangeTypeKey.String("removed")
+)
+
+// Enum values for vcs.provider.name
+var (
+ // [GitHub]
+ // Stability: development
+ //
+ // [GitHub]: https://github.com
+ VCSProviderNameGithub = VCSProviderNameKey.String("github")
+ // [GitLab]
+ // Stability: development
+ //
+ // [GitLab]: https://gitlab.com
+ VCSProviderNameGitlab = VCSProviderNameKey.String("gitlab")
+ // [Gitea]
+ // Stability: development
+ //
+ // [Gitea]: https://gitea.io
+ VCSProviderNameGitea = VCSProviderNameKey.String("gitea")
+ // [Bitbucket]
+ // Stability: development
+ //
+ // [Bitbucket]: https://bitbucket.org
+ VCSProviderNameBitbucket = VCSProviderNameKey.String("bitbucket")
+)
+
+// Enum values for vcs.ref.base.type
+var (
+ // [branch]
+ // Stability: development
+ //
+ // [branch]: https://git-scm.com/docs/gitglossary#Documentation/gitglossary.txt-aiddefbranchabranch
+ VCSRefBaseTypeBranch = VCSRefBaseTypeKey.String("branch")
+ // [tag]
+ // Stability: development
+ //
+ // [tag]: https://git-scm.com/docs/gitglossary#Documentation/gitglossary.txt-aiddeftagatag
+ VCSRefBaseTypeTag = VCSRefBaseTypeKey.String("tag")
+)
+
+// Enum values for vcs.ref.head.type
+var (
+ // [branch]
+ // Stability: development
+ //
+ // [branch]: https://git-scm.com/docs/gitglossary#Documentation/gitglossary.txt-aiddefbranchabranch
+ VCSRefHeadTypeBranch = VCSRefHeadTypeKey.String("branch")
+ // [tag]
+ // Stability: development
+ //
+ // [tag]: https://git-scm.com/docs/gitglossary#Documentation/gitglossary.txt-aiddeftagatag
+ VCSRefHeadTypeTag = VCSRefHeadTypeKey.String("tag")
+)
+
+// Enum values for vcs.ref.type
+var (
+ // [branch]
+ // Stability: development
+ //
+ // [branch]: https://git-scm.com/docs/gitglossary#Documentation/gitglossary.txt-aiddefbranchabranch
+ VCSRefTypeBranch = VCSRefTypeKey.String("branch")
+ // [tag]
+ // Stability: development
+ //
+ // [tag]: https://git-scm.com/docs/gitglossary#Documentation/gitglossary.txt-aiddeftagatag
+ VCSRefTypeTag = VCSRefTypeKey.String("tag")
+)
+
+// Enum values for vcs.revision_delta.direction
+var (
+ // How many revisions the change is behind the target ref.
+ // Stability: development
+ VCSRevisionDeltaDirectionBehind = VCSRevisionDeltaDirectionKey.String("behind")
+ // How many revisions the change is ahead of the target ref.
+ // Stability: development
+ VCSRevisionDeltaDirectionAhead = VCSRevisionDeltaDirectionKey.String("ahead")
+)
+
+// Namespace: webengine
+const (
+ // WebEngineDescriptionKey is the attribute Key conforming to the
+ // "webengine.description" semantic conventions. It represents the additional
+ // description of the web engine (e.g. detailed version and edition
+ // information).
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "WildFly Full 21.0.0.Final (WildFly Core 13.0.1.Final) -
+ // 2.2.2.Final"
+ WebEngineDescriptionKey = attribute.Key("webengine.description")
+
+ // WebEngineNameKey is the attribute Key conforming to the "webengine.name"
+ // semantic conventions. It represents the name of the web engine.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "WildFly"
+ WebEngineNameKey = attribute.Key("webengine.name")
+
+ // WebEngineVersionKey is the attribute Key conforming to the
+ // "webengine.version" semantic conventions. It represents the version of the
+ // web engine.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "21.0.0"
+ WebEngineVersionKey = attribute.Key("webengine.version")
+)
+
+// WebEngineDescription returns an attribute KeyValue conforming to the
+// "webengine.description" semantic conventions. It represents the additional
+// description of the web engine (e.g. detailed version and edition information).
+func WebEngineDescription(val string) attribute.KeyValue {
+ return WebEngineDescriptionKey.String(val)
+}
+
+// WebEngineName returns an attribute KeyValue conforming to the "webengine.name"
+// semantic conventions. It represents the name of the web engine.
+func WebEngineName(val string) attribute.KeyValue {
+ return WebEngineNameKey.String(val)
+}
+
+// WebEngineVersion returns an attribute KeyValue conforming to the
+// "webengine.version" semantic conventions. It represents the version of the web
+// engine.
+func WebEngineVersion(val string) attribute.KeyValue {
+ return WebEngineVersionKey.String(val)
+}
+
+// Namespace: zos
+const (
+ // ZOSSmfIDKey is the attribute Key conforming to the "zos.smf.id" semantic
+ // conventions. It represents the System Management Facility (SMF) Identifier
+ // uniquely identified a z/OS system within a SYSPLEX or mainframe environment
+ // and is used for system and performance analysis.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "SYS1"
+ ZOSSmfIDKey = attribute.Key("zos.smf.id")
+
+ // ZOSSysplexNameKey is the attribute Key conforming to the "zos.sysplex.name"
+ // semantic conventions. It represents the name of the SYSPLEX to which the z/OS
+ // system belongs too.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "SYSPLEX1"
+ ZOSSysplexNameKey = attribute.Key("zos.sysplex.name")
+)
+
+// ZOSSmfID returns an attribute KeyValue conforming to the "zos.smf.id" semantic
+// conventions. It represents the System Management Facility (SMF) Identifier
+// uniquely identified a z/OS system within a SYSPLEX or mainframe environment
+// and is used for system and performance analysis.
+func ZOSSmfID(val string) attribute.KeyValue {
+ return ZOSSmfIDKey.String(val)
+}
+
+// ZOSSysplexName returns an attribute KeyValue conforming to the
+// "zos.sysplex.name" semantic conventions. It represents the name of the SYSPLEX
+// to which the z/OS system belongs too.
+func ZOSSysplexName(val string) attribute.KeyValue {
+ return ZOSSysplexNameKey.String(val)
+}
diff --git a/vendor/go.opentelemetry.io/otel/semconv/v1.40.0/doc.go b/vendor/go.opentelemetry.io/otel/semconv/v1.40.0/doc.go
new file mode 100644
index 000000000..c5c41e4d2
--- /dev/null
+++ b/vendor/go.opentelemetry.io/otel/semconv/v1.40.0/doc.go
@@ -0,0 +1,9 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+// Package semconv implements OpenTelemetry semantic conventions.
+//
+// OpenTelemetry semantic conventions are agreed standardized naming
+// patterns for OpenTelemetry things. This package represents the v1.40.0
+// version of the OpenTelemetry semantic conventions.
+package semconv // import "go.opentelemetry.io/otel/semconv/v1.40.0"
diff --git a/vendor/go.opentelemetry.io/otel/semconv/v1.40.0/error_type.go b/vendor/go.opentelemetry.io/otel/semconv/v1.40.0/error_type.go
new file mode 100644
index 000000000..1cb89f79d
--- /dev/null
+++ b/vendor/go.opentelemetry.io/otel/semconv/v1.40.0/error_type.go
@@ -0,0 +1,81 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+package semconv // import "go.opentelemetry.io/otel/semconv/v1.40.0"
+
+import (
+ "errors"
+ "fmt"
+ "reflect"
+
+ "go.opentelemetry.io/otel/attribute"
+)
+
+// ErrorType returns an [attribute.KeyValue] identifying the error type of err.
+//
+// If err is nil, the returned attribute has the default value
+// [ErrorTypeOther].
+//
+// If err or one of the errors in its chain has the method
+//
+// ErrorType() string
+//
+// the returned attribute has that method's return value. If multiple errors in
+// the chain implement this method, the value from the first match found by
+// [errors.As] is used. Otherwise, the returned attribute has a value derived
+// from the concrete type of err after unwrapping any wrappers created with
+// [fmt.Errorf].
+//
+// The key of the returned attribute is [ErrorTypeKey].
+func ErrorType(err error) attribute.KeyValue {
+ if err == nil {
+ return ErrorTypeOther
+ }
+
+ return ErrorTypeKey.String(errorType(err))
+}
+
+func errorType(err error) string {
+ var s string
+ if et, ok := err.(interface{ ErrorType() string }); ok {
+ // Fast path: check the top-level error first.
+ s = et.ErrorType()
+ } else {
+ // Fallback: search the error chain for an ErrorType method.
+ var et interface{ ErrorType() string }
+ if errors.As(err, &et) {
+ // Prioritize the ErrorType method if available.
+ s = et.ErrorType()
+ }
+ }
+ if s == "" {
+ // Fallback to reflection if the ErrorType method is not supported or
+ // returns an empty value.
+
+ t := reflect.TypeOf(unwrapFmtWrapped(err))
+ pkg, name := t.PkgPath(), t.Name()
+ if pkg != "" && name != "" {
+ s = pkg + "." + name
+ } else {
+ // The type has no package path or name (predeclared, not-defined,
+ // or alias for a not-defined type).
+ //
+ // This is not guaranteed to be unique, but is a best effort.
+ s = t.String()
+ }
+ }
+ return s
+}
+
+var fmtWrapErrorType = reflect.TypeOf(fmt.Errorf("wrapped: %w", errors.New("err")))
+
+func unwrapFmtWrapped(err error) error {
+ for reflect.TypeOf(err) == fmtWrapErrorType {
+ u := errors.Unwrap(err)
+ if u == nil {
+ return err // Should never happen, but avoid returning nil if unwrapping fails.
+ }
+ err = u
+ }
+ return err
+}
diff --git a/vendor/go.opentelemetry.io/otel/semconv/v1.40.0/exception.go b/vendor/go.opentelemetry.io/otel/semconv/v1.40.0/exception.go
new file mode 100644
index 000000000..6a26231a1
--- /dev/null
+++ b/vendor/go.opentelemetry.io/otel/semconv/v1.40.0/exception.go
@@ -0,0 +1,9 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+package semconv // import "go.opentelemetry.io/otel/semconv/v1.40.0"
+
+const (
+ // ExceptionEventName is the name of the Span event representing an exception.
+ ExceptionEventName = "exception"
+)
diff --git a/vendor/go.opentelemetry.io/otel/semconv/v1.40.0/httpconv/metric.go b/vendor/go.opentelemetry.io/otel/semconv/v1.40.0/httpconv/metric.go
new file mode 100644
index 000000000..013629dc3
--- /dev/null
+++ b/vendor/go.opentelemetry.io/otel/semconv/v1.40.0/httpconv/metric.go
@@ -0,0 +1,1823 @@
+// Code generated from semantic convention specification. DO NOT EDIT.
+
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+// Package httpconv provides types and functionality for OpenTelemetry semantic
+// conventions in the "http" namespace.
+package httpconv
+
+import (
+ "context"
+ "sync"
+
+ "go.opentelemetry.io/otel/attribute"
+ "go.opentelemetry.io/otel/metric"
+ "go.opentelemetry.io/otel/metric/noop"
+)
+
+var (
+ addOptPool = &sync.Pool{New: func() any { return &[]metric.AddOption{} }}
+ recOptPool = &sync.Pool{New: func() any { return &[]metric.RecordOption{} }}
+)
+
+// ErrorTypeAttr is an attribute conforming to the error.type semantic
+// conventions. It represents the describes a class of error the operation ended
+// with.
+type ErrorTypeAttr string
+
+// ErrorTypeOther is a fallback error value to be used when the instrumentation
+// doesn't define a custom value.
+var ErrorTypeOther ErrorTypeAttr = "_OTHER"
+
+// ConnectionStateAttr is an attribute conforming to the http.connection.state
+// semantic conventions. It represents the state of the HTTP connection in the
+// HTTP connection pool.
+type ConnectionStateAttr string
+
+var (
+ // ConnectionStateActive is the active state.
+ ConnectionStateActive ConnectionStateAttr = "active"
+ // ConnectionStateIdle is the idle state.
+ ConnectionStateIdle ConnectionStateAttr = "idle"
+)
+
+// RequestMethodAttr is an attribute conforming to the http.request.method
+// semantic conventions. It represents the HTTP request method.
+type RequestMethodAttr string
+
+var (
+ // RequestMethodConnect is the CONNECT method.
+ RequestMethodConnect RequestMethodAttr = "CONNECT"
+ // RequestMethodDelete is the DELETE method.
+ RequestMethodDelete RequestMethodAttr = "DELETE"
+ // RequestMethodGet is the GET method.
+ RequestMethodGet RequestMethodAttr = "GET"
+ // RequestMethodHead is the HEAD method.
+ RequestMethodHead RequestMethodAttr = "HEAD"
+ // RequestMethodOptions is the OPTIONS method.
+ RequestMethodOptions RequestMethodAttr = "OPTIONS"
+ // RequestMethodPatch is the PATCH method.
+ RequestMethodPatch RequestMethodAttr = "PATCH"
+ // RequestMethodPost is the POST method.
+ RequestMethodPost RequestMethodAttr = "POST"
+ // RequestMethodPut is the PUT method.
+ RequestMethodPut RequestMethodAttr = "PUT"
+ // RequestMethodTrace is the TRACE method.
+ RequestMethodTrace RequestMethodAttr = "TRACE"
+ // RequestMethodQuery is the QUERY method.
+ RequestMethodQuery RequestMethodAttr = "QUERY"
+ // RequestMethodOther is the any HTTP method that the instrumentation has no
+ // prior knowledge of.
+ RequestMethodOther RequestMethodAttr = "_OTHER"
+)
+
+// UserAgentSyntheticTypeAttr is an attribute conforming to the
+// user_agent.synthetic.type semantic conventions. It represents the specifies
+// the category of synthetic traffic, such as tests or bots.
+type UserAgentSyntheticTypeAttr string
+
+var (
+ // UserAgentSyntheticTypeBot is the bot source.
+ UserAgentSyntheticTypeBot UserAgentSyntheticTypeAttr = "bot"
+ // UserAgentSyntheticTypeTest is the synthetic test source.
+ UserAgentSyntheticTypeTest UserAgentSyntheticTypeAttr = "test"
+)
+
+// ClientActiveRequests is an instrument used to record metric values conforming
+// to the "http.client.active_requests" semantic conventions. It represents the
+// number of active HTTP requests.
+type ClientActiveRequests struct {
+ metric.Int64UpDownCounter
+}
+
+var newClientActiveRequestsOpts = []metric.Int64UpDownCounterOption{
+ metric.WithDescription("Number of active HTTP requests."),
+ metric.WithUnit("{request}"),
+}
+
+// NewClientActiveRequests returns a new ClientActiveRequests instrument.
+func NewClientActiveRequests(
+ m metric.Meter,
+ opt ...metric.Int64UpDownCounterOption,
+) (ClientActiveRequests, error) {
+ // Check if the meter is nil.
+ if m == nil {
+ return ClientActiveRequests{noop.Int64UpDownCounter{}}, nil
+ }
+
+ if len(opt) == 0 {
+ opt = newClientActiveRequestsOpts
+ } else {
+ opt = append(opt, newClientActiveRequestsOpts...)
+ }
+
+ i, err := m.Int64UpDownCounter(
+ "http.client.active_requests",
+ opt...,
+ )
+ if err != nil {
+ return ClientActiveRequests{noop.Int64UpDownCounter{}}, err
+ }
+ return ClientActiveRequests{i}, nil
+}
+
+// Inst returns the underlying metric instrument.
+func (m ClientActiveRequests) Inst() metric.Int64UpDownCounter {
+ return m.Int64UpDownCounter
+}
+
+// Name returns the semantic convention name of the instrument.
+func (ClientActiveRequests) Name() string {
+ return "http.client.active_requests"
+}
+
+// Unit returns the semantic convention unit of the instrument
+func (ClientActiveRequests) Unit() string {
+ return "{request}"
+}
+
+// Description returns the semantic convention description of the instrument
+func (ClientActiveRequests) Description() string {
+ return "Number of active HTTP requests."
+}
+
+// Add adds incr to the existing count for attrs.
+//
+// The serverAddress is the server domain name if available without reverse DNS
+// lookup; otherwise, IP address or Unix domain socket name.
+//
+// The serverPort is the server port number.
+//
+// All additional attrs passed are included in the recorded value.
+func (m ClientActiveRequests) Add(
+ ctx context.Context,
+ incr int64,
+ serverAddress string,
+ serverPort int,
+ attrs ...attribute.KeyValue,
+) {
+ if !m.Int64UpDownCounter.Enabled(ctx) {
+ return
+ }
+ if len(attrs) == 0 {
+ m.Int64UpDownCounter.Add(ctx, incr, metric.WithAttributes(
+ attribute.String("server.address", serverAddress),
+ attribute.Int("server.port", serverPort),
+ ))
+ return
+ }
+
+ o := addOptPool.Get().(*[]metric.AddOption)
+ defer func() {
+ *o = (*o)[:0]
+ addOptPool.Put(o)
+ }()
+
+ *o = append(
+ *o,
+ metric.WithAttributes(
+ append(
+ attrs[:len(attrs):len(attrs)],
+ attribute.String("server.address", serverAddress),
+ attribute.Int("server.port", serverPort),
+ )...,
+ ),
+ )
+
+ m.Int64UpDownCounter.Add(ctx, incr, *o...)
+}
+
+// AddSet adds incr to the existing count for set.
+func (m ClientActiveRequests) AddSet(ctx context.Context, incr int64, set attribute.Set) {
+ if !m.Int64UpDownCounter.Enabled(ctx) {
+ return
+ }
+ if set.Len() == 0 {
+ m.Int64UpDownCounter.Add(ctx, incr)
+ return
+ }
+
+ o := addOptPool.Get().(*[]metric.AddOption)
+ defer func() {
+ *o = (*o)[:0]
+ addOptPool.Put(o)
+ }()
+
+ *o = append(*o, metric.WithAttributeSet(set))
+ m.Int64UpDownCounter.Add(ctx, incr, *o...)
+}
+
+// AttrURLTemplate returns an optional attribute for the "url.template" semantic
+// convention. It represents the low-cardinality template of an
+// [absolute path reference].
+//
+// [absolute path reference]: https://www.rfc-editor.org/rfc/rfc3986#section-4.2
+func (ClientActiveRequests) AttrURLTemplate(val string) attribute.KeyValue {
+ return attribute.String("url.template", val)
+}
+
+// AttrRequestMethod returns an optional attribute for the "http.request.method"
+// semantic convention. It represents the HTTP request method.
+func (ClientActiveRequests) AttrRequestMethod(val RequestMethodAttr) attribute.KeyValue {
+ return attribute.String("http.request.method", string(val))
+}
+
+// AttrURLScheme returns an optional attribute for the "url.scheme" semantic
+// convention. It represents the [URI scheme] component identifying the used
+// protocol.
+//
+// [URI scheme]: https://www.rfc-editor.org/rfc/rfc3986#section-3.1
+func (ClientActiveRequests) AttrURLScheme(val string) attribute.KeyValue {
+ return attribute.String("url.scheme", val)
+}
+
+// ClientConnectionDuration is an instrument used to record metric values
+// conforming to the "http.client.connection.duration" semantic conventions. It
+// represents the duration of the successfully established outbound HTTP
+// connections.
+type ClientConnectionDuration struct {
+ metric.Float64Histogram
+}
+
+var newClientConnectionDurationOpts = []metric.Float64HistogramOption{
+ metric.WithDescription("The duration of the successfully established outbound HTTP connections."),
+ metric.WithUnit("s"),
+}
+
+// NewClientConnectionDuration returns a new ClientConnectionDuration instrument.
+func NewClientConnectionDuration(
+ m metric.Meter,
+ opt ...metric.Float64HistogramOption,
+) (ClientConnectionDuration, error) {
+ // Check if the meter is nil.
+ if m == nil {
+ return ClientConnectionDuration{noop.Float64Histogram{}}, nil
+ }
+
+ if len(opt) == 0 {
+ opt = newClientConnectionDurationOpts
+ } else {
+ opt = append(opt, newClientConnectionDurationOpts...)
+ }
+
+ i, err := m.Float64Histogram(
+ "http.client.connection.duration",
+ opt...,
+ )
+ if err != nil {
+ return ClientConnectionDuration{noop.Float64Histogram{}}, err
+ }
+ return ClientConnectionDuration{i}, nil
+}
+
+// Inst returns the underlying metric instrument.
+func (m ClientConnectionDuration) Inst() metric.Float64Histogram {
+ return m.Float64Histogram
+}
+
+// Name returns the semantic convention name of the instrument.
+func (ClientConnectionDuration) Name() string {
+ return "http.client.connection.duration"
+}
+
+// Unit returns the semantic convention unit of the instrument
+func (ClientConnectionDuration) Unit() string {
+ return "s"
+}
+
+// Description returns the semantic convention description of the instrument
+func (ClientConnectionDuration) Description() string {
+ return "The duration of the successfully established outbound HTTP connections."
+}
+
+// Record records val to the current distribution for attrs.
+//
+// The serverAddress is the server domain name if available without reverse DNS
+// lookup; otherwise, IP address or Unix domain socket name.
+//
+// The serverPort is the server port number.
+//
+// All additional attrs passed are included in the recorded value.
+func (m ClientConnectionDuration) Record(
+ ctx context.Context,
+ val float64,
+ serverAddress string,
+ serverPort int,
+ attrs ...attribute.KeyValue,
+) {
+ if !m.Float64Histogram.Enabled(ctx) {
+ return
+ }
+ if len(attrs) == 0 {
+ m.Float64Histogram.Record(ctx, val, metric.WithAttributes(
+ attribute.String("server.address", serverAddress),
+ attribute.Int("server.port", serverPort),
+ ))
+ return
+ }
+
+ o := recOptPool.Get().(*[]metric.RecordOption)
+ defer func() {
+ *o = (*o)[:0]
+ recOptPool.Put(o)
+ }()
+
+ *o = append(
+ *o,
+ metric.WithAttributes(
+ append(
+ attrs[:len(attrs):len(attrs)],
+ attribute.String("server.address", serverAddress),
+ attribute.Int("server.port", serverPort),
+ )...,
+ ),
+ )
+
+ m.Float64Histogram.Record(ctx, val, *o...)
+}
+
+// RecordSet records val to the current distribution for set.
+func (m ClientConnectionDuration) RecordSet(ctx context.Context, val float64, set attribute.Set) {
+ if !m.Float64Histogram.Enabled(ctx) {
+ return
+ }
+ if set.Len() == 0 {
+ m.Float64Histogram.Record(ctx, val)
+ return
+ }
+
+ o := recOptPool.Get().(*[]metric.RecordOption)
+ defer func() {
+ *o = (*o)[:0]
+ recOptPool.Put(o)
+ }()
+
+ *o = append(*o, metric.WithAttributeSet(set))
+ m.Float64Histogram.Record(ctx, val, *o...)
+}
+
+// AttrNetworkPeerAddress returns an optional attribute for the
+// "network.peer.address" semantic convention. It represents the peer address of
+// the network connection - IP address or Unix domain socket name.
+func (ClientConnectionDuration) AttrNetworkPeerAddress(val string) attribute.KeyValue {
+ return attribute.String("network.peer.address", val)
+}
+
+// AttrNetworkProtocolVersion returns an optional attribute for the
+// "network.protocol.version" semantic convention. It represents the actual
+// version of the protocol used for network communication.
+func (ClientConnectionDuration) AttrNetworkProtocolVersion(val string) attribute.KeyValue {
+ return attribute.String("network.protocol.version", val)
+}
+
+// AttrURLScheme returns an optional attribute for the "url.scheme" semantic
+// convention. It represents the [URI scheme] component identifying the used
+// protocol.
+//
+// [URI scheme]: https://www.rfc-editor.org/rfc/rfc3986#section-3.1
+func (ClientConnectionDuration) AttrURLScheme(val string) attribute.KeyValue {
+ return attribute.String("url.scheme", val)
+}
+
+// ClientOpenConnections is an instrument used to record metric values conforming
+// to the "http.client.open_connections" semantic conventions. It represents the
+// number of outbound HTTP connections that are currently active or idle on the
+// client.
+type ClientOpenConnections struct {
+ metric.Int64UpDownCounter
+}
+
+var newClientOpenConnectionsOpts = []metric.Int64UpDownCounterOption{
+ metric.WithDescription("Number of outbound HTTP connections that are currently active or idle on the client."),
+ metric.WithUnit("{connection}"),
+}
+
+// NewClientOpenConnections returns a new ClientOpenConnections instrument.
+func NewClientOpenConnections(
+ m metric.Meter,
+ opt ...metric.Int64UpDownCounterOption,
+) (ClientOpenConnections, error) {
+ // Check if the meter is nil.
+ if m == nil {
+ return ClientOpenConnections{noop.Int64UpDownCounter{}}, nil
+ }
+
+ if len(opt) == 0 {
+ opt = newClientOpenConnectionsOpts
+ } else {
+ opt = append(opt, newClientOpenConnectionsOpts...)
+ }
+
+ i, err := m.Int64UpDownCounter(
+ "http.client.open_connections",
+ opt...,
+ )
+ if err != nil {
+ return ClientOpenConnections{noop.Int64UpDownCounter{}}, err
+ }
+ return ClientOpenConnections{i}, nil
+}
+
+// Inst returns the underlying metric instrument.
+func (m ClientOpenConnections) Inst() metric.Int64UpDownCounter {
+ return m.Int64UpDownCounter
+}
+
+// Name returns the semantic convention name of the instrument.
+func (ClientOpenConnections) Name() string {
+ return "http.client.open_connections"
+}
+
+// Unit returns the semantic convention unit of the instrument
+func (ClientOpenConnections) Unit() string {
+ return "{connection}"
+}
+
+// Description returns the semantic convention description of the instrument
+func (ClientOpenConnections) Description() string {
+ return "Number of outbound HTTP connections that are currently active or idle on the client."
+}
+
+// Add adds incr to the existing count for attrs.
+//
+// The connectionState is the state of the HTTP connection in the HTTP connection
+// pool.
+//
+// The serverAddress is the server domain name if available without reverse DNS
+// lookup; otherwise, IP address or Unix domain socket name.
+//
+// The serverPort is the server port number.
+//
+// All additional attrs passed are included in the recorded value.
+func (m ClientOpenConnections) Add(
+ ctx context.Context,
+ incr int64,
+ connectionState ConnectionStateAttr,
+ serverAddress string,
+ serverPort int,
+ attrs ...attribute.KeyValue,
+) {
+ if !m.Int64UpDownCounter.Enabled(ctx) {
+ return
+ }
+ if len(attrs) == 0 {
+ m.Int64UpDownCounter.Add(ctx, incr, metric.WithAttributes(
+ attribute.String("http.connection.state", string(connectionState)),
+ attribute.String("server.address", serverAddress),
+ attribute.Int("server.port", serverPort),
+ ))
+ return
+ }
+
+ o := addOptPool.Get().(*[]metric.AddOption)
+ defer func() {
+ *o = (*o)[:0]
+ addOptPool.Put(o)
+ }()
+
+ *o = append(
+ *o,
+ metric.WithAttributes(
+ append(
+ attrs[:len(attrs):len(attrs)],
+ attribute.String("http.connection.state", string(connectionState)),
+ attribute.String("server.address", serverAddress),
+ attribute.Int("server.port", serverPort),
+ )...,
+ ),
+ )
+
+ m.Int64UpDownCounter.Add(ctx, incr, *o...)
+}
+
+// AddSet adds incr to the existing count for set.
+func (m ClientOpenConnections) AddSet(ctx context.Context, incr int64, set attribute.Set) {
+ if !m.Int64UpDownCounter.Enabled(ctx) {
+ return
+ }
+ if set.Len() == 0 {
+ m.Int64UpDownCounter.Add(ctx, incr)
+ return
+ }
+
+ o := addOptPool.Get().(*[]metric.AddOption)
+ defer func() {
+ *o = (*o)[:0]
+ addOptPool.Put(o)
+ }()
+
+ *o = append(*o, metric.WithAttributeSet(set))
+ m.Int64UpDownCounter.Add(ctx, incr, *o...)
+}
+
+// AttrNetworkPeerAddress returns an optional attribute for the
+// "network.peer.address" semantic convention. It represents the peer address of
+// the network connection - IP address or Unix domain socket name.
+func (ClientOpenConnections) AttrNetworkPeerAddress(val string) attribute.KeyValue {
+ return attribute.String("network.peer.address", val)
+}
+
+// AttrNetworkProtocolVersion returns an optional attribute for the
+// "network.protocol.version" semantic convention. It represents the actual
+// version of the protocol used for network communication.
+func (ClientOpenConnections) AttrNetworkProtocolVersion(val string) attribute.KeyValue {
+ return attribute.String("network.protocol.version", val)
+}
+
+// AttrURLScheme returns an optional attribute for the "url.scheme" semantic
+// convention. It represents the [URI scheme] component identifying the used
+// protocol.
+//
+// [URI scheme]: https://www.rfc-editor.org/rfc/rfc3986#section-3.1
+func (ClientOpenConnections) AttrURLScheme(val string) attribute.KeyValue {
+ return attribute.String("url.scheme", val)
+}
+
+// ClientRequestBodySize is an instrument used to record metric values conforming
+// to the "http.client.request.body.size" semantic conventions. It represents the
+// size of HTTP client request bodies.
+type ClientRequestBodySize struct {
+ metric.Int64Histogram
+}
+
+var newClientRequestBodySizeOpts = []metric.Int64HistogramOption{
+ metric.WithDescription("Size of HTTP client request bodies."),
+ metric.WithUnit("By"),
+}
+
+// NewClientRequestBodySize returns a new ClientRequestBodySize instrument.
+func NewClientRequestBodySize(
+ m metric.Meter,
+ opt ...metric.Int64HistogramOption,
+) (ClientRequestBodySize, error) {
+ // Check if the meter is nil.
+ if m == nil {
+ return ClientRequestBodySize{noop.Int64Histogram{}}, nil
+ }
+
+ if len(opt) == 0 {
+ opt = newClientRequestBodySizeOpts
+ } else {
+ opt = append(opt, newClientRequestBodySizeOpts...)
+ }
+
+ i, err := m.Int64Histogram(
+ "http.client.request.body.size",
+ opt...,
+ )
+ if err != nil {
+ return ClientRequestBodySize{noop.Int64Histogram{}}, err
+ }
+ return ClientRequestBodySize{i}, nil
+}
+
+// Inst returns the underlying metric instrument.
+func (m ClientRequestBodySize) Inst() metric.Int64Histogram {
+ return m.Int64Histogram
+}
+
+// Name returns the semantic convention name of the instrument.
+func (ClientRequestBodySize) Name() string {
+ return "http.client.request.body.size"
+}
+
+// Unit returns the semantic convention unit of the instrument
+func (ClientRequestBodySize) Unit() string {
+ return "By"
+}
+
+// Description returns the semantic convention description of the instrument
+func (ClientRequestBodySize) Description() string {
+ return "Size of HTTP client request bodies."
+}
+
+// Record records val to the current distribution for attrs.
+//
+// The requestMethod is the HTTP request method.
+//
+// The serverAddress is the server domain name if available without reverse DNS
+// lookup; otherwise, IP address or Unix domain socket name.
+//
+// The serverPort is the server port number.
+//
+// All additional attrs passed are included in the recorded value.
+//
+// The size of the request payload body in bytes. This is the number of bytes
+// transferred excluding headers and is often, but not always, present as the
+// [Content-Length] header. For requests using transport encoding, this should be
+// the compressed size.
+//
+// [Content-Length]: https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length
+func (m ClientRequestBodySize) Record(
+ ctx context.Context,
+ val int64,
+ requestMethod RequestMethodAttr,
+ serverAddress string,
+ serverPort int,
+ attrs ...attribute.KeyValue,
+) {
+ if !m.Int64Histogram.Enabled(ctx) {
+ return
+ }
+ if len(attrs) == 0 {
+ m.Int64Histogram.Record(ctx, val, metric.WithAttributes(
+ attribute.String("http.request.method", string(requestMethod)),
+ attribute.String("server.address", serverAddress),
+ attribute.Int("server.port", serverPort),
+ ))
+ return
+ }
+
+ o := recOptPool.Get().(*[]metric.RecordOption)
+ defer func() {
+ *o = (*o)[:0]
+ recOptPool.Put(o)
+ }()
+
+ *o = append(
+ *o,
+ metric.WithAttributes(
+ append(
+ attrs[:len(attrs):len(attrs)],
+ attribute.String("http.request.method", string(requestMethod)),
+ attribute.String("server.address", serverAddress),
+ attribute.Int("server.port", serverPort),
+ )...,
+ ),
+ )
+
+ m.Int64Histogram.Record(ctx, val, *o...)
+}
+
+// RecordSet records val to the current distribution for set.
+//
+// The size of the request payload body in bytes. This is the number of bytes
+// transferred excluding headers and is often, but not always, present as the
+// [Content-Length] header. For requests using transport encoding, this should be
+// the compressed size.
+//
+// [Content-Length]: https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length
+func (m ClientRequestBodySize) RecordSet(ctx context.Context, val int64, set attribute.Set) {
+ if !m.Int64Histogram.Enabled(ctx) {
+ return
+ }
+ if set.Len() == 0 {
+ m.Int64Histogram.Record(ctx, val)
+ return
+ }
+
+ o := recOptPool.Get().(*[]metric.RecordOption)
+ defer func() {
+ *o = (*o)[:0]
+ recOptPool.Put(o)
+ }()
+
+ *o = append(*o, metric.WithAttributeSet(set))
+ m.Int64Histogram.Record(ctx, val, *o...)
+}
+
+// AttrErrorType returns an optional attribute for the "error.type" semantic
+// convention. It represents the describes a class of error the operation ended
+// with.
+func (ClientRequestBodySize) AttrErrorType(val ErrorTypeAttr) attribute.KeyValue {
+ return attribute.String("error.type", string(val))
+}
+
+// AttrResponseStatusCode returns an optional attribute for the
+// "http.response.status_code" semantic convention. It represents the
+// [HTTP response status code].
+//
+// [HTTP response status code]: https://tools.ietf.org/html/rfc7231#section-6
+func (ClientRequestBodySize) AttrResponseStatusCode(val int) attribute.KeyValue {
+ return attribute.Int("http.response.status_code", val)
+}
+
+// AttrNetworkProtocolName returns an optional attribute for the
+// "network.protocol.name" semantic convention. It represents the
+// [OSI application layer] or non-OSI equivalent.
+//
+// [OSI application layer]: https://wikipedia.org/wiki/Application_layer
+func (ClientRequestBodySize) AttrNetworkProtocolName(val string) attribute.KeyValue {
+ return attribute.String("network.protocol.name", val)
+}
+
+// AttrURLTemplate returns an optional attribute for the "url.template" semantic
+// convention. It represents the low-cardinality template of an
+// [absolute path reference].
+//
+// [absolute path reference]: https://www.rfc-editor.org/rfc/rfc3986#section-4.2
+func (ClientRequestBodySize) AttrURLTemplate(val string) attribute.KeyValue {
+ return attribute.String("url.template", val)
+}
+
+// AttrNetworkProtocolVersion returns an optional attribute for the
+// "network.protocol.version" semantic convention. It represents the actual
+// version of the protocol used for network communication.
+func (ClientRequestBodySize) AttrNetworkProtocolVersion(val string) attribute.KeyValue {
+ return attribute.String("network.protocol.version", val)
+}
+
+// AttrURLScheme returns an optional attribute for the "url.scheme" semantic
+// convention. It represents the [URI scheme] component identifying the used
+// protocol.
+//
+// [URI scheme]: https://www.rfc-editor.org/rfc/rfc3986#section-3.1
+func (ClientRequestBodySize) AttrURLScheme(val string) attribute.KeyValue {
+ return attribute.String("url.scheme", val)
+}
+
+// ClientRequestDuration is an instrument used to record metric values conforming
+// to the "http.client.request.duration" semantic conventions. It represents the
+// duration of HTTP client requests.
+type ClientRequestDuration struct {
+ metric.Float64Histogram
+}
+
+var newClientRequestDurationOpts = []metric.Float64HistogramOption{
+ metric.WithDescription("Duration of HTTP client requests."),
+ metric.WithUnit("s"),
+}
+
+// NewClientRequestDuration returns a new ClientRequestDuration instrument.
+func NewClientRequestDuration(
+ m metric.Meter,
+ opt ...metric.Float64HistogramOption,
+) (ClientRequestDuration, error) {
+ // Check if the meter is nil.
+ if m == nil {
+ return ClientRequestDuration{noop.Float64Histogram{}}, nil
+ }
+
+ if len(opt) == 0 {
+ opt = newClientRequestDurationOpts
+ } else {
+ opt = append(opt, newClientRequestDurationOpts...)
+ }
+
+ i, err := m.Float64Histogram(
+ "http.client.request.duration",
+ opt...,
+ )
+ if err != nil {
+ return ClientRequestDuration{noop.Float64Histogram{}}, err
+ }
+ return ClientRequestDuration{i}, nil
+}
+
+// Inst returns the underlying metric instrument.
+func (m ClientRequestDuration) Inst() metric.Float64Histogram {
+ return m.Float64Histogram
+}
+
+// Name returns the semantic convention name of the instrument.
+func (ClientRequestDuration) Name() string {
+ return "http.client.request.duration"
+}
+
+// Unit returns the semantic convention unit of the instrument
+func (ClientRequestDuration) Unit() string {
+ return "s"
+}
+
+// Description returns the semantic convention description of the instrument
+func (ClientRequestDuration) Description() string {
+ return "Duration of HTTP client requests."
+}
+
+// Record records val to the current distribution for attrs.
+//
+// The requestMethod is the HTTP request method.
+//
+// The serverAddress is the server domain name if available without reverse DNS
+// lookup; otherwise, IP address or Unix domain socket name.
+//
+// The serverPort is the server port number.
+//
+// All additional attrs passed are included in the recorded value.
+func (m ClientRequestDuration) Record(
+ ctx context.Context,
+ val float64,
+ requestMethod RequestMethodAttr,
+ serverAddress string,
+ serverPort int,
+ attrs ...attribute.KeyValue,
+) {
+ if !m.Float64Histogram.Enabled(ctx) {
+ return
+ }
+ if len(attrs) == 0 {
+ m.Float64Histogram.Record(ctx, val, metric.WithAttributes(
+ attribute.String("http.request.method", string(requestMethod)),
+ attribute.String("server.address", serverAddress),
+ attribute.Int("server.port", serverPort),
+ ))
+ return
+ }
+
+ o := recOptPool.Get().(*[]metric.RecordOption)
+ defer func() {
+ *o = (*o)[:0]
+ recOptPool.Put(o)
+ }()
+
+ *o = append(
+ *o,
+ metric.WithAttributes(
+ append(
+ attrs[:len(attrs):len(attrs)],
+ attribute.String("http.request.method", string(requestMethod)),
+ attribute.String("server.address", serverAddress),
+ attribute.Int("server.port", serverPort),
+ )...,
+ ),
+ )
+
+ m.Float64Histogram.Record(ctx, val, *o...)
+}
+
+// RecordSet records val to the current distribution for set.
+func (m ClientRequestDuration) RecordSet(ctx context.Context, val float64, set attribute.Set) {
+ if !m.Float64Histogram.Enabled(ctx) {
+ return
+ }
+ if set.Len() == 0 {
+ m.Float64Histogram.Record(ctx, val)
+ return
+ }
+
+ o := recOptPool.Get().(*[]metric.RecordOption)
+ defer func() {
+ *o = (*o)[:0]
+ recOptPool.Put(o)
+ }()
+
+ *o = append(*o, metric.WithAttributeSet(set))
+ m.Float64Histogram.Record(ctx, val, *o...)
+}
+
+// AttrErrorType returns an optional attribute for the "error.type" semantic
+// convention. It represents the describes a class of error the operation ended
+// with.
+func (ClientRequestDuration) AttrErrorType(val ErrorTypeAttr) attribute.KeyValue {
+ return attribute.String("error.type", string(val))
+}
+
+// AttrResponseStatusCode returns an optional attribute for the
+// "http.response.status_code" semantic convention. It represents the
+// [HTTP response status code].
+//
+// [HTTP response status code]: https://tools.ietf.org/html/rfc7231#section-6
+func (ClientRequestDuration) AttrResponseStatusCode(val int) attribute.KeyValue {
+ return attribute.Int("http.response.status_code", val)
+}
+
+// AttrNetworkProtocolName returns an optional attribute for the
+// "network.protocol.name" semantic convention. It represents the
+// [OSI application layer] or non-OSI equivalent.
+//
+// [OSI application layer]: https://wikipedia.org/wiki/Application_layer
+func (ClientRequestDuration) AttrNetworkProtocolName(val string) attribute.KeyValue {
+ return attribute.String("network.protocol.name", val)
+}
+
+// AttrNetworkProtocolVersion returns an optional attribute for the
+// "network.protocol.version" semantic convention. It represents the actual
+// version of the protocol used for network communication.
+func (ClientRequestDuration) AttrNetworkProtocolVersion(val string) attribute.KeyValue {
+ return attribute.String("network.protocol.version", val)
+}
+
+// AttrURLScheme returns an optional attribute for the "url.scheme" semantic
+// convention. It represents the [URI scheme] component identifying the used
+// protocol.
+//
+// [URI scheme]: https://www.rfc-editor.org/rfc/rfc3986#section-3.1
+func (ClientRequestDuration) AttrURLScheme(val string) attribute.KeyValue {
+ return attribute.String("url.scheme", val)
+}
+
+// AttrURLTemplate returns an optional attribute for the "url.template" semantic
+// convention. It represents the low-cardinality template of an
+// [absolute path reference].
+//
+// [absolute path reference]: https://www.rfc-editor.org/rfc/rfc3986#section-4.2
+func (ClientRequestDuration) AttrURLTemplate(val string) attribute.KeyValue {
+ return attribute.String("url.template", val)
+}
+
+// ClientResponseBodySize is an instrument used to record metric values
+// conforming to the "http.client.response.body.size" semantic conventions. It
+// represents the size of HTTP client response bodies.
+type ClientResponseBodySize struct {
+ metric.Int64Histogram
+}
+
+var newClientResponseBodySizeOpts = []metric.Int64HistogramOption{
+ metric.WithDescription("Size of HTTP client response bodies."),
+ metric.WithUnit("By"),
+}
+
+// NewClientResponseBodySize returns a new ClientResponseBodySize instrument.
+func NewClientResponseBodySize(
+ m metric.Meter,
+ opt ...metric.Int64HistogramOption,
+) (ClientResponseBodySize, error) {
+ // Check if the meter is nil.
+ if m == nil {
+ return ClientResponseBodySize{noop.Int64Histogram{}}, nil
+ }
+
+ if len(opt) == 0 {
+ opt = newClientResponseBodySizeOpts
+ } else {
+ opt = append(opt, newClientResponseBodySizeOpts...)
+ }
+
+ i, err := m.Int64Histogram(
+ "http.client.response.body.size",
+ opt...,
+ )
+ if err != nil {
+ return ClientResponseBodySize{noop.Int64Histogram{}}, err
+ }
+ return ClientResponseBodySize{i}, nil
+}
+
+// Inst returns the underlying metric instrument.
+func (m ClientResponseBodySize) Inst() metric.Int64Histogram {
+ return m.Int64Histogram
+}
+
+// Name returns the semantic convention name of the instrument.
+func (ClientResponseBodySize) Name() string {
+ return "http.client.response.body.size"
+}
+
+// Unit returns the semantic convention unit of the instrument
+func (ClientResponseBodySize) Unit() string {
+ return "By"
+}
+
+// Description returns the semantic convention description of the instrument
+func (ClientResponseBodySize) Description() string {
+ return "Size of HTTP client response bodies."
+}
+
+// Record records val to the current distribution for attrs.
+//
+// The requestMethod is the HTTP request method.
+//
+// The serverAddress is the server domain name if available without reverse DNS
+// lookup; otherwise, IP address or Unix domain socket name.
+//
+// The serverPort is the server port number.
+//
+// All additional attrs passed are included in the recorded value.
+//
+// The size of the response payload body in bytes. This is the number of bytes
+// transferred excluding headers and is often, but not always, present as the
+// [Content-Length] header. For requests using transport encoding, this should be
+// the compressed size.
+//
+// [Content-Length]: https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length
+func (m ClientResponseBodySize) Record(
+ ctx context.Context,
+ val int64,
+ requestMethod RequestMethodAttr,
+ serverAddress string,
+ serverPort int,
+ attrs ...attribute.KeyValue,
+) {
+ if !m.Int64Histogram.Enabled(ctx) {
+ return
+ }
+ if len(attrs) == 0 {
+ m.Int64Histogram.Record(ctx, val, metric.WithAttributes(
+ attribute.String("http.request.method", string(requestMethod)),
+ attribute.String("server.address", serverAddress),
+ attribute.Int("server.port", serverPort),
+ ))
+ return
+ }
+
+ o := recOptPool.Get().(*[]metric.RecordOption)
+ defer func() {
+ *o = (*o)[:0]
+ recOptPool.Put(o)
+ }()
+
+ *o = append(
+ *o,
+ metric.WithAttributes(
+ append(
+ attrs[:len(attrs):len(attrs)],
+ attribute.String("http.request.method", string(requestMethod)),
+ attribute.String("server.address", serverAddress),
+ attribute.Int("server.port", serverPort),
+ )...,
+ ),
+ )
+
+ m.Int64Histogram.Record(ctx, val, *o...)
+}
+
+// RecordSet records val to the current distribution for set.
+//
+// The size of the response payload body in bytes. This is the number of bytes
+// transferred excluding headers and is often, but not always, present as the
+// [Content-Length] header. For requests using transport encoding, this should be
+// the compressed size.
+//
+// [Content-Length]: https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length
+func (m ClientResponseBodySize) RecordSet(ctx context.Context, val int64, set attribute.Set) {
+ if !m.Int64Histogram.Enabled(ctx) {
+ return
+ }
+ if set.Len() == 0 {
+ m.Int64Histogram.Record(ctx, val)
+ return
+ }
+
+ o := recOptPool.Get().(*[]metric.RecordOption)
+ defer func() {
+ *o = (*o)[:0]
+ recOptPool.Put(o)
+ }()
+
+ *o = append(*o, metric.WithAttributeSet(set))
+ m.Int64Histogram.Record(ctx, val, *o...)
+}
+
+// AttrErrorType returns an optional attribute for the "error.type" semantic
+// convention. It represents the describes a class of error the operation ended
+// with.
+func (ClientResponseBodySize) AttrErrorType(val ErrorTypeAttr) attribute.KeyValue {
+ return attribute.String("error.type", string(val))
+}
+
+// AttrResponseStatusCode returns an optional attribute for the
+// "http.response.status_code" semantic convention. It represents the
+// [HTTP response status code].
+//
+// [HTTP response status code]: https://tools.ietf.org/html/rfc7231#section-6
+func (ClientResponseBodySize) AttrResponseStatusCode(val int) attribute.KeyValue {
+ return attribute.Int("http.response.status_code", val)
+}
+
+// AttrNetworkProtocolName returns an optional attribute for the
+// "network.protocol.name" semantic convention. It represents the
+// [OSI application layer] or non-OSI equivalent.
+//
+// [OSI application layer]: https://wikipedia.org/wiki/Application_layer
+func (ClientResponseBodySize) AttrNetworkProtocolName(val string) attribute.KeyValue {
+ return attribute.String("network.protocol.name", val)
+}
+
+// AttrURLTemplate returns an optional attribute for the "url.template" semantic
+// convention. It represents the low-cardinality template of an
+// [absolute path reference].
+//
+// [absolute path reference]: https://www.rfc-editor.org/rfc/rfc3986#section-4.2
+func (ClientResponseBodySize) AttrURLTemplate(val string) attribute.KeyValue {
+ return attribute.String("url.template", val)
+}
+
+// AttrNetworkProtocolVersion returns an optional attribute for the
+// "network.protocol.version" semantic convention. It represents the actual
+// version of the protocol used for network communication.
+func (ClientResponseBodySize) AttrNetworkProtocolVersion(val string) attribute.KeyValue {
+ return attribute.String("network.protocol.version", val)
+}
+
+// AttrURLScheme returns an optional attribute for the "url.scheme" semantic
+// convention. It represents the [URI scheme] component identifying the used
+// protocol.
+//
+// [URI scheme]: https://www.rfc-editor.org/rfc/rfc3986#section-3.1
+func (ClientResponseBodySize) AttrURLScheme(val string) attribute.KeyValue {
+ return attribute.String("url.scheme", val)
+}
+
+// ServerActiveRequests is an instrument used to record metric values conforming
+// to the "http.server.active_requests" semantic conventions. It represents the
+// number of active HTTP server requests.
+type ServerActiveRequests struct {
+ metric.Int64UpDownCounter
+}
+
+var newServerActiveRequestsOpts = []metric.Int64UpDownCounterOption{
+ metric.WithDescription("Number of active HTTP server requests."),
+ metric.WithUnit("{request}"),
+}
+
+// NewServerActiveRequests returns a new ServerActiveRequests instrument.
+func NewServerActiveRequests(
+ m metric.Meter,
+ opt ...metric.Int64UpDownCounterOption,
+) (ServerActiveRequests, error) {
+ // Check if the meter is nil.
+ if m == nil {
+ return ServerActiveRequests{noop.Int64UpDownCounter{}}, nil
+ }
+
+ if len(opt) == 0 {
+ opt = newServerActiveRequestsOpts
+ } else {
+ opt = append(opt, newServerActiveRequestsOpts...)
+ }
+
+ i, err := m.Int64UpDownCounter(
+ "http.server.active_requests",
+ opt...,
+ )
+ if err != nil {
+ return ServerActiveRequests{noop.Int64UpDownCounter{}}, err
+ }
+ return ServerActiveRequests{i}, nil
+}
+
+// Inst returns the underlying metric instrument.
+func (m ServerActiveRequests) Inst() metric.Int64UpDownCounter {
+ return m.Int64UpDownCounter
+}
+
+// Name returns the semantic convention name of the instrument.
+func (ServerActiveRequests) Name() string {
+ return "http.server.active_requests"
+}
+
+// Unit returns the semantic convention unit of the instrument
+func (ServerActiveRequests) Unit() string {
+ return "{request}"
+}
+
+// Description returns the semantic convention description of the instrument
+func (ServerActiveRequests) Description() string {
+ return "Number of active HTTP server requests."
+}
+
+// Add adds incr to the existing count for attrs.
+//
+// The requestMethod is the HTTP request method.
+//
+// The urlScheme is the the [URI scheme] component identifying the used protocol.
+//
+// All additional attrs passed are included in the recorded value.
+//
+// [URI scheme]: https://www.rfc-editor.org/rfc/rfc3986#section-3.1
+func (m ServerActiveRequests) Add(
+ ctx context.Context,
+ incr int64,
+ requestMethod RequestMethodAttr,
+ urlScheme string,
+ attrs ...attribute.KeyValue,
+) {
+ if !m.Int64UpDownCounter.Enabled(ctx) {
+ return
+ }
+ if len(attrs) == 0 {
+ m.Int64UpDownCounter.Add(ctx, incr, metric.WithAttributes(
+ attribute.String("http.request.method", string(requestMethod)),
+ attribute.String("url.scheme", urlScheme),
+ ))
+ return
+ }
+
+ o := addOptPool.Get().(*[]metric.AddOption)
+ defer func() {
+ *o = (*o)[:0]
+ addOptPool.Put(o)
+ }()
+
+ *o = append(
+ *o,
+ metric.WithAttributes(
+ append(
+ attrs[:len(attrs):len(attrs)],
+ attribute.String("http.request.method", string(requestMethod)),
+ attribute.String("url.scheme", urlScheme),
+ )...,
+ ),
+ )
+
+ m.Int64UpDownCounter.Add(ctx, incr, *o...)
+}
+
+// AddSet adds incr to the existing count for set.
+func (m ServerActiveRequests) AddSet(ctx context.Context, incr int64, set attribute.Set) {
+ if !m.Int64UpDownCounter.Enabled(ctx) {
+ return
+ }
+ if set.Len() == 0 {
+ m.Int64UpDownCounter.Add(ctx, incr)
+ return
+ }
+
+ o := addOptPool.Get().(*[]metric.AddOption)
+ defer func() {
+ *o = (*o)[:0]
+ addOptPool.Put(o)
+ }()
+
+ *o = append(*o, metric.WithAttributeSet(set))
+ m.Int64UpDownCounter.Add(ctx, incr, *o...)
+}
+
+// AttrServerAddress returns an optional attribute for the "server.address"
+// semantic convention. It represents the name of the local HTTP server that
+// received the request.
+func (ServerActiveRequests) AttrServerAddress(val string) attribute.KeyValue {
+ return attribute.String("server.address", val)
+}
+
+// AttrServerPort returns an optional attribute for the "server.port" semantic
+// convention. It represents the port of the local HTTP server that received the
+// request.
+func (ServerActiveRequests) AttrServerPort(val int) attribute.KeyValue {
+ return attribute.Int("server.port", val)
+}
+
+// ServerRequestBodySize is an instrument used to record metric values conforming
+// to the "http.server.request.body.size" semantic conventions. It represents the
+// size of HTTP server request bodies.
+type ServerRequestBodySize struct {
+ metric.Int64Histogram
+}
+
+var newServerRequestBodySizeOpts = []metric.Int64HistogramOption{
+ metric.WithDescription("Size of HTTP server request bodies."),
+ metric.WithUnit("By"),
+}
+
+// NewServerRequestBodySize returns a new ServerRequestBodySize instrument.
+func NewServerRequestBodySize(
+ m metric.Meter,
+ opt ...metric.Int64HistogramOption,
+) (ServerRequestBodySize, error) {
+ // Check if the meter is nil.
+ if m == nil {
+ return ServerRequestBodySize{noop.Int64Histogram{}}, nil
+ }
+
+ if len(opt) == 0 {
+ opt = newServerRequestBodySizeOpts
+ } else {
+ opt = append(opt, newServerRequestBodySizeOpts...)
+ }
+
+ i, err := m.Int64Histogram(
+ "http.server.request.body.size",
+ opt...,
+ )
+ if err != nil {
+ return ServerRequestBodySize{noop.Int64Histogram{}}, err
+ }
+ return ServerRequestBodySize{i}, nil
+}
+
+// Inst returns the underlying metric instrument.
+func (m ServerRequestBodySize) Inst() metric.Int64Histogram {
+ return m.Int64Histogram
+}
+
+// Name returns the semantic convention name of the instrument.
+func (ServerRequestBodySize) Name() string {
+ return "http.server.request.body.size"
+}
+
+// Unit returns the semantic convention unit of the instrument
+func (ServerRequestBodySize) Unit() string {
+ return "By"
+}
+
+// Description returns the semantic convention description of the instrument
+func (ServerRequestBodySize) Description() string {
+ return "Size of HTTP server request bodies."
+}
+
+// Record records val to the current distribution for attrs.
+//
+// The requestMethod is the HTTP request method.
+//
+// The urlScheme is the the [URI scheme] component identifying the used protocol.
+//
+// All additional attrs passed are included in the recorded value.
+//
+// The size of the request payload body in bytes. This is the number of bytes
+// transferred excluding headers and is often, but not always, present as the
+// [Content-Length] header. For requests using transport encoding, this should be
+// the compressed size.
+//
+// [URI scheme]: https://www.rfc-editor.org/rfc/rfc3986#section-3.1
+// [Content-Length]: https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length
+func (m ServerRequestBodySize) Record(
+ ctx context.Context,
+ val int64,
+ requestMethod RequestMethodAttr,
+ urlScheme string,
+ attrs ...attribute.KeyValue,
+) {
+ if !m.Int64Histogram.Enabled(ctx) {
+ return
+ }
+ if len(attrs) == 0 {
+ m.Int64Histogram.Record(ctx, val, metric.WithAttributes(
+ attribute.String("http.request.method", string(requestMethod)),
+ attribute.String("url.scheme", urlScheme),
+ ))
+ return
+ }
+
+ o := recOptPool.Get().(*[]metric.RecordOption)
+ defer func() {
+ *o = (*o)[:0]
+ recOptPool.Put(o)
+ }()
+
+ *o = append(
+ *o,
+ metric.WithAttributes(
+ append(
+ attrs[:len(attrs):len(attrs)],
+ attribute.String("http.request.method", string(requestMethod)),
+ attribute.String("url.scheme", urlScheme),
+ )...,
+ ),
+ )
+
+ m.Int64Histogram.Record(ctx, val, *o...)
+}
+
+// RecordSet records val to the current distribution for set.
+//
+// The size of the request payload body in bytes. This is the number of bytes
+// transferred excluding headers and is often, but not always, present as the
+// [Content-Length] header. For requests using transport encoding, this should be
+// the compressed size.
+//
+// [Content-Length]: https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length
+func (m ServerRequestBodySize) RecordSet(ctx context.Context, val int64, set attribute.Set) {
+ if !m.Int64Histogram.Enabled(ctx) {
+ return
+ }
+ if set.Len() == 0 {
+ m.Int64Histogram.Record(ctx, val)
+ return
+ }
+
+ o := recOptPool.Get().(*[]metric.RecordOption)
+ defer func() {
+ *o = (*o)[:0]
+ recOptPool.Put(o)
+ }()
+
+ *o = append(*o, metric.WithAttributeSet(set))
+ m.Int64Histogram.Record(ctx, val, *o...)
+}
+
+// AttrErrorType returns an optional attribute for the "error.type" semantic
+// convention. It represents the describes a class of error the operation ended
+// with.
+func (ServerRequestBodySize) AttrErrorType(val ErrorTypeAttr) attribute.KeyValue {
+ return attribute.String("error.type", string(val))
+}
+
+// AttrResponseStatusCode returns an optional attribute for the
+// "http.response.status_code" semantic convention. It represents the
+// [HTTP response status code].
+//
+// [HTTP response status code]: https://tools.ietf.org/html/rfc7231#section-6
+func (ServerRequestBodySize) AttrResponseStatusCode(val int) attribute.KeyValue {
+ return attribute.Int("http.response.status_code", val)
+}
+
+// AttrRoute returns an optional attribute for the "http.route" semantic
+// convention. It represents the matched route template for the request. This
+// MUST be low-cardinality and include all static path segments, with dynamic
+// path segments represented with placeholders.
+func (ServerRequestBodySize) AttrRoute(val string) attribute.KeyValue {
+ return attribute.String("http.route", val)
+}
+
+// AttrNetworkProtocolName returns an optional attribute for the
+// "network.protocol.name" semantic convention. It represents the
+// [OSI application layer] or non-OSI equivalent.
+//
+// [OSI application layer]: https://wikipedia.org/wiki/Application_layer
+func (ServerRequestBodySize) AttrNetworkProtocolName(val string) attribute.KeyValue {
+ return attribute.String("network.protocol.name", val)
+}
+
+// AttrNetworkProtocolVersion returns an optional attribute for the
+// "network.protocol.version" semantic convention. It represents the actual
+// version of the protocol used for network communication.
+func (ServerRequestBodySize) AttrNetworkProtocolVersion(val string) attribute.KeyValue {
+ return attribute.String("network.protocol.version", val)
+}
+
+// AttrServerAddress returns an optional attribute for the "server.address"
+// semantic convention. It represents the name of the local HTTP server that
+// received the request.
+func (ServerRequestBodySize) AttrServerAddress(val string) attribute.KeyValue {
+ return attribute.String("server.address", val)
+}
+
+// AttrServerPort returns an optional attribute for the "server.port" semantic
+// convention. It represents the port of the local HTTP server that received the
+// request.
+func (ServerRequestBodySize) AttrServerPort(val int) attribute.KeyValue {
+ return attribute.Int("server.port", val)
+}
+
+// AttrUserAgentSyntheticType returns an optional attribute for the
+// "user_agent.synthetic.type" semantic convention. It represents the specifies
+// the category of synthetic traffic, such as tests or bots.
+func (ServerRequestBodySize) AttrUserAgentSyntheticType(val UserAgentSyntheticTypeAttr) attribute.KeyValue {
+ return attribute.String("user_agent.synthetic.type", string(val))
+}
+
+// ServerRequestDuration is an instrument used to record metric values conforming
+// to the "http.server.request.duration" semantic conventions. It represents the
+// duration of HTTP server requests.
+type ServerRequestDuration struct {
+ metric.Float64Histogram
+}
+
+var newServerRequestDurationOpts = []metric.Float64HistogramOption{
+ metric.WithDescription("Duration of HTTP server requests."),
+ metric.WithUnit("s"),
+}
+
+// NewServerRequestDuration returns a new ServerRequestDuration instrument.
+func NewServerRequestDuration(
+ m metric.Meter,
+ opt ...metric.Float64HistogramOption,
+) (ServerRequestDuration, error) {
+ // Check if the meter is nil.
+ if m == nil {
+ return ServerRequestDuration{noop.Float64Histogram{}}, nil
+ }
+
+ if len(opt) == 0 {
+ opt = newServerRequestDurationOpts
+ } else {
+ opt = append(opt, newServerRequestDurationOpts...)
+ }
+
+ i, err := m.Float64Histogram(
+ "http.server.request.duration",
+ opt...,
+ )
+ if err != nil {
+ return ServerRequestDuration{noop.Float64Histogram{}}, err
+ }
+ return ServerRequestDuration{i}, nil
+}
+
+// Inst returns the underlying metric instrument.
+func (m ServerRequestDuration) Inst() metric.Float64Histogram {
+ return m.Float64Histogram
+}
+
+// Name returns the semantic convention name of the instrument.
+func (ServerRequestDuration) Name() string {
+ return "http.server.request.duration"
+}
+
+// Unit returns the semantic convention unit of the instrument
+func (ServerRequestDuration) Unit() string {
+ return "s"
+}
+
+// Description returns the semantic convention description of the instrument
+func (ServerRequestDuration) Description() string {
+ return "Duration of HTTP server requests."
+}
+
+// Record records val to the current distribution for attrs.
+//
+// The requestMethod is the HTTP request method.
+//
+// The urlScheme is the the [URI scheme] component identifying the used protocol.
+//
+// All additional attrs passed are included in the recorded value.
+//
+// [URI scheme]: https://www.rfc-editor.org/rfc/rfc3986#section-3.1
+func (m ServerRequestDuration) Record(
+ ctx context.Context,
+ val float64,
+ requestMethod RequestMethodAttr,
+ urlScheme string,
+ attrs ...attribute.KeyValue,
+) {
+ if !m.Float64Histogram.Enabled(ctx) {
+ return
+ }
+ if len(attrs) == 0 {
+ m.Float64Histogram.Record(ctx, val, metric.WithAttributes(
+ attribute.String("http.request.method", string(requestMethod)),
+ attribute.String("url.scheme", urlScheme),
+ ))
+ return
+ }
+
+ o := recOptPool.Get().(*[]metric.RecordOption)
+ defer func() {
+ *o = (*o)[:0]
+ recOptPool.Put(o)
+ }()
+
+ *o = append(
+ *o,
+ metric.WithAttributes(
+ append(
+ attrs[:len(attrs):len(attrs)],
+ attribute.String("http.request.method", string(requestMethod)),
+ attribute.String("url.scheme", urlScheme),
+ )...,
+ ),
+ )
+
+ m.Float64Histogram.Record(ctx, val, *o...)
+}
+
+// RecordSet records val to the current distribution for set.
+func (m ServerRequestDuration) RecordSet(ctx context.Context, val float64, set attribute.Set) {
+ if !m.Float64Histogram.Enabled(ctx) {
+ return
+ }
+ if set.Len() == 0 {
+ m.Float64Histogram.Record(ctx, val)
+ return
+ }
+
+ o := recOptPool.Get().(*[]metric.RecordOption)
+ defer func() {
+ *o = (*o)[:0]
+ recOptPool.Put(o)
+ }()
+
+ *o = append(*o, metric.WithAttributeSet(set))
+ m.Float64Histogram.Record(ctx, val, *o...)
+}
+
+// AttrErrorType returns an optional attribute for the "error.type" semantic
+// convention. It represents the describes a class of error the operation ended
+// with.
+func (ServerRequestDuration) AttrErrorType(val ErrorTypeAttr) attribute.KeyValue {
+ return attribute.String("error.type", string(val))
+}
+
+// AttrResponseStatusCode returns an optional attribute for the
+// "http.response.status_code" semantic convention. It represents the
+// [HTTP response status code].
+//
+// [HTTP response status code]: https://tools.ietf.org/html/rfc7231#section-6
+func (ServerRequestDuration) AttrResponseStatusCode(val int) attribute.KeyValue {
+ return attribute.Int("http.response.status_code", val)
+}
+
+// AttrRoute returns an optional attribute for the "http.route" semantic
+// convention. It represents the matched route template for the request. This
+// MUST be low-cardinality and include all static path segments, with dynamic
+// path segments represented with placeholders.
+func (ServerRequestDuration) AttrRoute(val string) attribute.KeyValue {
+ return attribute.String("http.route", val)
+}
+
+// AttrNetworkProtocolName returns an optional attribute for the
+// "network.protocol.name" semantic convention. It represents the
+// [OSI application layer] or non-OSI equivalent.
+//
+// [OSI application layer]: https://wikipedia.org/wiki/Application_layer
+func (ServerRequestDuration) AttrNetworkProtocolName(val string) attribute.KeyValue {
+ return attribute.String("network.protocol.name", val)
+}
+
+// AttrNetworkProtocolVersion returns an optional attribute for the
+// "network.protocol.version" semantic convention. It represents the actual
+// version of the protocol used for network communication.
+func (ServerRequestDuration) AttrNetworkProtocolVersion(val string) attribute.KeyValue {
+ return attribute.String("network.protocol.version", val)
+}
+
+// AttrServerAddress returns an optional attribute for the "server.address"
+// semantic convention. It represents the name of the local HTTP server that
+// received the request.
+func (ServerRequestDuration) AttrServerAddress(val string) attribute.KeyValue {
+ return attribute.String("server.address", val)
+}
+
+// AttrServerPort returns an optional attribute for the "server.port" semantic
+// convention. It represents the port of the local HTTP server that received the
+// request.
+func (ServerRequestDuration) AttrServerPort(val int) attribute.KeyValue {
+ return attribute.Int("server.port", val)
+}
+
+// AttrUserAgentSyntheticType returns an optional attribute for the
+// "user_agent.synthetic.type" semantic convention. It represents the specifies
+// the category of synthetic traffic, such as tests or bots.
+func (ServerRequestDuration) AttrUserAgentSyntheticType(val UserAgentSyntheticTypeAttr) attribute.KeyValue {
+ return attribute.String("user_agent.synthetic.type", string(val))
+}
+
+// ServerResponseBodySize is an instrument used to record metric values
+// conforming to the "http.server.response.body.size" semantic conventions. It
+// represents the size of HTTP server response bodies.
+type ServerResponseBodySize struct {
+ metric.Int64Histogram
+}
+
+var newServerResponseBodySizeOpts = []metric.Int64HistogramOption{
+ metric.WithDescription("Size of HTTP server response bodies."),
+ metric.WithUnit("By"),
+}
+
+// NewServerResponseBodySize returns a new ServerResponseBodySize instrument.
+func NewServerResponseBodySize(
+ m metric.Meter,
+ opt ...metric.Int64HistogramOption,
+) (ServerResponseBodySize, error) {
+ // Check if the meter is nil.
+ if m == nil {
+ return ServerResponseBodySize{noop.Int64Histogram{}}, nil
+ }
+
+ if len(opt) == 0 {
+ opt = newServerResponseBodySizeOpts
+ } else {
+ opt = append(opt, newServerResponseBodySizeOpts...)
+ }
+
+ i, err := m.Int64Histogram(
+ "http.server.response.body.size",
+ opt...,
+ )
+ if err != nil {
+ return ServerResponseBodySize{noop.Int64Histogram{}}, err
+ }
+ return ServerResponseBodySize{i}, nil
+}
+
+// Inst returns the underlying metric instrument.
+func (m ServerResponseBodySize) Inst() metric.Int64Histogram {
+ return m.Int64Histogram
+}
+
+// Name returns the semantic convention name of the instrument.
+func (ServerResponseBodySize) Name() string {
+ return "http.server.response.body.size"
+}
+
+// Unit returns the semantic convention unit of the instrument
+func (ServerResponseBodySize) Unit() string {
+ return "By"
+}
+
+// Description returns the semantic convention description of the instrument
+func (ServerResponseBodySize) Description() string {
+ return "Size of HTTP server response bodies."
+}
+
+// Record records val to the current distribution for attrs.
+//
+// The requestMethod is the HTTP request method.
+//
+// The urlScheme is the the [URI scheme] component identifying the used protocol.
+//
+// All additional attrs passed are included in the recorded value.
+//
+// The size of the response payload body in bytes. This is the number of bytes
+// transferred excluding headers and is often, but not always, present as the
+// [Content-Length] header. For requests using transport encoding, this should be
+// the compressed size.
+//
+// [URI scheme]: https://www.rfc-editor.org/rfc/rfc3986#section-3.1
+// [Content-Length]: https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length
+func (m ServerResponseBodySize) Record(
+ ctx context.Context,
+ val int64,
+ requestMethod RequestMethodAttr,
+ urlScheme string,
+ attrs ...attribute.KeyValue,
+) {
+ if !m.Int64Histogram.Enabled(ctx) {
+ return
+ }
+ if len(attrs) == 0 {
+ m.Int64Histogram.Record(ctx, val, metric.WithAttributes(
+ attribute.String("http.request.method", string(requestMethod)),
+ attribute.String("url.scheme", urlScheme),
+ ))
+ return
+ }
+
+ o := recOptPool.Get().(*[]metric.RecordOption)
+ defer func() {
+ *o = (*o)[:0]
+ recOptPool.Put(o)
+ }()
+
+ *o = append(
+ *o,
+ metric.WithAttributes(
+ append(
+ attrs[:len(attrs):len(attrs)],
+ attribute.String("http.request.method", string(requestMethod)),
+ attribute.String("url.scheme", urlScheme),
+ )...,
+ ),
+ )
+
+ m.Int64Histogram.Record(ctx, val, *o...)
+}
+
+// RecordSet records val to the current distribution for set.
+//
+// The size of the response payload body in bytes. This is the number of bytes
+// transferred excluding headers and is often, but not always, present as the
+// [Content-Length] header. For requests using transport encoding, this should be
+// the compressed size.
+//
+// [Content-Length]: https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length
+func (m ServerResponseBodySize) RecordSet(ctx context.Context, val int64, set attribute.Set) {
+ if !m.Int64Histogram.Enabled(ctx) {
+ return
+ }
+ if set.Len() == 0 {
+ m.Int64Histogram.Record(ctx, val)
+ return
+ }
+
+ o := recOptPool.Get().(*[]metric.RecordOption)
+ defer func() {
+ *o = (*o)[:0]
+ recOptPool.Put(o)
+ }()
+
+ *o = append(*o, metric.WithAttributeSet(set))
+ m.Int64Histogram.Record(ctx, val, *o...)
+}
+
+// AttrErrorType returns an optional attribute for the "error.type" semantic
+// convention. It represents the describes a class of error the operation ended
+// with.
+func (ServerResponseBodySize) AttrErrorType(val ErrorTypeAttr) attribute.KeyValue {
+ return attribute.String("error.type", string(val))
+}
+
+// AttrResponseStatusCode returns an optional attribute for the
+// "http.response.status_code" semantic convention. It represents the
+// [HTTP response status code].
+//
+// [HTTP response status code]: https://tools.ietf.org/html/rfc7231#section-6
+func (ServerResponseBodySize) AttrResponseStatusCode(val int) attribute.KeyValue {
+ return attribute.Int("http.response.status_code", val)
+}
+
+// AttrRoute returns an optional attribute for the "http.route" semantic
+// convention. It represents the matched route template for the request. This
+// MUST be low-cardinality and include all static path segments, with dynamic
+// path segments represented with placeholders.
+func (ServerResponseBodySize) AttrRoute(val string) attribute.KeyValue {
+ return attribute.String("http.route", val)
+}
+
+// AttrNetworkProtocolName returns an optional attribute for the
+// "network.protocol.name" semantic convention. It represents the
+// [OSI application layer] or non-OSI equivalent.
+//
+// [OSI application layer]: https://wikipedia.org/wiki/Application_layer
+func (ServerResponseBodySize) AttrNetworkProtocolName(val string) attribute.KeyValue {
+ return attribute.String("network.protocol.name", val)
+}
+
+// AttrNetworkProtocolVersion returns an optional attribute for the
+// "network.protocol.version" semantic convention. It represents the actual
+// version of the protocol used for network communication.
+func (ServerResponseBodySize) AttrNetworkProtocolVersion(val string) attribute.KeyValue {
+ return attribute.String("network.protocol.version", val)
+}
+
+// AttrServerAddress returns an optional attribute for the "server.address"
+// semantic convention. It represents the name of the local HTTP server that
+// received the request.
+func (ServerResponseBodySize) AttrServerAddress(val string) attribute.KeyValue {
+ return attribute.String("server.address", val)
+}
+
+// AttrServerPort returns an optional attribute for the "server.port" semantic
+// convention. It represents the port of the local HTTP server that received the
+// request.
+func (ServerResponseBodySize) AttrServerPort(val int) attribute.KeyValue {
+ return attribute.Int("server.port", val)
+}
+
+// AttrUserAgentSyntheticType returns an optional attribute for the
+// "user_agent.synthetic.type" semantic convention. It represents the specifies
+// the category of synthetic traffic, such as tests or bots.
+func (ServerResponseBodySize) AttrUserAgentSyntheticType(val UserAgentSyntheticTypeAttr) attribute.KeyValue {
+ return attribute.String("user_agent.synthetic.type", string(val))
+}
diff --git a/vendor/go.opentelemetry.io/otel/semconv/v1.40.0/otelconv/metric.go b/vendor/go.opentelemetry.io/otel/semconv/v1.40.0/otelconv/metric.go
new file mode 100644
index 000000000..ba9d29e9d
--- /dev/null
+++ b/vendor/go.opentelemetry.io/otel/semconv/v1.40.0/otelconv/metric.go
@@ -0,0 +1,2298 @@
+// Code generated from semantic convention specification. DO NOT EDIT.
+
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+// Package otelconv provides types and functionality for OpenTelemetry semantic
+// conventions in the "otel" namespace.
+package otelconv
+
+import (
+ "context"
+ "sync"
+
+ "go.opentelemetry.io/otel/attribute"
+ "go.opentelemetry.io/otel/metric"
+ "go.opentelemetry.io/otel/metric/noop"
+)
+
+var (
+ addOptPool = &sync.Pool{New: func() any { return &[]metric.AddOption{} }}
+ recOptPool = &sync.Pool{New: func() any { return &[]metric.RecordOption{} }}
+)
+
+// ErrorTypeAttr is an attribute conforming to the error.type semantic
+// conventions. It represents the describes a class of error the operation ended
+// with.
+type ErrorTypeAttr string
+
+// ErrorTypeOther is a fallback error value to be used when the instrumentation
+// doesn't define a custom value.
+var ErrorTypeOther ErrorTypeAttr = "_OTHER"
+
+// ComponentTypeAttr is an attribute conforming to the otel.component.type
+// semantic conventions. It represents a name identifying the type of the
+// OpenTelemetry component.
+type ComponentTypeAttr string
+
+var (
+ // ComponentTypeBatchingSpanProcessor is the builtin SDK batching span
+ // processor.
+ ComponentTypeBatchingSpanProcessor ComponentTypeAttr = "batching_span_processor"
+ // ComponentTypeSimpleSpanProcessor is the builtin SDK simple span processor.
+ ComponentTypeSimpleSpanProcessor ComponentTypeAttr = "simple_span_processor"
+ // ComponentTypeBatchingLogProcessor is the builtin SDK batching log record
+ // processor.
+ ComponentTypeBatchingLogProcessor ComponentTypeAttr = "batching_log_processor"
+ // ComponentTypeSimpleLogProcessor is the builtin SDK simple log record
+ // processor.
+ ComponentTypeSimpleLogProcessor ComponentTypeAttr = "simple_log_processor"
+ // ComponentTypeOtlpGRPCSpanExporter is the OTLP span exporter over gRPC with
+ // protobuf serialization.
+ ComponentTypeOtlpGRPCSpanExporter ComponentTypeAttr = "otlp_grpc_span_exporter"
+ // ComponentTypeOtlpHTTPSpanExporter is the OTLP span exporter over HTTP with
+ // protobuf serialization.
+ ComponentTypeOtlpHTTPSpanExporter ComponentTypeAttr = "otlp_http_span_exporter"
+ // ComponentTypeOtlpHTTPJSONSpanExporter is the OTLP span exporter over HTTP
+ // with JSON serialization.
+ ComponentTypeOtlpHTTPJSONSpanExporter ComponentTypeAttr = "otlp_http_json_span_exporter"
+ // ComponentTypeZipkinHTTPSpanExporter is the zipkin span exporter over HTTP.
+ ComponentTypeZipkinHTTPSpanExporter ComponentTypeAttr = "zipkin_http_span_exporter"
+ // ComponentTypeOtlpGRPCLogExporter is the OTLP log record exporter over gRPC
+ // with protobuf serialization.
+ ComponentTypeOtlpGRPCLogExporter ComponentTypeAttr = "otlp_grpc_log_exporter"
+ // ComponentTypeOtlpHTTPLogExporter is the OTLP log record exporter over HTTP
+ // with protobuf serialization.
+ ComponentTypeOtlpHTTPLogExporter ComponentTypeAttr = "otlp_http_log_exporter"
+ // ComponentTypeOtlpHTTPJSONLogExporter is the OTLP log record exporter over
+ // HTTP with JSON serialization.
+ ComponentTypeOtlpHTTPJSONLogExporter ComponentTypeAttr = "otlp_http_json_log_exporter"
+ // ComponentTypePeriodicMetricReader is the builtin SDK periodically exporting
+ // metric reader.
+ ComponentTypePeriodicMetricReader ComponentTypeAttr = "periodic_metric_reader"
+ // ComponentTypeOtlpGRPCMetricExporter is the OTLP metric exporter over gRPC
+ // with protobuf serialization.
+ ComponentTypeOtlpGRPCMetricExporter ComponentTypeAttr = "otlp_grpc_metric_exporter"
+ // ComponentTypeOtlpHTTPMetricExporter is the OTLP metric exporter over HTTP
+ // with protobuf serialization.
+ ComponentTypeOtlpHTTPMetricExporter ComponentTypeAttr = "otlp_http_metric_exporter"
+ // ComponentTypeOtlpHTTPJSONMetricExporter is the OTLP metric exporter over HTTP
+ // with JSON serialization.
+ ComponentTypeOtlpHTTPJSONMetricExporter ComponentTypeAttr = "otlp_http_json_metric_exporter"
+ // ComponentTypePrometheusHTTPTextMetricExporter is the prometheus metric
+ // exporter over HTTP with the default text-based format.
+ ComponentTypePrometheusHTTPTextMetricExporter ComponentTypeAttr = "prometheus_http_text_metric_exporter"
+)
+
+// SpanParentOriginAttr is an attribute conforming to the otel.span.parent.origin
+// semantic conventions. It represents the determines whether the span has a
+// parent span, and if so, [whether it is a remote parent].
+//
+// [whether it is a remote parent]: https://opentelemetry.io/docs/specs/otel/trace/api/#isremote
+type SpanParentOriginAttr string
+
+var (
+ // SpanParentOriginNone is the span does not have a parent, it is a root span.
+ SpanParentOriginNone SpanParentOriginAttr = "none"
+ // SpanParentOriginLocal is the span has a parent and the parent's span context
+ // [isRemote()] is false.
+ //
+ // [isRemote()]: https://opentelemetry.io/docs/specs/otel/trace/api/#isremote
+ SpanParentOriginLocal SpanParentOriginAttr = "local"
+ // SpanParentOriginRemote is the span has a parent and the parent's span context
+ // [isRemote()] is true.
+ //
+ // [isRemote()]: https://opentelemetry.io/docs/specs/otel/trace/api/#isremote
+ SpanParentOriginRemote SpanParentOriginAttr = "remote"
+)
+
+// SpanSamplingResultAttr is an attribute conforming to the
+// otel.span.sampling_result semantic conventions. It represents the result value
+// of the sampler for this span.
+type SpanSamplingResultAttr string
+
+var (
+ // SpanSamplingResultDrop is the span is not sampled and not recording.
+ SpanSamplingResultDrop SpanSamplingResultAttr = "DROP"
+ // SpanSamplingResultRecordOnly is the span is not sampled, but recording.
+ SpanSamplingResultRecordOnly SpanSamplingResultAttr = "RECORD_ONLY"
+ // SpanSamplingResultRecordAndSample is the span is sampled and recording.
+ SpanSamplingResultRecordAndSample SpanSamplingResultAttr = "RECORD_AND_SAMPLE"
+)
+
+// SDKExporterLogExported is an instrument used to record metric values
+// conforming to the "otel.sdk.exporter.log.exported" semantic conventions. It
+// represents the number of log records for which the export has finished, either
+// successful or failed.
+type SDKExporterLogExported struct {
+ metric.Int64Counter
+}
+
+var newSDKExporterLogExportedOpts = []metric.Int64CounterOption{
+ metric.WithDescription("The number of log records for which the export has finished, either successful or failed."),
+ metric.WithUnit("{log_record}"),
+}
+
+// NewSDKExporterLogExported returns a new SDKExporterLogExported instrument.
+func NewSDKExporterLogExported(
+ m metric.Meter,
+ opt ...metric.Int64CounterOption,
+) (SDKExporterLogExported, error) {
+ // Check if the meter is nil.
+ if m == nil {
+ return SDKExporterLogExported{noop.Int64Counter{}}, nil
+ }
+
+ if len(opt) == 0 {
+ opt = newSDKExporterLogExportedOpts
+ } else {
+ opt = append(opt, newSDKExporterLogExportedOpts...)
+ }
+
+ i, err := m.Int64Counter(
+ "otel.sdk.exporter.log.exported",
+ opt...,
+ )
+ if err != nil {
+ return SDKExporterLogExported{noop.Int64Counter{}}, err
+ }
+ return SDKExporterLogExported{i}, nil
+}
+
+// Inst returns the underlying metric instrument.
+func (m SDKExporterLogExported) Inst() metric.Int64Counter {
+ return m.Int64Counter
+}
+
+// Name returns the semantic convention name of the instrument.
+func (SDKExporterLogExported) Name() string {
+ return "otel.sdk.exporter.log.exported"
+}
+
+// Unit returns the semantic convention unit of the instrument
+func (SDKExporterLogExported) Unit() string {
+ return "{log_record}"
+}
+
+// Description returns the semantic convention description of the instrument
+func (SDKExporterLogExported) Description() string {
+ return "The number of log records for which the export has finished, either successful or failed."
+}
+
+// Add adds incr to the existing count for attrs.
+//
+// All additional attrs passed are included in the recorded value.
+//
+// For successful exports, `error.type` MUST NOT be set. For failed exports,
+// `error.type` MUST contain the failure cause.
+// For exporters with partial success semantics (e.g. OTLP with
+// `rejected_log_records`), rejected log records MUST count as failed and only
+// non-rejected log records count as success.
+// If no rejection reason is available, `rejected` SHOULD be used as value for
+// `error.type`.
+func (m SDKExporterLogExported) Add(
+ ctx context.Context,
+ incr int64,
+ attrs ...attribute.KeyValue,
+) {
+ if !m.Int64Counter.Enabled(ctx) {
+ return
+ }
+ if len(attrs) == 0 {
+ m.Int64Counter.Add(ctx, incr)
+ return
+ }
+
+ o := addOptPool.Get().(*[]metric.AddOption)
+ defer func() {
+ *o = (*o)[:0]
+ addOptPool.Put(o)
+ }()
+
+ *o = append(
+ *o,
+ metric.WithAttributes(
+ attrs...,
+ ),
+ )
+
+ m.Int64Counter.Add(ctx, incr, *o...)
+}
+
+// AddSet adds incr to the existing count for set.
+//
+// For successful exports, `error.type` MUST NOT be set. For failed exports,
+// `error.type` MUST contain the failure cause.
+// For exporters with partial success semantics (e.g. OTLP with
+// `rejected_log_records`), rejected log records MUST count as failed and only
+// non-rejected log records count as success.
+// If no rejection reason is available, `rejected` SHOULD be used as value for
+// `error.type`.
+func (m SDKExporterLogExported) AddSet(ctx context.Context, incr int64, set attribute.Set) {
+ if !m.Int64Counter.Enabled(ctx) {
+ return
+ }
+ if set.Len() == 0 {
+ m.Int64Counter.Add(ctx, incr)
+ return
+ }
+
+ o := addOptPool.Get().(*[]metric.AddOption)
+ defer func() {
+ *o = (*o)[:0]
+ addOptPool.Put(o)
+ }()
+
+ *o = append(*o, metric.WithAttributeSet(set))
+ m.Int64Counter.Add(ctx, incr, *o...)
+}
+
+// AttrErrorType returns an optional attribute for the "error.type" semantic
+// convention. It represents the describes a class of error the operation ended
+// with.
+func (SDKExporterLogExported) AttrErrorType(val ErrorTypeAttr) attribute.KeyValue {
+ return attribute.String("error.type", string(val))
+}
+
+// AttrComponentName returns an optional attribute for the "otel.component.name"
+// semantic convention. It represents a name uniquely identifying the instance of
+// the OpenTelemetry component within its containing SDK instance.
+func (SDKExporterLogExported) AttrComponentName(val string) attribute.KeyValue {
+ return attribute.String("otel.component.name", val)
+}
+
+// AttrComponentType returns an optional attribute for the "otel.component.type"
+// semantic convention. It represents a name identifying the type of the
+// OpenTelemetry component.
+func (SDKExporterLogExported) AttrComponentType(val ComponentTypeAttr) attribute.KeyValue {
+ return attribute.String("otel.component.type", string(val))
+}
+
+// AttrServerAddress returns an optional attribute for the "server.address"
+// semantic convention. It represents the server domain name if available without
+// reverse DNS lookup; otherwise, IP address or Unix domain socket name.
+func (SDKExporterLogExported) AttrServerAddress(val string) attribute.KeyValue {
+ return attribute.String("server.address", val)
+}
+
+// AttrServerPort returns an optional attribute for the "server.port" semantic
+// convention. It represents the server port number.
+func (SDKExporterLogExported) AttrServerPort(val int) attribute.KeyValue {
+ return attribute.Int("server.port", val)
+}
+
+// SDKExporterLogInflight is an instrument used to record metric values
+// conforming to the "otel.sdk.exporter.log.inflight" semantic conventions. It
+// represents the number of log records which were passed to the exporter, but
+// that have not been exported yet (neither successful, nor failed).
+type SDKExporterLogInflight struct {
+ metric.Int64UpDownCounter
+}
+
+var newSDKExporterLogInflightOpts = []metric.Int64UpDownCounterOption{
+ metric.WithDescription("The number of log records which were passed to the exporter, but that have not been exported yet (neither successful, nor failed)."),
+ metric.WithUnit("{log_record}"),
+}
+
+// NewSDKExporterLogInflight returns a new SDKExporterLogInflight instrument.
+func NewSDKExporterLogInflight(
+ m metric.Meter,
+ opt ...metric.Int64UpDownCounterOption,
+) (SDKExporterLogInflight, error) {
+ // Check if the meter is nil.
+ if m == nil {
+ return SDKExporterLogInflight{noop.Int64UpDownCounter{}}, nil
+ }
+
+ if len(opt) == 0 {
+ opt = newSDKExporterLogInflightOpts
+ } else {
+ opt = append(opt, newSDKExporterLogInflightOpts...)
+ }
+
+ i, err := m.Int64UpDownCounter(
+ "otel.sdk.exporter.log.inflight",
+ opt...,
+ )
+ if err != nil {
+ return SDKExporterLogInflight{noop.Int64UpDownCounter{}}, err
+ }
+ return SDKExporterLogInflight{i}, nil
+}
+
+// Inst returns the underlying metric instrument.
+func (m SDKExporterLogInflight) Inst() metric.Int64UpDownCounter {
+ return m.Int64UpDownCounter
+}
+
+// Name returns the semantic convention name of the instrument.
+func (SDKExporterLogInflight) Name() string {
+ return "otel.sdk.exporter.log.inflight"
+}
+
+// Unit returns the semantic convention unit of the instrument
+func (SDKExporterLogInflight) Unit() string {
+ return "{log_record}"
+}
+
+// Description returns the semantic convention description of the instrument
+func (SDKExporterLogInflight) Description() string {
+ return "The number of log records which were passed to the exporter, but that have not been exported yet (neither successful, nor failed)."
+}
+
+// Add adds incr to the existing count for attrs.
+//
+// All additional attrs passed are included in the recorded value.
+//
+// For successful exports, `error.type` MUST NOT be set. For failed exports,
+// `error.type` MUST contain the failure cause.
+func (m SDKExporterLogInflight) Add(
+ ctx context.Context,
+ incr int64,
+ attrs ...attribute.KeyValue,
+) {
+ if !m.Int64UpDownCounter.Enabled(ctx) {
+ return
+ }
+ if len(attrs) == 0 {
+ m.Int64UpDownCounter.Add(ctx, incr)
+ return
+ }
+
+ o := addOptPool.Get().(*[]metric.AddOption)
+ defer func() {
+ *o = (*o)[:0]
+ addOptPool.Put(o)
+ }()
+
+ *o = append(
+ *o,
+ metric.WithAttributes(
+ attrs...,
+ ),
+ )
+
+ m.Int64UpDownCounter.Add(ctx, incr, *o...)
+}
+
+// AddSet adds incr to the existing count for set.
+//
+// For successful exports, `error.type` MUST NOT be set. For failed exports,
+// `error.type` MUST contain the failure cause.
+func (m SDKExporterLogInflight) AddSet(ctx context.Context, incr int64, set attribute.Set) {
+ if !m.Int64UpDownCounter.Enabled(ctx) {
+ return
+ }
+ if set.Len() == 0 {
+ m.Int64UpDownCounter.Add(ctx, incr)
+ return
+ }
+
+ o := addOptPool.Get().(*[]metric.AddOption)
+ defer func() {
+ *o = (*o)[:0]
+ addOptPool.Put(o)
+ }()
+
+ *o = append(*o, metric.WithAttributeSet(set))
+ m.Int64UpDownCounter.Add(ctx, incr, *o...)
+}
+
+// AttrComponentName returns an optional attribute for the "otel.component.name"
+// semantic convention. It represents a name uniquely identifying the instance of
+// the OpenTelemetry component within its containing SDK instance.
+func (SDKExporterLogInflight) AttrComponentName(val string) attribute.KeyValue {
+ return attribute.String("otel.component.name", val)
+}
+
+// AttrComponentType returns an optional attribute for the "otel.component.type"
+// semantic convention. It represents a name identifying the type of the
+// OpenTelemetry component.
+func (SDKExporterLogInflight) AttrComponentType(val ComponentTypeAttr) attribute.KeyValue {
+ return attribute.String("otel.component.type", string(val))
+}
+
+// AttrServerAddress returns an optional attribute for the "server.address"
+// semantic convention. It represents the server domain name if available without
+// reverse DNS lookup; otherwise, IP address or Unix domain socket name.
+func (SDKExporterLogInflight) AttrServerAddress(val string) attribute.KeyValue {
+ return attribute.String("server.address", val)
+}
+
+// AttrServerPort returns an optional attribute for the "server.port" semantic
+// convention. It represents the server port number.
+func (SDKExporterLogInflight) AttrServerPort(val int) attribute.KeyValue {
+ return attribute.Int("server.port", val)
+}
+
+// SDKExporterMetricDataPointExported is an instrument used to record metric
+// values conforming to the "otel.sdk.exporter.metric_data_point.exported"
+// semantic conventions. It represents the number of metric data points for which
+// the export has finished, either successful or failed.
+type SDKExporterMetricDataPointExported struct {
+ metric.Int64Counter
+}
+
+var newSDKExporterMetricDataPointExportedOpts = []metric.Int64CounterOption{
+ metric.WithDescription("The number of metric data points for which the export has finished, either successful or failed."),
+ metric.WithUnit("{data_point}"),
+}
+
+// NewSDKExporterMetricDataPointExported returns a new
+// SDKExporterMetricDataPointExported instrument.
+func NewSDKExporterMetricDataPointExported(
+ m metric.Meter,
+ opt ...metric.Int64CounterOption,
+) (SDKExporterMetricDataPointExported, error) {
+ // Check if the meter is nil.
+ if m == nil {
+ return SDKExporterMetricDataPointExported{noop.Int64Counter{}}, nil
+ }
+
+ if len(opt) == 0 {
+ opt = newSDKExporterMetricDataPointExportedOpts
+ } else {
+ opt = append(opt, newSDKExporterMetricDataPointExportedOpts...)
+ }
+
+ i, err := m.Int64Counter(
+ "otel.sdk.exporter.metric_data_point.exported",
+ opt...,
+ )
+ if err != nil {
+ return SDKExporterMetricDataPointExported{noop.Int64Counter{}}, err
+ }
+ return SDKExporterMetricDataPointExported{i}, nil
+}
+
+// Inst returns the underlying metric instrument.
+func (m SDKExporterMetricDataPointExported) Inst() metric.Int64Counter {
+ return m.Int64Counter
+}
+
+// Name returns the semantic convention name of the instrument.
+func (SDKExporterMetricDataPointExported) Name() string {
+ return "otel.sdk.exporter.metric_data_point.exported"
+}
+
+// Unit returns the semantic convention unit of the instrument
+func (SDKExporterMetricDataPointExported) Unit() string {
+ return "{data_point}"
+}
+
+// Description returns the semantic convention description of the instrument
+func (SDKExporterMetricDataPointExported) Description() string {
+ return "The number of metric data points for which the export has finished, either successful or failed."
+}
+
+// Add adds incr to the existing count for attrs.
+//
+// All additional attrs passed are included in the recorded value.
+//
+// For successful exports, `error.type` MUST NOT be set. For failed exports,
+// `error.type` MUST contain the failure cause.
+// For exporters with partial success semantics (e.g. OTLP with
+// `rejected_data_points`), rejected data points MUST count as failed and only
+// non-rejected data points count as success.
+// If no rejection reason is available, `rejected` SHOULD be used as value for
+// `error.type`.
+func (m SDKExporterMetricDataPointExported) Add(
+ ctx context.Context,
+ incr int64,
+ attrs ...attribute.KeyValue,
+) {
+ if !m.Int64Counter.Enabled(ctx) {
+ return
+ }
+ if len(attrs) == 0 {
+ m.Int64Counter.Add(ctx, incr)
+ return
+ }
+
+ o := addOptPool.Get().(*[]metric.AddOption)
+ defer func() {
+ *o = (*o)[:0]
+ addOptPool.Put(o)
+ }()
+
+ *o = append(
+ *o,
+ metric.WithAttributes(
+ attrs...,
+ ),
+ )
+
+ m.Int64Counter.Add(ctx, incr, *o...)
+}
+
+// AddSet adds incr to the existing count for set.
+//
+// For successful exports, `error.type` MUST NOT be set. For failed exports,
+// `error.type` MUST contain the failure cause.
+// For exporters with partial success semantics (e.g. OTLP with
+// `rejected_data_points`), rejected data points MUST count as failed and only
+// non-rejected data points count as success.
+// If no rejection reason is available, `rejected` SHOULD be used as value for
+// `error.type`.
+func (m SDKExporterMetricDataPointExported) AddSet(ctx context.Context, incr int64, set attribute.Set) {
+ if !m.Int64Counter.Enabled(ctx) {
+ return
+ }
+ if set.Len() == 0 {
+ m.Int64Counter.Add(ctx, incr)
+ return
+ }
+
+ o := addOptPool.Get().(*[]metric.AddOption)
+ defer func() {
+ *o = (*o)[:0]
+ addOptPool.Put(o)
+ }()
+
+ *o = append(*o, metric.WithAttributeSet(set))
+ m.Int64Counter.Add(ctx, incr, *o...)
+}
+
+// AttrErrorType returns an optional attribute for the "error.type" semantic
+// convention. It represents the describes a class of error the operation ended
+// with.
+func (SDKExporterMetricDataPointExported) AttrErrorType(val ErrorTypeAttr) attribute.KeyValue {
+ return attribute.String("error.type", string(val))
+}
+
+// AttrComponentName returns an optional attribute for the "otel.component.name"
+// semantic convention. It represents a name uniquely identifying the instance of
+// the OpenTelemetry component within its containing SDK instance.
+func (SDKExporterMetricDataPointExported) AttrComponentName(val string) attribute.KeyValue {
+ return attribute.String("otel.component.name", val)
+}
+
+// AttrComponentType returns an optional attribute for the "otel.component.type"
+// semantic convention. It represents a name identifying the type of the
+// OpenTelemetry component.
+func (SDKExporterMetricDataPointExported) AttrComponentType(val ComponentTypeAttr) attribute.KeyValue {
+ return attribute.String("otel.component.type", string(val))
+}
+
+// AttrServerAddress returns an optional attribute for the "server.address"
+// semantic convention. It represents the server domain name if available without
+// reverse DNS lookup; otherwise, IP address or Unix domain socket name.
+func (SDKExporterMetricDataPointExported) AttrServerAddress(val string) attribute.KeyValue {
+ return attribute.String("server.address", val)
+}
+
+// AttrServerPort returns an optional attribute for the "server.port" semantic
+// convention. It represents the server port number.
+func (SDKExporterMetricDataPointExported) AttrServerPort(val int) attribute.KeyValue {
+ return attribute.Int("server.port", val)
+}
+
+// SDKExporterMetricDataPointInflight is an instrument used to record metric
+// values conforming to the "otel.sdk.exporter.metric_data_point.inflight"
+// semantic conventions. It represents the number of metric data points which
+// were passed to the exporter, but that have not been exported yet (neither
+// successful, nor failed).
+type SDKExporterMetricDataPointInflight struct {
+ metric.Int64UpDownCounter
+}
+
+var newSDKExporterMetricDataPointInflightOpts = []metric.Int64UpDownCounterOption{
+ metric.WithDescription("The number of metric data points which were passed to the exporter, but that have not been exported yet (neither successful, nor failed)."),
+ metric.WithUnit("{data_point}"),
+}
+
+// NewSDKExporterMetricDataPointInflight returns a new
+// SDKExporterMetricDataPointInflight instrument.
+func NewSDKExporterMetricDataPointInflight(
+ m metric.Meter,
+ opt ...metric.Int64UpDownCounterOption,
+) (SDKExporterMetricDataPointInflight, error) {
+ // Check if the meter is nil.
+ if m == nil {
+ return SDKExporterMetricDataPointInflight{noop.Int64UpDownCounter{}}, nil
+ }
+
+ if len(opt) == 0 {
+ opt = newSDKExporterMetricDataPointInflightOpts
+ } else {
+ opt = append(opt, newSDKExporterMetricDataPointInflightOpts...)
+ }
+
+ i, err := m.Int64UpDownCounter(
+ "otel.sdk.exporter.metric_data_point.inflight",
+ opt...,
+ )
+ if err != nil {
+ return SDKExporterMetricDataPointInflight{noop.Int64UpDownCounter{}}, err
+ }
+ return SDKExporterMetricDataPointInflight{i}, nil
+}
+
+// Inst returns the underlying metric instrument.
+func (m SDKExporterMetricDataPointInflight) Inst() metric.Int64UpDownCounter {
+ return m.Int64UpDownCounter
+}
+
+// Name returns the semantic convention name of the instrument.
+func (SDKExporterMetricDataPointInflight) Name() string {
+ return "otel.sdk.exporter.metric_data_point.inflight"
+}
+
+// Unit returns the semantic convention unit of the instrument
+func (SDKExporterMetricDataPointInflight) Unit() string {
+ return "{data_point}"
+}
+
+// Description returns the semantic convention description of the instrument
+func (SDKExporterMetricDataPointInflight) Description() string {
+ return "The number of metric data points which were passed to the exporter, but that have not been exported yet (neither successful, nor failed)."
+}
+
+// Add adds incr to the existing count for attrs.
+//
+// All additional attrs passed are included in the recorded value.
+//
+// For successful exports, `error.type` MUST NOT be set. For failed exports,
+// `error.type` MUST contain the failure cause.
+func (m SDKExporterMetricDataPointInflight) Add(
+ ctx context.Context,
+ incr int64,
+ attrs ...attribute.KeyValue,
+) {
+ if !m.Int64UpDownCounter.Enabled(ctx) {
+ return
+ }
+ if len(attrs) == 0 {
+ m.Int64UpDownCounter.Add(ctx, incr)
+ return
+ }
+
+ o := addOptPool.Get().(*[]metric.AddOption)
+ defer func() {
+ *o = (*o)[:0]
+ addOptPool.Put(o)
+ }()
+
+ *o = append(
+ *o,
+ metric.WithAttributes(
+ attrs...,
+ ),
+ )
+
+ m.Int64UpDownCounter.Add(ctx, incr, *o...)
+}
+
+// AddSet adds incr to the existing count for set.
+//
+// For successful exports, `error.type` MUST NOT be set. For failed exports,
+// `error.type` MUST contain the failure cause.
+func (m SDKExporterMetricDataPointInflight) AddSet(ctx context.Context, incr int64, set attribute.Set) {
+ if !m.Int64UpDownCounter.Enabled(ctx) {
+ return
+ }
+ if set.Len() == 0 {
+ m.Int64UpDownCounter.Add(ctx, incr)
+ return
+ }
+
+ o := addOptPool.Get().(*[]metric.AddOption)
+ defer func() {
+ *o = (*o)[:0]
+ addOptPool.Put(o)
+ }()
+
+ *o = append(*o, metric.WithAttributeSet(set))
+ m.Int64UpDownCounter.Add(ctx, incr, *o...)
+}
+
+// AttrComponentName returns an optional attribute for the "otel.component.name"
+// semantic convention. It represents a name uniquely identifying the instance of
+// the OpenTelemetry component within its containing SDK instance.
+func (SDKExporterMetricDataPointInflight) AttrComponentName(val string) attribute.KeyValue {
+ return attribute.String("otel.component.name", val)
+}
+
+// AttrComponentType returns an optional attribute for the "otel.component.type"
+// semantic convention. It represents a name identifying the type of the
+// OpenTelemetry component.
+func (SDKExporterMetricDataPointInflight) AttrComponentType(val ComponentTypeAttr) attribute.KeyValue {
+ return attribute.String("otel.component.type", string(val))
+}
+
+// AttrServerAddress returns an optional attribute for the "server.address"
+// semantic convention. It represents the server domain name if available without
+// reverse DNS lookup; otherwise, IP address or Unix domain socket name.
+func (SDKExporterMetricDataPointInflight) AttrServerAddress(val string) attribute.KeyValue {
+ return attribute.String("server.address", val)
+}
+
+// AttrServerPort returns an optional attribute for the "server.port" semantic
+// convention. It represents the server port number.
+func (SDKExporterMetricDataPointInflight) AttrServerPort(val int) attribute.KeyValue {
+ return attribute.Int("server.port", val)
+}
+
+// SDKExporterOperationDuration is an instrument used to record metric values
+// conforming to the "otel.sdk.exporter.operation.duration" semantic conventions.
+// It represents the duration of exporting a batch of telemetry records.
+type SDKExporterOperationDuration struct {
+ metric.Float64Histogram
+}
+
+var newSDKExporterOperationDurationOpts = []metric.Float64HistogramOption{
+ metric.WithDescription("The duration of exporting a batch of telemetry records."),
+ metric.WithUnit("s"),
+}
+
+// NewSDKExporterOperationDuration returns a new SDKExporterOperationDuration
+// instrument.
+func NewSDKExporterOperationDuration(
+ m metric.Meter,
+ opt ...metric.Float64HistogramOption,
+) (SDKExporterOperationDuration, error) {
+ // Check if the meter is nil.
+ if m == nil {
+ return SDKExporterOperationDuration{noop.Float64Histogram{}}, nil
+ }
+
+ if len(opt) == 0 {
+ opt = newSDKExporterOperationDurationOpts
+ } else {
+ opt = append(opt, newSDKExporterOperationDurationOpts...)
+ }
+
+ i, err := m.Float64Histogram(
+ "otel.sdk.exporter.operation.duration",
+ opt...,
+ )
+ if err != nil {
+ return SDKExporterOperationDuration{noop.Float64Histogram{}}, err
+ }
+ return SDKExporterOperationDuration{i}, nil
+}
+
+// Inst returns the underlying metric instrument.
+func (m SDKExporterOperationDuration) Inst() metric.Float64Histogram {
+ return m.Float64Histogram
+}
+
+// Name returns the semantic convention name of the instrument.
+func (SDKExporterOperationDuration) Name() string {
+ return "otel.sdk.exporter.operation.duration"
+}
+
+// Unit returns the semantic convention unit of the instrument
+func (SDKExporterOperationDuration) Unit() string {
+ return "s"
+}
+
+// Description returns the semantic convention description of the instrument
+func (SDKExporterOperationDuration) Description() string {
+ return "The duration of exporting a batch of telemetry records."
+}
+
+// Record records val to the current distribution for attrs.
+//
+// All additional attrs passed are included in the recorded value.
+//
+// This metric defines successful operations using the full success definitions
+// for [http]
+// and [grpc]. Anything else is defined as an unsuccessful operation. For
+// successful
+// operations, `error.type` MUST NOT be set. For unsuccessful export operations,
+// `error.type` MUST contain a relevant failure cause.
+//
+// [http]: https://github.com/open-telemetry/opentelemetry-proto/blob/v1.5.0/docs/specification.md#full-success-1
+// [grpc]: https://github.com/open-telemetry/opentelemetry-proto/blob/v1.5.0/docs/specification.md#full-success
+func (m SDKExporterOperationDuration) Record(
+ ctx context.Context,
+ val float64,
+ attrs ...attribute.KeyValue,
+) {
+ if !m.Float64Histogram.Enabled(ctx) {
+ return
+ }
+ if len(attrs) == 0 {
+ m.Float64Histogram.Record(ctx, val)
+ return
+ }
+
+ o := recOptPool.Get().(*[]metric.RecordOption)
+ defer func() {
+ *o = (*o)[:0]
+ recOptPool.Put(o)
+ }()
+
+ *o = append(
+ *o,
+ metric.WithAttributes(
+ attrs...,
+ ),
+ )
+
+ m.Float64Histogram.Record(ctx, val, *o...)
+}
+
+// RecordSet records val to the current distribution for set.
+//
+// This metric defines successful operations using the full success definitions
+// for [http]
+// and [grpc]. Anything else is defined as an unsuccessful operation. For
+// successful
+// operations, `error.type` MUST NOT be set. For unsuccessful export operations,
+// `error.type` MUST contain a relevant failure cause.
+//
+// [http]: https://github.com/open-telemetry/opentelemetry-proto/blob/v1.5.0/docs/specification.md#full-success-1
+// [grpc]: https://github.com/open-telemetry/opentelemetry-proto/blob/v1.5.0/docs/specification.md#full-success
+func (m SDKExporterOperationDuration) RecordSet(ctx context.Context, val float64, set attribute.Set) {
+ if !m.Float64Histogram.Enabled(ctx) {
+ return
+ }
+ if set.Len() == 0 {
+ m.Float64Histogram.Record(ctx, val)
+ return
+ }
+
+ o := recOptPool.Get().(*[]metric.RecordOption)
+ defer func() {
+ *o = (*o)[:0]
+ recOptPool.Put(o)
+ }()
+
+ *o = append(*o, metric.WithAttributeSet(set))
+ m.Float64Histogram.Record(ctx, val, *o...)
+}
+
+// AttrErrorType returns an optional attribute for the "error.type" semantic
+// convention. It represents the describes a class of error the operation ended
+// with.
+func (SDKExporterOperationDuration) AttrErrorType(val ErrorTypeAttr) attribute.KeyValue {
+ return attribute.String("error.type", string(val))
+}
+
+// AttrHTTPResponseStatusCode returns an optional attribute for the
+// "http.response.status_code" semantic convention. It represents the HTTP status
+// code of the last HTTP request performed in scope of this export call.
+func (SDKExporterOperationDuration) AttrHTTPResponseStatusCode(val int) attribute.KeyValue {
+ return attribute.Int("http.response.status_code", val)
+}
+
+// AttrComponentName returns an optional attribute for the "otel.component.name"
+// semantic convention. It represents a name uniquely identifying the instance of
+// the OpenTelemetry component within its containing SDK instance.
+func (SDKExporterOperationDuration) AttrComponentName(val string) attribute.KeyValue {
+ return attribute.String("otel.component.name", val)
+}
+
+// AttrComponentType returns an optional attribute for the "otel.component.type"
+// semantic convention. It represents a name identifying the type of the
+// OpenTelemetry component.
+func (SDKExporterOperationDuration) AttrComponentType(val ComponentTypeAttr) attribute.KeyValue {
+ return attribute.String("otel.component.type", string(val))
+}
+
+// AttrRPCResponseStatusCode returns an optional attribute for the
+// "rpc.response.status_code" semantic convention. It represents the gRPC status
+// code of the last gRPC request performed in scope of this export call.
+func (SDKExporterOperationDuration) AttrRPCResponseStatusCode(val string) attribute.KeyValue {
+ return attribute.String("rpc.response.status_code", val)
+}
+
+// AttrServerAddress returns an optional attribute for the "server.address"
+// semantic convention. It represents the server domain name if available without
+// reverse DNS lookup; otherwise, IP address or Unix domain socket name.
+func (SDKExporterOperationDuration) AttrServerAddress(val string) attribute.KeyValue {
+ return attribute.String("server.address", val)
+}
+
+// AttrServerPort returns an optional attribute for the "server.port" semantic
+// convention. It represents the server port number.
+func (SDKExporterOperationDuration) AttrServerPort(val int) attribute.KeyValue {
+ return attribute.Int("server.port", val)
+}
+
+// SDKExporterSpanExported is an instrument used to record metric values
+// conforming to the "otel.sdk.exporter.span.exported" semantic conventions. It
+// represents the number of spans for which the export has finished, either
+// successful or failed.
+type SDKExporterSpanExported struct {
+ metric.Int64Counter
+}
+
+var newSDKExporterSpanExportedOpts = []metric.Int64CounterOption{
+ metric.WithDescription("The number of spans for which the export has finished, either successful or failed."),
+ metric.WithUnit("{span}"),
+}
+
+// NewSDKExporterSpanExported returns a new SDKExporterSpanExported instrument.
+func NewSDKExporterSpanExported(
+ m metric.Meter,
+ opt ...metric.Int64CounterOption,
+) (SDKExporterSpanExported, error) {
+ // Check if the meter is nil.
+ if m == nil {
+ return SDKExporterSpanExported{noop.Int64Counter{}}, nil
+ }
+
+ if len(opt) == 0 {
+ opt = newSDKExporterSpanExportedOpts
+ } else {
+ opt = append(opt, newSDKExporterSpanExportedOpts...)
+ }
+
+ i, err := m.Int64Counter(
+ "otel.sdk.exporter.span.exported",
+ opt...,
+ )
+ if err != nil {
+ return SDKExporterSpanExported{noop.Int64Counter{}}, err
+ }
+ return SDKExporterSpanExported{i}, nil
+}
+
+// Inst returns the underlying metric instrument.
+func (m SDKExporterSpanExported) Inst() metric.Int64Counter {
+ return m.Int64Counter
+}
+
+// Name returns the semantic convention name of the instrument.
+func (SDKExporterSpanExported) Name() string {
+ return "otel.sdk.exporter.span.exported"
+}
+
+// Unit returns the semantic convention unit of the instrument
+func (SDKExporterSpanExported) Unit() string {
+ return "{span}"
+}
+
+// Description returns the semantic convention description of the instrument
+func (SDKExporterSpanExported) Description() string {
+ return "The number of spans for which the export has finished, either successful or failed."
+}
+
+// Add adds incr to the existing count for attrs.
+//
+// All additional attrs passed are included in the recorded value.
+//
+// For successful exports, `error.type` MUST NOT be set. For failed exports,
+// `error.type` MUST contain the failure cause.
+// For exporters with partial success semantics (e.g. OTLP with `rejected_spans`
+// ), rejected spans MUST count as failed and only non-rejected spans count as
+// success.
+// If no rejection reason is available, `rejected` SHOULD be used as value for
+// `error.type`.
+func (m SDKExporterSpanExported) Add(
+ ctx context.Context,
+ incr int64,
+ attrs ...attribute.KeyValue,
+) {
+ if !m.Int64Counter.Enabled(ctx) {
+ return
+ }
+ if len(attrs) == 0 {
+ m.Int64Counter.Add(ctx, incr)
+ return
+ }
+
+ o := addOptPool.Get().(*[]metric.AddOption)
+ defer func() {
+ *o = (*o)[:0]
+ addOptPool.Put(o)
+ }()
+
+ *o = append(
+ *o,
+ metric.WithAttributes(
+ attrs...,
+ ),
+ )
+
+ m.Int64Counter.Add(ctx, incr, *o...)
+}
+
+// AddSet adds incr to the existing count for set.
+//
+// For successful exports, `error.type` MUST NOT be set. For failed exports,
+// `error.type` MUST contain the failure cause.
+// For exporters with partial success semantics (e.g. OTLP with `rejected_spans`
+// ), rejected spans MUST count as failed and only non-rejected spans count as
+// success.
+// If no rejection reason is available, `rejected` SHOULD be used as value for
+// `error.type`.
+func (m SDKExporterSpanExported) AddSet(ctx context.Context, incr int64, set attribute.Set) {
+ if !m.Int64Counter.Enabled(ctx) {
+ return
+ }
+ if set.Len() == 0 {
+ m.Int64Counter.Add(ctx, incr)
+ return
+ }
+
+ o := addOptPool.Get().(*[]metric.AddOption)
+ defer func() {
+ *o = (*o)[:0]
+ addOptPool.Put(o)
+ }()
+
+ *o = append(*o, metric.WithAttributeSet(set))
+ m.Int64Counter.Add(ctx, incr, *o...)
+}
+
+// AttrErrorType returns an optional attribute for the "error.type" semantic
+// convention. It represents the describes a class of error the operation ended
+// with.
+func (SDKExporterSpanExported) AttrErrorType(val ErrorTypeAttr) attribute.KeyValue {
+ return attribute.String("error.type", string(val))
+}
+
+// AttrComponentName returns an optional attribute for the "otel.component.name"
+// semantic convention. It represents a name uniquely identifying the instance of
+// the OpenTelemetry component within its containing SDK instance.
+func (SDKExporterSpanExported) AttrComponentName(val string) attribute.KeyValue {
+ return attribute.String("otel.component.name", val)
+}
+
+// AttrComponentType returns an optional attribute for the "otel.component.type"
+// semantic convention. It represents a name identifying the type of the
+// OpenTelemetry component.
+func (SDKExporterSpanExported) AttrComponentType(val ComponentTypeAttr) attribute.KeyValue {
+ return attribute.String("otel.component.type", string(val))
+}
+
+// AttrServerAddress returns an optional attribute for the "server.address"
+// semantic convention. It represents the server domain name if available without
+// reverse DNS lookup; otherwise, IP address or Unix domain socket name.
+func (SDKExporterSpanExported) AttrServerAddress(val string) attribute.KeyValue {
+ return attribute.String("server.address", val)
+}
+
+// AttrServerPort returns an optional attribute for the "server.port" semantic
+// convention. It represents the server port number.
+func (SDKExporterSpanExported) AttrServerPort(val int) attribute.KeyValue {
+ return attribute.Int("server.port", val)
+}
+
+// SDKExporterSpanInflight is an instrument used to record metric values
+// conforming to the "otel.sdk.exporter.span.inflight" semantic conventions. It
+// represents the number of spans which were passed to the exporter, but that
+// have not been exported yet (neither successful, nor failed).
+type SDKExporterSpanInflight struct {
+ metric.Int64UpDownCounter
+}
+
+var newSDKExporterSpanInflightOpts = []metric.Int64UpDownCounterOption{
+ metric.WithDescription("The number of spans which were passed to the exporter, but that have not been exported yet (neither successful, nor failed)."),
+ metric.WithUnit("{span}"),
+}
+
+// NewSDKExporterSpanInflight returns a new SDKExporterSpanInflight instrument.
+func NewSDKExporterSpanInflight(
+ m metric.Meter,
+ opt ...metric.Int64UpDownCounterOption,
+) (SDKExporterSpanInflight, error) {
+ // Check if the meter is nil.
+ if m == nil {
+ return SDKExporterSpanInflight{noop.Int64UpDownCounter{}}, nil
+ }
+
+ if len(opt) == 0 {
+ opt = newSDKExporterSpanInflightOpts
+ } else {
+ opt = append(opt, newSDKExporterSpanInflightOpts...)
+ }
+
+ i, err := m.Int64UpDownCounter(
+ "otel.sdk.exporter.span.inflight",
+ opt...,
+ )
+ if err != nil {
+ return SDKExporterSpanInflight{noop.Int64UpDownCounter{}}, err
+ }
+ return SDKExporterSpanInflight{i}, nil
+}
+
+// Inst returns the underlying metric instrument.
+func (m SDKExporterSpanInflight) Inst() metric.Int64UpDownCounter {
+ return m.Int64UpDownCounter
+}
+
+// Name returns the semantic convention name of the instrument.
+func (SDKExporterSpanInflight) Name() string {
+ return "otel.sdk.exporter.span.inflight"
+}
+
+// Unit returns the semantic convention unit of the instrument
+func (SDKExporterSpanInflight) Unit() string {
+ return "{span}"
+}
+
+// Description returns the semantic convention description of the instrument
+func (SDKExporterSpanInflight) Description() string {
+ return "The number of spans which were passed to the exporter, but that have not been exported yet (neither successful, nor failed)."
+}
+
+// Add adds incr to the existing count for attrs.
+//
+// All additional attrs passed are included in the recorded value.
+//
+// For successful exports, `error.type` MUST NOT be set. For failed exports,
+// `error.type` MUST contain the failure cause.
+func (m SDKExporterSpanInflight) Add(
+ ctx context.Context,
+ incr int64,
+ attrs ...attribute.KeyValue,
+) {
+ if !m.Int64UpDownCounter.Enabled(ctx) {
+ return
+ }
+ if len(attrs) == 0 {
+ m.Int64UpDownCounter.Add(ctx, incr)
+ return
+ }
+
+ o := addOptPool.Get().(*[]metric.AddOption)
+ defer func() {
+ *o = (*o)[:0]
+ addOptPool.Put(o)
+ }()
+
+ *o = append(
+ *o,
+ metric.WithAttributes(
+ attrs...,
+ ),
+ )
+
+ m.Int64UpDownCounter.Add(ctx, incr, *o...)
+}
+
+// AddSet adds incr to the existing count for set.
+//
+// For successful exports, `error.type` MUST NOT be set. For failed exports,
+// `error.type` MUST contain the failure cause.
+func (m SDKExporterSpanInflight) AddSet(ctx context.Context, incr int64, set attribute.Set) {
+ if !m.Int64UpDownCounter.Enabled(ctx) {
+ return
+ }
+ if set.Len() == 0 {
+ m.Int64UpDownCounter.Add(ctx, incr)
+ return
+ }
+
+ o := addOptPool.Get().(*[]metric.AddOption)
+ defer func() {
+ *o = (*o)[:0]
+ addOptPool.Put(o)
+ }()
+
+ *o = append(*o, metric.WithAttributeSet(set))
+ m.Int64UpDownCounter.Add(ctx, incr, *o...)
+}
+
+// AttrComponentName returns an optional attribute for the "otel.component.name"
+// semantic convention. It represents a name uniquely identifying the instance of
+// the OpenTelemetry component within its containing SDK instance.
+func (SDKExporterSpanInflight) AttrComponentName(val string) attribute.KeyValue {
+ return attribute.String("otel.component.name", val)
+}
+
+// AttrComponentType returns an optional attribute for the "otel.component.type"
+// semantic convention. It represents a name identifying the type of the
+// OpenTelemetry component.
+func (SDKExporterSpanInflight) AttrComponentType(val ComponentTypeAttr) attribute.KeyValue {
+ return attribute.String("otel.component.type", string(val))
+}
+
+// AttrServerAddress returns an optional attribute for the "server.address"
+// semantic convention. It represents the server domain name if available without
+// reverse DNS lookup; otherwise, IP address or Unix domain socket name.
+func (SDKExporterSpanInflight) AttrServerAddress(val string) attribute.KeyValue {
+ return attribute.String("server.address", val)
+}
+
+// AttrServerPort returns an optional attribute for the "server.port" semantic
+// convention. It represents the server port number.
+func (SDKExporterSpanInflight) AttrServerPort(val int) attribute.KeyValue {
+ return attribute.Int("server.port", val)
+}
+
+// SDKLogCreated is an instrument used to record metric values conforming to the
+// "otel.sdk.log.created" semantic conventions. It represents the number of logs
+// submitted to enabled SDK Loggers.
+type SDKLogCreated struct {
+ metric.Int64Counter
+}
+
+var newSDKLogCreatedOpts = []metric.Int64CounterOption{
+ metric.WithDescription("The number of logs submitted to enabled SDK Loggers."),
+ metric.WithUnit("{log_record}"),
+}
+
+// NewSDKLogCreated returns a new SDKLogCreated instrument.
+func NewSDKLogCreated(
+ m metric.Meter,
+ opt ...metric.Int64CounterOption,
+) (SDKLogCreated, error) {
+ // Check if the meter is nil.
+ if m == nil {
+ return SDKLogCreated{noop.Int64Counter{}}, nil
+ }
+
+ if len(opt) == 0 {
+ opt = newSDKLogCreatedOpts
+ } else {
+ opt = append(opt, newSDKLogCreatedOpts...)
+ }
+
+ i, err := m.Int64Counter(
+ "otel.sdk.log.created",
+ opt...,
+ )
+ if err != nil {
+ return SDKLogCreated{noop.Int64Counter{}}, err
+ }
+ return SDKLogCreated{i}, nil
+}
+
+// Inst returns the underlying metric instrument.
+func (m SDKLogCreated) Inst() metric.Int64Counter {
+ return m.Int64Counter
+}
+
+// Name returns the semantic convention name of the instrument.
+func (SDKLogCreated) Name() string {
+ return "otel.sdk.log.created"
+}
+
+// Unit returns the semantic convention unit of the instrument
+func (SDKLogCreated) Unit() string {
+ return "{log_record}"
+}
+
+// Description returns the semantic convention description of the instrument
+func (SDKLogCreated) Description() string {
+ return "The number of logs submitted to enabled SDK Loggers."
+}
+
+// Add adds incr to the existing count for attrs.
+func (m SDKLogCreated) Add(ctx context.Context, incr int64, attrs ...attribute.KeyValue) {
+ if !m.Int64Counter.Enabled(ctx) {
+ return
+ }
+ if len(attrs) == 0 {
+ m.Int64Counter.Add(ctx, incr)
+ return
+ }
+
+ o := addOptPool.Get().(*[]metric.AddOption)
+ defer func() {
+ *o = (*o)[:0]
+ addOptPool.Put(o)
+ }()
+
+ *o = append(*o, metric.WithAttributes(attrs...))
+ m.Int64Counter.Add(ctx, incr, *o...)
+}
+
+// AddSet adds incr to the existing count for set.
+func (m SDKLogCreated) AddSet(ctx context.Context, incr int64, set attribute.Set) {
+ if !m.Int64Counter.Enabled(ctx) {
+ return
+ }
+ if set.Len() == 0 {
+ m.Int64Counter.Add(ctx, incr)
+ return
+ }
+
+ o := addOptPool.Get().(*[]metric.AddOption)
+ defer func() {
+ *o = (*o)[:0]
+ addOptPool.Put(o)
+ }()
+
+ *o = append(*o, metric.WithAttributeSet(set))
+ m.Int64Counter.Add(ctx, incr, *o...)
+}
+
+// SDKMetricReaderCollectionDuration is an instrument used to record metric
+// values conforming to the "otel.sdk.metric_reader.collection.duration" semantic
+// conventions. It represents the duration of the collect operation of the metric
+// reader.
+type SDKMetricReaderCollectionDuration struct {
+ metric.Float64Histogram
+}
+
+var newSDKMetricReaderCollectionDurationOpts = []metric.Float64HistogramOption{
+ metric.WithDescription("The duration of the collect operation of the metric reader."),
+ metric.WithUnit("s"),
+}
+
+// NewSDKMetricReaderCollectionDuration returns a new
+// SDKMetricReaderCollectionDuration instrument.
+func NewSDKMetricReaderCollectionDuration(
+ m metric.Meter,
+ opt ...metric.Float64HistogramOption,
+) (SDKMetricReaderCollectionDuration, error) {
+ // Check if the meter is nil.
+ if m == nil {
+ return SDKMetricReaderCollectionDuration{noop.Float64Histogram{}}, nil
+ }
+
+ if len(opt) == 0 {
+ opt = newSDKMetricReaderCollectionDurationOpts
+ } else {
+ opt = append(opt, newSDKMetricReaderCollectionDurationOpts...)
+ }
+
+ i, err := m.Float64Histogram(
+ "otel.sdk.metric_reader.collection.duration",
+ opt...,
+ )
+ if err != nil {
+ return SDKMetricReaderCollectionDuration{noop.Float64Histogram{}}, err
+ }
+ return SDKMetricReaderCollectionDuration{i}, nil
+}
+
+// Inst returns the underlying metric instrument.
+func (m SDKMetricReaderCollectionDuration) Inst() metric.Float64Histogram {
+ return m.Float64Histogram
+}
+
+// Name returns the semantic convention name of the instrument.
+func (SDKMetricReaderCollectionDuration) Name() string {
+ return "otel.sdk.metric_reader.collection.duration"
+}
+
+// Unit returns the semantic convention unit of the instrument
+func (SDKMetricReaderCollectionDuration) Unit() string {
+ return "s"
+}
+
+// Description returns the semantic convention description of the instrument
+func (SDKMetricReaderCollectionDuration) Description() string {
+ return "The duration of the collect operation of the metric reader."
+}
+
+// Record records val to the current distribution for attrs.
+//
+// All additional attrs passed are included in the recorded value.
+//
+// For successful collections, `error.type` MUST NOT be set. For failed
+// collections, `error.type` SHOULD contain the failure cause.
+// It can happen that metrics collection is successful for some MetricProducers,
+// while others fail. In that case `error.type` SHOULD be set to any of the
+// failure causes.
+func (m SDKMetricReaderCollectionDuration) Record(
+ ctx context.Context,
+ val float64,
+ attrs ...attribute.KeyValue,
+) {
+ if !m.Float64Histogram.Enabled(ctx) {
+ return
+ }
+ if len(attrs) == 0 {
+ m.Float64Histogram.Record(ctx, val)
+ return
+ }
+
+ o := recOptPool.Get().(*[]metric.RecordOption)
+ defer func() {
+ *o = (*o)[:0]
+ recOptPool.Put(o)
+ }()
+
+ *o = append(
+ *o,
+ metric.WithAttributes(
+ attrs...,
+ ),
+ )
+
+ m.Float64Histogram.Record(ctx, val, *o...)
+}
+
+// RecordSet records val to the current distribution for set.
+//
+// For successful collections, `error.type` MUST NOT be set. For failed
+// collections, `error.type` SHOULD contain the failure cause.
+// It can happen that metrics collection is successful for some MetricProducers,
+// while others fail. In that case `error.type` SHOULD be set to any of the
+// failure causes.
+func (m SDKMetricReaderCollectionDuration) RecordSet(ctx context.Context, val float64, set attribute.Set) {
+ if !m.Float64Histogram.Enabled(ctx) {
+ return
+ }
+ if set.Len() == 0 {
+ m.Float64Histogram.Record(ctx, val)
+ return
+ }
+
+ o := recOptPool.Get().(*[]metric.RecordOption)
+ defer func() {
+ *o = (*o)[:0]
+ recOptPool.Put(o)
+ }()
+
+ *o = append(*o, metric.WithAttributeSet(set))
+ m.Float64Histogram.Record(ctx, val, *o...)
+}
+
+// AttrErrorType returns an optional attribute for the "error.type" semantic
+// convention. It represents the describes a class of error the operation ended
+// with.
+func (SDKMetricReaderCollectionDuration) AttrErrorType(val ErrorTypeAttr) attribute.KeyValue {
+ return attribute.String("error.type", string(val))
+}
+
+// AttrComponentName returns an optional attribute for the "otel.component.name"
+// semantic convention. It represents a name uniquely identifying the instance of
+// the OpenTelemetry component within its containing SDK instance.
+func (SDKMetricReaderCollectionDuration) AttrComponentName(val string) attribute.KeyValue {
+ return attribute.String("otel.component.name", val)
+}
+
+// AttrComponentType returns an optional attribute for the "otel.component.type"
+// semantic convention. It represents a name identifying the type of the
+// OpenTelemetry component.
+func (SDKMetricReaderCollectionDuration) AttrComponentType(val ComponentTypeAttr) attribute.KeyValue {
+ return attribute.String("otel.component.type", string(val))
+}
+
+// SDKProcessorLogProcessed is an instrument used to record metric values
+// conforming to the "otel.sdk.processor.log.processed" semantic conventions. It
+// represents the number of log records for which the processing has finished,
+// either successful or failed.
+type SDKProcessorLogProcessed struct {
+ metric.Int64Counter
+}
+
+var newSDKProcessorLogProcessedOpts = []metric.Int64CounterOption{
+ metric.WithDescription("The number of log records for which the processing has finished, either successful or failed."),
+ metric.WithUnit("{log_record}"),
+}
+
+// NewSDKProcessorLogProcessed returns a new SDKProcessorLogProcessed instrument.
+func NewSDKProcessorLogProcessed(
+ m metric.Meter,
+ opt ...metric.Int64CounterOption,
+) (SDKProcessorLogProcessed, error) {
+ // Check if the meter is nil.
+ if m == nil {
+ return SDKProcessorLogProcessed{noop.Int64Counter{}}, nil
+ }
+
+ if len(opt) == 0 {
+ opt = newSDKProcessorLogProcessedOpts
+ } else {
+ opt = append(opt, newSDKProcessorLogProcessedOpts...)
+ }
+
+ i, err := m.Int64Counter(
+ "otel.sdk.processor.log.processed",
+ opt...,
+ )
+ if err != nil {
+ return SDKProcessorLogProcessed{noop.Int64Counter{}}, err
+ }
+ return SDKProcessorLogProcessed{i}, nil
+}
+
+// Inst returns the underlying metric instrument.
+func (m SDKProcessorLogProcessed) Inst() metric.Int64Counter {
+ return m.Int64Counter
+}
+
+// Name returns the semantic convention name of the instrument.
+func (SDKProcessorLogProcessed) Name() string {
+ return "otel.sdk.processor.log.processed"
+}
+
+// Unit returns the semantic convention unit of the instrument
+func (SDKProcessorLogProcessed) Unit() string {
+ return "{log_record}"
+}
+
+// Description returns the semantic convention description of the instrument
+func (SDKProcessorLogProcessed) Description() string {
+ return "The number of log records for which the processing has finished, either successful or failed."
+}
+
+// Add adds incr to the existing count for attrs.
+//
+// All additional attrs passed are included in the recorded value.
+//
+// For successful processing, `error.type` MUST NOT be set. For failed
+// processing, `error.type` MUST contain the failure cause.
+// For the SDK Simple and Batching Log Record Processor a log record is
+// considered to be processed already when it has been submitted to the exporter,
+// not when the corresponding export call has finished.
+func (m SDKProcessorLogProcessed) Add(
+ ctx context.Context,
+ incr int64,
+ attrs ...attribute.KeyValue,
+) {
+ if !m.Int64Counter.Enabled(ctx) {
+ return
+ }
+ if len(attrs) == 0 {
+ m.Int64Counter.Add(ctx, incr)
+ return
+ }
+
+ o := addOptPool.Get().(*[]metric.AddOption)
+ defer func() {
+ *o = (*o)[:0]
+ addOptPool.Put(o)
+ }()
+
+ *o = append(
+ *o,
+ metric.WithAttributes(
+ attrs...,
+ ),
+ )
+
+ m.Int64Counter.Add(ctx, incr, *o...)
+}
+
+// AddSet adds incr to the existing count for set.
+//
+// For successful processing, `error.type` MUST NOT be set. For failed
+// processing, `error.type` MUST contain the failure cause.
+// For the SDK Simple and Batching Log Record Processor a log record is
+// considered to be processed already when it has been submitted to the exporter,
+// not when the corresponding export call has finished.
+func (m SDKProcessorLogProcessed) AddSet(ctx context.Context, incr int64, set attribute.Set) {
+ if !m.Int64Counter.Enabled(ctx) {
+ return
+ }
+ if set.Len() == 0 {
+ m.Int64Counter.Add(ctx, incr)
+ return
+ }
+
+ o := addOptPool.Get().(*[]metric.AddOption)
+ defer func() {
+ *o = (*o)[:0]
+ addOptPool.Put(o)
+ }()
+
+ *o = append(*o, metric.WithAttributeSet(set))
+ m.Int64Counter.Add(ctx, incr, *o...)
+}
+
+// AttrErrorType returns an optional attribute for the "error.type" semantic
+// convention. It represents a low-cardinality description of the failure reason.
+// SDK Batching Log Record Processors MUST use `queue_full` for log records
+// dropped due to a full queue.
+func (SDKProcessorLogProcessed) AttrErrorType(val ErrorTypeAttr) attribute.KeyValue {
+ return attribute.String("error.type", string(val))
+}
+
+// AttrComponentName returns an optional attribute for the "otel.component.name"
+// semantic convention. It represents a name uniquely identifying the instance of
+// the OpenTelemetry component within its containing SDK instance.
+func (SDKProcessorLogProcessed) AttrComponentName(val string) attribute.KeyValue {
+ return attribute.String("otel.component.name", val)
+}
+
+// AttrComponentType returns an optional attribute for the "otel.component.type"
+// semantic convention. It represents a name identifying the type of the
+// OpenTelemetry component.
+func (SDKProcessorLogProcessed) AttrComponentType(val ComponentTypeAttr) attribute.KeyValue {
+ return attribute.String("otel.component.type", string(val))
+}
+
+// SDKProcessorLogQueueCapacity is an instrument used to record metric values
+// conforming to the "otel.sdk.processor.log.queue.capacity" semantic
+// conventions. It represents the maximum number of log records the queue of a
+// given instance of an SDK Log Record processor can hold.
+type SDKProcessorLogQueueCapacity struct {
+ metric.Int64ObservableUpDownCounter
+}
+
+var newSDKProcessorLogQueueCapacityOpts = []metric.Int64ObservableUpDownCounterOption{
+ metric.WithDescription("The maximum number of log records the queue of a given instance of an SDK Log Record processor can hold."),
+ metric.WithUnit("{log_record}"),
+}
+
+// NewSDKProcessorLogQueueCapacity returns a new SDKProcessorLogQueueCapacity
+// instrument.
+func NewSDKProcessorLogQueueCapacity(
+ m metric.Meter,
+ opt ...metric.Int64ObservableUpDownCounterOption,
+) (SDKProcessorLogQueueCapacity, error) {
+ // Check if the meter is nil.
+ if m == nil {
+ return SDKProcessorLogQueueCapacity{noop.Int64ObservableUpDownCounter{}}, nil
+ }
+
+ if len(opt) == 0 {
+ opt = newSDKProcessorLogQueueCapacityOpts
+ } else {
+ opt = append(opt, newSDKProcessorLogQueueCapacityOpts...)
+ }
+
+ i, err := m.Int64ObservableUpDownCounter(
+ "otel.sdk.processor.log.queue.capacity",
+ opt...,
+ )
+ if err != nil {
+ return SDKProcessorLogQueueCapacity{noop.Int64ObservableUpDownCounter{}}, err
+ }
+ return SDKProcessorLogQueueCapacity{i}, nil
+}
+
+// Inst returns the underlying metric instrument.
+func (m SDKProcessorLogQueueCapacity) Inst() metric.Int64ObservableUpDownCounter {
+ return m.Int64ObservableUpDownCounter
+}
+
+// Name returns the semantic convention name of the instrument.
+func (SDKProcessorLogQueueCapacity) Name() string {
+ return "otel.sdk.processor.log.queue.capacity"
+}
+
+// Unit returns the semantic convention unit of the instrument
+func (SDKProcessorLogQueueCapacity) Unit() string {
+ return "{log_record}"
+}
+
+// Description returns the semantic convention description of the instrument
+func (SDKProcessorLogQueueCapacity) Description() string {
+ return "The maximum number of log records the queue of a given instance of an SDK Log Record processor can hold."
+}
+
+// AttrComponentName returns an optional attribute for the "otel.component.name"
+// semantic convention. It represents a name uniquely identifying the instance of
+// the OpenTelemetry component within its containing SDK instance.
+func (SDKProcessorLogQueueCapacity) AttrComponentName(val string) attribute.KeyValue {
+ return attribute.String("otel.component.name", val)
+}
+
+// AttrComponentType returns an optional attribute for the "otel.component.type"
+// semantic convention. It represents a name identifying the type of the
+// OpenTelemetry component.
+func (SDKProcessorLogQueueCapacity) AttrComponentType(val ComponentTypeAttr) attribute.KeyValue {
+ return attribute.String("otel.component.type", string(val))
+}
+
+// SDKProcessorLogQueueSize is an instrument used to record metric values
+// conforming to the "otel.sdk.processor.log.queue.size" semantic conventions. It
+// represents the number of log records in the queue of a given instance of an
+// SDK log processor.
+type SDKProcessorLogQueueSize struct {
+ metric.Int64ObservableUpDownCounter
+}
+
+var newSDKProcessorLogQueueSizeOpts = []metric.Int64ObservableUpDownCounterOption{
+ metric.WithDescription("The number of log records in the queue of a given instance of an SDK log processor."),
+ metric.WithUnit("{log_record}"),
+}
+
+// NewSDKProcessorLogQueueSize returns a new SDKProcessorLogQueueSize instrument.
+func NewSDKProcessorLogQueueSize(
+ m metric.Meter,
+ opt ...metric.Int64ObservableUpDownCounterOption,
+) (SDKProcessorLogQueueSize, error) {
+ // Check if the meter is nil.
+ if m == nil {
+ return SDKProcessorLogQueueSize{noop.Int64ObservableUpDownCounter{}}, nil
+ }
+
+ if len(opt) == 0 {
+ opt = newSDKProcessorLogQueueSizeOpts
+ } else {
+ opt = append(opt, newSDKProcessorLogQueueSizeOpts...)
+ }
+
+ i, err := m.Int64ObservableUpDownCounter(
+ "otel.sdk.processor.log.queue.size",
+ opt...,
+ )
+ if err != nil {
+ return SDKProcessorLogQueueSize{noop.Int64ObservableUpDownCounter{}}, err
+ }
+ return SDKProcessorLogQueueSize{i}, nil
+}
+
+// Inst returns the underlying metric instrument.
+func (m SDKProcessorLogQueueSize) Inst() metric.Int64ObservableUpDownCounter {
+ return m.Int64ObservableUpDownCounter
+}
+
+// Name returns the semantic convention name of the instrument.
+func (SDKProcessorLogQueueSize) Name() string {
+ return "otel.sdk.processor.log.queue.size"
+}
+
+// Unit returns the semantic convention unit of the instrument
+func (SDKProcessorLogQueueSize) Unit() string {
+ return "{log_record}"
+}
+
+// Description returns the semantic convention description of the instrument
+func (SDKProcessorLogQueueSize) Description() string {
+ return "The number of log records in the queue of a given instance of an SDK log processor."
+}
+
+// AttrComponentName returns an optional attribute for the "otel.component.name"
+// semantic convention. It represents a name uniquely identifying the instance of
+// the OpenTelemetry component within its containing SDK instance.
+func (SDKProcessorLogQueueSize) AttrComponentName(val string) attribute.KeyValue {
+ return attribute.String("otel.component.name", val)
+}
+
+// AttrComponentType returns an optional attribute for the "otel.component.type"
+// semantic convention. It represents a name identifying the type of the
+// OpenTelemetry component.
+func (SDKProcessorLogQueueSize) AttrComponentType(val ComponentTypeAttr) attribute.KeyValue {
+ return attribute.String("otel.component.type", string(val))
+}
+
+// SDKProcessorSpanProcessed is an instrument used to record metric values
+// conforming to the "otel.sdk.processor.span.processed" semantic conventions. It
+// represents the number of spans for which the processing has finished, either
+// successful or failed.
+type SDKProcessorSpanProcessed struct {
+ metric.Int64Counter
+}
+
+var newSDKProcessorSpanProcessedOpts = []metric.Int64CounterOption{
+ metric.WithDescription("The number of spans for which the processing has finished, either successful or failed."),
+ metric.WithUnit("{span}"),
+}
+
+// NewSDKProcessorSpanProcessed returns a new SDKProcessorSpanProcessed
+// instrument.
+func NewSDKProcessorSpanProcessed(
+ m metric.Meter,
+ opt ...metric.Int64CounterOption,
+) (SDKProcessorSpanProcessed, error) {
+ // Check if the meter is nil.
+ if m == nil {
+ return SDKProcessorSpanProcessed{noop.Int64Counter{}}, nil
+ }
+
+ if len(opt) == 0 {
+ opt = newSDKProcessorSpanProcessedOpts
+ } else {
+ opt = append(opt, newSDKProcessorSpanProcessedOpts...)
+ }
+
+ i, err := m.Int64Counter(
+ "otel.sdk.processor.span.processed",
+ opt...,
+ )
+ if err != nil {
+ return SDKProcessorSpanProcessed{noop.Int64Counter{}}, err
+ }
+ return SDKProcessorSpanProcessed{i}, nil
+}
+
+// Inst returns the underlying metric instrument.
+func (m SDKProcessorSpanProcessed) Inst() metric.Int64Counter {
+ return m.Int64Counter
+}
+
+// Name returns the semantic convention name of the instrument.
+func (SDKProcessorSpanProcessed) Name() string {
+ return "otel.sdk.processor.span.processed"
+}
+
+// Unit returns the semantic convention unit of the instrument
+func (SDKProcessorSpanProcessed) Unit() string {
+ return "{span}"
+}
+
+// Description returns the semantic convention description of the instrument
+func (SDKProcessorSpanProcessed) Description() string {
+ return "The number of spans for which the processing has finished, either successful or failed."
+}
+
+// Add adds incr to the existing count for attrs.
+//
+// All additional attrs passed are included in the recorded value.
+//
+// For successful processing, `error.type` MUST NOT be set. For failed
+// processing, `error.type` MUST contain the failure cause.
+// For the SDK Simple and Batching Span Processor a span is considered to be
+// processed already when it has been submitted to the exporter, not when the
+// corresponding export call has finished.
+func (m SDKProcessorSpanProcessed) Add(
+ ctx context.Context,
+ incr int64,
+ attrs ...attribute.KeyValue,
+) {
+ if !m.Int64Counter.Enabled(ctx) {
+ return
+ }
+ if len(attrs) == 0 {
+ m.Int64Counter.Add(ctx, incr)
+ return
+ }
+
+ o := addOptPool.Get().(*[]metric.AddOption)
+ defer func() {
+ *o = (*o)[:0]
+ addOptPool.Put(o)
+ }()
+
+ *o = append(
+ *o,
+ metric.WithAttributes(
+ attrs...,
+ ),
+ )
+
+ m.Int64Counter.Add(ctx, incr, *o...)
+}
+
+// AddSet adds incr to the existing count for set.
+//
+// For successful processing, `error.type` MUST NOT be set. For failed
+// processing, `error.type` MUST contain the failure cause.
+// For the SDK Simple and Batching Span Processor a span is considered to be
+// processed already when it has been submitted to the exporter, not when the
+// corresponding export call has finished.
+func (m SDKProcessorSpanProcessed) AddSet(ctx context.Context, incr int64, set attribute.Set) {
+ if !m.Int64Counter.Enabled(ctx) {
+ return
+ }
+ if set.Len() == 0 {
+ m.Int64Counter.Add(ctx, incr)
+ return
+ }
+
+ o := addOptPool.Get().(*[]metric.AddOption)
+ defer func() {
+ *o = (*o)[:0]
+ addOptPool.Put(o)
+ }()
+
+ *o = append(*o, metric.WithAttributeSet(set))
+ m.Int64Counter.Add(ctx, incr, *o...)
+}
+
+// AttrErrorType returns an optional attribute for the "error.type" semantic
+// convention. It represents a low-cardinality description of the failure reason.
+// SDK Batching Span Processors MUST use `queue_full` for spans dropped due to a
+// full queue.
+func (SDKProcessorSpanProcessed) AttrErrorType(val ErrorTypeAttr) attribute.KeyValue {
+ return attribute.String("error.type", string(val))
+}
+
+// AttrComponentName returns an optional attribute for the "otel.component.name"
+// semantic convention. It represents a name uniquely identifying the instance of
+// the OpenTelemetry component within its containing SDK instance.
+func (SDKProcessorSpanProcessed) AttrComponentName(val string) attribute.KeyValue {
+ return attribute.String("otel.component.name", val)
+}
+
+// AttrComponentType returns an optional attribute for the "otel.component.type"
+// semantic convention. It represents a name identifying the type of the
+// OpenTelemetry component.
+func (SDKProcessorSpanProcessed) AttrComponentType(val ComponentTypeAttr) attribute.KeyValue {
+ return attribute.String("otel.component.type", string(val))
+}
+
+// SDKProcessorSpanQueueCapacity is an instrument used to record metric values
+// conforming to the "otel.sdk.processor.span.queue.capacity" semantic
+// conventions. It represents the maximum number of spans the queue of a given
+// instance of an SDK span processor can hold.
+type SDKProcessorSpanQueueCapacity struct {
+ metric.Int64ObservableUpDownCounter
+}
+
+var newSDKProcessorSpanQueueCapacityOpts = []metric.Int64ObservableUpDownCounterOption{
+ metric.WithDescription("The maximum number of spans the queue of a given instance of an SDK span processor can hold."),
+ metric.WithUnit("{span}"),
+}
+
+// NewSDKProcessorSpanQueueCapacity returns a new SDKProcessorSpanQueueCapacity
+// instrument.
+func NewSDKProcessorSpanQueueCapacity(
+ m metric.Meter,
+ opt ...metric.Int64ObservableUpDownCounterOption,
+) (SDKProcessorSpanQueueCapacity, error) {
+ // Check if the meter is nil.
+ if m == nil {
+ return SDKProcessorSpanQueueCapacity{noop.Int64ObservableUpDownCounter{}}, nil
+ }
+
+ if len(opt) == 0 {
+ opt = newSDKProcessorSpanQueueCapacityOpts
+ } else {
+ opt = append(opt, newSDKProcessorSpanQueueCapacityOpts...)
+ }
+
+ i, err := m.Int64ObservableUpDownCounter(
+ "otel.sdk.processor.span.queue.capacity",
+ opt...,
+ )
+ if err != nil {
+ return SDKProcessorSpanQueueCapacity{noop.Int64ObservableUpDownCounter{}}, err
+ }
+ return SDKProcessorSpanQueueCapacity{i}, nil
+}
+
+// Inst returns the underlying metric instrument.
+func (m SDKProcessorSpanQueueCapacity) Inst() metric.Int64ObservableUpDownCounter {
+ return m.Int64ObservableUpDownCounter
+}
+
+// Name returns the semantic convention name of the instrument.
+func (SDKProcessorSpanQueueCapacity) Name() string {
+ return "otel.sdk.processor.span.queue.capacity"
+}
+
+// Unit returns the semantic convention unit of the instrument
+func (SDKProcessorSpanQueueCapacity) Unit() string {
+ return "{span}"
+}
+
+// Description returns the semantic convention description of the instrument
+func (SDKProcessorSpanQueueCapacity) Description() string {
+ return "The maximum number of spans the queue of a given instance of an SDK span processor can hold."
+}
+
+// AttrComponentName returns an optional attribute for the "otel.component.name"
+// semantic convention. It represents a name uniquely identifying the instance of
+// the OpenTelemetry component within its containing SDK instance.
+func (SDKProcessorSpanQueueCapacity) AttrComponentName(val string) attribute.KeyValue {
+ return attribute.String("otel.component.name", val)
+}
+
+// AttrComponentType returns an optional attribute for the "otel.component.type"
+// semantic convention. It represents a name identifying the type of the
+// OpenTelemetry component.
+func (SDKProcessorSpanQueueCapacity) AttrComponentType(val ComponentTypeAttr) attribute.KeyValue {
+ return attribute.String("otel.component.type", string(val))
+}
+
+// SDKProcessorSpanQueueSize is an instrument used to record metric values
+// conforming to the "otel.sdk.processor.span.queue.size" semantic conventions.
+// It represents the number of spans in the queue of a given instance of an SDK
+// span processor.
+type SDKProcessorSpanQueueSize struct {
+ metric.Int64ObservableUpDownCounter
+}
+
+var newSDKProcessorSpanQueueSizeOpts = []metric.Int64ObservableUpDownCounterOption{
+ metric.WithDescription("The number of spans in the queue of a given instance of an SDK span processor."),
+ metric.WithUnit("{span}"),
+}
+
+// NewSDKProcessorSpanQueueSize returns a new SDKProcessorSpanQueueSize
+// instrument.
+func NewSDKProcessorSpanQueueSize(
+ m metric.Meter,
+ opt ...metric.Int64ObservableUpDownCounterOption,
+) (SDKProcessorSpanQueueSize, error) {
+ // Check if the meter is nil.
+ if m == nil {
+ return SDKProcessorSpanQueueSize{noop.Int64ObservableUpDownCounter{}}, nil
+ }
+
+ if len(opt) == 0 {
+ opt = newSDKProcessorSpanQueueSizeOpts
+ } else {
+ opt = append(opt, newSDKProcessorSpanQueueSizeOpts...)
+ }
+
+ i, err := m.Int64ObservableUpDownCounter(
+ "otel.sdk.processor.span.queue.size",
+ opt...,
+ )
+ if err != nil {
+ return SDKProcessorSpanQueueSize{noop.Int64ObservableUpDownCounter{}}, err
+ }
+ return SDKProcessorSpanQueueSize{i}, nil
+}
+
+// Inst returns the underlying metric instrument.
+func (m SDKProcessorSpanQueueSize) Inst() metric.Int64ObservableUpDownCounter {
+ return m.Int64ObservableUpDownCounter
+}
+
+// Name returns the semantic convention name of the instrument.
+func (SDKProcessorSpanQueueSize) Name() string {
+ return "otel.sdk.processor.span.queue.size"
+}
+
+// Unit returns the semantic convention unit of the instrument
+func (SDKProcessorSpanQueueSize) Unit() string {
+ return "{span}"
+}
+
+// Description returns the semantic convention description of the instrument
+func (SDKProcessorSpanQueueSize) Description() string {
+ return "The number of spans in the queue of a given instance of an SDK span processor."
+}
+
+// AttrComponentName returns an optional attribute for the "otel.component.name"
+// semantic convention. It represents a name uniquely identifying the instance of
+// the OpenTelemetry component within its containing SDK instance.
+func (SDKProcessorSpanQueueSize) AttrComponentName(val string) attribute.KeyValue {
+ return attribute.String("otel.component.name", val)
+}
+
+// AttrComponentType returns an optional attribute for the "otel.component.type"
+// semantic convention. It represents a name identifying the type of the
+// OpenTelemetry component.
+func (SDKProcessorSpanQueueSize) AttrComponentType(val ComponentTypeAttr) attribute.KeyValue {
+ return attribute.String("otel.component.type", string(val))
+}
+
+// SDKSpanLive is an instrument used to record metric values conforming to the
+// "otel.sdk.span.live" semantic conventions. It represents the number of created
+// spans with `recording=true` for which the end operation has not been called
+// yet.
+type SDKSpanLive struct {
+ metric.Int64UpDownCounter
+}
+
+var newSDKSpanLiveOpts = []metric.Int64UpDownCounterOption{
+ metric.WithDescription("The number of created spans with `recording=true` for which the end operation has not been called yet."),
+ metric.WithUnit("{span}"),
+}
+
+// NewSDKSpanLive returns a new SDKSpanLive instrument.
+func NewSDKSpanLive(
+ m metric.Meter,
+ opt ...metric.Int64UpDownCounterOption,
+) (SDKSpanLive, error) {
+ // Check if the meter is nil.
+ if m == nil {
+ return SDKSpanLive{noop.Int64UpDownCounter{}}, nil
+ }
+
+ if len(opt) == 0 {
+ opt = newSDKSpanLiveOpts
+ } else {
+ opt = append(opt, newSDKSpanLiveOpts...)
+ }
+
+ i, err := m.Int64UpDownCounter(
+ "otel.sdk.span.live",
+ opt...,
+ )
+ if err != nil {
+ return SDKSpanLive{noop.Int64UpDownCounter{}}, err
+ }
+ return SDKSpanLive{i}, nil
+}
+
+// Inst returns the underlying metric instrument.
+func (m SDKSpanLive) Inst() metric.Int64UpDownCounter {
+ return m.Int64UpDownCounter
+}
+
+// Name returns the semantic convention name of the instrument.
+func (SDKSpanLive) Name() string {
+ return "otel.sdk.span.live"
+}
+
+// Unit returns the semantic convention unit of the instrument
+func (SDKSpanLive) Unit() string {
+ return "{span}"
+}
+
+// Description returns the semantic convention description of the instrument
+func (SDKSpanLive) Description() string {
+ return "The number of created spans with `recording=true` for which the end operation has not been called yet."
+}
+
+// Add adds incr to the existing count for attrs.
+//
+// All additional attrs passed are included in the recorded value.
+func (m SDKSpanLive) Add(
+ ctx context.Context,
+ incr int64,
+ attrs ...attribute.KeyValue,
+) {
+ if !m.Int64UpDownCounter.Enabled(ctx) {
+ return
+ }
+ if len(attrs) == 0 {
+ m.Int64UpDownCounter.Add(ctx, incr)
+ return
+ }
+
+ o := addOptPool.Get().(*[]metric.AddOption)
+ defer func() {
+ *o = (*o)[:0]
+ addOptPool.Put(o)
+ }()
+
+ *o = append(
+ *o,
+ metric.WithAttributes(
+ attrs...,
+ ),
+ )
+
+ m.Int64UpDownCounter.Add(ctx, incr, *o...)
+}
+
+// AddSet adds incr to the existing count for set.
+func (m SDKSpanLive) AddSet(ctx context.Context, incr int64, set attribute.Set) {
+ if !m.Int64UpDownCounter.Enabled(ctx) {
+ return
+ }
+ if set.Len() == 0 {
+ m.Int64UpDownCounter.Add(ctx, incr)
+ return
+ }
+
+ o := addOptPool.Get().(*[]metric.AddOption)
+ defer func() {
+ *o = (*o)[:0]
+ addOptPool.Put(o)
+ }()
+
+ *o = append(*o, metric.WithAttributeSet(set))
+ m.Int64UpDownCounter.Add(ctx, incr, *o...)
+}
+
+// AttrSpanSamplingResult returns an optional attribute for the
+// "otel.span.sampling_result" semantic convention. It represents the result
+// value of the sampler for this span.
+func (SDKSpanLive) AttrSpanSamplingResult(val SpanSamplingResultAttr) attribute.KeyValue {
+ return attribute.String("otel.span.sampling_result", string(val))
+}
+
+// SDKSpanStarted is an instrument used to record metric values conforming to the
+// "otel.sdk.span.started" semantic conventions. It represents the number of
+// created spans.
+type SDKSpanStarted struct {
+ metric.Int64Counter
+}
+
+var newSDKSpanStartedOpts = []metric.Int64CounterOption{
+ metric.WithDescription("The number of created spans."),
+ metric.WithUnit("{span}"),
+}
+
+// NewSDKSpanStarted returns a new SDKSpanStarted instrument.
+func NewSDKSpanStarted(
+ m metric.Meter,
+ opt ...metric.Int64CounterOption,
+) (SDKSpanStarted, error) {
+ // Check if the meter is nil.
+ if m == nil {
+ return SDKSpanStarted{noop.Int64Counter{}}, nil
+ }
+
+ if len(opt) == 0 {
+ opt = newSDKSpanStartedOpts
+ } else {
+ opt = append(opt, newSDKSpanStartedOpts...)
+ }
+
+ i, err := m.Int64Counter(
+ "otel.sdk.span.started",
+ opt...,
+ )
+ if err != nil {
+ return SDKSpanStarted{noop.Int64Counter{}}, err
+ }
+ return SDKSpanStarted{i}, nil
+}
+
+// Inst returns the underlying metric instrument.
+func (m SDKSpanStarted) Inst() metric.Int64Counter {
+ return m.Int64Counter
+}
+
+// Name returns the semantic convention name of the instrument.
+func (SDKSpanStarted) Name() string {
+ return "otel.sdk.span.started"
+}
+
+// Unit returns the semantic convention unit of the instrument
+func (SDKSpanStarted) Unit() string {
+ return "{span}"
+}
+
+// Description returns the semantic convention description of the instrument
+func (SDKSpanStarted) Description() string {
+ return "The number of created spans."
+}
+
+// Add adds incr to the existing count for attrs.
+//
+// All additional attrs passed are included in the recorded value.
+//
+// Implementations MUST record this metric for all spans, even for non-recording
+// ones.
+func (m SDKSpanStarted) Add(
+ ctx context.Context,
+ incr int64,
+ attrs ...attribute.KeyValue,
+) {
+ if !m.Int64Counter.Enabled(ctx) {
+ return
+ }
+ if len(attrs) == 0 {
+ m.Int64Counter.Add(ctx, incr)
+ return
+ }
+
+ o := addOptPool.Get().(*[]metric.AddOption)
+ defer func() {
+ *o = (*o)[:0]
+ addOptPool.Put(o)
+ }()
+
+ *o = append(
+ *o,
+ metric.WithAttributes(
+ attrs...,
+ ),
+ )
+
+ m.Int64Counter.Add(ctx, incr, *o...)
+}
+
+// AddSet adds incr to the existing count for set.
+//
+// Implementations MUST record this metric for all spans, even for non-recording
+// ones.
+func (m SDKSpanStarted) AddSet(ctx context.Context, incr int64, set attribute.Set) {
+ if !m.Int64Counter.Enabled(ctx) {
+ return
+ }
+ if set.Len() == 0 {
+ m.Int64Counter.Add(ctx, incr)
+ return
+ }
+
+ o := addOptPool.Get().(*[]metric.AddOption)
+ defer func() {
+ *o = (*o)[:0]
+ addOptPool.Put(o)
+ }()
+
+ *o = append(*o, metric.WithAttributeSet(set))
+ m.Int64Counter.Add(ctx, incr, *o...)
+}
+
+// AttrSpanParentOrigin returns an optional attribute for the
+// "otel.span.parent.origin" semantic convention. It represents the determines
+// whether the span has a parent span, and if so, [whether it is a remote parent]
+// .
+//
+// [whether it is a remote parent]: https://opentelemetry.io/docs/specs/otel/trace/api/#isremote
+func (SDKSpanStarted) AttrSpanParentOrigin(val SpanParentOriginAttr) attribute.KeyValue {
+ return attribute.String("otel.span.parent.origin", string(val))
+}
+
+// AttrSpanSamplingResult returns an optional attribute for the
+// "otel.span.sampling_result" semantic convention. It represents the result
+// value of the sampler for this span.
+func (SDKSpanStarted) AttrSpanSamplingResult(val SpanSamplingResultAttr) attribute.KeyValue {
+ return attribute.String("otel.span.sampling_result", string(val))
+}
diff --git a/vendor/go.opentelemetry.io/otel/semconv/v1.40.0/schema.go b/vendor/go.opentelemetry.io/otel/semconv/v1.40.0/schema.go
new file mode 100644
index 000000000..a07ffa336
--- /dev/null
+++ b/vendor/go.opentelemetry.io/otel/semconv/v1.40.0/schema.go
@@ -0,0 +1,9 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+package semconv // import "go.opentelemetry.io/otel/semconv/v1.40.0"
+
+// SchemaURL is the schema URL that matches the version of the semantic conventions
+// that this package defines. Semconv packages starting from v1.4.0 must declare
+// non-empty schema URL in the form https://opentelemetry.io/schemas/
+const SchemaURL = "https://opentelemetry.io/schemas/1.40.0"
diff --git a/vendor/go.opentelemetry.io/otel/semconv/v1.41.0/MIGRATION.md b/vendor/go.opentelemetry.io/otel/semconv/v1.41.0/MIGRATION.md
new file mode 100644
index 000000000..ba52cadf7
--- /dev/null
+++ b/vendor/go.opentelemetry.io/otel/semconv/v1.41.0/MIGRATION.md
@@ -0,0 +1,17 @@
+
+# Migration from v1.40.0 to v1.41.0
+
+The `go.opentelemetry.io/otel/semconv/v1.41.0` package should be a drop-in replacement for `go.opentelemetry.io/otel/semconv/v1.40.0` with the following exceptions.
+
+## Removed
+
+The following declarations have been removed.
+Refer to the [OpenTelemetry Semantic Conventions documentation] for deprecation instructions.
+
+If the type is not listed in the documentation as deprecated, it has been removed in this version due to lack of applicability or use.
+If you use any of these non-deprecated declarations in your Go application, please [open an issue] describing your use-case.
+
+- `DeploymentEnvironmentName`
+
+[OpenTelemetry Semantic Conventions documentation]: https://github.com/open-telemetry/semantic-conventions
+[open an issue]: https://github.com/open-telemetry/opentelemetry-go/issues/new?template=Blank+issue
diff --git a/vendor/go.opentelemetry.io/otel/semconv/v1.41.0/README.md b/vendor/go.opentelemetry.io/otel/semconv/v1.41.0/README.md
new file mode 100644
index 000000000..8353bb715
--- /dev/null
+++ b/vendor/go.opentelemetry.io/otel/semconv/v1.41.0/README.md
@@ -0,0 +1,3 @@
+# Semconv v1.41.0
+
+[](https://pkg.go.dev/go.opentelemetry.io/otel/semconv/v1.41.0)
diff --git a/vendor/go.opentelemetry.io/otel/semconv/v1.41.0/attribute_group.go b/vendor/go.opentelemetry.io/otel/semconv/v1.41.0/attribute_group.go
new file mode 100644
index 000000000..7cee08680
--- /dev/null
+++ b/vendor/go.opentelemetry.io/otel/semconv/v1.41.0/attribute_group.go
@@ -0,0 +1,17285 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+// Code generated from semantic convention specification. DO NOT EDIT.
+
+package semconv // import "go.opentelemetry.io/otel/semconv/v1.41.0"
+
+import "go.opentelemetry.io/otel/attribute"
+
+// Namespace: android
+const (
+ // AndroidAppStateKey is the attribute Key conforming to the "android.app.state"
+ // semantic conventions. It represents the this attribute represents the state
+ // of the application.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "created"
+ // Note: The Android lifecycle states are defined in
+ // [Activity lifecycle callbacks], and from which the `OS identifiers` are
+ // derived.
+ //
+ // [Activity lifecycle callbacks]: https://developer.android.com/guide/components/activities/activity-lifecycle#lc
+ AndroidAppStateKey = attribute.Key("android.app.state")
+
+ // AndroidOSAPILevelKey is the attribute Key conforming to the
+ // "android.os.api_level" semantic conventions. It represents the uniquely
+ // identifies the framework API revision offered by a version (`os.version`) of
+ // the android operating system. More information can be found in the
+ // [Android API levels documentation].
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "33", "32"
+ //
+ // [Android API levels documentation]: https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels
+ AndroidOSAPILevelKey = attribute.Key("android.os.api_level")
+)
+
+// AndroidOSAPILevel returns an attribute KeyValue conforming to the
+// "android.os.api_level" semantic conventions. It represents the uniquely
+// identifies the framework API revision offered by a version (`os.version`) of
+// the android operating system. More information can be found in the
+// [Android API levels documentation].
+//
+// [Android API levels documentation]: https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels
+func AndroidOSAPILevel(val string) attribute.KeyValue {
+ return AndroidOSAPILevelKey.String(val)
+}
+
+// Enum values for android.app.state
+var (
+ // Any time before Activity.onResume() or, if the app has no Activity,
+ // Context.startService() has been called in the app for the first time.
+ //
+ // Stability: development
+ AndroidAppStateCreated = AndroidAppStateKey.String("created")
+ // Any time after Activity.onPause() or, if the app has no Activity,
+ // Context.stopService() has been called when the app was in the foreground
+ // state.
+ //
+ // Stability: development
+ AndroidAppStateBackground = AndroidAppStateKey.String("background")
+ // Any time after Activity.onResume() or, if the app has no Activity,
+ // Context.startService() has been called when the app was in either the created
+ // or background states.
+ //
+ // Stability: development
+ AndroidAppStateForeground = AndroidAppStateKey.String("foreground")
+)
+
+// Namespace: app
+const (
+ // AppBuildIDKey is the attribute Key conforming to the "app.build_id" semantic
+ // conventions. It represents the unique identifier for a particular build or
+ // compilation of the application.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "6cff0a7e-cefc-4668-96f5-1273d8b334d0",
+ // "9f2b833506aa6973a92fde9733e6271f", "my-app-1.0.0-code-123"
+ AppBuildIDKey = attribute.Key("app.build_id")
+
+ // AppInstallationIDKey is the attribute Key conforming to the
+ // "app.installation.id" semantic conventions. It represents a unique identifier
+ // representing the installation of an application on a specific device.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "2ab2916d-a51f-4ac8-80ee-45ac31a28092"
+ // Note: Its value SHOULD persist across launches of the same application
+ // installation, including through application upgrades.
+ // It SHOULD change if the application is uninstalled or if all applications of
+ // the vendor are uninstalled.
+ // Additionally, users might be able to reset this value (e.g. by clearing
+ // application data).
+ // If an app is installed multiple times on the same device (e.g. in different
+ // accounts on Android), each `app.installation.id` SHOULD have a different
+ // value.
+ // If multiple OpenTelemetry SDKs are used within the same application, they
+ // SHOULD use the same value for `app.installation.id`.
+ // Hardware IDs (e.g. serial number, IMEI, MAC address) MUST NOT be used as the
+ // `app.installation.id`.
+ //
+ // For iOS, this value SHOULD be equal to the [vendor identifier].
+ //
+ // For Android, examples of `app.installation.id` implementations include:
+ //
+ // - [Firebase Installation ID].
+ // - A globally unique UUID which is persisted across sessions in your
+ // application.
+ // - [App set ID].
+ // - [`Settings.getString(Settings.Secure.ANDROID_ID)`].
+ //
+ // More information about Android identifier best practices can be found in the
+ // [Android user data IDs guide].
+ //
+ // [vendor identifier]: https://developer.apple.com/documentation/uikit/uidevice/identifierforvendor
+ // [Firebase Installation ID]: https://firebase.google.com/docs/projects/manage-installations
+ // [App set ID]: https://developer.android.com/identity/app-set-id
+ // [`Settings.getString(Settings.Secure.ANDROID_ID)`]: https://developer.android.com/reference/android/provider/Settings.Secure#ANDROID_ID
+ // [Android user data IDs guide]: https://developer.android.com/training/articles/user-data-ids
+ AppInstallationIDKey = attribute.Key("app.installation.id")
+
+ // AppJankFrameCountKey is the attribute Key conforming to the
+ // "app.jank.frame_count" semantic conventions. It represents a number of frame
+ // renders that experienced jank.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 9, 42
+ // Note: Depending on platform limitations, the value provided MAY be
+ // approximation.
+ AppJankFrameCountKey = attribute.Key("app.jank.frame_count")
+
+ // AppJankPeriodKey is the attribute Key conforming to the "app.jank.period"
+ // semantic conventions. It represents the time period, in seconds, for which
+ // this jank is being reported.
+ //
+ // Type: double
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 1.0, 5.0, 10.24
+ AppJankPeriodKey = attribute.Key("app.jank.period")
+
+ // AppJankThresholdKey is the attribute Key conforming to the
+ // "app.jank.threshold" semantic conventions. It represents the minimum
+ // rendering threshold for this jank, in seconds.
+ //
+ // Type: double
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 0.016, 0.7, 1.024
+ AppJankThresholdKey = attribute.Key("app.jank.threshold")
+
+ // AppScreenCoordinateXKey is the attribute Key conforming to the
+ // "app.screen.coordinate.x" semantic conventions. It represents the x
+ // (horizontal) coordinate of a screen coordinate, in screen pixels.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 0, 131
+ AppScreenCoordinateXKey = attribute.Key("app.screen.coordinate.x")
+
+ // AppScreenCoordinateYKey is the attribute Key conforming to the
+ // "app.screen.coordinate.y" semantic conventions. It represents the y
+ // (vertical) component of a screen coordinate, in screen pixels.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 12, 99
+ AppScreenCoordinateYKey = attribute.Key("app.screen.coordinate.y")
+
+ // AppScreenIDKey is the attribute Key conforming to the "app.screen.id"
+ // semantic conventions. It represents an identifier that uniquely
+ // differentiates this screen from other screens in the same application.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "f9bc787d-ff05-48ad-90e1-fca1d46130b3",
+ // "com.example.app.MainActivity", "com.example.shop.ProductDetailFragment",
+ // "MyApp.ProfileView", "MyApp.ProfileViewController"
+ // Note: A screen represents only the part of the device display drawn by the
+ // app. It typically contains multiple widgets or UI components and is larger in
+ // scope than individual widgets. Multiple screens can coexist on the same
+ // display simultaneously (e.g., split view on tablets).
+ AppScreenIDKey = attribute.Key("app.screen.id")
+
+ // AppScreenNameKey is the attribute Key conforming to the "app.screen.name"
+ // semantic conventions. It represents the name of an application screen.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "MainActivity", "ProductDetailFragment", "ProfileView",
+ // "ProfileViewController"
+ // Note: A screen represents only the part of the device display drawn by the
+ // app. It typically contains multiple widgets or UI components and is larger in
+ // scope than individual widgets. Multiple screens can coexist on the same
+ // display simultaneously (e.g., split view on tablets).
+ AppScreenNameKey = attribute.Key("app.screen.name")
+
+ // AppWidgetIDKey is the attribute Key conforming to the "app.widget.id"
+ // semantic conventions. It represents an identifier that uniquely
+ // differentiates this widget from other widgets in the same application.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "f9bc787d-ff05-48ad-90e1-fca1d46130b3", "submit_order_1829"
+ // Note: A widget is an application component, typically an on-screen visual GUI
+ // element.
+ AppWidgetIDKey = attribute.Key("app.widget.id")
+
+ // AppWidgetNameKey is the attribute Key conforming to the "app.widget.name"
+ // semantic conventions. It represents the name of an application widget.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "submit", "attack", "Clear Cart"
+ // Note: A widget is an application component, typically an on-screen visual GUI
+ // element.
+ AppWidgetNameKey = attribute.Key("app.widget.name")
+)
+
+// AppBuildID returns an attribute KeyValue conforming to the "app.build_id"
+// semantic conventions. It represents the unique identifier for a particular
+// build or compilation of the application.
+func AppBuildID(val string) attribute.KeyValue {
+ return AppBuildIDKey.String(val)
+}
+
+// AppInstallationID returns an attribute KeyValue conforming to the
+// "app.installation.id" semantic conventions. It represents a unique identifier
+// representing the installation of an application on a specific device.
+func AppInstallationID(val string) attribute.KeyValue {
+ return AppInstallationIDKey.String(val)
+}
+
+// AppJankFrameCount returns an attribute KeyValue conforming to the
+// "app.jank.frame_count" semantic conventions. It represents a number of frame
+// renders that experienced jank.
+func AppJankFrameCount(val int) attribute.KeyValue {
+ return AppJankFrameCountKey.Int(val)
+}
+
+// AppJankPeriod returns an attribute KeyValue conforming to the
+// "app.jank.period" semantic conventions. It represents the time period, in
+// seconds, for which this jank is being reported.
+func AppJankPeriod(val float64) attribute.KeyValue {
+ return AppJankPeriodKey.Float64(val)
+}
+
+// AppJankThreshold returns an attribute KeyValue conforming to the
+// "app.jank.threshold" semantic conventions. It represents the minimum rendering
+// threshold for this jank, in seconds.
+func AppJankThreshold(val float64) attribute.KeyValue {
+ return AppJankThresholdKey.Float64(val)
+}
+
+// AppScreenCoordinateX returns an attribute KeyValue conforming to the
+// "app.screen.coordinate.x" semantic conventions. It represents the x
+// (horizontal) coordinate of a screen coordinate, in screen pixels.
+func AppScreenCoordinateX(val int) attribute.KeyValue {
+ return AppScreenCoordinateXKey.Int(val)
+}
+
+// AppScreenCoordinateY returns an attribute KeyValue conforming to the
+// "app.screen.coordinate.y" semantic conventions. It represents the y (vertical)
+// component of a screen coordinate, in screen pixels.
+func AppScreenCoordinateY(val int) attribute.KeyValue {
+ return AppScreenCoordinateYKey.Int(val)
+}
+
+// AppScreenID returns an attribute KeyValue conforming to the "app.screen.id"
+// semantic conventions. It represents an identifier that uniquely differentiates
+// this screen from other screens in the same application.
+func AppScreenID(val string) attribute.KeyValue {
+ return AppScreenIDKey.String(val)
+}
+
+// AppScreenName returns an attribute KeyValue conforming to the
+// "app.screen.name" semantic conventions. It represents the name of an
+// application screen.
+func AppScreenName(val string) attribute.KeyValue {
+ return AppScreenNameKey.String(val)
+}
+
+// AppWidgetID returns an attribute KeyValue conforming to the "app.widget.id"
+// semantic conventions. It represents an identifier that uniquely differentiates
+// this widget from other widgets in the same application.
+func AppWidgetID(val string) attribute.KeyValue {
+ return AppWidgetIDKey.String(val)
+}
+
+// AppWidgetName returns an attribute KeyValue conforming to the
+// "app.widget.name" semantic conventions. It represents the name of an
+// application widget.
+func AppWidgetName(val string) attribute.KeyValue {
+ return AppWidgetNameKey.String(val)
+}
+
+// Namespace: artifact
+const (
+ // ArtifactAttestationFilenameKey is the attribute Key conforming to the
+ // "artifact.attestation.filename" semantic conventions. It represents the
+ // provenance filename of the built attestation which directly relates to the
+ // build artifact filename. This filename SHOULD accompany the artifact at
+ // publish time. See the [SLSA Relationship] specification for more information.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "golang-binary-amd64-v0.1.0.attestation",
+ // "docker-image-amd64-v0.1.0.intoto.json1", "release-1.tar.gz.attestation",
+ // "file-name-package.tar.gz.intoto.json1"
+ //
+ // [SLSA Relationship]: https://slsa.dev/spec/v1.0/distributing-provenance#relationship-between-artifacts-and-attestations
+ ArtifactAttestationFilenameKey = attribute.Key("artifact.attestation.filename")
+
+ // ArtifactAttestationHashKey is the attribute Key conforming to the
+ // "artifact.attestation.hash" semantic conventions. It represents the full
+ // [hash value (see glossary)], of the built attestation. Some envelopes in the
+ // [software attestation space] also refer to this as the **digest**.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "1b31dfcd5b7f9267bf2ff47651df1cfb9147b9e4df1f335accf65b4cda498408"
+ //
+ // [hash value (see glossary)]: https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-5.pdf
+ // [software attestation space]: https://github.com/in-toto/attestation/tree/main/spec
+ ArtifactAttestationHashKey = attribute.Key("artifact.attestation.hash")
+
+ // ArtifactAttestationIDKey is the attribute Key conforming to the
+ // "artifact.attestation.id" semantic conventions. It represents the id of the
+ // build [software attestation].
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "123"
+ //
+ // [software attestation]: https://slsa.dev/attestation-model
+ ArtifactAttestationIDKey = attribute.Key("artifact.attestation.id")
+
+ // ArtifactFilenameKey is the attribute Key conforming to the
+ // "artifact.filename" semantic conventions. It represents the human readable
+ // file name of the artifact, typically generated during build and release
+ // processes. Often includes the package name and version in the file name.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "golang-binary-amd64-v0.1.0", "docker-image-amd64-v0.1.0",
+ // "release-1.tar.gz", "file-name-package.tar.gz"
+ // Note: This file name can also act as the [Package Name]
+ // in cases where the package ecosystem maps accordingly.
+ // Additionally, the artifact [can be published]
+ // for others, but that is not a guarantee.
+ //
+ // [Package Name]: https://slsa.dev/spec/v1.0/terminology#package-model
+ // [can be published]: https://slsa.dev/spec/v1.0/terminology#software-supply-chain
+ ArtifactFilenameKey = attribute.Key("artifact.filename")
+
+ // ArtifactHashKey is the attribute Key conforming to the "artifact.hash"
+ // semantic conventions. It represents the full [hash value (see glossary)],
+ // often found in checksum.txt on a release of the artifact and used to verify
+ // package integrity.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "9ff4c52759e2c4ac70b7d517bc7fcdc1cda631ca0045271ddd1b192544f8a3e9"
+ // Note: The specific algorithm used to create the cryptographic hash value is
+ // not defined. In situations where an artifact has multiple
+ // cryptographic hashes, it is up to the implementer to choose which
+ // hash value to set here; this should be the most secure hash algorithm
+ // that is suitable for the situation and consistent with the
+ // corresponding attestation. The implementer can then provide the other
+ // hash values through an additional set of attribute extensions as they
+ // deem necessary.
+ //
+ // [hash value (see glossary)]: https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-5.pdf
+ ArtifactHashKey = attribute.Key("artifact.hash")
+
+ // ArtifactPurlKey is the attribute Key conforming to the "artifact.purl"
+ // semantic conventions. It represents the [Package URL] of the
+ // [package artifact] provides a standard way to identify and locate the
+ // packaged artifact.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "pkg:github/package-url/purl-spec@1209109710924",
+ // "pkg:npm/foo@12.12.3"
+ //
+ // [Package URL]: https://github.com/package-url/purl-spec
+ // [package artifact]: https://slsa.dev/spec/v1.0/terminology#package-model
+ ArtifactPurlKey = attribute.Key("artifact.purl")
+
+ // ArtifactVersionKey is the attribute Key conforming to the "artifact.version"
+ // semantic conventions. It represents the version of the artifact.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "v0.1.0", "1.2.1", "122691-build"
+ ArtifactVersionKey = attribute.Key("artifact.version")
+)
+
+// ArtifactAttestationFilename returns an attribute KeyValue conforming to the
+// "artifact.attestation.filename" semantic conventions. It represents the
+// provenance filename of the built attestation which directly relates to the
+// build artifact filename. This filename SHOULD accompany the artifact at
+// publish time. See the [SLSA Relationship] specification for more information.
+//
+// [SLSA Relationship]: https://slsa.dev/spec/v1.0/distributing-provenance#relationship-between-artifacts-and-attestations
+func ArtifactAttestationFilename(val string) attribute.KeyValue {
+ return ArtifactAttestationFilenameKey.String(val)
+}
+
+// ArtifactAttestationHash returns an attribute KeyValue conforming to the
+// "artifact.attestation.hash" semantic conventions. It represents the full
+// [hash value (see glossary)], of the built attestation. Some envelopes in the
+// [software attestation space] also refer to this as the **digest**.
+//
+// [hash value (see glossary)]: https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-5.pdf
+// [software attestation space]: https://github.com/in-toto/attestation/tree/main/spec
+func ArtifactAttestationHash(val string) attribute.KeyValue {
+ return ArtifactAttestationHashKey.String(val)
+}
+
+// ArtifactAttestationID returns an attribute KeyValue conforming to the
+// "artifact.attestation.id" semantic conventions. It represents the id of the
+// build [software attestation].
+//
+// [software attestation]: https://slsa.dev/attestation-model
+func ArtifactAttestationID(val string) attribute.KeyValue {
+ return ArtifactAttestationIDKey.String(val)
+}
+
+// ArtifactFilename returns an attribute KeyValue conforming to the
+// "artifact.filename" semantic conventions. It represents the human readable
+// file name of the artifact, typically generated during build and release
+// processes. Often includes the package name and version in the file name.
+func ArtifactFilename(val string) attribute.KeyValue {
+ return ArtifactFilenameKey.String(val)
+}
+
+// ArtifactHash returns an attribute KeyValue conforming to the "artifact.hash"
+// semantic conventions. It represents the full [hash value (see glossary)],
+// often found in checksum.txt on a release of the artifact and used to verify
+// package integrity.
+//
+// [hash value (see glossary)]: https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-5.pdf
+func ArtifactHash(val string) attribute.KeyValue {
+ return ArtifactHashKey.String(val)
+}
+
+// ArtifactPurl returns an attribute KeyValue conforming to the "artifact.purl"
+// semantic conventions. It represents the [Package URL] of the
+// [package artifact] provides a standard way to identify and locate the packaged
+// artifact.
+//
+// [Package URL]: https://github.com/package-url/purl-spec
+// [package artifact]: https://slsa.dev/spec/v1.0/terminology#package-model
+func ArtifactPurl(val string) attribute.KeyValue {
+ return ArtifactPurlKey.String(val)
+}
+
+// ArtifactVersion returns an attribute KeyValue conforming to the
+// "artifact.version" semantic conventions. It represents the version of the
+// artifact.
+func ArtifactVersion(val string) attribute.KeyValue {
+ return ArtifactVersionKey.String(val)
+}
+
+// Namespace: aws
+const (
+ // AWSBedrockGuardrailIDKey is the attribute Key conforming to the
+ // "aws.bedrock.guardrail.id" semantic conventions. It represents the unique
+ // identifier of the AWS Bedrock Guardrail. A [guardrail] helps safeguard and
+ // prevent unwanted behavior from model responses or user messages.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "sgi5gkybzqak"
+ //
+ // [guardrail]: https://docs.aws.amazon.com/bedrock/latest/userguide/guardrails.html
+ AWSBedrockGuardrailIDKey = attribute.Key("aws.bedrock.guardrail.id")
+
+ // AWSBedrockKnowledgeBaseIDKey is the attribute Key conforming to the
+ // "aws.bedrock.knowledge_base.id" semantic conventions. It represents the
+ // unique identifier of the AWS Bedrock Knowledge base. A [knowledge base] is a
+ // bank of information that can be queried by models to generate more relevant
+ // responses and augment prompts.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "XFWUPB9PAW"
+ //
+ // [knowledge base]: https://docs.aws.amazon.com/bedrock/latest/userguide/knowledge-base.html
+ AWSBedrockKnowledgeBaseIDKey = attribute.Key("aws.bedrock.knowledge_base.id")
+
+ // AWSDynamoDBAttributeDefinitionsKey is the attribute Key conforming to the
+ // "aws.dynamodb.attribute_definitions" semantic conventions. It represents the
+ // JSON-serialized value of each item in the `AttributeDefinitions` request
+ // field.
+ //
+ // Type: string[]
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "{ "AttributeName": "string", "AttributeType": "string" }"
+ AWSDynamoDBAttributeDefinitionsKey = attribute.Key("aws.dynamodb.attribute_definitions")
+
+ // AWSDynamoDBAttributesToGetKey is the attribute Key conforming to the
+ // "aws.dynamodb.attributes_to_get" semantic conventions. It represents the
+ // value of the `AttributesToGet` request parameter.
+ //
+ // Type: string[]
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "lives", "id"
+ AWSDynamoDBAttributesToGetKey = attribute.Key("aws.dynamodb.attributes_to_get")
+
+ // AWSDynamoDBConsistentReadKey is the attribute Key conforming to the
+ // "aws.dynamodb.consistent_read" semantic conventions. It represents the value
+ // of the `ConsistentRead` request parameter.
+ //
+ // Type: boolean
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ AWSDynamoDBConsistentReadKey = attribute.Key("aws.dynamodb.consistent_read")
+
+ // AWSDynamoDBConsumedCapacityKey is the attribute Key conforming to the
+ // "aws.dynamodb.consumed_capacity" semantic conventions. It represents the
+ // JSON-serialized value of each item in the `ConsumedCapacity` response field.
+ //
+ // Type: string[]
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "{ "CapacityUnits": number, "GlobalSecondaryIndexes": { "string" :
+ // { "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits":
+ // number } }, "LocalSecondaryIndexes": { "string" : { "CapacityUnits": number,
+ // "ReadCapacityUnits": number, "WriteCapacityUnits": number } },
+ // "ReadCapacityUnits": number, "Table": { "CapacityUnits": number,
+ // "ReadCapacityUnits": number, "WriteCapacityUnits": number }, "TableName":
+ // "string", "WriteCapacityUnits": number }"
+ AWSDynamoDBConsumedCapacityKey = attribute.Key("aws.dynamodb.consumed_capacity")
+
+ // AWSDynamoDBCountKey is the attribute Key conforming to the
+ // "aws.dynamodb.count" semantic conventions. It represents the value of the
+ // `Count` response parameter.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 10
+ AWSDynamoDBCountKey = attribute.Key("aws.dynamodb.count")
+
+ // AWSDynamoDBExclusiveStartTableKey is the attribute Key conforming to the
+ // "aws.dynamodb.exclusive_start_table" semantic conventions. It represents the
+ // value of the `ExclusiveStartTableName` request parameter.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "Users", "CatsTable"
+ AWSDynamoDBExclusiveStartTableKey = attribute.Key("aws.dynamodb.exclusive_start_table")
+
+ // AWSDynamoDBGlobalSecondaryIndexUpdatesKey is the attribute Key conforming to
+ // the "aws.dynamodb.global_secondary_index_updates" semantic conventions. It
+ // represents the JSON-serialized value of each item in the
+ // `GlobalSecondaryIndexUpdates` request field.
+ //
+ // Type: string[]
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "{ "Create": { "IndexName": "string", "KeySchema": [ {
+ // "AttributeName": "string", "KeyType": "string" } ], "Projection": {
+ // "NonKeyAttributes": [ "string" ], "ProjectionType": "string" },
+ // "ProvisionedThroughput": { "ReadCapacityUnits": number, "WriteCapacityUnits":
+ // number } }"
+ AWSDynamoDBGlobalSecondaryIndexUpdatesKey = attribute.Key("aws.dynamodb.global_secondary_index_updates")
+
+ // AWSDynamoDBGlobalSecondaryIndexesKey is the attribute Key conforming to the
+ // "aws.dynamodb.global_secondary_indexes" semantic conventions. It represents
+ // the JSON-serialized value of each item of the `GlobalSecondaryIndexes`
+ // request field.
+ //
+ // Type: string[]
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "{ "IndexName": "string", "KeySchema": [ { "AttributeName":
+ // "string", "KeyType": "string" } ], "Projection": { "NonKeyAttributes": [
+ // "string" ], "ProjectionType": "string" }, "ProvisionedThroughput": {
+ // "ReadCapacityUnits": number, "WriteCapacityUnits": number } }"
+ AWSDynamoDBGlobalSecondaryIndexesKey = attribute.Key("aws.dynamodb.global_secondary_indexes")
+
+ // AWSDynamoDBIndexNameKey is the attribute Key conforming to the
+ // "aws.dynamodb.index_name" semantic conventions. It represents the value of
+ // the `IndexName` request parameter.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "name_to_group"
+ AWSDynamoDBIndexNameKey = attribute.Key("aws.dynamodb.index_name")
+
+ // AWSDynamoDBItemCollectionMetricsKey is the attribute Key conforming to the
+ // "aws.dynamodb.item_collection_metrics" semantic conventions. It represents
+ // the JSON-serialized value of the `ItemCollectionMetrics` response field.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "{ "string" : [ { "ItemCollectionKey": { "string" : { "B": blob,
+ // "BOOL": boolean, "BS": [ blob ], "L": [ "AttributeValue" ], "M": { "string" :
+ // "AttributeValue" }, "N": "string", "NS": [ "string" ], "NULL": boolean, "S":
+ // "string", "SS": [ "string" ] } }, "SizeEstimateRangeGB": [ number ] } ] }"
+ AWSDynamoDBItemCollectionMetricsKey = attribute.Key("aws.dynamodb.item_collection_metrics")
+
+ // AWSDynamoDBLimitKey is the attribute Key conforming to the
+ // "aws.dynamodb.limit" semantic conventions. It represents the value of the
+ // `Limit` request parameter.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 10
+ AWSDynamoDBLimitKey = attribute.Key("aws.dynamodb.limit")
+
+ // AWSDynamoDBLocalSecondaryIndexesKey is the attribute Key conforming to the
+ // "aws.dynamodb.local_secondary_indexes" semantic conventions. It represents
+ // the JSON-serialized value of each item of the `LocalSecondaryIndexes` request
+ // field.
+ //
+ // Type: string[]
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "{ "IndexArn": "string", "IndexName": "string", "IndexSizeBytes":
+ // number, "ItemCount": number, "KeySchema": [ { "AttributeName": "string",
+ // "KeyType": "string" } ], "Projection": { "NonKeyAttributes": [ "string" ],
+ // "ProjectionType": "string" } }"
+ AWSDynamoDBLocalSecondaryIndexesKey = attribute.Key("aws.dynamodb.local_secondary_indexes")
+
+ // AWSDynamoDBProjectionKey is the attribute Key conforming to the
+ // "aws.dynamodb.projection" semantic conventions. It represents the value of
+ // the `ProjectionExpression` request parameter.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "Title", "Title, Price, Color", "Title, Description, RelatedItems,
+ // ProductReviews"
+ AWSDynamoDBProjectionKey = attribute.Key("aws.dynamodb.projection")
+
+ // AWSDynamoDBProvisionedReadCapacityKey is the attribute Key conforming to the
+ // "aws.dynamodb.provisioned_read_capacity" semantic conventions. It represents
+ // the value of the `ProvisionedThroughput.ReadCapacityUnits` request parameter.
+ //
+ // Type: double
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 1.0, 2.0
+ AWSDynamoDBProvisionedReadCapacityKey = attribute.Key("aws.dynamodb.provisioned_read_capacity")
+
+ // AWSDynamoDBProvisionedWriteCapacityKey is the attribute Key conforming to the
+ // "aws.dynamodb.provisioned_write_capacity" semantic conventions. It represents
+ // the value of the `ProvisionedThroughput.WriteCapacityUnits` request
+ // parameter.
+ //
+ // Type: double
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 1.0, 2.0
+ AWSDynamoDBProvisionedWriteCapacityKey = attribute.Key("aws.dynamodb.provisioned_write_capacity")
+
+ // AWSDynamoDBScanForwardKey is the attribute Key conforming to the
+ // "aws.dynamodb.scan_forward" semantic conventions. It represents the value of
+ // the `ScanIndexForward` request parameter.
+ //
+ // Type: boolean
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ AWSDynamoDBScanForwardKey = attribute.Key("aws.dynamodb.scan_forward")
+
+ // AWSDynamoDBScannedCountKey is the attribute Key conforming to the
+ // "aws.dynamodb.scanned_count" semantic conventions. It represents the value of
+ // the `ScannedCount` response parameter.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 50
+ AWSDynamoDBScannedCountKey = attribute.Key("aws.dynamodb.scanned_count")
+
+ // AWSDynamoDBSegmentKey is the attribute Key conforming to the
+ // "aws.dynamodb.segment" semantic conventions. It represents the value of the
+ // `Segment` request parameter.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 10
+ AWSDynamoDBSegmentKey = attribute.Key("aws.dynamodb.segment")
+
+ // AWSDynamoDBSelectKey is the attribute Key conforming to the
+ // "aws.dynamodb.select" semantic conventions. It represents the value of the
+ // `Select` request parameter.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "ALL_ATTRIBUTES", "COUNT"
+ AWSDynamoDBSelectKey = attribute.Key("aws.dynamodb.select")
+
+ // AWSDynamoDBTableCountKey is the attribute Key conforming to the
+ // "aws.dynamodb.table_count" semantic conventions. It represents the number of
+ // items in the `TableNames` response parameter.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 20
+ AWSDynamoDBTableCountKey = attribute.Key("aws.dynamodb.table_count")
+
+ // AWSDynamoDBTableNamesKey is the attribute Key conforming to the
+ // "aws.dynamodb.table_names" semantic conventions. It represents the keys in
+ // the `RequestItems` object field.
+ //
+ // Type: string[]
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "Users", "Cats"
+ AWSDynamoDBTableNamesKey = attribute.Key("aws.dynamodb.table_names")
+
+ // AWSDynamoDBTotalSegmentsKey is the attribute Key conforming to the
+ // "aws.dynamodb.total_segments" semantic conventions. It represents the value
+ // of the `TotalSegments` request parameter.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 100
+ AWSDynamoDBTotalSegmentsKey = attribute.Key("aws.dynamodb.total_segments")
+
+ // AWSECSClusterARNKey is the attribute Key conforming to the
+ // "aws.ecs.cluster.arn" semantic conventions. It represents the ARN of an
+ // [ECS cluster].
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "arn:aws:ecs:us-west-2:123456789123:cluster/my-cluster"
+ //
+ // [ECS cluster]: https://docs.aws.amazon.com/AmazonECS/latest/developerguide/clusters.html
+ AWSECSClusterARNKey = attribute.Key("aws.ecs.cluster.arn")
+
+ // AWSECSContainerARNKey is the attribute Key conforming to the
+ // "aws.ecs.container.arn" semantic conventions. It represents the Amazon
+ // Resource Name (ARN) of an [ECS container instance].
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ // "arn:aws:ecs:us-west-1:123456789123:container/32624152-9086-4f0e-acae-1a75b14fe4d9"
+ //
+ // [ECS container instance]: https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ECS_instances.html
+ AWSECSContainerARNKey = attribute.Key("aws.ecs.container.arn")
+
+ // AWSECSLaunchtypeKey is the attribute Key conforming to the
+ // "aws.ecs.launchtype" semantic conventions. It represents the [launch type]
+ // for an ECS task.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ //
+ // [launch type]: https://docs.aws.amazon.com/AmazonECS/latest/developerguide/launch_types.html
+ AWSECSLaunchtypeKey = attribute.Key("aws.ecs.launchtype")
+
+ // AWSECSTaskARNKey is the attribute Key conforming to the "aws.ecs.task.arn"
+ // semantic conventions. It represents the ARN of a running [ECS task].
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ // "arn:aws:ecs:us-west-1:123456789123:task/10838bed-421f-43ef-870a-f43feacbbb5b",
+ // "arn:aws:ecs:us-west-1:123456789123:task/my-cluster/task-id/23ebb8ac-c18f-46c6-8bbe-d55d0e37cfbd"
+ //
+ // [ECS task]: https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs-account-settings.html#ecs-resource-ids
+ AWSECSTaskARNKey = attribute.Key("aws.ecs.task.arn")
+
+ // AWSECSTaskFamilyKey is the attribute Key conforming to the
+ // "aws.ecs.task.family" semantic conventions. It represents the family name of
+ // the [ECS task definition] used to create the ECS task.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "opentelemetry-family"
+ //
+ // [ECS task definition]: https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definitions.html
+ AWSECSTaskFamilyKey = attribute.Key("aws.ecs.task.family")
+
+ // AWSECSTaskIDKey is the attribute Key conforming to the "aws.ecs.task.id"
+ // semantic conventions. It represents the ID of a running ECS task. The ID MUST
+ // be extracted from `task.arn`.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "10838bed-421f-43ef-870a-f43feacbbb5b",
+ // "23ebb8ac-c18f-46c6-8bbe-d55d0e37cfbd"
+ AWSECSTaskIDKey = attribute.Key("aws.ecs.task.id")
+
+ // AWSECSTaskRevisionKey is the attribute Key conforming to the
+ // "aws.ecs.task.revision" semantic conventions. It represents the revision for
+ // the task definition used to create the ECS task.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "8", "26"
+ AWSECSTaskRevisionKey = attribute.Key("aws.ecs.task.revision")
+
+ // AWSEKSClusterARNKey is the attribute Key conforming to the
+ // "aws.eks.cluster.arn" semantic conventions. It represents the ARN of an EKS
+ // cluster.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "arn:aws:ecs:us-west-2:123456789123:cluster/my-cluster"
+ AWSEKSClusterARNKey = attribute.Key("aws.eks.cluster.arn")
+
+ // AWSExtendedRequestIDKey is the attribute Key conforming to the
+ // "aws.extended_request_id" semantic conventions. It represents the AWS
+ // extended request ID as returned in the response header `x-amz-id-2`.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ // "wzHcyEWfmOGDIE5QOhTAqFDoDWP3y8IUvpNINCwL9N4TEHbUw0/gZJ+VZTmCNCWR7fezEN3eCiQ="
+ AWSExtendedRequestIDKey = attribute.Key("aws.extended_request_id")
+
+ // AWSKinesisStreamNameKey is the attribute Key conforming to the
+ // "aws.kinesis.stream_name" semantic conventions. It represents the name of the
+ // AWS Kinesis [stream] the request refers to. Corresponds to the
+ // `--stream-name` parameter of the Kinesis [describe-stream] operation.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "some-stream-name"
+ //
+ // [stream]: https://docs.aws.amazon.com/streams/latest/dev/introduction.html
+ // [describe-stream]: https://docs.aws.amazon.com/cli/latest/reference/kinesis/describe-stream.html
+ AWSKinesisStreamNameKey = attribute.Key("aws.kinesis.stream_name")
+
+ // AWSLambdaInvokedARNKey is the attribute Key conforming to the
+ // "aws.lambda.invoked_arn" semantic conventions. It represents the full invoked
+ // ARN as provided on the `Context` passed to the function (
+ // `Lambda-Runtime-Invoked-Function-Arn` header on the
+ // `/runtime/invocation/next` applicable).
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "arn:aws:lambda:us-east-1:123456:function:myfunction:myalias"
+ // Note: This may be different from `cloud.resource_id` if an alias is involved.
+ AWSLambdaInvokedARNKey = attribute.Key("aws.lambda.invoked_arn")
+
+ // AWSLambdaResourceMappingIDKey is the attribute Key conforming to the
+ // "aws.lambda.resource_mapping.id" semantic conventions. It represents the UUID
+ // of the [AWS Lambda EvenSource Mapping]. An event source is mapped to a lambda
+ // function. It's contents are read by Lambda and used to trigger a function.
+ // This isn't available in the lambda execution context or the lambda runtime
+ // environment. This is going to be populated by the AWS SDK for each language
+ // when that UUID is present. Some of these operations are
+ // Create/Delete/Get/List/Update EventSourceMapping.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "587ad24b-03b9-4413-8202-bbd56b36e5b7"
+ //
+ // [AWS Lambda EvenSource Mapping]: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-eventsourcemapping.html
+ AWSLambdaResourceMappingIDKey = attribute.Key("aws.lambda.resource_mapping.id")
+
+ // AWSLogGroupARNsKey is the attribute Key conforming to the
+ // "aws.log.group.arns" semantic conventions. It represents the Amazon Resource
+ // Name(s) (ARN) of the AWS log group(s).
+ //
+ // Type: string[]
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "arn:aws:logs:us-west-1:123456789012:log-group:/aws/my/group:*"
+ // Note: See the [log group ARN format documentation].
+ //
+ // [log group ARN format documentation]: https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/iam-access-control-overview-cwl.html#CWL_ARN_Format
+ AWSLogGroupARNsKey = attribute.Key("aws.log.group.arns")
+
+ // AWSLogGroupNamesKey is the attribute Key conforming to the
+ // "aws.log.group.names" semantic conventions. It represents the name(s) of the
+ // AWS log group(s) an application is writing to.
+ //
+ // Type: string[]
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "/aws/lambda/my-function", "opentelemetry-service"
+ // Note: Multiple log groups must be supported for cases like multi-container
+ // applications, where a single application has sidecar containers, and each
+ // write to their own log group.
+ AWSLogGroupNamesKey = attribute.Key("aws.log.group.names")
+
+ // AWSLogStreamARNsKey is the attribute Key conforming to the
+ // "aws.log.stream.arns" semantic conventions. It represents the ARN(s) of the
+ // AWS log stream(s).
+ //
+ // Type: string[]
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ // "arn:aws:logs:us-west-1:123456789012:log-group:/aws/my/group:log-stream:logs/main/10838bed-421f-43ef-870a-f43feacbbb5b"
+ // Note: See the [log stream ARN format documentation]. One log group can
+ // contain several log streams, so these ARNs necessarily identify both a log
+ // group and a log stream.
+ //
+ // [log stream ARN format documentation]: https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/iam-access-control-overview-cwl.html#CWL_ARN_Format
+ AWSLogStreamARNsKey = attribute.Key("aws.log.stream.arns")
+
+ // AWSLogStreamNamesKey is the attribute Key conforming to the
+ // "aws.log.stream.names" semantic conventions. It represents the name(s) of the
+ // AWS log stream(s) an application is writing to.
+ //
+ // Type: string[]
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "logs/main/10838bed-421f-43ef-870a-f43feacbbb5b"
+ AWSLogStreamNamesKey = attribute.Key("aws.log.stream.names")
+
+ // AWSRequestIDKey is the attribute Key conforming to the "aws.request_id"
+ // semantic conventions. It represents the AWS request ID as returned in the
+ // response headers `x-amzn-requestid`, `x-amzn-request-id` or
+ // `x-amz-request-id`.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "79b9da39-b7ae-508a-a6bc-864b2829c622", "C9ER4AJX75574TDJ"
+ AWSRequestIDKey = attribute.Key("aws.request_id")
+
+ // AWSS3BucketKey is the attribute Key conforming to the "aws.s3.bucket"
+ // semantic conventions. It represents the S3 bucket name the request refers to.
+ // Corresponds to the `--bucket` parameter of the [S3 API] operations.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "some-bucket-name"
+ // Note: The `bucket` attribute is applicable to all S3 operations that
+ // reference a bucket, i.e. that require the bucket name as a mandatory
+ // parameter.
+ // This applies to almost all S3 operations except `list-buckets`.
+ //
+ // [S3 API]: https://docs.aws.amazon.com/cli/latest/reference/s3api/index.html
+ AWSS3BucketKey = attribute.Key("aws.s3.bucket")
+
+ // AWSS3CopySourceKey is the attribute Key conforming to the
+ // "aws.s3.copy_source" semantic conventions. It represents the source object
+ // (in the form `bucket`/`key`) for the copy operation.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "someFile.yml"
+ // Note: The `copy_source` attribute applies to S3 copy operations and
+ // corresponds to the `--copy-source` parameter
+ // of the [copy-object operation within the S3 API].
+ // This applies in particular to the following operations:
+ //
+ // - [copy-object]
+ // - [upload-part-copy]
+ //
+ //
+ // [copy-object operation within the S3 API]: https://docs.aws.amazon.com/cli/latest/reference/s3api/copy-object.html
+ // [copy-object]: https://docs.aws.amazon.com/cli/latest/reference/s3api/copy-object.html
+ // [upload-part-copy]: https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part-copy.html
+ AWSS3CopySourceKey = attribute.Key("aws.s3.copy_source")
+
+ // AWSS3DeleteKey is the attribute Key conforming to the "aws.s3.delete"
+ // semantic conventions. It represents the delete request container that
+ // specifies the objects to be deleted.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ // "Objects=[{Key=string,VersionId=string},{Key=string,VersionId=string}],Quiet=boolean"
+ // Note: The `delete` attribute is only applicable to the [delete-object]
+ // operation.
+ // The `delete` attribute corresponds to the `--delete` parameter of the
+ // [delete-objects operation within the S3 API].
+ //
+ // [delete-object]: https://docs.aws.amazon.com/cli/latest/reference/s3api/delete-object.html
+ // [delete-objects operation within the S3 API]: https://docs.aws.amazon.com/cli/latest/reference/s3api/delete-objects.html
+ AWSS3DeleteKey = attribute.Key("aws.s3.delete")
+
+ // AWSS3KeyKey is the attribute Key conforming to the "aws.s3.key" semantic
+ // conventions. It represents the S3 object key the request refers to.
+ // Corresponds to the `--key` parameter of the [S3 API] operations.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "someFile.yml"
+ // Note: The `key` attribute is applicable to all object-related S3 operations,
+ // i.e. that require the object key as a mandatory parameter.
+ // This applies in particular to the following operations:
+ //
+ // - [copy-object]
+ // - [delete-object]
+ // - [get-object]
+ // - [head-object]
+ // - [put-object]
+ // - [restore-object]
+ // - [select-object-content]
+ // - [abort-multipart-upload]
+ // - [complete-multipart-upload]
+ // - [create-multipart-upload]
+ // - [list-parts]
+ // - [upload-part]
+ // - [upload-part-copy]
+ //
+ //
+ // [S3 API]: https://docs.aws.amazon.com/cli/latest/reference/s3api/index.html
+ // [copy-object]: https://docs.aws.amazon.com/cli/latest/reference/s3api/copy-object.html
+ // [delete-object]: https://docs.aws.amazon.com/cli/latest/reference/s3api/delete-object.html
+ // [get-object]: https://docs.aws.amazon.com/cli/latest/reference/s3api/get-object.html
+ // [head-object]: https://docs.aws.amazon.com/cli/latest/reference/s3api/head-object.html
+ // [put-object]: https://docs.aws.amazon.com/cli/latest/reference/s3api/put-object.html
+ // [restore-object]: https://docs.aws.amazon.com/cli/latest/reference/s3api/restore-object.html
+ // [select-object-content]: https://docs.aws.amazon.com/cli/latest/reference/s3api/select-object-content.html
+ // [abort-multipart-upload]: https://docs.aws.amazon.com/cli/latest/reference/s3api/abort-multipart-upload.html
+ // [complete-multipart-upload]: https://docs.aws.amazon.com/cli/latest/reference/s3api/complete-multipart-upload.html
+ // [create-multipart-upload]: https://docs.aws.amazon.com/cli/latest/reference/s3api/create-multipart-upload.html
+ // [list-parts]: https://docs.aws.amazon.com/cli/latest/reference/s3api/list-parts.html
+ // [upload-part]: https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part.html
+ // [upload-part-copy]: https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part-copy.html
+ AWSS3KeyKey = attribute.Key("aws.s3.key")
+
+ // AWSS3PartNumberKey is the attribute Key conforming to the
+ // "aws.s3.part_number" semantic conventions. It represents the part number of
+ // the part being uploaded in a multipart-upload operation. This is a positive
+ // integer between 1 and 10,000.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 3456
+ // Note: The `part_number` attribute is only applicable to the [upload-part]
+ // and [upload-part-copy] operations.
+ // The `part_number` attribute corresponds to the `--part-number` parameter of
+ // the
+ // [upload-part operation within the S3 API].
+ //
+ // [upload-part]: https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part.html
+ // [upload-part-copy]: https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part-copy.html
+ // [upload-part operation within the S3 API]: https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part.html
+ AWSS3PartNumberKey = attribute.Key("aws.s3.part_number")
+
+ // AWSS3UploadIDKey is the attribute Key conforming to the "aws.s3.upload_id"
+ // semantic conventions. It represents the upload ID that identifies the
+ // multipart upload.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "dfRtDYWFbkRONycy.Yxwh66Yjlx.cph0gtNBtJ"
+ // Note: The `upload_id` attribute applies to S3 multipart-upload operations and
+ // corresponds to the `--upload-id` parameter
+ // of the [S3 API] multipart operations.
+ // This applies in particular to the following operations:
+ //
+ // - [abort-multipart-upload]
+ // - [complete-multipart-upload]
+ // - [list-parts]
+ // - [upload-part]
+ // - [upload-part-copy]
+ //
+ //
+ // [S3 API]: https://docs.aws.amazon.com/cli/latest/reference/s3api/index.html
+ // [abort-multipart-upload]: https://docs.aws.amazon.com/cli/latest/reference/s3api/abort-multipart-upload.html
+ // [complete-multipart-upload]: https://docs.aws.amazon.com/cli/latest/reference/s3api/complete-multipart-upload.html
+ // [list-parts]: https://docs.aws.amazon.com/cli/latest/reference/s3api/list-parts.html
+ // [upload-part]: https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part.html
+ // [upload-part-copy]: https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part-copy.html
+ AWSS3UploadIDKey = attribute.Key("aws.s3.upload_id")
+
+ // AWSSecretsmanagerSecretARNKey is the attribute Key conforming to the
+ // "aws.secretsmanager.secret.arn" semantic conventions. It represents the ARN
+ // of the Secret stored in the Secrets Manager.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ // "arn:aws:secretsmanager:us-east-1:123456789012:secret:SecretName-6RandomCharacters"
+ AWSSecretsmanagerSecretARNKey = attribute.Key("aws.secretsmanager.secret.arn")
+
+ // AWSSNSTopicARNKey is the attribute Key conforming to the "aws.sns.topic.arn"
+ // semantic conventions. It represents the ARN of the AWS SNS Topic. An Amazon
+ // SNS [topic] is a logical access point that acts as a communication channel.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "arn:aws:sns:us-east-1:123456789012:mystack-mytopic-NZJ5JSMVGFIE"
+ //
+ // [topic]: https://docs.aws.amazon.com/sns/latest/dg/sns-create-topic.html
+ AWSSNSTopicARNKey = attribute.Key("aws.sns.topic.arn")
+
+ // AWSSQSQueueURLKey is the attribute Key conforming to the "aws.sqs.queue.url"
+ // semantic conventions. It represents the URL of the AWS SQS Queue. It's a
+ // unique identifier for a queue in Amazon Simple Queue Service (SQS) and is
+ // used to access the queue and perform actions on it.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "https://sqs.us-east-1.amazonaws.com/123456789012/MyQueue"
+ AWSSQSQueueURLKey = attribute.Key("aws.sqs.queue.url")
+
+ // AWSStepFunctionsActivityARNKey is the attribute Key conforming to the
+ // "aws.step_functions.activity.arn" semantic conventions. It represents the ARN
+ // of the AWS Step Functions Activity.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "arn:aws:states:us-east-1:123456789012:activity:get-greeting"
+ AWSStepFunctionsActivityARNKey = attribute.Key("aws.step_functions.activity.arn")
+
+ // AWSStepFunctionsStateMachineARNKey is the attribute Key conforming to the
+ // "aws.step_functions.state_machine.arn" semantic conventions. It represents
+ // the ARN of the AWS Step Functions State Machine.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ // "arn:aws:states:us-east-1:123456789012:stateMachine:myStateMachine:1"
+ AWSStepFunctionsStateMachineARNKey = attribute.Key("aws.step_functions.state_machine.arn")
+)
+
+// AWSBedrockGuardrailID returns an attribute KeyValue conforming to the
+// "aws.bedrock.guardrail.id" semantic conventions. It represents the unique
+// identifier of the AWS Bedrock Guardrail. A [guardrail] helps safeguard and
+// prevent unwanted behavior from model responses or user messages.
+//
+// [guardrail]: https://docs.aws.amazon.com/bedrock/latest/userguide/guardrails.html
+func AWSBedrockGuardrailID(val string) attribute.KeyValue {
+ return AWSBedrockGuardrailIDKey.String(val)
+}
+
+// AWSBedrockKnowledgeBaseID returns an attribute KeyValue conforming to the
+// "aws.bedrock.knowledge_base.id" semantic conventions. It represents the unique
+// identifier of the AWS Bedrock Knowledge base. A [knowledge base] is a bank of
+// information that can be queried by models to generate more relevant responses
+// and augment prompts.
+//
+// [knowledge base]: https://docs.aws.amazon.com/bedrock/latest/userguide/knowledge-base.html
+func AWSBedrockKnowledgeBaseID(val string) attribute.KeyValue {
+ return AWSBedrockKnowledgeBaseIDKey.String(val)
+}
+
+// AWSDynamoDBAttributeDefinitions returns an attribute KeyValue conforming to
+// the "aws.dynamodb.attribute_definitions" semantic conventions. It represents
+// the JSON-serialized value of each item in the `AttributeDefinitions` request
+// field.
+func AWSDynamoDBAttributeDefinitions(val ...string) attribute.KeyValue {
+ return AWSDynamoDBAttributeDefinitionsKey.StringSlice(val)
+}
+
+// AWSDynamoDBAttributesToGet returns an attribute KeyValue conforming to the
+// "aws.dynamodb.attributes_to_get" semantic conventions. It represents the value
+// of the `AttributesToGet` request parameter.
+func AWSDynamoDBAttributesToGet(val ...string) attribute.KeyValue {
+ return AWSDynamoDBAttributesToGetKey.StringSlice(val)
+}
+
+// AWSDynamoDBConsistentRead returns an attribute KeyValue conforming to the
+// "aws.dynamodb.consistent_read" semantic conventions. It represents the value
+// of the `ConsistentRead` request parameter.
+func AWSDynamoDBConsistentRead(val bool) attribute.KeyValue {
+ return AWSDynamoDBConsistentReadKey.Bool(val)
+}
+
+// AWSDynamoDBConsumedCapacity returns an attribute KeyValue conforming to the
+// "aws.dynamodb.consumed_capacity" semantic conventions. It represents the
+// JSON-serialized value of each item in the `ConsumedCapacity` response field.
+func AWSDynamoDBConsumedCapacity(val ...string) attribute.KeyValue {
+ return AWSDynamoDBConsumedCapacityKey.StringSlice(val)
+}
+
+// AWSDynamoDBCount returns an attribute KeyValue conforming to the
+// "aws.dynamodb.count" semantic conventions. It represents the value of the
+// `Count` response parameter.
+func AWSDynamoDBCount(val int) attribute.KeyValue {
+ return AWSDynamoDBCountKey.Int(val)
+}
+
+// AWSDynamoDBExclusiveStartTable returns an attribute KeyValue conforming to the
+// "aws.dynamodb.exclusive_start_table" semantic conventions. It represents the
+// value of the `ExclusiveStartTableName` request parameter.
+func AWSDynamoDBExclusiveStartTable(val string) attribute.KeyValue {
+ return AWSDynamoDBExclusiveStartTableKey.String(val)
+}
+
+// AWSDynamoDBGlobalSecondaryIndexUpdates returns an attribute KeyValue
+// conforming to the "aws.dynamodb.global_secondary_index_updates" semantic
+// conventions. It represents the JSON-serialized value of each item in the
+// `GlobalSecondaryIndexUpdates` request field.
+func AWSDynamoDBGlobalSecondaryIndexUpdates(val ...string) attribute.KeyValue {
+ return AWSDynamoDBGlobalSecondaryIndexUpdatesKey.StringSlice(val)
+}
+
+// AWSDynamoDBGlobalSecondaryIndexes returns an attribute KeyValue conforming to
+// the "aws.dynamodb.global_secondary_indexes" semantic conventions. It
+// represents the JSON-serialized value of each item of the
+// `GlobalSecondaryIndexes` request field.
+func AWSDynamoDBGlobalSecondaryIndexes(val ...string) attribute.KeyValue {
+ return AWSDynamoDBGlobalSecondaryIndexesKey.StringSlice(val)
+}
+
+// AWSDynamoDBIndexName returns an attribute KeyValue conforming to the
+// "aws.dynamodb.index_name" semantic conventions. It represents the value of the
+// `IndexName` request parameter.
+func AWSDynamoDBIndexName(val string) attribute.KeyValue {
+ return AWSDynamoDBIndexNameKey.String(val)
+}
+
+// AWSDynamoDBItemCollectionMetrics returns an attribute KeyValue conforming to
+// the "aws.dynamodb.item_collection_metrics" semantic conventions. It represents
+// the JSON-serialized value of the `ItemCollectionMetrics` response field.
+func AWSDynamoDBItemCollectionMetrics(val string) attribute.KeyValue {
+ return AWSDynamoDBItemCollectionMetricsKey.String(val)
+}
+
+// AWSDynamoDBLimit returns an attribute KeyValue conforming to the
+// "aws.dynamodb.limit" semantic conventions. It represents the value of the
+// `Limit` request parameter.
+func AWSDynamoDBLimit(val int) attribute.KeyValue {
+ return AWSDynamoDBLimitKey.Int(val)
+}
+
+// AWSDynamoDBLocalSecondaryIndexes returns an attribute KeyValue conforming to
+// the "aws.dynamodb.local_secondary_indexes" semantic conventions. It represents
+// the JSON-serialized value of each item of the `LocalSecondaryIndexes` request
+// field.
+func AWSDynamoDBLocalSecondaryIndexes(val ...string) attribute.KeyValue {
+ return AWSDynamoDBLocalSecondaryIndexesKey.StringSlice(val)
+}
+
+// AWSDynamoDBProjection returns an attribute KeyValue conforming to the
+// "aws.dynamodb.projection" semantic conventions. It represents the value of the
+// `ProjectionExpression` request parameter.
+func AWSDynamoDBProjection(val string) attribute.KeyValue {
+ return AWSDynamoDBProjectionKey.String(val)
+}
+
+// AWSDynamoDBProvisionedReadCapacity returns an attribute KeyValue conforming to
+// the "aws.dynamodb.provisioned_read_capacity" semantic conventions. It
+// represents the value of the `ProvisionedThroughput.ReadCapacityUnits` request
+// parameter.
+func AWSDynamoDBProvisionedReadCapacity(val float64) attribute.KeyValue {
+ return AWSDynamoDBProvisionedReadCapacityKey.Float64(val)
+}
+
+// AWSDynamoDBProvisionedWriteCapacity returns an attribute KeyValue conforming
+// to the "aws.dynamodb.provisioned_write_capacity" semantic conventions. It
+// represents the value of the `ProvisionedThroughput.WriteCapacityUnits` request
+// parameter.
+func AWSDynamoDBProvisionedWriteCapacity(val float64) attribute.KeyValue {
+ return AWSDynamoDBProvisionedWriteCapacityKey.Float64(val)
+}
+
+// AWSDynamoDBScanForward returns an attribute KeyValue conforming to the
+// "aws.dynamodb.scan_forward" semantic conventions. It represents the value of
+// the `ScanIndexForward` request parameter.
+func AWSDynamoDBScanForward(val bool) attribute.KeyValue {
+ return AWSDynamoDBScanForwardKey.Bool(val)
+}
+
+// AWSDynamoDBScannedCount returns an attribute KeyValue conforming to the
+// "aws.dynamodb.scanned_count" semantic conventions. It represents the value of
+// the `ScannedCount` response parameter.
+func AWSDynamoDBScannedCount(val int) attribute.KeyValue {
+ return AWSDynamoDBScannedCountKey.Int(val)
+}
+
+// AWSDynamoDBSegment returns an attribute KeyValue conforming to the
+// "aws.dynamodb.segment" semantic conventions. It represents the value of the
+// `Segment` request parameter.
+func AWSDynamoDBSegment(val int) attribute.KeyValue {
+ return AWSDynamoDBSegmentKey.Int(val)
+}
+
+// AWSDynamoDBSelect returns an attribute KeyValue conforming to the
+// "aws.dynamodb.select" semantic conventions. It represents the value of the
+// `Select` request parameter.
+func AWSDynamoDBSelect(val string) attribute.KeyValue {
+ return AWSDynamoDBSelectKey.String(val)
+}
+
+// AWSDynamoDBTableCount returns an attribute KeyValue conforming to the
+// "aws.dynamodb.table_count" semantic conventions. It represents the number of
+// items in the `TableNames` response parameter.
+func AWSDynamoDBTableCount(val int) attribute.KeyValue {
+ return AWSDynamoDBTableCountKey.Int(val)
+}
+
+// AWSDynamoDBTableNames returns an attribute KeyValue conforming to the
+// "aws.dynamodb.table_names" semantic conventions. It represents the keys in the
+// `RequestItems` object field.
+func AWSDynamoDBTableNames(val ...string) attribute.KeyValue {
+ return AWSDynamoDBTableNamesKey.StringSlice(val)
+}
+
+// AWSDynamoDBTotalSegments returns an attribute KeyValue conforming to the
+// "aws.dynamodb.total_segments" semantic conventions. It represents the value of
+// the `TotalSegments` request parameter.
+func AWSDynamoDBTotalSegments(val int) attribute.KeyValue {
+ return AWSDynamoDBTotalSegmentsKey.Int(val)
+}
+
+// AWSECSClusterARN returns an attribute KeyValue conforming to the
+// "aws.ecs.cluster.arn" semantic conventions. It represents the ARN of an
+// [ECS cluster].
+//
+// [ECS cluster]: https://docs.aws.amazon.com/AmazonECS/latest/developerguide/clusters.html
+func AWSECSClusterARN(val string) attribute.KeyValue {
+ return AWSECSClusterARNKey.String(val)
+}
+
+// AWSECSContainerARN returns an attribute KeyValue conforming to the
+// "aws.ecs.container.arn" semantic conventions. It represents the Amazon
+// Resource Name (ARN) of an [ECS container instance].
+//
+// [ECS container instance]: https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ECS_instances.html
+func AWSECSContainerARN(val string) attribute.KeyValue {
+ return AWSECSContainerARNKey.String(val)
+}
+
+// AWSECSTaskARN returns an attribute KeyValue conforming to the
+// "aws.ecs.task.arn" semantic conventions. It represents the ARN of a running
+// [ECS task].
+//
+// [ECS task]: https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs-account-settings.html#ecs-resource-ids
+func AWSECSTaskARN(val string) attribute.KeyValue {
+ return AWSECSTaskARNKey.String(val)
+}
+
+// AWSECSTaskFamily returns an attribute KeyValue conforming to the
+// "aws.ecs.task.family" semantic conventions. It represents the family name of
+// the [ECS task definition] used to create the ECS task.
+//
+// [ECS task definition]: https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definitions.html
+func AWSECSTaskFamily(val string) attribute.KeyValue {
+ return AWSECSTaskFamilyKey.String(val)
+}
+
+// AWSECSTaskID returns an attribute KeyValue conforming to the "aws.ecs.task.id"
+// semantic conventions. It represents the ID of a running ECS task. The ID MUST
+// be extracted from `task.arn`.
+func AWSECSTaskID(val string) attribute.KeyValue {
+ return AWSECSTaskIDKey.String(val)
+}
+
+// AWSECSTaskRevision returns an attribute KeyValue conforming to the
+// "aws.ecs.task.revision" semantic conventions. It represents the revision for
+// the task definition used to create the ECS task.
+func AWSECSTaskRevision(val string) attribute.KeyValue {
+ return AWSECSTaskRevisionKey.String(val)
+}
+
+// AWSEKSClusterARN returns an attribute KeyValue conforming to the
+// "aws.eks.cluster.arn" semantic conventions. It represents the ARN of an EKS
+// cluster.
+func AWSEKSClusterARN(val string) attribute.KeyValue {
+ return AWSEKSClusterARNKey.String(val)
+}
+
+// AWSExtendedRequestID returns an attribute KeyValue conforming to the
+// "aws.extended_request_id" semantic conventions. It represents the AWS extended
+// request ID as returned in the response header `x-amz-id-2`.
+func AWSExtendedRequestID(val string) attribute.KeyValue {
+ return AWSExtendedRequestIDKey.String(val)
+}
+
+// AWSKinesisStreamName returns an attribute KeyValue conforming to the
+// "aws.kinesis.stream_name" semantic conventions. It represents the name of the
+// AWS Kinesis [stream] the request refers to. Corresponds to the `--stream-name`
+// parameter of the Kinesis [describe-stream] operation.
+//
+// [stream]: https://docs.aws.amazon.com/streams/latest/dev/introduction.html
+// [describe-stream]: https://docs.aws.amazon.com/cli/latest/reference/kinesis/describe-stream.html
+func AWSKinesisStreamName(val string) attribute.KeyValue {
+ return AWSKinesisStreamNameKey.String(val)
+}
+
+// AWSLambdaInvokedARN returns an attribute KeyValue conforming to the
+// "aws.lambda.invoked_arn" semantic conventions. It represents the full invoked
+// ARN as provided on the `Context` passed to the function (
+// `Lambda-Runtime-Invoked-Function-Arn` header on the `/runtime/invocation/next`
+// applicable).
+func AWSLambdaInvokedARN(val string) attribute.KeyValue {
+ return AWSLambdaInvokedARNKey.String(val)
+}
+
+// AWSLambdaResourceMappingID returns an attribute KeyValue conforming to the
+// "aws.lambda.resource_mapping.id" semantic conventions. It represents the UUID
+// of the [AWS Lambda EvenSource Mapping]. An event source is mapped to a lambda
+// function. It's contents are read by Lambda and used to trigger a function.
+// This isn't available in the lambda execution context or the lambda runtime
+// environment. This is going to be populated by the AWS SDK for each language
+// when that UUID is present. Some of these operations are
+// Create/Delete/Get/List/Update EventSourceMapping.
+//
+// [AWS Lambda EvenSource Mapping]: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-eventsourcemapping.html
+func AWSLambdaResourceMappingID(val string) attribute.KeyValue {
+ return AWSLambdaResourceMappingIDKey.String(val)
+}
+
+// AWSLogGroupARNs returns an attribute KeyValue conforming to the
+// "aws.log.group.arns" semantic conventions. It represents the Amazon Resource
+// Name(s) (ARN) of the AWS log group(s).
+func AWSLogGroupARNs(val ...string) attribute.KeyValue {
+ return AWSLogGroupARNsKey.StringSlice(val)
+}
+
+// AWSLogGroupNames returns an attribute KeyValue conforming to the
+// "aws.log.group.names" semantic conventions. It represents the name(s) of the
+// AWS log group(s) an application is writing to.
+func AWSLogGroupNames(val ...string) attribute.KeyValue {
+ return AWSLogGroupNamesKey.StringSlice(val)
+}
+
+// AWSLogStreamARNs returns an attribute KeyValue conforming to the
+// "aws.log.stream.arns" semantic conventions. It represents the ARN(s) of the
+// AWS log stream(s).
+func AWSLogStreamARNs(val ...string) attribute.KeyValue {
+ return AWSLogStreamARNsKey.StringSlice(val)
+}
+
+// AWSLogStreamNames returns an attribute KeyValue conforming to the
+// "aws.log.stream.names" semantic conventions. It represents the name(s) of the
+// AWS log stream(s) an application is writing to.
+func AWSLogStreamNames(val ...string) attribute.KeyValue {
+ return AWSLogStreamNamesKey.StringSlice(val)
+}
+
+// AWSRequestID returns an attribute KeyValue conforming to the "aws.request_id"
+// semantic conventions. It represents the AWS request ID as returned in the
+// response headers `x-amzn-requestid`, `x-amzn-request-id` or `x-amz-request-id`
+// .
+func AWSRequestID(val string) attribute.KeyValue {
+ return AWSRequestIDKey.String(val)
+}
+
+// AWSS3Bucket returns an attribute KeyValue conforming to the "aws.s3.bucket"
+// semantic conventions. It represents the S3 bucket name the request refers to.
+// Corresponds to the `--bucket` parameter of the [S3 API] operations.
+//
+// [S3 API]: https://docs.aws.amazon.com/cli/latest/reference/s3api/index.html
+func AWSS3Bucket(val string) attribute.KeyValue {
+ return AWSS3BucketKey.String(val)
+}
+
+// AWSS3CopySource returns an attribute KeyValue conforming to the
+// "aws.s3.copy_source" semantic conventions. It represents the source object (in
+// the form `bucket`/`key`) for the copy operation.
+func AWSS3CopySource(val string) attribute.KeyValue {
+ return AWSS3CopySourceKey.String(val)
+}
+
+// AWSS3Delete returns an attribute KeyValue conforming to the "aws.s3.delete"
+// semantic conventions. It represents the delete request container that
+// specifies the objects to be deleted.
+func AWSS3Delete(val string) attribute.KeyValue {
+ return AWSS3DeleteKey.String(val)
+}
+
+// AWSS3Key returns an attribute KeyValue conforming to the "aws.s3.key" semantic
+// conventions. It represents the S3 object key the request refers to.
+// Corresponds to the `--key` parameter of the [S3 API] operations.
+//
+// [S3 API]: https://docs.aws.amazon.com/cli/latest/reference/s3api/index.html
+func AWSS3Key(val string) attribute.KeyValue {
+ return AWSS3KeyKey.String(val)
+}
+
+// AWSS3PartNumber returns an attribute KeyValue conforming to the
+// "aws.s3.part_number" semantic conventions. It represents the part number of
+// the part being uploaded in a multipart-upload operation. This is a positive
+// integer between 1 and 10,000.
+func AWSS3PartNumber(val int) attribute.KeyValue {
+ return AWSS3PartNumberKey.Int(val)
+}
+
+// AWSS3UploadID returns an attribute KeyValue conforming to the
+// "aws.s3.upload_id" semantic conventions. It represents the upload ID that
+// identifies the multipart upload.
+func AWSS3UploadID(val string) attribute.KeyValue {
+ return AWSS3UploadIDKey.String(val)
+}
+
+// AWSSecretsmanagerSecretARN returns an attribute KeyValue conforming to the
+// "aws.secretsmanager.secret.arn" semantic conventions. It represents the ARN of
+// the Secret stored in the Secrets Manager.
+func AWSSecretsmanagerSecretARN(val string) attribute.KeyValue {
+ return AWSSecretsmanagerSecretARNKey.String(val)
+}
+
+// AWSSNSTopicARN returns an attribute KeyValue conforming to the
+// "aws.sns.topic.arn" semantic conventions. It represents the ARN of the AWS SNS
+// Topic. An Amazon SNS [topic] is a logical access point that acts as a
+// communication channel.
+//
+// [topic]: https://docs.aws.amazon.com/sns/latest/dg/sns-create-topic.html
+func AWSSNSTopicARN(val string) attribute.KeyValue {
+ return AWSSNSTopicARNKey.String(val)
+}
+
+// AWSSQSQueueURL returns an attribute KeyValue conforming to the
+// "aws.sqs.queue.url" semantic conventions. It represents the URL of the AWS SQS
+// Queue. It's a unique identifier for a queue in Amazon Simple Queue Service
+// (SQS) and is used to access the queue and perform actions on it.
+func AWSSQSQueueURL(val string) attribute.KeyValue {
+ return AWSSQSQueueURLKey.String(val)
+}
+
+// AWSStepFunctionsActivityARN returns an attribute KeyValue conforming to the
+// "aws.step_functions.activity.arn" semantic conventions. It represents the ARN
+// of the AWS Step Functions Activity.
+func AWSStepFunctionsActivityARN(val string) attribute.KeyValue {
+ return AWSStepFunctionsActivityARNKey.String(val)
+}
+
+// AWSStepFunctionsStateMachineARN returns an attribute KeyValue conforming to
+// the "aws.step_functions.state_machine.arn" semantic conventions. It represents
+// the ARN of the AWS Step Functions State Machine.
+func AWSStepFunctionsStateMachineARN(val string) attribute.KeyValue {
+ return AWSStepFunctionsStateMachineARNKey.String(val)
+}
+
+// Enum values for aws.ecs.launchtype
+var (
+ // Amazon EC2
+ // Stability: development
+ AWSECSLaunchtypeEC2 = AWSECSLaunchtypeKey.String("ec2")
+ // Amazon Fargate
+ // Stability: development
+ AWSECSLaunchtypeFargate = AWSECSLaunchtypeKey.String("fargate")
+)
+
+// Namespace: azure
+const (
+ // AzureClientIDKey is the attribute Key conforming to the "azure.client.id"
+ // semantic conventions. It represents the unique identifier of the client
+ // instance.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "3ba4827d-4422-483f-b59f-85b74211c11d", "storage-client-1"
+ AzureClientIDKey = attribute.Key("azure.client.id")
+
+ // AzureCosmosDBConnectionModeKey is the attribute Key conforming to the
+ // "azure.cosmosdb.connection.mode" semantic conventions. It represents the
+ // cosmos client connection mode.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ AzureCosmosDBConnectionModeKey = attribute.Key("azure.cosmosdb.connection.mode")
+
+ // AzureCosmosDBConsistencyLevelKey is the attribute Key conforming to the
+ // "azure.cosmosdb.consistency.level" semantic conventions. It represents the
+ // account or request [consistency level].
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "Eventual", "ConsistentPrefix", "BoundedStaleness", "Strong",
+ // "Session"
+ //
+ // [consistency level]: https://learn.microsoft.com/azure/cosmos-db/consistency-levels
+ AzureCosmosDBConsistencyLevelKey = attribute.Key("azure.cosmosdb.consistency.level")
+
+ // AzureCosmosDBOperationContactedRegionsKey is the attribute Key conforming to
+ // the "azure.cosmosdb.operation.contacted_regions" semantic conventions. It
+ // represents the list of regions contacted during operation in the order that
+ // they were contacted. If there is more than one region listed, it indicates
+ // that the operation was performed on multiple regions i.e. cross-regional
+ // call.
+ //
+ // Type: string[]
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "North Central US", "Australia East", "Australia Southeast"
+ // Note: Region name matches the format of `displayName` in [Azure Location API]
+ //
+ // [Azure Location API]: https://learn.microsoft.com/rest/api/resources/subscriptions/list-locations
+ AzureCosmosDBOperationContactedRegionsKey = attribute.Key("azure.cosmosdb.operation.contacted_regions")
+
+ // AzureCosmosDBOperationRequestChargeKey is the attribute Key conforming to the
+ // "azure.cosmosdb.operation.request_charge" semantic conventions. It represents
+ // the number of request units consumed by the operation.
+ //
+ // Type: double
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 46.18, 1.0
+ AzureCosmosDBOperationRequestChargeKey = attribute.Key("azure.cosmosdb.operation.request_charge")
+
+ // AzureCosmosDBRequestBodySizeKey is the attribute Key conforming to the
+ // "azure.cosmosdb.request.body.size" semantic conventions. It represents the
+ // request payload size in bytes.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ AzureCosmosDBRequestBodySizeKey = attribute.Key("azure.cosmosdb.request.body.size")
+
+ // AzureCosmosDBResponseSubStatusCodeKey is the attribute Key conforming to the
+ // "azure.cosmosdb.response.sub_status_code" semantic conventions. It represents
+ // the cosmos DB sub status code.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 1000, 1002
+ AzureCosmosDBResponseSubStatusCodeKey = attribute.Key("azure.cosmosdb.response.sub_status_code")
+
+ // AzureResourceProviderNamespaceKey is the attribute Key conforming to the
+ // "azure.resource_provider.namespace" semantic conventions. It represents the
+ // [Azure Resource Provider Namespace] as recognized by the client.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "Microsoft.Storage", "Microsoft.KeyVault", "Microsoft.ServiceBus"
+ //
+ // [Azure Resource Provider Namespace]: https://learn.microsoft.com/azure/azure-resource-manager/management/azure-services-resource-providers
+ AzureResourceProviderNamespaceKey = attribute.Key("azure.resource_provider.namespace")
+
+ // AzureServiceRequestIDKey is the attribute Key conforming to the
+ // "azure.service.request.id" semantic conventions. It represents the unique
+ // identifier of the service request. It's generated by the Azure service and
+ // returned with the response.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "00000000-0000-0000-0000-000000000000"
+ AzureServiceRequestIDKey = attribute.Key("azure.service.request.id")
+)
+
+// AzureClientID returns an attribute KeyValue conforming to the
+// "azure.client.id" semantic conventions. It represents the unique identifier of
+// the client instance.
+func AzureClientID(val string) attribute.KeyValue {
+ return AzureClientIDKey.String(val)
+}
+
+// AzureCosmosDBOperationContactedRegions returns an attribute KeyValue
+// conforming to the "azure.cosmosdb.operation.contacted_regions" semantic
+// conventions. It represents the list of regions contacted during operation in
+// the order that they were contacted. If there is more than one region listed,
+// it indicates that the operation was performed on multiple regions i.e.
+// cross-regional call.
+func AzureCosmosDBOperationContactedRegions(val ...string) attribute.KeyValue {
+ return AzureCosmosDBOperationContactedRegionsKey.StringSlice(val)
+}
+
+// AzureCosmosDBOperationRequestCharge returns an attribute KeyValue conforming
+// to the "azure.cosmosdb.operation.request_charge" semantic conventions. It
+// represents the number of request units consumed by the operation.
+func AzureCosmosDBOperationRequestCharge(val float64) attribute.KeyValue {
+ return AzureCosmosDBOperationRequestChargeKey.Float64(val)
+}
+
+// AzureCosmosDBRequestBodySize returns an attribute KeyValue conforming to the
+// "azure.cosmosdb.request.body.size" semantic conventions. It represents the
+// request payload size in bytes.
+func AzureCosmosDBRequestBodySize(val int) attribute.KeyValue {
+ return AzureCosmosDBRequestBodySizeKey.Int(val)
+}
+
+// AzureCosmosDBResponseSubStatusCode returns an attribute KeyValue conforming to
+// the "azure.cosmosdb.response.sub_status_code" semantic conventions. It
+// represents the cosmos DB sub status code.
+func AzureCosmosDBResponseSubStatusCode(val int) attribute.KeyValue {
+ return AzureCosmosDBResponseSubStatusCodeKey.Int(val)
+}
+
+// AzureResourceProviderNamespace returns an attribute KeyValue conforming to the
+// "azure.resource_provider.namespace" semantic conventions. It represents the
+// [Azure Resource Provider Namespace] as recognized by the client.
+//
+// [Azure Resource Provider Namespace]: https://learn.microsoft.com/azure/azure-resource-manager/management/azure-services-resource-providers
+func AzureResourceProviderNamespace(val string) attribute.KeyValue {
+ return AzureResourceProviderNamespaceKey.String(val)
+}
+
+// AzureServiceRequestID returns an attribute KeyValue conforming to the
+// "azure.service.request.id" semantic conventions. It represents the unique
+// identifier of the service request. It's generated by the Azure service and
+// returned with the response.
+func AzureServiceRequestID(val string) attribute.KeyValue {
+ return AzureServiceRequestIDKey.String(val)
+}
+
+// Enum values for azure.cosmosdb.connection.mode
+var (
+ // Gateway (HTTP) connection.
+ // Stability: development
+ AzureCosmosDBConnectionModeGateway = AzureCosmosDBConnectionModeKey.String("gateway")
+ // Direct connection.
+ // Stability: development
+ AzureCosmosDBConnectionModeDirect = AzureCosmosDBConnectionModeKey.String("direct")
+)
+
+// Enum values for azure.cosmosdb.consistency.level
+var (
+ // Strong
+ // Stability: development
+ AzureCosmosDBConsistencyLevelStrong = AzureCosmosDBConsistencyLevelKey.String("Strong")
+ // Bounded Staleness
+ // Stability: development
+ AzureCosmosDBConsistencyLevelBoundedStaleness = AzureCosmosDBConsistencyLevelKey.String("BoundedStaleness")
+ // Session
+ // Stability: development
+ AzureCosmosDBConsistencyLevelSession = AzureCosmosDBConsistencyLevelKey.String("Session")
+ // Eventual
+ // Stability: development
+ AzureCosmosDBConsistencyLevelEventual = AzureCosmosDBConsistencyLevelKey.String("Eventual")
+ // Consistent Prefix
+ // Stability: development
+ AzureCosmosDBConsistencyLevelConsistentPrefix = AzureCosmosDBConsistencyLevelKey.String("ConsistentPrefix")
+)
+
+// Namespace: browser
+const (
+ // BrowserBrandsKey is the attribute Key conforming to the "browser.brands"
+ // semantic conventions. It represents the array of brand name and version
+ // separated by a space.
+ //
+ // Type: string[]
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: " Not A;Brand 99", "Chromium 99", "Chrome 99"
+ // Note: This value is intended to be taken from the [UA client hints API] (
+ // `navigator.userAgentData.brands`).
+ //
+ // [UA client hints API]: https://wicg.github.io/ua-client-hints/#interface
+ BrowserBrandsKey = attribute.Key("browser.brands")
+
+ // BrowserLanguageKey is the attribute Key conforming to the "browser.language"
+ // semantic conventions. It represents the preferred language of the user using
+ // the browser.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "en", "en-US", "fr", "fr-FR"
+ // Note: This value is intended to be taken from the Navigator API
+ // `navigator.language`.
+ BrowserLanguageKey = attribute.Key("browser.language")
+
+ // BrowserMobileKey is the attribute Key conforming to the "browser.mobile"
+ // semantic conventions. It represents a boolean that is true if the browser is
+ // running on a mobile device.
+ //
+ // Type: boolean
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ // Note: This value is intended to be taken from the [UA client hints API] (
+ // `navigator.userAgentData.mobile`). If unavailable, this attribute SHOULD be
+ // left unset.
+ //
+ // [UA client hints API]: https://wicg.github.io/ua-client-hints/#interface
+ BrowserMobileKey = attribute.Key("browser.mobile")
+
+ // BrowserPlatformKey is the attribute Key conforming to the "browser.platform"
+ // semantic conventions. It represents the platform on which the browser is
+ // running.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "Windows", "macOS", "Android"
+ // Note: This value is intended to be taken from the [UA client hints API] (
+ // `navigator.userAgentData.platform`). If unavailable, the legacy
+ // `navigator.platform` API SHOULD NOT be used instead and this attribute SHOULD
+ // be left unset in order for the values to be consistent.
+ // The list of possible values is defined in the
+ // [W3C User-Agent Client Hints specification]. Note that some (but not all) of
+ // these values can overlap with values in the
+ // [`os.type` and `os.name` attributes]. However, for consistency, the values in
+ // the `browser.platform` attribute should capture the exact value that the user
+ // agent provides.
+ //
+ // [UA client hints API]: https://wicg.github.io/ua-client-hints/#interface
+ // [W3C User-Agent Client Hints specification]: https://wicg.github.io/ua-client-hints/#sec-ch-ua-platform
+ // [`os.type` and `os.name` attributes]: ./os.md
+ BrowserPlatformKey = attribute.Key("browser.platform")
+)
+
+// BrowserBrands returns an attribute KeyValue conforming to the "browser.brands"
+// semantic conventions. It represents the array of brand name and version
+// separated by a space.
+func BrowserBrands(val ...string) attribute.KeyValue {
+ return BrowserBrandsKey.StringSlice(val)
+}
+
+// BrowserLanguage returns an attribute KeyValue conforming to the
+// "browser.language" semantic conventions. It represents the preferred language
+// of the user using the browser.
+func BrowserLanguage(val string) attribute.KeyValue {
+ return BrowserLanguageKey.String(val)
+}
+
+// BrowserMobile returns an attribute KeyValue conforming to the "browser.mobile"
+// semantic conventions. It represents a boolean that is true if the browser is
+// running on a mobile device.
+func BrowserMobile(val bool) attribute.KeyValue {
+ return BrowserMobileKey.Bool(val)
+}
+
+// BrowserPlatform returns an attribute KeyValue conforming to the
+// "browser.platform" semantic conventions. It represents the platform on which
+// the browser is running.
+func BrowserPlatform(val string) attribute.KeyValue {
+ return BrowserPlatformKey.String(val)
+}
+
+// Namespace: cassandra
+const (
+ // CassandraConsistencyLevelKey is the attribute Key conforming to the
+ // "cassandra.consistency.level" semantic conventions. It represents the
+ // consistency level of the query. Based on consistency values from [CQL].
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ //
+ // [CQL]: https://docs.datastax.com/en/cassandra-oss/3.0/cassandra/dml/dmlConfigConsistency.html
+ CassandraConsistencyLevelKey = attribute.Key("cassandra.consistency.level")
+
+ // CassandraCoordinatorDCKey is the attribute Key conforming to the
+ // "cassandra.coordinator.dc" semantic conventions. It represents the data
+ // center of the coordinating node for a query.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: us-west-2
+ CassandraCoordinatorDCKey = attribute.Key("cassandra.coordinator.dc")
+
+ // CassandraCoordinatorIDKey is the attribute Key conforming to the
+ // "cassandra.coordinator.id" semantic conventions. It represents the ID of the
+ // coordinating node for a query.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: be13faa2-8574-4d71-926d-27f16cf8a7af
+ CassandraCoordinatorIDKey = attribute.Key("cassandra.coordinator.id")
+
+ // CassandraPageSizeKey is the attribute Key conforming to the
+ // "cassandra.page.size" semantic conventions. It represents the fetch size used
+ // for paging, i.e. how many rows will be returned at once.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 5000
+ CassandraPageSizeKey = attribute.Key("cassandra.page.size")
+
+ // CassandraQueryIdempotentKey is the attribute Key conforming to the
+ // "cassandra.query.idempotent" semantic conventions. It represents the whether
+ // or not the query is idempotent.
+ //
+ // Type: boolean
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ CassandraQueryIdempotentKey = attribute.Key("cassandra.query.idempotent")
+
+ // CassandraSpeculativeExecutionCountKey is the attribute Key conforming to the
+ // "cassandra.speculative_execution.count" semantic conventions. It represents
+ // the number of times a query was speculatively executed. Not set or `0` if the
+ // query was not executed speculatively.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 0, 2
+ CassandraSpeculativeExecutionCountKey = attribute.Key("cassandra.speculative_execution.count")
+)
+
+// CassandraCoordinatorDC returns an attribute KeyValue conforming to the
+// "cassandra.coordinator.dc" semantic conventions. It represents the data center
+// of the coordinating node for a query.
+func CassandraCoordinatorDC(val string) attribute.KeyValue {
+ return CassandraCoordinatorDCKey.String(val)
+}
+
+// CassandraCoordinatorID returns an attribute KeyValue conforming to the
+// "cassandra.coordinator.id" semantic conventions. It represents the ID of the
+// coordinating node for a query.
+func CassandraCoordinatorID(val string) attribute.KeyValue {
+ return CassandraCoordinatorIDKey.String(val)
+}
+
+// CassandraPageSize returns an attribute KeyValue conforming to the
+// "cassandra.page.size" semantic conventions. It represents the fetch size used
+// for paging, i.e. how many rows will be returned at once.
+func CassandraPageSize(val int) attribute.KeyValue {
+ return CassandraPageSizeKey.Int(val)
+}
+
+// CassandraQueryIdempotent returns an attribute KeyValue conforming to the
+// "cassandra.query.idempotent" semantic conventions. It represents the whether
+// or not the query is idempotent.
+func CassandraQueryIdempotent(val bool) attribute.KeyValue {
+ return CassandraQueryIdempotentKey.Bool(val)
+}
+
+// CassandraSpeculativeExecutionCount returns an attribute KeyValue conforming to
+// the "cassandra.speculative_execution.count" semantic conventions. It
+// represents the number of times a query was speculatively executed. Not set or
+// `0` if the query was not executed speculatively.
+func CassandraSpeculativeExecutionCount(val int) attribute.KeyValue {
+ return CassandraSpeculativeExecutionCountKey.Int(val)
+}
+
+// Enum values for cassandra.consistency.level
+var (
+ // All
+ // Stability: development
+ CassandraConsistencyLevelAll = CassandraConsistencyLevelKey.String("all")
+ // Each Quorum
+ // Stability: development
+ CassandraConsistencyLevelEachQuorum = CassandraConsistencyLevelKey.String("each_quorum")
+ // Quorum
+ // Stability: development
+ CassandraConsistencyLevelQuorum = CassandraConsistencyLevelKey.String("quorum")
+ // Local Quorum
+ // Stability: development
+ CassandraConsistencyLevelLocalQuorum = CassandraConsistencyLevelKey.String("local_quorum")
+ // One
+ // Stability: development
+ CassandraConsistencyLevelOne = CassandraConsistencyLevelKey.String("one")
+ // Two
+ // Stability: development
+ CassandraConsistencyLevelTwo = CassandraConsistencyLevelKey.String("two")
+ // Three
+ // Stability: development
+ CassandraConsistencyLevelThree = CassandraConsistencyLevelKey.String("three")
+ // Local One
+ // Stability: development
+ CassandraConsistencyLevelLocalOne = CassandraConsistencyLevelKey.String("local_one")
+ // Any
+ // Stability: development
+ CassandraConsistencyLevelAny = CassandraConsistencyLevelKey.String("any")
+ // Serial
+ // Stability: development
+ CassandraConsistencyLevelSerial = CassandraConsistencyLevelKey.String("serial")
+ // Local Serial
+ // Stability: development
+ CassandraConsistencyLevelLocalSerial = CassandraConsistencyLevelKey.String("local_serial")
+)
+
+// Namespace: cicd
+const (
+ // CICDPipelineActionNameKey is the attribute Key conforming to the
+ // "cicd.pipeline.action.name" semantic conventions. It represents the kind of
+ // action a pipeline run is performing.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "BUILD", "RUN", "SYNC"
+ CICDPipelineActionNameKey = attribute.Key("cicd.pipeline.action.name")
+
+ // CICDPipelineNameKey is the attribute Key conforming to the
+ // "cicd.pipeline.name" semantic conventions. It represents the human readable
+ // name of the pipeline within a CI/CD system.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "Build and Test", "Lint", "Deploy Go Project",
+ // "deploy_to_environment"
+ CICDPipelineNameKey = attribute.Key("cicd.pipeline.name")
+
+ // CICDPipelineResultKey is the attribute Key conforming to the
+ // "cicd.pipeline.result" semantic conventions. It represents the result of a
+ // pipeline run.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "success", "failure", "timeout", "skipped"
+ CICDPipelineResultKey = attribute.Key("cicd.pipeline.result")
+
+ // CICDPipelineRunIDKey is the attribute Key conforming to the
+ // "cicd.pipeline.run.id" semantic conventions. It represents the unique
+ // identifier of a pipeline run within a CI/CD system.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "120912"
+ CICDPipelineRunIDKey = attribute.Key("cicd.pipeline.run.id")
+
+ // CICDPipelineRunStateKey is the attribute Key conforming to the
+ // "cicd.pipeline.run.state" semantic conventions. It represents the pipeline
+ // run goes through these states during its lifecycle.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "pending", "executing", "finalizing"
+ CICDPipelineRunStateKey = attribute.Key("cicd.pipeline.run.state")
+
+ // CICDPipelineRunURLFullKey is the attribute Key conforming to the
+ // "cicd.pipeline.run.url.full" semantic conventions. It represents the [URL] of
+ // the pipeline run, providing the complete address in order to locate and
+ // identify the pipeline run.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ // "https://github.com/open-telemetry/semantic-conventions/actions/runs/9753949763?pr=1075"
+ //
+ // [URL]: https://wikipedia.org/wiki/URL
+ CICDPipelineRunURLFullKey = attribute.Key("cicd.pipeline.run.url.full")
+
+ // CICDPipelineTaskNameKey is the attribute Key conforming to the
+ // "cicd.pipeline.task.name" semantic conventions. It represents the human
+ // readable name of a task within a pipeline. Task here most closely aligns with
+ // a [computing process] in a pipeline. Other terms for tasks include commands,
+ // steps, and procedures.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "Run GoLang Linter", "Go Build", "go-test", "deploy_binary"
+ //
+ // [computing process]: https://wikipedia.org/wiki/Pipeline_(computing)
+ CICDPipelineTaskNameKey = attribute.Key("cicd.pipeline.task.name")
+
+ // CICDPipelineTaskRunIDKey is the attribute Key conforming to the
+ // "cicd.pipeline.task.run.id" semantic conventions. It represents the unique
+ // identifier of a task run within a pipeline.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "12097"
+ // Note: For a given pipeline run and task, the `cicd.pipeline.task.run.id` MUST
+ // be unique within that run. For the same task across different runs of the
+ // same pipeline, the `cicd.pipeline.task.run.id` MAY remain the same, enabling
+ // correlation of `cicd.pipeline.task.run.result` values across multiple
+ // pipeline runs.
+ CICDPipelineTaskRunIDKey = attribute.Key("cicd.pipeline.task.run.id")
+
+ // CICDPipelineTaskRunResultKey is the attribute Key conforming to the
+ // "cicd.pipeline.task.run.result" semantic conventions. It represents the
+ // result of a task run.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "success", "failure", "timeout", "skipped"
+ CICDPipelineTaskRunResultKey = attribute.Key("cicd.pipeline.task.run.result")
+
+ // CICDPipelineTaskRunURLFullKey is the attribute Key conforming to the
+ // "cicd.pipeline.task.run.url.full" semantic conventions. It represents the
+ // [URL] of the pipeline task run, providing the complete address in order to
+ // locate and identify the pipeline task run.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ // "https://github.com/open-telemetry/semantic-conventions/actions/runs/9753949763/job/26920038674?pr=1075"
+ //
+ // [URL]: https://wikipedia.org/wiki/URL
+ CICDPipelineTaskRunURLFullKey = attribute.Key("cicd.pipeline.task.run.url.full")
+
+ // CICDPipelineTaskTypeKey is the attribute Key conforming to the
+ // "cicd.pipeline.task.type" semantic conventions. It represents the type of the
+ // task within a pipeline.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "build", "test", "deploy"
+ CICDPipelineTaskTypeKey = attribute.Key("cicd.pipeline.task.type")
+
+ // CICDSystemComponentKey is the attribute Key conforming to the
+ // "cicd.system.component" semantic conventions. It represents the name of a
+ // component of the CICD system.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "controller", "scheduler", "agent"
+ CICDSystemComponentKey = attribute.Key("cicd.system.component")
+
+ // CICDWorkerIDKey is the attribute Key conforming to the "cicd.worker.id"
+ // semantic conventions. It represents the unique identifier of a worker within
+ // a CICD system.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "abc123", "10.0.1.2", "controller"
+ CICDWorkerIDKey = attribute.Key("cicd.worker.id")
+
+ // CICDWorkerNameKey is the attribute Key conforming to the "cicd.worker.name"
+ // semantic conventions. It represents the name of a worker within a CICD
+ // system.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "agent-abc", "controller", "Ubuntu LTS"
+ CICDWorkerNameKey = attribute.Key("cicd.worker.name")
+
+ // CICDWorkerStateKey is the attribute Key conforming to the "cicd.worker.state"
+ // semantic conventions. It represents the state of a CICD worker / agent.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "idle", "busy", "down"
+ CICDWorkerStateKey = attribute.Key("cicd.worker.state")
+
+ // CICDWorkerURLFullKey is the attribute Key conforming to the
+ // "cicd.worker.url.full" semantic conventions. It represents the [URL] of the
+ // worker, providing the complete address in order to locate and identify the
+ // worker.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "https://cicd.example.org/worker/abc123"
+ //
+ // [URL]: https://wikipedia.org/wiki/URL
+ CICDWorkerURLFullKey = attribute.Key("cicd.worker.url.full")
+)
+
+// CICDPipelineName returns an attribute KeyValue conforming to the
+// "cicd.pipeline.name" semantic conventions. It represents the human readable
+// name of the pipeline within a CI/CD system.
+func CICDPipelineName(val string) attribute.KeyValue {
+ return CICDPipelineNameKey.String(val)
+}
+
+// CICDPipelineRunID returns an attribute KeyValue conforming to the
+// "cicd.pipeline.run.id" semantic conventions. It represents the unique
+// identifier of a pipeline run within a CI/CD system.
+func CICDPipelineRunID(val string) attribute.KeyValue {
+ return CICDPipelineRunIDKey.String(val)
+}
+
+// CICDPipelineRunURLFull returns an attribute KeyValue conforming to the
+// "cicd.pipeline.run.url.full" semantic conventions. It represents the [URL] of
+// the pipeline run, providing the complete address in order to locate and
+// identify the pipeline run.
+//
+// [URL]: https://wikipedia.org/wiki/URL
+func CICDPipelineRunURLFull(val string) attribute.KeyValue {
+ return CICDPipelineRunURLFullKey.String(val)
+}
+
+// CICDPipelineTaskName returns an attribute KeyValue conforming to the
+// "cicd.pipeline.task.name" semantic conventions. It represents the human
+// readable name of a task within a pipeline. Task here most closely aligns with
+// a [computing process] in a pipeline. Other terms for tasks include commands,
+// steps, and procedures.
+//
+// [computing process]: https://wikipedia.org/wiki/Pipeline_(computing)
+func CICDPipelineTaskName(val string) attribute.KeyValue {
+ return CICDPipelineTaskNameKey.String(val)
+}
+
+// CICDPipelineTaskRunID returns an attribute KeyValue conforming to the
+// "cicd.pipeline.task.run.id" semantic conventions. It represents the unique
+// identifier of a task run within a pipeline.
+func CICDPipelineTaskRunID(val string) attribute.KeyValue {
+ return CICDPipelineTaskRunIDKey.String(val)
+}
+
+// CICDPipelineTaskRunURLFull returns an attribute KeyValue conforming to the
+// "cicd.pipeline.task.run.url.full" semantic conventions. It represents the
+// [URL] of the pipeline task run, providing the complete address in order to
+// locate and identify the pipeline task run.
+//
+// [URL]: https://wikipedia.org/wiki/URL
+func CICDPipelineTaskRunURLFull(val string) attribute.KeyValue {
+ return CICDPipelineTaskRunURLFullKey.String(val)
+}
+
+// CICDSystemComponent returns an attribute KeyValue conforming to the
+// "cicd.system.component" semantic conventions. It represents the name of a
+// component of the CICD system.
+func CICDSystemComponent(val string) attribute.KeyValue {
+ return CICDSystemComponentKey.String(val)
+}
+
+// CICDWorkerID returns an attribute KeyValue conforming to the "cicd.worker.id"
+// semantic conventions. It represents the unique identifier of a worker within a
+// CICD system.
+func CICDWorkerID(val string) attribute.KeyValue {
+ return CICDWorkerIDKey.String(val)
+}
+
+// CICDWorkerName returns an attribute KeyValue conforming to the
+// "cicd.worker.name" semantic conventions. It represents the name of a worker
+// within a CICD system.
+func CICDWorkerName(val string) attribute.KeyValue {
+ return CICDWorkerNameKey.String(val)
+}
+
+// CICDWorkerURLFull returns an attribute KeyValue conforming to the
+// "cicd.worker.url.full" semantic conventions. It represents the [URL] of the
+// worker, providing the complete address in order to locate and identify the
+// worker.
+//
+// [URL]: https://wikipedia.org/wiki/URL
+func CICDWorkerURLFull(val string) attribute.KeyValue {
+ return CICDWorkerURLFullKey.String(val)
+}
+
+// Enum values for cicd.pipeline.action.name
+var (
+ // The pipeline run is executing a build.
+ // Stability: development
+ CICDPipelineActionNameBuild = CICDPipelineActionNameKey.String("BUILD")
+ // The pipeline run is executing.
+ // Stability: development
+ CICDPipelineActionNameRun = CICDPipelineActionNameKey.String("RUN")
+ // The pipeline run is executing a sync.
+ // Stability: development
+ CICDPipelineActionNameSync = CICDPipelineActionNameKey.String("SYNC")
+)
+
+// Enum values for cicd.pipeline.result
+var (
+ // The pipeline run finished successfully.
+ // Stability: development
+ CICDPipelineResultSuccess = CICDPipelineResultKey.String("success")
+ // The pipeline run did not finish successfully, eg. due to a compile error or a
+ // failing test. Such failures are usually detected by non-zero exit codes of
+ // the tools executed in the pipeline run.
+ // Stability: development
+ CICDPipelineResultFailure = CICDPipelineResultKey.String("failure")
+ // The pipeline run failed due to an error in the CICD system, eg. due to the
+ // worker being killed.
+ // Stability: development
+ CICDPipelineResultError = CICDPipelineResultKey.String("error")
+ // A timeout caused the pipeline run to be interrupted.
+ // Stability: development
+ CICDPipelineResultTimeout = CICDPipelineResultKey.String("timeout")
+ // The pipeline run was cancelled, eg. by a user manually cancelling the
+ // pipeline run.
+ // Stability: development
+ CICDPipelineResultCancellation = CICDPipelineResultKey.String("cancellation")
+ // The pipeline run was skipped, eg. due to a precondition not being met.
+ // Stability: development
+ CICDPipelineResultSkip = CICDPipelineResultKey.String("skip")
+)
+
+// Enum values for cicd.pipeline.run.state
+var (
+ // The run pending state spans from the event triggering the pipeline run until
+ // the execution of the run starts (eg. time spent in a queue, provisioning
+ // agents, creating run resources).
+ //
+ // Stability: development
+ CICDPipelineRunStatePending = CICDPipelineRunStateKey.String("pending")
+ // The executing state spans the execution of any run tasks (eg. build, test).
+ // Stability: development
+ CICDPipelineRunStateExecuting = CICDPipelineRunStateKey.String("executing")
+ // The finalizing state spans from when the run has finished executing (eg.
+ // cleanup of run resources).
+ // Stability: development
+ CICDPipelineRunStateFinalizing = CICDPipelineRunStateKey.String("finalizing")
+)
+
+// Enum values for cicd.pipeline.task.run.result
+var (
+ // The task run finished successfully.
+ // Stability: development
+ CICDPipelineTaskRunResultSuccess = CICDPipelineTaskRunResultKey.String("success")
+ // The task run did not finish successfully, eg. due to a compile error or a
+ // failing test. Such failures are usually detected by non-zero exit codes of
+ // the tools executed in the task run.
+ // Stability: development
+ CICDPipelineTaskRunResultFailure = CICDPipelineTaskRunResultKey.String("failure")
+ // The task run failed due to an error in the CICD system, eg. due to the worker
+ // being killed.
+ // Stability: development
+ CICDPipelineTaskRunResultError = CICDPipelineTaskRunResultKey.String("error")
+ // A timeout caused the task run to be interrupted.
+ // Stability: development
+ CICDPipelineTaskRunResultTimeout = CICDPipelineTaskRunResultKey.String("timeout")
+ // The task run was cancelled, eg. by a user manually cancelling the task run.
+ // Stability: development
+ CICDPipelineTaskRunResultCancellation = CICDPipelineTaskRunResultKey.String("cancellation")
+ // The task run was skipped, eg. due to a precondition not being met.
+ // Stability: development
+ CICDPipelineTaskRunResultSkip = CICDPipelineTaskRunResultKey.String("skip")
+)
+
+// Enum values for cicd.pipeline.task.type
+var (
+ // build
+ // Stability: development
+ CICDPipelineTaskTypeBuild = CICDPipelineTaskTypeKey.String("build")
+ // test
+ // Stability: development
+ CICDPipelineTaskTypeTest = CICDPipelineTaskTypeKey.String("test")
+ // deploy
+ // Stability: development
+ CICDPipelineTaskTypeDeploy = CICDPipelineTaskTypeKey.String("deploy")
+)
+
+// Enum values for cicd.worker.state
+var (
+ // The worker is not performing work for the CICD system. It is available to the
+ // CICD system to perform work on (online / idle).
+ // Stability: development
+ CICDWorkerStateAvailable = CICDWorkerStateKey.String("available")
+ // The worker is performing work for the CICD system.
+ // Stability: development
+ CICDWorkerStateBusy = CICDWorkerStateKey.String("busy")
+ // The worker is not available to the CICD system (disconnected / down).
+ // Stability: development
+ CICDWorkerStateOffline = CICDWorkerStateKey.String("offline")
+)
+
+// Namespace: client
+const (
+ // ClientAddressKey is the attribute Key conforming to the "client.address"
+ // semantic conventions. It represents the client address - domain name if
+ // available without reverse DNS lookup; otherwise, IP address or Unix domain
+ // socket name.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ //
+ // Examples: "client.example.com", "10.1.2.80", "/tmp/my.sock"
+ // Note: When observed from the server side, and when communicating through an
+ // intermediary, `client.address` SHOULD represent the client address behind any
+ // intermediaries, for example proxies, if it's available.
+ ClientAddressKey = attribute.Key("client.address")
+
+ // ClientPortKey is the attribute Key conforming to the "client.port" semantic
+ // conventions. It represents the client port number.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ //
+ // Examples: 65123
+ // Note: When observed from the server side, and when communicating through an
+ // intermediary, `client.port` SHOULD represent the client port behind any
+ // intermediaries, for example proxies, if it's available.
+ ClientPortKey = attribute.Key("client.port")
+)
+
+// ClientAddress returns an attribute KeyValue conforming to the "client.address"
+// semantic conventions. It represents the client address - domain name if
+// available without reverse DNS lookup; otherwise, IP address or Unix domain
+// socket name.
+func ClientAddress(val string) attribute.KeyValue {
+ return ClientAddressKey.String(val)
+}
+
+// ClientPort returns an attribute KeyValue conforming to the "client.port"
+// semantic conventions. It represents the client port number.
+func ClientPort(val int) attribute.KeyValue {
+ return ClientPortKey.Int(val)
+}
+
+// Namespace: cloud
+const (
+ // CloudAccountIDKey is the attribute Key conforming to the "cloud.account.id"
+ // semantic conventions. It represents the cloud account ID the resource is
+ // assigned to.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "111111111111", "opentelemetry"
+ CloudAccountIDKey = attribute.Key("cloud.account.id")
+
+ // CloudAvailabilityZoneKey is the attribute Key conforming to the
+ // "cloud.availability_zone" semantic conventions. It represents the cloud
+ // regions often have multiple, isolated locations known as zones to increase
+ // availability. Availability zone represents the zone where the resource is
+ // running.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "us-east-1c"
+ // Note: Availability zones are called "zones" on Alibaba Cloud and Google
+ // Cloud.
+ CloudAvailabilityZoneKey = attribute.Key("cloud.availability_zone")
+
+ // CloudPlatformKey is the attribute Key conforming to the "cloud.platform"
+ // semantic conventions. It represents the cloud platform in use.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ // Note: The prefix of the service SHOULD match the one specified in
+ // `cloud.provider`.
+ CloudPlatformKey = attribute.Key("cloud.platform")
+
+ // CloudProviderKey is the attribute Key conforming to the "cloud.provider"
+ // semantic conventions. It represents the name of the cloud provider.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ CloudProviderKey = attribute.Key("cloud.provider")
+
+ // CloudRegionKey is the attribute Key conforming to the "cloud.region" semantic
+ // conventions. It represents the geographical region within a cloud provider.
+ // When associated with a resource, this attribute specifies the region where
+ // the resource operates. When calling services or APIs deployed on a cloud,
+ // this attribute identifies the region where the called destination is
+ // deployed.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "us-central1", "us-east-1"
+ // Note: Refer to your provider's docs to see the available regions, for example
+ // [Alibaba Cloud regions], [AWS regions], [Azure regions],
+ // [Google Cloud regions], or [Tencent Cloud regions].
+ //
+ // [Alibaba Cloud regions]: https://www.alibabacloud.com/help/doc-detail/40654.htm
+ // [AWS regions]: https://aws.amazon.com/about-aws/global-infrastructure/regions_az/
+ // [Azure regions]: https://azure.microsoft.com/global-infrastructure/geographies/
+ // [Google Cloud regions]: https://cloud.google.com/about/locations
+ // [Tencent Cloud regions]: https://www.tencentcloud.com/document/product/213/6091
+ CloudRegionKey = attribute.Key("cloud.region")
+
+ // CloudResourceIDKey is the attribute Key conforming to the "cloud.resource_id"
+ // semantic conventions. It represents the cloud provider-specific native
+ // identifier of the monitored cloud resource (e.g. an [ARN] on AWS, a
+ // [fully qualified resource ID] on Azure, a [full resource name] on GCP).
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "arn:aws:lambda:REGION:ACCOUNT_ID:function:my-function",
+ // "//run.googleapis.com/projects/PROJECT_ID/locations/LOCATION_ID/services/SERVICE_ID",
+ // "/subscriptions//resourceGroups/
+ // /providers/Microsoft.Web/sites//functions/"
+ // Note: On some cloud providers, it may not be possible to determine the full
+ // ID at startup,
+ // so it may be necessary to set `cloud.resource_id` as a span attribute
+ // instead.
+ //
+ // The exact value to use for `cloud.resource_id` depends on the cloud provider.
+ // The following well-known definitions MUST be used if you set this attribute
+ // and they apply:
+ //
+ // - **AWS Lambda:** The function [ARN].
+ // Take care not to use the "invoked ARN" directly but replace any
+ // [alias suffix]
+ // with the resolved function version, as the same runtime instance may be
+ // invocable with
+ // multiple different aliases.
+ // - **GCP:** The [URI of the resource]
+ // - **Azure:** The [Fully Qualified Resource ID] of the invoked function,
+ // *not* the function app, having the form
+ //
+ // `/subscriptions//resourceGroups//providers/Microsoft.Web/sites//functions/`
+ // .
+ // This means that a span attribute MUST be used, as an Azure function app
+ // can host multiple functions that would usually share
+ // a TracerProvider.
+ //
+ //
+ // [ARN]: https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html
+ // [fully qualified resource ID]: https://learn.microsoft.com/rest/api/resources/resources/get-by-id
+ // [full resource name]: https://google.aip.dev/122#full-resource-names
+ // [ARN]: https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html
+ // [alias suffix]: https://docs.aws.amazon.com/lambda/latest/dg/configuration-aliases.html
+ // [URI of the resource]: https://cloud.google.com/iam/docs/full-resource-names
+ // [Fully Qualified Resource ID]: https://learn.microsoft.com/rest/api/resources/resources/get-by-id
+ CloudResourceIDKey = attribute.Key("cloud.resource_id")
+)
+
+// CloudAccountID returns an attribute KeyValue conforming to the
+// "cloud.account.id" semantic conventions. It represents the cloud account ID
+// the resource is assigned to.
+func CloudAccountID(val string) attribute.KeyValue {
+ return CloudAccountIDKey.String(val)
+}
+
+// CloudAvailabilityZone returns an attribute KeyValue conforming to the
+// "cloud.availability_zone" semantic conventions. It represents the cloud
+// regions often have multiple, isolated locations known as zones to increase
+// availability. Availability zone represents the zone where the resource is
+// running.
+func CloudAvailabilityZone(val string) attribute.KeyValue {
+ return CloudAvailabilityZoneKey.String(val)
+}
+
+// CloudRegion returns an attribute KeyValue conforming to the "cloud.region"
+// semantic conventions. It represents the geographical region within a cloud
+// provider. When associated with a resource, this attribute specifies the region
+// where the resource operates. When calling services or APIs deployed on a
+// cloud, this attribute identifies the region where the called destination is
+// deployed.
+func CloudRegion(val string) attribute.KeyValue {
+ return CloudRegionKey.String(val)
+}
+
+// CloudResourceID returns an attribute KeyValue conforming to the
+// "cloud.resource_id" semantic conventions. It represents the cloud
+// provider-specific native identifier of the monitored cloud resource (e.g. an
+// [ARN] on AWS, a [fully qualified resource ID] on Azure, a [full resource name]
+// on GCP).
+//
+// [ARN]: https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html
+// [fully qualified resource ID]: https://learn.microsoft.com/rest/api/resources/resources/get-by-id
+// [full resource name]: https://google.aip.dev/122#full-resource-names
+func CloudResourceID(val string) attribute.KeyValue {
+ return CloudResourceIDKey.String(val)
+}
+
+// Enum values for cloud.platform
+var (
+ // Akamai Cloud Compute
+ // Stability: development
+ CloudPlatformAkamaiCloudCompute = CloudPlatformKey.String("akamai_cloud.compute")
+ // Alibaba Cloud Elastic Compute Service
+ // Stability: development
+ CloudPlatformAlibabaCloudECS = CloudPlatformKey.String("alibaba_cloud_ecs")
+ // Alibaba Cloud Function Compute
+ // Stability: development
+ CloudPlatformAlibabaCloudFC = CloudPlatformKey.String("alibaba_cloud_fc")
+ // Red Hat OpenShift on Alibaba Cloud
+ // Stability: development
+ CloudPlatformAlibabaCloudOpenShift = CloudPlatformKey.String("alibaba_cloud_openshift")
+ // AWS Elastic Compute Cloud
+ // Stability: development
+ CloudPlatformAWSEC2 = CloudPlatformKey.String("aws_ec2")
+ // AWS Elastic Container Service
+ // Stability: development
+ CloudPlatformAWSECS = CloudPlatformKey.String("aws_ecs")
+ // AWS Elastic Kubernetes Service
+ // Stability: development
+ CloudPlatformAWSEKS = CloudPlatformKey.String("aws_eks")
+ // AWS Lambda
+ // Stability: development
+ CloudPlatformAWSLambda = CloudPlatformKey.String("aws_lambda")
+ // AWS Elastic Beanstalk
+ // Stability: development
+ CloudPlatformAWSElasticBeanstalk = CloudPlatformKey.String("aws_elastic_beanstalk")
+ // AWS App Runner
+ // Stability: development
+ CloudPlatformAWSAppRunner = CloudPlatformKey.String("aws_app_runner")
+ // Red Hat OpenShift on AWS (ROSA)
+ // Stability: development
+ CloudPlatformAWSOpenShift = CloudPlatformKey.String("aws_openshift")
+ // Azure Virtual Machines
+ // Stability: development
+ CloudPlatformAzureVM = CloudPlatformKey.String("azure.vm")
+ // Azure Container Apps
+ // Stability: development
+ CloudPlatformAzureContainerApps = CloudPlatformKey.String("azure.container_apps")
+ // Azure Container Instances
+ // Stability: development
+ CloudPlatformAzureContainerInstances = CloudPlatformKey.String("azure.container_instances")
+ // Azure Kubernetes Service
+ // Stability: development
+ CloudPlatformAzureAKS = CloudPlatformKey.String("azure.aks")
+ // Azure Functions
+ // Stability: development
+ CloudPlatformAzureFunctions = CloudPlatformKey.String("azure.functions")
+ // Azure App Service
+ // Stability: development
+ CloudPlatformAzureAppService = CloudPlatformKey.String("azure.app_service")
+ // Azure Red Hat OpenShift
+ // Stability: development
+ CloudPlatformAzureOpenShift = CloudPlatformKey.String("azure.openshift")
+ // Google Vertex AI Agent Engine
+ // Stability: development
+ CloudPlatformGCPAgentEngine = CloudPlatformKey.String("gcp.agent_engine")
+ // Google Bare Metal Solution (BMS)
+ // Stability: development
+ CloudPlatformGCPBareMetalSolution = CloudPlatformKey.String("gcp_bare_metal_solution")
+ // Google Cloud Compute Engine (GCE)
+ // Stability: development
+ CloudPlatformGCPComputeEngine = CloudPlatformKey.String("gcp_compute_engine")
+ // Google Cloud Run
+ // Stability: development
+ CloudPlatformGCPCloudRun = CloudPlatformKey.String("gcp_cloud_run")
+ // Google Cloud Kubernetes Engine (GKE)
+ // Stability: development
+ CloudPlatformGCPKubernetesEngine = CloudPlatformKey.String("gcp_kubernetes_engine")
+ // Google Cloud Functions (GCF)
+ // Stability: development
+ CloudPlatformGCPCloudFunctions = CloudPlatformKey.String("gcp_cloud_functions")
+ // Google Cloud App Engine (GAE)
+ // Stability: development
+ CloudPlatformGCPAppEngine = CloudPlatformKey.String("gcp_app_engine")
+ // Red Hat OpenShift on Google Cloud
+ // Stability: development
+ CloudPlatformGCPOpenShift = CloudPlatformKey.String("gcp_openshift")
+ // Server on Hetzner Cloud
+ // Stability: development
+ CloudPlatformHetznerCloudServer = CloudPlatformKey.String("hetzner.cloud_server")
+ // Red Hat OpenShift on IBM Cloud
+ // Stability: development
+ CloudPlatformIBMCloudOpenShift = CloudPlatformKey.String("ibm_cloud_openshift")
+ // Compute on Oracle Cloud Infrastructure (OCI)
+ // Stability: development
+ CloudPlatformOracleCloudCompute = CloudPlatformKey.String("oracle_cloud_compute")
+ // Kubernetes Engine (OKE) on Oracle Cloud Infrastructure (OCI)
+ // Stability: development
+ CloudPlatformOracleCloudOKE = CloudPlatformKey.String("oracle_cloud_oke")
+ // Tencent Cloud Cloud Virtual Machine (CVM)
+ // Stability: development
+ CloudPlatformTencentCloudCVM = CloudPlatformKey.String("tencent_cloud_cvm")
+ // Tencent Cloud Elastic Kubernetes Service (EKS)
+ // Stability: development
+ CloudPlatformTencentCloudEKS = CloudPlatformKey.String("tencent_cloud_eks")
+ // Tencent Cloud Serverless Cloud Function (SCF)
+ // Stability: development
+ CloudPlatformTencentCloudSCF = CloudPlatformKey.String("tencent_cloud_scf")
+ // Vultr Cloud Compute
+ // Stability: development
+ CloudPlatformVultrCloudCompute = CloudPlatformKey.String("vultr.cloud_compute")
+)
+
+// Enum values for cloud.provider
+var (
+ // Akamai Cloud
+ // Stability: development
+ CloudProviderAkamaiCloud = CloudProviderKey.String("akamai_cloud")
+ // Alibaba Cloud
+ // Stability: development
+ CloudProviderAlibabaCloud = CloudProviderKey.String("alibaba_cloud")
+ // Amazon Web Services
+ // Stability: development
+ CloudProviderAWS = CloudProviderKey.String("aws")
+ // Microsoft Azure
+ // Stability: development
+ CloudProviderAzure = CloudProviderKey.String("azure")
+ // Google Cloud Platform
+ // Stability: development
+ CloudProviderGCP = CloudProviderKey.String("gcp")
+ // Heroku Platform as a Service
+ // Stability: development
+ CloudProviderHeroku = CloudProviderKey.String("heroku")
+ // Hetzner
+ // Stability: development
+ CloudProviderHetzner = CloudProviderKey.String("hetzner")
+ // IBM Cloud
+ // Stability: development
+ CloudProviderIBMCloud = CloudProviderKey.String("ibm_cloud")
+ // Oracle Cloud Infrastructure (OCI)
+ // Stability: development
+ CloudProviderOracleCloud = CloudProviderKey.String("oracle_cloud")
+ // Tencent Cloud
+ // Stability: development
+ CloudProviderTencentCloud = CloudProviderKey.String("tencent_cloud")
+ // Vultr
+ // Stability: development
+ CloudProviderVultr = CloudProviderKey.String("vultr")
+)
+
+// Namespace: cloudevents
+const (
+ // CloudEventsEventIDKey is the attribute Key conforming to the
+ // "cloudevents.event_id" semantic conventions. It represents the [event_id]
+ // uniquely identifies the event.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "123e4567-e89b-12d3-a456-426614174000", "0001"
+ //
+ // [event_id]: https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#id
+ CloudEventsEventIDKey = attribute.Key("cloudevents.event_id")
+
+ // CloudEventsEventSourceKey is the attribute Key conforming to the
+ // "cloudevents.event_source" semantic conventions. It represents the [source]
+ // identifies the context in which an event happened.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "https://github.com/cloudevents", "/cloudevents/spec/pull/123",
+ // "my-service"
+ //
+ // [source]: https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#source-1
+ CloudEventsEventSourceKey = attribute.Key("cloudevents.event_source")
+
+ // CloudEventsEventSpecVersionKey is the attribute Key conforming to the
+ // "cloudevents.event_spec_version" semantic conventions. It represents the
+ // [version of the CloudEvents specification] which the event uses.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 1.0
+ //
+ // [version of the CloudEvents specification]: https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#specversion
+ CloudEventsEventSpecVersionKey = attribute.Key("cloudevents.event_spec_version")
+
+ // CloudEventsEventSubjectKey is the attribute Key conforming to the
+ // "cloudevents.event_subject" semantic conventions. It represents the [subject]
+ // of the event in the context of the event producer (identified by source).
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: mynewfile.jpg
+ //
+ // [subject]: https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#subject
+ CloudEventsEventSubjectKey = attribute.Key("cloudevents.event_subject")
+
+ // CloudEventsEventTypeKey is the attribute Key conforming to the
+ // "cloudevents.event_type" semantic conventions. It represents the [event_type]
+ // contains a value describing the type of event related to the originating
+ // occurrence.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "com.github.pull_request.opened", "com.example.object.deleted.v2"
+ //
+ // [event_type]: https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#type
+ CloudEventsEventTypeKey = attribute.Key("cloudevents.event_type")
+)
+
+// CloudEventsEventID returns an attribute KeyValue conforming to the
+// "cloudevents.event_id" semantic conventions. It represents the [event_id]
+// uniquely identifies the event.
+//
+// [event_id]: https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#id
+func CloudEventsEventID(val string) attribute.KeyValue {
+ return CloudEventsEventIDKey.String(val)
+}
+
+// CloudEventsEventSource returns an attribute KeyValue conforming to the
+// "cloudevents.event_source" semantic conventions. It represents the [source]
+// identifies the context in which an event happened.
+//
+// [source]: https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#source-1
+func CloudEventsEventSource(val string) attribute.KeyValue {
+ return CloudEventsEventSourceKey.String(val)
+}
+
+// CloudEventsEventSpecVersion returns an attribute KeyValue conforming to the
+// "cloudevents.event_spec_version" semantic conventions. It represents the
+// [version of the CloudEvents specification] which the event uses.
+//
+// [version of the CloudEvents specification]: https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#specversion
+func CloudEventsEventSpecVersion(val string) attribute.KeyValue {
+ return CloudEventsEventSpecVersionKey.String(val)
+}
+
+// CloudEventsEventSubject returns an attribute KeyValue conforming to the
+// "cloudevents.event_subject" semantic conventions. It represents the [subject]
+// of the event in the context of the event producer (identified by source).
+//
+// [subject]: https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#subject
+func CloudEventsEventSubject(val string) attribute.KeyValue {
+ return CloudEventsEventSubjectKey.String(val)
+}
+
+// CloudEventsEventType returns an attribute KeyValue conforming to the
+// "cloudevents.event_type" semantic conventions. It represents the [event_type]
+// contains a value describing the type of event related to the originating
+// occurrence.
+//
+// [event_type]: https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#type
+func CloudEventsEventType(val string) attribute.KeyValue {
+ return CloudEventsEventTypeKey.String(val)
+}
+
+// Namespace: cloudfoundry
+const (
+ // CloudFoundryAppIDKey is the attribute Key conforming to the
+ // "cloudfoundry.app.id" semantic conventions. It represents the guid of the
+ // application.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "218fc5a9-a5f1-4b54-aa05-46717d0ab26d"
+ // Note: Application instrumentation should use the value from environment
+ // variable `VCAP_APPLICATION.application_id`. This is the same value as
+ // reported by `cf app --guid`.
+ CloudFoundryAppIDKey = attribute.Key("cloudfoundry.app.id")
+
+ // CloudFoundryAppInstanceIDKey is the attribute Key conforming to the
+ // "cloudfoundry.app.instance.id" semantic conventions. It represents the index
+ // of the application instance. 0 when just one instance is active.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "0", "1"
+ // Note: CloudFoundry defines the `instance_id` in the [Loggregator v2 envelope]
+ // .
+ // It is used for logs and metrics emitted by CloudFoundry. It is
+ // supposed to contain the application instance index for applications
+ // deployed on the runtime.
+ //
+ // Application instrumentation should use the value from environment
+ // variable `CF_INSTANCE_INDEX`.
+ //
+ // [Loggregator v2 envelope]: https://github.com/cloudfoundry/loggregator-api#v2-envelope
+ CloudFoundryAppInstanceIDKey = attribute.Key("cloudfoundry.app.instance.id")
+
+ // CloudFoundryAppNameKey is the attribute Key conforming to the
+ // "cloudfoundry.app.name" semantic conventions. It represents the name of the
+ // application.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "my-app-name"
+ // Note: Application instrumentation should use the value from environment
+ // variable `VCAP_APPLICATION.application_name`. This is the same value
+ // as reported by `cf apps`.
+ CloudFoundryAppNameKey = attribute.Key("cloudfoundry.app.name")
+
+ // CloudFoundryOrgIDKey is the attribute Key conforming to the
+ // "cloudfoundry.org.id" semantic conventions. It represents the guid of the
+ // CloudFoundry org the application is running in.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "218fc5a9-a5f1-4b54-aa05-46717d0ab26d"
+ // Note: Application instrumentation should use the value from environment
+ // variable `VCAP_APPLICATION.org_id`. This is the same value as
+ // reported by `cf org --guid`.
+ CloudFoundryOrgIDKey = attribute.Key("cloudfoundry.org.id")
+
+ // CloudFoundryOrgNameKey is the attribute Key conforming to the
+ // "cloudfoundry.org.name" semantic conventions. It represents the name of the
+ // CloudFoundry organization the app is running in.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "my-org-name"
+ // Note: Application instrumentation should use the value from environment
+ // variable `VCAP_APPLICATION.org_name`. This is the same value as
+ // reported by `cf orgs`.
+ CloudFoundryOrgNameKey = attribute.Key("cloudfoundry.org.name")
+
+ // CloudFoundryProcessIDKey is the attribute Key conforming to the
+ // "cloudfoundry.process.id" semantic conventions. It represents the UID
+ // identifying the process.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "218fc5a9-a5f1-4b54-aa05-46717d0ab26d"
+ // Note: Application instrumentation should use the value from environment
+ // variable `VCAP_APPLICATION.process_id`. It is supposed to be equal to
+ // `VCAP_APPLICATION.app_id` for applications deployed to the runtime.
+ // For system components, this could be the actual PID.
+ CloudFoundryProcessIDKey = attribute.Key("cloudfoundry.process.id")
+
+ // CloudFoundryProcessTypeKey is the attribute Key conforming to the
+ // "cloudfoundry.process.type" semantic conventions. It represents the type of
+ // process.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "web"
+ // Note: CloudFoundry applications can consist of multiple jobs. Usually the
+ // main process will be of type `web`. There can be additional background
+ // tasks or side-cars with different process types.
+ CloudFoundryProcessTypeKey = attribute.Key("cloudfoundry.process.type")
+
+ // CloudFoundrySpaceIDKey is the attribute Key conforming to the
+ // "cloudfoundry.space.id" semantic conventions. It represents the guid of the
+ // CloudFoundry space the application is running in.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "218fc5a9-a5f1-4b54-aa05-46717d0ab26d"
+ // Note: Application instrumentation should use the value from environment
+ // variable `VCAP_APPLICATION.space_id`. This is the same value as
+ // reported by `cf space --guid`.
+ CloudFoundrySpaceIDKey = attribute.Key("cloudfoundry.space.id")
+
+ // CloudFoundrySpaceNameKey is the attribute Key conforming to the
+ // "cloudfoundry.space.name" semantic conventions. It represents the name of the
+ // CloudFoundry space the application is running in.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "my-space-name"
+ // Note: Application instrumentation should use the value from environment
+ // variable `VCAP_APPLICATION.space_name`. This is the same value as
+ // reported by `cf spaces`.
+ CloudFoundrySpaceNameKey = attribute.Key("cloudfoundry.space.name")
+
+ // CloudFoundrySystemIDKey is the attribute Key conforming to the
+ // "cloudfoundry.system.id" semantic conventions. It represents a guid or
+ // another name describing the event source.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "cf/gorouter"
+ // Note: CloudFoundry defines the `source_id` in the [Loggregator v2 envelope].
+ // It is used for logs and metrics emitted by CloudFoundry. It is
+ // supposed to contain the component name, e.g. "gorouter", for
+ // CloudFoundry components.
+ //
+ // When system components are instrumented, values from the
+ // [Bosh spec]
+ // should be used. The `system.id` should be set to
+ // `spec.deployment/spec.name`.
+ //
+ // [Loggregator v2 envelope]: https://github.com/cloudfoundry/loggregator-api#v2-envelope
+ // [Bosh spec]: https://bosh.io/docs/jobs/#properties-spec
+ CloudFoundrySystemIDKey = attribute.Key("cloudfoundry.system.id")
+
+ // CloudFoundrySystemInstanceIDKey is the attribute Key conforming to the
+ // "cloudfoundry.system.instance.id" semantic conventions. It represents a guid
+ // describing the concrete instance of the event source.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "218fc5a9-a5f1-4b54-aa05-46717d0ab26d"
+ // Note: CloudFoundry defines the `instance_id` in the [Loggregator v2 envelope]
+ // .
+ // It is used for logs and metrics emitted by CloudFoundry. It is
+ // supposed to contain the vm id for CloudFoundry components.
+ //
+ // When system components are instrumented, values from the
+ // [Bosh spec]
+ // should be used. The `system.instance.id` should be set to `spec.id`.
+ //
+ // [Loggregator v2 envelope]: https://github.com/cloudfoundry/loggregator-api#v2-envelope
+ // [Bosh spec]: https://bosh.io/docs/jobs/#properties-spec
+ CloudFoundrySystemInstanceIDKey = attribute.Key("cloudfoundry.system.instance.id")
+)
+
+// CloudFoundryAppID returns an attribute KeyValue conforming to the
+// "cloudfoundry.app.id" semantic conventions. It represents the guid of the
+// application.
+func CloudFoundryAppID(val string) attribute.KeyValue {
+ return CloudFoundryAppIDKey.String(val)
+}
+
+// CloudFoundryAppInstanceID returns an attribute KeyValue conforming to the
+// "cloudfoundry.app.instance.id" semantic conventions. It represents the index
+// of the application instance. 0 when just one instance is active.
+func CloudFoundryAppInstanceID(val string) attribute.KeyValue {
+ return CloudFoundryAppInstanceIDKey.String(val)
+}
+
+// CloudFoundryAppName returns an attribute KeyValue conforming to the
+// "cloudfoundry.app.name" semantic conventions. It represents the name of the
+// application.
+func CloudFoundryAppName(val string) attribute.KeyValue {
+ return CloudFoundryAppNameKey.String(val)
+}
+
+// CloudFoundryOrgID returns an attribute KeyValue conforming to the
+// "cloudfoundry.org.id" semantic conventions. It represents the guid of the
+// CloudFoundry org the application is running in.
+func CloudFoundryOrgID(val string) attribute.KeyValue {
+ return CloudFoundryOrgIDKey.String(val)
+}
+
+// CloudFoundryOrgName returns an attribute KeyValue conforming to the
+// "cloudfoundry.org.name" semantic conventions. It represents the name of the
+// CloudFoundry organization the app is running in.
+func CloudFoundryOrgName(val string) attribute.KeyValue {
+ return CloudFoundryOrgNameKey.String(val)
+}
+
+// CloudFoundryProcessID returns an attribute KeyValue conforming to the
+// "cloudfoundry.process.id" semantic conventions. It represents the UID
+// identifying the process.
+func CloudFoundryProcessID(val string) attribute.KeyValue {
+ return CloudFoundryProcessIDKey.String(val)
+}
+
+// CloudFoundryProcessType returns an attribute KeyValue conforming to the
+// "cloudfoundry.process.type" semantic conventions. It represents the type of
+// process.
+func CloudFoundryProcessType(val string) attribute.KeyValue {
+ return CloudFoundryProcessTypeKey.String(val)
+}
+
+// CloudFoundrySpaceID returns an attribute KeyValue conforming to the
+// "cloudfoundry.space.id" semantic conventions. It represents the guid of the
+// CloudFoundry space the application is running in.
+func CloudFoundrySpaceID(val string) attribute.KeyValue {
+ return CloudFoundrySpaceIDKey.String(val)
+}
+
+// CloudFoundrySpaceName returns an attribute KeyValue conforming to the
+// "cloudfoundry.space.name" semantic conventions. It represents the name of the
+// CloudFoundry space the application is running in.
+func CloudFoundrySpaceName(val string) attribute.KeyValue {
+ return CloudFoundrySpaceNameKey.String(val)
+}
+
+// CloudFoundrySystemID returns an attribute KeyValue conforming to the
+// "cloudfoundry.system.id" semantic conventions. It represents a guid or another
+// name describing the event source.
+func CloudFoundrySystemID(val string) attribute.KeyValue {
+ return CloudFoundrySystemIDKey.String(val)
+}
+
+// CloudFoundrySystemInstanceID returns an attribute KeyValue conforming to the
+// "cloudfoundry.system.instance.id" semantic conventions. It represents a guid
+// describing the concrete instance of the event source.
+func CloudFoundrySystemInstanceID(val string) attribute.KeyValue {
+ return CloudFoundrySystemInstanceIDKey.String(val)
+}
+
+// Namespace: code
+const (
+ // CodeColumnNumberKey is the attribute Key conforming to the
+ // "code.column.number" semantic conventions. It represents the column number in
+ // `code.file.path` best representing the operation. It SHOULD point within the
+ // code unit named in `code.function.name`. This attribute MUST NOT be used on
+ // the Profile signal since the data is already captured in 'message Line'. This
+ // constraint is imposed to prevent redundancy and maintain data integrity.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ CodeColumnNumberKey = attribute.Key("code.column.number")
+
+ // CodeFilePathKey is the attribute Key conforming to the "code.file.path"
+ // semantic conventions. It represents the source code file name that identifies
+ // the code unit as uniquely as possible (preferably an absolute file path).
+ // This attribute MUST NOT be used on the Profile signal since the data is
+ // already captured in 'message Function'. This constraint is imposed to prevent
+ // redundancy and maintain data integrity.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ //
+ // Examples: /usr/local/MyApplication/content_root/app/index.php
+ CodeFilePathKey = attribute.Key("code.file.path")
+
+ // CodeFunctionNameKey is the attribute Key conforming to the
+ // "code.function.name" semantic conventions. It represents the method or
+ // function fully-qualified name without arguments. The value should fit the
+ // natural representation of the language runtime, which is also likely the same
+ // used within `code.stacktrace` attribute value. This attribute MUST NOT be
+ // used on the Profile signal since the data is already captured in 'message
+ // Function'. This constraint is imposed to prevent redundancy and maintain data
+ // integrity.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ //
+ // Examples: "com.example.MyHttpService.serveRequest",
+ // "GuzzleHttp\Client::transfer", "fopen"
+ // Note: Values and format depends on each language runtime, thus it is
+ // impossible to provide an exhaustive list of examples.
+ // The values are usually the same (or prefixes of) the ones found in native
+ // stack trace representation stored in
+ // `code.stacktrace` without information on arguments.
+ //
+ // Examples:
+ //
+ // - Java method: `com.example.MyHttpService.serveRequest`
+ // - Java anonymous class method: `com.mycompany.Main$1.myMethod`
+ // - Java lambda method:
+ // `com.mycompany.Main$$Lambda/0x0000748ae4149c00.myMethod`
+ // - PHP function: `GuzzleHttp\Client::transfer`
+ // - Go function: `github.com/my/repo/pkg.foo.func5`
+ // - Elixir: `OpenTelemetry.Ctx.new`
+ // - Erlang: `opentelemetry_ctx:new`
+ // - Rust: `playground::my_module::my_cool_func`
+ // - C function: `fopen`
+ CodeFunctionNameKey = attribute.Key("code.function.name")
+
+ // CodeLineNumberKey is the attribute Key conforming to the "code.line.number"
+ // semantic conventions. It represents the line number in `code.file.path` best
+ // representing the operation. It SHOULD point within the code unit named in
+ // `code.function.name`. This attribute MUST NOT be used on the Profile signal
+ // since the data is already captured in 'message Line'. This constraint is
+ // imposed to prevent redundancy and maintain data integrity.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ CodeLineNumberKey = attribute.Key("code.line.number")
+
+ // CodeStacktraceKey is the attribute Key conforming to the "code.stacktrace"
+ // semantic conventions. It represents a stacktrace as a string in the natural
+ // representation for the language runtime. The representation is identical to
+ // [`exception.stacktrace`]. This attribute MUST NOT be used on the Profile
+ // signal since the data is already captured in 'message Location'. This
+ // constraint is imposed to prevent redundancy and maintain data integrity.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ //
+ // Examples: at com.example.GenerateTrace.methodB(GenerateTrace.java:13)\n at
+ // com.example.GenerateTrace.methodA(GenerateTrace.java:9)\n at
+ // com.example.GenerateTrace.main(GenerateTrace.java:5)
+ //
+ // [`exception.stacktrace`]: /docs/exceptions/exceptions-spans.md#stacktrace-representation
+ CodeStacktraceKey = attribute.Key("code.stacktrace")
+)
+
+// CodeColumnNumber returns an attribute KeyValue conforming to the
+// "code.column.number" semantic conventions. It represents the column number in
+// `code.file.path` best representing the operation. It SHOULD point within the
+// code unit named in `code.function.name`. This attribute MUST NOT be used on
+// the Profile signal since the data is already captured in 'message Line'. This
+// constraint is imposed to prevent redundancy and maintain data integrity.
+func CodeColumnNumber(val int) attribute.KeyValue {
+ return CodeColumnNumberKey.Int(val)
+}
+
+// CodeFilePath returns an attribute KeyValue conforming to the "code.file.path"
+// semantic conventions. It represents the source code file name that identifies
+// the code unit as uniquely as possible (preferably an absolute file path). This
+// attribute MUST NOT be used on the Profile signal since the data is already
+// captured in 'message Function'. This constraint is imposed to prevent
+// redundancy and maintain data integrity.
+func CodeFilePath(val string) attribute.KeyValue {
+ return CodeFilePathKey.String(val)
+}
+
+// CodeFunctionName returns an attribute KeyValue conforming to the
+// "code.function.name" semantic conventions. It represents the method or
+// function fully-qualified name without arguments. The value should fit the
+// natural representation of the language runtime, which is also likely the same
+// used within `code.stacktrace` attribute value. This attribute MUST NOT be used
+// on the Profile signal since the data is already captured in 'message
+// Function'. This constraint is imposed to prevent redundancy and maintain data
+// integrity.
+func CodeFunctionName(val string) attribute.KeyValue {
+ return CodeFunctionNameKey.String(val)
+}
+
+// CodeLineNumber returns an attribute KeyValue conforming to the
+// "code.line.number" semantic conventions. It represents the line number in
+// `code.file.path` best representing the operation. It SHOULD point within the
+// code unit named in `code.function.name`. This attribute MUST NOT be used on
+// the Profile signal since the data is already captured in 'message Line'. This
+// constraint is imposed to prevent redundancy and maintain data integrity.
+func CodeLineNumber(val int) attribute.KeyValue {
+ return CodeLineNumberKey.Int(val)
+}
+
+// CodeStacktrace returns an attribute KeyValue conforming to the
+// "code.stacktrace" semantic conventions. It represents a stacktrace as a string
+// in the natural representation for the language runtime. The representation is
+// identical to [`exception.stacktrace`]. This attribute MUST NOT be used on the
+// Profile signal since the data is already captured in 'message Location'. This
+// constraint is imposed to prevent redundancy and maintain data integrity.
+//
+// [`exception.stacktrace`]: /docs/exceptions/exceptions-spans.md#stacktrace-representation
+func CodeStacktrace(val string) attribute.KeyValue {
+ return CodeStacktraceKey.String(val)
+}
+
+// Namespace: container
+const (
+ // ContainerCommandKey is the attribute Key conforming to the
+ // "container.command" semantic conventions. It represents the command used to
+ // run the container (i.e. the command name).
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "otelcontribcol"
+ // Note: If using embedded credentials or sensitive data, it is recommended to
+ // remove them to prevent potential leakage.
+ ContainerCommandKey = attribute.Key("container.command")
+
+ // ContainerCommandArgsKey is the attribute Key conforming to the
+ // "container.command_args" semantic conventions. It represents the all the
+ // command arguments (including the command/executable itself) run by the
+ // container.
+ //
+ // Type: string[]
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "otelcontribcol", "--config", "config.yaml"
+ ContainerCommandArgsKey = attribute.Key("container.command_args")
+
+ // ContainerCommandLineKey is the attribute Key conforming to the
+ // "container.command_line" semantic conventions. It represents the full command
+ // run by the container as a single string representing the full command.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "otelcontribcol --config config.yaml"
+ ContainerCommandLineKey = attribute.Key("container.command_line")
+
+ // ContainerCSIPluginNameKey is the attribute Key conforming to the
+ // "container.csi.plugin.name" semantic conventions. It represents the name of
+ // the CSI ([Container Storage Interface]) plugin used by the volume.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "pd.csi.storage.gke.io"
+ // Note: This can sometimes be referred to as a "driver" in CSI implementations.
+ // This should represent the `name` field of the GetPluginInfo RPC.
+ //
+ // [Container Storage Interface]: https://github.com/container-storage-interface/spec
+ ContainerCSIPluginNameKey = attribute.Key("container.csi.plugin.name")
+
+ // ContainerCSIVolumeIDKey is the attribute Key conforming to the
+ // "container.csi.volume.id" semantic conventions. It represents the unique
+ // volume ID returned by the CSI ([Container Storage Interface]) plugin.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "projects/my-gcp-project/zones/my-gcp-zone/disks/my-gcp-disk"
+ // Note: This can sometimes be referred to as a "volume handle" in CSI
+ // implementations. This should represent the `Volume.volume_id` field in CSI
+ // spec.
+ //
+ // [Container Storage Interface]: https://github.com/container-storage-interface/spec
+ ContainerCSIVolumeIDKey = attribute.Key("container.csi.volume.id")
+
+ // ContainerIDKey is the attribute Key conforming to the "container.id" semantic
+ // conventions. It represents the container ID. Usually a UUID, as for example
+ // used to [identify Docker containers]. The UUID might be abbreviated.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Release_Candidate
+ //
+ // Examples: "a3bf90e006b2"
+ //
+ // [identify Docker containers]: https://docs.docker.com/engine/containers/run/#container-identification
+ ContainerIDKey = attribute.Key("container.id")
+
+ // ContainerImageIDKey is the attribute Key conforming to the
+ // "container.image.id" semantic conventions. It represents the runtime specific
+ // image identifier. Usually a hash algorithm followed by a UUID.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ // "sha256:19c92d0a00d1b66d897bceaa7319bee0dd38a10a851c60bcec9474aa3f01e50f"
+ // Note: Docker defines a sha256 of the image id; `container.image.id`
+ // corresponds to the `Image` field from the Docker container inspect [API]
+ // endpoint.
+ // K8s defines a link to the container registry repository with digest
+ // `"imageID": "registry.azurecr.io /namespace/service/dockerfile@sha256:bdeabd40c3a8a492eaf9e8e44d0ebbb84bac7ee25ac0cf8a7159d25f62555625"`
+ // .
+ // The ID is assigned by the container runtime and can vary in different
+ // environments. Consider using `oci.manifest.digest` if it is important to
+ // identify the same image in different environments/runtimes.
+ //
+ // [API]: https://docs.docker.com/reference/api/engine/version/v1.52/#tag/Container/operation/ContainerInspect
+ ContainerImageIDKey = attribute.Key("container.image.id")
+
+ // ContainerImageNameKey is the attribute Key conforming to the
+ // "container.image.name" semantic conventions. It represents the name of the
+ // image the container was built on.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Release_Candidate
+ //
+ // Examples: "gcr.io/opentelemetry/operator"
+ ContainerImageNameKey = attribute.Key("container.image.name")
+
+ // ContainerImageRepoDigestsKey is the attribute Key conforming to the
+ // "container.image.repo_digests" semantic conventions. It represents the repo
+ // digests of the container image as provided by the container runtime.
+ //
+ // Type: string[]
+ // RequirementLevel: Recommended
+ // Stability: Release_Candidate
+ //
+ // Examples:
+ // "example@sha256:afcc7f1ac1b49db317a7196c902e61c6c3c4607d63599ee1a82d702d249a0ccb",
+ // "internal.registry.example.com:5000/example@sha256:b69959407d21e8a062e0416bf13405bb2b71ed7a84dde4158ebafacfa06f5578"
+ // Note: [Docker] and [CRI] report those under the `RepoDigests` field.
+ //
+ // [Docker]: https://docs.docker.com/reference/api/engine/version/v1.52/#tag/Image/operation/ImageInspect
+ // [CRI]: https://github.com/kubernetes/cri-api/blob/c75ef5b473bbe2d0a4fc92f82235efd665ea8e9f/pkg/apis/runtime/v1/api.proto#L1237-L1238
+ ContainerImageRepoDigestsKey = attribute.Key("container.image.repo_digests")
+
+ // ContainerImageTagsKey is the attribute Key conforming to the
+ // "container.image.tags" semantic conventions. It represents the container
+ // image tags. An example can be found in [Docker Image Inspect]. Should be only
+ // the `` section of the full name for example from
+ // `registry.example.com/my-org/my-image:`.
+ //
+ // Type: string[]
+ // RequirementLevel: Recommended
+ // Stability: Release_Candidate
+ //
+ // Examples: "v1.27.1", "3.5.7-0"
+ //
+ // [Docker Image Inspect]: https://docs.docker.com/reference/api/engine/version/v1.52/#tag/Image/operation/ImageInspect
+ ContainerImageTagsKey = attribute.Key("container.image.tags")
+
+ // ContainerNameKey is the attribute Key conforming to the "container.name"
+ // semantic conventions. It represents the container name used by container
+ // runtime.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "opentelemetry-autoconf"
+ ContainerNameKey = attribute.Key("container.name")
+
+ // ContainerRuntimeDescriptionKey is the attribute Key conforming to the
+ // "container.runtime.description" semantic conventions. It represents a
+ // description about the runtime which could include, for example details about
+ // the CRI/API version being used or other customizations.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "docker://19.3.1 - CRI: 1.22.0"
+ ContainerRuntimeDescriptionKey = attribute.Key("container.runtime.description")
+
+ // ContainerRuntimeNameKey is the attribute Key conforming to the
+ // "container.runtime.name" semantic conventions. It represents the container
+ // runtime managing this container.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "docker", "containerd", "rkt"
+ ContainerRuntimeNameKey = attribute.Key("container.runtime.name")
+
+ // ContainerRuntimeVersionKey is the attribute Key conforming to the
+ // "container.runtime.version" semantic conventions. It represents the version
+ // of the runtime of this process, as returned by the runtime without
+ // modification.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 1.0.0
+ ContainerRuntimeVersionKey = attribute.Key("container.runtime.version")
+)
+
+// ContainerCommand returns an attribute KeyValue conforming to the
+// "container.command" semantic conventions. It represents the command used to
+// run the container (i.e. the command name).
+func ContainerCommand(val string) attribute.KeyValue {
+ return ContainerCommandKey.String(val)
+}
+
+// ContainerCommandArgs returns an attribute KeyValue conforming to the
+// "container.command_args" semantic conventions. It represents the all the
+// command arguments (including the command/executable itself) run by the
+// container.
+func ContainerCommandArgs(val ...string) attribute.KeyValue {
+ return ContainerCommandArgsKey.StringSlice(val)
+}
+
+// ContainerCommandLine returns an attribute KeyValue conforming to the
+// "container.command_line" semantic conventions. It represents the full command
+// run by the container as a single string representing the full command.
+func ContainerCommandLine(val string) attribute.KeyValue {
+ return ContainerCommandLineKey.String(val)
+}
+
+// ContainerCSIPluginName returns an attribute KeyValue conforming to the
+// "container.csi.plugin.name" semantic conventions. It represents the name of
+// the CSI ([Container Storage Interface]) plugin used by the volume.
+//
+// [Container Storage Interface]: https://github.com/container-storage-interface/spec
+func ContainerCSIPluginName(val string) attribute.KeyValue {
+ return ContainerCSIPluginNameKey.String(val)
+}
+
+// ContainerCSIVolumeID returns an attribute KeyValue conforming to the
+// "container.csi.volume.id" semantic conventions. It represents the unique
+// volume ID returned by the CSI ([Container Storage Interface]) plugin.
+//
+// [Container Storage Interface]: https://github.com/container-storage-interface/spec
+func ContainerCSIVolumeID(val string) attribute.KeyValue {
+ return ContainerCSIVolumeIDKey.String(val)
+}
+
+// ContainerID returns an attribute KeyValue conforming to the "container.id"
+// semantic conventions. It represents the container ID. Usually a UUID, as for
+// example used to [identify Docker containers]. The UUID might be abbreviated.
+//
+// [identify Docker containers]: https://docs.docker.com/engine/containers/run/#container-identification
+func ContainerID(val string) attribute.KeyValue {
+ return ContainerIDKey.String(val)
+}
+
+// ContainerImageID returns an attribute KeyValue conforming to the
+// "container.image.id" semantic conventions. It represents the runtime specific
+// image identifier. Usually a hash algorithm followed by a UUID.
+func ContainerImageID(val string) attribute.KeyValue {
+ return ContainerImageIDKey.String(val)
+}
+
+// ContainerImageName returns an attribute KeyValue conforming to the
+// "container.image.name" semantic conventions. It represents the name of the
+// image the container was built on.
+func ContainerImageName(val string) attribute.KeyValue {
+ return ContainerImageNameKey.String(val)
+}
+
+// ContainerImageRepoDigests returns an attribute KeyValue conforming to the
+// "container.image.repo_digests" semantic conventions. It represents the repo
+// digests of the container image as provided by the container runtime.
+func ContainerImageRepoDigests(val ...string) attribute.KeyValue {
+ return ContainerImageRepoDigestsKey.StringSlice(val)
+}
+
+// ContainerImageTags returns an attribute KeyValue conforming to the
+// "container.image.tags" semantic conventions. It represents the container image
+// tags. An example can be found in [Docker Image Inspect]. Should be only the
+// `` section of the full name for example from
+// `registry.example.com/my-org/my-image:`.
+//
+// [Docker Image Inspect]: https://docs.docker.com/reference/api/engine/version/v1.52/#tag/Image/operation/ImageInspect
+func ContainerImageTags(val ...string) attribute.KeyValue {
+ return ContainerImageTagsKey.StringSlice(val)
+}
+
+// ContainerLabel returns an attribute KeyValue conforming to the
+// "container.label" semantic conventions. It represents the container labels,
+// `` being the label name, the value being the label value.
+func ContainerLabel(key string, val string) attribute.KeyValue {
+ return attribute.String("container.label."+key, val)
+}
+
+// ContainerName returns an attribute KeyValue conforming to the "container.name"
+// semantic conventions. It represents the container name used by container
+// runtime.
+func ContainerName(val string) attribute.KeyValue {
+ return ContainerNameKey.String(val)
+}
+
+// ContainerRuntimeDescription returns an attribute KeyValue conforming to the
+// "container.runtime.description" semantic conventions. It represents a
+// description about the runtime which could include, for example details about
+// the CRI/API version being used or other customizations.
+func ContainerRuntimeDescription(val string) attribute.KeyValue {
+ return ContainerRuntimeDescriptionKey.String(val)
+}
+
+// ContainerRuntimeName returns an attribute KeyValue conforming to the
+// "container.runtime.name" semantic conventions. It represents the container
+// runtime managing this container.
+func ContainerRuntimeName(val string) attribute.KeyValue {
+ return ContainerRuntimeNameKey.String(val)
+}
+
+// ContainerRuntimeVersion returns an attribute KeyValue conforming to the
+// "container.runtime.version" semantic conventions. It represents the version of
+// the runtime of this process, as returned by the runtime without modification.
+func ContainerRuntimeVersion(val string) attribute.KeyValue {
+ return ContainerRuntimeVersionKey.String(val)
+}
+
+// Namespace: cpu
+const (
+ // CPULogicalNumberKey is the attribute Key conforming to the
+ // "cpu.logical_number" semantic conventions. It represents the logical CPU
+ // number [0..n-1].
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 1
+ CPULogicalNumberKey = attribute.Key("cpu.logical_number")
+
+ // CPUModeKey is the attribute Key conforming to the "cpu.mode" semantic
+ // conventions. It represents the mode of the CPU.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "user", "system"
+ CPUModeKey = attribute.Key("cpu.mode")
+)
+
+// CPULogicalNumber returns an attribute KeyValue conforming to the
+// "cpu.logical_number" semantic conventions. It represents the logical CPU
+// number [0..n-1].
+func CPULogicalNumber(val int) attribute.KeyValue {
+ return CPULogicalNumberKey.Int(val)
+}
+
+// Enum values for cpu.mode
+var (
+ // User
+ // Stability: development
+ CPUModeUser = CPUModeKey.String("user")
+ // System
+ // Stability: development
+ CPUModeSystem = CPUModeKey.String("system")
+ // Nice
+ // Stability: development
+ CPUModeNice = CPUModeKey.String("nice")
+ // Idle
+ // Stability: development
+ CPUModeIdle = CPUModeKey.String("idle")
+ // IO Wait
+ // Stability: development
+ CPUModeIOWait = CPUModeKey.String("iowait")
+ // Interrupt
+ // Stability: development
+ CPUModeInterrupt = CPUModeKey.String("interrupt")
+ // Steal
+ // Stability: development
+ CPUModeSteal = CPUModeKey.String("steal")
+ // Kernel
+ // Stability: development
+ CPUModeKernel = CPUModeKey.String("kernel")
+)
+
+// Namespace: db
+const (
+ // DBClientConnectionPoolNameKey is the attribute Key conforming to the
+ // "db.client.connection.pool.name" semantic conventions. It represents the name
+ // of the connection pool; unique within the instrumented application. In case
+ // the connection pool implementation doesn't provide a name, instrumentation
+ // SHOULD use a combination of parameters that would make the name unique, for
+ // example, combining attributes `server.address`, `server.port`, and
+ // `db.namespace`, formatted as `server.address:server.port/db.namespace`.
+ // Instrumentations that generate connection pool name following different
+ // patterns SHOULD document it.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "myDataSource"
+ DBClientConnectionPoolNameKey = attribute.Key("db.client.connection.pool.name")
+
+ // DBClientConnectionStateKey is the attribute Key conforming to the
+ // "db.client.connection.state" semantic conventions. It represents the state of
+ // a connection in the pool.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "idle"
+ DBClientConnectionStateKey = attribute.Key("db.client.connection.state")
+
+ // DBCollectionNameKey is the attribute Key conforming to the
+ // "db.collection.name" semantic conventions. It represents the name of a
+ // collection (table, container) within the database.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ //
+ // Examples: "public.users", "customers"
+ // Note: It is RECOMMENDED to capture the value as provided by the application
+ // without attempting to do any case normalization.
+ //
+ // The collection name SHOULD NOT be extracted from `db.query.text`,
+ // when the database system supports query text with multiple collections
+ // in non-batch operations.
+ //
+ // For batch operations, if the individual operations are known to have the same
+ // collection name then that collection name SHOULD be used.
+ DBCollectionNameKey = attribute.Key("db.collection.name")
+
+ // DBNamespaceKey is the attribute Key conforming to the "db.namespace" semantic
+ // conventions. It represents the name of the database, fully qualified within
+ // the server address and port.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ //
+ // Examples: "customers", "test.users"
+ // Note: If a database system has multiple namespace components, they SHOULD be
+ // concatenated from the most general to the most specific namespace component,
+ // using `|` as a separator between the components. Any missing components (and
+ // their associated separators) SHOULD be omitted.
+ // Semantic conventions for individual database systems SHOULD document what
+ // `db.namespace` means in the context of that system.
+ // It is RECOMMENDED to capture the value as provided by the application without
+ // attempting to do any case normalization.
+ DBNamespaceKey = attribute.Key("db.namespace")
+
+ // DBOperationBatchSizeKey is the attribute Key conforming to the
+ // "db.operation.batch.size" semantic conventions. It represents the number of
+ // queries included in a batch operation.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ //
+ // Examples: 2, 3, 4
+ // Note: Operations are only considered batches when they contain two or more
+ // operations, and so `db.operation.batch.size` SHOULD never be `1`.
+ DBOperationBatchSizeKey = attribute.Key("db.operation.batch.size")
+
+ // DBOperationNameKey is the attribute Key conforming to the "db.operation.name"
+ // semantic conventions. It represents the name of the operation or command
+ // being executed.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ //
+ // Examples: "findAndModify", "HMSET", "SELECT"
+ // Note: It is RECOMMENDED to capture the value as provided by the application
+ // without attempting to do any case normalization.
+ //
+ // The operation name SHOULD NOT be extracted from `db.query.text`,
+ // when the database system supports query text with multiple operations
+ // in non-batch operations.
+ //
+ // If spaces can occur in the operation name, multiple consecutive spaces
+ // SHOULD be normalized to a single space.
+ //
+ // For batch operations, if the individual operations are known to have the same
+ // operation name
+ // then that operation name SHOULD be used prepended by `BATCH `,
+ // otherwise `db.operation.name` SHOULD be `BATCH` or some other database
+ // system specific term if more applicable.
+ DBOperationNameKey = attribute.Key("db.operation.name")
+
+ // DBQuerySummaryKey is the attribute Key conforming to the "db.query.summary"
+ // semantic conventions. It represents the low cardinality summary of a database
+ // query.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ //
+ // Examples: "SELECT wuser_table", "INSERT shipping_details SELECT orders", "get
+ // user by id"
+ // Note: The query summary describes a class of database queries and is useful
+ // as a grouping key, especially when analyzing telemetry for database
+ // calls involving complex queries.
+ //
+ // Summary may be available to the instrumentation through
+ // instrumentation hooks or other means. If it is not available,
+ // instrumentations
+ // that support query parsing SHOULD generate a summary following
+ // [Generating query summary]
+ // section.
+ //
+ // For batch operations, if the individual operations are known to have the same
+ // query summary
+ // then that query summary SHOULD be used prepended by `BATCH `,
+ // otherwise `db.query.summary` SHOULD be `BATCH` or some other database
+ // system specific term if more applicable.
+ //
+ // [Generating query summary]: /docs/db/database-spans.md#generating-a-summary-of-the-query
+ DBQuerySummaryKey = attribute.Key("db.query.summary")
+
+ // DBQueryTextKey is the attribute Key conforming to the "db.query.text"
+ // semantic conventions. It represents the database query being executed.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ //
+ // Examples: "SELECT * FROM wuser_table where username = ?", "SET mykey ?"
+ // Note: For sanitization see [Sanitization of `db.query.text`].
+ // For batch operations, if the individual operations are known to have the same
+ // query text then that query text SHOULD be used, otherwise all of the
+ // individual query texts SHOULD be concatenated with separator `; ` or some
+ // other database system specific separator if more applicable.
+ // Parameterized query text SHOULD NOT be sanitized. Even though parameterized
+ // query text can potentially have sensitive data, by using a parameterized
+ // query the user is giving a strong signal that any sensitive data will be
+ // passed as parameter values, and the benefit to observability of capturing the
+ // static part of the query text by default outweighs the risk.
+ //
+ // [Sanitization of `db.query.text`]: /docs/db/database-spans.md#sanitization-of-dbquerytext
+ DBQueryTextKey = attribute.Key("db.query.text")
+
+ // DBResponseReturnedRowsKey is the attribute Key conforming to the
+ // "db.response.returned_rows" semantic conventions. It represents the number of
+ // rows returned by the operation.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 10, 30, 1000
+ DBResponseReturnedRowsKey = attribute.Key("db.response.returned_rows")
+
+ // DBResponseStatusCodeKey is the attribute Key conforming to the
+ // "db.response.status_code" semantic conventions. It represents the database
+ // response status code.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ //
+ // Examples: "102", "ORA-17002", "08P01", "404"
+ // Note: The status code returned by the database. Usually it represents an
+ // error code, but may also represent partial success, warning, or differentiate
+ // between various types of successful outcomes.
+ // Semantic conventions for individual database systems SHOULD document what
+ // `db.response.status_code` means in the context of that system.
+ DBResponseStatusCodeKey = attribute.Key("db.response.status_code")
+
+ // DBStoredProcedureNameKey is the attribute Key conforming to the
+ // "db.stored_procedure.name" semantic conventions. It represents the name of a
+ // stored procedure within the database.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ //
+ // Examples: "GetCustomer"
+ // Note: It is RECOMMENDED to capture the value as provided by the application
+ // without attempting to do any case normalization.
+ //
+ // For batch operations, if the individual operations are known to have the same
+ // stored procedure name then that stored procedure name SHOULD be used.
+ DBStoredProcedureNameKey = attribute.Key("db.stored_procedure.name")
+
+ // DBSystemNameKey is the attribute Key conforming to the "db.system.name"
+ // semantic conventions. It represents the database management system (DBMS)
+ // product as identified by the client instrumentation.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ //
+ // Examples:
+ // Note: The actual DBMS may differ from the one identified by the client. For
+ // example, when using PostgreSQL client libraries to connect to a CockroachDB,
+ // the `db.system.name` is set to `postgresql` based on the instrumentation's
+ // best knowledge.
+ DBSystemNameKey = attribute.Key("db.system.name")
+)
+
+// DBClientConnectionPoolName returns an attribute KeyValue conforming to the
+// "db.client.connection.pool.name" semantic conventions. It represents the name
+// of the connection pool; unique within the instrumented application. In case
+// the connection pool implementation doesn't provide a name, instrumentation
+// SHOULD use a combination of parameters that would make the name unique, for
+// example, combining attributes `server.address`, `server.port`, and
+// `db.namespace`, formatted as `server.address:server.port/db.namespace`.
+// Instrumentations that generate connection pool name following different
+// patterns SHOULD document it.
+func DBClientConnectionPoolName(val string) attribute.KeyValue {
+ return DBClientConnectionPoolNameKey.String(val)
+}
+
+// DBCollectionName returns an attribute KeyValue conforming to the
+// "db.collection.name" semantic conventions. It represents the name of a
+// collection (table, container) within the database.
+func DBCollectionName(val string) attribute.KeyValue {
+ return DBCollectionNameKey.String(val)
+}
+
+// DBNamespace returns an attribute KeyValue conforming to the "db.namespace"
+// semantic conventions. It represents the name of the database, fully qualified
+// within the server address and port.
+func DBNamespace(val string) attribute.KeyValue {
+ return DBNamespaceKey.String(val)
+}
+
+// DBOperationBatchSize returns an attribute KeyValue conforming to the
+// "db.operation.batch.size" semantic conventions. It represents the number of
+// queries included in a batch operation.
+func DBOperationBatchSize(val int) attribute.KeyValue {
+ return DBOperationBatchSizeKey.Int(val)
+}
+
+// DBOperationName returns an attribute KeyValue conforming to the
+// "db.operation.name" semantic conventions. It represents the name of the
+// operation or command being executed.
+func DBOperationName(val string) attribute.KeyValue {
+ return DBOperationNameKey.String(val)
+}
+
+// DBOperationParameter returns an attribute KeyValue conforming to the
+// "db.operation.parameter" semantic conventions. It represents a database
+// operation parameter, with `` being the parameter name, and the attribute
+// value being a string representation of the parameter value.
+func DBOperationParameter(key string, val string) attribute.KeyValue {
+ return attribute.String("db.operation.parameter."+key, val)
+}
+
+// DBQueryParameter returns an attribute KeyValue conforming to the
+// "db.query.parameter" semantic conventions. It represents a database query
+// parameter, with `` being the parameter name, and the attribute value
+// being a string representation of the parameter value.
+func DBQueryParameter(key string, val string) attribute.KeyValue {
+ return attribute.String("db.query.parameter."+key, val)
+}
+
+// DBQuerySummary returns an attribute KeyValue conforming to the
+// "db.query.summary" semantic conventions. It represents the low cardinality
+// summary of a database query.
+func DBQuerySummary(val string) attribute.KeyValue {
+ return DBQuerySummaryKey.String(val)
+}
+
+// DBQueryText returns an attribute KeyValue conforming to the "db.query.text"
+// semantic conventions. It represents the database query being executed.
+func DBQueryText(val string) attribute.KeyValue {
+ return DBQueryTextKey.String(val)
+}
+
+// DBResponseReturnedRows returns an attribute KeyValue conforming to the
+// "db.response.returned_rows" semantic conventions. It represents the number of
+// rows returned by the operation.
+func DBResponseReturnedRows(val int) attribute.KeyValue {
+ return DBResponseReturnedRowsKey.Int(val)
+}
+
+// DBResponseStatusCode returns an attribute KeyValue conforming to the
+// "db.response.status_code" semantic conventions. It represents the database
+// response status code.
+func DBResponseStatusCode(val string) attribute.KeyValue {
+ return DBResponseStatusCodeKey.String(val)
+}
+
+// DBStoredProcedureName returns an attribute KeyValue conforming to the
+// "db.stored_procedure.name" semantic conventions. It represents the name of a
+// stored procedure within the database.
+func DBStoredProcedureName(val string) attribute.KeyValue {
+ return DBStoredProcedureNameKey.String(val)
+}
+
+// Enum values for db.client.connection.state
+var (
+ // idle
+ // Stability: development
+ DBClientConnectionStateIdle = DBClientConnectionStateKey.String("idle")
+ // used
+ // Stability: development
+ DBClientConnectionStateUsed = DBClientConnectionStateKey.String("used")
+)
+
+// Enum values for db.system.name
+var (
+ // Some other SQL database. Fallback only.
+ // Stability: development
+ DBSystemNameOtherSQL = DBSystemNameKey.String("other_sql")
+ // [Adabas (Adaptable Database System)]
+ // Stability: development
+ //
+ // [Adabas (Adaptable Database System)]: https://documentation.softwareag.com/?pf=adabas
+ DBSystemNameSoftwareagAdabas = DBSystemNameKey.String("softwareag.adabas")
+ // [Actian Ingres]
+ // Stability: development
+ //
+ // [Actian Ingres]: https://www.actian.com/databases/ingres/
+ DBSystemNameActianIngres = DBSystemNameKey.String("actian.ingres")
+ // [Amazon DynamoDB]
+ // Stability: development
+ //
+ // [Amazon DynamoDB]: https://aws.amazon.com/pm/dynamodb/
+ DBSystemNameAWSDynamoDB = DBSystemNameKey.String("aws.dynamodb")
+ // [Amazon Redshift]
+ // Stability: development
+ //
+ // [Amazon Redshift]: https://aws.amazon.com/redshift/
+ DBSystemNameAWSRedshift = DBSystemNameKey.String("aws.redshift")
+ // [Azure Cosmos DB]
+ // Stability: development
+ //
+ // [Azure Cosmos DB]: https://learn.microsoft.com/azure/cosmos-db
+ DBSystemNameAzureCosmosDB = DBSystemNameKey.String("azure.cosmosdb")
+ // [InterSystems Caché]
+ // Stability: development
+ //
+ // [InterSystems Caché]: https://www.intersystems.com/products/cache/
+ DBSystemNameIntersystemsCache = DBSystemNameKey.String("intersystems.cache")
+ // [Apache Cassandra]
+ // Stability: development
+ //
+ // [Apache Cassandra]: https://cassandra.apache.org/
+ DBSystemNameCassandra = DBSystemNameKey.String("cassandra")
+ // [ClickHouse]
+ // Stability: development
+ //
+ // [ClickHouse]: https://clickhouse.com/
+ DBSystemNameClickHouse = DBSystemNameKey.String("clickhouse")
+ // [CockroachDB]
+ // Stability: development
+ //
+ // [CockroachDB]: https://www.cockroachlabs.com/
+ DBSystemNameCockroachDB = DBSystemNameKey.String("cockroachdb")
+ // [Couchbase]
+ // Stability: development
+ //
+ // [Couchbase]: https://www.couchbase.com/
+ DBSystemNameCouchbase = DBSystemNameKey.String("couchbase")
+ // [Apache CouchDB]
+ // Stability: development
+ //
+ // [Apache CouchDB]: https://couchdb.apache.org/
+ DBSystemNameCouchDB = DBSystemNameKey.String("couchdb")
+ // [Apache Derby]
+ // Stability: development
+ //
+ // [Apache Derby]: https://db.apache.org/derby/
+ DBSystemNameDerby = DBSystemNameKey.String("derby")
+ // [Elasticsearch]
+ // Stability: development
+ //
+ // [Elasticsearch]: https://www.elastic.co/elasticsearch
+ DBSystemNameElasticsearch = DBSystemNameKey.String("elasticsearch")
+ // [Firebird]
+ // Stability: development
+ //
+ // [Firebird]: https://www.firebirdsql.org/
+ DBSystemNameFirebirdSQL = DBSystemNameKey.String("firebirdsql")
+ // [Google Cloud Spanner]
+ // Stability: development
+ //
+ // [Google Cloud Spanner]: https://cloud.google.com/spanner
+ DBSystemNameGCPSpanner = DBSystemNameKey.String("gcp.spanner")
+ // [Apache Geode]
+ // Stability: development
+ //
+ // [Apache Geode]: https://geode.apache.org/
+ DBSystemNameGeode = DBSystemNameKey.String("geode")
+ // [H2 Database]
+ // Stability: development
+ //
+ // [H2 Database]: https://h2database.com/
+ DBSystemNameH2database = DBSystemNameKey.String("h2database")
+ // [Apache HBase]
+ // Stability: development
+ //
+ // [Apache HBase]: https://hbase.apache.org/
+ DBSystemNameHBase = DBSystemNameKey.String("hbase")
+ // [Apache Hive]
+ // Stability: development
+ //
+ // [Apache Hive]: https://hive.apache.org/
+ DBSystemNameHive = DBSystemNameKey.String("hive")
+ // [HyperSQL Database]
+ // Stability: development
+ //
+ // [HyperSQL Database]: https://hsqldb.org/
+ DBSystemNameHSQLDB = DBSystemNameKey.String("hsqldb")
+ // [IBM Db2]
+ // Stability: development
+ //
+ // [IBM Db2]: https://www.ibm.com/db2
+ DBSystemNameIBMDB2 = DBSystemNameKey.String("ibm.db2")
+ // [IBM Informix]
+ // Stability: development
+ //
+ // [IBM Informix]: https://www.ibm.com/products/informix
+ DBSystemNameIBMInformix = DBSystemNameKey.String("ibm.informix")
+ // [IBM Netezza]
+ // Stability: development
+ //
+ // [IBM Netezza]: https://www.ibm.com/products/netezza
+ DBSystemNameIBMNetezza = DBSystemNameKey.String("ibm.netezza")
+ // [InfluxDB]
+ // Stability: development
+ //
+ // [InfluxDB]: https://www.influxdata.com/
+ DBSystemNameInfluxDB = DBSystemNameKey.String("influxdb")
+ // [Instant]
+ // Stability: development
+ //
+ // [Instant]: https://www.instantdb.com/
+ DBSystemNameInstantDB = DBSystemNameKey.String("instantdb")
+ // [MariaDB]
+ // Stability: stable
+ //
+ // [MariaDB]: https://mariadb.org/
+ DBSystemNameMariaDB = DBSystemNameKey.String("mariadb")
+ // [Memcached]
+ // Stability: development
+ //
+ // [Memcached]: https://memcached.org/
+ DBSystemNameMemcached = DBSystemNameKey.String("memcached")
+ // [MongoDB]
+ // Stability: development
+ //
+ // [MongoDB]: https://www.mongodb.com/
+ DBSystemNameMongoDB = DBSystemNameKey.String("mongodb")
+ // [Microsoft SQL Server]
+ // Stability: stable
+ //
+ // [Microsoft SQL Server]: https://www.microsoft.com/sql-server
+ DBSystemNameMicrosoftSQLServer = DBSystemNameKey.String("microsoft.sql_server")
+ // [MySQL]
+ // Stability: stable
+ //
+ // [MySQL]: https://www.mysql.com/
+ DBSystemNameMySQL = DBSystemNameKey.String("mysql")
+ // [Neo4j]
+ // Stability: development
+ //
+ // [Neo4j]: https://neo4j.com/
+ DBSystemNameNeo4j = DBSystemNameKey.String("neo4j")
+ // [OpenSearch]
+ // Stability: development
+ //
+ // [OpenSearch]: https://opensearch.org/
+ DBSystemNameOpenSearch = DBSystemNameKey.String("opensearch")
+ // [Oracle Database]
+ // Stability: development
+ //
+ // [Oracle Database]: https://www.oracle.com/database/
+ DBSystemNameOracleDB = DBSystemNameKey.String("oracle.db")
+ // [PostgreSQL]
+ // Stability: stable
+ //
+ // [PostgreSQL]: https://www.postgresql.org/
+ DBSystemNamePostgreSQL = DBSystemNameKey.String("postgresql")
+ // [Redis]
+ // Stability: development
+ //
+ // [Redis]: https://redis.io/
+ DBSystemNameRedis = DBSystemNameKey.String("redis")
+ // [SAP HANA]
+ // Stability: development
+ //
+ // [SAP HANA]: https://www.sap.com/products/technology-platform/hana/what-is-sap-hana.html
+ DBSystemNameSAPHANA = DBSystemNameKey.String("sap.hana")
+ // [SAP MaxDB]
+ // Stability: development
+ //
+ // [SAP MaxDB]: https://maxdb.sap.com/
+ DBSystemNameSAPMaxDB = DBSystemNameKey.String("sap.maxdb")
+ // [SQLite]
+ // Stability: development
+ //
+ // [SQLite]: https://www.sqlite.org/
+ DBSystemNameSQLite = DBSystemNameKey.String("sqlite")
+ // [Teradata]
+ // Stability: development
+ //
+ // [Teradata]: https://www.teradata.com/
+ DBSystemNameTeradata = DBSystemNameKey.String("teradata")
+ // [Trino]
+ // Stability: development
+ //
+ // [Trino]: https://trino.io/
+ DBSystemNameTrino = DBSystemNameKey.String("trino")
+)
+
+// Namespace: deployment
+const (
+ // DeploymentEnvironmentNameKey is the attribute Key conforming to the
+ // "deployment.environment.name" semantic conventions. It represents the name of
+ // the [deployment environment] (aka deployment tier).
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ //
+ // Examples: "staging", "production"
+ // Note: `deployment.environment.name` does not affect the uniqueness
+ // constraints defined through
+ // the `service.namespace`, `service.name` and `service.instance.id` resource
+ // attributes.
+ // This implies that resources carrying the following attribute combinations
+ // MUST be
+ // considered to be identifying the same service:
+ //
+ // - `service.name=frontend`, `deployment.environment.name=production`
+ // - `service.name=frontend`, `deployment.environment.name=staging`.
+ //
+ //
+ // [deployment environment]: https://wikipedia.org/wiki/Deployment_environment
+ DeploymentEnvironmentNameKey = attribute.Key("deployment.environment.name")
+
+ // DeploymentIDKey is the attribute Key conforming to the "deployment.id"
+ // semantic conventions. It represents the id of the deployment.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "1208"
+ DeploymentIDKey = attribute.Key("deployment.id")
+
+ // DeploymentNameKey is the attribute Key conforming to the "deployment.name"
+ // semantic conventions. It represents the name of the deployment.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "deploy my app", "deploy-frontend"
+ DeploymentNameKey = attribute.Key("deployment.name")
+
+ // DeploymentStatusKey is the attribute Key conforming to the
+ // "deployment.status" semantic conventions. It represents the status of the
+ // deployment.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ DeploymentStatusKey = attribute.Key("deployment.status")
+)
+
+// DeploymentID returns an attribute KeyValue conforming to the "deployment.id"
+// semantic conventions. It represents the id of the deployment.
+func DeploymentID(val string) attribute.KeyValue {
+ return DeploymentIDKey.String(val)
+}
+
+// DeploymentName returns an attribute KeyValue conforming to the
+// "deployment.name" semantic conventions. It represents the name of the
+// deployment.
+func DeploymentName(val string) attribute.KeyValue {
+ return DeploymentNameKey.String(val)
+}
+
+// Enum values for deployment.environment.name
+var (
+ // Production environment
+ // Stability: stable
+ DeploymentEnvironmentNameProduction = DeploymentEnvironmentNameKey.String("production")
+ // Staging environment
+ // Stability: stable
+ DeploymentEnvironmentNameStaging = DeploymentEnvironmentNameKey.String("staging")
+ // Testing environment
+ // Stability: stable
+ DeploymentEnvironmentNameTest = DeploymentEnvironmentNameKey.String("test")
+ // Development environment
+ // Stability: stable
+ DeploymentEnvironmentNameDevelopment = DeploymentEnvironmentNameKey.String("development")
+)
+
+// Enum values for deployment.status
+var (
+ // failed
+ // Stability: development
+ DeploymentStatusFailed = DeploymentStatusKey.String("failed")
+ // succeeded
+ // Stability: development
+ DeploymentStatusSucceeded = DeploymentStatusKey.String("succeeded")
+)
+
+// Namespace: destination
+const (
+ // DestinationAddressKey is the attribute Key conforming to the
+ // "destination.address" semantic conventions. It represents the destination
+ // address - domain name if available without reverse DNS lookup; otherwise, IP
+ // address or Unix domain socket name.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "destination.example.com", "10.1.2.80", "/tmp/my.sock"
+ // Note: When observed from the source side, and when communicating through an
+ // intermediary, `destination.address` SHOULD represent the destination address
+ // behind any intermediaries, for example proxies, if it's available.
+ DestinationAddressKey = attribute.Key("destination.address")
+
+ // DestinationPortKey is the attribute Key conforming to the "destination.port"
+ // semantic conventions. It represents the destination port number.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 3389, 2888
+ DestinationPortKey = attribute.Key("destination.port")
+)
+
+// DestinationAddress returns an attribute KeyValue conforming to the
+// "destination.address" semantic conventions. It represents the destination
+// address - domain name if available without reverse DNS lookup; otherwise, IP
+// address or Unix domain socket name.
+func DestinationAddress(val string) attribute.KeyValue {
+ return DestinationAddressKey.String(val)
+}
+
+// DestinationPort returns an attribute KeyValue conforming to the
+// "destination.port" semantic conventions. It represents the destination port
+// number.
+func DestinationPort(val int) attribute.KeyValue {
+ return DestinationPortKey.Int(val)
+}
+
+// Namespace: device
+const (
+ // DeviceIDKey is the attribute Key conforming to the "device.id" semantic
+ // conventions. It represents a unique identifier representing the device.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "123456789012345", "01:23:45:67:89:AB"
+ // Note: Its value SHOULD be identical for all apps on a device and it SHOULD
+ // NOT change if an app is uninstalled and re-installed.
+ // However, it might be resettable by the user for all apps on a device.
+ // Hardware IDs (e.g. vendor-specific serial number, IMEI or MAC address) MAY be
+ // used as values.
+ //
+ // More information about Android identifier best practices can be found in the
+ // [Android user data IDs guide].
+ //
+ // > [!WARNING]> This attribute may contain sensitive (PII) information. Caution
+ // > should be taken when storing personal data or anything which can identify a
+ // > user. GDPR and data protection laws may apply,
+ // > ensure you do your own due diligence.> Due to these reasons, this
+ // > identifier is not recommended for consumer applications and will likely
+ // > result in rejection from both Google Play and App Store.
+ // > However, it may be appropriate for specific enterprise scenarios, such as
+ // > kiosk devices or enterprise-managed devices, with appropriate compliance
+ // > clearance.
+ // > Any instrumentation providing this identifier MUST implement it as an
+ // > opt-in feature.> See [`app.installation.id`]> for a more
+ // > privacy-preserving alternative.
+ //
+ // [Android user data IDs guide]: https://developer.android.com/training/articles/user-data-ids
+ // [`app.installation.id`]: /docs/registry/attributes/app.md#app-installation-id
+ DeviceIDKey = attribute.Key("device.id")
+
+ // DeviceManufacturerKey is the attribute Key conforming to the
+ // "device.manufacturer" semantic conventions. It represents the name of the
+ // device manufacturer.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "Apple", "Samsung"
+ // Note: The Android OS provides this field via [Build]. iOS apps SHOULD
+ // hardcode the value `Apple`.
+ //
+ // [Build]: https://developer.android.com/reference/android/os/Build#MANUFACTURER
+ DeviceManufacturerKey = attribute.Key("device.manufacturer")
+
+ // DeviceModelIdentifierKey is the attribute Key conforming to the
+ // "device.model.identifier" semantic conventions. It represents the model
+ // identifier for the device.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "iPhone3,4", "SM-G920F"
+ // Note: It's recommended this value represents a machine-readable version of
+ // the model identifier rather than the market or consumer-friendly name of the
+ // device.
+ DeviceModelIdentifierKey = attribute.Key("device.model.identifier")
+
+ // DeviceModelNameKey is the attribute Key conforming to the "device.model.name"
+ // semantic conventions. It represents the marketing name for the device model.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "iPhone 6s Plus", "Samsung Galaxy S6"
+ // Note: It's recommended this value represents a human-readable version of the
+ // device model rather than a machine-readable alternative.
+ DeviceModelNameKey = attribute.Key("device.model.name")
+)
+
+// DeviceID returns an attribute KeyValue conforming to the "device.id" semantic
+// conventions. It represents a unique identifier representing the device.
+func DeviceID(val string) attribute.KeyValue {
+ return DeviceIDKey.String(val)
+}
+
+// DeviceManufacturer returns an attribute KeyValue conforming to the
+// "device.manufacturer" semantic conventions. It represents the name of the
+// device manufacturer.
+func DeviceManufacturer(val string) attribute.KeyValue {
+ return DeviceManufacturerKey.String(val)
+}
+
+// DeviceModelIdentifier returns an attribute KeyValue conforming to the
+// "device.model.identifier" semantic conventions. It represents the model
+// identifier for the device.
+func DeviceModelIdentifier(val string) attribute.KeyValue {
+ return DeviceModelIdentifierKey.String(val)
+}
+
+// DeviceModelName returns an attribute KeyValue conforming to the
+// "device.model.name" semantic conventions. It represents the marketing name for
+// the device model.
+func DeviceModelName(val string) attribute.KeyValue {
+ return DeviceModelNameKey.String(val)
+}
+
+// Namespace: disk
+const (
+ // DiskIODirectionKey is the attribute Key conforming to the "disk.io.direction"
+ // semantic conventions. It represents the disk IO operation direction.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "read"
+ DiskIODirectionKey = attribute.Key("disk.io.direction")
+)
+
+// Enum values for disk.io.direction
+var (
+ // read
+ // Stability: development
+ DiskIODirectionRead = DiskIODirectionKey.String("read")
+ // write
+ // Stability: development
+ DiskIODirectionWrite = DiskIODirectionKey.String("write")
+)
+
+// Namespace: dns
+const (
+ // DNSAnswersKey is the attribute Key conforming to the "dns.answers" semantic
+ // conventions. It represents the list of IPv4 or IPv6 addresses resolved during
+ // DNS lookup.
+ //
+ // Type: string[]
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "10.0.0.1", "2001:0db8:85a3:0000:0000:8a2e:0370:7334"
+ DNSAnswersKey = attribute.Key("dns.answers")
+
+ // DNSQuestionNameKey is the attribute Key conforming to the "dns.question.name"
+ // semantic conventions. It represents the name being queried.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "www.example.com", "opentelemetry.io"
+ // Note: The name represents the queried domain name as it appears in the DNS
+ // query without any additional normalization.
+ DNSQuestionNameKey = attribute.Key("dns.question.name")
+)
+
+// DNSAnswers returns an attribute KeyValue conforming to the "dns.answers"
+// semantic conventions. It represents the list of IPv4 or IPv6 addresses
+// resolved during DNS lookup.
+func DNSAnswers(val ...string) attribute.KeyValue {
+ return DNSAnswersKey.StringSlice(val)
+}
+
+// DNSQuestionName returns an attribute KeyValue conforming to the
+// "dns.question.name" semantic conventions. It represents the name being
+// queried.
+func DNSQuestionName(val string) attribute.KeyValue {
+ return DNSQuestionNameKey.String(val)
+}
+
+// Namespace: elasticsearch
+const (
+ // ElasticsearchNodeNameKey is the attribute Key conforming to the
+ // "elasticsearch.node.name" semantic conventions. It represents the represents
+ // the human-readable identifier of the node/instance to which a request was
+ // routed.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "instance-0000000001"
+ ElasticsearchNodeNameKey = attribute.Key("elasticsearch.node.name")
+)
+
+// ElasticsearchNodeName returns an attribute KeyValue conforming to the
+// "elasticsearch.node.name" semantic conventions. It represents the represents
+// the human-readable identifier of the node/instance to which a request was
+// routed.
+func ElasticsearchNodeName(val string) attribute.KeyValue {
+ return ElasticsearchNodeNameKey.String(val)
+}
+
+// Namespace: enduser
+const (
+ // EnduserIDKey is the attribute Key conforming to the "enduser.id" semantic
+ // conventions. It represents the unique identifier of an end user in the
+ // system. It maybe a username, email address, or other identifier.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "username"
+ // Note: Unique identifier of an end user in the system.
+ //
+ // > [!Warning]
+ // > This field contains sensitive (PII) information.
+ EnduserIDKey = attribute.Key("enduser.id")
+
+ // EnduserPseudoIDKey is the attribute Key conforming to the "enduser.pseudo.id"
+ // semantic conventions. It represents the pseudonymous identifier of an end
+ // user. This identifier should be a random value that is not directly linked or
+ // associated with the end user's actual identity.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "QdH5CAWJgqVT4rOr0qtumf"
+ // Note: Pseudonymous identifier of an end user.
+ //
+ // > [!Warning]
+ // > This field contains sensitive (linkable PII) information.
+ EnduserPseudoIDKey = attribute.Key("enduser.pseudo.id")
+)
+
+// EnduserID returns an attribute KeyValue conforming to the "enduser.id"
+// semantic conventions. It represents the unique identifier of an end user in
+// the system. It maybe a username, email address, or other identifier.
+func EnduserID(val string) attribute.KeyValue {
+ return EnduserIDKey.String(val)
+}
+
+// EnduserPseudoID returns an attribute KeyValue conforming to the
+// "enduser.pseudo.id" semantic conventions. It represents the pseudonymous
+// identifier of an end user. This identifier should be a random value that is
+// not directly linked or associated with the end user's actual identity.
+func EnduserPseudoID(val string) attribute.KeyValue {
+ return EnduserPseudoIDKey.String(val)
+}
+
+// Namespace: error
+const (
+ // ErrorTypeKey is the attribute Key conforming to the "error.type" semantic
+ // conventions. It represents the describes a class of error the operation ended
+ // with.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ //
+ // Examples: "timeout", "java.net.UnknownHostException",
+ // "server_certificate_invalid", "500"
+ // Note: The `error.type` SHOULD be predictable, and SHOULD have low
+ // cardinality.
+ //
+ // When `error.type` is set to a type (e.g., an exception type), its
+ // canonical class name identifying the type within the artifact SHOULD be used.
+ //
+ // If the recorded error type is a wrapper that is not meaningful for
+ // failure classification, instrumentation MAY use the type of the inner
+ // error instead. For example, in Go, errors created with `fmt.Errorf`
+ // using `%w` MAY be unwrapped when the wrapper type does not help
+ // classify the failure.
+ //
+ // Instrumentations SHOULD document the list of errors they report.
+ //
+ // The cardinality of `error.type` within one instrumentation library SHOULD be
+ // low.
+ // Telemetry consumers that aggregate data from multiple instrumentation
+ // libraries and applications
+ // should be prepared for `error.type` to have high cardinality at query time
+ // when no
+ // additional filters are applied.
+ //
+ // If the operation has completed successfully, instrumentations SHOULD NOT set
+ // `error.type`.
+ //
+ // If a specific domain defines its own set of error identifiers (such as HTTP
+ // or RPC status codes),
+ // it's RECOMMENDED to:
+ //
+ // - Use a domain-specific attribute
+ // - Set `error.type` to capture all errors, regardless of whether they are
+ // defined within the domain-specific set or not.
+ ErrorTypeKey = attribute.Key("error.type")
+)
+
+// Enum values for error.type
+var (
+ // A fallback error value to be used when the instrumentation doesn't define a
+ // custom value.
+ //
+ // Stability: stable
+ ErrorTypeOther = ErrorTypeKey.String("_OTHER")
+)
+
+// Namespace: exception
+const (
+ // ExceptionMessageKey is the attribute Key conforming to the
+ // "exception.message" semantic conventions. It represents the exception
+ // message.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ //
+ // Examples: "Division by zero", "Can't convert 'int' object to str implicitly"
+ // Note: > [!WARNING]
+ //
+ // > This attribute may contain sensitive information.
+ ExceptionMessageKey = attribute.Key("exception.message")
+
+ // ExceptionStacktraceKey is the attribute Key conforming to the
+ // "exception.stacktrace" semantic conventions. It represents a stacktrace as a
+ // string in the natural representation for the language runtime. The
+ // representation is to be determined and documented by each language SIG.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ //
+ // Examples: Exception in thread "main" java.lang.RuntimeException: Test
+ // exception\n at com.example.GenerateTrace.methodB(GenerateTrace.java:13)\n at
+ // com.example.GenerateTrace.methodA(GenerateTrace.java:9)\n at
+ // com.example.GenerateTrace.main(GenerateTrace.java:5)
+ ExceptionStacktraceKey = attribute.Key("exception.stacktrace")
+
+ // ExceptionTypeKey is the attribute Key conforming to the "exception.type"
+ // semantic conventions. It represents the type of the exception (its
+ // fully-qualified class name, if applicable). The dynamic type of the exception
+ // should be preferred over the static type in languages that support it.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ //
+ // Examples: "java.net.ConnectException", "OSError"
+ // Note: If the recorded exception type is a wrapper that is not meaningful for
+ // failure classification, instrumentation MAY use the type of the inner
+ // exception instead. For example, in Go, errors created with `fmt.Errorf`
+ // using `%w` MAY be unwrapped when the wrapper type does not help
+ // classify the failure.
+ ExceptionTypeKey = attribute.Key("exception.type")
+)
+
+// ExceptionMessage returns an attribute KeyValue conforming to the
+// "exception.message" semantic conventions. It represents the exception message.
+func ExceptionMessage(val string) attribute.KeyValue {
+ return ExceptionMessageKey.String(val)
+}
+
+// ExceptionStacktrace returns an attribute KeyValue conforming to the
+// "exception.stacktrace" semantic conventions. It represents a stacktrace as a
+// string in the natural representation for the language runtime. The
+// representation is to be determined and documented by each language SIG.
+func ExceptionStacktrace(val string) attribute.KeyValue {
+ return ExceptionStacktraceKey.String(val)
+}
+
+// ExceptionType returns an attribute KeyValue conforming to the "exception.type"
+// semantic conventions. It represents the type of the exception (its
+// fully-qualified class name, if applicable). The dynamic type of the exception
+// should be preferred over the static type in languages that support it.
+func ExceptionType(val string) attribute.KeyValue {
+ return ExceptionTypeKey.String(val)
+}
+
+// Namespace: faas
+const (
+ // FaaSColdstartKey is the attribute Key conforming to the "faas.coldstart"
+ // semantic conventions. It represents a boolean that is true if the serverless
+ // function is executed for the first time (aka cold-start).
+ //
+ // Type: boolean
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ FaaSColdstartKey = attribute.Key("faas.coldstart")
+
+ // FaaSCronKey is the attribute Key conforming to the "faas.cron" semantic
+ // conventions. It represents a string containing the schedule period as
+ // [Cron Expression].
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 0/5 * * * ? *
+ //
+ // [Cron Expression]: https://docs.oracle.com/cd/E12058_01/doc/doc.1014/e12030/cron_expressions.htm
+ FaaSCronKey = attribute.Key("faas.cron")
+
+ // FaaSDocumentCollectionKey is the attribute Key conforming to the
+ // "faas.document.collection" semantic conventions. It represents the name of
+ // the source on which the triggering operation was performed. For example, in
+ // Cloud Storage or S3 corresponds to the bucket name, and in Cosmos DB to the
+ // database name.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "myBucketName", "myDbName"
+ FaaSDocumentCollectionKey = attribute.Key("faas.document.collection")
+
+ // FaaSDocumentNameKey is the attribute Key conforming to the
+ // "faas.document.name" semantic conventions. It represents the document
+ // name/table subjected to the operation. For example, in Cloud Storage or S3 is
+ // the name of the file, and in Cosmos DB the table name.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "myFile.txt", "myTableName"
+ FaaSDocumentNameKey = attribute.Key("faas.document.name")
+
+ // FaaSDocumentOperationKey is the attribute Key conforming to the
+ // "faas.document.operation" semantic conventions. It represents the describes
+ // the type of the operation that was performed on the data.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ FaaSDocumentOperationKey = attribute.Key("faas.document.operation")
+
+ // FaaSDocumentTimeKey is the attribute Key conforming to the
+ // "faas.document.time" semantic conventions. It represents a string containing
+ // the time when the data was accessed in the [ISO 8601] format expressed in
+ // [UTC].
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 2020-01-23T13:47:06Z
+ //
+ // [ISO 8601]: https://www.iso.org/iso-8601-date-and-time-format.html
+ // [UTC]: https://www.w3.org/TR/NOTE-datetime
+ FaaSDocumentTimeKey = attribute.Key("faas.document.time")
+
+ // FaaSInstanceKey is the attribute Key conforming to the "faas.instance"
+ // semantic conventions. It represents the execution environment ID as a string,
+ // that will be potentially reused for other invocations to the same
+ // function/function version.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "2021/06/28/[$LATEST]2f399eb14537447da05ab2a2e39309de"
+ // Note: - **AWS Lambda:** Use the (full) log stream name.
+ FaaSInstanceKey = attribute.Key("faas.instance")
+
+ // FaaSInvocationIDKey is the attribute Key conforming to the
+ // "faas.invocation_id" semantic conventions. It represents the invocation ID of
+ // the current function invocation.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: af9d5aa4-a685-4c5f-a22b-444f80b3cc28
+ FaaSInvocationIDKey = attribute.Key("faas.invocation_id")
+
+ // FaaSInvokedNameKey is the attribute Key conforming to the "faas.invoked_name"
+ // semantic conventions. It represents the name of the invoked function.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: my-function
+ // Note: SHOULD be equal to the `faas.name` resource attribute of the invoked
+ // function.
+ FaaSInvokedNameKey = attribute.Key("faas.invoked_name")
+
+ // FaaSInvokedProviderKey is the attribute Key conforming to the
+ // "faas.invoked_provider" semantic conventions. It represents the cloud
+ // provider of the invoked function.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ // Note: SHOULD be equal to the `cloud.provider` resource attribute of the
+ // invoked function.
+ FaaSInvokedProviderKey = attribute.Key("faas.invoked_provider")
+
+ // FaaSInvokedRegionKey is the attribute Key conforming to the
+ // "faas.invoked_region" semantic conventions. It represents the cloud region of
+ // the invoked function.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: eu-central-1
+ // Note: SHOULD be equal to the `cloud.region` resource attribute of the invoked
+ // function.
+ FaaSInvokedRegionKey = attribute.Key("faas.invoked_region")
+
+ // FaaSMaxMemoryKey is the attribute Key conforming to the "faas.max_memory"
+ // semantic conventions. It represents the amount of memory available to the
+ // serverless function converted to Bytes.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Note: It's recommended to set this attribute since e.g. too little memory can
+ // easily stop a Java AWS Lambda function from working correctly. On AWS Lambda,
+ // the environment variable `AWS_LAMBDA_FUNCTION_MEMORY_SIZE` provides this
+ // information (which must be multiplied by 1,048,576).
+ FaaSMaxMemoryKey = attribute.Key("faas.max_memory")
+
+ // FaaSNameKey is the attribute Key conforming to the "faas.name" semantic
+ // conventions. It represents the name of the single function that this runtime
+ // instance executes.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "my-function", "myazurefunctionapp/some-function-name"
+ // Note: This is the name of the function as configured/deployed on the FaaS
+ // platform and is usually different from the name of the callback
+ // function (which may be stored in the
+ // [`code.namespace`/`code.function.name`]
+ // span attributes).
+ //
+ // For some cloud providers, the above definition is ambiguous. The following
+ // definition of function name MUST be used for this attribute
+ // (and consequently the span name) for the listed cloud providers/products:
+ //
+ // - **Azure:** The full name `/`, i.e., function app name
+ // followed by a forward slash followed by the function name (this form
+ // can also be seen in the resource JSON for the function).
+ // This means that a span attribute MUST be used, as an Azure function
+ // app can host multiple functions that would usually share
+ // a TracerProvider (see also the `cloud.resource_id` attribute).
+ //
+ //
+ // [`code.namespace`/`code.function.name`]: /docs/general/attributes.md#source-code-attributes
+ FaaSNameKey = attribute.Key("faas.name")
+
+ // FaaSTimeKey is the attribute Key conforming to the "faas.time" semantic
+ // conventions. It represents a string containing the function invocation time
+ // in the [ISO 8601] format expressed in [UTC].
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 2020-01-23T13:47:06Z
+ //
+ // [ISO 8601]: https://www.iso.org/iso-8601-date-and-time-format.html
+ // [UTC]: https://www.w3.org/TR/NOTE-datetime
+ FaaSTimeKey = attribute.Key("faas.time")
+
+ // FaaSTriggerKey is the attribute Key conforming to the "faas.trigger" semantic
+ // conventions. It represents the type of the trigger which caused this function
+ // invocation.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ FaaSTriggerKey = attribute.Key("faas.trigger")
+
+ // FaaSVersionKey is the attribute Key conforming to the "faas.version" semantic
+ // conventions. It represents the immutable version of the function being
+ // executed.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "26", "pinkfroid-00002"
+ // Note: Depending on the cloud provider and platform, use:
+ //
+ // - **AWS Lambda:** The [function version]
+ // (an integer represented as a decimal string).
+ // - **Google Cloud Run (Services):** The [revision]
+ // (i.e., the function name plus the revision suffix).
+ // - **Google Cloud Functions:** The value of the
+ // [`K_REVISION` environment variable].
+ // - **Azure Functions:** Not applicable. Do not set this attribute.
+ //
+ //
+ // [function version]: https://docs.aws.amazon.com/lambda/latest/dg/configuration-versions.html
+ // [revision]: https://cloud.google.com/run/docs/managing/revisions
+ // [`K_REVISION` environment variable]: https://cloud.google.com/run/docs/container-contract#services-env-vars
+ FaaSVersionKey = attribute.Key("faas.version")
+)
+
+// FaaSColdstart returns an attribute KeyValue conforming to the "faas.coldstart"
+// semantic conventions. It represents a boolean that is true if the serverless
+// function is executed for the first time (aka cold-start).
+func FaaSColdstart(val bool) attribute.KeyValue {
+ return FaaSColdstartKey.Bool(val)
+}
+
+// FaaSCron returns an attribute KeyValue conforming to the "faas.cron" semantic
+// conventions. It represents a string containing the schedule period as
+// [Cron Expression].
+//
+// [Cron Expression]: https://docs.oracle.com/cd/E12058_01/doc/doc.1014/e12030/cron_expressions.htm
+func FaaSCron(val string) attribute.KeyValue {
+ return FaaSCronKey.String(val)
+}
+
+// FaaSDocumentCollection returns an attribute KeyValue conforming to the
+// "faas.document.collection" semantic conventions. It represents the name of the
+// source on which the triggering operation was performed. For example, in Cloud
+// Storage or S3 corresponds to the bucket name, and in Cosmos DB to the database
+// name.
+func FaaSDocumentCollection(val string) attribute.KeyValue {
+ return FaaSDocumentCollectionKey.String(val)
+}
+
+// FaaSDocumentName returns an attribute KeyValue conforming to the
+// "faas.document.name" semantic conventions. It represents the document
+// name/table subjected to the operation. For example, in Cloud Storage or S3 is
+// the name of the file, and in Cosmos DB the table name.
+func FaaSDocumentName(val string) attribute.KeyValue {
+ return FaaSDocumentNameKey.String(val)
+}
+
+// FaaSDocumentTime returns an attribute KeyValue conforming to the
+// "faas.document.time" semantic conventions. It represents a string containing
+// the time when the data was accessed in the [ISO 8601] format expressed in
+// [UTC].
+//
+// [ISO 8601]: https://www.iso.org/iso-8601-date-and-time-format.html
+// [UTC]: https://www.w3.org/TR/NOTE-datetime
+func FaaSDocumentTime(val string) attribute.KeyValue {
+ return FaaSDocumentTimeKey.String(val)
+}
+
+// FaaSInstance returns an attribute KeyValue conforming to the "faas.instance"
+// semantic conventions. It represents the execution environment ID as a string,
+// that will be potentially reused for other invocations to the same
+// function/function version.
+func FaaSInstance(val string) attribute.KeyValue {
+ return FaaSInstanceKey.String(val)
+}
+
+// FaaSInvocationID returns an attribute KeyValue conforming to the
+// "faas.invocation_id" semantic conventions. It represents the invocation ID of
+// the current function invocation.
+func FaaSInvocationID(val string) attribute.KeyValue {
+ return FaaSInvocationIDKey.String(val)
+}
+
+// FaaSInvokedName returns an attribute KeyValue conforming to the
+// "faas.invoked_name" semantic conventions. It represents the name of the
+// invoked function.
+func FaaSInvokedName(val string) attribute.KeyValue {
+ return FaaSInvokedNameKey.String(val)
+}
+
+// FaaSInvokedRegion returns an attribute KeyValue conforming to the
+// "faas.invoked_region" semantic conventions. It represents the cloud region of
+// the invoked function.
+func FaaSInvokedRegion(val string) attribute.KeyValue {
+ return FaaSInvokedRegionKey.String(val)
+}
+
+// FaaSMaxMemory returns an attribute KeyValue conforming to the
+// "faas.max_memory" semantic conventions. It represents the amount of memory
+// available to the serverless function converted to Bytes.
+func FaaSMaxMemory(val int) attribute.KeyValue {
+ return FaaSMaxMemoryKey.Int(val)
+}
+
+// FaaSName returns an attribute KeyValue conforming to the "faas.name" semantic
+// conventions. It represents the name of the single function that this runtime
+// instance executes.
+func FaaSName(val string) attribute.KeyValue {
+ return FaaSNameKey.String(val)
+}
+
+// FaaSTime returns an attribute KeyValue conforming to the "faas.time" semantic
+// conventions. It represents a string containing the function invocation time in
+// the [ISO 8601] format expressed in [UTC].
+//
+// [ISO 8601]: https://www.iso.org/iso-8601-date-and-time-format.html
+// [UTC]: https://www.w3.org/TR/NOTE-datetime
+func FaaSTime(val string) attribute.KeyValue {
+ return FaaSTimeKey.String(val)
+}
+
+// FaaSVersion returns an attribute KeyValue conforming to the "faas.version"
+// semantic conventions. It represents the immutable version of the function
+// being executed.
+func FaaSVersion(val string) attribute.KeyValue {
+ return FaaSVersionKey.String(val)
+}
+
+// Enum values for faas.document.operation
+var (
+ // When a new object is created.
+ // Stability: development
+ FaaSDocumentOperationInsert = FaaSDocumentOperationKey.String("insert")
+ // When an object is modified.
+ // Stability: development
+ FaaSDocumentOperationEdit = FaaSDocumentOperationKey.String("edit")
+ // When an object is deleted.
+ // Stability: development
+ FaaSDocumentOperationDelete = FaaSDocumentOperationKey.String("delete")
+)
+
+// Enum values for faas.invoked_provider
+var (
+ // Alibaba Cloud
+ // Stability: development
+ FaaSInvokedProviderAlibabaCloud = FaaSInvokedProviderKey.String("alibaba_cloud")
+ // Amazon Web Services
+ // Stability: development
+ FaaSInvokedProviderAWS = FaaSInvokedProviderKey.String("aws")
+ // Microsoft Azure
+ // Stability: development
+ FaaSInvokedProviderAzure = FaaSInvokedProviderKey.String("azure")
+ // Google Cloud Platform
+ // Stability: development
+ FaaSInvokedProviderGCP = FaaSInvokedProviderKey.String("gcp")
+ // Tencent Cloud
+ // Stability: development
+ FaaSInvokedProviderTencentCloud = FaaSInvokedProviderKey.String("tencent_cloud")
+)
+
+// Enum values for faas.trigger
+var (
+ // A response to some data source operation such as a database or filesystem
+ // read/write
+ // Stability: development
+ FaaSTriggerDatasource = FaaSTriggerKey.String("datasource")
+ // To provide an answer to an inbound HTTP request
+ // Stability: development
+ FaaSTriggerHTTP = FaaSTriggerKey.String("http")
+ // A function is set to be executed when messages are sent to a messaging system
+ // Stability: development
+ FaaSTriggerPubSub = FaaSTriggerKey.String("pubsub")
+ // A function is scheduled to be executed regularly
+ // Stability: development
+ FaaSTriggerTimer = FaaSTriggerKey.String("timer")
+ // If none of the others apply
+ // Stability: development
+ FaaSTriggerOther = FaaSTriggerKey.String("other")
+)
+
+// Namespace: feature_flag
+const (
+ // FeatureFlagContextIDKey is the attribute Key conforming to the
+ // "feature_flag.context.id" semantic conventions. It represents the unique
+ // identifier for the flag evaluation context. For example, the targeting key.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Release_Candidate
+ //
+ // Examples: "5157782b-2203-4c80-a857-dbbd5e7761db"
+ FeatureFlagContextIDKey = attribute.Key("feature_flag.context.id")
+
+ // FeatureFlagErrorMessageKey is the attribute Key conforming to the
+ // "feature_flag.error.message" semantic conventions. It represents a message
+ // providing more detail about an error that occurred during feature flag
+ // evaluation in human-readable form.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Release_Candidate
+ //
+ // Examples: "Unexpected input type: string", "The user has exceeded their
+ // storage quota"
+ FeatureFlagErrorMessageKey = attribute.Key("feature_flag.error.message")
+
+ // FeatureFlagKeyKey is the attribute Key conforming to the "feature_flag.key"
+ // semantic conventions. It represents the lookup key of the feature flag.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Release_Candidate
+ //
+ // Examples: "logo-color"
+ FeatureFlagKeyKey = attribute.Key("feature_flag.key")
+
+ // FeatureFlagProviderNameKey is the attribute Key conforming to the
+ // "feature_flag.provider.name" semantic conventions. It represents the
+ // identifies the feature flag provider.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Release_Candidate
+ //
+ // Examples: "Flag Manager"
+ FeatureFlagProviderNameKey = attribute.Key("feature_flag.provider.name")
+
+ // FeatureFlagResultReasonKey is the attribute Key conforming to the
+ // "feature_flag.result.reason" semantic conventions. It represents the reason
+ // code which shows how a feature flag value was determined.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Release_Candidate
+ //
+ // Examples: "static", "targeting_match", "error", "default"
+ FeatureFlagResultReasonKey = attribute.Key("feature_flag.result.reason")
+
+ // FeatureFlagResultValueKey is the attribute Key conforming to the
+ // "feature_flag.result.value" semantic conventions. It represents the evaluated
+ // value of the feature flag.
+ //
+ // Type: any
+ // RequirementLevel: Recommended
+ // Stability: Release_Candidate
+ //
+ // Examples: "#ff0000", true, 3
+ // Note: With some feature flag providers, feature flag results can be quite
+ // large or contain private or sensitive details.
+ // Because of this, `feature_flag.result.variant` is often the preferred
+ // attribute if it is available.
+ //
+ // It may be desirable to redact or otherwise limit the size and scope of
+ // `feature_flag.result.value` if possible.
+ // Because the evaluated flag value is unstructured and may be any type, it is
+ // left to the instrumentation author to determine how best to achieve this.
+ FeatureFlagResultValueKey = attribute.Key("feature_flag.result.value")
+
+ // FeatureFlagResultVariantKey is the attribute Key conforming to the
+ // "feature_flag.result.variant" semantic conventions. It represents a semantic
+ // identifier for an evaluated flag value.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Release_Candidate
+ //
+ // Examples: "red", "true", "on"
+ // Note: A semantic identifier, commonly referred to as a variant, provides a
+ // means
+ // for referring to a value without including the value itself. This can
+ // provide additional context for understanding the meaning behind a value.
+ // For example, the variant `red` maybe be used for the value `#c05543`.
+ FeatureFlagResultVariantKey = attribute.Key("feature_flag.result.variant")
+
+ // FeatureFlagSetIDKey is the attribute Key conforming to the
+ // "feature_flag.set.id" semantic conventions. It represents the identifier of
+ // the [flag set] to which the feature flag belongs.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Release_Candidate
+ //
+ // Examples: "proj-1", "ab98sgs", "service1/dev"
+ //
+ // [flag set]: https://openfeature.dev/specification/glossary/#flag-set
+ FeatureFlagSetIDKey = attribute.Key("feature_flag.set.id")
+
+ // FeatureFlagVersionKey is the attribute Key conforming to the
+ // "feature_flag.version" semantic conventions. It represents the version of the
+ // ruleset used during the evaluation. This may be any stable value which
+ // uniquely identifies the ruleset.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Release_Candidate
+ //
+ // Examples: "1", "01ABCDEF"
+ FeatureFlagVersionKey = attribute.Key("feature_flag.version")
+)
+
+// FeatureFlagContextID returns an attribute KeyValue conforming to the
+// "feature_flag.context.id" semantic conventions. It represents the unique
+// identifier for the flag evaluation context. For example, the targeting key.
+func FeatureFlagContextID(val string) attribute.KeyValue {
+ return FeatureFlagContextIDKey.String(val)
+}
+
+// FeatureFlagErrorMessage returns an attribute KeyValue conforming to the
+// "feature_flag.error.message" semantic conventions. It represents a message
+// providing more detail about an error that occurred during feature flag
+// evaluation in human-readable form.
+func FeatureFlagErrorMessage(val string) attribute.KeyValue {
+ return FeatureFlagErrorMessageKey.String(val)
+}
+
+// FeatureFlagKey returns an attribute KeyValue conforming to the
+// "feature_flag.key" semantic conventions. It represents the lookup key of the
+// feature flag.
+func FeatureFlagKey(val string) attribute.KeyValue {
+ return FeatureFlagKeyKey.String(val)
+}
+
+// FeatureFlagProviderName returns an attribute KeyValue conforming to the
+// "feature_flag.provider.name" semantic conventions. It represents the
+// identifies the feature flag provider.
+func FeatureFlagProviderName(val string) attribute.KeyValue {
+ return FeatureFlagProviderNameKey.String(val)
+}
+
+// FeatureFlagResultVariant returns an attribute KeyValue conforming to the
+// "feature_flag.result.variant" semantic conventions. It represents a semantic
+// identifier for an evaluated flag value.
+func FeatureFlagResultVariant(val string) attribute.KeyValue {
+ return FeatureFlagResultVariantKey.String(val)
+}
+
+// FeatureFlagSetID returns an attribute KeyValue conforming to the
+// "feature_flag.set.id" semantic conventions. It represents the identifier of
+// the [flag set] to which the feature flag belongs.
+//
+// [flag set]: https://openfeature.dev/specification/glossary/#flag-set
+func FeatureFlagSetID(val string) attribute.KeyValue {
+ return FeatureFlagSetIDKey.String(val)
+}
+
+// FeatureFlagVersion returns an attribute KeyValue conforming to the
+// "feature_flag.version" semantic conventions. It represents the version of the
+// ruleset used during the evaluation. This may be any stable value which
+// uniquely identifies the ruleset.
+func FeatureFlagVersion(val string) attribute.KeyValue {
+ return FeatureFlagVersionKey.String(val)
+}
+
+// Enum values for feature_flag.result.reason
+var (
+ // The resolved value is static (no dynamic evaluation).
+ // Stability: release_candidate
+ FeatureFlagResultReasonStatic = FeatureFlagResultReasonKey.String("static")
+ // The resolved value fell back to a pre-configured value (no dynamic evaluation
+ // occurred or dynamic evaluation yielded no result).
+ // Stability: release_candidate
+ FeatureFlagResultReasonDefault = FeatureFlagResultReasonKey.String("default")
+ // The resolved value was the result of a dynamic evaluation, such as a rule or
+ // specific user-targeting.
+ // Stability: release_candidate
+ FeatureFlagResultReasonTargetingMatch = FeatureFlagResultReasonKey.String("targeting_match")
+ // The resolved value was the result of pseudorandom assignment.
+ // Stability: release_candidate
+ FeatureFlagResultReasonSplit = FeatureFlagResultReasonKey.String("split")
+ // The resolved value was retrieved from cache.
+ // Stability: release_candidate
+ FeatureFlagResultReasonCached = FeatureFlagResultReasonKey.String("cached")
+ // The resolved value was the result of the flag being disabled in the
+ // management system.
+ // Stability: release_candidate
+ FeatureFlagResultReasonDisabled = FeatureFlagResultReasonKey.String("disabled")
+ // The reason for the resolved value could not be determined.
+ // Stability: release_candidate
+ FeatureFlagResultReasonUnknown = FeatureFlagResultReasonKey.String("unknown")
+ // The resolved value is non-authoritative or possibly out of date
+ // Stability: release_candidate
+ FeatureFlagResultReasonStale = FeatureFlagResultReasonKey.String("stale")
+ // The resolved value was the result of an error.
+ // Stability: release_candidate
+ FeatureFlagResultReasonError = FeatureFlagResultReasonKey.String("error")
+)
+
+// Namespace: file
+const (
+ // FileAccessedKey is the attribute Key conforming to the "file.accessed"
+ // semantic conventions. It represents the time when the file was last accessed,
+ // in ISO 8601 format.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "2021-01-01T12:00:00Z"
+ // Note: This attribute might not be supported by some file systems — NFS,
+ // FAT32, in embedded OS, etc.
+ FileAccessedKey = attribute.Key("file.accessed")
+
+ // FileAttributesKey is the attribute Key conforming to the "file.attributes"
+ // semantic conventions. It represents the array of file attributes.
+ //
+ // Type: string[]
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "readonly", "hidden"
+ // Note: Attributes names depend on the OS or file system. Here’s a
+ // non-exhaustive list of values expected for this attribute: `archive`,
+ // `compressed`, `directory`, `encrypted`, `execute`, `hidden`, `immutable`,
+ // `journaled`, `read`, `readonly`, `symbolic link`, `system`, `temporary`,
+ // `write`.
+ FileAttributesKey = attribute.Key("file.attributes")
+
+ // FileChangedKey is the attribute Key conforming to the "file.changed" semantic
+ // conventions. It represents the time when the file attributes or metadata was
+ // last changed, in ISO 8601 format.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "2021-01-01T12:00:00Z"
+ // Note: `file.changed` captures the time when any of the file's properties or
+ // attributes (including the content) are changed, while `file.modified`
+ // captures the timestamp when the file content is modified.
+ FileChangedKey = attribute.Key("file.changed")
+
+ // FileCreatedKey is the attribute Key conforming to the "file.created" semantic
+ // conventions. It represents the time when the file was created, in ISO 8601
+ // format.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "2021-01-01T12:00:00Z"
+ // Note: This attribute might not be supported by some file systems — NFS,
+ // FAT32, in embedded OS, etc.
+ FileCreatedKey = attribute.Key("file.created")
+
+ // FileDirectoryKey is the attribute Key conforming to the "file.directory"
+ // semantic conventions. It represents the directory where the file is located.
+ // It should include the drive letter, when appropriate.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "/home/user", "C:\Program Files\MyApp"
+ FileDirectoryKey = attribute.Key("file.directory")
+
+ // FileExtensionKey is the attribute Key conforming to the "file.extension"
+ // semantic conventions. It represents the file extension, excluding the leading
+ // dot.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "png", "gz"
+ // Note: When the file name has multiple extensions (example.tar.gz), only the
+ // last one should be captured ("gz", not "tar.gz").
+ FileExtensionKey = attribute.Key("file.extension")
+
+ // FileForkNameKey is the attribute Key conforming to the "file.fork_name"
+ // semantic conventions. It represents the name of the fork. A fork is
+ // additional data associated with a filesystem object.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "Zone.Identifier"
+ // Note: On Linux, a resource fork is used to store additional data with a
+ // filesystem object. A file always has at least one fork for the data portion,
+ // and additional forks may exist.
+ // On NTFS, this is analogous to an Alternate Data Stream (ADS), and the default
+ // data stream for a file is just called $DATA. Zone.Identifier is commonly used
+ // by Windows to track contents downloaded from the Internet. An ADS is
+ // typically of the form: C:\path\to\filename.extension:some_fork_name, and
+ // some_fork_name is the value that should populate `fork_name`.
+ // `filename.extension` should populate `file.name`, and `extension` should
+ // populate `file.extension`. The full path, `file.path`, will include the fork
+ // name.
+ FileForkNameKey = attribute.Key("file.fork_name")
+
+ // FileGroupIDKey is the attribute Key conforming to the "file.group.id"
+ // semantic conventions. It represents the primary Group ID (GID) of the file.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "1000"
+ FileGroupIDKey = attribute.Key("file.group.id")
+
+ // FileGroupNameKey is the attribute Key conforming to the "file.group.name"
+ // semantic conventions. It represents the primary group name of the file.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "users"
+ FileGroupNameKey = attribute.Key("file.group.name")
+
+ // FileInodeKey is the attribute Key conforming to the "file.inode" semantic
+ // conventions. It represents the inode representing the file in the filesystem.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "256383"
+ FileInodeKey = attribute.Key("file.inode")
+
+ // FileModeKey is the attribute Key conforming to the "file.mode" semantic
+ // conventions. It represents the mode of the file in octal representation.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "0640"
+ FileModeKey = attribute.Key("file.mode")
+
+ // FileModifiedKey is the attribute Key conforming to the "file.modified"
+ // semantic conventions. It represents the time when the file content was last
+ // modified, in ISO 8601 format.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "2021-01-01T12:00:00Z"
+ FileModifiedKey = attribute.Key("file.modified")
+
+ // FileNameKey is the attribute Key conforming to the "file.name" semantic
+ // conventions. It represents the name of the file including the extension,
+ // without the directory.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "example.png"
+ FileNameKey = attribute.Key("file.name")
+
+ // FileOwnerIDKey is the attribute Key conforming to the "file.owner.id"
+ // semantic conventions. It represents the user ID (UID) or security identifier
+ // (SID) of the file owner.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "1000"
+ FileOwnerIDKey = attribute.Key("file.owner.id")
+
+ // FileOwnerNameKey is the attribute Key conforming to the "file.owner.name"
+ // semantic conventions. It represents the username of the file owner.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "root"
+ FileOwnerNameKey = attribute.Key("file.owner.name")
+
+ // FilePathKey is the attribute Key conforming to the "file.path" semantic
+ // conventions. It represents the full path to the file, including the file
+ // name. It should include the drive letter, when appropriate.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "/home/alice/example.png", "C:\Program Files\MyApp\myapp.exe"
+ FilePathKey = attribute.Key("file.path")
+
+ // FileSizeKey is the attribute Key conforming to the "file.size" semantic
+ // conventions. It represents the file size in bytes.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ FileSizeKey = attribute.Key("file.size")
+
+ // FileSymbolicLinkTargetPathKey is the attribute Key conforming to the
+ // "file.symbolic_link.target_path" semantic conventions. It represents the path
+ // to the target of a symbolic link.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "/usr/bin/python3"
+ // Note: This attribute is only applicable to symbolic links.
+ FileSymbolicLinkTargetPathKey = attribute.Key("file.symbolic_link.target_path")
+)
+
+// FileAccessed returns an attribute KeyValue conforming to the "file.accessed"
+// semantic conventions. It represents the time when the file was last accessed,
+// in ISO 8601 format.
+func FileAccessed(val string) attribute.KeyValue {
+ return FileAccessedKey.String(val)
+}
+
+// FileAttributes returns an attribute KeyValue conforming to the
+// "file.attributes" semantic conventions. It represents the array of file
+// attributes.
+func FileAttributes(val ...string) attribute.KeyValue {
+ return FileAttributesKey.StringSlice(val)
+}
+
+// FileChanged returns an attribute KeyValue conforming to the "file.changed"
+// semantic conventions. It represents the time when the file attributes or
+// metadata was last changed, in ISO 8601 format.
+func FileChanged(val string) attribute.KeyValue {
+ return FileChangedKey.String(val)
+}
+
+// FileCreated returns an attribute KeyValue conforming to the "file.created"
+// semantic conventions. It represents the time when the file was created, in ISO
+// 8601 format.
+func FileCreated(val string) attribute.KeyValue {
+ return FileCreatedKey.String(val)
+}
+
+// FileDirectory returns an attribute KeyValue conforming to the "file.directory"
+// semantic conventions. It represents the directory where the file is located.
+// It should include the drive letter, when appropriate.
+func FileDirectory(val string) attribute.KeyValue {
+ return FileDirectoryKey.String(val)
+}
+
+// FileExtension returns an attribute KeyValue conforming to the "file.extension"
+// semantic conventions. It represents the file extension, excluding the leading
+// dot.
+func FileExtension(val string) attribute.KeyValue {
+ return FileExtensionKey.String(val)
+}
+
+// FileForkName returns an attribute KeyValue conforming to the "file.fork_name"
+// semantic conventions. It represents the name of the fork. A fork is additional
+// data associated with a filesystem object.
+func FileForkName(val string) attribute.KeyValue {
+ return FileForkNameKey.String(val)
+}
+
+// FileGroupID returns an attribute KeyValue conforming to the "file.group.id"
+// semantic conventions. It represents the primary Group ID (GID) of the file.
+func FileGroupID(val string) attribute.KeyValue {
+ return FileGroupIDKey.String(val)
+}
+
+// FileGroupName returns an attribute KeyValue conforming to the
+// "file.group.name" semantic conventions. It represents the primary group name
+// of the file.
+func FileGroupName(val string) attribute.KeyValue {
+ return FileGroupNameKey.String(val)
+}
+
+// FileInode returns an attribute KeyValue conforming to the "file.inode"
+// semantic conventions. It represents the inode representing the file in the
+// filesystem.
+func FileInode(val string) attribute.KeyValue {
+ return FileInodeKey.String(val)
+}
+
+// FileMode returns an attribute KeyValue conforming to the "file.mode" semantic
+// conventions. It represents the mode of the file in octal representation.
+func FileMode(val string) attribute.KeyValue {
+ return FileModeKey.String(val)
+}
+
+// FileModified returns an attribute KeyValue conforming to the "file.modified"
+// semantic conventions. It represents the time when the file content was last
+// modified, in ISO 8601 format.
+func FileModified(val string) attribute.KeyValue {
+ return FileModifiedKey.String(val)
+}
+
+// FileName returns an attribute KeyValue conforming to the "file.name" semantic
+// conventions. It represents the name of the file including the extension,
+// without the directory.
+func FileName(val string) attribute.KeyValue {
+ return FileNameKey.String(val)
+}
+
+// FileOwnerID returns an attribute KeyValue conforming to the "file.owner.id"
+// semantic conventions. It represents the user ID (UID) or security identifier
+// (SID) of the file owner.
+func FileOwnerID(val string) attribute.KeyValue {
+ return FileOwnerIDKey.String(val)
+}
+
+// FileOwnerName returns an attribute KeyValue conforming to the
+// "file.owner.name" semantic conventions. It represents the username of the file
+// owner.
+func FileOwnerName(val string) attribute.KeyValue {
+ return FileOwnerNameKey.String(val)
+}
+
+// FilePath returns an attribute KeyValue conforming to the "file.path" semantic
+// conventions. It represents the full path to the file, including the file name.
+// It should include the drive letter, when appropriate.
+func FilePath(val string) attribute.KeyValue {
+ return FilePathKey.String(val)
+}
+
+// FileSize returns an attribute KeyValue conforming to the "file.size" semantic
+// conventions. It represents the file size in bytes.
+func FileSize(val int) attribute.KeyValue {
+ return FileSizeKey.Int(val)
+}
+
+// FileSymbolicLinkTargetPath returns an attribute KeyValue conforming to the
+// "file.symbolic_link.target_path" semantic conventions. It represents the path
+// to the target of a symbolic link.
+func FileSymbolicLinkTargetPath(val string) attribute.KeyValue {
+ return FileSymbolicLinkTargetPathKey.String(val)
+}
+
+// Namespace: gcp
+const (
+ // GCPAppHubApplicationContainerKey is the attribute Key conforming to the
+ // "gcp.apphub.application.container" semantic conventions. It represents the
+ // container within GCP where the AppHub application is defined.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "projects/my-container-project"
+ GCPAppHubApplicationContainerKey = attribute.Key("gcp.apphub.application.container")
+
+ // GCPAppHubApplicationIDKey is the attribute Key conforming to the
+ // "gcp.apphub.application.id" semantic conventions. It represents the name of
+ // the application as configured in AppHub.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "my-application"
+ GCPAppHubApplicationIDKey = attribute.Key("gcp.apphub.application.id")
+
+ // GCPAppHubApplicationLocationKey is the attribute Key conforming to the
+ // "gcp.apphub.application.location" semantic conventions. It represents the GCP
+ // zone or region where the application is defined.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "us-central1"
+ GCPAppHubApplicationLocationKey = attribute.Key("gcp.apphub.application.location")
+
+ // GCPAppHubServiceCriticalityTypeKey is the attribute Key conforming to the
+ // "gcp.apphub.service.criticality_type" semantic conventions. It represents the
+ // criticality of a service indicates its importance to the business.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ // Note: [See AppHub type enum]
+ //
+ // [See AppHub type enum]: https://cloud.google.com/app-hub/docs/reference/rest/v1/Attributes#type
+ GCPAppHubServiceCriticalityTypeKey = attribute.Key("gcp.apphub.service.criticality_type")
+
+ // GCPAppHubServiceEnvironmentTypeKey is the attribute Key conforming to the
+ // "gcp.apphub.service.environment_type" semantic conventions. It represents the
+ // environment of a service is the stage of a software lifecycle.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ // Note: [See AppHub environment type]
+ //
+ // [See AppHub environment type]: https://cloud.google.com/app-hub/docs/reference/rest/v1/Attributes#type_1
+ GCPAppHubServiceEnvironmentTypeKey = attribute.Key("gcp.apphub.service.environment_type")
+
+ // GCPAppHubServiceIDKey is the attribute Key conforming to the
+ // "gcp.apphub.service.id" semantic conventions. It represents the name of the
+ // service as configured in AppHub.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "my-service"
+ GCPAppHubServiceIDKey = attribute.Key("gcp.apphub.service.id")
+
+ // GCPAppHubWorkloadCriticalityTypeKey is the attribute Key conforming to the
+ // "gcp.apphub.workload.criticality_type" semantic conventions. It represents
+ // the criticality of a workload indicates its importance to the business.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ // Note: [See AppHub type enum]
+ //
+ // [See AppHub type enum]: https://cloud.google.com/app-hub/docs/reference/rest/v1/Attributes#type
+ GCPAppHubWorkloadCriticalityTypeKey = attribute.Key("gcp.apphub.workload.criticality_type")
+
+ // GCPAppHubWorkloadEnvironmentTypeKey is the attribute Key conforming to the
+ // "gcp.apphub.workload.environment_type" semantic conventions. It represents
+ // the environment of a workload is the stage of a software lifecycle.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ // Note: [See AppHub environment type]
+ //
+ // [See AppHub environment type]: https://cloud.google.com/app-hub/docs/reference/rest/v1/Attributes#type_1
+ GCPAppHubWorkloadEnvironmentTypeKey = attribute.Key("gcp.apphub.workload.environment_type")
+
+ // GCPAppHubWorkloadIDKey is the attribute Key conforming to the
+ // "gcp.apphub.workload.id" semantic conventions. It represents the name of the
+ // workload as configured in AppHub.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "my-workload"
+ GCPAppHubWorkloadIDKey = attribute.Key("gcp.apphub.workload.id")
+
+ // GCPAppHubDestinationApplicationContainerKey is the attribute Key conforming
+ // to the "gcp.apphub_destination.application.container" semantic conventions.
+ // It represents the container within GCP where the AppHub destination
+ // application is defined.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "projects/my-container-project"
+ GCPAppHubDestinationApplicationContainerKey = attribute.Key("gcp.apphub_destination.application.container")
+
+ // GCPAppHubDestinationApplicationIDKey is the attribute Key conforming to the
+ // "gcp.apphub_destination.application.id" semantic conventions. It represents
+ // the name of the destination application as configured in AppHub.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "my-application"
+ GCPAppHubDestinationApplicationIDKey = attribute.Key("gcp.apphub_destination.application.id")
+
+ // GCPAppHubDestinationApplicationLocationKey is the attribute Key conforming to
+ // the "gcp.apphub_destination.application.location" semantic conventions. It
+ // represents the GCP zone or region where the destination application is
+ // defined.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "us-central1"
+ GCPAppHubDestinationApplicationLocationKey = attribute.Key("gcp.apphub_destination.application.location")
+
+ // GCPAppHubDestinationServiceCriticalityTypeKey is the attribute Key conforming
+ // to the "gcp.apphub_destination.service.criticality_type" semantic
+ // conventions. It represents the criticality of a destination workload
+ // indicates its importance to the business as specified in [AppHub type enum].
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ //
+ // [AppHub type enum]: https://cloud.google.com/app-hub/docs/reference/rest/v1/Attributes#type
+ GCPAppHubDestinationServiceCriticalityTypeKey = attribute.Key("gcp.apphub_destination.service.criticality_type")
+
+ // GCPAppHubDestinationServiceEnvironmentTypeKey is the attribute Key conforming
+ // to the "gcp.apphub_destination.service.environment_type" semantic
+ // conventions. It represents the software lifecycle stage of a destination
+ // service as defined [AppHub environment type].
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ //
+ // [AppHub environment type]: https://cloud.google.com/app-hub/docs/reference/rest/v1/Attributes#type_1
+ GCPAppHubDestinationServiceEnvironmentTypeKey = attribute.Key("gcp.apphub_destination.service.environment_type")
+
+ // GCPAppHubDestinationServiceIDKey is the attribute Key conforming to the
+ // "gcp.apphub_destination.service.id" semantic conventions. It represents the
+ // name of the destination service as configured in AppHub.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "my-service"
+ GCPAppHubDestinationServiceIDKey = attribute.Key("gcp.apphub_destination.service.id")
+
+ // GCPAppHubDestinationWorkloadCriticalityTypeKey is the attribute Key
+ // conforming to the "gcp.apphub_destination.workload.criticality_type" semantic
+ // conventions. It represents the criticality of a destination workload
+ // indicates its importance to the business as specified in [AppHub type enum].
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ //
+ // [AppHub type enum]: https://cloud.google.com/app-hub/docs/reference/rest/v1/Attributes#type
+ GCPAppHubDestinationWorkloadCriticalityTypeKey = attribute.Key("gcp.apphub_destination.workload.criticality_type")
+
+ // GCPAppHubDestinationWorkloadEnvironmentTypeKey is the attribute Key
+ // conforming to the "gcp.apphub_destination.workload.environment_type" semantic
+ // conventions. It represents the environment of a destination workload is the
+ // stage of a software lifecycle as provided in the [AppHub environment type].
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ //
+ // [AppHub environment type]: https://cloud.google.com/app-hub/docs/reference/rest/v1/Attributes#type_1
+ GCPAppHubDestinationWorkloadEnvironmentTypeKey = attribute.Key("gcp.apphub_destination.workload.environment_type")
+
+ // GCPAppHubDestinationWorkloadIDKey is the attribute Key conforming to the
+ // "gcp.apphub_destination.workload.id" semantic conventions. It represents the
+ // name of the destination workload as configured in AppHub.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "my-workload"
+ GCPAppHubDestinationWorkloadIDKey = attribute.Key("gcp.apphub_destination.workload.id")
+
+ // GCPClientServiceKey is the attribute Key conforming to the
+ // "gcp.client.service" semantic conventions. It represents the identifies the
+ // Google Cloud service for which the official client library is intended.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "appengine", "run", "firestore", "alloydb", "spanner"
+ // Note: Intended to be a stable identifier for Google Cloud client libraries
+ // that is uniform across implementation languages. The value should be derived
+ // from the canonical service domain for the service; for example,
+ // 'foo.googleapis.com' should result in a value of 'foo'.
+ GCPClientServiceKey = attribute.Key("gcp.client.service")
+
+ // GCPCloudRunJobExecutionKey is the attribute Key conforming to the
+ // "gcp.cloud_run.job.execution" semantic conventions. It represents the name of
+ // the Cloud Run [execution] being run for the Job, as set by the
+ // [`CLOUD_RUN_EXECUTION`] environment variable.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "job-name-xxxx", "sample-job-mdw84"
+ //
+ // [execution]: https://cloud.google.com/run/docs/managing/job-executions
+ // [`CLOUD_RUN_EXECUTION`]: https://cloud.google.com/run/docs/container-contract#jobs-env-vars
+ GCPCloudRunJobExecutionKey = attribute.Key("gcp.cloud_run.job.execution")
+
+ // GCPCloudRunJobTaskIndexKey is the attribute Key conforming to the
+ // "gcp.cloud_run.job.task_index" semantic conventions. It represents the index
+ // for a task within an execution as provided by the [`CLOUD_RUN_TASK_INDEX`]
+ // environment variable.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 0, 1
+ //
+ // [`CLOUD_RUN_TASK_INDEX`]: https://cloud.google.com/run/docs/container-contract#jobs-env-vars
+ GCPCloudRunJobTaskIndexKey = attribute.Key("gcp.cloud_run.job.task_index")
+
+ // GCPGCEInstanceHostnameKey is the attribute Key conforming to the
+ // "gcp.gce.instance.hostname" semantic conventions. It represents the hostname
+ // of a GCE instance. This is the full value of the default or [custom hostname]
+ // .
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "my-host1234.example.com",
+ // "sample-vm.us-west1-b.c.my-project.internal"
+ //
+ // [custom hostname]: https://cloud.google.com/compute/docs/instances/custom-hostname-vm
+ GCPGCEInstanceHostnameKey = attribute.Key("gcp.gce.instance.hostname")
+
+ // GCPGCEInstanceNameKey is the attribute Key conforming to the
+ // "gcp.gce.instance.name" semantic conventions. It represents the instance name
+ // of a GCE instance. This is the value provided by `host.name`, the visible
+ // name of the instance in the Cloud Console UI, and the prefix for the default
+ // hostname of the instance as defined by the [default internal DNS name].
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "instance-1", "my-vm-name"
+ //
+ // [default internal DNS name]: https://cloud.google.com/compute/docs/internal-dns#instance-fully-qualified-domain-names
+ GCPGCEInstanceNameKey = attribute.Key("gcp.gce.instance.name")
+
+ // GCPGCEInstanceGroupManagerNameKey is the attribute Key conforming to the
+ // "gcp.gce.instance_group_manager.name" semantic conventions. It represents the
+ // name of the Instance Group Manager (IGM) that manages this VM, if any.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "web-igm", "my-managed-group"
+ GCPGCEInstanceGroupManagerNameKey = attribute.Key("gcp.gce.instance_group_manager.name")
+
+ // GCPGCEInstanceGroupManagerRegionKey is the attribute Key conforming to the
+ // "gcp.gce.instance_group_manager.region" semantic conventions. It represents
+ // the region of a **regional** Instance Group Manager (e.g., `us-central1`).
+ // Set this **only** when the IGM is regional.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "us-central1", "europe-west1"
+ GCPGCEInstanceGroupManagerRegionKey = attribute.Key("gcp.gce.instance_group_manager.region")
+
+ // GCPGCEInstanceGroupManagerZoneKey is the attribute Key conforming to the
+ // "gcp.gce.instance_group_manager.zone" semantic conventions. It represents the
+ // zone of a **zonal** Instance Group Manager (e.g., `us-central1-a`). Set this
+ // **only** when the IGM is zonal.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "us-central1-a", "europe-west1-b"
+ GCPGCEInstanceGroupManagerZoneKey = attribute.Key("gcp.gce.instance_group_manager.zone")
+)
+
+// GCPAppHubApplicationContainer returns an attribute KeyValue conforming to the
+// "gcp.apphub.application.container" semantic conventions. It represents the
+// container within GCP where the AppHub application is defined.
+func GCPAppHubApplicationContainer(val string) attribute.KeyValue {
+ return GCPAppHubApplicationContainerKey.String(val)
+}
+
+// GCPAppHubApplicationID returns an attribute KeyValue conforming to the
+// "gcp.apphub.application.id" semantic conventions. It represents the name of
+// the application as configured in AppHub.
+func GCPAppHubApplicationID(val string) attribute.KeyValue {
+ return GCPAppHubApplicationIDKey.String(val)
+}
+
+// GCPAppHubApplicationLocation returns an attribute KeyValue conforming to the
+// "gcp.apphub.application.location" semantic conventions. It represents the GCP
+// zone or region where the application is defined.
+func GCPAppHubApplicationLocation(val string) attribute.KeyValue {
+ return GCPAppHubApplicationLocationKey.String(val)
+}
+
+// GCPAppHubServiceID returns an attribute KeyValue conforming to the
+// "gcp.apphub.service.id" semantic conventions. It represents the name of the
+// service as configured in AppHub.
+func GCPAppHubServiceID(val string) attribute.KeyValue {
+ return GCPAppHubServiceIDKey.String(val)
+}
+
+// GCPAppHubWorkloadID returns an attribute KeyValue conforming to the
+// "gcp.apphub.workload.id" semantic conventions. It represents the name of the
+// workload as configured in AppHub.
+func GCPAppHubWorkloadID(val string) attribute.KeyValue {
+ return GCPAppHubWorkloadIDKey.String(val)
+}
+
+// GCPAppHubDestinationApplicationContainer returns an attribute KeyValue
+// conforming to the "gcp.apphub_destination.application.container" semantic
+// conventions. It represents the container within GCP where the AppHub
+// destination application is defined.
+func GCPAppHubDestinationApplicationContainer(val string) attribute.KeyValue {
+ return GCPAppHubDestinationApplicationContainerKey.String(val)
+}
+
+// GCPAppHubDestinationApplicationID returns an attribute KeyValue conforming to
+// the "gcp.apphub_destination.application.id" semantic conventions. It
+// represents the name of the destination application as configured in AppHub.
+func GCPAppHubDestinationApplicationID(val string) attribute.KeyValue {
+ return GCPAppHubDestinationApplicationIDKey.String(val)
+}
+
+// GCPAppHubDestinationApplicationLocation returns an attribute KeyValue
+// conforming to the "gcp.apphub_destination.application.location" semantic
+// conventions. It represents the GCP zone or region where the destination
+// application is defined.
+func GCPAppHubDestinationApplicationLocation(val string) attribute.KeyValue {
+ return GCPAppHubDestinationApplicationLocationKey.String(val)
+}
+
+// GCPAppHubDestinationServiceID returns an attribute KeyValue conforming to the
+// "gcp.apphub_destination.service.id" semantic conventions. It represents the
+// name of the destination service as configured in AppHub.
+func GCPAppHubDestinationServiceID(val string) attribute.KeyValue {
+ return GCPAppHubDestinationServiceIDKey.String(val)
+}
+
+// GCPAppHubDestinationWorkloadID returns an attribute KeyValue conforming to the
+// "gcp.apphub_destination.workload.id" semantic conventions. It represents the
+// name of the destination workload as configured in AppHub.
+func GCPAppHubDestinationWorkloadID(val string) attribute.KeyValue {
+ return GCPAppHubDestinationWorkloadIDKey.String(val)
+}
+
+// GCPClientService returns an attribute KeyValue conforming to the
+// "gcp.client.service" semantic conventions. It represents the identifies the
+// Google Cloud service for which the official client library is intended.
+func GCPClientService(val string) attribute.KeyValue {
+ return GCPClientServiceKey.String(val)
+}
+
+// GCPCloudRunJobExecution returns an attribute KeyValue conforming to the
+// "gcp.cloud_run.job.execution" semantic conventions. It represents the name of
+// the Cloud Run [execution] being run for the Job, as set by the
+// [`CLOUD_RUN_EXECUTION`] environment variable.
+//
+// [execution]: https://cloud.google.com/run/docs/managing/job-executions
+// [`CLOUD_RUN_EXECUTION`]: https://cloud.google.com/run/docs/container-contract#jobs-env-vars
+func GCPCloudRunJobExecution(val string) attribute.KeyValue {
+ return GCPCloudRunJobExecutionKey.String(val)
+}
+
+// GCPCloudRunJobTaskIndex returns an attribute KeyValue conforming to the
+// "gcp.cloud_run.job.task_index" semantic conventions. It represents the index
+// for a task within an execution as provided by the [`CLOUD_RUN_TASK_INDEX`]
+// environment variable.
+//
+// [`CLOUD_RUN_TASK_INDEX`]: https://cloud.google.com/run/docs/container-contract#jobs-env-vars
+func GCPCloudRunJobTaskIndex(val int) attribute.KeyValue {
+ return GCPCloudRunJobTaskIndexKey.Int(val)
+}
+
+// GCPGCEInstanceHostname returns an attribute KeyValue conforming to the
+// "gcp.gce.instance.hostname" semantic conventions. It represents the hostname
+// of a GCE instance. This is the full value of the default or [custom hostname]
+// .
+//
+// [custom hostname]: https://cloud.google.com/compute/docs/instances/custom-hostname-vm
+func GCPGCEInstanceHostname(val string) attribute.KeyValue {
+ return GCPGCEInstanceHostnameKey.String(val)
+}
+
+// GCPGCEInstanceName returns an attribute KeyValue conforming to the
+// "gcp.gce.instance.name" semantic conventions. It represents the instance name
+// of a GCE instance. This is the value provided by `host.name`, the visible name
+// of the instance in the Cloud Console UI, and the prefix for the default
+// hostname of the instance as defined by the [default internal DNS name].
+//
+// [default internal DNS name]: https://cloud.google.com/compute/docs/internal-dns#instance-fully-qualified-domain-names
+func GCPGCEInstanceName(val string) attribute.KeyValue {
+ return GCPGCEInstanceNameKey.String(val)
+}
+
+// GCPGCEInstanceGroupManagerName returns an attribute KeyValue conforming to the
+// "gcp.gce.instance_group_manager.name" semantic conventions. It represents the
+// name of the Instance Group Manager (IGM) that manages this VM, if any.
+func GCPGCEInstanceGroupManagerName(val string) attribute.KeyValue {
+ return GCPGCEInstanceGroupManagerNameKey.String(val)
+}
+
+// GCPGCEInstanceGroupManagerRegion returns an attribute KeyValue conforming to
+// the "gcp.gce.instance_group_manager.region" semantic conventions. It
+// represents the region of a **regional** Instance Group Manager (e.g.,
+// `us-central1`). Set this **only** when the IGM is regional.
+func GCPGCEInstanceGroupManagerRegion(val string) attribute.KeyValue {
+ return GCPGCEInstanceGroupManagerRegionKey.String(val)
+}
+
+// GCPGCEInstanceGroupManagerZone returns an attribute KeyValue conforming to the
+// "gcp.gce.instance_group_manager.zone" semantic conventions. It represents the
+// zone of a **zonal** Instance Group Manager (e.g., `us-central1-a`). Set this
+// **only** when the IGM is zonal.
+func GCPGCEInstanceGroupManagerZone(val string) attribute.KeyValue {
+ return GCPGCEInstanceGroupManagerZoneKey.String(val)
+}
+
+// Enum values for gcp.apphub.service.criticality_type
+var (
+ // Mission critical service.
+ // Stability: development
+ GCPAppHubServiceCriticalityTypeMissionCritical = GCPAppHubServiceCriticalityTypeKey.String("MISSION_CRITICAL")
+ // High impact.
+ // Stability: development
+ GCPAppHubServiceCriticalityTypeHigh = GCPAppHubServiceCriticalityTypeKey.String("HIGH")
+ // Medium impact.
+ // Stability: development
+ GCPAppHubServiceCriticalityTypeMedium = GCPAppHubServiceCriticalityTypeKey.String("MEDIUM")
+ // Low impact.
+ // Stability: development
+ GCPAppHubServiceCriticalityTypeLow = GCPAppHubServiceCriticalityTypeKey.String("LOW")
+)
+
+// Enum values for gcp.apphub.service.environment_type
+var (
+ // Production environment.
+ // Stability: development
+ GCPAppHubServiceEnvironmentTypeProduction = GCPAppHubServiceEnvironmentTypeKey.String("PRODUCTION")
+ // Staging environment.
+ // Stability: development
+ GCPAppHubServiceEnvironmentTypeStaging = GCPAppHubServiceEnvironmentTypeKey.String("STAGING")
+ // Test environment.
+ // Stability: development
+ GCPAppHubServiceEnvironmentTypeTest = GCPAppHubServiceEnvironmentTypeKey.String("TEST")
+ // Development environment.
+ // Stability: development
+ GCPAppHubServiceEnvironmentTypeDevelopment = GCPAppHubServiceEnvironmentTypeKey.String("DEVELOPMENT")
+)
+
+// Enum values for gcp.apphub.workload.criticality_type
+var (
+ // Mission critical service.
+ // Stability: development
+ GCPAppHubWorkloadCriticalityTypeMissionCritical = GCPAppHubWorkloadCriticalityTypeKey.String("MISSION_CRITICAL")
+ // High impact.
+ // Stability: development
+ GCPAppHubWorkloadCriticalityTypeHigh = GCPAppHubWorkloadCriticalityTypeKey.String("HIGH")
+ // Medium impact.
+ // Stability: development
+ GCPAppHubWorkloadCriticalityTypeMedium = GCPAppHubWorkloadCriticalityTypeKey.String("MEDIUM")
+ // Low impact.
+ // Stability: development
+ GCPAppHubWorkloadCriticalityTypeLow = GCPAppHubWorkloadCriticalityTypeKey.String("LOW")
+)
+
+// Enum values for gcp.apphub.workload.environment_type
+var (
+ // Production environment.
+ // Stability: development
+ GCPAppHubWorkloadEnvironmentTypeProduction = GCPAppHubWorkloadEnvironmentTypeKey.String("PRODUCTION")
+ // Staging environment.
+ // Stability: development
+ GCPAppHubWorkloadEnvironmentTypeStaging = GCPAppHubWorkloadEnvironmentTypeKey.String("STAGING")
+ // Test environment.
+ // Stability: development
+ GCPAppHubWorkloadEnvironmentTypeTest = GCPAppHubWorkloadEnvironmentTypeKey.String("TEST")
+ // Development environment.
+ // Stability: development
+ GCPAppHubWorkloadEnvironmentTypeDevelopment = GCPAppHubWorkloadEnvironmentTypeKey.String("DEVELOPMENT")
+)
+
+// Enum values for gcp.apphub_destination.service.criticality_type
+var (
+ // Mission critical service.
+ // Stability: development
+ GCPAppHubDestinationServiceCriticalityTypeMissionCritical = GCPAppHubDestinationServiceCriticalityTypeKey.String("MISSION_CRITICAL")
+ // High impact.
+ // Stability: development
+ GCPAppHubDestinationServiceCriticalityTypeHigh = GCPAppHubDestinationServiceCriticalityTypeKey.String("HIGH")
+ // Medium impact.
+ // Stability: development
+ GCPAppHubDestinationServiceCriticalityTypeMedium = GCPAppHubDestinationServiceCriticalityTypeKey.String("MEDIUM")
+ // Low impact.
+ // Stability: development
+ GCPAppHubDestinationServiceCriticalityTypeLow = GCPAppHubDestinationServiceCriticalityTypeKey.String("LOW")
+)
+
+// Enum values for gcp.apphub_destination.service.environment_type
+var (
+ // Production environment.
+ // Stability: development
+ GCPAppHubDestinationServiceEnvironmentTypeProduction = GCPAppHubDestinationServiceEnvironmentTypeKey.String("PRODUCTION")
+ // Staging environment.
+ // Stability: development
+ GCPAppHubDestinationServiceEnvironmentTypeStaging = GCPAppHubDestinationServiceEnvironmentTypeKey.String("STAGING")
+ // Test environment.
+ // Stability: development
+ GCPAppHubDestinationServiceEnvironmentTypeTest = GCPAppHubDestinationServiceEnvironmentTypeKey.String("TEST")
+ // Development environment.
+ // Stability: development
+ GCPAppHubDestinationServiceEnvironmentTypeDevelopment = GCPAppHubDestinationServiceEnvironmentTypeKey.String("DEVELOPMENT")
+)
+
+// Enum values for gcp.apphub_destination.workload.criticality_type
+var (
+ // Mission critical service.
+ // Stability: development
+ GCPAppHubDestinationWorkloadCriticalityTypeMissionCritical = GCPAppHubDestinationWorkloadCriticalityTypeKey.String("MISSION_CRITICAL")
+ // High impact.
+ // Stability: development
+ GCPAppHubDestinationWorkloadCriticalityTypeHigh = GCPAppHubDestinationWorkloadCriticalityTypeKey.String("HIGH")
+ // Medium impact.
+ // Stability: development
+ GCPAppHubDestinationWorkloadCriticalityTypeMedium = GCPAppHubDestinationWorkloadCriticalityTypeKey.String("MEDIUM")
+ // Low impact.
+ // Stability: development
+ GCPAppHubDestinationWorkloadCriticalityTypeLow = GCPAppHubDestinationWorkloadCriticalityTypeKey.String("LOW")
+)
+
+// Enum values for gcp.apphub_destination.workload.environment_type
+var (
+ // Production environment.
+ // Stability: development
+ GCPAppHubDestinationWorkloadEnvironmentTypeProduction = GCPAppHubDestinationWorkloadEnvironmentTypeKey.String("PRODUCTION")
+ // Staging environment.
+ // Stability: development
+ GCPAppHubDestinationWorkloadEnvironmentTypeStaging = GCPAppHubDestinationWorkloadEnvironmentTypeKey.String("STAGING")
+ // Test environment.
+ // Stability: development
+ GCPAppHubDestinationWorkloadEnvironmentTypeTest = GCPAppHubDestinationWorkloadEnvironmentTypeKey.String("TEST")
+ // Development environment.
+ // Stability: development
+ GCPAppHubDestinationWorkloadEnvironmentTypeDevelopment = GCPAppHubDestinationWorkloadEnvironmentTypeKey.String("DEVELOPMENT")
+)
+
+// Namespace: gen_ai
+const (
+ // GenAIAgentDescriptionKey is the attribute Key conforming to the
+ // "gen_ai.agent.description" semantic conventions. It represents the free-form
+ // description of the GenAI agent provided by the application.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "Helps with math problems", "Generates fiction stories"
+ GenAIAgentDescriptionKey = attribute.Key("gen_ai.agent.description")
+
+ // GenAIAgentIDKey is the attribute Key conforming to the "gen_ai.agent.id"
+ // semantic conventions. It represents the unique identifier of the GenAI agent.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "asst_5j66UpCpwteGg4YSxUnt7lPY"
+ GenAIAgentIDKey = attribute.Key("gen_ai.agent.id")
+
+ // GenAIAgentNameKey is the attribute Key conforming to the "gen_ai.agent.name"
+ // semantic conventions. It represents the human-readable name of the GenAI
+ // agent provided by the application.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "Math Tutor", "Fiction Writer"
+ GenAIAgentNameKey = attribute.Key("gen_ai.agent.name")
+
+ // GenAIAgentVersionKey is the attribute Key conforming to the
+ // "gen_ai.agent.version" semantic conventions. It represents the version of the
+ // GenAI agent.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "1.0.0", "2025-05-01"
+ GenAIAgentVersionKey = attribute.Key("gen_ai.agent.version")
+
+ // GenAIConversationIDKey is the attribute Key conforming to the
+ // "gen_ai.conversation.id" semantic conventions. It represents the unique
+ // identifier for a conversation (session, thread), used to store and correlate
+ // messages within this conversation.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "conv_5j66UpCpwteGg4YSxUnt7lPY"
+ GenAIConversationIDKey = attribute.Key("gen_ai.conversation.id")
+
+ // GenAIDataSourceIDKey is the attribute Key conforming to the
+ // "gen_ai.data_source.id" semantic conventions. It represents the data source
+ // identifier.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "H7STPQYOND"
+ // Note: Data sources are used by AI agents and RAG applications to store
+ // grounding data. A data source may be an external database, object store,
+ // document collection, website, or any other storage system used by the GenAI
+ // agent or application. The `gen_ai.data_source.id` SHOULD match the identifier
+ // used by the GenAI system rather than a name specific to the external storage,
+ // such as a database or object store. Semantic conventions referencing
+ // `gen_ai.data_source.id` MAY also leverage additional attributes, such as
+ // `db.*`, to further identify and describe the data source.
+ GenAIDataSourceIDKey = attribute.Key("gen_ai.data_source.id")
+
+ // GenAIEmbeddingsDimensionCountKey is the attribute Key conforming to the
+ // "gen_ai.embeddings.dimension.count" semantic conventions. It represents the
+ // number of dimensions the resulting output embeddings should have.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 512, 1024
+ GenAIEmbeddingsDimensionCountKey = attribute.Key("gen_ai.embeddings.dimension.count")
+
+ // GenAIEvaluationExplanationKey is the attribute Key conforming to the
+ // "gen_ai.evaluation.explanation" semantic conventions. It represents a
+ // free-form explanation for the assigned score provided by the evaluator.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "The response is factually accurate but lacks sufficient detail to
+ // fully address the question."
+ GenAIEvaluationExplanationKey = attribute.Key("gen_ai.evaluation.explanation")
+
+ // GenAIEvaluationNameKey is the attribute Key conforming to the
+ // "gen_ai.evaluation.name" semantic conventions. It represents the name of the
+ // evaluation metric used for the GenAI response.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "Relevance", "IntentResolution"
+ GenAIEvaluationNameKey = attribute.Key("gen_ai.evaluation.name")
+
+ // GenAIEvaluationScoreLabelKey is the attribute Key conforming to the
+ // "gen_ai.evaluation.score.label" semantic conventions. It represents the human
+ // readable label for evaluation.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "relevant", "not_relevant", "correct", "incorrect", "pass", "fail"
+ // Note: This attribute provides a human-readable interpretation of the
+ // evaluation score produced by an evaluator. For example, a score value of 1
+ // could mean "relevant" in one evaluation system and "not relevant" in another,
+ // depending on the scoring range and evaluator. The label SHOULD have low
+ // cardinality. Possible values depend on the evaluation metric and evaluator
+ // used; implementations SHOULD document the possible values.
+ GenAIEvaluationScoreLabelKey = attribute.Key("gen_ai.evaluation.score.label")
+
+ // GenAIEvaluationScoreValueKey is the attribute Key conforming to the
+ // "gen_ai.evaluation.score.value" semantic conventions. It represents the
+ // evaluation score returned by the evaluator.
+ //
+ // Type: double
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 4.0
+ GenAIEvaluationScoreValueKey = attribute.Key("gen_ai.evaluation.score.value")
+
+ // GenAIInputMessagesKey is the attribute Key conforming to the
+ // "gen_ai.input.messages" semantic conventions. It represents the chat history
+ // provided to the model as an input.
+ //
+ // Type: any
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "[\n {\n "role": "user",\n "parts": [\n {\n "type": "text",\n
+ // "content": "Weather in Paris?"\n }\n ]\n },\n {\n "role": "assistant",\n
+ // "parts": [\n {\n "type": "tool_call",\n "id":
+ // "call_VSPygqKTWdrhaFErNvMV18Yl",\n "name": "get_weather",\n "arguments": {\n
+ // "location": "Paris"\n }\n }\n ]\n },\n {\n "role": "tool",\n "parts": [\n {\n
+ // "type": "tool_call_response",\n "id": " call_VSPygqKTWdrhaFErNvMV18Yl",\n
+ // "result": "rainy, 57°F"\n }\n ]\n }\n]\n"
+ // Note: Instrumentations MUST follow [Input messages JSON schema].
+ // When the attribute is recorded on events, it MUST be recorded in structured
+ // form. When recorded on spans, it MAY be recorded as a JSON string if
+ // structured
+ // format is not supported and SHOULD be recorded in structured form otherwise.
+ //
+ // Messages MUST be provided in the order they were sent to the model.
+ // Instrumentations MAY provide a way for users to filter or truncate
+ // input messages.
+ //
+ // > [!Warning]
+ // > This attribute is likely to contain sensitive information including
+ // > user/PII data.
+ //
+ // See [Recording content on attributes]
+ // section for more details.
+ //
+ // [Input messages JSON schema]: /docs/gen-ai/gen-ai-input-messages.json
+ // [Recording content on attributes]: /docs/gen-ai/gen-ai-spans.md#recording-content-on-attributes
+ GenAIInputMessagesKey = attribute.Key("gen_ai.input.messages")
+
+ // GenAIOperationNameKey is the attribute Key conforming to the
+ // "gen_ai.operation.name" semantic conventions. It represents the name of the
+ // operation being performed.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ // Note: If one of the predefined values applies, but specific system uses a
+ // different name it's RECOMMENDED to document it in the semantic conventions
+ // for specific GenAI system and use system-specific name in the
+ // instrumentation. If a different name is not documented, instrumentation
+ // libraries SHOULD use applicable predefined value.
+ GenAIOperationNameKey = attribute.Key("gen_ai.operation.name")
+
+ // GenAIOutputMessagesKey is the attribute Key conforming to the
+ // "gen_ai.output.messages" semantic conventions. It represents the messages
+ // returned by the model where each message represents a specific model response
+ // (choice, candidate).
+ //
+ // Type: any
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "[\n {\n "role": "assistant",\n "parts": [\n {\n "type": "text",\n
+ // "content": "The weather in Paris is currently rainy with a temperature of
+ // 57°F."\n }\n ],\n "finish_reason": "stop"\n }\n]\n"
+ // Note: Instrumentations MUST follow [Output messages JSON schema]
+ //
+ // Each message represents a single output choice/candidate generated by
+ // the model. Each message corresponds to exactly one generation
+ // (choice/candidate) and vice versa - one choice cannot be split across
+ // multiple messages or one message cannot contain parts from multiple choices.
+ //
+ // When the attribute is recorded on events, it MUST be recorded in structured
+ // form. When recorded on spans, it MAY be recorded as a JSON string if
+ // structured
+ // format is not supported and SHOULD be recorded in structured form otherwise.
+ //
+ // Instrumentations MAY provide a way for users to filter or truncate
+ // output messages.
+ //
+ // > [!Warning]
+ // > This attribute is likely to contain sensitive information including
+ // > user/PII data.
+ //
+ // See [Recording content on attributes]
+ // section for more details.
+ //
+ // [Output messages JSON schema]: /docs/gen-ai/gen-ai-output-messages.json
+ // [Recording content on attributes]: /docs/gen-ai/gen-ai-spans.md#recording-content-on-attributes
+ GenAIOutputMessagesKey = attribute.Key("gen_ai.output.messages")
+
+ // GenAIOutputTypeKey is the attribute Key conforming to the
+ // "gen_ai.output.type" semantic conventions. It represents the represents the
+ // content type requested by the client.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ // Note: This attribute SHOULD be used when the client requests output of a
+ // specific type. The model may return zero or more outputs of this type.
+ // This attribute specifies the output modality and not the actual output
+ // format. For example, if an image is requested, the actual output could be a
+ // URL pointing to an image file.
+ // Additional output format details may be recorded in the future in the
+ // `gen_ai.output.{type}.*` attributes.
+ GenAIOutputTypeKey = attribute.Key("gen_ai.output.type")
+
+ // GenAIPromptNameKey is the attribute Key conforming to the
+ // "gen_ai.prompt.name" semantic conventions. It represents the name of the
+ // prompt that uniquely identifies it.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "analyze-code"
+ GenAIPromptNameKey = attribute.Key("gen_ai.prompt.name")
+
+ // GenAIProviderNameKey is the attribute Key conforming to the
+ // "gen_ai.provider.name" semantic conventions. It represents the Generative AI
+ // provider as identified by the client or server instrumentation.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ // Note: The attribute SHOULD be set based on the instrumentation's best
+ // knowledge and may differ from the actual model provider.
+ //
+ // Multiple providers, including Azure OpenAI, Gemini, and AI hosting platforms
+ // are accessible using the OpenAI REST API and corresponding client libraries,
+ // but may proxy or host models from different providers.
+ //
+ // The `gen_ai.request.model`, `gen_ai.response.model`, and `server.address`
+ // attributes may help identify the actual system in use.
+ //
+ // The `gen_ai.provider.name` attribute acts as a discriminator that
+ // identifies the GenAI telemetry format flavor specific to that provider
+ // within GenAI semantic conventions.
+ // It SHOULD be set consistently with provider-specific attributes and signals.
+ // For example, GenAI spans, metrics, and events related to AWS Bedrock
+ // should have the `gen_ai.provider.name` set to `aws.bedrock` and include
+ // applicable `aws.bedrock.*` attributes and are not expected to include
+ // `openai.*` attributes.
+ GenAIProviderNameKey = attribute.Key("gen_ai.provider.name")
+
+ // GenAIRequestChoiceCountKey is the attribute Key conforming to the
+ // "gen_ai.request.choice.count" semantic conventions. It represents the target
+ // number of candidate completions to return.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 3
+ GenAIRequestChoiceCountKey = attribute.Key("gen_ai.request.choice.count")
+
+ // GenAIRequestEncodingFormatsKey is the attribute Key conforming to the
+ // "gen_ai.request.encoding_formats" semantic conventions. It represents the
+ // encoding formats requested in an embeddings operation, if specified.
+ //
+ // Type: string[]
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "base64"], ["float", "binary"
+ // Note: In some GenAI systems the encoding formats are called embedding types.
+ // Also, some GenAI systems only accept a single format per request.
+ GenAIRequestEncodingFormatsKey = attribute.Key("gen_ai.request.encoding_formats")
+
+ // GenAIRequestFrequencyPenaltyKey is the attribute Key conforming to the
+ // "gen_ai.request.frequency_penalty" semantic conventions. It represents the
+ // frequency penalty setting for the GenAI request.
+ //
+ // Type: double
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 0.1
+ GenAIRequestFrequencyPenaltyKey = attribute.Key("gen_ai.request.frequency_penalty")
+
+ // GenAIRequestMaxTokensKey is the attribute Key conforming to the
+ // "gen_ai.request.max_tokens" semantic conventions. It represents the maximum
+ // number of tokens the model generates for a request.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 100
+ GenAIRequestMaxTokensKey = attribute.Key("gen_ai.request.max_tokens")
+
+ // GenAIRequestModelKey is the attribute Key conforming to the
+ // "gen_ai.request.model" semantic conventions. It represents the name of the
+ // GenAI model a request is being made to.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: gpt-4
+ GenAIRequestModelKey = attribute.Key("gen_ai.request.model")
+
+ // GenAIRequestPresencePenaltyKey is the attribute Key conforming to the
+ // "gen_ai.request.presence_penalty" semantic conventions. It represents the
+ // presence penalty setting for the GenAI request.
+ //
+ // Type: double
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 0.1
+ GenAIRequestPresencePenaltyKey = attribute.Key("gen_ai.request.presence_penalty")
+
+ // GenAIRequestSeedKey is the attribute Key conforming to the
+ // "gen_ai.request.seed" semantic conventions. It represents the requests with
+ // same seed value more likely to return same result.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 100
+ GenAIRequestSeedKey = attribute.Key("gen_ai.request.seed")
+
+ // GenAIRequestStopSequencesKey is the attribute Key conforming to the
+ // "gen_ai.request.stop_sequences" semantic conventions. It represents the list
+ // of sequences that the model will use to stop generating further tokens.
+ //
+ // Type: string[]
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "forest", "lived"
+ GenAIRequestStopSequencesKey = attribute.Key("gen_ai.request.stop_sequences")
+
+ // GenAIRequestStreamKey is the attribute Key conforming to the
+ // "gen_ai.request.stream" semantic conventions. It represents the indicates
+ // whether the GenAI request was made in streaming mode.
+ //
+ // Type: boolean
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ GenAIRequestStreamKey = attribute.Key("gen_ai.request.stream")
+
+ // GenAIRequestTemperatureKey is the attribute Key conforming to the
+ // "gen_ai.request.temperature" semantic conventions. It represents the
+ // temperature setting for the GenAI request.
+ //
+ // Type: double
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 0.0
+ GenAIRequestTemperatureKey = attribute.Key("gen_ai.request.temperature")
+
+ // GenAIRequestTopKKey is the attribute Key conforming to the
+ // "gen_ai.request.top_k" semantic conventions. It represents the top_k sampling
+ // setting for the GenAI request.
+ //
+ // Type: double
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 1.0
+ GenAIRequestTopKKey = attribute.Key("gen_ai.request.top_k")
+
+ // GenAIRequestTopPKey is the attribute Key conforming to the
+ // "gen_ai.request.top_p" semantic conventions. It represents the top_p sampling
+ // setting for the GenAI request.
+ //
+ // Type: double
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 1.0
+ GenAIRequestTopPKey = attribute.Key("gen_ai.request.top_p")
+
+ // GenAIResponseFinishReasonsKey is the attribute Key conforming to the
+ // "gen_ai.response.finish_reasons" semantic conventions. It represents the
+ // array of reasons the model stopped generating tokens, corresponding to each
+ // generation received.
+ //
+ // Type: string[]
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "stop"], ["stop", "length"
+ GenAIResponseFinishReasonsKey = attribute.Key("gen_ai.response.finish_reasons")
+
+ // GenAIResponseIDKey is the attribute Key conforming to the
+ // "gen_ai.response.id" semantic conventions. It represents the unique
+ // identifier for the completion.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "chatcmpl-123"
+ GenAIResponseIDKey = attribute.Key("gen_ai.response.id")
+
+ // GenAIResponseModelKey is the attribute Key conforming to the
+ // "gen_ai.response.model" semantic conventions. It represents the name of the
+ // model that generated the response.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "gpt-4-0613"
+ GenAIResponseModelKey = attribute.Key("gen_ai.response.model")
+
+ // GenAIResponseTimeToFirstChunkKey is the attribute Key conforming to the
+ // "gen_ai.response.time_to_first_chunk" semantic conventions. It represents the
+ // time to first chunk in a streaming response, measured from request issuance,
+ // in seconds. The value is measured from when the client issues the generation
+ // request to when the first chunk is received in the response stream.
+ //
+ // Type: double
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 0.5, 1.2
+ GenAIResponseTimeToFirstChunkKey = attribute.Key("gen_ai.response.time_to_first_chunk")
+
+ // GenAIRetrievalDocumentsKey is the attribute Key conforming to the
+ // "gen_ai.retrieval.documents" semantic conventions. It represents the
+ // documents retrieved.
+ //
+ // Type: any
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "[\n {\n "id": "doc_123",\n "score": 0.95\n },\n {\n "id":
+ // "doc_456",\n "score": 0.87\n },\n {\n "id": "doc_789",\n "score": 0.82\n
+ // }\n]\n"
+ // Note: Instrumentations MUST follow [Retrieval documents JSON schema].
+ // When the attribute is recorded on events, it MUST be recorded in structured
+ // form. When recorded on spans, it MAY be recorded as a JSON string if
+ // structured
+ // format is not supported and SHOULD be recorded in structured form otherwise.
+ //
+ // Each document object SHOULD contain at least the following properties:
+ // `id` (string): A unique identifier for the document, `score` (double): The
+ // relevance score of the document
+ //
+ // [Retrieval documents JSON schema]: /docs/gen-ai/gen-ai-retrieval-documents.json
+ GenAIRetrievalDocumentsKey = attribute.Key("gen_ai.retrieval.documents")
+
+ // GenAIRetrievalQueryTextKey is the attribute Key conforming to the
+ // "gen_ai.retrieval.query.text" semantic conventions. It represents the query
+ // text used for retrieval.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "What is the capital of France?", "weather in Paris"
+ // Note: > [!Warning]
+ //
+ // > This attribute may contain sensitive information.
+ GenAIRetrievalQueryTextKey = attribute.Key("gen_ai.retrieval.query.text")
+
+ // GenAISystemInstructionsKey is the attribute Key conforming to the
+ // "gen_ai.system_instructions" semantic conventions. It represents the system
+ // message or instructions provided to the GenAI model separately from the chat
+ // history.
+ //
+ // Type: any
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "[\n {\n "type": "text",\n "content": "You are an Agent that greet
+ // users, always use greetings tool to respond"\n }\n]\n", "[\n {\n "type":
+ // "text",\n "content": "You are a language translator."\n },\n {\n "type":
+ // "text",\n "content": "Your mission is to translate text in English to
+ // French."\n }\n]\n"
+ // Note: This attribute SHOULD be used when the corresponding provider or API
+ // allows to provide system instructions or messages separately from the
+ // chat history.
+ //
+ // Instructions that are part of the chat history SHOULD be recorded in
+ // `gen_ai.input.messages` attribute instead.
+ //
+ // Instrumentations MUST follow [System instructions JSON schema].
+ //
+ // When recorded on spans, it MAY be recorded as a JSON string if structured
+ // format is not supported and SHOULD be recorded in structured form otherwise.
+ //
+ // Instrumentations MAY provide a way for users to filter or truncate
+ // system instructions.
+ //
+ // > [!Warning]
+ // > This attribute may contain sensitive information.
+ //
+ // See [Recording content on attributes]
+ // section for more details.
+ //
+ // [System instructions JSON schema]: /docs/gen-ai/gen-ai-system-instructions.json
+ // [Recording content on attributes]: /docs/gen-ai/gen-ai-spans.md#recording-content-on-attributes
+ GenAISystemInstructionsKey = attribute.Key("gen_ai.system_instructions")
+
+ // GenAITokenTypeKey is the attribute Key conforming to the "gen_ai.token.type"
+ // semantic conventions. It represents the type of token being counted.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "input", "output"
+ GenAITokenTypeKey = attribute.Key("gen_ai.token.type")
+
+ // GenAIToolCallArgumentsKey is the attribute Key conforming to the
+ // "gen_ai.tool.call.arguments" semantic conventions. It represents the
+ // parameters passed to the tool call.
+ //
+ // Type: any
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "{\n "location": "San Francisco?",\n "date": "2025-10-01"\n}\n"
+ // Note: > [!WARNING]
+ //
+ // > This attribute may contain sensitive information.
+ //
+ // It's expected to be an object - in case a serialized string is available
+ // to the instrumentation, the instrumentation SHOULD do the best effort to
+ // deserialize it to an object. When recorded on spans, it MAY be recorded as a
+ // JSON string if structured format is not supported and SHOULD be recorded in
+ // structured form otherwise.
+ GenAIToolCallArgumentsKey = attribute.Key("gen_ai.tool.call.arguments")
+
+ // GenAIToolCallIDKey is the attribute Key conforming to the
+ // "gen_ai.tool.call.id" semantic conventions. It represents the tool call
+ // identifier.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "call_mszuSIzqtI65i1wAUOE8w5H4"
+ GenAIToolCallIDKey = attribute.Key("gen_ai.tool.call.id")
+
+ // GenAIToolCallResultKey is the attribute Key conforming to the
+ // "gen_ai.tool.call.result" semantic conventions. It represents the result
+ // returned by the tool call (if any and if execution was successful).
+ //
+ // Type: any
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "{\n "temperature_range": {\n "high": 75,\n "low": 60\n },\n
+ // "conditions": "sunny"\n}\n"
+ // Note: > [!WARNING]
+ //
+ // > This attribute may contain sensitive information.
+ //
+ // It's expected to be an object - in case a serialized string is available
+ // to the instrumentation, the instrumentation SHOULD do the best effort to
+ // deserialize it to an object. When recorded on spans, it MAY be recorded as a
+ // JSON string if structured format is not supported and SHOULD be recorded in
+ // structured form otherwise.
+ GenAIToolCallResultKey = attribute.Key("gen_ai.tool.call.result")
+
+ // GenAIToolDefinitionsKey is the attribute Key conforming to the
+ // "gen_ai.tool.definitions" semantic conventions. It represents the list of
+ // tool definitions available to the GenAI agent or model.
+ //
+ // Type: any
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "[\n {\n "type": "function",\n "name": "get_current_weather",\n
+ // "description": "Get the current weather in a given location",\n "parameters":
+ // {\n "type": "object",\n "properties": {\n "location": {\n "type": "string",\n
+ // "description": "The city and state, e.g. San Francisco, CA"\n },\n "unit":
+ // {\n "type": "string",\n "enum": [\n "celsius",\n "fahrenheit"\n ]\n }\n },\n
+ // "required": [\n "location",\n "unit"\n ]\n }\n }\n]\n"
+ // Note: Instrumentations MUST follow [Tool Definitions JSON Schema].
+ //
+ // When the attribute is recorded on events, it MUST be recorded in structured
+ // form. When recorded on spans, it MAY be recorded as a JSON string if
+ // structured
+ // format is not supported and SHOULD be recorded in structured form otherwise.
+ //
+ // Since this attribute could be large, it's NOT RECOMMENDED to populate
+ // non-required properties by default. Instrumentations MAY provide a way
+ // to enable populating optional properties.
+ //
+ // [Tool Definitions JSON Schema]: /docs/gen-ai/gen-ai-tool-definitions.json
+ GenAIToolDefinitionsKey = attribute.Key("gen_ai.tool.definitions")
+
+ // GenAIToolDescriptionKey is the attribute Key conforming to the
+ // "gen_ai.tool.description" semantic conventions. It represents the tool
+ // description.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "Multiply two numbers"
+ GenAIToolDescriptionKey = attribute.Key("gen_ai.tool.description")
+
+ // GenAIToolNameKey is the attribute Key conforming to the "gen_ai.tool.name"
+ // semantic conventions. It represents the name of the tool utilized by the
+ // agent.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "Flights"
+ GenAIToolNameKey = attribute.Key("gen_ai.tool.name")
+
+ // GenAIToolTypeKey is the attribute Key conforming to the "gen_ai.tool.type"
+ // semantic conventions. It represents the type of the tool utilized by the
+ // agent.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "function", "extension", "datastore"
+ // Note: Extension: A tool executed on the agent-side to directly call external
+ // APIs, bridging the gap between the agent and real-world systems.
+ // Agent-side operations involve actions that are performed by the agent on the
+ // server or within the agent's controlled environment.
+ // Function: A tool executed on the client-side, where the agent generates
+ // parameters for a predefined function, and the client executes the logic.
+ // Client-side operations are actions taken on the user's end or within the
+ // client application.
+ // Datastore: A tool used by the agent to access and query structured or
+ // unstructured external data for retrieval-augmented tasks or knowledge
+ // updates.
+ GenAIToolTypeKey = attribute.Key("gen_ai.tool.type")
+
+ // GenAIUsageCacheCreationInputTokensKey is the attribute Key conforming to the
+ // "gen_ai.usage.cache_creation.input_tokens" semantic conventions. It
+ // represents the number of input tokens written to a provider-managed cache.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 25
+ // Note: The value SHOULD be included in `gen_ai.usage.input_tokens`.
+ GenAIUsageCacheCreationInputTokensKey = attribute.Key("gen_ai.usage.cache_creation.input_tokens")
+
+ // GenAIUsageCacheReadInputTokensKey is the attribute Key conforming to the
+ // "gen_ai.usage.cache_read.input_tokens" semantic conventions. It represents
+ // the number of input tokens served from a provider-managed cache.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 50
+ // Note: The value SHOULD be included in `gen_ai.usage.input_tokens`.
+ GenAIUsageCacheReadInputTokensKey = attribute.Key("gen_ai.usage.cache_read.input_tokens")
+
+ // GenAIUsageInputTokensKey is the attribute Key conforming to the
+ // "gen_ai.usage.input_tokens" semantic conventions. It represents the number of
+ // tokens used in the GenAI input (prompt).
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 100
+ // Note: This value SHOULD include all types of input tokens, including cached
+ // tokens.
+ // Instrumentations SHOULD make a best effort to populate this value, using a
+ // total
+ // provided by the provider when available or, depending on the provider API,
+ // by summing different token types parsed from the provider output.
+ GenAIUsageInputTokensKey = attribute.Key("gen_ai.usage.input_tokens")
+
+ // GenAIUsageOutputTokensKey is the attribute Key conforming to the
+ // "gen_ai.usage.output_tokens" semantic conventions. It represents the number
+ // of tokens used in the GenAI response (completion).
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 180
+ GenAIUsageOutputTokensKey = attribute.Key("gen_ai.usage.output_tokens")
+
+ // GenAIUsageReasoningOutputTokensKey is the attribute Key conforming to the
+ // "gen_ai.usage.reasoning.output_tokens" semantic conventions. It represents
+ // the number of output tokens used for reasoning (e.g. chain-of-thought,
+ // extended thinking).
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 50
+ // Note: The value SHOULD be included in `gen_ai.usage.output_tokens`.
+ GenAIUsageReasoningOutputTokensKey = attribute.Key("gen_ai.usage.reasoning.output_tokens")
+
+ // GenAIWorkflowNameKey is the attribute Key conforming to the
+ // "gen_ai.workflow.name" semantic conventions. It represents the human-readable
+ // name of the GenAI workflow provided by the application.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "multi_agent_rag", "customer_support_pipeline"
+ // Note: This attribute can be populated in different frameworks eg: name of the
+ // first chain in LangChain OR name of the crew in CrewAI.
+ GenAIWorkflowNameKey = attribute.Key("gen_ai.workflow.name")
+)
+
+// GenAIAgentDescription returns an attribute KeyValue conforming to the
+// "gen_ai.agent.description" semantic conventions. It represents the free-form
+// description of the GenAI agent provided by the application.
+func GenAIAgentDescription(val string) attribute.KeyValue {
+ return GenAIAgentDescriptionKey.String(val)
+}
+
+// GenAIAgentID returns an attribute KeyValue conforming to the "gen_ai.agent.id"
+// semantic conventions. It represents the unique identifier of the GenAI agent.
+func GenAIAgentID(val string) attribute.KeyValue {
+ return GenAIAgentIDKey.String(val)
+}
+
+// GenAIAgentName returns an attribute KeyValue conforming to the
+// "gen_ai.agent.name" semantic conventions. It represents the human-readable
+// name of the GenAI agent provided by the application.
+func GenAIAgentName(val string) attribute.KeyValue {
+ return GenAIAgentNameKey.String(val)
+}
+
+// GenAIAgentVersion returns an attribute KeyValue conforming to the
+// "gen_ai.agent.version" semantic conventions. It represents the version of the
+// GenAI agent.
+func GenAIAgentVersion(val string) attribute.KeyValue {
+ return GenAIAgentVersionKey.String(val)
+}
+
+// GenAIConversationID returns an attribute KeyValue conforming to the
+// "gen_ai.conversation.id" semantic conventions. It represents the unique
+// identifier for a conversation (session, thread), used to store and correlate
+// messages within this conversation.
+func GenAIConversationID(val string) attribute.KeyValue {
+ return GenAIConversationIDKey.String(val)
+}
+
+// GenAIDataSourceID returns an attribute KeyValue conforming to the
+// "gen_ai.data_source.id" semantic conventions. It represents the data source
+// identifier.
+func GenAIDataSourceID(val string) attribute.KeyValue {
+ return GenAIDataSourceIDKey.String(val)
+}
+
+// GenAIEmbeddingsDimensionCount returns an attribute KeyValue conforming to the
+// "gen_ai.embeddings.dimension.count" semantic conventions. It represents the
+// number of dimensions the resulting output embeddings should have.
+func GenAIEmbeddingsDimensionCount(val int) attribute.KeyValue {
+ return GenAIEmbeddingsDimensionCountKey.Int(val)
+}
+
+// GenAIEvaluationExplanation returns an attribute KeyValue conforming to the
+// "gen_ai.evaluation.explanation" semantic conventions. It represents a
+// free-form explanation for the assigned score provided by the evaluator.
+func GenAIEvaluationExplanation(val string) attribute.KeyValue {
+ return GenAIEvaluationExplanationKey.String(val)
+}
+
+// GenAIEvaluationName returns an attribute KeyValue conforming to the
+// "gen_ai.evaluation.name" semantic conventions. It represents the name of the
+// evaluation metric used for the GenAI response.
+func GenAIEvaluationName(val string) attribute.KeyValue {
+ return GenAIEvaluationNameKey.String(val)
+}
+
+// GenAIEvaluationScoreLabel returns an attribute KeyValue conforming to the
+// "gen_ai.evaluation.score.label" semantic conventions. It represents the human
+// readable label for evaluation.
+func GenAIEvaluationScoreLabel(val string) attribute.KeyValue {
+ return GenAIEvaluationScoreLabelKey.String(val)
+}
+
+// GenAIEvaluationScoreValue returns an attribute KeyValue conforming to the
+// "gen_ai.evaluation.score.value" semantic conventions. It represents the
+// evaluation score returned by the evaluator.
+func GenAIEvaluationScoreValue(val float64) attribute.KeyValue {
+ return GenAIEvaluationScoreValueKey.Float64(val)
+}
+
+// GenAIPromptName returns an attribute KeyValue conforming to the
+// "gen_ai.prompt.name" semantic conventions. It represents the name of the
+// prompt that uniquely identifies it.
+func GenAIPromptName(val string) attribute.KeyValue {
+ return GenAIPromptNameKey.String(val)
+}
+
+// GenAIRequestChoiceCount returns an attribute KeyValue conforming to the
+// "gen_ai.request.choice.count" semantic conventions. It represents the target
+// number of candidate completions to return.
+func GenAIRequestChoiceCount(val int) attribute.KeyValue {
+ return GenAIRequestChoiceCountKey.Int(val)
+}
+
+// GenAIRequestEncodingFormats returns an attribute KeyValue conforming to the
+// "gen_ai.request.encoding_formats" semantic conventions. It represents the
+// encoding formats requested in an embeddings operation, if specified.
+func GenAIRequestEncodingFormats(val ...string) attribute.KeyValue {
+ return GenAIRequestEncodingFormatsKey.StringSlice(val)
+}
+
+// GenAIRequestFrequencyPenalty returns an attribute KeyValue conforming to the
+// "gen_ai.request.frequency_penalty" semantic conventions. It represents the
+// frequency penalty setting for the GenAI request.
+func GenAIRequestFrequencyPenalty(val float64) attribute.KeyValue {
+ return GenAIRequestFrequencyPenaltyKey.Float64(val)
+}
+
+// GenAIRequestMaxTokens returns an attribute KeyValue conforming to the
+// "gen_ai.request.max_tokens" semantic conventions. It represents the maximum
+// number of tokens the model generates for a request.
+func GenAIRequestMaxTokens(val int) attribute.KeyValue {
+ return GenAIRequestMaxTokensKey.Int(val)
+}
+
+// GenAIRequestModel returns an attribute KeyValue conforming to the
+// "gen_ai.request.model" semantic conventions. It represents the name of the
+// GenAI model a request is being made to.
+func GenAIRequestModel(val string) attribute.KeyValue {
+ return GenAIRequestModelKey.String(val)
+}
+
+// GenAIRequestPresencePenalty returns an attribute KeyValue conforming to the
+// "gen_ai.request.presence_penalty" semantic conventions. It represents the
+// presence penalty setting for the GenAI request.
+func GenAIRequestPresencePenalty(val float64) attribute.KeyValue {
+ return GenAIRequestPresencePenaltyKey.Float64(val)
+}
+
+// GenAIRequestSeed returns an attribute KeyValue conforming to the
+// "gen_ai.request.seed" semantic conventions. It represents the requests with
+// same seed value more likely to return same result.
+func GenAIRequestSeed(val int) attribute.KeyValue {
+ return GenAIRequestSeedKey.Int(val)
+}
+
+// GenAIRequestStopSequences returns an attribute KeyValue conforming to the
+// "gen_ai.request.stop_sequences" semantic conventions. It represents the list
+// of sequences that the model will use to stop generating further tokens.
+func GenAIRequestStopSequences(val ...string) attribute.KeyValue {
+ return GenAIRequestStopSequencesKey.StringSlice(val)
+}
+
+// GenAIRequestStream returns an attribute KeyValue conforming to the
+// "gen_ai.request.stream" semantic conventions. It represents the indicates
+// whether the GenAI request was made in streaming mode.
+func GenAIRequestStream(val bool) attribute.KeyValue {
+ return GenAIRequestStreamKey.Bool(val)
+}
+
+// GenAIRequestTemperature returns an attribute KeyValue conforming to the
+// "gen_ai.request.temperature" semantic conventions. It represents the
+// temperature setting for the GenAI request.
+func GenAIRequestTemperature(val float64) attribute.KeyValue {
+ return GenAIRequestTemperatureKey.Float64(val)
+}
+
+// GenAIRequestTopK returns an attribute KeyValue conforming to the
+// "gen_ai.request.top_k" semantic conventions. It represents the top_k sampling
+// setting for the GenAI request.
+func GenAIRequestTopK(val float64) attribute.KeyValue {
+ return GenAIRequestTopKKey.Float64(val)
+}
+
+// GenAIRequestTopP returns an attribute KeyValue conforming to the
+// "gen_ai.request.top_p" semantic conventions. It represents the top_p sampling
+// setting for the GenAI request.
+func GenAIRequestTopP(val float64) attribute.KeyValue {
+ return GenAIRequestTopPKey.Float64(val)
+}
+
+// GenAIResponseFinishReasons returns an attribute KeyValue conforming to the
+// "gen_ai.response.finish_reasons" semantic conventions. It represents the array
+// of reasons the model stopped generating tokens, corresponding to each
+// generation received.
+func GenAIResponseFinishReasons(val ...string) attribute.KeyValue {
+ return GenAIResponseFinishReasonsKey.StringSlice(val)
+}
+
+// GenAIResponseID returns an attribute KeyValue conforming to the
+// "gen_ai.response.id" semantic conventions. It represents the unique identifier
+// for the completion.
+func GenAIResponseID(val string) attribute.KeyValue {
+ return GenAIResponseIDKey.String(val)
+}
+
+// GenAIResponseModel returns an attribute KeyValue conforming to the
+// "gen_ai.response.model" semantic conventions. It represents the name of the
+// model that generated the response.
+func GenAIResponseModel(val string) attribute.KeyValue {
+ return GenAIResponseModelKey.String(val)
+}
+
+// GenAIResponseTimeToFirstChunk returns an attribute KeyValue conforming to the
+// "gen_ai.response.time_to_first_chunk" semantic conventions. It represents the
+// time to first chunk in a streaming response, measured from request issuance,
+// in seconds. The value is measured from when the client issues the generation
+// request to when the first chunk is received in the response stream.
+func GenAIResponseTimeToFirstChunk(val float64) attribute.KeyValue {
+ return GenAIResponseTimeToFirstChunkKey.Float64(val)
+}
+
+// GenAIRetrievalQueryText returns an attribute KeyValue conforming to the
+// "gen_ai.retrieval.query.text" semantic conventions. It represents the query
+// text used for retrieval.
+func GenAIRetrievalQueryText(val string) attribute.KeyValue {
+ return GenAIRetrievalQueryTextKey.String(val)
+}
+
+// GenAIToolCallID returns an attribute KeyValue conforming to the
+// "gen_ai.tool.call.id" semantic conventions. It represents the tool call
+// identifier.
+func GenAIToolCallID(val string) attribute.KeyValue {
+ return GenAIToolCallIDKey.String(val)
+}
+
+// GenAIToolDescription returns an attribute KeyValue conforming to the
+// "gen_ai.tool.description" semantic conventions. It represents the tool
+// description.
+func GenAIToolDescription(val string) attribute.KeyValue {
+ return GenAIToolDescriptionKey.String(val)
+}
+
+// GenAIToolName returns an attribute KeyValue conforming to the
+// "gen_ai.tool.name" semantic conventions. It represents the name of the tool
+// utilized by the agent.
+func GenAIToolName(val string) attribute.KeyValue {
+ return GenAIToolNameKey.String(val)
+}
+
+// GenAIToolType returns an attribute KeyValue conforming to the
+// "gen_ai.tool.type" semantic conventions. It represents the type of the tool
+// utilized by the agent.
+func GenAIToolType(val string) attribute.KeyValue {
+ return GenAIToolTypeKey.String(val)
+}
+
+// GenAIUsageCacheCreationInputTokens returns an attribute KeyValue conforming to
+// the "gen_ai.usage.cache_creation.input_tokens" semantic conventions. It
+// represents the number of input tokens written to a provider-managed cache.
+func GenAIUsageCacheCreationInputTokens(val int) attribute.KeyValue {
+ return GenAIUsageCacheCreationInputTokensKey.Int(val)
+}
+
+// GenAIUsageCacheReadInputTokens returns an attribute KeyValue conforming to the
+// "gen_ai.usage.cache_read.input_tokens" semantic conventions. It represents the
+// number of input tokens served from a provider-managed cache.
+func GenAIUsageCacheReadInputTokens(val int) attribute.KeyValue {
+ return GenAIUsageCacheReadInputTokensKey.Int(val)
+}
+
+// GenAIUsageInputTokens returns an attribute KeyValue conforming to the
+// "gen_ai.usage.input_tokens" semantic conventions. It represents the number of
+// tokens used in the GenAI input (prompt).
+func GenAIUsageInputTokens(val int) attribute.KeyValue {
+ return GenAIUsageInputTokensKey.Int(val)
+}
+
+// GenAIUsageOutputTokens returns an attribute KeyValue conforming to the
+// "gen_ai.usage.output_tokens" semantic conventions. It represents the number of
+// tokens used in the GenAI response (completion).
+func GenAIUsageOutputTokens(val int) attribute.KeyValue {
+ return GenAIUsageOutputTokensKey.Int(val)
+}
+
+// GenAIUsageReasoningOutputTokens returns an attribute KeyValue conforming to
+// the "gen_ai.usage.reasoning.output_tokens" semantic conventions. It represents
+// the number of output tokens used for reasoning (e.g. chain-of-thought,
+// extended thinking).
+func GenAIUsageReasoningOutputTokens(val int) attribute.KeyValue {
+ return GenAIUsageReasoningOutputTokensKey.Int(val)
+}
+
+// GenAIWorkflowName returns an attribute KeyValue conforming to the
+// "gen_ai.workflow.name" semantic conventions. It represents the human-readable
+// name of the GenAI workflow provided by the application.
+func GenAIWorkflowName(val string) attribute.KeyValue {
+ return GenAIWorkflowNameKey.String(val)
+}
+
+// Enum values for gen_ai.operation.name
+var (
+ // Chat completion operation such as [OpenAI Chat API]
+ // Stability: development
+ //
+ // [OpenAI Chat API]: https://platform.openai.com/docs/api-reference/chat
+ GenAIOperationNameChat = GenAIOperationNameKey.String("chat")
+ // Multimodal content generation operation such as [Gemini Generate Content]
+ // Stability: development
+ //
+ // [Gemini Generate Content]: https://ai.google.dev/api/generate-content
+ GenAIOperationNameGenerateContent = GenAIOperationNameKey.String("generate_content")
+ // Text completions operation such as [OpenAI Completions API (Legacy)]
+ // Stability: development
+ //
+ // [OpenAI Completions API (Legacy)]: https://platform.openai.com/docs/api-reference/completions
+ GenAIOperationNameTextCompletion = GenAIOperationNameKey.String("text_completion")
+ // Embeddings operation such as [OpenAI Create embeddings API]
+ // Stability: development
+ //
+ // [OpenAI Create embeddings API]: https://platform.openai.com/docs/api-reference/embeddings/create
+ GenAIOperationNameEmbeddings = GenAIOperationNameKey.String("embeddings")
+ // Retrieval operation such as [OpenAI Search Vector Store API]
+ // Stability: development
+ //
+ // [OpenAI Search Vector Store API]: https://platform.openai.com/docs/api-reference/vector-stores/search
+ GenAIOperationNameRetrieval = GenAIOperationNameKey.String("retrieval")
+ // Create GenAI agent
+ // Stability: development
+ GenAIOperationNameCreateAgent = GenAIOperationNameKey.String("create_agent")
+ // Invoke GenAI agent
+ // Stability: development
+ GenAIOperationNameInvokeAgent = GenAIOperationNameKey.String("invoke_agent")
+ // Execute a tool
+ // Stability: development
+ GenAIOperationNameExecuteTool = GenAIOperationNameKey.String("execute_tool")
+ // Invoke GenAI workflow
+ // Stability: development
+ GenAIOperationNameInvokeWorkflow = GenAIOperationNameKey.String("invoke_workflow")
+)
+
+// Enum values for gen_ai.output.type
+var (
+ // Plain text
+ // Stability: development
+ GenAIOutputTypeText = GenAIOutputTypeKey.String("text")
+ // JSON object with known or unknown schema
+ // Stability: development
+ GenAIOutputTypeJSON = GenAIOutputTypeKey.String("json")
+ // Image
+ // Stability: development
+ GenAIOutputTypeImage = GenAIOutputTypeKey.String("image")
+ // Speech
+ // Stability: development
+ GenAIOutputTypeSpeech = GenAIOutputTypeKey.String("speech")
+)
+
+// Enum values for gen_ai.provider.name
+var (
+ // [OpenAI]
+ // Stability: development
+ //
+ // [OpenAI]: https://openai.com/
+ GenAIProviderNameOpenAI = GenAIProviderNameKey.String("openai")
+ // Any Google generative AI endpoint
+ // Stability: development
+ GenAIProviderNameGCPGenAI = GenAIProviderNameKey.String("gcp.gen_ai")
+ // [Vertex AI]
+ // Stability: development
+ //
+ // [Vertex AI]: https://cloud.google.com/vertex-ai
+ GenAIProviderNameGCPVertexAI = GenAIProviderNameKey.String("gcp.vertex_ai")
+ // [Gemini]
+ // Stability: development
+ //
+ // [Gemini]: https://cloud.google.com/products/gemini
+ GenAIProviderNameGCPGemini = GenAIProviderNameKey.String("gcp.gemini")
+ // [Anthropic]
+ // Stability: development
+ //
+ // [Anthropic]: https://www.anthropic.com/
+ GenAIProviderNameAnthropic = GenAIProviderNameKey.String("anthropic")
+ // [Cohere]
+ // Stability: development
+ //
+ // [Cohere]: https://cohere.com/
+ GenAIProviderNameCohere = GenAIProviderNameKey.String("cohere")
+ // Azure AI Inference
+ // Stability: development
+ GenAIProviderNameAzureAIInference = GenAIProviderNameKey.String("azure.ai.inference")
+ // [Azure OpenAI]
+ // Stability: development
+ //
+ // [Azure OpenAI]: https://learn.microsoft.com/en-us/azure/ai-services/openai/overview
+ GenAIProviderNameAzureAIOpenAI = GenAIProviderNameKey.String("azure.ai.openai")
+ // [IBM Watsonx AI]
+ // Stability: development
+ //
+ // [IBM Watsonx AI]: https://www.ibm.com/products/watsonx-ai
+ GenAIProviderNameIBMWatsonxAI = GenAIProviderNameKey.String("ibm.watsonx.ai")
+ // [AWS Bedrock]
+ // Stability: development
+ //
+ // [AWS Bedrock]: https://aws.amazon.com/bedrock
+ GenAIProviderNameAWSBedrock = GenAIProviderNameKey.String("aws.bedrock")
+ // [Perplexity]
+ // Stability: development
+ //
+ // [Perplexity]: https://www.perplexity.ai/
+ GenAIProviderNamePerplexity = GenAIProviderNameKey.String("perplexity")
+ // [xAI]
+ // Stability: development
+ //
+ // [xAI]: https://x.ai/
+ GenAIProviderNameXAI = GenAIProviderNameKey.String("x_ai")
+ // [DeepSeek]
+ // Stability: development
+ //
+ // [DeepSeek]: https://www.deepseek.com/
+ GenAIProviderNameDeepseek = GenAIProviderNameKey.String("deepseek")
+ // [Groq]
+ // Stability: development
+ //
+ // [Groq]: https://groq.com/
+ GenAIProviderNameGroq = GenAIProviderNameKey.String("groq")
+ // [Mistral AI]
+ // Stability: development
+ //
+ // [Mistral AI]: https://mistral.ai/
+ GenAIProviderNameMistralAI = GenAIProviderNameKey.String("mistral_ai")
+)
+
+// Enum values for gen_ai.token.type
+var (
+ // Input tokens (prompt, input, etc.)
+ // Stability: development
+ GenAITokenTypeInput = GenAITokenTypeKey.String("input")
+ // Output tokens (completion, response, etc.)
+ // Stability: development
+ GenAITokenTypeOutput = GenAITokenTypeKey.String("output")
+)
+
+// Namespace: geo
+const (
+ // GeoContinentCodeKey is the attribute Key conforming to the
+ // "geo.continent.code" semantic conventions. It represents the two-letter code
+ // representing continent’s name.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ GeoContinentCodeKey = attribute.Key("geo.continent.code")
+
+ // GeoCountryISOCodeKey is the attribute Key conforming to the
+ // "geo.country.iso_code" semantic conventions. It represents the two-letter ISO
+ // Country Code ([ISO 3166-1 alpha2]).
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "CA"
+ //
+ // [ISO 3166-1 alpha2]: https://wikipedia.org/wiki/ISO_3166-1#Codes
+ GeoCountryISOCodeKey = attribute.Key("geo.country.iso_code")
+
+ // GeoLocalityNameKey is the attribute Key conforming to the "geo.locality.name"
+ // semantic conventions. It represents the locality name. Represents the name of
+ // a city, town, village, or similar populated place.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "Montreal", "Berlin"
+ GeoLocalityNameKey = attribute.Key("geo.locality.name")
+
+ // GeoLocationLatKey is the attribute Key conforming to the "geo.location.lat"
+ // semantic conventions. It represents the latitude of the geo location in
+ // [WGS84].
+ //
+ // Type: double
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 45.505918
+ //
+ // [WGS84]: https://wikipedia.org/wiki/World_Geodetic_System#WGS84
+ GeoLocationLatKey = attribute.Key("geo.location.lat")
+
+ // GeoLocationLonKey is the attribute Key conforming to the "geo.location.lon"
+ // semantic conventions. It represents the longitude of the geo location in
+ // [WGS84].
+ //
+ // Type: double
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: -73.61483
+ //
+ // [WGS84]: https://wikipedia.org/wiki/World_Geodetic_System#WGS84
+ GeoLocationLonKey = attribute.Key("geo.location.lon")
+
+ // GeoPostalCodeKey is the attribute Key conforming to the "geo.postal_code"
+ // semantic conventions. It represents the postal code associated with the
+ // location. Values appropriate for this field may also be known as a postcode
+ // or ZIP code and will vary widely from country to country.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "94040"
+ GeoPostalCodeKey = attribute.Key("geo.postal_code")
+
+ // GeoRegionISOCodeKey is the attribute Key conforming to the
+ // "geo.region.iso_code" semantic conventions. It represents the region ISO code
+ // ([ISO 3166-2]).
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "CA-QC"
+ //
+ // [ISO 3166-2]: https://wikipedia.org/wiki/ISO_3166-2
+ GeoRegionISOCodeKey = attribute.Key("geo.region.iso_code")
+)
+
+// GeoCountryISOCode returns an attribute KeyValue conforming to the
+// "geo.country.iso_code" semantic conventions. It represents the two-letter ISO
+// Country Code ([ISO 3166-1 alpha2]).
+//
+// [ISO 3166-1 alpha2]: https://wikipedia.org/wiki/ISO_3166-1#Codes
+func GeoCountryISOCode(val string) attribute.KeyValue {
+ return GeoCountryISOCodeKey.String(val)
+}
+
+// GeoLocalityName returns an attribute KeyValue conforming to the
+// "geo.locality.name" semantic conventions. It represents the locality name.
+// Represents the name of a city, town, village, or similar populated place.
+func GeoLocalityName(val string) attribute.KeyValue {
+ return GeoLocalityNameKey.String(val)
+}
+
+// GeoLocationLat returns an attribute KeyValue conforming to the
+// "geo.location.lat" semantic conventions. It represents the latitude of the geo
+// location in [WGS84].
+//
+// [WGS84]: https://wikipedia.org/wiki/World_Geodetic_System#WGS84
+func GeoLocationLat(val float64) attribute.KeyValue {
+ return GeoLocationLatKey.Float64(val)
+}
+
+// GeoLocationLon returns an attribute KeyValue conforming to the
+// "geo.location.lon" semantic conventions. It represents the longitude of the
+// geo location in [WGS84].
+//
+// [WGS84]: https://wikipedia.org/wiki/World_Geodetic_System#WGS84
+func GeoLocationLon(val float64) attribute.KeyValue {
+ return GeoLocationLonKey.Float64(val)
+}
+
+// GeoPostalCode returns an attribute KeyValue conforming to the
+// "geo.postal_code" semantic conventions. It represents the postal code
+// associated with the location. Values appropriate for this field may also be
+// known as a postcode or ZIP code and will vary widely from country to country.
+func GeoPostalCode(val string) attribute.KeyValue {
+ return GeoPostalCodeKey.String(val)
+}
+
+// GeoRegionISOCode returns an attribute KeyValue conforming to the
+// "geo.region.iso_code" semantic conventions. It represents the region ISO code
+// ([ISO 3166-2]).
+//
+// [ISO 3166-2]: https://wikipedia.org/wiki/ISO_3166-2
+func GeoRegionISOCode(val string) attribute.KeyValue {
+ return GeoRegionISOCodeKey.String(val)
+}
+
+// Enum values for geo.continent.code
+var (
+ // Africa
+ // Stability: development
+ GeoContinentCodeAf = GeoContinentCodeKey.String("AF")
+ // Antarctica
+ // Stability: development
+ GeoContinentCodeAn = GeoContinentCodeKey.String("AN")
+ // Asia
+ // Stability: development
+ GeoContinentCodeAs = GeoContinentCodeKey.String("AS")
+ // Europe
+ // Stability: development
+ GeoContinentCodeEu = GeoContinentCodeKey.String("EU")
+ // North America
+ // Stability: development
+ GeoContinentCodeNa = GeoContinentCodeKey.String("NA")
+ // Oceania
+ // Stability: development
+ GeoContinentCodeOc = GeoContinentCodeKey.String("OC")
+ // South America
+ // Stability: development
+ GeoContinentCodeSa = GeoContinentCodeKey.String("SA")
+)
+
+// Namespace: go
+const (
+ // GoCPUDetailedStateKey is the attribute Key conforming to the
+ // "go.cpu.detailed_state" semantic conventions. It represents the detailed
+ // state of the CPU.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "gc/pause", "gc/mark/assist"
+ // Note: Value SHOULD match the specific CPU class reported by the Go runtime
+ // under `/cpu/classes/...`. The list of possible values is subject to change
+ // with the Go version used.
+ GoCPUDetailedStateKey = attribute.Key("go.cpu.detailed_state")
+
+ // GoCPUStateKey is the attribute Key conforming to the "go.cpu.state" semantic
+ // conventions. It represents the state of the CPU.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "user", "gc"
+ GoCPUStateKey = attribute.Key("go.cpu.state")
+
+ // GoMemoryDetailedTypeKey is the attribute Key conforming to the
+ // "go.memory.detailed_type" semantic conventions. It represents the detailed
+ // type of memory.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "heap/objects", "heap/free"
+ // Note: Value SHOULD match the specific memory class reported by the Go runtime
+ // under `/memory/classes/...`. The list of possible values is subject to change
+ // with the Go version used.
+ GoMemoryDetailedTypeKey = attribute.Key("go.memory.detailed_type")
+
+ // GoMemoryTypeKey is the attribute Key conforming to the "go.memory.type"
+ // semantic conventions. It represents the type of memory.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "other", "stack"
+ GoMemoryTypeKey = attribute.Key("go.memory.type")
+)
+
+// GoCPUDetailedState returns an attribute KeyValue conforming to the
+// "go.cpu.detailed_state" semantic conventions. It represents the detailed state
+// of the CPU.
+func GoCPUDetailedState(val string) attribute.KeyValue {
+ return GoCPUDetailedStateKey.String(val)
+}
+
+// GoMemoryDetailedType returns an attribute KeyValue conforming to the
+// "go.memory.detailed_type" semantic conventions. It represents the detailed
+// type of memory.
+func GoMemoryDetailedType(val string) attribute.KeyValue {
+ return GoMemoryDetailedTypeKey.String(val)
+}
+
+// Enum values for go.cpu.state
+var (
+ // CPU time spent running user Go code.
+ // Stability: development
+ GoCPUStateUser = GoCPUStateKey.String("user")
+ // CPU time spent performing garbage collection tasks.
+ // Stability: development
+ GoCPUStateGC = GoCPUStateKey.String("gc")
+ // CPU time spent returning unused memory to the underlying platform.
+ // Stability: development
+ GoCPUStateScavenge = GoCPUStateKey.String("scavenge")
+ // Available CPU time not spent executing any Go or Go runtime code.
+ // Stability: development
+ GoCPUStateIdle = GoCPUStateKey.String("idle")
+)
+
+// Enum values for go.memory.type
+var (
+ // Memory allocated from the heap that is reserved for stack space, whether or
+ // not it is currently in-use.
+ // Stability: development
+ GoMemoryTypeStack = GoMemoryTypeKey.String("stack")
+ // Memory used by the Go runtime, excluding other categories of memory usage
+ // described in this enumeration.
+ // Stability: development
+ GoMemoryTypeOther = GoMemoryTypeKey.String("other")
+)
+
+// Namespace: graphql
+const (
+ // GraphQLDocumentKey is the attribute Key conforming to the "graphql.document"
+ // semantic conventions. It represents the GraphQL document being executed.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: query findBookById { bookById(id: ?) { name } }
+ // Note: If instrumentation can reliably identify and redact sensitive
+ // information it SHOULD do it.
+ GraphQLDocumentKey = attribute.Key("graphql.document")
+
+ // GraphQLOperationNameKey is the attribute Key conforming to the
+ // "graphql.operation.name" semantic conventions. It represents the name of the
+ // operation being executed.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: findBookById
+ GraphQLOperationNameKey = attribute.Key("graphql.operation.name")
+
+ // GraphQLOperationTypeKey is the attribute Key conforming to the
+ // "graphql.operation.type" semantic conventions. It represents the type of the
+ // operation being executed.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "query", "mutation", "subscription"
+ GraphQLOperationTypeKey = attribute.Key("graphql.operation.type")
+)
+
+// GraphQLDocument returns an attribute KeyValue conforming to the
+// "graphql.document" semantic conventions. It represents the GraphQL document
+// being executed.
+func GraphQLDocument(val string) attribute.KeyValue {
+ return GraphQLDocumentKey.String(val)
+}
+
+// GraphQLOperationName returns an attribute KeyValue conforming to the
+// "graphql.operation.name" semantic conventions. It represents the name of the
+// operation being executed.
+func GraphQLOperationName(val string) attribute.KeyValue {
+ return GraphQLOperationNameKey.String(val)
+}
+
+// Enum values for graphql.operation.type
+var (
+ // GraphQL query
+ // Stability: development
+ GraphQLOperationTypeQuery = GraphQLOperationTypeKey.String("query")
+ // GraphQL mutation
+ // Stability: development
+ GraphQLOperationTypeMutation = GraphQLOperationTypeKey.String("mutation")
+ // GraphQL subscription
+ // Stability: development
+ GraphQLOperationTypeSubscription = GraphQLOperationTypeKey.String("subscription")
+)
+
+// Namespace: heroku
+const (
+ // HerokuAppIDKey is the attribute Key conforming to the "heroku.app.id"
+ // semantic conventions. It represents the unique identifier for the
+ // application.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "2daa2797-e42b-4624-9322-ec3f968df4da"
+ HerokuAppIDKey = attribute.Key("heroku.app.id")
+
+ // HerokuReleaseCommitKey is the attribute Key conforming to the
+ // "heroku.release.commit" semantic conventions. It represents the commit hash
+ // for the current release.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "e6134959463efd8966b20e75b913cafe3f5ec"
+ HerokuReleaseCommitKey = attribute.Key("heroku.release.commit")
+
+ // HerokuReleaseCreationTimestampKey is the attribute Key conforming to the
+ // "heroku.release.creation_timestamp" semantic conventions. It represents the
+ // time and date the release was created.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "2022-10-23T18:00:42Z"
+ HerokuReleaseCreationTimestampKey = attribute.Key("heroku.release.creation_timestamp")
+)
+
+// HerokuAppID returns an attribute KeyValue conforming to the "heroku.app.id"
+// semantic conventions. It represents the unique identifier for the application.
+func HerokuAppID(val string) attribute.KeyValue {
+ return HerokuAppIDKey.String(val)
+}
+
+// HerokuReleaseCommit returns an attribute KeyValue conforming to the
+// "heroku.release.commit" semantic conventions. It represents the commit hash
+// for the current release.
+func HerokuReleaseCommit(val string) attribute.KeyValue {
+ return HerokuReleaseCommitKey.String(val)
+}
+
+// HerokuReleaseCreationTimestamp returns an attribute KeyValue conforming to the
+// "heroku.release.creation_timestamp" semantic conventions. It represents the
+// time and date the release was created.
+func HerokuReleaseCreationTimestamp(val string) attribute.KeyValue {
+ return HerokuReleaseCreationTimestampKey.String(val)
+}
+
+// Namespace: host
+const (
+ // HostArchKey is the attribute Key conforming to the "host.arch" semantic
+ // conventions. It represents the CPU architecture the host system is running
+ // on.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ HostArchKey = attribute.Key("host.arch")
+
+ // HostCPUCacheL2SizeKey is the attribute Key conforming to the
+ // "host.cpu.cache.l2.size" semantic conventions. It represents the amount of
+ // level 2 memory cache available to the processor (in Bytes).
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 12288000
+ HostCPUCacheL2SizeKey = attribute.Key("host.cpu.cache.l2.size")
+
+ // HostCPUFamilyKey is the attribute Key conforming to the "host.cpu.family"
+ // semantic conventions. It represents the family or generation of the CPU.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "6", "PA-RISC 1.1e"
+ HostCPUFamilyKey = attribute.Key("host.cpu.family")
+
+ // HostCPUModelIDKey is the attribute Key conforming to the "host.cpu.model.id"
+ // semantic conventions. It represents the model identifier. It provides more
+ // granular information about the CPU, distinguishing it from other CPUs within
+ // the same family.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "6", "9000/778/B180L"
+ HostCPUModelIDKey = attribute.Key("host.cpu.model.id")
+
+ // HostCPUModelNameKey is the attribute Key conforming to the
+ // "host.cpu.model.name" semantic conventions. It represents the model
+ // designation of the processor.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "11th Gen Intel(R) Core(TM) i7-1185G7 @ 3.00GHz"
+ HostCPUModelNameKey = attribute.Key("host.cpu.model.name")
+
+ // HostCPUSteppingKey is the attribute Key conforming to the "host.cpu.stepping"
+ // semantic conventions. It represents the stepping or core revisions.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "1", "r1p1"
+ HostCPUSteppingKey = attribute.Key("host.cpu.stepping")
+
+ // HostCPUVendorIDKey is the attribute Key conforming to the
+ // "host.cpu.vendor.id" semantic conventions. It represents the processor
+ // manufacturer identifier. A maximum 12-character string.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "GenuineIntel"
+ // Note: [CPUID] command returns the vendor ID string in EBX, EDX and ECX
+ // registers. Writing these to memory in this order results in a 12-character
+ // string.
+ //
+ // [CPUID]: https://wiki.osdev.org/CPUID
+ HostCPUVendorIDKey = attribute.Key("host.cpu.vendor.id")
+
+ // HostIDKey is the attribute Key conforming to the "host.id" semantic
+ // conventions. It represents the unique host ID. For Cloud, this must be the
+ // instance_id assigned by the cloud provider. For non-containerized systems,
+ // this should be the `machine-id`. See the table below for the sources to use
+ // to determine the `machine-id` based on operating system.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "fdbf79e8af94cb7f9e8df36789187052"
+ HostIDKey = attribute.Key("host.id")
+
+ // HostImageIDKey is the attribute Key conforming to the "host.image.id"
+ // semantic conventions. It represents the VM image ID or host OS image ID. For
+ // Cloud, this value is from the provider.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "ami-07b06b442921831e5"
+ HostImageIDKey = attribute.Key("host.image.id")
+
+ // HostImageNameKey is the attribute Key conforming to the "host.image.name"
+ // semantic conventions. It represents the name of the VM image or OS install
+ // the host was instantiated from.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "infra-ami-eks-worker-node-7d4ec78312", "CentOS-8-x86_64-1905"
+ HostImageNameKey = attribute.Key("host.image.name")
+
+ // HostImageVersionKey is the attribute Key conforming to the
+ // "host.image.version" semantic conventions. It represents the version string
+ // of the VM image or host OS as defined in [Version Attributes].
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "0.1"
+ //
+ // [Version Attributes]: /docs/resource/README.md#version-attributes
+ HostImageVersionKey = attribute.Key("host.image.version")
+
+ // HostIPKey is the attribute Key conforming to the "host.ip" semantic
+ // conventions. It represents the available IP addresses of the host, excluding
+ // loopback interfaces.
+ //
+ // Type: string[]
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "192.168.1.140", "fe80::abc2:4a28:737a:609e"
+ // Note: IPv4 Addresses MUST be specified in dotted-quad notation. IPv6
+ // addresses MUST be specified in the [RFC 5952] format.
+ //
+ // [RFC 5952]: https://www.rfc-editor.org/rfc/rfc5952.html
+ HostIPKey = attribute.Key("host.ip")
+
+ // HostMacKey is the attribute Key conforming to the "host.mac" semantic
+ // conventions. It represents the available MAC addresses of the host, excluding
+ // loopback interfaces.
+ //
+ // Type: string[]
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "AC-DE-48-23-45-67", "AC-DE-48-23-45-67-01-9F"
+ // Note: MAC Addresses MUST be represented in [IEEE RA hexadecimal form]: as
+ // hyphen-separated octets in uppercase hexadecimal form from most to least
+ // significant.
+ //
+ // [IEEE RA hexadecimal form]: https://standards.ieee.org/wp-content/uploads/import/documents/tutorials/eui.pdf
+ HostMacKey = attribute.Key("host.mac")
+
+ // HostNameKey is the attribute Key conforming to the "host.name" semantic
+ // conventions. It represents the name of the host. On Unix systems, it may
+ // contain what the hostname command returns, or the fully qualified hostname,
+ // or another name specified by the user.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "opentelemetry-test"
+ HostNameKey = attribute.Key("host.name")
+
+ // HostTypeKey is the attribute Key conforming to the "host.type" semantic
+ // conventions. It represents the type of host. For Cloud, this must be the
+ // machine type.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "n1-standard-1"
+ HostTypeKey = attribute.Key("host.type")
+)
+
+// HostCPUCacheL2Size returns an attribute KeyValue conforming to the
+// "host.cpu.cache.l2.size" semantic conventions. It represents the amount of
+// level 2 memory cache available to the processor (in Bytes).
+func HostCPUCacheL2Size(val int) attribute.KeyValue {
+ return HostCPUCacheL2SizeKey.Int(val)
+}
+
+// HostCPUFamily returns an attribute KeyValue conforming to the
+// "host.cpu.family" semantic conventions. It represents the family or generation
+// of the CPU.
+func HostCPUFamily(val string) attribute.KeyValue {
+ return HostCPUFamilyKey.String(val)
+}
+
+// HostCPUModelID returns an attribute KeyValue conforming to the
+// "host.cpu.model.id" semantic conventions. It represents the model identifier.
+// It provides more granular information about the CPU, distinguishing it from
+// other CPUs within the same family.
+func HostCPUModelID(val string) attribute.KeyValue {
+ return HostCPUModelIDKey.String(val)
+}
+
+// HostCPUModelName returns an attribute KeyValue conforming to the
+// "host.cpu.model.name" semantic conventions. It represents the model
+// designation of the processor.
+func HostCPUModelName(val string) attribute.KeyValue {
+ return HostCPUModelNameKey.String(val)
+}
+
+// HostCPUStepping returns an attribute KeyValue conforming to the
+// "host.cpu.stepping" semantic conventions. It represents the stepping or core
+// revisions.
+func HostCPUStepping(val string) attribute.KeyValue {
+ return HostCPUSteppingKey.String(val)
+}
+
+// HostCPUVendorID returns an attribute KeyValue conforming to the
+// "host.cpu.vendor.id" semantic conventions. It represents the processor
+// manufacturer identifier. A maximum 12-character string.
+func HostCPUVendorID(val string) attribute.KeyValue {
+ return HostCPUVendorIDKey.String(val)
+}
+
+// HostID returns an attribute KeyValue conforming to the "host.id" semantic
+// conventions. It represents the unique host ID. For Cloud, this must be the
+// instance_id assigned by the cloud provider. For non-containerized systems,
+// this should be the `machine-id`. See the table below for the sources to use to
+// determine the `machine-id` based on operating system.
+func HostID(val string) attribute.KeyValue {
+ return HostIDKey.String(val)
+}
+
+// HostImageID returns an attribute KeyValue conforming to the "host.image.id"
+// semantic conventions. It represents the VM image ID or host OS image ID. For
+// Cloud, this value is from the provider.
+func HostImageID(val string) attribute.KeyValue {
+ return HostImageIDKey.String(val)
+}
+
+// HostImageName returns an attribute KeyValue conforming to the
+// "host.image.name" semantic conventions. It represents the name of the VM image
+// or OS install the host was instantiated from.
+func HostImageName(val string) attribute.KeyValue {
+ return HostImageNameKey.String(val)
+}
+
+// HostImageVersion returns an attribute KeyValue conforming to the
+// "host.image.version" semantic conventions. It represents the version string of
+// the VM image or host OS as defined in [Version Attributes].
+//
+// [Version Attributes]: /docs/resource/README.md#version-attributes
+func HostImageVersion(val string) attribute.KeyValue {
+ return HostImageVersionKey.String(val)
+}
+
+// HostIP returns an attribute KeyValue conforming to the "host.ip" semantic
+// conventions. It represents the available IP addresses of the host, excluding
+// loopback interfaces.
+func HostIP(val ...string) attribute.KeyValue {
+ return HostIPKey.StringSlice(val)
+}
+
+// HostMac returns an attribute KeyValue conforming to the "host.mac" semantic
+// conventions. It represents the available MAC addresses of the host, excluding
+// loopback interfaces.
+func HostMac(val ...string) attribute.KeyValue {
+ return HostMacKey.StringSlice(val)
+}
+
+// HostName returns an attribute KeyValue conforming to the "host.name" semantic
+// conventions. It represents the name of the host. On Unix systems, it may
+// contain what the hostname command returns, or the fully qualified hostname, or
+// another name specified by the user.
+func HostName(val string) attribute.KeyValue {
+ return HostNameKey.String(val)
+}
+
+// HostType returns an attribute KeyValue conforming to the "host.type" semantic
+// conventions. It represents the type of host. For Cloud, this must be the
+// machine type.
+func HostType(val string) attribute.KeyValue {
+ return HostTypeKey.String(val)
+}
+
+// Enum values for host.arch
+var (
+ // AMD64
+ // Stability: development
+ HostArchAMD64 = HostArchKey.String("amd64")
+ // ARM32
+ // Stability: development
+ HostArchARM32 = HostArchKey.String("arm32")
+ // ARM64
+ // Stability: development
+ HostArchARM64 = HostArchKey.String("arm64")
+ // Itanium
+ // Stability: development
+ HostArchIA64 = HostArchKey.String("ia64")
+ // 32-bit PowerPC
+ // Stability: development
+ HostArchPPC32 = HostArchKey.String("ppc32")
+ // 64-bit PowerPC
+ // Stability: development
+ HostArchPPC64 = HostArchKey.String("ppc64")
+ // IBM z/Architecture
+ // Stability: development
+ HostArchS390x = HostArchKey.String("s390x")
+ // 32-bit x86
+ // Stability: development
+ HostArchX86 = HostArchKey.String("x86")
+)
+
+// Namespace: http
+const (
+ // HTTPConnectionStateKey is the attribute Key conforming to the
+ // "http.connection.state" semantic conventions. It represents the state of the
+ // HTTP connection in the HTTP connection pool.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "active", "idle"
+ HTTPConnectionStateKey = attribute.Key("http.connection.state")
+
+ // HTTPRequestBodySizeKey is the attribute Key conforming to the
+ // "http.request.body.size" semantic conventions. It represents the size of the
+ // request payload body in bytes. This is the number of bytes transferred
+ // excluding headers and is often, but not always, present as the
+ // [Content-Length] header. For requests using transport encoding, this should
+ // be the compressed size.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // [Content-Length]: https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length
+ HTTPRequestBodySizeKey = attribute.Key("http.request.body.size")
+
+ // HTTPRequestMethodKey is the attribute Key conforming to the
+ // "http.request.method" semantic conventions. It represents the HTTP request
+ // method.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ //
+ // Examples: "GET", "POST", "HEAD"
+ // Note: HTTP request method value SHOULD be "known" to the instrumentation.
+ // By default, this convention defines "known" methods as the ones listed in
+ // [RFC9110],
+ // the PATCH method defined in [RFC5789]
+ // and the QUERY method defined in [httpbis-safe-method-w-body].
+ //
+ // If the HTTP request method is not known to instrumentation, it MUST set the
+ // `http.request.method` attribute to `_OTHER`.
+ //
+ // If the HTTP instrumentation could end up converting valid HTTP request
+ // methods to `_OTHER`, then it MUST provide a way to override
+ // the list of known HTTP methods. If this override is done via environment
+ // variable, then the environment variable MUST be named
+ // OTEL_INSTRUMENTATION_HTTP_KNOWN_METHODS and support a comma-separated list of
+ // case-sensitive known HTTP methods.
+ //
+ //
+ // If this override is done via declarative configuration, then the list MUST be
+ // configurable via the `known_methods` property
+ // (an array of case-sensitive strings with minimum items 0) under
+ // `.instrumentation/development.general.http.client` and/or
+ // `.instrumentation/development.general.http.server`.
+ //
+ // In either case, this list MUST be a full override of the default known
+ // methods,
+ // it is not a list of known methods in addition to the defaults.
+ //
+ // HTTP method names are case-sensitive and `http.request.method` attribute
+ // value MUST match a known HTTP method name exactly.
+ // Instrumentations for specific web frameworks that consider HTTP methods to be
+ // case insensitive, SHOULD populate a canonical equivalent.
+ // Tracing instrumentations that do so, MUST also set
+ // `http.request.method_original` to the original value.
+ //
+ // [RFC9110]: https://www.rfc-editor.org/rfc/rfc9110.html#name-methods
+ // [RFC5789]: https://www.rfc-editor.org/rfc/rfc5789.html
+ // [httpbis-safe-method-w-body]: https://datatracker.ietf.org/doc/draft-ietf-httpbis-safe-method-w-body/?include_text=1
+ HTTPRequestMethodKey = attribute.Key("http.request.method")
+
+ // HTTPRequestMethodOriginalKey is the attribute Key conforming to the
+ // "http.request.method_original" semantic conventions. It represents the
+ // original HTTP method sent by the client in the request line.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ //
+ // Examples: "GeT", "ACL", "foo"
+ HTTPRequestMethodOriginalKey = attribute.Key("http.request.method_original")
+
+ // HTTPRequestResendCountKey is the attribute Key conforming to the
+ // "http.request.resend_count" semantic conventions. It represents the ordinal
+ // number of request resending attempt (for any reason, including redirects).
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ //
+ // Note: The resend count SHOULD be updated each time an HTTP request gets
+ // resent by the client, regardless of what was the cause of the resending (e.g.
+ // redirection, authorization failure, 503 Server Unavailable, network issues,
+ // or any other).
+ HTTPRequestResendCountKey = attribute.Key("http.request.resend_count")
+
+ // HTTPRequestSizeKey is the attribute Key conforming to the "http.request.size"
+ // semantic conventions. It represents the total size of the request in bytes.
+ // This should be the total number of bytes sent over the wire, including the
+ // request line (HTTP/1.1), framing (HTTP/2 and HTTP/3), headers, and request
+ // body if any.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ HTTPRequestSizeKey = attribute.Key("http.request.size")
+
+ // HTTPResponseBodySizeKey is the attribute Key conforming to the
+ // "http.response.body.size" semantic conventions. It represents the size of the
+ // response payload body in bytes. This is the number of bytes transferred
+ // excluding headers and is often, but not always, present as the
+ // [Content-Length] header. For requests using transport encoding, this should
+ // be the compressed size.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // [Content-Length]: https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length
+ HTTPResponseBodySizeKey = attribute.Key("http.response.body.size")
+
+ // HTTPResponseSizeKey is the attribute Key conforming to the
+ // "http.response.size" semantic conventions. It represents the total size of
+ // the response in bytes. This should be the total number of bytes sent over the
+ // wire, including the status line (HTTP/1.1), framing (HTTP/2 and HTTP/3),
+ // headers, and response body and trailers if any.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ HTTPResponseSizeKey = attribute.Key("http.response.size")
+
+ // HTTPResponseStatusCodeKey is the attribute Key conforming to the
+ // "http.response.status_code" semantic conventions. It represents the
+ // [HTTP response status code].
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ //
+ // Examples: 200
+ //
+ // [HTTP response status code]: https://tools.ietf.org/html/rfc7231#section-6
+ HTTPResponseStatusCodeKey = attribute.Key("http.response.status_code")
+
+ // HTTPRouteKey is the attribute Key conforming to the "http.route" semantic
+ // conventions. It represents the matched route template for the request. This
+ // MUST be low-cardinality and include all static path segments, with dynamic
+ // path segments represented with placeholders.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ //
+ // Examples: "/users/:userID?", "my-controller/my-action/{id?}"
+ // Note: MUST NOT be populated when this is not supported by the HTTP server
+ // framework as the route attribute should have low-cardinality and the URI path
+ // can NOT substitute it.
+ // SHOULD include the [application root] if there is one.
+ //
+ // A static path segment is a part of the route template with a fixed,
+ // low-cardinality value. This includes literal strings like `/users/` and
+ // placeholders that
+ // are constrained to a finite, predefined set of values, e.g. `{controller}` or
+ // `{action}`.
+ //
+ // A dynamic path segment is a placeholder for a value that can have high
+ // cardinality and is not constrained to a predefined list like static path
+ // segments.
+ //
+ // Instrumentations SHOULD use routing information provided by the corresponding
+ // web framework. They SHOULD pick the most precise source of routing
+ // information and MAY
+ // support custom route formatting. Instrumentations SHOULD document the format
+ // and the API used to obtain the route string.
+ //
+ // [application root]: /docs/http/http-spans.md#http-server-definitions
+ HTTPRouteKey = attribute.Key("http.route")
+)
+
+// HTTPRequestBodySize returns an attribute KeyValue conforming to the
+// "http.request.body.size" semantic conventions. It represents the size of the
+// request payload body in bytes. This is the number of bytes transferred
+// excluding headers and is often, but not always, present as the
+// [Content-Length] header. For requests using transport encoding, this should be
+// the compressed size.
+//
+// [Content-Length]: https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length
+func HTTPRequestBodySize(val int) attribute.KeyValue {
+ return HTTPRequestBodySizeKey.Int(val)
+}
+
+// HTTPRequestHeader returns an attribute KeyValue conforming to the
+// "http.request.header" semantic conventions. It represents the HTTP request
+// headers, `` being the normalized HTTP Header name (lowercase), the value
+// being the header values.
+func HTTPRequestHeader(key string, val ...string) attribute.KeyValue {
+ return attribute.StringSlice("http.request.header."+key, val)
+}
+
+// HTTPRequestMethodOriginal returns an attribute KeyValue conforming to the
+// "http.request.method_original" semantic conventions. It represents the
+// original HTTP method sent by the client in the request line.
+func HTTPRequestMethodOriginal(val string) attribute.KeyValue {
+ return HTTPRequestMethodOriginalKey.String(val)
+}
+
+// HTTPRequestResendCount returns an attribute KeyValue conforming to the
+// "http.request.resend_count" semantic conventions. It represents the ordinal
+// number of request resending attempt (for any reason, including redirects).
+func HTTPRequestResendCount(val int) attribute.KeyValue {
+ return HTTPRequestResendCountKey.Int(val)
+}
+
+// HTTPRequestSize returns an attribute KeyValue conforming to the
+// "http.request.size" semantic conventions. It represents the total size of the
+// request in bytes. This should be the total number of bytes sent over the wire,
+// including the request line (HTTP/1.1), framing (HTTP/2 and HTTP/3), headers,
+// and request body if any.
+func HTTPRequestSize(val int) attribute.KeyValue {
+ return HTTPRequestSizeKey.Int(val)
+}
+
+// HTTPResponseBodySize returns an attribute KeyValue conforming to the
+// "http.response.body.size" semantic conventions. It represents the size of the
+// response payload body in bytes. This is the number of bytes transferred
+// excluding headers and is often, but not always, present as the
+// [Content-Length] header. For requests using transport encoding, this should be
+// the compressed size.
+//
+// [Content-Length]: https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length
+func HTTPResponseBodySize(val int) attribute.KeyValue {
+ return HTTPResponseBodySizeKey.Int(val)
+}
+
+// HTTPResponseHeader returns an attribute KeyValue conforming to the
+// "http.response.header" semantic conventions. It represents the HTTP response
+// headers, `` being the normalized HTTP Header name (lowercase), the value
+// being the header values.
+func HTTPResponseHeader(key string, val ...string) attribute.KeyValue {
+ return attribute.StringSlice("http.response.header."+key, val)
+}
+
+// HTTPResponseSize returns an attribute KeyValue conforming to the
+// "http.response.size" semantic conventions. It represents the total size of the
+// response in bytes. This should be the total number of bytes sent over the
+// wire, including the status line (HTTP/1.1), framing (HTTP/2 and HTTP/3),
+// headers, and response body and trailers if any.
+func HTTPResponseSize(val int) attribute.KeyValue {
+ return HTTPResponseSizeKey.Int(val)
+}
+
+// HTTPResponseStatusCode returns an attribute KeyValue conforming to the
+// "http.response.status_code" semantic conventions. It represents the
+// [HTTP response status code].
+//
+// [HTTP response status code]: https://tools.ietf.org/html/rfc7231#section-6
+func HTTPResponseStatusCode(val int) attribute.KeyValue {
+ return HTTPResponseStatusCodeKey.Int(val)
+}
+
+// HTTPRoute returns an attribute KeyValue conforming to the "http.route"
+// semantic conventions. It represents the matched route template for the
+// request. This MUST be low-cardinality and include all static path segments,
+// with dynamic path segments represented with placeholders.
+func HTTPRoute(val string) attribute.KeyValue {
+ return HTTPRouteKey.String(val)
+}
+
+// Enum values for http.connection.state
+var (
+ // active state.
+ // Stability: development
+ HTTPConnectionStateActive = HTTPConnectionStateKey.String("active")
+ // idle state.
+ // Stability: development
+ HTTPConnectionStateIdle = HTTPConnectionStateKey.String("idle")
+)
+
+// Enum values for http.request.method
+var (
+ // CONNECT method.
+ // Stability: stable
+ HTTPRequestMethodConnect = HTTPRequestMethodKey.String("CONNECT")
+ // DELETE method.
+ // Stability: stable
+ HTTPRequestMethodDelete = HTTPRequestMethodKey.String("DELETE")
+ // GET method.
+ // Stability: stable
+ HTTPRequestMethodGet = HTTPRequestMethodKey.String("GET")
+ // HEAD method.
+ // Stability: stable
+ HTTPRequestMethodHead = HTTPRequestMethodKey.String("HEAD")
+ // OPTIONS method.
+ // Stability: stable
+ HTTPRequestMethodOptions = HTTPRequestMethodKey.String("OPTIONS")
+ // PATCH method.
+ // Stability: stable
+ HTTPRequestMethodPatch = HTTPRequestMethodKey.String("PATCH")
+ // POST method.
+ // Stability: stable
+ HTTPRequestMethodPost = HTTPRequestMethodKey.String("POST")
+ // PUT method.
+ // Stability: stable
+ HTTPRequestMethodPut = HTTPRequestMethodKey.String("PUT")
+ // TRACE method.
+ // Stability: stable
+ HTTPRequestMethodTrace = HTTPRequestMethodKey.String("TRACE")
+ // QUERY method.
+ // Stability: development
+ HTTPRequestMethodQuery = HTTPRequestMethodKey.String("QUERY")
+ // Any HTTP method that the instrumentation has no prior knowledge of.
+ // Stability: stable
+ HTTPRequestMethodOther = HTTPRequestMethodKey.String("_OTHER")
+)
+
+// Namespace: hw
+const (
+ // HwBatteryCapacityKey is the attribute Key conforming to the
+ // "hw.battery.capacity" semantic conventions. It represents the design capacity
+ // in Watts-hours or Ampere-hours.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "9.3Ah", "50Wh"
+ HwBatteryCapacityKey = attribute.Key("hw.battery.capacity")
+
+ // HwBatteryChemistryKey is the attribute Key conforming to the
+ // "hw.battery.chemistry" semantic conventions. It represents the battery
+ // [chemistry], e.g. Lithium-Ion, Nickel-Cadmium, etc.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "Li-ion", "NiMH"
+ //
+ // [chemistry]: https://schemas.dmtf.org/wbem/cim-html/2.31.0/CIM_Battery.html
+ HwBatteryChemistryKey = attribute.Key("hw.battery.chemistry")
+
+ // HwBatteryStateKey is the attribute Key conforming to the "hw.battery.state"
+ // semantic conventions. It represents the current state of the battery.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ HwBatteryStateKey = attribute.Key("hw.battery.state")
+
+ // HwBiosVersionKey is the attribute Key conforming to the "hw.bios_version"
+ // semantic conventions. It represents the BIOS version of the hardware
+ // component.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "1.2.3"
+ HwBiosVersionKey = attribute.Key("hw.bios_version")
+
+ // HwDriverVersionKey is the attribute Key conforming to the "hw.driver_version"
+ // semantic conventions. It represents the driver version for the hardware
+ // component.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "10.2.1-3"
+ HwDriverVersionKey = attribute.Key("hw.driver_version")
+
+ // HwEnclosureTypeKey is the attribute Key conforming to the "hw.enclosure.type"
+ // semantic conventions. It represents the type of the enclosure (useful for
+ // modular systems).
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "Computer", "Storage", "Switch"
+ HwEnclosureTypeKey = attribute.Key("hw.enclosure.type")
+
+ // HwFirmwareVersionKey is the attribute Key conforming to the
+ // "hw.firmware_version" semantic conventions. It represents the firmware
+ // version of the hardware component.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "2.0.1"
+ HwFirmwareVersionKey = attribute.Key("hw.firmware_version")
+
+ // HwGpuTaskKey is the attribute Key conforming to the "hw.gpu.task" semantic
+ // conventions. It represents the type of task the GPU is performing.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ HwGpuTaskKey = attribute.Key("hw.gpu.task")
+
+ // HwIDKey is the attribute Key conforming to the "hw.id" semantic conventions.
+ // It represents an identifier for the hardware component, unique within the
+ // monitored host.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "win32battery_battery_testsysa33_1"
+ HwIDKey = attribute.Key("hw.id")
+
+ // HwLimitTypeKey is the attribute Key conforming to the "hw.limit_type"
+ // semantic conventions. It represents the type of limit for hardware
+ // components.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ HwLimitTypeKey = attribute.Key("hw.limit_type")
+
+ // HwLogicalDiskRaidLevelKey is the attribute Key conforming to the
+ // "hw.logical_disk.raid_level" semantic conventions. It represents the RAID
+ // Level of the logical disk.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "RAID0+1", "RAID5", "RAID10"
+ HwLogicalDiskRaidLevelKey = attribute.Key("hw.logical_disk.raid_level")
+
+ // HwLogicalDiskStateKey is the attribute Key conforming to the
+ // "hw.logical_disk.state" semantic conventions. It represents the state of the
+ // logical disk space usage.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ HwLogicalDiskStateKey = attribute.Key("hw.logical_disk.state")
+
+ // HwMemoryTypeKey is the attribute Key conforming to the "hw.memory.type"
+ // semantic conventions. It represents the type of the memory module.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "DDR4", "DDR5", "LPDDR5"
+ HwMemoryTypeKey = attribute.Key("hw.memory.type")
+
+ // HwModelKey is the attribute Key conforming to the "hw.model" semantic
+ // conventions. It represents the descriptive model name of the hardware
+ // component.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "PERC H740P", "Intel(R) Core(TM) i7-10700K", "Dell XPS 15 Battery"
+ HwModelKey = attribute.Key("hw.model")
+
+ // HwNameKey is the attribute Key conforming to the "hw.name" semantic
+ // conventions. It represents an easily-recognizable name for the hardware
+ // component.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "eth0"
+ HwNameKey = attribute.Key("hw.name")
+
+ // HwNetworkLogicalAddressesKey is the attribute Key conforming to the
+ // "hw.network.logical_addresses" semantic conventions. It represents the
+ // logical addresses of the adapter (e.g. IP address, or WWPN).
+ //
+ // Type: string[]
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "172.16.8.21", "57.11.193.42"
+ HwNetworkLogicalAddressesKey = attribute.Key("hw.network.logical_addresses")
+
+ // HwNetworkPhysicalAddressKey is the attribute Key conforming to the
+ // "hw.network.physical_address" semantic conventions. It represents the
+ // physical address of the adapter (e.g. MAC address, or WWNN).
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "00-90-F5-E9-7B-36"
+ HwNetworkPhysicalAddressKey = attribute.Key("hw.network.physical_address")
+
+ // HwParentKey is the attribute Key conforming to the "hw.parent" semantic
+ // conventions. It represents the unique identifier of the parent component
+ // (typically the `hw.id` attribute of the enclosure, or disk controller).
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "dellStorage_perc_0"
+ HwParentKey = attribute.Key("hw.parent")
+
+ // HwPhysicalDiskSmartAttributeKey is the attribute Key conforming to the
+ // "hw.physical_disk.smart_attribute" semantic conventions. It represents the
+ // [S.M.A.R.T.] (Self-Monitoring, Analysis, and Reporting Technology) attribute
+ // of the physical disk.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "Spin Retry Count", "Seek Error Rate", "Raw Read Error Rate"
+ //
+ // [S.M.A.R.T.]: https://wikipedia.org/wiki/S.M.A.R.T.
+ HwPhysicalDiskSmartAttributeKey = attribute.Key("hw.physical_disk.smart_attribute")
+
+ // HwPhysicalDiskStateKey is the attribute Key conforming to the
+ // "hw.physical_disk.state" semantic conventions. It represents the state of the
+ // physical disk endurance utilization.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ HwPhysicalDiskStateKey = attribute.Key("hw.physical_disk.state")
+
+ // HwPhysicalDiskTypeKey is the attribute Key conforming to the
+ // "hw.physical_disk.type" semantic conventions. It represents the type of the
+ // physical disk.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "HDD", "SSD", "10K"
+ HwPhysicalDiskTypeKey = attribute.Key("hw.physical_disk.type")
+
+ // HwSensorLocationKey is the attribute Key conforming to the
+ // "hw.sensor_location" semantic conventions. It represents the location of the
+ // sensor.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "cpu0", "ps1", "INLET", "CPU0_DIE", "AMBIENT", "MOTHERBOARD", "PS0
+ // V3_3", "MAIN_12V", "CPU_VCORE"
+ HwSensorLocationKey = attribute.Key("hw.sensor_location")
+
+ // HwSerialNumberKey is the attribute Key conforming to the "hw.serial_number"
+ // semantic conventions. It represents the serial number of the hardware
+ // component.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "CNFCP0123456789"
+ HwSerialNumberKey = attribute.Key("hw.serial_number")
+
+ // HwStateKey is the attribute Key conforming to the "hw.state" semantic
+ // conventions. It represents the current state of the component.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ HwStateKey = attribute.Key("hw.state")
+
+ // HwTapeDriveOperationTypeKey is the attribute Key conforming to the
+ // "hw.tape_drive.operation_type" semantic conventions. It represents the type
+ // of tape drive operation.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ HwTapeDriveOperationTypeKey = attribute.Key("hw.tape_drive.operation_type")
+
+ // HwTypeKey is the attribute Key conforming to the "hw.type" semantic
+ // conventions. It represents the type of the component.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ // Note: Describes the category of the hardware component for which `hw.state`
+ // is being reported. For example, `hw.type=temperature` along with
+ // `hw.state=degraded` would indicate that the temperature of the hardware
+ // component has been reported as `degraded`.
+ HwTypeKey = attribute.Key("hw.type")
+
+ // HwVendorKey is the attribute Key conforming to the "hw.vendor" semantic
+ // conventions. It represents the vendor name of the hardware component.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "Dell", "HP", "Intel", "AMD", "LSI", "Lenovo"
+ HwVendorKey = attribute.Key("hw.vendor")
+)
+
+// HwBatteryCapacity returns an attribute KeyValue conforming to the
+// "hw.battery.capacity" semantic conventions. It represents the design capacity
+// in Watts-hours or Ampere-hours.
+func HwBatteryCapacity(val string) attribute.KeyValue {
+ return HwBatteryCapacityKey.String(val)
+}
+
+// HwBatteryChemistry returns an attribute KeyValue conforming to the
+// "hw.battery.chemistry" semantic conventions. It represents the battery
+// [chemistry], e.g. Lithium-Ion, Nickel-Cadmium, etc.
+//
+// [chemistry]: https://schemas.dmtf.org/wbem/cim-html/2.31.0/CIM_Battery.html
+func HwBatteryChemistry(val string) attribute.KeyValue {
+ return HwBatteryChemistryKey.String(val)
+}
+
+// HwBiosVersion returns an attribute KeyValue conforming to the
+// "hw.bios_version" semantic conventions. It represents the BIOS version of the
+// hardware component.
+func HwBiosVersion(val string) attribute.KeyValue {
+ return HwBiosVersionKey.String(val)
+}
+
+// HwDriverVersion returns an attribute KeyValue conforming to the
+// "hw.driver_version" semantic conventions. It represents the driver version for
+// the hardware component.
+func HwDriverVersion(val string) attribute.KeyValue {
+ return HwDriverVersionKey.String(val)
+}
+
+// HwEnclosureType returns an attribute KeyValue conforming to the
+// "hw.enclosure.type" semantic conventions. It represents the type of the
+// enclosure (useful for modular systems).
+func HwEnclosureType(val string) attribute.KeyValue {
+ return HwEnclosureTypeKey.String(val)
+}
+
+// HwFirmwareVersion returns an attribute KeyValue conforming to the
+// "hw.firmware_version" semantic conventions. It represents the firmware version
+// of the hardware component.
+func HwFirmwareVersion(val string) attribute.KeyValue {
+ return HwFirmwareVersionKey.String(val)
+}
+
+// HwID returns an attribute KeyValue conforming to the "hw.id" semantic
+// conventions. It represents an identifier for the hardware component, unique
+// within the monitored host.
+func HwID(val string) attribute.KeyValue {
+ return HwIDKey.String(val)
+}
+
+// HwLogicalDiskRaidLevel returns an attribute KeyValue conforming to the
+// "hw.logical_disk.raid_level" semantic conventions. It represents the RAID
+// Level of the logical disk.
+func HwLogicalDiskRaidLevel(val string) attribute.KeyValue {
+ return HwLogicalDiskRaidLevelKey.String(val)
+}
+
+// HwMemoryType returns an attribute KeyValue conforming to the "hw.memory.type"
+// semantic conventions. It represents the type of the memory module.
+func HwMemoryType(val string) attribute.KeyValue {
+ return HwMemoryTypeKey.String(val)
+}
+
+// HwModel returns an attribute KeyValue conforming to the "hw.model" semantic
+// conventions. It represents the descriptive model name of the hardware
+// component.
+func HwModel(val string) attribute.KeyValue {
+ return HwModelKey.String(val)
+}
+
+// HwName returns an attribute KeyValue conforming to the "hw.name" semantic
+// conventions. It represents an easily-recognizable name for the hardware
+// component.
+func HwName(val string) attribute.KeyValue {
+ return HwNameKey.String(val)
+}
+
+// HwNetworkLogicalAddresses returns an attribute KeyValue conforming to the
+// "hw.network.logical_addresses" semantic conventions. It represents the logical
+// addresses of the adapter (e.g. IP address, or WWPN).
+func HwNetworkLogicalAddresses(val ...string) attribute.KeyValue {
+ return HwNetworkLogicalAddressesKey.StringSlice(val)
+}
+
+// HwNetworkPhysicalAddress returns an attribute KeyValue conforming to the
+// "hw.network.physical_address" semantic conventions. It represents the physical
+// address of the adapter (e.g. MAC address, or WWNN).
+func HwNetworkPhysicalAddress(val string) attribute.KeyValue {
+ return HwNetworkPhysicalAddressKey.String(val)
+}
+
+// HwParent returns an attribute KeyValue conforming to the "hw.parent" semantic
+// conventions. It represents the unique identifier of the parent component
+// (typically the `hw.id` attribute of the enclosure, or disk controller).
+func HwParent(val string) attribute.KeyValue {
+ return HwParentKey.String(val)
+}
+
+// HwPhysicalDiskSmartAttribute returns an attribute KeyValue conforming to the
+// "hw.physical_disk.smart_attribute" semantic conventions. It represents the
+// [S.M.A.R.T.] (Self-Monitoring, Analysis, and Reporting Technology) attribute
+// of the physical disk.
+//
+// [S.M.A.R.T.]: https://wikipedia.org/wiki/S.M.A.R.T.
+func HwPhysicalDiskSmartAttribute(val string) attribute.KeyValue {
+ return HwPhysicalDiskSmartAttributeKey.String(val)
+}
+
+// HwPhysicalDiskType returns an attribute KeyValue conforming to the
+// "hw.physical_disk.type" semantic conventions. It represents the type of the
+// physical disk.
+func HwPhysicalDiskType(val string) attribute.KeyValue {
+ return HwPhysicalDiskTypeKey.String(val)
+}
+
+// HwSensorLocation returns an attribute KeyValue conforming to the
+// "hw.sensor_location" semantic conventions. It represents the location of the
+// sensor.
+func HwSensorLocation(val string) attribute.KeyValue {
+ return HwSensorLocationKey.String(val)
+}
+
+// HwSerialNumber returns an attribute KeyValue conforming to the
+// "hw.serial_number" semantic conventions. It represents the serial number of
+// the hardware component.
+func HwSerialNumber(val string) attribute.KeyValue {
+ return HwSerialNumberKey.String(val)
+}
+
+// HwVendor returns an attribute KeyValue conforming to the "hw.vendor" semantic
+// conventions. It represents the vendor name of the hardware component.
+func HwVendor(val string) attribute.KeyValue {
+ return HwVendorKey.String(val)
+}
+
+// Enum values for hw.battery.state
+var (
+ // Charging
+ // Stability: development
+ HwBatteryStateCharging = HwBatteryStateKey.String("charging")
+ // Discharging
+ // Stability: development
+ HwBatteryStateDischarging = HwBatteryStateKey.String("discharging")
+)
+
+// Enum values for hw.gpu.task
+var (
+ // Decoder
+ // Stability: development
+ HwGpuTaskDecoder = HwGpuTaskKey.String("decoder")
+ // Encoder
+ // Stability: development
+ HwGpuTaskEncoder = HwGpuTaskKey.String("encoder")
+ // General
+ // Stability: development
+ HwGpuTaskGeneral = HwGpuTaskKey.String("general")
+)
+
+// Enum values for hw.limit_type
+var (
+ // Critical
+ // Stability: development
+ HwLimitTypeCritical = HwLimitTypeKey.String("critical")
+ // Degraded
+ // Stability: development
+ HwLimitTypeDegraded = HwLimitTypeKey.String("degraded")
+ // High Critical
+ // Stability: development
+ HwLimitTypeHighCritical = HwLimitTypeKey.String("high.critical")
+ // High Degraded
+ // Stability: development
+ HwLimitTypeHighDegraded = HwLimitTypeKey.String("high.degraded")
+ // Low Critical
+ // Stability: development
+ HwLimitTypeLowCritical = HwLimitTypeKey.String("low.critical")
+ // Low Degraded
+ // Stability: development
+ HwLimitTypeLowDegraded = HwLimitTypeKey.String("low.degraded")
+ // Maximum
+ // Stability: development
+ HwLimitTypeMax = HwLimitTypeKey.String("max")
+ // Throttled
+ // Stability: development
+ HwLimitTypeThrottled = HwLimitTypeKey.String("throttled")
+ // Turbo
+ // Stability: development
+ HwLimitTypeTurbo = HwLimitTypeKey.String("turbo")
+)
+
+// Enum values for hw.logical_disk.state
+var (
+ // Used
+ // Stability: development
+ HwLogicalDiskStateUsed = HwLogicalDiskStateKey.String("used")
+ // Free
+ // Stability: development
+ HwLogicalDiskStateFree = HwLogicalDiskStateKey.String("free")
+)
+
+// Enum values for hw.physical_disk.state
+var (
+ // Remaining
+ // Stability: development
+ HwPhysicalDiskStateRemaining = HwPhysicalDiskStateKey.String("remaining")
+)
+
+// Enum values for hw.state
+var (
+ // Degraded
+ // Stability: development
+ HwStateDegraded = HwStateKey.String("degraded")
+ // Failed
+ // Stability: development
+ HwStateFailed = HwStateKey.String("failed")
+ // Needs Cleaning
+ // Stability: development
+ HwStateNeedsCleaning = HwStateKey.String("needs_cleaning")
+ // OK
+ // Stability: development
+ HwStateOk = HwStateKey.String("ok")
+ // Predicted Failure
+ // Stability: development
+ HwStatePredictedFailure = HwStateKey.String("predicted_failure")
+)
+
+// Enum values for hw.tape_drive.operation_type
+var (
+ // Mount
+ // Stability: development
+ HwTapeDriveOperationTypeMount = HwTapeDriveOperationTypeKey.String("mount")
+ // Unmount
+ // Stability: development
+ HwTapeDriveOperationTypeUnmount = HwTapeDriveOperationTypeKey.String("unmount")
+ // Clean
+ // Stability: development
+ HwTapeDriveOperationTypeClean = HwTapeDriveOperationTypeKey.String("clean")
+)
+
+// Enum values for hw.type
+var (
+ // Battery
+ // Stability: development
+ HwTypeBattery = HwTypeKey.String("battery")
+ // CPU
+ // Stability: development
+ HwTypeCPU = HwTypeKey.String("cpu")
+ // Disk controller
+ // Stability: development
+ HwTypeDiskController = HwTypeKey.String("disk_controller")
+ // Enclosure
+ // Stability: development
+ HwTypeEnclosure = HwTypeKey.String("enclosure")
+ // Fan
+ // Stability: development
+ HwTypeFan = HwTypeKey.String("fan")
+ // GPU
+ // Stability: development
+ HwTypeGpu = HwTypeKey.String("gpu")
+ // Logical disk
+ // Stability: development
+ HwTypeLogicalDisk = HwTypeKey.String("logical_disk")
+ // Memory
+ // Stability: development
+ HwTypeMemory = HwTypeKey.String("memory")
+ // Network
+ // Stability: development
+ HwTypeNetwork = HwTypeKey.String("network")
+ // Physical disk
+ // Stability: development
+ HwTypePhysicalDisk = HwTypeKey.String("physical_disk")
+ // Power supply
+ // Stability: development
+ HwTypePowerSupply = HwTypeKey.String("power_supply")
+ // Tape drive
+ // Stability: development
+ HwTypeTapeDrive = HwTypeKey.String("tape_drive")
+ // Temperature
+ // Stability: development
+ HwTypeTemperature = HwTypeKey.String("temperature")
+ // Voltage
+ // Stability: development
+ HwTypeVoltage = HwTypeKey.String("voltage")
+)
+
+// Namespace: ios
+const (
+ // IOSAppStateKey is the attribute Key conforming to the "ios.app.state"
+ // semantic conventions. It represents the this attribute represents the state
+ // of the application.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ // Note: The iOS lifecycle states are defined in the
+ // [UIApplicationDelegate documentation], and from which the `OS terminology`
+ // column values are derived.
+ //
+ // [UIApplicationDelegate documentation]: https://developer.apple.com/documentation/uikit/uiapplicationdelegate
+ IOSAppStateKey = attribute.Key("ios.app.state")
+)
+
+// Enum values for ios.app.state
+var (
+ // The app has become `active`. Associated with UIKit notification
+ // `applicationDidBecomeActive`.
+ //
+ // Stability: development
+ IOSAppStateActive = IOSAppStateKey.String("active")
+ // The app is now `inactive`. Associated with UIKit notification
+ // `applicationWillResignActive`.
+ //
+ // Stability: development
+ IOSAppStateInactive = IOSAppStateKey.String("inactive")
+ // The app is now in the background. This value is associated with UIKit
+ // notification `applicationDidEnterBackground`.
+ //
+ // Stability: development
+ IOSAppStateBackground = IOSAppStateKey.String("background")
+ // The app is now in the foreground. This value is associated with UIKit
+ // notification `applicationWillEnterForeground`.
+ //
+ // Stability: development
+ IOSAppStateForeground = IOSAppStateKey.String("foreground")
+ // The app is about to terminate. Associated with UIKit notification
+ // `applicationWillTerminate`.
+ //
+ // Stability: development
+ IOSAppStateTerminate = IOSAppStateKey.String("terminate")
+)
+
+// Namespace: jsonrpc
+const (
+ // JSONRPCProtocolVersionKey is the attribute Key conforming to the
+ // "jsonrpc.protocol.version" semantic conventions. It represents the protocol
+ // version, as specified in the `jsonrpc` property of the request and its
+ // corresponding response.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "2.0", "1.0"
+ JSONRPCProtocolVersionKey = attribute.Key("jsonrpc.protocol.version")
+
+ // JSONRPCRequestIDKey is the attribute Key conforming to the
+ // "jsonrpc.request.id" semantic conventions. It represents a string
+ // representation of the `id` property of the request and its corresponding
+ // response.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "10", "request-7"
+ // Note: Under the [JSON-RPC specification], the `id` property may be a string,
+ // number, null, or omitted entirely. When omitted, the request is treated as a
+ // notification. Using `null` is not equivalent to omitting the `id`, but it is
+ // discouraged.
+ // Instrumentations SHOULD NOT capture this attribute when the `id` is `null` or
+ // omitted.
+ //
+ // [JSON-RPC specification]: https://www.jsonrpc.org/specification
+ JSONRPCRequestIDKey = attribute.Key("jsonrpc.request.id")
+)
+
+// JSONRPCProtocolVersion returns an attribute KeyValue conforming to the
+// "jsonrpc.protocol.version" semantic conventions. It represents the protocol
+// version, as specified in the `jsonrpc` property of the request and its
+// corresponding response.
+func JSONRPCProtocolVersion(val string) attribute.KeyValue {
+ return JSONRPCProtocolVersionKey.String(val)
+}
+
+// JSONRPCRequestID returns an attribute KeyValue conforming to the
+// "jsonrpc.request.id" semantic conventions. It represents a string
+// representation of the `id` property of the request and its corresponding
+// response.
+func JSONRPCRequestID(val string) attribute.KeyValue {
+ return JSONRPCRequestIDKey.String(val)
+}
+
+// Namespace: k8s
+const (
+ // K8SClusterNameKey is the attribute Key conforming to the "k8s.cluster.name"
+ // semantic conventions. It represents the name of the cluster.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Release_Candidate
+ //
+ // Examples: "opentelemetry-cluster"
+ K8SClusterNameKey = attribute.Key("k8s.cluster.name")
+
+ // K8SClusterUIDKey is the attribute Key conforming to the "k8s.cluster.uid"
+ // semantic conventions. It represents a pseudo-ID for the cluster, set to the
+ // UID of the `kube-system` namespace.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Release_Candidate
+ //
+ // Examples: "218fc5a9-a5f1-4b54-aa05-46717d0ab26d"
+ // Note: K8s doesn't have support for obtaining a cluster ID. If this is ever
+ // added, we will recommend collecting the `k8s.cluster.uid` through the
+ // official APIs. In the meantime, we are able to use the `uid` of the
+ // `kube-system` namespace as a proxy for cluster ID. Read on for the
+ // rationale.
+ //
+ // Every object created in a K8s cluster is assigned a distinct UID. The
+ // `kube-system` namespace is used by Kubernetes itself and will exist
+ // for the lifetime of the cluster. Using the `uid` of the `kube-system`
+ // namespace is a reasonable proxy for the K8s ClusterID as it will only
+ // change if the cluster is rebuilt. Furthermore, Kubernetes UIDs are
+ // UUIDs as standardized by
+ // [ISO/IEC 9834-8 and ITU-T X.667].
+ // Which states:
+ //
+ // > If generated according to one of the mechanisms defined in Rec.
+ // > ITU-T X.667 | ISO/IEC 9834-8, a UUID is either guaranteed to be
+ // > different from all other UUIDs generated before 3603 A.D., or is
+ // > extremely likely to be different (depending on the mechanism chosen).
+ //
+ // Therefore, UIDs between clusters should be extremely unlikely to
+ // conflict.
+ //
+ // [ISO/IEC 9834-8 and ITU-T X.667]: https://www.itu.int/ITU-T/studygroups/com17/oid.html
+ K8SClusterUIDKey = attribute.Key("k8s.cluster.uid")
+
+ // K8SContainerNameKey is the attribute Key conforming to the
+ // "k8s.container.name" semantic conventions. It represents the name of the
+ // Container from Pod specification, must be unique within a Pod. Container
+ // runtime usually uses different globally unique name (`container.name`).
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Release_Candidate
+ //
+ // Examples: "redis"
+ K8SContainerNameKey = attribute.Key("k8s.container.name")
+
+ // K8SContainerRestartCountKey is the attribute Key conforming to the
+ // "k8s.container.restart_count" semantic conventions. It represents the number
+ // of times the container was restarted. This attribute can be used to identify
+ // a particular container (running or stopped) within a container spec.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Release_Candidate
+ //
+ // Examples:
+ K8SContainerRestartCountKey = attribute.Key("k8s.container.restart_count")
+
+ // K8SContainerStatusLastTerminatedReasonKey is the attribute Key conforming to
+ // the "k8s.container.status.last_terminated_reason" semantic conventions. It
+ // represents the last terminated reason of the Container.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "Evicted", "Error"
+ K8SContainerStatusLastTerminatedReasonKey = attribute.Key("k8s.container.status.last_terminated_reason")
+
+ // K8SContainerStatusReasonKey is the attribute Key conforming to the
+ // "k8s.container.status.reason" semantic conventions. It represents the reason
+ // for the container state. Corresponds to the `reason` field of the:
+ // [K8s ContainerStateWaiting] or [K8s ContainerStateTerminated].
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "ContainerCreating", "CrashLoopBackOff",
+ // "CreateContainerConfigError", "ErrImagePull", "ImagePullBackOff",
+ // "OOMKilled", "Completed", "Error", "ContainerCannotRun"
+ //
+ // [K8s ContainerStateWaiting]: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#containerstatewaiting-v1-core
+ // [K8s ContainerStateTerminated]: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#containerstateterminated-v1-core
+ K8SContainerStatusReasonKey = attribute.Key("k8s.container.status.reason")
+
+ // K8SContainerStatusStateKey is the attribute Key conforming to the
+ // "k8s.container.status.state" semantic conventions. It represents the state of
+ // the container. [K8s ContainerState].
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "terminated", "running", "waiting"
+ //
+ // [K8s ContainerState]: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#containerstate-v1-core
+ K8SContainerStatusStateKey = attribute.Key("k8s.container.status.state")
+
+ // K8SCronJobNameKey is the attribute Key conforming to the "k8s.cronjob.name"
+ // semantic conventions. It represents the name of the CronJob.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Release_Candidate
+ //
+ // Examples: "opentelemetry"
+ K8SCronJobNameKey = attribute.Key("k8s.cronjob.name")
+
+ // K8SCronJobUIDKey is the attribute Key conforming to the "k8s.cronjob.uid"
+ // semantic conventions. It represents the UID of the CronJob.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Release_Candidate
+ //
+ // Examples: "275ecb36-5aa8-4c2a-9c47-d8bb681b9aff"
+ K8SCronJobUIDKey = attribute.Key("k8s.cronjob.uid")
+
+ // K8SDaemonSetNameKey is the attribute Key conforming to the
+ // "k8s.daemonset.name" semantic conventions. It represents the name of the
+ // DaemonSet.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Release_Candidate
+ //
+ // Examples: "opentelemetry"
+ K8SDaemonSetNameKey = attribute.Key("k8s.daemonset.name")
+
+ // K8SDaemonSetUIDKey is the attribute Key conforming to the "k8s.daemonset.uid"
+ // semantic conventions. It represents the UID of the DaemonSet.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Release_Candidate
+ //
+ // Examples: "275ecb36-5aa8-4c2a-9c47-d8bb681b9aff"
+ K8SDaemonSetUIDKey = attribute.Key("k8s.daemonset.uid")
+
+ // K8SDeploymentNameKey is the attribute Key conforming to the
+ // "k8s.deployment.name" semantic conventions. It represents the name of the
+ // Deployment.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Release_Candidate
+ //
+ // Examples: "opentelemetry"
+ K8SDeploymentNameKey = attribute.Key("k8s.deployment.name")
+
+ // K8SDeploymentUIDKey is the attribute Key conforming to the
+ // "k8s.deployment.uid" semantic conventions. It represents the UID of the
+ // Deployment.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Release_Candidate
+ //
+ // Examples: "275ecb36-5aa8-4c2a-9c47-d8bb681b9aff"
+ K8SDeploymentUIDKey = attribute.Key("k8s.deployment.uid")
+
+ // K8SHPAMetricTypeKey is the attribute Key conforming to the
+ // "k8s.hpa.metric.type" semantic conventions. It represents the type of metric
+ // source for the horizontal pod autoscaler.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "Resource", "ContainerResource"
+ // Note: This attribute reflects the `type` field of spec.metrics[] in the HPA.
+ K8SHPAMetricTypeKey = attribute.Key("k8s.hpa.metric.type")
+
+ // K8SHPANameKey is the attribute Key conforming to the "k8s.hpa.name" semantic
+ // conventions. It represents the name of the horizontal pod autoscaler.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "opentelemetry"
+ K8SHPANameKey = attribute.Key("k8s.hpa.name")
+
+ // K8SHPAScaletargetrefAPIVersionKey is the attribute Key conforming to the
+ // "k8s.hpa.scaletargetref.api_version" semantic conventions. It represents the
+ // API version of the target resource to scale for the HorizontalPodAutoscaler.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "apps/v1", "autoscaling/v2"
+ // Note: This maps to the `apiVersion` field in the `scaleTargetRef` of the HPA
+ // spec.
+ K8SHPAScaletargetrefAPIVersionKey = attribute.Key("k8s.hpa.scaletargetref.api_version")
+
+ // K8SHPAScaletargetrefKindKey is the attribute Key conforming to the
+ // "k8s.hpa.scaletargetref.kind" semantic conventions. It represents the kind of
+ // the target resource to scale for the HorizontalPodAutoscaler.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "Deployment", "StatefulSet"
+ // Note: This maps to the `kind` field in the `scaleTargetRef` of the HPA spec.
+ K8SHPAScaletargetrefKindKey = attribute.Key("k8s.hpa.scaletargetref.kind")
+
+ // K8SHPAScaletargetrefNameKey is the attribute Key conforming to the
+ // "k8s.hpa.scaletargetref.name" semantic conventions. It represents the name of
+ // the target resource to scale for the HorizontalPodAutoscaler.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "my-deployment", "my-statefulset"
+ // Note: This maps to the `name` field in the `scaleTargetRef` of the HPA spec.
+ K8SHPAScaletargetrefNameKey = attribute.Key("k8s.hpa.scaletargetref.name")
+
+ // K8SHPAUIDKey is the attribute Key conforming to the "k8s.hpa.uid" semantic
+ // conventions. It represents the UID of the horizontal pod autoscaler.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "275ecb36-5aa8-4c2a-9c47-d8bb681b9aff"
+ K8SHPAUIDKey = attribute.Key("k8s.hpa.uid")
+
+ // K8SHugepageSizeKey is the attribute Key conforming to the "k8s.hugepage.size"
+ // semantic conventions. It represents the size (identifier) of the K8s huge
+ // page.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "2Mi"
+ K8SHugepageSizeKey = attribute.Key("k8s.hugepage.size")
+
+ // K8SJobNameKey is the attribute Key conforming to the "k8s.job.name" semantic
+ // conventions. It represents the name of the Job.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Release_Candidate
+ //
+ // Examples: "opentelemetry"
+ K8SJobNameKey = attribute.Key("k8s.job.name")
+
+ // K8SJobUIDKey is the attribute Key conforming to the "k8s.job.uid" semantic
+ // conventions. It represents the UID of the Job.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Release_Candidate
+ //
+ // Examples: "275ecb36-5aa8-4c2a-9c47-d8bb681b9aff"
+ K8SJobUIDKey = attribute.Key("k8s.job.uid")
+
+ // K8SNamespaceNameKey is the attribute Key conforming to the
+ // "k8s.namespace.name" semantic conventions. It represents the name of the
+ // namespace that the pod is running in.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Release_Candidate
+ //
+ // Examples: "default"
+ K8SNamespaceNameKey = attribute.Key("k8s.namespace.name")
+
+ // K8SNamespacePhaseKey is the attribute Key conforming to the
+ // "k8s.namespace.phase" semantic conventions. It represents the phase of the
+ // K8s namespace.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "active", "terminating"
+ // Note: This attribute aligns with the `phase` field of the
+ // [K8s NamespaceStatus]
+ //
+ // [K8s NamespaceStatus]: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#namespacestatus-v1-core
+ K8SNamespacePhaseKey = attribute.Key("k8s.namespace.phase")
+
+ // K8SNodeConditionStatusKey is the attribute Key conforming to the
+ // "k8s.node.condition.status" semantic conventions. It represents the status of
+ // the condition, one of True, False, Unknown.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "true", "false", "unknown"
+ // Note: This attribute aligns with the `status` field of the
+ // [NodeCondition]
+ //
+ // [NodeCondition]: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#nodecondition-v1-core
+ K8SNodeConditionStatusKey = attribute.Key("k8s.node.condition.status")
+
+ // K8SNodeConditionTypeKey is the attribute Key conforming to the
+ // "k8s.node.condition.type" semantic conventions. It represents the condition
+ // type of a K8s Node.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "Ready", "DiskPressure"
+ // Note: K8s Node conditions as described
+ // by [K8s documentation].
+ //
+ // This attribute aligns with the `type` field of the
+ // [NodeCondition]
+ //
+ // The set of possible values is not limited to those listed here. Managed
+ // Kubernetes environments,
+ // or custom controllers MAY introduce additional node condition types.
+ // When this occurs, the exact value as reported by the Kubernetes API SHOULD be
+ // used.
+ //
+ // [K8s documentation]: https://v1-32.docs.kubernetes.io/docs/reference/node/node-status/#condition
+ // [NodeCondition]: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#nodecondition-v1-core
+ K8SNodeConditionTypeKey = attribute.Key("k8s.node.condition.type")
+
+ // K8SNodeNameKey is the attribute Key conforming to the "k8s.node.name"
+ // semantic conventions. It represents the name of the Node.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Release_Candidate
+ //
+ // Examples: "node-1"
+ K8SNodeNameKey = attribute.Key("k8s.node.name")
+
+ // K8SNodeSystemContainerNameKey is the attribute Key conforming to the
+ // "k8s.node.system_container.name" semantic conventions. It represents the name
+ // of the system container running on the K8s Node.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "kubelet", "runtime", "pods", "misc"
+ K8SNodeSystemContainerNameKey = attribute.Key("k8s.node.system_container.name")
+
+ // K8SNodeUIDKey is the attribute Key conforming to the "k8s.node.uid" semantic
+ // conventions. It represents the UID of the Node.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Release_Candidate
+ //
+ // Examples: "1eb3a0c6-0477-4080-a9cb-0cb7db65c6a2"
+ K8SNodeUIDKey = attribute.Key("k8s.node.uid")
+
+ // K8SPersistentvolumeNameKey is the attribute Key conforming to the
+ // "k8s.persistentvolume.name" semantic conventions. It represents the name of
+ // the PersistentVolume.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "pv-data-01"
+ K8SPersistentvolumeNameKey = attribute.Key("k8s.persistentvolume.name")
+
+ // K8SPersistentvolumeReclaimPolicyKey is the attribute Key conforming to the
+ // "k8s.persistentvolume.reclaim_policy" semantic conventions. It represents the
+ // reclaim policy of the PersistentVolume.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "Delete", "Retain", "Recycle"
+ // Note: This attribute aligns with the `persistentVolumeReclaimPolicy` field of
+ // the
+ // [K8s PersistentVolumeSpec].
+ //
+ // [K8s PersistentVolumeSpec]: https://kubernetes.io/docs/reference/kubernetes-api/config-and-storage-resources/persistent-volume-v1/#PersistentVolumeSpec
+ K8SPersistentvolumeReclaimPolicyKey = attribute.Key("k8s.persistentvolume.reclaim_policy")
+
+ // K8SPersistentvolumeStatusPhaseKey is the attribute Key conforming to the
+ // "k8s.persistentvolume.status.phase" semantic conventions. It represents the
+ // phase of the PersistentVolume.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "Pending", "Available", "Bound", "Released", "Failed"
+ // Note: This attribute aligns with the `phase` field of the
+ // [K8s PersistentVolumeStatus].
+ //
+ // [K8s PersistentVolumeStatus]: https://kubernetes.io/docs/reference/kubernetes-api/config-and-storage-resources/persistent-volume-v1/#PersistentVolumeStatus
+ K8SPersistentvolumeStatusPhaseKey = attribute.Key("k8s.persistentvolume.status.phase")
+
+ // K8SPersistentvolumeUIDKey is the attribute Key conforming to the
+ // "k8s.persistentvolume.uid" semantic conventions. It represents the UID of the
+ // PersistentVolume.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "275ecb36-5aa8-4c2a-9c47-d8bb681b9aff"
+ K8SPersistentvolumeUIDKey = attribute.Key("k8s.persistentvolume.uid")
+
+ // K8SPersistentvolumeclaimNameKey is the attribute Key conforming to the
+ // "k8s.persistentvolumeclaim.name" semantic conventions. It represents the name
+ // of the PersistentVolumeClaim.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "pvc-data-01"
+ K8SPersistentvolumeclaimNameKey = attribute.Key("k8s.persistentvolumeclaim.name")
+
+ // K8SPersistentvolumeclaimStatusPhaseKey is the attribute Key conforming to the
+ // "k8s.persistentvolumeclaim.status.phase" semantic conventions. It represents
+ // the phase of the PersistentVolumeClaim.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "Pending", "Bound", "Lost"
+ // Note: This attribute aligns with the `phase` field of the
+ // [K8s PersistentVolumeClaimStatus].
+ //
+ // [K8s PersistentVolumeClaimStatus]: https://kubernetes.io/docs/reference/kubernetes-api/config-and-storage-resources/persistent-volume-claim-v1/#PersistentVolumeClaimStatus
+ K8SPersistentvolumeclaimStatusPhaseKey = attribute.Key("k8s.persistentvolumeclaim.status.phase")
+
+ // K8SPersistentvolumeclaimUIDKey is the attribute Key conforming to the
+ // "k8s.persistentvolumeclaim.uid" semantic conventions. It represents the UID
+ // of the PersistentVolumeClaim.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "275ecb36-5aa8-4c2a-9c47-d8bb681b9aff"
+ K8SPersistentvolumeclaimUIDKey = attribute.Key("k8s.persistentvolumeclaim.uid")
+
+ // K8SPodHostnameKey is the attribute Key conforming to the "k8s.pod.hostname"
+ // semantic conventions. It represents the specifies the hostname of the Pod.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Release_Candidate
+ //
+ // Examples: "collector-gateway"
+ // Note: The K8s Pod spec has an optional hostname field, which can be used to
+ // specify a hostname.
+ // Refer to [K8s docs]
+ // for more information about this field.
+ //
+ // This attribute aligns with the `hostname` field of the
+ // [K8s PodSpec].
+ //
+ // [K8s docs]: https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/#pod-hostname-and-subdomain-field
+ // [K8s PodSpec]: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#podspec-v1-core
+ K8SPodHostnameKey = attribute.Key("k8s.pod.hostname")
+
+ // K8SPodIPKey is the attribute Key conforming to the "k8s.pod.ip" semantic
+ // conventions. It represents the IP address allocated to the Pod.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Release_Candidate
+ //
+ // Examples: "172.18.0.2"
+ // Note: This attribute aligns with the `podIP` field of the
+ // [K8s PodStatus].
+ //
+ // [K8s PodStatus]: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#podstatus-v1-core
+ K8SPodIPKey = attribute.Key("k8s.pod.ip")
+
+ // K8SPodNameKey is the attribute Key conforming to the "k8s.pod.name" semantic
+ // conventions. It represents the name of the Pod.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Release_Candidate
+ //
+ // Examples: "opentelemetry-pod-autoconf"
+ K8SPodNameKey = attribute.Key("k8s.pod.name")
+
+ // K8SPodStartTimeKey is the attribute Key conforming to the
+ // "k8s.pod.start_time" semantic conventions. It represents the start timestamp
+ // of the Pod.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Release_Candidate
+ //
+ // Examples: "2025-12-04T08:41:03Z"
+ // Note: Date and time at which the object was acknowledged by the Kubelet.
+ // This is before the Kubelet pulled the container image(s) for the pod.
+ //
+ // This attribute aligns with the `startTime` field of the
+ // [K8s PodStatus],
+ // in ISO 8601 (RFC 3339 compatible) format.
+ //
+ // [K8s PodStatus]: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#podstatus-v1-core
+ K8SPodStartTimeKey = attribute.Key("k8s.pod.start_time")
+
+ // K8SPodStatusPhaseKey is the attribute Key conforming to the
+ // "k8s.pod.status.phase" semantic conventions. It represents the phase for the
+ // pod. Corresponds to the `phase` field of the: [K8s PodStatus].
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "Pending", "Running"
+ //
+ // [K8s PodStatus]: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.33/#podstatus-v1-core
+ K8SPodStatusPhaseKey = attribute.Key("k8s.pod.status.phase")
+
+ // K8SPodStatusReasonKey is the attribute Key conforming to the
+ // "k8s.pod.status.reason" semantic conventions. It represents the reason for
+ // the pod state. Corresponds to the `reason` field of the: [K8s PodStatus].
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "Evicted", "NodeAffinity"
+ //
+ // [K8s PodStatus]: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.33/#podstatus-v1-core
+ K8SPodStatusReasonKey = attribute.Key("k8s.pod.status.reason")
+
+ // K8SPodUIDKey is the attribute Key conforming to the "k8s.pod.uid" semantic
+ // conventions. It represents the UID of the Pod.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Release_Candidate
+ //
+ // Examples: "275ecb36-5aa8-4c2a-9c47-d8bb681b9aff"
+ K8SPodUIDKey = attribute.Key("k8s.pod.uid")
+
+ // K8SReplicaSetNameKey is the attribute Key conforming to the
+ // "k8s.replicaset.name" semantic conventions. It represents the name of the
+ // ReplicaSet.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Release_Candidate
+ //
+ // Examples: "opentelemetry"
+ K8SReplicaSetNameKey = attribute.Key("k8s.replicaset.name")
+
+ // K8SReplicaSetUIDKey is the attribute Key conforming to the
+ // "k8s.replicaset.uid" semantic conventions. It represents the UID of the
+ // ReplicaSet.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Release_Candidate
+ //
+ // Examples: "275ecb36-5aa8-4c2a-9c47-d8bb681b9aff"
+ K8SReplicaSetUIDKey = attribute.Key("k8s.replicaset.uid")
+
+ // K8SReplicationControllerNameKey is the attribute Key conforming to the
+ // "k8s.replicationcontroller.name" semantic conventions. It represents the name
+ // of the replication controller.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "opentelemetry"
+ K8SReplicationControllerNameKey = attribute.Key("k8s.replicationcontroller.name")
+
+ // K8SReplicationControllerUIDKey is the attribute Key conforming to the
+ // "k8s.replicationcontroller.uid" semantic conventions. It represents the UID
+ // of the replication controller.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "275ecb36-5aa8-4c2a-9c47-d8bb681b9aff"
+ K8SReplicationControllerUIDKey = attribute.Key("k8s.replicationcontroller.uid")
+
+ // K8SResourceQuotaNameKey is the attribute Key conforming to the
+ // "k8s.resourcequota.name" semantic conventions. It represents the name of the
+ // resource quota.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "opentelemetry"
+ K8SResourceQuotaNameKey = attribute.Key("k8s.resourcequota.name")
+
+ // K8SResourceQuotaResourceNameKey is the attribute Key conforming to the
+ // "k8s.resourcequota.resource_name" semantic conventions. It represents the
+ // name of the K8s resource a resource quota defines.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "count/replicationcontrollers"
+ // Note: The value for this attribute can be either the full
+ // `count/[.]` string (e.g., count/deployments.apps,
+ // count/pods), or, for certain core Kubernetes resources, just the resource
+ // name (e.g., pods, services, configmaps). Both forms are supported by
+ // Kubernetes for object count quotas. See
+ // [Kubernetes Resource Quotas documentation] for more details.
+ //
+ // [Kubernetes Resource Quotas documentation]: https://kubernetes.io/docs/concepts/policy/resource-quotas/#quota-on-object-count
+ K8SResourceQuotaResourceNameKey = attribute.Key("k8s.resourcequota.resource_name")
+
+ // K8SResourceQuotaUIDKey is the attribute Key conforming to the
+ // "k8s.resourcequota.uid" semantic conventions. It represents the UID of the
+ // resource quota.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "275ecb36-5aa8-4c2a-9c47-d8bb681b9aff"
+ K8SResourceQuotaUIDKey = attribute.Key("k8s.resourcequota.uid")
+
+ // K8SServiceEndpointAddressTypeKey is the attribute Key conforming to the
+ // "k8s.service.endpoint.address_type" semantic conventions. It represents the
+ // address type of the service endpoint.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "IPv4", "IPv6"
+ // Note: The network address family or type of the endpoint.
+ // This attribute aligns with the `addressType` field of the
+ // [K8s EndpointSlice].
+ // It is used to differentiate metrics when a Service is backed by multiple
+ // address types
+ // (e.g., in dual-stack clusters).
+ //
+ // [K8s EndpointSlice]: https://kubernetes.io/docs/reference/kubernetes-api/service-resources/endpoint-slice-v1/
+ K8SServiceEndpointAddressTypeKey = attribute.Key("k8s.service.endpoint.address_type")
+
+ // K8SServiceEndpointConditionKey is the attribute Key conforming to the
+ // "k8s.service.endpoint.condition" semantic conventions. It represents the
+ // condition of the service endpoint.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "ready", "serving", "terminating"
+ // Note: The current operational condition of the service endpoint.
+ // An endpoint can have multiple conditions set at once (e.g., both `serving`
+ // and `terminating` during rollout).
+ // This attribute aligns with the condition fields in the [K8s EndpointSlice].
+ //
+ // [K8s EndpointSlice]: https://kubernetes.io/docs/reference/kubernetes-api/service-resources/endpoint-slice-v1/
+ K8SServiceEndpointConditionKey = attribute.Key("k8s.service.endpoint.condition")
+
+ // K8SServiceEndpointZoneKey is the attribute Key conforming to the
+ // "k8s.service.endpoint.zone" semantic conventions. It represents the zone of
+ // the service endpoint.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "us-east-1a", "us-west-2b", "zone-a", ""
+ // Note: The zone where the endpoint is located, typically corresponding to a
+ // failure domain.
+ // This attribute aligns with the `zone` field of endpoints in the
+ // [K8s EndpointSlice].
+ // It enables zone-aware monitoring of service endpoint distribution and
+ // supports
+ // features like [Topology Aware Routing].
+ //
+ // If the zone is not populated (e.g., nodes without the
+ // `topology.kubernetes.io/zone` label),
+ // the attribute value will be an empty string.
+ //
+ // [K8s EndpointSlice]: https://kubernetes.io/docs/reference/kubernetes-api/service-resources/endpoint-slice-v1/
+ // [Topology Aware Routing]: https://kubernetes.io/docs/concepts/services-networking/topology-aware-routing/
+ K8SServiceEndpointZoneKey = attribute.Key("k8s.service.endpoint.zone")
+
+ // K8SServiceNameKey is the attribute Key conforming to the "k8s.service.name"
+ // semantic conventions. It represents the name of the Service.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "my-service"
+ K8SServiceNameKey = attribute.Key("k8s.service.name")
+
+ // K8SServicePublishNotReadyAddressesKey is the attribute Key conforming to the
+ // "k8s.service.publish_not_ready_addresses" semantic conventions. It represents
+ // the whether the Service publishes not-ready endpoints.
+ //
+ // Type: boolean
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: true, false
+ // Note: Whether the Service is configured to publish endpoints before the pods
+ // are ready.
+ // This attribute is typically used to indicate that a Service (such as a
+ // headless
+ // Service for a StatefulSet) allows peer discovery before pods pass their
+ // readiness probes.
+ // It aligns with the `publishNotReadyAddresses` field of the
+ // [K8s ServiceSpec].
+ //
+ // [K8s ServiceSpec]: https://kubernetes.io/docs/reference/kubernetes-api/service-resources/service-v1/#ServiceSpec
+ K8SServicePublishNotReadyAddressesKey = attribute.Key("k8s.service.publish_not_ready_addresses")
+
+ // K8SServiceTrafficDistributionKey is the attribute Key conforming to the
+ // "k8s.service.traffic_distribution" semantic conventions. It represents the
+ // traffic distribution policy for the Service.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "PreferSameZone", "PreferSameNode"
+ // Note: Specifies how traffic is distributed to endpoints for this Service.
+ // This attribute aligns with the `trafficDistribution` field of the
+ // [K8s ServiceSpec].
+ // Known values include `PreferSameZone` (prefer endpoints in the same zone as
+ // the client) and
+ // `PreferSameNode` (prefer endpoints on the same node, fallback to same zone,
+ // then cluster-wide).
+ // If this field is not set on the Service, the attribute SHOULD NOT be emitted.
+ // When not set, Kubernetes distributes traffic evenly across all endpoints
+ // cluster-wide.
+ //
+ // [K8s ServiceSpec]: https://kubernetes.io/docs/reference/networking/virtual-ips/#traffic-distribution
+ K8SServiceTrafficDistributionKey = attribute.Key("k8s.service.traffic_distribution")
+
+ // K8SServiceTypeKey is the attribute Key conforming to the "k8s.service.type"
+ // semantic conventions. It represents the type of the Kubernetes Service.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "ClusterIP", "NodePort", "LoadBalancer"
+ // Note: This attribute aligns with the `type` field of the
+ // [K8s ServiceSpec].
+ //
+ // [K8s ServiceSpec]: https://kubernetes.io/docs/reference/kubernetes-api/service-resources/service-v1/#ServiceSpec
+ K8SServiceTypeKey = attribute.Key("k8s.service.type")
+
+ // K8SServiceUIDKey is the attribute Key conforming to the "k8s.service.uid"
+ // semantic conventions. It represents the UID of the Service.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "275ecb36-5aa8-4c2a-9c47-d8bb681b9aff"
+ K8SServiceUIDKey = attribute.Key("k8s.service.uid")
+
+ // K8SStatefulSetNameKey is the attribute Key conforming to the
+ // "k8s.statefulset.name" semantic conventions. It represents the name of the
+ // StatefulSet.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Release_Candidate
+ //
+ // Examples: "opentelemetry"
+ K8SStatefulSetNameKey = attribute.Key("k8s.statefulset.name")
+
+ // K8SStatefulSetUIDKey is the attribute Key conforming to the
+ // "k8s.statefulset.uid" semantic conventions. It represents the UID of the
+ // StatefulSet.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Release_Candidate
+ //
+ // Examples: "275ecb36-5aa8-4c2a-9c47-d8bb681b9aff"
+ K8SStatefulSetUIDKey = attribute.Key("k8s.statefulset.uid")
+
+ // K8SStorageclassNameKey is the attribute Key conforming to the
+ // "k8s.storageclass.name" semantic conventions. It represents the name of K8s
+ // [StorageClass] object.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "gold.storageclass.storage.k8s.io"
+ //
+ // [StorageClass]: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#storageclass-v1-storage-k8s-io
+ K8SStorageclassNameKey = attribute.Key("k8s.storageclass.name")
+
+ // K8SVolumeNameKey is the attribute Key conforming to the "k8s.volume.name"
+ // semantic conventions. It represents the name of the K8s volume.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "volume0"
+ K8SVolumeNameKey = attribute.Key("k8s.volume.name")
+
+ // K8SVolumeTypeKey is the attribute Key conforming to the "k8s.volume.type"
+ // semantic conventions. It represents the type of the K8s volume.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "emptyDir", "persistentVolumeClaim"
+ K8SVolumeTypeKey = attribute.Key("k8s.volume.type")
+)
+
+// K8SClusterName returns an attribute KeyValue conforming to the
+// "k8s.cluster.name" semantic conventions. It represents the name of the
+// cluster.
+func K8SClusterName(val string) attribute.KeyValue {
+ return K8SClusterNameKey.String(val)
+}
+
+// K8SClusterUID returns an attribute KeyValue conforming to the
+// "k8s.cluster.uid" semantic conventions. It represents a pseudo-ID for the
+// cluster, set to the UID of the `kube-system` namespace.
+func K8SClusterUID(val string) attribute.KeyValue {
+ return K8SClusterUIDKey.String(val)
+}
+
+// K8SContainerName returns an attribute KeyValue conforming to the
+// "k8s.container.name" semantic conventions. It represents the name of the
+// Container from Pod specification, must be unique within a Pod. Container
+// runtime usually uses different globally unique name (`container.name`).
+func K8SContainerName(val string) attribute.KeyValue {
+ return K8SContainerNameKey.String(val)
+}
+
+// K8SContainerRestartCount returns an attribute KeyValue conforming to the
+// "k8s.container.restart_count" semantic conventions. It represents the number
+// of times the container was restarted. This attribute can be used to identify a
+// particular container (running or stopped) within a container spec.
+func K8SContainerRestartCount(val int) attribute.KeyValue {
+ return K8SContainerRestartCountKey.Int(val)
+}
+
+// K8SContainerStatusLastTerminatedReason returns an attribute KeyValue
+// conforming to the "k8s.container.status.last_terminated_reason" semantic
+// conventions. It represents the last terminated reason of the Container.
+func K8SContainerStatusLastTerminatedReason(val string) attribute.KeyValue {
+ return K8SContainerStatusLastTerminatedReasonKey.String(val)
+}
+
+// K8SCronJobAnnotation returns an attribute KeyValue conforming to the
+// "k8s.cronjob.annotation" semantic conventions. It represents the cronjob
+// annotation placed on the CronJob, the `` being the annotation name, the
+// value being the annotation value.
+func K8SCronJobAnnotation(key string, val string) attribute.KeyValue {
+ return attribute.String("k8s.cronjob.annotation."+key, val)
+}
+
+// K8SCronJobLabel returns an attribute KeyValue conforming to the
+// "k8s.cronjob.label" semantic conventions. It represents the label placed on
+// the CronJob, the `` being the label name, the value being the label
+// value.
+func K8SCronJobLabel(key string, val string) attribute.KeyValue {
+ return attribute.String("k8s.cronjob.label."+key, val)
+}
+
+// K8SCronJobName returns an attribute KeyValue conforming to the
+// "k8s.cronjob.name" semantic conventions. It represents the name of the
+// CronJob.
+func K8SCronJobName(val string) attribute.KeyValue {
+ return K8SCronJobNameKey.String(val)
+}
+
+// K8SCronJobUID returns an attribute KeyValue conforming to the
+// "k8s.cronjob.uid" semantic conventions. It represents the UID of the CronJob.
+func K8SCronJobUID(val string) attribute.KeyValue {
+ return K8SCronJobUIDKey.String(val)
+}
+
+// K8SDaemonSetAnnotation returns an attribute KeyValue conforming to the
+// "k8s.daemonset.annotation" semantic conventions. It represents the annotation
+// placed on the DaemonSet, the `` being the annotation name, the value
+// being the annotation value, even if the value is empty.
+func K8SDaemonSetAnnotation(key string, val string) attribute.KeyValue {
+ return attribute.String("k8s.daemonset.annotation."+key, val)
+}
+
+// K8SDaemonSetLabel returns an attribute KeyValue conforming to the
+// "k8s.daemonset.label" semantic conventions. It represents the label placed on
+// the DaemonSet, the `` being the label name, the value being the label
+// value, even if the value is empty.
+func K8SDaemonSetLabel(key string, val string) attribute.KeyValue {
+ return attribute.String("k8s.daemonset.label."+key, val)
+}
+
+// K8SDaemonSetName returns an attribute KeyValue conforming to the
+// "k8s.daemonset.name" semantic conventions. It represents the name of the
+// DaemonSet.
+func K8SDaemonSetName(val string) attribute.KeyValue {
+ return K8SDaemonSetNameKey.String(val)
+}
+
+// K8SDaemonSetUID returns an attribute KeyValue conforming to the
+// "k8s.daemonset.uid" semantic conventions. It represents the UID of the
+// DaemonSet.
+func K8SDaemonSetUID(val string) attribute.KeyValue {
+ return K8SDaemonSetUIDKey.String(val)
+}
+
+// K8SDeploymentAnnotation returns an attribute KeyValue conforming to the
+// "k8s.deployment.annotation" semantic conventions. It represents the annotation
+// placed on the Deployment, the `` being the annotation name, the value
+// being the annotation value, even if the value is empty.
+func K8SDeploymentAnnotation(key string, val string) attribute.KeyValue {
+ return attribute.String("k8s.deployment.annotation."+key, val)
+}
+
+// K8SDeploymentLabel returns an attribute KeyValue conforming to the
+// "k8s.deployment.label" semantic conventions. It represents the label placed on
+// the Deployment, the `` being the label name, the value being the label
+// value, even if the value is empty.
+func K8SDeploymentLabel(key string, val string) attribute.KeyValue {
+ return attribute.String("k8s.deployment.label."+key, val)
+}
+
+// K8SDeploymentName returns an attribute KeyValue conforming to the
+// "k8s.deployment.name" semantic conventions. It represents the name of the
+// Deployment.
+func K8SDeploymentName(val string) attribute.KeyValue {
+ return K8SDeploymentNameKey.String(val)
+}
+
+// K8SDeploymentUID returns an attribute KeyValue conforming to the
+// "k8s.deployment.uid" semantic conventions. It represents the UID of the
+// Deployment.
+func K8SDeploymentUID(val string) attribute.KeyValue {
+ return K8SDeploymentUIDKey.String(val)
+}
+
+// K8SHPAMetricType returns an attribute KeyValue conforming to the
+// "k8s.hpa.metric.type" semantic conventions. It represents the type of metric
+// source for the horizontal pod autoscaler.
+func K8SHPAMetricType(val string) attribute.KeyValue {
+ return K8SHPAMetricTypeKey.String(val)
+}
+
+// K8SHPAName returns an attribute KeyValue conforming to the "k8s.hpa.name"
+// semantic conventions. It represents the name of the horizontal pod autoscaler.
+func K8SHPAName(val string) attribute.KeyValue {
+ return K8SHPANameKey.String(val)
+}
+
+// K8SHPAScaletargetrefAPIVersion returns an attribute KeyValue conforming to the
+// "k8s.hpa.scaletargetref.api_version" semantic conventions. It represents the
+// API version of the target resource to scale for the HorizontalPodAutoscaler.
+func K8SHPAScaletargetrefAPIVersion(val string) attribute.KeyValue {
+ return K8SHPAScaletargetrefAPIVersionKey.String(val)
+}
+
+// K8SHPAScaletargetrefKind returns an attribute KeyValue conforming to the
+// "k8s.hpa.scaletargetref.kind" semantic conventions. It represents the kind of
+// the target resource to scale for the HorizontalPodAutoscaler.
+func K8SHPAScaletargetrefKind(val string) attribute.KeyValue {
+ return K8SHPAScaletargetrefKindKey.String(val)
+}
+
+// K8SHPAScaletargetrefName returns an attribute KeyValue conforming to the
+// "k8s.hpa.scaletargetref.name" semantic conventions. It represents the name of
+// the target resource to scale for the HorizontalPodAutoscaler.
+func K8SHPAScaletargetrefName(val string) attribute.KeyValue {
+ return K8SHPAScaletargetrefNameKey.String(val)
+}
+
+// K8SHPAUID returns an attribute KeyValue conforming to the "k8s.hpa.uid"
+// semantic conventions. It represents the UID of the horizontal pod autoscaler.
+func K8SHPAUID(val string) attribute.KeyValue {
+ return K8SHPAUIDKey.String(val)
+}
+
+// K8SHugepageSize returns an attribute KeyValue conforming to the
+// "k8s.hugepage.size" semantic conventions. It represents the size (identifier)
+// of the K8s huge page.
+func K8SHugepageSize(val string) attribute.KeyValue {
+ return K8SHugepageSizeKey.String(val)
+}
+
+// K8SJobAnnotation returns an attribute KeyValue conforming to the
+// "k8s.job.annotation" semantic conventions. It represents the annotation placed
+// on the Job, the `` being the annotation name, the value being the
+// annotation value, even if the value is empty.
+func K8SJobAnnotation(key string, val string) attribute.KeyValue {
+ return attribute.String("k8s.job.annotation."+key, val)
+}
+
+// K8SJobLabel returns an attribute KeyValue conforming to the "k8s.job.label"
+// semantic conventions. It represents the label placed on the Job, the ``
+// being the label name, the value being the label value, even if the value is
+// empty.
+func K8SJobLabel(key string, val string) attribute.KeyValue {
+ return attribute.String("k8s.job.label."+key, val)
+}
+
+// K8SJobName returns an attribute KeyValue conforming to the "k8s.job.name"
+// semantic conventions. It represents the name of the Job.
+func K8SJobName(val string) attribute.KeyValue {
+ return K8SJobNameKey.String(val)
+}
+
+// K8SJobUID returns an attribute KeyValue conforming to the "k8s.job.uid"
+// semantic conventions. It represents the UID of the Job.
+func K8SJobUID(val string) attribute.KeyValue {
+ return K8SJobUIDKey.String(val)
+}
+
+// K8SNamespaceAnnotation returns an attribute KeyValue conforming to the
+// "k8s.namespace.annotation" semantic conventions. It represents the annotation
+// placed on the Namespace, the `` being the annotation name, the value
+// being the annotation value, even if the value is empty.
+func K8SNamespaceAnnotation(key string, val string) attribute.KeyValue {
+ return attribute.String("k8s.namespace.annotation."+key, val)
+}
+
+// K8SNamespaceLabel returns an attribute KeyValue conforming to the
+// "k8s.namespace.label" semantic conventions. It represents the label placed on
+// the Namespace, the `` being the label name, the value being the label
+// value, even if the value is empty.
+func K8SNamespaceLabel(key string, val string) attribute.KeyValue {
+ return attribute.String("k8s.namespace.label."+key, val)
+}
+
+// K8SNamespaceName returns an attribute KeyValue conforming to the
+// "k8s.namespace.name" semantic conventions. It represents the name of the
+// namespace that the pod is running in.
+func K8SNamespaceName(val string) attribute.KeyValue {
+ return K8SNamespaceNameKey.String(val)
+}
+
+// K8SNodeAnnotation returns an attribute KeyValue conforming to the
+// "k8s.node.annotation" semantic conventions. It represents the annotation
+// placed on the Node, the `` being the annotation name, the value being the
+// annotation value, even if the value is empty.
+func K8SNodeAnnotation(key string, val string) attribute.KeyValue {
+ return attribute.String("k8s.node.annotation."+key, val)
+}
+
+// K8SNodeLabel returns an attribute KeyValue conforming to the "k8s.node.label"
+// semantic conventions. It represents the label placed on the Node, the ``
+// being the label name, the value being the label value, even if the value is
+// empty.
+func K8SNodeLabel(key string, val string) attribute.KeyValue {
+ return attribute.String("k8s.node.label."+key, val)
+}
+
+// K8SNodeName returns an attribute KeyValue conforming to the "k8s.node.name"
+// semantic conventions. It represents the name of the Node.
+func K8SNodeName(val string) attribute.KeyValue {
+ return K8SNodeNameKey.String(val)
+}
+
+// K8SNodeSystemContainerName returns an attribute KeyValue conforming to the
+// "k8s.node.system_container.name" semantic conventions. It represents the name
+// of the system container running on the K8s Node.
+func K8SNodeSystemContainerName(val string) attribute.KeyValue {
+ return K8SNodeSystemContainerNameKey.String(val)
+}
+
+// K8SNodeUID returns an attribute KeyValue conforming to the "k8s.node.uid"
+// semantic conventions. It represents the UID of the Node.
+func K8SNodeUID(val string) attribute.KeyValue {
+ return K8SNodeUIDKey.String(val)
+}
+
+// K8SPersistentvolumeAnnotation returns an attribute KeyValue conforming to the
+// "k8s.persistentvolume.annotation" semantic conventions. It represents the
+// annotation placed on the PersistentVolume, the `` being the annotation
+// name, the value being the annotation value, even if the value is empty.
+func K8SPersistentvolumeAnnotation(key string, val string) attribute.KeyValue {
+ return attribute.String("k8s.persistentvolume.annotation."+key, val)
+}
+
+// K8SPersistentvolumeLabel returns an attribute KeyValue conforming to the
+// "k8s.persistentvolume.label" semantic conventions. It represents the label
+// placed on the PersistentVolume, the `` being the label name, the value
+// being the label value, even if the value is empty.
+func K8SPersistentvolumeLabel(key string, val string) attribute.KeyValue {
+ return attribute.String("k8s.persistentvolume.label."+key, val)
+}
+
+// K8SPersistentvolumeName returns an attribute KeyValue conforming to the
+// "k8s.persistentvolume.name" semantic conventions. It represents the name of
+// the PersistentVolume.
+func K8SPersistentvolumeName(val string) attribute.KeyValue {
+ return K8SPersistentvolumeNameKey.String(val)
+}
+
+// K8SPersistentvolumeUID returns an attribute KeyValue conforming to the
+// "k8s.persistentvolume.uid" semantic conventions. It represents the UID of the
+// PersistentVolume.
+func K8SPersistentvolumeUID(val string) attribute.KeyValue {
+ return K8SPersistentvolumeUIDKey.String(val)
+}
+
+// K8SPersistentvolumeclaimAnnotation returns an attribute KeyValue conforming to
+// the "k8s.persistentvolumeclaim.annotation" semantic conventions. It represents
+// the annotation placed on the PersistentVolumeClaim, the `` being the
+// annotation name, the value being the annotation value, even if the value is
+// empty.
+func K8SPersistentvolumeclaimAnnotation(key string, val string) attribute.KeyValue {
+ return attribute.String("k8s.persistentvolumeclaim.annotation."+key, val)
+}
+
+// K8SPersistentvolumeclaimLabel returns an attribute KeyValue conforming to the
+// "k8s.persistentvolumeclaim.label" semantic conventions. It represents the
+// label placed on the PersistentVolumeClaim, the `` being the label name,
+// the value being the label value, even if the value is empty.
+func K8SPersistentvolumeclaimLabel(key string, val string) attribute.KeyValue {
+ return attribute.String("k8s.persistentvolumeclaim.label."+key, val)
+}
+
+// K8SPersistentvolumeclaimName returns an attribute KeyValue conforming to the
+// "k8s.persistentvolumeclaim.name" semantic conventions. It represents the name
+// of the PersistentVolumeClaim.
+func K8SPersistentvolumeclaimName(val string) attribute.KeyValue {
+ return K8SPersistentvolumeclaimNameKey.String(val)
+}
+
+// K8SPersistentvolumeclaimUID returns an attribute KeyValue conforming to the
+// "k8s.persistentvolumeclaim.uid" semantic conventions. It represents the UID of
+// the PersistentVolumeClaim.
+func K8SPersistentvolumeclaimUID(val string) attribute.KeyValue {
+ return K8SPersistentvolumeclaimUIDKey.String(val)
+}
+
+// K8SPodAnnotation returns an attribute KeyValue conforming to the
+// "k8s.pod.annotation" semantic conventions. It represents the annotation placed
+// on the Pod, the `` being the annotation name, the value being the
+// annotation value.
+func K8SPodAnnotation(key string, val string) attribute.KeyValue {
+ return attribute.String("k8s.pod.annotation."+key, val)
+}
+
+// K8SPodHostname returns an attribute KeyValue conforming to the
+// "k8s.pod.hostname" semantic conventions. It represents the specifies the
+// hostname of the Pod.
+func K8SPodHostname(val string) attribute.KeyValue {
+ return K8SPodHostnameKey.String(val)
+}
+
+// K8SPodIP returns an attribute KeyValue conforming to the "k8s.pod.ip" semantic
+// conventions. It represents the IP address allocated to the Pod.
+func K8SPodIP(val string) attribute.KeyValue {
+ return K8SPodIPKey.String(val)
+}
+
+// K8SPodLabel returns an attribute KeyValue conforming to the "k8s.pod.label"
+// semantic conventions. It represents the label placed on the Pod, the ``
+// being the label name, the value being the label value.
+func K8SPodLabel(key string, val string) attribute.KeyValue {
+ return attribute.String("k8s.pod.label."+key, val)
+}
+
+// K8SPodName returns an attribute KeyValue conforming to the "k8s.pod.name"
+// semantic conventions. It represents the name of the Pod.
+func K8SPodName(val string) attribute.KeyValue {
+ return K8SPodNameKey.String(val)
+}
+
+// K8SPodStartTime returns an attribute KeyValue conforming to the
+// "k8s.pod.start_time" semantic conventions. It represents the start timestamp
+// of the Pod.
+func K8SPodStartTime(val string) attribute.KeyValue {
+ return K8SPodStartTimeKey.String(val)
+}
+
+// K8SPodUID returns an attribute KeyValue conforming to the "k8s.pod.uid"
+// semantic conventions. It represents the UID of the Pod.
+func K8SPodUID(val string) attribute.KeyValue {
+ return K8SPodUIDKey.String(val)
+}
+
+// K8SReplicaSetAnnotation returns an attribute KeyValue conforming to the
+// "k8s.replicaset.annotation" semantic conventions. It represents the annotation
+// placed on the ReplicaSet, the `` being the annotation name, the value
+// being the annotation value, even if the value is empty.
+func K8SReplicaSetAnnotation(key string, val string) attribute.KeyValue {
+ return attribute.String("k8s.replicaset.annotation."+key, val)
+}
+
+// K8SReplicaSetLabel returns an attribute KeyValue conforming to the
+// "k8s.replicaset.label" semantic conventions. It represents the label placed on
+// the ReplicaSet, the `` being the label name, the value being the label
+// value, even if the value is empty.
+func K8SReplicaSetLabel(key string, val string) attribute.KeyValue {
+ return attribute.String("k8s.replicaset.label."+key, val)
+}
+
+// K8SReplicaSetName returns an attribute KeyValue conforming to the
+// "k8s.replicaset.name" semantic conventions. It represents the name of the
+// ReplicaSet.
+func K8SReplicaSetName(val string) attribute.KeyValue {
+ return K8SReplicaSetNameKey.String(val)
+}
+
+// K8SReplicaSetUID returns an attribute KeyValue conforming to the
+// "k8s.replicaset.uid" semantic conventions. It represents the UID of the
+// ReplicaSet.
+func K8SReplicaSetUID(val string) attribute.KeyValue {
+ return K8SReplicaSetUIDKey.String(val)
+}
+
+// K8SReplicationControllerName returns an attribute KeyValue conforming to the
+// "k8s.replicationcontroller.name" semantic conventions. It represents the name
+// of the replication controller.
+func K8SReplicationControllerName(val string) attribute.KeyValue {
+ return K8SReplicationControllerNameKey.String(val)
+}
+
+// K8SReplicationControllerUID returns an attribute KeyValue conforming to the
+// "k8s.replicationcontroller.uid" semantic conventions. It represents the UID of
+// the replication controller.
+func K8SReplicationControllerUID(val string) attribute.KeyValue {
+ return K8SReplicationControllerUIDKey.String(val)
+}
+
+// K8SResourceQuotaName returns an attribute KeyValue conforming to the
+// "k8s.resourcequota.name" semantic conventions. It represents the name of the
+// resource quota.
+func K8SResourceQuotaName(val string) attribute.KeyValue {
+ return K8SResourceQuotaNameKey.String(val)
+}
+
+// K8SResourceQuotaResourceName returns an attribute KeyValue conforming to the
+// "k8s.resourcequota.resource_name" semantic conventions. It represents the name
+// of the K8s resource a resource quota defines.
+func K8SResourceQuotaResourceName(val string) attribute.KeyValue {
+ return K8SResourceQuotaResourceNameKey.String(val)
+}
+
+// K8SResourceQuotaUID returns an attribute KeyValue conforming to the
+// "k8s.resourcequota.uid" semantic conventions. It represents the UID of the
+// resource quota.
+func K8SResourceQuotaUID(val string) attribute.KeyValue {
+ return K8SResourceQuotaUIDKey.String(val)
+}
+
+// K8SServiceAnnotation returns an attribute KeyValue conforming to the
+// "k8s.service.annotation" semantic conventions. It represents the annotation
+// placed on the Service, the `` being the annotation name, the value being
+// the annotation value, even if the value is empty.
+func K8SServiceAnnotation(key string, val string) attribute.KeyValue {
+ return attribute.String("k8s.service.annotation."+key, val)
+}
+
+// K8SServiceEndpointZone returns an attribute KeyValue conforming to the
+// "k8s.service.endpoint.zone" semantic conventions. It represents the zone of
+// the service endpoint.
+func K8SServiceEndpointZone(val string) attribute.KeyValue {
+ return K8SServiceEndpointZoneKey.String(val)
+}
+
+// K8SServiceLabel returns an attribute KeyValue conforming to the
+// "k8s.service.label" semantic conventions. It represents the label placed on
+// the Service, the `` being the label name, the value being the label
+// value, even if the value is empty.
+func K8SServiceLabel(key string, val string) attribute.KeyValue {
+ return attribute.String("k8s.service.label."+key, val)
+}
+
+// K8SServiceName returns an attribute KeyValue conforming to the
+// "k8s.service.name" semantic conventions. It represents the name of the
+// Service.
+func K8SServiceName(val string) attribute.KeyValue {
+ return K8SServiceNameKey.String(val)
+}
+
+// K8SServicePublishNotReadyAddresses returns an attribute KeyValue conforming to
+// the "k8s.service.publish_not_ready_addresses" semantic conventions. It
+// represents the whether the Service publishes not-ready endpoints.
+func K8SServicePublishNotReadyAddresses(val bool) attribute.KeyValue {
+ return K8SServicePublishNotReadyAddressesKey.Bool(val)
+}
+
+// K8SServiceSelector returns an attribute KeyValue conforming to the
+// "k8s.service.selector" semantic conventions. It represents the selector
+// key-value pair placed on the Service, the `` being the selector key, the
+// value being the selector value.
+func K8SServiceSelector(key string, val string) attribute.KeyValue {
+ return attribute.String("k8s.service.selector."+key, val)
+}
+
+// K8SServiceTrafficDistribution returns an attribute KeyValue conforming to the
+// "k8s.service.traffic_distribution" semantic conventions. It represents the
+// traffic distribution policy for the Service.
+func K8SServiceTrafficDistribution(val string) attribute.KeyValue {
+ return K8SServiceTrafficDistributionKey.String(val)
+}
+
+// K8SServiceUID returns an attribute KeyValue conforming to the
+// "k8s.service.uid" semantic conventions. It represents the UID of the Service.
+func K8SServiceUID(val string) attribute.KeyValue {
+ return K8SServiceUIDKey.String(val)
+}
+
+// K8SStatefulSetAnnotation returns an attribute KeyValue conforming to the
+// "k8s.statefulset.annotation" semantic conventions. It represents the
+// annotation placed on the StatefulSet, the `` being the annotation name,
+// the value being the annotation value, even if the value is empty.
+func K8SStatefulSetAnnotation(key string, val string) attribute.KeyValue {
+ return attribute.String("k8s.statefulset.annotation."+key, val)
+}
+
+// K8SStatefulSetLabel returns an attribute KeyValue conforming to the
+// "k8s.statefulset.label" semantic conventions. It represents the label placed
+// on the StatefulSet, the `` being the label name, the value being the
+// label value, even if the value is empty.
+func K8SStatefulSetLabel(key string, val string) attribute.KeyValue {
+ return attribute.String("k8s.statefulset.label."+key, val)
+}
+
+// K8SStatefulSetName returns an attribute KeyValue conforming to the
+// "k8s.statefulset.name" semantic conventions. It represents the name of the
+// StatefulSet.
+func K8SStatefulSetName(val string) attribute.KeyValue {
+ return K8SStatefulSetNameKey.String(val)
+}
+
+// K8SStatefulSetUID returns an attribute KeyValue conforming to the
+// "k8s.statefulset.uid" semantic conventions. It represents the UID of the
+// StatefulSet.
+func K8SStatefulSetUID(val string) attribute.KeyValue {
+ return K8SStatefulSetUIDKey.String(val)
+}
+
+// K8SStorageclassName returns an attribute KeyValue conforming to the
+// "k8s.storageclass.name" semantic conventions. It represents the name of K8s
+// [StorageClass] object.
+//
+// [StorageClass]: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#storageclass-v1-storage-k8s-io
+func K8SStorageclassName(val string) attribute.KeyValue {
+ return K8SStorageclassNameKey.String(val)
+}
+
+// K8SVolumeName returns an attribute KeyValue conforming to the
+// "k8s.volume.name" semantic conventions. It represents the name of the K8s
+// volume.
+func K8SVolumeName(val string) attribute.KeyValue {
+ return K8SVolumeNameKey.String(val)
+}
+
+// Enum values for k8s.container.status.reason
+var (
+ // The container is being created.
+ // Stability: development
+ K8SContainerStatusReasonContainerCreating = K8SContainerStatusReasonKey.String("ContainerCreating")
+ // The container is in a crash loop back off state.
+ // Stability: development
+ K8SContainerStatusReasonCrashLoopBackOff = K8SContainerStatusReasonKey.String("CrashLoopBackOff")
+ // There was an error creating the container configuration.
+ // Stability: development
+ K8SContainerStatusReasonCreateContainerConfigError = K8SContainerStatusReasonKey.String("CreateContainerConfigError")
+ // There was an error pulling the container image.
+ // Stability: development
+ K8SContainerStatusReasonErrImagePull = K8SContainerStatusReasonKey.String("ErrImagePull")
+ // The container image pull is in back off state.
+ // Stability: development
+ K8SContainerStatusReasonImagePullBackOff = K8SContainerStatusReasonKey.String("ImagePullBackOff")
+ // The container was killed due to out of memory.
+ // Stability: development
+ K8SContainerStatusReasonOomKilled = K8SContainerStatusReasonKey.String("OOMKilled")
+ // The container has completed execution.
+ // Stability: development
+ K8SContainerStatusReasonCompleted = K8SContainerStatusReasonKey.String("Completed")
+ // There was an error with the container.
+ // Stability: development
+ K8SContainerStatusReasonError = K8SContainerStatusReasonKey.String("Error")
+ // The container cannot run.
+ // Stability: development
+ K8SContainerStatusReasonContainerCannotRun = K8SContainerStatusReasonKey.String("ContainerCannotRun")
+)
+
+// Enum values for k8s.container.status.state
+var (
+ // The container has terminated.
+ // Stability: development
+ K8SContainerStatusStateTerminated = K8SContainerStatusStateKey.String("terminated")
+ // The container is running.
+ // Stability: development
+ K8SContainerStatusStateRunning = K8SContainerStatusStateKey.String("running")
+ // The container is waiting.
+ // Stability: development
+ K8SContainerStatusStateWaiting = K8SContainerStatusStateKey.String("waiting")
+)
+
+// Enum values for k8s.namespace.phase
+var (
+ // Active namespace phase as described by [K8s API]
+ // Stability: development
+ //
+ // [K8s API]: https://pkg.go.dev/k8s.io/api@v0.31.3/core/v1#NamespacePhase
+ K8SNamespacePhaseActive = K8SNamespacePhaseKey.String("active")
+ // Terminating namespace phase as described by [K8s API]
+ // Stability: development
+ //
+ // [K8s API]: https://pkg.go.dev/k8s.io/api@v0.31.3/core/v1#NamespacePhase
+ K8SNamespacePhaseTerminating = K8SNamespacePhaseKey.String("terminating")
+)
+
+// Enum values for k8s.node.condition.status
+var (
+ // condition_true
+ // Stability: development
+ K8SNodeConditionStatusConditionTrue = K8SNodeConditionStatusKey.String("true")
+ // condition_false
+ // Stability: development
+ K8SNodeConditionStatusConditionFalse = K8SNodeConditionStatusKey.String("false")
+ // condition_unknown
+ // Stability: development
+ K8SNodeConditionStatusConditionUnknown = K8SNodeConditionStatusKey.String("unknown")
+)
+
+// Enum values for k8s.node.condition.type
+var (
+ // The node is healthy and ready to accept pods
+ // Stability: development
+ K8SNodeConditionTypeReady = K8SNodeConditionTypeKey.String("Ready")
+ // Pressure exists on the disk size—that is, if the disk capacity is low
+ // Stability: development
+ K8SNodeConditionTypeDiskPressure = K8SNodeConditionTypeKey.String("DiskPressure")
+ // Pressure exists on the node memory—that is, if the node memory is low
+ // Stability: development
+ K8SNodeConditionTypeMemoryPressure = K8SNodeConditionTypeKey.String("MemoryPressure")
+ // Pressure exists on the processes—that is, if there are too many processes
+ // on the node
+ // Stability: development
+ K8SNodeConditionTypePIDPressure = K8SNodeConditionTypeKey.String("PIDPressure")
+ // The network for the node is not correctly configured
+ // Stability: development
+ K8SNodeConditionTypeNetworkUnavailable = K8SNodeConditionTypeKey.String("NetworkUnavailable")
+)
+
+// Enum values for k8s.persistentvolume.reclaim_policy
+var (
+ // The volume will be deleted when released from its claim.
+ // Stability: development
+ K8SPersistentvolumeReclaimPolicyDelete = K8SPersistentvolumeReclaimPolicyKey.String("Delete")
+ // The volume will be recycled (basic scrub) when released from its claim.
+ // Stability: development
+ K8SPersistentvolumeReclaimPolicyRecycle = K8SPersistentvolumeReclaimPolicyKey.String("Recycle")
+ // The volume will be retained when released from its claim.
+ // Stability: development
+ K8SPersistentvolumeReclaimPolicyRetain = K8SPersistentvolumeReclaimPolicyKey.String("Retain")
+)
+
+// Enum values for k8s.persistentvolume.status.phase
+var (
+ // The volume is available and not yet bound to a claim.
+ // Stability: development
+ K8SPersistentvolumeStatusPhaseAvailable = K8SPersistentvolumeStatusPhaseKey.String("Available")
+ // The volume is bound to a claim.
+ // Stability: development
+ K8SPersistentvolumeStatusPhaseBound = K8SPersistentvolumeStatusPhaseKey.String("Bound")
+ // The volume has failed its automatic reclamation.
+ // Stability: development
+ K8SPersistentvolumeStatusPhaseFailed = K8SPersistentvolumeStatusPhaseKey.String("Failed")
+ // The volume is being provisioned.
+ // Stability: development
+ K8SPersistentvolumeStatusPhasePending = K8SPersistentvolumeStatusPhaseKey.String("Pending")
+ // The claim has been deleted but the volume is not yet available.
+ // Stability: development
+ K8SPersistentvolumeStatusPhaseReleased = K8SPersistentvolumeStatusPhaseKey.String("Released")
+)
+
+// Enum values for k8s.persistentvolumeclaim.status.phase
+var (
+ // The claim is bound to a volume.
+ // Stability: development
+ K8SPersistentvolumeclaimStatusPhaseBound = K8SPersistentvolumeclaimStatusPhaseKey.String("Bound")
+ // The claim has lost its underlying volume (the volume does not exist anymore).
+ // Stability: development
+ K8SPersistentvolumeclaimStatusPhaseLost = K8SPersistentvolumeclaimStatusPhaseKey.String("Lost")
+ // The claim has not yet been bound to a volume.
+ // Stability: development
+ K8SPersistentvolumeclaimStatusPhasePending = K8SPersistentvolumeclaimStatusPhaseKey.String("Pending")
+)
+
+// Enum values for k8s.pod.status.phase
+var (
+ // The pod has been accepted by the system, but one or more of the containers
+ // has not been started. This includes time before being bound to a node, as
+ // well as time spent pulling images onto the host.
+ //
+ // Stability: development
+ K8SPodStatusPhasePending = K8SPodStatusPhaseKey.String("Pending")
+ // The pod has been bound to a node and all of the containers have been started.
+ // At least one container is still running or is in the process of being
+ // restarted.
+ //
+ // Stability: development
+ K8SPodStatusPhaseRunning = K8SPodStatusPhaseKey.String("Running")
+ // All containers in the pod have voluntarily terminated with a container exit
+ // code of 0, and the system is not going to restart any of these containers.
+ //
+ // Stability: development
+ K8SPodStatusPhaseSucceeded = K8SPodStatusPhaseKey.String("Succeeded")
+ // All containers in the pod have terminated, and at least one container has
+ // terminated in a failure (exited with a non-zero exit code or was stopped by
+ // the system).
+ //
+ // Stability: development
+ K8SPodStatusPhaseFailed = K8SPodStatusPhaseKey.String("Failed")
+ // For some reason the state of the pod could not be obtained, typically due to
+ // an error in communicating with the host of the pod.
+ //
+ // Stability: development
+ K8SPodStatusPhaseUnknown = K8SPodStatusPhaseKey.String("Unknown")
+)
+
+// Enum values for k8s.pod.status.reason
+var (
+ // The pod is evicted.
+ // Stability: development
+ K8SPodStatusReasonEvicted = K8SPodStatusReasonKey.String("Evicted")
+ // The pod is in a status because of its node affinity
+ // Stability: development
+ K8SPodStatusReasonNodeAffinity = K8SPodStatusReasonKey.String("NodeAffinity")
+ // The reason on a pod when its state cannot be confirmed as kubelet is
+ // unresponsive on the node it is (was) running.
+ //
+ // Stability: development
+ K8SPodStatusReasonNodeLost = K8SPodStatusReasonKey.String("NodeLost")
+ // The node is shutdown
+ // Stability: development
+ K8SPodStatusReasonShutdown = K8SPodStatusReasonKey.String("Shutdown")
+ // The pod was rejected admission to the node because of an error during
+ // admission that could not be categorized.
+ //
+ // Stability: development
+ K8SPodStatusReasonUnexpectedAdmissionError = K8SPodStatusReasonKey.String("UnexpectedAdmissionError")
+)
+
+// Enum values for k8s.service.endpoint.address_type
+var (
+ // IPv4 address type
+ // Stability: development
+ K8SServiceEndpointAddressTypeIPv4 = K8SServiceEndpointAddressTypeKey.String("IPv4")
+ // IPv6 address type
+ // Stability: development
+ K8SServiceEndpointAddressTypeIPv6 = K8SServiceEndpointAddressTypeKey.String("IPv6")
+ // FQDN address type
+ // Stability: development
+ K8SServiceEndpointAddressTypeFqdn = K8SServiceEndpointAddressTypeKey.String("FQDN")
+)
+
+// Enum values for k8s.service.endpoint.condition
+var (
+ // The endpoint is ready to receive new connections.
+ // Stability: development
+ K8SServiceEndpointConditionReady = K8SServiceEndpointConditionKey.String("ready")
+ // The endpoint is currently handling traffic.
+ // Stability: development
+ K8SServiceEndpointConditionServing = K8SServiceEndpointConditionKey.String("serving")
+ // The endpoint is in the process of shutting down.
+ // Stability: development
+ K8SServiceEndpointConditionTerminating = K8SServiceEndpointConditionKey.String("terminating")
+)
+
+// Enum values for k8s.service.type
+var (
+ // ClusterIP service type
+ // Stability: development
+ K8SServiceTypeClusterIP = K8SServiceTypeKey.String("ClusterIP")
+ // NodePort service type
+ // Stability: development
+ K8SServiceTypeNodePort = K8SServiceTypeKey.String("NodePort")
+ // LoadBalancer service type
+ // Stability: development
+ K8SServiceTypeLoadBalancer = K8SServiceTypeKey.String("LoadBalancer")
+ // ExternalName service type
+ // Stability: development
+ K8SServiceTypeExternalName = K8SServiceTypeKey.String("ExternalName")
+)
+
+// Enum values for k8s.volume.type
+var (
+ // A [persistentVolumeClaim] volume
+ // Stability: development
+ //
+ // [persistentVolumeClaim]: https://v1-30.docs.kubernetes.io/docs/concepts/storage/volumes/#persistentvolumeclaim
+ K8SVolumeTypePersistentVolumeClaim = K8SVolumeTypeKey.String("persistentVolumeClaim")
+ // A [configMap] volume
+ // Stability: development
+ //
+ // [configMap]: https://v1-30.docs.kubernetes.io/docs/concepts/storage/volumes/#configmap
+ K8SVolumeTypeConfigMap = K8SVolumeTypeKey.String("configMap")
+ // A [downwardAPI] volume
+ // Stability: development
+ //
+ // [downwardAPI]: https://v1-30.docs.kubernetes.io/docs/concepts/storage/volumes/#downwardapi
+ K8SVolumeTypeDownwardAPI = K8SVolumeTypeKey.String("downwardAPI")
+ // An [emptyDir] volume
+ // Stability: development
+ //
+ // [emptyDir]: https://v1-30.docs.kubernetes.io/docs/concepts/storage/volumes/#emptydir
+ K8SVolumeTypeEmptyDir = K8SVolumeTypeKey.String("emptyDir")
+ // A [secret] volume
+ // Stability: development
+ //
+ // [secret]: https://v1-30.docs.kubernetes.io/docs/concepts/storage/volumes/#secret
+ K8SVolumeTypeSecret = K8SVolumeTypeKey.String("secret")
+ // A [local] volume
+ // Stability: development
+ //
+ // [local]: https://v1-30.docs.kubernetes.io/docs/concepts/storage/volumes/#local
+ K8SVolumeTypeLocal = K8SVolumeTypeKey.String("local")
+)
+
+// Namespace: log
+const (
+ // LogFileNameKey is the attribute Key conforming to the "log.file.name"
+ // semantic conventions. It represents the basename of the file.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "audit.log"
+ LogFileNameKey = attribute.Key("log.file.name")
+
+ // LogFileNameResolvedKey is the attribute Key conforming to the
+ // "log.file.name_resolved" semantic conventions. It represents the basename of
+ // the file, with symlinks resolved.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "uuid.log"
+ LogFileNameResolvedKey = attribute.Key("log.file.name_resolved")
+
+ // LogFilePathKey is the attribute Key conforming to the "log.file.path"
+ // semantic conventions. It represents the full path to the file.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "/var/log/mysql/audit.log"
+ LogFilePathKey = attribute.Key("log.file.path")
+
+ // LogFilePathResolvedKey is the attribute Key conforming to the
+ // "log.file.path_resolved" semantic conventions. It represents the full path to
+ // the file, with symlinks resolved.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "/var/lib/docker/uuid.log"
+ LogFilePathResolvedKey = attribute.Key("log.file.path_resolved")
+
+ // LogIostreamKey is the attribute Key conforming to the "log.iostream" semantic
+ // conventions. It represents the stream associated with the log. See below for
+ // a list of well-known values.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ LogIostreamKey = attribute.Key("log.iostream")
+
+ // LogRecordOriginalKey is the attribute Key conforming to the
+ // "log.record.original" semantic conventions. It represents the complete
+ // original Log Record.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "77 <86>1 2015-08-06T21:58:59.694Z 192.168.2.133 inactive - - -
+ // Something happened", "[INFO] 8/3/24 12:34:56 Something happened"
+ // Note: This value MAY be added when processing a Log Record which was
+ // originally transmitted as a string or equivalent data type AND the Body field
+ // of the Log Record does not contain the same value. (e.g. a syslog or a log
+ // record read from a file.)
+ LogRecordOriginalKey = attribute.Key("log.record.original")
+
+ // LogRecordUIDKey is the attribute Key conforming to the "log.record.uid"
+ // semantic conventions. It represents a unique identifier for the Log Record.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "01ARZ3NDEKTSV4RRFFQ69G5FAV"
+ // Note: If an id is provided, other log records with the same id will be
+ // considered duplicates and can be removed safely. This means, that two
+ // distinguishable log records MUST have different values.
+ // The id MAY be an
+ // [Universally Unique Lexicographically Sortable Identifier (ULID)], but other
+ // identifiers (e.g. UUID) may be used as needed.
+ //
+ // [Universally Unique Lexicographically Sortable Identifier (ULID)]: https://github.com/ulid/spec
+ LogRecordUIDKey = attribute.Key("log.record.uid")
+)
+
+// LogFileName returns an attribute KeyValue conforming to the "log.file.name"
+// semantic conventions. It represents the basename of the file.
+func LogFileName(val string) attribute.KeyValue {
+ return LogFileNameKey.String(val)
+}
+
+// LogFileNameResolved returns an attribute KeyValue conforming to the
+// "log.file.name_resolved" semantic conventions. It represents the basename of
+// the file, with symlinks resolved.
+func LogFileNameResolved(val string) attribute.KeyValue {
+ return LogFileNameResolvedKey.String(val)
+}
+
+// LogFilePath returns an attribute KeyValue conforming to the "log.file.path"
+// semantic conventions. It represents the full path to the file.
+func LogFilePath(val string) attribute.KeyValue {
+ return LogFilePathKey.String(val)
+}
+
+// LogFilePathResolved returns an attribute KeyValue conforming to the
+// "log.file.path_resolved" semantic conventions. It represents the full path to
+// the file, with symlinks resolved.
+func LogFilePathResolved(val string) attribute.KeyValue {
+ return LogFilePathResolvedKey.String(val)
+}
+
+// LogRecordOriginal returns an attribute KeyValue conforming to the
+// "log.record.original" semantic conventions. It represents the complete
+// original Log Record.
+func LogRecordOriginal(val string) attribute.KeyValue {
+ return LogRecordOriginalKey.String(val)
+}
+
+// LogRecordUID returns an attribute KeyValue conforming to the "log.record.uid"
+// semantic conventions. It represents a unique identifier for the Log Record.
+func LogRecordUID(val string) attribute.KeyValue {
+ return LogRecordUIDKey.String(val)
+}
+
+// Enum values for log.iostream
+var (
+ // Logs from stdout stream
+ // Stability: development
+ LogIostreamStdout = LogIostreamKey.String("stdout")
+ // Events from stderr stream
+ // Stability: development
+ LogIostreamStderr = LogIostreamKey.String("stderr")
+)
+
+// Namespace: mainframe
+const (
+ // MainframeLparNameKey is the attribute Key conforming to the
+ // "mainframe.lpar.name" semantic conventions. It represents the name of the
+ // logical partition that hosts a systems with a mainframe operating system.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "LPAR01"
+ MainframeLparNameKey = attribute.Key("mainframe.lpar.name")
+)
+
+// MainframeLparName returns an attribute KeyValue conforming to the
+// "mainframe.lpar.name" semantic conventions. It represents the name of the
+// logical partition that hosts a systems with a mainframe operating system.
+func MainframeLparName(val string) attribute.KeyValue {
+ return MainframeLparNameKey.String(val)
+}
+
+// Namespace: mcp
+const (
+ // McpMethodNameKey is the attribute Key conforming to the "mcp.method.name"
+ // semantic conventions. It represents the name of the request or notification
+ // method.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ McpMethodNameKey = attribute.Key("mcp.method.name")
+
+ // McpProtocolVersionKey is the attribute Key conforming to the
+ // "mcp.protocol.version" semantic conventions. It represents the [version] of
+ // the Model Context Protocol used.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "2025-06-18"
+ //
+ // [version]: https://modelcontextprotocol.io/specification/versioning
+ McpProtocolVersionKey = attribute.Key("mcp.protocol.version")
+
+ // McpResourceURIKey is the attribute Key conforming to the "mcp.resource.uri"
+ // semantic conventions. It represents the value of the resource uri.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "postgres://database/customers/schema",
+ // "file:///home/user/documents/report.pdf"
+ // Note: This is a URI of the resource provided in the following requests or
+ // notifications: `resources/read`, `resources/subscribe`,
+ // `resources/unsubscribe`, or `notifications/resources/updated`.
+ McpResourceURIKey = attribute.Key("mcp.resource.uri")
+
+ // McpSessionIDKey is the attribute Key conforming to the "mcp.session.id"
+ // semantic conventions. It represents the identifies [MCP session].
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "191c4850af6c49e08843a3f6c80e5046"
+ //
+ // [MCP session]: https://modelcontextprotocol.io/specification/2025-06-18/basic/transports#session-management
+ McpSessionIDKey = attribute.Key("mcp.session.id")
+)
+
+// McpProtocolVersion returns an attribute KeyValue conforming to the
+// "mcp.protocol.version" semantic conventions. It represents the [version] of
+// the Model Context Protocol used.
+//
+// [version]: https://modelcontextprotocol.io/specification/versioning
+func McpProtocolVersion(val string) attribute.KeyValue {
+ return McpProtocolVersionKey.String(val)
+}
+
+// McpResourceURI returns an attribute KeyValue conforming to the
+// "mcp.resource.uri" semantic conventions. It represents the value of the
+// resource uri.
+func McpResourceURI(val string) attribute.KeyValue {
+ return McpResourceURIKey.String(val)
+}
+
+// McpSessionID returns an attribute KeyValue conforming to the "mcp.session.id"
+// semantic conventions. It represents the identifies [MCP session].
+//
+// [MCP session]: https://modelcontextprotocol.io/specification/2025-06-18/basic/transports#session-management
+func McpSessionID(val string) attribute.KeyValue {
+ return McpSessionIDKey.String(val)
+}
+
+// Enum values for mcp.method.name
+var (
+ // Notification cancelling a previously-issued request.
+ //
+ // Stability: development
+ McpMethodNameNotificationsCancelled = McpMethodNameKey.String("notifications/cancelled")
+ // Request to initialize the MCP client.
+ //
+ // Stability: development
+ McpMethodNameInitialize = McpMethodNameKey.String("initialize")
+ // Notification indicating that the MCP client has been initialized.
+ //
+ // Stability: development
+ McpMethodNameNotificationsInitialized = McpMethodNameKey.String("notifications/initialized")
+ // Notification indicating the progress for a long-running operation.
+ //
+ // Stability: development
+ McpMethodNameNotificationsProgress = McpMethodNameKey.String("notifications/progress")
+ // Request to check that the other party is still alive.
+ //
+ // Stability: development
+ McpMethodNamePing = McpMethodNameKey.String("ping")
+ // Request to list resources available on server.
+ //
+ // Stability: development
+ McpMethodNameResourcesList = McpMethodNameKey.String("resources/list")
+ // Request to list resource templates available on server.
+ //
+ // Stability: development
+ McpMethodNameResourcesTemplatesList = McpMethodNameKey.String("resources/templates/list")
+ // Request to read a resource.
+ //
+ // Stability: development
+ McpMethodNameResourcesRead = McpMethodNameKey.String("resources/read")
+ // Notification indicating that the list of resources has changed.
+ //
+ // Stability: development
+ McpMethodNameNotificationsResourcesListChanged = McpMethodNameKey.String("notifications/resources/list_changed")
+ // Request to subscribe to a resource.
+ //
+ // Stability: development
+ McpMethodNameResourcesSubscribe = McpMethodNameKey.String("resources/subscribe")
+ // Request to unsubscribe from resource updates.
+ //
+ // Stability: development
+ McpMethodNameResourcesUnsubscribe = McpMethodNameKey.String("resources/unsubscribe")
+ // Notification indicating that a resource has been updated.
+ //
+ // Stability: development
+ McpMethodNameNotificationsResourcesUpdated = McpMethodNameKey.String("notifications/resources/updated")
+ // Request to list prompts available on server.
+ //
+ // Stability: development
+ McpMethodNamePromptsList = McpMethodNameKey.String("prompts/list")
+ // Request to get a prompt.
+ //
+ // Stability: development
+ McpMethodNamePromptsGet = McpMethodNameKey.String("prompts/get")
+ // Notification indicating that the list of prompts has changed.
+ //
+ // Stability: development
+ McpMethodNameNotificationsPromptsListChanged = McpMethodNameKey.String("notifications/prompts/list_changed")
+ // Request to list tools available on server.
+ //
+ // Stability: development
+ McpMethodNameToolsList = McpMethodNameKey.String("tools/list")
+ // Request to call a tool.
+ //
+ // Stability: development
+ McpMethodNameToolsCall = McpMethodNameKey.String("tools/call")
+ // Notification indicating that the list of tools has changed.
+ //
+ // Stability: development
+ McpMethodNameNotificationsToolsListChanged = McpMethodNameKey.String("notifications/tools/list_changed")
+ // Request to set the logging level.
+ //
+ // Stability: development
+ McpMethodNameLoggingSetLevel = McpMethodNameKey.String("logging/setLevel")
+ // Notification indicating that a message has been received.
+ //
+ // Stability: development
+ McpMethodNameNotificationsMessage = McpMethodNameKey.String("notifications/message")
+ // Request to create a sampling message.
+ //
+ // Stability: development
+ McpMethodNameSamplingCreateMessage = McpMethodNameKey.String("sampling/createMessage")
+ // Request to complete a prompt.
+ //
+ // Stability: development
+ McpMethodNameCompletionComplete = McpMethodNameKey.String("completion/complete")
+ // Request to list roots available on server.
+ //
+ // Stability: development
+ McpMethodNameRootsList = McpMethodNameKey.String("roots/list")
+ // Notification indicating that the list of roots has changed.
+ //
+ // Stability: development
+ McpMethodNameNotificationsRootsListChanged = McpMethodNameKey.String("notifications/roots/list_changed")
+ // Request from the server to elicit additional information from the user via
+ // the client
+ //
+ // Stability: development
+ McpMethodNameElicitationCreate = McpMethodNameKey.String("elicitation/create")
+)
+
+// Namespace: messaging
+const (
+ // MessagingBatchMessageCountKey is the attribute Key conforming to the
+ // "messaging.batch.message_count" semantic conventions. It represents the
+ // number of messages sent, received, or processed in the scope of the batching
+ // operation.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 0, 1, 2
+ // Note: Instrumentations SHOULD NOT set `messaging.batch.message_count` on
+ // spans that operate with a single message. When a messaging client library
+ // supports both batch and single-message API for the same operation,
+ // instrumentations SHOULD use `messaging.batch.message_count` for batching APIs
+ // and SHOULD NOT use it for single-message APIs.
+ MessagingBatchMessageCountKey = attribute.Key("messaging.batch.message_count")
+
+ // MessagingClientIDKey is the attribute Key conforming to the
+ // "messaging.client.id" semantic conventions. It represents a unique identifier
+ // for the client that consumes or produces a message.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "client-5", "myhost@8742@s8083jm"
+ MessagingClientIDKey = attribute.Key("messaging.client.id")
+
+ // MessagingConsumerGroupNameKey is the attribute Key conforming to the
+ // "messaging.consumer.group.name" semantic conventions. It represents the name
+ // of the consumer group with which a consumer is associated.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "my-group", "indexer"
+ // Note: Semantic conventions for individual messaging systems SHOULD document
+ // whether `messaging.consumer.group.name` is applicable and what it means in
+ // the context of that system.
+ MessagingConsumerGroupNameKey = attribute.Key("messaging.consumer.group.name")
+
+ // MessagingDestinationAnonymousKey is the attribute Key conforming to the
+ // "messaging.destination.anonymous" semantic conventions. It represents a
+ // boolean that is true if the message destination is anonymous (could be
+ // unnamed or have auto-generated name).
+ //
+ // Type: boolean
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ MessagingDestinationAnonymousKey = attribute.Key("messaging.destination.anonymous")
+
+ // MessagingDestinationNameKey is the attribute Key conforming to the
+ // "messaging.destination.name" semantic conventions. It represents the message
+ // destination name.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "MyQueue", "MyTopic"
+ // Note: Destination name SHOULD uniquely identify a specific queue, topic or
+ // other entity within the broker. If
+ // the broker doesn't have such notion, the destination name SHOULD uniquely
+ // identify the broker.
+ MessagingDestinationNameKey = attribute.Key("messaging.destination.name")
+
+ // MessagingDestinationPartitionIDKey is the attribute Key conforming to the
+ // "messaging.destination.partition.id" semantic conventions. It represents the
+ // identifier of the partition messages are sent to or received from, unique
+ // within the `messaging.destination.name`.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 1
+ MessagingDestinationPartitionIDKey = attribute.Key("messaging.destination.partition.id")
+
+ // MessagingDestinationSubscriptionNameKey is the attribute Key conforming to
+ // the "messaging.destination.subscription.name" semantic conventions. It
+ // represents the name of the destination subscription from which a message is
+ // consumed.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "subscription-a"
+ // Note: Semantic conventions for individual messaging systems SHOULD document
+ // whether `messaging.destination.subscription.name` is applicable and what it
+ // means in the context of that system.
+ MessagingDestinationSubscriptionNameKey = attribute.Key("messaging.destination.subscription.name")
+
+ // MessagingDestinationTemplateKey is the attribute Key conforming to the
+ // "messaging.destination.template" semantic conventions. It represents the low
+ // cardinality representation of the messaging destination name.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "/customers/{customerId}"
+ // Note: Destination names could be constructed from templates. An example would
+ // be a destination name involving a user name or product id. Although the
+ // destination name in this case is of high cardinality, the underlying template
+ // is of low cardinality and can be effectively used for grouping and
+ // aggregation.
+ MessagingDestinationTemplateKey = attribute.Key("messaging.destination.template")
+
+ // MessagingDestinationTemporaryKey is the attribute Key conforming to the
+ // "messaging.destination.temporary" semantic conventions. It represents a
+ // boolean that is true if the message destination is temporary and might not
+ // exist anymore after messages are processed.
+ //
+ // Type: boolean
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ MessagingDestinationTemporaryKey = attribute.Key("messaging.destination.temporary")
+
+ // MessagingEventHubsMessageEnqueuedTimeKey is the attribute Key conforming to
+ // the "messaging.eventhubs.message.enqueued_time" semantic conventions. It
+ // represents the UTC epoch seconds at which the message has been accepted and
+ // stored in the entity.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ MessagingEventHubsMessageEnqueuedTimeKey = attribute.Key("messaging.eventhubs.message.enqueued_time")
+
+ // MessagingGCPPubSubMessageAckDeadlineKey is the attribute Key conforming to
+ // the "messaging.gcp_pubsub.message.ack_deadline" semantic conventions. It
+ // represents the ack deadline in seconds set for the modify ack deadline
+ // request.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ MessagingGCPPubSubMessageAckDeadlineKey = attribute.Key("messaging.gcp_pubsub.message.ack_deadline")
+
+ // MessagingGCPPubSubMessageAckIDKey is the attribute Key conforming to the
+ // "messaging.gcp_pubsub.message.ack_id" semantic conventions. It represents the
+ // ack id for a given message.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: ack_id
+ MessagingGCPPubSubMessageAckIDKey = attribute.Key("messaging.gcp_pubsub.message.ack_id")
+
+ // MessagingGCPPubSubMessageDeliveryAttemptKey is the attribute Key conforming
+ // to the "messaging.gcp_pubsub.message.delivery_attempt" semantic conventions.
+ // It represents the delivery attempt for a given message.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ MessagingGCPPubSubMessageDeliveryAttemptKey = attribute.Key("messaging.gcp_pubsub.message.delivery_attempt")
+
+ // MessagingGCPPubSubMessageOrderingKeyKey is the attribute Key conforming to
+ // the "messaging.gcp_pubsub.message.ordering_key" semantic conventions. It
+ // represents the ordering key for a given message. If the attribute is not
+ // present, the message does not have an ordering key.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: ordering_key
+ MessagingGCPPubSubMessageOrderingKeyKey = attribute.Key("messaging.gcp_pubsub.message.ordering_key")
+
+ // MessagingKafkaMessageKeyKey is the attribute Key conforming to the
+ // "messaging.kafka.message.key" semantic conventions. It represents the message
+ // keys in Kafka are used for grouping alike messages to ensure they're
+ // processed on the same partition. They differ from `messaging.message.id` in
+ // that they're not unique. If the key is `null`, the attribute MUST NOT be set.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: myKey
+ // Note: If the key type is not string, it's string representation has to be
+ // supplied for the attribute. If the key has no unambiguous, canonical string
+ // form, don't include its value.
+ MessagingKafkaMessageKeyKey = attribute.Key("messaging.kafka.message.key")
+
+ // MessagingKafkaMessageTombstoneKey is the attribute Key conforming to the
+ // "messaging.kafka.message.tombstone" semantic conventions. It represents a
+ // boolean that is true if the message is a tombstone.
+ //
+ // Type: boolean
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ MessagingKafkaMessageTombstoneKey = attribute.Key("messaging.kafka.message.tombstone")
+
+ // MessagingKafkaOffsetKey is the attribute Key conforming to the
+ // "messaging.kafka.offset" semantic conventions. It represents the offset of a
+ // record in the corresponding Kafka partition.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ MessagingKafkaOffsetKey = attribute.Key("messaging.kafka.offset")
+
+ // MessagingMessageBodySizeKey is the attribute Key conforming to the
+ // "messaging.message.body.size" semantic conventions. It represents the size of
+ // the message body in bytes.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Note: This can refer to both the compressed or uncompressed body size. If
+ // both sizes are known, the uncompressed
+ // body size should be used.
+ MessagingMessageBodySizeKey = attribute.Key("messaging.message.body.size")
+
+ // MessagingMessageConversationIDKey is the attribute Key conforming to the
+ // "messaging.message.conversation_id" semantic conventions. It represents the
+ // conversation ID identifying the conversation to which the message belongs,
+ // represented as a string. Sometimes called "Correlation ID".
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: MyConversationId
+ MessagingMessageConversationIDKey = attribute.Key("messaging.message.conversation_id")
+
+ // MessagingMessageEnvelopeSizeKey is the attribute Key conforming to the
+ // "messaging.message.envelope.size" semantic conventions. It represents the
+ // size of the message body and metadata in bytes.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Note: This can refer to both the compressed or uncompressed size. If both
+ // sizes are known, the uncompressed
+ // size should be used.
+ MessagingMessageEnvelopeSizeKey = attribute.Key("messaging.message.envelope.size")
+
+ // MessagingMessageIDKey is the attribute Key conforming to the
+ // "messaging.message.id" semantic conventions. It represents a value used by
+ // the messaging system as an identifier for the message, represented as a
+ // string.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 452a7c7c7c7048c2f887f61572b18fc2
+ MessagingMessageIDKey = attribute.Key("messaging.message.id")
+
+ // MessagingOperationNameKey is the attribute Key conforming to the
+ // "messaging.operation.name" semantic conventions. It represents the
+ // system-specific name of the messaging operation.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "ack", "nack", "send"
+ MessagingOperationNameKey = attribute.Key("messaging.operation.name")
+
+ // MessagingOperationTypeKey is the attribute Key conforming to the
+ // "messaging.operation.type" semantic conventions. It represents a string
+ // identifying the type of the messaging operation.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ // Note: If a custom value is used, it MUST be of low cardinality.
+ MessagingOperationTypeKey = attribute.Key("messaging.operation.type")
+
+ // MessagingRabbitMQDestinationRoutingKeyKey is the attribute Key conforming to
+ // the "messaging.rabbitmq.destination.routing_key" semantic conventions. It
+ // represents the rabbitMQ message routing key.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: myKey
+ MessagingRabbitMQDestinationRoutingKeyKey = attribute.Key("messaging.rabbitmq.destination.routing_key")
+
+ // MessagingRabbitMQMessageDeliveryTagKey is the attribute Key conforming to the
+ // "messaging.rabbitmq.message.delivery_tag" semantic conventions. It represents
+ // the rabbitMQ message delivery tag.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ MessagingRabbitMQMessageDeliveryTagKey = attribute.Key("messaging.rabbitmq.message.delivery_tag")
+
+ // MessagingRocketMQConsumptionModelKey is the attribute Key conforming to the
+ // "messaging.rocketmq.consumption_model" semantic conventions. It represents
+ // the model of message consumption. This only applies to consumer spans.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ MessagingRocketMQConsumptionModelKey = attribute.Key("messaging.rocketmq.consumption_model")
+
+ // MessagingRocketMQMessageDelayTimeLevelKey is the attribute Key conforming to
+ // the "messaging.rocketmq.message.delay_time_level" semantic conventions. It
+ // represents the delay time level for delay message, which determines the
+ // message delay time.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ MessagingRocketMQMessageDelayTimeLevelKey = attribute.Key("messaging.rocketmq.message.delay_time_level")
+
+ // MessagingRocketMQMessageDeliveryTimestampKey is the attribute Key conforming
+ // to the "messaging.rocketmq.message.delivery_timestamp" semantic conventions.
+ // It represents the timestamp in milliseconds that the delay message is
+ // expected to be delivered to consumer.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ MessagingRocketMQMessageDeliveryTimestampKey = attribute.Key("messaging.rocketmq.message.delivery_timestamp")
+
+ // MessagingRocketMQMessageGroupKey is the attribute Key conforming to the
+ // "messaging.rocketmq.message.group" semantic conventions. It represents the it
+ // is essential for FIFO message. Messages that belong to the same message group
+ // are always processed one by one within the same consumer group.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: myMessageGroup
+ MessagingRocketMQMessageGroupKey = attribute.Key("messaging.rocketmq.message.group")
+
+ // MessagingRocketMQMessageKeysKey is the attribute Key conforming to the
+ // "messaging.rocketmq.message.keys" semantic conventions. It represents the
+ // key(s) of message, another way to mark message besides message id.
+ //
+ // Type: string[]
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "keyA", "keyB"
+ MessagingRocketMQMessageKeysKey = attribute.Key("messaging.rocketmq.message.keys")
+
+ // MessagingRocketMQMessageTagKey is the attribute Key conforming to the
+ // "messaging.rocketmq.message.tag" semantic conventions. It represents the
+ // secondary classifier of message besides topic.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: tagA
+ MessagingRocketMQMessageTagKey = attribute.Key("messaging.rocketmq.message.tag")
+
+ // MessagingRocketMQMessageTypeKey is the attribute Key conforming to the
+ // "messaging.rocketmq.message.type" semantic conventions. It represents the
+ // type of message.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ MessagingRocketMQMessageTypeKey = attribute.Key("messaging.rocketmq.message.type")
+
+ // MessagingRocketMQNamespaceKey is the attribute Key conforming to the
+ // "messaging.rocketmq.namespace" semantic conventions. It represents the
+ // namespace of RocketMQ resources, resources in different namespaces are
+ // individual.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: myNamespace
+ MessagingRocketMQNamespaceKey = attribute.Key("messaging.rocketmq.namespace")
+
+ // MessagingServiceBusDispositionStatusKey is the attribute Key conforming to
+ // the "messaging.servicebus.disposition_status" semantic conventions. It
+ // represents the describes the [settlement type].
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ //
+ // [settlement type]: https://learn.microsoft.com/azure/service-bus-messaging/message-transfers-locks-settlement#peeklock
+ MessagingServiceBusDispositionStatusKey = attribute.Key("messaging.servicebus.disposition_status")
+
+ // MessagingServiceBusMessageDeliveryCountKey is the attribute Key conforming to
+ // the "messaging.servicebus.message.delivery_count" semantic conventions. It
+ // represents the number of deliveries that have been attempted for this
+ // message.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ MessagingServiceBusMessageDeliveryCountKey = attribute.Key("messaging.servicebus.message.delivery_count")
+
+ // MessagingServiceBusMessageEnqueuedTimeKey is the attribute Key conforming to
+ // the "messaging.servicebus.message.enqueued_time" semantic conventions. It
+ // represents the UTC epoch seconds at which the message has been accepted and
+ // stored in the entity.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ MessagingServiceBusMessageEnqueuedTimeKey = attribute.Key("messaging.servicebus.message.enqueued_time")
+
+ // MessagingSystemKey is the attribute Key conforming to the "messaging.system"
+ // semantic conventions. It represents the messaging system as identified by the
+ // client instrumentation.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ // Note: The actual messaging system may differ from the one known by the
+ // client. For example, when using Kafka client libraries to communicate with
+ // Azure Event Hubs, the `messaging.system` is set to `kafka` based on the
+ // instrumentation's best knowledge.
+ MessagingSystemKey = attribute.Key("messaging.system")
+)
+
+// MessagingBatchMessageCount returns an attribute KeyValue conforming to the
+// "messaging.batch.message_count" semantic conventions. It represents the number
+// of messages sent, received, or processed in the scope of the batching
+// operation.
+func MessagingBatchMessageCount(val int) attribute.KeyValue {
+ return MessagingBatchMessageCountKey.Int(val)
+}
+
+// MessagingClientID returns an attribute KeyValue conforming to the
+// "messaging.client.id" semantic conventions. It represents a unique identifier
+// for the client that consumes or produces a message.
+func MessagingClientID(val string) attribute.KeyValue {
+ return MessagingClientIDKey.String(val)
+}
+
+// MessagingConsumerGroupName returns an attribute KeyValue conforming to the
+// "messaging.consumer.group.name" semantic conventions. It represents the name
+// of the consumer group with which a consumer is associated.
+func MessagingConsumerGroupName(val string) attribute.KeyValue {
+ return MessagingConsumerGroupNameKey.String(val)
+}
+
+// MessagingDestinationAnonymous returns an attribute KeyValue conforming to the
+// "messaging.destination.anonymous" semantic conventions. It represents a
+// boolean that is true if the message destination is anonymous (could be unnamed
+// or have auto-generated name).
+func MessagingDestinationAnonymous(val bool) attribute.KeyValue {
+ return MessagingDestinationAnonymousKey.Bool(val)
+}
+
+// MessagingDestinationName returns an attribute KeyValue conforming to the
+// "messaging.destination.name" semantic conventions. It represents the message
+// destination name.
+func MessagingDestinationName(val string) attribute.KeyValue {
+ return MessagingDestinationNameKey.String(val)
+}
+
+// MessagingDestinationPartitionID returns an attribute KeyValue conforming to
+// the "messaging.destination.partition.id" semantic conventions. It represents
+// the identifier of the partition messages are sent to or received from, unique
+// within the `messaging.destination.name`.
+func MessagingDestinationPartitionID(val string) attribute.KeyValue {
+ return MessagingDestinationPartitionIDKey.String(val)
+}
+
+// MessagingDestinationSubscriptionName returns an attribute KeyValue conforming
+// to the "messaging.destination.subscription.name" semantic conventions. It
+// represents the name of the destination subscription from which a message is
+// consumed.
+func MessagingDestinationSubscriptionName(val string) attribute.KeyValue {
+ return MessagingDestinationSubscriptionNameKey.String(val)
+}
+
+// MessagingDestinationTemplate returns an attribute KeyValue conforming to the
+// "messaging.destination.template" semantic conventions. It represents the low
+// cardinality representation of the messaging destination name.
+func MessagingDestinationTemplate(val string) attribute.KeyValue {
+ return MessagingDestinationTemplateKey.String(val)
+}
+
+// MessagingDestinationTemporary returns an attribute KeyValue conforming to the
+// "messaging.destination.temporary" semantic conventions. It represents a
+// boolean that is true if the message destination is temporary and might not
+// exist anymore after messages are processed.
+func MessagingDestinationTemporary(val bool) attribute.KeyValue {
+ return MessagingDestinationTemporaryKey.Bool(val)
+}
+
+// MessagingEventHubsMessageEnqueuedTime returns an attribute KeyValue conforming
+// to the "messaging.eventhubs.message.enqueued_time" semantic conventions. It
+// represents the UTC epoch seconds at which the message has been accepted and
+// stored in the entity.
+func MessagingEventHubsMessageEnqueuedTime(val int) attribute.KeyValue {
+ return MessagingEventHubsMessageEnqueuedTimeKey.Int(val)
+}
+
+// MessagingGCPPubSubMessageAckDeadline returns an attribute KeyValue conforming
+// to the "messaging.gcp_pubsub.message.ack_deadline" semantic conventions. It
+// represents the ack deadline in seconds set for the modify ack deadline
+// request.
+func MessagingGCPPubSubMessageAckDeadline(val int) attribute.KeyValue {
+ return MessagingGCPPubSubMessageAckDeadlineKey.Int(val)
+}
+
+// MessagingGCPPubSubMessageAckID returns an attribute KeyValue conforming to the
+// "messaging.gcp_pubsub.message.ack_id" semantic conventions. It represents the
+// ack id for a given message.
+func MessagingGCPPubSubMessageAckID(val string) attribute.KeyValue {
+ return MessagingGCPPubSubMessageAckIDKey.String(val)
+}
+
+// MessagingGCPPubSubMessageDeliveryAttempt returns an attribute KeyValue
+// conforming to the "messaging.gcp_pubsub.message.delivery_attempt" semantic
+// conventions. It represents the delivery attempt for a given message.
+func MessagingGCPPubSubMessageDeliveryAttempt(val int) attribute.KeyValue {
+ return MessagingGCPPubSubMessageDeliveryAttemptKey.Int(val)
+}
+
+// MessagingGCPPubSubMessageOrderingKey returns an attribute KeyValue conforming
+// to the "messaging.gcp_pubsub.message.ordering_key" semantic conventions. It
+// represents the ordering key for a given message. If the attribute is not
+// present, the message does not have an ordering key.
+func MessagingGCPPubSubMessageOrderingKey(val string) attribute.KeyValue {
+ return MessagingGCPPubSubMessageOrderingKeyKey.String(val)
+}
+
+// MessagingKafkaMessageKey returns an attribute KeyValue conforming to the
+// "messaging.kafka.message.key" semantic conventions. It represents the message
+// keys in Kafka are used for grouping alike messages to ensure they're processed
+// on the same partition. They differ from `messaging.message.id` in that they're
+// not unique. If the key is `null`, the attribute MUST NOT be set.
+func MessagingKafkaMessageKey(val string) attribute.KeyValue {
+ return MessagingKafkaMessageKeyKey.String(val)
+}
+
+// MessagingKafkaMessageTombstone returns an attribute KeyValue conforming to the
+// "messaging.kafka.message.tombstone" semantic conventions. It represents a
+// boolean that is true if the message is a tombstone.
+func MessagingKafkaMessageTombstone(val bool) attribute.KeyValue {
+ return MessagingKafkaMessageTombstoneKey.Bool(val)
+}
+
+// MessagingKafkaOffset returns an attribute KeyValue conforming to the
+// "messaging.kafka.offset" semantic conventions. It represents the offset of a
+// record in the corresponding Kafka partition.
+func MessagingKafkaOffset(val int) attribute.KeyValue {
+ return MessagingKafkaOffsetKey.Int(val)
+}
+
+// MessagingMessageBodySize returns an attribute KeyValue conforming to the
+// "messaging.message.body.size" semantic conventions. It represents the size of
+// the message body in bytes.
+func MessagingMessageBodySize(val int) attribute.KeyValue {
+ return MessagingMessageBodySizeKey.Int(val)
+}
+
+// MessagingMessageConversationID returns an attribute KeyValue conforming to the
+// "messaging.message.conversation_id" semantic conventions. It represents the
+// conversation ID identifying the conversation to which the message belongs,
+// represented as a string. Sometimes called "Correlation ID".
+func MessagingMessageConversationID(val string) attribute.KeyValue {
+ return MessagingMessageConversationIDKey.String(val)
+}
+
+// MessagingMessageEnvelopeSize returns an attribute KeyValue conforming to the
+// "messaging.message.envelope.size" semantic conventions. It represents the size
+// of the message body and metadata in bytes.
+func MessagingMessageEnvelopeSize(val int) attribute.KeyValue {
+ return MessagingMessageEnvelopeSizeKey.Int(val)
+}
+
+// MessagingMessageID returns an attribute KeyValue conforming to the
+// "messaging.message.id" semantic conventions. It represents a value used by the
+// messaging system as an identifier for the message, represented as a string.
+func MessagingMessageID(val string) attribute.KeyValue {
+ return MessagingMessageIDKey.String(val)
+}
+
+// MessagingOperationName returns an attribute KeyValue conforming to the
+// "messaging.operation.name" semantic conventions. It represents the
+// system-specific name of the messaging operation.
+func MessagingOperationName(val string) attribute.KeyValue {
+ return MessagingOperationNameKey.String(val)
+}
+
+// MessagingRabbitMQDestinationRoutingKey returns an attribute KeyValue
+// conforming to the "messaging.rabbitmq.destination.routing_key" semantic
+// conventions. It represents the rabbitMQ message routing key.
+func MessagingRabbitMQDestinationRoutingKey(val string) attribute.KeyValue {
+ return MessagingRabbitMQDestinationRoutingKeyKey.String(val)
+}
+
+// MessagingRabbitMQMessageDeliveryTag returns an attribute KeyValue conforming
+// to the "messaging.rabbitmq.message.delivery_tag" semantic conventions. It
+// represents the rabbitMQ message delivery tag.
+func MessagingRabbitMQMessageDeliveryTag(val int) attribute.KeyValue {
+ return MessagingRabbitMQMessageDeliveryTagKey.Int(val)
+}
+
+// MessagingRocketMQMessageDelayTimeLevel returns an attribute KeyValue
+// conforming to the "messaging.rocketmq.message.delay_time_level" semantic
+// conventions. It represents the delay time level for delay message, which
+// determines the message delay time.
+func MessagingRocketMQMessageDelayTimeLevel(val int) attribute.KeyValue {
+ return MessagingRocketMQMessageDelayTimeLevelKey.Int(val)
+}
+
+// MessagingRocketMQMessageDeliveryTimestamp returns an attribute KeyValue
+// conforming to the "messaging.rocketmq.message.delivery_timestamp" semantic
+// conventions. It represents the timestamp in milliseconds that the delay
+// message is expected to be delivered to consumer.
+func MessagingRocketMQMessageDeliveryTimestamp(val int) attribute.KeyValue {
+ return MessagingRocketMQMessageDeliveryTimestampKey.Int(val)
+}
+
+// MessagingRocketMQMessageGroup returns an attribute KeyValue conforming to the
+// "messaging.rocketmq.message.group" semantic conventions. It represents the it
+// is essential for FIFO message. Messages that belong to the same message group
+// are always processed one by one within the same consumer group.
+func MessagingRocketMQMessageGroup(val string) attribute.KeyValue {
+ return MessagingRocketMQMessageGroupKey.String(val)
+}
+
+// MessagingRocketMQMessageKeys returns an attribute KeyValue conforming to the
+// "messaging.rocketmq.message.keys" semantic conventions. It represents the
+// key(s) of message, another way to mark message besides message id.
+func MessagingRocketMQMessageKeys(val ...string) attribute.KeyValue {
+ return MessagingRocketMQMessageKeysKey.StringSlice(val)
+}
+
+// MessagingRocketMQMessageTag returns an attribute KeyValue conforming to the
+// "messaging.rocketmq.message.tag" semantic conventions. It represents the
+// secondary classifier of message besides topic.
+func MessagingRocketMQMessageTag(val string) attribute.KeyValue {
+ return MessagingRocketMQMessageTagKey.String(val)
+}
+
+// MessagingRocketMQNamespace returns an attribute KeyValue conforming to the
+// "messaging.rocketmq.namespace" semantic conventions. It represents the
+// namespace of RocketMQ resources, resources in different namespaces are
+// individual.
+func MessagingRocketMQNamespace(val string) attribute.KeyValue {
+ return MessagingRocketMQNamespaceKey.String(val)
+}
+
+// MessagingServiceBusMessageDeliveryCount returns an attribute KeyValue
+// conforming to the "messaging.servicebus.message.delivery_count" semantic
+// conventions. It represents the number of deliveries that have been attempted
+// for this message.
+func MessagingServiceBusMessageDeliveryCount(val int) attribute.KeyValue {
+ return MessagingServiceBusMessageDeliveryCountKey.Int(val)
+}
+
+// MessagingServiceBusMessageEnqueuedTime returns an attribute KeyValue
+// conforming to the "messaging.servicebus.message.enqueued_time" semantic
+// conventions. It represents the UTC epoch seconds at which the message has been
+// accepted and stored in the entity.
+func MessagingServiceBusMessageEnqueuedTime(val int) attribute.KeyValue {
+ return MessagingServiceBusMessageEnqueuedTimeKey.Int(val)
+}
+
+// Enum values for messaging.operation.type
+var (
+ // A message is created. "Create" spans always refer to a single message and are
+ // used to provide a unique creation context for messages in batch sending
+ // scenarios.
+ //
+ // Stability: development
+ MessagingOperationTypeCreate = MessagingOperationTypeKey.String("create")
+ // One or more messages are provided for sending to an intermediary. If a single
+ // message is sent, the context of the "Send" span can be used as the creation
+ // context and no "Create" span needs to be created.
+ //
+ // Stability: development
+ MessagingOperationTypeSend = MessagingOperationTypeKey.String("send")
+ // One or more messages are requested by a consumer. This operation refers to
+ // pull-based scenarios, where consumers explicitly call methods of messaging
+ // SDKs to receive messages.
+ //
+ // Stability: development
+ MessagingOperationTypeReceive = MessagingOperationTypeKey.String("receive")
+ // One or more messages are processed by a consumer.
+ //
+ // Stability: development
+ MessagingOperationTypeProcess = MessagingOperationTypeKey.String("process")
+ // One or more messages are settled.
+ //
+ // Stability: development
+ MessagingOperationTypeSettle = MessagingOperationTypeKey.String("settle")
+)
+
+// Enum values for messaging.rocketmq.consumption_model
+var (
+ // Clustering consumption model
+ // Stability: development
+ MessagingRocketMQConsumptionModelClustering = MessagingRocketMQConsumptionModelKey.String("clustering")
+ // Broadcasting consumption model
+ // Stability: development
+ MessagingRocketMQConsumptionModelBroadcasting = MessagingRocketMQConsumptionModelKey.String("broadcasting")
+)
+
+// Enum values for messaging.rocketmq.message.type
+var (
+ // Normal message
+ // Stability: development
+ MessagingRocketMQMessageTypeNormal = MessagingRocketMQMessageTypeKey.String("normal")
+ // FIFO message
+ // Stability: development
+ MessagingRocketMQMessageTypeFifo = MessagingRocketMQMessageTypeKey.String("fifo")
+ // Delay message
+ // Stability: development
+ MessagingRocketMQMessageTypeDelay = MessagingRocketMQMessageTypeKey.String("delay")
+ // Transaction message
+ // Stability: development
+ MessagingRocketMQMessageTypeTransaction = MessagingRocketMQMessageTypeKey.String("transaction")
+)
+
+// Enum values for messaging.servicebus.disposition_status
+var (
+ // Message is completed
+ // Stability: development
+ MessagingServiceBusDispositionStatusComplete = MessagingServiceBusDispositionStatusKey.String("complete")
+ // Message is abandoned
+ // Stability: development
+ MessagingServiceBusDispositionStatusAbandon = MessagingServiceBusDispositionStatusKey.String("abandon")
+ // Message is sent to dead letter queue
+ // Stability: development
+ MessagingServiceBusDispositionStatusDeadLetter = MessagingServiceBusDispositionStatusKey.String("dead_letter")
+ // Message is deferred
+ // Stability: development
+ MessagingServiceBusDispositionStatusDefer = MessagingServiceBusDispositionStatusKey.String("defer")
+)
+
+// Enum values for messaging.system
+var (
+ // Apache ActiveMQ
+ // Stability: development
+ MessagingSystemActiveMQ = MessagingSystemKey.String("activemq")
+ // Amazon Simple Notification Service (SNS)
+ // Stability: development
+ MessagingSystemAWSSNS = MessagingSystemKey.String("aws.sns")
+ // Amazon Simple Queue Service (SQS)
+ // Stability: development
+ MessagingSystemAWSSQS = MessagingSystemKey.String("aws_sqs")
+ // Azure Event Grid
+ // Stability: development
+ MessagingSystemEventGrid = MessagingSystemKey.String("eventgrid")
+ // Azure Event Hubs
+ // Stability: development
+ MessagingSystemEventHubs = MessagingSystemKey.String("eventhubs")
+ // Azure Service Bus
+ // Stability: development
+ MessagingSystemServiceBus = MessagingSystemKey.String("servicebus")
+ // Google Cloud Pub/Sub
+ // Stability: development
+ MessagingSystemGCPPubSub = MessagingSystemKey.String("gcp_pubsub")
+ // Java Message Service
+ // Stability: development
+ MessagingSystemJMS = MessagingSystemKey.String("jms")
+ // Apache Kafka
+ // Stability: development
+ MessagingSystemKafka = MessagingSystemKey.String("kafka")
+ // RabbitMQ
+ // Stability: development
+ MessagingSystemRabbitMQ = MessagingSystemKey.String("rabbitmq")
+ // Apache RocketMQ
+ // Stability: development
+ MessagingSystemRocketMQ = MessagingSystemKey.String("rocketmq")
+ // Apache Pulsar
+ // Stability: development
+ MessagingSystemPulsar = MessagingSystemKey.String("pulsar")
+)
+
+// Namespace: network
+const (
+ // NetworkCarrierICCKey is the attribute Key conforming to the
+ // "network.carrier.icc" semantic conventions. It represents the ISO 3166-1
+ // alpha-2 2-character country code associated with the mobile carrier network.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: DE
+ NetworkCarrierICCKey = attribute.Key("network.carrier.icc")
+
+ // NetworkCarrierMCCKey is the attribute Key conforming to the
+ // "network.carrier.mcc" semantic conventions. It represents the mobile carrier
+ // country code.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 310
+ NetworkCarrierMCCKey = attribute.Key("network.carrier.mcc")
+
+ // NetworkCarrierMNCKey is the attribute Key conforming to the
+ // "network.carrier.mnc" semantic conventions. It represents the mobile carrier
+ // network code.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 001
+ NetworkCarrierMNCKey = attribute.Key("network.carrier.mnc")
+
+ // NetworkCarrierNameKey is the attribute Key conforming to the
+ // "network.carrier.name" semantic conventions. It represents the name of the
+ // mobile carrier.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: sprint
+ NetworkCarrierNameKey = attribute.Key("network.carrier.name")
+
+ // NetworkConnectionStateKey is the attribute Key conforming to the
+ // "network.connection.state" semantic conventions. It represents the state of
+ // network connection.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "close_wait"
+ // Note: Connection states are defined as part of the [rfc9293]
+ //
+ // [rfc9293]: https://datatracker.ietf.org/doc/html/rfc9293#section-3.3.2
+ NetworkConnectionStateKey = attribute.Key("network.connection.state")
+
+ // NetworkConnectionSubtypeKey is the attribute Key conforming to the
+ // "network.connection.subtype" semantic conventions. It represents the this
+ // describes more details regarding the connection.type. It may be the type of
+ // cell technology connection, but it could be used for describing details about
+ // a wifi connection.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: LTE
+ NetworkConnectionSubtypeKey = attribute.Key("network.connection.subtype")
+
+ // NetworkConnectionTypeKey is the attribute Key conforming to the
+ // "network.connection.type" semantic conventions. It represents the internet
+ // connection type.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: wifi
+ NetworkConnectionTypeKey = attribute.Key("network.connection.type")
+
+ // NetworkInterfaceNameKey is the attribute Key conforming to the
+ // "network.interface.name" semantic conventions. It represents the network
+ // interface name.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "lo", "eth0"
+ NetworkInterfaceNameKey = attribute.Key("network.interface.name")
+
+ // NetworkIODirectionKey is the attribute Key conforming to the
+ // "network.io.direction" semantic conventions. It represents the network IO
+ // operation direction.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "transmit"
+ NetworkIODirectionKey = attribute.Key("network.io.direction")
+
+ // NetworkLocalAddressKey is the attribute Key conforming to the
+ // "network.local.address" semantic conventions. It represents the local address
+ // of the network connection - IP address or Unix domain socket name.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ //
+ // Examples: "10.1.2.80", "/tmp/my.sock"
+ NetworkLocalAddressKey = attribute.Key("network.local.address")
+
+ // NetworkLocalPortKey is the attribute Key conforming to the
+ // "network.local.port" semantic conventions. It represents the local port
+ // number of the network connection.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ //
+ // Examples: 65123
+ NetworkLocalPortKey = attribute.Key("network.local.port")
+
+ // NetworkPeerAddressKey is the attribute Key conforming to the
+ // "network.peer.address" semantic conventions. It represents the peer address
+ // of the network connection - IP address or Unix domain socket name.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ //
+ // Examples: "10.1.2.80", "/tmp/my.sock"
+ NetworkPeerAddressKey = attribute.Key("network.peer.address")
+
+ // NetworkPeerPortKey is the attribute Key conforming to the "network.peer.port"
+ // semantic conventions. It represents the peer port number of the network
+ // connection.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ //
+ // Examples: 65123
+ NetworkPeerPortKey = attribute.Key("network.peer.port")
+
+ // NetworkProtocolNameKey is the attribute Key conforming to the
+ // "network.protocol.name" semantic conventions. It represents the
+ // [OSI application layer] or non-OSI equivalent.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ //
+ // Examples: "amqp", "http", "mqtt"
+ // Note: The value SHOULD be normalized to lowercase.
+ //
+ // [OSI application layer]: https://wikipedia.org/wiki/Application_layer
+ NetworkProtocolNameKey = attribute.Key("network.protocol.name")
+
+ // NetworkProtocolVersionKey is the attribute Key conforming to the
+ // "network.protocol.version" semantic conventions. It represents the actual
+ // version of the protocol used for network communication.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ //
+ // Examples: "1.1", "2"
+ // Note: If protocol version is subject to negotiation (for example using [ALPN]
+ // ), this attribute SHOULD be set to the negotiated version. If the actual
+ // protocol version is not known, this attribute SHOULD NOT be set.
+ //
+ // [ALPN]: https://www.rfc-editor.org/rfc/rfc7301.html
+ NetworkProtocolVersionKey = attribute.Key("network.protocol.version")
+
+ // NetworkTransportKey is the attribute Key conforming to the
+ // "network.transport" semantic conventions. It represents the
+ // [OSI transport layer] or [inter-process communication method].
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ //
+ // Examples: "tcp", "udp"
+ // Note: The value SHOULD be normalized to lowercase.
+ //
+ // Consider always setting the transport when setting a port number, since
+ // a port number is ambiguous without knowing the transport. For example
+ // different processes could be listening on TCP port 12345 and UDP port 12345.
+ //
+ // [OSI transport layer]: https://wikipedia.org/wiki/Transport_layer
+ // [inter-process communication method]: https://wikipedia.org/wiki/Inter-process_communication
+ NetworkTransportKey = attribute.Key("network.transport")
+
+ // NetworkTypeKey is the attribute Key conforming to the "network.type" semantic
+ // conventions. It represents the [OSI network layer] or non-OSI equivalent.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ //
+ // Examples: "ipv4", "ipv6"
+ // Note: The value SHOULD be normalized to lowercase.
+ //
+ // [OSI network layer]: https://wikipedia.org/wiki/Network_layer
+ NetworkTypeKey = attribute.Key("network.type")
+)
+
+// NetworkCarrierICC returns an attribute KeyValue conforming to the
+// "network.carrier.icc" semantic conventions. It represents the ISO 3166-1
+// alpha-2 2-character country code associated with the mobile carrier network.
+func NetworkCarrierICC(val string) attribute.KeyValue {
+ return NetworkCarrierICCKey.String(val)
+}
+
+// NetworkCarrierMCC returns an attribute KeyValue conforming to the
+// "network.carrier.mcc" semantic conventions. It represents the mobile carrier
+// country code.
+func NetworkCarrierMCC(val string) attribute.KeyValue {
+ return NetworkCarrierMCCKey.String(val)
+}
+
+// NetworkCarrierMNC returns an attribute KeyValue conforming to the
+// "network.carrier.mnc" semantic conventions. It represents the mobile carrier
+// network code.
+func NetworkCarrierMNC(val string) attribute.KeyValue {
+ return NetworkCarrierMNCKey.String(val)
+}
+
+// NetworkCarrierName returns an attribute KeyValue conforming to the
+// "network.carrier.name" semantic conventions. It represents the name of the
+// mobile carrier.
+func NetworkCarrierName(val string) attribute.KeyValue {
+ return NetworkCarrierNameKey.String(val)
+}
+
+// NetworkInterfaceName returns an attribute KeyValue conforming to the
+// "network.interface.name" semantic conventions. It represents the network
+// interface name.
+func NetworkInterfaceName(val string) attribute.KeyValue {
+ return NetworkInterfaceNameKey.String(val)
+}
+
+// NetworkLocalAddress returns an attribute KeyValue conforming to the
+// "network.local.address" semantic conventions. It represents the local address
+// of the network connection - IP address or Unix domain socket name.
+func NetworkLocalAddress(val string) attribute.KeyValue {
+ return NetworkLocalAddressKey.String(val)
+}
+
+// NetworkLocalPort returns an attribute KeyValue conforming to the
+// "network.local.port" semantic conventions. It represents the local port number
+// of the network connection.
+func NetworkLocalPort(val int) attribute.KeyValue {
+ return NetworkLocalPortKey.Int(val)
+}
+
+// NetworkPeerAddress returns an attribute KeyValue conforming to the
+// "network.peer.address" semantic conventions. It represents the peer address of
+// the network connection - IP address or Unix domain socket name.
+func NetworkPeerAddress(val string) attribute.KeyValue {
+ return NetworkPeerAddressKey.String(val)
+}
+
+// NetworkPeerPort returns an attribute KeyValue conforming to the
+// "network.peer.port" semantic conventions. It represents the peer port number
+// of the network connection.
+func NetworkPeerPort(val int) attribute.KeyValue {
+ return NetworkPeerPortKey.Int(val)
+}
+
+// NetworkProtocolName returns an attribute KeyValue conforming to the
+// "network.protocol.name" semantic conventions. It represents the
+// [OSI application layer] or non-OSI equivalent.
+//
+// [OSI application layer]: https://wikipedia.org/wiki/Application_layer
+func NetworkProtocolName(val string) attribute.KeyValue {
+ return NetworkProtocolNameKey.String(val)
+}
+
+// NetworkProtocolVersion returns an attribute KeyValue conforming to the
+// "network.protocol.version" semantic conventions. It represents the actual
+// version of the protocol used for network communication.
+func NetworkProtocolVersion(val string) attribute.KeyValue {
+ return NetworkProtocolVersionKey.String(val)
+}
+
+// Enum values for network.connection.state
+var (
+ // closed
+ // Stability: development
+ NetworkConnectionStateClosed = NetworkConnectionStateKey.String("closed")
+ // close_wait
+ // Stability: development
+ NetworkConnectionStateCloseWait = NetworkConnectionStateKey.String("close_wait")
+ // closing
+ // Stability: development
+ NetworkConnectionStateClosing = NetworkConnectionStateKey.String("closing")
+ // established
+ // Stability: development
+ NetworkConnectionStateEstablished = NetworkConnectionStateKey.String("established")
+ // fin_wait_1
+ // Stability: development
+ NetworkConnectionStateFinWait1 = NetworkConnectionStateKey.String("fin_wait_1")
+ // fin_wait_2
+ // Stability: development
+ NetworkConnectionStateFinWait2 = NetworkConnectionStateKey.String("fin_wait_2")
+ // last_ack
+ // Stability: development
+ NetworkConnectionStateLastAck = NetworkConnectionStateKey.String("last_ack")
+ // listen
+ // Stability: development
+ NetworkConnectionStateListen = NetworkConnectionStateKey.String("listen")
+ // syn_received
+ // Stability: development
+ NetworkConnectionStateSynReceived = NetworkConnectionStateKey.String("syn_received")
+ // syn_sent
+ // Stability: development
+ NetworkConnectionStateSynSent = NetworkConnectionStateKey.String("syn_sent")
+ // time_wait
+ // Stability: development
+ NetworkConnectionStateTimeWait = NetworkConnectionStateKey.String("time_wait")
+)
+
+// Enum values for network.connection.subtype
+var (
+ // GPRS
+ // Stability: development
+ NetworkConnectionSubtypeGprs = NetworkConnectionSubtypeKey.String("gprs")
+ // EDGE
+ // Stability: development
+ NetworkConnectionSubtypeEdge = NetworkConnectionSubtypeKey.String("edge")
+ // UMTS
+ // Stability: development
+ NetworkConnectionSubtypeUmts = NetworkConnectionSubtypeKey.String("umts")
+ // CDMA
+ // Stability: development
+ NetworkConnectionSubtypeCdma = NetworkConnectionSubtypeKey.String("cdma")
+ // EVDO Rel. 0
+ // Stability: development
+ NetworkConnectionSubtypeEvdo0 = NetworkConnectionSubtypeKey.String("evdo_0")
+ // EVDO Rev. A
+ // Stability: development
+ NetworkConnectionSubtypeEvdoA = NetworkConnectionSubtypeKey.String("evdo_a")
+ // CDMA2000 1XRTT
+ // Stability: development
+ NetworkConnectionSubtypeCdma20001xrtt = NetworkConnectionSubtypeKey.String("cdma2000_1xrtt")
+ // HSDPA
+ // Stability: development
+ NetworkConnectionSubtypeHsdpa = NetworkConnectionSubtypeKey.String("hsdpa")
+ // HSUPA
+ // Stability: development
+ NetworkConnectionSubtypeHsupa = NetworkConnectionSubtypeKey.String("hsupa")
+ // HSPA
+ // Stability: development
+ NetworkConnectionSubtypeHspa = NetworkConnectionSubtypeKey.String("hspa")
+ // IDEN
+ // Stability: development
+ NetworkConnectionSubtypeIden = NetworkConnectionSubtypeKey.String("iden")
+ // EVDO Rev. B
+ // Stability: development
+ NetworkConnectionSubtypeEvdoB = NetworkConnectionSubtypeKey.String("evdo_b")
+ // LTE
+ // Stability: development
+ NetworkConnectionSubtypeLte = NetworkConnectionSubtypeKey.String("lte")
+ // EHRPD
+ // Stability: development
+ NetworkConnectionSubtypeEhrpd = NetworkConnectionSubtypeKey.String("ehrpd")
+ // HSPAP
+ // Stability: development
+ NetworkConnectionSubtypeHspap = NetworkConnectionSubtypeKey.String("hspap")
+ // GSM
+ // Stability: development
+ NetworkConnectionSubtypeGsm = NetworkConnectionSubtypeKey.String("gsm")
+ // TD-SCDMA
+ // Stability: development
+ NetworkConnectionSubtypeTdScdma = NetworkConnectionSubtypeKey.String("td_scdma")
+ // IWLAN
+ // Stability: development
+ NetworkConnectionSubtypeIwlan = NetworkConnectionSubtypeKey.String("iwlan")
+ // 5G NR (New Radio)
+ // Stability: development
+ NetworkConnectionSubtypeNr = NetworkConnectionSubtypeKey.String("nr")
+ // 5G NRNSA (New Radio Non-Standalone)
+ // Stability: development
+ NetworkConnectionSubtypeNrnsa = NetworkConnectionSubtypeKey.String("nrnsa")
+ // LTE CA
+ // Stability: development
+ NetworkConnectionSubtypeLteCa = NetworkConnectionSubtypeKey.String("lte_ca")
+)
+
+// Enum values for network.connection.type
+var (
+ // wifi
+ // Stability: development
+ NetworkConnectionTypeWifi = NetworkConnectionTypeKey.String("wifi")
+ // wired
+ // Stability: development
+ NetworkConnectionTypeWired = NetworkConnectionTypeKey.String("wired")
+ // cell
+ // Stability: development
+ NetworkConnectionTypeCell = NetworkConnectionTypeKey.String("cell")
+ // unavailable
+ // Stability: development
+ NetworkConnectionTypeUnavailable = NetworkConnectionTypeKey.String("unavailable")
+ // unknown
+ // Stability: development
+ NetworkConnectionTypeUnknown = NetworkConnectionTypeKey.String("unknown")
+)
+
+// Enum values for network.io.direction
+var (
+ // transmit
+ // Stability: development
+ NetworkIODirectionTransmit = NetworkIODirectionKey.String("transmit")
+ // receive
+ // Stability: development
+ NetworkIODirectionReceive = NetworkIODirectionKey.String("receive")
+)
+
+// Enum values for network.transport
+var (
+ // TCP
+ // Stability: stable
+ NetworkTransportTCP = NetworkTransportKey.String("tcp")
+ // UDP
+ // Stability: stable
+ NetworkTransportUDP = NetworkTransportKey.String("udp")
+ // Named or anonymous pipe.
+ // Stability: stable
+ NetworkTransportPipe = NetworkTransportKey.String("pipe")
+ // Unix domain socket
+ // Stability: stable
+ NetworkTransportUnix = NetworkTransportKey.String("unix")
+ // QUIC
+ // Stability: stable
+ NetworkTransportQUIC = NetworkTransportKey.String("quic")
+)
+
+// Enum values for network.type
+var (
+ // IPv4
+ // Stability: stable
+ NetworkTypeIPv4 = NetworkTypeKey.String("ipv4")
+ // IPv6
+ // Stability: stable
+ NetworkTypeIPv6 = NetworkTypeKey.String("ipv6")
+)
+
+// Namespace: nfs
+const (
+ // NfsOperationNameKey is the attribute Key conforming to the
+ // "nfs.operation.name" semantic conventions. It represents the NFSv4+ operation
+ // name.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "OPEN", "READ", "GETATTR"
+ NfsOperationNameKey = attribute.Key("nfs.operation.name")
+
+ // NfsServerRepcacheStatusKey is the attribute Key conforming to the
+ // "nfs.server.repcache.status" semantic conventions. It represents the linux:
+ // one of "hit" (NFSD_STATS_RC_HITS), "miss" (NFSD_STATS_RC_MISSES), or
+ // "nocache" (NFSD_STATS_RC_NOCACHE -- uncacheable).
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: hit
+ NfsServerRepcacheStatusKey = attribute.Key("nfs.server.repcache.status")
+)
+
+// NfsOperationName returns an attribute KeyValue conforming to the
+// "nfs.operation.name" semantic conventions. It represents the NFSv4+ operation
+// name.
+func NfsOperationName(val string) attribute.KeyValue {
+ return NfsOperationNameKey.String(val)
+}
+
+// NfsServerRepcacheStatus returns an attribute KeyValue conforming to the
+// "nfs.server.repcache.status" semantic conventions. It represents the linux:
+// one of "hit" (NFSD_STATS_RC_HITS), "miss" (NFSD_STATS_RC_MISSES), or "nocache"
+// (NFSD_STATS_RC_NOCACHE -- uncacheable).
+func NfsServerRepcacheStatus(val string) attribute.KeyValue {
+ return NfsServerRepcacheStatusKey.String(val)
+}
+
+// Namespace: oci
+const (
+ // OCIManifestDigestKey is the attribute Key conforming to the
+ // "oci.manifest.digest" semantic conventions. It represents the digest of the
+ // OCI image manifest. For container images specifically is the digest by which
+ // the container image is known.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ // "sha256:e4ca62c0d62f3e886e684806dfe9d4e0cda60d54986898173c1083856cfda0f4"
+ // Note: Follows [OCI Image Manifest Specification], and specifically the
+ // [Digest property].
+ // An example can be found in [Example Image Manifest].
+ //
+ // [OCI Image Manifest Specification]: https://github.com/opencontainers/image-spec/blob/main/manifest.md
+ // [Digest property]: https://github.com/opencontainers/image-spec/blob/main/descriptor.md#digests
+ // [Example Image Manifest]: https://github.com/opencontainers/image-spec/blob/main/manifest.md#example-image-manifest
+ OCIManifestDigestKey = attribute.Key("oci.manifest.digest")
+)
+
+// OCIManifestDigest returns an attribute KeyValue conforming to the
+// "oci.manifest.digest" semantic conventions. It represents the digest of the
+// OCI image manifest. For container images specifically is the digest by which
+// the container image is known.
+func OCIManifestDigest(val string) attribute.KeyValue {
+ return OCIManifestDigestKey.String(val)
+}
+
+// Namespace: onc_rpc
+const (
+ // OncRPCProcedureNameKey is the attribute Key conforming to the
+ // "onc_rpc.procedure.name" semantic conventions. It represents the ONC/Sun RPC
+ // procedure name.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "OPEN", "READ", "GETATTR"
+ OncRPCProcedureNameKey = attribute.Key("onc_rpc.procedure.name")
+
+ // OncRPCProcedureNumberKey is the attribute Key conforming to the
+ // "onc_rpc.procedure.number" semantic conventions. It represents the ONC/Sun
+ // RPC procedure number.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ OncRPCProcedureNumberKey = attribute.Key("onc_rpc.procedure.number")
+
+ // OncRPCProgramNameKey is the attribute Key conforming to the
+ // "onc_rpc.program.name" semantic conventions. It represents the ONC/Sun RPC
+ // program name.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "portmapper", "nfs"
+ OncRPCProgramNameKey = attribute.Key("onc_rpc.program.name")
+
+ // OncRPCVersionKey is the attribute Key conforming to the "onc_rpc.version"
+ // semantic conventions. It represents the ONC/Sun RPC program version.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ OncRPCVersionKey = attribute.Key("onc_rpc.version")
+)
+
+// OncRPCProcedureName returns an attribute KeyValue conforming to the
+// "onc_rpc.procedure.name" semantic conventions. It represents the ONC/Sun RPC
+// procedure name.
+func OncRPCProcedureName(val string) attribute.KeyValue {
+ return OncRPCProcedureNameKey.String(val)
+}
+
+// OncRPCProcedureNumber returns an attribute KeyValue conforming to the
+// "onc_rpc.procedure.number" semantic conventions. It represents the ONC/Sun RPC
+// procedure number.
+func OncRPCProcedureNumber(val int) attribute.KeyValue {
+ return OncRPCProcedureNumberKey.Int(val)
+}
+
+// OncRPCProgramName returns an attribute KeyValue conforming to the
+// "onc_rpc.program.name" semantic conventions. It represents the ONC/Sun RPC
+// program name.
+func OncRPCProgramName(val string) attribute.KeyValue {
+ return OncRPCProgramNameKey.String(val)
+}
+
+// OncRPCVersion returns an attribute KeyValue conforming to the
+// "onc_rpc.version" semantic conventions. It represents the ONC/Sun RPC program
+// version.
+func OncRPCVersion(val int) attribute.KeyValue {
+ return OncRPCVersionKey.Int(val)
+}
+
+// Namespace: openai
+const (
+ // OpenAIAPITypeKey is the attribute Key conforming to the "openai.api.type"
+ // semantic conventions. It represents the type of OpenAI API being used.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ OpenAIAPITypeKey = attribute.Key("openai.api.type")
+
+ // OpenAIRequestServiceTierKey is the attribute Key conforming to the
+ // "openai.request.service_tier" semantic conventions. It represents the service
+ // tier requested. May be a specific tier, default, or auto.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "auto", "default"
+ OpenAIRequestServiceTierKey = attribute.Key("openai.request.service_tier")
+
+ // OpenAIResponseServiceTierKey is the attribute Key conforming to the
+ // "openai.response.service_tier" semantic conventions. It represents the
+ // service tier used for the response.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "scale", "default"
+ OpenAIResponseServiceTierKey = attribute.Key("openai.response.service_tier")
+
+ // OpenAIResponseSystemFingerprintKey is the attribute Key conforming to the
+ // "openai.response.system_fingerprint" semantic conventions. It represents a
+ // fingerprint to track any eventual change in the Generative AI environment.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "fp_44709d6fcb"
+ OpenAIResponseSystemFingerprintKey = attribute.Key("openai.response.system_fingerprint")
+)
+
+// OpenAIResponseServiceTier returns an attribute KeyValue conforming to the
+// "openai.response.service_tier" semantic conventions. It represents the service
+// tier used for the response.
+func OpenAIResponseServiceTier(val string) attribute.KeyValue {
+ return OpenAIResponseServiceTierKey.String(val)
+}
+
+// OpenAIResponseSystemFingerprint returns an attribute KeyValue conforming to
+// the "openai.response.system_fingerprint" semantic conventions. It represents a
+// fingerprint to track any eventual change in the Generative AI environment.
+func OpenAIResponseSystemFingerprint(val string) attribute.KeyValue {
+ return OpenAIResponseSystemFingerprintKey.String(val)
+}
+
+// Enum values for openai.api.type
+var (
+ // The OpenAI [Chat Completions API].
+ // Stability: development
+ //
+ // [Chat Completions API]: https://developers.openai.com/api/reference/chat-completions/overview
+ OpenAIAPITypeChatCompletions = OpenAIAPITypeKey.String("chat_completions")
+ // The OpenAI [Responses API].
+ // Stability: development
+ //
+ // [Responses API]: https://developers.openai.com/api/reference/responses/overview
+ OpenAIAPITypeResponses = OpenAIAPITypeKey.String("responses")
+)
+
+// Enum values for openai.request.service_tier
+var (
+ // The system will utilize scale tier credits until they are exhausted.
+ // Stability: development
+ OpenAIRequestServiceTierAuto = OpenAIRequestServiceTierKey.String("auto")
+ // The system will utilize the default scale tier.
+ // Stability: development
+ OpenAIRequestServiceTierDefault = OpenAIRequestServiceTierKey.String("default")
+)
+
+// Namespace: openshift
+const (
+ // OpenShiftClusterquotaNameKey is the attribute Key conforming to the
+ // "openshift.clusterquota.name" semantic conventions. It represents the name of
+ // the cluster quota.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "opentelemetry"
+ OpenShiftClusterquotaNameKey = attribute.Key("openshift.clusterquota.name")
+
+ // OpenShiftClusterquotaUIDKey is the attribute Key conforming to the
+ // "openshift.clusterquota.uid" semantic conventions. It represents the UID of
+ // the cluster quota.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "275ecb36-5aa8-4c2a-9c47-d8bb681b9aff"
+ OpenShiftClusterquotaUIDKey = attribute.Key("openshift.clusterquota.uid")
+)
+
+// OpenShiftClusterquotaName returns an attribute KeyValue conforming to the
+// "openshift.clusterquota.name" semantic conventions. It represents the name of
+// the cluster quota.
+func OpenShiftClusterquotaName(val string) attribute.KeyValue {
+ return OpenShiftClusterquotaNameKey.String(val)
+}
+
+// OpenShiftClusterquotaUID returns an attribute KeyValue conforming to the
+// "openshift.clusterquota.uid" semantic conventions. It represents the UID of
+// the cluster quota.
+func OpenShiftClusterquotaUID(val string) attribute.KeyValue {
+ return OpenShiftClusterquotaUIDKey.String(val)
+}
+
+// Namespace: opentracing
+const (
+ // OpenTracingRefTypeKey is the attribute Key conforming to the
+ // "opentracing.ref_type" semantic conventions. It represents the parent-child
+ // Reference type.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ // Note: The causal relationship between a child Span and a parent Span.
+ OpenTracingRefTypeKey = attribute.Key("opentracing.ref_type")
+)
+
+// Enum values for opentracing.ref_type
+var (
+ // The parent Span depends on the child Span in some capacity
+ // Stability: development
+ OpenTracingRefTypeChildOf = OpenTracingRefTypeKey.String("child_of")
+ // The parent Span doesn't depend in any way on the result of the child Span
+ // Stability: development
+ OpenTracingRefTypeFollowsFrom = OpenTracingRefTypeKey.String("follows_from")
+)
+
+// Namespace: oracle
+const (
+ // OracleDBDomainKey is the attribute Key conforming to the "oracle.db.domain"
+ // semantic conventions. It represents the database domain associated with the
+ // connection.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "example.com", "corp.internal", "prod.db.local"
+ // Note: This attribute SHOULD be set to the value of the `DB_DOMAIN`
+ // initialization parameter,
+ // as exposed in `v$parameter`. `DB_DOMAIN` defines the domain portion of the
+ // global
+ // database name and SHOULD be configured when a database is, or may become,
+ // part of a
+ // distributed environment. Its value consists of one or more valid identifiers
+ // (alphanumeric ASCII characters) separated by periods.
+ OracleDBDomainKey = attribute.Key("oracle.db.domain")
+
+ // OracleDBInstanceNameKey is the attribute Key conforming to the
+ // "oracle.db.instance.name" semantic conventions. It represents the instance
+ // name associated with the connection in an Oracle Real Application Clusters
+ // environment.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "ORCL1", "ORCL2", "ORCL3"
+ // Note: There can be multiple instances associated with a single database
+ // service. It indicates the
+ // unique instance name to which the connection is currently bound. For non-RAC
+ // databases, this value
+ // defaults to the `oracle.db.name`.
+ OracleDBInstanceNameKey = attribute.Key("oracle.db.instance.name")
+
+ // OracleDBNameKey is the attribute Key conforming to the "oracle.db.name"
+ // semantic conventions. It represents the database name associated with the
+ // connection.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "ORCL1", "FREE"
+ // Note: This attribute SHOULD be set to the value of the parameter `DB_NAME`
+ // exposed in `v$parameter`.
+ OracleDBNameKey = attribute.Key("oracle.db.name")
+
+ // OracleDBPdbKey is the attribute Key conforming to the "oracle.db.pdb"
+ // semantic conventions. It represents the pluggable database (PDB) name
+ // associated with the connection.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "PDB1", "FREEPDB"
+ // Note: This attribute SHOULD reflect the PDB that the session is currently
+ // connected to.
+ // If instrumentation cannot reliably obtain the active PDB name for each
+ // operation
+ // without issuing an additional query (such as `SELECT SYS_CONTEXT`), it is
+ // RECOMMENDED to fall back to the PDB name specified at connection
+ // establishment.
+ OracleDBPdbKey = attribute.Key("oracle.db.pdb")
+
+ // OracleDBServiceKey is the attribute Key conforming to the "oracle.db.service"
+ // semantic conventions. It represents the service name currently associated
+ // with the database connection.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "order-processing-service", "db_low.adb.oraclecloud.com",
+ // "db_high.adb.oraclecloud.com"
+ // Note: The effective service name for a connection can change during its
+ // lifetime,
+ // for example after executing sql, `ALTER SESSION`. If an instrumentation
+ // cannot reliably
+ // obtain the current service name for each operation without issuing an
+ // additional
+ // query (such as `SELECT SYS_CONTEXT`), it is RECOMMENDED to fall back to the
+ // service name originally provided at connection establishment.
+ OracleDBServiceKey = attribute.Key("oracle.db.service")
+)
+
+// OracleDBDomain returns an attribute KeyValue conforming to the
+// "oracle.db.domain" semantic conventions. It represents the database domain
+// associated with the connection.
+func OracleDBDomain(val string) attribute.KeyValue {
+ return OracleDBDomainKey.String(val)
+}
+
+// OracleDBInstanceName returns an attribute KeyValue conforming to the
+// "oracle.db.instance.name" semantic conventions. It represents the instance
+// name associated with the connection in an Oracle Real Application Clusters
+// environment.
+func OracleDBInstanceName(val string) attribute.KeyValue {
+ return OracleDBInstanceNameKey.String(val)
+}
+
+// OracleDBName returns an attribute KeyValue conforming to the "oracle.db.name"
+// semantic conventions. It represents the database name associated with the
+// connection.
+func OracleDBName(val string) attribute.KeyValue {
+ return OracleDBNameKey.String(val)
+}
+
+// OracleDBPdb returns an attribute KeyValue conforming to the "oracle.db.pdb"
+// semantic conventions. It represents the pluggable database (PDB) name
+// associated with the connection.
+func OracleDBPdb(val string) attribute.KeyValue {
+ return OracleDBPdbKey.String(val)
+}
+
+// OracleDBService returns an attribute KeyValue conforming to the
+// "oracle.db.service" semantic conventions. It represents the service name
+// currently associated with the database connection.
+func OracleDBService(val string) attribute.KeyValue {
+ return OracleDBServiceKey.String(val)
+}
+
+// Namespace: oracle_cloud
+const (
+ // OracleCloudRealmKey is the attribute Key conforming to the
+ // "oracle_cloud.realm" semantic conventions. It represents the OCI realm
+ // identifier that indicates the isolated partition in which the tenancy and its
+ // resources reside.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "oc1", "oc2"
+ // Note: See [OCI documentation on realms]
+ //
+ // [OCI documentation on realms]: https://docs.oracle.com/iaas/Content/General/Concepts/regions.htm
+ OracleCloudRealmKey = attribute.Key("oracle_cloud.realm")
+)
+
+// OracleCloudRealm returns an attribute KeyValue conforming to the
+// "oracle_cloud.realm" semantic conventions. It represents the OCI realm
+// identifier that indicates the isolated partition in which the tenancy and its
+// resources reside.
+func OracleCloudRealm(val string) attribute.KeyValue {
+ return OracleCloudRealmKey.String(val)
+}
+
+// Namespace: os
+const (
+ // OSBuildIDKey is the attribute Key conforming to the "os.build_id" semantic
+ // conventions. It represents the unique identifier for a particular build or
+ // compilation of the operating system.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "TQ3C.230805.001.B2", "20E247", "22621"
+ OSBuildIDKey = attribute.Key("os.build_id")
+
+ // OSDescriptionKey is the attribute Key conforming to the "os.description"
+ // semantic conventions. It represents the human readable (not intended to be
+ // parsed) OS version information, like e.g. reported by `ver` or
+ // `lsb_release -a` commands.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "Microsoft Windows [Version 10.0.18363.778]", "Ubuntu 18.04.1 LTS"
+ OSDescriptionKey = attribute.Key("os.description")
+
+ // OSNameKey is the attribute Key conforming to the "os.name" semantic
+ // conventions. It represents the human readable operating system name.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "iOS", "Android", "Ubuntu"
+ OSNameKey = attribute.Key("os.name")
+
+ // OSTypeKey is the attribute Key conforming to the "os.type" semantic
+ // conventions. It represents the operating system type.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ OSTypeKey = attribute.Key("os.type")
+
+ // OSVersionKey is the attribute Key conforming to the "os.version" semantic
+ // conventions. It represents the version string of the operating system as
+ // defined in [Version Attributes].
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "14.2.1", "18.04.1"
+ //
+ // [Version Attributes]: /docs/resource/README.md#version-attributes
+ OSVersionKey = attribute.Key("os.version")
+)
+
+// OSBuildID returns an attribute KeyValue conforming to the "os.build_id"
+// semantic conventions. It represents the unique identifier for a particular
+// build or compilation of the operating system.
+func OSBuildID(val string) attribute.KeyValue {
+ return OSBuildIDKey.String(val)
+}
+
+// OSDescription returns an attribute KeyValue conforming to the "os.description"
+// semantic conventions. It represents the human readable (not intended to be
+// parsed) OS version information, like e.g. reported by `ver` or
+// `lsb_release -a` commands.
+func OSDescription(val string) attribute.KeyValue {
+ return OSDescriptionKey.String(val)
+}
+
+// OSName returns an attribute KeyValue conforming to the "os.name" semantic
+// conventions. It represents the human readable operating system name.
+func OSName(val string) attribute.KeyValue {
+ return OSNameKey.String(val)
+}
+
+// OSVersion returns an attribute KeyValue conforming to the "os.version"
+// semantic conventions. It represents the version string of the operating system
+// as defined in [Version Attributes].
+//
+// [Version Attributes]: /docs/resource/README.md#version-attributes
+func OSVersion(val string) attribute.KeyValue {
+ return OSVersionKey.String(val)
+}
+
+// Enum values for os.type
+var (
+ // Microsoft Windows
+ // Stability: development
+ OSTypeWindows = OSTypeKey.String("windows")
+ // Linux
+ // Stability: development
+ OSTypeLinux = OSTypeKey.String("linux")
+ // Apple Darwin
+ // Stability: development
+ OSTypeDarwin = OSTypeKey.String("darwin")
+ // FreeBSD
+ // Stability: development
+ OSTypeFreeBSD = OSTypeKey.String("freebsd")
+ // NetBSD
+ // Stability: development
+ OSTypeNetBSD = OSTypeKey.String("netbsd")
+ // OpenBSD
+ // Stability: development
+ OSTypeOpenBSD = OSTypeKey.String("openbsd")
+ // DragonFly BSD
+ // Stability: development
+ OSTypeDragonflyBSD = OSTypeKey.String("dragonflybsd")
+ // HP-UX (Hewlett Packard Unix)
+ // Stability: development
+ OSTypeHPUX = OSTypeKey.String("hpux")
+ // AIX (Advanced Interactive eXecutive)
+ // Stability: development
+ OSTypeAIX = OSTypeKey.String("aix")
+ // SunOS, Oracle Solaris
+ // Stability: development
+ OSTypeSolaris = OSTypeKey.String("solaris")
+ // IBM z/OS
+ // Stability: development
+ OSTypeZOS = OSTypeKey.String("zos")
+)
+
+// Namespace: otel
+const (
+ // OTelComponentNameKey is the attribute Key conforming to the
+ // "otel.component.name" semantic conventions. It represents a name uniquely
+ // identifying the instance of the OpenTelemetry component within its containing
+ // SDK instance.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "otlp_grpc_span_exporter/0", "custom-name"
+ // Note: Implementations SHOULD ensure a low cardinality for this attribute,
+ // even across application or SDK restarts.
+ // E.g. implementations MUST NOT use UUIDs as values for this attribute.
+ //
+ // Implementations MAY achieve these goals by following a
+ // `/` pattern, e.g.
+ // `batching_span_processor/0`.
+ // Hereby `otel.component.type` refers to the corresponding attribute value of
+ // the component.
+ //
+ // The value of `instance-counter` MAY be automatically assigned by the
+ // component and uniqueness within the enclosing SDK instance MUST be
+ // guaranteed.
+ // For example, `` MAY be implemented by using a monotonically
+ // increasing counter (starting with `0`), which is incremented every time an
+ // instance of the given component type is started.
+ //
+ // With this implementation, for example the first Batching Span Processor would
+ // have `batching_span_processor/0`
+ // as `otel.component.name`, the second one `batching_span_processor/1` and so
+ // on.
+ // These values will therefore be reused in the case of an application restart.
+ OTelComponentNameKey = attribute.Key("otel.component.name")
+
+ // OTelComponentTypeKey is the attribute Key conforming to the
+ // "otel.component.type" semantic conventions. It represents a name identifying
+ // the type of the OpenTelemetry component.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "batching_span_processor", "com.example.MySpanExporter"
+ // Note: If none of the standardized values apply, implementations SHOULD use
+ // the language-defined name of the type.
+ // E.g. for Java the fully qualified classname SHOULD be used in this case.
+ OTelComponentTypeKey = attribute.Key("otel.component.type")
+
+ // OTelEventNameKey is the attribute Key conforming to the "otel.event.name"
+ // semantic conventions. It represents the identifies the class / type of event.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ //
+ // Examples: "browser.mouse.click", "device.app.lifecycle"
+ // Note: This attribute SHOULD be used by non-OTLP exporters when destination
+ // does not support `EventName` or equivalent field. This attribute MAY be used
+ // by applications using existing logging libraries so that it can be used to
+ // set the `EventName` field by Collector or SDK components.
+ OTelEventNameKey = attribute.Key("otel.event.name")
+
+ // OTelScopeNameKey is the attribute Key conforming to the "otel.scope.name"
+ // semantic conventions. It represents the name of the instrumentation scope - (
+ // `InstrumentationScope.Name` in OTLP).
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ //
+ // Examples: "io.opentelemetry.contrib.mongodb"
+ OTelScopeNameKey = attribute.Key("otel.scope.name")
+
+ // OTelScopeSchemaURLKey is the attribute Key conforming to the
+ // "otel.scope.schema_url" semantic conventions. It represents the schema URL of
+ // the instrumentation scope.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "https://opentelemetry.io/schemas/1.31.0"
+ OTelScopeSchemaURLKey = attribute.Key("otel.scope.schema_url")
+
+ // OTelScopeVersionKey is the attribute Key conforming to the
+ // "otel.scope.version" semantic conventions. It represents the version of the
+ // instrumentation scope - (`InstrumentationScope.Version` in OTLP).
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ //
+ // Examples: "1.0.0"
+ OTelScopeVersionKey = attribute.Key("otel.scope.version")
+
+ // OTelSpanParentOriginKey is the attribute Key conforming to the
+ // "otel.span.parent.origin" semantic conventions. It represents the determines
+ // whether the span has a parent span, and if so,
+ // [whether it is a remote parent].
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ //
+ // [whether it is a remote parent]: https://opentelemetry.io/docs/specs/otel/trace/api/#isremote
+ OTelSpanParentOriginKey = attribute.Key("otel.span.parent.origin")
+
+ // OTelSpanSamplingResultKey is the attribute Key conforming to the
+ // "otel.span.sampling_result" semantic conventions. It represents the result
+ // value of the sampler for this span.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ OTelSpanSamplingResultKey = attribute.Key("otel.span.sampling_result")
+
+ // OTelStatusCodeKey is the attribute Key conforming to the "otel.status_code"
+ // semantic conventions. It represents the name of the code, either "OK" or
+ // "ERROR". MUST NOT be set if the status code is UNSET.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ //
+ // Examples:
+ OTelStatusCodeKey = attribute.Key("otel.status_code")
+
+ // OTelStatusDescriptionKey is the attribute Key conforming to the
+ // "otel.status_description" semantic conventions. It represents the description
+ // of the Status if it has a value, otherwise not set.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ //
+ // Examples: "resource not found"
+ OTelStatusDescriptionKey = attribute.Key("otel.status_description")
+)
+
+// OTelComponentName returns an attribute KeyValue conforming to the
+// "otel.component.name" semantic conventions. It represents a name uniquely
+// identifying the instance of the OpenTelemetry component within its containing
+// SDK instance.
+func OTelComponentName(val string) attribute.KeyValue {
+ return OTelComponentNameKey.String(val)
+}
+
+// OTelEventName returns an attribute KeyValue conforming to the
+// "otel.event.name" semantic conventions. It represents the identifies the class
+// / type of event.
+func OTelEventName(val string) attribute.KeyValue {
+ return OTelEventNameKey.String(val)
+}
+
+// OTelScopeName returns an attribute KeyValue conforming to the
+// "otel.scope.name" semantic conventions. It represents the name of the
+// instrumentation scope - (`InstrumentationScope.Name` in OTLP).
+func OTelScopeName(val string) attribute.KeyValue {
+ return OTelScopeNameKey.String(val)
+}
+
+// OTelScopeSchemaURL returns an attribute KeyValue conforming to the
+// "otel.scope.schema_url" semantic conventions. It represents the schema URL of
+// the instrumentation scope.
+func OTelScopeSchemaURL(val string) attribute.KeyValue {
+ return OTelScopeSchemaURLKey.String(val)
+}
+
+// OTelScopeVersion returns an attribute KeyValue conforming to the
+// "otel.scope.version" semantic conventions. It represents the version of the
+// instrumentation scope - (`InstrumentationScope.Version` in OTLP).
+func OTelScopeVersion(val string) attribute.KeyValue {
+ return OTelScopeVersionKey.String(val)
+}
+
+// OTelStatusDescription returns an attribute KeyValue conforming to the
+// "otel.status_description" semantic conventions. It represents the description
+// of the Status if it has a value, otherwise not set.
+func OTelStatusDescription(val string) attribute.KeyValue {
+ return OTelStatusDescriptionKey.String(val)
+}
+
+// Enum values for otel.component.type
+var (
+ // The builtin SDK batching span processor
+ //
+ // Stability: development
+ OTelComponentTypeBatchingSpanProcessor = OTelComponentTypeKey.String("batching_span_processor")
+ // The builtin SDK simple span processor
+ //
+ // Stability: development
+ OTelComponentTypeSimpleSpanProcessor = OTelComponentTypeKey.String("simple_span_processor")
+ // The builtin SDK batching log record processor
+ //
+ // Stability: development
+ OTelComponentTypeBatchingLogProcessor = OTelComponentTypeKey.String("batching_log_processor")
+ // The builtin SDK simple log record processor
+ //
+ // Stability: development
+ OTelComponentTypeSimpleLogProcessor = OTelComponentTypeKey.String("simple_log_processor")
+ // OTLP span exporter over gRPC with protobuf serialization
+ //
+ // Stability: development
+ OTelComponentTypeOtlpGRPCSpanExporter = OTelComponentTypeKey.String("otlp_grpc_span_exporter")
+ // OTLP span exporter over HTTP with protobuf serialization
+ //
+ // Stability: development
+ OTelComponentTypeOtlpHTTPSpanExporter = OTelComponentTypeKey.String("otlp_http_span_exporter")
+ // OTLP span exporter over HTTP with JSON serialization
+ //
+ // Stability: development
+ OTelComponentTypeOtlpHTTPJSONSpanExporter = OTelComponentTypeKey.String("otlp_http_json_span_exporter")
+ // Zipkin span exporter over HTTP
+ //
+ // Stability: development
+ OTelComponentTypeZipkinHTTPSpanExporter = OTelComponentTypeKey.String("zipkin_http_span_exporter")
+ // OTLP log record exporter over gRPC with protobuf serialization
+ //
+ // Stability: development
+ OTelComponentTypeOtlpGRPCLogExporter = OTelComponentTypeKey.String("otlp_grpc_log_exporter")
+ // OTLP log record exporter over HTTP with protobuf serialization
+ //
+ // Stability: development
+ OTelComponentTypeOtlpHTTPLogExporter = OTelComponentTypeKey.String("otlp_http_log_exporter")
+ // OTLP log record exporter over HTTP with JSON serialization
+ //
+ // Stability: development
+ OTelComponentTypeOtlpHTTPJSONLogExporter = OTelComponentTypeKey.String("otlp_http_json_log_exporter")
+ // The builtin SDK periodically exporting metric reader
+ //
+ // Stability: development
+ OTelComponentTypePeriodicMetricReader = OTelComponentTypeKey.String("periodic_metric_reader")
+ // OTLP metric exporter over gRPC with protobuf serialization
+ //
+ // Stability: development
+ OTelComponentTypeOtlpGRPCMetricExporter = OTelComponentTypeKey.String("otlp_grpc_metric_exporter")
+ // OTLP metric exporter over HTTP with protobuf serialization
+ //
+ // Stability: development
+ OTelComponentTypeOtlpHTTPMetricExporter = OTelComponentTypeKey.String("otlp_http_metric_exporter")
+ // OTLP metric exporter over HTTP with JSON serialization
+ //
+ // Stability: development
+ OTelComponentTypeOtlpHTTPJSONMetricExporter = OTelComponentTypeKey.String("otlp_http_json_metric_exporter")
+ // Prometheus metric exporter over HTTP with the default text-based format
+ //
+ // Stability: development
+ OTelComponentTypePrometheusHTTPTextMetricExporter = OTelComponentTypeKey.String("prometheus_http_text_metric_exporter")
+)
+
+// Enum values for otel.span.parent.origin
+var (
+ // The span does not have a parent, it is a root span
+ // Stability: development
+ OTelSpanParentOriginNone = OTelSpanParentOriginKey.String("none")
+ // The span has a parent and the parent's span context [isRemote()] is false
+ // Stability: development
+ //
+ // [isRemote()]: https://opentelemetry.io/docs/specs/otel/trace/api/#isremote
+ OTelSpanParentOriginLocal = OTelSpanParentOriginKey.String("local")
+ // The span has a parent and the parent's span context [isRemote()] is true
+ // Stability: development
+ //
+ // [isRemote()]: https://opentelemetry.io/docs/specs/otel/trace/api/#isremote
+ OTelSpanParentOriginRemote = OTelSpanParentOriginKey.String("remote")
+)
+
+// Enum values for otel.span.sampling_result
+var (
+ // The span is not sampled and not recording
+ // Stability: development
+ OTelSpanSamplingResultDrop = OTelSpanSamplingResultKey.String("DROP")
+ // The span is not sampled, but recording
+ // Stability: development
+ OTelSpanSamplingResultRecordOnly = OTelSpanSamplingResultKey.String("RECORD_ONLY")
+ // The span is sampled and recording
+ // Stability: development
+ OTelSpanSamplingResultRecordAndSample = OTelSpanSamplingResultKey.String("RECORD_AND_SAMPLE")
+)
+
+// Enum values for otel.status_code
+var (
+ // The operation has been validated by an Application developer or Operator to
+ // have completed successfully.
+ // Stability: stable
+ OTelStatusCodeOk = OTelStatusCodeKey.String("OK")
+ // The operation contains an error.
+ // Stability: stable
+ OTelStatusCodeError = OTelStatusCodeKey.String("ERROR")
+)
+
+// Namespace: pprof
+const (
+ // PprofLocationIsFoldedKey is the attribute Key conforming to the
+ // "pprof.location.is_folded" semantic conventions. It represents the provides
+ // an indication that multiple symbols map to this location's address, for
+ // example due to identical code folding by the linker. In that case the line
+ // information represents one of the multiple symbols. This field must be
+ // recomputed when the symbolization state of the profile changes.
+ //
+ // Type: boolean
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ PprofLocationIsFoldedKey = attribute.Key("pprof.location.is_folded")
+
+ // PprofMappingHasFilenamesKey is the attribute Key conforming to the
+ // "pprof.mapping.has_filenames" semantic conventions. It represents the
+ // indicates that there are filenames related to this mapping.
+ //
+ // Type: boolean
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ PprofMappingHasFilenamesKey = attribute.Key("pprof.mapping.has_filenames")
+
+ // PprofMappingHasFunctionsKey is the attribute Key conforming to the
+ // "pprof.mapping.has_functions" semantic conventions. It represents the
+ // indicates that there are functions related to this mapping.
+ //
+ // Type: boolean
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ PprofMappingHasFunctionsKey = attribute.Key("pprof.mapping.has_functions")
+
+ // PprofMappingHasInlineFramesKey is the attribute Key conforming to the
+ // "pprof.mapping.has_inline_frames" semantic conventions. It represents the
+ // indicates that there are inline frames related to this mapping.
+ //
+ // Type: boolean
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ PprofMappingHasInlineFramesKey = attribute.Key("pprof.mapping.has_inline_frames")
+
+ // PprofMappingHasLineNumbersKey is the attribute Key conforming to the
+ // "pprof.mapping.has_line_numbers" semantic conventions. It represents the
+ // indicates that there are line numbers related to this mapping.
+ //
+ // Type: boolean
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ PprofMappingHasLineNumbersKey = attribute.Key("pprof.mapping.has_line_numbers")
+
+ // PprofProfileCommentKey is the attribute Key conforming to the
+ // "pprof.profile.comment" semantic conventions. It represents the free-form
+ // text associated with the profile. This field should not be used to store any
+ // machine-readable information, it is only for human-friendly content.
+ //
+ // Type: string[]
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "hello world", "bazinga"
+ PprofProfileCommentKey = attribute.Key("pprof.profile.comment")
+
+ // PprofProfileDocURLKey is the attribute Key conforming to the
+ // "pprof.profile.doc_url" semantic conventions. It represents the documentation
+ // link for this profile type.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "http://pprof.example.com/cpu-profile.html"
+ // Note: The URL must be absolute and may be missing if the profile was
+ // generated by code that did not supply a link
+ PprofProfileDocURLKey = attribute.Key("pprof.profile.doc_url")
+
+ // PprofProfileDropFramesKey is the attribute Key conforming to the
+ // "pprof.profile.drop_frames" semantic conventions. It represents the frames
+ // with Function.function_name fully matching the regexp will be dropped from
+ // the samples, along with their successors.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "/foobar/"
+ PprofProfileDropFramesKey = attribute.Key("pprof.profile.drop_frames")
+
+ // PprofProfileKeepFramesKey is the attribute Key conforming to the
+ // "pprof.profile.keep_frames" semantic conventions. It represents the frames
+ // with Function.function_name fully matching the regexp will be kept, even if
+ // it matches drop_frames.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "/bazinga/"
+ PprofProfileKeepFramesKey = attribute.Key("pprof.profile.keep_frames")
+
+ // PprofScopeDefaultSampleTypeKey is the attribute Key conforming to the
+ // "pprof.scope.default_sample_type" semantic conventions. It represents the
+ // records the pprof's default_sample_type in the original profile. Not set if
+ // the default sample type was missing.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "cpu"
+ // Note: This attribute, if present, MUST be set at the scope level
+ // (resource_profiles[].scope_profiles[].scope.attributes[]).
+ PprofScopeDefaultSampleTypeKey = attribute.Key("pprof.scope.default_sample_type")
+
+ // PprofScopeSampleTypeOrderKey is the attribute Key conforming to the
+ // "pprof.scope.sample_type_order" semantic conventions. It represents the
+ // records the indexes of the sample types in the original profile.
+ //
+ // Type: int[]
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 3, 0, 1, 2
+ // Note: This attribute, if present, MUST be set at the scope level
+ // (resource_profiles[].scope_profiles[].scope.attributes[]).
+ PprofScopeSampleTypeOrderKey = attribute.Key("pprof.scope.sample_type_order")
+)
+
+// PprofLocationIsFolded returns an attribute KeyValue conforming to the
+// "pprof.location.is_folded" semantic conventions. It represents the provides an
+// indication that multiple symbols map to this location's address, for example
+// due to identical code folding by the linker. In that case the line information
+// represents one of the multiple symbols. This field must be recomputed when the
+// symbolization state of the profile changes.
+func PprofLocationIsFolded(val bool) attribute.KeyValue {
+ return PprofLocationIsFoldedKey.Bool(val)
+}
+
+// PprofMappingHasFilenames returns an attribute KeyValue conforming to the
+// "pprof.mapping.has_filenames" semantic conventions. It represents the
+// indicates that there are filenames related to this mapping.
+func PprofMappingHasFilenames(val bool) attribute.KeyValue {
+ return PprofMappingHasFilenamesKey.Bool(val)
+}
+
+// PprofMappingHasFunctions returns an attribute KeyValue conforming to the
+// "pprof.mapping.has_functions" semantic conventions. It represents the
+// indicates that there are functions related to this mapping.
+func PprofMappingHasFunctions(val bool) attribute.KeyValue {
+ return PprofMappingHasFunctionsKey.Bool(val)
+}
+
+// PprofMappingHasInlineFrames returns an attribute KeyValue conforming to the
+// "pprof.mapping.has_inline_frames" semantic conventions. It represents the
+// indicates that there are inline frames related to this mapping.
+func PprofMappingHasInlineFrames(val bool) attribute.KeyValue {
+ return PprofMappingHasInlineFramesKey.Bool(val)
+}
+
+// PprofMappingHasLineNumbers returns an attribute KeyValue conforming to the
+// "pprof.mapping.has_line_numbers" semantic conventions. It represents the
+// indicates that there are line numbers related to this mapping.
+func PprofMappingHasLineNumbers(val bool) attribute.KeyValue {
+ return PprofMappingHasLineNumbersKey.Bool(val)
+}
+
+// PprofProfileComment returns an attribute KeyValue conforming to the
+// "pprof.profile.comment" semantic conventions. It represents the free-form text
+// associated with the profile. This field should not be used to store any
+// machine-readable information, it is only for human-friendly content.
+func PprofProfileComment(val ...string) attribute.KeyValue {
+ return PprofProfileCommentKey.StringSlice(val)
+}
+
+// PprofProfileDocURL returns an attribute KeyValue conforming to the
+// "pprof.profile.doc_url" semantic conventions. It represents the documentation
+// link for this profile type.
+func PprofProfileDocURL(val string) attribute.KeyValue {
+ return PprofProfileDocURLKey.String(val)
+}
+
+// PprofProfileDropFrames returns an attribute KeyValue conforming to the
+// "pprof.profile.drop_frames" semantic conventions. It represents the frames
+// with Function.function_name fully matching the regexp will be dropped from the
+// samples, along with their successors.
+func PprofProfileDropFrames(val string) attribute.KeyValue {
+ return PprofProfileDropFramesKey.String(val)
+}
+
+// PprofProfileKeepFrames returns an attribute KeyValue conforming to the
+// "pprof.profile.keep_frames" semantic conventions. It represents the frames
+// with Function.function_name fully matching the regexp will be kept, even if it
+// matches drop_frames.
+func PprofProfileKeepFrames(val string) attribute.KeyValue {
+ return PprofProfileKeepFramesKey.String(val)
+}
+
+// PprofScopeDefaultSampleType returns an attribute KeyValue conforming to the
+// "pprof.scope.default_sample_type" semantic conventions. It represents the
+// records the pprof's default_sample_type in the original profile. Not set if
+// the default sample type was missing.
+func PprofScopeDefaultSampleType(val string) attribute.KeyValue {
+ return PprofScopeDefaultSampleTypeKey.String(val)
+}
+
+// PprofScopeSampleTypeOrder returns an attribute KeyValue conforming to the
+// "pprof.scope.sample_type_order" semantic conventions. It represents the
+// records the indexes of the sample types in the original profile.
+func PprofScopeSampleTypeOrder(val ...int) attribute.KeyValue {
+ return PprofScopeSampleTypeOrderKey.IntSlice(val)
+}
+
+// Namespace: process
+const (
+ // ProcessArgsCountKey is the attribute Key conforming to the
+ // "process.args_count" semantic conventions. It represents the length of the
+ // process.command_args array.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 4
+ // Note: This field can be useful for querying or performing bucket analysis on
+ // how many arguments were provided to start a process. More arguments may be an
+ // indication of suspicious activity.
+ ProcessArgsCountKey = attribute.Key("process.args_count")
+
+ // ProcessCommandKey is the attribute Key conforming to the "process.command"
+ // semantic conventions. It represents the command used to launch the process
+ // (i.e. the command name). On Linux based systems, can be set to the zeroth
+ // string in `proc/[pid]/cmdline`. On Windows, can be set to the first parameter
+ // extracted from `GetCommandLineW`.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "cmd/otelcol"
+ ProcessCommandKey = attribute.Key("process.command")
+
+ // ProcessCommandArgsKey is the attribute Key conforming to the
+ // "process.command_args" semantic conventions. It represents the all the
+ // command arguments (including the command/executable itself) as received by
+ // the process. On Linux-based systems (and some other Unixoid systems
+ // supporting procfs), can be set according to the list of null-delimited
+ // strings extracted from `proc/[pid]/cmdline`. For libc-based executables, this
+ // would be the full argv vector passed to `main`. SHOULD NOT be collected by
+ // default unless there is sanitization that excludes sensitive data.
+ //
+ // Type: string[]
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "cmd/otecol", "--config=config.yaml"
+ ProcessCommandArgsKey = attribute.Key("process.command_args")
+
+ // ProcessCommandLineKey is the attribute Key conforming to the
+ // "process.command_line" semantic conventions. It represents the full command
+ // used to launch the process as a single string representing the full command.
+ // On Windows, can be set to the result of `GetCommandLineW`. Do not set this if
+ // you have to assemble it just for monitoring; use `process.command_args`
+ // instead. SHOULD NOT be collected by default unless there is sanitization that
+ // excludes sensitive data.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "C:\cmd\otecol --config="my directory\config.yaml""
+ ProcessCommandLineKey = attribute.Key("process.command_line")
+
+ // ProcessContextSwitchTypeKey is the attribute Key conforming to the
+ // "process.context_switch.type" semantic conventions. It represents the
+ // specifies whether the context switches for this data point were voluntary or
+ // involuntary.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ ProcessContextSwitchTypeKey = attribute.Key("process.context_switch.type")
+
+ // ProcessCreationTimeKey is the attribute Key conforming to the
+ // "process.creation.time" semantic conventions. It represents the date and time
+ // the process was created, in ISO 8601 format.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "2023-11-21T09:25:34.853Z"
+ ProcessCreationTimeKey = attribute.Key("process.creation.time")
+
+ // ProcessExecutableBuildIDGNUKey is the attribute Key conforming to the
+ // "process.executable.build_id.gnu" semantic conventions. It represents the GNU
+ // build ID as found in the `.note.gnu.build-id` ELF section (hex string).
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "c89b11207f6479603b0d49bf291c092c2b719293"
+ ProcessExecutableBuildIDGNUKey = attribute.Key("process.executable.build_id.gnu")
+
+ // ProcessExecutableBuildIDGoKey is the attribute Key conforming to the
+ // "process.executable.build_id.go" semantic conventions. It represents the Go
+ // build ID as retrieved by `go tool buildid `.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ // "foh3mEXu7BLZjsN9pOwG/kATcXlYVCDEFouRMQed_/WwRFB1hPo9LBkekthSPG/x8hMC8emW2cCjXD0_1aY"
+ ProcessExecutableBuildIDGoKey = attribute.Key("process.executable.build_id.go")
+
+ // ProcessExecutableBuildIDHtlhashKey is the attribute Key conforming to the
+ // "process.executable.build_id.htlhash" semantic conventions. It represents the
+ // deterministic build ID for executables.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "600DCAFE4A110000F2BF38C493F5FB92"
+ // Note: GNU and Go build IDs may be stripped or unavailable in some
+ // environments
+ // (e.g., Alpine Linux, Docker images). This attribute provides a deterministic
+ // build ID computed by hashing the first and last 4096 bytes of the file
+ // along with its length:
+ //
+ // ```
+ // Input ← Concat(File[:4096], File[-4096:], BigEndianUInt64(Len(File)))
+ // Digest ← SHA256(Input)
+ // BuildID ← Digest[:16]
+ // ```
+ //
+ // The result is the first 16 bytes (128 bits) of the SHA256 digest,
+ // represented as a hex string.
+ ProcessExecutableBuildIDHtlhashKey = attribute.Key("process.executable.build_id.htlhash")
+
+ // ProcessExecutableNameKey is the attribute Key conforming to the
+ // "process.executable.name" semantic conventions. It represents the name of the
+ // process executable. On Linux based systems, this SHOULD be set to the base
+ // name of the target of `/proc/[pid]/exe`. On Windows, this SHOULD be set to
+ // the base name of `GetProcessImageFileNameW`.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "otelcol"
+ ProcessExecutableNameKey = attribute.Key("process.executable.name")
+
+ // ProcessExecutablePathKey is the attribute Key conforming to the
+ // "process.executable.path" semantic conventions. It represents the full path
+ // to the process executable. On Linux based systems, can be set to the target
+ // of `proc/[pid]/exe`. On Windows, can be set to the result of
+ // `GetProcessImageFileNameW`.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "/usr/bin/cmd/otelcol"
+ ProcessExecutablePathKey = attribute.Key("process.executable.path")
+
+ // ProcessExitCodeKey is the attribute Key conforming to the "process.exit.code"
+ // semantic conventions. It represents the exit code of the process.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 127
+ ProcessExitCodeKey = attribute.Key("process.exit.code")
+
+ // ProcessExitTimeKey is the attribute Key conforming to the "process.exit.time"
+ // semantic conventions. It represents the date and time the process exited, in
+ // ISO 8601 format.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "2023-11-21T09:26:12.315Z"
+ ProcessExitTimeKey = attribute.Key("process.exit.time")
+
+ // ProcessGroupLeaderPIDKey is the attribute Key conforming to the
+ // "process.group_leader.pid" semantic conventions. It represents the PID of the
+ // process's group leader. This is also the process group ID (PGID) of the
+ // process.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 23
+ ProcessGroupLeaderPIDKey = attribute.Key("process.group_leader.pid")
+
+ // ProcessInteractiveKey is the attribute Key conforming to the
+ // "process.interactive" semantic conventions. It represents the whether the
+ // process is connected to an interactive shell.
+ //
+ // Type: boolean
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ ProcessInteractiveKey = attribute.Key("process.interactive")
+
+ // ProcessLinuxCgroupKey is the attribute Key conforming to the
+ // "process.linux.cgroup" semantic conventions. It represents the control group
+ // associated with the process.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "1:name=systemd:/user.slice/user-1000.slice/session-3.scope",
+ // "0::/user.slice/user-1000.slice/user@1000.service/tmux-spawn-0267755b-4639-4a27-90ed-f19f88e53748.scope"
+ // Note: Control groups (cgroups) are a kernel feature used to organize and
+ // manage process resources. This attribute provides the path(s) to the
+ // cgroup(s) associated with the process, which should match the contents of the
+ // [/proc/[PID]/cgroup] file.
+ //
+ // [/proc/[PID]/cgroup]: https://man7.org/linux/man-pages/man7/cgroups.7.html
+ ProcessLinuxCgroupKey = attribute.Key("process.linux.cgroup")
+
+ // ProcessOwnerKey is the attribute Key conforming to the "process.owner"
+ // semantic conventions. It represents the username of the user that owns the
+ // process.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "root"
+ ProcessOwnerKey = attribute.Key("process.owner")
+
+ // ProcessParentPIDKey is the attribute Key conforming to the
+ // "process.parent_pid" semantic conventions. It represents the parent Process
+ // identifier (PPID).
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 111
+ ProcessParentPIDKey = attribute.Key("process.parent_pid")
+
+ // ProcessPIDKey is the attribute Key conforming to the "process.pid" semantic
+ // conventions. It represents the process identifier (PID).
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 1234
+ ProcessPIDKey = attribute.Key("process.pid")
+
+ // ProcessRealUserIDKey is the attribute Key conforming to the
+ // "process.real_user.id" semantic conventions. It represents the real user ID
+ // (RUID) of the process.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 1000
+ ProcessRealUserIDKey = attribute.Key("process.real_user.id")
+
+ // ProcessRealUserNameKey is the attribute Key conforming to the
+ // "process.real_user.name" semantic conventions. It represents the username of
+ // the real user of the process.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "operator"
+ ProcessRealUserNameKey = attribute.Key("process.real_user.name")
+
+ // ProcessRuntimeDescriptionKey is the attribute Key conforming to the
+ // "process.runtime.description" semantic conventions. It represents an
+ // additional description about the runtime of the process, for example a
+ // specific vendor customization of the runtime environment.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: Eclipse OpenJ9 Eclipse OpenJ9 VM openj9-0.21.0
+ ProcessRuntimeDescriptionKey = attribute.Key("process.runtime.description")
+
+ // ProcessRuntimeNameKey is the attribute Key conforming to the
+ // "process.runtime.name" semantic conventions. It represents the name of the
+ // runtime of this process.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "OpenJDK Runtime Environment"
+ ProcessRuntimeNameKey = attribute.Key("process.runtime.name")
+
+ // ProcessRuntimeVersionKey is the attribute Key conforming to the
+ // "process.runtime.version" semantic conventions. It represents the version of
+ // the runtime of this process, as returned by the runtime without modification.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 14.0.2
+ ProcessRuntimeVersionKey = attribute.Key("process.runtime.version")
+
+ // ProcessSavedUserIDKey is the attribute Key conforming to the
+ // "process.saved_user.id" semantic conventions. It represents the saved user ID
+ // (SUID) of the process.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 1002
+ ProcessSavedUserIDKey = attribute.Key("process.saved_user.id")
+
+ // ProcessSavedUserNameKey is the attribute Key conforming to the
+ // "process.saved_user.name" semantic conventions. It represents the username of
+ // the saved user.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "operator"
+ ProcessSavedUserNameKey = attribute.Key("process.saved_user.name")
+
+ // ProcessSessionLeaderPIDKey is the attribute Key conforming to the
+ // "process.session_leader.pid" semantic conventions. It represents the PID of
+ // the process's session leader. This is also the session ID (SID) of the
+ // process.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 14
+ ProcessSessionLeaderPIDKey = attribute.Key("process.session_leader.pid")
+
+ // ProcessStateKey is the attribute Key conforming to the "process.state"
+ // semantic conventions. It represents the process state, e.g.,
+ // [Linux Process State Codes].
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "running"
+ //
+ // [Linux Process State Codes]: https://man7.org/linux/man-pages/man1/ps.1.html#PROCESS_STATE_CODES
+ ProcessStateKey = attribute.Key("process.state")
+
+ // ProcessTitleKey is the attribute Key conforming to the "process.title"
+ // semantic conventions. It represents the process title (proctitle).
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "cat /etc/hostname", "xfce4-session", "bash"
+ // Note: In many Unix-like systems, process title (proctitle), is the string
+ // that represents the name or command line of a running process, displayed by
+ // system monitoring tools like ps, top, and htop.
+ ProcessTitleKey = attribute.Key("process.title")
+
+ // ProcessUserIDKey is the attribute Key conforming to the "process.user.id"
+ // semantic conventions. It represents the effective user ID (EUID) of the
+ // process.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 1001
+ ProcessUserIDKey = attribute.Key("process.user.id")
+
+ // ProcessUserNameKey is the attribute Key conforming to the "process.user.name"
+ // semantic conventions. It represents the username of the effective user of the
+ // process.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "root"
+ ProcessUserNameKey = attribute.Key("process.user.name")
+
+ // ProcessVpidKey is the attribute Key conforming to the "process.vpid" semantic
+ // conventions. It represents the virtual process identifier.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 12
+ // Note: The process ID within a PID namespace. This is not necessarily unique
+ // across all processes on the host but it is unique within the process
+ // namespace that the process exists within.
+ ProcessVpidKey = attribute.Key("process.vpid")
+
+ // ProcessWorkingDirectoryKey is the attribute Key conforming to the
+ // "process.working_directory" semantic conventions. It represents the working
+ // directory of the process.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "/root"
+ ProcessWorkingDirectoryKey = attribute.Key("process.working_directory")
+)
+
+// ProcessArgsCount returns an attribute KeyValue conforming to the
+// "process.args_count" semantic conventions. It represents the length of the
+// process.command_args array.
+func ProcessArgsCount(val int) attribute.KeyValue {
+ return ProcessArgsCountKey.Int(val)
+}
+
+// ProcessCommand returns an attribute KeyValue conforming to the
+// "process.command" semantic conventions. It represents the command used to
+// launch the process (i.e. the command name). On Linux based systems, can be set
+// to the zeroth string in `proc/[pid]/cmdline`. On Windows, can be set to the
+// first parameter extracted from `GetCommandLineW`.
+func ProcessCommand(val string) attribute.KeyValue {
+ return ProcessCommandKey.String(val)
+}
+
+// ProcessCommandArgs returns an attribute KeyValue conforming to the
+// "process.command_args" semantic conventions. It represents the all the command
+// arguments (including the command/executable itself) as received by the
+// process. On Linux-based systems (and some other Unixoid systems supporting
+// procfs), can be set according to the list of null-delimited strings extracted
+// from `proc/[pid]/cmdline`. For libc-based executables, this would be the full
+// argv vector passed to `main`. SHOULD NOT be collected by default unless there
+// is sanitization that excludes sensitive data.
+func ProcessCommandArgs(val ...string) attribute.KeyValue {
+ return ProcessCommandArgsKey.StringSlice(val)
+}
+
+// ProcessCommandLine returns an attribute KeyValue conforming to the
+// "process.command_line" semantic conventions. It represents the full command
+// used to launch the process as a single string representing the full command.
+// On Windows, can be set to the result of `GetCommandLineW`. Do not set this if
+// you have to assemble it just for monitoring; use `process.command_args`
+// instead. SHOULD NOT be collected by default unless there is sanitization that
+// excludes sensitive data.
+func ProcessCommandLine(val string) attribute.KeyValue {
+ return ProcessCommandLineKey.String(val)
+}
+
+// ProcessCreationTime returns an attribute KeyValue conforming to the
+// "process.creation.time" semantic conventions. It represents the date and time
+// the process was created, in ISO 8601 format.
+func ProcessCreationTime(val string) attribute.KeyValue {
+ return ProcessCreationTimeKey.String(val)
+}
+
+// ProcessEnvironmentVariable returns an attribute KeyValue conforming to the
+// "process.environment_variable" semantic conventions. It represents the process
+// environment variables, `` being the environment variable name, the value
+// being the environment variable value.
+func ProcessEnvironmentVariable(key string, val string) attribute.KeyValue {
+ return attribute.String("process.environment_variable."+key, val)
+}
+
+// ProcessExecutableBuildIDGNU returns an attribute KeyValue conforming to the
+// "process.executable.build_id.gnu" semantic conventions. It represents the GNU
+// build ID as found in the `.note.gnu.build-id` ELF section (hex string).
+func ProcessExecutableBuildIDGNU(val string) attribute.KeyValue {
+ return ProcessExecutableBuildIDGNUKey.String(val)
+}
+
+// ProcessExecutableBuildIDGo returns an attribute KeyValue conforming to the
+// "process.executable.build_id.go" semantic conventions. It represents the Go
+// build ID as retrieved by `go tool buildid `.
+func ProcessExecutableBuildIDGo(val string) attribute.KeyValue {
+ return ProcessExecutableBuildIDGoKey.String(val)
+}
+
+// ProcessExecutableBuildIDHtlhash returns an attribute KeyValue conforming to
+// the "process.executable.build_id.htlhash" semantic conventions. It represents
+// the deterministic build ID for executables.
+func ProcessExecutableBuildIDHtlhash(val string) attribute.KeyValue {
+ return ProcessExecutableBuildIDHtlhashKey.String(val)
+}
+
+// ProcessExecutableName returns an attribute KeyValue conforming to the
+// "process.executable.name" semantic conventions. It represents the name of the
+// process executable. On Linux based systems, this SHOULD be set to the base
+// name of the target of `/proc/[pid]/exe`. On Windows, this SHOULD be set to the
+// base name of `GetProcessImageFileNameW`.
+func ProcessExecutableName(val string) attribute.KeyValue {
+ return ProcessExecutableNameKey.String(val)
+}
+
+// ProcessExecutablePath returns an attribute KeyValue conforming to the
+// "process.executable.path" semantic conventions. It represents the full path to
+// the process executable. On Linux based systems, can be set to the target of
+// `proc/[pid]/exe`. On Windows, can be set to the result of
+// `GetProcessImageFileNameW`.
+func ProcessExecutablePath(val string) attribute.KeyValue {
+ return ProcessExecutablePathKey.String(val)
+}
+
+// ProcessExitCode returns an attribute KeyValue conforming to the
+// "process.exit.code" semantic conventions. It represents the exit code of the
+// process.
+func ProcessExitCode(val int) attribute.KeyValue {
+ return ProcessExitCodeKey.Int(val)
+}
+
+// ProcessExitTime returns an attribute KeyValue conforming to the
+// "process.exit.time" semantic conventions. It represents the date and time the
+// process exited, in ISO 8601 format.
+func ProcessExitTime(val string) attribute.KeyValue {
+ return ProcessExitTimeKey.String(val)
+}
+
+// ProcessGroupLeaderPID returns an attribute KeyValue conforming to the
+// "process.group_leader.pid" semantic conventions. It represents the PID of the
+// process's group leader. This is also the process group ID (PGID) of the
+// process.
+func ProcessGroupLeaderPID(val int) attribute.KeyValue {
+ return ProcessGroupLeaderPIDKey.Int(val)
+}
+
+// ProcessInteractive returns an attribute KeyValue conforming to the
+// "process.interactive" semantic conventions. It represents the whether the
+// process is connected to an interactive shell.
+func ProcessInteractive(val bool) attribute.KeyValue {
+ return ProcessInteractiveKey.Bool(val)
+}
+
+// ProcessLinuxCgroup returns an attribute KeyValue conforming to the
+// "process.linux.cgroup" semantic conventions. It represents the control group
+// associated with the process.
+func ProcessLinuxCgroup(val string) attribute.KeyValue {
+ return ProcessLinuxCgroupKey.String(val)
+}
+
+// ProcessOwner returns an attribute KeyValue conforming to the "process.owner"
+// semantic conventions. It represents the username of the user that owns the
+// process.
+func ProcessOwner(val string) attribute.KeyValue {
+ return ProcessOwnerKey.String(val)
+}
+
+// ProcessParentPID returns an attribute KeyValue conforming to the
+// "process.parent_pid" semantic conventions. It represents the parent Process
+// identifier (PPID).
+func ProcessParentPID(val int) attribute.KeyValue {
+ return ProcessParentPIDKey.Int(val)
+}
+
+// ProcessPID returns an attribute KeyValue conforming to the "process.pid"
+// semantic conventions. It represents the process identifier (PID).
+func ProcessPID(val int) attribute.KeyValue {
+ return ProcessPIDKey.Int(val)
+}
+
+// ProcessRealUserID returns an attribute KeyValue conforming to the
+// "process.real_user.id" semantic conventions. It represents the real user ID
+// (RUID) of the process.
+func ProcessRealUserID(val int) attribute.KeyValue {
+ return ProcessRealUserIDKey.Int(val)
+}
+
+// ProcessRealUserName returns an attribute KeyValue conforming to the
+// "process.real_user.name" semantic conventions. It represents the username of
+// the real user of the process.
+func ProcessRealUserName(val string) attribute.KeyValue {
+ return ProcessRealUserNameKey.String(val)
+}
+
+// ProcessRuntimeDescription returns an attribute KeyValue conforming to the
+// "process.runtime.description" semantic conventions. It represents an
+// additional description about the runtime of the process, for example a
+// specific vendor customization of the runtime environment.
+func ProcessRuntimeDescription(val string) attribute.KeyValue {
+ return ProcessRuntimeDescriptionKey.String(val)
+}
+
+// ProcessRuntimeName returns an attribute KeyValue conforming to the
+// "process.runtime.name" semantic conventions. It represents the name of the
+// runtime of this process.
+func ProcessRuntimeName(val string) attribute.KeyValue {
+ return ProcessRuntimeNameKey.String(val)
+}
+
+// ProcessRuntimeVersion returns an attribute KeyValue conforming to the
+// "process.runtime.version" semantic conventions. It represents the version of
+// the runtime of this process, as returned by the runtime without modification.
+func ProcessRuntimeVersion(val string) attribute.KeyValue {
+ return ProcessRuntimeVersionKey.String(val)
+}
+
+// ProcessSavedUserID returns an attribute KeyValue conforming to the
+// "process.saved_user.id" semantic conventions. It represents the saved user ID
+// (SUID) of the process.
+func ProcessSavedUserID(val int) attribute.KeyValue {
+ return ProcessSavedUserIDKey.Int(val)
+}
+
+// ProcessSavedUserName returns an attribute KeyValue conforming to the
+// "process.saved_user.name" semantic conventions. It represents the username of
+// the saved user.
+func ProcessSavedUserName(val string) attribute.KeyValue {
+ return ProcessSavedUserNameKey.String(val)
+}
+
+// ProcessSessionLeaderPID returns an attribute KeyValue conforming to the
+// "process.session_leader.pid" semantic conventions. It represents the PID of
+// the process's session leader. This is also the session ID (SID) of the
+// process.
+func ProcessSessionLeaderPID(val int) attribute.KeyValue {
+ return ProcessSessionLeaderPIDKey.Int(val)
+}
+
+// ProcessTitle returns an attribute KeyValue conforming to the "process.title"
+// semantic conventions. It represents the process title (proctitle).
+func ProcessTitle(val string) attribute.KeyValue {
+ return ProcessTitleKey.String(val)
+}
+
+// ProcessUserID returns an attribute KeyValue conforming to the
+// "process.user.id" semantic conventions. It represents the effective user ID
+// (EUID) of the process.
+func ProcessUserID(val int) attribute.KeyValue {
+ return ProcessUserIDKey.Int(val)
+}
+
+// ProcessUserName returns an attribute KeyValue conforming to the
+// "process.user.name" semantic conventions. It represents the username of the
+// effective user of the process.
+func ProcessUserName(val string) attribute.KeyValue {
+ return ProcessUserNameKey.String(val)
+}
+
+// ProcessVpid returns an attribute KeyValue conforming to the "process.vpid"
+// semantic conventions. It represents the virtual process identifier.
+func ProcessVpid(val int) attribute.KeyValue {
+ return ProcessVpidKey.Int(val)
+}
+
+// ProcessWorkingDirectory returns an attribute KeyValue conforming to the
+// "process.working_directory" semantic conventions. It represents the working
+// directory of the process.
+func ProcessWorkingDirectory(val string) attribute.KeyValue {
+ return ProcessWorkingDirectoryKey.String(val)
+}
+
+// Enum values for process.context_switch.type
+var (
+ // voluntary
+ // Stability: development
+ ProcessContextSwitchTypeVoluntary = ProcessContextSwitchTypeKey.String("voluntary")
+ // involuntary
+ // Stability: development
+ ProcessContextSwitchTypeInvoluntary = ProcessContextSwitchTypeKey.String("involuntary")
+)
+
+// Enum values for process.state
+var (
+ // running
+ // Stability: development
+ ProcessStateRunning = ProcessStateKey.String("running")
+ // sleeping
+ // Stability: development
+ ProcessStateSleeping = ProcessStateKey.String("sleeping")
+ // stopped
+ // Stability: development
+ ProcessStateStopped = ProcessStateKey.String("stopped")
+ // defunct
+ // Stability: development
+ ProcessStateDefunct = ProcessStateKey.String("defunct")
+)
+
+// Namespace: profile
+const (
+ // ProfileFrameTypeKey is the attribute Key conforming to the
+ // "profile.frame.type" semantic conventions. It represents the describes the
+ // interpreter or compiler of a single frame.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "cpython"
+ ProfileFrameTypeKey = attribute.Key("profile.frame.type")
+)
+
+// Enum values for profile.frame.type
+var (
+ // [.NET]
+ //
+ // Stability: development
+ //
+ // [.NET]: https://wikipedia.org/wiki/.NET
+ ProfileFrameTypeDotnet = ProfileFrameTypeKey.String("dotnet")
+ // [JVM]
+ //
+ // Stability: development
+ //
+ // [JVM]: https://wikipedia.org/wiki/Java_virtual_machine
+ ProfileFrameTypeJVM = ProfileFrameTypeKey.String("jvm")
+ // [Kernel]
+ //
+ // Stability: development
+ //
+ // [Kernel]: https://wikipedia.org/wiki/Kernel_(operating_system)
+ ProfileFrameTypeKernel = ProfileFrameTypeKey.String("kernel")
+ // Can be one of but not limited to [C], [C++], [Go] or [Rust]. If possible, a
+ // more precise value MUST be used.
+ //
+ // Stability: development
+ //
+ // [C]: https://wikipedia.org/wiki/C_(programming_language)
+ // [C++]: https://wikipedia.org/wiki/C%2B%2B
+ // [Go]: https://wikipedia.org/wiki/Go_(programming_language)
+ // [Rust]: https://wikipedia.org/wiki/Rust_(programming_language)
+ ProfileFrameTypeNative = ProfileFrameTypeKey.String("native")
+ // [Perl]
+ //
+ // Stability: development
+ //
+ // [Perl]: https://wikipedia.org/wiki/Perl
+ ProfileFrameTypePerl = ProfileFrameTypeKey.String("perl")
+ // [PHP]
+ //
+ // Stability: development
+ //
+ // [PHP]: https://wikipedia.org/wiki/PHP
+ ProfileFrameTypePHP = ProfileFrameTypeKey.String("php")
+ // [Python]
+ //
+ // Stability: development
+ //
+ // [Python]: https://wikipedia.org/wiki/Python_(programming_language)
+ ProfileFrameTypeCpython = ProfileFrameTypeKey.String("cpython")
+ // [Ruby]
+ //
+ // Stability: development
+ //
+ // [Ruby]: https://wikipedia.org/wiki/Ruby_(programming_language)
+ ProfileFrameTypeRuby = ProfileFrameTypeKey.String("ruby")
+ // [V8JS]
+ //
+ // Stability: development
+ //
+ // [V8JS]: https://wikipedia.org/wiki/V8_(JavaScript_engine)
+ ProfileFrameTypeV8JS = ProfileFrameTypeKey.String("v8js")
+ // [Erlang]
+ //
+ // Stability: development
+ //
+ // [Erlang]: https://en.wikipedia.org/wiki/BEAM_(Erlang_virtual_machine)
+ ProfileFrameTypeBeam = ProfileFrameTypeKey.String("beam")
+ // [Go],
+ //
+ // Stability: development
+ //
+ // [Go]: https://wikipedia.org/wiki/Go_(programming_language)
+ ProfileFrameTypeGo = ProfileFrameTypeKey.String("go")
+ // [Rust]
+ //
+ // Stability: development
+ //
+ // [Rust]: https://wikipedia.org/wiki/Rust_(programming_language)
+ ProfileFrameTypeRust = ProfileFrameTypeKey.String("rust")
+)
+
+// Namespace: rpc
+const (
+ // RPCMethodKey is the attribute Key conforming to the "rpc.method" semantic
+ // conventions. It represents the fully-qualified logical name of the method
+ // from the RPC interface perspective.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Release_Candidate
+ //
+ // Examples: "com.example.ExampleService/exampleMethod", "EchoService/Echo",
+ // "_OTHER"
+ // Note: The method name MAY have unbounded cardinality in edge or error cases.
+ //
+ // Some RPC frameworks or libraries provide a fixed set of recognized methods
+ // for client stubs and server implementations. Instrumentations for such
+ // frameworks MUST set this attribute to the original method name only
+ // when the method is recognized by the framework or library.
+ //
+ // When the method is not recognized, for example, when the server receives
+ // a request for a method that is not predefined on the server, or when
+ // instrumentation is not able to reliably detect if the method is predefined,
+ // the attribute MUST be set to `_OTHER`. In such cases, tracing
+ // instrumentations MUST also set `rpc.method_original` attribute to
+ // the original method value.
+ //
+ // If the RPC instrumentation could end up converting valid RPC methods to
+ // `_OTHER`, then it SHOULD provide a way to configure the list of recognized
+ // RPC methods.
+ //
+ // The `rpc.method` can be different from the name of any implementing
+ // method/function.
+ // The `code.function.name` attribute may be used to record the fully-qualified
+ // method actually executing the call on the server side, or the
+ // RPC client stub method on the client side.
+ RPCMethodKey = attribute.Key("rpc.method")
+
+ // RPCMethodOriginalKey is the attribute Key conforming to the
+ // "rpc.method_original" semantic conventions. It represents the original name
+ // of the method used by the client.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Release_Candidate
+ //
+ // Examples: "com.myservice.EchoService/catchAll",
+ // "com.myservice.EchoService/unknownMethod", "InvalidMethod"
+ RPCMethodOriginalKey = attribute.Key("rpc.method_original")
+
+ // RPCResponseStatusCodeKey is the attribute Key conforming to the
+ // "rpc.response.status_code" semantic conventions. It represents the status
+ // code of the RPC returned by the RPC server or generated by the client.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Release_Candidate
+ //
+ // Examples: "OK", "DEADLINE_EXCEEDED", "-32602"
+ // Note: Usually it represents an error code, but may also represent partial
+ // success, warning, or differentiate between various types of successful
+ // outcomes.
+ // Semantic conventions for individual RPC frameworks SHOULD document what
+ // `rpc.response.status_code` means in the context of that system and which
+ // values are considered to represent errors.
+ RPCResponseStatusCodeKey = attribute.Key("rpc.response.status_code")
+
+ // RPCSystemNameKey is the attribute Key conforming to the "rpc.system.name"
+ // semantic conventions. It represents the Remote Procedure Call (RPC) system.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Release_Candidate
+ //
+ // Examples:
+ // Note: The client and server RPC systems may differ for the same RPC
+ // interaction. For example, a client may use Apache Dubbo or Connect RPC to
+ // communicate with a server that uses gRPC since both protocols provide
+ // compatibility with gRPC.
+ RPCSystemNameKey = attribute.Key("rpc.system.name")
+)
+
+// RPCMethod returns an attribute KeyValue conforming to the "rpc.method"
+// semantic conventions. It represents the fully-qualified logical name of the
+// method from the RPC interface perspective.
+func RPCMethod(val string) attribute.KeyValue {
+ return RPCMethodKey.String(val)
+}
+
+// RPCMethodOriginal returns an attribute KeyValue conforming to the
+// "rpc.method_original" semantic conventions. It represents the original name of
+// the method used by the client.
+func RPCMethodOriginal(val string) attribute.KeyValue {
+ return RPCMethodOriginalKey.String(val)
+}
+
+// RPCRequestMetadata returns an attribute KeyValue conforming to the
+// "rpc.request.metadata" semantic conventions. It represents the RPC request
+// metadata, `` being the normalized RPC metadata key (lowercase), the value
+// being the metadata values.
+func RPCRequestMetadata(key string, val ...string) attribute.KeyValue {
+ return attribute.StringSlice("rpc.request.metadata."+key, val)
+}
+
+// RPCResponseMetadata returns an attribute KeyValue conforming to the
+// "rpc.response.metadata" semantic conventions. It represents the RPC response
+// metadata, `` being the normalized RPC metadata key (lowercase), the value
+// being the metadata values.
+func RPCResponseMetadata(key string, val ...string) attribute.KeyValue {
+ return attribute.StringSlice("rpc.response.metadata."+key, val)
+}
+
+// RPCResponseStatusCode returns an attribute KeyValue conforming to the
+// "rpc.response.status_code" semantic conventions. It represents the status code
+// of the RPC returned by the RPC server or generated by the client.
+func RPCResponseStatusCode(val string) attribute.KeyValue {
+ return RPCResponseStatusCodeKey.String(val)
+}
+
+// Enum values for rpc.system.name
+var (
+ // [gRPC]
+ // Stability: release_candidate
+ //
+ // [gRPC]: https://grpc.io/
+ RPCSystemNameGRPC = RPCSystemNameKey.String("grpc")
+ // [Apache Dubbo]
+ // Stability: release_candidate
+ //
+ // [Apache Dubbo]: https://dubbo.apache.org/
+ RPCSystemNameDubbo = RPCSystemNameKey.String("dubbo")
+ // [Connect RPC]
+ // Stability: development
+ //
+ // [Connect RPC]: https://connectrpc.com/
+ RPCSystemNameConnectrpc = RPCSystemNameKey.String("connectrpc")
+ // [JSON-RPC]
+ // Stability: development
+ //
+ // [JSON-RPC]: https://www.jsonrpc.org/
+ RPCSystemNameJSONRPC = RPCSystemNameKey.String("jsonrpc")
+)
+
+// Namespace: security_rule
+const (
+ // SecurityRuleCategoryKey is the attribute Key conforming to the
+ // "security_rule.category" semantic conventions. It represents a categorization
+ // value keyword used by the entity using the rule for detection of this event.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "Attempted Information Leak"
+ SecurityRuleCategoryKey = attribute.Key("security_rule.category")
+
+ // SecurityRuleDescriptionKey is the attribute Key conforming to the
+ // "security_rule.description" semantic conventions. It represents the
+ // description of the rule generating the event.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "Block requests to public DNS over HTTPS / TLS protocols"
+ SecurityRuleDescriptionKey = attribute.Key("security_rule.description")
+
+ // SecurityRuleLicenseKey is the attribute Key conforming to the
+ // "security_rule.license" semantic conventions. It represents the name of the
+ // license under which the rule used to generate this event is made available.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "Apache 2.0"
+ SecurityRuleLicenseKey = attribute.Key("security_rule.license")
+
+ // SecurityRuleNameKey is the attribute Key conforming to the
+ // "security_rule.name" semantic conventions. It represents the name of the rule
+ // or signature generating the event.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "BLOCK_DNS_over_TLS"
+ SecurityRuleNameKey = attribute.Key("security_rule.name")
+
+ // SecurityRuleReferenceKey is the attribute Key conforming to the
+ // "security_rule.reference" semantic conventions. It represents the reference
+ // URL to additional information about the rule used to generate this event.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "https://en.wikipedia.org/wiki/DNS_over_TLS"
+ // Note: The URL can point to the vendor’s documentation about the rule. If
+ // that’s not available, it can also be a link to a more general page
+ // describing this type of alert.
+ SecurityRuleReferenceKey = attribute.Key("security_rule.reference")
+
+ // SecurityRuleRulesetNameKey is the attribute Key conforming to the
+ // "security_rule.ruleset.name" semantic conventions. It represents the name of
+ // the ruleset, policy, group, or parent category in which the rule used to
+ // generate this event is a member.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "Standard_Protocol_Filters"
+ SecurityRuleRulesetNameKey = attribute.Key("security_rule.ruleset.name")
+
+ // SecurityRuleUUIDKey is the attribute Key conforming to the
+ // "security_rule.uuid" semantic conventions. It represents a rule ID that is
+ // unique within the scope of a set or group of agents, observers, or other
+ // entities using the rule for detection of this event.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "550e8400-e29b-41d4-a716-446655440000", "1100110011"
+ SecurityRuleUUIDKey = attribute.Key("security_rule.uuid")
+
+ // SecurityRuleVersionKey is the attribute Key conforming to the
+ // "security_rule.version" semantic conventions. It represents the version /
+ // revision of the rule being used for analysis.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "1.0.0"
+ SecurityRuleVersionKey = attribute.Key("security_rule.version")
+)
+
+// SecurityRuleCategory returns an attribute KeyValue conforming to the
+// "security_rule.category" semantic conventions. It represents a categorization
+// value keyword used by the entity using the rule for detection of this event.
+func SecurityRuleCategory(val string) attribute.KeyValue {
+ return SecurityRuleCategoryKey.String(val)
+}
+
+// SecurityRuleDescription returns an attribute KeyValue conforming to the
+// "security_rule.description" semantic conventions. It represents the
+// description of the rule generating the event.
+func SecurityRuleDescription(val string) attribute.KeyValue {
+ return SecurityRuleDescriptionKey.String(val)
+}
+
+// SecurityRuleLicense returns an attribute KeyValue conforming to the
+// "security_rule.license" semantic conventions. It represents the name of the
+// license under which the rule used to generate this event is made available.
+func SecurityRuleLicense(val string) attribute.KeyValue {
+ return SecurityRuleLicenseKey.String(val)
+}
+
+// SecurityRuleName returns an attribute KeyValue conforming to the
+// "security_rule.name" semantic conventions. It represents the name of the rule
+// or signature generating the event.
+func SecurityRuleName(val string) attribute.KeyValue {
+ return SecurityRuleNameKey.String(val)
+}
+
+// SecurityRuleReference returns an attribute KeyValue conforming to the
+// "security_rule.reference" semantic conventions. It represents the reference
+// URL to additional information about the rule used to generate this event.
+func SecurityRuleReference(val string) attribute.KeyValue {
+ return SecurityRuleReferenceKey.String(val)
+}
+
+// SecurityRuleRulesetName returns an attribute KeyValue conforming to the
+// "security_rule.ruleset.name" semantic conventions. It represents the name of
+// the ruleset, policy, group, or parent category in which the rule used to
+// generate this event is a member.
+func SecurityRuleRulesetName(val string) attribute.KeyValue {
+ return SecurityRuleRulesetNameKey.String(val)
+}
+
+// SecurityRuleUUID returns an attribute KeyValue conforming to the
+// "security_rule.uuid" semantic conventions. It represents a rule ID that is
+// unique within the scope of a set or group of agents, observers, or other
+// entities using the rule for detection of this event.
+func SecurityRuleUUID(val string) attribute.KeyValue {
+ return SecurityRuleUUIDKey.String(val)
+}
+
+// SecurityRuleVersion returns an attribute KeyValue conforming to the
+// "security_rule.version" semantic conventions. It represents the version /
+// revision of the rule being used for analysis.
+func SecurityRuleVersion(val string) attribute.KeyValue {
+ return SecurityRuleVersionKey.String(val)
+}
+
+// Namespace: server
+const (
+ // ServerAddressKey is the attribute Key conforming to the "server.address"
+ // semantic conventions. It represents the server domain name if available
+ // without reverse DNS lookup; otherwise, IP address or Unix domain socket name.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ //
+ // Examples: "example.com", "10.1.2.80", "/tmp/my.sock"
+ // Note: When observed from the client side, and when communicating through an
+ // intermediary, `server.address` SHOULD represent the server address behind any
+ // intermediaries, for example proxies, if it's available.
+ ServerAddressKey = attribute.Key("server.address")
+
+ // ServerPortKey is the attribute Key conforming to the "server.port" semantic
+ // conventions. It represents the server port number.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ //
+ // Examples: 80, 8080, 443
+ // Note: When observed from the client side, and when communicating through an
+ // intermediary, `server.port` SHOULD represent the server port behind any
+ // intermediaries, for example proxies, if it's available.
+ ServerPortKey = attribute.Key("server.port")
+)
+
+// ServerAddress returns an attribute KeyValue conforming to the "server.address"
+// semantic conventions. It represents the server domain name if available
+// without reverse DNS lookup; otherwise, IP address or Unix domain socket name.
+func ServerAddress(val string) attribute.KeyValue {
+ return ServerAddressKey.String(val)
+}
+
+// ServerPort returns an attribute KeyValue conforming to the "server.port"
+// semantic conventions. It represents the server port number.
+func ServerPort(val int) attribute.KeyValue {
+ return ServerPortKey.Int(val)
+}
+
+// Namespace: service
+const (
+ // ServiceCriticalityKey is the attribute Key conforming to the
+ // "service.criticality" semantic conventions. It represents the operational
+ // criticality of the service.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "critical", "high", "medium", "low"
+ // Note: Application developers are encouraged to set `service.criticality` to
+ // express the operational importance of their services. Telemetry consumers MAY
+ // use this attribute to optimize telemetry collection or improve user
+ // experience.
+ ServiceCriticalityKey = attribute.Key("service.criticality")
+
+ // ServiceInstanceIDKey is the attribute Key conforming to the
+ // "service.instance.id" semantic conventions. It represents the string ID of
+ // the service instance.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ //
+ // Examples: "627cc493-f310-47de-96bd-71410b7dec09"
+ // Note: MUST be unique for each instance of the same
+ // `service.namespace,service.name` pair (in other words
+ // `service.namespace,service.name,service.instance.id` triplet MUST be globally
+ // unique). The ID helps to
+ // distinguish instances of the same service that exist at the same time (e.g.
+ // instances of a horizontally scaled
+ // service).
+ //
+ // Implementations, such as SDKs, are recommended to generate a random Version 1
+ // or Version 4 [RFC
+ // 4122] UUID, but are free to use an inherent unique ID as
+ // the source of
+ // this value if stability is desirable. In that case, the ID SHOULD be used as
+ // source of a UUID Version 5 and
+ // SHOULD use the following UUID as the namespace:
+ // `4d63009a-8d0f-11ee-aad7-4c796ed8e320`.
+ //
+ // UUIDs are typically recommended, as only an opaque value for the purposes of
+ // identifying a service instance is
+ // needed. Similar to what can be seen in the man page for the
+ // [`/etc/machine-id`] file, the underlying
+ // data, such as pod name and namespace should be treated as confidential, being
+ // the user's choice to expose it
+ // or not via another resource attribute.
+ //
+ // For applications running behind an application server (like unicorn), we do
+ // not recommend using one identifier
+ // for all processes participating in the application. Instead, it's recommended
+ // each division (e.g. a worker
+ // thread in unicorn) to have its own instance.id.
+ //
+ // It's not recommended for a Collector to set `service.instance.id` if it can't
+ // unambiguously determine the
+ // service instance that is generating that telemetry. For instance, creating an
+ // UUID based on `pod.name` will
+ // likely be wrong, as the Collector might not know from which container within
+ // that pod the telemetry originated.
+ // However, Collectors can set the `service.instance.id` if they can
+ // unambiguously determine the service instance
+ // for that telemetry. This is typically the case for scraping receivers, as
+ // they know the target address and
+ // port.
+ //
+ // [RFC
+ // 4122]: https://www.ietf.org/rfc/rfc4122.txt
+ // [`/etc/machine-id`]: https://www.freedesktop.org/software/systemd/man/latest/machine-id.html
+ ServiceInstanceIDKey = attribute.Key("service.instance.id")
+
+ // ServiceNameKey is the attribute Key conforming to the "service.name" semantic
+ // conventions. It represents the logical name of the service.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ //
+ // Examples: "shoppingcart"
+ // Note: MUST be the same for all instances of horizontally scaled services. If
+ // the value was not specified, SDKs MUST fallback to `unknown_service:`
+ // concatenated with the process executable name, e.g. `unknown_service:bash`.
+ // If the process executable name is not available, the value MUST be set to
+ // `unknown_service`.
+ // The process executable name is the name of the process executable, the same
+ // value as described by the [`process.executable.name`] resource attribute.
+ //
+ // [`process.executable.name`]: process.md
+ ServiceNameKey = attribute.Key("service.name")
+
+ // ServiceNamespaceKey is the attribute Key conforming to the
+ // "service.namespace" semantic conventions. It represents a namespace for
+ // `service.name`.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ //
+ // Examples: "Shop"
+ // Note: A string value having a meaning that helps to distinguish a group of
+ // services, for example the team name that owns a group of services.
+ // `service.name` is expected to be unique within the same namespace. If
+ // `service.namespace` is not specified in the Resource then `service.name` is
+ // expected to be unique for all services that have no explicit namespace
+ // defined (so the empty/unspecified namespace is simply one more valid
+ // namespace). Zero-length namespace string is assumed equal to unspecified
+ // namespace.
+ ServiceNamespaceKey = attribute.Key("service.namespace")
+
+ // ServicePeerNameKey is the attribute Key conforming to the "service.peer.name"
+ // semantic conventions. It represents the logical name of the service on the
+ // other side of the connection. SHOULD be equal to the actual [`service.name`]
+ // resource attribute of the remote service if any.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "shoppingcart"
+ //
+ // [`service.name`]: /docs/resource/README.md#service
+ ServicePeerNameKey = attribute.Key("service.peer.name")
+
+ // ServicePeerNamespaceKey is the attribute Key conforming to the
+ // "service.peer.namespace" semantic conventions. It represents the logical
+ // namespace of the service on the other side of the connection. SHOULD be equal
+ // to the actual [`service.namespace`] resource attribute of the remote service
+ // if any.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "Shop"
+ //
+ // [`service.namespace`]: /docs/resource/README.md#service
+ ServicePeerNamespaceKey = attribute.Key("service.peer.namespace")
+
+ // ServiceVersionKey is the attribute Key conforming to the "service.version"
+ // semantic conventions. It represents the version string of the service
+ // component. The format is not defined by these conventions.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ //
+ // Examples: "2.0.0", "a01dbef8a"
+ ServiceVersionKey = attribute.Key("service.version")
+)
+
+// ServiceInstanceID returns an attribute KeyValue conforming to the
+// "service.instance.id" semantic conventions. It represents the string ID of the
+// service instance.
+func ServiceInstanceID(val string) attribute.KeyValue {
+ return ServiceInstanceIDKey.String(val)
+}
+
+// ServiceName returns an attribute KeyValue conforming to the "service.name"
+// semantic conventions. It represents the logical name of the service.
+func ServiceName(val string) attribute.KeyValue {
+ return ServiceNameKey.String(val)
+}
+
+// ServiceNamespace returns an attribute KeyValue conforming to the
+// "service.namespace" semantic conventions. It represents a namespace for
+// `service.name`.
+func ServiceNamespace(val string) attribute.KeyValue {
+ return ServiceNamespaceKey.String(val)
+}
+
+// ServicePeerName returns an attribute KeyValue conforming to the
+// "service.peer.name" semantic conventions. It represents the logical name of
+// the service on the other side of the connection. SHOULD be equal to the actual
+// [`service.name`] resource attribute of the remote service if any.
+//
+// [`service.name`]: /docs/resource/README.md#service
+func ServicePeerName(val string) attribute.KeyValue {
+ return ServicePeerNameKey.String(val)
+}
+
+// ServicePeerNamespace returns an attribute KeyValue conforming to the
+// "service.peer.namespace" semantic conventions. It represents the logical
+// namespace of the service on the other side of the connection. SHOULD be equal
+// to the actual [`service.namespace`] resource attribute of the remote service
+// if any.
+//
+// [`service.namespace`]: /docs/resource/README.md#service
+func ServicePeerNamespace(val string) attribute.KeyValue {
+ return ServicePeerNamespaceKey.String(val)
+}
+
+// ServiceVersion returns an attribute KeyValue conforming to the
+// "service.version" semantic conventions. It represents the version string of
+// the service component. The format is not defined by these conventions.
+func ServiceVersion(val string) attribute.KeyValue {
+ return ServiceVersionKey.String(val)
+}
+
+// Enum values for service.criticality
+var (
+ // Service is business-critical; downtime directly impacts revenue, user
+ // experience, or core functionality.
+ //
+ // Stability: development
+ ServiceCriticalityCritical = ServiceCriticalityKey.String("critical")
+ // Service is important but has degradation tolerance or fallback mechanisms.
+ //
+ // Stability: development
+ ServiceCriticalityHigh = ServiceCriticalityKey.String("high")
+ // Service provides supplementary functionality; degradation has limited user
+ // impact.
+ //
+ // Stability: development
+ ServiceCriticalityMedium = ServiceCriticalityKey.String("medium")
+ // Service is non-essential to core operations; used for background tasks or
+ // internal tools.
+ //
+ // Stability: development
+ ServiceCriticalityLow = ServiceCriticalityKey.String("low")
+)
+
+// Namespace: session
+const (
+ // SessionIDKey is the attribute Key conforming to the "session.id" semantic
+ // conventions. It represents a unique id to identify a session.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 00112233-4455-6677-8899-aabbccddeeff
+ SessionIDKey = attribute.Key("session.id")
+
+ // SessionPreviousIDKey is the attribute Key conforming to the
+ // "session.previous_id" semantic conventions. It represents the previous
+ // `session.id` for this user, when known.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 00112233-4455-6677-8899-aabbccddeeff
+ SessionPreviousIDKey = attribute.Key("session.previous_id")
+)
+
+// SessionID returns an attribute KeyValue conforming to the "session.id"
+// semantic conventions. It represents a unique id to identify a session.
+func SessionID(val string) attribute.KeyValue {
+ return SessionIDKey.String(val)
+}
+
+// SessionPreviousID returns an attribute KeyValue conforming to the
+// "session.previous_id" semantic conventions. It represents the previous
+// `session.id` for this user, when known.
+func SessionPreviousID(val string) attribute.KeyValue {
+ return SessionPreviousIDKey.String(val)
+}
+
+// Namespace: signalr
+const (
+ // SignalRConnectionStatusKey is the attribute Key conforming to the
+ // "signalr.connection.status" semantic conventions. It represents the signalR
+ // HTTP connection closure status.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ //
+ // Examples: "app_shutdown", "timeout"
+ SignalRConnectionStatusKey = attribute.Key("signalr.connection.status")
+
+ // SignalRTransportKey is the attribute Key conforming to the
+ // "signalr.transport" semantic conventions. It represents the
+ // [SignalR transport type].
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ //
+ // Examples: "web_sockets", "long_polling"
+ //
+ // [SignalR transport type]: https://github.com/dotnet/aspnetcore/blob/main/src/SignalR/docs/specs/TransportProtocols.md
+ SignalRTransportKey = attribute.Key("signalr.transport")
+)
+
+// Enum values for signalr.connection.status
+var (
+ // The connection was closed normally.
+ // Stability: stable
+ SignalRConnectionStatusNormalClosure = SignalRConnectionStatusKey.String("normal_closure")
+ // The connection was closed due to a timeout.
+ // Stability: stable
+ SignalRConnectionStatusTimeout = SignalRConnectionStatusKey.String("timeout")
+ // The connection was closed because the app is shutting down.
+ // Stability: stable
+ SignalRConnectionStatusAppShutdown = SignalRConnectionStatusKey.String("app_shutdown")
+)
+
+// Enum values for signalr.transport
+var (
+ // ServerSentEvents protocol
+ // Stability: stable
+ SignalRTransportServerSentEvents = SignalRTransportKey.String("server_sent_events")
+ // LongPolling protocol
+ // Stability: stable
+ SignalRTransportLongPolling = SignalRTransportKey.String("long_polling")
+ // WebSockets protocol
+ // Stability: stable
+ SignalRTransportWebSockets = SignalRTransportKey.String("web_sockets")
+)
+
+// Namespace: source
+const (
+ // SourceAddressKey is the attribute Key conforming to the "source.address"
+ // semantic conventions. It represents the source address - domain name if
+ // available without reverse DNS lookup; otherwise, IP address or Unix domain
+ // socket name.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "source.example.com", "10.1.2.80", "/tmp/my.sock"
+ // Note: When observed from the destination side, and when communicating through
+ // an intermediary, `source.address` SHOULD represent the source address behind
+ // any intermediaries, for example proxies, if it's available.
+ SourceAddressKey = attribute.Key("source.address")
+
+ // SourcePortKey is the attribute Key conforming to the "source.port" semantic
+ // conventions. It represents the source port number.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 3389, 2888
+ SourcePortKey = attribute.Key("source.port")
+)
+
+// SourceAddress returns an attribute KeyValue conforming to the "source.address"
+// semantic conventions. It represents the source address - domain name if
+// available without reverse DNS lookup; otherwise, IP address or Unix domain
+// socket name.
+func SourceAddress(val string) attribute.KeyValue {
+ return SourceAddressKey.String(val)
+}
+
+// SourcePort returns an attribute KeyValue conforming to the "source.port"
+// semantic conventions. It represents the source port number.
+func SourcePort(val int) attribute.KeyValue {
+ return SourcePortKey.Int(val)
+}
+
+// Namespace: system
+const (
+ // SystemDeviceKey is the attribute Key conforming to the "system.device"
+ // semantic conventions. It represents the device identifier.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "(identifier)"
+ SystemDeviceKey = attribute.Key("system.device")
+
+ // SystemFilesystemModeKey is the attribute Key conforming to the
+ // "system.filesystem.mode" semantic conventions. It represents the filesystem
+ // mode.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "rw, ro"
+ SystemFilesystemModeKey = attribute.Key("system.filesystem.mode")
+
+ // SystemFilesystemMountpointKey is the attribute Key conforming to the
+ // "system.filesystem.mountpoint" semantic conventions. It represents the
+ // filesystem mount path.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "/mnt/data"
+ SystemFilesystemMountpointKey = attribute.Key("system.filesystem.mountpoint")
+
+ // SystemFilesystemStateKey is the attribute Key conforming to the
+ // "system.filesystem.state" semantic conventions. It represents the filesystem
+ // state.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "used"
+ SystemFilesystemStateKey = attribute.Key("system.filesystem.state")
+
+ // SystemFilesystemTypeKey is the attribute Key conforming to the
+ // "system.filesystem.type" semantic conventions. It represents the filesystem
+ // type.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "ext4"
+ SystemFilesystemTypeKey = attribute.Key("system.filesystem.type")
+
+ // SystemMemoryLinuxHugepagesStateKey is the attribute Key conforming to the
+ // "system.memory.linux.hugepages.state" semantic conventions. It represents the
+ // Linux HugePages memory state.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "free", "used"
+ SystemMemoryLinuxHugepagesStateKey = attribute.Key("system.memory.linux.hugepages.state")
+
+ // SystemMemoryLinuxSlabStateKey is the attribute Key conforming to the
+ // "system.memory.linux.slab.state" semantic conventions. It represents the
+ // Linux Slab memory state.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "reclaimable", "unreclaimable"
+ SystemMemoryLinuxSlabStateKey = attribute.Key("system.memory.linux.slab.state")
+
+ // SystemMemoryStateKey is the attribute Key conforming to the
+ // "system.memory.state" semantic conventions. It represents the memory state.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "free", "cached"
+ SystemMemoryStateKey = attribute.Key("system.memory.state")
+
+ // SystemPagingDirectionKey is the attribute Key conforming to the
+ // "system.paging.direction" semantic conventions. It represents the paging
+ // access direction.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "in"
+ SystemPagingDirectionKey = attribute.Key("system.paging.direction")
+
+ // SystemPagingFaultTypeKey is the attribute Key conforming to the
+ // "system.paging.fault.type" semantic conventions. It represents the paging
+ // fault type.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "minor"
+ SystemPagingFaultTypeKey = attribute.Key("system.paging.fault.type")
+
+ // SystemPagingStateKey is the attribute Key conforming to the
+ // "system.paging.state" semantic conventions. It represents the memory paging
+ // state.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "free"
+ SystemPagingStateKey = attribute.Key("system.paging.state")
+)
+
+// SystemDevice returns an attribute KeyValue conforming to the "system.device"
+// semantic conventions. It represents the device identifier.
+func SystemDevice(val string) attribute.KeyValue {
+ return SystemDeviceKey.String(val)
+}
+
+// SystemFilesystemMode returns an attribute KeyValue conforming to the
+// "system.filesystem.mode" semantic conventions. It represents the filesystem
+// mode.
+func SystemFilesystemMode(val string) attribute.KeyValue {
+ return SystemFilesystemModeKey.String(val)
+}
+
+// SystemFilesystemMountpoint returns an attribute KeyValue conforming to the
+// "system.filesystem.mountpoint" semantic conventions. It represents the
+// filesystem mount path.
+func SystemFilesystemMountpoint(val string) attribute.KeyValue {
+ return SystemFilesystemMountpointKey.String(val)
+}
+
+// Enum values for system.filesystem.state
+var (
+ // used
+ // Stability: development
+ SystemFilesystemStateUsed = SystemFilesystemStateKey.String("used")
+ // free
+ // Stability: development
+ SystemFilesystemStateFree = SystemFilesystemStateKey.String("free")
+ // reserved
+ // Stability: development
+ SystemFilesystemStateReserved = SystemFilesystemStateKey.String("reserved")
+)
+
+// Enum values for system.filesystem.type
+var (
+ // fat32
+ // Stability: development
+ SystemFilesystemTypeFat32 = SystemFilesystemTypeKey.String("fat32")
+ // exfat
+ // Stability: development
+ SystemFilesystemTypeExfat = SystemFilesystemTypeKey.String("exfat")
+ // ntfs
+ // Stability: development
+ SystemFilesystemTypeNtfs = SystemFilesystemTypeKey.String("ntfs")
+ // refs
+ // Stability: development
+ SystemFilesystemTypeRefs = SystemFilesystemTypeKey.String("refs")
+ // hfsplus
+ // Stability: development
+ SystemFilesystemTypeHfsplus = SystemFilesystemTypeKey.String("hfsplus")
+ // ext4
+ // Stability: development
+ SystemFilesystemTypeExt4 = SystemFilesystemTypeKey.String("ext4")
+)
+
+// Enum values for system.memory.linux.hugepages.state
+var (
+ // free
+ // Stability: development
+ SystemMemoryLinuxHugepagesStateFree = SystemMemoryLinuxHugepagesStateKey.String("free")
+ // used
+ // Stability: development
+ SystemMemoryLinuxHugepagesStateUsed = SystemMemoryLinuxHugepagesStateKey.String("used")
+)
+
+// Enum values for system.memory.linux.slab.state
+var (
+ // reclaimable
+ // Stability: development
+ SystemMemoryLinuxSlabStateReclaimable = SystemMemoryLinuxSlabStateKey.String("reclaimable")
+ // unreclaimable
+ // Stability: development
+ SystemMemoryLinuxSlabStateUnreclaimable = SystemMemoryLinuxSlabStateKey.String("unreclaimable")
+)
+
+// Enum values for system.memory.state
+var (
+ // Actual used virtual memory in bytes.
+ // Stability: development
+ SystemMemoryStateUsed = SystemMemoryStateKey.String("used")
+ // free
+ // Stability: development
+ SystemMemoryStateFree = SystemMemoryStateKey.String("free")
+ // buffers
+ // Stability: development
+ SystemMemoryStateBuffers = SystemMemoryStateKey.String("buffers")
+ // cached
+ // Stability: development
+ SystemMemoryStateCached = SystemMemoryStateKey.String("cached")
+)
+
+// Enum values for system.paging.direction
+var (
+ // in
+ // Stability: development
+ SystemPagingDirectionIn = SystemPagingDirectionKey.String("in")
+ // out
+ // Stability: development
+ SystemPagingDirectionOut = SystemPagingDirectionKey.String("out")
+)
+
+// Enum values for system.paging.fault.type
+var (
+ // major
+ // Stability: development
+ SystemPagingFaultTypeMajor = SystemPagingFaultTypeKey.String("major")
+ // minor
+ // Stability: development
+ SystemPagingFaultTypeMinor = SystemPagingFaultTypeKey.String("minor")
+)
+
+// Enum values for system.paging.state
+var (
+ // used
+ // Stability: development
+ SystemPagingStateUsed = SystemPagingStateKey.String("used")
+ // free
+ // Stability: development
+ SystemPagingStateFree = SystemPagingStateKey.String("free")
+)
+
+// Namespace: telemetry
+const (
+ // TelemetryDistroNameKey is the attribute Key conforming to the
+ // "telemetry.distro.name" semantic conventions. It represents the name of the
+ // auto instrumentation agent or distribution, if used.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ //
+ // Examples: "parts-unlimited-java"
+ // Note: Official auto instrumentation agents and distributions SHOULD set the
+ // `telemetry.distro.name` attribute to
+ // a string starting with `opentelemetry-`, e.g.
+ // `opentelemetry-java-instrumentation`.
+ TelemetryDistroNameKey = attribute.Key("telemetry.distro.name")
+
+ // TelemetryDistroVersionKey is the attribute Key conforming to the
+ // "telemetry.distro.version" semantic conventions. It represents the version
+ // string of the auto instrumentation agent or distribution, if used.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ //
+ // Examples: "1.2.3"
+ TelemetryDistroVersionKey = attribute.Key("telemetry.distro.version")
+
+ // TelemetrySDKLanguageKey is the attribute Key conforming to the
+ // "telemetry.sdk.language" semantic conventions. It represents the language of
+ // the telemetry SDK.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ //
+ // Examples:
+ TelemetrySDKLanguageKey = attribute.Key("telemetry.sdk.language")
+
+ // TelemetrySDKNameKey is the attribute Key conforming to the
+ // "telemetry.sdk.name" semantic conventions. It represents the name of the
+ // telemetry SDK as defined above.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ //
+ // Examples: "opentelemetry"
+ // Note: The OpenTelemetry SDK MUST set the `telemetry.sdk.name` attribute to
+ // `opentelemetry`.
+ // If another SDK, like a fork or a vendor-provided implementation, is used,
+ // this SDK MUST set the
+ // `telemetry.sdk.name` attribute to the fully-qualified class or module name of
+ // this SDK's main entry point
+ // or another suitable identifier depending on the language.
+ // The identifier `opentelemetry` is reserved and MUST NOT be used in this case.
+ // All custom identifiers SHOULD be stable across different versions of an
+ // implementation.
+ TelemetrySDKNameKey = attribute.Key("telemetry.sdk.name")
+
+ // TelemetrySDKVersionKey is the attribute Key conforming to the
+ // "telemetry.sdk.version" semantic conventions. It represents the version
+ // string of the telemetry SDK.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ //
+ // Examples: "1.2.3"
+ TelemetrySDKVersionKey = attribute.Key("telemetry.sdk.version")
+)
+
+// TelemetryDistroName returns an attribute KeyValue conforming to the
+// "telemetry.distro.name" semantic conventions. It represents the name of the
+// auto instrumentation agent or distribution, if used.
+func TelemetryDistroName(val string) attribute.KeyValue {
+ return TelemetryDistroNameKey.String(val)
+}
+
+// TelemetryDistroVersion returns an attribute KeyValue conforming to the
+// "telemetry.distro.version" semantic conventions. It represents the version
+// string of the auto instrumentation agent or distribution, if used.
+func TelemetryDistroVersion(val string) attribute.KeyValue {
+ return TelemetryDistroVersionKey.String(val)
+}
+
+// TelemetrySDKName returns an attribute KeyValue conforming to the
+// "telemetry.sdk.name" semantic conventions. It represents the name of the
+// telemetry SDK as defined above.
+func TelemetrySDKName(val string) attribute.KeyValue {
+ return TelemetrySDKNameKey.String(val)
+}
+
+// TelemetrySDKVersion returns an attribute KeyValue conforming to the
+// "telemetry.sdk.version" semantic conventions. It represents the version string
+// of the telemetry SDK.
+func TelemetrySDKVersion(val string) attribute.KeyValue {
+ return TelemetrySDKVersionKey.String(val)
+}
+
+// Enum values for telemetry.sdk.language
+var (
+ // cpp
+ // Stability: stable
+ TelemetrySDKLanguageCPP = TelemetrySDKLanguageKey.String("cpp")
+ // dotnet
+ // Stability: stable
+ TelemetrySDKLanguageDotnet = TelemetrySDKLanguageKey.String("dotnet")
+ // erlang
+ // Stability: stable
+ TelemetrySDKLanguageErlang = TelemetrySDKLanguageKey.String("erlang")
+ // go
+ // Stability: stable
+ TelemetrySDKLanguageGo = TelemetrySDKLanguageKey.String("go")
+ // java
+ // Stability: stable
+ TelemetrySDKLanguageJava = TelemetrySDKLanguageKey.String("java")
+ // nodejs
+ // Stability: stable
+ TelemetrySDKLanguageNodejs = TelemetrySDKLanguageKey.String("nodejs")
+ // php
+ // Stability: stable
+ TelemetrySDKLanguagePHP = TelemetrySDKLanguageKey.String("php")
+ // python
+ // Stability: stable
+ TelemetrySDKLanguagePython = TelemetrySDKLanguageKey.String("python")
+ // ruby
+ // Stability: stable
+ TelemetrySDKLanguageRuby = TelemetrySDKLanguageKey.String("ruby")
+ // rust
+ // Stability: stable
+ TelemetrySDKLanguageRust = TelemetrySDKLanguageKey.String("rust")
+ // swift
+ // Stability: stable
+ TelemetrySDKLanguageSwift = TelemetrySDKLanguageKey.String("swift")
+ // webjs
+ // Stability: stable
+ TelemetrySDKLanguageWebJS = TelemetrySDKLanguageKey.String("webjs")
+)
+
+// Namespace: test
+const (
+ // TestCaseNameKey is the attribute Key conforming to the "test.case.name"
+ // semantic conventions. It represents the fully qualified human readable name
+ // of the [test case].
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "org.example.TestCase1.test1", "example/tests/TestCase1.test1",
+ // "ExampleTestCase1_test1"
+ //
+ // [test case]: https://wikipedia.org/wiki/Test_case
+ TestCaseNameKey = attribute.Key("test.case.name")
+
+ // TestCaseResultStatusKey is the attribute Key conforming to the
+ // "test.case.result.status" semantic conventions. It represents the status of
+ // the actual test case result from test execution.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "pass", "fail"
+ TestCaseResultStatusKey = attribute.Key("test.case.result.status")
+
+ // TestSuiteNameKey is the attribute Key conforming to the "test.suite.name"
+ // semantic conventions. It represents the human readable name of a [test suite]
+ // .
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "TestSuite1"
+ //
+ // [test suite]: https://wikipedia.org/wiki/Test_suite
+ TestSuiteNameKey = attribute.Key("test.suite.name")
+
+ // TestSuiteRunStatusKey is the attribute Key conforming to the
+ // "test.suite.run.status" semantic conventions. It represents the status of the
+ // test suite run.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "success", "failure", "skipped", "aborted", "timed_out",
+ // "in_progress"
+ TestSuiteRunStatusKey = attribute.Key("test.suite.run.status")
+)
+
+// TestCaseName returns an attribute KeyValue conforming to the "test.case.name"
+// semantic conventions. It represents the fully qualified human readable name of
+// the [test case].
+//
+// [test case]: https://wikipedia.org/wiki/Test_case
+func TestCaseName(val string) attribute.KeyValue {
+ return TestCaseNameKey.String(val)
+}
+
+// TestSuiteName returns an attribute KeyValue conforming to the
+// "test.suite.name" semantic conventions. It represents the human readable name
+// of a [test suite].
+//
+// [test suite]: https://wikipedia.org/wiki/Test_suite
+func TestSuiteName(val string) attribute.KeyValue {
+ return TestSuiteNameKey.String(val)
+}
+
+// Enum values for test.case.result.status
+var (
+ // pass
+ // Stability: development
+ TestCaseResultStatusPass = TestCaseResultStatusKey.String("pass")
+ // fail
+ // Stability: development
+ TestCaseResultStatusFail = TestCaseResultStatusKey.String("fail")
+)
+
+// Enum values for test.suite.run.status
+var (
+ // success
+ // Stability: development
+ TestSuiteRunStatusSuccess = TestSuiteRunStatusKey.String("success")
+ // failure
+ // Stability: development
+ TestSuiteRunStatusFailure = TestSuiteRunStatusKey.String("failure")
+ // skipped
+ // Stability: development
+ TestSuiteRunStatusSkipped = TestSuiteRunStatusKey.String("skipped")
+ // aborted
+ // Stability: development
+ TestSuiteRunStatusAborted = TestSuiteRunStatusKey.String("aborted")
+ // timed_out
+ // Stability: development
+ TestSuiteRunStatusTimedOut = TestSuiteRunStatusKey.String("timed_out")
+ // in_progress
+ // Stability: development
+ TestSuiteRunStatusInProgress = TestSuiteRunStatusKey.String("in_progress")
+)
+
+// Namespace: thread
+const (
+ // ThreadIDKey is the attribute Key conforming to the "thread.id" semantic
+ // conventions. It represents the current "managed" thread ID (as opposed to OS
+ // thread ID).
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Note:
+ // Examples of where the value can be extracted from:
+ //
+ // | Language or platform | Source |
+ // | --- | --- |
+ // | JVM | `Thread.currentThread().threadId()` |
+ // | .NET | `Thread.CurrentThread.ManagedThreadId` |
+ // | Python | `threading.current_thread().ident` |
+ // | Ruby | `Thread.current.object_id` |
+ // | C++ | `std::this_thread::get_id()` |
+ // | Erlang | `erlang:self()` |
+ ThreadIDKey = attribute.Key("thread.id")
+
+ // ThreadNameKey is the attribute Key conforming to the "thread.name" semantic
+ // conventions. It represents the current thread name.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: main
+ // Note:
+ // Examples of where the value can be extracted from:
+ //
+ // | Language or platform | Source |
+ // | --- | --- |
+ // | JVM | `Thread.currentThread().getName()` |
+ // | .NET | `Thread.CurrentThread.Name` |
+ // | Python | `threading.current_thread().name` |
+ // | Ruby | `Thread.current.name` |
+ // | Erlang | `erlang:process_info(self(), registered_name)` |
+ ThreadNameKey = attribute.Key("thread.name")
+)
+
+// ThreadID returns an attribute KeyValue conforming to the "thread.id" semantic
+// conventions. It represents the current "managed" thread ID (as opposed to OS
+// thread ID).
+func ThreadID(val int) attribute.KeyValue {
+ return ThreadIDKey.Int(val)
+}
+
+// ThreadName returns an attribute KeyValue conforming to the "thread.name"
+// semantic conventions. It represents the current thread name.
+func ThreadName(val string) attribute.KeyValue {
+ return ThreadNameKey.String(val)
+}
+
+// Namespace: tls
+const (
+ // TLSCipherKey is the attribute Key conforming to the "tls.cipher" semantic
+ // conventions. It represents the string indicating the [cipher] used during the
+ // current connection.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "TLS_RSA_WITH_3DES_EDE_CBC_SHA",
+ // "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256"
+ // Note: The values allowed for `tls.cipher` MUST be one of the `Descriptions`
+ // of the [registered TLS Cipher Suits].
+ //
+ // [cipher]: https://datatracker.ietf.org/doc/html/rfc5246#appendix-A.5
+ // [registered TLS Cipher Suits]: https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#table-tls-parameters-4
+ TLSCipherKey = attribute.Key("tls.cipher")
+
+ // TLSClientCertificateKey is the attribute Key conforming to the
+ // "tls.client.certificate" semantic conventions. It represents the PEM-encoded
+ // stand-alone certificate offered by the client. This is usually
+ // mutually-exclusive of `client.certificate_chain` since this value also exists
+ // in that list.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "MII..."
+ TLSClientCertificateKey = attribute.Key("tls.client.certificate")
+
+ // TLSClientCertificateChainKey is the attribute Key conforming to the
+ // "tls.client.certificate_chain" semantic conventions. It represents the array
+ // of PEM-encoded certificates that make up the certificate chain offered by the
+ // client. This is usually mutually-exclusive of `client.certificate` since that
+ // value should be the first certificate in the chain.
+ //
+ // Type: string[]
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "MII...", "MI..."
+ TLSClientCertificateChainKey = attribute.Key("tls.client.certificate_chain")
+
+ // TLSClientHashMd5Key is the attribute Key conforming to the
+ // "tls.client.hash.md5" semantic conventions. It represents the certificate
+ // fingerprint using the MD5 digest of DER-encoded version of certificate
+ // offered by the client. For consistency with other hash values, this value
+ // should be formatted as an uppercase hash.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "0F76C7F2C55BFD7D8E8B8F4BFBF0C9EC"
+ TLSClientHashMd5Key = attribute.Key("tls.client.hash.md5")
+
+ // TLSClientHashSha1Key is the attribute Key conforming to the
+ // "tls.client.hash.sha1" semantic conventions. It represents the certificate
+ // fingerprint using the SHA1 digest of DER-encoded version of certificate
+ // offered by the client. For consistency with other hash values, this value
+ // should be formatted as an uppercase hash.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "9E393D93138888D288266C2D915214D1D1CCEB2A"
+ TLSClientHashSha1Key = attribute.Key("tls.client.hash.sha1")
+
+ // TLSClientHashSha256Key is the attribute Key conforming to the
+ // "tls.client.hash.sha256" semantic conventions. It represents the certificate
+ // fingerprint using the SHA256 digest of DER-encoded version of certificate
+ // offered by the client. For consistency with other hash values, this value
+ // should be formatted as an uppercase hash.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "0687F666A054EF17A08E2F2162EAB4CBC0D265E1D7875BE74BF3C712CA92DAF0"
+ TLSClientHashSha256Key = attribute.Key("tls.client.hash.sha256")
+
+ // TLSClientIssuerKey is the attribute Key conforming to the "tls.client.issuer"
+ // semantic conventions. It represents the distinguished name of [subject] of
+ // the issuer of the x.509 certificate presented by the client.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "CN=Example Root CA, OU=Infrastructure Team, DC=example, DC=com"
+ //
+ // [subject]: https://datatracker.ietf.org/doc/html/rfc5280#section-4.1.2.6
+ TLSClientIssuerKey = attribute.Key("tls.client.issuer")
+
+ // TLSClientJa3Key is the attribute Key conforming to the "tls.client.ja3"
+ // semantic conventions. It represents a hash that identifies clients based on
+ // how they perform an SSL/TLS handshake.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "d4e5b18d6b55c71272893221c96ba240"
+ TLSClientJa3Key = attribute.Key("tls.client.ja3")
+
+ // TLSClientNotAfterKey is the attribute Key conforming to the
+ // "tls.client.not_after" semantic conventions. It represents the date/Time
+ // indicating when client certificate is no longer considered valid.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "2021-01-01T00:00:00.000Z"
+ TLSClientNotAfterKey = attribute.Key("tls.client.not_after")
+
+ // TLSClientNotBeforeKey is the attribute Key conforming to the
+ // "tls.client.not_before" semantic conventions. It represents the date/Time
+ // indicating when client certificate is first considered valid.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "1970-01-01T00:00:00.000Z"
+ TLSClientNotBeforeKey = attribute.Key("tls.client.not_before")
+
+ // TLSClientSubjectKey is the attribute Key conforming to the
+ // "tls.client.subject" semantic conventions. It represents the distinguished
+ // name of subject of the x.509 certificate presented by the client.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "CN=myclient, OU=Documentation Team, DC=example, DC=com"
+ TLSClientSubjectKey = attribute.Key("tls.client.subject")
+
+ // TLSClientSupportedCiphersKey is the attribute Key conforming to the
+ // "tls.client.supported_ciphers" semantic conventions. It represents the array
+ // of ciphers offered by the client during the client hello.
+ //
+ // Type: string[]
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
+ // "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384"
+ TLSClientSupportedCiphersKey = attribute.Key("tls.client.supported_ciphers")
+
+ // TLSCurveKey is the attribute Key conforming to the "tls.curve" semantic
+ // conventions. It represents the string indicating the curve used for the given
+ // cipher, when applicable.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "secp256r1"
+ TLSCurveKey = attribute.Key("tls.curve")
+
+ // TLSEstablishedKey is the attribute Key conforming to the "tls.established"
+ // semantic conventions. It represents the boolean flag indicating if the TLS
+ // negotiation was successful and transitioned to an encrypted tunnel.
+ //
+ // Type: boolean
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: true
+ TLSEstablishedKey = attribute.Key("tls.established")
+
+ // TLSNextProtocolKey is the attribute Key conforming to the "tls.next_protocol"
+ // semantic conventions. It represents the string indicating the protocol being
+ // tunneled. Per the values in the [IANA registry], this string should be lower
+ // case.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "http/1.1"
+ //
+ // [IANA registry]: https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#alpn-protocol-ids
+ TLSNextProtocolKey = attribute.Key("tls.next_protocol")
+
+ // TLSProtocolNameKey is the attribute Key conforming to the "tls.protocol.name"
+ // semantic conventions. It represents the normalized lowercase protocol name
+ // parsed from original string of the negotiated [SSL/TLS protocol version].
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ //
+ // [SSL/TLS protocol version]: https://docs.openssl.org/1.1.1/man3/SSL_get_version/#return-values
+ TLSProtocolNameKey = attribute.Key("tls.protocol.name")
+
+ // TLSProtocolVersionKey is the attribute Key conforming to the
+ // "tls.protocol.version" semantic conventions. It represents the numeric part
+ // of the version parsed from the original string of the negotiated
+ // [SSL/TLS protocol version].
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "1.2", "3"
+ //
+ // [SSL/TLS protocol version]: https://docs.openssl.org/1.1.1/man3/SSL_get_version/#return-values
+ TLSProtocolVersionKey = attribute.Key("tls.protocol.version")
+
+ // TLSResumedKey is the attribute Key conforming to the "tls.resumed" semantic
+ // conventions. It represents the boolean flag indicating if this TLS connection
+ // was resumed from an existing TLS negotiation.
+ //
+ // Type: boolean
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: true
+ TLSResumedKey = attribute.Key("tls.resumed")
+
+ // TLSServerCertificateKey is the attribute Key conforming to the
+ // "tls.server.certificate" semantic conventions. It represents the PEM-encoded
+ // stand-alone certificate offered by the server. This is usually
+ // mutually-exclusive of `server.certificate_chain` since this value also exists
+ // in that list.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "MII..."
+ TLSServerCertificateKey = attribute.Key("tls.server.certificate")
+
+ // TLSServerCertificateChainKey is the attribute Key conforming to the
+ // "tls.server.certificate_chain" semantic conventions. It represents the array
+ // of PEM-encoded certificates that make up the certificate chain offered by the
+ // server. This is usually mutually-exclusive of `server.certificate` since that
+ // value should be the first certificate in the chain.
+ //
+ // Type: string[]
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "MII...", "MI..."
+ TLSServerCertificateChainKey = attribute.Key("tls.server.certificate_chain")
+
+ // TLSServerHashMd5Key is the attribute Key conforming to the
+ // "tls.server.hash.md5" semantic conventions. It represents the certificate
+ // fingerprint using the MD5 digest of DER-encoded version of certificate
+ // offered by the server. For consistency with other hash values, this value
+ // should be formatted as an uppercase hash.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "0F76C7F2C55BFD7D8E8B8F4BFBF0C9EC"
+ TLSServerHashMd5Key = attribute.Key("tls.server.hash.md5")
+
+ // TLSServerHashSha1Key is the attribute Key conforming to the
+ // "tls.server.hash.sha1" semantic conventions. It represents the certificate
+ // fingerprint using the SHA1 digest of DER-encoded version of certificate
+ // offered by the server. For consistency with other hash values, this value
+ // should be formatted as an uppercase hash.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "9E393D93138888D288266C2D915214D1D1CCEB2A"
+ TLSServerHashSha1Key = attribute.Key("tls.server.hash.sha1")
+
+ // TLSServerHashSha256Key is the attribute Key conforming to the
+ // "tls.server.hash.sha256" semantic conventions. It represents the certificate
+ // fingerprint using the SHA256 digest of DER-encoded version of certificate
+ // offered by the server. For consistency with other hash values, this value
+ // should be formatted as an uppercase hash.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "0687F666A054EF17A08E2F2162EAB4CBC0D265E1D7875BE74BF3C712CA92DAF0"
+ TLSServerHashSha256Key = attribute.Key("tls.server.hash.sha256")
+
+ // TLSServerIssuerKey is the attribute Key conforming to the "tls.server.issuer"
+ // semantic conventions. It represents the distinguished name of [subject] of
+ // the issuer of the x.509 certificate presented by the client.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "CN=Example Root CA, OU=Infrastructure Team, DC=example, DC=com"
+ //
+ // [subject]: https://datatracker.ietf.org/doc/html/rfc5280#section-4.1.2.6
+ TLSServerIssuerKey = attribute.Key("tls.server.issuer")
+
+ // TLSServerJa3sKey is the attribute Key conforming to the "tls.server.ja3s"
+ // semantic conventions. It represents a hash that identifies servers based on
+ // how they perform an SSL/TLS handshake.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "d4e5b18d6b55c71272893221c96ba240"
+ TLSServerJa3sKey = attribute.Key("tls.server.ja3s")
+
+ // TLSServerNotAfterKey is the attribute Key conforming to the
+ // "tls.server.not_after" semantic conventions. It represents the date/Time
+ // indicating when server certificate is no longer considered valid.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "2021-01-01T00:00:00.000Z"
+ TLSServerNotAfterKey = attribute.Key("tls.server.not_after")
+
+ // TLSServerNotBeforeKey is the attribute Key conforming to the
+ // "tls.server.not_before" semantic conventions. It represents the date/Time
+ // indicating when server certificate is first considered valid.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "1970-01-01T00:00:00.000Z"
+ TLSServerNotBeforeKey = attribute.Key("tls.server.not_before")
+
+ // TLSServerSubjectKey is the attribute Key conforming to the
+ // "tls.server.subject" semantic conventions. It represents the distinguished
+ // name of subject of the x.509 certificate presented by the server.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "CN=myserver, OU=Documentation Team, DC=example, DC=com"
+ TLSServerSubjectKey = attribute.Key("tls.server.subject")
+)
+
+// TLSCipher returns an attribute KeyValue conforming to the "tls.cipher"
+// semantic conventions. It represents the string indicating the [cipher] used
+// during the current connection.
+//
+// [cipher]: https://datatracker.ietf.org/doc/html/rfc5246#appendix-A.5
+func TLSCipher(val string) attribute.KeyValue {
+ return TLSCipherKey.String(val)
+}
+
+// TLSClientCertificate returns an attribute KeyValue conforming to the
+// "tls.client.certificate" semantic conventions. It represents the PEM-encoded
+// stand-alone certificate offered by the client. This is usually
+// mutually-exclusive of `client.certificate_chain` since this value also exists
+// in that list.
+func TLSClientCertificate(val string) attribute.KeyValue {
+ return TLSClientCertificateKey.String(val)
+}
+
+// TLSClientCertificateChain returns an attribute KeyValue conforming to the
+// "tls.client.certificate_chain" semantic conventions. It represents the array
+// of PEM-encoded certificates that make up the certificate chain offered by the
+// client. This is usually mutually-exclusive of `client.certificate` since that
+// value should be the first certificate in the chain.
+func TLSClientCertificateChain(val ...string) attribute.KeyValue {
+ return TLSClientCertificateChainKey.StringSlice(val)
+}
+
+// TLSClientHashMd5 returns an attribute KeyValue conforming to the
+// "tls.client.hash.md5" semantic conventions. It represents the certificate
+// fingerprint using the MD5 digest of DER-encoded version of certificate offered
+// by the client. For consistency with other hash values, this value should be
+// formatted as an uppercase hash.
+func TLSClientHashMd5(val string) attribute.KeyValue {
+ return TLSClientHashMd5Key.String(val)
+}
+
+// TLSClientHashSha1 returns an attribute KeyValue conforming to the
+// "tls.client.hash.sha1" semantic conventions. It represents the certificate
+// fingerprint using the SHA1 digest of DER-encoded version of certificate
+// offered by the client. For consistency with other hash values, this value
+// should be formatted as an uppercase hash.
+func TLSClientHashSha1(val string) attribute.KeyValue {
+ return TLSClientHashSha1Key.String(val)
+}
+
+// TLSClientHashSha256 returns an attribute KeyValue conforming to the
+// "tls.client.hash.sha256" semantic conventions. It represents the certificate
+// fingerprint using the SHA256 digest of DER-encoded version of certificate
+// offered by the client. For consistency with other hash values, this value
+// should be formatted as an uppercase hash.
+func TLSClientHashSha256(val string) attribute.KeyValue {
+ return TLSClientHashSha256Key.String(val)
+}
+
+// TLSClientIssuer returns an attribute KeyValue conforming to the
+// "tls.client.issuer" semantic conventions. It represents the distinguished name
+// of [subject] of the issuer of the x.509 certificate presented by the client.
+//
+// [subject]: https://datatracker.ietf.org/doc/html/rfc5280#section-4.1.2.6
+func TLSClientIssuer(val string) attribute.KeyValue {
+ return TLSClientIssuerKey.String(val)
+}
+
+// TLSClientJa3 returns an attribute KeyValue conforming to the "tls.client.ja3"
+// semantic conventions. It represents a hash that identifies clients based on
+// how they perform an SSL/TLS handshake.
+func TLSClientJa3(val string) attribute.KeyValue {
+ return TLSClientJa3Key.String(val)
+}
+
+// TLSClientNotAfter returns an attribute KeyValue conforming to the
+// "tls.client.not_after" semantic conventions. It represents the date/Time
+// indicating when client certificate is no longer considered valid.
+func TLSClientNotAfter(val string) attribute.KeyValue {
+ return TLSClientNotAfterKey.String(val)
+}
+
+// TLSClientNotBefore returns an attribute KeyValue conforming to the
+// "tls.client.not_before" semantic conventions. It represents the date/Time
+// indicating when client certificate is first considered valid.
+func TLSClientNotBefore(val string) attribute.KeyValue {
+ return TLSClientNotBeforeKey.String(val)
+}
+
+// TLSClientSubject returns an attribute KeyValue conforming to the
+// "tls.client.subject" semantic conventions. It represents the distinguished
+// name of subject of the x.509 certificate presented by the client.
+func TLSClientSubject(val string) attribute.KeyValue {
+ return TLSClientSubjectKey.String(val)
+}
+
+// TLSClientSupportedCiphers returns an attribute KeyValue conforming to the
+// "tls.client.supported_ciphers" semantic conventions. It represents the array
+// of ciphers offered by the client during the client hello.
+func TLSClientSupportedCiphers(val ...string) attribute.KeyValue {
+ return TLSClientSupportedCiphersKey.StringSlice(val)
+}
+
+// TLSCurve returns an attribute KeyValue conforming to the "tls.curve" semantic
+// conventions. It represents the string indicating the curve used for the given
+// cipher, when applicable.
+func TLSCurve(val string) attribute.KeyValue {
+ return TLSCurveKey.String(val)
+}
+
+// TLSEstablished returns an attribute KeyValue conforming to the
+// "tls.established" semantic conventions. It represents the boolean flag
+// indicating if the TLS negotiation was successful and transitioned to an
+// encrypted tunnel.
+func TLSEstablished(val bool) attribute.KeyValue {
+ return TLSEstablishedKey.Bool(val)
+}
+
+// TLSNextProtocol returns an attribute KeyValue conforming to the
+// "tls.next_protocol" semantic conventions. It represents the string indicating
+// the protocol being tunneled. Per the values in the [IANA registry], this
+// string should be lower case.
+//
+// [IANA registry]: https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#alpn-protocol-ids
+func TLSNextProtocol(val string) attribute.KeyValue {
+ return TLSNextProtocolKey.String(val)
+}
+
+// TLSProtocolVersion returns an attribute KeyValue conforming to the
+// "tls.protocol.version" semantic conventions. It represents the numeric part of
+// the version parsed from the original string of the negotiated
+// [SSL/TLS protocol version].
+//
+// [SSL/TLS protocol version]: https://docs.openssl.org/1.1.1/man3/SSL_get_version/#return-values
+func TLSProtocolVersion(val string) attribute.KeyValue {
+ return TLSProtocolVersionKey.String(val)
+}
+
+// TLSResumed returns an attribute KeyValue conforming to the "tls.resumed"
+// semantic conventions. It represents the boolean flag indicating if this TLS
+// connection was resumed from an existing TLS negotiation.
+func TLSResumed(val bool) attribute.KeyValue {
+ return TLSResumedKey.Bool(val)
+}
+
+// TLSServerCertificate returns an attribute KeyValue conforming to the
+// "tls.server.certificate" semantic conventions. It represents the PEM-encoded
+// stand-alone certificate offered by the server. This is usually
+// mutually-exclusive of `server.certificate_chain` since this value also exists
+// in that list.
+func TLSServerCertificate(val string) attribute.KeyValue {
+ return TLSServerCertificateKey.String(val)
+}
+
+// TLSServerCertificateChain returns an attribute KeyValue conforming to the
+// "tls.server.certificate_chain" semantic conventions. It represents the array
+// of PEM-encoded certificates that make up the certificate chain offered by the
+// server. This is usually mutually-exclusive of `server.certificate` since that
+// value should be the first certificate in the chain.
+func TLSServerCertificateChain(val ...string) attribute.KeyValue {
+ return TLSServerCertificateChainKey.StringSlice(val)
+}
+
+// TLSServerHashMd5 returns an attribute KeyValue conforming to the
+// "tls.server.hash.md5" semantic conventions. It represents the certificate
+// fingerprint using the MD5 digest of DER-encoded version of certificate offered
+// by the server. For consistency with other hash values, this value should be
+// formatted as an uppercase hash.
+func TLSServerHashMd5(val string) attribute.KeyValue {
+ return TLSServerHashMd5Key.String(val)
+}
+
+// TLSServerHashSha1 returns an attribute KeyValue conforming to the
+// "tls.server.hash.sha1" semantic conventions. It represents the certificate
+// fingerprint using the SHA1 digest of DER-encoded version of certificate
+// offered by the server. For consistency with other hash values, this value
+// should be formatted as an uppercase hash.
+func TLSServerHashSha1(val string) attribute.KeyValue {
+ return TLSServerHashSha1Key.String(val)
+}
+
+// TLSServerHashSha256 returns an attribute KeyValue conforming to the
+// "tls.server.hash.sha256" semantic conventions. It represents the certificate
+// fingerprint using the SHA256 digest of DER-encoded version of certificate
+// offered by the server. For consistency with other hash values, this value
+// should be formatted as an uppercase hash.
+func TLSServerHashSha256(val string) attribute.KeyValue {
+ return TLSServerHashSha256Key.String(val)
+}
+
+// TLSServerIssuer returns an attribute KeyValue conforming to the
+// "tls.server.issuer" semantic conventions. It represents the distinguished name
+// of [subject] of the issuer of the x.509 certificate presented by the client.
+//
+// [subject]: https://datatracker.ietf.org/doc/html/rfc5280#section-4.1.2.6
+func TLSServerIssuer(val string) attribute.KeyValue {
+ return TLSServerIssuerKey.String(val)
+}
+
+// TLSServerJa3s returns an attribute KeyValue conforming to the
+// "tls.server.ja3s" semantic conventions. It represents a hash that identifies
+// servers based on how they perform an SSL/TLS handshake.
+func TLSServerJa3s(val string) attribute.KeyValue {
+ return TLSServerJa3sKey.String(val)
+}
+
+// TLSServerNotAfter returns an attribute KeyValue conforming to the
+// "tls.server.not_after" semantic conventions. It represents the date/Time
+// indicating when server certificate is no longer considered valid.
+func TLSServerNotAfter(val string) attribute.KeyValue {
+ return TLSServerNotAfterKey.String(val)
+}
+
+// TLSServerNotBefore returns an attribute KeyValue conforming to the
+// "tls.server.not_before" semantic conventions. It represents the date/Time
+// indicating when server certificate is first considered valid.
+func TLSServerNotBefore(val string) attribute.KeyValue {
+ return TLSServerNotBeforeKey.String(val)
+}
+
+// TLSServerSubject returns an attribute KeyValue conforming to the
+// "tls.server.subject" semantic conventions. It represents the distinguished
+// name of subject of the x.509 certificate presented by the server.
+func TLSServerSubject(val string) attribute.KeyValue {
+ return TLSServerSubjectKey.String(val)
+}
+
+// Enum values for tls.protocol.name
+var (
+ // ssl
+ // Stability: development
+ TLSProtocolNameSsl = TLSProtocolNameKey.String("ssl")
+ // tls
+ // Stability: development
+ TLSProtocolNameTLS = TLSProtocolNameKey.String("tls")
+)
+
+// Namespace: url
+const (
+ // URLDomainKey is the attribute Key conforming to the "url.domain" semantic
+ // conventions. It represents the domain extracted from the `url.full`, such as
+ // "opentelemetry.io".
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "www.foo.bar", "opentelemetry.io", "3.12.167.2",
+ // "[1080:0:0:0:8:800:200C:417A]"
+ // Note: In some cases a URL may refer to an IP and/or port directly, without a
+ // domain name. In this case, the IP address would go to the domain field. If
+ // the URL contains a [literal IPv6 address] enclosed by `[` and `]`, the `[`
+ // and `]` characters should also be captured in the domain field.
+ //
+ // [literal IPv6 address]: https://www.rfc-editor.org/rfc/rfc2732#section-2
+ URLDomainKey = attribute.Key("url.domain")
+
+ // URLExtensionKey is the attribute Key conforming to the "url.extension"
+ // semantic conventions. It represents the file extension extracted from the
+ // `url.full`, excluding the leading dot.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "png", "gz"
+ // Note: The file extension is only set if it exists, as not every url has a
+ // file extension. When the file name has multiple extensions `example.tar.gz`,
+ // only the last one should be captured `gz`, not `tar.gz`.
+ URLExtensionKey = attribute.Key("url.extension")
+
+ // URLFragmentKey is the attribute Key conforming to the "url.fragment" semantic
+ // conventions. It represents the [URI fragment] component.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ //
+ // Examples: "SemConv"
+ //
+ // [URI fragment]: https://www.rfc-editor.org/rfc/rfc3986#section-3.5
+ URLFragmentKey = attribute.Key("url.fragment")
+
+ // URLFullKey is the attribute Key conforming to the "url.full" semantic
+ // conventions. It represents the absolute URL describing a network resource
+ // according to [RFC3986].
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ //
+ // Examples: "https://www.foo.bar/search?q=OpenTelemetry#SemConv", "//localhost"
+ // Note: For network calls, URL usually has
+ // `scheme://host[:port][path][?query][#fragment]` format, where the fragment
+ // is not transmitted over HTTP, but if it is known, it SHOULD be included
+ // nevertheless.
+ //
+ // `url.full` MUST NOT contain credentials passed via URL in form of
+ // `https://username:password@www.example.com/`.
+ // In such case username and password SHOULD be redacted and attribute's value
+ // SHOULD be `https://REDACTED:REDACTED@www.example.com/`.
+ //
+ // `url.full` SHOULD capture the absolute URL when it is available (or can be
+ // reconstructed).
+ //
+ // Sensitive content provided in `url.full` SHOULD be scrubbed when
+ // instrumentations can identify it.
+ //
+ //
+ // Query string values for the following keys SHOULD be redacted by default and
+ // replaced by the
+ // value `REDACTED`:
+ //
+ // - [`AWSAccessKeyId`]
+ // - [`Signature`]
+ // - [`sig`]
+ // - [`X-Goog-Signature`]
+ //
+ // This list is subject to change over time.
+ //
+ // Matching of query parameter keys against the sensitive list SHOULD be
+ // case-sensitive.
+ //
+ //
+ // Instrumentation MAY provide a way to override this list via declarative
+ // configuration.
+ // If so, it SHOULD use the `sensitive_query_parameters` property
+ // (an array of case-sensitive strings with minimum items 0) under
+ // `.instrumentation/development.general.sanitization.url`.
+ // This list is a full override of the default sensitive query parameter keys,
+ // it is not a list of keys in addition to the defaults.
+ //
+ // When a query string value is redacted, the query string key SHOULD still be
+ // preserved, e.g.
+ // `https://www.example.com/path?color=blue&sig=REDACTED`.
+ //
+ // [RFC3986]: https://www.rfc-editor.org/rfc/rfc3986
+ // [`AWSAccessKeyId`]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/RESTAuthentication.html#RESTAuthenticationQueryStringAuth
+ // [`Signature`]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/RESTAuthentication.html#RESTAuthenticationQueryStringAuth
+ // [`sig`]: https://learn.microsoft.com/azure/storage/common/storage-sas-overview#sas-token
+ // [`X-Goog-Signature`]: https://cloud.google.com/storage/docs/access-control/signed-urls
+ URLFullKey = attribute.Key("url.full")
+
+ // URLOriginalKey is the attribute Key conforming to the "url.original" semantic
+ // conventions. It represents the unmodified original URL as seen in the event
+ // source.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "https://www.foo.bar/search?q=OpenTelemetry#SemConv",
+ // "search?q=OpenTelemetry"
+ // Note: In network monitoring, the observed URL may be a full URL, whereas in
+ // access logs, the URL is often just represented as a path. This field is meant
+ // to represent the URL as it was observed, complete or not.
+ // `url.original` might contain credentials passed via URL in form of
+ // `https://username:password@www.example.com/`. In such case password and
+ // username SHOULD NOT be redacted and attribute's value SHOULD remain the same.
+ URLOriginalKey = attribute.Key("url.original")
+
+ // URLPathKey is the attribute Key conforming to the "url.path" semantic
+ // conventions. It represents the [URI path] component.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ //
+ // Examples: "/search"
+ // Note: Sensitive content provided in `url.path` SHOULD be scrubbed when
+ // instrumentations can identify it.
+ //
+ // [URI path]: https://www.rfc-editor.org/rfc/rfc3986#section-3.3
+ URLPathKey = attribute.Key("url.path")
+
+ // URLPortKey is the attribute Key conforming to the "url.port" semantic
+ // conventions. It represents the port extracted from the `url.full`.
+ //
+ // Type: int
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: 443
+ URLPortKey = attribute.Key("url.port")
+
+ // URLQueryKey is the attribute Key conforming to the "url.query" semantic
+ // conventions. It represents the [URI query] component.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ //
+ // Examples: "q=OpenTelemetry"
+ // Note: Sensitive content provided in `url.query` SHOULD be scrubbed when
+ // instrumentations can identify it.
+ //
+ //
+ // Query string values for the following keys SHOULD be redacted by default and
+ // replaced by the value `REDACTED`:
+ //
+ // - [`AWSAccessKeyId`]
+ // - [`Signature`]
+ // - [`sig`]
+ // - [`X-Goog-Signature`]
+ //
+ // This list is subject to change over time.
+ //
+ // Matching of query parameter keys against the sensitive list SHOULD be
+ // case-sensitive.
+ //
+ // Instrumentation MAY provide a way to override this list via declarative
+ // configuration.
+ // If so, it SHOULD use the `sensitive_query_parameters` property
+ // (an array of case-sensitive strings with minimum items 0) under
+ // `.instrumentation/development.general.sanitization.url`.
+ // This list is a full override of the default sensitive query parameter keys,
+ // it is not a list of keys in addition to the defaults.
+ //
+ // When a query string value is redacted, the query string key SHOULD still be
+ // preserved, e.g.
+ // `q=OpenTelemetry&sig=REDACTED`.
+ //
+ // [URI query]: https://www.rfc-editor.org/rfc/rfc3986#section-3.4
+ // [`AWSAccessKeyId`]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/RESTAuthentication.html#RESTAuthenticationQueryStringAuth
+ // [`Signature`]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/RESTAuthentication.html#RESTAuthenticationQueryStringAuth
+ // [`sig`]: https://learn.microsoft.com/azure/storage/common/storage-sas-overview#sas-token
+ // [`X-Goog-Signature`]: https://cloud.google.com/storage/docs/access-control/signed-urls
+ URLQueryKey = attribute.Key("url.query")
+
+ // URLRegisteredDomainKey is the attribute Key conforming to the
+ // "url.registered_domain" semantic conventions. It represents the highest
+ // registered url domain, stripped of the subdomain.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "example.com", "foo.co.uk"
+ // Note: This value can be determined precisely with the [public suffix list].
+ // For example, the registered domain for `foo.example.com` is `example.com`.
+ // Trying to approximate this by simply taking the last two labels will not work
+ // well for TLDs such as `co.uk`.
+ //
+ // [public suffix list]: https://publicsuffix.org/
+ URLRegisteredDomainKey = attribute.Key("url.registered_domain")
+
+ // URLSchemeKey is the attribute Key conforming to the "url.scheme" semantic
+ // conventions. It represents the [URI scheme] component identifying the used
+ // protocol.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ //
+ // Examples: "https", "ftp", "telnet"
+ //
+ // [URI scheme]: https://www.rfc-editor.org/rfc/rfc3986#section-3.1
+ URLSchemeKey = attribute.Key("url.scheme")
+
+ // URLSubdomainKey is the attribute Key conforming to the "url.subdomain"
+ // semantic conventions. It represents the subdomain portion of a fully
+ // qualified domain name includes all of the names except the host name under
+ // the registered_domain. In a partially qualified domain, or if the
+ // qualification level of the full name cannot be determined, subdomain contains
+ // all of the names below the registered domain.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "east", "sub2.sub1"
+ // Note: The subdomain portion of `www.east.mydomain.co.uk` is `east`. If the
+ // domain has multiple levels of subdomain, such as `sub2.sub1.example.com`, the
+ // subdomain field should contain `sub2.sub1`, with no trailing period.
+ URLSubdomainKey = attribute.Key("url.subdomain")
+
+ // URLTemplateKey is the attribute Key conforming to the "url.template" semantic
+ // conventions. It represents the low-cardinality template of an
+ // [absolute path reference].
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "/users/{id}", "/users/:id", "/users?id={id}"
+ //
+ // [absolute path reference]: https://www.rfc-editor.org/rfc/rfc3986#section-4.2
+ URLTemplateKey = attribute.Key("url.template")
+
+ // URLTopLevelDomainKey is the attribute Key conforming to the
+ // "url.top_level_domain" semantic conventions. It represents the effective top
+ // level domain (eTLD), also known as the domain suffix, is the last part of the
+ // domain name. For example, the top level domain for example.com is `com`.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "com", "co.uk"
+ // Note: This value can be determined precisely with the [public suffix list].
+ //
+ // [public suffix list]: https://publicsuffix.org/
+ URLTopLevelDomainKey = attribute.Key("url.top_level_domain")
+)
+
+// URLDomain returns an attribute KeyValue conforming to the "url.domain"
+// semantic conventions. It represents the domain extracted from the `url.full`,
+// such as "opentelemetry.io".
+func URLDomain(val string) attribute.KeyValue {
+ return URLDomainKey.String(val)
+}
+
+// URLExtension returns an attribute KeyValue conforming to the "url.extension"
+// semantic conventions. It represents the file extension extracted from the
+// `url.full`, excluding the leading dot.
+func URLExtension(val string) attribute.KeyValue {
+ return URLExtensionKey.String(val)
+}
+
+// URLFragment returns an attribute KeyValue conforming to the "url.fragment"
+// semantic conventions. It represents the [URI fragment] component.
+//
+// [URI fragment]: https://www.rfc-editor.org/rfc/rfc3986#section-3.5
+func URLFragment(val string) attribute.KeyValue {
+ return URLFragmentKey.String(val)
+}
+
+// URLFull returns an attribute KeyValue conforming to the "url.full" semantic
+// conventions. It represents the absolute URL describing a network resource
+// according to [RFC3986].
+//
+// [RFC3986]: https://www.rfc-editor.org/rfc/rfc3986
+func URLFull(val string) attribute.KeyValue {
+ return URLFullKey.String(val)
+}
+
+// URLOriginal returns an attribute KeyValue conforming to the "url.original"
+// semantic conventions. It represents the unmodified original URL as seen in the
+// event source.
+func URLOriginal(val string) attribute.KeyValue {
+ return URLOriginalKey.String(val)
+}
+
+// URLPath returns an attribute KeyValue conforming to the "url.path" semantic
+// conventions. It represents the [URI path] component.
+//
+// [URI path]: https://www.rfc-editor.org/rfc/rfc3986#section-3.3
+func URLPath(val string) attribute.KeyValue {
+ return URLPathKey.String(val)
+}
+
+// URLPort returns an attribute KeyValue conforming to the "url.port" semantic
+// conventions. It represents the port extracted from the `url.full`.
+func URLPort(val int) attribute.KeyValue {
+ return URLPortKey.Int(val)
+}
+
+// URLQuery returns an attribute KeyValue conforming to the "url.query" semantic
+// conventions. It represents the [URI query] component.
+//
+// [URI query]: https://www.rfc-editor.org/rfc/rfc3986#section-3.4
+func URLQuery(val string) attribute.KeyValue {
+ return URLQueryKey.String(val)
+}
+
+// URLRegisteredDomain returns an attribute KeyValue conforming to the
+// "url.registered_domain" semantic conventions. It represents the highest
+// registered url domain, stripped of the subdomain.
+func URLRegisteredDomain(val string) attribute.KeyValue {
+ return URLRegisteredDomainKey.String(val)
+}
+
+// URLScheme returns an attribute KeyValue conforming to the "url.scheme"
+// semantic conventions. It represents the [URI scheme] component identifying the
+// used protocol.
+//
+// [URI scheme]: https://www.rfc-editor.org/rfc/rfc3986#section-3.1
+func URLScheme(val string) attribute.KeyValue {
+ return URLSchemeKey.String(val)
+}
+
+// URLSubdomain returns an attribute KeyValue conforming to the "url.subdomain"
+// semantic conventions. It represents the subdomain portion of a fully qualified
+// domain name includes all of the names except the host name under the
+// registered_domain. In a partially qualified domain, or if the qualification
+// level of the full name cannot be determined, subdomain contains all of the
+// names below the registered domain.
+func URLSubdomain(val string) attribute.KeyValue {
+ return URLSubdomainKey.String(val)
+}
+
+// URLTemplate returns an attribute KeyValue conforming to the "url.template"
+// semantic conventions. It represents the low-cardinality template of an
+// [absolute path reference].
+//
+// [absolute path reference]: https://www.rfc-editor.org/rfc/rfc3986#section-4.2
+func URLTemplate(val string) attribute.KeyValue {
+ return URLTemplateKey.String(val)
+}
+
+// URLTopLevelDomain returns an attribute KeyValue conforming to the
+// "url.top_level_domain" semantic conventions. It represents the effective top
+// level domain (eTLD), also known as the domain suffix, is the last part of the
+// domain name. For example, the top level domain for example.com is `com`.
+func URLTopLevelDomain(val string) attribute.KeyValue {
+ return URLTopLevelDomainKey.String(val)
+}
+
+// Namespace: user
+const (
+ // UserEmailKey is the attribute Key conforming to the "user.email" semantic
+ // conventions. It represents the user email address.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "a.einstein@example.com"
+ UserEmailKey = attribute.Key("user.email")
+
+ // UserFullNameKey is the attribute Key conforming to the "user.full_name"
+ // semantic conventions. It represents the user's full name.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "Albert Einstein"
+ UserFullNameKey = attribute.Key("user.full_name")
+
+ // UserHashKey is the attribute Key conforming to the "user.hash" semantic
+ // conventions. It represents the unique user hash to correlate information for
+ // a user in anonymized form.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "364fc68eaf4c8acec74a4e52d7d1feaa"
+ // Note: Useful if `user.id` or `user.name` contain confidential information and
+ // cannot be used.
+ UserHashKey = attribute.Key("user.hash")
+
+ // UserIDKey is the attribute Key conforming to the "user.id" semantic
+ // conventions. It represents the unique identifier of the user.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "S-1-5-21-202424912787-2692429404-2351956786-1000"
+ UserIDKey = attribute.Key("user.id")
+
+ // UserNameKey is the attribute Key conforming to the "user.name" semantic
+ // conventions. It represents the short name or login/username of the user.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "a.einstein"
+ UserNameKey = attribute.Key("user.name")
+
+ // UserRolesKey is the attribute Key conforming to the "user.roles" semantic
+ // conventions. It represents the array of user roles at the time of the event.
+ //
+ // Type: string[]
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "admin", "reporting_user"
+ UserRolesKey = attribute.Key("user.roles")
+)
+
+// UserEmail returns an attribute KeyValue conforming to the "user.email"
+// semantic conventions. It represents the user email address.
+func UserEmail(val string) attribute.KeyValue {
+ return UserEmailKey.String(val)
+}
+
+// UserFullName returns an attribute KeyValue conforming to the "user.full_name"
+// semantic conventions. It represents the user's full name.
+func UserFullName(val string) attribute.KeyValue {
+ return UserFullNameKey.String(val)
+}
+
+// UserHash returns an attribute KeyValue conforming to the "user.hash" semantic
+// conventions. It represents the unique user hash to correlate information for a
+// user in anonymized form.
+func UserHash(val string) attribute.KeyValue {
+ return UserHashKey.String(val)
+}
+
+// UserID returns an attribute KeyValue conforming to the "user.id" semantic
+// conventions. It represents the unique identifier of the user.
+func UserID(val string) attribute.KeyValue {
+ return UserIDKey.String(val)
+}
+
+// UserName returns an attribute KeyValue conforming to the "user.name" semantic
+// conventions. It represents the short name or login/username of the user.
+func UserName(val string) attribute.KeyValue {
+ return UserNameKey.String(val)
+}
+
+// UserRoles returns an attribute KeyValue conforming to the "user.roles"
+// semantic conventions. It represents the array of user roles at the time of the
+// event.
+func UserRoles(val ...string) attribute.KeyValue {
+ return UserRolesKey.StringSlice(val)
+}
+
+// Namespace: user_agent
+const (
+ // UserAgentNameKey is the attribute Key conforming to the "user_agent.name"
+ // semantic conventions. It represents the name of the user-agent extracted from
+ // original. Usually refers to the browser's name.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "Safari", "YourApp"
+ // Note: [Example] of extracting browser's name from original string. In the
+ // case of using a user-agent for non-browser products, such as microservices
+ // with multiple names/versions inside the `user_agent.original`, the most
+ // significant name SHOULD be selected. In such a scenario it should align with
+ // `user_agent.version`
+ //
+ // [Example]: https://uaparser.dev/#demo
+ UserAgentNameKey = attribute.Key("user_agent.name")
+
+ // UserAgentOriginalKey is the attribute Key conforming to the
+ // "user_agent.original" semantic conventions. It represents the value of the
+ // [HTTP User-Agent] header sent by the client.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Stable
+ //
+ // Examples: "CERN-LineMode/2.15 libwww/2.17b3", "Mozilla/5.0 (iPhone; CPU
+ // iPhone OS 14_7_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko)
+ // Version/14.1.2 Mobile/15E148 Safari/604.1", "YourApp/1.0.0
+ // grpc-java-okhttp/1.27.2"
+ //
+ // [HTTP User-Agent]: https://www.rfc-editor.org/rfc/rfc9110.html#field.user-agent
+ UserAgentOriginalKey = attribute.Key("user_agent.original")
+
+ // UserAgentOSNameKey is the attribute Key conforming to the
+ // "user_agent.os.name" semantic conventions. It represents the human readable
+ // operating system name.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "iOS", "Android", "Ubuntu"
+ // Note: For mapping user agent strings to OS names, libraries such as
+ // [ua-parser] can be utilized.
+ //
+ // [ua-parser]: https://github.com/ua-parser
+ UserAgentOSNameKey = attribute.Key("user_agent.os.name")
+
+ // UserAgentOSVersionKey is the attribute Key conforming to the
+ // "user_agent.os.version" semantic conventions. It represents the version
+ // string of the operating system as defined in [Version Attributes].
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "14.2.1", "18.04.1"
+ // Note: For mapping user agent strings to OS versions, libraries such as
+ // [ua-parser] can be utilized.
+ //
+ // [Version Attributes]: /docs/resource/README.md#version-attributes
+ // [ua-parser]: https://github.com/ua-parser
+ UserAgentOSVersionKey = attribute.Key("user_agent.os.version")
+
+ // UserAgentSyntheticTypeKey is the attribute Key conforming to the
+ // "user_agent.synthetic.type" semantic conventions. It represents the specifies
+ // the category of synthetic traffic, such as tests or bots.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ // Note: This attribute MAY be derived from the contents of the
+ // `user_agent.original` attribute. Components that populate the attribute are
+ // responsible for determining what they consider to be synthetic bot or test
+ // traffic. This attribute can either be set for self-identification purposes,
+ // or on telemetry detected to be generated as a result of a synthetic request.
+ // This attribute is useful for distinguishing between genuine client traffic
+ // and synthetic traffic generated by bots or tests.
+ UserAgentSyntheticTypeKey = attribute.Key("user_agent.synthetic.type")
+
+ // UserAgentVersionKey is the attribute Key conforming to the
+ // "user_agent.version" semantic conventions. It represents the version of the
+ // user-agent extracted from original. Usually refers to the browser's version.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "14.1.2", "1.0.0"
+ // Note: [Example] of extracting browser's version from original string. In the
+ // case of using a user-agent for non-browser products, such as microservices
+ // with multiple names/versions inside the `user_agent.original`, the most
+ // significant version SHOULD be selected. In such a scenario it should align
+ // with `user_agent.name`
+ //
+ // [Example]: https://uaparser.dev/#demo
+ UserAgentVersionKey = attribute.Key("user_agent.version")
+)
+
+// UserAgentName returns an attribute KeyValue conforming to the
+// "user_agent.name" semantic conventions. It represents the name of the
+// user-agent extracted from original. Usually refers to the browser's name.
+func UserAgentName(val string) attribute.KeyValue {
+ return UserAgentNameKey.String(val)
+}
+
+// UserAgentOriginal returns an attribute KeyValue conforming to the
+// "user_agent.original" semantic conventions. It represents the value of the
+// [HTTP User-Agent] header sent by the client.
+//
+// [HTTP User-Agent]: https://www.rfc-editor.org/rfc/rfc9110.html#field.user-agent
+func UserAgentOriginal(val string) attribute.KeyValue {
+ return UserAgentOriginalKey.String(val)
+}
+
+// UserAgentOSName returns an attribute KeyValue conforming to the
+// "user_agent.os.name" semantic conventions. It represents the human readable
+// operating system name.
+func UserAgentOSName(val string) attribute.KeyValue {
+ return UserAgentOSNameKey.String(val)
+}
+
+// UserAgentOSVersion returns an attribute KeyValue conforming to the
+// "user_agent.os.version" semantic conventions. It represents the version string
+// of the operating system as defined in [Version Attributes].
+//
+// [Version Attributes]: /docs/resource/README.md#version-attributes
+func UserAgentOSVersion(val string) attribute.KeyValue {
+ return UserAgentOSVersionKey.String(val)
+}
+
+// UserAgentVersion returns an attribute KeyValue conforming to the
+// "user_agent.version" semantic conventions. It represents the version of the
+// user-agent extracted from original. Usually refers to the browser's version.
+func UserAgentVersion(val string) attribute.KeyValue {
+ return UserAgentVersionKey.String(val)
+}
+
+// Enum values for user_agent.synthetic.type
+var (
+ // Bot source.
+ // Stability: development
+ UserAgentSyntheticTypeBot = UserAgentSyntheticTypeKey.String("bot")
+ // Synthetic test source.
+ // Stability: development
+ UserAgentSyntheticTypeTest = UserAgentSyntheticTypeKey.String("test")
+)
+
+// Namespace: vcs
+const (
+ // VCSChangeIDKey is the attribute Key conforming to the "vcs.change.id"
+ // semantic conventions. It represents the ID of the change (pull request/merge
+ // request/changelist) if applicable. This is usually a unique (within
+ // repository) identifier generated by the VCS system.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "123"
+ VCSChangeIDKey = attribute.Key("vcs.change.id")
+
+ // VCSChangeStateKey is the attribute Key conforming to the "vcs.change.state"
+ // semantic conventions. It represents the state of the change (pull
+ // request/merge request/changelist).
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "open", "closed", "merged"
+ VCSChangeStateKey = attribute.Key("vcs.change.state")
+
+ // VCSChangeTitleKey is the attribute Key conforming to the "vcs.change.title"
+ // semantic conventions. It represents the human readable title of the change
+ // (pull request/merge request/changelist). This title is often a brief summary
+ // of the change and may get merged in to a ref as the commit summary.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "Fixes broken thing", "feat: add my new feature", "[chore] update
+ // dependency"
+ VCSChangeTitleKey = attribute.Key("vcs.change.title")
+
+ // VCSLineChangeTypeKey is the attribute Key conforming to the
+ // "vcs.line_change.type" semantic conventions. It represents the type of line
+ // change being measured on a branch or change.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "added", "removed"
+ VCSLineChangeTypeKey = attribute.Key("vcs.line_change.type")
+
+ // VCSOwnerNameKey is the attribute Key conforming to the "vcs.owner.name"
+ // semantic conventions. It represents the group owner within the version
+ // control system.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "my-org", "myteam", "business-unit"
+ VCSOwnerNameKey = attribute.Key("vcs.owner.name")
+
+ // VCSProviderNameKey is the attribute Key conforming to the "vcs.provider.name"
+ // semantic conventions. It represents the name of the version control system
+ // provider.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "github", "gitlab", "gitea", "bitbucket"
+ VCSProviderNameKey = attribute.Key("vcs.provider.name")
+
+ // VCSRefBaseNameKey is the attribute Key conforming to the "vcs.ref.base.name"
+ // semantic conventions. It represents the name of the [reference] such as
+ // **branch** or **tag** in the repository.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "my-feature-branch", "tag-1-test"
+ // Note: `base` refers to the starting point of a change. For example, `main`
+ // would be the base reference of type branch if you've created a new
+ // reference of type branch from it and created new commits.
+ //
+ // [reference]: https://git-scm.com/docs/gitglossary#def_ref
+ VCSRefBaseNameKey = attribute.Key("vcs.ref.base.name")
+
+ // VCSRefBaseRevisionKey is the attribute Key conforming to the
+ // "vcs.ref.base.revision" semantic conventions. It represents the revision,
+ // literally [revised version], The revision most often refers to a commit
+ // object in Git, or a revision number in SVN.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "9d59409acf479dfa0df1aa568182e43e43df8bbe28d60fcf2bc52e30068802cc",
+ // "main", "123", "HEAD"
+ // Note: `base` refers to the starting point of a change. For example, `main`
+ // would be the base reference of type branch if you've created a new
+ // reference of type branch from it and created new commits. The
+ // revision can be a full [hash value (see
+ // glossary)],
+ // of the recorded change to a ref within a repository pointing to a
+ // commit [commit] object. It does
+ // not necessarily have to be a hash; it can simply define a [revision
+ // number]
+ // which is an integer that is monotonically increasing. In cases where
+ // it is identical to the `ref.base.name`, it SHOULD still be included.
+ // It is up to the implementer to decide which value to set as the
+ // revision based on the VCS system and situational context.
+ //
+ // [revised version]: https://www.merriam-webster.com/dictionary/revision
+ // [hash value (see
+ // glossary)]: https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-5.pdf
+ // [commit]: https://git-scm.com/docs/git-commit
+ // [revision
+ // number]: https://svnbook.red-bean.com/en/1.7/svn.tour.revs.specifiers.html
+ VCSRefBaseRevisionKey = attribute.Key("vcs.ref.base.revision")
+
+ // VCSRefBaseTypeKey is the attribute Key conforming to the "vcs.ref.base.type"
+ // semantic conventions. It represents the type of the [reference] in the
+ // repository.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "branch", "tag"
+ // Note: `base` refers to the starting point of a change. For example, `main`
+ // would be the base reference of type branch if you've created a new
+ // reference of type branch from it and created new commits.
+ //
+ // [reference]: https://git-scm.com/docs/gitglossary#def_ref
+ VCSRefBaseTypeKey = attribute.Key("vcs.ref.base.type")
+
+ // VCSRefHeadNameKey is the attribute Key conforming to the "vcs.ref.head.name"
+ // semantic conventions. It represents the name of the [reference] such as
+ // **branch** or **tag** in the repository.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "my-feature-branch", "tag-1-test"
+ // Note: `head` refers to where you are right now; the current reference at a
+ // given time.
+ //
+ // [reference]: https://git-scm.com/docs/gitglossary#def_ref
+ VCSRefHeadNameKey = attribute.Key("vcs.ref.head.name")
+
+ // VCSRefHeadRevisionKey is the attribute Key conforming to the
+ // "vcs.ref.head.revision" semantic conventions. It represents the revision,
+ // literally [revised version], The revision most often refers to a commit
+ // object in Git, or a revision number in SVN.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "9d59409acf479dfa0df1aa568182e43e43df8bbe28d60fcf2bc52e30068802cc",
+ // "main", "123", "HEAD"
+ // Note: `head` refers to where you are right now; the current reference at a
+ // given time.The revision can be a full [hash value (see
+ // glossary)],
+ // of the recorded change to a ref within a repository pointing to a
+ // commit [commit] object. It does
+ // not necessarily have to be a hash; it can simply define a [revision
+ // number]
+ // which is an integer that is monotonically increasing. In cases where
+ // it is identical to the `ref.head.name`, it SHOULD still be included.
+ // It is up to the implementer to decide which value to set as the
+ // revision based on the VCS system and situational context.
+ //
+ // [revised version]: https://www.merriam-webster.com/dictionary/revision
+ // [hash value (see
+ // glossary)]: https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-5.pdf
+ // [commit]: https://git-scm.com/docs/git-commit
+ // [revision
+ // number]: https://svnbook.red-bean.com/en/1.7/svn.tour.revs.specifiers.html
+ VCSRefHeadRevisionKey = attribute.Key("vcs.ref.head.revision")
+
+ // VCSRefHeadTypeKey is the attribute Key conforming to the "vcs.ref.head.type"
+ // semantic conventions. It represents the type of the [reference] in the
+ // repository.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "branch", "tag"
+ // Note: `head` refers to where you are right now; the current reference at a
+ // given time.
+ //
+ // [reference]: https://git-scm.com/docs/gitglossary#def_ref
+ VCSRefHeadTypeKey = attribute.Key("vcs.ref.head.type")
+
+ // VCSRefTypeKey is the attribute Key conforming to the "vcs.ref.type" semantic
+ // conventions. It represents the type of the [reference] in the repository.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "branch", "tag"
+ //
+ // [reference]: https://git-scm.com/docs/gitglossary#def_ref
+ VCSRefTypeKey = attribute.Key("vcs.ref.type")
+
+ // VCSRepositoryNameKey is the attribute Key conforming to the
+ // "vcs.repository.name" semantic conventions. It represents the human readable
+ // name of the repository. It SHOULD NOT include any additional identifier like
+ // Group/SubGroup in GitLab or organization in GitHub.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "semantic-conventions", "my-cool-repo"
+ // Note: Due to it only being the name, it can clash with forks of the same
+ // repository if collecting telemetry across multiple orgs or groups in
+ // the same backends.
+ VCSRepositoryNameKey = attribute.Key("vcs.repository.name")
+
+ // VCSRepositoryURLFullKey is the attribute Key conforming to the
+ // "vcs.repository.url.full" semantic conventions. It represents the
+ // [canonical URL] of the repository providing the complete HTTP(S) address in
+ // order to locate and identify the repository through a browser.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples:
+ // "https://github.com/opentelemetry/open-telemetry-collector-contrib",
+ // "https://gitlab.com/my-org/my-project/my-projects-project/repo"
+ // Note: In Git Version Control Systems, the canonical URL SHOULD NOT include
+ // the `.git` extension.
+ //
+ // [canonical URL]: https://support.google.com/webmasters/answer/10347851
+ VCSRepositoryURLFullKey = attribute.Key("vcs.repository.url.full")
+
+ // VCSRevisionDeltaDirectionKey is the attribute Key conforming to the
+ // "vcs.revision_delta.direction" semantic conventions. It represents the type
+ // of revision comparison.
+ //
+ // Type: Enum
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "ahead", "behind"
+ VCSRevisionDeltaDirectionKey = attribute.Key("vcs.revision_delta.direction")
+)
+
+// VCSChangeID returns an attribute KeyValue conforming to the "vcs.change.id"
+// semantic conventions. It represents the ID of the change (pull request/merge
+// request/changelist) if applicable. This is usually a unique (within
+// repository) identifier generated by the VCS system.
+func VCSChangeID(val string) attribute.KeyValue {
+ return VCSChangeIDKey.String(val)
+}
+
+// VCSChangeTitle returns an attribute KeyValue conforming to the
+// "vcs.change.title" semantic conventions. It represents the human readable
+// title of the change (pull request/merge request/changelist). This title is
+// often a brief summary of the change and may get merged in to a ref as the
+// commit summary.
+func VCSChangeTitle(val string) attribute.KeyValue {
+ return VCSChangeTitleKey.String(val)
+}
+
+// VCSOwnerName returns an attribute KeyValue conforming to the "vcs.owner.name"
+// semantic conventions. It represents the group owner within the version control
+// system.
+func VCSOwnerName(val string) attribute.KeyValue {
+ return VCSOwnerNameKey.String(val)
+}
+
+// VCSRefBaseName returns an attribute KeyValue conforming to the
+// "vcs.ref.base.name" semantic conventions. It represents the name of the
+// [reference] such as **branch** or **tag** in the repository.
+//
+// [reference]: https://git-scm.com/docs/gitglossary#def_ref
+func VCSRefBaseName(val string) attribute.KeyValue {
+ return VCSRefBaseNameKey.String(val)
+}
+
+// VCSRefBaseRevision returns an attribute KeyValue conforming to the
+// "vcs.ref.base.revision" semantic conventions. It represents the revision,
+// literally [revised version], The revision most often refers to a commit object
+// in Git, or a revision number in SVN.
+//
+// [revised version]: https://www.merriam-webster.com/dictionary/revision
+func VCSRefBaseRevision(val string) attribute.KeyValue {
+ return VCSRefBaseRevisionKey.String(val)
+}
+
+// VCSRefHeadName returns an attribute KeyValue conforming to the
+// "vcs.ref.head.name" semantic conventions. It represents the name of the
+// [reference] such as **branch** or **tag** in the repository.
+//
+// [reference]: https://git-scm.com/docs/gitglossary#def_ref
+func VCSRefHeadName(val string) attribute.KeyValue {
+ return VCSRefHeadNameKey.String(val)
+}
+
+// VCSRefHeadRevision returns an attribute KeyValue conforming to the
+// "vcs.ref.head.revision" semantic conventions. It represents the revision,
+// literally [revised version], The revision most often refers to a commit object
+// in Git, or a revision number in SVN.
+//
+// [revised version]: https://www.merriam-webster.com/dictionary/revision
+func VCSRefHeadRevision(val string) attribute.KeyValue {
+ return VCSRefHeadRevisionKey.String(val)
+}
+
+// VCSRepositoryName returns an attribute KeyValue conforming to the
+// "vcs.repository.name" semantic conventions. It represents the human readable
+// name of the repository. It SHOULD NOT include any additional identifier like
+// Group/SubGroup in GitLab or organization in GitHub.
+func VCSRepositoryName(val string) attribute.KeyValue {
+ return VCSRepositoryNameKey.String(val)
+}
+
+// VCSRepositoryURLFull returns an attribute KeyValue conforming to the
+// "vcs.repository.url.full" semantic conventions. It represents the
+// [canonical URL] of the repository providing the complete HTTP(S) address in
+// order to locate and identify the repository through a browser.
+//
+// [canonical URL]: https://support.google.com/webmasters/answer/10347851
+func VCSRepositoryURLFull(val string) attribute.KeyValue {
+ return VCSRepositoryURLFullKey.String(val)
+}
+
+// Enum values for vcs.change.state
+var (
+ // Open means the change is currently active and under review. It hasn't been
+ // merged into the target branch yet, and it's still possible to make changes or
+ // add comments.
+ // Stability: development
+ VCSChangeStateOpen = VCSChangeStateKey.String("open")
+ // WIP (work-in-progress, draft) means the change is still in progress and not
+ // yet ready for a full review. It might still undergo significant changes.
+ // Stability: development
+ VCSChangeStateWip = VCSChangeStateKey.String("wip")
+ // Closed means the merge request has been closed without merging. This can
+ // happen for various reasons, such as the changes being deemed unnecessary, the
+ // issue being resolved in another way, or the author deciding to withdraw the
+ // request.
+ // Stability: development
+ VCSChangeStateClosed = VCSChangeStateKey.String("closed")
+ // Merged indicates that the change has been successfully integrated into the
+ // target codebase.
+ // Stability: development
+ VCSChangeStateMerged = VCSChangeStateKey.String("merged")
+)
+
+// Enum values for vcs.line_change.type
+var (
+ // How many lines were added.
+ // Stability: development
+ VCSLineChangeTypeAdded = VCSLineChangeTypeKey.String("added")
+ // How many lines were removed.
+ // Stability: development
+ VCSLineChangeTypeRemoved = VCSLineChangeTypeKey.String("removed")
+)
+
+// Enum values for vcs.provider.name
+var (
+ // [GitHub]
+ // Stability: development
+ //
+ // [GitHub]: https://github.com
+ VCSProviderNameGithub = VCSProviderNameKey.String("github")
+ // [GitLab]
+ // Stability: development
+ //
+ // [GitLab]: https://gitlab.com
+ VCSProviderNameGitlab = VCSProviderNameKey.String("gitlab")
+ // [Gitea]
+ // Stability: development
+ //
+ // [Gitea]: https://gitea.io
+ VCSProviderNameGitea = VCSProviderNameKey.String("gitea")
+ // [Bitbucket]
+ // Stability: development
+ //
+ // [Bitbucket]: https://bitbucket.org
+ VCSProviderNameBitbucket = VCSProviderNameKey.String("bitbucket")
+)
+
+// Enum values for vcs.ref.base.type
+var (
+ // [branch]
+ // Stability: development
+ //
+ // [branch]: https://git-scm.com/docs/gitglossary#Documentation/gitglossary.txt-aiddefbranchabranch
+ VCSRefBaseTypeBranch = VCSRefBaseTypeKey.String("branch")
+ // [tag]
+ // Stability: development
+ //
+ // [tag]: https://git-scm.com/docs/gitglossary#Documentation/gitglossary.txt-aiddeftagatag
+ VCSRefBaseTypeTag = VCSRefBaseTypeKey.String("tag")
+)
+
+// Enum values for vcs.ref.head.type
+var (
+ // [branch]
+ // Stability: development
+ //
+ // [branch]: https://git-scm.com/docs/gitglossary#Documentation/gitglossary.txt-aiddefbranchabranch
+ VCSRefHeadTypeBranch = VCSRefHeadTypeKey.String("branch")
+ // [tag]
+ // Stability: development
+ //
+ // [tag]: https://git-scm.com/docs/gitglossary#Documentation/gitglossary.txt-aiddeftagatag
+ VCSRefHeadTypeTag = VCSRefHeadTypeKey.String("tag")
+)
+
+// Enum values for vcs.ref.type
+var (
+ // [branch]
+ // Stability: development
+ //
+ // [branch]: https://git-scm.com/docs/gitglossary#Documentation/gitglossary.txt-aiddefbranchabranch
+ VCSRefTypeBranch = VCSRefTypeKey.String("branch")
+ // [tag]
+ // Stability: development
+ //
+ // [tag]: https://git-scm.com/docs/gitglossary#Documentation/gitglossary.txt-aiddeftagatag
+ VCSRefTypeTag = VCSRefTypeKey.String("tag")
+)
+
+// Enum values for vcs.revision_delta.direction
+var (
+ // How many revisions the change is behind the target ref.
+ // Stability: development
+ VCSRevisionDeltaDirectionBehind = VCSRevisionDeltaDirectionKey.String("behind")
+ // How many revisions the change is ahead of the target ref.
+ // Stability: development
+ VCSRevisionDeltaDirectionAhead = VCSRevisionDeltaDirectionKey.String("ahead")
+)
+
+// Namespace: webengine
+const (
+ // WebEngineDescriptionKey is the attribute Key conforming to the
+ // "webengine.description" semantic conventions. It represents the additional
+ // description of the web engine (e.g. detailed version and edition
+ // information).
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "WildFly Full 21.0.0.Final (WildFly Core 13.0.1.Final) -
+ // 2.2.2.Final"
+ WebEngineDescriptionKey = attribute.Key("webengine.description")
+
+ // WebEngineNameKey is the attribute Key conforming to the "webengine.name"
+ // semantic conventions. It represents the name of the web engine.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "WildFly"
+ WebEngineNameKey = attribute.Key("webengine.name")
+
+ // WebEngineVersionKey is the attribute Key conforming to the
+ // "webengine.version" semantic conventions. It represents the version of the
+ // web engine.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "21.0.0"
+ WebEngineVersionKey = attribute.Key("webengine.version")
+)
+
+// WebEngineDescription returns an attribute KeyValue conforming to the
+// "webengine.description" semantic conventions. It represents the additional
+// description of the web engine (e.g. detailed version and edition information).
+func WebEngineDescription(val string) attribute.KeyValue {
+ return WebEngineDescriptionKey.String(val)
+}
+
+// WebEngineName returns an attribute KeyValue conforming to the "webengine.name"
+// semantic conventions. It represents the name of the web engine.
+func WebEngineName(val string) attribute.KeyValue {
+ return WebEngineNameKey.String(val)
+}
+
+// WebEngineVersion returns an attribute KeyValue conforming to the
+// "webengine.version" semantic conventions. It represents the version of the web
+// engine.
+func WebEngineVersion(val string) attribute.KeyValue {
+ return WebEngineVersionKey.String(val)
+}
+
+// Namespace: zos
+const (
+ // ZOSSmfIDKey is the attribute Key conforming to the "zos.smf.id" semantic
+ // conventions. It represents the System Management Facility (SMF) Identifier
+ // uniquely identified a z/OS system within a SYSPLEX or mainframe environment
+ // and is used for system and performance analysis.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "SYS1"
+ ZOSSmfIDKey = attribute.Key("zos.smf.id")
+
+ // ZOSSysplexNameKey is the attribute Key conforming to the "zos.sysplex.name"
+ // semantic conventions. It represents the name of the SYSPLEX to which the z/OS
+ // system belongs too.
+ //
+ // Type: string
+ // RequirementLevel: Recommended
+ // Stability: Development
+ //
+ // Examples: "SYSPLEX1"
+ ZOSSysplexNameKey = attribute.Key("zos.sysplex.name")
+)
+
+// ZOSSmfID returns an attribute KeyValue conforming to the "zos.smf.id" semantic
+// conventions. It represents the System Management Facility (SMF) Identifier
+// uniquely identified a z/OS system within a SYSPLEX or mainframe environment
+// and is used for system and performance analysis.
+func ZOSSmfID(val string) attribute.KeyValue {
+ return ZOSSmfIDKey.String(val)
+}
+
+// ZOSSysplexName returns an attribute KeyValue conforming to the
+// "zos.sysplex.name" semantic conventions. It represents the name of the SYSPLEX
+// to which the z/OS system belongs too.
+func ZOSSysplexName(val string) attribute.KeyValue {
+ return ZOSSysplexNameKey.String(val)
+}
\ No newline at end of file
diff --git a/vendor/go.opentelemetry.io/otel/semconv/v1.41.0/doc.go b/vendor/go.opentelemetry.io/otel/semconv/v1.41.0/doc.go
new file mode 100644
index 000000000..a45d424d8
--- /dev/null
+++ b/vendor/go.opentelemetry.io/otel/semconv/v1.41.0/doc.go
@@ -0,0 +1,11 @@
+// Code generated from semantic convention specification. DO NOT EDIT.
+
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+// Package semconv implements OpenTelemetry semantic conventions.
+//
+// OpenTelemetry semantic conventions are agreed standardized naming
+// patterns for OpenTelemetry things. This package represents the v1.41.0
+// version of the OpenTelemetry semantic conventions.
+package semconv // import "go.opentelemetry.io/otel/semconv/v1.41.0"
diff --git a/vendor/go.opentelemetry.io/otel/semconv/v1.41.0/error_type.go b/vendor/go.opentelemetry.io/otel/semconv/v1.41.0/error_type.go
new file mode 100644
index 000000000..0b13f0de8
--- /dev/null
+++ b/vendor/go.opentelemetry.io/otel/semconv/v1.41.0/error_type.go
@@ -0,0 +1,83 @@
+// Code generated from semantic convention specification. DO NOT EDIT.
+
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+package semconv // import "go.opentelemetry.io/otel/semconv/v1.41.0"
+
+import (
+ "errors"
+ "fmt"
+ "reflect"
+
+ "go.opentelemetry.io/otel/attribute"
+)
+
+// ErrorType returns an [attribute.KeyValue] identifying the error type of err.
+//
+// If err is nil, the returned attribute has the default value
+// [ErrorTypeOther].
+//
+// If err or one of the errors in its chain has the method
+//
+// ErrorType() string
+//
+// the returned attribute has that method's return value. If multiple errors in
+// the chain implement this method, the value from the first match found by
+// [errors.As] is used. Otherwise, the returned attribute has a value derived
+// from the concrete type of err after unwrapping any wrappers created with
+// [fmt.Errorf].
+//
+// The key of the returned attribute is [ErrorTypeKey].
+func ErrorType(err error) attribute.KeyValue {
+ if err == nil {
+ return ErrorTypeOther
+ }
+
+ return ErrorTypeKey.String(errorType(err))
+}
+
+func errorType(err error) string {
+ var s string
+ if et, ok := err.(interface{ ErrorType() string }); ok {
+ // Fast path: check the top-level error first.
+ s = et.ErrorType()
+ } else {
+ // Fallback: search the error chain for an ErrorType method.
+ var et interface{ ErrorType() string }
+ if errors.As(err, &et) {
+ // Prioritize the ErrorType method if available.
+ s = et.ErrorType()
+ }
+ }
+ if s == "" {
+ // Fallback to reflection if the ErrorType method is not supported or
+ // returns an empty value.
+
+ t := reflect.TypeOf(unwrapFmtWrapped(err))
+ pkg, name := t.PkgPath(), t.Name()
+ if pkg != "" && name != "" {
+ s = pkg + "." + name
+ } else {
+ // The type has no package path or name (predeclared, not-defined,
+ // or alias for a not-defined type).
+ //
+ // This is not guaranteed to be unique, but is a best effort.
+ s = t.String()
+ }
+ }
+ return s
+}
+
+var fmtWrapErrorType = reflect.TypeOf(fmt.Errorf("wrapped: %w", errors.New("err")))
+
+func unwrapFmtWrapped(err error) error {
+ for reflect.TypeOf(err) == fmtWrapErrorType {
+ u := errors.Unwrap(err)
+ if u == nil {
+ return err // When the wrapped error is nil, use the concrete type of the wrapper.
+ }
+ err = u
+ }
+ return err
+}
diff --git a/vendor/go.opentelemetry.io/otel/semconv/v1.41.0/exception.go b/vendor/go.opentelemetry.io/otel/semconv/v1.41.0/exception.go
new file mode 100644
index 000000000..5f0151aff
--- /dev/null
+++ b/vendor/go.opentelemetry.io/otel/semconv/v1.41.0/exception.go
@@ -0,0 +1,11 @@
+// Code generated from semantic convention specification. DO NOT EDIT.
+
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+package semconv // import "go.opentelemetry.io/otel/semconv/v1.41.0"
+
+const (
+ // ExceptionEventName is the name of the Span event representing an exception.
+ ExceptionEventName = "exception"
+)
diff --git a/vendor/go.opentelemetry.io/otel/semconv/v1.41.0/schema.go b/vendor/go.opentelemetry.io/otel/semconv/v1.41.0/schema.go
new file mode 100644
index 000000000..24948a48f
--- /dev/null
+++ b/vendor/go.opentelemetry.io/otel/semconv/v1.41.0/schema.go
@@ -0,0 +1,11 @@
+// Code generated from semantic convention specification. DO NOT EDIT.
+
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+package semconv // import "go.opentelemetry.io/otel/semconv/v1.41.0"
+
+// SchemaURL is the schema URL that matches the version of the semantic conventions
+// that this package defines. Semconv packages starting from v1.4.0 must declare
+// non-empty schema URL in the form https://opentelemetry.io/schemas/
+const SchemaURL = "https://opentelemetry.io/schemas/1.41.0"
diff --git a/vendor/go.opentelemetry.io/otel/trace/auto.go b/vendor/go.opentelemetry.io/otel/trace/auto.go
index 604fdab44..a75cf047d 100644
--- a/vendor/go.opentelemetry.io/otel/trace/auto.go
+++ b/vendor/go.opentelemetry.io/otel/trace/auto.go
@@ -20,7 +20,7 @@ import (
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/codes"
- semconv "go.opentelemetry.io/otel/semconv/v1.39.0"
+ semconv "go.opentelemetry.io/otel/semconv/v1.41.0"
"go.opentelemetry.io/otel/trace/embedded"
"go.opentelemetry.io/otel/trace/internal/telemetry"
)
@@ -314,6 +314,14 @@ func convAttrValue(value attribute.Value) telemetry.Value {
case attribute.STRING:
v := truncate(maxSpan.AttrValueLen, value.AsString())
return telemetry.StringValue(v)
+ case attribute.BYTESLICE:
+ // len(v.AsString()) is identical to len(v.AsByteSlice()) but
+ // avoids allocating the full slice before truncation.
+ s := value.AsString()
+ if maxSpan.AttrValueLen >= 0 && len(s) > maxSpan.AttrValueLen {
+ return telemetry.BytesValue([]byte(s[:maxSpan.AttrValueLen]))
+ }
+ return telemetry.BytesValue([]byte(s))
case attribute.BOOLSLICE:
slice := value.AsBoolSlice()
out := make([]telemetry.Value, 0, len(slice))
@@ -343,6 +351,13 @@ func convAttrValue(value attribute.Value) telemetry.Value {
out = append(out, telemetry.StringValue(v))
}
return telemetry.SliceValue(out...)
+ case attribute.SLICE:
+ slice := value.AsSlice()
+ out := make([]telemetry.Value, 0, len(slice))
+ for _, v := range slice {
+ out = append(out, convAttrValue(v))
+ }
+ return telemetry.SliceValue(out...)
}
return telemetry.Value{}
}
@@ -463,7 +478,8 @@ func (s *autoSpan) RecordError(err error, opts ...EventOption) {
cfg := NewEventConfig(opts...)
attrs := cfg.Attributes()
- attrs = append(attrs,
+ attrs = append(
+ attrs,
semconv.ExceptionType(typeStr(err)),
semconv.ExceptionMessage(err.Error()),
)
diff --git a/vendor/go.opentelemetry.io/otel/trace/config.go b/vendor/go.opentelemetry.io/otel/trace/config.go
index d9ecef1ca..4cedba5ac 100644
--- a/vendor/go.opentelemetry.io/otel/trace/config.go
+++ b/vendor/go.opentelemetry.io/otel/trace/config.go
@@ -34,10 +34,17 @@ func (t *TracerConfig) SchemaURL() string {
return t.schemaURL
}
+type experimentalOption interface {
+ Experimental()
+}
+
// NewTracerConfig applies all the options to a returned TracerConfig.
func NewTracerConfig(options ...TracerOption) TracerConfig {
var config TracerConfig
for _, option := range options {
+ if _, ok := option.(experimentalOption); ok {
+ continue
+ }
config = option.apply(config)
}
return config
@@ -103,6 +110,9 @@ func (cfg *SpanConfig) SpanKind() SpanKind {
func NewSpanStartConfig(options ...SpanStartOption) SpanConfig {
var c SpanConfig
for _, option := range options {
+ if _, ok := option.(experimentalOption); ok {
+ continue
+ }
c = option.applySpanStart(c)
}
return c
@@ -115,6 +125,9 @@ func NewSpanStartConfig(options ...SpanStartOption) SpanConfig {
func NewSpanEndConfig(options ...SpanEndOption) SpanConfig {
var c SpanConfig
for _, option := range options {
+ if _, ok := option.(experimentalOption); ok {
+ continue
+ }
c = option.applySpanEnd(c)
}
return c
@@ -167,6 +180,9 @@ func (cfg *EventConfig) StackTrace() bool {
func NewEventConfig(options ...EventOption) EventConfig {
var c EventConfig
for _, option := range options {
+ if _, ok := option.(experimentalOption); ok {
+ continue
+ }
c = option.applyEvent(c)
}
if c.timestamp.IsZero() {
diff --git a/vendor/go.opentelemetry.io/otel/trace/internal/telemetry/span.go b/vendor/go.opentelemetry.io/otel/trace/internal/telemetry/span.go
index e7ca62c66..61c7819a2 100644
--- a/vendor/go.opentelemetry.io/otel/trace/internal/telemetry/span.go
+++ b/vendor/go.opentelemetry.io/otel/trace/internal/telemetry/span.go
@@ -314,9 +314,9 @@ type SpanEvent struct {
}
// MarshalJSON encodes e into OTLP formatted JSON.
-func (e SpanEvent) MarshalJSON() ([]byte, error) {
- t := e.Time.UnixNano()
- if e.Time.IsZero() || t < 0 {
+func (se SpanEvent) MarshalJSON() ([]byte, error) {
+ t := se.Time.UnixNano()
+ if se.Time.IsZero() || t < 0 {
t = 0
}
@@ -325,7 +325,7 @@ func (e SpanEvent) MarshalJSON() ([]byte, error) {
Alias
Time uint64 `json:"timeUnixNano,omitempty"`
}{
- Alias: Alias(e),
+ Alias: Alias(se),
Time: uint64(t), // nolint: gosec // >0 checked above
})
}
diff --git a/vendor/go.opentelemetry.io/otel/trace/trace.go b/vendor/go.opentelemetry.io/otel/trace/trace.go
index ee6f4bcb2..e3d103c4b 100644
--- a/vendor/go.opentelemetry.io/otel/trace/trace.go
+++ b/vendor/go.opentelemetry.io/otel/trace/trace.go
@@ -12,6 +12,11 @@ const (
// with the sampling bit set means the span is sampled.
FlagsSampled = TraceFlags(0x01)
+ // FlagsRandom is a bitmask with the random trace ID flag set. When
+ // set, it signals that the trace ID was generated randomly with at
+ // least 56 bits of randomness (W3C Trace Context Level 2).
+ FlagsRandom = TraceFlags(0x02)
+
errInvalidHexID errorConst = "trace-id and span-id can only contain [0-9a-f] characters, all lowercase"
errInvalidTraceIDLength errorConst = "hex encoded trace-id must have length equals to 32"
@@ -191,6 +196,20 @@ func (tf TraceFlags) WithSampled(sampled bool) TraceFlags { // nolint:revive //
return tf &^ FlagsSampled
}
+// IsRandom reports whether the random bit is set in the TraceFlags.
+func (tf TraceFlags) IsRandom() bool {
+ return tf&FlagsRandom == FlagsRandom
+}
+
+// WithRandom sets the random bit in a new copy of the TraceFlags.
+func (tf TraceFlags) WithRandom(random bool) TraceFlags { // nolint:revive // random is not a control flag.
+ if random {
+ return tf | FlagsRandom
+ }
+
+ return tf &^ FlagsRandom
+}
+
// MarshalJSON implements a custom marshal function to encode TraceFlags
// as a hex string.
func (tf TraceFlags) MarshalJSON() ([]byte, error) {
@@ -317,6 +336,11 @@ func (sc SpanContext) IsSampled() bool {
return sc.traceFlags.IsSampled()
}
+// IsRandom reports whether the random bit is set in the SpanContext's TraceFlags.
+func (sc SpanContext) IsRandom() bool {
+ return sc.traceFlags.IsRandom()
+}
+
// WithTraceFlags returns a new SpanContext with the TraceFlags replaced.
func (sc SpanContext) WithTraceFlags(flags TraceFlags) SpanContext {
return SpanContext{
diff --git a/vendor/go.opentelemetry.io/otel/trace/tracestate.go b/vendor/go.opentelemetry.io/otel/trace/tracestate.go
index df65c5cc7..e9cb3fd4d 100644
--- a/vendor/go.opentelemetry.io/otel/trace/tracestate.go
+++ b/vendor/go.opentelemetry.io/otel/trace/tracestate.go
@@ -64,7 +64,7 @@ func checkKeyRemain(key string) bool {
if v > 127 {
return false
}
- if isAlphaNum(byte(v)) {
+ if isAlphaNumASCII(v) {
continue
}
switch v {
@@ -92,7 +92,7 @@ func checkKeyPart(key string, n int) bool {
return ret && checkKeyRemain(key[1:])
}
-func isAlphaNum(c byte) bool {
+func isAlphaNumASCII[T rune | byte](c T) bool {
if c >= 'a' && c <= 'z' {
return true
}
@@ -108,7 +108,7 @@ func checkKeyTenant(key string, n int) bool {
if key == "" {
return false
}
- return isAlphaNum(key[0]) && len(key[1:]) <= n && checkKeyRemain(key[1:])
+ return isAlphaNumASCII(key[0]) && len(key[1:]) <= n && checkKeyRemain(key[1:])
}
// based on the W3C Trace Context specification
diff --git a/vendor/go.opentelemetry.io/otel/version.go b/vendor/go.opentelemetry.io/otel/version.go
index 900453406..72746acfd 100644
--- a/vendor/go.opentelemetry.io/otel/version.go
+++ b/vendor/go.opentelemetry.io/otel/version.go
@@ -5,5 +5,5 @@ package otel // import "go.opentelemetry.io/otel"
// Version is the current release version of OpenTelemetry in use.
func Version() string {
- return "1.41.0"
+ return "1.44.0"
}
diff --git a/vendor/go.opentelemetry.io/otel/versions.yaml b/vendor/go.opentelemetry.io/otel/versions.yaml
index 479c74787..d6dbf803e 100644
--- a/vendor/go.opentelemetry.io/otel/versions.yaml
+++ b/vendor/go.opentelemetry.io/otel/versions.yaml
@@ -3,7 +3,7 @@
module-sets:
stable-v1:
- version: v1.41.0
+ version: v1.44.0
modules:
- go.opentelemetry.io/otel
- go.opentelemetry.io/otel/bridge/opencensus
@@ -22,11 +22,12 @@ module-sets:
- go.opentelemetry.io/otel/sdk/metric
- go.opentelemetry.io/otel/trace
experimental-metrics:
- version: v0.63.0
+ version: v0.66.0
modules:
- go.opentelemetry.io/otel/exporters/prometheus
+ - go.opentelemetry.io/otel/metric/x
experimental-logs:
- version: v0.17.0
+ version: v0.20.0
modules:
- go.opentelemetry.io/otel/log
- go.opentelemetry.io/otel/log/logtest
@@ -36,7 +37,7 @@ module-sets:
- go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp
- go.opentelemetry.io/otel/exporters/stdout/stdoutlog
experimental-schema:
- version: v0.0.15
+ version: v0.0.17
modules:
- go.opentelemetry.io/otel/schema
excluded-modules:
@@ -55,6 +56,9 @@ modules:
go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc:
version-refs:
- ./internal/version.go
+ go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp:
+ version-refs:
+ - ./internal/version.go
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc:
version-refs:
- ./internal/version.go
@@ -64,3 +68,6 @@ modules:
go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp:
version-refs:
- ./internal/version.go
+ go.opentelemetry.io/otel/exporters/stdout/stdoutlog:
+ version-refs:
+ - ./internal/version.go
diff --git a/vendor/go.uber.org/automaxprocs/LICENSE b/vendor/go.uber.org/automaxprocs/LICENSE
deleted file mode 100644
index 20dcf51d9..000000000
--- a/vendor/go.uber.org/automaxprocs/LICENSE
+++ /dev/null
@@ -1,19 +0,0 @@
-Copyright (c) 2017 Uber Technologies, Inc.
-
-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.
\ No newline at end of file
diff --git a/vendor/go.uber.org/automaxprocs/internal/cgroups/cgroup.go b/vendor/go.uber.org/automaxprocs/internal/cgroups/cgroup.go
deleted file mode 100644
index fe4ecf561..000000000
--- a/vendor/go.uber.org/automaxprocs/internal/cgroups/cgroup.go
+++ /dev/null
@@ -1,79 +0,0 @@
-// Copyright (c) 2017 Uber Technologies, Inc.
-//
-// 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.
-
-//go:build linux
-// +build linux
-
-package cgroups
-
-import (
- "bufio"
- "io"
- "os"
- "path/filepath"
- "strconv"
-)
-
-// CGroup represents the data structure for a Linux control group.
-type CGroup struct {
- path string
-}
-
-// NewCGroup returns a new *CGroup from a given path.
-func NewCGroup(path string) *CGroup {
- return &CGroup{path: path}
-}
-
-// Path returns the path of the CGroup*.
-func (cg *CGroup) Path() string {
- return cg.path
-}
-
-// ParamPath returns the path of the given cgroup param under itself.
-func (cg *CGroup) ParamPath(param string) string {
- return filepath.Join(cg.path, param)
-}
-
-// readFirstLine reads the first line from a cgroup param file.
-func (cg *CGroup) readFirstLine(param string) (string, error) {
- paramFile, err := os.Open(cg.ParamPath(param))
- if err != nil {
- return "", err
- }
- defer paramFile.Close()
-
- scanner := bufio.NewScanner(paramFile)
- if scanner.Scan() {
- return scanner.Text(), nil
- }
- if err := scanner.Err(); err != nil {
- return "", err
- }
- return "", io.ErrUnexpectedEOF
-}
-
-// readInt parses the first line from a cgroup param file as int.
-func (cg *CGroup) readInt(param string) (int, error) {
- text, err := cg.readFirstLine(param)
- if err != nil {
- return 0, err
- }
- return strconv.Atoi(text)
-}
diff --git a/vendor/go.uber.org/automaxprocs/internal/cgroups/cgroups.go b/vendor/go.uber.org/automaxprocs/internal/cgroups/cgroups.go
deleted file mode 100644
index e89f54360..000000000
--- a/vendor/go.uber.org/automaxprocs/internal/cgroups/cgroups.go
+++ /dev/null
@@ -1,118 +0,0 @@
-// Copyright (c) 2017 Uber Technologies, Inc.
-//
-// 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.
-
-//go:build linux
-// +build linux
-
-package cgroups
-
-const (
- // _cgroupFSType is the Linux CGroup file system type used in
- // `/proc/$PID/mountinfo`.
- _cgroupFSType = "cgroup"
- // _cgroupSubsysCPU is the CPU CGroup subsystem.
- _cgroupSubsysCPU = "cpu"
- // _cgroupSubsysCPUAcct is the CPU accounting CGroup subsystem.
- _cgroupSubsysCPUAcct = "cpuacct"
- // _cgroupSubsysCPUSet is the CPUSet CGroup subsystem.
- _cgroupSubsysCPUSet = "cpuset"
- // _cgroupSubsysMemory is the Memory CGroup subsystem.
- _cgroupSubsysMemory = "memory"
-
- // _cgroupCPUCFSQuotaUsParam is the file name for the CGroup CFS quota
- // parameter.
- _cgroupCPUCFSQuotaUsParam = "cpu.cfs_quota_us"
- // _cgroupCPUCFSPeriodUsParam is the file name for the CGroup CFS period
- // parameter.
- _cgroupCPUCFSPeriodUsParam = "cpu.cfs_period_us"
-)
-
-const (
- _procPathCGroup = "/proc/self/cgroup"
- _procPathMountInfo = "/proc/self/mountinfo"
-)
-
-// CGroups is a map that associates each CGroup with its subsystem name.
-type CGroups map[string]*CGroup
-
-// NewCGroups returns a new *CGroups from given `mountinfo` and `cgroup` files
-// under for some process under `/proc` file system (see also proc(5) for more
-// information).
-func NewCGroups(procPathMountInfo, procPathCGroup string) (CGroups, error) {
- cgroupSubsystems, err := parseCGroupSubsystems(procPathCGroup)
- if err != nil {
- return nil, err
- }
-
- cgroups := make(CGroups)
- newMountPoint := func(mp *MountPoint) error {
- if mp.FSType != _cgroupFSType {
- return nil
- }
-
- for _, opt := range mp.SuperOptions {
- subsys, exists := cgroupSubsystems[opt]
- if !exists {
- continue
- }
-
- cgroupPath, err := mp.Translate(subsys.Name)
- if err != nil {
- return err
- }
- cgroups[opt] = NewCGroup(cgroupPath)
- }
-
- return nil
- }
-
- if err := parseMountInfo(procPathMountInfo, newMountPoint); err != nil {
- return nil, err
- }
- return cgroups, nil
-}
-
-// NewCGroupsForCurrentProcess returns a new *CGroups instance for the current
-// process.
-func NewCGroupsForCurrentProcess() (CGroups, error) {
- return NewCGroups(_procPathMountInfo, _procPathCGroup)
-}
-
-// CPUQuota returns the CPU quota applied with the CPU cgroup controller.
-// It is a result of `cpu.cfs_quota_us / cpu.cfs_period_us`. If the value of
-// `cpu.cfs_quota_us` was not set (-1), the method returns `(-1, nil)`.
-func (cg CGroups) CPUQuota() (float64, bool, error) {
- cpuCGroup, exists := cg[_cgroupSubsysCPU]
- if !exists {
- return -1, false, nil
- }
-
- cfsQuotaUs, err := cpuCGroup.readInt(_cgroupCPUCFSQuotaUsParam)
- if defined := cfsQuotaUs > 0; err != nil || !defined {
- return -1, defined, err
- }
-
- cfsPeriodUs, err := cpuCGroup.readInt(_cgroupCPUCFSPeriodUsParam)
- if defined := cfsPeriodUs > 0; err != nil || !defined {
- return -1, defined, err
- }
-
- return float64(cfsQuotaUs) / float64(cfsPeriodUs), true, nil
-}
diff --git a/vendor/go.uber.org/automaxprocs/internal/cgroups/cgroups2.go b/vendor/go.uber.org/automaxprocs/internal/cgroups/cgroups2.go
deleted file mode 100644
index 78556062f..000000000
--- a/vendor/go.uber.org/automaxprocs/internal/cgroups/cgroups2.go
+++ /dev/null
@@ -1,176 +0,0 @@
-// Copyright (c) 2022 Uber Technologies, Inc.
-//
-// 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.
-
-//go:build linux
-// +build linux
-
-package cgroups
-
-import (
- "bufio"
- "errors"
- "fmt"
- "io"
- "os"
- "path"
- "strconv"
- "strings"
-)
-
-const (
- // _cgroupv2CPUMax is the file name for the CGroup-V2 CPU max and period
- // parameter.
- _cgroupv2CPUMax = "cpu.max"
- // _cgroupFSType is the Linux CGroup-V2 file system type used in
- // `/proc/$PID/mountinfo`.
- _cgroupv2FSType = "cgroup2"
-
- _cgroupv2MountPoint = "/sys/fs/cgroup"
-
- _cgroupV2CPUMaxDefaultPeriod = 100000
- _cgroupV2CPUMaxQuotaMax = "max"
-)
-
-const (
- _cgroupv2CPUMaxQuotaIndex = iota
- _cgroupv2CPUMaxPeriodIndex
-)
-
-// ErrNotV2 indicates that the system is not using cgroups2.
-var ErrNotV2 = errors.New("not using cgroups2")
-
-// CGroups2 provides access to cgroups data for systems using cgroups2.
-type CGroups2 struct {
- mountPoint string
- groupPath string
- cpuMaxFile string
-}
-
-// NewCGroups2ForCurrentProcess builds a CGroups2 for the current process.
-//
-// This returns ErrNotV2 if the system is not using cgroups2.
-func NewCGroups2ForCurrentProcess() (*CGroups2, error) {
- return newCGroups2From(_procPathMountInfo, _procPathCGroup)
-}
-
-func newCGroups2From(mountInfoPath, procPathCGroup string) (*CGroups2, error) {
- isV2, err := isCGroupV2(mountInfoPath)
- if err != nil {
- return nil, err
- }
-
- if !isV2 {
- return nil, ErrNotV2
- }
-
- subsystems, err := parseCGroupSubsystems(procPathCGroup)
- if err != nil {
- return nil, err
- }
-
- // Find v2 subsystem by looking for the `0` id
- var v2subsys *CGroupSubsys
- for _, subsys := range subsystems {
- if subsys.ID == 0 {
- v2subsys = subsys
- break
- }
- }
-
- if v2subsys == nil {
- return nil, ErrNotV2
- }
-
- return &CGroups2{
- mountPoint: _cgroupv2MountPoint,
- groupPath: v2subsys.Name,
- cpuMaxFile: _cgroupv2CPUMax,
- }, nil
-}
-
-func isCGroupV2(procPathMountInfo string) (bool, error) {
- var (
- isV2 bool
- newMountPoint = func(mp *MountPoint) error {
- isV2 = isV2 || (mp.FSType == _cgroupv2FSType && mp.MountPoint == _cgroupv2MountPoint)
- return nil
- }
- )
-
- if err := parseMountInfo(procPathMountInfo, newMountPoint); err != nil {
- return false, err
- }
-
- return isV2, nil
-}
-
-// CPUQuota returns the CPU quota applied with the CPU cgroup2 controller.
-// It is a result of reading cpu quota and period from cpu.max file.
-// It will return `cpu.max / cpu.period`. If cpu.max is set to max, it returns
-// (-1, false, nil)
-func (cg *CGroups2) CPUQuota() (float64, bool, error) {
- cpuMaxParams, err := os.Open(path.Join(cg.mountPoint, cg.groupPath, cg.cpuMaxFile))
- if err != nil {
- if os.IsNotExist(err) {
- return -1, false, nil
- }
- return -1, false, err
- }
- defer cpuMaxParams.Close()
-
- scanner := bufio.NewScanner(cpuMaxParams)
- if scanner.Scan() {
- fields := strings.Fields(scanner.Text())
- if len(fields) == 0 || len(fields) > 2 {
- return -1, false, fmt.Errorf("invalid format")
- }
-
- if fields[_cgroupv2CPUMaxQuotaIndex] == _cgroupV2CPUMaxQuotaMax {
- return -1, false, nil
- }
-
- max, err := strconv.Atoi(fields[_cgroupv2CPUMaxQuotaIndex])
- if err != nil {
- return -1, false, err
- }
-
- var period int
- if len(fields) == 1 {
- period = _cgroupV2CPUMaxDefaultPeriod
- } else {
- period, err = strconv.Atoi(fields[_cgroupv2CPUMaxPeriodIndex])
- if err != nil {
- return -1, false, err
- }
-
- if period == 0 {
- return -1, false, errors.New("zero value for period is not allowed")
- }
- }
-
- return float64(max) / float64(period), true, nil
- }
-
- if err := scanner.Err(); err != nil {
- return -1, false, err
- }
-
- return 0, false, io.ErrUnexpectedEOF
-}
diff --git a/vendor/go.uber.org/automaxprocs/internal/cgroups/doc.go b/vendor/go.uber.org/automaxprocs/internal/cgroups/doc.go
deleted file mode 100644
index 113555f63..000000000
--- a/vendor/go.uber.org/automaxprocs/internal/cgroups/doc.go
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright (c) 2017 Uber Technologies, Inc.
-//
-// 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.
-
-// Package cgroups provides utilities to access Linux control group (CGroups)
-// parameters (CPU quota, for example) for a given process.
-package cgroups
diff --git a/vendor/go.uber.org/automaxprocs/internal/cgroups/errors.go b/vendor/go.uber.org/automaxprocs/internal/cgroups/errors.go
deleted file mode 100644
index 94ac75a46..000000000
--- a/vendor/go.uber.org/automaxprocs/internal/cgroups/errors.go
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright (c) 2017 Uber Technologies, Inc.
-//
-// 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.
-
-//go:build linux
-// +build linux
-
-package cgroups
-
-import "fmt"
-
-type cgroupSubsysFormatInvalidError struct {
- line string
-}
-
-type mountPointFormatInvalidError struct {
- line string
-}
-
-type pathNotExposedFromMountPointError struct {
- mountPoint string
- root string
- path string
-}
-
-func (err cgroupSubsysFormatInvalidError) Error() string {
- return fmt.Sprintf("invalid format for CGroupSubsys: %q", err.line)
-}
-
-func (err mountPointFormatInvalidError) Error() string {
- return fmt.Sprintf("invalid format for MountPoint: %q", err.line)
-}
-
-func (err pathNotExposedFromMountPointError) Error() string {
- return fmt.Sprintf("path %q is not a descendant of mount point root %q and cannot be exposed from %q", err.path, err.root, err.mountPoint)
-}
diff --git a/vendor/go.uber.org/automaxprocs/internal/cgroups/mountpoint.go b/vendor/go.uber.org/automaxprocs/internal/cgroups/mountpoint.go
deleted file mode 100644
index f3877f78a..000000000
--- a/vendor/go.uber.org/automaxprocs/internal/cgroups/mountpoint.go
+++ /dev/null
@@ -1,171 +0,0 @@
-// Copyright (c) 2017 Uber Technologies, Inc.
-//
-// 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.
-
-//go:build linux
-// +build linux
-
-package cgroups
-
-import (
- "bufio"
- "os"
- "path/filepath"
- "strconv"
- "strings"
-)
-
-const (
- _mountInfoSep = " "
- _mountInfoOptsSep = ","
- _mountInfoOptionalFieldsSep = "-"
-)
-
-const (
- _miFieldIDMountID = iota
- _miFieldIDParentID
- _miFieldIDDeviceID
- _miFieldIDRoot
- _miFieldIDMountPoint
- _miFieldIDOptions
- _miFieldIDOptionalFields
-
- _miFieldCountFirstHalf
-)
-
-const (
- _miFieldOffsetFSType = iota
- _miFieldOffsetMountSource
- _miFieldOffsetSuperOptions
-
- _miFieldCountSecondHalf
-)
-
-const _miFieldCountMin = _miFieldCountFirstHalf + _miFieldCountSecondHalf
-
-// MountPoint is the data structure for the mount points in
-// `/proc/$PID/mountinfo`. See also proc(5) for more information.
-type MountPoint struct {
- MountID int
- ParentID int
- DeviceID string
- Root string
- MountPoint string
- Options []string
- OptionalFields []string
- FSType string
- MountSource string
- SuperOptions []string
-}
-
-// NewMountPointFromLine parses a line read from `/proc/$PID/mountinfo` and
-// returns a new *MountPoint.
-func NewMountPointFromLine(line string) (*MountPoint, error) {
- fields := strings.Split(line, _mountInfoSep)
-
- if len(fields) < _miFieldCountMin {
- return nil, mountPointFormatInvalidError{line}
- }
-
- mountID, err := strconv.Atoi(fields[_miFieldIDMountID])
- if err != nil {
- return nil, err
- }
-
- parentID, err := strconv.Atoi(fields[_miFieldIDParentID])
- if err != nil {
- return nil, err
- }
-
- for i, field := range fields[_miFieldIDOptionalFields:] {
- if field == _mountInfoOptionalFieldsSep {
- // End of optional fields.
- fsTypeStart := _miFieldIDOptionalFields + i + 1
-
- // Now we know where the optional fields end, split the line again with a
- // limit to avoid issues with spaces in super options as present on WSL.
- fields = strings.SplitN(line, _mountInfoSep, fsTypeStart+_miFieldCountSecondHalf)
- if len(fields) != fsTypeStart+_miFieldCountSecondHalf {
- return nil, mountPointFormatInvalidError{line}
- }
-
- miFieldIDFSType := _miFieldOffsetFSType + fsTypeStart
- miFieldIDMountSource := _miFieldOffsetMountSource + fsTypeStart
- miFieldIDSuperOptions := _miFieldOffsetSuperOptions + fsTypeStart
-
- return &MountPoint{
- MountID: mountID,
- ParentID: parentID,
- DeviceID: fields[_miFieldIDDeviceID],
- Root: fields[_miFieldIDRoot],
- MountPoint: fields[_miFieldIDMountPoint],
- Options: strings.Split(fields[_miFieldIDOptions], _mountInfoOptsSep),
- OptionalFields: fields[_miFieldIDOptionalFields:(fsTypeStart - 1)],
- FSType: fields[miFieldIDFSType],
- MountSource: fields[miFieldIDMountSource],
- SuperOptions: strings.Split(fields[miFieldIDSuperOptions], _mountInfoOptsSep),
- }, nil
- }
- }
-
- return nil, mountPointFormatInvalidError{line}
-}
-
-// Translate converts an absolute path inside the *MountPoint's file system to
-// the host file system path in the mount namespace the *MountPoint belongs to.
-func (mp *MountPoint) Translate(absPath string) (string, error) {
- relPath, err := filepath.Rel(mp.Root, absPath)
-
- if err != nil {
- return "", err
- }
- if relPath == ".." || strings.HasPrefix(relPath, "../") {
- return "", pathNotExposedFromMountPointError{
- mountPoint: mp.MountPoint,
- root: mp.Root,
- path: absPath,
- }
- }
-
- return filepath.Join(mp.MountPoint, relPath), nil
-}
-
-// parseMountInfo parses procPathMountInfo (usually at `/proc/$PID/mountinfo`)
-// and yields parsed *MountPoint into newMountPoint.
-func parseMountInfo(procPathMountInfo string, newMountPoint func(*MountPoint) error) error {
- mountInfoFile, err := os.Open(procPathMountInfo)
- if err != nil {
- return err
- }
- defer mountInfoFile.Close()
-
- scanner := bufio.NewScanner(mountInfoFile)
-
- for scanner.Scan() {
- mountPoint, err := NewMountPointFromLine(scanner.Text())
- if err != nil {
- return err
- }
- if err := newMountPoint(mountPoint); err != nil {
- return err
- }
- }
-
- return scanner.Err()
-}
diff --git a/vendor/go.uber.org/automaxprocs/internal/cgroups/subsys.go b/vendor/go.uber.org/automaxprocs/internal/cgroups/subsys.go
deleted file mode 100644
index cddc3eaec..000000000
--- a/vendor/go.uber.org/automaxprocs/internal/cgroups/subsys.go
+++ /dev/null
@@ -1,103 +0,0 @@
-// Copyright (c) 2017 Uber Technologies, Inc.
-//
-// 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.
-
-//go:build linux
-// +build linux
-
-package cgroups
-
-import (
- "bufio"
- "os"
- "strconv"
- "strings"
-)
-
-const (
- _cgroupSep = ":"
- _cgroupSubsysSep = ","
-)
-
-const (
- _csFieldIDID = iota
- _csFieldIDSubsystems
- _csFieldIDName
- _csFieldCount
-)
-
-// CGroupSubsys represents the data structure for entities in
-// `/proc/$PID/cgroup`. See also proc(5) for more information.
-type CGroupSubsys struct {
- ID int
- Subsystems []string
- Name string
-}
-
-// NewCGroupSubsysFromLine returns a new *CGroupSubsys by parsing a string in
-// the format of `/proc/$PID/cgroup`
-func NewCGroupSubsysFromLine(line string) (*CGroupSubsys, error) {
- fields := strings.SplitN(line, _cgroupSep, _csFieldCount)
-
- if len(fields) != _csFieldCount {
- return nil, cgroupSubsysFormatInvalidError{line}
- }
-
- id, err := strconv.Atoi(fields[_csFieldIDID])
- if err != nil {
- return nil, err
- }
-
- cgroup := &CGroupSubsys{
- ID: id,
- Subsystems: strings.Split(fields[_csFieldIDSubsystems], _cgroupSubsysSep),
- Name: fields[_csFieldIDName],
- }
-
- return cgroup, nil
-}
-
-// parseCGroupSubsystems parses procPathCGroup (usually at `/proc/$PID/cgroup`)
-// and returns a new map[string]*CGroupSubsys.
-func parseCGroupSubsystems(procPathCGroup string) (map[string]*CGroupSubsys, error) {
- cgroupFile, err := os.Open(procPathCGroup)
- if err != nil {
- return nil, err
- }
- defer cgroupFile.Close()
-
- scanner := bufio.NewScanner(cgroupFile)
- subsystems := make(map[string]*CGroupSubsys)
-
- for scanner.Scan() {
- cgroup, err := NewCGroupSubsysFromLine(scanner.Text())
- if err != nil {
- return nil, err
- }
- for _, subsys := range cgroup.Subsystems {
- subsystems[subsys] = cgroup
- }
- }
-
- if err := scanner.Err(); err != nil {
- return nil, err
- }
-
- return subsystems, nil
-}
diff --git a/vendor/go.uber.org/automaxprocs/internal/runtime/cpu_quota_linux.go b/vendor/go.uber.org/automaxprocs/internal/runtime/cpu_quota_linux.go
deleted file mode 100644
index f9057fd27..000000000
--- a/vendor/go.uber.org/automaxprocs/internal/runtime/cpu_quota_linux.go
+++ /dev/null
@@ -1,75 +0,0 @@
-// Copyright (c) 2017 Uber Technologies, Inc.
-//
-// 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.
-
-//go:build linux
-// +build linux
-
-package runtime
-
-import (
- "errors"
-
- cg "go.uber.org/automaxprocs/internal/cgroups"
-)
-
-// CPUQuotaToGOMAXPROCS converts the CPU quota applied to the calling process
-// to a valid GOMAXPROCS value. The quota is converted from float to int using round.
-// If round == nil, DefaultRoundFunc is used.
-func CPUQuotaToGOMAXPROCS(minValue int, round func(v float64) int) (int, CPUQuotaStatus, error) {
- if round == nil {
- round = DefaultRoundFunc
- }
- cgroups, err := _newQueryer()
- if err != nil {
- return -1, CPUQuotaUndefined, err
- }
-
- quota, defined, err := cgroups.CPUQuota()
- if !defined || err != nil {
- return -1, CPUQuotaUndefined, err
- }
-
- maxProcs := round(quota)
- if minValue > 0 && maxProcs < minValue {
- return minValue, CPUQuotaMinUsed, nil
- }
- return maxProcs, CPUQuotaUsed, nil
-}
-
-type queryer interface {
- CPUQuota() (float64, bool, error)
-}
-
-var (
- _newCgroups2 = cg.NewCGroups2ForCurrentProcess
- _newCgroups = cg.NewCGroupsForCurrentProcess
- _newQueryer = newQueryer
-)
-
-func newQueryer() (queryer, error) {
- cgroups, err := _newCgroups2()
- if err == nil {
- return cgroups, nil
- }
- if errors.Is(err, cg.ErrNotV2) {
- return _newCgroups()
- }
- return nil, err
-}
diff --git a/vendor/go.uber.org/automaxprocs/internal/runtime/cpu_quota_unsupported.go b/vendor/go.uber.org/automaxprocs/internal/runtime/cpu_quota_unsupported.go
deleted file mode 100644
index e74701508..000000000
--- a/vendor/go.uber.org/automaxprocs/internal/runtime/cpu_quota_unsupported.go
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright (c) 2017 Uber Technologies, Inc.
-//
-// 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.
-
-//go:build !linux
-// +build !linux
-
-package runtime
-
-// CPUQuotaToGOMAXPROCS converts the CPU quota applied to the calling process
-// to a valid GOMAXPROCS value. This is Linux-specific and not supported in the
-// current OS.
-func CPUQuotaToGOMAXPROCS(_ int, _ func(v float64) int) (int, CPUQuotaStatus, error) {
- return -1, CPUQuotaUndefined, nil
-}
diff --git a/vendor/go.uber.org/automaxprocs/internal/runtime/runtime.go b/vendor/go.uber.org/automaxprocs/internal/runtime/runtime.go
deleted file mode 100644
index f8a2834ac..000000000
--- a/vendor/go.uber.org/automaxprocs/internal/runtime/runtime.go
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright (c) 2017 Uber Technologies, Inc.
-//
-// 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.
-
-package runtime
-
-import "math"
-
-// CPUQuotaStatus presents the status of how CPU quota is used
-type CPUQuotaStatus int
-
-const (
- // CPUQuotaUndefined is returned when CPU quota is undefined
- CPUQuotaUndefined CPUQuotaStatus = iota
- // CPUQuotaUsed is returned when a valid CPU quota can be used
- CPUQuotaUsed
- // CPUQuotaMinUsed is returned when CPU quota is smaller than the min value
- CPUQuotaMinUsed
-)
-
-// DefaultRoundFunc is the default function to convert CPU quota from float to int. It rounds the value down (floor).
-func DefaultRoundFunc(v float64) int {
- return int(math.Floor(v))
-}
diff --git a/vendor/go.uber.org/automaxprocs/maxprocs/maxprocs.go b/vendor/go.uber.org/automaxprocs/maxprocs/maxprocs.go
deleted file mode 100644
index e561fe60b..000000000
--- a/vendor/go.uber.org/automaxprocs/maxprocs/maxprocs.go
+++ /dev/null
@@ -1,139 +0,0 @@
-// Copyright (c) 2017 Uber Technologies, Inc.
-//
-// 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.
-
-// Package maxprocs lets Go programs easily configure runtime.GOMAXPROCS to
-// match the configured Linux CPU quota. Unlike the top-level automaxprocs
-// package, it lets the caller configure logging and handle errors.
-package maxprocs // import "go.uber.org/automaxprocs/maxprocs"
-
-import (
- "os"
- "runtime"
-
- iruntime "go.uber.org/automaxprocs/internal/runtime"
-)
-
-const _maxProcsKey = "GOMAXPROCS"
-
-func currentMaxProcs() int {
- return runtime.GOMAXPROCS(0)
-}
-
-type config struct {
- printf func(string, ...interface{})
- procs func(int, func(v float64) int) (int, iruntime.CPUQuotaStatus, error)
- minGOMAXPROCS int
- roundQuotaFunc func(v float64) int
-}
-
-func (c *config) log(fmt string, args ...interface{}) {
- if c.printf != nil {
- c.printf(fmt, args...)
- }
-}
-
-// An Option alters the behavior of Set.
-type Option interface {
- apply(*config)
-}
-
-// Logger uses the supplied printf implementation for log output. By default,
-// Set doesn't log anything.
-func Logger(printf func(string, ...interface{})) Option {
- return optionFunc(func(cfg *config) {
- cfg.printf = printf
- })
-}
-
-// Min sets the minimum GOMAXPROCS value that will be used.
-// Any value below 1 is ignored.
-func Min(n int) Option {
- return optionFunc(func(cfg *config) {
- if n >= 1 {
- cfg.minGOMAXPROCS = n
- }
- })
-}
-
-// RoundQuotaFunc sets the function that will be used to covert the CPU quota from float to int.
-func RoundQuotaFunc(rf func(v float64) int) Option {
- return optionFunc(func(cfg *config) {
- cfg.roundQuotaFunc = rf
- })
-}
-
-type optionFunc func(*config)
-
-func (of optionFunc) apply(cfg *config) { of(cfg) }
-
-// Set GOMAXPROCS to match the Linux container CPU quota (if any), returning
-// any error encountered and an undo function.
-//
-// Set is a no-op on non-Linux systems and in Linux environments without a
-// configured CPU quota.
-func Set(opts ...Option) (func(), error) {
- cfg := &config{
- procs: iruntime.CPUQuotaToGOMAXPROCS,
- roundQuotaFunc: iruntime.DefaultRoundFunc,
- minGOMAXPROCS: 1,
- }
- for _, o := range opts {
- o.apply(cfg)
- }
-
- undoNoop := func() {
- cfg.log("maxprocs: No GOMAXPROCS change to reset")
- }
-
- // Honor the GOMAXPROCS environment variable if present. Otherwise, amend
- // `runtime.GOMAXPROCS()` with the current process' CPU quota if the OS is
- // Linux, and guarantee a minimum value of 1. The minimum guaranteed value
- // can be overridden using `maxprocs.Min()`.
- if max, exists := os.LookupEnv(_maxProcsKey); exists {
- cfg.log("maxprocs: Honoring GOMAXPROCS=%q as set in environment", max)
- return undoNoop, nil
- }
-
- maxProcs, status, err := cfg.procs(cfg.minGOMAXPROCS, cfg.roundQuotaFunc)
- if err != nil {
- return undoNoop, err
- }
-
- if status == iruntime.CPUQuotaUndefined {
- cfg.log("maxprocs: Leaving GOMAXPROCS=%v: CPU quota undefined", currentMaxProcs())
- return undoNoop, nil
- }
-
- prev := currentMaxProcs()
- undo := func() {
- cfg.log("maxprocs: Resetting GOMAXPROCS to %v", prev)
- runtime.GOMAXPROCS(prev)
- }
-
- switch status {
- case iruntime.CPUQuotaMinUsed:
- cfg.log("maxprocs: Updating GOMAXPROCS=%v: using minimum allowed GOMAXPROCS", maxProcs)
- case iruntime.CPUQuotaUsed:
- cfg.log("maxprocs: Updating GOMAXPROCS=%v: determined from CPU quota", maxProcs)
- }
-
- runtime.GOMAXPROCS(maxProcs)
- return undo, nil
-}
diff --git a/vendor/go.uber.org/automaxprocs/maxprocs/version.go b/vendor/go.uber.org/automaxprocs/maxprocs/version.go
deleted file mode 100644
index cc7fc5aee..000000000
--- a/vendor/go.uber.org/automaxprocs/maxprocs/version.go
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright (c) 2017 Uber Technologies, Inc.
-//
-// 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.
-
-package maxprocs
-
-// Version is the current package version.
-const Version = "1.6.0"
diff --git a/vendor/go.uber.org/zap/CHANGELOG.md b/vendor/go.uber.org/zap/CHANGELOG.md
index 86e7e6f98..53848733c 100644
--- a/vendor/go.uber.org/zap/CHANGELOG.md
+++ b/vendor/go.uber.org/zap/CHANGELOG.md
@@ -3,6 +3,10 @@ All notable changes to this project will be documented in this file.
This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
+## 1.28.0 (27 Apr 2026)
+Enhancements:
+* [#1534][]: Add `zapcore.CheckPreWriteHook` and `CheckedEntry.Before` method for transforming entries before they are written to any Cores.
+
## 1.27.1 (19 Nov 2025)
Enhancements:
* [#1501][]: prevent `Object` from panicking on nils
diff --git a/vendor/go.uber.org/zap/zapcore/entry.go b/vendor/go.uber.org/zap/zapcore/entry.go
index 841752f2e..e1fc07a1f 100644
--- a/vendor/go.uber.org/zap/zapcore/entry.go
+++ b/vendor/go.uber.org/zap/zapcore/entry.go
@@ -201,6 +201,14 @@ func (a CheckWriteAction) OnWrite(ce *CheckedEntry, _ []Field) {
var _ CheckWriteHook = CheckWriteAction(0)
+// CheckPreWriteHook is a function that transforms an Entry and its Fields
+// before they are written to cores. Register one on a CheckedEntry with the
+// Before method.
+//
+// Pre-write hooks run in the order they were added, before any Core's Write
+// method is called. They may modify the Entry and Fields freely.
+type CheckPreWriteHook func(Entry, []Field) (Entry, []Field)
+
// CheckedEntry is an Entry together with a collection of Cores that have
// already agreed to log it.
//
@@ -213,6 +221,7 @@ type CheckedEntry struct {
dirty bool // best-effort detection of pool misuse
after CheckWriteHook
cores []Core
+ before []CheckPreWriteHook
}
func (ce *CheckedEntry) reset() {
@@ -225,6 +234,10 @@ func (ce *CheckedEntry) reset() {
ce.cores[i] = nil
}
ce.cores = ce.cores[:0]
+ for i := range ce.before {
+ ce.before[i] = nil
+ }
+ ce.before = ce.before[:0]
}
// Write writes the entry to the stored Cores, returns any errors, and returns
@@ -253,9 +266,14 @@ func (ce *CheckedEntry) Write(fields ...Field) {
}
ce.dirty = true
+ ent := ce.Entry
+ for i := range ce.before {
+ ent, fields = ce.before[i](ent, fields)
+ }
+
var err error
for i := range ce.cores {
- err = multierr.Append(err, ce.cores[i].Write(ce.Entry, fields))
+ err = multierr.Append(err, ce.cores[i].Write(ent, fields))
}
if err != nil && ce.ErrorOutput != nil {
_, _ = fmt.Fprintf(
@@ -295,6 +313,18 @@ func (ce *CheckedEntry) Should(ent Entry, should CheckWriteAction) *CheckedEntry
return ce.After(ent, should)
}
+// Before adds a pre-write hook that transforms the Entry and Fields before
+// they are written to any registered Cores. Multiple hooks run in the order
+// they were added. It's safe to call this on nil CheckedEntry references.
+func (ce *CheckedEntry) Before(ent Entry, hook CheckPreWriteHook) *CheckedEntry {
+ if ce == nil {
+ ce = getCheckedEntry()
+ ce.Entry = ent
+ }
+ ce.before = append(ce.before, hook)
+ return ce
+}
+
// After sets this CheckEntry's CheckWriteHook, which will be called after this
// log entry has been written. It's safe to call this on nil CheckedEntry
// references.
diff --git a/vendor/go.yaml.in/yaml/v3/parserc.go b/vendor/go.yaml.in/yaml/v3/parserc.go
index 25fe82363..f35829db4 100644
--- a/vendor/go.yaml.in/yaml/v3/parserc.go
+++ b/vendor/go.yaml.in/yaml/v3/parserc.go
@@ -226,9 +226,9 @@ func yaml_parser_state_machine(parser *yaml_parser_t, event *yaml_event_t) bool
}
// Parse the production:
-// stream ::= STREAM-START implicit_document? explicit_document* STREAM-END
//
-// ************
+// stream ::= STREAM-START implicit_document? explicit_document* STREAM-END
+// ************
func yaml_parser_parse_stream_start(parser *yaml_parser_t, event *yaml_event_t) bool {
token := peek_token(parser)
if token == nil {
@@ -249,13 +249,11 @@ func yaml_parser_parse_stream_start(parser *yaml_parser_t, event *yaml_event_t)
}
// Parse the productions:
-// implicit_document ::= block_node DOCUMENT-END*
-//
-// *
//
-// explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
-//
-// *************************
+// implicit_document ::= block_node DOCUMENT-END*
+// *
+// explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
+// *************************
func yaml_parser_parse_document_start(parser *yaml_parser_t, event *yaml_event_t, implicit bool) bool {
token := peek_token(parser)
@@ -359,9 +357,9 @@ func yaml_parser_parse_document_start(parser *yaml_parser_t, event *yaml_event_t
}
// Parse the productions:
-// explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
//
-// ***********
+// explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
+// ***********
func yaml_parser_parse_document_content(parser *yaml_parser_t, event *yaml_event_t) bool {
token := peek_token(parser)
if token == nil {
@@ -382,11 +380,10 @@ func yaml_parser_parse_document_content(parser *yaml_parser_t, event *yaml_event
}
// Parse the productions:
-// implicit_document ::= block_node DOCUMENT-END*
-//
-// *************
//
-// explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
+// implicit_document ::= block_node DOCUMENT-END*
+// *************
+// explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
func yaml_parser_parse_document_end(parser *yaml_parser_t, event *yaml_event_t) bool {
token := peek_token(parser)
if token == nil {
@@ -432,42 +429,32 @@ func yaml_parser_set_event_comments(parser *yaml_parser_t, event *yaml_event_t)
}
// Parse the productions:
-// block_node_or_indentless_sequence ::=
-//
-// ALIAS
-// *****
-// | properties (block_content | indentless_block_sequence)?
-// ********** *
-// | block_content | indentless_block_sequence
-// *
-//
-// block_node ::= ALIAS
-//
-// *****
-// | properties block_content?
-// ********** *
-// | block_content
-// *
-//
-// flow_node ::= ALIAS
-//
-// *****
-// | properties flow_content?
-// ********** *
-// | flow_content
-// *
-//
-// properties ::= TAG ANCHOR? | ANCHOR TAG?
-//
-// *************************
-//
-// block_content ::= block_collection | flow_collection | SCALAR
-//
-// ******
//
-// flow_content ::= flow_collection | SCALAR
-//
-// ******
+// block_node_or_indentless_sequence ::=
+// ALIAS
+// *****
+// | properties (block_content | indentless_block_sequence)?
+// ********** *
+// | block_content | indentless_block_sequence
+// *
+// block_node ::= ALIAS
+// *****
+// | properties block_content?
+// ********** *
+// | block_content
+// *
+// flow_node ::= ALIAS
+// *****
+// | properties flow_content?
+// ********** *
+// | flow_content
+// *
+// properties ::= TAG ANCHOR? | ANCHOR TAG?
+// *************************
+// block_content ::= block_collection | flow_collection | SCALAR
+// ******
+// flow_content ::= flow_collection | SCALAR
+// ******
func yaml_parser_parse_node(parser *yaml_parser_t, event *yaml_event_t, block, indentless_sequence bool) bool {
//defer trace("yaml_parser_parse_node", "block:", block, "indentless_sequence:", indentless_sequence)()
@@ -697,9 +684,9 @@ func yaml_parser_parse_node(parser *yaml_parser_t, event *yaml_event_t, block, i
}
// Parse the productions:
-// block_sequence ::= BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)* BLOCK-END
//
-// ******************** *********** * *********
+// block_sequence ::= BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)* BLOCK-END
+// ******************** *********** * *********
func yaml_parser_parse_block_sequence_entry(parser *yaml_parser_t, event *yaml_event_t, first bool) bool {
if first {
token := peek_token(parser)
@@ -755,9 +742,9 @@ func yaml_parser_parse_block_sequence_entry(parser *yaml_parser_t, event *yaml_e
}
// Parse the productions:
-// indentless_sequence ::= (BLOCK-ENTRY block_node?)+
//
-// *********** *
+// indentless_sequence ::= (BLOCK-ENTRY block_node?)+
+// *********** *
func yaml_parser_parse_indentless_sequence_entry(parser *yaml_parser_t, event *yaml_event_t) bool {
token := peek_token(parser)
if token == nil {
@@ -821,15 +808,15 @@ func yaml_parser_split_stem_comment(parser *yaml_parser_t, stem_len int) {
}
// Parse the productions:
-// block_mapping ::= BLOCK-MAPPING_START
//
-// *******************
-// ((KEY block_node_or_indentless_sequence?)?
-// *** *
-// (VALUE block_node_or_indentless_sequence?)?)*
+// block_mapping ::= BLOCK-MAPPING_START
+// *******************
+// ((KEY block_node_or_indentless_sequence?)?
+// *** *
+// (VALUE block_node_or_indentless_sequence?)?)*
//
-// BLOCK-END
-// *********
+// BLOCK-END
+// *********
func yaml_parser_parse_block_mapping_key(parser *yaml_parser_t, event *yaml_event_t, first bool) bool {
if first {
token := peek_token(parser)
@@ -896,13 +883,14 @@ func yaml_parser_parse_block_mapping_key(parser *yaml_parser_t, event *yaml_even
}
// Parse the productions:
-// block_mapping ::= BLOCK-MAPPING_START
//
-// ((KEY block_node_or_indentless_sequence?)?
+// block_mapping ::= BLOCK-MAPPING_START
+//
+// ((KEY block_node_or_indentless_sequence?)?
//
-// (VALUE block_node_or_indentless_sequence?)?)*
-// ***** *
-// BLOCK-END
+// (VALUE block_node_or_indentless_sequence?)?)*
+// ***** *
+// BLOCK-END
func yaml_parser_parse_block_mapping_value(parser *yaml_parser_t, event *yaml_event_t) bool {
token := peek_token(parser)
if token == nil {
@@ -929,19 +917,17 @@ func yaml_parser_parse_block_mapping_value(parser *yaml_parser_t, event *yaml_ev
}
// Parse the productions:
-// flow_sequence ::= FLOW-SEQUENCE-START
-//
-// *******************
-// (flow_sequence_entry FLOW-ENTRY)*
-// * **********
-// flow_sequence_entry?
-// *
-// FLOW-SEQUENCE-END
-// *****************
//
-// flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
-//
-// *
+// flow_sequence ::= FLOW-SEQUENCE-START
+// *******************
+// (flow_sequence_entry FLOW-ENTRY)*
+// * **********
+// flow_sequence_entry?
+// *
+// FLOW-SEQUENCE-END
+// *****************
+// flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
+// *
func yaml_parser_parse_flow_sequence_entry(parser *yaml_parser_t, event *yaml_event_t, first bool) bool {
if first {
token := peek_token(parser)
@@ -1005,9 +991,9 @@ func yaml_parser_parse_flow_sequence_entry(parser *yaml_parser_t, event *yaml_ev
}
// Parse the productions:
-// flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
//
-// *** *
+// flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
+// *** *
func yaml_parser_parse_flow_sequence_entry_mapping_key(parser *yaml_parser_t, event *yaml_event_t) bool {
token := peek_token(parser)
if token == nil {
@@ -1026,9 +1012,9 @@ func yaml_parser_parse_flow_sequence_entry_mapping_key(parser *yaml_parser_t, ev
}
// Parse the productions:
-// flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
//
-// ***** *
+// flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
+// ***** *
func yaml_parser_parse_flow_sequence_entry_mapping_value(parser *yaml_parser_t, event *yaml_event_t) bool {
token := peek_token(parser)
if token == nil {
@@ -1050,9 +1036,9 @@ func yaml_parser_parse_flow_sequence_entry_mapping_value(parser *yaml_parser_t,
}
// Parse the productions:
-// flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
//
-// *
+// flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
+// *
func yaml_parser_parse_flow_sequence_entry_mapping_end(parser *yaml_parser_t, event *yaml_event_t) bool {
token := peek_token(parser)
if token == nil {
@@ -1068,18 +1054,17 @@ func yaml_parser_parse_flow_sequence_entry_mapping_end(parser *yaml_parser_t, ev
}
// Parse the productions:
-// flow_mapping ::= FLOW-MAPPING-START
-//
-// ******************
-// (flow_mapping_entry FLOW-ENTRY)*
-// * **********
-// flow_mapping_entry?
-// ******************
-// FLOW-MAPPING-END
-// ****************
//
-// flow_mapping_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
-// - *** *
+// flow_mapping ::= FLOW-MAPPING-START
+// ******************
+// (flow_mapping_entry FLOW-ENTRY)*
+// * **********
+// flow_mapping_entry?
+// ******************
+// FLOW-MAPPING-END
+// ****************
+// flow_mapping_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
+// * *** *
func yaml_parser_parse_flow_mapping_key(parser *yaml_parser_t, event *yaml_event_t, first bool) bool {
if first {
token := peek_token(parser)
@@ -1144,8 +1129,9 @@ func yaml_parser_parse_flow_mapping_key(parser *yaml_parser_t, event *yaml_event
}
// Parse the productions:
-// flow_mapping_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
-// - ***** *
+//
+// flow_mapping_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
+// * ***** *
func yaml_parser_parse_flow_mapping_value(parser *yaml_parser_t, event *yaml_event_t, empty bool) bool {
token := peek_token(parser)
if token == nil {
diff --git a/vendor/go.yaml.in/yaml/v3/yamlh.go b/vendor/go.yaml.in/yaml/v3/yamlh.go
index f59aa40f6..07c442361 100644
--- a/vendor/go.yaml.in/yaml/v3/yamlh.go
+++ b/vendor/go.yaml.in/yaml/v3/yamlh.go
@@ -433,21 +433,19 @@ type yaml_document_t struct {
// The prototype of a read handler.
//
-// The read handler is called when the parser needs to read more bytes from the
-// source. The handler should write not more than size bytes to the buffer.
-// The number of written bytes should be set to the size_read variable.
+// The read handler is called when the parser needs to read more bytes from the
+// source. The handler should write not more than size bytes to the buffer.
+// The number of written bytes should be set to the size_read variable.
//
-// [in,out] data A pointer to an application data specified by
+// [in,out] data A pointer to an application data specified by
+// yaml_parser_set_input().
+// [out] buffer The buffer to write the data from the source.
+// [in] size The size of the buffer.
+// [out] size_read The actual number of bytes read from the source.
//
-// yaml_parser_set_input().
-//
-// [out] buffer The buffer to write the data from the source.
-// [in] size The size of the buffer.
-// [out] size_read The actual number of bytes read from the source.
-//
-// On success, the handler should return 1. If the handler failed,
-// the returned value should be 0. On EOF, the handler should set the
-// size_read to 0 and return 1.
+// On success, the handler should return 1. If the handler failed,
+// the returned value should be 0. On EOF, the handler should set the
+// size_read to 0 and return 1.
type yaml_read_handler_t func(parser *yaml_parser_t, buffer []byte) (n int, err error)
// This structure holds information about a potential simple key.
@@ -655,19 +653,17 @@ type yaml_comment_t struct {
// The prototype of a write handler.
//
-// The write handler is called when the emitter needs to flush the accumulated
-// characters to the output. The handler should write @a size bytes of the
-// @a buffer to the output.
-//
-// @param[in,out] data A pointer to an application data specified by
-//
-// yaml_emitter_set_output().
+// The write handler is called when the emitter needs to flush the accumulated
+// characters to the output. The handler should write @a size bytes of the
+// @a buffer to the output.
//
-// @param[in] buffer The buffer with bytes to be written.
-// @param[in] size The size of the buffer.
+// @param[in,out] data A pointer to an application data specified by
+// yaml_emitter_set_output().
+// @param[in] buffer The buffer with bytes to be written.
+// @param[in] size The size of the buffer.
//
-// @returns On success, the handler should return @c 1. If the handler failed,
-// the returned value should be @c 0.
+// @returns On success, the handler should return @c 1. If the handler failed,
+// the returned value should be @c 0.
type yaml_write_handler_t func(emitter *yaml_emitter_t, buffer []byte) error
type yaml_emitter_state_t int
diff --git a/vendor/golang.org/x/crypto/bcrypt/base64.go b/vendor/golang.org/x/crypto/bcrypt/base64.go
new file mode 100644
index 000000000..fc3116090
--- /dev/null
+++ b/vendor/golang.org/x/crypto/bcrypt/base64.go
@@ -0,0 +1,35 @@
+// Copyright 2011 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 bcrypt
+
+import "encoding/base64"
+
+const alphabet = "./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
+
+var bcEncoding = base64.NewEncoding(alphabet)
+
+func base64Encode(src []byte) []byte {
+ n := bcEncoding.EncodedLen(len(src))
+ dst := make([]byte, n)
+ bcEncoding.Encode(dst, src)
+ for dst[n-1] == '=' {
+ n--
+ }
+ return dst[:n]
+}
+
+func base64Decode(src []byte) ([]byte, error) {
+ numOfEquals := 4 - (len(src) % 4)
+ for i := 0; i < numOfEquals; i++ {
+ src = append(src, '=')
+ }
+
+ dst := make([]byte, bcEncoding.DecodedLen(len(src)))
+ n, err := bcEncoding.Decode(dst, src)
+ if err != nil {
+ return nil, err
+ }
+ return dst[:n], nil
+}
diff --git a/vendor/golang.org/x/crypto/bcrypt/bcrypt.go b/vendor/golang.org/x/crypto/bcrypt/bcrypt.go
new file mode 100644
index 000000000..3e7f8df87
--- /dev/null
+++ b/vendor/golang.org/x/crypto/bcrypt/bcrypt.go
@@ -0,0 +1,304 @@
+// Copyright 2011 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 bcrypt implements Provos and Mazières's bcrypt adaptive hashing
+// algorithm. See http://www.usenix.org/event/usenix99/provos/provos.pdf
+package bcrypt
+
+// The code is a port of Provos and Mazières's C implementation.
+import (
+ "crypto/rand"
+ "crypto/subtle"
+ "errors"
+ "fmt"
+ "io"
+ "strconv"
+
+ "golang.org/x/crypto/blowfish"
+)
+
+const (
+ MinCost int = 4 // the minimum allowable cost as passed in to GenerateFromPassword
+ MaxCost int = 31 // the maximum allowable cost as passed in to GenerateFromPassword
+ DefaultCost int = 10 // the cost that will actually be set if a cost below MinCost is passed into GenerateFromPassword
+)
+
+// The error returned from CompareHashAndPassword when a password and hash do
+// not match.
+var ErrMismatchedHashAndPassword = errors.New("crypto/bcrypt: hashedPassword is not the hash of the given password")
+
+// The error returned from CompareHashAndPassword when a hash is too short to
+// be a bcrypt hash.
+var ErrHashTooShort = errors.New("crypto/bcrypt: hashedSecret too short to be a bcrypted password")
+
+// The error returned from CompareHashAndPassword when a hash was created with
+// a bcrypt algorithm newer than this implementation.
+type HashVersionTooNewError byte
+
+func (hv HashVersionTooNewError) Error() string {
+ return fmt.Sprintf("crypto/bcrypt: bcrypt algorithm version '%c' requested is newer than current version '%c'", byte(hv), majorVersion)
+}
+
+// The error returned from CompareHashAndPassword when a hash starts with something other than '$'
+type InvalidHashPrefixError byte
+
+func (ih InvalidHashPrefixError) Error() string {
+ return fmt.Sprintf("crypto/bcrypt: bcrypt hashes must start with '$', but hashedSecret started with '%c'", byte(ih))
+}
+
+type InvalidCostError int
+
+func (ic InvalidCostError) Error() string {
+ return fmt.Sprintf("crypto/bcrypt: cost %d is outside allowed inclusive range %d..%d", int(ic), MinCost, MaxCost)
+}
+
+const (
+ majorVersion = '2'
+ minorVersion = 'a'
+ maxSaltSize = 16
+ maxCryptedHashSize = 23
+ encodedSaltSize = 22
+ encodedHashSize = 31
+ minHashSize = 59
+)
+
+// magicCipherData is an IV for the 64 Blowfish encryption calls in
+// bcrypt(). It's the string "OrpheanBeholderScryDoubt" in big-endian bytes.
+var magicCipherData = []byte{
+ 0x4f, 0x72, 0x70, 0x68,
+ 0x65, 0x61, 0x6e, 0x42,
+ 0x65, 0x68, 0x6f, 0x6c,
+ 0x64, 0x65, 0x72, 0x53,
+ 0x63, 0x72, 0x79, 0x44,
+ 0x6f, 0x75, 0x62, 0x74,
+}
+
+type hashed struct {
+ hash []byte
+ salt []byte
+ cost int // allowed range is MinCost to MaxCost
+ major byte
+ minor byte
+}
+
+// ErrPasswordTooLong is returned when the password passed to
+// GenerateFromPassword is too long (i.e. > 72 bytes).
+var ErrPasswordTooLong = errors.New("bcrypt: password length exceeds 72 bytes")
+
+// GenerateFromPassword returns the bcrypt hash of the password at the given
+// cost. If the cost given is less than MinCost, the cost will be set to
+// DefaultCost, instead. Use CompareHashAndPassword, as defined in this package,
+// to compare the returned hashed password with its cleartext version.
+// GenerateFromPassword does not accept passwords longer than 72 bytes, which
+// is the longest password bcrypt will operate on.
+func GenerateFromPassword(password []byte, cost int) ([]byte, error) {
+ if len(password) > 72 {
+ return nil, ErrPasswordTooLong
+ }
+ p, err := newFromPassword(password, cost)
+ if err != nil {
+ return nil, err
+ }
+ return p.Hash(), nil
+}
+
+// CompareHashAndPassword compares a bcrypt hashed password with its possible
+// plaintext equivalent. Returns nil on success, or an error on failure.
+func CompareHashAndPassword(hashedPassword, password []byte) error {
+ p, err := newFromHash(hashedPassword)
+ if err != nil {
+ return err
+ }
+
+ otherHash, err := bcrypt(password, p.cost, p.salt)
+ if err != nil {
+ return err
+ }
+
+ otherP := &hashed{otherHash, p.salt, p.cost, p.major, p.minor}
+ if subtle.ConstantTimeCompare(p.Hash(), otherP.Hash()) == 1 {
+ return nil
+ }
+
+ return ErrMismatchedHashAndPassword
+}
+
+// Cost returns the hashing cost used to create the given hashed
+// password. When, in the future, the hashing cost of a password system needs
+// to be increased in order to adjust for greater computational power, this
+// function allows one to establish which passwords need to be updated.
+func Cost(hashedPassword []byte) (int, error) {
+ p, err := newFromHash(hashedPassword)
+ if err != nil {
+ return 0, err
+ }
+ return p.cost, nil
+}
+
+func newFromPassword(password []byte, cost int) (*hashed, error) {
+ if cost < MinCost {
+ cost = DefaultCost
+ }
+ p := new(hashed)
+ p.major = majorVersion
+ p.minor = minorVersion
+
+ err := checkCost(cost)
+ if err != nil {
+ return nil, err
+ }
+ p.cost = cost
+
+ unencodedSalt := make([]byte, maxSaltSize)
+ _, err = io.ReadFull(rand.Reader, unencodedSalt)
+ if err != nil {
+ return nil, err
+ }
+
+ p.salt = base64Encode(unencodedSalt)
+ hash, err := bcrypt(password, p.cost, p.salt)
+ if err != nil {
+ return nil, err
+ }
+ p.hash = hash
+ return p, err
+}
+
+func newFromHash(hashedSecret []byte) (*hashed, error) {
+ if len(hashedSecret) < minHashSize {
+ return nil, ErrHashTooShort
+ }
+ p := new(hashed)
+ n, err := p.decodeVersion(hashedSecret)
+ if err != nil {
+ return nil, err
+ }
+ hashedSecret = hashedSecret[n:]
+ n, err = p.decodeCost(hashedSecret)
+ if err != nil {
+ return nil, err
+ }
+ hashedSecret = hashedSecret[n:]
+
+ // The "+2" is here because we'll have to append at most 2 '=' to the salt
+ // when base64 decoding it in expensiveBlowfishSetup().
+ p.salt = make([]byte, encodedSaltSize, encodedSaltSize+2)
+ copy(p.salt, hashedSecret[:encodedSaltSize])
+
+ hashedSecret = hashedSecret[encodedSaltSize:]
+ p.hash = make([]byte, len(hashedSecret))
+ copy(p.hash, hashedSecret)
+
+ return p, nil
+}
+
+func bcrypt(password []byte, cost int, salt []byte) ([]byte, error) {
+ cipherData := make([]byte, len(magicCipherData))
+ copy(cipherData, magicCipherData)
+
+ c, err := expensiveBlowfishSetup(password, uint32(cost), salt)
+ if err != nil {
+ return nil, err
+ }
+
+ for i := 0; i < 24; i += 8 {
+ for j := 0; j < 64; j++ {
+ c.Encrypt(cipherData[i:i+8], cipherData[i:i+8])
+ }
+ }
+
+ // Bug compatibility with C bcrypt implementations. We only encode 23 of
+ // the 24 bytes encrypted.
+ hsh := base64Encode(cipherData[:maxCryptedHashSize])
+ return hsh, nil
+}
+
+func expensiveBlowfishSetup(key []byte, cost uint32, salt []byte) (*blowfish.Cipher, error) {
+ csalt, err := base64Decode(salt)
+ if err != nil {
+ return nil, err
+ }
+
+ // Bug compatibility with C bcrypt implementations. They use the trailing
+ // NULL in the key string during expansion.
+ // We copy the key to prevent changing the underlying array.
+ ckey := append(key[:len(key):len(key)], 0)
+
+ c, err := blowfish.NewSaltedCipher(ckey, csalt)
+ if err != nil {
+ return nil, err
+ }
+
+ var i, rounds uint64
+ rounds = 1 << cost
+ for i = 0; i < rounds; i++ {
+ blowfish.ExpandKey(ckey, c)
+ blowfish.ExpandKey(csalt, c)
+ }
+
+ return c, nil
+}
+
+func (p *hashed) Hash() []byte {
+ arr := make([]byte, 60)
+ arr[0] = '$'
+ arr[1] = p.major
+ n := 2
+ if p.minor != 0 {
+ arr[2] = p.minor
+ n = 3
+ }
+ arr[n] = '$'
+ n++
+ copy(arr[n:], []byte(fmt.Sprintf("%02d", p.cost)))
+ n += 2
+ arr[n] = '$'
+ n++
+ copy(arr[n:], p.salt)
+ n += encodedSaltSize
+ copy(arr[n:], p.hash)
+ n += encodedHashSize
+ return arr[:n]
+}
+
+func (p *hashed) decodeVersion(sbytes []byte) (int, error) {
+ if sbytes[0] != '$' {
+ return -1, InvalidHashPrefixError(sbytes[0])
+ }
+ if sbytes[1] > majorVersion {
+ return -1, HashVersionTooNewError(sbytes[1])
+ }
+ p.major = sbytes[1]
+ n := 3
+ if sbytes[2] != '$' {
+ p.minor = sbytes[2]
+ n++
+ }
+ return n, nil
+}
+
+// sbytes should begin where decodeVersion left off.
+func (p *hashed) decodeCost(sbytes []byte) (int, error) {
+ cost, err := strconv.Atoi(string(sbytes[0:2]))
+ if err != nil {
+ return -1, err
+ }
+ err = checkCost(cost)
+ if err != nil {
+ return -1, err
+ }
+ p.cost = cost
+ return 3, nil
+}
+
+func (p *hashed) String() string {
+ return fmt.Sprintf("&{hash: %#v, salt: %#v, cost: %d, major: %c, minor: %c}", string(p.hash), p.salt, p.cost, p.major, p.minor)
+}
+
+func checkCost(cost int) error {
+ if cost < MinCost || cost > MaxCost {
+ return InvalidCostError(cost)
+ }
+ return nil
+}
diff --git a/vendor/golang.org/x/crypto/blowfish/block.go b/vendor/golang.org/x/crypto/blowfish/block.go
new file mode 100644
index 000000000..9d80f1952
--- /dev/null
+++ b/vendor/golang.org/x/crypto/blowfish/block.go
@@ -0,0 +1,159 @@
+// Copyright 2010 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 blowfish
+
+// getNextWord returns the next big-endian uint32 value from the byte slice
+// at the given position in a circular manner, updating the position.
+func getNextWord(b []byte, pos *int) uint32 {
+ var w uint32
+ j := *pos
+ for i := 0; i < 4; i++ {
+ w = w<<8 | uint32(b[j])
+ j++
+ if j >= len(b) {
+ j = 0
+ }
+ }
+ *pos = j
+ return w
+}
+
+// ExpandKey performs a key expansion on the given *Cipher. Specifically, it
+// performs the Blowfish algorithm's key schedule which sets up the *Cipher's
+// pi and substitution tables for calls to Encrypt. This is used, primarily,
+// by the bcrypt package to reuse the Blowfish key schedule during its
+// set up. It's unlikely that you need to use this directly.
+func ExpandKey(key []byte, c *Cipher) {
+ j := 0
+ for i := 0; i < 18; i++ {
+ // Using inlined getNextWord for performance.
+ var d uint32
+ for k := 0; k < 4; k++ {
+ d = d<<8 | uint32(key[j])
+ j++
+ if j >= len(key) {
+ j = 0
+ }
+ }
+ c.p[i] ^= d
+ }
+
+ var l, r uint32
+ for i := 0; i < 18; i += 2 {
+ l, r = encryptBlock(l, r, c)
+ c.p[i], c.p[i+1] = l, r
+ }
+
+ for i := 0; i < 256; i += 2 {
+ l, r = encryptBlock(l, r, c)
+ c.s0[i], c.s0[i+1] = l, r
+ }
+ for i := 0; i < 256; i += 2 {
+ l, r = encryptBlock(l, r, c)
+ c.s1[i], c.s1[i+1] = l, r
+ }
+ for i := 0; i < 256; i += 2 {
+ l, r = encryptBlock(l, r, c)
+ c.s2[i], c.s2[i+1] = l, r
+ }
+ for i := 0; i < 256; i += 2 {
+ l, r = encryptBlock(l, r, c)
+ c.s3[i], c.s3[i+1] = l, r
+ }
+}
+
+// This is similar to ExpandKey, but folds the salt during the key
+// schedule. While ExpandKey is essentially expandKeyWithSalt with an all-zero
+// salt passed in, reusing ExpandKey turns out to be a place of inefficiency
+// and specializing it here is useful.
+func expandKeyWithSalt(key []byte, salt []byte, c *Cipher) {
+ j := 0
+ for i := 0; i < 18; i++ {
+ c.p[i] ^= getNextWord(key, &j)
+ }
+
+ j = 0
+ var l, r uint32
+ for i := 0; i < 18; i += 2 {
+ l ^= getNextWord(salt, &j)
+ r ^= getNextWord(salt, &j)
+ l, r = encryptBlock(l, r, c)
+ c.p[i], c.p[i+1] = l, r
+ }
+
+ for i := 0; i < 256; i += 2 {
+ l ^= getNextWord(salt, &j)
+ r ^= getNextWord(salt, &j)
+ l, r = encryptBlock(l, r, c)
+ c.s0[i], c.s0[i+1] = l, r
+ }
+
+ for i := 0; i < 256; i += 2 {
+ l ^= getNextWord(salt, &j)
+ r ^= getNextWord(salt, &j)
+ l, r = encryptBlock(l, r, c)
+ c.s1[i], c.s1[i+1] = l, r
+ }
+
+ for i := 0; i < 256; i += 2 {
+ l ^= getNextWord(salt, &j)
+ r ^= getNextWord(salt, &j)
+ l, r = encryptBlock(l, r, c)
+ c.s2[i], c.s2[i+1] = l, r
+ }
+
+ for i := 0; i < 256; i += 2 {
+ l ^= getNextWord(salt, &j)
+ r ^= getNextWord(salt, &j)
+ l, r = encryptBlock(l, r, c)
+ c.s3[i], c.s3[i+1] = l, r
+ }
+}
+
+func encryptBlock(l, r uint32, c *Cipher) (uint32, uint32) {
+ xl, xr := l, r
+ xl ^= c.p[0]
+ xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[1]
+ xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[2]
+ xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[3]
+ xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[4]
+ xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[5]
+ xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[6]
+ xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[7]
+ xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[8]
+ xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[9]
+ xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[10]
+ xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[11]
+ xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[12]
+ xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[13]
+ xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[14]
+ xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[15]
+ xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[16]
+ xr ^= c.p[17]
+ return xr, xl
+}
+
+func decryptBlock(l, r uint32, c *Cipher) (uint32, uint32) {
+ xl, xr := l, r
+ xl ^= c.p[17]
+ xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[16]
+ xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[15]
+ xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[14]
+ xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[13]
+ xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[12]
+ xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[11]
+ xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[10]
+ xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[9]
+ xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[8]
+ xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[7]
+ xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[6]
+ xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[5]
+ xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[4]
+ xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[3]
+ xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[2]
+ xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[1]
+ xr ^= c.p[0]
+ return xr, xl
+}
diff --git a/vendor/golang.org/x/crypto/blowfish/cipher.go b/vendor/golang.org/x/crypto/blowfish/cipher.go
new file mode 100644
index 000000000..089895680
--- /dev/null
+++ b/vendor/golang.org/x/crypto/blowfish/cipher.go
@@ -0,0 +1,99 @@
+// Copyright 2010 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 blowfish implements Bruce Schneier's Blowfish encryption algorithm.
+//
+// Blowfish is a legacy cipher and its short block size makes it vulnerable to
+// birthday bound attacks (see https://sweet32.info). It should only be used
+// where compatibility with legacy systems, not security, is the goal.
+//
+// Deprecated: any new system should use AES (from crypto/aes, if necessary in
+// an AEAD mode like crypto/cipher.NewGCM) or XChaCha20-Poly1305 (from
+// golang.org/x/crypto/chacha20poly1305).
+package blowfish
+
+// The code is a port of Bruce Schneier's C implementation.
+// See https://www.schneier.com/blowfish.html.
+
+import "strconv"
+
+// The Blowfish block size in bytes.
+const BlockSize = 8
+
+// A Cipher is an instance of Blowfish encryption using a particular key.
+type Cipher struct {
+ p [18]uint32
+ s0, s1, s2, s3 [256]uint32
+}
+
+type KeySizeError int
+
+func (k KeySizeError) Error() string {
+ return "crypto/blowfish: invalid key size " + strconv.Itoa(int(k))
+}
+
+// NewCipher creates and returns a Cipher.
+// The key argument should be the Blowfish key, from 1 to 56 bytes.
+func NewCipher(key []byte) (*Cipher, error) {
+ var result Cipher
+ if k := len(key); k < 1 || k > 56 {
+ return nil, KeySizeError(k)
+ }
+ initCipher(&result)
+ ExpandKey(key, &result)
+ return &result, nil
+}
+
+// NewSaltedCipher creates a returns a Cipher that folds a salt into its key
+// schedule. For most purposes, NewCipher, instead of NewSaltedCipher, is
+// sufficient and desirable. For bcrypt compatibility, the key can be over 56
+// bytes.
+func NewSaltedCipher(key, salt []byte) (*Cipher, error) {
+ if len(salt) == 0 {
+ return NewCipher(key)
+ }
+ var result Cipher
+ if k := len(key); k < 1 {
+ return nil, KeySizeError(k)
+ }
+ initCipher(&result)
+ expandKeyWithSalt(key, salt, &result)
+ return &result, nil
+}
+
+// BlockSize returns the Blowfish block size, 8 bytes.
+// It is necessary to satisfy the Block interface in the
+// package "crypto/cipher".
+func (c *Cipher) BlockSize() int { return BlockSize }
+
+// Encrypt encrypts the 8-byte buffer src using the key k
+// and stores the result in dst.
+// Note that for amounts of data larger than a block,
+// it is not safe to just call Encrypt on successive blocks;
+// instead, use an encryption mode like CBC (see crypto/cipher/cbc.go).
+func (c *Cipher) Encrypt(dst, src []byte) {
+ l := uint32(src[0])<<24 | uint32(src[1])<<16 | uint32(src[2])<<8 | uint32(src[3])
+ r := uint32(src[4])<<24 | uint32(src[5])<<16 | uint32(src[6])<<8 | uint32(src[7])
+ l, r = encryptBlock(l, r, c)
+ dst[0], dst[1], dst[2], dst[3] = byte(l>>24), byte(l>>16), byte(l>>8), byte(l)
+ dst[4], dst[5], dst[6], dst[7] = byte(r>>24), byte(r>>16), byte(r>>8), byte(r)
+}
+
+// Decrypt decrypts the 8-byte buffer src using the key k
+// and stores the result in dst.
+func (c *Cipher) Decrypt(dst, src []byte) {
+ l := uint32(src[0])<<24 | uint32(src[1])<<16 | uint32(src[2])<<8 | uint32(src[3])
+ r := uint32(src[4])<<24 | uint32(src[5])<<16 | uint32(src[6])<<8 | uint32(src[7])
+ l, r = decryptBlock(l, r, c)
+ dst[0], dst[1], dst[2], dst[3] = byte(l>>24), byte(l>>16), byte(l>>8), byte(l)
+ dst[4], dst[5], dst[6], dst[7] = byte(r>>24), byte(r>>16), byte(r>>8), byte(r)
+}
+
+func initCipher(c *Cipher) {
+ copy(c.p[0:], p[0:])
+ copy(c.s0[0:], s0[0:])
+ copy(c.s1[0:], s1[0:])
+ copy(c.s2[0:], s2[0:])
+ copy(c.s3[0:], s3[0:])
+}
diff --git a/vendor/golang.org/x/crypto/blowfish/const.go b/vendor/golang.org/x/crypto/blowfish/const.go
new file mode 100644
index 000000000..d04077595
--- /dev/null
+++ b/vendor/golang.org/x/crypto/blowfish/const.go
@@ -0,0 +1,199 @@
+// Copyright 2010 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.
+
+// The startup permutation array and substitution boxes.
+// They are the hexadecimal digits of PI; see:
+// https://www.schneier.com/code/constants.txt.
+
+package blowfish
+
+var s0 = [256]uint32{
+ 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, 0xb8e1afed, 0x6a267e96,
+ 0xba7c9045, 0xf12c7f99, 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16,
+ 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e, 0x0d95748f, 0x728eb658,
+ 0x718bcd58, 0x82154aee, 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013,
+ 0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef, 0x8e79dcb0, 0x603a180e,
+ 0x6c9e0e8b, 0xb01e8a3e, 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60,
+ 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440, 0x55ca396a, 0x2aab10b6,
+ 0xb4cc5c34, 0x1141e8ce, 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a,
+ 0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e, 0xafd6ba33, 0x6c24cf5c,
+ 0x7a325381, 0x28958677, 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193,
+ 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032, 0xef845d5d, 0xe98575b1,
+ 0xdc262302, 0xeb651b88, 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239,
+ 0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e, 0x21c66842, 0xf6e96c9a,
+ 0x670c9c61, 0xabd388f0, 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3,
+ 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98, 0xa1f1651d, 0x39af0176,
+ 0x66ca593e, 0x82430e88, 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe,
+ 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6, 0x4ed3aa62, 0x363f7706,
+ 0x1bfedf72, 0x429b023d, 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b,
+ 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7, 0xe3fe501a, 0xb6794c3b,
+ 0x976ce0bd, 0x04c006ba, 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463,
+ 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f, 0x6dfc511f, 0x9b30952c,
+ 0xcc814544, 0xaf5ebd09, 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3,
+ 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb, 0x5579c0bd, 0x1a60320a,
+ 0xd6a100c6, 0x402c7279, 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8,
+ 0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab, 0x323db5fa, 0xfd238760,
+ 0x53317b48, 0x3e00df82, 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db,
+ 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573, 0x695b27b0, 0xbbca58c8,
+ 0xe1ffa35d, 0xb8f011a0, 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b,
+ 0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790, 0xe1ddf2da, 0xa4cb7e33,
+ 0x62fb1341, 0xcee4c6e8, 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4,
+ 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0, 0xd08ed1d0, 0xafc725e0,
+ 0x8e3c5b2f, 0x8e7594b7, 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c,
+ 0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad, 0x2f2f2218, 0xbe0e1777,
+ 0xea752dfe, 0x8b021fa1, 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299,
+ 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9, 0x165fa266, 0x80957705,
+ 0x93cc7314, 0x211a1477, 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf,
+ 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49, 0x00250e2d, 0x2071b35e,
+ 0x226800bb, 0x57b8e0af, 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa,
+ 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5, 0x83260376, 0x6295cfa9,
+ 0x11c81968, 0x4e734a41, 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915,
+ 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400, 0x08ba6fb5, 0x571be91f,
+ 0xf296ec6b, 0x2a0dd915, 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664,
+ 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a,
+}
+
+var s1 = [256]uint32{
+ 0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623, 0xad6ea6b0, 0x49a7df7d,
+ 0x9cee60b8, 0x8fedb266, 0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1,
+ 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e, 0x3f54989a, 0x5b429d65,
+ 0x6b8fe4d6, 0x99f73fd6, 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1,
+ 0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e, 0x09686b3f, 0x3ebaefc9,
+ 0x3c971814, 0x6b6a70a1, 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737,
+ 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8, 0xb03ada37, 0xf0500c0d,
+ 0xf01c1f04, 0x0200b3ff, 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd,
+ 0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701, 0x3ae5e581, 0x37c2dadc,
+ 0xc8b57634, 0x9af3dda7, 0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41,
+ 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331, 0x4e548b38, 0x4f6db908,
+ 0x6f420d03, 0xf60a04bf, 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af,
+ 0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e, 0x5512721f, 0x2e6b7124,
+ 0x501adde6, 0x9f84cd87, 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c,
+ 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2, 0xef1c1847, 0x3215d908,
+ 0xdd433b37, 0x24c2ba16, 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd,
+ 0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b, 0x043556f1, 0xd7a3c76b,
+ 0x3c11183b, 0x5924a509, 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e,
+ 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3, 0x771fe71c, 0x4e3d06fa,
+ 0x2965dcb9, 0x99e71d0f, 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a,
+ 0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4, 0xf2f74ea7, 0x361d2b3d,
+ 0x1939260f, 0x19c27960, 0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66,
+ 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28, 0xc332ddef, 0xbe6c5aa5,
+ 0x65582185, 0x68ab9802, 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84,
+ 0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510, 0x13cca830, 0xeb61bd96,
+ 0x0334fe1e, 0xaa0363cf, 0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14,
+ 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e, 0x648b1eaf, 0x19bdf0ca,
+ 0xa02369b9, 0x655abb50, 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7,
+ 0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8, 0xf837889a, 0x97e32d77,
+ 0x11ed935f, 0x16681281, 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99,
+ 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696, 0xcdb30aeb, 0x532e3054,
+ 0x8fd948e4, 0x6dbc3128, 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73,
+ 0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0, 0x45eee2b6, 0xa3aaabea,
+ 0xdb6c4f15, 0xfacb4fd0, 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105,
+ 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250, 0xcf62a1f2, 0x5b8d2646,
+ 0xfc8883a0, 0xc1c7b6a3, 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285,
+ 0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00, 0x58428d2a, 0x0c55f5ea,
+ 0x1dadf43e, 0x233f7061, 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb,
+ 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e, 0xa6078084, 0x19f8509e,
+ 0xe8efd855, 0x61d99735, 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc,
+ 0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9, 0xdb73dbd3, 0x105588cd,
+ 0x675fda79, 0xe3674340, 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20,
+ 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7,
+}
+
+var s2 = [256]uint32{
+ 0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934, 0x411520f7, 0x7602d4f7,
+ 0xbcf46b2e, 0xd4a20068, 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af,
+ 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840, 0x4d95fc1d, 0x96b591af,
+ 0x70f4ddd3, 0x66a02f45, 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504,
+ 0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a, 0x28507825, 0x530429f4,
+ 0x0a2c86da, 0xe9b66dfb, 0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee,
+ 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6, 0xaace1e7c, 0xd3375fec,
+ 0xce78a399, 0x406b2a42, 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b,
+ 0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2, 0x3a6efa74, 0xdd5b4332,
+ 0x6841e7f7, 0xca7820fb, 0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527,
+ 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b, 0x55a867bc, 0xa1159a58,
+ 0xcca92963, 0x99e1db33, 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c,
+ 0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3, 0x95c11548, 0xe4c66d22,
+ 0x48c1133f, 0xc70f86dc, 0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17,
+ 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564, 0x257b7834, 0x602a9c60,
+ 0xdff8e8a3, 0x1f636c1b, 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115,
+ 0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922, 0x85b2a20e, 0xe6ba0d99,
+ 0xde720c8c, 0x2da2f728, 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0,
+ 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e, 0x0a476341, 0x992eff74,
+ 0x3a6f6eab, 0xf4f8fd37, 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d,
+ 0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804, 0xf1290dc7, 0xcc00ffa3,
+ 0xb5390f92, 0x690fed0b, 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3,
+ 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb, 0x37392eb3, 0xcc115979,
+ 0x8026e297, 0xf42e312d, 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c,
+ 0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350, 0x1a6b1018, 0x11caedfa,
+ 0x3d25bdd8, 0xe2e1c3c9, 0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a,
+ 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe, 0x9dbc8057, 0xf0f7c086,
+ 0x60787bf8, 0x6003604d, 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc,
+ 0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f, 0x77a057be, 0xbde8ae24,
+ 0x55464299, 0xbf582e61, 0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2,
+ 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9, 0x7aeb2661, 0x8b1ddf84,
+ 0x846a0e79, 0x915f95e2, 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c,
+ 0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e, 0xb77f19b6, 0xe0a9dc09,
+ 0x662d09a1, 0xc4324633, 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10,
+ 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169, 0xdcb7da83, 0x573906fe,
+ 0xa1e2ce9b, 0x4fcd7f52, 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027,
+ 0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5, 0xf0177a28, 0xc0f586e0,
+ 0x006058aa, 0x30dc7d62, 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634,
+ 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76, 0x6f05e409, 0x4b7c0188,
+ 0x39720a3d, 0x7c927c24, 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc,
+ 0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4, 0x1e50ef5e, 0xb161e6f8,
+ 0xa28514d9, 0x6c51133c, 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837,
+ 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0,
+}
+
+var s3 = [256]uint32{
+ 0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b, 0x5cb0679e, 0x4fa33742,
+ 0xd3822740, 0x99bc9bbe, 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b,
+ 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4, 0x5748ab2f, 0xbc946e79,
+ 0xc6a376d2, 0x6549c2c8, 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6,
+ 0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304, 0xa1fad5f0, 0x6a2d519a,
+ 0x63ef8ce2, 0x9a86ee22, 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4,
+ 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6, 0x2826a2f9, 0xa73a3ae1,
+ 0x4ba99586, 0xef5562e9, 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59,
+ 0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593, 0xe990fd5a, 0x9e34d797,
+ 0x2cf0b7d9, 0x022b8b51, 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28,
+ 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c, 0xe029ac71, 0xe019a5e6,
+ 0x47b0acfd, 0xed93fa9b, 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28,
+ 0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c, 0x15056dd4, 0x88f46dba,
+ 0x03a16125, 0x0564f0bd, 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a,
+ 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319, 0x7533d928, 0xb155fdf5,
+ 0x03563482, 0x8aba3cbb, 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f,
+ 0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991, 0xea7a90c2, 0xfb3e7bce,
+ 0x5121ce64, 0x774fbe32, 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680,
+ 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166, 0xb39a460a, 0x6445c0dd,
+ 0x586cdecf, 0x1c20c8ae, 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb,
+ 0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5, 0x72eacea8, 0xfa6484bb,
+ 0x8d6612ae, 0xbf3c6f47, 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370,
+ 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d, 0x4040cb08, 0x4eb4e2cc,
+ 0x34d2466a, 0x0115af84, 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048,
+ 0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8, 0x611560b1, 0xe7933fdc,
+ 0xbb3a792b, 0x344525bd, 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9,
+ 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7, 0x1a908749, 0xd44fbd9a,
+ 0xd0dadecb, 0xd50ada38, 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f,
+ 0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c, 0xbf97222c, 0x15e6fc2a,
+ 0x0f91fc71, 0x9b941525, 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1,
+ 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442, 0xe0ec6e0e, 0x1698db3b,
+ 0x4c98a0be, 0x3278e964, 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e,
+ 0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8, 0xdf359f8d, 0x9b992f2e,
+ 0xe60b6f47, 0x0fe3f11d, 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f,
+ 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299, 0xf523f357, 0xa6327623,
+ 0x93a83531, 0x56cccd02, 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc,
+ 0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614, 0xe6c6c7bd, 0x327a140a,
+ 0x45e1d006, 0xc3f27b9a, 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6,
+ 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b, 0x53113ec0, 0x1640e3d3,
+ 0x38abbd60, 0x2547adf0, 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060,
+ 0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e, 0x1948c25c, 0x02fb8a8c,
+ 0x01c36ae4, 0xd6ebe1f9, 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f,
+ 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6,
+}
+
+var p = [18]uint32{
+ 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, 0xa4093822, 0x299f31d0,
+ 0x082efa98, 0xec4e6c89, 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c,
+ 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917, 0x9216d5d9, 0x8979fb1b,
+}
diff --git a/vendor/golang.org/x/tools/go/analysis/passes/fieldalignment/fieldalignment.go b/vendor/golang.org/x/tools/go/analysis/passes/fieldalignment/fieldalignment.go
index 53c746344..02791bc73 100644
--- a/vendor/golang.org/x/tools/go/analysis/passes/fieldalignment/fieldalignment.go
+++ b/vendor/golang.org/x/tools/go/analysis/passes/fieldalignment/fieldalignment.go
@@ -14,6 +14,7 @@ import (
"go/token"
"go/types"
"sort"
+ "strings"
"golang.org/x/tools/go/analysis"
"golang.org/x/tools/go/analysis/passes/inspect"
@@ -68,37 +69,66 @@ var Analyzer = &analysis.Analyzer{
func run(pass *analysis.Pass) (any, error) {
inspect := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector)
- nodeFilter := []ast.Node{
- (*ast.StructType)(nil),
- }
- inspect.Preorder(nodeFilter, func(node ast.Node) {
- var s *ast.StructType
- var ok bool
- if s, ok = node.(*ast.StructType); !ok {
- return
- }
- if tv, ok := pass.TypesInfo.Types[s]; ok {
- fieldalignment(pass, s, tv.Type.(*types.Struct))
+ for curStruct := range inspect.Root().Preorder((*ast.StructType)(nil)) {
+ s := curStruct.Node().(*ast.StructType)
+ // For every named struct defined as "type Name struct { ... }",
+ // the *ast.StructType node has a parent *ast.TypeSpec,
+ // which contains the struct's name in its Name field.
+ name := "struct" // (anonymous)
+ if spec, ok := curStruct.Parent().Node().(*ast.TypeSpec); ok {
+ name = spec.Name.Name
}
- })
+ fieldalignment(pass, s, name)
+ }
+
return nil, nil
}
-var unsafePointerTyp = types.Unsafe.Scope().Lookup("Pointer").(*types.TypeName).Type()
+func fieldalignment(pass *analysis.Pass, node *ast.StructType, name string) {
+ var (
+ sizes = &gcSizes{
+ wordSize: pass.TypesSizes.Sizeof(types.Typ[types.UnsafePointer]),
+ maxAlign: pass.TypesSizes.Alignof(types.Typ[types.UnsafePointer]),
+ }
-func fieldalignment(pass *analysis.Pass, node *ast.StructType, typ *types.Struct) {
- wordSize := pass.TypesSizes.Sizeof(unsafePointerTyp)
- maxAlign := pass.TypesSizes.Alignof(unsafePointerTyp)
+ typ = pass.TypesInfo.TypeOf(node).(*types.Struct)
+ optimal, indexes = optimalOrder(typ, sizes)
+
+ actualSize = sizes.sizeof(typ)
+ actualPtrs = sizes.ptrdata(typ)
+
+ optimalSize = sizes.sizeof(optimal)
+ optimalPtrs = sizes.ptrdata(optimal)
+ )
+
+ var message strings.Builder
+ if actualSize != optimalSize {
+ // Struct could be smaller.
+ // TODO(adonovan): IMHO the criterion should be "significantly smaller".
+ fmt.Fprintf(&message, "%s has size %d", name, actualSize)
+ actualClass := classSize(actualSize)
+ if actualClass == -1 {
+ actualClass = actualSize
+ fmt.Fprint(&message, " (uses global allocator)")
+ } else if actualClass != actualSize {
+ fmt.Fprintf(&message, " (allocator size class %d)", actualClass)
+ }
- s := gcSizes{wordSize, maxAlign}
- optimal, indexes := optimalOrder(typ, &s)
- optsz, optptrs := s.Sizeof(optimal), s.ptrdata(optimal)
+ fmt.Fprintf(&message, " but the optimal size is %d", optimalSize)
+ optimalClass := classSize(optimalSize)
+ if optimalClass == -1 {
+ optimalClass = optimalSize
+ } else if optimalClass != optimalSize {
+ fmt.Fprintf(&message, " (allocator size class %d)", optimalClass)
+ }
- var message string
- if sz := s.Sizeof(typ); sz != optsz {
- message = fmt.Sprintf("struct of size %d could be %d", sz, optsz)
- } else if ptrs := s.ptrdata(typ); ptrs != optptrs {
- message = fmt.Sprintf("struct with %d pointer bytes could be %d", ptrs, optptrs)
+ wastage := actualClass - optimalClass
+ if percentage := wastage * 100 / actualClass; percentage > 25 {
+ fmt.Fprintf(&message, " leading to a waste of %d bytes (%d%%)", wastage, percentage)
+ }
+ } else if actualPtrs != optimalPtrs {
+ // Struct could place pointers more efficiently for GC marking.
+ fmt.Fprintf(&message, "%s has %d leading bytes of pointer data but optimal value is %d", name, actualPtrs, optimalPtrs)
} else {
// Already optimal order.
return
@@ -151,7 +181,7 @@ func fieldalignment(pass *analysis.Pass, node *ast.StructType, typ *types.Struct
pass.Report(analysis.Diagnostic{
Pos: node.Pos(),
End: node.Pos() + token.Pos(len("struct")),
- Message: message,
+ Message: message.String(),
SuggestedFixes: []analysis.SuggestedFix{{
Message: "Rearrange fields",
TextEdits: []analysis.TextEdit{{
@@ -179,8 +209,8 @@ func optimalOrder(str *types.Struct, sizes *gcSizes) (*types.Struct, []int) {
ft := field.Type()
elems[i] = elem{
i,
- sizes.Alignof(ft),
- sizes.Sizeof(ft),
+ sizes.alignof(ft),
+ sizes.sizeof(ft),
sizes.ptrdata(ft),
}
}
@@ -240,40 +270,42 @@ func optimalOrder(str *types.Struct, sizes *gcSizes) (*types.Struct, []int) {
return types.NewStruct(fields, nil), indexes
}
-// Code below based on go/types.StdSizes.
+// gcSizes implements cmd/compile layout rules, providing ptrdata (GC
+// scanning limits) and trailing zero-size field padding not available
+// in [types.Sizes].
type gcSizes struct {
- WordSize int64
- MaxAlign int64
+ wordSize int64
+ maxAlign int64
}
-func (s *gcSizes) Alignof(T types.Type) int64 {
+func (s *gcSizes) alignof(T types.Type) int64 {
// For arrays and structs, alignment is defined in terms
// of alignment of the elements and fields, respectively.
switch t := T.Underlying().(type) {
case *types.Array:
// spec: "For a variable x of array type: unsafe.Alignof(x)
// is the same as unsafe.Alignof(x[0]), but at least 1."
- return s.Alignof(t.Elem())
+ return s.alignof(t.Elem())
case *types.Struct:
// spec: "For a variable x of struct type: unsafe.Alignof(x)
// is the largest of the values unsafe.Alignof(x.f) for each
// field f of x, but at least 1."
max := int64(1)
for i, nf := 0, t.NumFields(); i < nf; i++ {
- if a := s.Alignof(t.Field(i).Type()); a > max {
+ if a := s.alignof(t.Field(i).Type()); a > max {
max = a
}
}
return max
}
- a := s.Sizeof(T) // may be 0
+ a := s.sizeof(T) // may be 0
// spec: "For a variable x of any type: unsafe.Alignof(x) is at least 1."
if a < 1 {
return 1
}
- if a > s.MaxAlign {
- return s.MaxAlign
+ if a > s.maxAlign {
+ return s.maxAlign
}
return a
}
@@ -294,7 +326,7 @@ var basicSizes = [...]byte{
types.Complex128: 16,
}
-func (s *gcSizes) Sizeof(T types.Type) int64 {
+func (s *gcSizes) sizeof(T types.Type) int64 {
switch t := T.Underlying().(type) {
case *types.Basic:
k := t.Kind()
@@ -304,12 +336,12 @@ func (s *gcSizes) Sizeof(T types.Type) int64 {
}
}
if k == types.String {
- return s.WordSize * 2
+ return s.wordSize * 2
}
case *types.Array:
- return t.Len() * s.Sizeof(t.Elem())
+ return t.Len() * s.sizeof(t.Elem())
case *types.Slice:
- return s.WordSize * 3
+ return s.wordSize * 3
case *types.Struct:
nf := t.NumFields()
if nf == 0 {
@@ -320,7 +352,7 @@ func (s *gcSizes) Sizeof(T types.Type) int64 {
max := int64(1)
for i := range nf {
ft := t.Field(i).Type()
- a, sz := s.Alignof(ft), s.Sizeof(ft)
+ a, sz := s.alignof(ft), s.sizeof(ft)
if a > max {
max = a
}
@@ -331,9 +363,9 @@ func (s *gcSizes) Sizeof(T types.Type) int64 {
}
return align(o, max)
case *types.Interface:
- return s.WordSize * 2
+ return s.wordSize * 2
}
- return s.WordSize // catch-all
+ return s.wordSize // catch-all
}
// align returns the smallest y >= x such that y % a == 0.
@@ -347,13 +379,13 @@ func (s *gcSizes) ptrdata(T types.Type) int64 {
case *types.Basic:
switch t.Kind() {
case types.String, types.UnsafePointer:
- return s.WordSize
+ return s.wordSize
}
return 0
case *types.Chan, *types.Map, *types.Pointer, *types.Signature, *types.Slice:
- return s.WordSize
+ return s.wordSize
case *types.Interface:
- return 2 * s.WordSize
+ return 2 * s.wordSize
case *types.Array:
n := t.Len()
if n == 0 {
@@ -363,7 +395,7 @@ func (s *gcSizes) ptrdata(T types.Type) int64 {
if a == 0 {
return 0
}
- z := s.Sizeof(t.Elem())
+ z := s.sizeof(t.Elem())
return (n-1)*z + a
case *types.Struct:
nf := t.NumFields()
@@ -374,7 +406,7 @@ func (s *gcSizes) ptrdata(T types.Type) int64 {
var o, p int64
for i := range nf {
ft := t.Field(i).Type()
- a, sz := s.Alignof(ft), s.Sizeof(ft)
+ a, sz := s.alignof(ft), s.sizeof(ft)
fp := s.ptrdata(ft)
o = align(o, a)
if fp != 0 {
@@ -387,3 +419,16 @@ func (s *gcSizes) ptrdata(T types.Type) int64 {
panic("impossible")
}
+
+// Code below based on tools/gopls/internal/golang/hover.go
+
+// classSize reports the size class for a struct of the specified size, or -1 if unknown.
+// See GOROOT/src/runtime/msize.go for details.
+func classSize(size int64) int64 {
+ if size > 1<<15 {
+ return -1 // avoid allocation
+ }
+ // We assume that bytes.Clone doesn't trim,
+ // and reports the underlying size class
+ return int64(cap(bytes.Clone(make([]byte, size))))
+}
diff --git a/vendor/golang.org/x/tools/go/analysis/passes/inline/doc.go b/vendor/golang.org/x/tools/go/analysis/passes/inline/doc.go
new file mode 100644
index 000000000..fea596b9e
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/analysis/passes/inline/doc.go
@@ -0,0 +1,130 @@
+// Copyright 2025 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 inline defines an analyzer that inlines calls to functions
+and uses of constants marked with a "//go:fix inline" directive.
+
+# Analyzer inline
+
+inline: apply fixes based on 'go:fix inline' comment directives
+
+The inline analyzer inlines functions, constants, and type aliases
+that are marked for inlining.
+
+Use this command to apply (just) inline fixes en masse:
+
+ $ go fix -inline ./...
+
+## Functions
+
+Given a function that is marked for inlining, like this one:
+
+ //go:fix inline
+ func Square(x int) int { return Pow(x, 2) }
+
+this analyzer will recommend that calls to the function elsewhere, in the same
+or other packages, should be inlined.
+
+Inlining can be used to move off of a deprecated function:
+
+ // Deprecated: prefer Pow(x, 2).
+ //go:fix inline
+ func Square(x int) int { return Pow(x, 2) }
+
+It can also be used to move off of an obsolete package,
+as when the import path has changed or a higher major version is available:
+
+ package pkg
+
+ import pkg2 "pkg/v2"
+
+ //go:fix inline
+ func F() { pkg2.F(nil) }
+
+Replacing a call pkg.F() by pkg2.F(nil) can have no effect on the program,
+so this mechanism provides a low-risk way to update large numbers of calls.
+We recommend, where possible, expressing the old API in terms of the new one
+to enable automatic migration.
+
+The inliner takes care to avoid behavior changes, even subtle ones,
+such as changes to the order in which argument expressions are
+evaluated. When it cannot safely eliminate all parameter variables,
+it may introduce a "binding declaration" of the form
+
+ var params = args
+
+to evaluate argument expressions in the correct order and bind them to
+parameter variables. Since the resulting code transformation may be
+stylistically suboptimal, such inlinings may be disabled by specifying
+the -inline.allow_binding_decl=false flag to the analyzer driver.
+
+(In cases where it is not safe to "reduce" a call—that is, to replace
+a call f(x) by the body of function f, suitably substituted—the
+inliner machinery is capable of replacing f by a function literal,
+func(){...}(). However, the inline analyzer discards all such
+"literalizations" unconditionally, again on grounds of style.)
+
+## Constants
+
+Given a constant that is marked for inlining, like this one:
+
+ //go:fix inline
+ const Ptr = Pointer
+
+this analyzer will recommend that uses of Ptr should be replaced with Pointer.
+
+As with functions, inlining can be used to replace deprecated constants and
+constants in obsolete packages.
+
+A constant definition can be marked for inlining only if it refers to another
+named constant.
+
+The "//go:fix inline" comment must appear before a single const declaration on its own,
+as above; before a const declaration that is part of a group, as in this case:
+
+ const (
+ C = 1
+ //go:fix inline
+ Ptr = Pointer
+ )
+
+or before a group, applying to every constant in the group:
+
+ //go:fix inline
+ const (
+ Ptr = Pointer
+ Val = Value
+ )
+
+## Type aliases
+
+Similar to named constants, a type alias can also be marked for inlining:
+
+ //go:fix inline
+ type A = newpkg.A
+
+The analyzer will replace all references to the annotated type
+(A) by the type on the right-hand side of the declaration (newpkg.A).
+
+## Tests
+
+A use of a function, named constant, or type alias X from its
+dedicated test (TestX), is not inlined, since the purpose of the test
+is to exercise X itself, even if it is deprecated and other uses of it
+should be inlined.
+This applies to benchmarks and examples too, and follows the usual
+conventions of test function naming.
+
+Similarly, if the symbol X is declared in a file named foo.go, any use
+of it within a file named foo_test.go will also not be inlined.
+
+# Analyzer gofixdirective
+
+gofixdirective: validate uses of //go:fix comment directives
+
+The gofixdirective analyzer checks "//go:fix inline" directives for correctness.
+See the documentation for the gofix analyzer for more about "/go:fix inline".
+*/
+package inline
diff --git a/vendor/golang.org/x/tools/go/analysis/passes/inline/inline.go b/vendor/golang.org/x/tools/go/analysis/passes/inline/inline.go
new file mode 100644
index 000000000..d16e0d0b6
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/analysis/passes/inline/inline.go
@@ -0,0 +1,638 @@
+// Copyright 2023 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 inline
+
+import (
+ "fmt"
+ "go/ast"
+ "go/types"
+ "slices"
+ "strings"
+
+ _ "embed"
+
+ "golang.org/x/tools/go/analysis"
+ "golang.org/x/tools/go/analysis/passes/inspect"
+ "golang.org/x/tools/go/analysis/passes/internal/gofixdirective"
+ "golang.org/x/tools/go/ast/edge"
+ "golang.org/x/tools/go/ast/inspector"
+ "golang.org/x/tools/go/types/typeutil"
+ "golang.org/x/tools/internal/analysis/analyzerutil"
+ typeindexanalyzer "golang.org/x/tools/internal/analysis/typeindex"
+ "golang.org/x/tools/internal/astutil"
+ "golang.org/x/tools/internal/moreiters"
+ "golang.org/x/tools/internal/packagepath"
+ "golang.org/x/tools/internal/refactor"
+ "golang.org/x/tools/internal/refactor/inline"
+ "golang.org/x/tools/internal/typesinternal"
+ "golang.org/x/tools/internal/typesinternal/typeindex"
+)
+
+//go:embed doc.go
+var doc string
+
+var Analyzer = &analysis.Analyzer{
+ Name: "inline",
+ Doc: analyzerutil.MustExtractDoc(doc, "inline"),
+ URL: "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/inline",
+ Run: run,
+ FactTypes: []analysis.Fact{
+ (*goFixInlineFuncFact)(nil),
+ (*goFixInlineConstFact)(nil),
+ (*goFixInlineAliasFact)(nil),
+ },
+ Requires: []*analysis.Analyzer{
+ inspect.Analyzer,
+ typeindexanalyzer.Analyzer,
+ },
+}
+
+var (
+ allowBindingDecl bool
+ lazyEdits bool
+)
+
+func init() {
+ Analyzer.Flags.BoolVar(&allowBindingDecl, "allow_binding_decl", false,
+ "permit inlinings that require a 'var params = args' declaration")
+ Analyzer.Flags.BoolVar(&lazyEdits, "lazy_edits", false,
+ "compute edits lazily (only meaningful to gopls driver)")
+}
+
+// analyzer holds the state for this analysis.
+type analyzer struct {
+ pass *analysis.Pass
+ root inspector.Cursor
+ index *typeindex.Index
+ // memoization of repeated calls for same file.
+ fileContent map[string][]byte
+ // memoization of fact imports (nil => no fact)
+ inlinableFuncs map[*types.Func]*inline.Callee
+ inlinableConsts map[*types.Const]*goFixInlineConstFact
+ inlinableAliases map[*types.TypeName]*goFixInlineAliasFact
+}
+
+func run(pass *analysis.Pass) (any, error) {
+ a := &analyzer{
+ pass: pass,
+ root: pass.ResultOf[inspect.Analyzer].(*inspector.Inspector).Root(),
+ index: pass.ResultOf[typeindexanalyzer.Analyzer].(*typeindex.Index),
+ fileContent: make(map[string][]byte),
+ inlinableFuncs: make(map[*types.Func]*inline.Callee),
+ inlinableConsts: make(map[*types.Const]*goFixInlineConstFact),
+ inlinableAliases: make(map[*types.TypeName]*goFixInlineAliasFact),
+ }
+ gofixdirective.Find(pass, a.root, a)
+ a.inline()
+ return nil, nil
+}
+
+// HandleFunc exports a fact for functions marked with go:fix.
+func (a *analyzer) HandleFunc(decl *ast.FuncDecl) {
+ content, err := a.readFile(decl)
+ if err != nil {
+ a.pass.Reportf(decl.Doc.Pos(), "invalid inlining candidate: cannot read source file: %v", err)
+ return
+ }
+ callee, err := inline.AnalyzeCallee(discard, a.pass.Fset, a.pass.Pkg, a.pass.TypesInfo, decl, content)
+ if err != nil {
+ a.pass.Reportf(decl.Doc.Pos(), "invalid inlining candidate: %v", err)
+ return
+ }
+ fn := a.pass.TypesInfo.Defs[decl.Name].(*types.Func)
+ a.pass.ExportObjectFact(fn, &goFixInlineFuncFact{callee})
+ a.inlinableFuncs[fn] = callee
+}
+
+// HandleAlias exports a fact for aliases marked with go:fix.
+func (a *analyzer) HandleAlias(spec *ast.TypeSpec) {
+ // Remember that this is an inlinable alias.
+ typ := &goFixInlineAliasFact{}
+ lhs := a.pass.TypesInfo.Defs[spec.Name].(*types.TypeName)
+ a.inlinableAliases[lhs] = typ
+ // Create a fact only if the LHS is exported and defined at top level.
+ // We create a fact even if the RHS is non-exported,
+ // so we can warn about uses in other packages.
+ if lhs.Exported() && typesinternal.IsPackageLevel(lhs) {
+ a.pass.ExportObjectFact(lhs, typ)
+ }
+}
+
+// HandleConst exports a fact for constants marked with go:fix.
+func (a *analyzer) HandleConst(nameIdent, rhsIdent *ast.Ident) {
+ lhs := a.pass.TypesInfo.Defs[nameIdent].(*types.Const)
+ rhs := a.pass.TypesInfo.Uses[rhsIdent].(*types.Const) // must be so in a well-typed program
+ con := &goFixInlineConstFact{
+ RHSName: rhs.Name(),
+ RHSPkgName: rhs.Pkg().Name(),
+ RHSPkgPath: rhs.Pkg().Path(),
+ }
+ if rhs.Pkg() == a.pass.Pkg {
+ con.rhsObj = rhs
+ }
+ a.inlinableConsts[lhs] = con
+ // Create a fact only if the LHS is exported and defined at top level.
+ // We create a fact even if the RHS is non-exported,
+ // so we can warn about uses in other packages.
+ if lhs.Exported() && typesinternal.IsPackageLevel(lhs) {
+ a.pass.ExportObjectFact(lhs, con)
+ }
+}
+
+// inline inlines each static call to an inlinable function
+// and each reference to an inlinable constant or type alias.
+func (a *analyzer) inline() {
+ for cur := range a.root.Preorder((*ast.CallExpr)(nil), (*ast.Ident)(nil)) {
+ switch n := cur.Node().(type) {
+ case *ast.CallExpr:
+ a.inlineCall(n, cur)
+
+ case *ast.Ident:
+ switch obj := a.pass.TypesInfo.Uses[n].(type) {
+ case *types.TypeName:
+ a.inlineAlias(obj, cur)
+ case *types.Const:
+ a.inlineConst(obj, cur)
+ }
+ }
+ }
+}
+
+// If call is a call to an inlinable func, suggest inlining its use at cur.
+func (a *analyzer) inlineCall(call *ast.CallExpr, cur inspector.Cursor) {
+ if fn := typeutil.StaticCallee(a.pass.TypesInfo, call); fn != nil {
+ // Inlinable?
+ callee, ok := a.inlinableFuncs[fn]
+ if !ok {
+ var fact goFixInlineFuncFact
+ if a.pass.ImportObjectFact(fn, &fact) {
+ callee = fact.Callee
+ a.inlinableFuncs[fn] = callee
+ }
+ }
+ if callee == nil {
+ return // nope
+ }
+
+ if a.withinTestOf(cur, fn) {
+ return // don't inline a function from within its own test
+ }
+
+ // Compute the edits.
+ //
+ // Ordinarily the analyzer reports a fix containing
+ // edits. However, the algorithm is somewhat expensive
+ // (unnecessarily so: see go.dev/issue/75773) so
+ // to reduce costs in gopls, we omit the edits,
+ // meaning that gopls must compute them on demand
+ // (based on the Diagnostic.Category) when they are
+ // requested via a code action.
+ //
+ // This does mean that the following categories of
+ // caller-dependent obstacles to inlining will be
+ // reported when the gopls user requests the fix,
+ // rather than by quietly suppressing the diagnostic:
+ // - shadowing problems
+ // - callee imports inaccessible "internal" packages
+ // - callee refers to nonexported symbols
+ // - callee uses too-new Go features
+ // - inlining call from a cgo file
+ var edits []analysis.TextEdit
+ if !lazyEdits {
+ // Inline the call.
+ caller := &inline.Caller{
+ Fset: a.pass.Fset,
+ Types: a.pass.Pkg,
+ Info: a.pass.TypesInfo,
+ File: astutil.EnclosingFile(cur),
+ Call: call,
+ CountUses: func(pkgname *types.PkgName) int {
+ return moreiters.Len(a.index.Uses(pkgname))
+ },
+ }
+ res, err := inline.Inline(caller, callee, &inline.Options{Logf: discard})
+ if err != nil {
+ a.pass.Reportf(call.Lparen, "%v", err)
+ return
+ }
+
+ if res.Literalized {
+ // Users are not fond of inlinings that literalize
+ // f(x) to func() { ... }(), so avoid them.
+ //
+ // (Unfortunately the inliner is very timid,
+ // and often literalizes when it cannot prove that
+ // reducing the call is safe; the user of this tool
+ // has no indication of what the problem is.)
+ return
+ }
+ if res.BindingDecl && !allowBindingDecl {
+ // When applying fix en masse, users are similarly
+ // unenthusiastic about inlinings that cannot
+ // entirely eliminate the parameters and
+ // insert a 'var params = args' declaration.
+ // The flag allows them to decline such fixes.
+ return
+ }
+ edits = res.Edits
+ }
+
+ a.pass.Report(analysis.Diagnostic{
+ Pos: call.Pos(),
+ End: call.End(),
+ Message: fmt.Sprintf("Call of %v should be inlined", callee),
+ Category: "inline_call", // keep consistent with gopls/internal/golang.fixInlineCall
+ SuggestedFixes: []analysis.SuggestedFix{{
+ Message: fmt.Sprintf("Inline call of %v", callee),
+ TextEdits: edits, // within gopls, this is nil => compute fix's edits lazily
+ }},
+ })
+ }
+}
+
+// withinTestOf reports whether curUse is within a dedicated test
+// function for the inlinable target symbol.
+// A call within its dedicated test should not be inlined.
+func (a *analyzer) withinTestOf(curUse inspector.Cursor, target types.Object) bool {
+ // x_test.go -> x
+ useFileBase, isTest := strings.CutSuffix(a.pass.Fset.File(curUse.Node().Pos()).Name(), "_test.go")
+ if !isTest {
+ return false // not a test file
+ }
+
+ // Suppress fixes for uses in x_test.go of target symbol defined in x.go (#79272).
+ if useFileBase == strings.TrimSuffix(a.pass.Fset.File(target.Pos()).Name(), ".go") {
+ return true
+ }
+
+ curFuncDecl, ok := moreiters.First(curUse.Enclosing((*ast.FuncDecl)(nil)))
+ if !ok {
+ return false // not in a function
+ }
+ funcDecl := curFuncDecl.Node().(*ast.FuncDecl)
+ if funcDecl.Recv != nil {
+ return false // not a test func
+ }
+ if strings.TrimSuffix(a.pass.Pkg.Path(), "_test") != target.Pkg().Path() {
+ return false // different package
+ }
+
+ // Computed expected SYMBOL portion of "ExampleSYMBOL_comment"
+ // for the target symbol. (Strictly, this convention applies
+ // only to Example functions.)
+ // TODO(adonovan): use a proper Test function parser.
+ symbol := target.Name()
+ if fn, ok := target.(*types.Func); ok {
+ if recv := fn.Signature().Recv(); recv != nil {
+ _, named := typesinternal.ReceiverNamed(recv)
+ symbol = named.Obj().Name() + "_" + symbol
+ }
+ }
+ fname := funcDecl.Name.Name
+ for _, pre := range []string{"Test", "Example", "Bench", "Fuzz"} {
+ if fname == pre+symbol || strings.HasPrefix(fname, pre+symbol+"_") {
+ return true // use of X within TestX
+ }
+ }
+
+ return false
+}
+
+// If tn is the TypeName of an inlinable alias, suggest inlining its use at cur.
+func (a *analyzer) inlineAlias(tn *types.TypeName, curId inspector.Cursor) {
+ inalias, ok := a.inlinableAliases[tn]
+ if !ok {
+ var fact goFixInlineAliasFact
+ if a.pass.ImportObjectFact(tn, &fact) {
+ inalias = &fact
+ a.inlinableAliases[tn] = inalias
+ }
+ }
+ if inalias == nil {
+ return // nope
+ }
+
+ if a.withinTestOf(curId, tn) {
+ return // don't inline a type alias from within its own test
+ }
+
+ alias := tn.Type().(*types.Alias)
+ // Remember the names of the alias's type params. When we check for shadowing
+ // later, we'll ignore these because they won't appear in the replacement text.
+ typeParamNames := map[*types.TypeName]bool{}
+ for tp := range alias.TypeParams().TypeParams() {
+ typeParamNames[tp.Obj()] = true
+ }
+ rhs := alias.Rhs()
+ curPath := a.pass.Pkg.Path()
+ curFile := astutil.EnclosingFile(curId)
+ id := curId.Node().(*ast.Ident)
+
+ // Find the complete identifier, which may take any of these forms:
+ // Id
+ // Id[T]
+ // Id[K, V]
+ // pkg.Id
+ // pkg.Id[T]
+ // pkg.Id[K, V]
+ var expr ast.Expr = id
+ if curId.ParentEdgeKind() == edge.SelectorExpr_Sel {
+ curId = curId.Parent()
+ expr = curId.Node().(ast.Expr)
+ }
+ // If expr is part of an IndexExpr or IndexListExpr, we'll need that node.
+ // Given C[int], TypeOf(C) is generic but TypeOf(C[int]) is instantiated.
+ switch curId.ParentEdgeKind() {
+ case edge.IndexExpr_X:
+ curId = curId.Parent()
+ expr = curId.Node().(*ast.IndexExpr)
+ case edge.IndexListExpr_X:
+ curId = curId.Parent()
+ expr = curId.Node().(*ast.IndexListExpr)
+ }
+
+ // Reject inlining of a type alias used to declare an embedded
+ // struct field if doing so would change the field's name.
+ if v, ok := a.pass.TypesInfo.Defs[id].(*types.Var); ok && v.Embedded() {
+ identicalName := false
+ // TODO(adonovan): should we allow a pointer (type A = *pkg.A)?
+ if rhs, ok := alias.Rhs().(*types.Named); ok {
+ identicalName = alias.Obj().Name() == rhs.Obj().Name()
+ }
+ if !identicalName {
+ // Type is embedded, inlining the alias will cause
+ // the field name to be changed, which might break
+ // programs in terms of backwards compatibility.
+ return
+ }
+ }
+
+ t := a.pass.TypesInfo.TypeOf(expr).(*types.Alias) // type of entire identifier
+ if targs := t.TypeArgs(); targs.Len() > 0 {
+ // Instantiate the alias with the type args from this use.
+ // For example, given type A = M[K, V], compute the type of the use
+ // A[int, Foo] as M[int, Foo].
+ // Don't validate instantiation: it can't panic unless we have a bug,
+ // in which case seeing the stack trace via telemetry would be helpful.
+ instAlias, _ := types.Instantiate(nil, alias, slices.Collect(targs.Types()), false)
+ rhs = instAlias.(*types.Alias).Rhs()
+ }
+
+ // We have an identifier A here (n), possibly qualified by a package
+ // identifier (sel.n), and an inlinable "type A = rhs" elsewhere.
+ //
+ // We can replace A with rhs if no name in rhs is shadowed at n's position,
+ // and every package in rhs is importable by the current package.
+ var (
+ importPrefixes = map[string]string{curPath: ""} // from pkg path to prefix
+ edits []analysis.TextEdit
+ )
+ for _, tn := range typenames(rhs) {
+ // Ignore the type parameters of the alias: they won't appear in the result.
+ if typeParamNames[tn] {
+ continue
+ }
+ var pkgPath, pkgName string
+ if pkg := tn.Pkg(); pkg != nil {
+ pkgPath = pkg.Path()
+ pkgName = pkg.Name()
+ }
+ if pkgPath == "" || pkgPath == curPath {
+ // The name is in the current package or the universe scope, so no import
+ // is required. Check that it is not shadowed (that is, that the type
+ // it refers to in rhs is the same one it refers to at n).
+ scope := a.pass.TypesInfo.Scopes[curFile].Innermost(id.Pos()) // n's scope
+ _, obj := scope.LookupParent(tn.Name(), id.Pos()) // what qn.name means in n's scope
+ if obj != tn {
+ return
+ }
+ } else if !packagepath.CanImport(a.pass.Pkg.Path(), pkgPath) {
+ // If this package can't see the package of this part of rhs, we can't inline.
+ return
+ } else if _, ok := importPrefixes[pkgPath]; !ok {
+ // Use AddImport to add pkgPath if it's not there already. Associate the prefix it assigns
+ // with the prefix it assigns
+ // with the package path for use by the TypeString qualifier below.
+ prefix, eds := refactor.AddImport(
+ a.pass.TypesInfo, curFile, pkgName, pkgPath, tn.Name(), id.Pos())
+ importPrefixes[pkgPath] = strings.TrimSuffix(prefix, ".")
+ edits = append(edits, eds...)
+ }
+ }
+
+ // To get the replacement text, render the alias RHS using the package prefixes
+ // we assigned above.
+ newText := types.TypeString(rhs, func(p *types.Package) string {
+ if p == a.pass.Pkg {
+ return ""
+ }
+ if prefix, ok := importPrefixes[p.Path()]; ok {
+ return prefix
+ }
+ panic(fmt.Sprintf("in %q, package path %q has no import prefix", rhs, p.Path()))
+ })
+ a.reportInline("type alias", "Type alias", expr, edits, newText)
+}
+
+// typenames returns the TypeNames for types within t (including t itself) that have
+// them: basic types, named types and alias types.
+// The same name may appear more than once.
+func typenames(t types.Type) []*types.TypeName {
+ var tns []*types.TypeName
+
+ var visit func(types.Type)
+ visit = func(t types.Type) {
+ if hasName, ok := t.(interface{ Obj() *types.TypeName }); ok {
+ tns = append(tns, hasName.Obj())
+ }
+ switch t := t.(type) {
+ case *types.Basic:
+ tns = append(tns, types.Universe.Lookup(t.Name()).(*types.TypeName))
+ case *types.Named:
+ for t := range t.TypeArgs().Types() {
+ visit(t)
+ }
+ case *types.Alias:
+ for t := range t.TypeArgs().Types() {
+ visit(t)
+ }
+ case *types.TypeParam:
+ tns = append(tns, t.Obj())
+ case *types.Pointer:
+ visit(t.Elem())
+ case *types.Slice:
+ visit(t.Elem())
+ case *types.Array:
+ visit(t.Elem())
+ case *types.Chan:
+ visit(t.Elem())
+ case *types.Map:
+ visit(t.Key())
+ visit(t.Elem())
+ case *types.Struct:
+ for field := range t.Fields() {
+ visit(field.Type())
+ }
+ case *types.Signature:
+ // Ignore the receiver: although it may be present, it has no meaning
+ // in a type expression.
+ // Ditto for receiver type params.
+ // Also, function type params cannot appear in a type expression.
+ if t.TypeParams() != nil {
+ panic("Signature.TypeParams in type expression")
+ }
+ visit(t.Params())
+ visit(t.Results())
+ case *types.Interface:
+ for etyp := range t.EmbeddedTypes() {
+ visit(etyp)
+ }
+ for method := range t.ExplicitMethods() {
+ visit(method.Type())
+ }
+ case *types.Tuple:
+ for v := range t.Variables() {
+ visit(v.Type())
+ }
+ case *types.Union:
+ panic("Union in type expression")
+ default:
+ panic(fmt.Sprintf("unknown type %T", t))
+ }
+ }
+
+ visit(t)
+
+ return tns
+}
+
+// If con is an inlinable constant, suggest inlining its use at cur.
+func (a *analyzer) inlineConst(con *types.Const, cur inspector.Cursor) {
+ incon, ok := a.inlinableConsts[con]
+ if !ok {
+ var fact goFixInlineConstFact
+ if a.pass.ImportObjectFact(con, &fact) {
+ incon = &fact
+ a.inlinableConsts[con] = incon
+ }
+ }
+ if incon == nil {
+ return // nope
+ }
+
+ if a.withinTestOf(cur, con) {
+ return // don't inline a type alias from within its own test
+ }
+
+ // If n is qualified by a package identifier, we'll need the full selector expression.
+ curFile := astutil.EnclosingFile(cur)
+ n := cur.Node().(*ast.Ident)
+
+ // We have an identifier A here (n), possibly qualified by a package identifier (sel.X,
+ // where sel is the parent of n), // and an inlinable "const A = B" elsewhere (incon).
+ // Consider replacing A with B.
+
+ // Check that the expression we are inlining (B) means the same thing
+ // (refers to the same object) in n's scope as it does in A's scope.
+ // If the RHS is not in the current package, AddImport will handle
+ // shadowing, so we only need to worry about when both expressions
+ // are in the current package.
+ if a.pass.Pkg.Path() == incon.RHSPkgPath {
+ // incon.rhsObj is the object referred to by B in the definition of A.
+ scope := a.pass.TypesInfo.Scopes[curFile].Innermost(n.Pos()) // n's scope
+ _, obj := scope.LookupParent(incon.RHSName, n.Pos()) // what "B" means in n's scope
+ if obj == nil {
+ // Should be impossible: if code at n can refer to the LHS,
+ // it can refer to the RHS.
+ panic(fmt.Sprintf("no object for inlinable const %s RHS %s", n.Name, incon.RHSName))
+ }
+ if obj != incon.rhsObj {
+ // "B" means something different here than at the inlinable const's scope.
+ return
+ }
+ } else if !packagepath.CanImport(a.pass.Pkg.Path(), incon.RHSPkgPath) {
+ // If this package can't see the RHS's package, we can't inline.
+ return
+ }
+ var (
+ importPrefix string
+ edits []analysis.TextEdit
+ )
+ if incon.RHSPkgPath != a.pass.Pkg.Path() {
+ importPrefix, edits = refactor.AddImport(
+ a.pass.TypesInfo, curFile, incon.RHSPkgName, incon.RHSPkgPath, incon.RHSName, n.Pos())
+ }
+ // If n is qualified by a package identifier, we'll need the full selector expression.
+ var expr ast.Expr = n
+ if cur.ParentEdgeKind() == edge.SelectorExpr_Sel {
+ expr = cur.Parent().Node().(ast.Expr)
+ }
+ a.reportInline("constant", "Constant", expr, edits, importPrefix+incon.RHSName)
+}
+
+// reportInline reports a diagnostic for fixing an inlinable name.
+func (a *analyzer) reportInline(kind, capKind string, ident ast.Expr, edits []analysis.TextEdit, newText string) {
+ edits = append(edits, analysis.TextEdit{
+ Pos: ident.Pos(),
+ End: ident.End(),
+ NewText: []byte(newText),
+ })
+ name := astutil.Format(a.pass.Fset, ident)
+ a.pass.Report(analysis.Diagnostic{
+ Pos: ident.Pos(),
+ End: ident.End(),
+ Message: fmt.Sprintf("%s %s should be inlined", capKind, name),
+ SuggestedFixes: []analysis.SuggestedFix{{
+ Message: fmt.Sprintf("Inline %s %s", kind, name),
+ TextEdits: edits,
+ }},
+ })
+}
+
+func (a *analyzer) readFile(node ast.Node) ([]byte, error) {
+ filename := a.pass.Fset.File(node.Pos()).Name()
+ content, ok := a.fileContent[filename]
+ if !ok {
+ var err error
+ content, err = a.pass.ReadFile(filename)
+ if err != nil {
+ return nil, err
+ }
+ a.fileContent[filename] = content
+ }
+ return content, nil
+}
+
+// A goFixInlineFuncFact is exported for each function marked "//go:fix inline".
+// It holds information about the callee to support inlining.
+type goFixInlineFuncFact struct{ Callee *inline.Callee }
+
+func (f *goFixInlineFuncFact) String() string { return "goFixInline " + f.Callee.String() }
+func (*goFixInlineFuncFact) AFact() {}
+
+// A goFixInlineConstFact is exported for each constant marked "//go:fix inline".
+// It holds information about an inlinable constant. Gob-serializable.
+type goFixInlineConstFact struct {
+ // Information about "const LHSName = RHSName".
+ RHSName string
+ RHSPkgPath string
+ RHSPkgName string
+ rhsObj types.Object // for current package
+}
+
+func (c *goFixInlineConstFact) String() string {
+ return fmt.Sprintf("goFixInline const %q.%s", c.RHSPkgPath, c.RHSName)
+}
+
+func (*goFixInlineConstFact) AFact() {}
+
+// A goFixInlineAliasFact is exported for each type alias marked "//go:fix inline".
+// It holds no information; its mere existence demonstrates that an alias is inlinable.
+type goFixInlineAliasFact struct{}
+
+func (c *goFixInlineAliasFact) String() string { return "goFixInline alias" }
+func (*goFixInlineAliasFact) AFact() {}
+
+func discard(string, ...any) {}
diff --git a/vendor/golang.org/x/tools/go/analysis/passes/internal/gofixdirective/gofixdirective.go b/vendor/golang.org/x/tools/go/analysis/passes/internal/gofixdirective/gofixdirective.go
new file mode 100644
index 000000000..949df4bfe
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/analysis/passes/internal/gofixdirective/gofixdirective.go
@@ -0,0 +1,143 @@
+// Copyright 2025 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 gofixdirective searches for and validates go:fix directives. The
+// go/analysis/passes/inline package uses findgofix to perform inlining.
+// The go/analysis/passes/gofix package uses findgofix to check for problems
+// with go:fix directives.
+//
+// gofixdirective is separate from gofix to avoid depending on refactor/inline,
+// which is large.
+package gofixdirective
+
+// This package is tested by go/analysis/passes/inline.
+
+import (
+ "go/ast"
+ "go/token"
+ "go/types"
+
+ "golang.org/x/tools/go/analysis"
+ "golang.org/x/tools/go/ast/inspector"
+ internalastutil "golang.org/x/tools/internal/astutil"
+)
+
+// A Handler handles language entities with go:fix directives.
+type Handler interface {
+ HandleFunc(*ast.FuncDecl)
+ HandleAlias(*ast.TypeSpec)
+ HandleConst(name, rhs *ast.Ident)
+}
+
+// Find finds functions and constants annotated with an appropriate "//go:fix"
+// comment (the syntax proposed by #32816), and calls handler methods for each one.
+// h may be nil.
+func Find(pass *analysis.Pass, root inspector.Cursor, h Handler) {
+ for cur := range root.Preorder((*ast.FuncDecl)(nil), (*ast.GenDecl)(nil)) {
+ switch decl := cur.Node().(type) {
+ case *ast.FuncDecl:
+ findFunc(decl, h)
+
+ case *ast.GenDecl:
+ if decl.Tok != token.CONST && decl.Tok != token.TYPE {
+ continue
+ }
+ declInline := hasFixInline(decl.Doc)
+ // Accept inline directives on the entire decl as well as individual specs.
+ for _, spec := range decl.Specs {
+ switch spec := spec.(type) {
+ case *ast.TypeSpec: // Tok == TYPE
+ findAlias(pass, spec, declInline, h)
+
+ case *ast.ValueSpec: // Tok == CONST
+ findConst(pass, spec, declInline, h)
+ }
+ }
+ }
+ }
+}
+
+func findFunc(decl *ast.FuncDecl, h Handler) {
+ if !hasFixInline(decl.Doc) {
+ return
+ }
+ if h != nil {
+ h.HandleFunc(decl)
+ }
+}
+
+func findAlias(pass *analysis.Pass, spec *ast.TypeSpec, declInline bool, h Handler) {
+ if !declInline && !hasFixInline(spec.Doc) {
+ return
+ }
+ if !spec.Assign.IsValid() {
+ pass.Reportf(spec.Pos(), "invalid //go:fix inline directive: not a type alias")
+ return
+ }
+
+ // Disallow inlines of type expressions containing array types.
+ // Given an array type like [N]int where N is a named constant, go/types provides
+ // only the value of the constant as an int64. So inlining A in this code:
+ //
+ // const N = 5
+ // type A = [N]int
+ //
+ // would result in [5]int, breaking the connection with N.
+ for n := range ast.Preorder(spec.Type) {
+ if ar, ok := n.(*ast.ArrayType); ok && ar.Len != nil {
+ // Make an exception when the array length is a literal int.
+ if lit, ok := ast.Unparen(ar.Len).(*ast.BasicLit); ok && lit.Kind == token.INT {
+ continue
+ }
+ pass.Reportf(spec.Pos(), "invalid //go:fix inline directive: array types not supported")
+ return
+ }
+ }
+ if h != nil {
+ h.HandleAlias(spec)
+ }
+}
+
+func findConst(pass *analysis.Pass, spec *ast.ValueSpec, declInline bool, h Handler) {
+ specInline := hasFixInline(spec.Doc)
+ if declInline || specInline {
+ for i, nameIdent := range spec.Names {
+ if i >= len(spec.Values) {
+ // Possible following an iota.
+ break
+ }
+ var rhsIdent *ast.Ident
+ switch val := spec.Values[i].(type) {
+ case *ast.Ident:
+ // Constants defined with the predeclared iota cannot be inlined.
+ if pass.TypesInfo.Uses[val] == builtinIota {
+ pass.Reportf(val.Pos(), "invalid //go:fix inline directive: const value is iota")
+ return
+ }
+ rhsIdent = val
+ case *ast.SelectorExpr:
+ rhsIdent = val.Sel
+ default:
+ pass.Reportf(val.Pos(), "invalid //go:fix inline directive: const value is not the name of another constant")
+ return
+ }
+ if h != nil {
+ h.HandleConst(nameIdent, rhsIdent)
+ }
+ }
+ }
+}
+
+// hasFixInline reports the presence of a "//go:fix inline" directive
+// in the comments.
+func hasFixInline(cg *ast.CommentGroup) bool {
+ for _, d := range internalastutil.Directives(cg) {
+ if d.Tool == "go" && d.Name == "fix" && d.Args == "inline" {
+ return true
+ }
+ }
+ return false
+}
+
+var builtinIota = types.Universe.Lookup("iota")
diff --git a/vendor/golang.org/x/tools/go/analysis/passes/modernize/any.go b/vendor/golang.org/x/tools/go/analysis/passes/modernize/any.go
index 579ab865d..79e2802c6 100644
--- a/vendor/golang.org/x/tools/go/analysis/passes/modernize/any.go
+++ b/vendor/golang.org/x/tools/go/analysis/passes/modernize/any.go
@@ -18,7 +18,7 @@ var AnyAnalyzer = &analysis.Analyzer{
Doc: analyzerutil.MustExtractDoc(doc, "any"),
Requires: []*analysis.Analyzer{inspect.Analyzer},
Run: runAny,
- URL: "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/modernize#any",
+ URL: "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/modernize#hdr-Analyzer_any",
}
// The any pass replaces interface{} with go1.18's 'any'.
diff --git a/vendor/golang.org/x/tools/go/analysis/passes/modernize/atomictypes.go b/vendor/golang.org/x/tools/go/analysis/passes/modernize/atomictypes.go
index 9df39fb23..6fd618f9a 100644
--- a/vendor/golang.org/x/tools/go/analysis/passes/modernize/atomictypes.go
+++ b/vendor/golang.org/x/tools/go/analysis/passes/modernize/atomictypes.go
@@ -33,7 +33,7 @@ var AtomicTypesAnalyzer = &analysis.Analyzer{
typeindexanalyzer.Analyzer,
},
Run: runAtomic,
- URL: "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/modernize#atomictypes",
+ URL: "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/modernize#hdr-Analyzer_atomictypes",
}
// TODO(mkalil): support the Pointer variants.
diff --git a/vendor/golang.org/x/tools/go/analysis/passes/modernize/bloop.go b/vendor/golang.org/x/tools/go/analysis/passes/modernize/bloop.go
index ad45d7447..d44c85674 100644
--- a/vendor/golang.org/x/tools/go/analysis/passes/modernize/bloop.go
+++ b/vendor/golang.org/x/tools/go/analysis/passes/modernize/bloop.go
@@ -32,7 +32,7 @@ var BLoopAnalyzer = &analysis.Analyzer{
typeindexanalyzer.Analyzer,
},
Run: bloop,
- URL: "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/modernize#bloop",
+ URL: "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/modernize#hdr-Analyzer_bloop",
}
// bloop updates benchmarks that use "for range b.N", replacing it
diff --git a/vendor/golang.org/x/tools/go/analysis/passes/modernize/doc.go b/vendor/golang.org/x/tools/go/analysis/passes/modernize/doc.go
index c5545c0cc..caf3df950 100644
--- a/vendor/golang.org/x/tools/go/analysis/passes/modernize/doc.go
+++ b/vendor/golang.org/x/tools/go/analysis/passes/modernize/doc.go
@@ -15,13 +15,16 @@ causing build breakage. However, these problems are generally
trivial to fix. We regard any modernizer whose fix changes program
behavior to have a serious bug and will endeavor to fix it.
-To apply all modernization fixes en masse, you can use the
+Since Go 1.26, the 'go fix' command has included the modernize suite,
+so to apply all modernization fixes en masse, you can use the
following command:
- $ go run golang.org/x/tools/go/analysis/passes/modernize/cmd/modernize@latest -fix ./...
+ $ go fix ./...
+
+If you need to run a modernizer added or modified since the Go
+release, you can use this standalone command:
-(Do not use "go get -tool" to add gopls as a dependency of your
-module; gopls commands must be built from their release branch.)
+ $ go run golang.org/x/tools/go/analysis/passes/modernize/cmd/modernize@latest -fix ./...
If the tool warns of conflicting fixes, you may need to run it more
than once until it has applied all fixes cleanly. This command is
@@ -344,6 +347,21 @@ No fix is offered in cases when the runtime type is dynamic, such as:
or when the operand has potential side effects.
+# Analyzer reflecttypeassert
+
+reflecttypeassert: replace v.Interface().(T) with reflect.TypeAssert[T](v)
+
+This analyzer suggests fixes to replace two-valued type assertions on
+the result of (reflect.Value).Interface with reflect.TypeAssert,
+introduced in go1.25, which avoids the intermediate allocation of an
+interface value, for example:
+
+ x, ok := v.Interface().(string) -> x, ok := reflect.TypeAssert[string](v)
+
+No fix is offered for single-valued assertions, since they panic when
+the assertion fails whereas reflect.TypeAssert does not. Nor is a fix
+offered for a type switch.
+
# Analyzer slicesbackward
slicesbackward: replace backward loops over slices with slices.Backward
@@ -366,6 +384,22 @@ the index and value variables are kept:
for i, v := range slices.Backward(s) { ... }
+# Analyzer slicesclip
+
+slicesclip: replace three-index slice expressions with slices.Clip
+
+The slicesclip analyzer suggests replacing a full slice expression of
+the form
+
+ x[:len(x):len(x)]
+
+which clips the capacity of a slice to its length, with the simpler
+and more readable
+
+ slices.Clip(x)
+
+added in Go 1.21.
+
# Analyzer slicescontains
slicescontains: replace loops with slices.Contains or slices.ContainsFunc
@@ -422,7 +456,7 @@ or its "for elem := range x.Len()" equivalent by a range loop over an
iterator offered by the same data type:
for elem := range x.All() {
- use(x.At(i)
+ use(elem)
}
where x is one of various well-known types in the standard library.
diff --git a/vendor/golang.org/x/tools/go/analysis/passes/modernize/embedlit.go b/vendor/golang.org/x/tools/go/analysis/passes/modernize/embedlit.go
index d2c71b57a..a30276a02 100644
--- a/vendor/golang.org/x/tools/go/analysis/passes/modernize/embedlit.go
+++ b/vendor/golang.org/x/tools/go/analysis/passes/modernize/embedlit.go
@@ -33,7 +33,7 @@ var EmbedLitAnalyzer = &analysis.Analyzer{
typeindexanalyzer.Analyzer,
},
Run: runEmbedLit,
- URL: "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/modernize#embedlit",
+ URL: "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/modernize#hdr-Analyzer_embedlit",
}
// Go1.27 introduced the ability to directly access embedded struct fields.
@@ -209,15 +209,25 @@ func embedlitCombine(pass *analysis.Pass, index *typeindex.Index, info *types.In
case edge.AssignStmt_Rhs:
assign := curLit.Parent().Node().(*ast.AssignStmt)
// TODO(mkalil): Handle lhs forms that aren't idents, i.e. x.y[i] = T{...}.
- if id, ok := assign.Lhs[curLit.ParentEdgeIndex()].(*ast.Ident); ok {
+ // TODO(mkalil): Handle multi-assignments like t1, t2 := A{}, B{}
+ if len(assign.Lhs) != 1 {
+ return nil
+ }
+ if id, ok := assign.Lhs[0].(*ast.Ident); ok {
lhs = id
curStmt = curLit.Parent()
}
case edge.ValueSpec_Values:
spec := curLit.Parent().Node().(*ast.ValueSpec)
- lhs = spec.Names[curLit.ParentEdgeIndex()]
+ // TODO(mkalil): Handle multi-declarations like var (x = A{}; y = B{}) or var x, y = ...
+ if len(spec.Names) != 1 {
+ return nil
+ }
+ lhs = spec.Names[0]
if decl, ok := moreiters.First(curLit.Enclosing((*ast.DeclStmt)(nil))); ok {
- curStmt = decl
+ if gdecl, ok := decl.Node().(*ast.DeclStmt).Decl.(*ast.GenDecl); ok && len(gdecl.Specs) == 1 {
+ curStmt = decl
+ }
}
default:
return nil
@@ -231,7 +241,8 @@ func embedlitCombine(pass *analysis.Pass, index *typeindex.Index, info *types.In
tObj = info.ObjectOf(lhs)
// Marks the contiguous block of embedded field assign statements that will
// be moved into the struct initialization.
- firstStmt, lastStmt inspector.Cursor
+ firstStmt, lastStmt inspector.Cursor
+ hasEmbeddedSelection bool
)
stmtloop:
for {
@@ -262,6 +273,15 @@ stmtloop:
if obj != tObj {
break
}
+ // The selection is from an embedded field if it directly
+ // assigns an embedded struct field (t.B = B{...}) or if
+ // the length of the index path is greater than one.
+ seln := info.Selections[sel]
+ if v, ok := seln.Obj().(*types.Var); ok && v.Embedded() ||
+ len(seln.Index()) > 1 {
+ hasEmbeddedSelection = true
+ }
+
rhsCur := curStmt.ChildAt(edge.AssignStmt_Rhs, 0)
if uses(index, rhsCur, tObj) {
break
@@ -284,7 +304,8 @@ stmtloop:
lastStmt = curStmt
}
- if !firstStmt.Valid() {
+ if !firstStmt.Valid() || !hasEmbeddedSelection {
+ // We should not suggest a fix if none of the selections are from embedded fields.
return nil
}
diff --git a/vendor/golang.org/x/tools/go/analysis/passes/modernize/errorsastype.go b/vendor/golang.org/x/tools/go/analysis/passes/modernize/errorsastype.go
index 0e3f17fbc..8a3f1c10b 100644
--- a/vendor/golang.org/x/tools/go/analysis/passes/modernize/errorsastype.go
+++ b/vendor/golang.org/x/tools/go/analysis/passes/modernize/errorsastype.go
@@ -27,7 +27,7 @@ import (
var ErrorsAsTypeAnalyzer = &analysis.Analyzer{
Name: "errorsastype",
Doc: analyzerutil.MustExtractDoc(doc, "errorsastype"),
- URL: "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/modernize#errorsastype",
+ URL: "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/modernize#hdr-Analyzer_errorsastype",
Requires: []*analysis.Analyzer{typeindexanalyzer.Analyzer},
Run: errorsastype,
}
@@ -228,6 +228,9 @@ func canUseErrorsAsType(info *types.Info, index *typeindex.Index, curCall inspec
len(curDecl.Node().(*ast.GenDecl).Specs) != 1 {
return // not a simple "var v T" decl
}
+ if curDecl.ParentEdgeKind() != edge.DeclStmt_Decl {
+ return // package-level var, not a local declaration statement
+ }
// AsType requires that its type argument implements error.
// Reject if v does not implement error.
if !types.AssignableTo(v.Type(), errorType) {
@@ -239,5 +242,5 @@ func canUseErrorsAsType(info *types.Info, index *typeindex.Index, curCall inspec
// ...
// if errors.As(err, &v) { ... }
// with no uses of v outside the IfStmt.
- return v, curDecl.Parent(), curIfStmt // curDecl.Parent() is a DeclStmt
+ return v, curDecl.Parent(), curIfStmt
}
diff --git a/vendor/golang.org/x/tools/go/analysis/passes/modernize/fmtappendf.go b/vendor/golang.org/x/tools/go/analysis/passes/modernize/fmtappendf.go
index 821065413..d67b6ad14 100644
--- a/vendor/golang.org/x/tools/go/analysis/passes/modernize/fmtappendf.go
+++ b/vendor/golang.org/x/tools/go/analysis/passes/modernize/fmtappendf.go
@@ -30,7 +30,7 @@ var FmtAppendfAnalyzer = &analysis.Analyzer{
typeindexanalyzer.Analyzer,
},
Run: fmtappendf,
- URL: "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/modernize#fmtappendf",
+ URL: "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/modernize#hdr-Analyzer_fmtappendf",
}
// The fmtappend function replaces []byte(fmt.Sprintf(...)) by
diff --git a/vendor/golang.org/x/tools/go/analysis/passes/modernize/forvar.go b/vendor/golang.org/x/tools/go/analysis/passes/modernize/forvar.go
index ba54daebb..d79f1f9f7 100644
--- a/vendor/golang.org/x/tools/go/analysis/passes/modernize/forvar.go
+++ b/vendor/golang.org/x/tools/go/analysis/passes/modernize/forvar.go
@@ -21,7 +21,7 @@ var ForVarAnalyzer = &analysis.Analyzer{
Doc: analyzerutil.MustExtractDoc(doc, "forvar"),
Requires: []*analysis.Analyzer{inspect.Analyzer},
Run: forvar,
- URL: "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/modernize#forvar",
+ URL: "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/modernize#hdr-Analyzer_forvar",
}
// forvar offers to fix unnecessary copying of a for variable
diff --git a/vendor/golang.org/x/tools/go/analysis/passes/modernize/importcomment.go b/vendor/golang.org/x/tools/go/analysis/passes/modernize/importcomment.go
index 15387835e..de0f68796 100644
--- a/vendor/golang.org/x/tools/go/analysis/passes/modernize/importcomment.go
+++ b/vendor/golang.org/x/tools/go/analysis/passes/modernize/importcomment.go
@@ -14,7 +14,7 @@ import (
var importCommentAnalyzer = &analysis.Analyzer{
Name: "importcomment",
Doc: analyzerutil.MustExtractDoc(doc, "importcomment"),
- URL: "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/modernize#importcomment",
+ URL: "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/modernize#hdr-Analyzer_importcomment",
Run: importcomment,
}
diff --git a/vendor/golang.org/x/tools/go/analysis/passes/modernize/maps.go b/vendor/golang.org/x/tools/go/analysis/passes/modernize/maps.go
index 7f3fd4e6f..38d0f2323 100644
--- a/vendor/golang.org/x/tools/go/analysis/passes/modernize/maps.go
+++ b/vendor/golang.org/x/tools/go/analysis/passes/modernize/maps.go
@@ -28,7 +28,7 @@ var MapsLoopAnalyzer = &analysis.Analyzer{
Doc: analyzerutil.MustExtractDoc(doc, "mapsloop"),
Requires: []*analysis.Analyzer{inspect.Analyzer},
Run: mapsloop,
- URL: "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/modernize#mapsloop",
+ URL: "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/modernize#hdr-Analyzer_mapsloop",
}
// The mapsloop pass offers to simplify a loop of map insertions:
diff --git a/vendor/golang.org/x/tools/go/analysis/passes/modernize/minmax.go b/vendor/golang.org/x/tools/go/analysis/passes/modernize/minmax.go
index 9fd865758..928fcf588 100644
--- a/vendor/golang.org/x/tools/go/analysis/passes/modernize/minmax.go
+++ b/vendor/golang.org/x/tools/go/analysis/passes/modernize/minmax.go
@@ -32,7 +32,7 @@ var MinMaxAnalyzer = &analysis.Analyzer{
typeindexanalyzer.Analyzer,
},
Run: minmax,
- URL: "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/modernize#minmax",
+ URL: "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/modernize#hdr-Analyzer_minmax",
}
// The minmax pass replaces if/else statements with calls to min or max,
@@ -451,18 +451,3 @@ func checkMinMaxPattern(ifStmt *ast.IfStmt, falseResult ast.Expr, funcName, para
// Check if the sign matches the function name
return cond(sign < 0, "min", "max") == funcName
}
-
-// -- utils --
-
-func is[T any](x any) bool {
- _, ok := x.(T)
- return ok
-}
-
-func cond[T any](cond bool, t, f T) T {
- if cond {
- return t
- } else {
- return f
- }
-}
diff --git a/vendor/golang.org/x/tools/go/analysis/passes/modernize/modernize.go b/vendor/golang.org/x/tools/go/analysis/passes/modernize/modernize.go
index 23dd8ab50..9e950d7c4 100644
--- a/vendor/golang.org/x/tools/go/analysis/passes/modernize/modernize.go
+++ b/vendor/golang.org/x/tools/go/analysis/passes/modernize/modernize.go
@@ -45,8 +45,10 @@ var Suite = []*analysis.Analyzer{
OmitZeroAnalyzer,
PlusBuildAnalyzer,
RangeIntAnalyzer,
+ reflectTypeAssertAnalyzer, // awaiting public symbol
ReflectTypeForAnalyzer,
slicesBackwardAnalyzer, // awaiting public symbol
+ slicesClipAnalyzer, // awaiting public symbol
SlicesContainsAnalyzer,
SlicesSortAnalyzer,
StdIteratorsAnalyzer,
@@ -122,7 +124,7 @@ func filesUsingGoVersion(pass *analysis.Pass, version string) iter.Seq[inspector
// specified standard packages or their dependencies.
func within(pass *analysis.Pass, pkgs ...string) bool {
path := pass.Pkg.Path()
- return packagepath.IsStdPackage(path) &&
+ return packagepath.MaybeStdPackage(path) &&
moreiters.Contains(stdlib.Dependencies(pkgs...), path)
}
@@ -136,6 +138,7 @@ var (
builtinMake = types.Universe.Lookup("make")
builtinNew = types.Universe.Lookup("new")
builtinNil = types.Universe.Lookup("nil")
+ builtinRecover = types.Universe.Lookup("recover")
builtinString = types.Universe.Lookup("string")
builtinTrue = types.Universe.Lookup("true")
byteSliceType = types.NewSlice(types.Typ[types.Byte])
@@ -185,3 +188,16 @@ func isLocal(obj types.Object) bool {
}
return depth >= 4
}
+
+func is[T any](x any) bool {
+ _, ok := x.(T)
+ return ok
+}
+
+func cond[T any](cond bool, t, f T) T {
+ if cond {
+ return t
+ } else {
+ return f
+ }
+}
diff --git a/vendor/golang.org/x/tools/go/analysis/passes/modernize/newexpr.go b/vendor/golang.org/x/tools/go/analysis/passes/modernize/newexpr.go
index 15d52d12d..168c09fde 100644
--- a/vendor/golang.org/x/tools/go/analysis/passes/modernize/newexpr.go
+++ b/vendor/golang.org/x/tools/go/analysis/passes/modernize/newexpr.go
@@ -24,7 +24,7 @@ import (
var NewExprAnalyzer = &analysis.Analyzer{
Name: "newexpr",
Doc: analyzerutil.MustExtractDoc(doc, "newexpr"),
- URL: "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/modernize#newexpr",
+ URL: "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/modernize#hdr-Analyzer_newexpr",
Requires: []*analysis.Analyzer{inspect.Analyzer},
Run: run,
FactTypes: []analysis.Fact{&newLike{}},
diff --git a/vendor/golang.org/x/tools/go/analysis/passes/modernize/omitzero.go b/vendor/golang.org/x/tools/go/analysis/passes/modernize/omitzero.go
index 59ba95065..4d93f7f47 100644
--- a/vendor/golang.org/x/tools/go/analysis/passes/modernize/omitzero.go
+++ b/vendor/golang.org/x/tools/go/analysis/passes/modernize/omitzero.go
@@ -24,7 +24,7 @@ var OmitZeroAnalyzer = &analysis.Analyzer{
Doc: analyzerutil.MustExtractDoc(doc, "omitzero"),
Requires: []*analysis.Analyzer{inspect.Analyzer},
Run: omitzero,
- URL: "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/modernize#omitzero",
+ URL: "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/modernize#hdr-Analyzer_omitzero",
}
// The omitzero pass searches for instances of "omitempty" in a json field tag on a
diff --git a/vendor/golang.org/x/tools/go/analysis/passes/modernize/plusbuild.go b/vendor/golang.org/x/tools/go/analysis/passes/modernize/plusbuild.go
index 574ce0a89..09877f892 100644
--- a/vendor/golang.org/x/tools/go/analysis/passes/modernize/plusbuild.go
+++ b/vendor/golang.org/x/tools/go/analysis/passes/modernize/plusbuild.go
@@ -17,7 +17,7 @@ import (
var PlusBuildAnalyzer = &analysis.Analyzer{
Name: "plusbuild",
Doc: analyzerutil.MustExtractDoc(doc, "plusbuild"),
- URL: "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/modernize#plusbuild",
+ URL: "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/modernize#hdr-Analyzer_plusbuild",
Run: plusbuild,
}
diff --git a/vendor/golang.org/x/tools/go/analysis/passes/modernize/rangeint.go b/vendor/golang.org/x/tools/go/analysis/passes/modernize/rangeint.go
index f7cb965f3..9cd766334 100644
--- a/vendor/golang.org/x/tools/go/analysis/passes/modernize/rangeint.go
+++ b/vendor/golang.org/x/tools/go/analysis/passes/modernize/rangeint.go
@@ -13,8 +13,6 @@ import (
"golang.org/x/tools/go/analysis"
"golang.org/x/tools/go/analysis/passes/inspect"
- "golang.org/x/tools/go/ast/edge"
- "golang.org/x/tools/go/ast/inspector"
"golang.org/x/tools/go/types/typeutil"
"golang.org/x/tools/internal/analysis/analyzerutil"
typeindexanalyzer "golang.org/x/tools/internal/analysis/typeindex"
@@ -33,7 +31,7 @@ var RangeIntAnalyzer = &analysis.Analyzer{
typeindexanalyzer.Analyzer,
},
Run: rangeint,
- URL: "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/modernize#rangeint",
+ URL: "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/modernize#hdr-Analyzer_rangeint",
}
// rangeint offers a fix to replace a 3-clause 'for' loop:
@@ -112,7 +110,7 @@ func rangeint(pass *analysis.Pass) (any, error) {
// limit is a local or unexported global var.
// (An exported global may have uses we can't see.)
for cur := range typeindex.Uses(v) {
- if isScalarLvalue(info, cur) {
+ if typesinternal.IsAssignedOrAddressTaken(info, cur) {
// Limit var is assigned or address-taken.
continue nextLoop
}
@@ -161,7 +159,7 @@ func rangeint(pass *analysis.Pass) (any, error) {
// Reject if any is an l-value (assigned or address-taken):
// a "for range int" loop does not respect assignments to
// the loop variable.
- if isScalarLvalue(info, curId) {
+ if typesinternal.IsAssignedOrAddressTaken(info, curId) {
continue nextLoop
}
}
@@ -345,40 +343,3 @@ func rangeint(pass *analysis.Pass) (any, error) {
}
return nil, nil
}
-
-// isScalarLvalue reports whether the specified identifier is
-// address-taken or appears on the left side of an assignment.
-//
-// This function is valid only for scalars (x = ...),
-// not for aggregates (x.a[i] = ...)
-func isScalarLvalue(info *types.Info, curId inspector.Cursor) bool {
- // Unfortunately we can't simply use info.Types[e].Assignable()
- // as it is always true for a variable even when that variable is
- // used only as an r-value. So we must inspect enclosing syntax.
-
- cur := astutil.UnparenEnclosingCursor(curId)
-
- switch cur.ParentEdgeKind() {
- case edge.AssignStmt_Lhs:
- assign := cur.Parent().Node().(*ast.AssignStmt)
- if assign.Tok != token.DEFINE {
- return true // i = j or i += j
- }
- id := curId.Node().(*ast.Ident)
- if v, ok := info.Defs[id]; ok && v.Pos() != id.Pos() {
- return true // reassignment of i (i, j := 1, 2)
- }
- case edge.RangeStmt_Key:
- rng := cur.Parent().Node().(*ast.RangeStmt)
- if rng.Tok == token.ASSIGN {
- return true // "for k, v = range x" is like an AssignStmt to k, v
- }
- case edge.IncDecStmt_X:
- return true // i++, i--
- case edge.UnaryExpr_X:
- if cur.Parent().Node().(*ast.UnaryExpr).Op == token.AND {
- return true // &i
- }
- }
- return false
-}
diff --git a/vendor/golang.org/x/tools/go/analysis/passes/modernize/reflect.go b/vendor/golang.org/x/tools/go/analysis/passes/modernize/reflect.go
index 10fbdf8b4..14446a13f 100644
--- a/vendor/golang.org/x/tools/go/analysis/passes/modernize/reflect.go
+++ b/vendor/golang.org/x/tools/go/analysis/passes/modernize/reflect.go
@@ -30,7 +30,7 @@ var ReflectTypeForAnalyzer = &analysis.Analyzer{
typeindexanalyzer.Analyzer,
},
Run: reflecttypefor,
- URL: "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/modernize#reflecttypefor",
+ URL: "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/modernize#hdr-Analyzer_reflecttypefor",
}
func reflecttypefor(pass *analysis.Pass) (any, error) {
diff --git a/vendor/golang.org/x/tools/go/analysis/passes/modernize/reflecttypeassert.go b/vendor/golang.org/x/tools/go/analysis/passes/modernize/reflecttypeassert.go
new file mode 100644
index 000000000..ff41e43a6
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/analysis/passes/modernize/reflecttypeassert.go
@@ -0,0 +1,118 @@
+// Copyright 2026 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 modernize
+
+import (
+ "go/ast"
+ "go/token"
+
+ "golang.org/x/tools/go/analysis"
+ "golang.org/x/tools/go/analysis/passes/inspect"
+ "golang.org/x/tools/go/ast/edge"
+ "golang.org/x/tools/internal/analysis/analyzerutil"
+ typeindexanalyzer "golang.org/x/tools/internal/analysis/typeindex"
+ "golang.org/x/tools/internal/astutil"
+ "golang.org/x/tools/internal/refactor"
+ "golang.org/x/tools/internal/typesinternal"
+ "golang.org/x/tools/internal/typesinternal/typeindex"
+ "golang.org/x/tools/internal/versions"
+)
+
+var reflectTypeAssertAnalyzer = &analysis.Analyzer{
+ Name: "reflecttypeassert",
+ Doc: analyzerutil.MustExtractDoc(doc, "reflecttypeassert"),
+ Requires: []*analysis.Analyzer{
+ inspect.Analyzer,
+ typeindexanalyzer.Analyzer,
+ },
+ Run: reflecttypeassert,
+ URL: "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/modernize#hdr-Analyzer_reflecttypeassert",
+}
+
+func reflecttypeassert(pass *analysis.Pass) (any, error) {
+ var (
+ index = pass.ResultOf[typeindexanalyzer.Analyzer].(*typeindex.Index)
+ info = pass.TypesInfo
+
+ valueInterface = index.Selection("reflect", "Value", "Interface")
+ )
+
+ for curCall := range index.Calls(valueInterface) {
+ call := curCall.Node().(*ast.CallExpr)
+ // Have: v.Interface()
+
+ sel, ok := call.Fun.(*ast.SelectorExpr)
+ if !ok {
+ continue // method expression reflect.Value.Interface(v)
+ }
+
+ // TypeAssert's argument must be a reflect.Value; a pointer
+ // receiver would need an explicit dereference in the rewrite.
+ if !typesinternal.IsTypeNamed(info.TypeOf(sel.X), "reflect", "Value") {
+ continue
+ }
+
+ // The call must be the operand of a type assertion
+ // (not a type switch, whose Type field is nil).
+ curOperand := astutil.UnparenEnclosingCursor(curCall)
+ if curOperand.ParentEdgeKind() != edge.TypeAssertExpr_X {
+ continue
+ }
+ curAssert := curOperand.Parent()
+ assert := curAssert.Node().(*ast.TypeAssertExpr)
+ if assert.Type == nil {
+ continue // type switch
+ }
+
+ // The assertion must be the sole RHS of a two-valued
+ // assignment, x, ok := v.Interface().(T), so that the
+ // rewrite preserves the "commaOK" semantics; a single-valued
+ // assertion panics on failure whereas TypeAssert does not.
+ curRhs := astutil.UnparenEnclosingCursor(curAssert)
+ if curRhs.ParentEdgeKind() != edge.AssignStmt_Rhs {
+ continue
+ }
+ assign := curRhs.Parent().Node().(*ast.AssignStmt)
+ if len(assign.Lhs) != 2 || len(assign.Rhs) != 1 ||
+ (assign.Tok != token.ASSIGN && assign.Tok != token.DEFINE) {
+ continue
+ }
+
+ file := astutil.EnclosingFile(curCall)
+ if !analyzerutil.FileUsesGoVersion(pass, file, versions.Go1_25) {
+ continue // TypeAssert requires go1.25
+ }
+
+ prefix, importEdits := refactor.AddImport(info, file, "reflect", "reflect", "TypeAssert", assert.Pos())
+
+ tstr := astutil.Format(pass.Fset, assert.Type)
+ pass.Report(analysis.Diagnostic{
+ Pos: assert.Pos(),
+ End: assert.End(),
+ Message: "Interface().(" + tstr + ") can be simplified using reflect.TypeAssert",
+ SuggestedFixes: []analysis.SuggestedFix{{
+ // v.Interface().(T) -> reflect.TypeAssert[T](v)
+ Message: "Replace Interface().(" + tstr + ") by reflect.TypeAssert[" + tstr + "]",
+ // Edit around sel.X instead of reformatting it, so its
+ // comments and spacing are preserved; only the type,
+ // which must move, is reformatted.
+ TextEdits: append(importEdits,
+ analysis.TextEdit{
+ Pos: assert.Pos(),
+ End: sel.X.Pos(),
+ NewText: []byte(prefix + "TypeAssert[" + tstr + "]("),
+ },
+ analysis.TextEdit{
+ Pos: sel.X.End(),
+ End: assert.End(),
+ NewText: []byte(")"),
+ },
+ ),
+ }},
+ })
+ }
+
+ return nil, nil
+}
diff --git a/vendor/golang.org/x/tools/go/analysis/passes/modernize/slices.go b/vendor/golang.org/x/tools/go/analysis/passes/modernize/slices.go
index 6c8ea22b3..4fb40a893 100644
--- a/vendor/golang.org/x/tools/go/analysis/passes/modernize/slices.go
+++ b/vendor/golang.org/x/tools/go/analysis/passes/modernize/slices.go
@@ -27,7 +27,7 @@ var AppendClippedAnalyzer = &analysis.Analyzer{
Doc: analyzerutil.MustExtractDoc(doc, "appendclipped"),
Requires: []*analysis.Analyzer{inspect.Analyzer},
Run: appendclipped,
- URL: "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/modernize#appendclipped",
+ URL: "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/modernize#hdr-Analyzer_appendclipped",
}
// The appendclipped pass offers to simplify a tower of append calls:
diff --git a/vendor/golang.org/x/tools/go/analysis/passes/modernize/slicesbackward.go b/vendor/golang.org/x/tools/go/analysis/passes/modernize/slicesbackward.go
index 02cd30a25..c65a6c7ea 100644
--- a/vendor/golang.org/x/tools/go/analysis/passes/modernize/slicesbackward.go
+++ b/vendor/golang.org/x/tools/go/analysis/passes/modernize/slicesbackward.go
@@ -19,6 +19,7 @@ import (
typeindexanalyzer "golang.org/x/tools/internal/analysis/typeindex"
"golang.org/x/tools/internal/astutil"
"golang.org/x/tools/internal/refactor"
+ "golang.org/x/tools/internal/typesinternal"
"golang.org/x/tools/internal/typesinternal/typeindex"
"golang.org/x/tools/internal/versions"
)
@@ -32,7 +33,7 @@ var slicesBackwardAnalyzer = &analysis.Analyzer{
typeindexanalyzer.Analyzer,
},
Run: slicesbackward,
- URL: "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/modernize#slicesbackward",
+ URL: "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/modernize#hdr-Analyzer_slicesbackward",
}
// slicesbackward offers a fix to replace a manually-written backward loop:
@@ -128,7 +129,7 @@ func slicesbackward(pass *analysis.Pass) (any, error) {
// (e.g. &i before the loop).
bodyCur := curLoop.Child(loop.Body)
for curUse := range index.Uses(indexObj) {
- if !isScalarLvalue(info, curUse) {
+ if !typesinternal.IsAssignedOrAddressTaken(info, curUse) {
continue
}
if bodyCur.Contains(curUse) {
@@ -160,20 +161,25 @@ func slicesbackward(pass *analysis.Pass) (any, error) {
// If so, we also need to check whether s[i] is an lvalue. If we're
// mutating the slice or taking an element's address, a fix will not
// be offered.
+ // Modernization to "for _, v := range slices.Backward(s)" is unsafe if
+ // s[i] is mutated or address-taken (since v would be a local copy of
+ // the element so s[i] wouldn't get mutated).
+ // We don't need to worry about indirect selections (e.g. s[i].n++ where
+ // s is []*item) or indirect references like indexing a slice of slices.
if curUse.ParentEdgeKind() == edge.IndexExpr_Index {
- if isScalarLvalue(pass.TypesInfo, curUse.Parent()) {
+ curIdx := curUse.Parent()
+ if typesinternal.IsAssignedOrAddressTaken(info, curIdx) {
continue nextLoop
}
- idxCur := curUse.Parent()
- idxExpr := idxCur.Node().(*ast.IndexExpr)
+ idxExpr := curIdx.Node().(*ast.IndexExpr)
if astutil.EqualSyntax(idxExpr.X, sliceExpr) {
sliceIdxs++
// If the current statement is the first in the body of the form
// "name := s[i]", save it so we can use "name" as the value
// variable in slices.Backward. We can also remove the entire assign
// statement.
- if firstSliceIdxAssign == nil && idxCur.ParentEdgeKind() == edge.AssignStmt_Rhs {
- assignStmt := idxCur.Parent().Node().(*ast.AssignStmt)
+ if firstSliceIdxAssign == nil && curIdx.ParentEdgeKind() == edge.AssignStmt_Rhs {
+ assignStmt := curIdx.Parent().Node().(*ast.AssignStmt)
if len(assignStmt.Lhs) == 1 && assignStmt.Tok == token.DEFINE {
// The condition above implies that assignStmt.Lhs[0] is a valid
// identifier.
diff --git a/vendor/golang.org/x/tools/go/analysis/passes/modernize/slicesclip.go b/vendor/golang.org/x/tools/go/analysis/passes/modernize/slicesclip.go
new file mode 100644
index 000000000..b08cbc697
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/analysis/passes/modernize/slicesclip.go
@@ -0,0 +1,81 @@
+// Copyright 2026 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 modernize
+
+import (
+ "fmt"
+ "go/ast"
+ "go/types"
+
+ "golang.org/x/tools/go/analysis"
+ "golang.org/x/tools/go/analysis/passes/inspect"
+ "golang.org/x/tools/go/types/typeutil"
+ "golang.org/x/tools/internal/analysis/analyzerutil"
+ "golang.org/x/tools/internal/astutil"
+ "golang.org/x/tools/internal/refactor"
+ "golang.org/x/tools/internal/typesinternal"
+ "golang.org/x/tools/internal/versions"
+)
+
+var slicesClipAnalyzer = &analysis.Analyzer{
+ Name: "slicesclip",
+ Doc: analyzerutil.MustExtractDoc(doc, "slicesclip"),
+ Requires: []*analysis.Analyzer{
+ inspect.Analyzer,
+ },
+ Run: slicesclip,
+ URL: "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/modernize#hdr-Analyzer_slicesclip",
+}
+
+func slicesclip(pass *analysis.Pass) (any, error) {
+ if within(pass, "slices", "runtime") {
+ return nil, nil
+ }
+ info := pass.TypesInfo
+
+ // isLenX reports whether e is a call len(x) where x is
+ // syntactically identical to the operand x of the slice expr.
+ isLenX := func(e, x ast.Expr) bool {
+ call, ok := e.(*ast.CallExpr)
+ if !ok || len(call.Args) != 1 {
+ return false
+ }
+ return typeutil.Callee(info, call) == builtinLen &&
+ astutil.EqualSyntax(call.Args[0], x)
+ }
+
+ for curFile := range filesUsingGoVersion(pass, versions.Go1_21) {
+ file := curFile.Node().(*ast.File)
+
+ for curSlice := range curFile.Preorder((*ast.SliceExpr)(nil)) {
+ slice := curSlice.Node().(*ast.SliceExpr)
+ _, ok := info.TypeOf(slice.X).Underlying().(*types.Slice) // in case x is an array/pointer to array
+ if !slice.Slice3 || slice.Low != nil || !ok {
+ continue
+ }
+
+ if isLenX(slice.High, slice.X) && isLenX(slice.Max, slice.X) && typesinternal.NoEffects(info, slice.X) {
+ // Have x[:len(x):len(x)] -> slices.Clip(x)
+ prefix, edits := refactor.AddImport(info, file, "slices", "slices", "Clip", slice.Pos())
+ sx := astutil.Format(pass.Fset, slice.X)
+ pass.Report(analysis.Diagnostic{
+ Pos: slice.Pos(),
+ End: slice.End(),
+ Message: "x[:len(x):len(x)] can be simplified using slices.Clip",
+ SuggestedFixes: []analysis.SuggestedFix{{
+ Message: fmt.Sprintf("Replace with slices.Clip(%s)", sx),
+ TextEdits: append(edits, analysis.TextEdit{
+ Pos: slice.Pos(),
+ End: slice.End(),
+ NewText: fmt.Appendf(nil, "%sClip(%s)", prefix, sx),
+ }),
+ }},
+ })
+ }
+ }
+ }
+
+ return nil, nil
+}
diff --git a/vendor/golang.org/x/tools/go/analysis/passes/modernize/slicescontains.go b/vendor/golang.org/x/tools/go/analysis/passes/modernize/slicescontains.go
index ed75e05e9..b27be6fc2 100644
--- a/vendor/golang.org/x/tools/go/analysis/passes/modernize/slicescontains.go
+++ b/vendor/golang.org/x/tools/go/analysis/passes/modernize/slicescontains.go
@@ -32,7 +32,7 @@ var SlicesContainsAnalyzer = &analysis.Analyzer{
typeindexanalyzer.Analyzer,
},
Run: slicescontains,
- URL: "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/modernize#slicescontains",
+ URL: "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/modernize#hdr-Analyzer_slicescontains",
}
// The slicescontains pass identifies loops that can be replaced by a
diff --git a/vendor/golang.org/x/tools/go/analysis/passes/modernize/slicesdelete.go b/vendor/golang.org/x/tools/go/analysis/passes/modernize/slicesdelete.go
index 7b3aa875c..c623aede1 100644
--- a/vendor/golang.org/x/tools/go/analysis/passes/modernize/slicesdelete.go
+++ b/vendor/golang.org/x/tools/go/analysis/passes/modernize/slicesdelete.go
@@ -25,7 +25,7 @@ var SlicesDeleteAnalyzer = &analysis.Analyzer{
Doc: analyzerutil.MustExtractDoc(doc, "slicesdelete"),
Requires: []*analysis.Analyzer{inspect.Analyzer},
Run: slicesdelete,
- URL: "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/modernize#slicesdelete",
+ URL: "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/modernize#hdr-Analyzer_slicesdelete",
}
// The slicesdelete pass attempts to replace instances of append(s[:i], s[i+k:]...)
diff --git a/vendor/golang.org/x/tools/go/analysis/passes/modernize/sortslice.go b/vendor/golang.org/x/tools/go/analysis/passes/modernize/sortslice.go
index e22b8c55f..08d866767 100644
--- a/vendor/golang.org/x/tools/go/analysis/passes/modernize/sortslice.go
+++ b/vendor/golang.org/x/tools/go/analysis/passes/modernize/sortslice.go
@@ -28,7 +28,7 @@ var SlicesSortAnalyzer = &analysis.Analyzer{
typeindexanalyzer.Analyzer,
},
Run: slicessort,
- URL: "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/modernize#slicessort",
+ URL: "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/modernize#hdr-Analyzer_slicessort",
}
// The slicessort pass replaces sort.Slice(slice, less) with
diff --git a/vendor/golang.org/x/tools/go/analysis/passes/modernize/stditerators.go b/vendor/golang.org/x/tools/go/analysis/passes/modernize/stditerators.go
index 195326863..25208863d 100644
--- a/vendor/golang.org/x/tools/go/analysis/passes/modernize/stditerators.go
+++ b/vendor/golang.org/x/tools/go/analysis/passes/modernize/stditerators.go
@@ -28,7 +28,7 @@ var StdIteratorsAnalyzer = &analysis.Analyzer{
typeindexanalyzer.Analyzer,
},
Run: stditerators,
- URL: "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/modernize#stditerators",
+ URL: "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/modernize#hdr-Analyzer_stditerators",
}
// stditeratorsTable records std types that have legacy T.{Len,At}
diff --git a/vendor/golang.org/x/tools/go/analysis/passes/modernize/stringsbuilder.go b/vendor/golang.org/x/tools/go/analysis/passes/modernize/stringsbuilder.go
index 6aa9c881a..ca1cc1490 100644
--- a/vendor/golang.org/x/tools/go/analysis/passes/modernize/stringsbuilder.go
+++ b/vendor/golang.org/x/tools/go/analysis/passes/modernize/stringsbuilder.go
@@ -34,7 +34,7 @@ var StringsBuilderAnalyzer = &analysis.Analyzer{
typeindexanalyzer.Analyzer,
},
Run: stringsbuilder,
- URL: "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/modernize#stringbuilder",
+ URL: "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/modernize#hdr-Analyzer_stringsbuilder",
}
// stringsbuilder replaces string += string in a loop by strings.Builder.
diff --git a/vendor/golang.org/x/tools/go/analysis/passes/modernize/stringscut.go b/vendor/golang.org/x/tools/go/analysis/passes/modernize/stringscut.go
index ae93d4d3f..daa6a6781 100644
--- a/vendor/golang.org/x/tools/go/analysis/passes/modernize/stringscut.go
+++ b/vendor/golang.org/x/tools/go/analysis/passes/modernize/stringscut.go
@@ -35,7 +35,7 @@ var StringsCutAnalyzer = &analysis.Analyzer{
typeindexanalyzer.Analyzer,
},
Run: stringscut,
- URL: "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/modernize#stringscut",
+ URL: "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/modernize#hdr-Analyzer_stringscut",
}
// stringscut offers a fix to replace an occurrence of strings.Index{,Byte} with
@@ -513,9 +513,12 @@ func indexArgValid(info *types.Info, index *typeindex.Index, expr ast.Expr, afte
info.Types[expr.Fun].IsType() && // make sure this isn't a function that returns a byte slice
indexArgValid(info, index, expr.Args[0], afterPos) // check s in []byte(s)
case *ast.Ident:
- sObj := info.Uses[expr]
- sUses := index.Uses(sObj)
- return !hasModifyingUses(sUses, afterPos)
+ for use := range index.Uses(info.Uses[expr]) {
+ if typesinternal.IsAssignedOrAddressTaken(info, use) {
+ return false
+ }
+ }
+ return true
default:
// For now, skip instances where s or substr are not
// identifiers, basic lits, or call expressions of the form
@@ -612,30 +615,6 @@ func checkIdxUses(info *types.Info, uses iter.Seq[inspector.Cursor], s, substr a
return negative, nonnegative, beforeSlice, afterSlice
}
-// hasModifyingUses reports whether any of the uses involve potential
-// modifications. Uses involving assignments before the "afterPos" won't be
-// considered.
-func hasModifyingUses(uses iter.Seq[inspector.Cursor], afterPos token.Pos) bool {
- for curUse := range uses {
- ek := curUse.ParentEdgeKind()
- if ek == edge.AssignStmt_Lhs {
- if curUse.Node().Pos() <= afterPos {
- continue
- }
- // Any use on the LHS is a modifying use.
- return true
- } else if ek == edge.UnaryExpr_X &&
- curUse.Parent().Node().(*ast.UnaryExpr).Op == token.AND {
- // Modifying use because we might be passing the object by reference (an explicit &).
- // We can ignore the case where we have a method call on the expression (which
- // has an implicit &) because we know the type of s and substr are strings
- // which cannot have methods on them.
- return true
- }
- }
- return false
-}
-
// checkIdxComparison reports whether the check is equivalent to i < 0 or its negation, or neither.
// For equivalent to i >= 0, we only accept this exact BinaryExpr since
// expressions like i > 0 or i >= 1 make a stronger statement about the value of i.
diff --git a/vendor/golang.org/x/tools/go/analysis/passes/modernize/stringscutprefix.go b/vendor/golang.org/x/tools/go/analysis/passes/modernize/stringscutprefix.go
index 11d335909..6e285456a 100644
--- a/vendor/golang.org/x/tools/go/analysis/passes/modernize/stringscutprefix.go
+++ b/vendor/golang.org/x/tools/go/analysis/passes/modernize/stringscutprefix.go
@@ -31,7 +31,7 @@ var StringsCutPrefixAnalyzer = &analysis.Analyzer{
typeindexanalyzer.Analyzer,
},
Run: stringscutprefix,
- URL: "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/modernize#stringscutprefix",
+ URL: "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/modernize#hdr-Analyzer_stringscutprefix",
}
// stringscutprefix offers a fix to replace an if statement which
diff --git a/vendor/golang.org/x/tools/go/analysis/passes/modernize/stringsseq.go b/vendor/golang.org/x/tools/go/analysis/passes/modernize/stringsseq.go
index d02a53230..064444dc0 100644
--- a/vendor/golang.org/x/tools/go/analysis/passes/modernize/stringsseq.go
+++ b/vendor/golang.org/x/tools/go/analysis/passes/modernize/stringsseq.go
@@ -28,7 +28,7 @@ var StringsSeqAnalyzer = &analysis.Analyzer{
typeindexanalyzer.Analyzer,
},
Run: stringsseq,
- URL: "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/modernize#stringsseq",
+ URL: "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/modernize#hdr-Analyzer_stringsseq",
}
// stringsseq offers a fix to replace a call to strings.Split with
@@ -117,6 +117,8 @@ func stringsseq(pass *analysis.Pass) (any, error) {
}
switch obj := typeutil.Callee(info, call); obj {
+ case nil:
+ // a conversion, not a call
case stringsSplit, stringsFields, bytesSplit, bytesFields:
oldFnName := obj.Name()
seqFnName := fmt.Sprintf("%sSeq", oldFnName)
diff --git a/vendor/golang.org/x/tools/go/analysis/passes/modernize/testingcontext.go b/vendor/golang.org/x/tools/go/analysis/passes/modernize/testingcontext.go
index 939330521..da7236470 100644
--- a/vendor/golang.org/x/tools/go/analysis/passes/modernize/testingcontext.go
+++ b/vendor/golang.org/x/tools/go/analysis/passes/modernize/testingcontext.go
@@ -33,7 +33,7 @@ var TestingContextAnalyzer = &analysis.Analyzer{
typeindexanalyzer.Analyzer,
},
Run: testingContext,
- URL: "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/modernize#testingcontext",
+ URL: "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/modernize#hdr-Analyzer_testingcontext",
}
// The testingContext pass replaces calls to context.WithCancel from within
diff --git a/vendor/golang.org/x/tools/go/analysis/passes/modernize/unsafefuncs.go b/vendor/golang.org/x/tools/go/analysis/passes/modernize/unsafefuncs.go
index 34c135ca6..08198c9b3 100644
--- a/vendor/golang.org/x/tools/go/analysis/passes/modernize/unsafefuncs.go
+++ b/vendor/golang.org/x/tools/go/analysis/passes/modernize/unsafefuncs.go
@@ -34,7 +34,7 @@ var unsafeFuncsAnalyzer = &analysis.Analyzer{
Doc: analyzerutil.MustExtractDoc(doc, "unsafefuncs"),
Requires: []*analysis.Analyzer{inspect.Analyzer},
Run: unsafefuncs,
- URL: "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/modernize#unsafefuncs",
+ URL: "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/modernize#hdr-Analyzer_unsafefuncs",
}
func unsafefuncs(pass *analysis.Pass) (any, error) {
diff --git a/vendor/golang.org/x/tools/go/analysis/passes/modernize/waitgroupgo.go b/vendor/golang.org/x/tools/go/analysis/passes/modernize/waitgroupgo.go
index 9af2d3bdc..4bc88d0f8 100644
--- a/vendor/golang.org/x/tools/go/analysis/passes/modernize/waitgroupgo.go
+++ b/vendor/golang.org/x/tools/go/analysis/passes/modernize/waitgroupgo.go
@@ -9,6 +9,7 @@ import (
"fmt"
"go/ast"
"go/printer"
+ "go/types"
"slices"
"golang.org/x/tools/go/analysis"
@@ -30,7 +31,7 @@ var WaitGroupGoAnalyzer = &analysis.Analyzer{
typeindexanalyzer.Analyzer,
},
Run: waitgroup,
- URL: "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/modernize#waitgroupgo",
+ URL: "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/modernize#hdr-Analyzer_waitgroupgo",
}
// The waitgroupgo pass replaces old more complex code with
@@ -112,7 +113,7 @@ func waitgroup(pass *analysis.Pass) (any, error) {
astutil.EqualSyntax(ast.Unparen(deferStmt.Call.Fun).(*ast.SelectorExpr).X, addCallRecv) {
doneStmt = deferStmt // "defer wg.Done()"
- } else if lastStmt, ok := list[len(list)-1].(*ast.ExprStmt); ok {
+ } else if lastStmt, ok := list[len(list)-1].(*ast.ExprStmt); ok && cannotRecover(lit.Body, info) {
if doneCall, ok := lastStmt.X.(*ast.CallExpr); ok &&
typeutil.Callee(info, doneCall) == syncWaitGroupDone &&
astutil.EqualSyntax(ast.Unparen(doneCall.Fun).(*ast.SelectorExpr).X, addCallRecv) {
@@ -175,3 +176,44 @@ func waitgroup(pass *analysis.Pass) (any, error) {
}
return nil, nil
}
+
+// cannotRecover reports whether no panic arising in body can be
+// recovered. It conservatively treats a defer of anything but a
+// recover-free function literal (e.g. a named function) as able to recover.
+func cannotRecover(body *ast.BlockStmt, info *types.Info) bool {
+ res := true
+ ast.Inspect(body, func(n ast.Node) bool {
+ switch n := n.(type) {
+ case *ast.DeferStmt:
+ lit, ok := ast.Unparen(n.Call.Fun).(*ast.FuncLit)
+ if !ok || containsRecover(lit.Body, info) {
+ res = false
+ }
+ // Each defer is fully handled here; don't descend into it.
+ return false
+ case *ast.FuncLit:
+ // Defers in nested functions cannot recover panics from this body.
+ return false
+ }
+ return true
+ })
+ return res
+}
+
+func containsRecover(body *ast.BlockStmt, info *types.Info) bool {
+ found := false
+ ast.Inspect(body, func(n ast.Node) bool {
+ switch n := n.(type) {
+ case *ast.CallExpr:
+ if typeutil.Callee(info, n) == builtinRecover {
+ found = true
+ return false
+ }
+ case *ast.FuncLit:
+ // Recover calls in nested functions cannot recover panics from body.
+ return false
+ }
+ return true
+ })
+ return found
+}
diff --git a/vendor/golang.org/x/tools/go/analysis/passes/printf/printf.go b/vendor/golang.org/x/tools/go/analysis/passes/printf/printf.go
index f82d2eaea..6573c3fc7 100644
--- a/vendor/golang.org/x/tools/go/analysis/passes/printf/printf.go
+++ b/vendor/golang.org/x/tools/go/analysis/passes/printf/printf.go
@@ -1184,15 +1184,6 @@ func checkPrint(pass *analysis.Pass, call *ast.CallExpr, name string) {
}
}
}
- if strings.HasSuffix(name, "ln") {
- // The last item, if a string, should not have a newline.
- arg = args[len(args)-1]
- if s, ok := stringConstantExpr(pass, arg); ok {
- if strings.HasSuffix(s, "\n") {
- pass.ReportRangef(call, "%s arg list ends with redundant newline", name)
- }
- }
- }
for _, arg := range args {
if isFunctionValue(pass, arg) {
pass.ReportRangef(call, "%s arg %s is a func value, not called", name, astutil.Format(pass.Fset, arg))
diff --git a/vendor/golang.org/x/tools/go/analysis/passes/stdversion/stdversion.go b/vendor/golang.org/x/tools/go/analysis/passes/stdversion/stdversion.go
index d1fda880e..3d44c4e86 100644
--- a/vendor/golang.org/x/tools/go/analysis/passes/stdversion/stdversion.go
+++ b/vendor/golang.org/x/tools/go/analysis/passes/stdversion/stdversion.go
@@ -15,6 +15,7 @@ import (
"golang.org/x/tools/go/analysis"
"golang.org/x/tools/go/analysis/passes/inspect"
"golang.org/x/tools/go/ast/inspector"
+ "golang.org/x/tools/internal/stdlib"
"golang.org/x/tools/internal/typesinternal"
"golang.org/x/tools/internal/versions"
)
@@ -64,8 +65,8 @@ func run(pass *analysis.Pass) (any, error) {
pkg *types.Package
version string
}
- memo := make(map[key]map[types.Object]string) // records symbol's minimum Go version
- disallowedSymbols := func(pkg *types.Package, version string) map[types.Object]string {
+ memo := make(map[key]map[types.Object]stdlib.Symbol)
+ disallowedSymbols := func(pkg *types.Package, version string) map[types.Object]stdlib.Symbol {
k := key{pkg, version}
disallowed, ok := memo[k]
if !ok {
@@ -98,20 +99,12 @@ func run(pass *analysis.Pass) (any, error) {
if fileVersion != "" {
if obj, ok := pass.TypesInfo.Uses[n]; ok && obj.Pkg() != nil {
disallowed := disallowedSymbols(obj.Pkg(), fileVersion)
- if minVersion, ok := disallowed[origin(obj)]; ok {
- // Some symbols are accessible before their release but
- // only with specific build tags unknown to us here.
- // Avoid false positives in such cases.
- // TODO(mkalil): move this check into typesinternal.TooNewStdSymbols.
- if obj.Pkg().Path() == "testing/synctest" && versions.AtLeast(fileVersion, "go1.24") {
- break // requires go1.24 && goexperiment.synctest || go1.25
- }
- noun := "module"
- if fileVersion != pkgVersion {
- noun = "file"
- }
+ if sym, ok := disallowed[origin(obj)]; ok {
pass.ReportRangef(n, "%s.%s requires %v or later (%s is %s)",
- obj.Pkg().Name(), obj.Name(), minVersion, noun, fileVersion)
+ obj.Pkg().Name(), sym.Name,
+ sym.Version,
+ cond(fileVersion != pkgVersion, "file", "module"),
+ fileVersion)
}
}
}
@@ -134,3 +127,11 @@ func origin(obj types.Object) types.Object {
}
return obj
}
+
+func cond[T any](cond bool, t, f T) T {
+ if cond {
+ return t
+ } else {
+ return f
+ }
+}
diff --git a/vendor/golang.org/x/tools/go/analysis/passes/unusedresult/unusedresult.go b/vendor/golang.org/x/tools/go/analysis/passes/unusedresult/unusedresult.go
index bd32d5869..82968f464 100644
--- a/vendor/golang.org/x/tools/go/analysis/passes/unusedresult/unusedresult.go
+++ b/vendor/golang.org/x/tools/go/analysis/passes/unusedresult/unusedresult.go
@@ -16,7 +16,6 @@ package unusedresult
import (
_ "embed"
"go/ast"
- "go/token"
"go/types"
"sort"
"strings"
@@ -27,6 +26,7 @@ import (
"golang.org/x/tools/go/types/typeutil"
"golang.org/x/tools/internal/analysis/analyzerutil"
"golang.org/x/tools/internal/astutil"
+ "golang.org/x/tools/internal/typesinternal"
)
//go:embed doc.go
@@ -172,7 +172,7 @@ func run(pass *analysis.Pass) (any, error) {
}
// func() string
-var sigNoArgsStringResult = types.NewSignatureType(nil, nil, nil, nil, types.NewTuple(types.NewParam(token.NoPos, nil, "", types.Typ[types.String])), false)
+var sigNoArgsStringResult = types.NewSignatureType(nil, nil, nil, nil, typesinternal.TupleOf(types.Typ[types.String]), false)
type stringSetFlag map[string]bool
diff --git a/vendor/golang.org/x/tools/go/ast/inspector/cursor.go b/vendor/golang.org/x/tools/go/ast/inspector/cursor.go
index 239b10c4d..1c482252d 100644
--- a/vendor/golang.org/x/tools/go/ast/inspector/cursor.go
+++ b/vendor/golang.org/x/tools/go/ast/inspector/cursor.go
@@ -10,6 +10,7 @@ import (
"go/token"
"iter"
"reflect"
+ "strings"
"golang.org/x/tools/go/ast/edge"
)
@@ -110,6 +111,46 @@ func (c Cursor) String() string {
return reflect.TypeOf(c.Node()).String()
}
+// GoString returns a string describing the cursor's path from the
+// root, if any.
+func (c Cursor) GoString() string {
+ if !c.Valid() {
+ return "(invalid)"
+ }
+ if c.index < 0 {
+ return "(root)"
+ }
+ // e.g "File.Decls[1].(*ast.GenDecl).Specs[0].(*ast.TypeSpec)"
+ //
+ // In hindsight even the File node should have reported a
+ // virtual ParentEdge of (Root_Files, i) where i is the index
+ // among the files passed to NewInspector. Then the path would
+ // read "(root).Files[i]", etc; but we missed the boat.
+ var buf strings.Builder
+ buf.WriteString("File")
+ var visit func(Cursor)
+ visit = func(c Cursor) {
+ ek, idx := c.ParentEdge()
+ if ek == edge.Invalid {
+ return // File
+ }
+ visit(c.Parent())
+ fmt.Fprintf(&buf, ".%s", ek.FieldName())
+ if idx >= 0 {
+ fmt.Fprintf(&buf, "[%d]", idx)
+ }
+ ftype := ek.FieldType()
+ if idx >= 0 {
+ ftype = ftype.Elem() // []T -> T
+ }
+ if ftype.Kind() == reflect.Interface {
+ fmt.Fprintf(&buf, ".(%T)", c.Node())
+ }
+ }
+ visit(c)
+ return buf.String()
+}
+
// indices return the [start, end) half-open interval of event indices.
func (c Cursor) indices() (int32, int32) {
if c.index < 0 {
diff --git a/vendor/golang.org/x/tools/go/loader/loader.go b/vendor/golang.org/x/tools/go/loader/loader.go
index 9c5f7db1d..3c9d4fe75 100644
--- a/vendor/golang.org/x/tools/go/loader/loader.go
+++ b/vendor/golang.org/x/tools/go/loader/loader.go
@@ -738,7 +738,9 @@ func (conf *Config) parsePackageFiles(bp *build.Package, which rune) ([]*ast.Fil
// Preprocess CgoFiles and parse the outputs (sequentially).
if which == 'g' && bp.CgoFiles != nil {
+ ioLimit <- true
cgofiles, err := cgo.ProcessFiles(bp, conf.fset(), conf.DisplayPath, conf.ParserMode)
+ <-ioLimit
if err != nil {
errs = append(errs, err)
} else {
diff --git a/vendor/golang.org/x/tools/go/packages/visit.go b/vendor/golang.org/x/tools/go/packages/visit.go
index c546b1b63..06747a9df 100644
--- a/vendor/golang.org/x/tools/go/packages/visit.go
+++ b/vendor/golang.org/x/tools/go/packages/visit.go
@@ -5,11 +5,11 @@
package packages
import (
- "cmp"
"fmt"
"iter"
"os"
- "slices"
+
+ "golang.org/x/tools/internal/moremaps"
)
// Visit visits all the packages in the import graph whose roots are
@@ -40,7 +40,7 @@ func Visit(pkgs []*Package, pre func(*Package) bool, post func(*Package)) {
seen[pkg] = true
if pre == nil || pre(pkg) {
- for _, imp := range sorted(pkg.Imports) { // for determinism
+ for _, imp := range moremaps.Sorted(pkg.Imports) { // for determinism
visit(imp)
}
}
@@ -88,7 +88,7 @@ func Postorder(pkgs []*Package) iter.Seq[*Package] {
visit = func(pkg *Package) bool {
if !seen[pkg] {
seen[pkg] = true
- for _, imp := range sorted(pkg.Imports) { // for determinism
+ for _, imp := range moremaps.Sorted(pkg.Imports) { // for determinism
if !visit(imp) {
return false
}
@@ -106,28 +106,3 @@ func Postorder(pkgs []*Package) iter.Seq[*Package] {
}
}
}
-
-// -- copied from golang.org.x/tools/gopls/internal/util/moremaps --
-
-// sorted returns an iterator over the entries of m in key order.
-func sorted[M ~map[K]V, K cmp.Ordered, V any](m M) iter.Seq2[K, V] {
- // TODO(adonovan): use maps.Sorted if proposal #68598 is accepted.
- return func(yield func(K, V) bool) {
- keys := keySlice(m)
- slices.Sort(keys)
- for _, k := range keys {
- if !yield(k, m[k]) {
- break
- }
- }
- }
-}
-
-// KeySlice returns the keys of the map M, like slices.Collect(maps.Keys(m)).
-func keySlice[M ~map[K]V, K comparable, V any](m M) []K {
- r := make([]K, 0, len(m))
- for k := range m {
- r = append(r, k)
- }
- return r
-}
diff --git a/vendor/golang.org/x/tools/go/ssa/builder.go b/vendor/golang.org/x/tools/go/ssa/builder.go
index 1669d80b3..a663af8f3 100644
--- a/vendor/golang.org/x/tools/go/ssa/builder.go
+++ b/vendor/golang.org/x/tools/go/ssa/builder.go
@@ -85,6 +85,7 @@ import (
"slices"
"golang.org/x/tools/internal/typeparams"
+ "golang.org/x/tools/internal/typesinternal"
"golang.org/x/tools/internal/versions"
)
@@ -124,7 +125,7 @@ var (
// The ssa:deferstack intrinsic returns the current function's defer stack.
vDeferStack = &Builtin{
name: "ssa:deferstack",
- sig: types.NewSignatureType(nil, nil, nil, nil, types.NewTuple(anonVar(tDeferStack)), false),
+ sig: types.NewSignatureType(nil, nil, nil, nil, typesinternal.TupleOf(tDeferStack), false),
}
)
@@ -1719,7 +1720,7 @@ func (b *builder) selectStmt(fn *Function, s *ast.SelectStmt, label *lblock) {
for _, st := range states {
if st.Dir == types.RecvOnly {
chtyp := typeparams.CoreType(fn.typ(st.Chan.Type())).(*types.Chan)
- vars = append(vars, anonVar(chtyp.Elem()))
+ vars = append(vars, newVar("", chtyp.Elem()))
}
}
sel.setType(types.NewTuple(vars...))
diff --git a/vendor/golang.org/x/tools/go/ssa/methods.go b/vendor/golang.org/x/tools/go/ssa/methods.go
index 82faadeb6..8de0785ca 100644
--- a/vendor/golang.org/x/tools/go/ssa/methods.go
+++ b/vendor/golang.org/x/tools/go/ssa/methods.go
@@ -167,10 +167,18 @@ func (prog *Program) RuntimeTypes() []types.Type {
// eliminates the need to eagerly compute all the element
// types during SSA building.
var runtimeTypes []types.Type
- add := func(t types.Type) { runtimeTypes = append(runtimeTypes, t) }
var set typeutil.Map // for de-duping identical types
for t := range prog.makeInterfaceTypes {
- typesinternal.ForEachElement(&set, &prog.MethodSets, t, add)
+ typesinternal.ForEachElement(prog.MethodSets.MethodSet, t, func(t types.Type, access bool) bool {
+ if !access {
+ return false // inaccessible to reflection
+ }
+ seen, _ := set.Set(t, true).(bool)
+ if !seen {
+ runtimeTypes = append(runtimeTypes, t)
+ }
+ return seen
+ })
}
return runtimeTypes
diff --git a/vendor/golang.org/x/tools/go/ssa/util.go b/vendor/golang.org/x/tools/go/ssa/util.go
index 42f9621c3..5dfca7206 100644
--- a/vendor/golang.org/x/tools/go/ssa/util.go
+++ b/vendor/golang.org/x/tools/go/ssa/util.go
@@ -181,19 +181,13 @@ func newVar(name string, typ types.Type) *types.Var {
return types.NewParam(token.NoPos, nil, name, typ)
}
-// anonVar creates an anonymous 'var' for use in a types.Tuple.
-func anonVar(typ types.Type) *types.Var {
- return newVar("", typ)
-}
-
-var lenResults = types.NewTuple(anonVar(tInt))
+var lenResults = typesinternal.TupleOf(tInt)
// makeLen returns the len builtin specialized to type func(T)int.
func makeLen(T types.Type) *Builtin {
- lenParams := types.NewTuple(anonVar(T))
return &Builtin{
name: "len",
- sig: types.NewSignatureType(nil, nil, nil, lenParams, lenResults, false),
+ sig: types.NewSignatureType(nil, nil, nil, typesinternal.TupleOf(T), lenResults, false),
}
}
diff --git a/vendor/golang.org/x/tools/go/ssa/wrappers.go b/vendor/golang.org/x/tools/go/ssa/wrappers.go
index 6cadd0497..fbb067437 100644
--- a/vendor/golang.org/x/tools/go/ssa/wrappers.go
+++ b/vendor/golang.org/x/tools/go/ssa/wrappers.go
@@ -26,6 +26,7 @@ import (
"go/types"
"golang.org/x/tools/internal/typeparams"
+ "golang.org/x/tools/internal/typesinternal"
)
// -- wrappers -----------------------------------------------------------
@@ -118,10 +119,12 @@ func (b *builder) buildWrapper(fn *Function) {
// For simple indirection wrappers, perform an informative nil-check:
// "value method (T).f called using nil *T pointer"
if len(indices) == 1 && !isPointer(recvType(fn.object)) {
+ params := typesinternal.TupleOf(fn.method.recv, tString, tString)
+ results := typesinternal.TupleOf(fn.method.recv)
var c Call
c.Call.Value = &Builtin{
name: "ssa:wrapnilchk",
- sig: types.NewSignatureType(nil, nil, nil, types.NewTuple(anonVar(fn.method.recv), anonVar(tString), anonVar(tString)), types.NewTuple(anonVar(fn.method.recv)), false),
+ sig: types.NewSignatureType(nil, nil, nil, params, results, false),
}
c.Call.Args = []Value{
v,
diff --git a/vendor/golang.org/x/tools/go/types/typeutil/callee.go b/vendor/golang.org/x/tools/go/types/typeutil/callee.go
index 3d24a8c63..b64a8f454 100644
--- a/vendor/golang.org/x/tools/go/types/typeutil/callee.go
+++ b/vendor/golang.org/x/tools/go/types/typeutil/callee.go
@@ -7,7 +7,8 @@ package typeutil
import (
"go/ast"
"go/types"
- _ "unsafe" // for linkname
+
+ "golang.org/x/tools/internal/typesinternal"
)
// Callee returns the named target of a function call, if any:
@@ -19,14 +20,7 @@ import (
// Note: for calls of instantiated functions and methods, Callee returns
// the corresponding generic function or method on the generic type.
func Callee(info *types.Info, call *ast.CallExpr) types.Object {
- obj := info.Uses[usedIdent(info, call.Fun)]
- if obj == nil {
- return nil
- }
- if _, ok := obj.(*types.TypeName); ok {
- return nil
- }
- return obj
+ return typesinternal.Callee(info, call)
}
// StaticCallee returns the target (function or method) of a static function
@@ -35,52 +29,5 @@ func Callee(info *types.Info, call *ast.CallExpr) types.Object {
// Note: for calls of instantiated functions and methods, StaticCallee returns
// the corresponding generic function or method on the generic type.
func StaticCallee(info *types.Info, call *ast.CallExpr) *types.Func {
- obj := info.Uses[usedIdent(info, call.Fun)]
- fn, _ := obj.(*types.Func)
- if fn == nil || interfaceMethod(fn) {
- return nil
- }
- return fn
-}
-
-// usedIdent is the implementation of [internal/typesinternal.UsedIdent].
-// It returns the identifier associated with e.
-// See typesinternal.UsedIdent for a fuller description.
-// This function should live in typesinternal, but cannot because it would
-// create an import cycle.
-//
-//go:linkname usedIdent golang.org/x/tools/go/types/typeutil.usedIdent
-func usedIdent(info *types.Info, e ast.Expr) *ast.Ident {
- if info.Types == nil || info.Uses == nil {
- panic("one of info.Types or info.Uses is nil; both must be populated")
- }
- // Look through type instantiation if necessary.
- switch d := ast.Unparen(e).(type) {
- case *ast.IndexExpr:
- if info.Types[d.Index].IsType() {
- e = d.X
- }
- case *ast.IndexListExpr:
- e = d.X
- }
-
- switch e := ast.Unparen(e).(type) {
- // info.Uses always has the object we want, even for selector expressions.
- // We don't need info.Selections.
- // See go/types/recording.go:recordSelection.
- case *ast.Ident:
- return e
- case *ast.SelectorExpr:
- return e.Sel
- }
- return nil
-}
-
-// interfaceMethod reports whether its argument is a method of an interface.
-// This function should live in typesinternal, but cannot because it would create an import cycle.
-//
-//go:linkname interfaceMethod golang.org/x/tools/go/types/typeutil.interfaceMethod
-func interfaceMethod(f *types.Func) bool {
- recv := f.Signature().Recv()
- return recv != nil && types.IsInterface(recv.Type())
+ return typesinternal.StaticCallee(info, call)
}
diff --git a/vendor/golang.org/x/tools/internal/analysis/analyzerutil/version.go b/vendor/golang.org/x/tools/internal/analysis/analyzerutil/version.go
index 700d53eff..60d7253c0 100644
--- a/vendor/golang.org/x/tools/internal/analysis/analyzerutil/version.go
+++ b/vendor/golang.org/x/tools/internal/analysis/analyzerutil/version.go
@@ -38,7 +38,7 @@ func FileUsesGoVersion(pass *analysis.Pass, file *ast.File, version string) (_re
// The bootstrap rule does not cover tests,
// and some tests (e.g. debug/elf/file_test.go) rely on this.
pkgpath := pass.Pkg.Path()
- if packagepath.IsStdPackage(pkgpath) &&
+ if packagepath.MaybeStdPackage(pkgpath) &&
stdlib.IsBootstrapPackage(pkgpath) && // (excludes "*_test" external test packages)
!strings.HasSuffix(pass.Fset.File(file.Pos()).Name(), "_test.go") { // (excludes all tests)
fileVersion = stdlib.BootstrapVersion.String() // package must bootstrap
diff --git a/vendor/golang.org/x/tools/internal/astutil/free/free.go b/vendor/golang.org/x/tools/internal/astutil/free/free.go
new file mode 100644
index 000000000..2c4d2c4e5
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/astutil/free/free.go
@@ -0,0 +1,418 @@
+// Copyright 2025 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 free defines utilities for computing the free variables of
+// a syntax tree without type information. This is inherently
+// heuristic because of the T{f: x} ambiguity, in which f may or may
+// not be a lexical reference depending on whether T is a struct type.
+package free
+
+import (
+ "go/ast"
+ "go/token"
+)
+
+// Copied, with considerable changes, from go/parser/resolver.go
+// at af53bd2c03.
+
+// Names computes an approximation to the set of free names of the AST
+// at node n based solely on syntax.
+//
+// In the absence of composite literals, the set of free names is exact. Composite
+// literals introduce an ambiguity that can only be resolved with type information:
+// whether F is a field name or a value in `T{F: ...}`.
+// If includeComplitIdents is true, this function conservatively assumes
+// T is not a struct type, so freeishNames overapproximates: the resulting
+// set may contain spurious entries that are not free lexical references
+// but are references to struct fields.
+// If includeComplitIdents is false, this function assumes that T *is*
+// a struct type, so freeishNames underapproximates: the resulting set
+// may omit names that are free lexical references.
+//
+// TODO(adonovan): includeComplitIdents is a crude hammer: the caller
+// may have partial or heuristic information about whether a given T
+// is struct type. Replace includeComplitIdents with a hook to query
+// the caller.
+//
+// The code is based on go/parser.resolveFile, but heavily simplified. Crucial
+// differences are:
+// - Instead of resolving names to their objects, this function merely records
+// whether they are free.
+// - Labels are ignored: they do not refer to values.
+// - This is never called on ImportSpecs, so the function panics if it sees one.
+func Names(n ast.Node, includeComplitIdents bool) map[string]bool {
+ v := &freeVisitor{
+ free: make(map[string]bool),
+ includeComplitIdents: includeComplitIdents,
+ }
+ // Begin with a scope, even though n might not be a form that establishes a scope.
+ // For example, n might be:
+ // x := ...
+ // Then we need to add the first x to some scope.
+ v.openScope()
+ ast.Walk(v, n)
+ v.closeScope()
+ if v.scope != nil {
+ panic("unbalanced scopes")
+ }
+ return v.free
+}
+
+// A freeVisitor holds state for a free-name analysis.
+type freeVisitor struct {
+ scope *scope // the current innermost scope
+ free map[string]bool // free names seen so far
+ includeComplitIdents bool // include identifier key in composite literals
+}
+
+// scope contains all the names defined in a lexical scope.
+// It is like ast.Scope, but without deprecation warnings.
+type scope struct {
+ names map[string]bool
+ outer *scope
+}
+
+func (s *scope) defined(name string) bool {
+ for ; s != nil; s = s.outer {
+ if s.names[name] {
+ return true
+ }
+ }
+ return false
+}
+
+func (v *freeVisitor) Visit(n ast.Node) ast.Visitor {
+ switch n := n.(type) {
+
+ // Expressions.
+ case *ast.Ident:
+ v.use(n)
+
+ case *ast.FuncLit:
+ v.openScope()
+ defer v.closeScope()
+ v.walkFuncType(nil, n.Type)
+ v.walkBody(n.Body)
+
+ case *ast.SelectorExpr:
+ v.walk(n.X)
+ // Skip n.Sel: it cannot be free.
+
+ case *ast.StructType:
+ v.openScope()
+ defer v.closeScope()
+ v.walkFieldList(n.Fields)
+
+ case *ast.FuncType:
+ v.openScope()
+ defer v.closeScope()
+ v.walkFuncType(nil, n)
+
+ case *ast.CompositeLit:
+ v.walk(n.Type)
+ for _, e := range n.Elts {
+ if kv, _ := e.(*ast.KeyValueExpr); kv != nil {
+ if ident, _ := kv.Key.(*ast.Ident); ident != nil {
+ // It is not possible from syntax alone to know whether
+ // an identifier used as a composite literal key is
+ // a struct field (if n.Type is a struct) or a value
+ // (if n.Type is a map, slice or array).
+ if v.includeComplitIdents {
+ // Over-approximate by treating both cases as potentially
+ // free names.
+ v.use(ident)
+ } else {
+ // Under-approximate by ignoring potentially free names.
+ }
+ } else {
+ v.walk(kv.Key)
+ }
+ v.walk(kv.Value)
+ } else {
+ v.walk(e)
+ }
+ }
+
+ case *ast.InterfaceType:
+ v.openScope()
+ defer v.closeScope()
+ v.walkFieldList(n.Methods)
+
+ // Statements
+ case *ast.AssignStmt:
+ walkSlice(v, n.Rhs)
+ if n.Tok == token.DEFINE {
+ v.shortVarDecl(n.Lhs)
+ } else {
+ walkSlice(v, n.Lhs)
+ }
+
+ case *ast.LabeledStmt:
+ // Ignore labels.
+ v.walk(n.Stmt)
+
+ case *ast.BranchStmt:
+ // Ignore labels.
+
+ case *ast.BlockStmt:
+ v.openScope()
+ defer v.closeScope()
+ walkSlice(v, n.List)
+
+ case *ast.IfStmt:
+ v.openScope()
+ defer v.closeScope()
+ v.walk(n.Init)
+ v.walk(n.Cond)
+ v.walk(n.Body)
+ v.walk(n.Else)
+
+ case *ast.CaseClause:
+ walkSlice(v, n.List)
+ v.openScope()
+ defer v.closeScope()
+ walkSlice(v, n.Body)
+
+ case *ast.SwitchStmt:
+ v.openScope()
+ defer v.closeScope()
+ v.walk(n.Init)
+ v.walk(n.Tag)
+ v.walkBody(n.Body)
+
+ case *ast.TypeSwitchStmt:
+ v.openScope()
+ defer v.closeScope()
+ if n.Init != nil {
+ v.walk(n.Init)
+ }
+ v.walk(n.Assign)
+ // We can use walkBody here because we don't track label scopes.
+ v.walkBody(n.Body)
+
+ case *ast.CommClause:
+ v.openScope()
+ defer v.closeScope()
+ v.walk(n.Comm)
+ walkSlice(v, n.Body)
+
+ case *ast.SelectStmt:
+ v.walkBody(n.Body)
+
+ case *ast.ForStmt:
+ v.openScope()
+ defer v.closeScope()
+ v.walk(n.Init)
+ v.walk(n.Cond)
+ v.walk(n.Post)
+ v.walk(n.Body)
+
+ case *ast.RangeStmt:
+ v.openScope()
+ defer v.closeScope()
+ v.walk(n.X)
+ var lhs []ast.Expr
+ if n.Key != nil {
+ lhs = append(lhs, n.Key)
+ }
+ if n.Value != nil {
+ lhs = append(lhs, n.Value)
+ }
+ if len(lhs) > 0 {
+ if n.Tok == token.DEFINE {
+ v.shortVarDecl(lhs)
+ } else {
+ walkSlice(v, lhs)
+ }
+ }
+ v.walk(n.Body)
+
+ // Declarations
+ case *ast.GenDecl:
+ switch n.Tok {
+ case token.CONST, token.VAR:
+ for _, spec := range n.Specs {
+ spec := spec.(*ast.ValueSpec)
+ walkSlice(v, spec.Values)
+ v.walk(spec.Type)
+ v.declare(spec.Names...)
+ }
+
+ case token.TYPE:
+ for _, spec := range n.Specs {
+ spec := spec.(*ast.TypeSpec)
+ // Go spec: The scope of a type identifier declared inside a
+ // function begins at the identifier in the TypeSpec and ends
+ // at the end of the innermost containing block.
+ v.declare(spec.Name)
+ if spec.TypeParams != nil {
+ v.openScope()
+ defer v.closeScope()
+ v.walkTypeParams(spec.TypeParams)
+ }
+ v.walk(spec.Type)
+ }
+
+ case token.IMPORT:
+ panic("encountered import declaration in free analysis")
+ }
+
+ case *ast.FuncDecl:
+ if n.Recv == nil && n.Name.Name != "init" { // package-level function
+ v.declare(n.Name)
+ }
+ v.openScope()
+ defer v.closeScope()
+ v.walkTypeParams(n.Type.TypeParams)
+ v.walkFuncType(n.Recv, n.Type)
+ v.walkBody(n.Body)
+
+ default:
+ return v
+ }
+
+ return nil
+}
+
+func (v *freeVisitor) openScope() {
+ v.scope = &scope{map[string]bool{}, v.scope}
+}
+
+func (v *freeVisitor) closeScope() {
+ v.scope = v.scope.outer
+}
+
+func (v *freeVisitor) walk(n ast.Node) {
+ if n != nil {
+ ast.Walk(v, n)
+ }
+}
+
+func (v *freeVisitor) walkFuncType(recv *ast.FieldList, typ *ast.FuncType) {
+ // First use field types...
+ v.walkRecvFieldType(recv)
+ v.walkFieldTypes(typ.Params)
+ v.walkFieldTypes(typ.Results)
+
+ // ...then declare field names.
+ v.declareFieldNames(recv)
+ v.declareFieldNames(typ.Params)
+ v.declareFieldNames(typ.Results)
+}
+
+// A receiver field is not like a param or result field because
+// "func (recv R[T]) method()" uses R but declares T.
+func (v *freeVisitor) walkRecvFieldType(list *ast.FieldList) {
+ if list == nil {
+ return
+ }
+ for _, f := range list.List { // valid => len=1
+ typ := f.Type
+ if ptr, ok := typ.(*ast.StarExpr); ok {
+ typ = ptr.X
+ }
+
+ // Analyze receiver type as Base[Index, ...]
+ var (
+ base ast.Expr
+ indices []ast.Expr
+ )
+ switch typ := typ.(type) {
+ case *ast.IndexExpr: // B[T]
+ base, indices = typ.X, []ast.Expr{typ.Index}
+ case *ast.IndexListExpr: // B[K, V]
+ base, indices = typ.X, typ.Indices
+ default: // B
+ base = typ
+ }
+ for _, expr := range indices {
+ if id, ok := expr.(*ast.Ident); ok {
+ v.declare(id)
+ }
+ }
+ v.walk(base)
+ }
+}
+
+// walkTypeParams is like walkFieldList, but declares type parameters eagerly so
+// that they may be resolved in the constraint expressions held in the field
+// Type.
+func (v *freeVisitor) walkTypeParams(list *ast.FieldList) {
+ v.declareFieldNames(list)
+ v.walkFieldTypes(list) // constraints
+}
+
+func (v *freeVisitor) walkBody(body *ast.BlockStmt) {
+ if body == nil {
+ return
+ }
+ walkSlice(v, body.List)
+}
+
+func (v *freeVisitor) walkFieldList(list *ast.FieldList) {
+ if list == nil {
+ return
+ }
+ v.walkFieldTypes(list) // .Type may contain references
+ v.declareFieldNames(list) // .Names declares names
+}
+
+func (v *freeVisitor) shortVarDecl(lhs []ast.Expr) {
+ // Go spec: A short variable declaration may redeclare variables provided
+ // they were originally declared in the same block with the same type, and
+ // at least one of the non-blank variables is new.
+ //
+ // However, it doesn't matter to free analysis whether a variable is declared
+ // fresh or redeclared.
+ for _, x := range lhs {
+ // In a well-formed program each expr must be an identifier,
+ // but be forgiving.
+ if id, ok := x.(*ast.Ident); ok {
+ v.declare(id)
+ }
+ }
+}
+
+func walkSlice[S ~[]E, E ast.Node](r *freeVisitor, list S) {
+ for _, e := range list {
+ r.walk(e)
+ }
+}
+
+// walkFieldTypes resolves the types of the walkFieldTypes in list.
+// The companion method declareFieldList declares the names of the walkFieldTypes.
+func (v *freeVisitor) walkFieldTypes(list *ast.FieldList) {
+ if list != nil {
+ for _, f := range list.List {
+ v.walk(f.Type)
+ }
+ }
+}
+
+// declareFieldNames declares the names of the fields in list.
+// (Names in a FieldList always establish new bindings.)
+// The companion method resolveFieldList resolves the types of the fields.
+func (v *freeVisitor) declareFieldNames(list *ast.FieldList) {
+ if list != nil {
+ for _, f := range list.List {
+ v.declare(f.Names...)
+ }
+ }
+}
+
+// use marks ident as free if it is not in scope.
+func (v *freeVisitor) use(ident *ast.Ident) {
+ if s := ident.Name; s != "_" && !v.scope.defined(s) {
+ v.free[s] = true
+ }
+}
+
+// declare adds each non-blank ident to the current scope.
+func (v *freeVisitor) declare(idents ...*ast.Ident) {
+ for _, id := range idents {
+ if id.Name != "_" {
+ v.scope.names[id.Name] = true
+ }
+ }
+}
diff --git a/vendor/golang.org/x/tools/internal/moremaps/maps.go b/vendor/golang.org/x/tools/internal/moremaps/maps.go
new file mode 100644
index 000000000..a1bae078b
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/moremaps/maps.go
@@ -0,0 +1,116 @@
+// Copyright 2023 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 moremaps contains more functions for working with maps.
+package moremaps
+
+import (
+ "cmp"
+ "iter"
+ "maps"
+ "slices"
+)
+
+// Arbitrary returns an arbitrary (key, value) entry from the map and ok is true, if
+// the map is not empty. Otherwise, it returns zero values for K and V, and false.
+func Arbitrary[K comparable, V any](m map[K]V) (_ K, _ V, ok bool) {
+ for k, v := range m {
+ return k, v, true
+ }
+ return
+}
+
+// Group returns a new non-nil map containing the elements of s grouped by the
+// keys returned from the key func.
+func Group[K comparable, V any](s []V, key func(V) K) map[K][]V {
+ m := make(map[K][]V)
+ for _, v := range s {
+ k := key(v)
+ m[k] = append(m[k], v)
+ }
+ return m
+}
+
+// KeySlice returns the keys of the map M, like slices.Collect(maps.Keys(m)).
+func KeySlice[M ~map[K]V, K comparable, V any](m M) []K {
+ r := make([]K, 0, len(m))
+ for k := range m {
+ r = append(r, k)
+ }
+ return r
+}
+
+// ValueSlice returns the values of the map M, like slices.Collect(maps.Values(m)).
+func ValueSlice[M ~map[K]V, K comparable, V any](m M) []V {
+ r := make([]V, 0, len(m))
+ for _, v := range m {
+ r = append(r, v)
+ }
+ return r
+}
+
+// SameKeys reports whether x and y have equal sets of keys.
+func SameKeys[K comparable, V1, V2 any](x map[K]V1, y map[K]V2) bool {
+ ignoreValues := func(V1, V2) bool { return true }
+ return maps.EqualFunc(x, y, ignoreValues)
+}
+
+// Sorted returns an iterator over the entries of m in key order.
+func Sorted[M ~map[K]V, K cmp.Ordered, V any](m M) iter.Seq2[K, V] {
+ // TODO(adonovan): use maps.Sorted if proposal #68598 is accepted.
+ return func(yield func(K, V) bool) {
+ keys := KeySlice(m)
+ slices.Sort(keys)
+ for _, k := range keys {
+ if !yield(k, m[k]) {
+ break
+ }
+ }
+ }
+}
+
+// SortedFunc returns an iterator over the entries of m in the key order determined by cmp.
+func SortedFunc[M ~map[K]V, K comparable, V any](m M, cmp func(x, y K) int) iter.Seq2[K, V] {
+ // TODO(adonovan): use maps.SortedFunc if proposal #68598 is accepted.
+ return func(yield func(K, V) bool) {
+ keys := KeySlice(m)
+ slices.SortFunc(keys, cmp)
+ for _, k := range keys {
+ if !yield(k, m[k]) {
+ break
+ }
+ }
+ }
+}
+
+// Delete is like delete(m, k) but reports whether deletion occurred.
+func Delete[M ~map[K]V, K comparable, V any](m M, k K) bool {
+ pre := len(m)
+ delete(m, k)
+ return pre != len(m)
+}
+
+// Entry is a key-value pair obtained from a map.
+type Entry[K comparable, V any] struct {
+ Key K
+ Value V
+}
+
+// Entries returns a new unordered array of the entries of a map.
+func Entries[M ~map[K]V, K comparable, V any](m M) []Entry[K, V] {
+ entries := make([]Entry[K, V], 0, len(m))
+ for k, v := range m {
+ entries = append(entries, Entry[K, V]{k, v})
+ }
+ return entries
+}
+
+// FromEntries returns a new map into which the entries have been inserted in order.
+func FromEntries[K comparable, V any](entries []Entry[K, V]) map[K]V {
+ m := make(map[K]V, len(entries))
+ for _, e := range entries {
+ m[e.Key] = e.Value
+ }
+ return m
+}
diff --git a/vendor/golang.org/x/tools/internal/packagepath/packagepath.go b/vendor/golang.org/x/tools/internal/packagepath/packagepath.go
index fa39a13f9..7b25340da 100644
--- a/vendor/golang.org/x/tools/internal/packagepath/packagepath.go
+++ b/vendor/golang.org/x/tools/internal/packagepath/packagepath.go
@@ -36,9 +36,19 @@ func CanImport(from, to string) bool {
return true
}
-// IsStdPackage reports whether the specified package path belongs to a
-// package in the standard library (including internal dependencies).
-func IsStdPackage(path string) bool {
+// MaybeStdPackage reports whether the specified package path might
+// belong to a package in the standard library (including internal
+// dependencies), based only on its form.
+//
+// It may spuriously return true, but a result of false is definitive:
+//
+// MaybeStdPackage("fmt") = true
+// MaybeStdPackage("maybe/tomorrow") = true // false positive
+// MaybeStdPackage("example.com/foo") = false
+//
+// For a definitive answer, use [stdlib.HasPackage], which consults a
+// huge table.
+func MaybeStdPackage(path string) bool {
// A standard package has no dot in its first segment.
// (It may yet have a dot, e.g. "vendor/golang.org/x/foo".)
slash := strings.IndexByte(path, '/')
diff --git a/vendor/golang.org/x/tools/internal/refactor/imports.go b/vendor/golang.org/x/tools/internal/refactor/imports.go
index 5ce70aee8..046038cc8 100644
--- a/vendor/golang.org/x/tools/internal/refactor/imports.go
+++ b/vendor/golang.org/x/tools/internal/refactor/imports.go
@@ -125,13 +125,13 @@ func AddImportEdits(file *ast.File, name, pkgpath string) []Edit {
var pos token.Pos
if gd, ok := decl0.(*ast.GenDecl); ok && gd.Tok == token.IMPORT && gd.Rparen.IsValid() {
// Have existing grouped import ( ... ) decl.
- if packagepath.IsStdPackage(pkgpath) && len(gd.Specs) > 0 {
+ if packagepath.MaybeStdPackage(pkgpath) && len(gd.Specs) > 0 {
// Add spec for a std package before
// first existing spec, followed by
// a blank line if the next one is non-std.
first := gd.Specs[0].(*ast.ImportSpec)
pos = first.Pos()
- if !packagepath.IsStdPackage(first.Path.Value) {
+ if !packagepath.MaybeStdPackage(first.Path.Value) {
newText += "\n"
}
newText += "\n\t"
diff --git a/vendor/golang.org/x/tools/internal/refactor/inline/callee.go b/vendor/golang.org/x/tools/internal/refactor/inline/callee.go
new file mode 100644
index 000000000..313e0f71e
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/refactor/inline/callee.go
@@ -0,0 +1,962 @@
+// Copyright 2023 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 inline
+
+// This file defines the analysis of the callee function.
+
+import (
+ "bytes"
+ "cmp"
+ "encoding/gob"
+ "fmt"
+ "go/ast"
+ "go/parser"
+ "go/token"
+ "go/types"
+ "slices"
+ "strings"
+
+ "golang.org/x/tools/go/types/typeutil"
+ "golang.org/x/tools/internal/moremaps"
+ "golang.org/x/tools/internal/typeparams"
+ "golang.org/x/tools/internal/typesinternal"
+)
+
+// A Callee holds information about an inlinable function. Gob-serializable.
+type Callee struct {
+ impl gobCallee
+}
+
+func (callee *Callee) String() string { return callee.impl.Name }
+
+type gobCallee struct {
+ Content []byte // file content, compacted to a single func decl
+
+ // results of type analysis (does not reach go/types data structures)
+ PkgPath string // package path of declaring package
+ Name string // user-friendly name for error messages
+ GoVersion string // version of Go effective in callee file
+ Unexported []string // names of free objects that are unexported
+ FreeRefs []freeRef // locations of references to free objects
+ FreeObjs []object // descriptions of free objects
+ ValidForCallStmt bool // function body is "return expr" where expr is f() or <-ch
+ NumResults int // number of results (according to type, not ast.FieldList)
+ Params []*paramInfo // information about parameters (incl. receiver)
+ TypeParams []*paramInfo // information about type parameters
+ Results []*paramInfo // information about result variables
+ Effects []int // order in which parameters are evaluated (see calleefx)
+ HasDefer bool // uses defer
+ HasBareReturn bool // uses bare return in non-void function
+ Returns [][]returnOperandFlags // metadata about result expressions for each return
+ Labels []string // names of all control labels
+ Falcon falconResult // falcon constraint system
+}
+
+// returnOperandFlags records metadata about a single result expression in a return
+// statement.
+type returnOperandFlags int
+
+const (
+ nonTrivialResult returnOperandFlags = 1 << iota // return operand has non-trivial conversion to result type
+ untypedNilResult // return operand is nil literal
+)
+
+// A freeRef records a reference to a free object. Gob-serializable.
+// (This means free relative to the FuncDecl as a whole, i.e. excluding parameters.)
+type freeRef struct {
+ Offset int // byte offset of the reference relative to the FuncDecl
+ Object int // index into Callee.freeObjs
+}
+
+// An object abstracts a free types.Object referenced by the callee. Gob-serializable.
+type object struct {
+ Name string // Object.Name()
+ Kind string // one of {var,func,const,type,pkgname,nil,builtin}
+ PkgPath string // path of object's package (or imported package if kind="pkgname")
+ PkgName string // name of object's package (or imported package if kind="pkgname")
+ // TODO(rfindley): should we also track LocalPkgName here? Do we want to
+ // preserve the local package name?
+ ValidPos bool // Object.Pos().IsValid()
+ Shadow shadowMap // shadowing info for the object's refs
+}
+
+// AnalyzeCallee analyzes a function that is a candidate for inlining
+// and returns a Callee that describes it. The Callee object, which is
+// serializable, can be passed to one or more subsequent calls to
+// Inline, each with a different Caller.
+//
+// This design allows separate analysis of callers and callees in the
+// golang.org/x/tools/go/analysis framework: the inlining information
+// about a callee can be recorded as a "fact".
+//
+// The content should be the actual input to the compiler, not the
+// apparent source file according to any //line directives that
+// may be present within it.
+func AnalyzeCallee(logf func(string, ...any), fset *token.FileSet, pkg *types.Package, info *types.Info, decl *ast.FuncDecl, content []byte) (*Callee, error) {
+ checkInfoFields(info)
+
+ // The client is expected to have determined that the callee
+ // is a function with a declaration (not a built-in or var).
+ fn := info.Defs[decl.Name].(*types.Func)
+ sig := fn.Type().(*types.Signature)
+
+ logf("analyzeCallee %v @ %v", fn, fset.PositionFor(decl.Pos(), false))
+
+ // Create user-friendly name ("pkg.Func" or "(pkg.T).Method")
+ var name string
+ if sig.Recv() == nil {
+ name = fmt.Sprintf("%s.%s", fn.Pkg().Name(), fn.Name())
+ } else {
+ name = fmt.Sprintf("(%s).%s", types.TypeString(sig.Recv().Type(), (*types.Package).Name), fn.Name())
+ }
+
+ if decl.Body == nil {
+ return nil, fmt.Errorf("cannot inline function %s as it has no body", name)
+ }
+
+ // Record the file's Go goVersion so that we don't
+ // inline newer code into file using an older dialect.
+ //
+ // Using the file version is overly conservative.
+ // A more precise solution would be for the type checker to
+ // record which language features the callee actually needs;
+ // see https://go.dev/issue/75726.
+ //
+ // We don't have the ast.File handy, so instead of a
+ // lookup we must scan the entire FileVersions map.
+ var goVersion string
+ for file, v := range info.FileVersions {
+ if file.Pos() < decl.Pos() && decl.Pos() < file.End() {
+ goVersion = v
+ break
+ }
+ }
+
+ // Record the location of all free references in the FuncDecl.
+ // (Parameters are not free by this definition.)
+ var (
+ fieldObjs = fieldObjs(sig)
+ freeObjIndex = make(map[types.Object]int)
+ freeObjs []object
+ freeRefs []freeRef // free refs that may need renaming
+ unexported []string // free refs to unexported objects, for later error checks
+ )
+ var f func(n ast.Node, stack []ast.Node) bool
+ var stack []ast.Node
+ stack = append(stack, decl.Type) // for scope of function itself
+ visit := func(n ast.Node, stack []ast.Node) { ast.PreorderStack(n, stack, f) }
+ f = func(n ast.Node, stack []ast.Node) bool {
+ switch n := n.(type) {
+ case *ast.SelectorExpr:
+ // Check selections of free fields/methods.
+ if sel, ok := info.Selections[n]; ok &&
+ !within(sel.Obj().Pos(), decl) &&
+ !n.Sel.IsExported() {
+ sym := fmt.Sprintf("(%s).%s", info.TypeOf(n.X), n.Sel.Name)
+ unexported = append(unexported, sym)
+ }
+
+ // Don't recur into SelectorExpr.Sel.
+ visit(n.X, stack)
+ return false
+
+ case *ast.CompositeLit:
+ // Check for struct literals that refer to unexported fields,
+ // whether keyed or unkeyed. (Logic assumes well-typedness.)
+ litType := typeparams.Deref(info.TypeOf(n))
+ if s, ok := typeparams.CoreType(litType).(*types.Struct); ok {
+ if n.Type != nil {
+ visit(n.Type, stack)
+ }
+ for i, elt := range n.Elts {
+ var field *types.Var
+ var value ast.Expr
+ if kv, ok := elt.(*ast.KeyValueExpr); ok {
+ field = info.Uses[kv.Key.(*ast.Ident)].(*types.Var)
+ value = kv.Value
+ } else {
+ field = s.Field(i)
+ value = elt
+ }
+ if !within(field.Pos(), decl) && !field.Exported() {
+ sym := fmt.Sprintf("(%s).%s", litType, field.Name())
+ unexported = append(unexported, sym)
+ }
+
+ // Don't recur into KeyValueExpr.Key.
+ visit(value, stack)
+ }
+ return false
+ }
+
+ case *ast.Ident:
+ if obj, ok := info.Uses[n]; ok {
+ // Methods and fields are handled by SelectorExpr and CompositeLit.
+ if isField(obj) || isMethod(obj) {
+ panic(obj)
+ }
+ // Inv: id is a lexical reference.
+
+ // A reference to an unexported package-level declaration
+ // cannot be inlined into another package.
+ if !n.IsExported() &&
+ obj.Pkg() != nil && obj.Parent() == obj.Pkg().Scope() {
+ unexported = append(unexported, n.Name)
+ }
+
+ // Record free reference (incl. self-reference).
+ if obj == fn || !within(obj.Pos(), decl) {
+ objidx, ok := freeObjIndex[obj]
+ if !ok {
+ objidx = len(freeObjIndex)
+ var pkgPath, pkgName string
+ if pn, ok := obj.(*types.PkgName); ok {
+ pkgPath = pn.Imported().Path()
+ pkgName = pn.Imported().Name()
+ } else if obj.Pkg() != nil {
+ pkgPath = obj.Pkg().Path()
+ pkgName = obj.Pkg().Name()
+ }
+ freeObjs = append(freeObjs, object{
+ Name: obj.Name(),
+ Kind: objectKind(obj),
+ PkgName: pkgName,
+ PkgPath: pkgPath,
+ ValidPos: obj.Pos().IsValid(),
+ })
+ freeObjIndex[obj] = objidx
+ }
+
+ freeObjs[objidx].Shadow = freeObjs[objidx].Shadow.add(info, fieldObjs, obj.Name(), stack)
+
+ freeRefs = append(freeRefs, freeRef{
+ Offset: int(n.Pos() - decl.Pos()),
+ Object: objidx,
+ })
+ }
+ }
+ }
+ return true
+ }
+ visit(decl, stack)
+
+ // Analyze callee body for "return expr" form,
+ // where expr is f() or <-ch. These forms are
+ // safe to inline as a standalone statement.
+ validForCallStmt := false
+ if len(decl.Body.List) != 1 {
+ // not just a return statement
+ } else if ret, ok := decl.Body.List[0].(*ast.ReturnStmt); ok && len(ret.Results) == 1 {
+ validForCallStmt = func() bool {
+ switch expr := ast.Unparen(ret.Results[0]).(type) {
+ case *ast.CallExpr: // f(x)
+ callee := typeutil.Callee(info, expr)
+ if callee == nil {
+ return false // conversion T(x)
+ }
+
+ // The only non-void built-in functions that may be
+ // called as a statement are copy and recover
+ // (though arguably a call to recover should never
+ // be inlined as that changes its behavior).
+ if builtin, ok := callee.(*types.Builtin); ok {
+ return builtin.Name() == "copy" ||
+ builtin.Name() == "recover"
+ }
+
+ return true // ordinary call f()
+
+ case *ast.UnaryExpr: // <-x
+ return expr.Op == token.ARROW // channel receive <-ch
+ }
+
+ // No other expressions are valid statements.
+ return false
+ }()
+ }
+
+ // Record information about control flow in the callee
+ // (but not any nested functions).
+ var (
+ hasDefer = false
+ hasBareReturn = false
+ returnInfo [][]returnOperandFlags
+ labels []string
+ )
+ ast.Inspect(decl.Body, func(n ast.Node) bool {
+ switch n := n.(type) {
+ case *ast.FuncLit:
+ return false // prune traversal
+ case *ast.DeferStmt:
+ hasDefer = true
+ case *ast.LabeledStmt:
+ labels = append(labels, n.Label.Name)
+ case *ast.ReturnStmt:
+
+ // Are implicit assignment conversions
+ // to result variables all trivial?
+ var resultInfo []returnOperandFlags
+ if len(n.Results) > 0 {
+ argInfo := func(i int) (ast.Expr, types.Type) {
+ expr := n.Results[i]
+ return expr, info.TypeOf(expr)
+ }
+ if len(n.Results) == 1 && sig.Results().Len() > 1 {
+ // Spread return: return f() where f.Results > 1.
+ tuple := info.TypeOf(n.Results[0]).(*types.Tuple)
+ argInfo = func(i int) (ast.Expr, types.Type) {
+ return nil, tuple.At(i).Type()
+ }
+ }
+ for i := range sig.Results().Len() {
+ expr, typ := argInfo(i)
+ var flags returnOperandFlags
+ if typ == types.Typ[types.UntypedNil] { // untyped nil is preserved by go/types
+ flags |= untypedNilResult
+ }
+ if !trivialConversion(info.Types[expr].Value, typ, sig.Results().At(i).Type()) {
+ flags |= nonTrivialResult
+ }
+ resultInfo = append(resultInfo, flags)
+ }
+ } else if sig.Results().Len() > 0 {
+ hasBareReturn = true
+ }
+ returnInfo = append(returnInfo, resultInfo)
+ }
+ return true
+ })
+
+ // Reject attempts to inline cgo-generated functions.
+ for _, obj := range freeObjs {
+ // There are others (iconst fconst sconst fpvar macro)
+ // but this is probably sufficient.
+ if strings.HasPrefix(obj.Name, "_Cfunc_") ||
+ strings.HasPrefix(obj.Name, "_Ctype_") ||
+ strings.HasPrefix(obj.Name, "_Cvar_") {
+ return nil, fmt.Errorf("cannot inline cgo-generated functions")
+ }
+ }
+
+ // Compact content to just the FuncDecl.
+ //
+ // As a space optimization, we don't retain the complete
+ // callee file content; all we need is "package _; func f() { ... }".
+ // This reduces the size of analysis facts.
+ //
+ // Offsets in the callee information are "relocatable"
+ // since they are all relative to the FuncDecl.
+
+ content = append([]byte("package _\n"),
+ content[offsetOf(fset, decl.Pos()):offsetOf(fset, decl.End())]...)
+ // Sanity check: re-parse the compacted content.
+ if _, _, err := parseCompact(content); err != nil {
+ return nil, err
+ }
+
+ params, results, effects, falcon := analyzeParams(logf, fset, info, decl)
+ tparams := analyzeTypeParams(logf, fset, info, decl)
+ return &Callee{gobCallee{
+ Content: content,
+ PkgPath: pkg.Path(),
+ Name: name,
+ GoVersion: goVersion,
+ Unexported: unexported,
+ FreeObjs: freeObjs,
+ FreeRefs: freeRefs,
+ ValidForCallStmt: validForCallStmt,
+ NumResults: sig.Results().Len(),
+ Params: params,
+ TypeParams: tparams,
+ Results: results,
+ Effects: effects,
+ HasDefer: hasDefer,
+ HasBareReturn: hasBareReturn,
+ Returns: returnInfo,
+ Labels: labels,
+ Falcon: falcon,
+ }}, nil
+}
+
+// parseCompact parses a Go source file of the form "package _\n func f() { ... }"
+// and returns the sole function declaration.
+func parseCompact(content []byte) (*token.FileSet, *ast.FuncDecl, error) {
+ fset := token.NewFileSet()
+ const mode = parser.ParseComments | parser.SkipObjectResolution | parser.AllErrors
+ f, err := parser.ParseFile(fset, "callee.go", content, mode)
+ if err != nil {
+ return nil, nil, fmt.Errorf("internal error: cannot compact file: %v", err)
+ }
+ return fset, f.Decls[0].(*ast.FuncDecl), nil
+}
+
+// A paramInfo records information about a callee receiver, parameter, or result variable.
+type paramInfo struct {
+ Name string // parameter name (may be blank, or even "")
+ Index int // index within signature
+ IsResult bool // false for receiver or parameter, true for result variable
+ IsInterface bool // parameter has a (non-type parameter) interface type
+ Assigned bool // parameter appears on left side of an assignment statement
+ Escapes bool // parameter has its address taken
+ Refs []refInfo // information about references to parameter within body
+ Shadow shadowMap // shadowing info for the above refs; see [shadowMap]
+ FalconType string // name of this parameter's type (if basic) in the falcon system
+}
+
+type refInfo struct {
+ Offset int // FuncDecl-relative byte offset of parameter ref within body
+ Assignable bool // ref appears in context of assignment to known type
+ IfaceAssignment bool // ref is being assigned to an interface
+ AffectsInference bool // ref type may affect type inference
+ // IsSelectionOperand indicates whether the parameter reference is the
+ // operand of a selection (param.f). If so, and param's argument is itself
+ // a receiver parameter (a common case), we don't need to desugar (&v or *ptr)
+ // the selection: if param.Method is a valid selection, then so is param.fieldOrMethod.
+ IsSelectionOperand bool
+}
+
+// analyzeParams computes information about parameters of the function declared by decl,
+// including a simple "address taken" escape analysis.
+//
+// It returns two new arrays, one of the receiver and parameters, and
+// the other of the result variables of the function.
+//
+// The input must be well-typed.
+func analyzeParams(logf func(string, ...any), fset *token.FileSet, info *types.Info, decl *ast.FuncDecl) (params, results []*paramInfo, effects []int, _ falconResult) {
+ sig := signature(fset, info, decl)
+
+ paramInfos := make(map[*types.Var]*paramInfo)
+ {
+ newParamInfo := func(param *types.Var, isResult bool) *paramInfo {
+ info := ¶mInfo{
+ Name: param.Name(),
+ IsResult: isResult,
+ Index: len(paramInfos),
+ IsInterface: isNonTypeParamInterface(param.Type()),
+ }
+ paramInfos[param] = info
+ return info
+ }
+ if sig.Recv() != nil {
+ params = append(params, newParamInfo(sig.Recv(), false))
+ }
+ for v := range sig.Params().Variables() {
+ params = append(params, newParamInfo(v, false))
+ }
+ for v := range sig.Results().Variables() {
+ results = append(results, newParamInfo(v, true))
+ }
+ }
+
+ // Search function body for operations &x, x.f(), and x = y
+ // where x is a parameter, and record it.
+ escape(info, decl, func(v *types.Var, escapes bool) {
+ if info := paramInfos[v]; info != nil {
+ if escapes {
+ info.Escapes = true
+ } else {
+ info.Assigned = true
+ }
+ }
+ })
+
+ // Record locations of all references to parameters.
+ // And record the set of intervening definitions for each parameter.
+ //
+ // TODO(adonovan): combine this traversal with the one that computes
+ // FreeRefs. The tricky part is that calleefx needs this one first.
+ fieldObjs := fieldObjs(sig)
+ var stack []ast.Node
+ stack = append(stack, decl.Type) // for scope of function itself
+ ast.PreorderStack(decl.Body, stack, func(n ast.Node, stack []ast.Node) bool {
+ if id, ok := n.(*ast.Ident); ok {
+ if v, ok := info.Uses[id].(*types.Var); ok {
+ if pinfo, ok := paramInfos[v]; ok {
+ // Record ref information, and any intervening (shadowing) names.
+ //
+ // If the parameter v has an interface type, and the reference id
+ // appears in a context where assignability rules apply, there may be
+ // an implicit interface-to-interface widening. In that case it is
+ // not necessary to insert an explicit conversion from the argument
+ // to the parameter's type.
+ //
+ // Contrapositively, if param is not an interface type, then the
+ // assignment may lose type information, for example in the case that
+ // the substituted expression is an untyped constant or unnamed type.
+ stack = append(stack, n) // (the two calls below want n)
+ assignable, ifaceAssign, affectsInference := analyzeAssignment(info, stack)
+ ref := refInfo{
+ Offset: int(n.Pos() - decl.Pos()),
+ Assignable: assignable,
+ IfaceAssignment: ifaceAssign,
+ AffectsInference: affectsInference,
+ IsSelectionOperand: isSelectionOperand(stack),
+ }
+ pinfo.Refs = append(pinfo.Refs, ref)
+ pinfo.Shadow = pinfo.Shadow.add(info, fieldObjs, pinfo.Name, stack)
+ }
+ }
+ }
+ return true
+ })
+
+ // Compute subset and order of parameters that are strictly evaluated.
+ // (Depends on Refs computed above.)
+ effects = calleefx(info, decl.Body, paramInfos)
+ logf("effects list = %v", effects)
+
+ falcon := falcon(logf, fset, paramInfos, info, decl)
+
+ return params, results, effects, falcon
+}
+
+// analyzeTypeParams computes information about the type parameters of the function declared by decl.
+func analyzeTypeParams(_ logger, fset *token.FileSet, info *types.Info, decl *ast.FuncDecl) []*paramInfo {
+ sig := signature(fset, info, decl)
+ paramInfos := make(map[*types.TypeName]*paramInfo)
+ var params []*paramInfo
+ collect := func(tpl *types.TypeParamList) {
+ for tparam := range tpl.TypeParams() {
+ typeName := tparam.Obj()
+ info := ¶mInfo{Name: typeName.Name()}
+ params = append(params, info)
+ paramInfos[typeName] = info
+ }
+ }
+ collect(sig.RecvTypeParams())
+ collect(sig.TypeParams())
+
+ // Find references.
+ // We don't care about most of the properties that matter for parameter references:
+ // a type is immutable, cannot have its address taken, and does not undergo conversions.
+ // TODO(jba): can we nevertheless combine this with the traversal in analyzeParams?
+ visit := func(n ast.Node, stack []ast.Node) bool {
+ if id, ok := n.(*ast.Ident); ok {
+ if v, ok := info.Uses[id].(*types.TypeName); ok {
+ if pinfo, ok := paramInfos[v]; ok {
+ ref := refInfo{Offset: int(n.Pos() - decl.Pos())}
+ pinfo.Refs = append(pinfo.Refs, ref)
+ pinfo.Shadow = pinfo.Shadow.add(info, nil, pinfo.Name, stack)
+ }
+ }
+ }
+ return true
+ }
+ var stack []ast.Node
+ stack = append(stack, decl.Type) // for scope of function itself
+ if decl.Type.Params != nil {
+ ast.PreorderStack(decl.Type.Params, stack, visit)
+ }
+ if decl.Type.Results != nil {
+ ast.PreorderStack(decl.Type.Results, stack, visit)
+ }
+ ast.PreorderStack(decl.Body, stack, visit)
+ return params
+}
+
+func signature(fset *token.FileSet, info *types.Info, decl *ast.FuncDecl) *types.Signature {
+ fnobj, ok := info.Defs[decl.Name]
+ if !ok {
+ panic(fmt.Sprintf("%s: no func object for %q",
+ fset.PositionFor(decl.Name.Pos(), false), decl.Name)) // ill-typed?
+ }
+ return fnobj.Type().(*types.Signature)
+}
+
+// -- callee helpers --
+
+// analyzeAssignment looks at the given stack, and analyzes certain
+// attributes of the innermost expression.
+//
+// In all cases we 'fail closed' when we cannot detect (or for simplicity
+// choose not to detect) the condition in question, meaning we err on the side
+// of the more restrictive rule. This is noted for each result below.
+//
+// - assignable reports whether the expression is used in a position where
+// assignability rules apply, such as in an actual assignment, as call
+// argument, or in a send to a channel. Defaults to 'false'. If assignable
+// is false, the other two results are irrelevant.
+// - ifaceAssign reports whether that assignment is to an interface type.
+// This is important as we want to preserve the concrete type in that
+// assignment. Defaults to 'true'. Notably, if the assigned type is a type
+// parameter, we assume that it could have interface type.
+// - affectsInference is (somewhat vaguely) defined as whether or not the
+// type of the operand may affect the type of the surrounding syntax,
+// through type inference. It is infeasible to completely reverse engineer
+// type inference, so we over approximate: if the expression is an argument
+// to a call to a generic function (but not method!) that uses type
+// parameters, assume that unification of that argument may affect the
+// inferred types.
+func analyzeAssignment(info *types.Info, stack []ast.Node) (assignable, ifaceAssign, affectsInference bool) {
+ remaining, parent, expr := exprContext(stack)
+ if parent == nil {
+ return false, false, false
+ }
+
+ // TODO(golang/go#70638): simplify when types.Info records implicit conversions.
+
+ // Types do not need to match for assignment to a variable.
+ if assign, ok := parent.(*ast.AssignStmt); ok {
+ for i, v := range assign.Rhs {
+ if v == expr {
+ if i >= len(assign.Lhs) {
+ return false, false, false // ill typed
+ }
+ // Check to see if the assignment is to an interface type.
+ if i < len(assign.Lhs) {
+ // TODO: We could handle spread calls here, but in current usage expr
+ // is an ident.
+ if id, _ := assign.Lhs[i].(*ast.Ident); id != nil && info.Defs[id] != nil {
+ // Types must match for a defining identifier in a short variable
+ // declaration.
+ return false, false, false
+ }
+ // In all other cases, types should be known.
+ typ := info.TypeOf(assign.Lhs[i])
+ return true, typ == nil || types.IsInterface(typ), false
+ }
+ // Default:
+ return assign.Tok == token.ASSIGN, true, false
+ }
+ }
+ }
+
+ // Types do not need to match for an initializer with known type.
+ if spec, ok := parent.(*ast.ValueSpec); ok && spec.Type != nil {
+ if slices.Contains(spec.Values, expr) {
+ typ := info.TypeOf(spec.Type)
+ return true, typ == nil || types.IsInterface(typ), false
+ }
+ }
+
+ // Types do not need to match for index expressions.
+ if ix, ok := parent.(*ast.IndexExpr); ok {
+ if ix.Index == expr {
+ typ := info.TypeOf(ix.X)
+ if typ == nil {
+ return true, true, false
+ }
+ m, _ := typeparams.CoreType(typ).(*types.Map)
+ return true, m == nil || types.IsInterface(m.Key()), false
+ }
+ }
+
+ // Types do not need to match for composite literal keys, values, or
+ // fields.
+ if kv, ok := parent.(*ast.KeyValueExpr); ok {
+ var under types.Type
+ if len(remaining) > 0 {
+ if complit, ok := remaining[len(remaining)-1].(*ast.CompositeLit); ok {
+ if typ := info.TypeOf(complit); typ != nil {
+ // Unpointer to allow for pointers to slices or arrays, which are
+ // permitted as the types of nested composite literals without a type
+ // name.
+ under = typesinternal.Unpointer(typeparams.CoreType(typ))
+ }
+ }
+ }
+ if kv.Key == expr { // M{expr: ...}: assign to map key
+ m, _ := under.(*types.Map)
+ return true, m == nil || types.IsInterface(m.Key()), false
+ }
+ if kv.Value == expr {
+ switch under := under.(type) {
+ case interface{ Elem() types.Type }: // T{...: expr}: assign to map/array/slice element
+ return true, types.IsInterface(under.Elem()), false
+ case *types.Struct: // Struct{k: expr}
+ if id, _ := kv.Key.(*ast.Ident); id != nil {
+ for field := range under.Fields() {
+ if info.Uses[id] == field {
+ return true, types.IsInterface(field.Type()), false
+ }
+ }
+ }
+ default:
+ return true, true, false
+ }
+ }
+ }
+ if lit, ok := parent.(*ast.CompositeLit); ok {
+ for i, v := range lit.Elts {
+ if v == expr {
+ typ := info.TypeOf(lit)
+ if typ == nil {
+ return true, true, false
+ }
+ // As in the KeyValueExpr case above, unpointer to handle pointers to
+ // array/slice literals.
+ under := typesinternal.Unpointer(typeparams.CoreType(typ))
+ switch under := under.(type) {
+ case interface{ Elem() types.Type }: // T{expr}: assign to map/array/slice element
+ return true, types.IsInterface(under.Elem()), false
+ case *types.Struct: // Struct{expr}: assign to unkeyed struct field
+ if i < under.NumFields() {
+ return true, types.IsInterface(under.Field(i).Type()), false
+ }
+ }
+ return true, true, false
+ }
+ }
+ }
+
+ // Types do not need to match for values sent to a channel.
+ if send, ok := parent.(*ast.SendStmt); ok {
+ if send.Value == expr {
+ typ := info.TypeOf(send.Chan)
+ if typ == nil {
+ return true, true, false
+ }
+ ch, _ := typeparams.CoreType(typ).(*types.Chan)
+ return true, ch == nil || types.IsInterface(ch.Elem()), false
+ }
+ }
+
+ // Types do not need to match for an argument to a call, unless the
+ // corresponding parameter has type parameters, as in that case the
+ // argument type may affect inference.
+ if call, ok := parent.(*ast.CallExpr); ok {
+ if _, ok := isConversion(info, call); ok {
+ return false, false, false // redundant conversions are handled at the call site
+ }
+ // Ordinary call. Could be a call of a func, builtin, or function value.
+ for i, arg := range call.Args {
+ if arg == expr {
+ typ := info.TypeOf(call.Fun)
+ if typ == nil {
+ return true, true, false
+ }
+ sig, _ := typeparams.CoreType(typ).(*types.Signature)
+ if sig != nil {
+ // Find the relevant parameter type, accounting for variadics.
+ paramType := paramTypeAtIndex(sig, call, i)
+ ifaceAssign := paramType == nil || types.IsInterface(paramType)
+ affectsInference := false
+ switch callee := typeutil.Callee(info, call).(type) {
+ case *types.Builtin:
+ // Consider this litmus test:
+ //
+ // func f(x int64) any { return max(x) }
+ // func main() { fmt.Printf("%T", f(42)) }
+ //
+ // If we lose the implicit conversion from untyped int
+ // to int64, the type inferred for the max(x) call changes,
+ // resulting in a different dynamic behavior: it prints
+ // int, not int64.
+ //
+ // Inferred result type affected:
+ // new
+ // complex, real, imag
+ // min, max
+ //
+ // Dynamic behavior change:
+ // append -- dynamic type of append([]any(nil), x)[0]
+ // delete(m, x) -- dynamic key type where m is map[any]unit
+ // panic -- dynamic type of panic value
+ //
+ // Unaffected:
+ // recover
+ // make
+ // len, cap
+ // clear
+ // close
+ // copy
+ // print, println -- only uses underlying types (?)
+ //
+ // The dynamic type cases are all covered by
+ // the ifaceAssign logic.
+ switch callee.Name() {
+ case "new", "complex", "real", "imag", "min", "max":
+ affectsInference = true
+ }
+
+ case *types.Func:
+ // Only standalone (non-method) functions have type
+ // parameters affected by the call arguments.
+ if sig2 := callee.Signature(); sig2.Recv() == nil {
+ originParamType := paramTypeAtIndex(sig2, call, i)
+ affectsInference = originParamType == nil || new(typeparams.Free).Has(originParamType)
+ }
+ }
+ return true, ifaceAssign, affectsInference
+ }
+ }
+ }
+ }
+
+ return false, false, false
+}
+
+// paramTypeAtIndex returns the effective parameter type at the given argument
+// index in call, if valid.
+func paramTypeAtIndex(sig *types.Signature, call *ast.CallExpr, index int) types.Type {
+ if plen := sig.Params().Len(); sig.Variadic() && index >= plen-1 && !call.Ellipsis.IsValid() {
+ if s, ok := sig.Params().At(plen - 1).Type().(*types.Slice); ok {
+ return s.Elem()
+ }
+ } else if index < plen {
+ return sig.Params().At(index).Type()
+ }
+ return nil // ill typed
+}
+
+// exprContext returns the innermost parent->child expression nodes for the
+// given outer-to-inner stack, after stripping parentheses, along with the
+// remaining stack up to the parent node.
+//
+// If no such context exists, returns (nil, nil, nil).
+func exprContext(stack []ast.Node) (remaining []ast.Node, parent ast.Node, expr ast.Expr) {
+ expr, _ = stack[len(stack)-1].(ast.Expr)
+ if expr == nil {
+ return nil, nil, nil
+ }
+ i := len(stack) - 2
+ for ; i >= 0; i-- {
+ if pexpr, ok := stack[i].(*ast.ParenExpr); ok {
+ expr = pexpr
+ } else {
+ parent = stack[i]
+ break
+ }
+ }
+ if parent == nil {
+ return nil, nil, nil
+ }
+ // inv: i is the index of parent in the stack.
+ return stack[:i], parent, expr
+}
+
+// isSelectionOperand reports whether the innermost node of stack is operand
+// (x) of a selection x.f.
+func isSelectionOperand(stack []ast.Node) bool {
+ _, parent, expr := exprContext(stack)
+ if parent == nil {
+ return false
+ }
+ sel, ok := parent.(*ast.SelectorExpr)
+ return ok && sel.X == expr
+}
+
+// A shadowMap records information about shadowing at any of the parameter's
+// references within the callee decl.
+//
+// For each name shadowed at a reference to the parameter within the callee
+// body, shadow map records the 1-based index of the callee decl parameter
+// causing the shadowing, or -1, if the shadowing is not due to a callee decl.
+// A value of zero (or missing) indicates no shadowing. By convention,
+// self-shadowing is excluded from the map.
+//
+// For example, in the following callee
+//
+// func f(a, b int) int {
+// c := 2 + b
+// return a + c
+// }
+//
+// the shadow map of a is {b: 2, c: -1}, because b is shadowed by the 2nd
+// parameter. The shadow map of b is {a: 1}, because c is not shadowed at the
+// use of b.
+type shadowMap map[string]int
+
+// add returns the [shadowMap] augmented by the set of names
+// locally shadowed at the location of the reference in the callee
+// (identified by the stack). The name of the reference itself is
+// excluded.
+//
+// These shadowed names may not be used in a replacement expression
+// for the reference.
+func (s shadowMap) add(info *types.Info, paramIndexes map[types.Object]int, exclude string, stack []ast.Node) shadowMap {
+ for _, n := range stack {
+ if scope := scopeFor(info, n); scope != nil {
+ for _, name := range scope.Names() {
+ if name != exclude {
+ if s == nil {
+ s = make(shadowMap)
+ }
+ obj := scope.Lookup(name)
+ if idx, ok := paramIndexes[obj]; ok {
+ s[name] = idx + 1
+ } else {
+ s[name] = -1
+ }
+ }
+ }
+ }
+ }
+ return s
+}
+
+var (
+ _ gob.GobEncoder = (*shadowMap)(nil)
+ _ gob.GobDecoder = (*shadowMap)(nil)
+)
+
+// GobEncode implements gob.GobEncoder, encoding the map's entries in a
+// deterministic order so that serialized facts are stable.
+func (s *shadowMap) GobEncode() ([]byte, error) {
+ entries := moremaps.Entries(*s)
+ slices.SortFunc(entries, func(x, y moremaps.Entry[string, int]) int {
+ return cmp.Compare(x.Key, y.Key)
+ })
+ var out bytes.Buffer
+ if err := gob.NewEncoder(&out).Encode(entries); err != nil {
+ return nil, err
+ }
+ return out.Bytes(), nil
+}
+
+func (s *shadowMap) GobDecode(data []byte) error {
+ var entries []moremaps.Entry[string, int]
+ if err := gob.NewDecoder(bytes.NewReader(data)).Decode(&entries); err != nil {
+ return err
+ }
+ *s = moremaps.FromEntries(entries)
+ return nil
+}
+
+// fieldObjs returns a map of each types.Object defined by the given signature
+// to its index in the parameter list. Parameters with missing or blank name
+// are skipped.
+func fieldObjs(sig *types.Signature) map[types.Object]int {
+ m := make(map[types.Object]int)
+ for i := range sig.Params().Len() {
+ if p := sig.Params().At(i); p.Name() != "" && p.Name() != "_" {
+ m[p] = i
+ }
+ }
+ return m
+}
+
+func isField(obj types.Object) bool {
+ if v, ok := obj.(*types.Var); ok && v.IsField() {
+ return true
+ }
+ return false
+}
+
+func isMethod(obj types.Object) bool {
+ if f, ok := obj.(*types.Func); ok && f.Type().(*types.Signature).Recv() != nil {
+ return true
+ }
+ return false
+}
+
+// -- serialization --
+
+var (
+ _ gob.GobEncoder = (*Callee)(nil)
+ _ gob.GobDecoder = (*Callee)(nil)
+)
+
+func (callee *Callee) GobEncode() ([]byte, error) {
+ var out bytes.Buffer
+ if err := gob.NewEncoder(&out).Encode(callee.impl); err != nil {
+ return nil, err
+ }
+ return out.Bytes(), nil
+}
+
+func (callee *Callee) GobDecode(data []byte) error {
+ return gob.NewDecoder(bytes.NewReader(data)).Decode(&callee.impl)
+}
diff --git a/vendor/golang.org/x/tools/internal/refactor/inline/calleefx.go b/vendor/golang.org/x/tools/internal/refactor/inline/calleefx.go
new file mode 100644
index 000000000..6dcf0b975
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/refactor/inline/calleefx.go
@@ -0,0 +1,356 @@
+// Copyright 2023 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 inline
+
+// This file defines the analysis of callee effects.
+
+import (
+ "go/ast"
+ "go/token"
+ "go/types"
+ "slices"
+
+ "golang.org/x/tools/internal/typesinternal"
+)
+
+const (
+ rinf = -1 // R∞: arbitrary read from memory
+ winf = -2 // W∞: arbitrary write to memory (or unknown control)
+)
+
+// calleefx returns a list of parameter indices indicating the order
+// in which parameters are first referenced during evaluation of the
+// callee, relative both to each other and to other effects of the
+// callee (if any), such as arbitrary reads (rinf) and arbitrary
+// effects (winf), including unknown control flow. Each parameter
+// that is referenced appears once in the list.
+//
+// For example, the effects list of this function:
+//
+// func f(x, y, z int) int {
+// return y + x + g() + z
+// }
+//
+// is [1 0 -2 2], indicating reads of y and x, followed by the unknown
+// effects of the g() call, and finally the read of parameter z. This
+// information is used during inlining to ascertain when it is safe
+// for parameter references to be replaced by their corresponding
+// argument expressions. Such substitutions are permitted only when
+// they do not cause "write" operations (those with effects) to
+// commute with "read" operations (those that have no effect but are
+// not pure). Impure operations may be reordered with other impure
+// operations, and pure operations may be reordered arbitrarily.
+//
+// The analysis ignores the effects of runtime panics, on the
+// assumption that well-behaved programs shouldn't encounter them.
+func calleefx(info *types.Info, body *ast.BlockStmt, paramInfos map[*types.Var]*paramInfo) []int {
+ // This traversal analyzes the callee's statements (in syntax
+ // form, though one could do better with SSA) to compute the
+ // sequence of events of the following kinds:
+ //
+ // 1 read of a parameter variable.
+ // 2. reads from other memory.
+ // 3. writes to memory
+
+ var effects []int // indices of parameters, or rinf/winf (-ve)
+ seen := make(map[int]bool)
+ effect := func(i int) {
+ if !seen[i] {
+ seen[i] = true
+ effects = append(effects, i)
+ }
+ }
+
+ // unknown is called for statements of unknown effects (or control).
+ unknown := func() {
+ effect(winf)
+
+ // Ensure that all remaining parameters are "seen"
+ // after we go into the unknown (unless they are
+ // unreferenced by the function body). This lets us
+ // not bother implementing the complete traversal into
+ // control structures.
+
+ // Sort params by Index for determinism
+ sortedParams := make([]*types.Var, 0, len(paramInfos))
+ for obj, pinfo := range paramInfos {
+ if !pinfo.IsResult && len(pinfo.Refs) > 0 {
+ sortedParams = append(sortedParams, obj)
+ }
+ }
+ slices.SortFunc(sortedParams, func(a, b *types.Var) int {
+ return paramInfos[a].Index - paramInfos[b].Index
+ })
+ for _, obj := range sortedParams {
+ effect(paramInfos[obj].Index)
+ }
+ }
+
+ var visitExpr func(n ast.Expr)
+ var visitStmt func(n ast.Stmt) bool
+ visitExpr = func(n ast.Expr) {
+ switch n := n.(type) {
+ case *ast.Ident:
+ if v, ok := info.Uses[n].(*types.Var); ok && !v.IsField() {
+ // Use of global?
+ if v.Parent() == v.Pkg().Scope() {
+ effect(rinf) // read global var
+ }
+
+ // Use of parameter?
+ if pinfo, ok := paramInfos[v]; ok && !pinfo.IsResult {
+ effect(pinfo.Index) // read parameter var
+ }
+
+ // Use of local variables is ok.
+ }
+
+ case *ast.BasicLit:
+ // no effect
+
+ case *ast.FuncLit:
+ // A func literal has no read or write effect
+ // until called, and (most) function calls are
+ // considered to have arbitrary effects.
+ // So, no effect.
+
+ case *ast.CompositeLit:
+ for _, elt := range n.Elts {
+ visitExpr(elt) // note: visits KeyValueExpr
+ }
+
+ case *ast.ParenExpr:
+ visitExpr(n.X)
+
+ case *ast.SelectorExpr:
+ if seln, ok := info.Selections[n]; ok {
+ visitExpr(n.X)
+
+ // See types.SelectionKind for background.
+ switch seln.Kind() {
+ case types.MethodExpr:
+ // A method expression T.f acts like a
+ // reference to a func decl,
+ // so it doesn't read x until called.
+
+ case types.MethodVal, types.FieldVal:
+ // A field or method value selection x.f
+ // reads x if the selection indirects a pointer.
+
+ if indirectSelection(seln) {
+ effect(rinf)
+ }
+ }
+ } else {
+ // qualified identifier: treat like unqualified
+ visitExpr(n.Sel)
+ }
+
+ case *ast.IndexExpr:
+ if tv := info.Types[n.Index]; tv.IsType() {
+ // no effect (G[T] instantiation)
+ } else {
+ visitExpr(n.X)
+ visitExpr(n.Index)
+ switch tv.Type.Underlying().(type) {
+ case *types.Slice, *types.Pointer: // []T, *[n]T (not string, [n]T)
+ effect(rinf) // indirect read of slice/array element
+ }
+ }
+
+ case *ast.IndexListExpr:
+ // no effect (M[K,V] instantiation)
+
+ case *ast.SliceExpr:
+ visitExpr(n.X)
+ visitExpr(n.Low)
+ visitExpr(n.High)
+ visitExpr(n.Max)
+
+ case *ast.TypeAssertExpr:
+ visitExpr(n.X)
+
+ case *ast.CallExpr:
+ if info.Types[n.Fun].IsType() {
+ // conversion T(x)
+ visitExpr(n.Args[0])
+ } else {
+ // call f(args)
+ visitExpr(n.Fun)
+ for i, arg := range n.Args {
+ if i == 0 && info.Types[arg].IsType() {
+ continue // new(T), make(T, n)
+ }
+ visitExpr(arg)
+ }
+
+ // The pure built-ins have no effects beyond
+ // those of their operands (not even memory reads).
+ // All other calls have unknown effects.
+ if !typesinternal.CallsPureBuiltin(info, n) {
+ unknown() // arbitrary effects
+ }
+ }
+
+ case *ast.StarExpr:
+ visitExpr(n.X)
+ effect(rinf) // *ptr load or store depends on state of heap
+
+ case *ast.UnaryExpr: // + - ! ^ & ~ <-
+ visitExpr(n.X)
+ if n.Op == token.ARROW {
+ unknown() // effect: channel receive
+ }
+
+ case *ast.BinaryExpr:
+ visitExpr(n.X)
+ visitExpr(n.Y)
+
+ case *ast.KeyValueExpr:
+ visitExpr(n.Key) // may be a struct field
+ visitExpr(n.Value)
+
+ case *ast.BadExpr:
+ // no effect
+
+ case nil:
+ // optional subtree
+
+ default:
+ // type syntax: unreachable given traversal
+ panic(n)
+ }
+ }
+
+ // visitStmt's result indicates the continuation:
+ // false for return, true for the next statement.
+ //
+ // We could treat return as an unknown, but this way
+ // yields definite effects for simple sequences like
+ // {S1; S2; return}, so unreferenced parameters are
+ // not spuriously added to the effects list, and thus
+ // not spuriously disqualified from elimination.
+ visitStmt = func(n ast.Stmt) bool {
+ switch n := n.(type) {
+ case *ast.DeclStmt:
+ decl := n.Decl.(*ast.GenDecl)
+ for _, spec := range decl.Specs {
+ switch spec := spec.(type) {
+ case *ast.ValueSpec:
+ for _, v := range spec.Values {
+ visitExpr(v)
+ }
+
+ case *ast.TypeSpec:
+ // no effect
+ }
+ }
+
+ case *ast.LabeledStmt:
+ return visitStmt(n.Stmt)
+
+ case *ast.ExprStmt:
+ visitExpr(n.X)
+
+ case *ast.SendStmt:
+ visitExpr(n.Chan)
+ visitExpr(n.Value)
+ unknown() // effect: channel send
+
+ case *ast.IncDecStmt:
+ visitExpr(n.X)
+ unknown() // effect: variable increment
+
+ case *ast.AssignStmt:
+ for _, lhs := range n.Lhs {
+ visitExpr(lhs)
+ }
+ for _, rhs := range n.Rhs {
+ visitExpr(rhs)
+ }
+ for _, lhs := range n.Lhs {
+ id, _ := lhs.(*ast.Ident)
+ if id != nil && id.Name == "_" {
+ continue // blank assign has no effect
+ }
+ if n.Tok == token.DEFINE && id != nil && info.Defs[id] != nil {
+ continue // new var declared by := has no effect
+ }
+ unknown() // assignment to existing var
+ break
+ }
+
+ case *ast.GoStmt:
+ visitExpr(n.Call.Fun)
+ for _, arg := range n.Call.Args {
+ visitExpr(arg)
+ }
+ unknown() // effect: create goroutine
+
+ case *ast.DeferStmt:
+ visitExpr(n.Call.Fun)
+ for _, arg := range n.Call.Args {
+ visitExpr(arg)
+ }
+ unknown() // effect: push defer
+
+ case *ast.ReturnStmt:
+ for _, res := range n.Results {
+ visitExpr(res)
+ }
+ return false
+
+ case *ast.BlockStmt:
+ for _, stmt := range n.List {
+ if !visitStmt(stmt) {
+ return false
+ }
+ }
+
+ case *ast.BranchStmt:
+ unknown() // control flow
+
+ case *ast.IfStmt:
+ visitStmt(n.Init)
+ visitExpr(n.Cond)
+ unknown() // control flow
+
+ case *ast.SwitchStmt:
+ visitStmt(n.Init)
+ visitExpr(n.Tag)
+ unknown() // control flow
+
+ case *ast.TypeSwitchStmt:
+ visitStmt(n.Init)
+ visitStmt(n.Assign)
+ unknown() // control flow
+
+ case *ast.SelectStmt:
+ unknown() // control flow
+
+ case *ast.ForStmt:
+ visitStmt(n.Init)
+ visitExpr(n.Cond)
+ unknown() // control flow
+
+ case *ast.RangeStmt:
+ visitExpr(n.X)
+ unknown() // control flow
+
+ case *ast.EmptyStmt, *ast.BadStmt:
+ // no effect
+
+ case nil:
+ // optional subtree
+
+ default:
+ panic(n)
+ }
+ return true
+ }
+ visitStmt(body)
+
+ return effects
+}
diff --git a/vendor/golang.org/x/tools/internal/refactor/inline/doc.go b/vendor/golang.org/x/tools/internal/refactor/inline/doc.go
new file mode 100644
index 000000000..6bb4cef05
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/refactor/inline/doc.go
@@ -0,0 +1,288 @@
+// Copyright 2023 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 inline implements inlining of Go function calls.
+
+The client provides information about the caller and callee,
+including the source text, syntax tree, and type information, and
+the inliner returns the modified source file for the caller, or an
+error if the inlining operation is invalid (for example because the
+function body refers to names that are inaccessible to the caller).
+
+Although this interface demands more information from the client
+than might seem necessary, it enables smoother integration with
+existing batch and interactive tools that have their own ways of
+managing the processes of reading, parsing, and type-checking
+packages. In particular, this package does not assume that the
+caller and callee belong to the same token.FileSet or
+types.Importer realms.
+
+There are many aspects to a function call. It is the only construct
+that can simultaneously bind multiple variables of different
+explicit types, with implicit assignment conversions. (Neither var
+nor := declarations can do that.) It defines the scope of control
+labels, of return statements, and of defer statements. Arguments
+and results of function calls may be tuples even though tuples are
+not first-class values in Go, and a tuple-valued call expression
+may be "spread" across the argument list of a call or the operands
+of a return statement. All these unique features mean that in the
+general case, not everything that can be expressed by a function
+call can be expressed without one.
+
+So, in general, inlining consists of modifying a function or method
+call expression f(a1, ..., an) so that the name of the function f
+is replaced ("literalized") by a literal copy of the function
+declaration, with free identifiers suitably modified to use the
+locally appropriate identifiers or perhaps constant argument
+values.
+
+Inlining must not change the semantics of the call. Semantics
+preservation is crucial for clients such as codebase maintenance
+tools that automatically inline all calls to designated functions
+on a large scale. Such tools must not introduce subtle behavior
+changes. (Fully inlining a call is dynamically observable using
+reflection over the call stack, but this exception to the rule is
+explicitly allowed.)
+
+In many cases it is possible to entirely replace ("reduce") the
+call by a copy of the function's body in which parameters have been
+replaced by arguments. The inliner supports a number of reduction
+strategies, and we expect this set to grow. Nonetheless, sound
+reduction is surprisingly tricky.
+
+The inliner is in some ways like an optimizing compiler. A compiler
+is considered correct if it doesn't change the meaning of the
+program in translation from source language to target language. An
+optimizing compiler exploits the particulars of the input to
+generate better code, where "better" usually means more efficient.
+When a case is found in which it emits suboptimal code, the
+compiler is improved to recognize more cases, or more rules, and
+more exceptions to rules; this process has no end. Inlining is
+similar except that "better" code means tidier code. The baseline
+translation (literalization) is correct, but there are endless
+rules--and exceptions to rules--by which the output can be
+improved.
+
+The following section lists some of the challenges, and ways in
+which they can be addressed.
+
+ - All effects of the call argument expressions must be preserved,
+ both in their number (they must not be eliminated or repeated),
+ and in their order (both with respect to other arguments, and any
+ effects in the callee function).
+
+ This must be the case even if the corresponding parameters are
+ never referenced, are referenced multiple times, referenced in
+ a different order from the arguments, or referenced within a
+ nested function that may be executed an arbitrary number of
+ times.
+
+ Currently, parameter replacement is not applied to arguments
+ with effects, but with further analysis of the sequence of
+ strict effects within the callee we could relax this constraint.
+
+ - When not all parameters can be substituted by their arguments
+ (e.g. due to possible effects), if the call appears in a
+ statement context, the inliner may introduce a var declaration
+ that declares the parameter variables (with the correct types)
+ and assigns them to their corresponding argument values.
+ The rest of the function body may then follow.
+ For example, the call
+
+ f(1, 2)
+
+ to the function
+
+ func f(x, y int32) { stmts }
+
+ may be reduced to
+
+ { var x, y int32 = 1, 2; stmts }.
+
+ There are many reasons why this is not always possible. For
+ example, true parameters are statically resolved in the same
+ scope, and are dynamically assigned their arguments in
+ parallel; but each spec in a var declaration is statically
+ resolved in sequence and dynamically executed in sequence, so
+ earlier parameters may shadow references in later ones.
+
+ - Even an argument expression as simple as ptr.x may not be
+ referentially transparent, because another argument may have the
+ effect of changing the value of ptr.
+
+ This constraint could be relaxed by some kind of alias or
+ escape analysis that proves that ptr cannot be mutated during
+ the call.
+
+ - Although constants are referentially transparent, as a matter of
+ style we do not wish to duplicate literals that are referenced
+ multiple times in the body because this undoes proper factoring.
+ Also, string literals may be arbitrarily large.
+
+ - If the function body consists of statements other than just
+ "return expr", in some contexts it may be syntactically
+ impossible to reduce the call. Consider:
+
+ if x := f(); cond { ... }
+
+ Go has no equivalent to Lisp's progn or Rust's blocks,
+ nor ML's let expressions (let param = arg in body);
+ its closest equivalent is func(param){body}(arg).
+ Reduction strategies must therefore consider the syntactic
+ context of the call.
+
+ In such situations we could work harder to extract a statement
+ context for the call, by transforming it to:
+
+ { x := f(); if cond { ... } }
+
+ - Similarly, without the equivalent of Rust-style blocks and
+ first-class tuples, there is no general way to reduce a call
+ to a function such as
+
+ func(params)(args)(results) { stmts; return expr }
+
+ to an expression such as
+
+ { var params = args; stmts; expr }
+
+ or even a statement such as
+
+ results = { var params = args; stmts; expr }
+
+ Consequently the declaration and scope of the result variables,
+ and the assignment and control-flow implications of the return
+ statement, must be dealt with by cases.
+
+ - A standalone call statement that calls a function whose body is
+ "return expr" cannot be simply replaced by the body expression
+ if it is not itself a call or channel receive expression; it is
+ necessary to explicitly discard the result using "_ = expr".
+
+ Similarly, if the body is a call expression, only calls to some
+ built-in functions with no result (such as copy or panic) are
+ permitted as statements, whereas others (such as append) return
+ a result that must be used, even if just by discarding.
+
+ - If a parameter or result variable is updated by an assignment
+ within the function body, it cannot always be safely replaced
+ by a variable in the caller. For example, given
+
+ func f(a int) int { a++; return a }
+
+ The call y = f(x) cannot be replaced by { x++; y = x } because
+ this would change the value of the caller's variable x.
+ Only if the caller is finished with x is this safe.
+
+ A similar argument applies to parameter or result variables
+ that escape: by eliminating a variable, inlining would change
+ the identity of the variable that escapes.
+
+ - If the function body uses 'defer' and the inlined call is not a
+ tail-call, inlining may delay the deferred effects.
+
+ - Because the scope of a control label is the entire function, a
+ call cannot be reduced if the caller and callee have intersecting
+ sets of control labels. (It is possible to α-rename any
+ conflicting ones, but our colleagues building C++ refactoring
+ tools report that, when tools must choose new identifiers, they
+ generally do a poor job.)
+
+ - Given
+
+ func f() uint8 { return 0 }
+
+ var x any = f()
+
+ reducing the call to var x any = 0 is unsound because it
+ discards the implicit conversion to uint8. We may need to make
+ each argument-to-parameter conversion explicit if the types
+ differ. Assignments to variadic parameters may need to
+ explicitly construct a slice.
+
+ An analogous problem applies to the implicit assignments in
+ return statements:
+
+ func g() any { return f() }
+
+ Replacing the call f() with 0 would silently lose a
+ conversion to uint8 and change the behavior of the program.
+
+ - When inlining a call f(1, x, g()) where those parameters are
+ unreferenced, we should be able to avoid evaluating 1 and x
+ since they are pure and thus have no effect. But x may be the
+ last reference to a local variable in the caller, so removing
+ it would cause a compilation error. Parameter substitution must
+ avoid making the caller's local variables unreferenced (or must
+ be prepared to eliminate the declaration too---this is where an
+ iterative framework for simplification would really help).
+
+ - An expression such as s[i] may be valid if s and i are
+ variables but invalid if either or both of them are constants.
+ For example, a negative constant index s[-1] is always out of
+ bounds, and even a non-negative constant index may be out of
+ bounds depending on the particular string constant (e.g.
+ "abc"[4]).
+
+ So, if a parameter participates in any expression that is
+ subject to additional compile-time checks when its operands are
+ constant, it may be unsafe to substitute that parameter by a
+ constant argument value (#62664).
+
+More complex callee functions are inlinable with more elaborate and
+invasive changes to the statements surrounding the call expression.
+
+TODO(adonovan): future work:
+
+ - Handle more of the above special cases by careful analysis,
+ thoughtful factoring of the large design space, and thorough
+ test coverage.
+
+ - Compute precisely (not conservatively) when parameter
+ substitution would remove the last reference to a caller local
+ variable, and blank out the local instead of retreating from
+ the substitution.
+
+ - Afford the client more control such as a limit on the total
+ increase in line count, or a refusal to inline using the
+ general approach (replacing name by function literal). This
+ could be achieved by returning metadata alongside the result
+ and having the client conditionally discard the change.
+
+ - Support inlining of generic functions, replacing type parameters
+ by their instantiations.
+
+ - Support inlining of calls to function literals ("closures").
+ But note that the existing algorithm makes widespread assumptions
+ that the callee is a package-level function or method.
+
+ - Eliminate explicit conversions of "untyped" literals inserted
+ conservatively when they are redundant. For example, the
+ conversion int32(1) is redundant when this value is used only as a
+ slice index; but it may be crucial if it is used in x := int32(1)
+ as it changes the type of x, which may have further implications.
+ The conversions may also be important to the falcon analysis.
+
+ - Allow non-'go' build systems such as Bazel/Blaze a chance to
+ decide whether an import is accessible using logic other than
+ "/internal/" path segments. This could be achieved by returning
+ the list of added import paths instead of a text diff.
+
+ - Inlining a function from another module may change the
+ effective version of the Go language spec that governs it. We
+ should probably make the client responsible for rejecting
+ attempts to inline from newer callees to older callers, since
+ there's no way for this package to access module versions.
+
+ - Use an alternative implementation of the import-organizing
+ operation that doesn't require operating on a complete file
+ (and reformatting). Then return the results in a higher-level
+ form as a set of import additions and deletions plus a single
+ diff that encloses the call expression. This interface could
+ perhaps be implemented atop imports.Process by post-processing
+ its result to obtain the abstract import changes and discarding
+ its formatted output.
+*/
+package inline
diff --git a/vendor/golang.org/x/tools/internal/refactor/inline/escape.go b/vendor/golang.org/x/tools/internal/refactor/inline/escape.go
new file mode 100644
index 000000000..45cce11a9
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/refactor/inline/escape.go
@@ -0,0 +1,102 @@
+// Copyright 2023 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 inline
+
+import (
+ "fmt"
+ "go/ast"
+ "go/token"
+ "go/types"
+)
+
+// escape implements a simple "address-taken" escape analysis. It
+// calls f for each local variable that appears on the left side of an
+// assignment (escapes=false) or has its address taken (escapes=true).
+// The initialization of a variable by its declaration does not count
+// as an assignment.
+func escape(info *types.Info, root ast.Node, f func(v *types.Var, escapes bool)) {
+
+ // lvalue is called for each address-taken expression or LHS of assignment.
+ // Supported forms are: x, (x), x[i], x.f, *x, T{}.
+ var lvalue func(e ast.Expr, escapes bool)
+ lvalue = func(e ast.Expr, escapes bool) {
+ switch e := e.(type) {
+ case *ast.Ident:
+ if v, ok := info.Uses[e].(*types.Var); ok {
+ if !isPkgLevel(v) {
+ f(v, escapes)
+ }
+ }
+ case *ast.ParenExpr:
+ lvalue(e.X, escapes)
+ case *ast.IndexExpr:
+ // TODO(adonovan): support generics without assuming e.X has a core type.
+ // Consider:
+ //
+ // func Index[T interface{ [3]int | []int }](t T, i int) *int {
+ // return &t[i]
+ // }
+ //
+ // We must traverse the normal terms and check
+ // whether any of them is an array.
+ //
+ // We assume TypeOf returns non-nil.
+ if _, ok := info.TypeOf(e.X).Underlying().(*types.Array); ok {
+ lvalue(e.X, escapes) // &a[i] on array
+ }
+ case *ast.SelectorExpr:
+ // We assume TypeOf returns non-nil.
+ if _, ok := info.TypeOf(e.X).Underlying().(*types.Struct); ok {
+ lvalue(e.X, escapes) // &s.f on struct
+ }
+ case *ast.StarExpr:
+ // *ptr indirects an existing pointer
+ case *ast.CompositeLit:
+ // &T{...} creates a new variable
+ default:
+ panic(fmt.Sprintf("&x on %T", e)) // unreachable in well-typed code
+ }
+ }
+
+ // Search function body for operations &x, x.f(), x++, and x = y
+ // where x is a parameter. Each of these treats x as an address.
+ ast.Inspect(root, func(n ast.Node) bool {
+ switch n := n.(type) {
+ case *ast.UnaryExpr:
+ if n.Op == token.AND {
+ lvalue(n.X, true) // &x
+ }
+
+ case *ast.CallExpr:
+ // implicit &x in method call x.f(),
+ // where x has type T and method is (*T).f
+ if sel, ok := n.Fun.(*ast.SelectorExpr); ok {
+ if seln, ok := info.Selections[sel]; ok &&
+ seln.Kind() == types.MethodVal &&
+ isPointer(seln.Obj().Type().Underlying().(*types.Signature).Recv().Type()) {
+ tArg, indirect := effectiveReceiver(seln)
+ if !indirect && !isPointer(tArg) {
+ lvalue(sel.X, true) // &x.f
+ }
+ }
+ }
+
+ case *ast.AssignStmt:
+ for _, lhs := range n.Lhs {
+ if id, ok := lhs.(*ast.Ident); ok &&
+ info.Defs[id] != nil &&
+ n.Tok == token.DEFINE {
+ // declaration: doesn't count
+ } else {
+ lvalue(lhs, false)
+ }
+ }
+
+ case *ast.IncDecStmt:
+ lvalue(n.X, false)
+ }
+ return true
+ })
+}
diff --git a/vendor/golang.org/x/tools/internal/refactor/inline/falcon.go b/vendor/golang.org/x/tools/internal/refactor/inline/falcon.go
new file mode 100644
index 000000000..884a807a0
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/refactor/inline/falcon.go
@@ -0,0 +1,889 @@
+// Copyright 2023 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 inline
+
+// This file defines the callee side of the "fallible constant" analysis.
+
+import (
+ "fmt"
+ "go/ast"
+ "go/constant"
+ "go/format"
+ "go/token"
+ "go/types"
+ "slices"
+ "strconv"
+ "strings"
+
+ "golang.org/x/tools/go/types/typeutil"
+ "golang.org/x/tools/internal/typeparams"
+)
+
+// falconResult is the result of the analysis of the callee.
+type falconResult struct {
+ Types []falconType // types for falcon constraint environment
+ Constraints []string // constraints (Go expressions) on values of fallible constants
+}
+
+// A falconType specifies the name and underlying type of a synthetic
+// defined type for use in falcon constraints.
+//
+// Unique types from callee code are bijectively mapped onto falcon
+// types so that constraints are independent of callee type
+// information but preserve type equivalence classes.
+//
+// Fresh names are deliberately obscure to avoid shadowing even if a
+// callee parameter has a name like "int" or "any".
+type falconType struct {
+ Name string
+ Kind types.BasicKind // string/number/bool
+}
+
+// falcon identifies "fallible constant" expressions, which are
+// expressions that may fail to compile if one or more of their
+// operands is changed from non-constant to constant.
+//
+// Consider:
+//
+// func sub(s string, i, j int) string { return s[i:j] }
+//
+// If parameters are replaced by constants, the compiler is
+// required to perform these additional checks:
+//
+// - if i is constant, 0 <= i.
+// - if s and i are constant, i <= len(s).
+// - ditto for j.
+// - if i and j are constant, i <= j.
+//
+// s[i:j] is thus a "fallible constant" expression dependent on {s, i,
+// j}. Each falcon creates a set of conditional constraints across one
+// or more parameter variables.
+//
+// - When inlining a call such as sub("abc", -1, 2), the parameter i
+// cannot be eliminated by substitution as its argument value is
+// negative.
+//
+// - When inlining sub("", 2, 1), all three parameters cannot be
+// simultaneously eliminated by substitution without violating i
+// <= len(s) and j <= len(s), but the parameters i and j could be
+// safely eliminated without s.
+//
+// Parameters that cannot be eliminated must remain non-constant,
+// either in the form of a binding declaration:
+//
+// { var i int = -1; return "abc"[i:2] }
+//
+// or a parameter of a literalization:
+//
+// func (i int) string { return "abc"[i:2] }(-1)
+//
+// These example expressions are obviously doomed to fail at run
+// time, but in realistic cases such expressions are dominated by
+// appropriate conditions that make them reachable only when safe:
+//
+// if 0 <= i && i <= j && j <= len(s) { _ = s[i:j] }
+//
+// (In principle a more sophisticated inliner could entirely eliminate
+// such unreachable blocks based on the condition being always-false
+// for the given parameter substitution, but this is tricky to do safely
+// because the type-checker considers only a single configuration.
+// Consider: if runtime.GOOS == "linux" { ... }.)
+//
+// We believe this is an exhaustive list of "fallible constant" operations:
+//
+// - switch z { case x: case y } // duplicate case values
+// - s[i], s[i:j], s[i:j:k] // index out of bounds (0 <= i <= j <= k <= len(s))
+// - T{x: 0} // index out of bounds, duplicate index
+// - x/y, x%y, x/=y, x%=y // integer division by zero; minint/-1 overflow
+// - x+y, x-y, x*y // arithmetic overflow
+// - x< 1 {
+ var elts []ast.Expr
+ for _, elem := range elems {
+ elts = append(elts, &ast.KeyValueExpr{
+ Key: elem,
+ Value: makeIntLit(0),
+ })
+ }
+ st.emit(&ast.CompositeLit{
+ Type: typ,
+ Elts: elts,
+ })
+ }
+}
+
+// -- traversal --
+
+// The traversal functions scan the callee body for expressions that
+// are not constant but would become constant if the parameter vars
+// were redeclared as constants, and emits for each one a constraint
+// (a Go expression) with the property that it will not type-check
+// (using types.CheckExpr) if the particular argument values are
+// unsuitable.
+//
+// These constraints are checked by Inline with the actual
+// constant argument values. Violations cause it to reject
+// parameters as candidates for substitution.
+
+func (st *falconState) stmt(s ast.Stmt) {
+ ast.Inspect(s, func(n ast.Node) bool {
+ switch n := n.(type) {
+ case ast.Expr:
+ _ = st.expr(n)
+ return false // skip usual traversal
+
+ case *ast.AssignStmt:
+ switch n.Tok {
+ case token.QUO_ASSIGN, token.REM_ASSIGN:
+ // x /= y
+ // Possible "integer division by zero"
+ // Emit constraint: 1/y.
+ _ = st.expr(n.Lhs[0])
+ kY := st.expr(n.Rhs[0])
+ if kY, ok := kY.(ast.Expr); ok {
+ op := token.QUO
+ if n.Tok == token.REM_ASSIGN {
+ op = token.REM
+ }
+ st.emit(&ast.BinaryExpr{
+ Op: op,
+ X: makeIntLit(1),
+ Y: kY,
+ })
+ }
+ return false // skip usual traversal
+ }
+
+ case *ast.SwitchStmt:
+ if n.Init != nil {
+ st.stmt(n.Init)
+ }
+ tBool := types.Type(types.Typ[types.Bool])
+ tagType := tBool // default: true
+ if n.Tag != nil {
+ st.expr(n.Tag)
+ tagType = st.info.TypeOf(n.Tag)
+ }
+
+ // Possible "duplicate case value".
+ // Emit constraint map[T]int{v1: 0, ..., vN:0}
+ // to ensure all maybe-constant case values are unique
+ // (unless switch tag is boolean, which is relaxed).
+ var unique []ast.Expr
+ for _, clause := range n.Body.List {
+ clause := clause.(*ast.CaseClause)
+ for _, caseval := range clause.List {
+ if k := st.expr(caseval); k != nil {
+ unique = append(unique, st.toExpr(k))
+ }
+ }
+ for _, stmt := range clause.Body {
+ st.stmt(stmt)
+ }
+ }
+ if unique != nil && !types.Identical(tagType.Underlying(), tBool) {
+ tname := st.any
+ if !types.IsInterface(tagType) {
+ tname = st.typename(tagType)
+ }
+ t := &ast.MapType{
+ Key: makeIdent(tname),
+ Value: makeIdent(st.int),
+ }
+ st.emitUnique(t, unique)
+ }
+ }
+ return true
+ })
+}
+
+// fieldTypes visits the .Type of each field in the list.
+func (st *falconState) fieldTypes(fields *ast.FieldList) {
+ if fields != nil {
+ for _, field := range fields.List {
+ _ = st.expr(field.Type)
+ }
+ }
+}
+
+// expr visits the expression (or type) and returns a
+// non-nil result if the expression is constant or would
+// become constant if all suitable function parameters were
+// redeclared as constants.
+//
+// If the expression is constant, st.expr returns its type
+// and value (types.TypeAndValue). If the expression would
+// become constant, st.expr returns an ast.Expr tree whose
+// leaves are literals and parameter references, and whose
+// interior nodes are operations that may become constant,
+// such as -x, x+y, f(x), and T(x). We call these would-be
+// constant expressions "fallible constants", since they may
+// fail to type-check for some values of x, i, and j. (We
+// refer to the non-nil cases collectively as "maybe
+// constant", and the nil case as "definitely non-constant".)
+//
+// As a side effect, st.expr emits constraints for each
+// fallible constant expression; this is its main purpose.
+//
+// Consequently, st.expr must visit the entire subtree so
+// that all necessary constraints are emitted. It may not
+// short-circuit the traversal when it encounters a constant
+// subexpression as constants may contain arbitrary other
+// syntax that may impose constraints. Consider (as always)
+// this contrived but legal example of a type parameter (!)
+// that contains statement syntax:
+//
+// func f[T [unsafe.Sizeof(func() { stmts })]int]()
+//
+// There is no need to emit constraints for (e.g.) s[i] when s
+// and i are already constants, because we know the expression
+// is sound, but it is sometimes easier to emit these
+// redundant constraints than to avoid them.
+func (st *falconState) expr(e ast.Expr) (res any) { // = types.TypeAndValue | ast.Expr
+ tv := st.info.Types[e]
+ if tv.Value != nil {
+ // A constant value overrides any other result.
+ defer func() { res = tv }()
+ }
+
+ switch e := e.(type) {
+ case *ast.Ident:
+ if v, ok := st.info.Uses[e].(*types.Var); ok {
+ if _, ok := st.params[v]; ok && isBasic(v.Type(), types.IsConstType) {
+ return e // reference to constable parameter
+ }
+ }
+ // (References to *types.Const are handled by the defer.)
+
+ case *ast.BasicLit:
+ // constant
+
+ case *ast.ParenExpr:
+ return st.expr(e.X)
+
+ case *ast.FuncLit:
+ _ = st.expr(e.Type)
+ st.stmt(e.Body)
+ // definitely non-constant
+
+ case *ast.CompositeLit:
+ // T{k: v, ...}, where T ∈ {array,*array,slice,map},
+ // imposes a constraint that all constant k are
+ // distinct and, for arrays [n]T, within range 0-n.
+ //
+ // Types matter, not just values. For example,
+ // an interface-keyed map may contain keys
+ // that are numerically equal so long as they
+ // are of distinct types. For example:
+ //
+ // type myint int
+ // map[any]bool{1: true, 1: true} // error: duplicate key
+ // map[any]bool{1: true, int16(1): true} // ok
+ // map[any]bool{1: true, myint(1): true} // ok
+ //
+ // This can be asserted by emitting a
+ // constraint of the form T{k1: 0, ..., kN: 0}.
+ if e.Type != nil {
+ _ = st.expr(e.Type)
+ }
+ t := types.Unalias(typeparams.Deref(tv.Type))
+ ct := typeparams.CoreType(t)
+ var mapKeys []ast.Expr // map key expressions; must be distinct if constant
+ for _, elt := range e.Elts {
+ if kv, ok := elt.(*ast.KeyValueExpr); ok {
+ if is[*types.Map](ct) {
+ if k := st.expr(kv.Key); k != nil {
+ mapKeys = append(mapKeys, st.toExpr(k))
+ }
+ }
+ _ = st.expr(kv.Value)
+ } else {
+ _ = st.expr(elt)
+ }
+ }
+ if len(mapKeys) > 0 {
+ // Inlining a map literal may replace variable key expressions by constants.
+ // All such constants must have distinct values.
+ // (Array and slice literals do not permit non-constant keys.)
+ t := ct.(*types.Map)
+ var typ ast.Expr
+ if types.IsInterface(t.Key()) {
+ typ = &ast.MapType{
+ Key: makeIdent(st.any),
+ Value: makeIdent(st.int),
+ }
+ } else {
+ typ = &ast.MapType{
+ Key: makeIdent(st.typename(t.Key())),
+ Value: makeIdent(st.int),
+ }
+ }
+ st.emitUnique(typ, mapKeys)
+ }
+ // definitely non-constant
+
+ case *ast.SelectorExpr:
+ _ = st.expr(e.X)
+ _ = st.expr(e.Sel)
+ // The defer is sufficient to handle
+ // qualified identifiers (pkg.Const).
+ // All other cases are definitely non-constant.
+
+ case *ast.IndexExpr:
+ if tv.IsType() {
+ // type C[T]
+ _ = st.expr(e.X)
+ _ = st.expr(e.Index)
+ } else {
+ // term x[i]
+ //
+ // Constraints (if x is slice/string/array/*array, not map):
+ // - i >= 0
+ // if i is a fallible constant
+ // - i < len(x)
+ // if x is array/*array and
+ // i is a fallible constant;
+ // or if s is a string and both i,
+ // s are maybe-constants,
+ // but not both are constants.
+ kX := st.expr(e.X)
+ kI := st.expr(e.Index)
+ if kI != nil && !is[*types.Map](st.info.TypeOf(e.X).Underlying()) {
+ if kI, ok := kI.(ast.Expr); ok {
+ st.emitNonNegative(kI)
+ }
+ // Emit constraint to check indices against known length.
+ // TODO(adonovan): factor with SliceExpr logic.
+ var x ast.Expr
+ if kX != nil {
+ // string
+ x = st.toExpr(kX)
+ } else if arr, ok := typeparams.CoreType(typeparams.Deref(st.info.TypeOf(e.X))).(*types.Array); ok {
+ // array, *array
+ x = &ast.CompositeLit{
+ Type: &ast.ArrayType{
+ Len: makeIntLit(arr.Len()),
+ Elt: makeIdent(st.int),
+ },
+ }
+ }
+ if x != nil {
+ st.emit(&ast.IndexExpr{
+ X: x,
+ Index: st.toExpr(kI),
+ })
+ }
+ }
+ }
+ // definitely non-constant
+
+ case *ast.SliceExpr:
+ // x[low:high:max]
+ //
+ // Emit non-negative constraints for each index,
+ // plus low <= high <= max <= len(x)
+ // for each pair that are maybe-constant
+ // but not definitely constant.
+
+ kX := st.expr(e.X)
+ var kLow, kHigh, kMax any
+ if e.Low != nil {
+ kLow = st.expr(e.Low)
+ if kLow != nil {
+ if kLow, ok := kLow.(ast.Expr); ok {
+ st.emitNonNegative(kLow)
+ }
+ }
+ }
+ if e.High != nil {
+ kHigh = st.expr(e.High)
+ if kHigh != nil {
+ if kHigh, ok := kHigh.(ast.Expr); ok {
+ st.emitNonNegative(kHigh)
+ }
+ if kLow != nil {
+ st.emitMonotonic(st.toExpr(kLow), st.toExpr(kHigh))
+ }
+ }
+ }
+ if e.Max != nil {
+ kMax = st.expr(e.Max)
+ if kMax != nil {
+ if kMax, ok := kMax.(ast.Expr); ok {
+ st.emitNonNegative(kMax)
+ }
+ if kHigh != nil {
+ st.emitMonotonic(st.toExpr(kHigh), st.toExpr(kMax))
+ }
+ }
+ }
+
+ // Emit constraint to check indices against known length.
+ var x ast.Expr
+ if kX != nil {
+ // string
+ x = st.toExpr(kX)
+ } else if arr, ok := typeparams.CoreType(typeparams.Deref(st.info.TypeOf(e.X))).(*types.Array); ok {
+ // array, *array
+ x = &ast.CompositeLit{
+ Type: &ast.ArrayType{
+ Len: makeIntLit(arr.Len()),
+ Elt: makeIdent(st.int),
+ },
+ }
+ }
+ if x != nil {
+ // Avoid slice[::max] if kHigh is nonconstant (nil).
+ high, max := st.toExpr(kHigh), st.toExpr(kMax)
+ if high == nil {
+ high = max // => slice[:max:max]
+ }
+ st.emit(&ast.SliceExpr{
+ X: x,
+ Low: st.toExpr(kLow),
+ High: high,
+ Max: max,
+ })
+ }
+ // definitely non-constant
+
+ case *ast.TypeAssertExpr:
+ _ = st.expr(e.X)
+ if e.Type != nil {
+ _ = st.expr(e.Type)
+ }
+
+ case *ast.CallExpr:
+ _ = st.expr(e.Fun)
+ if tv, ok := st.info.Types[e.Fun]; ok && tv.IsType() {
+ // conversion T(x)
+ //
+ // Possible "value out of range".
+ kX := st.expr(e.Args[0])
+ if kX != nil && isBasic(tv.Type, types.IsConstType) {
+ conv := convert(makeIdent(st.typename(tv.Type)), st.toExpr(kX))
+ if is[ast.Expr](kX) {
+ st.emit(conv)
+ }
+ return conv
+ }
+ return nil // definitely non-constant
+ }
+
+ // call f(x)
+
+ all := true // all args are possibly-constant
+ kArgs := make([]ast.Expr, len(e.Args))
+ for i, arg := range e.Args {
+ if kArg := st.expr(arg); kArg != nil {
+ kArgs[i] = st.toExpr(kArg)
+ } else {
+ all = false
+ }
+ }
+
+ // Calls to built-ins with fallibly constant arguments
+ // may become constant. All other calls are either
+ // constant or non-constant
+ if id, ok := e.Fun.(*ast.Ident); ok && all && tv.Value == nil {
+ if builtin, ok := st.info.Uses[id].(*types.Builtin); ok {
+ switch builtin.Name() {
+ case "len", "imag", "real", "complex", "min", "max":
+ return &ast.CallExpr{
+ Fun: id,
+ Args: kArgs,
+ Ellipsis: e.Ellipsis,
+ }
+ }
+ }
+ }
+
+ case *ast.StarExpr: // *T, *ptr
+ _ = st.expr(e.X)
+
+ case *ast.UnaryExpr:
+ // + - ! ^ & <- ~
+ //
+ // Possible "negation of minint".
+ // Emit constraint: -x
+ kX := st.expr(e.X)
+ if kX != nil && !is[types.TypeAndValue](kX) {
+ if e.Op == token.SUB {
+ st.emit(&ast.UnaryExpr{
+ Op: e.Op,
+ X: st.toExpr(kX),
+ })
+ }
+
+ return &ast.UnaryExpr{
+ Op: e.Op,
+ X: st.toExpr(kX),
+ }
+ }
+
+ case *ast.BinaryExpr:
+ kX := st.expr(e.X)
+ kY := st.expr(e.Y)
+ switch e.Op {
+ case token.QUO, token.REM:
+ // x/y, x%y
+ //
+ // Possible "integer division by zero" or
+ // "minint / -1" overflow.
+ // Emit constraint: x/y or 1/y
+ if kY != nil {
+ if kX == nil {
+ kX = makeIntLit(1)
+ }
+ st.emit(&ast.BinaryExpr{
+ Op: e.Op,
+ X: st.toExpr(kX),
+ Y: st.toExpr(kY),
+ })
+ }
+
+ case token.ADD, token.SUB, token.MUL:
+ // x+y, x-y, x*y
+ //
+ // Possible "arithmetic overflow".
+ // Emit constraint: x+y
+ if kX != nil && kY != nil {
+ st.emit(&ast.BinaryExpr{
+ Op: e.Op,
+ X: st.toExpr(kX),
+ Y: st.toExpr(kY),
+ })
+ }
+
+ case token.SHL, token.SHR:
+ // x << y, x >> y
+ //
+ // Possible "constant shift too large".
+ // Either operand may be too large individually,
+ // and they may be too large together.
+ // Emit constraint:
+ // x << y (if both maybe-constant)
+ // x << 0 (if y is non-constant)
+ // 1 << y (if x is non-constant)
+ if kX != nil || kY != nil {
+ x := st.toExpr(kX)
+ if x == nil {
+ x = makeIntLit(1)
+ }
+ y := st.toExpr(kY)
+ if y == nil {
+ y = makeIntLit(0)
+ }
+ st.emit(&ast.BinaryExpr{
+ Op: e.Op,
+ X: x,
+ Y: y,
+ })
+ }
+
+ case token.LSS, token.GTR, token.EQL, token.NEQ, token.LEQ, token.GEQ:
+ // < > == != <= <=
+ //
+ // A "x cmp y" expression with constant operands x, y is
+ // itself constant, but I can't see how a constant bool
+ // could be fallible: the compiler doesn't reject duplicate
+ // boolean cases in a switch, presumably because boolean
+ // switches are less like n-way branches and more like
+ // sequential if-else chains with possibly overlapping
+ // conditions; and there is (sadly) no way to convert a
+ // boolean constant to an int constant.
+ }
+ if kX != nil && kY != nil {
+ return &ast.BinaryExpr{
+ Op: e.Op,
+ X: st.toExpr(kX),
+ Y: st.toExpr(kY),
+ }
+ }
+
+ // types
+ //
+ // We need to visit types (and even type parameters)
+ // in order to reach all the places where things could go wrong:
+ //
+ // const (
+ // s = ""
+ // i = 0
+ // )
+ // type C[T [unsafe.Sizeof(func() { _ = s[i] })]int] bool
+
+ case *ast.IndexListExpr:
+ _ = st.expr(e.X)
+ for _, expr := range e.Indices {
+ _ = st.expr(expr)
+ }
+
+ case *ast.Ellipsis:
+ if e.Elt != nil {
+ _ = st.expr(e.Elt)
+ }
+
+ case *ast.ArrayType:
+ if e.Len != nil {
+ _ = st.expr(e.Len)
+ }
+ _ = st.expr(e.Elt)
+
+ case *ast.StructType:
+ st.fieldTypes(e.Fields)
+
+ case *ast.FuncType:
+ st.fieldTypes(e.TypeParams)
+ st.fieldTypes(e.Params)
+ st.fieldTypes(e.Results)
+
+ case *ast.InterfaceType:
+ st.fieldTypes(e.Methods)
+
+ case *ast.MapType:
+ _ = st.expr(e.Key)
+ _ = st.expr(e.Value)
+
+ case *ast.ChanType:
+ _ = st.expr(e.Value)
+ }
+ return
+}
+
+// toExpr converts the result of visitExpr to a falcon expression.
+// (We don't do this in visitExpr as we first need to discriminate
+// constants from maybe-constants.)
+func (st *falconState) toExpr(x any) ast.Expr {
+ switch x := x.(type) {
+ case nil:
+ return nil
+
+ case types.TypeAndValue:
+ lit := makeLiteral(x.Value)
+ if !isBasic(x.Type, types.IsUntyped) {
+ // convert to "typed" type
+ lit = &ast.CallExpr{
+ Fun: makeIdent(st.typename(x.Type)),
+ Args: []ast.Expr{lit},
+ }
+ }
+ return lit
+
+ case ast.Expr:
+ return x
+
+ default:
+ panic(x)
+ }
+}
+
+func makeLiteral(v constant.Value) ast.Expr {
+ switch v.Kind() {
+ case constant.Bool:
+ // Rather than refer to the true or false built-ins,
+ // which could be shadowed by poorly chosen parameter
+ // names, we use 0 == 0 for true and 0 != 0 for false.
+ op := token.EQL
+ if !constant.BoolVal(v) {
+ op = token.NEQ
+ }
+ return &ast.BinaryExpr{
+ Op: op,
+ X: makeIntLit(0),
+ Y: makeIntLit(0),
+ }
+
+ case constant.String:
+ return &ast.BasicLit{
+ Kind: token.STRING,
+ Value: v.ExactString(),
+ }
+
+ case constant.Int:
+ return &ast.BasicLit{
+ Kind: token.INT,
+ Value: v.ExactString(),
+ }
+
+ case constant.Float:
+ return &ast.BasicLit{
+ Kind: token.FLOAT,
+ Value: v.ExactString(),
+ }
+
+ case constant.Complex:
+ // The components could be float or int.
+ y := makeLiteral(constant.Imag(v))
+ y.(*ast.BasicLit).Value += "i" // ugh
+ if re := constant.Real(v); !consteq(re, kZeroInt) {
+ // complex: x + yi
+ y = &ast.BinaryExpr{
+ Op: token.ADD,
+ X: makeLiteral(re),
+ Y: y,
+ }
+ }
+ return y
+
+ default:
+ panic(v.Kind())
+ }
+}
+
+func makeIntLit(x int64) *ast.BasicLit {
+ return &ast.BasicLit{
+ Kind: token.INT,
+ Value: strconv.FormatInt(x, 10),
+ }
+}
+
+func isBasic(t types.Type, info types.BasicInfo) bool {
+ basic, ok := t.Underlying().(*types.Basic)
+ return ok && basic.Info()&info != 0
+}
diff --git a/vendor/golang.org/x/tools/internal/refactor/inline/inline.go b/vendor/golang.org/x/tools/internal/refactor/inline/inline.go
new file mode 100644
index 000000000..b329ab6f5
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/refactor/inline/inline.go
@@ -0,0 +1,3557 @@
+// Copyright 2023 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 inline
+
+import (
+ "bytes"
+ "fmt"
+ "go/ast"
+ "go/constant"
+ "go/format"
+ "go/parser"
+ "go/token"
+ "go/types"
+ "maps"
+ pathpkg "path"
+ "reflect"
+ "slices"
+ "strings"
+
+ "golang.org/x/tools/go/ast/astutil"
+ "golang.org/x/tools/go/types/typeutil"
+ internalastutil "golang.org/x/tools/internal/astutil"
+ "golang.org/x/tools/internal/astutil/free"
+ "golang.org/x/tools/internal/packagepath"
+ "golang.org/x/tools/internal/refactor"
+ "golang.org/x/tools/internal/typeparams"
+ "golang.org/x/tools/internal/typesinternal"
+ "golang.org/x/tools/internal/versions"
+)
+
+// A Caller describes the function call and its enclosing context.
+//
+// The client is responsible for populating this struct and passing it to Inline.
+type Caller struct {
+ Fset *token.FileSet
+ Types *types.Package
+ Info *types.Info
+ File *ast.File
+ Call *ast.CallExpr
+
+ // CountUses is an optional optimized computation of
+ // the number of times pkgname appears in Info.Uses.
+ CountUses func(pkgname *types.PkgName) int
+
+ path []ast.Node // path from call to root of file syntax tree
+ enclosingFunc *ast.FuncDecl // top-level function/method enclosing the call, if any
+}
+
+type logger = func(string, ...any)
+
+// Options specifies parameters affecting the inliner algorithm.
+// All fields are optional.
+type Options struct {
+ Logf logger // log output function, records decision-making process
+ IgnoreEffects bool // ignore potential side effects of arguments (unsound)
+}
+
+// Result holds the result of code transformation.
+type Result struct {
+ Edits []refactor.Edit // edits around CallExpr and imports
+ Literalized bool // chosen strategy replaced callee() with func(){...}()
+ BindingDecl bool // transformation added "var params = args" declaration
+}
+
+// Inline inlines the called function (callee) into the function call (caller)
+// and returns the updated, formatted content of the caller source file.
+//
+// Inline does not mutate any public fields of Caller or Callee.
+func Inline(caller *Caller, callee *Callee, opts *Options) (*Result, error) {
+ copy := *opts // shallow copy
+ opts = ©
+ // Set default options.
+ if opts.Logf == nil {
+ opts.Logf = func(string, ...any) {}
+ }
+
+ st := &state{
+ caller: caller,
+ callee: callee,
+ opts: opts,
+ }
+ return st.inline()
+}
+
+// state holds the working state of the inliner.
+type state struct {
+ caller *Caller
+ callee *Callee
+ opts *Options
+}
+
+func (st *state) inline() (*Result, error) {
+ logf, caller, callee := st.opts.Logf, st.caller, st.callee
+
+ logf("inline %s @ %v",
+ debugFormatNode(caller.Fset, caller.Call),
+ caller.Fset.PositionFor(caller.Call.Lparen, false))
+
+ if ast.IsGenerated(caller.File) {
+ return nil, fmt.Errorf("cannot inline calls from generated files")
+ }
+
+ res, err := st.inlineCall()
+ if err != nil {
+ return nil, err
+ }
+
+ // Replace the call (or some node that encloses it) by new syntax.
+ assert(res.old != nil, "old is nil")
+ assert(res.new != nil, "new is nil")
+
+ // A single return operand inlined to a unary
+ // expression context may need parens. Otherwise:
+ // func two() int { return 1+1 }
+ // print(-two()) => print(-1+1) // oops!
+ //
+ // Usually it is not necessary to insert ParenExprs
+ // as the formatter is smart enough to insert them as
+ // needed by the context. But the res.{old,new}
+ // substitution is done by formatting res.new in isolation
+ // and then splicing its text over res.old, so the
+ // formatter doesn't see the parent node and cannot do
+ // the right thing. (One solution would be to always
+ // format the enclosing node of old, but that requires
+ // non-lossy comment handling, #20744.)
+ //
+ // So, we must analyze the call's context
+ // to see whether ambiguity is possible.
+ // For example, if the context is x[y:z], then
+ // the x subtree is subject to precedence ambiguity
+ // (replacing x by p+q would give p+q[y:z] which is wrong)
+ // but the y and z subtrees are safe.
+ if new, ok := res.new.(ast.Expr); ok {
+ parent := caller.path[slices.Index(caller.path, res.old)+1]
+ res.new = internalastutil.MaybeParenthesize(parent, res.old.(ast.Expr), new)
+ }
+
+ // Some reduction strategies return a new block holding the
+ // callee's statements. The block's braces may be elided when
+ // there is no conflict between names declared in the block
+ // with those declared by the parent block, and no risk of
+ // a caller's goto jumping forward across a declaration.
+ //
+ // This elision is only safe when the ExprStmt is beneath a
+ // BlockStmt, CaseClause.Body, or CommClause.Body;
+ // (see "statement theory").
+ //
+ // The inlining analysis may have already determined that eliding braces is
+ // safe. Otherwise, we analyze its safety here.
+ elideBraces := res.elideBraces
+ if !elideBraces {
+ if newBlock, ok := res.new.(*ast.BlockStmt); ok {
+ i := slices.Index(caller.path, res.old)
+ parent := caller.path[i+1]
+ var body []ast.Stmt
+ switch parent := parent.(type) {
+ case *ast.BlockStmt:
+ body = parent.List
+ case *ast.CommClause:
+ body = parent.Body
+ case *ast.CaseClause:
+ body = parent.Body
+ }
+ if body != nil {
+ callerNames := declares(body)
+
+ // If BlockStmt is a function body,
+ // include its receiver, params, and results.
+ addFieldNames := func(fields *ast.FieldList) {
+ if fields != nil {
+ for _, field := range fields.List {
+ for _, id := range field.Names {
+ callerNames[id.Name] = true
+ }
+ }
+ }
+ }
+ switch f := caller.path[i+2].(type) {
+ case *ast.FuncDecl:
+ addFieldNames(f.Recv)
+ addFieldNames(f.Type.Params)
+ addFieldNames(f.Type.Results)
+ case *ast.FuncLit:
+ addFieldNames(f.Type.Params)
+ addFieldNames(f.Type.Results)
+ }
+
+ if len(callerLabels(caller.path)) > 0 {
+ // TODO(adonovan): be more precise and reject
+ // only forward gotos across the inlined block.
+ logf("keeping block braces: caller uses control labels")
+ } else if intersects(declares(newBlock.List), callerNames) {
+ logf("keeping block braces: avoids name conflict")
+ } else {
+ elideBraces = true
+ }
+ }
+ }
+ }
+
+ var edits []refactor.Edit
+
+ // Format the cloned callee.
+ {
+ // TODO(adonovan): might it make more sense to use
+ // callee.Fset when formatting res.new?
+ // The new tree is a mix of (cloned) caller nodes for
+ // the argument expressions and callee nodes for the
+ // function body. In essence the question is: which
+ // is more likely to have comments?
+ // Usually the callee body will be larger and more
+ // statement-heavy than the arguments, but a
+ // strategy may widen the scope of the replacement
+ // (res.old) from CallExpr to, say, its enclosing
+ // block, so the caller nodes dominate.
+ // Precise comment handling would make this a
+ // non-issue. Formatting wouldn't really need a
+ // FileSet at all.
+
+ var out bytes.Buffer
+ if elideBraces {
+ for i, stmt := range res.new.(*ast.BlockStmt).List {
+ if i > 0 {
+ out.WriteByte('\n')
+ }
+ if err := format.Node(&out, caller.Fset, stmt); err != nil {
+ return nil, err
+ }
+ }
+ } else {
+ if err := format.Node(&out, caller.Fset, res.new); err != nil {
+ return nil, err
+ }
+ }
+
+ edits = append(edits, refactor.Edit{
+ Pos: res.old.Pos(),
+ End: res.old.End(),
+ NewText: out.Bytes(),
+ })
+ }
+
+ // Add new imports.
+ //
+ // It's possible that not all are needed (e.g. for type names
+ // that melted away), but we'll let the client (such as an
+ // analysis driver) clean it up since it must remove unused
+ // imports anyway.
+ for _, imp := range res.newImports {
+ // Check that the new imports are accessible.
+ if !packagepath.CanImport(caller.Types.Path(), imp.path) {
+ return nil, fmt.Errorf("can't inline function %v as its body refers to inaccessible package %q", callee, imp.path)
+ }
+
+ // We've already validated the import, so we call
+ // AddImportEdits directly to compute the edit.
+ name := ""
+ if imp.explicit {
+ name = imp.name
+ }
+ edits = append(edits, refactor.AddImportEdits(caller.File, name, imp.path)...)
+ }
+
+ literalized := false
+ if call, ok := res.new.(*ast.CallExpr); ok && is[*ast.FuncLit](call.Fun) {
+ literalized = true
+ }
+
+ // Delete imports referenced only by caller.Call.Fun.
+ //
+ // It's ambiguous to let the client (e.g. analysis driver)
+ // remove unneeded imports in this case because it is common
+ // to inlining a call from "dir1/a".F to "dir2/a".F, which
+ // leaves two imports of packages named 'a', both providing a.F.
+ //
+ // However, the only two import deletion tools at our disposal
+ // are astutil.DeleteNamedImport, which mutates the AST, and
+ // refactor.Delete{Spec,Decl}, which need a Cursor. So we need
+ // to reinvent the wheel here.
+ for _, oldImport := range res.oldImports {
+ spec := oldImport.spec
+
+ // Include adjacent comments.
+ pos := spec.Pos()
+ if doc := spec.Doc; doc != nil {
+ pos = doc.Pos()
+ }
+ end := spec.End()
+ if doc := spec.Comment; doc != nil {
+ end = doc.End()
+ }
+
+ // Find the enclosing import decl.
+ // If it's paren-less, we must delete it too.
+ for _, decl := range caller.File.Decls {
+ decl, ok := decl.(*ast.GenDecl)
+ if !(ok && decl.Tok == token.IMPORT) {
+ break // stop at first non-import decl
+ }
+ if internalastutil.NodeContainsPos(decl, spec.Pos()) && !decl.Rparen.IsValid() {
+ // Include adjacent comments.
+ pos = decl.Pos()
+ if doc := decl.Doc; doc != nil {
+ pos = doc.Pos()
+ }
+ end = decl.End()
+ break
+ }
+ }
+
+ edits = append(edits, refactor.Edit{
+ Pos: pos,
+ End: end,
+ })
+ }
+
+ return &Result{
+ Edits: edits,
+ Literalized: literalized,
+ BindingDecl: res.bindingDecl,
+ }, nil
+}
+
+// An oldImport is an import that will be deleted from the caller file.
+type oldImport struct {
+ pkgName *types.PkgName
+ spec *ast.ImportSpec
+}
+
+// A newImport is an import that will be added to the caller file.
+type newImport struct {
+ name string
+ path string
+ explicit bool // use name as ImportSpec.Name
+}
+
+// importState tracks information about imports.
+type importState struct {
+ logf func(string, ...any)
+ caller *Caller
+ importMap map[string][]string // from package paths in the caller's file to local names
+ newImports []newImport // for references to free names in callee; to be added to the file
+ oldImports []oldImport // referenced only by caller.Call.Fun; to be removed from the file
+}
+
+// newImportState returns an importState with initial information about the caller's imports.
+func newImportState(logf func(string, ...any), caller *Caller, callee *gobCallee) *importState {
+ // For simplicity we ignore existing dot imports, so that a qualified
+ // identifier (QI) in the callee is always represented by a QI in the caller,
+ // allowing us to treat a QI like a selection on a package name.
+ ist := &importState{
+ logf: logf,
+ caller: caller,
+ importMap: make(map[string][]string),
+ }
+
+ // Provide an inefficient default implementation of CountUses.
+ // (Ideally clients amortize this for the entire package.)
+ countUses := caller.CountUses
+ if countUses == nil {
+ uses := make(map[*types.PkgName]int)
+ for _, obj := range caller.Info.Uses {
+ if pkgname, ok := obj.(*types.PkgName); ok {
+ uses[pkgname]++
+ }
+ }
+ countUses = func(pkgname *types.PkgName) int {
+ return uses[pkgname]
+ }
+ }
+
+ for _, imp := range caller.File.Imports {
+ if pkgName, ok := importedPkgName(caller.Info, imp); ok &&
+ pkgName.Name() != "." &&
+ pkgName.Name() != "_" {
+
+ // If the import's sole use is in caller.Call.Fun of the form p.F(...),
+ // where p.F is a qualified identifier, the p import may not be
+ // necessary.
+ //
+ // Only the qualified identifier case matters, as other references to
+ // imported package names in the Call.Fun expression (e.g.
+ // x.after(3*time.Second).f() or time.Second.String()) will remain after
+ // inlining, as arguments.
+ //
+ // If that is the case, proactively check if any of the callee FreeObjs
+ // need this import. Doing so eagerly simplifies the resulting logic.
+ needed := true
+ if sel, ok := ast.Unparen(caller.Call.Fun).(*ast.SelectorExpr); ok &&
+ is[*ast.Ident](sel.X) &&
+ caller.Info.Uses[sel.X.(*ast.Ident)] == pkgName &&
+ countUses(pkgName) == 1 {
+ needed = false // no longer needed by caller
+ // Check to see if any of the inlined free objects need this package.
+ for _, obj := range callee.FreeObjs {
+ if obj.PkgPath == pkgName.Imported().Path() && obj.Shadow[pkgName.Name()] == 0 {
+ needed = true // needed by callee
+ break
+ }
+ }
+ }
+
+ // Exclude imports not needed by the caller or callee after inlining; the second
+ // return value holds these.
+ if needed {
+ path := pkgName.Imported().Path()
+ ist.importMap[path] = append(ist.importMap[path], pkgName.Name())
+ } else {
+ ist.oldImports = append(ist.oldImports, oldImport{pkgName: pkgName, spec: imp})
+ }
+ }
+ }
+ return ist
+}
+
+// importName finds an existing import name to use in a particular shadowing
+// context. It is used to determine the set of new imports in
+// localName, and is also used for writing out names in inlining
+// strategies below.
+func (i *importState) importName(pkgPath string, shadow shadowMap) string {
+ for _, name := range i.importMap[pkgPath] {
+ // Check that either the import preexisted, or that it was newly added
+ // (no PkgName) but is not shadowed, either in the callee (shadows) or
+ // caller (caller.lookup).
+ if shadow[name] == 0 {
+ found := i.caller.lookup(name)
+ if is[*types.PkgName](found) || found == nil {
+ return name
+ }
+ }
+ }
+ return ""
+}
+
+// findNewLocalName returns a new local package name to use in a particular shadowing context.
+// It considers the existing local name used by the callee, or construct a new local name
+// based on the package name.
+func (i *importState) findNewLocalName(pkgName, calleePkgName string, shadow shadowMap) string {
+ newlyAdded := func(name string) bool {
+ return slices.ContainsFunc(i.newImports, func(n newImport) bool { return n.name == name })
+ }
+
+ // shadowedInCaller reports whether a candidate package name
+ // already refers to a declaration in the caller.
+ shadowedInCaller := func(name string) bool {
+ obj := i.caller.lookup(name)
+ if obj == nil {
+ return false
+ }
+ // If obj will be removed, the name is available.
+ return !slices.ContainsFunc(i.oldImports, func(o oldImport) bool { return o.pkgName == obj })
+ }
+
+ // import added by callee
+ //
+ // Try to preserve the local package name used by the callee first.
+ //
+ // If that is shadowed, choose a local package name based on last segment of
+ // package path plus, if needed, a numeric suffix to ensure uniqueness.
+ //
+ // "init" is not a legal PkgName.
+ if shadow[calleePkgName] == 0 && !shadowedInCaller(calleePkgName) && !newlyAdded(calleePkgName) && calleePkgName != "init" {
+ return calleePkgName
+ }
+
+ base := pkgName
+ name := base
+ for n := 0; shadow[name] != 0 || shadowedInCaller(name) || newlyAdded(name) || name == "init"; n++ {
+ name = fmt.Sprintf("%s%d", base, n)
+ }
+
+ return name
+}
+
+// localName returns the local name for a given imported package path,
+// adding one if it doesn't exists.
+func (i *importState) localName(pkgPath, pkgName, calleePkgName string, shadow shadowMap) string {
+ // Does an import already exist that works in this shadowing context?
+ if name := i.importName(pkgPath, shadow); name != "" {
+ return name
+ }
+
+ name := i.findNewLocalName(pkgName, calleePkgName, shadow)
+ i.logf("adding import %s %q", name, pkgPath)
+ // Use explicit pkgname (out of necessity) when it differs from the declared name,
+ // or (for good style) when it differs from base(pkgpath).
+ i.newImports = append(i.newImports, newImport{
+ name: name,
+ path: pkgPath,
+ explicit: name != pkgName || name != pathpkg.Base(pkgPath),
+ })
+ i.importMap[pkgPath] = append(i.importMap[pkgPath], name)
+ return name
+}
+
+type inlineCallResult struct {
+ newImports []newImport // to add
+ oldImports []oldImport // to remove
+
+ // If elideBraces is set, old is an ast.Stmt and new is an ast.BlockStmt to
+ // be spliced in. This allows the inlining analysis to assert that inlining
+ // the block is OK; if elideBraces is unset and old is an ast.Stmt and new is
+ // an ast.BlockStmt, braces may still be elided if the post-processing
+ // analysis determines that it is safe to do so.
+ //
+ // Ideally, it would not be necessary for the inlining analysis to "reach
+ // through" to the post-processing pass in this way. Instead, inlining could
+ // just set old to be an ast.BlockStmt and rewrite the entire BlockStmt, but
+ // unfortunately in order to preserve comments, it is important that inlining
+ // replace as little syntax as possible.
+ elideBraces bool
+ bindingDecl bool // transformation inserted "var params = args" declaration
+ old, new ast.Node // e.g. replace call expr by callee function body expression
+}
+
+// inlineCall returns a pair of an old node (the call, or something
+// enclosing it) and a new node (its replacement, which may be a
+// combination of caller, callee, and new nodes), along with the set
+// of new imports needed.
+//
+// TODO(adonovan): rethink the 'result' interface. The assumption of a
+// one-to-one replacement seems fragile. One can easily imagine the
+// transformation replacing the call and adding new variable
+// declarations, for example, or replacing a call statement by zero or
+// many statements.)
+// NOTE(rfindley): we've sort-of done this, with the 'elideBraces' flag that
+// allows inlining a statement list. However, due to loss of comments, more
+// sophisticated rewrites are challenging.
+//
+// TODO(rfindley): see if we can reduce the amount of comment lossiness by
+// using printer.CommentedNode, which has been useful elsewhere.
+//
+// TODO(rfindley): inlineCall is getting very long, and very stateful, making
+// it very hard to read. The following refactoring may improve readability and
+// maintainability:
+// - Rename 'state' to 'callsite', since that is what it encapsulates.
+// - Add results of pre-processing analysis into the callsite struct, such as
+// the effective importMap, new/old imports, arguments, etc. Essentially
+// anything that resulted from initial analysis of the call site, and which
+// may be useful to inlining strategies.
+// - Delegate this call site analysis to a constructor or initializer, such
+// as 'analyzeCallsite', so that it does not consume bandwidth in the
+// 'inlineCall' logical flow.
+// - Once analyzeCallsite returns, the callsite is immutable, much in the
+// same way as the Callee and Caller are immutable.
+// - Decide on a standard interface for strategies (and substrategies), such
+// that they may be delegated to a separate method on callsite.
+//
+// In this way, the logical flow of inline call will clearly follow the
+// following structure:
+// 1. Analyze the call site.
+// 2. Try strategies, in order, until one succeeds.
+// 3. Process the results.
+//
+// If any expensive analysis may be avoided by earlier strategies, it can be
+// encapsulated in its own type and passed to subsequent strategies.
+func (st *state) inlineCall() (*inlineCallResult, error) {
+ logf, caller, callee := st.opts.Logf, st.caller, &st.callee.impl
+
+ checkInfoFields(caller.Info)
+
+ // Inlining of dynamic calls is not currently supported,
+ // even for local closure calls. (This would be a lot of work.)
+ calleeSymbol := typeutil.StaticCallee(caller.Info, caller.Call)
+ if calleeSymbol == nil {
+ // e.g. interface method
+ return nil, fmt.Errorf("cannot inline: not a static function call")
+ }
+
+ // Reject cross-package inlining if callee has
+ // free references to unexported symbols.
+ samePkg := caller.Types.Path() == callee.PkgPath
+ if !samePkg && len(callee.Unexported) > 0 {
+ return nil, fmt.Errorf("cannot inline call to %s because body refers to non-exported %s",
+ callee.Name, callee.Unexported[0])
+ }
+
+ // Reject cross-file inlining if callee requires a newer dialect of Go (#75726).
+ // (Versions default to types.Config.GoVersion, which is unset in many tests,
+ // though should be populated by an analysis driver.)
+ callerGoVersion := caller.Info.FileVersions[caller.File]
+ if callerGoVersion != "" && callee.GoVersion != "" && versions.Before(callerGoVersion, callee.GoVersion) {
+ return nil, fmt.Errorf("cannot inline call to %s (declared using %s) into a file using %s",
+ callee.Name, callee.GoVersion, callerGoVersion)
+ }
+
+ // -- analyze callee's free references in caller context --
+
+ // Compute syntax path enclosing Call, innermost first (Path[0]=Call),
+ // and outermost enclosing function, if any.
+ caller.path, _ = astutil.PathEnclosingInterval(caller.File, caller.Call.Pos(), caller.Call.End())
+ for _, n := range caller.path {
+ if decl, ok := n.(*ast.FuncDecl); ok {
+ caller.enclosingFunc = decl
+ break
+ }
+ }
+
+ // If call is within a function, analyze all its
+ // local vars for the "single assignment" property.
+ // (Taking the address &v counts as a potential assignment.)
+ var assign1 func(v *types.Var) bool // reports whether v a single-assignment local var
+ {
+ updatedLocals := make(map[*types.Var]bool)
+ if caller.enclosingFunc != nil {
+ escape(caller.Info, caller.enclosingFunc, func(v *types.Var, _ bool) {
+ updatedLocals[v] = true
+ })
+ logf("multiple-assignment vars: %v", updatedLocals)
+ }
+ assign1 = func(v *types.Var) bool { return !updatedLocals[v] }
+ }
+
+ // Extract information about the caller's imports.
+ istate := newImportState(logf, caller, callee)
+
+ // Compute the renaming of the callee's free identifiers.
+ objRenames, err := st.renameFreeObjs(istate)
+ if err != nil {
+ return nil, err
+ }
+
+ res := &inlineCallResult{
+ newImports: istate.newImports,
+ oldImports: istate.oldImports,
+ }
+
+ // Parse callee function declaration.
+ calleeFset, calleeDecl, err := parseCompact(callee.Content)
+ if err != nil {
+ return nil, err // "can't happen"
+ }
+
+ // replaceCalleeID replaces an identifier in the callee. See [replacer] for
+ // more detailed semantics.
+ replaceCalleeID := func(offset int, repl ast.Expr, unpackVariadic bool) {
+ path, id := findIdent(calleeDecl, calleeDecl.Pos()+token.Pos(offset))
+ logf("- replace id %q @ #%d to %q", id.Name, offset, debugFormatNode(calleeFset, repl))
+ // Replace f([]T{a, b, c}...) with f(a, b, c).
+ if lit, ok := repl.(*ast.CompositeLit); ok && unpackVariadic && len(path) > 0 {
+ if call, ok := last(path).(*ast.CallExpr); ok &&
+ call.Ellipsis.IsValid() &&
+ id == last(call.Args) {
+
+ call.Args = append(call.Args[:len(call.Args)-1], lit.Elts...)
+ call.Ellipsis = token.NoPos
+ return
+ }
+ }
+ if len(path) > 0 {
+ repl = internalastutil.MaybeParenthesize(last(path), id, repl)
+ }
+ replaceNode(calleeDecl, id, repl)
+ }
+
+ // Generate replacements for each free identifier.
+ // (The same tree may be spliced in multiple times, resulting in a DAG.)
+ for _, ref := range callee.FreeRefs {
+ if repl := objRenames[ref.Object]; repl != nil {
+ replaceCalleeID(ref.Offset, repl, false)
+ }
+ }
+
+ // Gather the effective call arguments, including the receiver.
+ // Later, elements will be eliminated (=> nil) by parameter substitution.
+ args, err := st.arguments(caller, calleeDecl, assign1)
+ if err != nil {
+ return nil, err // e.g. implicit field selection cannot be made explicit
+ }
+
+ // Gather effective parameter tuple, including the receiver if any.
+ // Simplify variadic parameters to slices (in all cases but one).
+ var params []*parameter // including receiver; nil => parameter substituted
+ {
+ sig := calleeSymbol.Type().(*types.Signature)
+ if sig.Recv() != nil {
+ params = append(params, ¶meter{
+ obj: sig.Recv(),
+ fieldType: calleeDecl.Recv.List[0].Type,
+ info: callee.Params[0],
+ })
+ }
+
+ // Flatten the list of syntactic types.
+ var types []ast.Expr
+ for _, field := range calleeDecl.Type.Params.List {
+ if field.Names == nil {
+ types = append(types, field.Type)
+ } else {
+ for range field.Names {
+ types = append(types, field.Type)
+ }
+ }
+ }
+
+ for i := 0; i < sig.Params().Len(); i++ {
+ params = append(params, ¶meter{
+ obj: sig.Params().At(i),
+ fieldType: types[i],
+ info: callee.Params[len(params)],
+ })
+ }
+
+ // Variadic function?
+ //
+ // There are three possible types of call:
+ // - ordinary f(a1, ..., aN)
+ // - ellipsis f(a1, ..., slice...)
+ // - spread f(recv?, g()) where g() is a tuple.
+ // The first two are desugared to non-variadic calls
+ // with an ordinary slice parameter;
+ // the third is tricky and cannot be reduced, and (if
+ // a receiver is present) cannot even be literalized.
+ // Fortunately it is vanishingly rare.
+ //
+ // TODO(adonovan): extract this to a function.
+ if sig.Variadic() {
+ lastParam := last(params)
+ if len(args) > 0 && last(args).spread {
+ // spread call to variadic: tricky
+ lastParam.variadic = true
+ } else {
+ // ordinary/ellipsis call to variadic
+
+ // simplify decl: func(T...) -> func([]T)
+ lastParamField := last(calleeDecl.Type.Params.List)
+ lastParamField.Type = &ast.ArrayType{
+ Elt: lastParamField.Type.(*ast.Ellipsis).Elt,
+ }
+
+ if caller.Call.Ellipsis.IsValid() {
+ // ellipsis call: f(slice...) -> f(slice)
+ // nop
+ } else {
+ // ordinary call: f(a1, ... aN) -> f([]T{a1, ..., aN})
+ //
+ // Substitution of []T{...} in the callee body may lead to
+ // g([]T{a1, ..., aN}...), which we simplify to g(a1, ..., an)
+ // later; see replaceCalleeID.
+ n := len(params) - 1
+ ordinary, extra := args[:n], args[n:]
+ var elts []ast.Expr
+ freevars := make(map[string]bool)
+ pure, effects := true, false
+ for _, arg := range extra {
+ elts = append(elts, arg.expr)
+ pure = pure && arg.pure
+ effects = effects || arg.effects
+ maps.Copy(freevars, arg.freevars)
+ }
+ args = append(ordinary, &argument{
+ expr: &ast.CompositeLit{
+ Type: lastParamField.Type,
+ Elts: elts,
+ },
+ typ: lastParam.obj.Type(),
+ constant: nil,
+ pure: pure,
+ effects: effects,
+ duplicable: false,
+ freevars: freevars,
+ variadic: true,
+ })
+ }
+ }
+ }
+ }
+
+ // Substitute type parameters in calleeDecl AST with type arguments from the
+ // call, and synchronize the parameter metadata.
+ {
+ typeArgs := st.typeArguments(caller.Call)
+ if len(typeArgs) != len(callee.TypeParams) {
+ return nil, fmt.Errorf("cannot inline: type parameter inference is not yet supported")
+ }
+ if err := substituteTypeParams(logf, callee.TypeParams, typeArgs, replaceCalleeID); err != nil {
+ return nil, err
+ }
+ // Synchronize the parameters' type pointers with the mutated calleeDecl.
+ syncParamFieldTypes(calleeDecl, params)
+ }
+
+ // Log effective arguments.
+ for i, arg := range args {
+ logf("arg #%d: %s pure=%t effects=%t duplicable=%t free=%v type=%v",
+ i, debugFormatNode(caller.Fset, arg.expr),
+ arg.pure, arg.effects, arg.duplicable, arg.freevars, arg.typ)
+ }
+
+ // Note: computation below should be expressed in terms of
+ // the args and params slices, not the raw material.
+
+ // Perform parameter substitution.
+ // May eliminate some elements of params/args.
+ substitute(logf, caller, params, args, callee.Effects, callee.Falcon, replaceCalleeID)
+
+ // Update the callee's signature syntax.
+ updateCalleeParams(calleeDecl, params)
+
+ // Create a var (param = arg; ...) decl for use by some strategies.
+ bindingDecl := createBindingDecl(logf, caller, args, calleeDecl, callee.Results)
+
+ var remainingArgs []ast.Expr
+ for _, arg := range args {
+ if arg != nil {
+ remainingArgs = append(remainingArgs, arg.expr)
+ }
+ }
+
+ // -- let the inlining strategies begin --
+ //
+ // When we commit to a strategy, we log a message of the form:
+ //
+ // "strategy: reduce expr-context call to { return expr }"
+ //
+ // This is a terse way of saying:
+ //
+ // we plan to reduce a call
+ // that appears in expression context
+ // to a function whose body is of the form { return expr }
+
+ // TODO(adonovan): split this huge function into a sequence of
+ // function calls with an error sentinel that means "try the
+ // next strategy", and make sure each strategy writes to the
+ // log the reason it didn't match.
+
+ // Special case: eliminate a call to a function whose body is empty.
+ // (=> callee has no results and caller is a statement.)
+ //
+ // func f(params) {}
+ // f(args)
+ // => _, _ = args
+ //
+ if len(calleeDecl.Body.List) == 0 {
+ logf("strategy: reduce call to empty body")
+
+ // Evaluate the arguments for effects and delete the call entirely.
+ // Note(golang/go#71486): stmt can be nil if the call is in a go or defer
+ // statement.
+ // TODO: discard go or defer statements as well.
+ if stmt := callStmt(caller.path, false); stmt != nil {
+ res.old = stmt
+ if nargs := len(remainingArgs); nargs > 0 {
+ // Emit "_, _ = args" to discard results.
+
+ // TODO(adonovan): if args is the []T{a1, ..., an}
+ // literal synthesized during variadic simplification,
+ // consider unwrapping it to its (pure) elements.
+ // Perhaps there's no harm doing this for any slice literal.
+
+ // Make correction for spread calls
+ // f(g()) or recv.f(g()) where g() is a tuple.
+ if last := last(args); last != nil && last.spread {
+ nspread := last.typ.(*types.Tuple).Len()
+ if len(args) > 1 { // [recv, g()]
+ // A single AssignStmt cannot discard both, so use a 2-spec var decl.
+ res.new = &ast.GenDecl{
+ Tok: token.VAR,
+ Specs: []ast.Spec{
+ &ast.ValueSpec{
+ Names: []*ast.Ident{makeIdent("_")},
+ Values: []ast.Expr{args[0].expr},
+ },
+ &ast.ValueSpec{
+ Names: blanks[*ast.Ident](nspread),
+ Values: []ast.Expr{args[1].expr},
+ },
+ },
+ }
+ return res, nil
+ }
+
+ // Sole argument is spread call.
+ nargs = nspread
+ }
+
+ res.new = &ast.AssignStmt{
+ Lhs: blanks[ast.Expr](nargs),
+ Tok: token.ASSIGN,
+ Rhs: remainingArgs,
+ }
+
+ } else {
+ // No remaining arguments: delete call statement entirely
+ res.new = &ast.EmptyStmt{}
+ }
+ return res, nil
+ }
+ }
+
+ // If all parameters have been substituted and no result
+ // variable is referenced, we don't need a binding decl.
+ // This may enable better reduction strategies.
+ allResultsUnreferenced := forall(callee.Results, func(i int, r *paramInfo) bool { return len(r.Refs) == 0 })
+ needBindingDecl := !allResultsUnreferenced ||
+ exists(params, func(i int, p *parameter) bool { return p != nil })
+
+ // The two strategies below overlap for a tail call of {return exprs}:
+ // The expr-context reduction is nice because it keeps the
+ // caller's return stmt and merely switches its operand,
+ // without introducing a new block, but it doesn't work with
+ // implicit return conversions.
+ //
+ // TODO(adonovan): unify these cases more cleanly, allowing return-
+ // operand replacement and implicit conversions, by adding
+ // conversions around each return operand (if not a spread return).
+
+ // Special case: call to { return exprs }.
+ //
+ // Reduces to:
+ // { var (bindings); _, _ = exprs }
+ // or _, _ = exprs
+ // or expr
+ //
+ // If:
+ // - the body is just "return expr" with trivial implicit conversions,
+ // or the caller's return type matches the callee's,
+ // - all parameters and result vars can be eliminated
+ // or replaced by a binding decl,
+ // then the call expression can be replaced by the
+ // callee's body expression, suitably substituted.
+ if len(calleeDecl.Body.List) == 1 &&
+ is[*ast.ReturnStmt](calleeDecl.Body.List[0]) &&
+ len(calleeDecl.Body.List[0].(*ast.ReturnStmt).Results) > 0 { // not a bare return
+ results := calleeDecl.Body.List[0].(*ast.ReturnStmt).Results
+
+ parent, grandparent := callContext(caller.path)
+
+ // statement context
+ if stmt, ok := parent.(*ast.ExprStmt); ok &&
+ (!needBindingDecl || bindingDecl != nil) {
+ logf("strategy: reduce stmt-context call to { return exprs }")
+ clearPositions(calleeDecl.Body)
+
+ if callee.ValidForCallStmt {
+ logf("callee body is valid as statement")
+ // Inv: len(results) == 1
+ if !needBindingDecl {
+ // Reduces to: expr
+ res.old = caller.Call
+ res.new = results[0]
+ } else {
+ // Reduces to: { var (bindings); expr }
+ res.bindingDecl = true
+ res.old = stmt
+ res.new = &ast.BlockStmt{
+ List: []ast.Stmt{
+ bindingDecl.stmt,
+ &ast.ExprStmt{X: results[0]},
+ },
+ }
+ }
+ } else {
+ logf("callee body is not valid as statement")
+ // The call is a standalone statement, but the
+ // callee body is not suitable as a standalone statement
+ // (f() or <-ch), explicitly discard the results:
+ // Reduces to: _, _ = exprs
+ discard := &ast.AssignStmt{
+ Lhs: blanks[ast.Expr](callee.NumResults),
+ Tok: token.ASSIGN,
+ Rhs: results,
+ }
+ res.old = stmt
+ if !needBindingDecl {
+ // Reduces to: _, _ = exprs
+ res.new = discard
+ } else {
+ // Reduces to: { var (bindings); _, _ = exprs }
+ res.bindingDecl = true
+ res.new = &ast.BlockStmt{
+ List: []ast.Stmt{
+ bindingDecl.stmt,
+ discard,
+ },
+ }
+ }
+ }
+ return res, nil
+ }
+
+ // Assignment context.
+ //
+ // If there is no binding decl, or if the binding decl declares no names,
+ // an assignment a, b := f() can be reduced to a, b := x, y.
+ if stmt, ok := parent.(*ast.AssignStmt); ok &&
+ is[*ast.BlockStmt](grandparent) &&
+ (!needBindingDecl || (bindingDecl != nil && len(bindingDecl.names) == 0)) {
+
+ // Reduces to: { var (bindings); lhs... := rhs... }
+ if newStmts, ok := st.assignStmts(stmt, results, istate.importName); ok {
+ logf("strategy: reduce assign-context call to { return exprs }")
+
+ clearPositions(calleeDecl.Body)
+
+ block := &ast.BlockStmt{
+ List: newStmts,
+ }
+ if needBindingDecl {
+ res.bindingDecl = true
+ block.List = prepend(bindingDecl.stmt, block.List...)
+ }
+
+ // assignStmts does not introduce new bindings, and replacing an
+ // assignment only works if the replacement occurs in the same scope.
+ // Therefore, we must ensure that braces are elided.
+ res.elideBraces = true
+ res.old = stmt
+ res.new = block
+ return res, nil
+ }
+ }
+
+ // expression context
+ if !needBindingDecl {
+ clearPositions(calleeDecl.Body)
+
+ anyNonTrivialReturns := hasNonTrivialReturn(callee.Returns)
+
+ if callee.NumResults == 1 {
+ logf("strategy: reduce expr-context call to { return expr }")
+ // (includes some simple tail-calls)
+
+ // Make implicit return conversion explicit.
+ if anyNonTrivialReturns {
+ results[0] = convert(calleeDecl.Type.Results.List[0].Type, results[0])
+ }
+
+ res.old = caller.Call
+ res.new = results[0]
+ return res, nil
+
+ } else if !anyNonTrivialReturns {
+ logf("strategy: reduce spread-context call to { return expr }")
+ // There is no general way to reify conversions in a spread
+ // return, hence the requirement above.
+ //
+ // TODO(adonovan): allow this reduction when no
+ // conversion is required by the context.
+
+ // The call returns multiple results but is
+ // not a standalone call statement. It must
+ // be the RHS of a spread assignment:
+ // var x, y = f()
+ // x, y := f()
+ // x, y = f()
+ // or the sole argument to a spread call:
+ // printf(f())
+ // or spread return statement:
+ // return f()
+ res.old = parent
+ switch context := parent.(type) {
+ case *ast.AssignStmt:
+ // Inv: the call must be in Rhs[0], not Lhs.
+ assign := shallowCopy(context)
+ assign.Rhs = results
+ res.new = assign
+ case *ast.ValueSpec:
+ // Inv: the call must be in Values[0], not Names.
+ spec := shallowCopy(context)
+ spec.Values = results
+ res.new = spec
+ case *ast.CallExpr:
+ // Inv: the call must be in Args[0], not Fun.
+ call := shallowCopy(context)
+ call.Args = results
+ res.new = call
+ case *ast.ReturnStmt:
+ // Inv: the call must be Results[0].
+ ret := shallowCopy(context)
+ ret.Results = results
+ res.new = ret
+ default:
+ return nil, fmt.Errorf("internal error: unexpected context %T for spread call", context)
+ }
+ return res, nil
+ }
+ }
+ }
+
+ // Special case: tail-call.
+ //
+ // Inlining:
+ // return f(args)
+ // where:
+ // func f(params) (results) { body }
+ // reduces to:
+ // { var (bindings); body }
+ // { body }
+ // so long as:
+ // - all parameters can be eliminated or replaced by a binding decl,
+ // - call is a tail-call;
+ // - all returns in body have trivial result conversions,
+ // or the caller's return type matches the callee's,
+ // - there is no label conflict;
+ // - no result variable is referenced by name,
+ // or implicitly by a bare return.
+ //
+ // The body may use defer, arbitrary control flow, and
+ // multiple returns.
+ //
+ // TODO(adonovan): add a strategy for a 'void tail
+ // call', i.e. a call statement prior to an (explicit
+ // or implicit) return.
+ parent, _ := callContext(caller.path)
+ if ret, ok := parent.(*ast.ReturnStmt); ok &&
+ len(ret.Results) == 1 &&
+ tailCallSafeReturn(caller, calleeSymbol, callee) &&
+ !callee.HasBareReturn &&
+ (!needBindingDecl || bindingDecl != nil) &&
+ !hasLabelConflict(caller.path, callee.Labels) &&
+ allResultsUnreferenced {
+ logf("strategy: reduce tail-call")
+ body := calleeDecl.Body
+ clearPositions(body)
+ if needBindingDecl {
+ res.bindingDecl = true
+ body.List = prepend(bindingDecl.stmt, body.List...)
+ }
+ res.old = ret
+ res.new = body
+ return res, nil
+ }
+
+ // Special case: call to void function
+ //
+ // Inlining:
+ // f(args)
+ // where:
+ // func f(params) { stmts }
+ // reduces to:
+ // { var (bindings); stmts }
+ // { stmts }
+ // so long as:
+ // - callee is a void function (no returns)
+ // - callee does not use defer
+ // - there is no label conflict between caller and callee
+ // - all parameters and result vars can be eliminated
+ // or replaced by a binding decl,
+ // - caller ExprStmt is in unrestricted statement context.
+ if stmt := callStmt(caller.path, true); stmt != nil &&
+ (!needBindingDecl || bindingDecl != nil) &&
+ !callee.HasDefer &&
+ !hasLabelConflict(caller.path, callee.Labels) &&
+ len(callee.Returns) == 0 {
+ logf("strategy: reduce stmt-context call to { stmts }")
+ body := calleeDecl.Body
+ var repl ast.Stmt = body
+ clearPositions(repl)
+ if needBindingDecl {
+ body.List = prepend(bindingDecl.stmt, body.List...)
+ }
+ res.old = stmt
+ res.new = repl
+ return res, nil
+ }
+
+ // TODO(adonovan): parameterless call to { stmts; return expr }
+ // from one of these contexts:
+ // x, y = f()
+ // x, y := f()
+ // var x, y = f()
+ // =>
+ // var (x T1, y T2); { stmts; x, y = expr }
+ //
+ // Because the params are no longer declared simultaneously
+ // we need to check that (for example) x ∉ freevars(T2),
+ // in addition to the usual checks for arg/result conversions,
+ // complex control, etc.
+ // Also test cases where expr is an n-ary call (spread returns).
+
+ // Literalization isn't quite infallible.
+ // Consider a spread call to a method in which
+ // no parameters are eliminated, e.g.
+ // new(T).f(g())
+ // where
+ // func (recv *T) f(x, y int) { body }
+ // func g() (int, int)
+ // This would be literalized to:
+ // func (recv *T, x, y int) { body }(new(T), g()),
+ // which is not a valid argument list because g() must appear alone.
+ // Reject this case for now.
+ if len(args) == 2 && args[0] != nil && args[1] != nil && is[*types.Tuple](args[1].typ) {
+ return nil, fmt.Errorf("can't yet inline spread call to method")
+ }
+
+ // Infallible general case: literalization.
+ //
+ // func(params) { body }(args)
+ //
+ logf("strategy: literalization")
+ funcLit := &ast.FuncLit{
+ Type: calleeDecl.Type,
+ Body: calleeDecl.Body,
+ }
+ // clear positions before prepending the binding decl below, since the
+ // binding decl contains syntax from the caller and we must not mutate the
+ // caller. (This was a prior bug.)
+ clearPositions(funcLit)
+
+ // Literalization can still make use of a binding
+ // decl as it gives a more natural reading order:
+ //
+ // func() { var params = args; body }()
+ //
+ // TODO(adonovan): relax the allResultsUnreferenced requirement
+ // by adding a parameter-only (no named results) binding decl.
+ if bindingDecl != nil && allResultsUnreferenced {
+ funcLit.Type.Params.List = nil
+ remainingArgs = nil
+ res.bindingDecl = true
+ funcLit.Body.List = prepend(bindingDecl.stmt, funcLit.Body.List...)
+ }
+
+ // Emit a new call to a function literal in place of
+ // the callee name, with appropriate replacements.
+ newCall := &ast.CallExpr{
+ Fun: funcLit,
+ Ellipsis: token.NoPos, // f(slice...) is always simplified
+ Args: remainingArgs,
+ }
+ res.old = caller.Call
+ res.new = newCall
+ return res, nil
+}
+
+// renameFreeObjs computes the renaming of the callee's free identifiers.
+// It returns a slice of names (identifiers or selector expressions) corresponding
+// to the callee's free objects (gobCallee.FreeObjs).
+func (st *state) renameFreeObjs(istate *importState) ([]ast.Expr, error) {
+ caller, callee := st.caller, &st.callee.impl
+ objRenames := make([]ast.Expr, len(callee.FreeObjs)) // nil => no change
+ for i, obj := range callee.FreeObjs {
+ // obj is a free object of the callee.
+ //
+ // Possible cases are:
+ // - builtin function, type, or value (e.g. nil, zero)
+ // => check not shadowed in caller.
+ // - package-level var/func/const/types
+ // => same package: check not shadowed in caller.
+ // => otherwise: import other package, form a qualified identifier.
+ // (Unexported cross-package references were rejected already.)
+ // - type parameter
+ // => not yet supported
+ // - pkgname
+ // => import other package and use its local name.
+ //
+ // There can be no free references to labels, fields, or methods.
+
+ // Note that we must consider potential shadowing both
+ // at the caller side (caller.lookup) and, when
+ // choosing new PkgNames, within the callee (obj.shadow).
+
+ var newName ast.Expr
+ if obj.Kind == "pkgname" {
+ // Use locally appropriate import, creating as needed.
+ n := istate.localName(obj.PkgPath, obj.PkgName, obj.Name, obj.Shadow)
+ newName = makeIdent(n) // imported package
+ } else if !obj.ValidPos {
+ // Built-in function, type, or value (e.g. nil, zero):
+ // check not shadowed at caller.
+ found := caller.lookup(obj.Name) // always finds something
+ if found.Pos().IsValid() {
+ return nil, fmt.Errorf("cannot inline, because the callee refers to built-in %q, which in the caller is shadowed by a %s (declared at line %d)",
+ obj.Name, objectKind(found),
+ caller.Fset.PositionFor(found.Pos(), false).Line)
+ }
+
+ } else {
+ // Must be reference to package-level var/func/const/type,
+ // since type parameters are not yet supported.
+ qualify := false
+ if obj.PkgPath == callee.PkgPath {
+ // reference within callee package
+ if caller.Types.Path() == callee.PkgPath {
+ // Caller and callee are in same package.
+ // Check caller has not shadowed the decl.
+ //
+ // This may fail if the callee is "fake", such as for signature
+ // refactoring where the callee is modified to be a trivial wrapper
+ // around the refactored signature.
+ found := caller.lookup(obj.Name)
+ if found != nil && !isPkgLevel(found) {
+ return nil, fmt.Errorf("cannot inline, because the callee refers to %s %q, which in the caller is shadowed by a %s (declared at line %d)",
+ obj.Kind, obj.Name,
+ objectKind(found),
+ caller.Fset.PositionFor(found.Pos(), false).Line)
+ }
+ } else {
+ // Cross-package reference.
+ qualify = true
+ }
+ } else {
+ // Reference to a package-level declaration
+ // in another package, without a qualified identifier:
+ // it must be a dot import.
+ qualify = true
+ }
+
+ // Form a qualified identifier, pkg.Name.
+ if qualify {
+ pkgName := istate.localName(obj.PkgPath, obj.PkgName, obj.PkgName, obj.Shadow)
+ newName = &ast.SelectorExpr{
+ X: makeIdent(pkgName),
+ Sel: makeIdent(obj.Name),
+ }
+ }
+ }
+ objRenames[i] = newName
+ }
+ return objRenames, nil
+}
+
+type argument struct {
+ expr ast.Expr
+ typ types.Type // may be tuple for sole non-receiver arg in spread call
+ constant constant.Value // value of argument if constant
+ spread bool // final arg is call() assigned to multiple params
+ pure bool // expr is pure (doesn't read variables)
+ effects bool // expr has effects (updates variables)
+ duplicable bool // expr may be duplicated
+ freevars map[string]bool // free names of expr
+ variadic bool // is explicit []T{...} for eliminated variadic
+ desugaredRecv bool // is *recv or &recv, where operator was elided
+}
+
+// typeArguments returns the type arguments of the call.
+// It only collects the arguments that are explicitly provided; it does
+// not attempt type inference.
+func (st *state) typeArguments(call *ast.CallExpr) []*argument {
+ var exprs []ast.Expr
+ switch d := ast.Unparen(call.Fun).(type) {
+ case *ast.IndexExpr:
+ exprs = []ast.Expr{d.Index}
+ case *ast.IndexListExpr:
+ exprs = d.Indices
+ default:
+ // No type arguments
+ return nil
+ }
+ var args []*argument
+ for _, e := range exprs {
+ arg := &argument{expr: e, freevars: freeVars(st.caller.Info, e)}
+ args = append(args, arg)
+ }
+ return args
+}
+
+// arguments returns the effective arguments of the call.
+//
+// If the receiver argument and parameter have
+// different pointerness, make the "&" or "*" explicit.
+//
+// Also, if x.f() is shorthand for promoted method x.y.f(),
+// make the .y explicit in T.f(x.y, ...).
+//
+// Beware that:
+//
+// - a method can only be called through a selection, but only
+// the first of these two forms needs special treatment:
+//
+// expr.f(args) -> ([&*]expr, args) MethodVal
+// T.f(recv, args) -> ( expr, args) MethodExpr
+//
+// - the presence of a value in receiver-position in the call
+// is a property of the caller, not the callee. A method
+// (calleeDecl.Recv != nil) may be called like an ordinary
+// function.
+//
+// - the types.Signatures seen by the caller (from
+// StaticCallee) and by the callee (from decl type)
+// differ in this case.
+//
+// In a spread call f(g()), the sole ordinary argument g(),
+// always last in args, has a tuple type.
+//
+// We compute type-based predicates like pure, duplicable,
+// freevars, etc, now, before we start modifying syntax.
+func (st *state) arguments(caller *Caller, calleeDecl *ast.FuncDecl, assign1 func(*types.Var) bool) ([]*argument, error) {
+ var args []*argument
+
+ callArgs := caller.Call.Args
+ if calleeDecl.Recv != nil {
+ if len(st.callee.impl.TypeParams) > 0 {
+ return nil, fmt.Errorf("cannot inline: generic methods not yet supported")
+ }
+ sel := ast.Unparen(caller.Call.Fun).(*ast.SelectorExpr)
+ seln := caller.Info.Selections[sel]
+ var recvArg ast.Expr
+ switch seln.Kind() {
+ case types.MethodVal: // recv.f(callArgs)
+ recvArg = sel.X
+ case types.MethodExpr: // T.f(recv, callArgs)
+ recvArg = callArgs[0]
+ callArgs = callArgs[1:]
+ }
+ if recvArg != nil {
+ // Compute all the type-based predicates now,
+ // before we start meddling with the syntax;
+ // the meddling will update them.
+ arg := &argument{
+ expr: recvArg,
+ typ: caller.Info.TypeOf(recvArg),
+ constant: caller.Info.Types[recvArg].Value,
+ pure: pure(caller.Info, assign1, recvArg),
+ effects: st.effects(caller.Info, recvArg),
+ duplicable: duplicable(caller.Info, recvArg),
+ freevars: freeVars(caller.Info, recvArg),
+ }
+ recvArg = nil // prevent accidental use
+
+ // Move receiver argument recv.f(args) to argument list f(&recv, args).
+ args = append(args, arg)
+
+ // Make field selections explicit (recv.f -> recv.y.f),
+ // updating arg.{expr,typ}.
+ indices := seln.Index()
+ for _, index := range indices[:len(indices)-1] {
+ fld := typeparams.CoreType(typeparams.Deref(arg.typ)).(*types.Struct).Field(index)
+ if fld.Pkg() != caller.Types && !fld.Exported() {
+ return nil, fmt.Errorf("in %s, implicit reference to unexported field .%s cannot be made explicit",
+ debugFormatNode(caller.Fset, caller.Call.Fun),
+ fld.Name())
+ }
+ if isPointer(arg.typ) {
+ arg.pure = false // implicit *ptr operation => impure
+ }
+ arg.expr = &ast.SelectorExpr{
+ X: arg.expr,
+ Sel: makeIdent(fld.Name()),
+ }
+ arg.typ = fld.Type()
+ arg.duplicable = false
+ }
+
+ // Make * or & explicit.
+ argIsPtr := isPointer(arg.typ)
+ paramIsPtr := isPointer(seln.Obj().Type().Underlying().(*types.Signature).Recv().Type())
+ if !argIsPtr && paramIsPtr {
+ // &recv
+ arg.expr = &ast.UnaryExpr{Op: token.AND, X: arg.expr}
+ arg.typ = types.NewPointer(arg.typ)
+ arg.desugaredRecv = true
+ } else if argIsPtr && !paramIsPtr {
+ // *recv
+ arg.expr = &ast.StarExpr{X: arg.expr}
+ arg.typ = typeparams.Deref(arg.typ)
+ arg.duplicable = false
+ arg.pure = false
+ arg.desugaredRecv = true
+ }
+ }
+ }
+ for _, expr := range callArgs {
+ tv := caller.Info.Types[expr]
+ args = append(args, &argument{
+ expr: expr,
+ typ: tv.Type,
+ constant: tv.Value,
+ spread: is[*types.Tuple](tv.Type), // => last
+ pure: pure(caller.Info, assign1, expr),
+ effects: st.effects(caller.Info, expr),
+ duplicable: duplicable(caller.Info, expr),
+ freevars: freeVars(caller.Info, expr),
+ })
+ }
+
+ // Re-typecheck each constant argument expression in a neutral context.
+ //
+ // In a call such as func(int16){}(1), the type checker infers
+ // the type "int16", not "untyped int", for the argument 1,
+ // because it has incorporated information from the left-hand
+ // side of the assignment implicit in parameter passing, but
+ // of course in a different context, the expression 1 may have
+ // a different type.
+ //
+ // So, we must use CheckExpr to recompute the type of the
+ // argument in a neutral context to find its inherent type.
+ // (This is arguably a bug in go/types, but I'm pretty certain
+ // I requested it be this way long ago... -adonovan)
+ //
+ // This is only needed for constants. Other implicit
+ // assignment conversions, such as unnamed-to-named struct or
+ // chan to <-chan, do not result in the type-checker imposing
+ // the LHS type on the RHS value.
+ for _, arg := range args {
+ if arg.constant == nil {
+ continue
+ }
+ info := &types.Info{Types: make(map[ast.Expr]types.TypeAndValue)}
+ if err := types.CheckExpr(caller.Fset, caller.Types, caller.Call.Pos(), arg.expr, info); err != nil {
+ return nil, err
+ }
+ arg.typ = info.TypeOf(arg.expr)
+ }
+
+ return args, nil
+}
+
+type parameter struct {
+ obj *types.Var // parameter var from caller's signature
+ fieldType ast.Expr // syntax of type, from calleeDecl.Type.{Recv,Params}
+ info *paramInfo // information from AnalyzeCallee
+ variadic bool // (final) parameter is unsimplified ...T
+}
+
+// A replacer replaces an identifier at the given offset in the callee.
+// The replacement tree must not belong to the caller; use cloneNode as needed.
+// If unpackVariadic is set, the replacement is a composite resulting from
+// variadic elimination, and may be unpacked into variadic calls.
+type replacer = func(offset int, repl ast.Expr, unpackVariadic bool)
+
+// substituteTypeParams replaces type parameters in the callee with the
+// corresponding type arguments from the call.
+func substituteTypeParams(logf logger, typeParams []*paramInfo, typeArgs []*argument, replace replacer) error {
+ assert(len(typeParams) == len(typeArgs), "mismatched number of type params/args")
+ for i, paramInfo := range typeParams {
+ arg := typeArgs[i]
+ // Perform a simplified, conservative shadow analysis: fail if there is any shadowing.
+ for free := range arg.freevars {
+ if paramInfo.Shadow[free] != 0 {
+ return fmt.Errorf("cannot inline: type argument #%d (type parameter %s) is shadowed", i, paramInfo.Name)
+ }
+ }
+ logf("replacing type param %s with %s", paramInfo.Name, debugFormatNode(token.NewFileSet(), arg.expr))
+ for _, ref := range paramInfo.Refs {
+ replace(ref.Offset, internalastutil.CloneNode(arg.expr), false)
+ }
+ }
+ return nil
+}
+
+// syncParamFieldTypes synchronizes the fieldType of each parameter in params
+// with the mutated calleeDecl AST. This is necessary because substituteTypeParams
+// mutates the calleeDecl AST, replacing type nodes, but params still references
+// the original (now outdated) type nodes.
+func syncParamFieldTypes(calleeDecl *ast.FuncDecl, params []*parameter) {
+ var i int
+ setFieldType := func(t ast.Expr) {
+ assert(i < len(params), "mismatched parameter count")
+ params[i].fieldType = t
+ i++
+ }
+
+ if calleeDecl.Recv != nil && len(calleeDecl.Recv.List) > 0 {
+ setFieldType(calleeDecl.Recv.List[0].Type)
+ }
+ if calleeDecl.Type.Params != nil {
+ for _, field := range calleeDecl.Type.Params.List {
+ if field.Names == nil {
+ setFieldType(field.Type)
+ } else {
+ for range field.Names {
+ setFieldType(field.Type)
+ }
+ }
+ }
+ }
+ assert(i == len(params), "mismatched parameter count")
+}
+
+// substitute implements parameter elimination by substitution.
+//
+// It considers each parameter and its corresponding argument in turn
+// and evaluate these conditions:
+//
+// - the parameter is neither address-taken nor assigned;
+// - the argument is pure;
+// - if the parameter refcount is zero, the argument must
+// not contain the last use of a local var;
+// - if the parameter refcount is > 1, the argument must be duplicable;
+// - the argument (or types.Default(argument) if it's untyped) has
+// the same type as the parameter.
+//
+// If all conditions are met then the parameter can be substituted and
+// each reference to it replaced by the argument. In that case, the
+// replaceCalleeID function is called for each reference to the
+// parameter, and is provided with its relative offset and replacement
+// expression (argument), and the corresponding elements of params and
+// args are replaced by nil.
+func substitute(logf logger, caller *Caller, params []*parameter, args []*argument, effects []int, falcon falconResult, replace replacer) {
+ // Inv:
+ // in calls to variadic, len(args) >= len(params)-1
+ // in spread calls to non-variadic, len(args) < len(params)
+ // in spread calls to variadic, len(args) <= len(params)
+ // (In spread calls len(args) = 1, or 2 if call has receiver.)
+ // Non-spread variadics have been simplified away already,
+ // so the args[i] lookup is safe if we stop after the spread arg.
+ assert(len(args) <= len(params), "too many arguments")
+
+ // Collect candidates for substitution.
+ //
+ // An argument is a candidate if it is not otherwise rejected, and any free
+ // variables that are shadowed only by other parameters.
+ //
+ // Therefore, substitution candidates are represented by a graph, where edges
+ // lead from each argument to the other arguments that, if substituted, would
+ // allow the argument to be substituted. We collect these edges in the
+ // [substGraph]. Any node that is known not to be elided from the graph.
+ // Arguments in this graph with no edges are substitutable independent of
+ // other nodes, though they may be removed due to falcon or effects analysis.
+ sg := make(substGraph)
+next:
+ for i, param := range params {
+ arg := args[i]
+
+ // Check argument against parameter.
+ //
+ // Beware: don't use types.Info on arg since
+ // the syntax may be synthetic (not created by parser)
+ // and thus lacking positions and types;
+ // do it earlier (see pure/duplicable/freevars).
+
+ if arg.spread {
+ // spread => last argument, but not always last parameter
+ logf("keeping param %q and following ones: argument %s is spread",
+ param.info.Name, debugFormatNode(caller.Fset, arg.expr))
+ return // give up
+ }
+ assert(!param.variadic, "unsimplified variadic parameter")
+ if param.info.Escapes {
+ logf("keeping param %q: escapes from callee", param.info.Name)
+ continue
+ }
+ if param.info.Assigned {
+ logf("keeping param %q: assigned by callee", param.info.Name)
+ continue // callee needs the parameter variable
+ }
+ if len(param.info.Refs) > 1 && !arg.duplicable {
+ logf("keeping param %q: argument is not duplicable", param.info.Name)
+ continue // incorrect or poor style to duplicate an expression
+ }
+ if len(param.info.Refs) == 0 {
+ if arg.effects {
+ logf("keeping param %q: though unreferenced, it has effects", param.info.Name)
+ continue
+ }
+
+ // If the caller is within a function body,
+ // eliminating an unreferenced parameter might
+ // remove the last reference to a caller local var.
+ if caller.enclosingFunc != nil {
+ for free := range arg.freevars {
+ // TODO(rfindley): we can get this 100% right by looking for
+ // references among other arguments which have non-zero references
+ // within the callee.
+ if v, ok := caller.lookup(free).(*types.Var); ok && within(v.Pos(), caller.enclosingFunc.Body) && !isUsedOutsideCall(caller, v) {
+
+ // Check to see if the substituted var is used within other args
+ // whose corresponding params ARE used in the callee
+ usedElsewhere := func() bool {
+ for i, param := range params {
+ if i < len(args) && len(param.info.Refs) > 0 { // excludes original param
+ for name := range args[i].freevars {
+ if caller.lookup(name) == v {
+ return true
+ }
+ }
+ }
+ }
+ return false
+ }
+ if !usedElsewhere() {
+ logf("keeping param %q: arg contains perhaps the last reference to caller local %v @ %v",
+ param.info.Name, v, caller.Fset.PositionFor(v.Pos(), false))
+ continue next
+ }
+ }
+ }
+ }
+ }
+
+ // Arg is a potential substitution candidate: analyze its shadowing.
+ //
+ // Consider inlining a call f(z, 1) to
+ //
+ // func f(x, y int) int { z := y; return x + y + z }
+ //
+ // we can't replace x in the body by z (or any
+ // expression that has z as a free identifier) because there's an
+ // intervening declaration of z that would shadow the caller's one.
+ //
+ // However, we *could* replace x in the body by y, as long as the y
+ // parameter is also removed by substitution.
+
+ sg[arg] = nil // Absent shadowing, the arg is substitutable.
+ for free := range arg.freevars {
+ switch s := param.info.Shadow[free]; {
+ case s < 0:
+ // Shadowed by a non-parameter symbol, so arg is not substitutable.
+ delete(sg, arg)
+ case s > 0:
+ // Shadowed by a parameter; arg may be substitutable, if only shadowed
+ // by other substitutable parameters.
+ if s > len(args) {
+ // Defensive: this should not happen in the current factoring, since
+ // spread arguments are already handled.
+ delete(sg, arg)
+ }
+ if edges, ok := sg[arg]; ok {
+ sg[arg] = append(edges, args[s-1])
+ }
+ }
+ }
+ }
+
+ // Process the initial state of the substitution graph.
+ sg.prune()
+
+ // Now we check various conditions on the substituted argument set as a
+ // whole. These conditions reject substitution candidates, but since their
+ // analysis depends on the full set of candidates, we do not process side
+ // effects of their candidate rejection until after the analysis completes,
+ // in a call to prune. After pruning, we must re-run the analysis to check
+ // for additional rejections.
+ //
+ // Here's an example of that in practice:
+ //
+ // var a [3]int
+ //
+ // func falcon(x, y, z int) {
+ // _ = x + a[y+z]
+ // }
+ //
+ // func _() {
+ // var y int
+ // const x, z = 1, 2
+ // falcon(y, x, z)
+ // }
+ //
+ // In this example, arguments 0 and 1 are shadowed by each other's
+ // corresponding parameter, and so each can be substituted only if they are
+ // both substituted. But the fallible constant analysis finds a violated
+ // constraint: x + z = 3, and so the constant array index would cause a
+ // compile-time error if argument 1 (x) were substituted. Therefore,
+ // following the falcon analysis, we must also prune argument 0.
+ //
+ // As far as I (rfindley) can tell, the falcon analysis should always succeed
+ // after the first pass, as it's not possible for additional bindings to
+ // cause new constraint failures. Nevertheless, we re-run it to be sure.
+ //
+ // However, the same cannot be said of the effects analysis, as demonstrated
+ // by this example:
+ //
+ // func effects(w, x, y, z int) {
+ // _ = x + w + y + z
+ // }
+
+ // func _() {
+ // v := 0
+ // w := func() int { v++; return 0 }
+ // x := func() int { v++; return 0 }
+ // y := func() int { v++; return 0 }
+ // effects(x(), w(), y(), x()) //@ inline(re"effects", effects)
+ // }
+ //
+ // In this example, arguments 0, 1, and 3 are related by the substitution
+ // graph. The first effects analysis implies that arguments 0 and 1 must be
+ // bound, and therefore argument 3 must be bound. But then a subsequent
+ // effects analysis forces argument 2 to also be bound.
+
+ // Reject constant arguments as substitution candidates if they cause
+ // violation of falcon constraints.
+ //
+ // Keep redoing the analysis until we no longer reject additional arguments,
+ // as the set of substituted parameters affects the falcon package.
+ for checkFalconConstraints(logf, params, args, falcon, sg) {
+ sg.prune()
+ }
+
+ // As a final step, introduce bindings to resolve any
+ // evaluation order hazards. This must be done last, as
+ // additional subsequent bindings could introduce new hazards.
+ //
+ // As with the falcon analysis, keep redoing the analysis until the no more
+ // arguments are rejected.
+ for resolveEffects(logf, args, effects, sg) {
+ sg.prune()
+ }
+
+ // The remaining candidates are safe to substitute.
+ for i, param := range params {
+ if arg := args[i]; sg.has(arg) {
+
+ // It is safe to substitute param and replace it with arg.
+ // The formatter introduces parens as needed for precedence.
+ //
+ // Because arg.expr belongs to the caller,
+ // we clone it before splicing it into the callee tree.
+ logf("replacing parameter %q by argument %q",
+ param.info.Name, debugFormatNode(caller.Fset, arg.expr))
+ for _, ref := range param.info.Refs {
+ // Apply any transformations necessary for this reference.
+ argExpr := arg.expr
+
+ // If the reference itself is being selected, and we applied desugaring
+ // (an explicit &x or *x), we can undo that desugaring here as it is
+ // not necessary for a selector. We don't need to check addressability
+ // here because if we desugared, the receiver must have been
+ // addressable.
+ if ref.IsSelectionOperand && arg.desugaredRecv {
+ switch e := argExpr.(type) {
+ case *ast.UnaryExpr:
+ argExpr = e.X
+ case *ast.StarExpr:
+ argExpr = e.X
+ }
+ }
+
+ // If the reference requires exact type agreement between parameter and
+ // argument, wrap the argument in an explicit conversion if
+ // substitution might materially change its type. (We already did the
+ // necessary shadowing check on the parameter type syntax.)
+ //
+ // The types must agree in any of these cases:
+ // - the argument affects type inference;
+ // - the reference's concrete type is assigned to an interface type;
+ // - the reference is not an assignment, nor a trivial conversion of an untyped constant.
+ //
+ // In all other cases, no explicit conversion is necessary as either
+ // the type does not matter, or must have already agreed for well-typed
+ // code.
+ //
+ // This is only needed for substituted arguments. All other arguments
+ // are given explicit types in either a binding decl or when using the
+ // literalization strategy.
+ //
+ // If the types are identical, we can eliminate
+ // redundant type conversions such as this:
+ //
+ // Callee:
+ // func f(i int32) { fmt.Println(i) }
+ // Caller:
+ // func g() { f(int32(1)) }
+ // Inlined as:
+ // func g() { fmt.Println(int32(int32(1)))
+ //
+ // Recall that non-trivial does not imply non-identical for constant
+ // conversions; however, at this point state.arguments has already
+ // re-typechecked the constant and set arg.type to its (possibly
+ // "untyped") inherent type, so the conversion from untyped 1 to int32
+ // is non-trivial even though both arg and param have identical types
+ // (int32).
+ needType := ref.AffectsInference ||
+ (ref.Assignable && ref.IfaceAssignment && !param.info.IsInterface) ||
+ (!ref.Assignable && !trivialConversion(arg.constant, arg.typ, param.obj.Type()))
+
+ if needType &&
+ !types.Identical(types.Default(arg.typ), param.obj.Type()) {
+
+ // If arg.expr is already an interface call, strip it.
+ if call, ok := argExpr.(*ast.CallExpr); ok && len(call.Args) == 1 {
+ if typ, ok := isConversion(caller.Info, call); ok && isNonTypeParamInterface(typ) {
+ argExpr = call.Args[0]
+ }
+ }
+
+ argExpr = convert(param.fieldType, argExpr)
+ logf("param %q (offset %d): adding explicit %s -> %s conversion around argument",
+ param.info.Name, ref.Offset, arg.typ, param.obj.Type())
+ }
+ replace(ref.Offset, internalastutil.CloneNode(argExpr).(ast.Expr), arg.variadic)
+ }
+ params[i] = nil // substituted
+ args[i] = nil // substituted
+ }
+ }
+}
+
+// isConversion reports whether the given call is a type conversion, returning
+// (operand, true) if so.
+//
+// If the call is not a conversion, it returns (nil, false).
+func isConversion(info *types.Info, call *ast.CallExpr) (types.Type, bool) {
+ if tv, ok := info.Types[call.Fun]; ok && tv.IsType() {
+ return tv.Type, true
+ }
+ return nil, false
+}
+
+// isNonTypeParamInterface reports whether t is a non-type parameter interface
+// type.
+func isNonTypeParamInterface(t types.Type) bool {
+ return !typeparams.IsTypeParam(t) && types.IsInterface(t)
+}
+
+// isUsedOutsideCall reports whether v is used outside of caller.Call, within
+// the body of caller.enclosingFunc.
+func isUsedOutsideCall(caller *Caller, v *types.Var) bool {
+ used := false
+ ast.Inspect(caller.enclosingFunc.Body, func(n ast.Node) bool {
+ if n == caller.Call {
+ return false
+ }
+ switch n := n.(type) {
+ case *ast.Ident:
+ if use := caller.Info.Uses[n]; use == v {
+ used = true
+ }
+ case *ast.FuncType:
+ // All params are used.
+ for _, fld := range n.Params.List {
+ for _, n := range fld.Names {
+ if def := caller.Info.Defs[n]; def == v {
+ used = true
+ }
+ }
+ }
+ }
+ return !used // keep going until we find a use
+ })
+ return used
+}
+
+// checkFalconConstraints checks whether constant arguments
+// are safe to substitute (e.g. s[i] -> ""[0] is not safe.)
+//
+// Any failed constraint causes us to reject all constant arguments as
+// substitution candidates (by clearing args[i].substitution=false).
+//
+// TODO(adonovan): we could obtain a finer result rejecting only the
+// freevars of each failed constraint, and processing constraints in
+// order of increasing arity, but failures are quite rare.
+func checkFalconConstraints(logf logger, params []*parameter, args []*argument, falcon falconResult, sg substGraph) bool {
+ // Create a dummy package, as this is the only
+ // way to create an environment for CheckExpr.
+ pkg := types.NewPackage("falcon", "falcon")
+
+ // Declare types used by constraints.
+ for _, typ := range falcon.Types {
+ logf("falcon env: type %s %s", typ.Name, types.Typ[typ.Kind])
+ pkg.Scope().Insert(types.NewTypeName(token.NoPos, pkg, typ.Name, types.Typ[typ.Kind]))
+ }
+
+ // Declared constants and variables for parameters.
+ nconst := 0
+ for i, param := range params {
+ name := param.info.Name
+ if name == "" {
+ continue // unreferenced
+ }
+ arg := args[i]
+ if arg.constant != nil && sg.has(arg) && param.info.FalconType != "" {
+ t := pkg.Scope().Lookup(param.info.FalconType).Type()
+ pkg.Scope().Insert(types.NewConst(token.NoPos, pkg, name, t, arg.constant))
+ logf("falcon env: const %s %s = %v", name, param.info.FalconType, arg.constant)
+ nconst++
+ } else {
+ v := types.NewVar(token.NoPos, pkg, name, arg.typ)
+ typesinternal.SetVarKind(v, typesinternal.PackageVar)
+ pkg.Scope().Insert(v)
+ logf("falcon env: var %s %s", name, arg.typ)
+ }
+ }
+ if nconst == 0 {
+ return false // nothing to do
+ }
+
+ // Parse and evaluate the constraints in the environment.
+ fset := token.NewFileSet()
+ removed := false
+ for _, falcon := range falcon.Constraints {
+ expr, err := parser.ParseExprFrom(fset, "falcon", falcon, 0)
+ if err != nil {
+ panic(fmt.Sprintf("failed to parse falcon constraint %s: %v", falcon, err))
+ }
+ if err := types.CheckExpr(fset, pkg, token.NoPos, expr, nil); err != nil {
+ logf("falcon: constraint %s violated: %v", falcon, err)
+ for j, arg := range args {
+ if arg.constant != nil && sg.has(arg) {
+ logf("keeping param %q due falcon violation", params[j].info.Name)
+ removed = sg.remove(arg) || removed
+ }
+ }
+ break
+ }
+ logf("falcon: constraint %s satisfied", falcon)
+ }
+ return removed
+}
+
+// resolveEffects marks arguments as non-substitutable to resolve
+// hazards resulting from the callee evaluation order described by the
+// effects list.
+//
+// To do this, each argument is categorized as a read (R), write (W),
+// or pure. A hazard occurs when the order of evaluation of a W
+// changes with respect to any R or W. Pure arguments can be
+// effectively ignored, as they can be safely evaluated in any order.
+//
+// The callee effects list contains the index of each parameter in the
+// order it is first evaluated during execution of the callee. In
+// addition, the two special values R∞ and W∞ indicate the relative
+// position of the callee's first non-parameter read and its first
+// effects (or other unknown behavior).
+// For example, the list [0 2 1 R∞ 3 W∞] for func(a, b, c, d)
+// indicates that the callee referenced parameters a, c, and b,
+// followed by an arbitrary read, then parameter d, and finally
+// unknown behavior.
+//
+// When an argument is marked as not substitutable, we say that it is
+// 'bound', in the sense that its evaluation occurs in a binding decl
+// or literalized call. Such bindings always occur in the original
+// callee parameter order.
+//
+// In this context, "resolving hazards" means binding arguments so
+// that they are evaluated in a valid, hazard-free order. A trivial
+// solution to this problem would be to bind all arguments, but of
+// course that's not useful. The goal is to bind as few arguments as
+// possible.
+//
+// The algorithm proceeds by inspecting arguments in reverse parameter
+// order (right to left), preserving the invariant that every
+// higher-ordered argument is either already substituted or does not
+// need to be substituted. At each iteration, if there is an
+// evaluation hazard in the callee effects relative to the current
+// argument, the argument must be bound. Subsequently, if the argument
+// is bound for any reason, each lower-ordered argument must also be
+// bound if either the argument or lower-order argument is a
+// W---otherwise the binding itself would introduce a hazard.
+//
+// Thus, after each iteration, there are no hazards relative to the
+// current argument. Subsequent iterations cannot introduce hazards
+// with that argument because they can result only in additional
+// binding of lower-ordered arguments.
+func resolveEffects(logf logger, args []*argument, effects []int, sg substGraph) bool {
+ effectStr := func(effects bool, idx int) string {
+ i := fmt.Sprint(idx)
+ if idx == len(args) {
+ i = "∞"
+ }
+ return string("RW"[btoi(effects)]) + i
+ }
+ removed := false
+ for i, argi := range slices.Backward(args) {
+ if sg.has(argi) && !argi.pure {
+ // i is not bound: check whether it must be bound due to hazards.
+ idx := slices.Index(effects, i)
+ if idx >= 0 {
+ for _, j := range effects[:idx] {
+ var (
+ ji int // effective param index
+ jw bool // j is a write
+ )
+ if j == winf || j == rinf {
+ jw = j == winf
+ ji = len(args)
+ } else {
+ jw = args[j].effects
+ ji = j
+ }
+ if ji > i && (jw || argi.effects) { // out of order evaluation
+ logf("binding argument %s: preceded by %s",
+ effectStr(argi.effects, i), effectStr(jw, ji))
+
+ removed = sg.remove(argi) || removed
+ break
+ }
+ }
+ }
+ }
+ if !sg.has(argi) {
+ for j := range i {
+ argj := args[j]
+ if argj.pure {
+ continue
+ }
+ if (argi.effects || argj.effects) && sg.has(argj) {
+ logf("binding argument %s: %s is bound",
+ effectStr(argj.effects, j), effectStr(argi.effects, i))
+
+ removed = sg.remove(argj) || removed
+ }
+ }
+ }
+ }
+ return removed
+}
+
+// A substGraph is a directed graph representing arguments that may be
+// substituted, provided all of their related arguments (or "dependencies") are
+// also substituted. The candidates arguments for substitution are the keys in
+// this graph, and the edges represent shadowing of free variables of the key
+// by parameters corresponding to the dependency arguments.
+//
+// Any argument not present as a map key is known not to be substitutable. Some
+// arguments may have edges leading to other arguments that are not present in
+// the graph. In this case, those arguments also cannot be substituted, because
+// they have free variables that are shadowed by parameters that cannot be
+// substituted. Calling [substGraph.prune] removes these arguments from the
+// graph.
+//
+// The 'prune' operation is not built into the 'remove' step both because
+// analyses (falcon, effects) need local information about each argument
+// independent of dependencies, and for the efficiency of pruning once en masse
+// after each analysis.
+type substGraph map[*argument][]*argument
+
+// has reports whether arg is a candidate for substitution.
+func (g substGraph) has(arg *argument) bool {
+ _, ok := g[arg]
+ return ok
+}
+
+// remove marks arg as not substitutable, reporting whether the arg was
+// previously substitutable.
+//
+// remove does not have side effects on other arguments that may be
+// unsubstitutable as a result of their dependency being removed.
+// Call [substGraph.prune] to propagate these side effects, removing dependent
+// arguments.
+func (g substGraph) remove(arg *argument) bool {
+ pre := len(g)
+ delete(g, arg)
+ return len(g) < pre
+}
+
+// prune updates the graph to remove any keys that reach other arguments not
+// present in the graph.
+func (g substGraph) prune() {
+ // visit visits the forward transitive closure of arg and reports whether any
+ // missing argument was encountered, removing all nodes on the path to it
+ // from arg.
+ //
+ // The seen map is used for cycle breaking. In the presence of cycles, visit
+ // may report a false positive for an intermediate argument. For example,
+ // consider the following graph, where only a and b are candidates for
+ // substitution (meaning, only a and b are present in the graph).
+ //
+ // a ↔ b
+ // ↓
+ // [c]
+ //
+ // In this case, starting a visit from a, visit(b, seen) may report 'true',
+ // because c has not yet been considered. For this reason, we must guarantee
+ // that visit is called with an empty seen map at least once for each node.
+ var visit func(*argument, map[*argument]unit) bool
+ visit = func(arg *argument, seen map[*argument]unit) bool {
+ deps, ok := g[arg]
+ if !ok {
+ return false
+ }
+ if _, ok := seen[arg]; !ok {
+ seen[arg] = unit{}
+ for _, dep := range deps {
+ if !visit(dep, seen) {
+ delete(g, arg)
+ return false
+ }
+ }
+ }
+ return true
+ }
+ for arg := range g {
+ // Remove any argument that is, or transitively depends upon,
+ // an unsubstitutable argument.
+ //
+ // Each visitation gets a fresh cycle-breaking set.
+ visit(arg, make(map[*argument]unit))
+ }
+}
+
+// updateCalleeParams updates the calleeDecl syntax to remove
+// substituted parameters and move the receiver (if any) to the head
+// of the ordinary parameters.
+func updateCalleeParams(calleeDecl *ast.FuncDecl, params []*parameter) {
+ // The logic is fiddly because of the three forms of ast.Field:
+ //
+ // func(int), func(x int), func(x, y int)
+ //
+ // Also, ensure that all remaining parameters are named
+ // to avoid a mix of named/unnamed when joining (recv, params...).
+ // func (T) f(int, bool) -> (_ T, _ int, _ bool)
+ // (Strictly, we need do this only for methods and only when
+ // the namednesses of Recv and Params differ; that might be tidier.)
+
+ paramIdx := 0 // index in original parameter list (incl. receiver)
+ var newParams []*ast.Field
+ filterParams := func(field *ast.Field) {
+ var names []*ast.Ident
+ if field.Names == nil {
+ // Unnamed parameter field (e.g. func f(int)
+ if params[paramIdx] != nil {
+ // Give it an explicit name "_" since we will
+ // make the receiver (if any) a regular parameter
+ // and one cannot mix named and unnamed parameters.
+ names = append(names, makeIdent("_"))
+ }
+ paramIdx++
+ } else {
+ // Named parameter field e.g. func f(x, y int)
+ // Remove substituted parameters in place.
+ // If all were substituted, delete field.
+ for _, id := range field.Names {
+ if pinfo := params[paramIdx]; pinfo != nil {
+ // Rename unreferenced parameters with "_".
+ // This is crucial for binding decls, since
+ // unlike parameters, they are subject to
+ // "unreferenced var" checks.
+ if len(pinfo.info.Refs) == 0 {
+ id = makeIdent("_")
+ }
+ names = append(names, id)
+ }
+ paramIdx++
+ }
+ }
+ if names != nil {
+ newParams = append(newParams, &ast.Field{
+ Names: names,
+ Type: field.Type,
+ })
+ }
+ }
+ if calleeDecl.Recv != nil {
+ filterParams(calleeDecl.Recv.List[0])
+ calleeDecl.Recv = nil
+ }
+ for _, field := range calleeDecl.Type.Params.List {
+ filterParams(field)
+ }
+ calleeDecl.Type.Params.List = newParams
+}
+
+// bindingDeclInfo records information about the binding decl produced by
+// createBindingDecl.
+type bindingDeclInfo struct {
+ names map[string]bool // names bound by the binding decl; possibly empty
+ stmt ast.Stmt // the binding decl itself
+}
+
+// createBindingDecl constructs a "binding decl" that implements
+// parameter assignment and declares any named result variables
+// referenced by the callee. It returns nil if there were no
+// unsubstituted parameters.
+//
+// It may not always be possible to create the decl (e.g. due to
+// shadowing), in which case it also returns nil; but if it succeeds,
+// the declaration may be used by reduction strategies to relax the
+// requirement that all parameters have been substituted.
+//
+// For example, a call:
+//
+// f(a0, a1, a2)
+//
+// where:
+//
+// func f(p0, p1 T0, p2 T1) { body }
+//
+// reduces to:
+//
+// {
+// var (
+// p0, p1 T0 = a0, a1
+// p2 T1 = a2
+// )
+// body
+// }
+//
+// so long as p0, p1 ∉ freevars(T1) or freevars(a2), and so on,
+// because each spec is statically resolved in sequence and
+// dynamically assigned in sequence. By contrast, all
+// parameters are resolved simultaneously and assigned
+// simultaneously.
+//
+// The pX names should already be blank ("_") if the parameter
+// is unreferenced; this avoids "unreferenced local var" checks.
+//
+// Strategies may impose additional checks on return
+// conversions, labels, defer, etc.
+func createBindingDecl(logf logger, caller *Caller, args []*argument, calleeDecl *ast.FuncDecl, results []*paramInfo) *bindingDeclInfo {
+ // Spread calls are tricky as they may not align with the
+ // parameters' field groupings nor types.
+ // For example, given
+ // func g() (int, string)
+ // the call
+ // f(g())
+ // is legal with these decls of f:
+ // func f(int, string)
+ // func f(x, y any)
+ // func f(x, y ...any)
+ // TODO(adonovan): support binding decls for spread calls by
+ // splitting parameter groupings as needed.
+ if lastArg := last(args); lastArg != nil && lastArg.spread {
+ logf("binding decls not yet supported for spread calls")
+ return nil
+ }
+
+ var (
+ specs []ast.Spec
+ names = make(map[string]bool) // names defined by previous specs
+ )
+ // shadow reports whether any name referenced by spec is
+ // shadowed by a name declared by a previous spec (since,
+ // unlike parameters, each spec of a var decl is within the
+ // scope of the previous specs).
+ shadow := func(spec *ast.ValueSpec) bool {
+ // Compute union of free names of type and values
+ // and detect shadowing. Values is the arguments
+ // (caller syntax), so we can use type info.
+ // But Type is the untyped callee syntax,
+ // so we have to use a syntax-only algorithm.
+ const includeComplitIdents = true
+ free := free.Names(spec.Type, includeComplitIdents)
+ for _, value := range spec.Values {
+ for name := range freeVars(caller.Info, value) {
+ free[name] = true
+ }
+ }
+ for name := range free {
+ if names[name] {
+ logf("binding decl would shadow free name %q", name)
+ return true
+ }
+ }
+ for _, id := range spec.Names {
+ if id.Name != "_" {
+ names[id.Name] = true
+ }
+ }
+ return false
+ }
+
+ // parameters
+ //
+ // Bind parameters that were not eliminated through
+ // substitution. (Non-nil arguments correspond to the
+ // remaining parameters in calleeDecl.)
+ var values []ast.Expr
+ for _, arg := range args {
+ if arg != nil {
+ values = append(values, arg.expr)
+ }
+ }
+ for _, field := range calleeDecl.Type.Params.List {
+ // Each field (param group) becomes a ValueSpec.
+ spec := &ast.ValueSpec{
+ Names: cleanNodes(field.Names),
+ Type: cleanNode(field.Type),
+ Values: values[:len(field.Names)],
+ }
+ values = values[len(field.Names):]
+ if shadow(spec) {
+ return nil
+ }
+ specs = append(specs, spec)
+ }
+ assert(len(values) == 0, "args/params mismatch")
+
+ // results
+ //
+ // Add specs to declare any named result
+ // variables that are referenced by the body.
+ if calleeDecl.Type.Results != nil {
+ resultIdx := 0
+ for _, field := range calleeDecl.Type.Results.List {
+ if field.Names == nil {
+ resultIdx++
+ continue // unnamed field
+ }
+ var names []*ast.Ident
+ for _, id := range field.Names {
+ if len(results[resultIdx].Refs) > 0 {
+ names = append(names, id)
+ }
+ resultIdx++
+ }
+ if len(names) > 0 {
+ spec := &ast.ValueSpec{
+ Names: cleanNodes(names),
+ Type: cleanNode(field.Type),
+ }
+ if shadow(spec) {
+ return nil
+ }
+ specs = append(specs, spec)
+ }
+ }
+ }
+
+ if len(specs) == 0 {
+ logf("binding decl not needed: all parameters substituted")
+ return nil
+ }
+
+ stmt := &ast.DeclStmt{
+ Decl: &ast.GenDecl{
+ Tok: token.VAR,
+ Specs: specs,
+ },
+ }
+ logf("binding decl: %s", debugFormatNode(caller.Fset, stmt))
+ return &bindingDeclInfo{names: names, stmt: stmt}
+}
+
+// lookup does a symbol lookup in the lexical environment of the caller.
+func (caller *Caller) lookup(name string) types.Object {
+ pos := caller.Call.Pos()
+ for _, n := range caller.path {
+ if scope := scopeFor(caller.Info, n); scope != nil {
+ if _, obj := scope.LookupParent(name, pos); obj != nil {
+ return obj
+ }
+ }
+ }
+ return nil
+}
+
+func scopeFor(info *types.Info, n ast.Node) *types.Scope {
+ // The function body scope (containing not just params)
+ // is associated with the function's type, not body.
+ switch fn := n.(type) {
+ case *ast.FuncDecl:
+ n = fn.Type
+ case *ast.FuncLit:
+ n = fn.Type
+ }
+ return info.Scopes[n]
+}
+
+// -- predicates over expressions --
+
+// freeVars returns the names of all free identifiers of e:
+// those lexically referenced by it but not defined within it.
+// (Fields and methods are not included.)
+func freeVars(info *types.Info, e ast.Expr) map[string]bool {
+ free := make(map[string]bool)
+ ast.Inspect(e, func(n ast.Node) bool {
+ if id, ok := n.(*ast.Ident); ok {
+ // The isField check is so that we don't treat T{f: 0} as a ref to f.
+ if obj, ok := info.Uses[id]; ok && !within(obj.Pos(), e) && !isField(obj) {
+ free[obj.Name()] = true
+ }
+ }
+ return true
+ })
+ return free
+}
+
+// effects reports whether an expression might change the state of the
+// program (through function calls and channel receives) and affect
+// the evaluation of subsequent expressions.
+func (st *state) effects(info *types.Info, expr ast.Expr) bool {
+ effects := false
+ ast.Inspect(expr, func(n ast.Node) bool {
+ switch n := n.(type) {
+ case *ast.FuncLit:
+ return false // prune descent
+
+ case *ast.CallExpr:
+ if info.Types[n.Fun].IsType() {
+ // A conversion T(x) has only the effect of its operand.
+ } else if !typesinternal.CallsPureBuiltin(info, n) {
+ // A handful of built-ins have no effect
+ // beyond those of their arguments.
+ // All other calls (including append, copy, recover)
+ // have unknown effects.
+ //
+ // As with 'pure', there is room for
+ // improvement by inspecting the callee.
+ effects = true
+ }
+
+ case *ast.UnaryExpr:
+ if n.Op == token.ARROW { // <-ch
+ effects = true
+ }
+ }
+ return true
+ })
+
+ // Even if consideration of effects is not desired,
+ // we continue to compute, log, and discard them.
+ if st.opts.IgnoreEffects && effects {
+ effects = false
+ st.opts.Logf("ignoring potential effects of argument %s",
+ debugFormatNode(st.caller.Fset, expr))
+ }
+
+ return effects
+}
+
+// pure reports whether an expression has the same result no matter
+// when it is executed relative to other expressions, so it can be
+// commuted with any other expression or statement without changing
+// its meaning.
+//
+// An expression is considered impure if it reads the contents of any
+// variable, with the exception of "single assignment" local variables
+// (as classified by the provided callback), which are never updated
+// after their initialization.
+//
+// Pure does not imply duplicable: for example, new(T) and T{} are
+// pure expressions but both return a different value each time they
+// are evaluated, so they are not safe to duplicate.
+//
+// Purity does not imply freedom from run-time panics. We assume that
+// target programs do not encounter run-time panics nor depend on them
+// for correct operation.
+//
+// TODO(adonovan): add unit tests of this function.
+func pure(info *types.Info, assign1 func(*types.Var) bool, e ast.Expr) bool {
+ var pure func(e ast.Expr) bool
+ pure = func(e ast.Expr) bool {
+ switch e := e.(type) {
+ case *ast.ParenExpr:
+ return pure(e.X)
+
+ case *ast.Ident:
+ if v, ok := info.Uses[e].(*types.Var); ok {
+ // In general variables are impure
+ // as they may be updated, but
+ // single-assignment local variables
+ // never change value.
+ //
+ // We assume all package-level variables
+ // may be updated, but for non-exported
+ // ones we could do better by analyzing
+ // the complete package.
+ return !isPkgLevel(v) && assign1(v)
+ }
+
+ // All other kinds of reference are pure.
+ return true
+
+ case *ast.FuncLit:
+ // A function literal may allocate a closure that
+ // references mutable variables, but mutation
+ // cannot be observed without calling the function,
+ // and calls are considered impure.
+ return true
+
+ case *ast.BasicLit:
+ return true
+
+ case *ast.UnaryExpr: // + - ! ^ & but not <-
+ return e.Op != token.ARROW && pure(e.X)
+
+ case *ast.BinaryExpr: // arithmetic, shifts, comparisons, &&/||
+ return pure(e.X) && pure(e.Y)
+
+ case *ast.CallExpr:
+ // A conversion is as pure as its operand.
+ if info.Types[e.Fun].IsType() {
+ return pure(e.Args[0])
+ }
+
+ // Calls to some built-ins are as pure as their arguments.
+ if typesinternal.CallsPureBuiltin(info, e) {
+ for _, arg := range e.Args {
+ if !pure(arg) {
+ return false
+ }
+ }
+ return true
+ }
+
+ // All other calls are impure, so we can
+ // reject them without even looking at e.Fun.
+ //
+ // More sophisticated analysis could infer purity in
+ // commonly used functions such as strings.Contains;
+ // perhaps we could offer the client a hook so that
+ // go/analysis-based implementation could exploit the
+ // results of a purity analysis. But that would make
+ // the inliner's choices harder to explain.
+ return false
+
+ case *ast.CompositeLit:
+ // T{...} is as pure as its elements.
+ for _, elt := range e.Elts {
+ if kv, ok := elt.(*ast.KeyValueExpr); ok {
+ if !pure(kv.Value) {
+ return false
+ }
+ if id, ok := kv.Key.(*ast.Ident); ok {
+ if v, ok := info.Uses[id].(*types.Var); ok && v.IsField() {
+ continue // struct {field: value}
+ }
+ }
+ // map/slice/array {key: value}
+ if !pure(kv.Key) {
+ return false
+ }
+
+ } else if !pure(elt) {
+ return false
+ }
+ }
+ return true
+
+ case *ast.SelectorExpr:
+ if seln, ok := info.Selections[e]; ok {
+ // See types.SelectionKind for background.
+ switch seln.Kind() {
+ case types.MethodExpr:
+ // A method expression T.f acts like a
+ // reference to a func decl, so it is pure.
+ return true
+
+ case types.MethodVal, types.FieldVal:
+ // A field or method selection x.f is pure
+ // if x is pure and the selection does
+ // not indirect a pointer.
+ return !indirectSelection(seln) && pure(e.X)
+
+ default:
+ panic(seln)
+ }
+ } else {
+ // A qualified identifier is
+ // treated like an unqualified one.
+ return pure(e.Sel)
+ }
+
+ case *ast.StarExpr:
+ return false // *ptr depends on the state of the heap
+
+ default:
+ return false
+ }
+ }
+ return pure(e)
+}
+
+// duplicable reports whether it is appropriate for the expression to
+// be freely duplicated.
+//
+// Given the declaration
+//
+// func f(x T) T { return x + g() + x }
+//
+// an argument y is considered duplicable if we would wish to see a
+// call f(y) simplified to y+g()+y. This is true for identifiers,
+// integer literals, unary negation, and selectors x.f where x is not
+// a pointer. But we would not wish to duplicate expressions that:
+// - have side effects (e.g. nearly all calls),
+// - are not referentially transparent (e.g. &T{}, ptr.field, *ptr), or
+// - are long (e.g. "huge string literal").
+func duplicable(info *types.Info, e ast.Expr) bool {
+ switch e := e.(type) {
+ case *ast.ParenExpr:
+ return duplicable(info, e.X)
+
+ case *ast.Ident:
+ return true
+
+ case *ast.BasicLit:
+ v := info.Types[e].Value
+ switch e.Kind {
+ case token.INT:
+ return true // any int
+ case token.STRING:
+ return consteq(v, kZeroString) // only ""
+ case token.FLOAT:
+ return consteq(v, kZeroFloat) || consteq(v, kOneFloat) // only 0.0 or 1.0
+ }
+
+ case *ast.UnaryExpr: // e.g. +1, -1
+ return (e.Op == token.ADD || e.Op == token.SUB) && duplicable(info, e.X)
+
+ case *ast.CompositeLit:
+ // Empty struct or array literals T{} are duplicable.
+ // (Non-empty literals are too verbose, and slice/map
+ // literals allocate indirect variables.)
+ if len(e.Elts) == 0 {
+ switch info.TypeOf(e).Underlying().(type) {
+ case *types.Struct, *types.Array:
+ return true
+ }
+ }
+ return false
+
+ case *ast.CallExpr:
+ // Treat type conversions as duplicable if they do not observably allocate.
+ // The only cases of observable allocations are
+ // the `[]byte(string)` and `[]rune(string)` conversions.
+ //
+ // Duplicating string([]byte) conversions increases
+ // allocation but doesn't change behavior, but the
+ // reverse, []byte(string), allocates a distinct array,
+ // which is observable.
+
+ if !info.Types[e.Fun].IsType() { // check whether e.Fun is a type conversion
+ return false
+ }
+
+ fun := info.TypeOf(e.Fun)
+ arg := info.TypeOf(e.Args[0])
+
+ switch fun := fun.Underlying().(type) {
+ case *types.Slice:
+ // Do not mark []byte(string) and []rune(string) as duplicable.
+ elem, ok := fun.Elem().Underlying().(*types.Basic)
+ if ok && (elem.Kind() == types.Rune || elem.Kind() == types.Byte) {
+ from, ok := arg.Underlying().(*types.Basic)
+ isString := ok && from.Info()&types.IsString != 0
+ return !isString
+ }
+ case *types.TypeParam:
+ return false // be conservative
+ }
+ return true
+
+ case *ast.SelectorExpr:
+ if seln, ok := info.Selections[e]; ok {
+ // A field or method selection x.f is referentially
+ // transparent if it does not indirect a pointer.
+ return !indirectSelection(seln)
+ }
+ // A qualified identifier pkg.Name is referentially transparent.
+ return true
+ }
+ return false
+}
+
+func consteq(x, y constant.Value) bool {
+ return constant.Compare(x, token.EQL, y)
+}
+
+var (
+ kZeroInt = constant.MakeInt64(0)
+ kZeroString = constant.MakeString("")
+ kZeroFloat = constant.MakeFloat64(0.0)
+ kOneFloat = constant.MakeFloat64(1.0)
+)
+
+// -- inline helpers --
+
+func assert(cond bool, msg string) {
+ if !cond {
+ panic(msg)
+ }
+}
+
+// blanks returns a slice of n > 0 blank identifiers.
+func blanks[E ast.Expr](n int) []E {
+ if n == 0 {
+ panic("blanks(0)")
+ }
+ res := make([]E, n)
+ for i := range res {
+ res[i] = ast.Expr(makeIdent("_")).(E) // ugh
+ }
+ return res
+}
+
+func makeIdent(name string) *ast.Ident {
+ return &ast.Ident{Name: name}
+}
+
+// importedPkgName returns the PkgName object declared by an ImportSpec.
+// TODO(adonovan): make this a method of types.Info (#62037).
+func importedPkgName(info *types.Info, imp *ast.ImportSpec) (*types.PkgName, bool) {
+ var obj types.Object
+ if imp.Name != nil {
+ obj = info.Defs[imp.Name]
+ } else {
+ obj = info.Implicits[imp]
+ }
+ pkgname, ok := obj.(*types.PkgName)
+ return pkgname, ok
+}
+
+func isPkgLevel(obj types.Object) bool {
+ // TODO(adonovan): consider using the simpler obj.Parent() ==
+ // obj.Pkg().Scope() instead. But be sure to test carefully
+ // with instantiations of generics.
+ return obj.Pkg().Scope().Lookup(obj.Name()) == obj
+}
+
+// callContext returns the two nodes immediately enclosing the call
+// (specified as a PathEnclosingInterval), ignoring parens.
+func callContext(callPath []ast.Node) (parent, grandparent ast.Node) {
+ _ = callPath[0].(*ast.CallExpr) // sanity check
+ for _, n := range callPath[1:] {
+ if !is[*ast.ParenExpr](n) {
+ if parent == nil {
+ parent = n
+ } else {
+ return parent, n
+ }
+ }
+ }
+ return parent, nil
+}
+
+// hasLabelConflict reports whether the set of labels of the function
+// enclosing the call (specified as a PathEnclosingInterval)
+// intersects with the set of callee labels.
+func hasLabelConflict(callPath []ast.Node, calleeLabels []string) bool {
+ labels := callerLabels(callPath)
+ for _, label := range calleeLabels {
+ if labels[label] {
+ return true // conflict
+ }
+ }
+ return false
+}
+
+// callerLabels returns the set of control labels in the function (if
+// any) enclosing the call (specified as a PathEnclosingInterval).
+func callerLabels(callPath []ast.Node) map[string]bool {
+ var callerBody *ast.BlockStmt
+ switch f := callerFunc(callPath).(type) {
+ case *ast.FuncDecl:
+ callerBody = f.Body
+ case *ast.FuncLit:
+ callerBody = f.Body
+ }
+ var labels map[string]bool
+ if callerBody != nil {
+ ast.Inspect(callerBody, func(n ast.Node) bool {
+ switch n := n.(type) {
+ case *ast.FuncLit:
+ return false // prune traversal
+ case *ast.LabeledStmt:
+ if labels == nil {
+ labels = make(map[string]bool)
+ }
+ labels[n.Label.Name] = true
+ }
+ return true
+ })
+ }
+ return labels
+}
+
+// callerFunc returns the innermost Func{Decl,Lit} node enclosing the
+// call (specified as a PathEnclosingInterval).
+func callerFunc(callPath []ast.Node) ast.Node {
+ _ = callPath[0].(*ast.CallExpr) // sanity check
+ for _, n := range callPath[1:] {
+ if is[*ast.FuncDecl](n) || is[*ast.FuncLit](n) {
+ return n
+ }
+ }
+ return nil
+}
+
+// callStmt reports whether the function call (specified
+// as a PathEnclosingInterval) appears within an ExprStmt,
+// and returns it if so.
+//
+// If unrestricted, callStmt returns nil if the ExprStmt f() appears
+// in a restricted context (such as "if f(); cond {") where it cannot
+// be replaced by an arbitrary statement. (See "statement theory".)
+func callStmt(callPath []ast.Node, unrestricted bool) *ast.ExprStmt {
+ parent, _ := callContext(callPath)
+ stmt, ok := parent.(*ast.ExprStmt)
+ if ok && unrestricted {
+ switch callPath[slices.Index(callPath, ast.Node(stmt))+1].(type) {
+ case *ast.LabeledStmt,
+ *ast.BlockStmt,
+ *ast.CaseClause,
+ *ast.CommClause:
+ // unrestricted
+ default:
+ // TODO(adonovan): handle restricted
+ // XYZStmt.Init contexts (but not ForStmt.Post)
+ // by creating a block around the if/for/switch:
+ // "if f(); cond {" -> "{ stmts; if cond {"
+
+ return nil // restricted
+ }
+ }
+ return stmt
+}
+
+// Statement theory
+//
+// These are all the places a statement may appear in the AST:
+//
+// LabeledStmt.Stmt Stmt -- any
+// BlockStmt.List []Stmt -- any (but see switch/select)
+// IfStmt.Init Stmt? -- simple
+// IfStmt.Body BlockStmt
+// IfStmt.Else Stmt? -- IfStmt or BlockStmt
+// CaseClause.Body []Stmt -- any
+// SwitchStmt.Init Stmt? -- simple
+// SwitchStmt.Body BlockStmt -- CaseClauses only
+// TypeSwitchStmt.Init Stmt? -- simple
+// TypeSwitchStmt.Assign Stmt -- AssignStmt(TypeAssertExpr) or ExprStmt(TypeAssertExpr)
+// TypeSwitchStmt.Body BlockStmt -- CaseClauses only
+// CommClause.Comm Stmt? -- SendStmt or ExprStmt(UnaryExpr) or AssignStmt(UnaryExpr)
+// CommClause.Body []Stmt -- any
+// SelectStmt.Body BlockStmt -- CommClauses only
+// ForStmt.Init Stmt? -- simple
+// ForStmt.Post Stmt? -- simple
+// ForStmt.Body BlockStmt
+// RangeStmt.Body BlockStmt
+//
+// simple = AssignStmt | SendStmt | IncDecStmt | ExprStmt.
+//
+// A BlockStmt cannot replace an ExprStmt in
+// {If,Switch,TypeSwitch}Stmt.Init or ForStmt.Post.
+// That is allowed only within:
+// LabeledStmt.Stmt Stmt
+// BlockStmt.List []Stmt
+// CaseClause.Body []Stmt
+// CommClause.Body []Stmt
+
+// replaceNode performs a destructive update of the tree rooted at
+// root, replacing each occurrence of "from" with "to". If to is nil and
+// the element is within a slice, the slice element is removed.
+//
+// The root itself cannot be replaced; an attempt will panic.
+//
+// This function must not be called on the caller's syntax tree.
+//
+// TODO(adonovan): polish this up and move it to astutil package.
+// TODO(adonovan): needs a unit test.
+func replaceNode(root ast.Node, from, to ast.Node) {
+ if from == nil {
+ panic("from == nil")
+ }
+ if reflect.ValueOf(from).IsNil() {
+ panic(fmt.Sprintf("from == (%T)(nil)", from))
+ }
+ if from == root {
+ panic("from == root")
+ }
+ found := false
+ var parent reflect.Value // parent variable of interface type, containing a pointer
+ var visit func(reflect.Value)
+ visit = func(v reflect.Value) {
+ switch v.Kind() {
+ case reflect.Pointer:
+ if v.Interface() == from {
+ found = true
+
+ // If v is a struct field or array element
+ // (e.g. Field.Comment or Field.Names[i])
+ // then it is addressable (a pointer variable).
+ //
+ // But if it was the value an interface
+ // (e.g. *ast.Ident within ast.Node)
+ // then it is non-addressable, and we need
+ // to set the enclosing interface (parent).
+ if !v.CanAddr() {
+ v = parent
+ }
+
+ // to=nil => use zero value
+ var toV reflect.Value
+ if to != nil {
+ toV = reflect.ValueOf(to)
+ } else {
+ toV = reflect.Zero(v.Type()) // e.g. ast.Expr(nil)
+ }
+ v.Set(toV)
+
+ } else if !v.IsNil() {
+ switch v.Interface().(type) {
+ case *ast.Object, *ast.Scope:
+ // Skip fields of types potentially involved in cycles.
+ default:
+ visit(v.Elem())
+ }
+ }
+
+ case reflect.Struct:
+ for i := range v.Type().NumField() {
+ visit(v.Field(i))
+ }
+
+ case reflect.Slice:
+ compact := false
+ for i := range v.Len() {
+ visit(v.Index(i))
+ if v.Index(i).IsNil() {
+ compact = true
+ }
+ }
+ if compact {
+ // Elements were deleted. Eliminate nils.
+ // (Do this is a second pass to avoid
+ // unnecessary writes in the common case.)
+ j := 0
+ for i := range v.Len() {
+ if !v.Index(i).IsNil() {
+ v.Index(j).Set(v.Index(i))
+ j++
+ }
+ }
+ v.SetLen(j)
+ }
+ case reflect.Interface:
+ parent = v
+ visit(v.Elem())
+
+ case reflect.Array, reflect.Chan, reflect.Func, reflect.Map, reflect.UnsafePointer:
+ panic(v) // unreachable in AST
+ default:
+ // bool, string, number: nop
+ }
+ parent = reflect.Value{}
+ }
+ visit(reflect.ValueOf(root))
+ if !found {
+ panic(fmt.Sprintf("%T not found", from))
+ }
+}
+
+// cleanNode returns a clone of node with positions cleared.
+//
+// It should be used for any callee nodes that are formatted using the caller
+// file set.
+func cleanNode[T ast.Node](node T) T {
+ clone := internalastutil.CloneNode(node)
+ clearPositions(clone)
+ return clone
+}
+
+func cleanNodes[T ast.Node](nodes []T) []T {
+ var clean []T
+ for _, node := range nodes {
+ clean = append(clean, cleanNode(node))
+ }
+ return clean
+}
+
+// clearPositions destroys token.Pos information within the tree rooted at root,
+// as positions in callee trees may cause caller comments to be emitted prematurely.
+//
+// In general it isn't safe to clear a valid Pos because some of them
+// (e.g. CallExpr.Ellipsis, TypeSpec.Assign) are significant to
+// go/printer, so this function sets each non-zero Pos to 1, which
+// suffices to avoid advancing the printer's comment cursor.
+//
+// This function mutates its argument; do not invoke on caller syntax.
+//
+// TODO(adonovan): remove this horrendous workaround when #20744 is finally fixed.
+func clearPositions(root ast.Node) {
+ posType := reflect.TypeFor[token.Pos]()
+ ast.Inspect(root, func(n ast.Node) bool {
+ if n != nil {
+ v := reflect.ValueOf(n).Elem() // deref the pointer to struct
+ fields := v.Type().NumField()
+ for i := range fields {
+ f := v.Field(i)
+ // Clearing Pos arbitrarily is destructive,
+ // as its presence may be semantically significant
+ // (e.g. CallExpr.Ellipsis, TypeSpec.Assign)
+ // or affect formatting preferences (e.g. GenDecl.Lparen).
+ //
+ // Note: for proper formatting, it may be necessary to be selective
+ // about which positions we set to 1 vs which we set to token.NoPos.
+ // (e.g. we can set most to token.NoPos, save the few that are
+ // significant).
+ if f.Type() == posType {
+ if f.Interface() != token.NoPos {
+ f.Set(reflect.ValueOf(token.Pos(1)))
+ }
+ }
+ }
+ }
+ return true
+ })
+}
+
+// findIdent finds the Ident beneath root that has the given pos.
+// It returns the path to the ident (excluding the ident), and the ident
+// itself, where the path is the sequence of ast.Nodes encountered in a
+// depth-first search to find ident.
+func findIdent(root ast.Node, pos token.Pos) ([]ast.Node, *ast.Ident) {
+ // TODO(adonovan): opt: skip subtrees that don't contain pos.
+ var (
+ path []ast.Node
+ found *ast.Ident
+ )
+ ast.Inspect(root, func(n ast.Node) bool {
+ if found != nil {
+ return false
+ }
+ if n == nil {
+ path = path[:len(path)-1]
+ return false
+ }
+ if id, ok := n.(*ast.Ident); ok {
+ if id.Pos() == pos {
+ found = id
+ return true
+ }
+ }
+ path = append(path, n)
+ return true
+ })
+ if found == nil {
+ panic(fmt.Sprintf("findIdent %d not found in %s",
+ pos, debugFormatNode(token.NewFileSet(), root)))
+ }
+ return path, found
+}
+
+func prepend[T any](elem T, slice ...T) []T {
+ return append([]T{elem}, slice...)
+}
+
+// debugFormatNode formats a node or returns a formatting error.
+// Its sloppy treatment of errors is appropriate only for logging.
+func debugFormatNode(fset *token.FileSet, n ast.Node) string {
+ var out strings.Builder
+ if err := format.Node(&out, fset, n); err != nil {
+ out.WriteString(err.Error())
+ }
+ return out.String()
+}
+
+func shallowCopy[T any](ptr *T) *T {
+ copy := *ptr
+ return ©
+}
+
+// ∀
+func forall[T any](list []T, f func(i int, x T) bool) bool {
+ for i, x := range list {
+ if !f(i, x) {
+ return false
+ }
+ }
+ return true
+}
+
+// ∃
+func exists[T any](list []T, f func(i int, x T) bool) bool {
+ for i, x := range list {
+ if f(i, x) {
+ return true
+ }
+ }
+ return false
+}
+
+// last returns the last element of a slice, or zero if empty.
+func last[T any](slice []T) T {
+ n := len(slice)
+ if n > 0 {
+ return slice[n-1]
+ }
+ return *new(T)
+}
+
+// declares returns the set of lexical names declared by a
+// sequence of statements from the same block, excluding sub-blocks.
+// (Lexical names do not include control labels.)
+func declares(stmts []ast.Stmt) map[string]bool {
+ names := make(map[string]bool)
+ for _, stmt := range stmts {
+ switch stmt := stmt.(type) {
+ case *ast.DeclStmt:
+ for _, spec := range stmt.Decl.(*ast.GenDecl).Specs {
+ switch spec := spec.(type) {
+ case *ast.ValueSpec:
+ for _, id := range spec.Names {
+ names[id.Name] = true
+ }
+ case *ast.TypeSpec:
+ names[spec.Name.Name] = true
+ }
+ }
+
+ case *ast.AssignStmt:
+ if stmt.Tok == token.DEFINE {
+ for _, lhs := range stmt.Lhs {
+ names[lhs.(*ast.Ident).Name] = true
+ }
+ }
+ }
+ }
+ delete(names, "_")
+ return names
+}
+
+// A importNameFunc is used to query local import names in the caller, in a
+// particular shadowing context.
+//
+// The shadow map contains additional names shadowed in the inlined code, at
+// the position the local import name is to be used. The shadow map only needs
+// to contain newly introduced names in the inlined code; names shadowed at the
+// caller are handled automatically.
+type importNameFunc = func(pkgPath string, shadow shadowMap) string
+
+// assignStmts rewrites a statement assigning the results of a call into zero
+// or more statements that assign its return operands, or (nil, false) if no
+// such rewrite is possible. The set of bindings created by the result of
+// assignStmts is the same as the set of bindings created by the callerStmt.
+//
+// The callee must contain exactly one return statement.
+//
+// This is (once again) a surprisingly complex task. For example, depending on
+// types and existing bindings, the assignment
+//
+// a, b := f()
+//
+// could be rewritten as:
+//
+// a, b := 1, 2
+//
+// but may need to be written as:
+//
+// a, b := int8(1), int32(2)
+//
+// In the case where the return statement within f is a spread call to another
+// function g(), we cannot explicitly convert the return values inline, and so
+// it may be necessary to split the declaration and assignment of variables
+// into separate statements:
+//
+// a, b := g()
+//
+// or
+//
+// var a int32
+// a, b = g()
+//
+// or
+//
+// var (
+// a int8
+// b int32
+// )
+// a, b = g()
+//
+// Note: assignStmts may return (nil, true) if it determines that the rewritten
+// assignment consists only of _ = nil assignments.
+func (st *state) assignStmts(callerStmt *ast.AssignStmt, returnOperands []ast.Expr, importName importNameFunc) ([]ast.Stmt, bool) {
+ logf, caller, callee := st.opts.Logf, st.caller, &st.callee.impl
+
+ assert(len(callee.Returns) == 1, "unexpected multiple returns")
+ resultInfo := callee.Returns[0]
+
+ // When constructing assign statements, we need to make sure that we don't
+ // modify types on the left-hand side, such as would happen if the type of a
+ // RHS expression does not match the corresponding LHS type at the caller
+ // (due to untyped conversion or interface widening).
+ //
+ // This turns out to be remarkably tricky to handle correctly.
+ //
+ // Substrategies below are labeled as `Substrategy :`.
+
+ // Collect LHS information.
+ var (
+ lhs []ast.Expr // shallow copy of the LHS slice, for mutation
+ defs = make([]*ast.Ident, len(callerStmt.Lhs)) // indexes in lhs of defining identifiers
+ blanks = make([]bool, len(callerStmt.Lhs)) // indexes in lhs of blank identifiers
+ byType typeutil.Map // map of distinct types -> indexes, for writing specs later
+ )
+ for i, expr := range callerStmt.Lhs {
+ lhs = append(lhs, expr)
+ if name, ok := expr.(*ast.Ident); ok {
+ if name.Name == "_" {
+ blanks[i] = true
+ continue // no type
+ }
+
+ if obj, isDef := caller.Info.Defs[name]; isDef {
+ defs[i] = name
+ typ := obj.Type()
+ idxs, _ := byType.At(typ).([]int)
+ idxs = append(idxs, i)
+ byType.Set(typ, idxs)
+ }
+ }
+ }
+
+ // Collect RHS information
+ //
+ // The RHS is either a parallel assignment or spread assignment, but by
+ // looping over both callerStmt.Rhs and returnOperands we handle both.
+ var (
+ rhs []ast.Expr // new RHS of assignment, owned by the inliner
+ callIdx = -1 // index of the call among the original RHS
+ nilBlankAssigns = make(map[int]unit) // indexes in rhs of _ = nil assignments, which can be deleted
+ freeNames = make(map[string]bool) // free(ish) names among rhs expressions
+ nonTrivial = make(map[int]bool) // indexes in rhs of nontrivial result conversions
+ )
+ const includeComplitIdents = true
+
+ for i, expr := range callerStmt.Rhs {
+ if expr == caller.Call {
+ assert(callIdx == -1, "malformed (duplicative) AST")
+ callIdx = i
+ for j, returnOperand := range returnOperands {
+ maps.Copy(freeNames, free.Names(returnOperand, includeComplitIdents))
+ rhs = append(rhs, returnOperand)
+ if resultInfo[j]&nonTrivialResult != 0 {
+ nonTrivial[i+j] = true
+ }
+ if blanks[i+j] && resultInfo[j]&untypedNilResult != 0 {
+ nilBlankAssigns[i+j] = unit{}
+ }
+ }
+ } else {
+ // We must clone before clearing positions, since e came from the caller.
+ expr = internalastutil.CloneNode(expr)
+ clearPositions(expr)
+ maps.Copy(freeNames, free.Names(expr, includeComplitIdents))
+ rhs = append(rhs, expr)
+ }
+ }
+ assert(callIdx >= 0, "failed to find call in RHS")
+
+ // Substrategy "splice": Check to see if we can simply splice in the result
+ // expressions from the callee, such as simplifying
+ //
+ // x, y := f()
+ //
+ // to
+ //
+ // x, y := e1, e2
+ //
+ // where the types of x and y match the types of e1 and e2.
+ //
+ // This works as long as we don't need to write any additional type
+ // information.
+ if len(nonTrivial) == 0 { // no non-trivial conversions to worry about
+
+ logf("substrategy: splice assignment")
+ return []ast.Stmt{&ast.AssignStmt{
+ Lhs: lhs,
+ Tok: callerStmt.Tok,
+ TokPos: callerStmt.TokPos,
+ Rhs: rhs,
+ }}, true
+ }
+
+ // Inlining techniques below will need to write type information in order to
+ // preserve the correct types of LHS identifiers.
+ //
+ // typeExpr is a simple helper to write out type expressions. It currently
+ // handles (possibly qualified) type names.
+ //
+ // TODO(rfindley):
+ // 1. expand this to handle more type expressions.
+ // 2. refactor to share logic with callee rewriting.
+ universeAny := types.Universe.Lookup("any")
+ typeExpr := func(typ types.Type, shadow shadowMap) ast.Expr {
+ var (
+ typeName string
+ obj *types.TypeName // nil for basic types
+ )
+ if tname := typesinternal.TypeNameFor(typ); tname != nil {
+ obj = tname
+ typeName = tname.Name()
+ }
+
+ // Special case: check for universe "any".
+ // TODO(golang/go#66921): this may become unnecessary if any becomes a proper alias.
+ if typ == universeAny.Type() {
+ typeName = "any"
+ }
+
+ if typeName == "" {
+ return nil
+ }
+
+ if obj == nil || obj.Pkg() == nil || obj.Pkg() == caller.Types { // local type or builtin
+ if shadow[typeName] != 0 {
+ logf("cannot write shadowed type name %q", typeName)
+ return nil
+ }
+ obj, _ := caller.lookup(typeName).(*types.TypeName)
+ if obj != nil && types.Identical(obj.Type(), typ) {
+ return ast.NewIdent(typeName)
+ }
+ } else if pkgName := importName(obj.Pkg().Path(), shadow); pkgName != "" {
+ return &ast.SelectorExpr{
+ X: ast.NewIdent(pkgName),
+ Sel: ast.NewIdent(typeName),
+ }
+ }
+ return nil
+ }
+
+ // Substrategy "spread": in the case of a spread call (func f() (T1, T2) return
+ // g()), since we didn't hit the 'splice' substrategy, there must be some
+ // non-declaring expression on the LHS. Simplify this by pre-declaring
+ // variables, rewriting
+ //
+ // x, y := f()
+ //
+ // to
+ //
+ // var x int
+ // x, y = g()
+ //
+ // Which works as long as the predeclared variables do not overlap with free
+ // names on the RHS.
+ if len(rhs) != len(lhs) {
+ assert(len(rhs) == 1 && len(returnOperands) == 1, "expected spread call")
+
+ for _, id := range defs {
+ if id != nil && freeNames[id.Name] {
+ // By predeclaring variables, we're changing them to be in scope of the
+ // RHS. We can't do this if their names are free on the RHS.
+ return nil, false
+ }
+ }
+
+ // Write out the specs, being careful to avoid shadowing free names in
+ // their type expressions.
+ var (
+ specs []ast.Spec
+ specIdxs []int
+ shadow = make(shadowMap)
+ )
+ failed := false
+ byType.Iterate(func(typ types.Type, v any) {
+ if failed {
+ return
+ }
+ idxs := v.([]int)
+ specIdxs = append(specIdxs, idxs[0])
+ texpr := typeExpr(typ, shadow)
+ if texpr == nil {
+ failed = true
+ return
+ }
+ spec := &ast.ValueSpec{
+ Type: texpr,
+ }
+ for _, idx := range idxs {
+ spec.Names = append(spec.Names, ast.NewIdent(defs[idx].Name))
+ }
+ specs = append(specs, spec)
+ })
+ if failed {
+ return nil, false
+ }
+ logf("substrategy: spread assignment")
+ return []ast.Stmt{
+ &ast.DeclStmt{
+ Decl: &ast.GenDecl{
+ Tok: token.VAR,
+ Specs: specs,
+ },
+ },
+ &ast.AssignStmt{
+ Lhs: callerStmt.Lhs,
+ Tok: token.ASSIGN,
+ Rhs: returnOperands,
+ },
+ }, true
+ }
+
+ assert(len(lhs) == len(rhs), "mismatching LHS and RHS")
+
+ // Substrategy "convert": write out RHS expressions with explicit type conversions
+ // as necessary, rewriting
+ //
+ // x, y := f()
+ //
+ // to
+ //
+ // x, y := 1, int32(2)
+ //
+ // As required to preserve types.
+ //
+ // In the special case of _ = nil, which is disallowed by the type checker
+ // (since nil has no default type), we delete the assignment.
+ var origIdxs []int // maps back to original indexes after lhs and rhs are pruned
+ i := 0
+ for j := range lhs {
+ if _, ok := nilBlankAssigns[j]; !ok {
+ lhs[i] = lhs[j]
+ rhs[i] = rhs[j]
+ origIdxs = append(origIdxs, j)
+ i++
+ }
+ }
+ lhs = lhs[:i]
+ rhs = rhs[:i]
+
+ if len(lhs) == 0 {
+ logf("trivial assignment after pruning nil blanks assigns")
+ // After pruning, we have no remaining assignments.
+ // Signal this by returning a non-nil slice of statements.
+ return nil, true
+ }
+
+ // Write out explicit conversions as necessary.
+ //
+ // A conversion is necessary if the LHS is being defined, and the RHS return
+ // involved a nontrivial implicit conversion.
+ for i, expr := range rhs {
+ idx := origIdxs[i]
+ if nonTrivial[idx] && defs[idx] != nil {
+ typ := caller.Info.TypeOf(lhs[i])
+ texpr := typeExpr(typ, nil)
+ if texpr == nil {
+ return nil, false
+ }
+ if _, ok := texpr.(*ast.StarExpr); ok {
+ // TODO(rfindley): is this necessary? Doesn't the formatter add these parens?
+ texpr = &ast.ParenExpr{X: texpr} // *T -> (*T) so that (*T)(x) is valid
+ }
+ rhs[i] = &ast.CallExpr{
+ Fun: texpr,
+ Args: []ast.Expr{expr},
+ }
+ }
+ }
+ logf("substrategy: convert assignment")
+ return []ast.Stmt{&ast.AssignStmt{
+ Lhs: lhs,
+ Tok: callerStmt.Tok,
+ Rhs: rhs,
+ }}, true
+}
+
+// tailCallSafeReturn reports whether the callee's return statements may be safely
+// used to return from the function enclosing the caller (which must exist).
+func tailCallSafeReturn(caller *Caller, calleeSymbol *types.Func, callee *gobCallee) bool {
+ // It is safe if all callee returns involve only trivial conversions.
+ if !hasNonTrivialReturn(callee.Returns) {
+ return true
+ }
+
+ var callerType types.Type
+ // Find type of innermost function enclosing call.
+ // (Beware: Caller.enclosingFunc is the outermost.)
+loop:
+ for _, n := range caller.path {
+ switch f := n.(type) {
+ case *ast.FuncDecl:
+ callerType = caller.Info.ObjectOf(f.Name).Type()
+ break loop
+ case *ast.FuncLit:
+ callerType = caller.Info.TypeOf(f)
+ break loop
+ }
+ }
+
+ // Non-trivial return conversions in the callee are permitted
+ // if the same non-trivial conversion would occur after inlining,
+ // i.e. if the caller and callee results tuples are identical.
+ callerResults := callerType.(*types.Signature).Results()
+ calleeResults := calleeSymbol.Type().(*types.Signature).Results()
+ return types.Identical(callerResults, calleeResults)
+}
+
+// hasNonTrivialReturn reports whether any of the returns involve a nontrivial
+// implicit conversion of a result expression.
+func hasNonTrivialReturn(returnInfo [][]returnOperandFlags) bool {
+ for _, resultInfo := range returnInfo {
+ for _, r := range resultInfo {
+ if r&nonTrivialResult != 0 {
+ return true
+ }
+ }
+ }
+ return false
+}
+
+type unit struct{} // for representing sets as maps
diff --git a/vendor/golang.org/x/tools/internal/refactor/inline/util.go b/vendor/golang.org/x/tools/internal/refactor/inline/util.go
new file mode 100644
index 000000000..5f895cce5
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/refactor/inline/util.go
@@ -0,0 +1,169 @@
+// Copyright 2023 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 inline
+
+// This file defines various common helpers.
+
+import (
+ "go/ast"
+ "go/constant"
+ "go/token"
+ "go/types"
+ "reflect"
+ "strings"
+
+ "golang.org/x/tools/internal/typeparams"
+)
+
+func is[T any](x any) bool {
+ _, ok := x.(T)
+ return ok
+}
+
+func btoi(b bool) int {
+ if b {
+ return 1
+ } else {
+ return 0
+ }
+}
+
+func offsetOf(fset *token.FileSet, pos token.Pos) int {
+ return fset.PositionFor(pos, false).Offset
+}
+
+// objectKind returns an object's kind (e.g. var, func, const, typename).
+func objectKind(obj types.Object) string {
+ return strings.TrimPrefix(strings.ToLower(reflect.TypeOf(obj).String()), "*types.")
+}
+
+// within reports whether pos is within the half-open interval [n.Pos, n.End).
+func within(pos token.Pos, n ast.Node) bool {
+ return n.Pos() <= pos && pos < n.End()
+}
+
+// trivialConversion reports whether it is safe to omit the implicit
+// value-to-variable conversion that occurs in argument passing or
+// result return. The only case currently allowed is converting from
+// untyped constant to its default type (e.g. 0 to int).
+//
+// The reason for this check is that converting from A to B to C may
+// yield a different result than converting A directly to C: consider
+// 0 to int32 to any.
+//
+// trivialConversion under-approximates trivial conversions, as unfortunately
+// go/types does not record the type of an expression *before* it is implicitly
+// converted, and therefore it cannot distinguish typed constant
+// expressions from untyped constant expressions. For example, in the
+// expression `c + 2`, where c is a uint32 constant, trivialConversion does not
+// detect that the default type of this expression is actually uint32, not untyped
+// int.
+//
+// We could, of course, do better here by reverse engineering some of go/types'
+// constant handling. That may or may not be worthwhile.
+//
+// Example: in func f() int32 { return 0 },
+// the type recorded for 0 is int32, not untyped int;
+// although it is Identical to the result var,
+// the conversion is non-trivial.
+func trivialConversion(fromValue constant.Value, from, to types.Type) bool {
+ if fromValue != nil {
+ var defaultType types.Type
+ switch fromValue.Kind() {
+ case constant.Bool:
+ defaultType = types.Typ[types.Bool]
+ case constant.String:
+ defaultType = types.Typ[types.String]
+ case constant.Int:
+ defaultType = types.Typ[types.Int]
+ case constant.Float:
+ defaultType = types.Typ[types.Float64]
+ case constant.Complex:
+ defaultType = types.Typ[types.Complex128]
+ default:
+ return false
+ }
+ return types.Identical(defaultType, to)
+ }
+ return types.Identical(from, to)
+}
+
+func checkInfoFields(info *types.Info) {
+ assert(info.Defs != nil, "types.Info.Defs is nil")
+ assert(info.Implicits != nil, "types.Info.Implicits is nil")
+ assert(info.Scopes != nil, "types.Info.Scopes is nil")
+ assert(info.Selections != nil, "types.Info.Selections is nil")
+ assert(info.Types != nil, "types.Info.Types is nil")
+ assert(info.Uses != nil, "types.Info.Uses is nil")
+ assert(info.FileVersions != nil, "types.Info.FileVersions is nil")
+}
+
+// intersects reports whether the maps' key sets intersect.
+func intersects[K comparable, T1, T2 any](x map[K]T1, y map[K]T2) bool {
+ if len(x) > len(y) {
+ return intersects(y, x)
+ }
+ for k := range x {
+ if _, ok := y[k]; ok {
+ return true
+ }
+ }
+ return false
+}
+
+// convert returns syntax for the conversion T(x).
+func convert(T, x ast.Expr) *ast.CallExpr {
+ // The formatter generally adds parens as needed,
+ // but before go1.22 it had a bug (#63362) for
+ // channel types that requires this workaround.
+ if ch, ok := T.(*ast.ChanType); ok && ch.Dir == ast.RECV {
+ T = &ast.ParenExpr{X: T}
+ }
+ return &ast.CallExpr{
+ Fun: T,
+ Args: []ast.Expr{x},
+ }
+}
+
+// isPointer reports whether t's core type is a pointer.
+func isPointer(t types.Type) bool {
+ return is[*types.Pointer](typeparams.CoreType(t))
+}
+
+// indirectSelection is like seln.Indirect() without bug #8353.
+func indirectSelection(seln *types.Selection) bool {
+ // Work around bug #8353 in Selection.Indirect when Kind=MethodVal.
+ if seln.Kind() == types.MethodVal {
+ tArg, indirect := effectiveReceiver(seln)
+ if indirect {
+ return true
+ }
+
+ tParam := seln.Obj().Type().Underlying().(*types.Signature).Recv().Type()
+ return isPointer(tArg) && !isPointer(tParam) // implicit *
+ }
+
+ return seln.Indirect()
+}
+
+// effectiveReceiver returns the effective type of the method
+// receiver after all implicit field selections (but not implicit * or
+// & operations) have been applied.
+//
+// The boolean indicates whether any implicit field selection was indirect.
+func effectiveReceiver(seln *types.Selection) (types.Type, bool) {
+ assert(seln.Kind() == types.MethodVal, "not MethodVal")
+ t := seln.Recv()
+ indices := seln.Index()
+ indirect := false
+ for _, index := range indices[:len(indices)-1] {
+ if isPointer(t) {
+ indirect = true
+ t = typeparams.MustDeref(t)
+ }
+ t = typeparams.CoreType(t).(*types.Struct).Field(index).Type()
+ }
+ return t, indirect
+}
diff --git a/vendor/golang.org/x/tools/internal/typesinternal/assignedaddress.go b/vendor/golang.org/x/tools/internal/typesinternal/assignedaddress.go
new file mode 100644
index 000000000..020defc38
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/typesinternal/assignedaddress.go
@@ -0,0 +1,128 @@
+// Copyright 2026 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 typesinternal
+
+import (
+ "go/ast"
+ "go/token"
+ "go/types"
+
+ "golang.org/x/tools/go/ast/edge"
+ "golang.org/x/tools/go/ast/inspector"
+)
+
+// IsAssignedOrAddressTaken reports whether the expression cur denotes a
+// variable and appears in a context that assigns it or that takes its address,
+// potentially leading to indirect assignment.
+//
+// These examples cause IsAssignedOrAddressTaken on the identifier for x to
+// return true:
+//
+// x = 1
+// x++
+// x[i] = 1 (assume x is an array)
+// x.a[i] = 1 (assume x.a is a non-pointer struct field)
+// use(&x)
+//
+// whereas these cause it to return false:
+//
+// y = x
+// f(x)
+// use(x.a[i])
+// use(*x)
+//
+// The expression may itself be a compound, for example:
+//
+// use(&(*ptr)) => IsAssignedOrAddressTaken("*ptr") = true
+// x.a[i] = 1 => IsAssignedOrAddressTaken("x.a") = true
+// _ = x.a[i] => IsAssignedOrAddressTaken("x.a") = false
+//
+// A variable's declaration is not considered to be an assignment:
+//
+// var x int => IsAssignedOrAddressTaken(x) = false
+// x := 1 => IsAssignedOrAddressTaken(x) = false
+//
+// TODO(adonovan): revisit the surprising behavior for declarations.
+func IsAssignedOrAddressTaken(info *types.Info, cur inspector.Cursor) bool {
+ // Unfortunately we can't simply use info.Types[e].Assignable()
+ // as it is always true for a variable even when that variable is
+ // used only as an r-value. So we must inspect enclosing syntax.
+outer:
+ // Ascend to outermost aggregate of which
+ // original cur is a part:
+ // x -> (x) | x.f | x[i] | x[i:j]
+ for cur = range cur.Enclosing() {
+ switch cur.ParentEdgeKind() {
+ case edge.ParenExpr_X:
+ // If x is an lvalue, then (x) is an lvalue.
+ case edge.SelectorExpr_X:
+ // If x is an lvalue, then x.f is an lvalue iff
+ // the selection does not traverse a pointer.
+ sel := cur.Parent().Node().(*ast.SelectorExpr)
+ if seln, ok := info.Selections[sel]; ok {
+ // Note: there is a bug in Indirect() where it spuriously returns true
+ // when both the selection receiver and parameter are pointers. However,
+ // it's okay in this case because there is no address taken when a
+ // pointer receiver method is called on a pointer type.
+ if seln.Indirect() {
+ return false
+ }
+ if seln.Kind() == types.MethodVal {
+ sig := seln.Obj().Type().(*types.Signature)
+ if is[*types.Pointer](sig.Recv().Type().Underlying()) {
+ t := seln.Recv()
+ // The receiver may be an embedded field, so we need
+ // to get the inner-most type (right before the method
+ // call in seln.Index())
+ for _, idx := range seln.Index()[:len(seln.Index())-1] {
+ t = t.Underlying().(*types.Struct).Field(idx).Type()
+ }
+ if !is[*types.Pointer](t.Underlying()) {
+ return true // takes address of receiver
+ }
+ }
+ return false
+ }
+ }
+ case edge.IndexExpr_X, edge.SliceExpr_X:
+ // If x[i] or x[i:j] is an lvalue,
+ // then x is an lvalue iff x is an array.
+ if !is[*types.Array](info.TypeOf(cur.Node().(ast.Expr)).Underlying()) {
+ return false
+ }
+ default:
+ break outer
+ }
+ }
+ switch cur.ParentEdgeKind() {
+ case edge.AssignStmt_Lhs:
+ assign := cur.Parent().Node().(*ast.AssignStmt)
+ if assign.Tok != token.DEFINE {
+ return true // x = j or x += j
+ }
+ id := cur.Node().(*ast.Ident)
+ // Re-assigned identifiers are recorded in the Uses map.
+ if _, ok := info.Uses[id]; ok {
+ return true // reassignment of x (x, y := 1, 2)
+ }
+ case edge.RangeStmt_Key, edge.RangeStmt_Value:
+ rng := cur.Parent().Node().(*ast.RangeStmt)
+ if rng.Tok == token.ASSIGN {
+ return true // "for k, v = range x" is like an AssignStmt to k, v
+ }
+ case edge.IncDecStmt_X:
+ return true // x++, x--
+ case edge.UnaryExpr_X:
+ if cur.Parent().Node().(*ast.UnaryExpr).Op == token.AND {
+ return true // &x
+ }
+ }
+ return false
+}
+
+func is[T any](x any) bool {
+ _, ok := x.(T)
+ return ok
+}
diff --git a/vendor/golang.org/x/tools/internal/typesinternal/classify_call.go b/vendor/golang.org/x/tools/internal/typesinternal/classify_call.go
index 7ebe9768b..d5c40a2e5 100644
--- a/vendor/golang.org/x/tools/internal/typesinternal/classify_call.go
+++ b/vendor/golang.org/x/tools/internal/typesinternal/classify_call.go
@@ -8,7 +8,6 @@ import (
"fmt"
"go/ast"
"go/types"
- _ "unsafe" // for go:linkname hack
)
// CallKind describes the function position of an [*ast.CallExpr].
@@ -72,11 +71,15 @@ func ClassifyCall(info *types.Info, call *ast.CallExpr) CallKind {
if tv.IsBuiltin() {
return CallBuiltin
}
- obj := info.Uses[UsedIdent(info, call.Fun)]
+ id := UsedIdent(info, call.Fun)
+ if id == nil {
+ return CallDynamic
+ }
+ obj := info.Uses[id]
// Classify the call by the type of the object, if any.
switch obj := obj.(type) {
case *types.Func:
- if interfaceMethod(obj) {
+ if isInterfaceMethod(obj) {
return CallInterface
}
return CallStatic
@@ -127,11 +130,69 @@ func ClassifyCall(info *types.Info, call *ast.CallExpr) CallKind {
// Note: if e is an instantiated function or method, UsedIdent returns
// the corresponding generic function or method on the generic type.
func UsedIdent(info *types.Info, e ast.Expr) *ast.Ident {
- return usedIdent(info, e)
+ if info.Types == nil || info.Uses == nil {
+ panic("one of info.Types or info.Uses is nil; both must be populated")
+ }
+ // Look through type instantiation if necessary.
+ switch d := ast.Unparen(e).(type) {
+ case *ast.IndexExpr:
+ if info.Types[d.Index].IsType() {
+ e = d.X
+ }
+ case *ast.IndexListExpr:
+ e = d.X
+ }
+
+ switch e := ast.Unparen(e).(type) {
+ // info.Uses always has the object we want, even for selector expressions.
+ // We don't need info.Selections.
+ // See go/types/recording.go:recordSelection.
+ case *ast.Ident:
+ return e
+ case *ast.SelectorExpr:
+ return e.Sel
+ }
+ return nil
+}
+
+// See [golang.org/x/tools/go/types/typeutil.Callee].
+func Callee(info *types.Info, call *ast.CallExpr) types.Object {
+ id := UsedIdent(info, call.Fun)
+ if id == nil {
+ return nil
+ }
+ obj := info.Uses[id]
+ if obj == nil {
+ return nil
+ }
+ if _, ok := obj.(*types.TypeName); ok {
+ return nil
+ }
+ if fn, ok := obj.(*types.Func); ok {
+ return fn.Origin()
+ }
+ return obj
}
-//go:linkname usedIdent golang.org/x/tools/go/types/typeutil.usedIdent
-func usedIdent(info *types.Info, e ast.Expr) *ast.Ident
+// See [golang.org/x/tools/go/types/typeutil.StaticCallee].
+func StaticCallee(info *types.Info, call *ast.CallExpr) *types.Func {
+ id := UsedIdent(info, call.Fun)
+ if id == nil {
+ return nil
+ }
+ obj := info.Uses[id]
+ if obj == nil {
+ return nil
+ }
+ fn, _ := obj.(*types.Func)
+ if fn == nil || isInterfaceMethod(fn) {
+ return nil
+ }
+ return fn.Origin()
+}
-//go:linkname interfaceMethod golang.org/x/tools/go/types/typeutil.interfaceMethod
-func interfaceMethod(f *types.Func) bool
+// isInterfaceMethod reports whether its argument is a method of an interface.
+func isInterfaceMethod(f *types.Func) bool {
+ recv := f.Signature().Recv()
+ return recv != nil && types.IsInterface(recv.Type())
+}
diff --git a/vendor/golang.org/x/tools/internal/typesinternal/element.go b/vendor/golang.org/x/tools/internal/typesinternal/element.go
index 89eeea165..bab37fbfe 100644
--- a/vendor/golang.org/x/tools/internal/typesinternal/element.go
+++ b/vendor/golang.org/x/tools/internal/typesinternal/element.go
@@ -7,8 +7,6 @@ package typesinternal
import (
"fmt"
"go/types"
-
- "golang.org/x/tools/go/types/typeutil"
)
// ForEachElement calls f for type T and each type reachable from its
@@ -16,25 +14,24 @@ import (
// type constructors; in addition, for each named type N, the type *N
// is added to the result as it may have additional methods.
//
-// The caller must provide an initially empty set used to de-duplicate
-// identical types, potentially across multiple calls to ForEachElement.
-// (Its final value holds all the elements seen, matching the arguments
-// passed to f.)
+// The access argument passed to f indicates whether the type is
+// inaccessible to reflection (for example, intermediate tuple types
+// or underlying types of named types).
//
-// TODO(adonovan): share/harmonize with go/callgraph/rta.
-func ForEachElement(rtypes *typeutil.Map, msets *typeutil.MethodSetCache, T types.Type, f func(types.Type)) {
- var visit func(T types.Type, skip bool)
- visit = func(T types.Type, skip bool) {
- if !skip {
- if seen, _ := rtypes.Set(T, true).(bool); seen {
- return // de-dup
- }
-
- f(T) // notify caller of new element type
+// The result of f indicates whether the caller has seen this type
+// already, so we can prune the traversal.
+//
+// methodSetOf abstracts (*typeutil.MethodSetCache).MethodSet,
+// avoiding an import cycle.
+func ForEachElement(methodSetOf func(types.Type) *types.MethodSet, T types.Type, f func(T types.Type, access bool) bool) {
+ var visit func(T types.Type, access bool)
+ visit = func(T types.Type, access bool) {
+ if f(T, access) {
+ return // duplicate; prune descent
}
// Recursion over signatures of each method.
- tmset := msets.MethodSet(T)
+ tmset := methodSetOf(T)
for method := range tmset.Methods() {
sig := method.Type().(*types.Signature)
if sig.TypeParams() != nil {
@@ -65,13 +62,13 @@ func ForEachElement(rtypes *typeutil.Map, msets *typeutil.MethodSetCache, T type
//
// TODO(adonovan): document whether or not it is
// safe to skip non-exported methods (as RTA does).
- visit(sig.Params(), true) // skip the Tuple
- visit(sig.Results(), true) // skip the Tuple
+ visit(sig.Params(), false) // the Tuple is inaccessible
+ visit(sig.Results(), false) // the Tuple is inaccessible
}
switch T := T.(type) {
case *types.Alias:
- visit(types.Unalias(T), skip) // emulates the pre-Alias behavior
+ visit(types.Unalias(T), access) // emulates the pre-Alias behavior
case *types.Basic:
// nop
@@ -80,49 +77,49 @@ func ForEachElement(rtypes *typeutil.Map, msets *typeutil.MethodSetCache, T type
// nop---handled by recursion over method set.
case *types.Pointer:
- visit(T.Elem(), false)
+ visit(T.Elem(), true)
case *types.Slice:
- visit(T.Elem(), false)
+ visit(T.Elem(), true)
case *types.Chan:
- visit(T.Elem(), false)
+ visit(T.Elem(), true)
case *types.Map:
- visit(T.Key(), false)
- visit(T.Elem(), false)
+ visit(T.Key(), true)
+ visit(T.Elem(), true)
case *types.Signature:
if T.Recv() != nil {
panic(fmt.Sprintf("Signature %s has Recv %s", T, T.Recv()))
}
- visit(T.Params(), true) // skip the Tuple
- visit(T.Results(), true) // skip the Tuple
+ visit(T.Params(), false) // the Tuple is inaccessible
+ visit(T.Results(), false) // the Tuple is inaccessible
case *types.Named:
// A pointer-to-named type can be derived from a named
// type via reflection. It may have methods too.
- visit(types.NewPointer(T), false)
+ visit(types.NewPointer(T), true)
// Consider 'type T struct{S}' where S has methods.
// Reflection provides no way to get from T to struct{S},
// only to S, so the method set of struct{S} is unwanted,
- // so set 'skip' flag during recursion.
- visit(T.Underlying(), true) // skip the unnamed type
+ // so mark it inaccessible during recursion.
+ visit(T.Underlying(), false) // skip the unnamed type
case *types.Array:
- visit(T.Elem(), false)
+ visit(T.Elem(), true)
case *types.Struct:
for i, n := 0, T.NumFields(); i < n; i++ {
// TODO(adonovan): document whether or not
// it is safe to skip non-exported fields.
- visit(T.Field(i).Type(), false)
+ visit(T.Field(i).Type(), true)
}
case *types.Tuple:
for i, n := 0, T.Len(); i < n; i++ {
- visit(T.At(i).Type(), false)
+ visit(T.At(i).Type(), true)
}
case *types.TypeParam, *types.Union:
@@ -133,5 +130,5 @@ func ForEachElement(rtypes *typeutil.Map, msets *typeutil.MethodSetCache, T type
panic(fmt.Sprintf("ForEachElement called on unexpected type %T", T))
}
}
- visit(T, false)
+ visit(T, true)
}
diff --git a/vendor/golang.org/x/tools/internal/typesinternal/toonew.go b/vendor/golang.org/x/tools/internal/typesinternal/toonew.go
index cc86487ea..386c59c74 100644
--- a/vendor/golang.org/x/tools/internal/typesinternal/toonew.go
+++ b/vendor/golang.org/x/tools/internal/typesinternal/toonew.go
@@ -13,20 +13,30 @@ import (
// TooNewStdSymbols computes the set of package-level symbols
// exported by pkg that are not available at the specified version.
-// The result maps each symbol to its minimum version.
//
// The pkg is allowed to contain type errors.
-func TooNewStdSymbols(pkg *types.Package, version string) map[types.Object]string {
- disallowed := make(map[types.Object]string)
+func TooNewStdSymbols(pkg *types.Package, version string) map[types.Object]stdlib.Symbol {
+ disallowed := make(map[types.Object]stdlib.Symbol)
+
+ // Some symbols are accessible before their release but
+ // only with specific build tags unknown to us here.
+ // Avoid false positives in such cases.
+ if pkg.Path() == "testing/synctest" && versions.AtLeast(version, "go1.24") {
+ // requires go1.24 && goexperiment.synctest || go1.25
+ return disallowed
+ }
+ if (pkg.Path() == "encoding/json/v2" || pkg.Path() == "encoding/json/jsontext") && versions.AtLeast(version, "go1.25") {
+ // requires go1.25 && goexperiment.jsonv2 || go1.27
+ return disallowed
+ }
// Pass 1: package-level symbols.
symbols := stdlib.PackageSymbols[pkg.Path()]
for _, sym := range symbols {
- symver := sym.Version.String()
- if versions.Before(version, symver) {
+ if versions.Before(version, sym.Version.String()) {
switch sym.Kind {
case stdlib.Func, stdlib.Var, stdlib.Const, stdlib.Type:
- disallowed[pkg.Scope().Lookup(sym.Name)] = symver
+ disallowed[pkg.Scope().Lookup(sym.Name)] = sym
}
}
}
@@ -60,28 +70,36 @@ func TooNewStdSymbols(pkg *types.Package, version string) map[types.Object]strin
// spuriously cause the analyzer to report a reference to a
// too-new symbol even though this expression compiles just
// fine (with the fake implementation) using go1.21.
+ var noSym stdlib.Symbol
+ depth := make(map[types.Object]int)
for _, sym := range symbols {
- symVersion := sym.Version.String()
- if !versions.Before(version, symVersion) {
+ if !versions.Before(version, sym.Version.String()) {
continue // allowed
}
var obj types.Object
+ var indices []int
switch sym.Kind {
case stdlib.Field:
typename, name := sym.SplitField()
- if t := pkg.Scope().Lookup(typename); t != nil && disallowed[t] == "" {
- obj, _, _ = types.LookupFieldOrMethod(t.Type(), false, pkg, name)
+ if t := pkg.Scope().Lookup(typename); t != nil && disallowed[t] == noSym {
+ obj, indices, _ = types.LookupFieldOrMethod(t.Type(), false, pkg, name)
}
case stdlib.Method:
ptr, recvname, name := sym.SplitMethod()
- if t := pkg.Scope().Lookup(recvname); t != nil && disallowed[t] == "" {
- obj, _, _ = types.LookupFieldOrMethod(t.Type(), ptr, pkg, name)
+ if t := pkg.Scope().Lookup(recvname); t != nil && disallowed[t] == noSym {
+ obj, indices, _ = types.LookupFieldOrMethod(t.Type(), ptr, pkg, name)
}
}
if obj != nil {
- disallowed[obj] = symVersion
+ // In the presence of embedding, two or more "pkg.T.name"
+ // strings may map to the same types.Object.
+ // Prefer the Object with the shorter index path.
+ if min, ok := depth[obj]; !ok || len(indices) < min {
+ depth[obj] = len(indices)
+ disallowed[obj] = sym
+ }
}
}
diff --git a/vendor/golang.org/x/tools/internal/typesinternal/types.go b/vendor/golang.org/x/tools/internal/typesinternal/types.go
index d2c0b4c5f..9fd48b088 100644
--- a/vendor/golang.org/x/tools/internal/typesinternal/types.go
+++ b/vendor/golang.org/x/tools/internal/typesinternal/types.go
@@ -270,3 +270,11 @@ func ImplicitFieldSelections(seln types.Selection) iter.Seq2[*types.Var, bool] {
}
}
}
+
+func TupleOf(elems ...types.Type) *types.Tuple {
+ params := make([]*types.Var, len(elems))
+ for i, elem := range elems {
+ params[i] = types.NewParam(token.NoPos, nil, "", elem)
+ }
+ return types.NewTuple(params...)
+}
diff --git a/vendor/golang.org/x/tools/refactor/satisfy/find.go b/vendor/golang.org/x/tools/refactor/satisfy/find.go
index 720ecc17d..429986871 100644
--- a/vendor/golang.org/x/tools/refactor/satisfy/find.go
+++ b/vendor/golang.org/x/tools/refactor/satisfy/find.go
@@ -11,7 +11,7 @@
// It requires well-typed inputs, and may panic otherwise.
//
// This package reimplements parts of the type checker. See
-// https://go.dev/issue/70638 for a proposal to expose the the work
+// https://go.dev/issue/70638 for a proposal to expose the work
// already done by the type checker, which would make this package
// redundant.
package satisfy
@@ -355,7 +355,8 @@ func (f *Finder) expr(e ast.Expr) types.Type {
if e.Name == "_" { // e.g. "for _ = range x"
return tInvalid
}
- panic("undefined ident: " + e.Name)
+ // There could be a missing definition, return an invalid type
+ return tInvalid
case *ast.Ellipsis:
if e.Elt != nil {
@@ -374,7 +375,14 @@ func (f *Finder) expr(e ast.Expr) types.Type {
case *types.Struct:
for i, elem := range e.Elts {
if kv, ok := elem.(*ast.KeyValueExpr); ok {
- f.assign(f.info.Uses[kv.Key.(*ast.Ident)].Type(), f.expr(kv.Value))
+ // in weird code, kv.Key might not be an identifier
+ id, ok := kv.Key.(*ast.Ident)
+ if !ok || f.info.Uses[id] == nil {
+ f.expr(kv.Value)
+ continue
+
+ }
+ f.assign(f.info.Uses[id].Type(), f.expr(kv.Value))
} else {
f.assign(T.Field(i).Type(), f.expr(elem))
}
@@ -412,7 +420,10 @@ func (f *Finder) expr(e ast.Expr) types.Type {
f.expr(e.X)
}
} else {
- return f.info.Uses[e.Sel].Type() // qualified identifier
+ if obj, ok := f.info.Uses[e.Sel]; ok {
+ return obj.Type() // qualified identifier
+ }
+ return tInvalid
}
case *ast.IndexExpr:
diff --git a/vendor/golang.org/x/vuln/cmd/govulncheck/gotypesalias.go b/vendor/golang.org/x/vuln/cmd/govulncheck/gotypesalias.go
deleted file mode 100644
index 288c10c2d..000000000
--- a/vendor/golang.org/x/vuln/cmd/govulncheck/gotypesalias.go
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright 2024 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.
-
-//go:build go1.23
-
-//go:debug gotypesalias=1
-
-package main
-
-// Materialize aliases whenever the go toolchain version is after 1.23 (#69772).
-// Remove this file after go.mod >= 1.23 (which implies gotypesalias=1).
diff --git a/vendor/golang.org/x/vuln/cmd/govulncheck/main.go b/vendor/golang.org/x/vuln/cmd/govulncheck/main.go
index 73e3370a4..b15397dd0 100644
--- a/vendor/golang.org/x/vuln/cmd/govulncheck/main.go
+++ b/vendor/golang.org/x/vuln/cmd/govulncheck/main.go
@@ -6,6 +6,7 @@ package main
import (
"context"
+ "errors"
"fmt"
"os"
@@ -23,11 +24,20 @@ func main() {
if err == nil {
err = cmd.Wait()
}
- switch err := err.(type) {
- case nil:
- case interface{ ExitCode() int }:
- os.Exit(err.ExitCode())
- default:
+ if err != nil {
+ var e interface{ ExitCode() int }
+ if errors.As(err, &e) {
+ printErrorToStderr := true
+ if _, ok := err.(interface{ ExitCode() int }); ok {
+ // Avoid printing the error to stderr if the exit code error wasn't
+ // wrapped with another error providing context.
+ printErrorToStderr = false
+ }
+ if printErrorToStderr {
+ fmt.Fprintln(os.Stderr, err)
+ }
+ os.Exit(e.ExitCode())
+ }
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
diff --git a/vendor/golang.org/x/vuln/internal/buildinfo/additions_buildinfo.go b/vendor/golang.org/x/vuln/internal/buildinfo/additions_buildinfo.go
index 49869ce36..8cb7d69d9 100644
--- a/vendor/golang.org/x/vuln/internal/buildinfo/additions_buildinfo.go
+++ b/vendor/golang.org/x/vuln/internal/buildinfo/additions_buildinfo.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build go1.18
-// +build go1.18
package buildinfo
diff --git a/vendor/golang.org/x/vuln/internal/buildinfo/additions_scan.go b/vendor/golang.org/x/vuln/internal/buildinfo/additions_scan.go
index ddbdea083..b94878f61 100644
--- a/vendor/golang.org/x/vuln/internal/buildinfo/additions_scan.go
+++ b/vendor/golang.org/x/vuln/internal/buildinfo/additions_scan.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build go1.18
-// +build go1.18
package buildinfo
diff --git a/vendor/golang.org/x/vuln/internal/buildinfo/buildinfo.go b/vendor/golang.org/x/vuln/internal/buildinfo/buildinfo.go
index f29dffa21..15243ae31 100644
--- a/vendor/golang.org/x/vuln/internal/buildinfo/buildinfo.go
+++ b/vendor/golang.org/x/vuln/internal/buildinfo/buildinfo.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build go1.18
-// +build go1.18
package buildinfo
diff --git a/vendor/golang.org/x/vuln/internal/scan/errors.go b/vendor/golang.org/x/vuln/internal/scan/errors.go
index c28e3c5ab..905e1e690 100644
--- a/vendor/golang.org/x/vuln/internal/scan/errors.go
+++ b/vendor/golang.org/x/vuln/internal/scan/errors.go
@@ -11,7 +11,7 @@ import (
//lint:file-ignore ST1005 Ignore staticcheck message about error formatting
var (
- // ErrVulnerabilitiesFound indicates that vulnerabilities were detected
+ // errVulnerabilitiesFound indicates that vulnerabilities were detected
// when running govulncheck. This returns exit status 3 when running
// without the -json flag.
errVulnerabilitiesFound = &exitCodeError{message: "vulnerabilities found", code: 3}
@@ -25,6 +25,18 @@ var (
// govulncheck and exit with status 2.
errUsage = &exitCodeError{message: "invalid usage", code: 2}
+ // errNoPatterns indicates that no package patterns were provided if the scan level is WantPackages.
+ errNoPatterns = &exitCodeError{
+ message: "no package patterns provided\n\nTo scan the current module, run: govulncheck ./...",
+ code: 2,
+ }
+
+ // errNoPackagesMatched indicates that the provided patterns matched no packages if scan level is WantPackages.
+ errNoPackagesMatched = &exitCodeError{
+ message: "no packages matched the provided patterns",
+ code: 2,
+ }
+
// errGoVersionMismatch is used to indicate that there is a mismatch between
// the Go version used to build govulncheck and the one currently on PATH.
errGoVersionMismatch = errors.New(`Loading packages failed, possibly due to a mismatch between the Go version
diff --git a/vendor/golang.org/x/vuln/internal/scan/flags.go b/vendor/golang.org/x/vuln/internal/scan/flags.go
index 5512540fa..e67c0a17f 100644
--- a/vendor/golang.org/x/vuln/internal/scan/flags.go
+++ b/vendor/golang.org/x/vuln/internal/scan/flags.go
@@ -25,6 +25,7 @@ type config struct {
test bool
show ShowFlag
format FormatFlag
+ version bool
env []string
}
@@ -72,6 +73,7 @@ Usage:
cfg.patterns = flags.Args()
if version {
cfg.show = append(cfg.show, "version")
+ cfg.version = true
}
cfg.ScanLevel = govulncheck.ScanLevel(scanFlag)
cfg.ScanMode = govulncheck.ScanMode(modeFlag)
diff --git a/vendor/golang.org/x/vuln/internal/scan/run.go b/vendor/golang.org/x/vuln/internal/scan/run.go
index f29b9d31d..560a3ad8f 100644
--- a/vendor/golang.org/x/vuln/internal/scan/run.go
+++ b/vendor/golang.org/x/vuln/internal/scan/run.go
@@ -22,9 +22,8 @@ import (
"golang.org/x/vuln/internal/sarif"
)
-// RunGovulncheck performs main govulncheck functionality and exits the
-// program upon success with an appropriate exit status. Otherwise,
-// returns an error.
+// RunGovulncheck performs main govulncheck functionality.
+// On failure, the returned error wraps an exit code error (see scan.Cmd.Wait).
func RunGovulncheck(ctx context.Context, env []string, r io.Reader, stdout io.Writer, stderr io.Writer, args []string) error {
cfg := &config{env: env}
if err := parseFlags(cfg, stderr, args); err != nil {
@@ -55,6 +54,12 @@ func RunGovulncheck(ctx context.Context, env []string, r io.Reader, stdout io.Wr
return err
}
+ if cfg.version {
+ // If the -version flag is passed, exit before doing anything else. This is different than
+ // passing -show which includes "version".
+ return nil
+ }
+
incTelemetryFlagCounters(cfg)
switch cfg.ScanMode {
@@ -104,7 +109,7 @@ func prepareConfig(ctx context.Context, cfg *config, client *client.Client) {
// this binary used from the build info.
func scannerVersion(cfg *config, bi *debug.BuildInfo) {
if bi.Path != "" {
- cfg.ScannerName = path.Base(bi.Path)
+ cfg.ScannerName = strings.TrimSuffix(path.Base(bi.Path), ".test")
}
if bi.Main.Version != "" && bi.Main.Version != "(devel)" {
cfg.ScannerVersion = bi.Main.Version
diff --git a/vendor/golang.org/x/vuln/internal/scan/source.go b/vendor/golang.org/x/vuln/internal/scan/source.go
index e9232112a..b34e443fc 100644
--- a/vendor/golang.org/x/vuln/internal/scan/source.go
+++ b/vendor/golang.org/x/vuln/internal/scan/source.go
@@ -24,7 +24,7 @@ func runSource(ctx context.Context, handler govulncheck.Handler, cfg *config, cl
defer derrors.Wrap(&err, "govulncheck")
if cfg.ScanLevel.WantPackages() && len(cfg.patterns) == 0 {
- return nil // don't throw an error here
+ return errNoPatterns
}
if !gomodExists(dir) {
return errNoGoMod
@@ -43,7 +43,7 @@ func runSource(ctx context.Context, handler govulncheck.Handler, cfg *config, cl
}
if cfg.ScanLevel.WantPackages() && len(graph.TopPkgs()) == 0 {
- return nil // early exit
+ return errNoPackagesMatched
}
return vulncheck.Source(ctx, handler, &cfg.Config, client, graph)
}
diff --git a/vendor/golang.org/x/vuln/internal/vulncheck/utils.go b/vendor/golang.org/x/vuln/internal/vulncheck/utils.go
index e752f4a00..fb32a2c38 100644
--- a/vendor/golang.org/x/vuln/internal/vulncheck/utils.go
+++ b/vendor/golang.org/x/vuln/internal/vulncheck/utils.go
@@ -93,7 +93,7 @@ func callGraph(ctx context.Context, prog *ssa.Program, entries []*ssa.Function)
// - pointer designation * is skipped
// - full path prefix is skipped as well
func dbTypeFormat(t types.Type) string {
- switch tt := t.(type) {
+ switch tt := types.Unalias(t).(type) {
case *types.Pointer:
return dbTypeFormat(tt.Elem())
case *types.Named:
diff --git a/vendor/golang.org/x/vuln/scan/scan.go b/vendor/golang.org/x/vuln/scan/scan.go
index 0aa9975e0..459fc3644 100644
--- a/vendor/golang.org/x/vuln/scan/scan.go
+++ b/vendor/golang.org/x/vuln/scan/scan.go
@@ -89,6 +89,16 @@ func (c *Cmd) Start() error {
// Wait waits for the command to exit. The command must have been started by
// Start.
//
+// If the command fails to run or does not complete successfully, the returned
+// error wraps an error implementing:
+//
+// interface {
+// ExitCode() int
+// }
+//
+// Callers can use errors.As to retrieve the exit code. Other errors may be
+// returned for other problems (e.g. I/O issues).
+//
// Wait releases any resources associated with the Cmd.
func (c *Cmd) Wait() error {
if c.done == nil {
diff --git a/vendor/google.golang.org/genproto/googleapis/api/httpbody/httpbody.pb.go b/vendor/google.golang.org/genproto/googleapis/api/httpbody/httpbody.pb.go
index d083dde3e..902ae4498 100644
--- a/vendor/google.golang.org/genproto/googleapis/api/httpbody/httpbody.pb.go
+++ b/vendor/google.golang.org/genproto/googleapis/api/httpbody/httpbody.pb.go
@@ -1,4 +1,4 @@
-// Copyright 2025 Google LLC
+// Copyright 2026 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
diff --git a/vendor/google.golang.org/genproto/googleapis/rpc/errdetails/error_details.pb.go b/vendor/google.golang.org/genproto/googleapis/rpc/errdetails/error_details.pb.go
index e017ef071..842a5d9b5 100644
--- a/vendor/google.golang.org/genproto/googleapis/rpc/errdetails/error_details.pb.go
+++ b/vendor/google.golang.org/genproto/googleapis/rpc/errdetails/error_details.pb.go
@@ -1,4 +1,4 @@
-// Copyright 2025 Google LLC
+// Copyright 2026 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -957,17 +957,17 @@ type BadRequest_FieldViolation struct {
// In this example, in proto `field` could take one of the following values:
//
// - `full_name` for a violation in the `full_name` value
- // - `email_addresses[1].email` for a violation in the `email` field of the
+ // - `email_addresses[0].email` for a violation in the `email` field of the
// first `email_addresses` message
- // - `email_addresses[3].type[2]` for a violation in the second `type`
+ // - `email_addresses[2].type[1]` for a violation in the second `type`
// value in the third `email_addresses` message.
//
// In JSON, the same values are represented as:
//
// - `fullName` for a violation in the `fullName` value
- // - `emailAddresses[1].email` for a violation in the `email` field of the
+ // - `emailAddresses[0].email` for a violation in the `email` field of the
// first `emailAddresses` message
- // - `emailAddresses[3].type[2]` for a violation in the second `type`
+ // - `emailAddresses[2].type[1]` for a violation in the second `type`
// value in the third `emailAddresses` message.
Field string `protobuf:"bytes,1,opt,name=field,proto3" json:"field,omitempty"`
// A description of why the request element is bad.
diff --git a/vendor/google.golang.org/genproto/googleapis/rpc/status/status.pb.go b/vendor/google.golang.org/genproto/googleapis/rpc/status/status.pb.go
index 06a3f7106..f25a7bcc7 100644
--- a/vendor/google.golang.org/genproto/googleapis/rpc/status/status.pb.go
+++ b/vendor/google.golang.org/genproto/googleapis/rpc/status/status.pb.go
@@ -1,4 +1,4 @@
-// Copyright 2025 Google LLC
+// Copyright 2026 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -127,14 +127,13 @@ var file_google_rpc_status_proto_rawDesc = []byte{
0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x2e, 0x0a, 0x07, 0x64, 0x65, 0x74, 0x61,
0x69, 0x6c, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x6f, 0x6f, 0x67,
0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, 0x6e, 0x79, 0x52,
- 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x42, 0x61, 0x0a, 0x0e, 0x63, 0x6f, 0x6d, 0x2e,
+ 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x42, 0x5e, 0x0a, 0x0e, 0x63, 0x6f, 0x6d, 0x2e,
0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x72, 0x70, 0x63, 0x42, 0x0b, 0x53, 0x74, 0x61, 0x74,
0x75, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x37, 0x67, 0x6f, 0x6f, 0x67, 0x6c,
0x65, 0x2e, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x67, 0x65, 0x6e,
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73,
0x2f, 0x72, 0x70, 0x63, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x3b, 0x73, 0x74, 0x61, 0x74,
- 0x75, 0x73, 0xf8, 0x01, 0x01, 0xa2, 0x02, 0x03, 0x52, 0x50, 0x43, 0x62, 0x06, 0x70, 0x72, 0x6f,
- 0x74, 0x6f, 0x33,
+ 0x75, 0x73, 0xa2, 0x02, 0x03, 0x52, 0x50, 0x43, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
diff --git a/vendor/google.golang.org/grpc/attributes/attributes.go b/vendor/google.golang.org/grpc/attributes/attributes.go
index 52d530d7a..4c60518c7 100644
--- a/vendor/google.golang.org/grpc/attributes/attributes.go
+++ b/vendor/google.golang.org/grpc/attributes/attributes.go
@@ -27,6 +27,8 @@ package attributes
import (
"fmt"
+ "iter"
+ "maps"
"strings"
)
@@ -37,37 +39,46 @@ import (
// any) bool', it will be called by (*Attributes).Equal to determine whether
// two values with the same key should be considered equal.
type Attributes struct {
- m map[any]any
+ parent *Attributes
+ key, value any
}
// New returns a new Attributes containing the key/value pair.
func New(key, value any) *Attributes {
- return &Attributes{m: map[any]any{key: value}}
+ return &Attributes{
+ key: key,
+ value: value,
+ }
}
// WithValue returns a new Attributes containing the previous keys and values
// and the new key/value pair. If the same key appears multiple times, the
-// last value overwrites all previous values for that key. To remove an
-// existing key, use a nil value. value should not be modified later.
+// last value overwrites all previous values for that key. value should not be
+// modified later.
+//
+// Note that Attributes do not support deletion. Avoid using untyped nil values.
+// Since the Value method returns an untyped nil when a key is absent, it is
+// impossible to distinguish between a missing key and a key explicitly set to
+// an untyped nil. If you need to represent a value being unset, consider
+// storing a specific sentinel type or a wrapper struct with a boolean field
+// indicating presence.
func (a *Attributes) WithValue(key, value any) *Attributes {
- if a == nil {
- return New(key, value)
+ return &Attributes{
+ parent: a,
+ key: key,
+ value: value,
}
- n := &Attributes{m: make(map[any]any, len(a.m)+1)}
- for k, v := range a.m {
- n.m[k] = v
- }
- n.m[key] = value
- return n
}
// Value returns the value associated with these attributes for key, or nil if
// no value is associated with key. The returned value should not be modified.
func (a *Attributes) Value(key any) any {
- if a == nil {
- return nil
+ for cur := a; cur != nil; cur = cur.parent {
+ if cur.key == key {
+ return cur.value
+ }
}
- return a.m[key]
+ return nil
}
// Equal returns whether a and o are equivalent. If 'Equal(o any) bool' is
@@ -83,11 +94,15 @@ func (a *Attributes) Equal(o *Attributes) bool {
if a == nil || o == nil {
return false
}
- if len(a.m) != len(o.m) {
- return false
+ if a == o {
+ return true
}
- for k, v := range a.m {
- ov, ok := o.m[k]
+ m := maps.Collect(o.all())
+ lenA := 0
+
+ for k, v := range a.all() {
+ lenA++
+ ov, ok := m[k]
if !ok {
// o missing element of a
return false
@@ -101,7 +116,7 @@ func (a *Attributes) Equal(o *Attributes) bool {
return false
}
}
- return true
+ return lenA == len(m)
}
// String prints the attribute map. If any key or values throughout the map
@@ -110,11 +125,11 @@ func (a *Attributes) String() string {
var sb strings.Builder
sb.WriteString("{")
first := true
- for k, v := range a.m {
+ for k, v := range a.all() {
if !first {
sb.WriteString(", ")
}
- sb.WriteString(fmt.Sprintf("%q: %q ", str(k), str(v)))
+ fmt.Fprintf(&sb, "%q: %q ", str(k), str(v))
first = false
}
sb.WriteString("}")
@@ -139,3 +154,21 @@ func str(x any) (s string) {
func (a *Attributes) MarshalJSON() ([]byte, error) {
return []byte(a.String()), nil
}
+
+// all returns an iterator that yields all key-value pairs in the Attributes
+// chain. If a key appears multiple times, only the most recently added value
+// is yielded.
+func (a *Attributes) all() iter.Seq2[any, any] {
+ return func(yield func(any, any) bool) {
+ seen := map[any]bool{}
+ for cur := a; cur != nil; cur = cur.parent {
+ if seen[cur.key] {
+ continue
+ }
+ if !yield(cur.key, cur.value) {
+ return
+ }
+ seen[cur.key] = true
+ }
+ }
+}
diff --git a/vendor/google.golang.org/grpc/balancer/balancer.go b/vendor/google.golang.org/grpc/balancer/balancer.go
index d08b7ad63..7e3dbaad2 100644
--- a/vendor/google.golang.org/grpc/balancer/balancer.go
+++ b/vendor/google.golang.org/grpc/balancer/balancer.go
@@ -33,6 +33,7 @@ import (
estats "google.golang.org/grpc/experimental/stats"
"google.golang.org/grpc/grpclog"
"google.golang.org/grpc/internal"
+ "google.golang.org/grpc/internal/envconfig"
"google.golang.org/grpc/metadata"
"google.golang.org/grpc/resolver"
"google.golang.org/grpc/serviceconfig"
@@ -46,8 +47,8 @@ var (
)
// Register registers the balancer builder to the balancer map. b.Name
-// (lowercased) will be used as the name registered with this builder. If the
-// Builder implements ConfigParser, ParseConfig will be called when new service
+// will be used as the name registered with this builder. If the Builder
+// implements ConfigParser, ParseConfig will be called when new service
// configs are received by the resolver, and the result will be provided to the
// Balancer in UpdateClientConnState.
//
@@ -55,12 +56,12 @@ var (
// an init() function), and is not thread-safe. If multiple Balancers are
// registered with the same name, the one registered last will take effect.
func Register(b Builder) {
- name := strings.ToLower(b.Name())
- if name != b.Name() {
- // TODO: Skip the use of strings.ToLower() to index the map after v1.59
- // is released to switch to case sensitive balancer registry. Also,
- // remove this warning and update the docstrings for Register and Get.
- logger.Warningf("Balancer registered with name %q. grpc-go will be switching to case sensitive balancer registries soon", b.Name())
+ name := b.Name()
+ if !envconfig.CaseSensitiveBalancerRegistries {
+ name = strings.ToLower(name)
+ if name != b.Name() {
+ logger.Warningf("Balancer registered with name %q. grpc-go has switched to case sensitive balancer registries. GRPC_GO_EXPERIMENTAL_CASE_SENSITIVE_BALANCER_REGISTRIES env variable will be removed in release v1.82.0", b.Name())
+ }
}
m[name] = b
}
@@ -78,16 +79,17 @@ func init() {
}
// Get returns the resolver builder registered with the given name.
-// Note that the compare is done in a case-insensitive fashion.
+// Note that the compare is done in a case-sensitive fashion.
// If no builder is register with the name, nil will be returned.
func Get(name string) Builder {
- if strings.ToLower(name) != name {
- // TODO: Skip the use of strings.ToLower() to index the map after v1.59
- // is released to switch to case sensitive balancer registry. Also,
- // remove this warning and update the docstrings for Register and Get.
- logger.Warningf("Balancer retrieved for name %q. grpc-go will be switching to case sensitive balancer registries soon", name)
+ if !envconfig.CaseSensitiveBalancerRegistries {
+ lowerName := strings.ToLower(name)
+ if lowerName != name {
+ logger.Warningf("Balancer retrieved for name %q. grpc-go has switched to case sensitive balancer registries. GRPC_GO_EXPERIMENTAL_CASE_SENSITIVE_BALANCER_REGISTRIES env variable will be removed in release v1.82.0", name)
+ }
+ name = lowerName
}
- if b, ok := m[strings.ToLower(name)]; ok {
+ if b, ok := m[name]; ok {
return b
}
return nil
diff --git a/vendor/google.golang.org/grpc/balancer/base/balancer.go b/vendor/google.golang.org/grpc/balancer/base/balancer.go
index 4d576876d..4399ba014 100644
--- a/vendor/google.golang.org/grpc/balancer/base/balancer.go
+++ b/vendor/google.golang.org/grpc/balancer/base/balancer.go
@@ -121,8 +121,7 @@ func (b *baseBalancer) UpdateClientConnState(s balancer.ClientConnState) error {
sc.Connect()
}
}
- for _, a := range b.subConns.Keys() {
- sc, _ := b.subConns.Get(a)
+ for a, sc := range b.subConns.All() {
// a was removed by resolver.
if _, ok := addrsSet.Get(a); !ok {
sc.Shutdown()
@@ -171,8 +170,7 @@ func (b *baseBalancer) regeneratePicker() {
readySCs := make(map[balancer.SubConn]SubConnInfo)
// Filter out all ready SCs from full subConn map.
- for _, addr := range b.subConns.Keys() {
- sc, _ := b.subConns.Get(addr)
+ for addr, sc := range b.subConns.All() {
if st, ok := b.scStates[sc]; ok && st == connectivity.Ready {
readySCs[sc] = SubConnInfo{Address: addr}
}
diff --git a/vendor/google.golang.org/grpc/balancer/endpointsharding/endpointsharding.go b/vendor/google.golang.org/grpc/balancer/endpointsharding/endpointsharding.go
index 360db08eb..12479f698 100644
--- a/vendor/google.golang.org/grpc/balancer/endpointsharding/endpointsharding.go
+++ b/vendor/google.golang.org/grpc/balancer/endpointsharding/endpointsharding.go
@@ -187,8 +187,7 @@ func (es *endpointSharding) UpdateClientConnState(state balancer.ClientConnState
}
}
// Delete old children that are no longer present.
- for _, e := range children.Keys() {
- child, _ := children.Get(e)
+ for e, child := range children.All() {
if _, ok := newChildren.Get(e); !ok {
child.closeLocked()
}
@@ -212,7 +211,7 @@ func (es *endpointSharding) ResolverError(err error) {
es.updateState()
}()
children := es.children.Load()
- for _, child := range children.Values() {
+ for _, child := range children.All() {
child.resolverErrorLocked(err)
}
}
@@ -225,7 +224,7 @@ func (es *endpointSharding) Close() {
es.childMu.Lock()
defer es.childMu.Unlock()
children := es.children.Load()
- for _, child := range children.Values() {
+ for _, child := range children.All() {
child.closeLocked()
}
}
@@ -233,7 +232,7 @@ func (es *endpointSharding) Close() {
func (es *endpointSharding) ExitIdle() {
es.childMu.Lock()
defer es.childMu.Unlock()
- for _, bw := range es.children.Load().Values() {
+ for _, bw := range es.children.Load().All() {
if !bw.isClosed {
bw.child.ExitIdle()
}
@@ -255,7 +254,7 @@ func (es *endpointSharding) updateState() {
children := es.children.Load()
childStates := make([]ChildState, 0, children.Len())
- for _, child := range children.Values() {
+ for _, child := range children.All() {
childState := child.childState
childStates = append(childStates, childState)
childPicker := childState.State.Picker
diff --git a/vendor/google.golang.org/grpc/balancer/pickfirst/pickfirst.go b/vendor/google.golang.org/grpc/balancer/pickfirst/pickfirst.go
index dccd9f0bf..d48bc304c 100644
--- a/vendor/google.golang.org/grpc/balancer/pickfirst/pickfirst.go
+++ b/vendor/google.golang.org/grpc/balancer/pickfirst/pickfirst.go
@@ -35,9 +35,9 @@ import (
"google.golang.org/grpc/balancer"
"google.golang.org/grpc/balancer/pickfirst/internal"
"google.golang.org/grpc/connectivity"
+ "google.golang.org/grpc/experimental/balancer/weight"
expstats "google.golang.org/grpc/experimental/stats"
"google.golang.org/grpc/grpclog"
- "google.golang.org/grpc/internal/balancer/weight"
"google.golang.org/grpc/internal/envconfig"
internalgrpclog "google.golang.org/grpc/internal/grpclog"
"google.golang.org/grpc/internal/pretty"
@@ -399,14 +399,14 @@ func (b *pickfirstBalancer) startFirstPassLocked() {
b.firstPass = true
b.numTF = 0
// Reset the connection attempt record for existing SubConns.
- for _, sd := range b.subConns.Values() {
+ for _, sd := range b.subConns.All() {
sd.connectionFailedInFirstPass = false
}
b.requestConnectionLocked()
}
func (b *pickfirstBalancer) closeSubConnsLocked() {
- for _, sd := range b.subConns.Values() {
+ for _, sd := range b.subConns.All() {
sd.subConn.Shutdown()
}
b.subConns = resolver.NewAddressMapV2[*scData]()
@@ -506,7 +506,7 @@ func (b *pickfirstBalancer) reconcileSubConnsLocked(newAddrs []resolver.Address)
newAddrsMap.Set(addr, true)
}
- for _, oldAddr := range b.subConns.Keys() {
+ for oldAddr := range b.subConns.All() {
if _, ok := newAddrsMap.Get(oldAddr); ok {
continue
}
@@ -520,7 +520,7 @@ func (b *pickfirstBalancer) reconcileSubConnsLocked(newAddrs []resolver.Address)
// becomes ready, which means that all other subConn must be shutdown.
func (b *pickfirstBalancer) shutdownRemainingLocked(selected *scData) {
b.cancelConnectionTimer()
- for _, sd := range b.subConns.Values() {
+ for _, sd := range b.subConns.All() {
if sd.subConn != selected.subConn {
sd.subConn.Shutdown()
}
@@ -771,7 +771,7 @@ func (b *pickfirstBalancer) endFirstPassIfPossibleLocked(lastErr error) {
}
// Connect() has been called on all the SubConns. The first pass can be
// ended if all the SubConns have reported a failure.
- for _, sd := range b.subConns.Values() {
+ for _, sd := range b.subConns.All() {
if !sd.connectionFailedInFirstPass {
return
}
@@ -782,7 +782,7 @@ func (b *pickfirstBalancer) endFirstPassIfPossibleLocked(lastErr error) {
Picker: &picker{err: lastErr},
})
// Start re-connecting all the SubConns that are already in IDLE.
- for _, sd := range b.subConns.Values() {
+ for _, sd := range b.subConns.All() {
if sd.rawConnectivityState == connectivity.Idle {
sd.subConn.Connect()
}
diff --git a/vendor/google.golang.org/grpc/binarylog/grpc_binarylog_v1/binarylog.pb.go b/vendor/google.golang.org/grpc/binarylog/grpc_binarylog_v1/binarylog.pb.go
index 42c61cf9f..296123e20 100644
--- a/vendor/google.golang.org/grpc/binarylog/grpc_binarylog_v1/binarylog.pb.go
+++ b/vendor/google.golang.org/grpc/binarylog/grpc_binarylog_v1/binarylog.pb.go
@@ -18,7 +18,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
-// protoc-gen-go v1.36.10
+// protoc-gen-go v1.36.11
// protoc v5.27.1
// source: grpc/binlog/v1/binarylog.proto
diff --git a/vendor/google.golang.org/grpc/clientconn.go b/vendor/google.golang.org/grpc/clientconn.go
index 5dec2dacc..c4bca5203 100644
--- a/vendor/google.golang.org/grpc/clientconn.go
+++ b/vendor/google.golang.org/grpc/clientconn.go
@@ -24,10 +24,12 @@ import (
"fmt"
"math"
"net/url"
+ "os"
"slices"
"strings"
"sync"
"sync/atomic"
+ "syscall"
"time"
"google.golang.org/grpc/balancer"
@@ -1268,8 +1270,9 @@ type addrConn struct {
channelz *channelz.SubChannel
- localityLabel string
- backendServiceLabel string
+ localityLabel string
+ backendServiceLabel string
+ disconnectErrorLabel string
}
// Note: this requires a lock on ac.mu.
@@ -1286,9 +1289,14 @@ func (ac *addrConn) updateConnectivityState(s connectivity.State, lastErr error)
// TODO: https://github.com/grpc/grpc-go/issues/7862 - Remove the second
// part of the if condition below once the issue is fixed.
if ac.state == connectivity.Ready || (ac.state == connectivity.Connecting && s == connectivity.Idle) {
- disconnectionsMetric.Record(ac.cc.metricsRecorderList, 1, ac.cc.target, ac.backendServiceLabel, ac.localityLabel, "unknown")
+ disconnectError := ac.disconnectErrorLabel
+ if disconnectError == "" {
+ disconnectError = "unknown"
+ }
+ disconnectionsMetric.Record(ac.cc.metricsRecorderList, 1, ac.cc.target, ac.backendServiceLabel, ac.localityLabel, disconnectError)
openConnectionsMetric.Record(ac.cc.metricsRecorderList, -1, ac.cc.target, ac.backendServiceLabel, ac.securityLevelLocked(), ac.localityLabel)
}
+ ac.disconnectErrorLabel = "" // Reset for next time
ac.state = s
ac.channelz.ChannelMetrics.State.Store(&s)
if lastErr == nil {
@@ -1483,11 +1491,11 @@ func (ac *addrConn) createTransport(ctx context.Context, addr resolver.Address,
addr.ServerName = ac.cc.getServerName(addr)
hctx, hcancel := context.WithCancel(ctx)
- onClose := func(r transport.GoAwayReason) {
+ onClose := func(info transport.GoAwayInfo) {
ac.mu.Lock()
defer ac.mu.Unlock()
// adjust params based on GoAwayReason
- ac.adjustParams(r)
+ ac.adjustParams(info.Reason)
if ctx.Err() != nil {
// Already shut down or connection attempt canceled. tearDown() or
// updateAddrs() already cleared the transport and canceled hctx
@@ -1504,6 +1512,7 @@ func (ac *addrConn) createTransport(ctx context.Context, addr resolver.Address,
return
}
ac.transport = nil
+ ac.disconnectErrorLabel = disconnectErrorString(info)
// Refresh the name resolver on any connection loss.
ac.cc.resolveNow(resolver.ResolveNowOptions{})
// Always go idle and wait for the LB policy to initiate a new
@@ -1560,6 +1569,32 @@ func (ac *addrConn) createTransport(ctx context.Context, addr resolver.Address,
return nil
}
+// disconnectErrorString returns the grpc.disconnect_error metric label corresponding
+// to the provided transport.GoAwayInfo, as specified by gRFC A94:
+// https://github.com/grpc/proposal/blob/master/A94-grpc-subchannel-disconnections-metrics.md
+func disconnectErrorString(info transport.GoAwayInfo) string {
+ err := info.Err
+ var sysErr syscall.Errno
+ switch {
+ case info.Reason != transport.GoAwayInvalid:
+ return fmt.Sprintf("GOAWAY %s", info.GoAwayCode.String())
+ case err == nil:
+ return "unknown"
+ case errors.Is(err, context.Canceled):
+ return "subchannel shutdown"
+ case errors.Is(err, syscall.ECONNRESET):
+ return "connection reset"
+ case errors.Is(err, syscall.ETIMEDOUT), errors.Is(err, context.DeadlineExceeded), errors.Is(err, os.ErrDeadlineExceeded):
+ return "connection timed out"
+ case errors.Is(err, syscall.ECONNABORTED):
+ return "connection aborted"
+ case errors.As(err, &sysErr):
+ return "socket error"
+ default:
+ return "unknown"
+ }
+}
+
// startHealthCheck starts the health checking stream (RPC) to watch the health
// stats of this connection if health checking is requested and configured.
//
@@ -1663,6 +1698,9 @@ func (ac *addrConn) tearDown(err error) {
}
curTr := ac.transport
ac.transport = nil
+ if ac.disconnectErrorLabel == "" {
+ ac.disconnectErrorLabel = "subchannel shutdown"
+ }
// We have to set the state to Shutdown before anything else to prevent races
// between setting the state and logic that waits on context cancellation / etc.
ac.updateConnectivityState(connectivity.Shutdown, nil)
diff --git a/vendor/google.golang.org/grpc/credentials/tls.go b/vendor/google.golang.org/grpc/credentials/tls.go
index 0bcd16dbb..a6083c3b0 100644
--- a/vendor/google.golang.org/grpc/credentials/tls.go
+++ b/vendor/google.golang.org/grpc/credentials/tls.go
@@ -22,7 +22,6 @@ import (
"context"
"crypto/tls"
"crypto/x509"
- "errors"
"fmt"
"net"
"net/url"
@@ -52,22 +51,21 @@ func (t TLSInfo) AuthType() string {
}
// ValidateAuthority validates the provided authority being used to override the
-// :authority header by verifying it against the peer certificates. It returns a
+// :authority header by verifying it against the peer certificate. It returns a
// non-nil error if the validation fails.
func (t TLSInfo) ValidateAuthority(authority string) error {
- var errs []error
host, _, err := net.SplitHostPort(authority)
if err != nil {
host = authority
}
- for _, cert := range t.State.PeerCertificates {
- var err error
- if err = cert.VerifyHostname(host); err == nil {
- return nil
- }
- errs = append(errs, err)
+
+ // Verify authority against the leaf certificate.
+ if len(t.State.PeerCertificates) == 0 {
+ // This is not expected to happen as the TLS handshake has already
+ // completed and should have populated PeerCertificates.
+ return fmt.Errorf("credentials: no peer certificates found to verify authority %q", host)
}
- return fmt.Errorf("credentials: invalid authority %q: %v", authority, errors.Join(errs...))
+ return t.State.PeerCertificates[0].VerifyHostname(host)
}
// cipherSuiteLookup returns the string version of a TLS cipher suite ID.
diff --git a/vendor/google.golang.org/grpc/dialoptions.go b/vendor/google.golang.org/grpc/dialoptions.go
index 7a5ac2e7c..3af08e1ab 100644
--- a/vendor/google.golang.org/grpc/dialoptions.go
+++ b/vendor/google.golang.org/grpc/dialoptions.go
@@ -173,10 +173,8 @@ func newJoinDialOption(opts ...DialOption) DialOption {
// If this option is set to true every connection will release the buffer after
// flushing the data on the wire.
//
-// # Experimental
-//
-// Notice: This API is EXPERIMENTAL and may be changed or removed in a
-// later release.
+// Deprecated: shared write buffer is enabled by default. WithSharedWriteBuffer
+// will be removed in a future release.
func WithSharedWriteBuffer(val bool) DialOption {
return newFuncDialOption(func(o *dialOptions) {
o.copts.SharedWriteBuffer = val
@@ -229,6 +227,14 @@ func WithInitialConnWindowSize(s int32) DialOption {
// WithStaticStreamWindowSize returns a DialOption which sets the initial
// stream window size to the value provided and disables dynamic flow control.
+//
+// Note that this also disables dynamic flow control for the connection,
+// falling back to a default static connection-level window of 64KB. To
+// use a larger connection-level window, you must also use the
+// [WithStaticConnWindowSize] DialOption.
+//
+// Most users should not configure static flow control windows unless
+// operating in a memory-constrained environment.
func WithStaticStreamWindowSize(s int32) DialOption {
return newFuncDialOption(func(o *dialOptions) {
o.copts.InitialWindowSize = s
@@ -239,6 +245,14 @@ func WithStaticStreamWindowSize(s int32) DialOption {
// WithStaticConnWindowSize returns a DialOption which sets the initial
// connection window size to the value provided and disables dynamic flow
// control.
+//
+// Note that this also disables dynamic flow control for individual streams,
+// falling back to a default static connection-level window of 64KB. To
+// explicitly configure the stream-level window size, you must also use the
+// [WithStaticStreamWindowSize] DialOption.
+//
+// Most users should not configure static flow control windows unless
+// operating in a memory-constrained environment.
func WithStaticConnWindowSize(s int32) DialOption {
return newFuncDialOption(func(o *dialOptions) {
o.copts.InitialConnWindowSize = s
@@ -705,10 +719,11 @@ func WithDisableHealthCheck() DialOption {
func defaultDialOptions() dialOptions {
return dialOptions{
copts: transport.ConnectOptions{
- ReadBufferSize: defaultReadBufSize,
- WriteBufferSize: defaultWriteBufSize,
- UserAgent: grpcUA,
- BufferPool: mem.DefaultBufferPool(),
+ ReadBufferSize: defaultReadBufSize,
+ WriteBufferSize: defaultWriteBufSize,
+ SharedWriteBuffer: true,
+ UserAgent: grpcUA,
+ BufferPool: mem.DefaultBufferPool(),
},
bs: internalbackoff.DefaultExponential,
idleTimeout: 30 * time.Minute,
diff --git a/vendor/google.golang.org/grpc/encoding/encoding.go b/vendor/google.golang.org/grpc/encoding/encoding.go
index 296f38c3a..bfa8b268f 100644
--- a/vendor/google.golang.org/grpc/encoding/encoding.go
+++ b/vendor/google.golang.org/grpc/encoding/encoding.go
@@ -66,6 +66,9 @@ type Compressor interface {
// Decompress reads data from r, decompresses it, and provides the
// uncompressed data via the returned io.Reader. If an error occurs while
// initializing the decompressor, that error is returned instead.
+ //
+ // The returned io.Reader may optionally implement io.ReadCloser, and if it
+ // does, gRPC will call Close() exactly once.
Decompress(r io.Reader) (io.Reader, error)
// Name is the name of the compression codec and is used to set the content
// coding header. The result must be static; the result cannot change
diff --git a/vendor/google.golang.org/grpc/encoding/gzip/gzip.go b/vendor/google.golang.org/grpc/encoding/gzip/gzip.go
index 153e4dbfb..65908d9a2 100644
--- a/vendor/google.golang.org/grpc/encoding/gzip/gzip.go
+++ b/vendor/google.golang.org/grpc/encoding/gzip/gzip.go
@@ -81,6 +81,8 @@ func (z *writer) Close() error {
return z.Writer.Close()
}
+var _ io.Closer = &reader{}
+
type reader struct {
*gzip.Reader
pool *sync.Pool
@@ -102,14 +104,16 @@ func (c *compressor) Decompress(r io.Reader) (io.Reader, error) {
return z, nil
}
-func (z *reader) Read(p []byte) (n int, err error) {
- n, err = z.Reader.Read(p)
- if err == io.EOF {
- z.pool.Put(z)
- }
+func (r *reader) Read(p []byte) (n int, err error) {
+ n, err = r.Reader.Read(p)
return n, err
}
+func (r *reader) Close() error {
+ defer r.pool.Put(r)
+ return r.Reader.Close()
+}
+
func (c *compressor) Name() string {
return Name
}
diff --git a/vendor/google.golang.org/grpc/experimental/balancer/weight/weight.go b/vendor/google.golang.org/grpc/experimental/balancer/weight/weight.go
new file mode 100644
index 000000000..beab9e07c
--- /dev/null
+++ b/vendor/google.golang.org/grpc/experimental/balancer/weight/weight.go
@@ -0,0 +1,60 @@
+/*
+ *
+ * Copyright 2025 gRPC authors.
+ *
+ * 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 weight contains utilities to manage endpoint weights.
+// Weights may be used by LB policies to distribute load across
+// multiple endpoints.
+//
+// # Experimental
+//
+// Notice: All APIs in this package are EXPERIMENTAL and may be changed
+// or removed in a later release.
+package weight
+
+import "google.golang.org/grpc/resolver"
+
+// attributeKey is the type used as the key to store EndpointInfo in the
+// Attributes field of resolver.Endpoint.
+type attributeKey struct{}
+
+// EndpointInfo will be stored in the Attributes field of Endpoints.
+type EndpointInfo struct {
+ Weight uint32
+}
+
+// Equal allows the values to be compared by Attributes.Equal.
+func (a EndpointInfo) Equal(o any) bool {
+ oa, ok := o.(EndpointInfo)
+ return ok && oa.Weight == a.Weight
+}
+
+// Set returns a copy of endpoint in which the Attributes field is
+// updated with EndpointInfo.
+func Set(endpoint resolver.Endpoint, epInfo EndpointInfo) resolver.Endpoint {
+ endpoint.Attributes = endpoint.Attributes.WithValue(attributeKey{}, epInfo)
+ return endpoint
+}
+
+// FromEndpoint returns the EndpointInfo stored in the Attributes
+// field of an endpoint. It returns an empty EndpointInfo if attribute
+// is not found.
+func FromEndpoint(endpoint resolver.Endpoint) EndpointInfo {
+ v := endpoint.Attributes.Value(attributeKey{})
+ ei, _ := v.(EndpointInfo)
+ return ei
+}
diff --git a/vendor/google.golang.org/grpc/experimental/stats/metrics.go b/vendor/google.golang.org/grpc/experimental/stats/metrics.go
index 88742724a..8732e53bd 100644
--- a/vendor/google.golang.org/grpc/experimental/stats/metrics.go
+++ b/vendor/google.golang.org/grpc/experimental/stats/metrics.go
@@ -20,10 +20,27 @@
package stats
import (
+ "context"
+
"google.golang.org/grpc/internal"
"google.golang.org/grpc/stats"
)
+type customLabelKey struct{}
+
+// NewContextWithCustomLabel returns a new context with the provided custom label
+// attached. The label will be propagated to all metric instruments specified in gRFC A108.
+func NewContextWithCustomLabel(ctx context.Context, label string) context.Context {
+ return context.WithValue(ctx, customLabelKey{}, label)
+}
+
+// CustomLabelFromContext returns the custom label from the context if it exists.
+// If the custom label is not present, it returns an empty string.
+func CustomLabelFromContext(ctx context.Context) string {
+ label, _ := ctx.Value(customLabelKey{}).(string)
+ return label
+}
+
// MetricsRecorder records on metrics derived from metric registry.
// Implementors must embed UnimplementedMetricsRecorder.
type MetricsRecorder interface {
diff --git a/vendor/google.golang.org/grpc/health/grpc_health_v1/health.pb.go b/vendor/google.golang.org/grpc/health/grpc_health_v1/health.pb.go
index 8f7d9f6bb..dcb98cdbc 100644
--- a/vendor/google.golang.org/grpc/health/grpc_health_v1/health.pb.go
+++ b/vendor/google.golang.org/grpc/health/grpc_health_v1/health.pb.go
@@ -17,7 +17,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
-// protoc-gen-go v1.36.10
+// protoc-gen-go v1.36.11
// protoc v5.27.1
// source: grpc/health/v1/health.proto
diff --git a/vendor/google.golang.org/grpc/health/grpc_health_v1/health_grpc.pb.go b/vendor/google.golang.org/grpc/health/grpc_health_v1/health_grpc.pb.go
index e99cd5c83..537ba0571 100644
--- a/vendor/google.golang.org/grpc/health/grpc_health_v1/health_grpc.pb.go
+++ b/vendor/google.golang.org/grpc/health/grpc_health_v1/health_grpc.pb.go
@@ -17,7 +17,7 @@
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
// versions:
-// - protoc-gen-go-grpc v1.6.0
+// - protoc-gen-go-grpc v1.6.2
// - protoc v5.27.1
// source: grpc/health/v1/health.proto
diff --git a/vendor/google.golang.org/grpc/internal/balancer/weight/weight.go b/vendor/google.golang.org/grpc/internal/balancer/weight/weight.go
deleted file mode 100644
index 11beb07d1..000000000
--- a/vendor/google.golang.org/grpc/internal/balancer/weight/weight.go
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- *
- * Copyright 2025 gRPC authors.
- *
- * 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 weight contains utilities to manage endpoint weights. Weights are
-// used by LB policies such as ringhash to distribute load across multiple
-// endpoints.
-package weight
-
-import (
- "fmt"
-
- "google.golang.org/grpc/resolver"
-)
-
-// attributeKey is the type used as the key to store EndpointInfo in the
-// Attributes field of resolver.Endpoint.
-type attributeKey struct{}
-
-// EndpointInfo will be stored in the Attributes field of Endpoints in order to
-// use the ringhash balancer.
-type EndpointInfo struct {
- Weight uint32
-}
-
-// Equal allows the values to be compared by Attributes.Equal.
-func (a EndpointInfo) Equal(o any) bool {
- oa, ok := o.(EndpointInfo)
- return ok && oa.Weight == a.Weight
-}
-
-// Set returns a copy of endpoint in which the Attributes field is updated with
-// EndpointInfo.
-func Set(endpoint resolver.Endpoint, epInfo EndpointInfo) resolver.Endpoint {
- endpoint.Attributes = endpoint.Attributes.WithValue(attributeKey{}, epInfo)
- return endpoint
-}
-
-// String returns a human-readable representation of EndpointInfo.
-// This method is intended for logging, testing, and debugging purposes only.
-// Do not rely on the output format, as it is not guaranteed to remain stable.
-func (a EndpointInfo) String() string {
- return fmt.Sprintf("Weight: %d", a.Weight)
-}
-
-// FromEndpoint returns the EndpointInfo stored in the Attributes field of an
-// endpoint. It returns an empty EndpointInfo if attribute is not found.
-func FromEndpoint(endpoint resolver.Endpoint) EndpointInfo {
- v := endpoint.Attributes.Value(attributeKey{})
- ei, _ := v.(EndpointInfo)
- return ei
-}
diff --git a/vendor/google.golang.org/grpc/internal/envconfig/envconfig.go b/vendor/google.golang.org/grpc/internal/envconfig/envconfig.go
index 7ad6fb44c..29d332e7b 100644
--- a/vendor/google.golang.org/grpc/internal/envconfig/envconfig.go
+++ b/vendor/google.golang.org/grpc/internal/envconfig/envconfig.go
@@ -54,17 +54,25 @@ var (
// XDSEndpointHashKeyBackwardCompat controls the parsing of the endpoint hash
// key from EDS LbEndpoint metadata. Endpoint hash keys can be disabled by
- // setting "GRPC_XDS_ENDPOINT_HASH_KEY_BACKWARD_COMPAT" to "true". When the
- // implementation of A76 is stable, we will flip the default value to false
- // in a subsequent release. A final release will remove this environment
- // variable, enabling the new behavior unconditionally.
- XDSEndpointHashKeyBackwardCompat = boolFromEnv("GRPC_XDS_ENDPOINT_HASH_KEY_BACKWARD_COMPAT", true)
+ // setting "GRPC_XDS_ENDPOINT_HASH_KEY_BACKWARD_COMPAT" to "true". A future
+ // release will remove this environment variable, enabling the new behavior
+ // unconditionally.
+ XDSEndpointHashKeyBackwardCompat = boolFromEnv("GRPC_XDS_ENDPOINT_HASH_KEY_BACKWARD_COMPAT", false)
+
+ // LabelServerGoroutines controls setting [runtime/pprof.Labels] on the
+ // goroutines spawned by [grpc.Server] type.
+ // For now, this is limited to the goroutines spawned to handle incoming
+ // requests on the server.
+ // Set "GRPC_GO_SERVER_GOROUTINE_LABELS" to "grpc.method=true" to
+ // enable this grpc.method label, or "all" to enable all valid labels.
+ // This variable is a bit-field.
+ LabelServerGoroutines = goroutineLabelsFromEnv("GRPC_GO_SERVER_GOROUTINE_LABELS", 0)
// RingHashSetRequestHashKey is set if the ring hash balancer can get the
// request hash header by setting the "requestHashHeader" field, according
- // to gRFC A76. It can be enabled by setting the environment variable
- // "GRPC_EXPERIMENTAL_RING_HASH_SET_REQUEST_HASH_KEY" to "true".
- RingHashSetRequestHashKey = boolFromEnv("GRPC_EXPERIMENTAL_RING_HASH_SET_REQUEST_HASH_KEY", false)
+ // to gRFC A76. It can be disabled by setting the environment variable
+ // "GRPC_EXPERIMENTAL_RING_HASH_SET_REQUEST_HASH_KEY" to "false".
+ RingHashSetRequestHashKey = boolFromEnv("GRPC_EXPERIMENTAL_RING_HASH_SET_REQUEST_HASH_KEY", true)
// ALTSHandshakerKeepaliveParams is set if we should add the
// KeepaliveParams when dial the ALTS handshaker service.
@@ -78,6 +86,14 @@ var (
// - The DNS resolver is being used.
EnableDefaultPortForProxyTarget = boolFromEnv("GRPC_EXPERIMENTAL_ENABLE_DEFAULT_PORT_FOR_PROXY_TARGET", true)
+ // CaseSensitiveBalancerRegistries is set if the balancer registry should be
+ // case-sensitive. This is enabled by default, but can be disabled by setting
+ // the env variable "GRPC_GO_EXPERIMENTAL_CASE_SENSITIVE_BALANCER_REGISTRIES"
+ // to "false".
+ //
+ // This env varible will be removed in release v1.82.0.
+ CaseSensitiveBalancerRegistries = boolFromEnv("GRPC_GO_EXPERIMENTAL_CASE_SENSITIVE_BALANCER_REGISTRIES", true)
+
// XDSAuthorityRewrite indicates whether xDS authority rewriting is enabled.
// This feature is defined in gRFC A81 and is enabled by setting the
// environment variable GRPC_EXPERIMENTAL_XDS_AUTHORITY_REWRITE to "true".
@@ -89,21 +105,53 @@ var (
// GRPC_EXPERIMENTAL_PF_WEIGHTED_SHUFFLING to "false".
PickFirstWeightedShuffling = boolFromEnv("GRPC_EXPERIMENTAL_PF_WEIGHTED_SHUFFLING", true)
- // DisableStrictPathChecking indicates whether strict path checking is
- // disabled. This feature can be disabled by setting the environment
- // variable GRPC_GO_EXPERIMENTAL_DISABLE_STRICT_PATH_CHECKING to "true".
+ // XDSRecoverPanicInResourceParsing indicates whether the xdsclient should
+ // recover from panics while parsing xDS resources.
//
- // When strict path checking is enabled, gRPC will reject requests with
- // paths that do not conform to the gRPC over HTTP/2 specification found at
- // https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md.
+ // This feature can be disabled (e.g. for fuzz testing) by setting the
+ // environment variable "GRPC_GO_EXPERIMENTAL_XDS_RESOURCE_PANIC_RECOVERY"
+ // to "false".
+ XDSRecoverPanicInResourceParsing = boolFromEnv("GRPC_GO_EXPERIMENTAL_XDS_RESOURCE_PANIC_RECOVERY", true)
+
+ // EnablePriorityLBChildPolicyCache controls whether the priority balancer
+ // should cache child balancers that are removed from the LB policy config,
+ // for a period of 15 minutes. This is disabled by default, but can be
+ // enabled by setting the env variable
+ // GRPC_EXPERIMENTAL_ENABLE_PRIORITY_LB_CHILD_POLICY_CACHE to true.
+ EnablePriorityLBChildPolicyCache = boolFromEnv("GRPC_EXPERIMENTAL_ENABLE_PRIORITY_LB_CHILD_POLICY_CACHE", false)
+
+ // Enable8KBDefaultHeaderListSize indicates that default maximum header list
+ // size is restricted to 8KB. This is disabled by default, but can be enabled
+ // by setting the environment variable
+ // "GRPC_GO_EXPERIMENTAL_ENABLE_8KB_DEFAULT_HEADER_LIST_SIZE" to "true".
+ // When disabled, the default maximum header list size of 16MB is used.
//
- // When disabled, gRPC will allow paths that do not contain a leading slash.
- // Enabling strict path checking is recommended for security reasons, as it
- // prevents potential path traversal vulnerabilities.
+ // When enabled, RPCs with a total size of headers exceeding 8KB will fail
+ // unless explicitly configured otherwise by the user.
+ //
+ // TODO: In release v1.82.0, env var will be enabled by default.
+ Enable8KBDefaultHeaderListSize = boolFromEnv("GRPC_GO_EXPERIMENTAL_ENABLE_8KB_DEFAULT_HEADER_LIST_SIZE", false)
+
+ // EnableHTTPFramerReadBufferPooling enables the use of the
+ // readyreader.Reader interface to perform non-memory-pinning reads,
+ // provided the underlying net.Conn supports it. This reduces memory usage
+ // when subchannels are idle.
//
- // A future release will remove this environment variable, enabling strict
- // path checking behavior unconditionally.
- DisableStrictPathChecking = boolFromEnv("GRPC_GO_EXPERIMENTAL_DISABLE_STRICT_PATH_CHECKING", false)
+ // This environment variable serves as an escape hatch to disable the
+ // feature if unforeseen issues arise, and it will be removed in a future
+ // release.
+ EnableHTTPFramerReadBufferPooling = boolFromEnv("GRPC_GO_EXPERIMENTAL_HTTP_FRAMER_READ_BUFFER_POOLING", true)
+
+ // ControlBufferThrottleLimit is the maximum number of control frames that can
+ // be queued in the control buffer before throttling is applied. The value
+ // must be between 1 and 10,000, and is set to 100 by default.
+ //
+ // This environment variable serves as an escape hatch to increase the
+ // throttling limit if unforeseen issues arise, and it will be removed in a
+ // future release.
+ //
+ // TODO: Remove this env var once v1.83.0 is release.
+ ControlBufferThrottleLimit = uint64FromEnv("GRPC_GO_EXPERIMENTAL_CONTROL_BUFFER_THROTTLE_LIMIT", 100, 1, 10000)
)
func boolFromEnv(envVar string, def bool) bool {
@@ -128,3 +176,52 @@ func uint64FromEnv(envVar string, def, min, max uint64) uint64 {
}
return v
}
+
+// GoroutineLabels is a bitfield indicating which goroutine labels are enabled.
+type GoroutineLabels uint16
+
+func goroutineLabelsFromEnv(envVar string, def GoroutineLabels) GoroutineLabels {
+ val := def
+ v := os.Getenv(envVar)
+ if strings.EqualFold(v, "all") {
+ return AllGoroutineLabels
+ } else if strings.EqualFold(v, "none") {
+ return 0
+ }
+ for s := range strings.SplitSeq(v, ",") {
+ s = strings.TrimSpace(s)
+ if len(s) == 0 {
+ continue
+ }
+ pre, post, ok := strings.Cut(s, "=")
+ if !ok {
+ // no equals sign
+ continue
+ }
+ post = strings.TrimSpace(post)
+ pre = strings.TrimSpace(pre)
+ bitDesignator := GoroutineLabels(0)
+ switch {
+ case strings.EqualFold(pre, "grpc.method"):
+ bitDesignator = GoroutineLabelServerMethod
+ default:
+ continue
+ }
+ if strings.EqualFold(post, "true") {
+ val |= bitDesignator
+ } else if strings.EqualFold(post, "false") {
+ val &^= bitDesignator
+ }
+ }
+ return val
+}
+
+const (
+ // GoroutineLabelServerMethod sets the grpc.method label on new
+ // server-side gRPC streams.
+ GoroutineLabelServerMethod GoroutineLabels = 1 << iota
+)
+
+// AllGoroutineLabels is an or'd together bitfield of all valid GoroutineLabels
+// constant values (above).
+const AllGoroutineLabels = GoroutineLabelServerMethod
diff --git a/vendor/google.golang.org/grpc/internal/envconfig/xds.go b/vendor/google.golang.org/grpc/internal/envconfig/xds.go
index 7685d08b5..a2312f8ea 100644
--- a/vendor/google.golang.org/grpc/internal/envconfig/xds.go
+++ b/vendor/google.golang.org/grpc/internal/envconfig/xds.go
@@ -79,4 +79,24 @@ var (
// xDS bootstrap configuration via the `call_creds` field. For more details,
// see: https://github.com/grpc/proposal/blob/master/A97-xds-jwt-call-creds.md
XDSBootstrapCallCredsEnabled = boolFromEnv("GRPC_EXPERIMENTAL_XDS_BOOTSTRAP_CALL_CREDS", false)
+
+ // XDSSNIEnabled controls if gRPC should send SNI information in xDS
+ // configured TLS handshakes. For more details, see:
+ // https://github.com/grpc/proposal/blob/master/A101-SNI-setting-and-SNI-SAN-validation.md
+ XDSSNIEnabled = boolFromEnv("GRPC_EXPERIMENTAL_XDS_SNI", false)
+
+ // XDSORCAToLRSPropEnabled controls whether ORCA metrics are explicitly
+ // filtered and prefix-propagated to the LRS server. For more details, see:
+ // https://github.com/grpc/proposal/blob/master/A85-lrs-custom-metrics-changes.md
+ XDSORCAToLRSPropEnabled = boolFromEnv("GRPC_EXPERIMENTAL_XDS_ORCA_LRS_PROPAGATION", false)
+
+ // XDSClientExtProcEnabled indicates whether ExtProc filter is enabled on
+ // the client side. For more details, see:
+ // https://github.com/grpc/proposal/blob/master/A93-xds-ext-proc.md
+ XDSClientExtProcEnabled = boolFromEnv("GRPC_EXPERIMENTAL_XDS_EXT_PROC_ON_CLIENT", false)
+
+ // GCPAuthenticationFilterEnabled enables the xDS GCP Authentication
+ // filter. For more details, see:
+ // https://github.com/grpc/proposal/blob/master/A83-xds-gcp-authn-filter.md
+ GCPAuthenticationFilterEnabled = boolFromEnv("GRPC_EXPERIMENTAL_XDS_GCP_AUTHENTICATION_FILTER", false)
)
diff --git a/vendor/google.golang.org/grpc/internal/grpcutil/encode_duration.go b/vendor/google.golang.org/grpc/internal/grpcutil/encode_duration.go
index b25b0baec..1cc43fc6b 100644
--- a/vendor/google.golang.org/grpc/internal/grpcutil/encode_duration.go
+++ b/vendor/google.golang.org/grpc/internal/grpcutil/encode_duration.go
@@ -39,7 +39,6 @@ func div(d, r time.Duration) int64 {
//
// https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md#requests
func EncodeDuration(t time.Duration) string {
- // TODO: This is simplistic and not bandwidth efficient. Improve it.
if t <= 0 {
return "0n"
}
diff --git a/vendor/google.golang.org/grpc/internal/grpcutil/regex.go b/vendor/google.golang.org/grpc/internal/grpcutil/regex.go
deleted file mode 100644
index 7a092b2b8..000000000
--- a/vendor/google.golang.org/grpc/internal/grpcutil/regex.go
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- *
- * Copyright 2021 gRPC authors.
- *
- * 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 grpcutil
-
-import "regexp"
-
-// FullMatchWithRegex returns whether the full text matches the regex provided.
-func FullMatchWithRegex(re *regexp.Regexp, text string) bool {
- if len(text) == 0 {
- return re.MatchString(text)
- }
- re.Longest()
- rem := re.FindString(text)
- return len(rem) == len(text)
-}
diff --git a/vendor/google.golang.org/grpc/internal/mem/buffer_pool.go b/vendor/google.golang.org/grpc/internal/mem/buffer_pool.go
new file mode 100644
index 000000000..2d83b2ece
--- /dev/null
+++ b/vendor/google.golang.org/grpc/internal/mem/buffer_pool.go
@@ -0,0 +1,349 @@
+/*
+ *
+ * Copyright 2026 gRPC authors.
+ *
+ * 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 mem provides utilities that facilitate memory reuse in byte slices
+// that are used as buffers.
+package mem
+
+import (
+ "fmt"
+ "math/bits"
+ "slices"
+ "sort"
+ "sync"
+)
+
+const (
+ goPageSize = 4 * 1024 // 4KiB. N.B. this must be a power of 2.
+)
+
+var uintSize = bits.UintSize // use a variable for mocking during tests.
+
+// bufferPool is a copy of the public bufferPool interface used to avoid
+// circular dependencies.
+type bufferPool interface {
+ // Get returns a buffer with specified length from the pool.
+ Get(length int) *[]byte
+
+ // Put returns a buffer to the pool.
+ //
+ // The provided pointer must hold a prefix of the buffer obtained via
+ // BufferPool.Get to ensure the buffer's entire capacity can be re-used.
+ Put(*[]byte)
+}
+
+// BinaryTieredBufferPool is a buffer pool that uses multiple sub-pools with
+// power-of-two sizes.
+type BinaryTieredBufferPool struct {
+ // exponentToNextLargestPoolMap maps a power-of-two exponent (e.g., 12 for
+ // 4KB) to the index of the next largest sizedBufferPool. This is used by
+ // Get() to find the smallest pool that can satisfy a request for a given
+ // size.
+ exponentToNextLargestPoolMap []int
+ // exponentToPreviousLargestPoolMap maps a power-of-two exponent to the
+ // index of the previous largest sizedBufferPool. This is used by Put()
+ // to return a buffer to the most appropriate pool based on its capacity.
+ exponentToPreviousLargestPoolMap []int
+ sizedPools []bufferPool
+ fallbackPool bufferPool
+ maxPoolCap int // Optimization: Cache max capacity
+}
+
+// NewBinaryTieredBufferPool returns a BufferPool backed by multiple sub-pools.
+// This structure enables O(1) lookup time for Get and Put operations.
+//
+// The arguments provided are the exponents for the buffer capacities (powers
+// of 2), not the raw byte sizes. For example, to create a pool of 16KB buffers
+// (2^14 bytes), pass 14 as the argument.
+func NewBinaryTieredBufferPool(powerOfTwoExponents ...uint8) (*BinaryTieredBufferPool, error) {
+ return newBinaryTiered(func(size int) bufferPool {
+ return newSizedBufferPool(size, true)
+ }, &SimpleBufferPool{shouldZero: true}, powerOfTwoExponents...)
+}
+
+// NewDirtyBinaryTieredBufferPool returns a BufferPool backed by multiple
+// sub-pools. It is similar to NewBinaryTieredBufferPool but it does not
+// initialize the buffers before returning them.
+func NewDirtyBinaryTieredBufferPool(powerOfTwoExponents ...uint8) (*BinaryTieredBufferPool, error) {
+ return newBinaryTiered(func(size int) bufferPool {
+ return newSizedBufferPool(size, false)
+ }, NewDirtySimplePool(), powerOfTwoExponents...)
+}
+
+func newBinaryTiered(sizedPoolFactory func(int) bufferPool, fallbackPool bufferPool, powerOfTwoExponents ...uint8) (*BinaryTieredBufferPool, error) {
+ slices.Sort(powerOfTwoExponents)
+ powerOfTwoExponents = slices.Compact(powerOfTwoExponents)
+
+ // Determine the maximum exponent we need to support. This depends on the
+ // word size (32-bit vs 64-bit).
+ maxExponent := uintSize - 2
+ indexOfNextLargestBit := slices.Repeat([]int{-1}, maxExponent+1)
+ indexOfPreviousLargestBit := slices.Repeat([]int{-1}, maxExponent+1)
+
+ maxTier := 0
+ pools := make([]bufferPool, 0, len(powerOfTwoExponents))
+
+ for i, exp := range powerOfTwoExponents {
+ // Allocating slices of size > 2^maxExponent isn't possible on
+ // maxExponent-bit machines.
+ if int(exp) > maxExponent {
+ return nil, fmt.Errorf("mem: allocating slice of size 2^%d is not possible", exp)
+ }
+ tierSize := 1 << exp
+ pools = append(pools, sizedPoolFactory(tierSize))
+ maxTier = max(maxTier, tierSize)
+
+ // Map the exact power of 2 to this pool index.
+ indexOfNextLargestBit[exp] = i
+ indexOfPreviousLargestBit[exp] = i
+ }
+
+ // Fill gaps for Get() (Next Largest)
+ // We iterate backwards. If current is empty, take the value from the right (larger).
+ for i := maxExponent - 1; i >= 0; i-- {
+ if indexOfNextLargestBit[i] == -1 {
+ indexOfNextLargestBit[i] = indexOfNextLargestBit[i+1]
+ }
+ }
+
+ // Fill gaps for Put() (Previous Largest)
+ // We iterate forwards. If current is empty, take the value from the left (smaller).
+ for i := 1; i <= maxExponent; i++ {
+ if indexOfPreviousLargestBit[i] == -1 {
+ indexOfPreviousLargestBit[i] = indexOfPreviousLargestBit[i-1]
+ }
+ }
+
+ return &BinaryTieredBufferPool{
+ exponentToNextLargestPoolMap: indexOfNextLargestBit,
+ exponentToPreviousLargestPoolMap: indexOfPreviousLargestBit,
+ sizedPools: pools,
+ maxPoolCap: maxTier,
+ fallbackPool: fallbackPool,
+ }, nil
+}
+
+// Get returns a buffer with specified length from the pool.
+func (b *BinaryTieredBufferPool) Get(size int) *[]byte {
+ return b.poolForGet(size).Get(size)
+}
+
+func (b *BinaryTieredBufferPool) poolForGet(size int) bufferPool {
+ if size == 0 || size > b.maxPoolCap {
+ return b.fallbackPool
+ }
+
+ // Calculate the exponent of the smallest power of 2 >= size.
+ // We subtract 1 from size to handle exact powers of 2 correctly.
+ //
+ // Examples:
+ // size=16 (0b10000) -> size-1=15 (0b01111) -> bits.Len=4 -> Pool for 2^4
+ // size=17 (0b10001) -> size-1=16 (0b10000) -> bits.Len=5 -> Pool for 2^5
+ querySize := uint(size - 1)
+ poolIdx := b.exponentToNextLargestPoolMap[bits.Len(querySize)]
+
+ return b.sizedPools[poolIdx]
+}
+
+// Put returns a buffer to the pool.
+func (b *BinaryTieredBufferPool) Put(buf *[]byte) {
+ // We pass the capacity of the buffer, and not the size of the buffer here.
+ // If we did the latter, all buffers would eventually move to the smallest
+ // pool.
+ b.poolForPut(cap(*buf)).Put(buf)
+}
+
+func (b *BinaryTieredBufferPool) poolForPut(bCap int) bufferPool {
+ if bCap == 0 {
+ return NopBufferPool{}
+ }
+ if bCap > b.maxPoolCap {
+ return b.fallbackPool
+ }
+ // Find the pool with the largest capacity <= bCap.
+ //
+ // We calculate the exponent of the largest power of 2 <= bCap.
+ // bits.Len(x) returns the minimum number of bits required to represent x;
+ // i.e. the number of bits up to and including the most significant bit.
+ // Subtracting 1 gives the 0-based index of the most significant bit,
+ // which is the exponent of the largest power of 2 <= bCap.
+ //
+ // Examples:
+ // cap=16 (0b10000) -> Len=5 -> 5-1=4 -> 2^4
+ // cap=15 (0b01111) -> Len=4 -> 4-1=3 -> 2^3
+ largestPowerOfTwo := bits.Len(uint(bCap)) - 1
+ poolIdx := b.exponentToPreviousLargestPoolMap[largestPowerOfTwo]
+ // The buffer is smaller than the smallest power of 2, discard it.
+ if poolIdx == -1 {
+ // Buffer is smaller than our smallest pool bucket.
+ return NopBufferPool{}
+ }
+ return b.sizedPools[poolIdx]
+}
+
+// NopBufferPool is a buffer pool that returns new buffers without pooling.
+type NopBufferPool struct{}
+
+// Get returns a buffer with specified length from the pool.
+func (NopBufferPool) Get(length int) *[]byte {
+ b := make([]byte, length)
+ return &b
+}
+
+// Put returns a buffer to the pool.
+func (NopBufferPool) Put(*[]byte) {
+}
+
+// sizedBufferPool is a BufferPool implementation that is optimized for specific
+// buffer sizes. For example, HTTP/2 frames within gRPC have a default max size
+// of 16kb and a sizedBufferPool can be configured to only return buffers with a
+// capacity of 16kb. Note that however it does not support returning larger
+// buffers and in fact panics if such a buffer is requested. Because of this,
+// this BufferPool implementation is not meant to be used on its own and rather
+// is intended to be embedded in a TieredBufferPool such that Get is only
+// invoked when the required size is smaller than or equal to defaultSize.
+type sizedBufferPool struct {
+ pool sync.Pool
+ defaultSize int
+ shouldZero bool
+}
+
+func (p *sizedBufferPool) Get(size int) *[]byte {
+ buf, ok := p.pool.Get().(*[]byte)
+ if !ok {
+ buf := make([]byte, size, p.defaultSize)
+ return &buf
+ }
+ b := *buf
+ if p.shouldZero {
+ clear(b[:cap(b)])
+ }
+ *buf = b[:size]
+ return buf
+}
+
+func (p *sizedBufferPool) Put(buf *[]byte) {
+ if cap(*buf) < p.defaultSize {
+ // Ignore buffers that are too small to fit in the pool. Otherwise, when
+ // Get is called it will panic as it tries to index outside the bounds
+ // of the buffer.
+ return
+ }
+ p.pool.Put(buf)
+}
+
+func newSizedBufferPool(size int, zero bool) *sizedBufferPool {
+ return &sizedBufferPool{
+ defaultSize: size,
+ shouldZero: zero,
+ }
+}
+
+// TieredBufferPool implements the BufferPool interface with multiple tiers of
+// buffer pools for different sizes of buffers.
+type TieredBufferPool struct {
+ sizedPools []*sizedBufferPool
+ fallbackPool SimpleBufferPool
+}
+
+// NewTieredBufferPool returns a BufferPool implementation that uses multiple
+// underlying pools of the given pool sizes.
+func NewTieredBufferPool(poolSizes ...int) *TieredBufferPool {
+ sort.Ints(poolSizes)
+ pools := make([]*sizedBufferPool, len(poolSizes))
+ for i, s := range poolSizes {
+ pools[i] = newSizedBufferPool(s, true)
+ }
+ return &TieredBufferPool{
+ sizedPools: pools,
+ fallbackPool: SimpleBufferPool{shouldZero: true},
+ }
+}
+
+// Get returns a buffer with specified length from the pool.
+func (p *TieredBufferPool) Get(size int) *[]byte {
+ return p.getPool(size).Get(size)
+}
+
+// Put returns a buffer to the pool.
+func (p *TieredBufferPool) Put(buf *[]byte) {
+ p.getPool(cap(*buf)).Put(buf)
+}
+
+func (p *TieredBufferPool) getPool(size int) bufferPool {
+ poolIdx := sort.Search(len(p.sizedPools), func(i int) bool {
+ return p.sizedPools[i].defaultSize >= size
+ })
+
+ if poolIdx == len(p.sizedPools) {
+ return &p.fallbackPool
+ }
+
+ return p.sizedPools[poolIdx]
+}
+
+// SimpleBufferPool is an implementation of the mem.BufferPool interface that
+// attempts to pool buffers with a sync.Pool. When Get is invoked, it tries to
+// acquire a buffer from the pool but if that buffer is too small, it returns it
+// to the pool and creates a new one.
+type SimpleBufferPool struct {
+ pool sync.Pool
+ shouldZero bool
+}
+
+// NewDirtySimplePool constructs a [SimpleBufferPool]. It does not initialize
+// the buffers before returning them. Callers must ensure they don't read the
+// buffers before writing data to them.
+func NewDirtySimplePool() *SimpleBufferPool {
+ return &SimpleBufferPool{
+ shouldZero: false,
+ }
+}
+
+// Get returns a buffer with specified length from the pool.
+func (p *SimpleBufferPool) Get(size int) *[]byte {
+ bs, ok := p.pool.Get().(*[]byte)
+ if ok && cap(*bs) >= size {
+ if p.shouldZero {
+ clear((*bs)[:cap(*bs)])
+ }
+ *bs = (*bs)[:size]
+ return bs
+ }
+
+ // A buffer was pulled from the pool, but it is too small. Put it back in
+ // the pool and create one large enough.
+ if ok {
+ p.pool.Put(bs)
+ }
+
+ // If we're going to allocate, round up to the nearest page. This way if
+ // requests frequently arrive with small variation we don't allocate
+ // repeatedly if we get unlucky and they increase over time. By default we
+ // only allocate here if size > 1MiB. Because goPageSize is a power of 2, we
+ // can round up efficiently.
+ allocSize := (size + goPageSize - 1) & ^(goPageSize - 1)
+
+ b := make([]byte, size, allocSize)
+ return &b
+}
+
+// Put returns a buffer to the pool.
+func (p *SimpleBufferPool) Put(buf *[]byte) {
+ p.pool.Put(buf)
+}
diff --git a/vendor/google.golang.org/grpc/internal/resolver/config_selector.go b/vendor/google.golang.org/grpc/internal/resolver/config_selector.go
index f0603871c..6320e9b57 100644
--- a/vendor/google.golang.org/grpc/internal/resolver/config_selector.go
+++ b/vendor/google.golang.org/grpc/internal/resolver/config_selector.go
@@ -106,15 +106,28 @@ type ClientStream interface {
// ClientInterceptor is an interceptor for gRPC client streams.
type ClientInterceptor interface {
- // NewStream produces a ClientStream for an RPC which may optionally use
- // the provided function to produce a stream for delegation. Note:
- // RPCInfo.Context should not be used (will be nil).
+ // NewStream creates a ClientStream for an RPC.
//
- // done is invoked when the RPC is finished using its connection, or could
- // not be assigned a connection. RPC operations may still occur on
- // ClientStream after done is called, since the interceptor is invoked by
- // application-layer operations. done must never be nil when called.
+ // Implementations must delegate stream creation to the provided newStream
+ // function. To intercept or override stream behavior, implementations
+ // may wrap the ClientStream returned by the delegate.
+ //
+ // Note: RPCInfo.Context is currently unused and will be nil.
+ //
+ // The done function is invoked when the RPC has finished using its
+ // underlying connection or if a connection could not be assigned. Because
+ // interceptors operate at the application layer, RPC operations may
+ // continue on the ClientStream even after done has been called. The
+ // caller must ensure done is non-nil.
+ //
+ // To ensure RPC completion notifications propagate through the entire
+ // interceptor chain, implementations must ensure that the done function
+ // passed to the delegate newStream invokes the done function passed to
+ // NewStream.
NewStream(ctx context.Context, ri RPCInfo, done func(), newStream func(ctx context.Context, done func()) (ClientStream, error)) (ClientStream, error)
+ // Close closes the interceptor. Once called, no new calls to NewStream are
+ // accepted. Ongoing calls to NewStream are allowed to complete.
+ Close()
}
// ServerInterceptor is an interceptor for incoming RPC's on gRPC server side.
@@ -123,6 +136,9 @@ type ServerInterceptor interface {
// information about connection RPC was received on, and HTTP Headers. This
// information will be piped into context.
AllowRPC(ctx context.Context) error // TODO: Make this a real interceptor for filters such as rate limiting.
+ // Close closes the interceptor. Once called, no new calls to NewStream are
+ // accepted. Ongoing calls to NewStream are allowed to complete.
+ Close()
}
type csKeyType string
diff --git a/vendor/google.golang.org/grpc/internal/stats/labels.go b/vendor/google.golang.org/grpc/internal/stats/labels.go
index fd33af51a..5ea898cb5 100644
--- a/vendor/google.golang.org/grpc/internal/stats/labels.go
+++ b/vendor/google.golang.org/grpc/internal/stats/labels.go
@@ -19,24 +19,56 @@
// Package stats provides internal stats related functionality.
package stats
-import "context"
+import (
+ "context"
+ "maps"
+)
-// Labels are the labels for metrics.
-type Labels struct {
- // TelemetryLabels are the telemetry labels to record.
- TelemetryLabels map[string]string
+// LabelCallback is a function that is executed when telemetry
+// label keys are updated.
+type LabelCallback func(map[string]string)
+type telemetryLabelCallbackKey struct{}
+
+// UpdateLabels executes registered telemetry callbacks with the update labels. Labels
+// are copied before being processed by any callbacks to ensure mutations are not
+// shared among derived contexts.
+//
+// It is the responsibility of the registrant to handle conflicts or label resets.
+func UpdateLabels(ctx context.Context, update map[string]string) {
+ executeTelemetryLabelCallbacks(ctx, update)
}
-type labelsKey struct{}
+// RegisterTelemetryLabelCallback registers a callback function that is executed whenever
+// telemetry labels are updated.
+func RegisterTelemetryLabelCallback(ctx context.Context, callback LabelCallback) context.Context {
+ if callback == nil {
+ return ctx
+ }
+
+ callbacks, ok := ctx.Value(telemetryLabelCallbackKey{}).([]LabelCallback)
+ if !ok {
+ return context.WithValue(ctx, telemetryLabelCallbackKey{}, []LabelCallback{callback})
+ }
+ return context.WithValue(ctx, telemetryLabelCallbackKey{}, append(append([]LabelCallback(nil), callbacks...), callback))
-// GetLabels returns the Labels stored in the context, or nil if there is one.
-func GetLabels(ctx context.Context) *Labels {
- labels, _ := ctx.Value(labelsKey{}).(*Labels)
- return labels
}
-// SetLabels sets the Labels in the context.
-func SetLabels(ctx context.Context, labels *Labels) context.Context {
- // could also append
- return context.WithValue(ctx, labelsKey{}, labels)
+// executeTelemetryLabelCallback runs the registered callbacks in the order they were
+// registered on the context with the provided labels. If no callbacks are registered
+// it does nothing.
+//
+// To ensure callbacks do not mutate the state of the provided label map it is copied
+// before execution.
+func executeTelemetryLabelCallbacks(ctx context.Context, labels map[string]string) {
+ callbacks, ok := ctx.Value(telemetryLabelCallbackKey{}).([]LabelCallback)
+ if !ok {
+ return
+ }
+
+ labelsCopy := map[string]string{}
+ maps.Copy(labelsCopy, labels)
+ for _, callback := range callbacks {
+ callback(labelsCopy)
+ }
+
}
diff --git a/vendor/google.golang.org/grpc/internal/transport/client_stream.go b/vendor/google.golang.org/grpc/internal/transport/client_stream.go
index cd8152ef1..ad382b0fd 100644
--- a/vendor/google.golang.org/grpc/internal/transport/client_stream.go
+++ b/vendor/google.golang.org/grpc/internal/transport/client_stream.go
@@ -19,6 +19,7 @@
package transport
import (
+ "fmt"
"sync/atomic"
"golang.org/x/net/http2"
@@ -28,6 +29,12 @@ import (
"google.golang.org/grpc/status"
)
+// nonGRPCDataMaxLen is the maximum length of nonGRPCDataBuf.
+//
+// NOTE: If changed this value, you MUST update the corresponding test in:
+// - /test/end2end_test.go:TestHTTPServerSendsNonGRPCHeaderSurfaceFurtherData
+const nonGRPCDataMaxLen = 1024
+
// ClientStream implements streaming functionality for a gRPC client.
type ClientStream struct {
Stream // Embed for common stream functionality.
@@ -46,7 +53,11 @@ type ClientStream struct {
// headerValid indicates whether a valid header was received. Only
// meaningful after headerChan is closed (always call waitOnHeader() before
// reading its value).
- headerValid bool
+ headerValid bool
+
+ nonGRPCStatus *status.Status // the initial status from the non-gRPC response header, finalized with collected data before closing.
+ nonGRPCDataBuf []byte // stores the data of a non-gRPC response.
+
noHeaders bool // set if the client never received headers (set only after the stream is done).
headerChanClosed uint32 // set when headerChan is closed. Used to avoid closing headerChan multiple times.
bytesReceived atomic.Bool // indicates whether any bytes have been received on this stream
@@ -54,6 +65,29 @@ type ClientStream struct {
statsHandler stats.Handler // nil for internal streams (e.g., health check, ORCA) where telemetry is not supported.
}
+func (s *ClientStream) startNonGRPCDataCollection(st *status.Status) {
+ s.nonGRPCStatus = st
+ s.nonGRPCDataBuf = make([]byte, 0, nonGRPCDataMaxLen)
+}
+
+// finalizeNonGRPCStatus builds the terminal status by appending the collected
+// response body to the original non-gRPC status message.
+func (s *ClientStream) finalizeNonGRPCStatus() *status.Status {
+ msg := fmt.Sprintf("%s\ndata: %q", s.nonGRPCStatus.Message(), s.nonGRPCDataBuf)
+ return status.New(s.nonGRPCStatus.Code(), msg)
+}
+
+// handleNonGRPCData collects non-gRPC body from the given data frame.
+// It returns non-nil value when the stream should be closed with it.
+func (s *ClientStream) handleNonGRPCData(f *parsedDataFrame) *status.Status {
+ n := min(f.data.Len(), nonGRPCDataMaxLen-len(s.nonGRPCDataBuf))
+ s.nonGRPCDataBuf = append(s.nonGRPCDataBuf, f.data.ReadOnlyData()[0:n]...)
+ if len(s.nonGRPCDataBuf) >= nonGRPCDataMaxLen || f.StreamEnded() {
+ return s.finalizeNonGRPCStatus()
+ }
+ return nil
+}
+
// Read reads an n byte message from the input stream.
func (s *ClientStream) Read(n int) (mem.BufferSlice, error) {
b, err := s.Stream.read(n)
diff --git a/vendor/google.golang.org/grpc/internal/transport/controlbuf.go b/vendor/google.golang.org/grpc/internal/transport/controlbuf.go
index 7efa52478..b9bae0249 100644
--- a/vendor/google.golang.org/grpc/internal/transport/controlbuf.go
+++ b/vendor/google.golang.org/grpc/internal/transport/controlbuf.go
@@ -29,6 +29,7 @@ import (
"golang.org/x/net/http2"
"golang.org/x/net/http2/hpack"
+ "google.golang.org/grpc/internal/envconfig"
"google.golang.org/grpc/internal/grpclog"
"google.golang.org/grpc/mem"
)
@@ -96,61 +97,70 @@ func (il *itemList) isEmpty() bool {
return il.head == nil
}
-// The following defines various control items which could flow through
-// the control buffer of transport. They represent different aspects of
-// control tasks, e.g., flow control, settings, streaming resetting, etc.
-
-// maxQueuedTransportResponseFrames is the most queued "transport response"
-// frames we will buffer before preventing new reads from occurring on the
-// transport. These are control frames sent in response to client requests,
-// such as RST_STREAM due to bad headers or settings acks.
-const maxQueuedTransportResponseFrames = 50
+// maxQueuedControlBufferItems is the maximum number of frames (other than
+// HEADERS and DATA) that we will buffer before preventing new reads from
+// occurring on the transport. These are control frames sent in response to
+// client requests, or frames that result in work being scheduled, such as
+// RST_STREAM due to bad headers or settings acks.
+var maxQueuedControlBufferItems = int(envconfig.ControlBufferThrottleLimit)
type cbItem interface {
- isTransportResponseFrame() bool
+ isThrottled() bool
}
+// throttledItem represents every item in the controlBuffer to which the overall
+// throttling limit applies, other than outgoing HEADERS and DATA frames.
+type throttledItem struct{}
+
+func (throttledItem) isThrottled() bool { return true }
+
+// The following defines various control items which could flow through
+// the control buffer of transport. They represent different aspects of
+// control tasks, e.g., flow control, settings, streaming resetting, etc.
+
// registerStream is used to register an incoming stream with loopy writer.
type registerStream struct {
+ throttledItem
streamID uint32
wq *writeQuota
}
-func (*registerStream) isTransportResponseFrame() bool { return false }
-
-// headerFrame is also used to register stream on the client-side.
-type headerFrame struct {
+type clientHeaders struct {
streamID uint32
hf []hpack.HeaderField
- endStream bool // Valid on server side.
- initStream func(uint32) error // Used only on the client side.
+ initStream func(uint32) error
onWrite func()
- wq *writeQuota // write quota for the stream created.
- cleanup *cleanupStream // Valid on the server side.
- onOrphaned func(error) // Valid on client-side
+ wq *writeQuota
+ onOrphaned func(error)
}
-func (h *headerFrame) isTransportResponseFrame() bool {
- return h.cleanup != nil && h.cleanup.rst // Results in a RST_STREAM
+func (*clientHeaders) isThrottled() bool { return false }
+
+type serverHeaders struct {
+ streamID uint32
+ hf []hpack.HeaderField
+ endStream bool
+ onWrite func()
+ cleanup *cleanupStream
}
+func (h *serverHeaders) isThrottled() bool { return false }
+
type cleanupStream struct {
+ throttledItem
streamID uint32
rst bool
rstCode http2.ErrCode
onWrite func()
}
-func (c *cleanupStream) isTransportResponseFrame() bool { return c.rst } // Results in a RST_STREAM
-
type earlyAbortStream struct {
+ throttledItem
streamID uint32
rst bool
hf []hpack.HeaderField // Pre-built header fields
}
-func (*earlyAbortStream) isTransportResponseFrame() bool { return false }
-
type dataFrame struct {
streamID uint32
endStream bool
@@ -162,70 +172,60 @@ type dataFrame struct {
onEachWrite func()
}
-func (*dataFrame) isTransportResponseFrame() bool { return false }
+func (*dataFrame) isThrottled() bool { return false }
type incomingWindowUpdate struct {
+ throttledItem
streamID uint32
increment uint32
}
-func (*incomingWindowUpdate) isTransportResponseFrame() bool { return false }
-
type outgoingWindowUpdate struct {
+ throttledItem
streamID uint32
increment uint32
}
-func (*outgoingWindowUpdate) isTransportResponseFrame() bool {
- return false // window updates are throttled by thresholds
-}
-
type incomingSettings struct {
+ throttledItem
ss []http2.Setting
}
-func (*incomingSettings) isTransportResponseFrame() bool { return true } // Results in a settings ACK
-
type outgoingSettings struct {
+ throttledItem
ss []http2.Setting
}
-func (*outgoingSettings) isTransportResponseFrame() bool { return false }
-
type incomingGoAway struct {
+ throttledItem
}
-func (*incomingGoAway) isTransportResponseFrame() bool { return false }
-
type goAway struct {
+ throttledItem
code http2.ErrCode
debugData []byte
headsUp bool
closeConn error // if set, loopyWriter will exit with this error
}
-func (*goAway) isTransportResponseFrame() bool { return false }
-
type ping struct {
+ throttledItem
ack bool
data [8]byte
}
-func (*ping) isTransportResponseFrame() bool { return true }
-
type outFlowControlSizeRequest struct {
+ throttledItem
resp chan uint32
}
-func (*outFlowControlSizeRequest) isTransportResponseFrame() bool { return false }
-
// closeConnection is an instruction to tell the loopy writer to flush the
// framer and exit, which will cause the transport's connection to be closed
// (by the client or server). The transport itself will close after the reader
// encounters the EOF caused by the connection closure.
-type closeConnection struct{}
-
-func (closeConnection) isTransportResponseFrame() bool { return false }
+type closeConnection struct {
+ throttledItem
+}
type outStreamState int
@@ -379,9 +379,9 @@ func (c *controlBuffer) executeAndPut(f func() bool, it cbItem) (bool, error) {
c.consumerWaiting = false
}
c.list.enqueue(it)
- if it.isTransportResponseFrame() {
+ if it.isThrottled() {
c.transportResponseFrames++
- if c.transportResponseFrames == maxQueuedTransportResponseFrames {
+ if c.transportResponseFrames == maxQueuedControlBufferItems {
// We are adding the frame that puts us over the threshold; create
// a throttling channel.
ch := make(chan struct{})
@@ -436,8 +436,8 @@ func (c *controlBuffer) getOnceLocked() (any, error) {
return nil, nil
}
h := c.list.dequeue().(cbItem)
- if h.isTransportResponseFrame() {
- if c.transportResponseFrames == maxQueuedTransportResponseFrames {
+ if h.isThrottled() {
+ if c.transportResponseFrames == maxQueuedControlBufferItems {
// We are removing the frame that put us over the
// threshold; close and clear the throttling channel.
ch := c.trfChan.Swap(nil)
@@ -464,10 +464,8 @@ func (c *controlBuffer) finish() {
// is still not aware of these yet.
for head := c.list.dequeueAll(); head != nil; head = head.next {
switch v := head.it.(type) {
- case *headerFrame:
- if v.onOrphaned != nil { // It will be nil on the server-side.
- v.onOrphaned(ErrConnClosing)
- }
+ case *clientHeaders:
+ v.onOrphaned(ErrConnClosing)
case *dataFrame:
if !v.processing {
v.data.Free()
@@ -680,42 +678,38 @@ func (l *loopyWriter) registerStreamHandler(h *registerStream) {
l.estdStreams[h.streamID] = str
}
-func (l *loopyWriter) headerHandler(h *headerFrame) error {
- if l.side == serverSide {
- str, ok := l.estdStreams[h.streamID]
- if !ok {
- if l.logger.V(logLevel) {
- l.logger.Infof("Unrecognized streamID %d in loopyWriter", h.streamID)
- }
- return nil
- }
- // Case 1.A: Server is responding back with headers.
- if !h.endStream {
- return l.writeHeader(h.streamID, h.endStream, h.hf, h.onWrite)
+func (l *loopyWriter) serverHeaderHandler(hdr *serverHeaders) error {
+ str, ok := l.estdStreams[hdr.streamID]
+ if !ok {
+ if l.logger.V(logLevel) {
+ l.logger.Infof("Unrecognized streamID %d in loopyWriter", hdr.streamID)
}
- // else: Case 1.B: Server wants to close stream.
+ return nil
+ }
- if str.state != empty { // either active or waiting on stream quota.
- // add it str's list of items.
- str.itl.enqueue(h)
- return nil
- }
- if err := l.writeHeader(h.streamID, h.endStream, h.hf, h.onWrite); err != nil {
- return err
- }
- return l.cleanupStreamHandler(h.cleanup)
+ // Case 1: Server is responding back with headers.
+ if !hdr.endStream {
+ return l.writeHeader(hdr.streamID, hdr.endStream, hdr.hf, hdr.onWrite)
+ }
+
+ // Case 2: Server is closing the stream.
+ if str.state != empty { // either active or waiting on stream quota.
+ str.itl.enqueue(hdr)
+ return nil
+ }
+ if err := l.writeHeader(hdr.streamID, hdr.endStream, hdr.hf, hdr.onWrite); err != nil {
+ return err
}
- // Case 2: Client wants to originate stream.
+ return l.cleanupStreamHandler(hdr.cleanup)
+}
+
+func (l *loopyWriter) clientHeaderHandler(hdr *clientHeaders) error {
str := &outStream{
- id: h.streamID,
+ id: hdr.streamID,
state: empty,
itl: &itemList{},
- wq: h.wq,
+ wq: hdr.wq,
}
- return l.originateStream(str, h)
-}
-
-func (l *loopyWriter) originateStream(str *outStream, hdr *headerFrame) error {
// l.draining is set when handling GoAway. In which case, we want to avoid
// creating new streams.
if l.draining {
@@ -726,7 +720,7 @@ func (l *loopyWriter) originateStream(str *outStream, hdr *headerFrame) error {
if err := hdr.initStream(str.id); err != nil {
return err
}
- if err := l.writeHeader(str.id, hdr.endStream, hdr.hf, hdr.onWrite); err != nil {
+ if err := l.writeHeader(str.id, false, hdr.hf, hdr.onWrite); err != nil {
return err
}
l.estdStreams[str.id] = str
@@ -882,8 +876,10 @@ func (l *loopyWriter) handle(i any) error {
return l.incomingSettingsHandler(i)
case *outgoingSettings:
return l.outgoingSettingsHandler(i)
- case *headerFrame:
- return l.headerHandler(i)
+ case *clientHeaders:
+ return l.clientHeaderHandler(i)
+ case *serverHeaders:
+ return l.serverHeaderHandler(i)
case *registerStream:
l.registerStreamHandler(i)
case *cleanupStream:
@@ -956,39 +952,16 @@ func (l *loopyWriter) processData() (bool, error) {
// from data is copied to h to make as big as the maximum possible HTTP2 frame
// size.
- if len(dataItem.h) == 0 && reader.Remaining() == 0 { // Empty data frame
- // Client sends out empty data frame with endStream = true
- if err := l.framer.writeData(dataItem.streamID, dataItem.endStream, nil); err != nil {
- return false, err
- }
- str.itl.dequeue() // remove the empty data item from stream
- reader.Close()
- if str.itl.isEmpty() {
- str.state = empty
- } else if trailer, ok := str.itl.peek().(*headerFrame); ok { // the next item is trailers.
- if err := l.writeHeader(trailer.streamID, trailer.endStream, trailer.hf, trailer.onWrite); err != nil {
- return false, err
- }
- if err := l.cleanupStreamHandler(trailer.cleanup); err != nil {
- return false, err
- }
- } else {
- l.activeStreams.enqueue(str)
- }
- return false, nil
- }
-
+ isEmpty := len(dataItem.h) == 0 && reader.Remaining() == 0
// Figure out the maximum size we can send
maxSize := http2MaxFrameLen
- if strQuota := int(l.oiws) - str.bytesOutStanding; strQuota <= 0 { // stream-level flow control.
+ strQuota := int(l.oiws) - str.bytesOutStanding
+ if strQuota <= 0 && !isEmpty { // stream-level flow control.
str.state = waitingOnStreamQuota
return false, nil
- } else if maxSize > strQuota {
- maxSize = strQuota
- }
- if maxSize > int(l.sendQuota) { // connection-level flow control.
- maxSize = int(l.sendQuota)
}
+ maxSize = min(maxSize, max(strQuota, 0))
+ maxSize = min(maxSize, int(l.sendQuota)) // connection-level flow control.
// Compute how much of the header and data we can send within quota and max frame length
hSize := min(maxSize, len(dataItem.h))
dSize := min(maxSize-hSize, reader.Remaining())
@@ -1039,19 +1012,23 @@ func (l *loopyWriter) processData() (bool, error) {
reader.Close()
str.itl.dequeue()
}
+ return false, l.updateStreamAfterWrite(str)
+}
+
+func (l *loopyWriter) updateStreamAfterWrite(str *outStream) error {
if str.itl.isEmpty() {
str.state = empty
- } else if trailer, ok := str.itl.peek().(*headerFrame); ok { // The next item is trailers.
+ } else if trailer, ok := str.itl.peek().(*serverHeaders); ok { // the next item is trailers.
if err := l.writeHeader(trailer.streamID, trailer.endStream, trailer.hf, trailer.onWrite); err != nil {
- return false, err
+ return err
}
if err := l.cleanupStreamHandler(trailer.cleanup); err != nil {
- return false, err
+ return err
}
} else if int(l.oiws)-str.bytesOutStanding <= 0 { // Ran out of stream quota.
str.state = waitingOnStreamQuota
} else { // Otherwise add it back to the list of active streams.
l.activeStreams.enqueue(str)
}
- return false, nil
+ return nil
}
diff --git a/vendor/google.golang.org/grpc/internal/transport/defaults.go b/vendor/google.golang.org/grpc/internal/transport/defaults.go
index bc8ee0747..0b2269a50 100644
--- a/vendor/google.golang.org/grpc/internal/transport/defaults.go
+++ b/vendor/google.golang.org/grpc/internal/transport/defaults.go
@@ -46,6 +46,7 @@ const (
defaultWriteQuota = 64 * 1024
defaultClientMaxHeaderListSize = uint32(16 << 20)
defaultServerMaxHeaderListSize = uint32(16 << 20)
+ upcomingDefaultHeaderListSize = uint32(8 << 10)
)
// MaxStreamID is the upper bound for the stream ID before the current
diff --git a/vendor/google.golang.org/grpc/internal/transport/flowcontrol.go b/vendor/google.golang.org/grpc/internal/transport/flowcontrol.go
index 7cfbc9637..98cef9ec2 100644
--- a/vendor/google.golang.org/grpc/internal/transport/flowcontrol.go
+++ b/vendor/google.golang.org/grpc/internal/transport/flowcontrol.go
@@ -115,7 +115,6 @@ func (f *trInFlow) getSize() uint32 {
return atomic.LoadUint32(&f.effectiveWindowSize)
}
-// TODO(mmukhi): Simplify this code.
// inFlow deals with inbound flow control
type inFlow struct {
mu sync.Mutex
@@ -174,14 +173,14 @@ func (f *inFlow) maybeAdjust(n uint32) uint32 {
// onData is invoked when some data frame is received. It updates pendingData.
func (f *inFlow) onData(n uint32) error {
f.mu.Lock()
+ defer f.mu.Unlock()
+
f.pendingData += n
if f.pendingData+f.pendingUpdate > f.limit+f.delta {
limit := f.limit
rcvd := f.pendingData + f.pendingUpdate
- f.mu.Unlock()
return fmt.Errorf("received %d-bytes data exceeding the limit %d bytes", rcvd, limit)
}
- f.mu.Unlock()
return nil
}
@@ -189,8 +188,9 @@ func (f *inFlow) onData(n uint32) error {
// to be sent to the peer.
func (f *inFlow) onRead(n uint32) uint32 {
f.mu.Lock()
+ defer f.mu.Unlock()
+
if f.pendingData == 0 {
- f.mu.Unlock()
return 0
}
f.pendingData -= n
@@ -205,9 +205,7 @@ func (f *inFlow) onRead(n uint32) uint32 {
if f.pendingUpdate >= f.limit/4 {
wu := f.pendingUpdate
f.pendingUpdate = 0
- f.mu.Unlock()
return wu
}
- f.mu.Unlock()
return 0
}
diff --git a/vendor/google.golang.org/grpc/internal/transport/handler_server.go b/vendor/google.golang.org/grpc/internal/transport/handler_server.go
index 7ab3422b8..a8356c9ad 100644
--- a/vendor/google.golang.org/grpc/internal/transport/handler_server.go
+++ b/vendor/google.golang.org/grpc/internal/transport/handler_server.go
@@ -479,8 +479,8 @@ func (ht *serverHandlerTransport) runStream() {
func (ht *serverHandlerTransport) incrMsgRecv() {}
-func (ht *serverHandlerTransport) Drain(string) {
- panic("Drain() is not implemented")
+func (ht *serverHandlerTransport) Drain(s string) {
+ ht.Close(errors.New(s))
}
// mapRecvMsgError returns the non-nil err into the appropriate
diff --git a/vendor/google.golang.org/grpc/internal/transport/http2_client.go b/vendor/google.golang.org/grpc/internal/transport/http2_client.go
index 37b1acc34..822c09ba6 100644
--- a/vendor/google.golang.org/grpc/internal/transport/http2_client.go
+++ b/vendor/google.golang.org/grpc/internal/transport/http2_client.go
@@ -39,6 +39,7 @@ import (
"google.golang.org/grpc/internal"
"google.golang.org/grpc/internal/channelz"
icredentials "google.golang.org/grpc/internal/credentials"
+ "google.golang.org/grpc/internal/envconfig"
"google.golang.org/grpc/internal/grpclog"
"google.golang.org/grpc/internal/grpcsync"
"google.golang.org/grpc/internal/grpcutil"
@@ -134,6 +135,8 @@ type http2Client struct {
// goAwayDebugMessage contains a detailed human readable string about a
// GoAway frame, useful for error messages.
goAwayDebugMessage string
+ // goAwayCode records the http2.ErrCode received with the GoAway frame.
+ goAwayCode http2.ErrCode
// A condition variable used to signal when the keepalive goroutine should
// go dormant. The condition for dormancy is based on the number of active
// streams and the `PermitWithoutStream` keepalive client parameter. And
@@ -147,7 +150,7 @@ type http2Client struct {
channelz *channelz.Socket
- onClose func(GoAwayReason)
+ onClose OnCloseFunc
bufferPool mem.BufferPool
@@ -204,7 +207,7 @@ func isTemporary(err error) bool {
// NewHTTP2Client constructs a connected ClientTransport to addr based on HTTP2
// and starts to receive messages on it. Non-nil error returns if construction
// fails.
-func NewHTTP2Client(connectCtx, ctx context.Context, addr resolver.Address, opts ConnectOptions, onClose func(GoAwayReason)) (_ ClientTransport, err error) {
+func NewHTTP2Client(connectCtx, ctx context.Context, addr resolver.Address, opts ConnectOptions, onClose OnCloseFunc) (_ ClientTransport, err error) {
scheme := "http"
ctx, cancel := context.WithCancel(ctx)
defer func() {
@@ -316,7 +319,13 @@ func NewHTTP2Client(connectCtx, ctx context.Context, addr resolver.Address, opts
}
writeBufSize := opts.WriteBufferSize
readBufSize := opts.ReadBufferSize
+ // The default header list size is moving from 16MB to 8KB. The 8KB limit
+ // is only used if Enable8KBDefaultHeaderListSize is true; otherwise, the
+ // old 16MB default is used. User-specified options always take precedence.
maxHeaderListSize := defaultClientMaxHeaderListSize
+ if envconfig.Enable8KBDefaultHeaderListSize {
+ maxHeaderListSize = upcomingDefaultHeaderListSize
+ }
if opts.MaxHeaderListSize != nil {
maxHeaderListSize = *opts.MaxHeaderListSize
}
@@ -797,9 +806,8 @@ func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr, handler s
close(s.headerChan)
}
}
- hdr := &headerFrame{
- hf: headerFields,
- endStream: false,
+ hdr := &clientHeaders{
+ hf: headerFields,
initStream: func(uint32) error {
t.mu.Lock()
// TODO: handle transport closure in loopy instead and remove this
@@ -871,11 +879,15 @@ func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr, handler s
}
var sz int64
for _, f := range hdr.hf {
- if sz += int64(f.Size()); sz > int64(*t.maxSendHeaderListSize) {
+ sz += int64(f.Size())
+ if sz > int64(*t.maxSendHeaderListSize) {
hdrListSizeErr = status.Errorf(codes.Internal, "header list size to send violates the maximum size (%d bytes) set by server", *t.maxSendHeaderListSize)
return false
}
}
+ if !envconfig.Enable8KBDefaultHeaderListSize && sz > int64(upcomingDefaultHeaderListSize) {
+ t.logger.Warningf("Header list size to send (%d bytes) is larger than the upcoming default limit (%d bytes). In release v1.82.0, GRPC_GO_EXPERIMENTAL_ENABLE_8KB_DEFAULT_HEADER_LIST_SIZE will be enabled by default, enforcing this limit.", sz, upcomingDefaultHeaderListSize)
+ }
return true
}
for {
@@ -1011,7 +1023,7 @@ func (t *http2Client) Close(err error) {
// Call t.onClose ASAP to prevent the client from attempting to create new
// streams.
if t.state != draining {
- t.onClose(GoAwayInvalid)
+ t.onClose(GoAwayInfo{Reason: GoAwayInvalid, GoAwayCode: http2.ErrCodeNo, Err: err})
}
t.state = closing
streams := t.activeStreams
@@ -1082,7 +1094,7 @@ func (t *http2Client) GracefulClose() {
if t.logger.V(logLevel) {
t.logger.Infof("GracefulClose called")
}
- t.onClose(GoAwayInvalid)
+ t.onClose(GoAwayInfo{Reason: GoAwayInvalid, GoAwayCode: http2.ErrCodeNo})
t.state = draining
active := len(t.activeStreams)
t.mu.Unlock()
@@ -1218,10 +1230,30 @@ func (t *http2Client) handleData(f *parsedDataFrame) {
t.closeStream(s, io.EOF, true, http2.ErrCodeFlowControl, status.New(codes.Internal, err.Error()), nil, false)
return
}
+
+ if s.nonGRPCStatus != nil {
+ // The frame should be handled as a non-gRPC response body
+ st := s.handleNonGRPCData(f)
+ if st != nil {
+ t.closeStream(s, st.Err(), true, http2.ErrCodeProtocol, st, nil, true)
+ return
+ }
+ if w := s.fc.onRead(size); w > 0 {
+ t.controlBuf.put(&outgoingWindowUpdate{
+ streamID: s.id,
+ increment: w,
+ })
+ }
+ return
+ }
+
dataLen := f.data.Len()
if f.Header().Flags.Has(http2.FlagDataPadded) {
if w := s.fc.onRead(size - uint32(dataLen)); w > 0 {
- t.controlBuf.put(&outgoingWindowUpdate{s.id, w})
+ t.controlBuf.put(&outgoingWindowUpdate{
+ streamID: s.id,
+ increment: w,
+ })
}
}
if dataLen > 0 {
@@ -1232,7 +1264,10 @@ func (t *http2Client) handleData(f *parsedDataFrame) {
// The server has closed the stream without sending trailers. Record that
// the read direction is closed, and set the status appropriately.
if f.StreamEnded() {
- t.closeStream(s, io.EOF, false, http2.ErrCodeNo, status.New(codes.Internal, "server closed the stream without sending trailers"), nil, true)
+ // If client received END_STREAM from server while stream was still
+ // active, send RST_STREAM.
+ rstStream := s.getState() == streamActive
+ t.closeStream(s, io.EOF, rstStream, http2.ErrCodeNo, status.New(codes.Internal, "server closed the stream without sending trailers"), nil, true)
}
}
@@ -1368,7 +1403,7 @@ func (t *http2Client) handleGoAway(f *http2.GoAwayFrame) error {
// draining, to allow the client to stop attempting to create streams
// before disallowing new streams on this connection.
if t.state != draining {
- t.onClose(t.goAwayReason)
+ t.onClose(GoAwayInfo{Reason: t.goAwayReason, GoAwayCode: t.goAwayCode})
t.state = draining
}
}
@@ -1418,6 +1453,7 @@ func (t *http2Client) setGoAwayReason(f *http2.GoAwayFrame) {
} else {
t.goAwayDebugMessage = fmt.Sprintf("code: %s, debug data: %q", f.ErrCode, string(f.DebugData()))
}
+ t.goAwayCode = f.ErrCode
}
func (t *http2Client) GetGoAwayReason() (GoAwayReason, string) {
@@ -1458,6 +1494,17 @@ func (t *http2Client) operateHeaders(frame *http2.MetaHeadersFrame) {
return
}
+ // If we are collecting non-gRPC response data and receive a trailing
+ // HEADERS frame with END_STREAM, finalize the buffered data and close
+ // the stream.
+ if s.nonGRPCStatus != nil {
+ if endStream {
+ st := s.finalizeNonGRPCStatus()
+ t.closeStream(s, st.Err(), true, http2.ErrCodeProtocol, st, nil, true)
+ }
+ return
+ }
+
var (
// If a gRPC Response-Headers has already been received, then it means
// that the peer is speaking gRPC and we are in gRPC mode.
@@ -1558,7 +1605,12 @@ func (t *http2Client) operateHeaders(frame *http2.MetaHeadersFrame) {
}
se := status.New(grpcErrorCode, strings.Join(errs, "; "))
- t.closeStream(s, se.Err(), true, http2.ErrCodeProtocol, se, nil, endStream)
+ if endStream {
+ t.closeStream(s, se.Err(), true, http2.ErrCodeProtocol, se, nil, true)
+ return
+ }
+
+ s.startNonGRPCDataCollection(se)
return
}
@@ -1829,7 +1881,7 @@ func (t *http2Client) getOutFlowWindow() int64 {
resp := make(chan uint32, 1)
timer := time.NewTimer(time.Second)
defer timer.Stop()
- t.controlBuf.put(&outFlowControlSizeRequest{resp})
+ t.controlBuf.put(&outFlowControlSizeRequest{resp: resp})
select {
case sz := <-resp:
return int64(sz)
diff --git a/vendor/google.golang.org/grpc/internal/transport/http2_server.go b/vendor/google.golang.org/grpc/internal/transport/http2_server.go
index a1a14e14f..be8ae9f9c 100644
--- a/vendor/google.golang.org/grpc/internal/transport/http2_server.go
+++ b/vendor/google.golang.org/grpc/internal/transport/http2_server.go
@@ -38,11 +38,13 @@ import (
"google.golang.org/protobuf/proto"
"google.golang.org/grpc/internal"
+ "google.golang.org/grpc/internal/envconfig"
"google.golang.org/grpc/internal/grpclog"
"google.golang.org/grpc/internal/grpcutil"
"google.golang.org/grpc/internal/pretty"
istatus "google.golang.org/grpc/internal/status"
"google.golang.org/grpc/internal/syscall"
+ transportinternal "google.golang.org/grpc/internal/transport/internal"
"google.golang.org/grpc/mem"
"google.golang.org/grpc/codes"
@@ -165,7 +167,13 @@ func NewServerTransport(conn net.Conn, config *ServerConfig) (_ ServerTransport,
}
writeBufSize := config.WriteBufferSize
readBufSize := config.ReadBufferSize
+ // The default header list size is moving from 16MB to 8KB. The 8KB limit
+ // is only used if Enable8KBDefaultHeaderListSize is true; otherwise, the
+ // old 16MB default is used. User-specified options always take precedence.
maxHeaderListSize := defaultServerMaxHeaderListSize
+ if envconfig.Enable8KBDefaultHeaderListSize {
+ maxHeaderListSize = upcomingDefaultHeaderListSize
+ }
if config.MaxHeaderListSize != nil {
maxHeaderListSize = *config.MaxHeaderListSize
}
@@ -802,7 +810,10 @@ func (t *http2Server) handleData(f *parsedDataFrame) {
dataLen := f.data.Len()
if f.Header().Flags.Has(http2.FlagDataPadded) {
if w := s.fc.onRead(size - uint32(dataLen)); w > 0 {
- t.controlBuf.put(&outgoingWindowUpdate{s.id, w})
+ t.controlBuf.put(&outgoingWindowUpdate{
+ streamID: s.id,
+ increment: w,
+ })
}
}
if dataLen > 0 {
@@ -940,13 +951,17 @@ func (t *http2Server) checkForHeaderListSize(hf []hpack.HeaderField) bool {
}
var sz int64
for _, f := range hf {
- if sz += int64(f.Size()); sz > int64(*t.maxSendHeaderListSize) {
+ sz += int64(f.Size())
+ if sz > int64(*t.maxSendHeaderListSize) {
if t.logger.V(logLevel) {
t.logger.Infof("Header list size to send violates the maximum size (%d bytes) set by client", *t.maxSendHeaderListSize)
}
return false
}
}
+ if !envconfig.Enable8KBDefaultHeaderListSize && sz > int64(upcomingDefaultHeaderListSize) {
+ t.logger.Warningf("Header list size to send (%d bytes) is larger than the upcoming default limit (%d bytes). In release v1.82.0, GRPC_GO_EXPERIMENTAL_ENABLE_8KB_DEFAULT_HEADER_LIST_SIZE will be enabled by default, enforcing this limit.", sz, upcomingDefaultHeaderListSize)
+ }
return true
}
@@ -1035,7 +1050,7 @@ func (t *http2Server) writeHeaderLocked(s *ServerStream) error {
headerFields = append(headerFields, hpack.HeaderField{Name: "grpc-encoding", Value: s.sendCompress})
}
headerFields = appendHeaderFieldsFromMD(headerFields, s.header)
- hf := &headerFrame{
+ hf := &serverHeaders{
streamID: s.id,
hf: headerFields,
endStream: false,
@@ -1103,7 +1118,7 @@ func (t *http2Server) writeStatus(s *ServerStream, st *status.Status) error {
// Attach the trailer metadata.
headerFields = appendHeaderFieldsFromMD(headerFields, s.trailer)
- trailingHeader := &headerFrame{
+ trailingHeader := &serverHeaders{
streamID: s.id,
hf: headerFields,
endStream: true,
@@ -1313,7 +1328,7 @@ func (t *http2Server) deleteStream(s *ServerStream, eosReceived bool) {
}
// finishStream closes the stream and puts the trailing headerFrame into controlbuf.
-func (t *http2Server) finishStream(s *ServerStream, rst bool, rstCode http2.ErrCode, hdr *headerFrame, eosReceived bool) {
+func (t *http2Server) finishStream(s *ServerStream, rst bool, rstCode http2.ErrCode, hdr *serverHeaders, eosReceived bool) {
// In case stream sending and receiving are invoked in separate
// goroutines (e.g., bi-directional streaming), cancel needs to be
// called to interrupt the potential blocking on other goroutines.
@@ -1437,14 +1452,14 @@ func (t *http2Server) socketMetrics() *channelz.EphemeralSocketMetrics {
func (t *http2Server) incrMsgSent() {
if channelz.IsOn() {
t.channelz.SocketMetrics.MessagesSent.Add(1)
- t.channelz.SocketMetrics.LastMessageSentTimestamp.Add(1)
+ t.channelz.SocketMetrics.LastMessageSentTimestamp.Store(transportinternal.TimeNowFunc())
}
}
func (t *http2Server) incrMsgRecv() {
if channelz.IsOn() {
t.channelz.SocketMetrics.MessagesReceived.Add(1)
- t.channelz.SocketMetrics.LastMessageReceivedTimestamp.Add(1)
+ t.channelz.SocketMetrics.LastMessageReceivedTimestamp.Store(transportinternal.TimeNowFunc())
}
}
@@ -1452,7 +1467,7 @@ func (t *http2Server) getOutFlowWindow() int64 {
resp := make(chan uint32, 1)
timer := time.NewTimer(time.Second)
defer timer.Stop()
- t.controlBuf.put(&outFlowControlSizeRequest{resp})
+ t.controlBuf.put(&outFlowControlSizeRequest{resp: resp})
select {
case sz := <-resp:
return int64(sz)
diff --git a/vendor/google.golang.org/grpc/internal/transport/http_util.go b/vendor/google.golang.org/grpc/internal/transport/http_util.go
index 5bbb641ad..c34975ffe 100644
--- a/vendor/google.golang.org/grpc/internal/transport/http_util.go
+++ b/vendor/google.golang.org/grpc/internal/transport/http_util.go
@@ -36,6 +36,9 @@ import (
"golang.org/x/net/http2"
"golang.org/x/net/http2/hpack"
"google.golang.org/grpc/codes"
+ "google.golang.org/grpc/internal/envconfig"
+ imem "google.golang.org/grpc/internal/mem"
+ "google.golang.org/grpc/internal/transport/readyreader"
"google.golang.org/grpc/mem"
)
@@ -296,7 +299,7 @@ func decodeGrpcMessageUnchecked(msg string) string {
}
type bufWriter struct {
- pool *sync.Pool
+ pool *imem.SimpleBufferPool
buf []byte
offset int
batchSize int
@@ -304,7 +307,7 @@ type bufWriter struct {
err error
}
-func newBufWriter(conn io.Writer, batchSize int, pool *sync.Pool) *bufWriter {
+func newBufWriter(conn io.Writer, batchSize int, pool *imem.SimpleBufferPool) *bufWriter {
w := &bufWriter{
batchSize: batchSize,
conn: conn,
@@ -326,7 +329,7 @@ func (w *bufWriter) Write(b []byte) (int, error) {
return n, toIOError(err)
}
if w.buf == nil {
- b := w.pool.Get().(*[]byte)
+ b := w.pool.Get(w.batchSize)
w.buf = *b
}
written := 0
@@ -407,22 +410,32 @@ type framer struct {
errDetail error
}
-var writeBufferPoolMap = make(map[int]*sync.Pool)
-var writeBufferMutex sync.Mutex
+var ioBufferPoolMap = make(map[int]*imem.SimpleBufferPool)
+var ioBufferMutex sync.Mutex
+
+func bufferedReader(r io.Reader, bufSize int) io.Reader {
+ if bufSize <= 0 {
+ return r
+ }
+ if envconfig.EnableHTTPFramerReadBufferPooling {
+ if rr := readyreader.NewNonBlocking(r); rr != nil {
+ readPool := ioBufferPool(bufSize)
+ return readyreader.NewBuffered(rr, bufSize, readPool)
+ }
+ }
+ return bufio.NewReaderSize(r, bufSize)
+}
func newFramer(conn io.ReadWriter, writeBufferSize, readBufferSize int, sharedWriteBuffer bool, maxHeaderListSize uint32, memPool mem.BufferPool) *framer {
if writeBufferSize < 0 {
writeBufferSize = 0
}
- var r io.Reader = conn
- if readBufferSize > 0 {
- r = bufio.NewReaderSize(r, readBufferSize)
- }
- var pool *sync.Pool
+ r := bufferedReader(conn, readBufferSize)
+ var writePool *imem.SimpleBufferPool
if sharedWriteBuffer {
- pool = getWriteBufferPool(writeBufferSize)
+ writePool = ioBufferPool(writeBufferSize)
}
- w := newBufWriter(conn, writeBufferSize, pool)
+ w := newBufWriter(conn, writeBufferSize, writePool)
f := &framer{
writer: w,
fr: http2.NewFramer(w, r),
@@ -578,20 +591,15 @@ func (df *parsedDataFrame) Header() http2.FrameHeader {
return df.FrameHeader
}
-func getWriteBufferPool(size int) *sync.Pool {
- writeBufferMutex.Lock()
- defer writeBufferMutex.Unlock()
- pool, ok := writeBufferPoolMap[size]
+func ioBufferPool(size int) *imem.SimpleBufferPool {
+ ioBufferMutex.Lock()
+ defer ioBufferMutex.Unlock()
+ pool, ok := ioBufferPoolMap[size]
if ok {
return pool
}
- pool = &sync.Pool{
- New: func() any {
- b := make([]byte, size)
- return &b
- },
- }
- writeBufferPoolMap[size] = pool
+ pool = imem.NewDirtySimplePool()
+ ioBufferPoolMap[size] = pool
return pool
}
diff --git a/vendor/google.golang.org/grpc/internal/transport/internal/internal.go b/vendor/google.golang.org/grpc/internal/transport/internal/internal.go
new file mode 100644
index 000000000..a7c7c7d5a
--- /dev/null
+++ b/vendor/google.golang.org/grpc/internal/transport/internal/internal.go
@@ -0,0 +1,25 @@
+/*
+ *
+ * Copyright 2026 gRPC authors.
+ *
+ * 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 internal contains functionality internal to the transport package.
+package internal
+
+// TimeNowFunc is a variable that can be set to override the default behavior of
+// getting the current time in nanoseconds. It is used in transport code to set
+// channelz timestamps, and is exposed here for testing purposes.
+var TimeNowFunc func() int64
diff --git a/vendor/google.golang.org/grpc/internal/transport/readyreader/raw_conn_linux.go b/vendor/google.golang.org/grpc/internal/transport/readyreader/raw_conn_linux.go
new file mode 100644
index 000000000..56906c35b
--- /dev/null
+++ b/vendor/google.golang.org/grpc/internal/transport/readyreader/raw_conn_linux.go
@@ -0,0 +1,39 @@
+/*
+ *
+ * Copyright 2026 gRPC authors.
+ *
+ * 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 readyreader
+
+import "syscall"
+
+func isRawConnSupported() bool {
+ return true
+}
+
+// sysRead uses the standard syscall package rather than the modern unix package
+// to avoid triggering the race detector. Because both packages perform sync
+// operations on a local variable to satisfy the race detector, mixing them
+// for read and write syscalls causes data races. We use syscall here to remain
+// consistent with net.Conn implementations in standard library.
+func sysRead(fd uintptr, p []byte) (int, error) {
+ return syscall.Read(int(fd), p)
+}
+
+// wouldBlock checks standard Unix non-blocking errors.
+func wouldBlock(err error) bool {
+ return err == syscall.EAGAIN || err == syscall.EWOULDBLOCK
+}
diff --git a/vendor/google.golang.org/grpc/internal/transport/readyreader/raw_conn_nonlinux.go b/vendor/google.golang.org/grpc/internal/transport/readyreader/raw_conn_nonlinux.go
new file mode 100644
index 000000000..4d1f33006
--- /dev/null
+++ b/vendor/google.golang.org/grpc/internal/transport/readyreader/raw_conn_nonlinux.go
@@ -0,0 +1,35 @@
+//go:build !linux
+
+/*
+ *
+ * Copyright 2026 gRPC authors.
+ *
+ * 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 readyreader
+
+func isRawConnSupported() bool {
+ return false
+}
+
+// sysRead is not implemented. Support can be added in the future if necessary.
+func sysRead(uintptr, []byte) (int, error) {
+ panic("RawConn functionality is not implemented for non-unix platforms.")
+}
+
+// wouldBlock is not implemented. Support can be added in the future if necessary.
+func wouldBlock(error) bool {
+ panic("RawConn functionality is not implemented for non-unix platforms.")
+}
diff --git a/vendor/google.golang.org/grpc/internal/transport/readyreader/ready_reader.go b/vendor/google.golang.org/grpc/internal/transport/readyreader/ready_reader.go
new file mode 100644
index 000000000..250a300c7
--- /dev/null
+++ b/vendor/google.golang.org/grpc/internal/transport/readyreader/ready_reader.go
@@ -0,0 +1,253 @@
+/*
+ *
+ * Copyright 2026 gRPC authors.
+ *
+ * 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 readyreader provides utilities to perform non-memory-pinning reads.
+package readyreader
+
+import (
+ "io"
+ "net"
+ "syscall"
+
+ "google.golang.org/grpc/mem"
+)
+
+// Reader is an optional interface that can be implemented by [net.Conn]
+// implementations to enable gRPC to perform non-memory-pinning reads.
+type Reader interface {
+ // ReadOnReady waits for data to arrive, fetches a buffer, and performs a
+ // read. When the underlying IO is readable, it allocates a buffer of size
+ // bufSize from the pool and reads up to bufSize bytes into the buffer.
+ //
+ // It returns a pointer to the buffer so it can be returned to the pool
+ // later, the number of bytes read, and an error.
+ //
+ // Callers should always process the n > 0 bytes returned before considering
+ // the error. Doing so correctly handles I/O errors that happen after
+ // reading some bytes, as well as both of the allowed EOF behaviors.
+ ReadOnReady(bufSize int, pool mem.BufferPool) (b *[]byte, n int, err error)
+}
+
+// nonBlockingReader is optimized for non-memory-pinning reads using the RawConn
+// interface.
+type nonBlockingReader struct {
+ raw syscall.RawConn
+ // The following fields are stored as field to avoid heap allocations.
+ state readState
+ doRead func(fd uintptr) bool
+}
+
+type readState struct {
+ // Request params.
+ bufSize int
+ pool mem.BufferPool
+
+ // Response params.
+ readError error
+ bytesRead int
+ buf *[]byte
+}
+
+// NewNonBlocking returns a ReadyReader if the passed reader supports
+// non-memory-pinning reads, else nil.
+func NewNonBlocking(r io.Reader) Reader {
+ if rr, ok := r.(Reader); ok {
+ return rr
+ }
+ if !isRawConnSupported() {
+ return nil
+ }
+ // We restrict the types before asserting syscall.Conn. The credentials
+ // package may return a wrapper that implements syscall.Conn by embedding
+ // both the raw connection and the encrypted connection. If the code
+ // attempts to read directly from the raw syscall.RawConn, it would read
+ // encrypted data.
+ switch r.(type) {
+ case *net.TCPConn, *net.UDPConn, *net.UnixConn, *net.IPConn:
+ default:
+ return nil
+ }
+ sysConn, ok := r.(syscall.Conn)
+ if !ok {
+ return nil
+ }
+ raw, err := sysConn.SyscallConn()
+ if err != nil {
+ return nil
+ }
+ rr := &nonBlockingReader{raw: raw}
+ rr.doRead = func(fd uintptr) bool {
+ s := &rr.state
+
+ s.buf = s.pool.Get(s.bufSize)
+ s.bytesRead, s.readError = sysRead(fd, *s.buf)
+
+ if s.readError != nil {
+ s.pool.Put(s.buf)
+ s.buf = nil
+ }
+ return !wouldBlock(s.readError)
+ }
+ return rr
+}
+
+func (c *nonBlockingReader) ReadOnReady(bufSize int, pool mem.BufferPool) (*[]byte, int, error) {
+ c.state = readState{
+ pool: pool,
+ bufSize: bufSize,
+ }
+ err := c.raw.Read(c.doRead)
+
+ buf := c.state.buf
+ n := c.state.bytesRead
+ readErr := c.state.readError
+ c.state = readState{}
+
+ if err != nil {
+ if buf != nil {
+ pool.Put(buf)
+ }
+ return nil, 0, err
+ }
+ if readErr != nil {
+ // buffer is already released in the callback.
+ return nil, 0, readErr
+ }
+ if n == 0 {
+ // syscall.Read doesn't consider a graceful socket closure to be an
+ // error condition, but Go's io.Reader expects an EOF error.
+ pool.Put(buf)
+ return nil, 0, io.EOF
+ }
+ return buf, n, nil
+}
+
+type blockingReader struct {
+ reader io.Reader
+}
+
+func (c *blockingReader) ReadOnReady(bufSize int, pool mem.BufferPool) (*[]byte, int, error) {
+ buf := pool.Get(bufSize)
+ n, err := c.reader.Read(*buf)
+ if err != nil {
+ pool.Put(buf)
+ return nil, 0, err
+ }
+ return buf, n, nil
+}
+
+// New detects if [syscall.RawConn] is available for non-memory-pinning reads.
+// If [syscall.RawConn] is unavailable, it falls back to using the simpler
+// [io.Reader] interface for reads.
+func New(r io.Reader) Reader {
+ if r := NewNonBlocking(r); r != nil {
+ return r
+ }
+ return &blockingReader{reader: r}
+}
+
+// bufReadyReader implements buffering for a ReadyReader object.
+// A new bufReadyReader is created by calling [NewBuffered].
+type bufReadyReader struct {
+ buf *[]byte
+ pool mem.BufferPool
+ bufSize int
+ rd Reader // reader provided by the caller
+ r, w int // buf read and write positions
+ err error
+ constPool constBufferPool // stored as a field to avoid heap allocations.
+}
+
+// NewBuffered returns a new [io.Reader] with a buffer of the specified size
+// which is allocated from the provided pool.
+func NewBuffered(rd Reader, size int, pool mem.BufferPool) io.Reader {
+ return &bufReadyReader{
+ rd: rd,
+ pool: pool,
+ bufSize: size,
+ }
+}
+
+func (b *bufReadyReader) readErr() error {
+ err := b.err
+ b.err = nil
+ return err
+}
+
+func (b *bufReadyReader) buffered() int { return b.w - b.r }
+
+// Read reads data into p. It returns the number of bytes read into p. The
+// bytes are taken from at most one Read on the underlying [ReadyReader],
+// hence n may be less than len(p). If the underlying [ReadyReader] can return
+// a non-zero count with io.EOF, then this Read method can do so as well; see
+// the [io.Reader] docs.
+func (b *bufReadyReader) Read(p []byte) (n int, err error) {
+ n = len(p)
+ if n == 0 {
+ if b.buffered() > 0 {
+ return 0, nil
+ }
+ return 0, b.readErr()
+ }
+ if b.r == b.w {
+ if b.err != nil {
+ return 0, b.readErr()
+ }
+ if len(p) >= b.bufSize {
+ // Large read, empty buffer.
+ // Read directly into p to avoid copy.
+ b.constPool.buffer = p
+ _, n, b.err = b.rd.ReadOnReady(len(p), &b.constPool)
+ return n, b.readErr()
+ }
+ // One read.
+ b.r = 0
+ b.w = 0
+ b.buf, n, b.err = b.rd.ReadOnReady(b.bufSize, b.pool)
+ if n == 0 {
+ if b.buf != nil {
+ b.pool.Put(b.buf)
+ b.buf = nil
+ }
+ return 0, b.readErr()
+ }
+ b.w += n
+ }
+
+ // copy as much as we can
+ // b.buf must be non-nil since b.r != b.w.
+ buf := *b.buf
+ n = copy(p, buf[b.r:b.w])
+ b.r += n
+ if b.r == b.w {
+ // Consumed entire buffer, release it.
+ b.pool.Put(b.buf)
+ b.buf = nil
+ }
+ return n, nil
+}
+
+type constBufferPool struct {
+ buffer []byte
+}
+
+func (p *constBufferPool) Get(int) *[]byte {
+ return &p.buffer
+}
+
+func (p *constBufferPool) Put(*[]byte) {}
diff --git a/vendor/google.golang.org/grpc/internal/transport/transport.go b/vendor/google.golang.org/grpc/internal/transport/transport.go
index b86094da9..6dfae3984 100644
--- a/vendor/google.golang.org/grpc/internal/transport/transport.go
+++ b/vendor/google.golang.org/grpc/internal/transport/transport.go
@@ -31,9 +31,11 @@ import (
"sync/atomic"
"time"
+ "golang.org/x/net/http2"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/credentials"
"google.golang.org/grpc/internal/channelz"
+ "google.golang.org/grpc/internal/transport/internal"
"google.golang.org/grpc/keepalive"
"google.golang.org/grpc/mem"
"google.golang.org/grpc/metadata"
@@ -45,6 +47,10 @@ import (
const logLevel = 2
+func init() {
+ internal.TimeNowFunc = func() int64 { return time.Now().UnixNano() }
+}
+
// recvMsg represents the received msg from the transport. All transport
// protocol specific info has been removed.
type recvMsg struct {
@@ -742,6 +748,22 @@ const (
GoAwayTooManyPings GoAwayReason = 2
)
+// GoAwayInfo contains metadata about why a connection was closed.
+type GoAwayInfo struct {
+ // Reason is the parsed reason for an HTTP/2 GOAWAY frame.
+ Reason GoAwayReason
+ // GoAwayCode is the raw HTTP/2 error code received in a GOAWAY frame.
+ GoAwayCode http2.ErrCode
+ // Err is the underlying error that caused the connection to close. It is
+ // populated if the connection was closed due to a socket error or context
+ // cancellation without receiving a GOAWAY frame. If the connection was
+ // closed due to a GOAWAY frame, this field will be nil.
+ Err error
+}
+
+// OnCloseFunc is a callback invoked when a ClientTransport closes.
+type OnCloseFunc func(GoAwayInfo)
+
// ContextErr converts the error from context package into a status error.
func ContextErr(err error) error {
switch err {
diff --git a/vendor/google.golang.org/grpc/mem/buffer_pool.go b/vendor/google.golang.org/grpc/mem/buffer_pool.go
index 2ea763a49..3b02b9091 100644
--- a/vendor/google.golang.org/grpc/mem/buffer_pool.go
+++ b/vendor/google.golang.org/grpc/mem/buffer_pool.go
@@ -19,10 +19,10 @@
package mem
import (
- "sort"
- "sync"
+ "fmt"
"google.golang.org/grpc/internal"
+ "google.golang.org/grpc/internal/mem"
)
// BufferPool is a pool of buffers that can be shared and reused, resulting in
@@ -38,20 +38,23 @@ type BufferPool interface {
Put(*[]byte)
}
-const goPageSize = 4 << 10 // 4KiB. N.B. this must be a power of 2.
-
-var defaultBufferPoolSizes = []int{
- 256,
- goPageSize,
- 16 << 10, // 16KB (max HTTP/2 frame size used by gRPC)
- 32 << 10, // 32KB (default buffer size for io.Copy)
- 1 << 20, // 1MB
-}
-
-var defaultBufferPool BufferPool
+var (
+ defaultBufferPoolSizeExponents = []uint8{
+ 8,
+ 12, // Go page size, 4KB
+ 14, // 16KB (max HTTP/2 frame size used by gRPC)
+ 15, // 32KB (default buffer size for io.Copy)
+ 20, // 1MB
+ }
+ defaultBufferPool BufferPool
+)
func init() {
- defaultBufferPool = NewTieredBufferPool(defaultBufferPoolSizes...)
+ var err error
+ defaultBufferPool, err = NewBinaryTieredBufferPool(defaultBufferPoolSizeExponents...)
+ if err != nil {
+ panic(fmt.Sprintf("Failed to create default buffer pool: %v", err))
+ }
internal.SetDefaultBufferPool = func(pool BufferPool) {
defaultBufferPool = pool
@@ -72,134 +75,22 @@ func DefaultBufferPool() BufferPool {
// NewTieredBufferPool returns a BufferPool implementation that uses multiple
// underlying pools of the given pool sizes.
func NewTieredBufferPool(poolSizes ...int) BufferPool {
- sort.Ints(poolSizes)
- pools := make([]*sizedBufferPool, len(poolSizes))
- for i, s := range poolSizes {
- pools[i] = newSizedBufferPool(s)
- }
- return &tieredBufferPool{
- sizedPools: pools,
- }
-}
-
-// tieredBufferPool implements the BufferPool interface with multiple tiers of
-// buffer pools for different sizes of buffers.
-type tieredBufferPool struct {
- sizedPools []*sizedBufferPool
- fallbackPool simpleBufferPool
-}
-
-func (p *tieredBufferPool) Get(size int) *[]byte {
- return p.getPool(size).Get(size)
+ return mem.NewTieredBufferPool(poolSizes...)
}
-func (p *tieredBufferPool) Put(buf *[]byte) {
- p.getPool(cap(*buf)).Put(buf)
+// NewBinaryTieredBufferPool returns a BufferPool backed by multiple sub-pools.
+// This structure enables O(1) lookup time for Get and Put operations.
+//
+// The arguments provided are the exponents for the buffer capacities (powers
+// of 2), not the raw byte sizes. For example, to create a pool of 16KB buffers
+// (2^14 bytes), pass 14 as the argument.
+func NewBinaryTieredBufferPool(powerOfTwoExponents ...uint8) (BufferPool, error) {
+ return mem.NewBinaryTieredBufferPool(powerOfTwoExponents...)
}
-func (p *tieredBufferPool) getPool(size int) BufferPool {
- poolIdx := sort.Search(len(p.sizedPools), func(i int) bool {
- return p.sizedPools[i].defaultSize >= size
- })
-
- if poolIdx == len(p.sizedPools) {
- return &p.fallbackPool
- }
-
- return p.sizedPools[poolIdx]
-}
-
-// sizedBufferPool is a BufferPool implementation that is optimized for specific
-// buffer sizes. For example, HTTP/2 frames within gRPC have a default max size
-// of 16kb and a sizedBufferPool can be configured to only return buffers with a
-// capacity of 16kb. Note that however it does not support returning larger
-// buffers and in fact panics if such a buffer is requested. Because of this,
-// this BufferPool implementation is not meant to be used on its own and rather
-// is intended to be embedded in a tieredBufferPool such that Get is only
-// invoked when the required size is smaller than or equal to defaultSize.
-type sizedBufferPool struct {
- pool sync.Pool
- defaultSize int
-}
-
-func (p *sizedBufferPool) Get(size int) *[]byte {
- buf, ok := p.pool.Get().(*[]byte)
- if !ok {
- buf := make([]byte, size, p.defaultSize)
- return &buf
- }
- b := *buf
- clear(b[:cap(b)])
- *buf = b[:size]
- return buf
-}
-
-func (p *sizedBufferPool) Put(buf *[]byte) {
- if cap(*buf) < p.defaultSize {
- // Ignore buffers that are too small to fit in the pool. Otherwise, when
- // Get is called it will panic as it tries to index outside the bounds
- // of the buffer.
- return
- }
- p.pool.Put(buf)
-}
-
-func newSizedBufferPool(size int) *sizedBufferPool {
- return &sizedBufferPool{
- defaultSize: size,
- }
-}
-
-var _ BufferPool = (*simpleBufferPool)(nil)
-
-// simpleBufferPool is an implementation of the BufferPool interface that
-// attempts to pool buffers with a sync.Pool. When Get is invoked, it tries to
-// acquire a buffer from the pool but if that buffer is too small, it returns it
-// to the pool and creates a new one.
-type simpleBufferPool struct {
- pool sync.Pool
-}
-
-func (p *simpleBufferPool) Get(size int) *[]byte {
- bs, ok := p.pool.Get().(*[]byte)
- if ok && cap(*bs) >= size {
- clear((*bs)[:cap(*bs)])
- *bs = (*bs)[:size]
- return bs
- }
-
- // A buffer was pulled from the pool, but it is too small. Put it back in
- // the pool and create one large enough.
- if ok {
- p.pool.Put(bs)
- }
-
- // If we're going to allocate, round up to the nearest page. This way if
- // requests frequently arrive with small variation we don't allocate
- // repeatedly if we get unlucky and they increase over time. By default we
- // only allocate here if size > 1MiB. Because goPageSize is a power of 2, we
- // can round up efficiently.
- allocSize := (size + goPageSize - 1) & ^(goPageSize - 1)
-
- b := make([]byte, size, allocSize)
- return &b
-}
-
-func (p *simpleBufferPool) Put(buf *[]byte) {
- p.pool.Put(buf)
-}
-
-var _ BufferPool = NopBufferPool{}
-
// NopBufferPool is a buffer pool that returns new buffers without pooling.
-type NopBufferPool struct{}
-
-// Get returns a buffer with specified length from the pool.
-func (NopBufferPool) Get(length int) *[]byte {
- b := make([]byte, length)
- return &b
+type NopBufferPool struct {
+ mem.NopBufferPool
}
-// Put returns a buffer to the pool.
-func (NopBufferPool) Put(*[]byte) {
-}
+var _ BufferPool = NopBufferPool{}
diff --git a/vendor/google.golang.org/grpc/mem/buffer_slice.go b/vendor/google.golang.org/grpc/mem/buffer_slice.go
index 084fb19c6..086e9f95d 100644
--- a/vendor/google.golang.org/grpc/mem/buffer_slice.go
+++ b/vendor/google.golang.org/grpc/mem/buffer_slice.go
@@ -165,7 +165,7 @@ func (r *Reader) Close() error {
}
func (r *Reader) freeFirstBufferIfEmpty() bool {
- if len(r.data) == 0 || r.bufferIdx != len(r.data[0].ReadOnlyData()) {
+ if len(r.data) == 0 || r.bufferIdx != r.data[0].Len() {
return false
}
diff --git a/vendor/google.golang.org/grpc/mem/buffers.go b/vendor/google.golang.org/grpc/mem/buffers.go
index db1620e6a..2b410b16e 100644
--- a/vendor/google.golang.org/grpc/mem/buffers.go
+++ b/vendor/google.golang.org/grpc/mem/buffers.go
@@ -53,6 +53,10 @@ type Buffer interface {
Free()
// Len returns the Buffer's size.
Len() int
+ // Slice returns a new Buffer that is a view into this buffer's data
+ // from [start:end). The buffer is not modified. Panics if the buffer
+ // has been freed or if start/end are out of bounds.
+ Slice(start, end int) Buffer
split(n int) (left, right Buffer)
read(buf []byte) (int, Buffer)
@@ -180,6 +184,32 @@ func (b *buffer) Len() int {
return len(b.ReadOnlyData())
}
+func (b *buffer) Slice(start, end int) Buffer {
+ if b.rootBuf == nil {
+ panic("Cannot slice freed buffer")
+ }
+
+ data := b.data[start:end] // access the data to check slice bounds
+
+ if len(data) == 0 {
+ return emptyBuffer{}
+ }
+ if len(data) == len(b.data) {
+ b.Ref()
+ return b
+ }
+ // We are creating a new reference (view) to a portion of the root buffer's
+ // data. Therefore, we must increment the reference count of the root buffer
+ // to ensure the underlying data is not freed while this view is still in
+ // use.
+ b.rootBuf.Ref()
+ s := newBuffer()
+ s.data = data
+ s.rootBuf = b.rootBuf
+ s.refs.Store(1)
+ return s
+}
+
func (b *buffer) split(n int) (Buffer, Buffer) {
if b.rootBuf == nil || b.rootBuf.refs.Add(1) <= 1 {
panic("Cannot split freed buffer")
@@ -240,6 +270,13 @@ func (e emptyBuffer) Len() int {
return 0
}
+func (e emptyBuffer) Slice(start, end int) Buffer {
+ if start != 0 || end != 0 {
+ panic(fmt.Sprintf("slice bounds out of range [%d:%d] with length 0", start, end))
+ }
+ return e
+}
+
func (e emptyBuffer) split(int) (left, right Buffer) {
return e, e
}
@@ -264,6 +301,9 @@ func (s SliceBuffer) Free() {}
// Len is a noop implementation of Len.
func (s SliceBuffer) Len() int { return len(s) }
+// Slice returns a new SliceBuffer that is a view into the receiver from [start:end).
+func (s SliceBuffer) Slice(start, end int) Buffer { return s[start:end] }
+
func (s SliceBuffer) split(n int) (left, right Buffer) {
return s[:n], s[n:]
}
diff --git a/vendor/google.golang.org/grpc/picker_wrapper.go b/vendor/google.golang.org/grpc/picker_wrapper.go
index aa52bfe95..0183ab22f 100644
--- a/vendor/google.golang.org/grpc/picker_wrapper.go
+++ b/vendor/google.golang.org/grpc/picker_wrapper.go
@@ -192,7 +192,9 @@ func (pw *pickerWrapper) pick(ctx context.Context, failfast bool, info balancer.
// DoneInfo with default value works.
pickResult.Done(balancer.DoneInfo{})
}
- logger.Infof("blockingPicker: the picked transport is not ready, loop back to repick")
+ if logger.V(2) {
+ logger.Infof("blockingPicker: the picked transport is not ready, loop back to repick")
+ }
// If ok == false, ac.state is not READY.
// A valid picker always returns READY subConn. This means the state of ac
// just changed, and picker will be updated shortly.
diff --git a/vendor/google.golang.org/grpc/resolver/map.go b/vendor/google.golang.org/grpc/resolver/map.go
index c3c15ac96..789a5abab 100644
--- a/vendor/google.golang.org/grpc/resolver/map.go
+++ b/vendor/google.golang.org/grpc/resolver/map.go
@@ -20,6 +20,7 @@ package resolver
import (
"encoding/base64"
+ "iter"
"sort"
"strings"
)
@@ -135,6 +136,7 @@ func (a *AddressMapV2[T]) Len() int {
}
// Keys returns a slice of all current map keys.
+// Deprecated: Use AddressMapV2.All() instead.
func (a *AddressMapV2[T]) Keys() []Address {
ret := make([]Address, 0, a.Len())
for _, entryList := range a.m {
@@ -146,6 +148,7 @@ func (a *AddressMapV2[T]) Keys() []Address {
}
// Values returns a slice of all current map values.
+// Deprecated: Use AddressMapV2.All() instead.
func (a *AddressMapV2[T]) Values() []T {
ret := make([]T, 0, a.Len())
for _, entryList := range a.m {
@@ -156,6 +159,19 @@ func (a *AddressMapV2[T]) Values() []T {
return ret
}
+// All returns an iterator over all elements.
+func (a *AddressMapV2[T]) All() iter.Seq2[Address, T] {
+ return func(yield func(Address, T) bool) {
+ for _, entryList := range a.m {
+ for _, entry := range entryList {
+ if !yield(entry.addr, entry.value) {
+ return
+ }
+ }
+ }
+ }
+}
+
type endpointMapKey string
// EndpointMap is a map of endpoints to arbitrary values keyed on only the
@@ -223,6 +239,7 @@ func (em *EndpointMap[T]) Len() int {
// the unordered set of addresses. Thus, endpoint information returned is not
// the full endpoint data (drops duplicated addresses and attributes) but can be
// used for EndpointMap accesses.
+// Deprecated: Use EndpointMap.All() instead.
func (em *EndpointMap[T]) Keys() []Endpoint {
ret := make([]Endpoint, 0, len(em.endpoints))
for _, en := range em.endpoints {
@@ -232,6 +249,7 @@ func (em *EndpointMap[T]) Keys() []Endpoint {
}
// Values returns a slice of all current map values.
+// Deprecated: Use EndpointMap.All() instead.
func (em *EndpointMap[T]) Values() []T {
ret := make([]T, 0, len(em.endpoints))
for _, val := range em.endpoints {
@@ -240,6 +258,22 @@ func (em *EndpointMap[T]) Values() []T {
return ret
}
+// All returns an iterator over all elements.
+// The map keys are endpoints specifying the addresses present in the endpoint
+// map, in which uniqueness is determined by the unordered set of addresses.
+// Thus, endpoint information returned is not the full endpoint data (drops
+// duplicated addresses and attributes) but can be used for EndpointMap
+// accesses.
+func (em *EndpointMap[T]) All() iter.Seq2[Endpoint, T] {
+ return func(yield func(Endpoint, T) bool) {
+ for _, en := range em.endpoints {
+ if !yield(en.decodedKey, en.value) {
+ return
+ }
+ }
+ }
+}
+
// Delete removes the specified endpoint from the map.
func (em *EndpointMap[T]) Delete(e Endpoint) {
en := encodeEndpoint(e)
diff --git a/vendor/google.golang.org/grpc/rpc_util.go b/vendor/google.golang.org/grpc/rpc_util.go
index 8160f9430..52f4ea513 100644
--- a/vendor/google.golang.org/grpc/rpc_util.go
+++ b/vendor/google.golang.org/grpc/rpc_util.go
@@ -128,6 +128,16 @@ func NewGZIPDecompressor() Decompressor {
}
func (d *gzipDecompressor) Do(r io.Reader) ([]byte, error) {
+ return d.doWithMaxSize(r, math.MaxInt64)
+}
+
+// doWithMaxSize behaves like Do but caps the size of the decompressed
+// payload at maxMessageSize+1 bytes. The Decompressor interface does not
+// allow extra parameters, so callers inside the package type-assert to
+// *gzipDecompressor to invoke this method directly. The +1 byte makes it
+// possible for the caller to detect that the limit was exceeded and
+// return ResourceExhausted instead of materializing an unbounded payload.
+func (d *gzipDecompressor) doWithMaxSize(r io.Reader, maxMessageSize int64) ([]byte, error) {
var z *gzip.Reader
switch maybeZ := d.pool.Get().(type) {
case nil:
@@ -148,7 +158,11 @@ func (d *gzipDecompressor) Do(r io.Reader) ([]byte, error) {
z.Close()
d.pool.Put(z)
}()
- return io.ReadAll(z)
+ var src io.Reader = z
+ if maxMessageSize < math.MaxInt64 {
+ src = io.LimitReader(z, maxMessageSize+1)
+ }
+ return io.ReadAll(src)
}
func (d *gzipDecompressor) Type() string {
@@ -830,15 +844,15 @@ func compress(in mem.BufferSlice, cp Compressor, compressor encoding.Compressor,
if compressor != nil {
z, err := compressor.Compress(w)
if err != nil {
- return nil, 0, wrapErr(err)
+ return nil, compressionNone, wrapErr(err)
}
for _, b := range in {
if _, err := z.Write(b.ReadOnlyData()); err != nil {
- return nil, 0, wrapErr(err)
+ return nil, compressionNone, wrapErr(err)
}
}
if err := z.Close(); err != nil {
- return nil, 0, wrapErr(err)
+ return nil, compressionNone, wrapErr(err)
}
} else {
// This is obviously really inefficient since it fully materializes the data, but
@@ -848,7 +862,7 @@ func compress(in mem.BufferSlice, cp Compressor, compressor encoding.Compressor,
buf := in.MaterializeToBuffer(pool)
defer buf.Free()
if err := cp.Do(w, buf.ReadOnlyData()); err != nil {
- return nil, 0, wrapErr(err)
+ return nil, compressionNone, wrapErr(err)
}
}
return out, compressionMade, nil
@@ -961,26 +975,50 @@ func recvAndDecompress(p *parser, s recvCompressor, dc Decompressor, maxReceiveM
return out, nil
}
-// decompress processes the given data by decompressing it using either a custom decompressor or a standard compressor.
-// If a custom decompressor is provided, it takes precedence. The function validates that the decompressed data
-// does not exceed the specified maximum size and returns an error if this limit is exceeded.
-// On success, it returns the decompressed data. Otherwise, it returns an error if decompression fails or the data exceeds the size limit.
+// decompress processes the given data by decompressing it using either
+// a custom decompressor or a standard compressor. If a custom decompressor
+// is provided, it takes precedence. The function validates that
+// the decompressed data does not exceed the specified maximum size and returns
+// an error if this limit is exceeded. On success, it returns the decompressed
+// data. Otherwise, it returns an error if decompression fails or the data
+// exceeds the size limit.
func decompress(compressor encoding.Compressor, d mem.BufferSlice, dc Decompressor, maxReceiveMessageSize int, pool mem.BufferPool) (mem.BufferSlice, error) {
if dc != nil {
- uncompressed, err := dc.Do(d.Reader())
+ r := d.Reader()
+ // For the built-in gzip decompressor, bound the decompressed output
+ // at maxReceiveMessageSize+1 so that a small but highly compressed
+ // payload (a "zip bomb") cannot expand to gigabytes in memory before
+ // the post-decompression size check below has a chance to fire. The
+ // Decompressor interface does not accept an extra size parameter,
+ // so we type-assert to invoke a size-aware helper. Third-party
+ // Decompressor implementations keep the original Do behavior.
+ var uncompressed []byte
+ var err error
+ if gd, ok := dc.(*gzipDecompressor); ok {
+ uncompressed, err = gd.doWithMaxSize(r, int64(maxReceiveMessageSize))
+ } else {
+ uncompressed, err = dc.Do(r)
+ }
if err != nil {
+ r.Close() // ensure buffers are reused
return nil, status.Errorf(codes.Internal, "grpc: failed to decompress the received message: %v", err)
}
if len(uncompressed) > maxReceiveMessageSize {
+ r.Close() // ensure buffers are reused
return nil, status.Errorf(codes.ResourceExhausted, "grpc: message after decompression larger than max (%d vs. %d)", len(uncompressed), maxReceiveMessageSize)
}
return mem.BufferSlice{mem.SliceBuffer(uncompressed)}, nil
}
if compressor != nil {
- dcReader, err := compressor.Decompress(d.Reader())
+ r := d.Reader()
+ dcReader, err := compressor.Decompress(r)
if err != nil {
+ r.Close() // ensure buffers are reused
return nil, status.Errorf(codes.Internal, "grpc: failed to decompress the message: %v", err)
}
+ if closer, ok := dcReader.(io.Closer); ok {
+ defer closer.Close()
+ }
// Read at most one byte more than the limit from the decompressor.
// Unless the limit is MaxInt64, in which case, that's impossible, so
@@ -990,11 +1028,13 @@ func decompress(compressor encoding.Compressor, d mem.BufferSlice, dc Decompress
}
out, err := mem.ReadAll(dcReader, pool)
if err != nil {
+ r.Close() // ensure buffers are reused
out.Free()
return nil, status.Errorf(codes.Internal, "grpc: failed to read decompressed data: %v", err)
}
if out.Len() > maxReceiveMessageSize {
+ r.Close() // ensure buffers are reused
out.Free()
return nil, status.Errorf(codes.ResourceExhausted, "grpc: received message after decompression larger than max %d", maxReceiveMessageSize)
}
diff --git a/vendor/google.golang.org/grpc/server.go b/vendor/google.golang.org/grpc/server.go
index 8efb29a7b..cf0a20671 100644
--- a/vendor/google.golang.org/grpc/server.go
+++ b/vendor/google.golang.org/grpc/server.go
@@ -28,6 +28,7 @@ import (
"net/http"
"reflect"
"runtime"
+ "runtime/pprof"
"strings"
"sync"
"sync/atomic"
@@ -150,8 +151,6 @@ type Server struct {
serverWorkerChannel chan func()
serverWorkerChannelClose func()
-
- strictPathCheckingLogEmitted atomic.Bool
}
type serverOptions struct {
@@ -192,6 +191,7 @@ var defaultServerOptions = serverOptions{
maxSendMessageSize: defaultServerMaxSendMessageSize,
connectionTimeout: 120 * time.Second,
writeBufferSize: defaultWriteBufSize,
+ sharedWriteBuffer: true,
readBufferSize: defaultReadBufSize,
bufferPool: mem.DefaultBufferPool(),
}
@@ -249,10 +249,8 @@ func newJoinServerOption(opts ...ServerOption) ServerOption {
// If this option is set to true every connection will release the buffer after
// flushing the data on the wire.
//
-// # Experimental
-//
-// Notice: This API is EXPERIMENTAL and may be changed or removed in a
-// later release.
+// Deprecated: shared write buffer is enabled by default. SharedWriteBuffer
+// will be removed in a future release.
func SharedWriteBuffer(val bool) ServerOption {
return newFuncServerOption(func(o *serverOptions) {
o.sharedWriteBuffer = val
@@ -301,6 +299,14 @@ func InitialConnWindowSize(s int32) ServerOption {
// window size to the value provided and disables dynamic flow control.
// The lower bound for window size is 64K and any value smaller than that
// will be ignored.
+//
+// Note that this also disables dynamic flow control for the connection,
+// falling back to a default static connection-level window of 64KB. To
+// use a larger connection-level window, you must also use the
+// [StaticConnWindowSize] ServerOption.
+//
+// Most users should not configure static flow control windows unless
+// operating in a memory-constrained environment.
func StaticStreamWindowSize(s int32) ServerOption {
return newFuncServerOption(func(o *serverOptions) {
o.initialWindowSize = s
@@ -312,6 +318,14 @@ func StaticStreamWindowSize(s int32) ServerOption {
// window size to the value provided and disables dynamic flow control.
// The lower bound for window size is 64K and any value smaller than that
// will be ignored.
+//
+// Note that this also disables dynamic flow control for individual streams,
+// falling back to a default static connection-level window of 64KB. To
+// explicitly configure the stream-level window size, you must also use the
+// [StaticStreamWindowSize] ServerOption.
+//
+// Most users should not configure static flow control windows unless
+// operating in a memory-constrained environment.
func StaticConnWindowSize(s int32) ServerOption {
return newFuncServerOption(func(o *serverOptions) {
o.initialConnWindowSize = s
@@ -1786,6 +1800,12 @@ func (s *Server) handleMalformedMethodName(stream *transport.ServerStream, ti *t
func (s *Server) handleStream(t transport.ServerTransport, stream *transport.ServerStream) {
ctx := stream.Context()
ctx = contextWithServer(ctx, s)
+ if envconfig.LabelServerGoroutines&envconfig.GoroutineLabelServerMethod != 0 {
+ // This method always runs in its own goroutine, so we can set a
+ // goroutine label without needing to restore a previous context.
+ ctx = pprof.WithLabels(ctx, pprof.Labels("grpc.method", stream.Method()))
+ pprof.SetGoroutineLabels(ctx)
+ }
var ti *traceInfo
if EnableTracing {
tr := newTrace("grpc.Recv."+methodFamily(stream.Method()), stream.Method())
@@ -1802,28 +1822,11 @@ func (s *Server) handleStream(t transport.ServerTransport, stream *transport.Ser
}
}
- sm := stream.Method()
- if sm == "" {
+ sm, found := strings.CutPrefix(stream.Method(), "/")
+ if !found {
s.handleMalformedMethodName(stream, ti)
return
}
- if sm[0] != '/' {
- // TODO(easwars): Add a link to the CVE in the below log messages once
- // published.
- if envconfig.DisableStrictPathChecking {
- if old := s.strictPathCheckingLogEmitted.Swap(true); !old {
- channelz.Warningf(logger, s.channelz, "grpc: Server.handleStream received malformed method name %q. Allowing it because the environment variable GRPC_GO_EXPERIMENTAL_DISABLE_STRICT_PATH_CHECKING is set to true, but this option will be removed in a future release.", sm)
- }
- } else {
- if old := s.strictPathCheckingLogEmitted.Swap(true); !old {
- channelz.Warningf(logger, s.channelz, "grpc: Server.handleStream rejected malformed method name %q. To temporarily allow such requests, set the environment variable GRPC_GO_EXPERIMENTAL_DISABLE_STRICT_PATH_CHECKING to true. Note that this is not recommended as it may allow requests to bypass security policies.", sm)
- }
- s.handleMalformedMethodName(stream, ti)
- return
- }
- } else {
- sm = sm[1:]
- }
pos := strings.LastIndex(sm, "/")
if pos == -1 {
s.handleMalformedMethodName(stream, ti)
diff --git a/vendor/google.golang.org/grpc/stream.go b/vendor/google.golang.org/grpc/stream.go
index eedb5f9b9..4aac644a8 100644
--- a/vendor/google.golang.org/grpc/stream.go
+++ b/vendor/google.golang.org/grpc/stream.go
@@ -21,6 +21,7 @@ package grpc
import (
"context"
"errors"
+ "fmt"
"io"
"math"
rand "math/rand/v2"
@@ -749,7 +750,7 @@ func (a *csAttempt) shouldRetry(err error) (bool, error) {
return false, err
}
if cs.numRetries+1 >= rp.MaxAttempts {
- return false, err
+ return false, fmt.Errorf("max retries exhausted: failed after %d attempts: %w", cs.numRetries+1, err)
}
var dur time.Duration
diff --git a/vendor/google.golang.org/grpc/version.go b/vendor/google.golang.org/grpc/version.go
index 76c2eed77..53c737fee 100644
--- a/vendor/google.golang.org/grpc/version.go
+++ b/vendor/google.golang.org/grpc/version.go
@@ -19,4 +19,4 @@
package grpc
// Version is the current grpc version.
-const Version = "1.79.3"
+const Version = "1.82.1"
diff --git a/vendor/google.golang.org/protobuf/internal/editiondefaults/editions_defaults.binpb b/vendor/google.golang.org/protobuf/internal/editiondefaults/editions_defaults.binpb
index 04696351e..ad35ea4c4 100644
Binary files a/vendor/google.golang.org/protobuf/internal/editiondefaults/editions_defaults.binpb and b/vendor/google.golang.org/protobuf/internal/editiondefaults/editions_defaults.binpb differ
diff --git a/vendor/google.golang.org/protobuf/internal/encoding/defval/default.go b/vendor/google.golang.org/protobuf/internal/encoding/defval/default.go
index 328dc733b..079a53dd1 100644
--- a/vendor/google.golang.org/protobuf/internal/encoding/defval/default.go
+++ b/vendor/google.golang.org/protobuf/internal/encoding/defval/default.go
@@ -69,19 +69,19 @@ func Unmarshal(s string, k protoreflect.Kind, evs protoreflect.EnumValueDescript
}
}
case protoreflect.Int32Kind, protoreflect.Sint32Kind, protoreflect.Sfixed32Kind:
- if v, err := strconv.ParseInt(s, 10, 32); err == nil {
+ if v, err := strconv.ParseInt(s, 0, 32); err == nil {
return protoreflect.ValueOfInt32(int32(v)), nil, nil
}
case protoreflect.Int64Kind, protoreflect.Sint64Kind, protoreflect.Sfixed64Kind:
- if v, err := strconv.ParseInt(s, 10, 64); err == nil {
+ if v, err := strconv.ParseInt(s, 0, 64); err == nil {
return protoreflect.ValueOfInt64(int64(v)), nil, nil
}
case protoreflect.Uint32Kind, protoreflect.Fixed32Kind:
- if v, err := strconv.ParseUint(s, 10, 32); err == nil {
+ if v, err := strconv.ParseUint(s, 0, 32); err == nil {
return protoreflect.ValueOfUint32(uint32(v)), nil, nil
}
case protoreflect.Uint64Kind, protoreflect.Fixed64Kind:
- if v, err := strconv.ParseUint(s, 10, 64); err == nil {
+ if v, err := strconv.ParseUint(s, 0, 64); err == nil {
return protoreflect.ValueOfUint64(uint64(v)), nil, nil
}
case protoreflect.FloatKind, protoreflect.DoubleKind:
diff --git a/vendor/google.golang.org/protobuf/internal/genid/descriptor_gen.go b/vendor/google.golang.org/protobuf/internal/genid/descriptor_gen.go
index 65aaf4d21..58aeff845 100644
--- a/vendor/google.golang.org/protobuf/internal/genid/descriptor_gen.go
+++ b/vendor/google.golang.org/protobuf/internal/genid/descriptor_gen.go
@@ -26,6 +26,7 @@ const (
Edition_EDITION_PROTO3_enum_value = 999
Edition_EDITION_2023_enum_value = 1000
Edition_EDITION_2024_enum_value = 1001
+ Edition_EDITION_2026_enum_value = 1002
Edition_EDITION_UNSTABLE_enum_value = 9999
Edition_EDITION_1_TEST_ONLY_enum_value = 1
Edition_EDITION_2_TEST_ONLY_enum_value = 2
@@ -806,11 +807,13 @@ const (
FieldOptions_FeatureSupport_EditionDeprecated_field_name protoreflect.Name = "edition_deprecated"
FieldOptions_FeatureSupport_DeprecationWarning_field_name protoreflect.Name = "deprecation_warning"
FieldOptions_FeatureSupport_EditionRemoved_field_name protoreflect.Name = "edition_removed"
+ FieldOptions_FeatureSupport_RemovalError_field_name protoreflect.Name = "removal_error"
FieldOptions_FeatureSupport_EditionIntroduced_field_fullname protoreflect.FullName = "google.protobuf.FieldOptions.FeatureSupport.edition_introduced"
FieldOptions_FeatureSupport_EditionDeprecated_field_fullname protoreflect.FullName = "google.protobuf.FieldOptions.FeatureSupport.edition_deprecated"
FieldOptions_FeatureSupport_DeprecationWarning_field_fullname protoreflect.FullName = "google.protobuf.FieldOptions.FeatureSupport.deprecation_warning"
FieldOptions_FeatureSupport_EditionRemoved_field_fullname protoreflect.FullName = "google.protobuf.FieldOptions.FeatureSupport.edition_removed"
+ FieldOptions_FeatureSupport_RemovalError_field_fullname protoreflect.FullName = "google.protobuf.FieldOptions.FeatureSupport.removal_error"
)
// Field numbers for google.protobuf.FieldOptions.FeatureSupport.
@@ -819,6 +822,7 @@ const (
FieldOptions_FeatureSupport_EditionDeprecated_field_number protoreflect.FieldNumber = 2
FieldOptions_FeatureSupport_DeprecationWarning_field_number protoreflect.FieldNumber = 3
FieldOptions_FeatureSupport_EditionRemoved_field_number protoreflect.FieldNumber = 4
+ FieldOptions_FeatureSupport_RemovalError_field_number protoreflect.FieldNumber = 5
)
// Names for google.protobuf.OneofOptions.
@@ -1152,6 +1156,7 @@ const (
FeatureSet_ENFORCE_NAMING_STYLE_UNKNOWN_enum_value = 0
FeatureSet_STYLE2024_enum_value = 1
FeatureSet_STYLE_LEGACY_enum_value = 2
+ FeatureSet_STYLE2026_enum_value = 3
)
// Names for google.protobuf.FeatureSet.VisibilityFeature.
diff --git a/vendor/google.golang.org/protobuf/internal/version/version.go b/vendor/google.golang.org/protobuf/internal/version/version.go
index bfb2cfdea..58ff0e246 100644
--- a/vendor/google.golang.org/protobuf/internal/version/version.go
+++ b/vendor/google.golang.org/protobuf/internal/version/version.go
@@ -52,8 +52,8 @@ import (
const (
Major = 1
Minor = 36
- Patch = 11
- PreRelease = "devel"
+ Patch = 12
+ PreRelease = ""
)
// String formats the version string for this module in semver format.
diff --git a/vendor/google.golang.org/protobuf/reflect/protoreflect/source_gen.go b/vendor/google.golang.org/protobuf/reflect/protoreflect/source_gen.go
index 730331e66..86f0d0926 100644
--- a/vendor/google.golang.org/protobuf/reflect/protoreflect/source_gen.go
+++ b/vendor/google.golang.org/protobuf/reflect/protoreflect/source_gen.go
@@ -546,6 +546,8 @@ func (p *SourcePath) appendFieldOptions_FeatureSupport(b []byte) []byte {
b = p.appendSingularField(b, "deprecation_warning", nil)
case 4:
b = p.appendSingularField(b, "edition_removed", nil)
+ case 5:
+ b = p.appendSingularField(b, "removal_error", nil)
}
return b
}
diff --git a/vendor/google.golang.org/protobuf/types/descriptorpb/descriptor.pb.go b/vendor/google.golang.org/protobuf/types/descriptorpb/descriptor.pb.go
index 0b23faa95..a51cb1e54 100644
--- a/vendor/google.golang.org/protobuf/types/descriptorpb/descriptor.pb.go
+++ b/vendor/google.golang.org/protobuf/types/descriptorpb/descriptor.pb.go
@@ -1,32 +1,9 @@
// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc. All rights reserved.
-// https://developers.google.com/protocol-buffers/
+// Copyright 2008 Google LLC. 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.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file or at
+// https://developers.google.com/open-source/licenses/bsd
// Author: kenton@google.com (Kenton Varda)
// Based on original Protocol Buffers design by
@@ -69,6 +46,7 @@ const (
// comparison.
Edition_EDITION_2023 Edition = 1000
Edition_EDITION_2024 Edition = 1001
+ Edition_EDITION_2026 Edition = 1002
// A placeholder edition for developing and testing unscheduled features.
Edition_EDITION_UNSTABLE Edition = 9999
// Placeholder editions for testing feature resolution. These should not be
@@ -93,6 +71,7 @@ var (
999: "EDITION_PROTO3",
1000: "EDITION_2023",
1001: "EDITION_2024",
+ 1002: "EDITION_2026",
9999: "EDITION_UNSTABLE",
1: "EDITION_1_TEST_ONLY",
2: "EDITION_2_TEST_ONLY",
@@ -108,6 +87,7 @@ var (
"EDITION_PROTO3": 999,
"EDITION_2023": 1000,
"EDITION_2024": 1001,
+ "EDITION_2026": 1002,
"EDITION_UNSTABLE": 9999,
"EDITION_1_TEST_ONLY": 1,
"EDITION_2_TEST_ONLY": 2,
@@ -1213,6 +1193,7 @@ const (
FeatureSet_ENFORCE_NAMING_STYLE_UNKNOWN FeatureSet_EnforceNamingStyle = 0
FeatureSet_STYLE2024 FeatureSet_EnforceNamingStyle = 1
FeatureSet_STYLE_LEGACY FeatureSet_EnforceNamingStyle = 2
+ FeatureSet_STYLE2026 FeatureSet_EnforceNamingStyle = 3
)
// Enum value maps for FeatureSet_EnforceNamingStyle.
@@ -1221,11 +1202,13 @@ var (
0: "ENFORCE_NAMING_STYLE_UNKNOWN",
1: "STYLE2024",
2: "STYLE_LEGACY",
+ 3: "STYLE2026",
}
FeatureSet_EnforceNamingStyle_value = map[string]int32{
"ENFORCE_NAMING_STYLE_UNKNOWN": 0,
"STYLE2024": 1,
"STYLE_LEGACY": 2,
+ "STYLE2026": 3,
}
)
@@ -4204,8 +4187,11 @@ type FieldOptions_FeatureSupport struct {
// this one, the last default assigned will be used, and proto files will
// not be able to override it.
EditionRemoved *Edition `protobuf:"varint,4,opt,name=edition_removed,json=editionRemoved,enum=google.protobuf.Edition" json:"edition_removed,omitempty"`
- unknownFields protoimpl.UnknownFields
- sizeCache protoimpl.SizeCache
+ // The removal error text if this feature is used after the edition it was
+ // removed in.
+ RemovalError *string `protobuf:"bytes,5,opt,name=removal_error,json=removalError" json:"removal_error,omitempty"`
+ unknownFields protoimpl.UnknownFields
+ sizeCache protoimpl.SizeCache
}
func (x *FieldOptions_FeatureSupport) Reset() {
@@ -4266,6 +4252,13 @@ func (x *FieldOptions_FeatureSupport) GetEditionRemoved() Edition {
return Edition_EDITION_UNKNOWN
}
+func (x *FieldOptions_FeatureSupport) GetRemovalError() string {
+ if x != nil && x.RemovalError != nil {
+ return *x.RemovalError
+ }
+ return ""
+}
+
// The name of the uninterpreted option. Each string represents a segment in
// a dot-separated name. is_extension is true iff a segment represents an
// extension (denoted with parentheses in options specs in .proto files).
@@ -4719,7 +4712,7 @@ const file_google_protobuf_descriptor_proto_rawDesc = "" +
"\aoptions\x18\x03 \x01(\v2&.google.protobuf.ExtensionRangeOptionsR\aoptions\x1a7\n" +
"\rReservedRange\x12\x14\n" +
"\x05start\x18\x01 \x01(\x05R\x05start\x12\x10\n" +
- "\x03end\x18\x02 \x01(\x05R\x03end\"\xcc\x04\n" +
+ "\x03end\x18\x02 \x01(\x05R\x03end\"\xd4\x04\n" +
"\x15ExtensionRangeOptions\x12X\n" +
"\x14uninterpreted_option\x18\xe7\a \x03(\v2$.google.protobuf.UninterpretedOptionR\x13uninterpretedOption\x12Y\n" +
"\vdeclaration\x18\x02 \x03(\v22.google.protobuf.ExtensionRangeOptions.DeclarationB\x03\x88\x01\x02R\vdeclaration\x127\n" +
@@ -4735,7 +4728,7 @@ const file_google_protobuf_descriptor_proto_rawDesc = "" +
"\x11VerificationState\x12\x0f\n" +
"\vDECLARATION\x10\x00\x12\x0e\n" +
"\n" +
- "UNVERIFIED\x10\x01*\t\b\xe8\a\x10\x80\x80\x80\x80\x02\"\xc1\x06\n" +
+ "UNVERIFIED\x10\x01*\x06\b\xde\a\x10\xe7\a*\t\b\xe8\a\x10\x80\x80\x80\x80\x02\"\xc1\x06\n" +
"\x14FieldDescriptorProto\x12\x12\n" +
"\x04name\x18\x01 \x01(\tR\x04name\x12\x16\n" +
"\x06number\x18\x03 \x01(\x05R\x06number\x12A\n" +
@@ -4810,12 +4803,13 @@ const file_google_protobuf_descriptor_proto_rawDesc = "" +
"outputType\x128\n" +
"\aoptions\x18\x04 \x01(\v2\x1e.google.protobuf.MethodOptionsR\aoptions\x120\n" +
"\x10client_streaming\x18\x05 \x01(\b:\x05falseR\x0fclientStreaming\x120\n" +
- "\x10server_streaming\x18\x06 \x01(\b:\x05falseR\x0fserverStreaming\"\xad\t\n" +
+ "\x10server_streaming\x18\x06 \x01(\b:\x05falseR\x0fserverStreaming\"\xfa\n" +
+ "\n" +
"\vFileOptions\x12!\n" +
"\fjava_package\x18\x01 \x01(\tR\vjavaPackage\x120\n" +
- "\x14java_outer_classname\x18\b \x01(\tR\x12javaOuterClassname\x125\n" +
+ "\x14java_outer_classname\x18\b \x01(\tR\x12javaOuterClassname\x12\xf9\x01\n" +
"\x13java_multiple_files\x18\n" +
- " \x01(\b:\x05falseR\x11javaMultipleFiles\x12D\n" +
+ " \x01(\b:\x05falseB\xc1\x01\xb2\x01\xbd\x01\b\xe6\a \xe9\a*\xb4\x01This behavior is enabled by default in editions 2024 and above. To disable it, you can set `features.(pb.java).nest_in_file_class = YES` on individual messages, enums, or services.R\x11javaMultipleFiles\x12D\n" +
"\x1djava_generate_equals_and_hash\x18\x14 \x01(\bB\x02\x18\x01R\x19javaGenerateEqualsAndHash\x12:\n" +
"\x16java_string_check_utf8\x18\x1b \x01(\b:\x05falseR\x13javaStringCheckUtf8\x12S\n" +
"\foptimize_for\x18\t \x01(\x0e2).google.protobuf.FileOptions.OptimizeMode:\x05SPEEDR\voptimizeFor\x12\x1d\n" +
@@ -4840,7 +4834,7 @@ const file_google_protobuf_descriptor_proto_rawDesc = "" +
"\fOptimizeMode\x12\t\n" +
"\x05SPEED\x10\x01\x12\r\n" +
"\tCODE_SIZE\x10\x02\x12\x10\n" +
- "\fLITE_RUNTIME\x10\x03*\t\b\xe8\a\x10\x80\x80\x80\x80\x02J\x04\b*\x10+J\x04\b&\x10'R\x14php_generic_services\"\xf4\x03\n" +
+ "\fLITE_RUNTIME\x10\x03*\x06\b\xde\a\x10\xe7\a*\t\b\xe8\a\x10\x80\x80\x80\x80\x02J\x04\b*\x10+J\x04\b&\x10'R\x14php_generic_services\"\xfc\x03\n" +
"\x0eMessageOptions\x12<\n" +
"\x17message_set_wire_format\x18\x01 \x01(\b:\x05falseR\x14messageSetWireFormat\x12L\n" +
"\x1fno_standard_descriptor_accessor\x18\x02 \x01(\b:\x05falseR\x1cnoStandardDescriptorAccessor\x12%\n" +
@@ -4850,8 +4844,8 @@ const file_google_protobuf_descriptor_proto_rawDesc = "" +
"\tmap_entry\x18\a \x01(\bR\bmapEntry\x12V\n" +
"&deprecated_legacy_json_field_conflicts\x18\v \x01(\bB\x02\x18\x01R\"deprecatedLegacyJsonFieldConflicts\x127\n" +
"\bfeatures\x18\f \x01(\v2\x1b.google.protobuf.FeatureSetR\bfeatures\x12X\n" +
- "\x14uninterpreted_option\x18\xe7\a \x03(\v2$.google.protobuf.UninterpretedOptionR\x13uninterpretedOption*\t\b\xe8\a\x10\x80\x80\x80\x80\x02J\x04\b\x04\x10\x05J\x04\b\x05\x10\x06J\x04\b\x06\x10\aJ\x04\b\b\x10\tJ\x04\b\t\x10\n" +
- "\"\xa1\r\n" +
+ "\x14uninterpreted_option\x18\xe7\a \x03(\v2$.google.protobuf.UninterpretedOptionR\x13uninterpretedOption*\x06\b\xde\a\x10\xe7\a*\t\b\xe8\a\x10\x80\x80\x80\x80\x02J\x04\b\x04\x10\x05J\x04\b\x05\x10\x06J\x04\b\x06\x10\aJ\x04\b\b\x10\tJ\x04\b\t\x10\n" +
+ "\"\xce\r\n" +
"\fFieldOptions\x12A\n" +
"\x05ctype\x18\x01 \x01(\x0e2#.google.protobuf.FieldOptions.CType:\x06STRINGR\x05ctype\x12\x16\n" +
"\x06packed\x18\x02 \x01(\bR\x06packed\x12G\n" +
@@ -4872,12 +4866,13 @@ const file_google_protobuf_descriptor_proto_rawDesc = "" +
"\x14uninterpreted_option\x18\xe7\a \x03(\v2$.google.protobuf.UninterpretedOptionR\x13uninterpretedOption\x1aZ\n" +
"\x0eEditionDefault\x122\n" +
"\aedition\x18\x03 \x01(\x0e2\x18.google.protobuf.EditionR\aedition\x12\x14\n" +
- "\x05value\x18\x02 \x01(\tR\x05value\x1a\x96\x02\n" +
+ "\x05value\x18\x02 \x01(\tR\x05value\x1a\xbb\x02\n" +
"\x0eFeatureSupport\x12G\n" +
"\x12edition_introduced\x18\x01 \x01(\x0e2\x18.google.protobuf.EditionR\x11editionIntroduced\x12G\n" +
"\x12edition_deprecated\x18\x02 \x01(\x0e2\x18.google.protobuf.EditionR\x11editionDeprecated\x12/\n" +
"\x13deprecation_warning\x18\x03 \x01(\tR\x12deprecationWarning\x12A\n" +
- "\x0fedition_removed\x18\x04 \x01(\x0e2\x18.google.protobuf.EditionR\x0eeditionRemoved\"/\n" +
+ "\x0fedition_removed\x18\x04 \x01(\x0e2\x18.google.protobuf.EditionR\x0eeditionRemoved\x12#\n" +
+ "\rremoval_error\x18\x05 \x01(\tR\fremovalError\"/\n" +
"\x05CType\x12\n" +
"\n" +
"\x06STRING\x10\x00\x12\b\n" +
@@ -4901,10 +4896,10 @@ const file_google_protobuf_descriptor_proto_rawDesc = "" +
"\x10TARGET_TYPE_ENUM\x10\x06\x12\x1a\n" +
"\x16TARGET_TYPE_ENUM_ENTRY\x10\a\x12\x17\n" +
"\x13TARGET_TYPE_SERVICE\x10\b\x12\x16\n" +
- "\x12TARGET_TYPE_METHOD\x10\t*\t\b\xe8\a\x10\x80\x80\x80\x80\x02J\x04\b\x04\x10\x05J\x04\b\x12\x10\x13\"\xac\x01\n" +
+ "\x12TARGET_TYPE_METHOD\x10\t*\x06\b\xde\a\x10\xe7\a*\t\b\xe8\a\x10\x80\x80\x80\x80\x02J\x04\b\x04\x10\x05J\x04\b\x12\x10\x13\"\xb4\x01\n" +
"\fOneofOptions\x127\n" +
"\bfeatures\x18\x01 \x01(\v2\x1b.google.protobuf.FeatureSetR\bfeatures\x12X\n" +
- "\x14uninterpreted_option\x18\xe7\a \x03(\v2$.google.protobuf.UninterpretedOptionR\x13uninterpretedOption*\t\b\xe8\a\x10\x80\x80\x80\x80\x02\"\xd1\x02\n" +
+ "\x14uninterpreted_option\x18\xe7\a \x03(\v2$.google.protobuf.UninterpretedOptionR\x13uninterpretedOption*\x06\b\xde\a\x10\xe7\a*\t\b\xe8\a\x10\x80\x80\x80\x80\x02\"\xd9\x02\n" +
"\vEnumOptions\x12\x1f\n" +
"\vallow_alias\x18\x02 \x01(\bR\n" +
"allowAlias\x12%\n" +
@@ -4913,7 +4908,7 @@ const file_google_protobuf_descriptor_proto_rawDesc = "" +
"deprecated\x12V\n" +
"&deprecated_legacy_json_field_conflicts\x18\x06 \x01(\bB\x02\x18\x01R\"deprecatedLegacyJsonFieldConflicts\x127\n" +
"\bfeatures\x18\a \x01(\v2\x1b.google.protobuf.FeatureSetR\bfeatures\x12X\n" +
- "\x14uninterpreted_option\x18\xe7\a \x03(\v2$.google.protobuf.UninterpretedOptionR\x13uninterpretedOption*\t\b\xe8\a\x10\x80\x80\x80\x80\x02J\x04\b\x05\x10\x06\"\xd8\x02\n" +
+ "\x14uninterpreted_option\x18\xe7\a \x03(\v2$.google.protobuf.UninterpretedOptionR\x13uninterpretedOption*\x06\b\xde\a\x10\xe7\a*\t\b\xe8\a\x10\x80\x80\x80\x80\x02J\x04\b\x05\x10\x06\"\xe0\x02\n" +
"\x10EnumValueOptions\x12%\n" +
"\n" +
"deprecated\x18\x01 \x01(\b:\x05falseR\n" +
@@ -4921,13 +4916,13 @@ const file_google_protobuf_descriptor_proto_rawDesc = "" +
"\bfeatures\x18\x02 \x01(\v2\x1b.google.protobuf.FeatureSetR\bfeatures\x12(\n" +
"\fdebug_redact\x18\x03 \x01(\b:\x05falseR\vdebugRedact\x12U\n" +
"\x0ffeature_support\x18\x04 \x01(\v2,.google.protobuf.FieldOptions.FeatureSupportR\x0efeatureSupport\x12X\n" +
- "\x14uninterpreted_option\x18\xe7\a \x03(\v2$.google.protobuf.UninterpretedOptionR\x13uninterpretedOption*\t\b\xe8\a\x10\x80\x80\x80\x80\x02\"\xd5\x01\n" +
+ "\x14uninterpreted_option\x18\xe7\a \x03(\v2$.google.protobuf.UninterpretedOptionR\x13uninterpretedOption*\x06\b\xde\a\x10\xe7\a*\t\b\xe8\a\x10\x80\x80\x80\x80\x02\"\xdd\x01\n" +
"\x0eServiceOptions\x127\n" +
"\bfeatures\x18\" \x01(\v2\x1b.google.protobuf.FeatureSetR\bfeatures\x12%\n" +
"\n" +
"deprecated\x18! \x01(\b:\x05falseR\n" +
"deprecated\x12X\n" +
- "\x14uninterpreted_option\x18\xe7\a \x03(\v2$.google.protobuf.UninterpretedOptionR\x13uninterpretedOption*\t\b\xe8\a\x10\x80\x80\x80\x80\x02\"\x99\x03\n" +
+ "\x14uninterpreted_option\x18\xe7\a \x03(\v2$.google.protobuf.UninterpretedOptionR\x13uninterpretedOption*\x06\b\xde\a\x10\xe7\a*\t\b\xe8\a\x10\x80\x80\x80\x80\x02\"\xa1\x03\n" +
"\rMethodOptions\x12%\n" +
"\n" +
"deprecated\x18! \x01(\b:\x05falseR\n" +
@@ -4939,7 +4934,7 @@ const file_google_protobuf_descriptor_proto_rawDesc = "" +
"\x13IDEMPOTENCY_UNKNOWN\x10\x00\x12\x13\n" +
"\x0fNO_SIDE_EFFECTS\x10\x01\x12\x0e\n" +
"\n" +
- "IDEMPOTENT\x10\x02*\t\b\xe8\a\x10\x80\x80\x80\x80\x02\"\x9a\x03\n" +
+ "IDEMPOTENT\x10\x02*\x06\b\xde\a\x10\xe7\a*\t\b\xe8\a\x10\x80\x80\x80\x80\x02\"\x9a\x03\n" +
"\x13UninterpretedOption\x12A\n" +
"\x04name\x18\x02 \x03(\v2-.google.protobuf.UninterpretedOption.NamePartR\x04name\x12)\n" +
"\x10identifier_value\x18\x03 \x01(\tR\x0fidentifierValue\x12,\n" +
@@ -4950,7 +4945,7 @@ const file_google_protobuf_descriptor_proto_rawDesc = "" +
"\x0faggregate_value\x18\b \x01(\tR\x0eaggregateValue\x1aJ\n" +
"\bNamePart\x12\x1b\n" +
"\tname_part\x18\x01 \x02(\tR\bnamePart\x12!\n" +
- "\fis_extension\x18\x02 \x02(\bR\visExtension\"\x8e\x0f\n" +
+ "\fis_extension\x18\x02 \x02(\bR\visExtension\"\xae\x0f\n" +
"\n" +
"FeatureSet\x12\x91\x01\n" +
"\x0efield_presence\x18\x01 \x01(\x0e2).google.protobuf.FeatureSet.FieldPresenceB?\x88\x01\x01\x98\x01\x04\x98\x01\x01\xa2\x01\r\x12\bEXPLICIT\x18\x84\a\xa2\x01\r\x12\bIMPLICIT\x18\xe7\a\xa2\x01\r\x12\bEXPLICIT\x18\xe8\a\xb2\x01\x03\b\xe8\aR\rfieldPresence\x12l\n" +
@@ -4960,8 +4955,8 @@ const file_google_protobuf_descriptor_proto_rawDesc = "" +
"\x10message_encoding\x18\x05 \x01(\x0e2+.google.protobuf.FeatureSet.MessageEncodingB&\x88\x01\x01\x98\x01\x04\x98\x01\x01\xa2\x01\x14\x12\x0fLENGTH_PREFIXED\x18\x84\a\xb2\x01\x03\b\xe8\aR\x0fmessageEncoding\x12\x82\x01\n" +
"\vjson_format\x18\x06 \x01(\x0e2&.google.protobuf.FeatureSet.JsonFormatB9\x88\x01\x01\x98\x01\x03\x98\x01\x06\x98\x01\x01\xa2\x01\x17\x12\x12LEGACY_BEST_EFFORT\x18\x84\a\xa2\x01\n" +
"\x12\x05ALLOW\x18\xe7\a\xb2\x01\x03\b\xe8\aR\n" +
- "jsonFormat\x12\xab\x01\n" +
- "\x14enforce_naming_style\x18\a \x01(\x0e2..google.protobuf.FeatureSet.EnforceNamingStyleBI\x88\x01\x02\x98\x01\x01\x98\x01\x02\x98\x01\x03\x98\x01\x04\x98\x01\x05\x98\x01\x06\x98\x01\a\x98\x01\b\x98\x01\t\xa2\x01\x11\x12\fSTYLE_LEGACY\x18\x84\a\xa2\x01\x0e\x12\tSTYLE2024\x18\xe9\a\xb2\x01\x03\b\xe9\aR\x12enforceNamingStyle\x12\xb9\x01\n" +
+ "jsonFormat\x12\xbc\x01\n" +
+ "\x14enforce_naming_style\x18\a \x01(\x0e2..google.protobuf.FeatureSet.EnforceNamingStyleBZ\x88\x01\x02\x98\x01\x01\x98\x01\x02\x98\x01\x03\x98\x01\x04\x98\x01\x05\x98\x01\x06\x98\x01\a\x98\x01\b\x98\x01\t\xa2\x01\x11\x12\fSTYLE_LEGACY\x18\x84\a\xa2\x01\x0e\x12\tSTYLE2024\x18\xe9\a\xa2\x01\x0e\x12\tSTYLE2026\x18\x8fN\xb2\x01\x03\b\xe9\aR\x12enforceNamingStyle\x12\xb9\x01\n" +
"\x19default_symbol_visibility\x18\b \x01(\x0e2E.google.protobuf.FeatureSet.VisibilityFeature.DefaultSymbolVisibilityB6\x88\x01\x02\x98\x01\x01\xa2\x01\x0f\x12\n" +
"EXPORT_ALL\x18\x84\a\xa2\x01\x15\x12\x10EXPORT_TOP_LEVEL\x18\xe9\a\xb2\x01\x03\b\xe9\aR\x17defaultSymbolVisibility\x1a\xa1\x01\n" +
"\x11VisibilityFeature\"\x81\x01\n" +
@@ -5001,11 +4996,12 @@ const file_google_protobuf_descriptor_proto_rawDesc = "" +
"JsonFormat\x12\x17\n" +
"\x13JSON_FORMAT_UNKNOWN\x10\x00\x12\t\n" +
"\x05ALLOW\x10\x01\x12\x16\n" +
- "\x12LEGACY_BEST_EFFORT\x10\x02\"W\n" +
+ "\x12LEGACY_BEST_EFFORT\x10\x02\"f\n" +
"\x12EnforceNamingStyle\x12 \n" +
"\x1cENFORCE_NAMING_STYLE_UNKNOWN\x10\x00\x12\r\n" +
"\tSTYLE2024\x10\x01\x12\x10\n" +
- "\fSTYLE_LEGACY\x10\x02*\x06\b\xe8\a\x10\x8bN*\x06\b\x8bN\x10\x90N*\x06\b\x90N\x10\x91NJ\x06\b\xe7\a\x10\xe8\a\"\xef\x03\n" +
+ "\fSTYLE_LEGACY\x10\x02\x12\r\n" +
+ "\tSTYLE2026\x10\x03*\x06\b\xe8\a\x10\x8bN*\x06\b\x8bN\x10\x90N*\x06\b\x90N\x10\x91NJ\x06\b\xe7\a\x10\xe8\a\"\xef\x03\n" +
"\x12FeatureSetDefaults\x12X\n" +
"\bdefaults\x18\x01 \x03(\v2<.google.protobuf.FeatureSetDefaults.FeatureSetEditionDefaultR\bdefaults\x12A\n" +
"\x0fminimum_edition\x18\x04 \x01(\x0e2\x18.google.protobuf.EditionR\x0eminimumEdition\x12A\n" +
@@ -5037,14 +5033,15 @@ const file_google_protobuf_descriptor_proto_rawDesc = "" +
"\bSemantic\x12\b\n" +
"\x04NONE\x10\x00\x12\a\n" +
"\x03SET\x10\x01\x12\t\n" +
- "\x05ALIAS\x10\x02*\xbe\x02\n" +
+ "\x05ALIAS\x10\x02*\xd1\x02\n" +
"\aEdition\x12\x13\n" +
"\x0fEDITION_UNKNOWN\x10\x00\x12\x13\n" +
"\x0eEDITION_LEGACY\x10\x84\a\x12\x13\n" +
"\x0eEDITION_PROTO2\x10\xe6\a\x12\x13\n" +
"\x0eEDITION_PROTO3\x10\xe7\a\x12\x11\n" +
"\fEDITION_2023\x10\xe8\a\x12\x11\n" +
- "\fEDITION_2024\x10\xe9\a\x12\x15\n" +
+ "\fEDITION_2024\x10\xe9\a\x12\x11\n" +
+ "\fEDITION_2026\x10\xea\a\x12\x15\n" +
"\x10EDITION_UNSTABLE\x10\x8fN\x12\x17\n" +
"\x13EDITION_1_TEST_ONLY\x10\x01\x12\x17\n" +
"\x13EDITION_2_TEST_ONLY\x10\x02\x12\x1d\n" +
diff --git a/vendor/google.golang.org/protobuf/types/known/anypb/any.pb.go b/vendor/google.golang.org/protobuf/types/known/anypb/any.pb.go
index 1ff0d1494..510894f2b 100644
--- a/vendor/google.golang.org/protobuf/types/known/anypb/any.pb.go
+++ b/vendor/google.golang.org/protobuf/types/known/anypb/any.pb.go
@@ -128,120 +128,66 @@ import (
// `Any` contains an arbitrary serialized protocol buffer message along with a
// URL that describes the type of the serialized message.
//
-// Protobuf library provides support to pack/unpack Any values in the form
-// of utility functions or additional generated methods of the Any type.
-//
-// Example 1: Pack and unpack a message in C++.
-//
-// Foo foo = ...;
-// Any any;
-// any.PackFrom(foo);
-// ...
-// if (any.UnpackTo(&foo)) {
-// ...
-// }
-//
-// Example 2: Pack and unpack a message in Java.
-//
-// Foo foo = ...;
-// Any any = Any.pack(foo);
-// ...
-// if (any.is(Foo.class)) {
-// foo = any.unpack(Foo.class);
-// }
-// // or ...
-// if (any.isSameTypeAs(Foo.getDefaultInstance())) {
-// foo = any.unpack(Foo.getDefaultInstance());
-// }
-//
-// Example 3: Pack and unpack a message in Python.
-//
-// foo = Foo(...)
-// any = Any()
-// any.Pack(foo)
-// ...
-// if any.Is(Foo.DESCRIPTOR):
-// any.Unpack(foo)
-// ...
-//
-// Example 4: Pack and unpack a message in Go
-//
-// foo := &pb.Foo{...}
-// any, err := anypb.New(foo)
-// if err != nil {
-// ...
-// }
-// ...
-// foo := &pb.Foo{}
-// if err := any.UnmarshalTo(foo); err != nil {
-// ...
-// }
-//
-// The pack methods provided by protobuf library will by default use
-// 'type.googleapis.com/full.type.name' as the type URL and the unpack
-// methods only use the fully qualified type name after the last '/'
-// in the type URL, for example "foo.bar.com/x/y.z" will yield type
-// name "y.z".
-//
-// JSON
-// ====
-// The JSON representation of an `Any` value uses the regular
-// representation of the deserialized, embedded message, with an
-// additional field `@type` which contains the type URL. Example:
-//
-// package google.profile;
-// message Person {
-// string first_name = 1;
-// string last_name = 2;
-// }
-//
-// {
-// "@type": "type.googleapis.com/google.profile.Person",
-// "firstName": ,
-// "lastName":
-// }
-//
-// If the embedded message type is well-known and has a custom JSON
-// representation, that representation will be embedded adding a field
-// `value` which holds the custom JSON in addition to the `@type`
-// field. Example (for message [google.protobuf.Duration][]):
-//
-// {
-// "@type": "type.googleapis.com/google.protobuf.Duration",
-// "value": "1.212s"
-// }
+// In its binary encoding, an `Any` is an ordinary message; but in other wire
+// forms like JSON, it has a special encoding. The format of the type URL is
+// described on the `type_url` field.
+//
+// Protobuf APIs provide utilities to interact with `Any` values:
+//
+// - A 'pack' operation accepts a message and constructs a generic `Any` wrapper
+// around it.
+// - An 'unpack' operation reads the content of an `Any` message, either into an
+// existing message or a new one. Unpack operations must check the type of the
+// value they unpack against the declared `type_url`.
+// - An 'is' operation decides whether an `Any` contains a message of the given
+// type, i.e. whether it can 'unpack' that type.
+//
+// The JSON format representation of an `Any` follows one of these cases:
+//
+// - For types without special-cased JSON encodings, the JSON format
+// representation of the `Any` is the same as that of the message, with an
+// additional `@type` field which contains the type URL.
+// - For types with special-cased JSON encodings (typically called 'well-known'
+// types, listed in https://protobuf.dev/programming-guides/json/#any), the
+// JSON format representation has a key `@type` which contains the type URL
+// and a key `value` which contains the JSON-serialized value.
+//
+// The text format representation of an `Any` is like a message with one field
+// whose name is the type URL in brackets. For example, an `Any` containing a
+// `foo.Bar` message may be written `[type.googleapis.com/foo.Bar] { a: 2 }`.
type Any struct {
state protoimpl.MessageState `protogen:"open.v1"`
- // A URL/resource name that uniquely identifies the type of the serialized
- // protocol buffer message. This string must contain at least
- // one "/" character. The last segment of the URL's path must represent
- // the fully qualified name of the type (as in
- // `path/google.protobuf.Duration`). The name should be in a canonical form
- // (e.g., leading "." is not accepted).
+ // Identifies the type of the serialized Protobuf message with a URI reference
+ // consisting of a prefix ending in a slash and the fully-qualified type name.
+ //
+ // Example: type.googleapis.com/google.protobuf.StringValue
//
- // In practice, teams usually precompile into the binary all types that they
- // expect it to use in the context of Any. However, for URLs which use the
- // scheme `http`, `https`, or no scheme, one can optionally set up a type
- // server that maps type URLs to message definitions as follows:
+ // This string must contain at least one `/` character, and the content after
+ // the last `/` must be the fully-qualified name of the type in canonical
+ // form, without a leading dot. Do not write a scheme on these URI references
+ // so that clients do not attempt to contact them.
//
- // - If no scheme is provided, `https` is assumed.
- // - An HTTP GET on the URL must yield a [google.protobuf.Type][]
- // value in binary format, or produce an error.
- // - Applications are allowed to cache lookup results based on the
- // URL, or have them precompiled into a binary to avoid any
- // lookup. Therefore, binary compatibility needs to be preserved
- // on changes to types. (Use versioned type names to manage
- // breaking changes.)
+ // The prefix is arbitrary and Protobuf implementations are expected to
+ // simply strip off everything up to and including the last `/` to identify
+ // the type. `type.googleapis.com/` is a common default prefix that some
+ // legacy implementations require. This prefix does not indicate the origin of
+ // the type, and URIs containing it are not expected to respond to any
+ // requests.
//
- // Note: this functionality is not currently available in the official
- // protobuf release, and it is not used for type URLs beginning with
- // type.googleapis.com. As of May 2023, there are no widely used type server
- // implementations and no plans to implement one.
+ // All type URL strings must be legal URI references with the additional
+ // restriction (for the text format) that the content of the reference
+ // must consist only of alphanumeric characters, percent-encoded escapes, and
+ // characters in the following set (not including the outer backticks):
+ // `/-.~_!$&()*+,;=`. Despite our allowing percent encodings, implementations
+ // should not unescape them to prevent confusion with existing parsers. For
+ // example, `type.googleapis.com%2FFoo` should be rejected.
//
- // Schemes other than `http`, `https` (or the empty scheme) might be
- // used with implementation specific semantics.
+ // In the original design of `Any`, the possibility of launching a type
+ // resolution service at these type URLs was considered but Protobuf never
+ // implemented one and considers contacting these URLs to be problematic and
+ // a potential security issue. Do not attempt to contact type URLs.
TypeUrl string `protobuf:"bytes,1,opt,name=type_url,json=typeUrl,proto3" json:"type_url,omitempty"`
- // Must be a valid serialized protocol buffer of the above specified type.
+ // Holds a Protobuf serialization of the type described by type_url.
Value []byte `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
diff --git a/vendor/google.golang.org/protobuf/types/known/fieldmaskpb/field_mask.pb.go b/vendor/google.golang.org/protobuf/types/known/fieldmaskpb/field_mask.pb.go
index 91ee89a5c..4a0437911 100644
--- a/vendor/google.golang.org/protobuf/types/known/fieldmaskpb/field_mask.pb.go
+++ b/vendor/google.golang.org/protobuf/types/known/fieldmaskpb/field_mask.pb.go
@@ -197,24 +197,22 @@ import (
// An implementation may provide options to override this default behavior for
// repeated and message fields.
//
-// In order to reset a field's value to the default, the field must
-// be in the mask and set to the default value in the provided resource.
-// Hence, in order to reset all fields of a resource, provide a default
-// instance of the resource and set all fields in the mask, or do
-// not provide a mask as described below.
-//
-// If a field mask is not present on update, the operation applies to
-// all fields (as if a field mask of all fields has been specified).
-// Note that in the presence of schema evolution, this may mean that
-// fields the client does not know and has therefore not filled into
-// the request will be reset to their default. If this is unwanted
-// behavior, a specific service may require a client to always specify
-// a field mask, producing an error if not.
-//
-// As with get operations, the location of the resource which
-// describes the updated values in the request message depends on the
-// operation kind. In any case, the effect of the field mask is
-// required to be honored by the API.
+// Note that libraries which implement FieldMask resolution have various
+// different behaviors in the face of empty masks or the special "*" mask.
+// When implementing a service you should confirm these cases have the
+// appropriate behavior in the underlying FieldMask library that you desire,
+// and you may need to special case those cases in your application code if
+// the underlying field mask library behavior differs from your intended
+// service semantics.
+//
+// Update methods implementing https://google.aip.dev/134
+// - MUST support the special value * meaning "full replace"
+// - MUST treat an omitted field mask as "replace fields which are present".
+//
+// Other methods implementing https://google.aip.dev/157
+// - SHOULD support the special value "*" to mean "get all".
+// - MUST treat an omitted field mask to mean "get all", unless otherwise
+// documented.
//
// ## Considerations for HTTP REST
//
diff --git a/vendor/google.golang.org/protobuf/types/known/structpb/struct.pb.go b/vendor/google.golang.org/protobuf/types/known/structpb/struct.pb.go
index 30411b728..8325a5048 100644
--- a/vendor/google.golang.org/protobuf/types/known/structpb/struct.pb.go
+++ b/vendor/google.golang.org/protobuf/types/known/structpb/struct.pb.go
@@ -131,10 +131,15 @@ import (
unsafe "unsafe"
)
-// `NullValue` is a singleton enumeration to represent the null value for the
-// `Value` type union.
+// Represents a JSON `null`.
//
-// The JSON representation for `NullValue` is JSON `null`.
+// `NullValue` is a sentinel, using an enum with only one value to represent
+// the null value for the `Value` type union.
+//
+// A field of type `NullValue` with any value other than `0` is considered
+// invalid. Most ProtoJSON serializers will emit a Value with a `null_value` set
+// as a JSON `null` regardless of the integer value, and so will round trip to
+// a `0` value.
type NullValue int32
const (
@@ -179,14 +184,19 @@ func (NullValue) EnumDescriptor() ([]byte, []int) {
return file_google_protobuf_struct_proto_rawDescGZIP(), []int{0}
}
-// `Struct` represents a structured data value, consisting of fields
-// which map to dynamically typed values. In some languages, `Struct`
-// might be supported by a native representation. For example, in
-// scripting languages like JS a struct is represented as an
-// object. The details of that representation are described together
-// with the proto support for the language.
+// Represents a JSON object.
+//
+// An unordered key-value map, intending to perfectly capture the semantics of a
+// JSON object. This enables parsing any arbitrary JSON payload as a message
+// field in ProtoJSON format.
+//
+// This follows RFC 8259 guidelines for interoperable JSON: notably this type
+// cannot represent large Int64 values or `NaN`/`Infinity` numbers,
+// since the JSON format generally does not support those values in its number
+// type.
//
-// The JSON representation for `Struct` is JSON object.
+// If you do not intend to parse arbitrary JSON into your message, a custom
+// typed message should be preferred instead of using this type.
type Struct struct {
state protoimpl.MessageState `protogen:"open.v1"`
// Unordered map of dynamically typed values.
@@ -269,12 +279,12 @@ func (x *Struct) GetFields() map[string]*Value {
return nil
}
+// Represents a JSON value.
+//
// `Value` represents a dynamically typed value which can be either
// null, a number, a string, a boolean, a recursive struct value, or a
// list of values. A producer of value is expected to set one of these
-// variants. Absence of any variant indicates an error.
-//
-// The JSON representation for `Value` is JSON value.
+// variants. Absence of any variant is an invalid state.
type Value struct {
state protoimpl.MessageState `protogen:"open.v1"`
// The kind of value.
@@ -548,32 +558,35 @@ type isValue_Kind interface {
}
type Value_NullValue struct {
- // Represents a null value.
+ // Represents a JSON `null`.
NullValue NullValue `protobuf:"varint,1,opt,name=null_value,json=nullValue,proto3,enum=google.protobuf.NullValue,oneof"`
}
type Value_NumberValue struct {
- // Represents a double value.
+ // Represents a JSON number. Must not be `NaN`, `Infinity` or
+ // `-Infinity`, since those are not supported in JSON. This also cannot
+ // represent large Int64 values, since JSON format generally does not
+ // support them in its number type.
NumberValue float64 `protobuf:"fixed64,2,opt,name=number_value,json=numberValue,proto3,oneof"`
}
type Value_StringValue struct {
- // Represents a string value.
+ // Represents a JSON string.
StringValue string `protobuf:"bytes,3,opt,name=string_value,json=stringValue,proto3,oneof"`
}
type Value_BoolValue struct {
- // Represents a boolean value.
+ // Represents a JSON boolean (`true` or `false` literal in JSON).
BoolValue bool `protobuf:"varint,4,opt,name=bool_value,json=boolValue,proto3,oneof"`
}
type Value_StructValue struct {
- // Represents a structured value.
+ // Represents a JSON object.
StructValue *Struct `protobuf:"bytes,5,opt,name=struct_value,json=structValue,proto3,oneof"`
}
type Value_ListValue struct {
- // Represents a repeated `Value`.
+ // Represents a JSON array.
ListValue *ListValue `protobuf:"bytes,6,opt,name=list_value,json=listValue,proto3,oneof"`
}
@@ -589,9 +602,7 @@ func (*Value_StructValue) isValue_Kind() {}
func (*Value_ListValue) isValue_Kind() {}
-// `ListValue` is a wrapper around a repeated field of values.
-//
-// The JSON representation for `ListValue` is JSON array.
+// Represents a JSON array.
type ListValue struct {
state protoimpl.MessageState `protogen:"open.v1"`
// Repeated field of dynamically typed values.
diff --git a/vendor/google.golang.org/protobuf/types/known/timestamppb/timestamp.pb.go b/vendor/google.golang.org/protobuf/types/known/timestamppb/timestamp.pb.go
index 484c21fd5..2cd60946c 100644
--- a/vendor/google.golang.org/protobuf/types/known/timestamppb/timestamp.pb.go
+++ b/vendor/google.golang.org/protobuf/types/known/timestamppb/timestamp.pb.go
@@ -153,8 +153,8 @@ import (
// {hour}, {min}, and {sec} are zero-padded to two digits each. The fractional
// seconds, which can go up to 9 digits (i.e. up to 1 nanosecond resolution),
// are optional. The "Z" suffix indicates the timezone ("UTC"); the timezone
-// is required. A proto3 JSON serializer should always use UTC (as indicated by
-// "Z") when printing the Timestamp type and a proto3 JSON parser should be
+// is required. A ProtoJSON serializer should always use UTC (as indicated by
+// "Z") when printing the Timestamp type and a ProtoJSON parser should be
// able to accept both UTC and other timezones (as indicated by an offset).
//
// For example, "2017-01-15T01:30:15.01Z" encodes 15.01 seconds past
@@ -173,7 +173,7 @@ import (
type Timestamp struct {
state protoimpl.MessageState `protogen:"open.v1"`
// Represents seconds of UTC time since Unix epoch 1970-01-01T00:00:00Z. Must
- // be between -315576000000 and 315576000000 inclusive (which corresponds to
+ // be between -62135596800 and 253402300799 inclusive (which corresponds to
// 0001-01-01T00:00:00Z to 9999-12-31T23:59:59Z).
Seconds int64 `protobuf:"varint,1,opt,name=seconds,proto3" json:"seconds,omitempty"`
// Non-negative fractions of a second at nanosecond resolution. This field is
diff --git a/vendor/gopkg.in/ini.v1/.golangci.yml b/vendor/gopkg.in/ini.v1/.golangci.yml
index 631e36925..fabbdb621 100644
--- a/vendor/gopkg.in/ini.v1/.golangci.yml
+++ b/vendor/gopkg.in/ini.v1/.golangci.yml
@@ -1,27 +1,36 @@
-linters-settings:
- staticcheck:
- checks: [
- "all",
- "-SA1019" # There are valid use cases of strings.Title
- ]
- nakedret:
- max-func-lines: 0 # Disallow any unnamed return statement
-
+version: "2"
linters:
enable:
- - deadcode
- - errcheck
- - gosimple
- - govet
- - ineffassign
- - staticcheck
- - structcheck
- - typecheck
- - unused
- - varcheck
- nakedret
- - gofmt
- rowserrcheck
- unconvert
- - goimports
- unparam
+ settings:
+ govet:
+ disable:
+ # printf: non-constant format string in call to fmt.Errorf (govet)
+ # showing up since golangci-lint version 1.60.1
+ - printf
+ nakedret:
+ max-func-lines: 0 # Disallow any unnamed return statement
+ exclusions:
+ generated: lax
+ presets:
+ - comments
+ - common-false-positives
+ - legacy
+ - std-error-handling
+ paths:
+ - third_party$
+ - builtin$
+ - examples$
+formatters:
+ enable:
+ - gofmt
+ - goimports
+ exclusions:
+ generated: lax
+ paths:
+ - third_party$
+ - builtin$
+ - examples$
diff --git a/vendor/gopkg.in/ini.v1/README.md b/vendor/gopkg.in/ini.v1/README.md
index 30606d970..e4c723d1b 100644
--- a/vendor/gopkg.in/ini.v1/README.md
+++ b/vendor/gopkg.in/ini.v1/README.md
@@ -1,9 +1,7 @@
# INI
[](https://github.com/go-ini/ini/actions?query=branch%3Amain)
-[](https://codecov.io/gh/go-ini/ini)
[](https://pkg.go.dev/github.com/go-ini/ini?tab=doc)
-[](https://sourcegraph.com/github.com/go-ini/ini)

@@ -27,10 +25,14 @@ Package ini provides INI file read and write functionality in Go.
The minimum requirement of Go is **1.13**.
```sh
-$ go get gopkg.in/ini.v1
+$ go get gopkg.in/ini.v1@latest
```
-Please add `-u` flag to update in the future.
+> [!NOTE]
+> If you previously used `github.com/go-ini/ini` as the import path in your project, without updating all of your code, you can use the following command to replace the import path in your `go.mod`:
+> ```zsh
+> go mod edit -replace github.com/go-ini/ini=gopkg.in/ini.v1@latest
+> ```
## Getting Help
diff --git a/vendor/gopkg.in/ini.v1/key.go b/vendor/gopkg.in/ini.v1/key.go
index a19d9f38e..1a7767a2e 100644
--- a/vendor/gopkg.in/ini.v1/key.go
+++ b/vendor/gopkg.in/ini.v1/key.go
@@ -170,7 +170,7 @@ func (k *Key) transformValue(val string) string {
}
// Substitute by new value and take off leading '%(' and trailing ')s'.
- val = strings.Replace(val, vr, nk.value, -1)
+ val = strings.ReplaceAll(val, vr, nk.value)
}
return val
}
@@ -429,7 +429,7 @@ func (k *Key) InUint64(defaultVal uint64, candidates []uint64) uint64 {
func (k *Key) InTimeFormat(format string, defaultVal time.Time, candidates []time.Time) time.Time {
val := k.MustTimeFormat(format)
for _, cand := range candidates {
- if val == cand {
+ if val.Equal(cand) {
return val
}
}
diff --git a/vendor/gopkg.in/ini.v1/parser.go b/vendor/gopkg.in/ini.v1/parser.go
index 44fc526c2..513b19e72 100644
--- a/vendor/gopkg.in/ini.v1/parser.go
+++ b/vendor/gopkg.in/ini.v1/parser.go
@@ -130,13 +130,14 @@ func readKeyName(delimiters string, in []byte) (string, int, error) {
// Check if key name surrounded by quotes.
var keyQuote string
- if line[0] == '"' {
+ switch line[0] {
+ case '"':
if len(line) > 6 && line[0:3] == `"""` {
keyQuote = `"""`
} else {
keyQuote = `"`
}
- } else if line[0] == '`' {
+ case '`':
keyQuote = "`"
}
@@ -181,6 +182,13 @@ func (p *parser) readMultilines(line, val, valQuote string) (string, error) {
pos := strings.LastIndex(next, valQuote)
if pos > -1 {
+ // Check if the line ends with backslash continuation after the quote
+ restOfLine := strings.TrimRight(next[pos+len(valQuote):], "\r\n")
+ if !p.options.IgnoreContinuation && strings.HasSuffix(strings.TrimSpace(restOfLine), `\`) {
+ val += next
+ continue
+ }
+
val += next[:pos]
comment, has := cleanComment([]byte(next[pos:]))
@@ -253,7 +261,7 @@ func (p *parser) readValue(in []byte, bufferSize int) (string, error) {
}
if p.options.UnescapeValueDoubleQuotes && valQuote == `"` {
- return strings.Replace(line[startIdx:pos+startIdx], `\"`, `"`, -1), nil
+ return strings.ReplaceAll(line[startIdx:pos+startIdx], `\"`, `"`), nil
}
return line[startIdx : pos+startIdx], nil
}
diff --git a/vendor/honnef.co/go/tools/analysis/callcheck/callcheck.go b/vendor/honnef.co/go/tools/analysis/callcheck/callcheck.go
index 11ec3fb91..3ad6888c6 100644
--- a/vendor/honnef.co/go/tools/analysis/callcheck/callcheck.go
+++ b/vendor/honnef.co/go/tools/analysis/callcheck/callcheck.go
@@ -44,13 +44,13 @@ func (arg *Argument) Invalid(msg string) {
type Check func(call *Call)
-func Analyzer(rules map[string]Check) func(pass *analysis.Pass) (interface{}, error) {
- return func(pass *analysis.Pass) (interface{}, error) {
+func Analyzer(rules map[string]Check) func(pass *analysis.Pass) (any, error) {
+ return func(pass *analysis.Pass) (any, error) {
return checkCalls(pass, rules)
}
}
-func checkCalls(pass *analysis.Pass, rules map[string]Check) (interface{}, error) {
+func checkCalls(pass *analysis.Pass, rules map[string]Check) (any, error) {
cb := func(caller *ir.Function, site ir.CallInstruction, callee *ir.Function) {
obj, ok := callee.Object().(*types.Func)
if !ok {
diff --git a/vendor/honnef.co/go/tools/analysis/code/code.go b/vendor/honnef.co/go/tools/analysis/code/code.go
index e456947fa..9e4791921 100644
--- a/vendor/honnef.co/go/tools/analysis/code/code.go
+++ b/vendor/honnef.co/go/tools/analysis/code/code.go
@@ -10,6 +10,7 @@ import (
"go/types"
"go/version"
"path/filepath"
+ "slices"
"strings"
"honnef.co/go/tools/analysis/facts/generated"
@@ -222,12 +223,7 @@ func IsCallToAny(pass *analysis.Pass, node ast.Node, names ...string) bool {
return false
}
q := CallName(pass, call)
- for _, name := range names {
- if q == name {
- return true
- }
- }
- return false
+ return slices.Contains(names, q)
}
func File(pass *analysis.Pass, node Positioner) *ast.File {
diff --git a/vendor/honnef.co/go/tools/analysis/code/visit.go b/vendor/honnef.co/go/tools/analysis/code/visit.go
index 0f0d644a1..83b585d90 100644
--- a/vendor/honnef.co/go/tools/analysis/code/visit.go
+++ b/vendor/honnef.co/go/tools/analysis/code/visit.go
@@ -2,9 +2,15 @@ package code
import (
"bytes"
+ "fmt"
"go/ast"
"go/format"
+ "go/types"
+ "iter"
+ "slices"
+ typeindexanalyzer "honnef.co/go/tools/internal/analysisinternal/typeindex"
+ "honnef.co/go/tools/internal/typesinternal/typeindex"
"honnef.co/go/tools/pattern"
"golang.org/x/tools/go/analysis"
@@ -12,6 +18,12 @@ import (
"golang.org/x/tools/go/ast/inspector"
)
+var RequiredAnalyzers = []*analysis.Analyzer{inspect.Analyzer, typeindexanalyzer.Analyzer}
+
+func Cursor(pass *analysis.Pass) inspector.Cursor {
+ return pass.ResultOf[inspect.Analyzer].(*inspector.Inspector).Root()
+}
+
func Preorder(pass *analysis.Pass, fn func(ast.Node), types ...ast.Node) {
pass.ResultOf[inspect.Analyzer].(*inspector.Inspector).Preorder(types, fn)
}
@@ -25,6 +37,49 @@ func PreorderStack(pass *analysis.Pass, fn func(ast.Node, []ast.Node), types ...
})
}
+func Matches(pass *analysis.Pass, qs ...pattern.Pattern) iter.Seq2[ast.Node, *pattern.Matcher] {
+ return func(yield func(ast.Node, *pattern.Matcher) bool) {
+ for _, q := range qs {
+ if !CouldMatchAny(pass, q) {
+ continue
+ }
+
+ if len(q.RootCallSymbols) != 0 {
+ index := pass.ResultOf[typeindexanalyzer.Analyzer].(*typeindex.Index)
+ for _, isym := range q.RootCallSymbols {
+ var obj types.Object
+ if isym.Type == "" {
+ obj = index.Object(isym.Path, isym.Ident)
+ } else {
+ obj = index.Selection(isym.Path, isym.Type, isym.Ident)
+ }
+ for c := range index.Calls(obj) {
+ node := c.Node()
+ if m, ok := Match(pass, q, node); ok {
+ if !yield(node, m) {
+ return
+ }
+ }
+ }
+ }
+ } else {
+ ins := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector)
+ fn := func(node ast.Node, push bool) bool {
+ if !push {
+ return true
+ }
+
+ if m, ok := Match(pass, q, node); ok {
+ return yield(node, m)
+ }
+ return true
+ }
+ ins.Nodes(q.EntryNodes, fn)
+ }
+ }
+ }
+}
+
func Match(pass *analysis.Pass, q pattern.Pattern, node ast.Node) (*pattern.Matcher, bool) {
// Note that we ignore q.Relevant – callers of Match usually use
// AST inspectors that already filter on nodes we're interested
@@ -34,6 +89,41 @@ func Match(pass *analysis.Pass, q pattern.Pattern, node ast.Node) (*pattern.Matc
return m, ok
}
+func CouldMatchAny(pass *analysis.Pass, qs ...pattern.Pattern) bool {
+ index := pass.ResultOf[typeindexanalyzer.Analyzer].(*typeindex.Index)
+ var do func(node pattern.Node) bool
+ do = func(node pattern.Node) bool {
+ switch node := node.(type) {
+ case pattern.Any:
+ return true
+ case pattern.Or:
+ return slices.ContainsFunc(node.Nodes, do)
+ case pattern.And:
+ for _, child := range node.Nodes {
+ if !do(child) {
+ return false
+ }
+ }
+ return true
+ case pattern.IndexSymbol:
+ if node.Type == "" {
+ return index.Object(node.Path, node.Ident) != nil
+ } else {
+ return index.Selection(node.Path, node.Type, node.Ident) != nil
+ }
+ default:
+ panic(fmt.Sprintf("internal error: unexpected type %T", node))
+ }
+ }
+
+ for _, q := range qs {
+ if do(q.SymbolsPattern) {
+ return true
+ }
+ }
+ return false
+}
+
func MatchAndEdit(pass *analysis.Pass, before, after pattern.Pattern, node ast.Node) (*pattern.Matcher, []analysis.TextEdit, bool) {
m, ok := Match(pass, before, node)
if !ok {
@@ -49,3 +139,15 @@ func MatchAndEdit(pass *analysis.Pass, before, after pattern.Pattern, node ast.N
}}
return m, edit, true
}
+
+func EditMatch(pass *analysis.Pass, node ast.Node, m *pattern.Matcher, after pattern.Pattern) []analysis.TextEdit {
+ r := pattern.NodeToAST(after.Root, m.State)
+ buf := &bytes.Buffer{}
+ format.Node(buf, pass.Fset, r)
+ edit := []analysis.TextEdit{{
+ Pos: node.Pos(),
+ End: node.End(),
+ NewText: buf.Bytes(),
+ }}
+ return edit
+}
diff --git a/vendor/honnef.co/go/tools/analysis/facts/deprecated/deprecated.go b/vendor/honnef.co/go/tools/analysis/facts/deprecated/deprecated.go
index dd6d655c3..03c06218e 100644
--- a/vendor/honnef.co/go/tools/analysis/facts/deprecated/deprecated.go
+++ b/vendor/honnef.co/go/tools/analysis/facts/deprecated/deprecated.go
@@ -25,10 +25,10 @@ var Analyzer = &analysis.Analyzer{
Doc: "Mark deprecated objects",
Run: deprecated,
FactTypes: []analysis.Fact{(*IsDeprecated)(nil)},
- ResultType: reflect.TypeOf(Result{}),
+ ResultType: reflect.TypeFor[Result](),
}
-func deprecated(pass *analysis.Pass) (interface{}, error) {
+func deprecated(pass *analysis.Pass) (any, error) {
var names []*ast.Ident
extractDeprecatedMessage := func(docs []*ast.CommentGroup) string {
@@ -36,8 +36,8 @@ func deprecated(pass *analysis.Pass) (interface{}, error) {
if doc == nil {
continue
}
- parts := strings.Split(doc.Text(), "\n\n")
- for _, part := range parts {
+ parts := strings.SplitSeq(doc.Text(), "\n\n")
+ for part := range parts {
if !strings.HasPrefix(part, "Deprecated: ") {
continue
}
diff --git a/vendor/honnef.co/go/tools/analysis/facts/directives/directives.go b/vendor/honnef.co/go/tools/analysis/facts/directives/directives.go
index a8c3522dd..467527bff 100644
--- a/vendor/honnef.co/go/tools/analysis/facts/directives/directives.go
+++ b/vendor/honnef.co/go/tools/analysis/facts/directives/directives.go
@@ -7,7 +7,7 @@ import (
"honnef.co/go/tools/analysis/lint"
)
-func directives(pass *analysis.Pass) (interface{}, error) {
+func directives(pass *analysis.Pass) (any, error) {
return lint.ParseDirectives(pass.Files, pass.Fset), nil
}
@@ -16,5 +16,5 @@ var Analyzer = &analysis.Analyzer{
Doc: "extracts linter directives",
Run: directives,
RunDespiteErrors: true,
- ResultType: reflect.TypeOf([]lint.Directive{}),
+ ResultType: reflect.TypeFor[[]lint.Directive](),
}
diff --git a/vendor/honnef.co/go/tools/analysis/facts/generated/generated.go b/vendor/honnef.co/go/tools/analysis/facts/generated/generated.go
index 240d06669..301ad0e3e 100644
--- a/vendor/honnef.co/go/tools/analysis/facts/generated/generated.go
+++ b/vendor/honnef.co/go/tools/analysis/facts/generated/generated.go
@@ -81,7 +81,7 @@ func isGenerated(path string) (Generator, bool) {
var Analyzer = &analysis.Analyzer{
Name: "isgenerated",
Doc: "annotate file names that have been code generated",
- Run: func(pass *analysis.Pass) (interface{}, error) {
+ Run: func(pass *analysis.Pass) (any, error) {
m := map[string]Generator{}
for _, f := range pass.Files {
path := pass.Fset.PositionFor(f.Pos(), false).Filename
@@ -93,5 +93,5 @@ var Analyzer = &analysis.Analyzer{
return m, nil
},
RunDespiteErrors: true,
- ResultType: reflect.TypeOf(map[string]Generator{}),
+ ResultType: reflect.TypeFor[map[string]Generator](),
}
diff --git a/vendor/honnef.co/go/tools/analysis/facts/nilness/nilness.go b/vendor/honnef.co/go/tools/analysis/facts/nilness/nilness.go
index 17d344fab..a7c91a7aa 100644
--- a/vendor/honnef.co/go/tools/analysis/facts/nilness/nilness.go
+++ b/vendor/honnef.co/go/tools/analysis/facts/nilness/nilness.go
@@ -35,7 +35,7 @@ var Analysis = &analysis.Analyzer{
Run: run,
Requires: []*analysis.Analyzer{buildir.Analyzer},
FactTypes: []analysis.Fact{(*neverReturnsNilFact)(nil)},
- ResultType: reflect.TypeOf((*Result)(nil)),
+ ResultType: reflect.TypeFor[*Result](),
}
// MayReturnNil reports whether the ret's return value of fn might be
@@ -57,7 +57,7 @@ func (r *Result) MayReturnNil(fn *types.Func, ret int) (yes bool, globalOnly boo
return v != neverNil, v == onlyGlobal
}
-func run(pass *analysis.Pass) (interface{}, error) {
+func run(pass *analysis.Pass) (any, error) {
seen := map[*ir.Function]struct{}{}
out := &Result{
m: map[*types.Func][]neverNilness{},
diff --git a/vendor/honnef.co/go/tools/analysis/facts/purity/purity.go b/vendor/honnef.co/go/tools/analysis/facts/purity/purity.go
index 0f6895a8c..92c7f282a 100644
--- a/vendor/honnef.co/go/tools/analysis/facts/purity/purity.go
+++ b/vendor/honnef.co/go/tools/analysis/facts/purity/purity.go
@@ -27,7 +27,7 @@ var Analyzer = &analysis.Analyzer{
Run: purity,
Requires: []*analysis.Analyzer{buildir.Analyzer},
FactTypes: []analysis.Fact{(*IsPure)(nil)},
- ResultType: reflect.TypeOf(Result{}),
+ ResultType: reflect.TypeFor[Result](),
}
var pureStdlib = map[string]struct{}{
@@ -104,7 +104,7 @@ var pureStdlib = map[string]struct{}{
"(time.Time).ZoneBounds": {},
}
-func purity(pass *analysis.Pass) (interface{}, error) {
+func purity(pass *analysis.Pass) (any, error) {
seen := map[*ir.Function]struct{}{}
irpkg := pass.ResultOf[buildir.Analyzer].(*buildir.IR).Pkg
var check func(fn *ir.Function) (ret bool)
@@ -154,8 +154,8 @@ func purity(pass *analysis.Pass) (interface{}, error) {
case *types.Basic:
return true
case *types.Struct:
- for i := 0; i < u.NumFields(); i++ {
- if !isBasic(u.Field(i).Type()) {
+ for field := range u.Fields() {
+ if !isBasic(field.Type()) {
return false
}
}
diff --git a/vendor/honnef.co/go/tools/analysis/facts/tokenfile/token.go b/vendor/honnef.co/go/tools/analysis/facts/tokenfile/token.go
index e7f747f00..3618c8949 100644
--- a/vendor/honnef.co/go/tools/analysis/facts/tokenfile/token.go
+++ b/vendor/honnef.co/go/tools/analysis/facts/tokenfile/token.go
@@ -11,7 +11,7 @@ import (
var Analyzer = &analysis.Analyzer{
Name: "tokenfileanalyzer",
Doc: "creates a mapping of *token.File to *ast.File",
- Run: func(pass *analysis.Pass) (interface{}, error) {
+ Run: func(pass *analysis.Pass) (any, error) {
m := map[*token.File]*ast.File{}
for _, af := range pass.Files {
tf := pass.Fset.File(af.Pos())
@@ -20,5 +20,5 @@ var Analyzer = &analysis.Analyzer{
return m, nil
},
RunDespiteErrors: true,
- ResultType: reflect.TypeOf(map[*token.File]*ast.File{}),
+ ResultType: reflect.TypeFor[map[*token.File]*ast.File](),
}
diff --git a/vendor/honnef.co/go/tools/analysis/facts/typedness/typedness.go b/vendor/honnef.co/go/tools/analysis/facts/typedness/typedness.go
index 3bbe20603..fd21dd228 100644
--- a/vendor/honnef.co/go/tools/analysis/facts/typedness/typedness.go
+++ b/vendor/honnef.co/go/tools/analysis/facts/typedness/typedness.go
@@ -35,7 +35,7 @@ var Analysis = &analysis.Analyzer{
Run: run,
Requires: []*analysis.Analyzer{buildir.Analyzer},
FactTypes: []analysis.Fact{(*alwaysTypedFact)(nil)},
- ResultType: reflect.TypeOf((*Result)(nil)),
+ ResultType: reflect.TypeFor[*Result](),
}
// MustReturnTyped reports whether the ret's return value of fn must
@@ -51,7 +51,7 @@ func (r *Result) MustReturnTyped(fn *types.Func, ret int) bool {
return (r.m[fn] & (1 << ret)) != 0
}
-func run(pass *analysis.Pass) (interface{}, error) {
+func run(pass *analysis.Pass) (any, error) {
seen := map[*ir.Function]struct{}{}
out := &Result{
m: map[*types.Func]uint8{},
diff --git a/vendor/honnef.co/go/tools/analysis/lint/lint.go b/vendor/honnef.co/go/tools/analysis/lint/lint.go
index 6f5861221..c82bc2461 100644
--- a/vendor/honnef.co/go/tools/analysis/lint/lint.go
+++ b/vendor/honnef.co/go/tools/analysis/lint/lint.go
@@ -127,13 +127,13 @@ func (doc *Documentation) format(markdown bool, metadata bool) string {
if doc.Before != "" {
fmt.Fprintln(b, "Before:")
fmt.Fprintln(b, "")
- for _, line := range strings.Split(doc.Before, "\n") {
+ for line := range strings.SplitSeq(doc.Before, "\n") {
fmt.Fprint(b, " ", line, "\n")
}
fmt.Fprintln(b, "")
fmt.Fprintln(b, "After:")
fmt.Fprintln(b, "")
- for _, line := range strings.Split(doc.After, "\n") {
+ for line := range strings.SplitSeq(doc.After, "\n") {
fmt.Fprint(b, " ", line, "\n")
}
fmt.Fprintln(b, "")
@@ -168,7 +168,7 @@ func (doc *Documentation) String() string {
// ExhaustiveTypeSwitch panics when called. It can be used to ensure
// that type switches are exhaustive.
-func ExhaustiveTypeSwitch(v interface{}) {
+func ExhaustiveTypeSwitch(v any) {
panic(fmt.Sprintf("internal error: unhandled case %T", v))
}
diff --git a/vendor/honnef.co/go/tools/analysis/report/report.go b/vendor/honnef.co/go/tools/analysis/report/report.go
index fcc2317ce..82befcaef 100644
--- a/vendor/honnef.co/go/tools/analysis/report/report.go
+++ b/vendor/honnef.co/go/tools/analysis/report/report.go
@@ -226,7 +226,7 @@ func Report(pass *analysis.Pass, node Positioner, message string, opts ...Option
pass.Report(d)
}
-func Render(pass *analysis.Pass, x interface{}) string {
+func Render(pass *analysis.Pass, x any) string {
var buf bytes.Buffer
if err := format.Node(&buf, pass.Fset, x); err != nil {
panic(err)
diff --git a/vendor/honnef.co/go/tools/config/config.go b/vendor/honnef.co/go/tools/config/config.go
index a815a8a84..1c47f699f 100644
--- a/vendor/honnef.co/go/tools/config/config.go
+++ b/vendor/honnef.co/go/tools/config/config.go
@@ -59,7 +59,7 @@ func dirAST(files []*ast.File, fset *token.FileSet) string {
var Analyzer = &analysis.Analyzer{
Name: "config",
Doc: "loads configuration for the current package tree",
- Run: func(pass *analysis.Pass) (interface{}, error) {
+ Run: func(pass *analysis.Pass) (any, error) {
dir := dirAST(pass.Files, pass.Fset)
if dir == "" {
cfg := DefaultConfig
@@ -72,7 +72,7 @@ var Analyzer = &analysis.Analyzer{
return &cfg, nil
},
RunDespiteErrors: true,
- ResultType: reflect.TypeOf((*Config)(nil)),
+ ResultType: reflect.TypeFor[*Config](),
}
func For(pass *analysis.Pass) *Config {
@@ -174,6 +174,7 @@ var DefaultConfig = Config{
"XSS", "SIP", "RTP", "AMQP", "DB", "TS",
},
DotImportWhitelist: []string{
+ "simd/archsimd",
"github.com/mmcloughlin/avo/build",
"github.com/mmcloughlin/avo/operand",
"github.com/mmcloughlin/avo/reg",
@@ -193,8 +194,10 @@ func parseConfigs(dir string) ([]Config, error) {
// TODO(dh): consider stopping at the GOPATH/module boundary
for dir != "" {
- f, err := os.Open(filepath.Join(dir, ConfigName))
- if os.IsNotExist(err) {
+ path := filepath.Join(dir, ConfigName)
+ fi, err := os.Stat(path)
+ if os.IsNotExist(err) || (err == nil && !fi.Mode().IsRegular()) {
+ // walk up
ndir := filepath.Dir(dir)
if ndir == dir {
break
@@ -205,6 +208,15 @@ func parseConfigs(dir string) ([]Config, error) {
if err != nil {
return nil, err
}
+
+ // There is a small TOCTOU window here, but we're fine with reporting an
+ // error if the source tree is modified concurrently in weird ways while
+ // running Staticcheck.
+ f, err := os.Open(path)
+ if err != nil {
+ return nil, err
+ }
+
var cfg Config
_, err = toml.NewDecoder(f).Decode(&cfg)
f.Close()
diff --git a/vendor/honnef.co/go/tools/config/example.conf b/vendor/honnef.co/go/tools/config/example.conf
index dc102fbc0..acc9d69e6 100644
--- a/vendor/honnef.co/go/tools/config/example.conf
+++ b/vendor/honnef.co/go/tools/config/example.conf
@@ -7,6 +7,7 @@ initialisms = ["ACL", "API", "ASCII", "CPU", "CSS", "DNS",
"URL", "UTF8", "VM", "XML", "XMPP", "XSRF",
"XSS", "SIP", "RTP", "AMQP", "DB", "TS"]
dot_import_whitelist = [
+ "simd/archsimd",
"github.com/mmcloughlin/avo/build",
"github.com/mmcloughlin/avo/operand",
"github.com/mmcloughlin/avo/reg",
diff --git a/vendor/honnef.co/go/tools/go/ir/UPSTREAM b/vendor/honnef.co/go/tools/go/ir/UPSTREAM
index bfcf02856..03f487ae8 100644
--- a/vendor/honnef.co/go/tools/go/ir/UPSTREAM
+++ b/vendor/honnef.co/go/tools/go/ir/UPSTREAM
@@ -5,5 +5,5 @@ The changes are too many to list here, and it is best to consider this package i
Upstream changes still get applied when they address bugs in portions of code we have inherited.
The last upstream commit we've looked at was:
-ac2946029ad3806349fa00546449da9f59320e89
+05409620da166985e94b711ad4103bee40406eee
diff --git a/vendor/honnef.co/go/tools/go/ir/builder.go b/vendor/honnef.co/go/tools/go/ir/builder.go
index fb6183a50..17a6c8917 100644
--- a/vendor/honnef.co/go/tools/go/ir/builder.go
+++ b/vendor/honnef.co/go/tools/go/ir/builder.go
@@ -201,7 +201,7 @@ func (b *builder) exprN(fn *Function, e ast.Expr) Value {
var c Call
b.setCall(fn, e, &c.Call)
c.typ = typ
- return fn.emit(&c, e)
+ return emitCall(fn, &c, e)
case *ast.IndexExpr:
mapt := typeutil.CoreType(fn.Pkg.typeOf(e.X)).Underlying().(*types.Map)
@@ -288,7 +288,12 @@ func (b *builder) builtin(fn *Function, obj *types.Builtin, args []ast.Expr, typ
}
case "new":
- return emitNew(fn, deref(typ), source, "new")
+ alloc := emitNew(fn, deref(typ), source, "new")
+ if !fn.Pkg.info.Types[args[0]].IsType() {
+ v := b.expr(fn, args[0])
+ emitStore(fn, alloc, v, source)
+ }
+ return alloc
case "len", "cap":
// Special case: len or cap of an array or *array is based on the type, not the value which may be nil. We must
@@ -657,7 +662,7 @@ func (b *builder) expr0(fn *Function, e ast.Expr, tv types.TypeAndValue) Value {
var v Call
b.setCall(fn, e, &v.Call)
v.setType(tv.Type)
- return fn.emit(&v, e)
+ return emitCall(fn, &v, e)
case *ast.UnaryExpr:
switch e.Op {
@@ -2726,6 +2731,8 @@ func (b *builder) rangeFunc(fn *Function, x Value, tk, tv types.Type, rng *ast.R
b.buildYieldResume(fn, jump, exits, done)
fn.currentBlock = done
+ // pop the stack for the range-over-func
+ fn.targets = fn.targets.tail
}
// buildYieldResume emits to fn code for how to resume execution once a call to
@@ -3084,16 +3091,6 @@ func (b *builder) buildFunction(fn *Function) {
panic(n)
}
- if fn.Package().Pkg.Path() == "syscall" && fn.Name() == "Exit" {
- // syscall.Exit is a stub and the way os.Exit terminates the
- // process. Note that there are other functions in the runtime
- // that also terminate or unwind that we cannot analyze.
- // However, they aren't stubs, so buildExits ends up getting
- // called on them, so that's where we handle those special
- // cases.
- fn.NoReturn = AlwaysExits
- }
-
if body == nil {
// External function.
if fn.Params == nil {
@@ -3141,8 +3138,6 @@ func (b *builder) buildFunction(fn *Function) {
}
optimizeBlocks(fn)
buildFakeExits(fn)
- b.buildExits(fn)
- b.addUnreachables(fn)
fn.finishBody()
b.blocksets = fn.blocksets
fn.functionBody = nil
@@ -3167,8 +3162,8 @@ func (b *builder) buildYieldFunc(fn *Function) {
fn.sourceFn = fn.parent.sourceFn
fn.startBody()
params := fn.Signature.Params()
- for i := 0; i < params.Len(); i++ {
- fn.addParamVar(params.At(i), nil)
+ for v := range params.Variables() {
+ fn.addParamVar(v, nil)
}
fn.addResultVar(fn.Signature.Results().At(0), nil)
fn.exitBlock()
@@ -3186,6 +3181,7 @@ func (b *builder) buildYieldFunc(fn *Function) {
}
}
fn.targets = &targets{
+ tail: fn.targets,
_continue: ycont,
// `break` statement targets fn.parent.targets._break.
}
@@ -3267,6 +3263,7 @@ func (b *builder) buildYieldFunc(fn *Function) {
// unreachable.
emitJump(fn, ycont, nil)
}
+ fn.targets = fn.targets.tail
// Clean up exits and promote any unresolved exits to fn.parent.
for _, e := range fn.exits {
diff --git a/vendor/honnef.co/go/tools/go/ir/create.go b/vendor/honnef.co/go/tools/go/ir/create.go
index 9aef3a5df..046ffb758 100644
--- a/vendor/honnef.co/go/tools/go/ir/create.go
+++ b/vendor/honnef.co/go/tools/go/ir/create.go
@@ -294,3 +294,7 @@ func (prog *Program) AllPackages() []*Package {
func (prog *Program) ImportedPackage(path string) *Package {
return prog.imported[path]
}
+
+func (prog *Program) SetNoReturn(fn func(*types.Func) bool) {
+ prog.noReturn = fn
+}
diff --git a/vendor/honnef.co/go/tools/go/ir/dom.go b/vendor/honnef.co/go/tools/go/ir/dom.go
index 3f44c7c2a..f63a4c407 100644
--- a/vendor/honnef.co/go/tools/go/ir/dom.go
+++ b/vendor/honnef.co/go/tools/go/ir/dom.go
@@ -359,8 +359,8 @@ func sanityCheckDomTree(f *Function) {
// Check the entire relation. O(n^2).
ok := true
- for i := 0; i < n; i++ {
- for j := 0; j < n; j++ {
+ for i := range n {
+ for j := range n {
b, c := f.Blocks[i], f.Blocks[j]
actual := b.Dominates(c)
expected := D[j].Bit(i) == 1
diff --git a/vendor/honnef.co/go/tools/go/ir/emit.go b/vendor/honnef.co/go/tools/go/ir/emit.go
index b04852d4e..4eecf24d5 100644
--- a/vendor/honnef.co/go/tools/go/ir/emit.go
+++ b/vendor/honnef.co/go/tools/go/ir/emit.go
@@ -481,7 +481,7 @@ func emitTailCall(f *Function, call *Call, source ast.Node) {
case 1:
ret.Results = []Value{tuple}
default:
- for i := 0; i < nr; i++ {
+ for i := range nr {
v := emitExtract(f, tuple, i, source)
// TODO(adonovan): in principle, this is required:
// v = emitConv(f, o.Type, f.Signature.Results[i].Type)
@@ -498,6 +498,25 @@ func emitTailCall(f *Function, call *Call, source ast.Node) {
f.currentBlock = nil
}
+func emitCall(fn *Function, call *Call, source ast.Node) Value {
+ res := fn.emit(call, source)
+
+ callee := call.Call.StaticCallee()
+ if callee != nil &&
+ callee.object != nil &&
+ fn.Prog.noReturn != nil &&
+ fn.Prog.noReturn(callee.object) {
+ // Call doesn't return normally. Either it doesn't return at all
+ // (infinitely blocked or exitting the process), or it unwinds the stack
+ // (panic, runtime.Goexit). In case it unwinds, jump to the exit block.
+ fn.emit(new(Jump), source)
+ addEdge(fn.currentBlock, fn.Exit)
+ fn.currentBlock = fn.newBasicBlock("unreachable")
+ }
+
+ return res
+}
+
// emitImplicitSelections emits to f code to apply the sequence of
// implicit field selections specified by indices to base value v, and
// returns the selected value.
diff --git a/vendor/honnef.co/go/tools/go/ir/exits.go b/vendor/honnef.co/go/tools/go/ir/exits.go
deleted file mode 100644
index 03aa2866c..000000000
--- a/vendor/honnef.co/go/tools/go/ir/exits.go
+++ /dev/null
@@ -1,369 +0,0 @@
-package ir
-
-import (
- "go/types"
-)
-
-func (b *builder) buildExits(fn *Function) {
- if obj := fn.Object(); obj != nil {
- switch obj.Pkg().Path() {
- case "runtime":
- switch obj.Name() {
- case "exit":
- fn.NoReturn = AlwaysExits
- return
- case "throw":
- fn.NoReturn = AlwaysExits
- return
- case "Goexit":
- fn.NoReturn = AlwaysUnwinds
- return
- }
- case "go.uber.org/zap":
- switch obj.(*types.Func).FullName() {
- case "(*go.uber.org/zap.Logger).Fatal",
- "(*go.uber.org/zap.SugaredLogger).Fatal",
- "(*go.uber.org/zap.SugaredLogger).Fatalw",
- "(*go.uber.org/zap.SugaredLogger).Fatalf":
- // Technically, this method does not unconditionally exit
- // the process. It dynamically calls a function stored in
- // the logger. If the function is nil, it defaults to
- // os.Exit.
- //
- // The main intent of this method is to terminate the
- // process, and that's what the vast majority of people
- // will use it for. We'll happily accept some false
- // negatives to avoid a lot of false positives.
- fn.NoReturn = AlwaysExits
- case "(*go.uber.org/zap.Logger).Panic",
- "(*go.uber.org/zap.SugaredLogger).Panicw",
- "(*go.uber.org/zap.SugaredLogger).Panicf":
- fn.NoReturn = AlwaysUnwinds
- return
- case "(*go.uber.org/zap.Logger).DPanic",
- "(*go.uber.org/zap.SugaredLogger).DPanicf",
- "(*go.uber.org/zap.SugaredLogger).DPanicw":
- // These methods will only panic in development.
- }
- case "github.com/sirupsen/logrus":
- switch obj.(*types.Func).FullName() {
- case "(*github.com/sirupsen/logrus.Logger).Exit":
- // Technically, this method does not unconditionally exit
- // the process. It dynamically calls a function stored in
- // the logger. If the function is nil, it defaults to
- // os.Exit.
- //
- // The main intent of this method is to terminate the
- // process, and that's what the vast majority of people
- // will use it for. We'll happily accept some false
- // negatives to avoid a lot of false positives.
- fn.NoReturn = AlwaysExits
- return
- case "(*github.com/sirupsen/logrus.Logger).Panic",
- "(*github.com/sirupsen/logrus.Logger).Panicf",
- "(*github.com/sirupsen/logrus.Logger).Panicln":
-
- // These methods will always panic, but that's not
- // statically known from the code alone, because they
- // take a detour through the generic Log methods.
- fn.NoReturn = AlwaysUnwinds
- return
- case "(*github.com/sirupsen/logrus.Entry).Panicf",
- "(*github.com/sirupsen/logrus.Entry).Panicln":
-
- // Entry.Panic has an explicit panic, but Panicf and
- // Panicln do not, relying fully on the generic Log
- // method.
- fn.NoReturn = AlwaysUnwinds
- return
- case "(*github.com/sirupsen/logrus.Logger).Log",
- "(*github.com/sirupsen/logrus.Logger).Logf",
- "(*github.com/sirupsen/logrus.Logger).Logln":
- // TODO(dh): we cannot handle these cases. Whether they
- // exit or unwind depends on the level, which is set
- // via the first argument. We don't currently support
- // call-site-specific exit information.
- }
- case "github.com/golang/glog":
- switch obj.(*types.Func).FullName() {
- case "github.com/golang/glog.Exit",
- "github.com/golang/glog.ExitDepth",
- "github.com/golang/glog.Exitf",
- "github.com/golang/glog.Exitln",
- "github.com/golang/glog.Fatal",
- "github.com/golang/glog.FatalDepth",
- "github.com/golang/glog.Fatalf",
- "github.com/golang/glog.Fatalln":
- // all of these call os.Exit after logging
- fn.NoReturn = AlwaysExits
- }
- case "k8s.io/klog":
- switch obj.(*types.Func).FullName() {
- case "k8s.io/klog.Exit",
- "k8s.io/klog.ExitDepth",
- "k8s.io/klog.Exitf",
- "k8s.io/klog.Exitln",
- "k8s.io/klog.Fatal",
- "k8s.io/klog.FatalDepth",
- "k8s.io/klog.Fatalf",
- "k8s.io/klog.Fatalln":
- // all of these call os.Exit after logging
- fn.NoReturn = AlwaysExits
- }
- case "k8s.io/klog/v2":
- switch obj.(*types.Func).FullName() {
- case "k8s.io/klog/v2.Exit",
- "k8s.io/klog/v2.ExitDepth",
- "k8s.io/klog/v2.Exitf",
- "k8s.io/klog/v2.Exitln",
- "k8s.io/klog/v2.Fatal",
- "k8s.io/klog/v2.FatalDepth",
- "k8s.io/klog/v2.Fatalf",
- "k8s.io/klog/v2.Fatalln":
- // all of these call os.Exit after logging
- fn.NoReturn = AlwaysExits
- }
- }
- }
-
- isRecoverCall := func(instr Instruction) bool {
- if instr, ok := instr.(*Call); ok {
- if builtin, ok := instr.Call.Value.(*Builtin); ok {
- if builtin.Name() == "recover" {
- return true
- }
- }
- }
- return false
- }
-
- both := NewBlockSet(len(fn.Blocks))
- exits := NewBlockSet(len(fn.Blocks))
- unwinds := NewBlockSet(len(fn.Blocks))
- recovers := false
- for _, u := range fn.Blocks {
- for _, instr := range u.Instrs {
- instrSwitch:
- switch instr := instr.(type) {
- case *Defer:
- if recovers {
- // avoid doing extra work, we already know that this function calls recover
- continue
- }
- call := instr.Call.StaticCallee()
- if call == nil {
- // not a static call, so we can't be sure the
- // deferred call isn't calling recover
- recovers = true
- break
- }
- if call.Package() == fn.Package() {
- b.buildFunction(call)
- }
- if len(call.Blocks) == 0 {
- // external function, we don't know what's
- // happening inside it
- //
- // TODO(dh): this includes functions from
- // imported packages, due to how go/analysis
- // works. We could introduce another fact,
- // like we've done for exiting and unwinding.
- recovers = true
- break
- }
- for _, y := range call.Blocks {
- for _, instr2 := range y.Instrs {
- if isRecoverCall(instr2) {
- recovers = true
- break instrSwitch
- }
- }
- }
-
- case *Panic:
- both.Add(u)
- unwinds.Add(u)
-
- case CallInstruction:
- switch instr.(type) {
- case *Defer, *Call:
- default:
- continue
- }
- if instr.Common().IsInvoke() {
- // give up
- return
- }
- var call *Function
- switch instr.Common().Value.(type) {
- case *Function, *MakeClosure:
- call = instr.Common().StaticCallee()
- case *Builtin:
- // the only builtins that affect control flow are
- // panic and recover, and we've already handled
- // those
- continue
- default:
- // dynamic dispatch
- return
- }
- // buildFunction is idempotent. if we're part of a
- // (mutually) recursive call chain, then buildFunction
- // will immediately return, and fn.WillExit will be false.
- if call.Package() == fn.Package() {
- b.buildFunction(call)
- }
- switch call.NoReturn {
- case AlwaysExits:
- both.Add(u)
- exits.Add(u)
- case AlwaysUnwinds:
- both.Add(u)
- unwinds.Add(u)
- case NeverReturns:
- both.Add(u)
- }
- }
- }
- }
-
- // depth-first search trying to find a path to the exit block that
- // doesn't cross any of the blacklisted blocks
- seen := NewBlockSet(len(fn.Blocks))
- var findPath func(root *BasicBlock, bl *BlockSet) bool
- findPath = func(root *BasicBlock, bl *BlockSet) bool {
- if root == fn.Exit {
- return true
- }
- if seen.Has(root) {
- return false
- }
- if bl.Has(root) {
- return false
- }
- seen.Add(root)
- for _, succ := range root.Succs {
- if findPath(succ, bl) {
- return true
- }
- }
- return false
- }
- findPathEntry := func(root *BasicBlock, bl *BlockSet) bool {
- if bl.Num() == 0 {
- return true
- }
- seen.Clear()
- return findPath(root, bl)
- }
-
- if !findPathEntry(fn.Blocks[0], exits) {
- fn.NoReturn = AlwaysExits
- } else if !recovers {
- // Only consider unwinding and "never returns" if we don't
- // call recover. If we do call recover, then panics don't
- // bubble up the stack.
-
- // TODO(dh): the position of the defer matters. If we
- // unconditionally terminate before we defer a recover, then
- // the recover is ineffective.
-
- if !findPathEntry(fn.Blocks[0], unwinds) {
- fn.NoReturn = AlwaysUnwinds
- } else if !findPathEntry(fn.Blocks[0], both) {
- fn.NoReturn = NeverReturns
- }
- }
-}
-
-func (b *builder) addUnreachables(fn *Function) {
- var unreachable *BasicBlock
-
- for _, bb := range fn.Blocks {
- instrLoop:
- for i, instr := range bb.Instrs {
- if instr, ok := instr.(*Call); ok {
- var call *Function
- switch v := instr.Common().Value.(type) {
- case *Function:
- call = v
- case *MakeClosure:
- call = v.Fn.(*Function)
- }
- if call == nil {
- continue
- }
- if call.Package() == fn.Package() {
- // make sure we have information on all functions in this package
- b.buildFunction(call)
- }
- switch call.NoReturn {
- case AlwaysExits:
- // This call will cause the process to terminate.
- // Remove remaining instructions in the block and
- // replace any control flow with Unreachable.
- for _, succ := range bb.Succs {
- succ.removePred(bb)
- }
- bb.Succs = bb.Succs[:0]
-
- bb.Instrs = bb.Instrs[:i+1]
- bb.emit(new(Unreachable), instr.Source())
- addEdge(bb, fn.Exit)
- break instrLoop
-
- case AlwaysUnwinds:
- // This call will cause the goroutine to terminate
- // and defers to run (i.e. a panic or
- // runtime.Goexit). Remove remaining instructions
- // in the block and replace any control flow with
- // an unconditional jump to the exit block.
- for _, succ := range bb.Succs {
- succ.removePred(bb)
- }
- bb.Succs = bb.Succs[:0]
-
- bb.Instrs = bb.Instrs[:i+1]
- bb.emit(new(Jump), instr.Source())
- addEdge(bb, fn.Exit)
- break instrLoop
-
- case NeverReturns:
- // This call will either cause the goroutine to
- // terminate, or the process to terminate. Remove
- // remaining instructions in the block and replace
- // any control flow with a conditional jump to
- // either the exit block, or Unreachable.
- for _, succ := range bb.Succs {
- succ.removePred(bb)
- }
- bb.Succs = bb.Succs[:0]
-
- bb.Instrs = bb.Instrs[:i+1]
- var c Call
- c.Call.Value = &Builtin{
- name: "ir:noreturnWasPanic",
- sig: types.NewSignatureType(nil, nil, nil,
- types.NewTuple(),
- types.NewTuple(anonVar(types.Typ[types.Bool])),
- false,
- ),
- }
- c.setType(types.Typ[types.Bool])
-
- if unreachable == nil {
- unreachable = fn.newBasicBlock("unreachable")
- unreachable.emit(&Unreachable{}, nil)
- addEdge(unreachable, fn.Exit)
- }
-
- bb.emit(&c, instr.Source())
- bb.emit(&If{Cond: &c}, instr.Source())
- addEdge(bb, fn.Exit)
- addEdge(bb, unreachable)
- break instrLoop
- }
- }
- }
- }
-}
diff --git a/vendor/honnef.co/go/tools/go/ir/html.go b/vendor/honnef.co/go/tools/go/ir/html.go
index ae502db4e..86b2a63de 100644
--- a/vendor/honnef.co/go/tools/go/ir/html.go
+++ b/vendor/honnef.co/go/tools/go/ir/html.go
@@ -93,10 +93,7 @@ func fprintFunc(p funcPrinter, f *Function) {
// p.startBlock(b, reachable[b.Index])
p.startBlock(b, true)
- end := len(b.Instrs) - 1
- if end < 0 {
- end = 0
- }
+ end := max(len(b.Instrs)-1, 0)
for _, v := range b.Instrs[:end] {
if _, ok := v.(*DebugRef); !ok {
p.value(v, l[v.ID()])
@@ -784,7 +781,7 @@ func (w *HTMLWriter) WriteColumn(phase, title, class, html string) {
w.WriteString("")
}
-func (w *HTMLWriter) Printf(msg string, v ...interface{}) {
+func (w *HTMLWriter) Printf(msg string, v ...any) {
if _, err := fmt.Fprintf(w.w, msg, v...); err != nil {
log.Fatalf("%v", err)
}
@@ -822,7 +819,8 @@ func valueLongHTML(v Node) string {
// but a little bit might be valuable.
// We already have visual noise in the form of punctuation
// maybe we could replace some of that with formatting.
- s := fmt.Sprintf("", v.ID())
+ var s strings.Builder
+ s.WriteString(fmt.Sprintf("", v.ID()))
linenumber := "(?) "
if v.Pos().IsValid() {
@@ -830,22 +828,22 @@ func valueLongHTML(v Node) string {
linenumber = fmt.Sprintf("(%d) ", line, line)
}
- s += fmt.Sprintf("%s %s = %s", valueHTML(v), linenumber, opName(v))
+ s.WriteString(fmt.Sprintf("%s %s = %s", valueHTML(v), linenumber, opName(v)))
if v, ok := v.(Value); ok {
- s += " <" + html.EscapeString(v.Type().String()) + ">"
+ s.WriteString(" <" + html.EscapeString(v.Type().String()) + ">")
}
switch v := v.(type) {
case *Parameter:
- s += fmt.Sprintf(" {%s}", html.EscapeString(v.name))
+ s.WriteString(fmt.Sprintf(" {%s}", html.EscapeString(v.name)))
case *BinOp:
- s += fmt.Sprintf(" {%s}", html.EscapeString(v.Op.String()))
+ s.WriteString(fmt.Sprintf(" {%s}", html.EscapeString(v.Op.String())))
case *UnOp:
- s += fmt.Sprintf(" {%s}", html.EscapeString(v.Op.String()))
+ s.WriteString(fmt.Sprintf(" {%s}", html.EscapeString(v.Op.String())))
case *Extract:
name := v.Tuple.Type().(*types.Tuple).At(v.Index).Name()
- s += fmt.Sprintf(" [%d] (%s)", v.Index, name)
+ s.WriteString(fmt.Sprintf(" [%d] (%s)", v.Index, name))
case *Field:
st := v.X.Type().Underlying().(*types.Struct)
// Be robust against a bad index.
@@ -853,7 +851,7 @@ func valueLongHTML(v Node) string {
if 0 <= v.Field && v.Field < st.NumFields() {
name = st.Field(v.Field).Name()
}
- s += fmt.Sprintf(" [%d] (%s)", v.Field, name)
+ s.WriteString(fmt.Sprintf(" [%d] (%s)", v.Field, name))
case *FieldAddr:
st := deref(v.X.Type()).Underlying().(*types.Struct)
// Be robust against a bad index.
@@ -862,27 +860,27 @@ func valueLongHTML(v Node) string {
name = st.Field(v.Field).Name()
}
- s += fmt.Sprintf(" [%d] (%s)", v.Field, name)
+ s.WriteString(fmt.Sprintf(" [%d] (%s)", v.Field, name))
case *Recv:
- s += fmt.Sprintf(" {%t}", v.CommaOk)
+ s.WriteString(fmt.Sprintf(" {%t}", v.CommaOk))
case *Call:
if v.Common().IsInvoke() {
- s += fmt.Sprintf(" {%s}", html.EscapeString(v.Common().Method.FullName()))
+ s.WriteString(fmt.Sprintf(" {%s}", html.EscapeString(v.Common().Method.FullName())))
}
case *Const:
if v.Value == nil {
- s += " {<nil>}"
+ s.WriteString(" {<nil>}")
} else {
- s += fmt.Sprintf(" {%s}", html.EscapeString(v.Value.String()))
+ s.WriteString(fmt.Sprintf(" {%s}", html.EscapeString(v.Value.String())))
}
case *Sigma:
- s += fmt.Sprintf(" [#%s]", v.From)
+ s.WriteString(fmt.Sprintf(" [#%s]", v.From))
}
for _, a := range v.Operands(nil) {
- s += fmt.Sprintf(" %s", valueHTML(*a))
+ s.WriteString(fmt.Sprintf(" %s", valueHTML(*a)))
}
if v, ok := v.(Instruction); ok {
- s += fmt.Sprintf(" (%s)", v.Comment())
+ s.WriteString(fmt.Sprintf(" (%s)", v.Comment()))
}
// OPT(dh): we're calling namedValues many times on the same function.
@@ -897,11 +895,11 @@ func valueLongHTML(v Node) string {
}
}
if len(names) != 0 {
- s += " (" + strings.Join(names, ", ") + ")"
+ s.WriteString(" (" + strings.Join(names, ", ") + ")")
}
- s += " "
- return s
+ s.WriteString(" ")
+ return s.String()
}
func blockHTML(b *BasicBlock) string {
@@ -920,7 +918,8 @@ func blockLongHTML(b *BasicBlock) string {
kind = opName(term)
}
// TODO: improve this for HTML?
- s := fmt.Sprintf("%s ", b.Index, kind)
+ var s strings.Builder
+ s.WriteString(fmt.Sprintf("%s ", b.Index, kind))
if term != nil {
ops := term.Operands(nil)
@@ -929,16 +928,16 @@ func blockLongHTML(b *BasicBlock) string {
for _, op := range ops {
ss = append(ss, valueHTML(*op))
}
- s += " " + strings.Join(ss, ", ")
+ s.WriteString(" " + strings.Join(ss, ", "))
}
}
if len(b.Succs) > 0 {
- s += " →" // right arrow
+ s.WriteString(" →") // right arrow
for _, c := range b.Succs {
- s += " " + blockHTML(c)
+ s.WriteString(" " + blockHTML(c))
}
}
- return s
+ return s.String()
}
func funcHTML(f *Function, phase string, dot *dotWriter) string {
diff --git a/vendor/honnef.co/go/tools/go/ir/irutil/util.go b/vendor/honnef.co/go/tools/go/ir/irutil/util.go
index d2f10948d..9fed28bb8 100644
--- a/vendor/honnef.co/go/tools/go/ir/irutil/util.go
+++ b/vendor/honnef.co/go/tools/go/ir/irutil/util.go
@@ -2,6 +2,7 @@ package irutil
import (
"go/types"
+ "slices"
"strings"
"honnef.co/go/tools/go/ir"
@@ -107,12 +108,7 @@ func IsCallTo(call *ir.CallCommon, name string) bool { return CallName(call) ==
func IsCallToAny(call *ir.CallCommon, names ...string) bool {
q := CallName(call)
- for _, name := range names {
- if q == name {
- return true
- }
- }
- return false
+ return slices.Contains(names, q)
}
func FilterDebug(instr []ir.Instruction) []ir.Instruction {
diff --git a/vendor/honnef.co/go/tools/go/ir/lift.go b/vendor/honnef.co/go/tools/go/ir/lift.go
index 08be0d371..c2da8774a 100644
--- a/vendor/honnef.co/go/tools/go/ir/lift.go
+++ b/vendor/honnef.co/go/tools/go/ir/lift.go
@@ -901,10 +901,8 @@ func liftable(alloc *Alloc, instructions BlockMap[liftInstructions]) bool {
// Don't lift result values in functions that defer
// calls that may recover from panic.
if fn.hasDefer {
- for _, nr := range fn.results {
- if nr == alloc {
- return false
- }
+ if slices.Contains(fn.results, alloc) {
+ return false
}
}
diff --git a/vendor/honnef.co/go/tools/go/ir/methods.go b/vendor/honnef.co/go/tools/go/ir/methods.go
index f8607b03d..082029da3 100644
--- a/vendor/honnef.co/go/tools/go/ir/methods.go
+++ b/vendor/honnef.co/go/tools/go/ir/methods.go
@@ -171,15 +171,15 @@ func (prog *Program) needMethods(T types.Type, skip bool) {
if !mset.complete {
mset.complete = true
n := tmset.Len()
- for i := 0; i < n; i++ {
+ for i := range n {
prog.addMethod(mset, tmset.At(i))
}
}
}
// Recursion over signatures of each method.
- for i := 0; i < tmset.Len(); i++ {
- sig := tmset.At(i).Type().(*types.Signature)
+ for method := range tmset.Methods() {
+ sig := method.Type().(*types.Signature)
prog.needMethods(sig.Params(), false)
prog.needMethods(sig.Results(), false)
}
diff --git a/vendor/honnef.co/go/tools/go/ir/mode.go b/vendor/honnef.co/go/tools/go/ir/mode.go
index 15b5a33f7..8a87a605c 100644
--- a/vendor/honnef.co/go/tools/go/ir/mode.go
+++ b/vendor/honnef.co/go/tools/go/ir/mode.go
@@ -101,4 +101,4 @@ func (m *BuilderMode) Set(s string) error {
}
// Get returns m.
-func (m BuilderMode) Get() interface{} { return m }
+func (m BuilderMode) Get() any { return m }
diff --git a/vendor/honnef.co/go/tools/go/ir/print.go b/vendor/honnef.co/go/tools/go/ir/print.go
index b30753dff..f2468763a 100644
--- a/vendor/honnef.co/go/tools/go/ir/print.go
+++ b/vendor/honnef.co/go/tools/go/ir/print.go
@@ -347,7 +347,7 @@ func (v *CompositeValue) String() string {
fmt.Fprint(&b, " [none]")
} else {
// Some values provided
- bits := []byte(fmt.Sprintf("%0*b", len(v.Values), &v.Bitmap))
+ bits := fmt.Appendf(nil, "%0*b", len(v.Values), &v.Bitmap)
for i := 0; i < len(bits)/2; i++ {
o := len(bits) - 1 - i
bits[i], bits[o] = bits[o], bits[i]
@@ -453,7 +453,7 @@ func (s *MapUpdate) String() string {
func (s *DebugRef) String() string {
p := s.Parent().Prog.Fset.Position(s.Pos())
- var descr interface{}
+ var descr any
if s.object != nil {
descr = s.object // e.g. "var x int"
} else {
diff --git a/vendor/honnef.co/go/tools/go/ir/sanity.go b/vendor/honnef.co/go/tools/go/ir/sanity.go
index 4bbd711fa..5663b4cf2 100644
--- a/vendor/honnef.co/go/tools/go/ir/sanity.go
+++ b/vendor/honnef.co/go/tools/go/ir/sanity.go
@@ -14,6 +14,7 @@ import (
"go/types"
"io"
"os"
+ "slices"
"strings"
"honnef.co/go/tools/go/types/typeutil"
@@ -50,7 +51,7 @@ func mustSanityCheck(fn *Function, reporter io.Writer) {
}
}
-func (s *sanity) diagnostic(prefix, format string, args ...interface{}) {
+func (s *sanity) diagnostic(prefix, format string, args ...any) {
fmt.Fprintf(s.reporter, "%s: function %s", prefix, s.fn)
if s.block != nil {
fmt.Fprintf(s.reporter, ", block %s", s.block)
@@ -60,12 +61,12 @@ func (s *sanity) diagnostic(prefix, format string, args ...interface{}) {
io.WriteString(s.reporter, "\n")
}
-func (s *sanity) errorf(format string, args ...interface{}) {
+func (s *sanity) errorf(format string, args ...any) {
s.insane = true
s.diagnostic("Error", format, args...)
}
-func (s *sanity) warnf(format string, args ...interface{}) {
+func (s *sanity) warnf(format string, args ...any) {
s.diagnostic("Warning", format, args...)
}
@@ -126,17 +127,8 @@ func (s *sanity) checkInstr(idx int, instr Instruction) {
}
case *Alloc:
- if !instr.Heap {
- found := false
- for _, l := range s.fn.Locals {
- if l == instr {
- found = true
- break
- }
- }
- if !found {
- s.errorf("local alloc %s = %s does not appear in Function.Locals", instr.Name(), instr)
- }
+ if !instr.Heap && !slices.Contains(s.fn.Locals, instr) {
+ s.errorf("local alloc %s = %s does not appear in Function.Locals", instr.Name(), instr)
}
case *BinOp:
@@ -306,14 +298,7 @@ func (s *sanity) checkBlock(b *BasicBlock, index int) {
// Check predecessor and successor relations are dual,
// and that all blocks in CFG belong to same function.
for _, a := range b.Preds {
- found := false
- for _, bb := range a.Succs {
- if bb == b {
- found = true
- break
- }
- }
- if !found {
+ if !slices.Contains(a.Succs, b) {
s.errorf("expected successor edge in predecessor %s; found only: %s", a, a.Succs)
}
if a.parent != s.fn {
@@ -321,14 +306,7 @@ func (s *sanity) checkBlock(b *BasicBlock, index int) {
}
}
for _, c := range b.Succs {
- found := false
- for _, bb := range c.Preds {
- if bb == b {
- found = true
- break
- }
- }
- if !found {
+ if !slices.Contains(c.Preds, b) {
s.errorf("expected predecessor edge in successor %s; found only: %s", c, c.Preds)
}
if c.parent != s.fn {
diff --git a/vendor/honnef.co/go/tools/go/ir/ssa.go b/vendor/honnef.co/go/tools/go/ir/ssa.go
index 6061b6085..cd8ae0120 100644
--- a/vendor/honnef.co/go/tools/go/ir/ssa.go
+++ b/vendor/honnef.co/go/tools/go/ir/ssa.go
@@ -40,6 +40,8 @@ type Program struct {
methodSets typeutil.Map[*methodSet] // maps type to its concrete methodSet
runtimeTypes typeutil.Map[bool] // types for which rtypes are needed
canon typeutil.Map[types.Type] // type canonicalization map
+
+ noReturn func(*types.Func) bool
}
// A Package is a single analyzed Go package containing Members for
@@ -386,7 +388,6 @@ type Function struct {
Exit *BasicBlock // The function's exit block
AnonFuncs []*Function // anonymous functions (from FuncLit, RangeStmt) directly beneath this one
referrers []Instruction // referring instructions (iff Parent() != nil)
- NoReturn NoReturn // Calling this function will always terminate control flow.
goversion string // Go version of syntax (NB: init is special)
@@ -429,8 +430,7 @@ func (m *instanceWrapperMap) At(key *types.TypeList) *Function {
}
var hash uint32
- for i := 0; i < key.Len(); i++ {
- t := key.At(i)
+ for t := range key.Types() {
hash += m.h.Hash(t)
}
@@ -452,8 +452,7 @@ func (m *instanceWrapperMap) Set(key *types.TypeList, val *Function) {
}
var hash uint32
- for i := 0; i < key.Len(); i++ {
- t := key.At(i)
+ for t := range key.Types() {
hash += m.h.Hash(t)
}
for i, e := range m.entries[hash] {
@@ -473,15 +472,6 @@ func (m *instanceWrapperMap) Len() int {
return m.len
}
-type NoReturn uint8
-
-const (
- Returns NoReturn = iota
- AlwaysExits
- AlwaysUnwinds
- NeverReturns
-)
-
type constValue struct {
c Constant
idx int
diff --git a/vendor/honnef.co/go/tools/go/ir/util.go b/vendor/honnef.co/go/tools/go/ir/util.go
index 3a0e3ad92..97fe9c5f5 100644
--- a/vendor/honnef.co/go/tools/go/ir/util.go
+++ b/vendor/honnef.co/go/tools/go/ir/util.go
@@ -71,7 +71,7 @@ func recvType(obj *types.Func) types.Type {
// returns a closure that prints the corresponding "end" message.
// Call using 'defer logStack(...)()' to show builder stack on panic.
// Don't forget trailing parens!
-func logStack(format string, args ...interface{}) func() {
+func logStack(format string, args ...any) func() {
msg := fmt.Sprintf(format, args...)
io.WriteString(os.Stderr, msg)
io.WriteString(os.Stderr, "\n")
diff --git a/vendor/honnef.co/go/tools/go/ir/wrappers.go b/vendor/honnef.co/go/tools/go/ir/wrappers.go
index d5afb2cda..6b358a7c6 100644
--- a/vendor/honnef.co/go/tools/go/ir/wrappers.go
+++ b/vendor/honnef.co/go/tools/go/ir/wrappers.go
@@ -313,8 +313,7 @@ func makeInstance(prog *Program, fn *Function, sig *types.Signature, targs *type
c.Call.Args = append(c.Call.Args, changeType(arg, fn.Signature.Params().At(i).Type()))
}
}
- for i := 0; i < targs.Len(); i++ {
- arg := targs.At(i)
+ for arg := range targs.Types() {
c.Call.TypeArgs = append(c.Call.TypeArgs, arg)
}
results := w.emit(&c, nil)
diff --git a/vendor/honnef.co/go/tools/go/types/typeutil/typeparams.go b/vendor/honnef.co/go/tools/go/types/typeutil/typeparams.go
index 2bf6ec609..15b20a74f 100644
--- a/vendor/honnef.co/go/tools/go/types/typeutil/typeparams.go
+++ b/vendor/honnef.co/go/tools/go/types/typeutil/typeparams.go
@@ -3,6 +3,7 @@ package typeutil
import (
"errors"
"go/types"
+ "slices"
"golang.org/x/exp/typeparams"
)
@@ -86,12 +87,7 @@ func (ts TypeSet) All(fn func(*types.Term) bool) bool {
// Any calls fn for each term in the type set and reports whether any invocation returned true.
// It stops after the first call that returned true.
func (ts TypeSet) Any(fn func(*types.Term) bool) bool {
- for _, term := range ts.Terms {
- if fn(term) {
- return true
- }
- }
- return false
+ return slices.ContainsFunc(ts.Terms, fn)
}
// All is a wrapper for NewTypeSet(typ).All(fn).
diff --git a/vendor/honnef.co/go/tools/go/types/typeutil/upstream.go b/vendor/honnef.co/go/tools/go/types/typeutil/upstream.go
index 04d8c21ba..064964e98 100644
--- a/vendor/honnef.co/go/tools/go/types/typeutil/upstream.go
+++ b/vendor/honnef.co/go/tools/go/types/typeutil/upstream.go
@@ -40,7 +40,7 @@ func (m *Map[V]) At(key types.Type) (V, bool) {
func (m *Map[V]) Set(key types.Type, value V) { m.m.Set(key, value) }
func (m *Map[V]) Len() int { return m.m.Len() }
func (m *Map[V]) Iterate(f func(key types.Type, value V)) {
- ff := func(key types.Type, value interface{}) {
+ ff := func(key types.Type, value any) {
f(key, value.(V))
}
m.m.Iterate(ff)
diff --git a/vendor/honnef.co/go/tools/go/types/typeutil/util.go b/vendor/honnef.co/go/tools/go/types/typeutil/util.go
index ef11564c7..bb506622b 100644
--- a/vendor/honnef.co/go/tools/go/types/typeutil/util.go
+++ b/vendor/honnef.co/go/tools/go/types/typeutil/util.go
@@ -10,7 +10,7 @@ import (
)
var bufferPool = &sync.Pool{
- New: func() interface{} {
+ New: func() any {
buf := bytes.NewBuffer(nil)
buf.Grow(64)
return buf
diff --git a/vendor/honnef.co/go/tools/internal/analysisinternal/typeindex/typeindex.go b/vendor/honnef.co/go/tools/internal/analysisinternal/typeindex/typeindex.go
new file mode 100644
index 000000000..44d207c0c
--- /dev/null
+++ b/vendor/honnef.co/go/tools/internal/analysisinternal/typeindex/typeindex.go
@@ -0,0 +1,33 @@
+// Copyright 2025 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 typeindex defines an analyzer that provides a
+// [golang.org/x/tools/internal/typesinternal/typeindex.Index].
+//
+// Like [golang.org/x/tools/go/analysis/passes/inspect], it is
+// intended to be used as a helper by other analyzers; it reports no
+// diagnostics of its own.
+package typeindex
+
+import (
+ "reflect"
+
+ "golang.org/x/tools/go/analysis"
+ "golang.org/x/tools/go/analysis/passes/inspect"
+ "golang.org/x/tools/go/ast/inspector"
+ "honnef.co/go/tools/internal/typesinternal/typeindex"
+)
+
+var Analyzer = &analysis.Analyzer{
+ Name: "typeindex",
+ Doc: "indexes of type information for later passes",
+ URL: "https://pkg.go.dev/golang.org/x/tools/internal/analysisinternal/typeindex",
+ Run: func(pass *analysis.Pass) (any, error) {
+ inspect := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector)
+ return typeindex.New(inspect, pass.Pkg, pass.TypesInfo), nil
+ },
+ RunDespiteErrors: true,
+ Requires: []*analysis.Analyzer{inspect.Analyzer},
+ ResultType: reflect.TypeFor[*typeindex.Index](),
+}
diff --git a/vendor/honnef.co/go/tools/internal/passes/buildir/buildir.go b/vendor/honnef.co/go/tools/internal/passes/buildir/buildir.go
index dc26a6721..5db18e305 100644
--- a/vendor/honnef.co/go/tools/internal/passes/buildir/buildir.go
+++ b/vendor/honnef.co/go/tools/internal/passes/buildir/buildir.go
@@ -11,27 +11,25 @@
package buildir
import (
- "go/ast"
"go/types"
"reflect"
"honnef.co/go/tools/go/ir"
"golang.org/x/tools/go/analysis"
+ "golang.org/x/tools/go/analysis/passes/ctrlflow"
)
-type noReturn struct {
- Kind ir.NoReturn
-}
-
-func (*noReturn) AFact() {}
+var Debug = struct {
+ Mode ir.BuilderMode
+}{}
var Analyzer = &analysis.Analyzer{
Name: "buildir",
Doc: "build IR for later passes",
Run: run,
- ResultType: reflect.TypeOf(new(IR)),
- FactTypes: []analysis.Fact{new(noReturn)},
+ ResultType: reflect.TypeFor[*IR](),
+ Requires: []*analysis.Analyzer{ctrlflow.Analyzer},
}
// IR provides intermediate representation for all the
@@ -41,7 +39,9 @@ type IR struct {
SrcFuncs []*ir.Function
}
-func run(pass *analysis.Pass) (interface{}, error) {
+func run(pass *analysis.Pass) (any, error) {
+ cfgs := pass.ResultOf[ctrlflow.Analyzer].(*ctrlflow.CFGs)
+
// Plundered from ssautil.BuildPackage.
// We must create a new Program for each Package because the
@@ -55,9 +55,14 @@ func run(pass *analysis.Pass) (interface{}, error) {
// to a single Program.
mode := ir.GlobalDebug
+ if Debug.Mode != 0 {
+ mode = Debug.Mode
+ }
prog := ir.NewProgram(pass.Fset, mode)
+ prog.SetNoReturn(cfgs.NoReturn)
+
// Create IR packages for all imports.
// Order is not significant.
created := make(map[*types.Package]bool)
@@ -66,15 +71,7 @@ func run(pass *analysis.Pass) (interface{}, error) {
for _, p := range pkgs {
if !created[p] {
created[p] = true
- irpkg := prog.CreatePackage(p, nil, nil, true)
- for _, fn := range irpkg.Functions {
- if ast.IsExported(fn.Name()) {
- var noRet noReturn
- if pass.ImportObjectFact(fn.Object(), &noRet) {
- fn.NoReturn = noRet.Kind
- }
- }
- }
+ prog.CreatePackage(p, nil, nil, true)
createAll(p.Imports())
}
}
@@ -98,9 +95,6 @@ func run(pass *analysis.Pass) (interface{}, error) {
}
for _, fn := range irpkg.Functions {
addAnons(fn)
- if fn.NoReturn > 0 {
- pass.ExportObjectFact(fn.Object(), &noReturn{fn.NoReturn})
- }
}
return &IR{Pkg: irpkg, SrcFuncs: funcs}, nil
diff --git a/vendor/honnef.co/go/tools/internal/sharedcheck/lint.go b/vendor/honnef.co/go/tools/internal/sharedcheck/lint.go
index b78899ab5..f07496dd2 100644
--- a/vendor/honnef.co/go/tools/internal/sharedcheck/lint.go
+++ b/vendor/honnef.co/go/tools/internal/sharedcheck/lint.go
@@ -21,7 +21,7 @@ import (
"golang.org/x/tools/go/analysis/passes/inspect"
)
-func CheckRangeStringRunes(pass *analysis.Pass) (interface{}, error) {
+func CheckRangeStringRunes(pass *analysis.Pass) (any, error) {
for _, fn := range pass.ResultOf[buildir.Analyzer].(*buildir.IR).SrcFuncs {
cb := func(node ast.Node) bool {
rng, ok := node.(*ast.RangeStmt)
@@ -94,7 +94,7 @@ func CheckRangeStringRunes(pass *analysis.Pass) (interface{}, error) {
// - variables named the blank identifier – a pattern used to confirm the types of variables
// - untyped expressions on the rhs – the explicitness might aid readability
func RedundantTypeInDeclarationChecker(verb string, flagHelpfulTypes bool) *analysis.Analyzer {
- fn := func(pass *analysis.Pass) (interface{}, error) {
+ fn := func(pass *analysis.Pass) (any, error) {
eval := func(expr ast.Expr) (types.TypeAndValue, error) {
info := &types.Info{
Types: map[ast.Expr]types.TypeAndValue{},
diff --git a/vendor/honnef.co/go/tools/internal/typesinternal/typeindex/typeindex.go b/vendor/honnef.co/go/tools/internal/typesinternal/typeindex/typeindex.go
new file mode 100644
index 000000000..fccc2ba72
--- /dev/null
+++ b/vendor/honnef.co/go/tools/internal/typesinternal/typeindex/typeindex.go
@@ -0,0 +1,226 @@
+// Copyright 2025 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 typeindex provides an [Index] of type information for a
+// package, allowing efficient lookup of, say, whether a given symbol
+// is referenced and, if so, where from; or of the [inspector.Cursor] for
+// the declaration of a particular [types.Object] symbol.
+package typeindex
+
+import (
+ "encoding/binary"
+ "go/ast"
+ "go/types"
+ "iter"
+
+ "golang.org/x/tools/go/ast/edge"
+ "golang.org/x/tools/go/ast/inspector"
+ "golang.org/x/tools/go/types/typeutil"
+)
+
+// IsPackageLevel reports whether obj is a package-level symbol.
+func IsPackageLevel(obj types.Object) bool {
+ return obj.Pkg() != nil && obj.Parent() == obj.Pkg().Scope()
+}
+
+// New constructs an Index for the package of type-annotated syntax
+//
+// TODO(adonovan): accept a FileSet too?
+// We regret not requiring one in inspector.New.
+func New(inspect *inspector.Inspector, pkg *types.Package, info *types.Info) *Index {
+ ix := &Index{
+ inspect: inspect,
+ info: info,
+ packages: make(map[string]*types.Package),
+ def: make(map[types.Object]inspector.Cursor),
+ uses: make(map[types.Object]*uses),
+ }
+
+ addPackage := func(pkg2 *types.Package) {
+ if pkg2 != nil && pkg2 != pkg {
+ ix.packages[pkg2.Path()] = pkg2
+ }
+ }
+
+ for cur := range inspect.Root().Preorder((*ast.ImportSpec)(nil), (*ast.Ident)(nil)) {
+ switch n := cur.Node().(type) {
+ case *ast.ImportSpec:
+ // Index direct imports, including blank ones.
+ if pkgname := info.PkgNameOf(n); pkgname != nil {
+ addPackage(pkgname.Imported())
+ }
+
+ case *ast.Ident:
+ // Index all defining and using identifiers.
+ if obj := info.Defs[n]; obj != nil {
+ ix.def[obj] = cur
+ }
+
+ if obj := info.Uses[n]; obj != nil {
+ // Index indirect dependencies (via fields and methods).
+ if !IsPackageLevel(obj) {
+ addPackage(obj.Pkg())
+ }
+
+ us, ok := ix.uses[obj]
+ if !ok {
+ us = &uses{}
+ us.code = us.initial[:0]
+ ix.uses[obj] = us
+ }
+ delta := cur.Index() - us.last
+ if delta < 0 {
+ panic("non-monotonic")
+ }
+ us.code = binary.AppendUvarint(us.code, uint64(delta))
+ us.last = cur.Index()
+ }
+ }
+ }
+ return ix
+}
+
+// An Index holds an index mapping [types.Object] symbols to their syntax.
+// In effect, it is the inverse of [types.Info].
+type Index struct {
+ inspect *inspector.Inspector
+ info *types.Info
+ packages map[string]*types.Package // packages of all symbols referenced from this package
+ def map[types.Object]inspector.Cursor // Cursor of *ast.Ident that defines the Object
+ uses map[types.Object]*uses // Cursors of *ast.Idents that use the Object
+}
+
+// A uses holds the list of Cursors of Idents that use a given symbol.
+//
+// The Uses map of [types.Info] is substantial, so it pays to compress
+// its inverse mapping here, both in space and in CPU due to reduced
+// allocation. A Cursor is 2 words; a Cursor.Index is 4 bytes; but
+// since Cursors are naturally delivered in ascending order, we can
+// use varint-encoded deltas at a cost of only ~1.7-2.2 bytes per use.
+//
+// Many variables have only one or two uses, so their encoded uses may
+// fit in the 4 bytes of initial, saving further CPU and space
+// essentially for free since the struct's size class is 4 words.
+type uses struct {
+ code []byte // varint-encoded deltas of successive Cursor.Index values
+ last int32 // most recent Cursor.Index value; used during encoding
+ initial [4]byte // use slack in size class as initial space for code
+}
+
+// Uses returns the sequence of Cursors of [*ast.Ident]s in this package
+// that refer to obj. If obj is nil, the sequence is empty.
+func (ix *Index) Uses(obj types.Object) iter.Seq[inspector.Cursor] {
+ return func(yield func(inspector.Cursor) bool) {
+ if uses := ix.uses[obj]; uses != nil {
+ var last int32
+ for code := uses.code; len(code) > 0; {
+ delta, n := binary.Uvarint(code)
+ last += int32(delta)
+ if !yield(ix.inspect.At(last)) {
+ return
+ }
+ code = code[n:]
+ }
+ }
+ }
+}
+
+// Used reports whether any of the specified objects are used, in
+// other words, obj != nil && Uses(obj) is non-empty for some obj in objs.
+//
+// (This treatment of nil allows Used to be called directly on the
+// result of [Index.Object] so that analyzers can conveniently skip
+// packages that don't use a symbol of interest.)
+func (ix *Index) Used(objs ...types.Object) bool {
+ for _, obj := range objs {
+ if obj != nil && ix.uses[obj] != nil {
+ return true
+ }
+ }
+ return false
+}
+
+// Def returns the Cursor of the [*ast.Ident] in this package
+// that declares the specified object, if any.
+func (ix *Index) Def(obj types.Object) (inspector.Cursor, bool) {
+ cur, ok := ix.def[obj]
+ return cur, ok
+}
+
+// Package returns the package of the specified path,
+// or nil if it is not referenced from this package.
+func (ix *Index) Package(path string) *types.Package {
+ return ix.packages[path]
+}
+
+// Object returns the package-level symbol name within the package of
+// the specified path, or nil if the package or symbol does not exist
+// or is not visible from this package.
+func (ix *Index) Object(path, name string) types.Object {
+ if pkg := ix.Package(path); pkg != nil {
+ return pkg.Scope().Lookup(name)
+ }
+ return nil
+}
+
+// Selection returns the named method or field belonging to the
+// package-level type returned by Object(path, typename).
+func (ix *Index) Selection(path, typename, name string) types.Object {
+ if obj := ix.Object(path, typename); obj != nil {
+ if tname, ok := obj.(*types.TypeName); ok {
+ obj, _, _ := types.LookupFieldOrMethod(tname.Type(), true, obj.Pkg(), name)
+ return obj
+ }
+ }
+ return nil
+}
+
+// Calls returns the sequence of cursors for *ast.CallExpr nodes that
+// call the specified callee, as defined by [typeutil.Callee].
+// If callee is nil, the sequence is empty.
+func (ix *Index) Calls(callee types.Object) iter.Seq[inspector.Cursor] {
+ return func(yield func(inspector.Cursor) bool) {
+ for cur := range ix.Uses(callee) {
+ ek, _ := cur.ParentEdge()
+
+ // The call may be of the form f() or x.f(),
+ // optionally with parens; ascend from f to call.
+ //
+ // It is tempting but wrong to use the first
+ // CallExpr ancestor: we have to make sure the
+ // ident is in the CallExpr.Fun position, otherwise
+ // f(f, f) would have two spurious matches.
+ // Avoiding Enclosing is also significantly faster.
+
+ // inverse unparen: f -> (f)
+ for ek == edge.ParenExpr_X {
+ cur = cur.Parent()
+ ek, _ = cur.ParentEdge()
+ }
+
+ // ascend selector: f -> x.f
+ if ek == edge.SelectorExpr_Sel {
+ cur = cur.Parent()
+ ek, _ = cur.ParentEdge()
+ }
+
+ // inverse unparen again
+ for ek == edge.ParenExpr_X {
+ cur = cur.Parent()
+ ek, _ = cur.ParentEdge()
+ }
+
+ // ascend from f or x.f to call
+ if ek == edge.CallExpr_Fun {
+ curCall := cur.Parent()
+ call := curCall.Node().(*ast.CallExpr)
+ if typeutil.Callee(ix.info, call) == callee {
+ if !yield(curCall) {
+ return
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/vendor/honnef.co/go/tools/knowledge/deprecated.go b/vendor/honnef.co/go/tools/knowledge/deprecated.go
index f7dd4fce0..89ff8d9e0 100644
--- a/vendor/honnef.co/go/tools/knowledge/deprecated.go
+++ b/vendor/honnef.co/go/tools/knowledge/deprecated.go
@@ -188,16 +188,22 @@ var StdlibDeprecations = map[string]Deprecation{
"syscall.Syscall6": {"go1.18", "go1.18"},
"syscall.Syscall9": {"go1.18", "go1.18"},
- "reflect.SliceHeader": {"go1.21", "go1.17"},
- "reflect.StringHeader": {"go1.21", "go1.20"},
- "crypto/elliptic.GenerateKey": {"go1.21", "go1.21"},
- "crypto/elliptic.Marshal": {"go1.21", "go1.21"},
- "crypto/elliptic.Unmarshal": {"go1.21", "go1.21"},
- "(*crypto/elliptic.CurveParams).Add": {"go1.21", "go1.21"},
- "(*crypto/elliptic.CurveParams).Double": {"go1.21", "go1.21"},
- "(*crypto/elliptic.CurveParams).IsOnCurve": {"go1.21", "go1.21"},
- "(*crypto/elliptic.CurveParams).ScalarBaseMult": {"go1.21", "go1.21"},
- "(*crypto/elliptic.CurveParams).ScalarMult": {"go1.21", "go1.21"},
+ "reflect.SliceHeader": {"go1.21", "go1.17"},
+ "reflect.StringHeader": {"go1.21", "go1.20"},
+ "crypto/elliptic.GenerateKey": {"go1.21", "go1.21"},
+ "crypto/elliptic.Marshal": {"go1.21", "go1.21"},
+ "crypto/elliptic.Unmarshal": {"go1.21", "go1.21"},
+ "(*crypto/elliptic.CurveParams).Add": {"go1.21", "go1.21"},
+ "(*crypto/elliptic.CurveParams).Double": {"go1.21", "go1.21"},
+ "(*crypto/elliptic.CurveParams).IsOnCurve": {"go1.21", "go1.21"},
+ "(*crypto/elliptic.CurveParams).ScalarBaseMult": {"go1.21", "go1.21"},
+ "(*crypto/elliptic.CurveParams).ScalarMult": {"go1.21", "go1.21"},
+ "(crypto/elliptic.Curve).Add": {"go1.21", "go1.21"},
+ "(crypto/elliptic.Curve).Double": {"go1.21", "go1.21"},
+ "(crypto/elliptic.Curve).IsOnCurve": {"go1.21", "go1.21"},
+ "(crypto/elliptic.Curve).ScalarBaseMult": {"go1.21", "go1.21"},
+ "(crypto/elliptic.Curve).ScalarMult": {"go1.21", "go1.21"},
+
"crypto/rsa.GenerateMultiPrimeKey": {"go1.21", DeprecatedNeverUse},
"(crypto/rsa.PrecomputedValues).CRTValues": {"go1.21", DeprecatedNeverUse},
"(crypto/x509.RevocationList).RevokedCertificates": {"go1.21", "go1.21"},
@@ -217,6 +223,29 @@ var StdlibDeprecations = map[string]Deprecation{
"crypto/cipher.NewCFBDecrypter": {"go1.24", "go1.2"},
"crypto/cipher.NewCFBEncrypter": {"go1.24", "go1.2"},
"crypto/cipher.NewOFB": {"go1.24", "go1.2"},
+
+ "go/ast.FilterFuncDuplicates": {"go1.25", "go1.0"},
+ "go/ast.FilterImportDuplicates": {"go1.25", "go1.0"},
+ "go/ast.FilterUnassociatedComments": {"go1.25", "go1.0"},
+ "go/ast.FilterPackage": {"go1.25", "go1.0"},
+ "go/ast.MergePackageFiles": {"go1.25", "go1.0"},
+ "go/ast.PackageExports": {"go1.25", "go1.0"},
+ "go/ast.MergeMode": {"go1.25", "go1.0"},
+ // Go 1.11 because that's around the time x/tools/go/packages was released.
+ "go/parser.ParseDir": {"go1.25", "go1.11"},
+
+ // Go 1.25 is the first version to provide all of the alternatives mentioned
+ // by the deprecation note.
+ "(crypto/ecdsa.PublicKey).X": {"go1.26", "go1.25"},
+ "(crypto/ecdsa.PublicKey).Y": {"go1.26", "go1.25"},
+ "(crypto/ecdsa.PrivateKey).D": {"go1.26", "go1.25"},
+
+ "crypto/rsa.DecryptPKCS1v15": {"go1.26", DeprecatedNeverUse},
+ "crypto/rsa.DecryptPKCS1v15SessionKey": {"go1.26", DeprecatedNeverUse},
+ "crypto/rsa.PKCS1v15DecryptOptions": {"go1.26", DeprecatedNeverUse},
+ "crypto/rsa.EncryptPKCS1v15": {"go1.26", DeprecatedNeverUse},
+
+ "(net/http/httputil.ReverseProxy).Director": {"go1.26", "go1.20"},
}
-// Last imported from GOROOT/api/go1.24.txt at fadfe2fc80f6b37e99b3e7aa068112ff539717c9.
+// Last imported from GOROOT/api/go1.26.txt at d3ddc4854429185e6e06ca1f7628bb790404abb5.
diff --git a/vendor/honnef.co/go/tools/pattern/convert.go b/vendor/honnef.co/go/tools/pattern/convert.go
index aed3617cd..ae9a0a558 100644
--- a/vendor/honnef.co/go/tools/pattern/convert.go
+++ b/vendor/honnef.co/go/tools/pattern/convert.go
@@ -9,52 +9,52 @@ import (
)
var astTypes = map[string]reflect.Type{
- "Ellipsis": reflect.TypeOf(ast.Ellipsis{}),
- "RangeStmt": reflect.TypeOf(ast.RangeStmt{}),
- "AssignStmt": reflect.TypeOf(ast.AssignStmt{}),
- "IndexExpr": reflect.TypeOf(ast.IndexExpr{}),
- "IndexListExpr": reflect.TypeOf(ast.IndexListExpr{}),
- "Ident": reflect.TypeOf(ast.Ident{}),
- "ValueSpec": reflect.TypeOf(ast.ValueSpec{}),
- "GenDecl": reflect.TypeOf(ast.GenDecl{}),
- "BinaryExpr": reflect.TypeOf(ast.BinaryExpr{}),
- "ForStmt": reflect.TypeOf(ast.ForStmt{}),
- "ArrayType": reflect.TypeOf(ast.ArrayType{}),
- "DeferStmt": reflect.TypeOf(ast.DeferStmt{}),
- "MapType": reflect.TypeOf(ast.MapType{}),
- "ReturnStmt": reflect.TypeOf(ast.ReturnStmt{}),
- "SliceExpr": reflect.TypeOf(ast.SliceExpr{}),
- "StarExpr": reflect.TypeOf(ast.StarExpr{}),
- "UnaryExpr": reflect.TypeOf(ast.UnaryExpr{}),
- "SendStmt": reflect.TypeOf(ast.SendStmt{}),
- "SelectStmt": reflect.TypeOf(ast.SelectStmt{}),
- "ImportSpec": reflect.TypeOf(ast.ImportSpec{}),
- "IfStmt": reflect.TypeOf(ast.IfStmt{}),
- "GoStmt": reflect.TypeOf(ast.GoStmt{}),
- "Field": reflect.TypeOf(ast.Field{}),
- "SelectorExpr": reflect.TypeOf(ast.SelectorExpr{}),
- "StructType": reflect.TypeOf(ast.StructType{}),
- "KeyValueExpr": reflect.TypeOf(ast.KeyValueExpr{}),
- "FuncType": reflect.TypeOf(ast.FuncType{}),
- "FuncLit": reflect.TypeOf(ast.FuncLit{}),
- "FuncDecl": reflect.TypeOf(ast.FuncDecl{}),
- "ChanType": reflect.TypeOf(ast.ChanType{}),
- "CallExpr": reflect.TypeOf(ast.CallExpr{}),
- "CaseClause": reflect.TypeOf(ast.CaseClause{}),
- "CommClause": reflect.TypeOf(ast.CommClause{}),
- "CompositeLit": reflect.TypeOf(ast.CompositeLit{}),
- "EmptyStmt": reflect.TypeOf(ast.EmptyStmt{}),
- "SwitchStmt": reflect.TypeOf(ast.SwitchStmt{}),
- "TypeSwitchStmt": reflect.TypeOf(ast.TypeSwitchStmt{}),
- "TypeAssertExpr": reflect.TypeOf(ast.TypeAssertExpr{}),
- "TypeSpec": reflect.TypeOf(ast.TypeSpec{}),
- "InterfaceType": reflect.TypeOf(ast.InterfaceType{}),
- "BranchStmt": reflect.TypeOf(ast.BranchStmt{}),
- "IncDecStmt": reflect.TypeOf(ast.IncDecStmt{}),
- "BasicLit": reflect.TypeOf(ast.BasicLit{}),
+ "Ellipsis": reflect.TypeFor[ast.Ellipsis](),
+ "RangeStmt": reflect.TypeFor[ast.RangeStmt](),
+ "AssignStmt": reflect.TypeFor[ast.AssignStmt](),
+ "IndexExpr": reflect.TypeFor[ast.IndexExpr](),
+ "IndexListExpr": reflect.TypeFor[ast.IndexListExpr](),
+ "Ident": reflect.TypeFor[ast.Ident](),
+ "ValueSpec": reflect.TypeFor[ast.ValueSpec](),
+ "GenDecl": reflect.TypeFor[ast.GenDecl](),
+ "BinaryExpr": reflect.TypeFor[ast.BinaryExpr](),
+ "ForStmt": reflect.TypeFor[ast.ForStmt](),
+ "ArrayType": reflect.TypeFor[ast.ArrayType](),
+ "DeferStmt": reflect.TypeFor[ast.DeferStmt](),
+ "MapType": reflect.TypeFor[ast.MapType](),
+ "ReturnStmt": reflect.TypeFor[ast.ReturnStmt](),
+ "SliceExpr": reflect.TypeFor[ast.SliceExpr](),
+ "StarExpr": reflect.TypeFor[ast.StarExpr](),
+ "UnaryExpr": reflect.TypeFor[ast.UnaryExpr](),
+ "SendStmt": reflect.TypeFor[ast.SendStmt](),
+ "SelectStmt": reflect.TypeFor[ast.SelectStmt](),
+ "ImportSpec": reflect.TypeFor[ast.ImportSpec](),
+ "IfStmt": reflect.TypeFor[ast.IfStmt](),
+ "GoStmt": reflect.TypeFor[ast.GoStmt](),
+ "Field": reflect.TypeFor[ast.Field](),
+ "SelectorExpr": reflect.TypeFor[ast.SelectorExpr](),
+ "StructType": reflect.TypeFor[ast.StructType](),
+ "KeyValueExpr": reflect.TypeFor[ast.KeyValueExpr](),
+ "FuncType": reflect.TypeFor[ast.FuncType](),
+ "FuncLit": reflect.TypeFor[ast.FuncLit](),
+ "FuncDecl": reflect.TypeFor[ast.FuncDecl](),
+ "ChanType": reflect.TypeFor[ast.ChanType](),
+ "CallExpr": reflect.TypeFor[ast.CallExpr](),
+ "CaseClause": reflect.TypeFor[ast.CaseClause](),
+ "CommClause": reflect.TypeFor[ast.CommClause](),
+ "CompositeLit": reflect.TypeFor[ast.CompositeLit](),
+ "EmptyStmt": reflect.TypeFor[ast.EmptyStmt](),
+ "SwitchStmt": reflect.TypeFor[ast.SwitchStmt](),
+ "TypeSwitchStmt": reflect.TypeFor[ast.TypeSwitchStmt](),
+ "TypeAssertExpr": reflect.TypeFor[ast.TypeAssertExpr](),
+ "TypeSpec": reflect.TypeFor[ast.TypeSpec](),
+ "InterfaceType": reflect.TypeFor[ast.InterfaceType](),
+ "BranchStmt": reflect.TypeFor[ast.BranchStmt](),
+ "IncDecStmt": reflect.TypeFor[ast.IncDecStmt](),
+ "BasicLit": reflect.TypeFor[ast.BasicLit](),
}
-func ASTToNode(node interface{}) Node {
+func ASTToNode(node any) Node {
switch node := node.(type) {
case *ast.File:
panic("cannot convert *ast.File to Node")
@@ -132,7 +132,7 @@ func ASTToNode(node interface{}) Node {
panic(fmt.Sprintf("internal error: unhandled type %T", node))
}
-func NodeToAST(node Node, state State) interface{} {
+func NodeToAST(node Node, state State) any {
switch node := node.(type) {
case Binding:
v, ok := state[node.Name]
diff --git a/vendor/honnef.co/go/tools/pattern/lexer.go b/vendor/honnef.co/go/tools/pattern/lexer.go
index fb72e392b..8ab8f5696 100644
--- a/vendor/honnef.co/go/tools/pattern/lexer.go
+++ b/vendor/honnef.co/go/tools/pattern/lexer.go
@@ -3,10 +3,24 @@ package pattern
import (
"fmt"
"go/token"
+ "iter"
"unicode"
"unicode/utf8"
)
+// lex returns the sequence of tokens in the input.
+func lex(f *token.File, input string) iter.Seq[item] {
+ return func(yield func(item) bool) {
+ lex := &lexer{
+ f: f,
+ input: input,
+ yield: yield,
+ }
+ lex.run()
+ }
+}
+
+// lexer holds the state of a single [lex] iteration.
type lexer struct {
f *token.File
@@ -14,7 +28,8 @@ type lexer struct {
start int
pos int
width int
- items chan item
+
+ yield func(item) bool
}
type itemType int
@@ -79,40 +94,55 @@ func (l *lexer) run() {
for state := lexStart; state != nil; {
state = state(l)
}
- close(l.items)
}
-func (l *lexer) emitValue(t itemType, value string) {
- l.items <- item{t, value, l.start}
+func (l *lexer) emitValue(t itemType, value string) bool {
+ ok := l.yield(item{t, value, l.start})
l.start = l.pos
+ return ok
}
-func (l *lexer) emit(t itemType) {
- l.items <- item{t, l.input[l.start:l.pos], l.start}
+func (l *lexer) emit(t itemType) bool {
+ ok := l.yield(item{t, l.input[l.start:l.pos], l.start})
l.start = l.pos
+ return ok
}
func lexStart(l *lexer) stateFn {
switch r := l.next(); {
case r == eof:
- l.emit(itemEOF)
+ _ = l.emit(itemEOF)
return nil
case unicode.IsSpace(r):
l.ignore()
case r == '(':
- l.emit(itemLeftParen)
+ if !l.emit(itemLeftParen) {
+ return nil
+ }
case r == ')':
- l.emit(itemRightParen)
+ if !l.emit(itemRightParen) {
+ return nil
+ }
case r == '[':
- l.emit(itemLeftBracket)
+ if !l.emit(itemLeftBracket) {
+ return nil
+ }
case r == ']':
- l.emit(itemRightBracket)
+ if !l.emit(itemRightBracket) {
+ return nil
+ }
case r == '@':
- l.emit(itemAt)
+ if !l.emit(itemAt) {
+ return nil
+ }
case r == ':':
- l.emit(itemColon)
+ if !l.emit(itemColon) {
+ return nil
+ }
case r == '_':
- l.emit(itemBlank)
+ if !l.emit(itemBlank) {
+ return nil
+ }
case r == '"':
l.backup()
return lexString
@@ -152,13 +182,13 @@ func (l *lexer) backup() {
l.pos -= l.width
}
-func (l *lexer) errorf(format string, args ...interface{}) stateFn {
+func (l *lexer) errorf(format string, args ...any) stateFn {
// TODO(dh): emit position information in errors
- l.items <- item{
+ _ = l.yield(item{
itemError,
fmt.Sprintf(format, args...),
l.start,
- }
+ })
return nil
}
@@ -179,7 +209,9 @@ func lexString(l *lexer) stateFn {
return l.errorf("unterminated string")
case '"':
if !escape {
- l.emitValue(itemString, string(runes))
+ if !l.emitValue(itemString, string(runes)) {
+ return nil
+ }
return lexStart
} else {
runes = append(runes, '"')
@@ -203,7 +235,9 @@ func lexType(l *lexer) stateFn {
for {
if !isAlphaNumeric(l.next()) {
l.backup()
- l.emit(itemTypeName)
+ if !l.emit(itemTypeName) {
+ return nil
+ }
return lexStart
}
}
@@ -214,7 +248,9 @@ func lexVariable(l *lexer) stateFn {
for {
if !isAlphaNumeric(l.next()) {
l.backup()
- l.emit(itemVariable)
+ if !l.emit(itemVariable) {
+ return nil
+ }
return lexStart
}
}
diff --git a/vendor/honnef.co/go/tools/pattern/match.go b/vendor/honnef.co/go/tools/pattern/match.go
index 3c4b5ffb8..1d3eaae0c 100644
--- a/vendor/honnef.co/go/tools/pattern/match.go
+++ b/vendor/honnef.co/go/tools/pattern/match.go
@@ -6,8 +6,6 @@ import (
"go/token"
"go/types"
"reflect"
-
- "golang.org/x/tools/go/ast/astutil"
)
var tokensByString = map[string]Token{
@@ -73,7 +71,7 @@ func maybeToken(node Node) (Node, bool) {
return node, false
}
-func isNil(v interface{}) bool {
+func isNil(v any) bool {
if v == nil {
return true
}
@@ -84,7 +82,7 @@ func isNil(v interface{}) bool {
}
type matcher interface {
- Match(*Matcher, interface{}) (interface{}, bool)
+ Match(*Matcher, any) (any, bool)
}
type State = map[string]any
@@ -98,7 +96,7 @@ type Matcher struct {
setBindings []uint64
}
-func (m *Matcher) set(b Binding, value interface{}) {
+func (m *Matcher) set(b Binding, value any) {
m.State[b.Name] = value
m.setBindings[len(m.setBindings)-1] |= 1 << b.idx
}
@@ -143,7 +141,7 @@ func Match(a Pattern, b ast.Node) (*Matcher, bool) {
}
// Match two items, which may be (Node, AST) or (AST, AST)
-func match(m *Matcher, l, r interface{}) (interface{}, bool) {
+func match(m *Matcher, l, r any) (any, bool) {
if _, ok := r.(Node); ok {
panic("Node mustn't be on right side of match")
}
@@ -323,7 +321,7 @@ func match(m *Matcher, l, r interface{}) (interface{}, bool) {
}
// Match a Node with an AST node
-func matchNodeAST(m *Matcher, a Node, b interface{}) (interface{}, bool) {
+func matchNodeAST(m *Matcher, a Node, b any) (any, bool) {
switch b := b.(type) {
case []ast.Stmt:
// 'a' is not a List or we'd be using its Match
@@ -384,7 +382,7 @@ func matchNodeAST(m *Matcher, a Node, b interface{}) (interface{}, bool) {
}
// Match two AST nodes
-func matchAST(m *Matcher, a, b ast.Node) (interface{}, bool) {
+func matchAST(m *Matcher, a, b ast.Node) (any, bool) {
ra := reflect.ValueOf(a)
rb := reflect.ValueOf(b)
@@ -426,7 +424,7 @@ func matchAST(m *Matcher, a, b ast.Node) (interface{}, bool) {
if af.Bool() != bf.Bool() {
return nil, false
}
- case reflect.Ptr, reflect.Interface:
+ case reflect.Pointer, reflect.Interface:
if _, ok := match(m, af.Interface(), bf.Interface()); !ok {
return nil, false
}
@@ -437,7 +435,7 @@ func matchAST(m *Matcher, a, b ast.Node) (interface{}, bool) {
return b, true
}
-func (b Binding) Match(m *Matcher, node interface{}) (interface{}, bool) {
+func (b Binding) Match(m *Matcher, node any) (any, bool) {
if isNil(b.Node) {
v, ok := m.State[b.Name]
if ok {
@@ -459,11 +457,11 @@ func (b Binding) Match(m *Matcher, node interface{}) (interface{}, bool) {
return new, ret
}
-func (Any) Match(m *Matcher, node interface{}) (interface{}, bool) {
+func (Any) Match(m *Matcher, node any) (any, bool) {
return node, true
}
-func (l List) Match(m *Matcher, node interface{}) (interface{}, bool) {
+func (l List) Match(m *Matcher, node any) (any, bool) {
v := reflect.ValueOf(node)
if v.Kind() == reflect.Slice {
if isNil(l.Head) {
@@ -482,7 +480,7 @@ func (l List) Match(m *Matcher, node interface{}) (interface{}, bool) {
return nil, false
}
-func (s String) Match(m *Matcher, node interface{}) (interface{}, bool) {
+func (s String) Match(m *Matcher, node any) (any, bool) {
switch o := node.(type) {
case token.Token:
if tok, ok := maybeToken(s); ok {
@@ -498,7 +496,7 @@ func (s String) Match(m *Matcher, node interface{}) (interface{}, bool) {
}
}
-func (tok Token) Match(m *Matcher, node interface{}) (interface{}, bool) {
+func (tok Token) Match(m *Matcher, node any) (any, bool) {
o, ok := node.(token.Token)
if !ok {
return nil, false
@@ -506,7 +504,7 @@ func (tok Token) Match(m *Matcher, node interface{}) (interface{}, bool) {
return o, token.Token(tok) == o
}
-func (Nil) Match(m *Matcher, node interface{}) (interface{}, bool) {
+func (Nil) Match(m *Matcher, node any) (any, bool) {
if isNil(node) {
return nil, true
}
@@ -519,7 +517,7 @@ func (Nil) Match(m *Matcher, node interface{}) (interface{}, bool) {
}
}
-func (builtin Builtin) Match(m *Matcher, node interface{}) (interface{}, bool) {
+func (builtin Builtin) Match(m *Matcher, node any) (any, bool) {
r, ok := match(m, Ident(builtin), node)
if !ok {
return nil, false
@@ -532,7 +530,7 @@ func (builtin Builtin) Match(m *Matcher, node interface{}) (interface{}, bool) {
return ident, true
}
-func (obj Object) Match(m *Matcher, node interface{}) (interface{}, bool) {
+func (obj Object) Match(m *Matcher, node any) (any, bool) {
r, ok := match(m, Ident(obj), node)
if !ok {
return nil, false
@@ -544,7 +542,7 @@ func (obj Object) Match(m *Matcher, node interface{}) (interface{}, bool) {
return id, ok
}
-func (fn Symbol) Match(m *Matcher, node interface{}) (interface{}, bool) {
+func (fn Symbol) Match(m *Matcher, node any) (any, bool) {
var name string
var obj types.Object
@@ -569,9 +567,8 @@ func (fn Symbol) Match(m *Matcher, node interface{}) (interface{}, bool) {
case *ast.IndexListExpr:
fun = idx.X
}
- fun = astutil.Unparen(fun)
- switch fun := fun.(type) {
+ switch fun := ast.Unparen(fun).(type) {
case *ast.Ident:
obj = m.TypesInfo.ObjectOf(fun)
case *ast.SelectorExpr:
@@ -624,7 +621,7 @@ func (fn Symbol) Match(m *Matcher, node interface{}) (interface{}, bool) {
return obj, ok
}
-func (or Or) Match(m *Matcher, node interface{}) (interface{}, bool) {
+func (or Or) Match(m *Matcher, node any) (any, bool) {
for _, opt := range or.Nodes {
m.push()
if ret, ok := match(m, opt, node); ok {
@@ -637,7 +634,7 @@ func (or Or) Match(m *Matcher, node interface{}) (interface{}, bool) {
return nil, false
}
-func (not Not) Match(m *Matcher, node interface{}) (interface{}, bool) {
+func (not Not) Match(m *Matcher, node any) (any, bool) {
_, ok := match(m, not.Node, node)
if ok {
return nil, false
@@ -647,7 +644,7 @@ func (not Not) Match(m *Matcher, node interface{}) (interface{}, bool) {
var integerLiteralQ = MustParse(`(Or (BasicLit "INT" _) (UnaryExpr (Or "+" "-") (IntegerLiteral _)))`)
-func (lit IntegerLiteral) Match(m *Matcher, node interface{}) (interface{}, bool) {
+func (lit IntegerLiteral) Match(m *Matcher, node any) (any, bool) {
matched, ok := match(m, integerLiteralQ.Root, node)
if !ok {
return nil, false
@@ -663,7 +660,7 @@ func (lit IntegerLiteral) Match(m *Matcher, node interface{}) (interface{}, bool
return matched, ok
}
-func (texpr TrulyConstantExpression) Match(m *Matcher, node interface{}) (interface{}, bool) {
+func (texpr TrulyConstantExpression) Match(m *Matcher, node any) (any, bool) {
expr, ok := node.(ast.Expr)
if !ok {
return nil, false
@@ -692,10 +689,10 @@ func (texpr TrulyConstantExpression) Match(m *Matcher, node interface{}) (interf
var (
// Types of fields in go/ast structs that we want to skip
- rtTokPos = reflect.TypeOf(token.Pos(0))
+ rtTokPos = reflect.TypeFor[token.Pos]()
//lint:ignore SA1019 It's deprecated, but we still want to skip the field.
- rtObject = reflect.TypeOf((*ast.Object)(nil))
- rtCommentGroup = reflect.TypeOf((*ast.CommentGroup)(nil))
+ rtObject = reflect.TypeFor[*ast.Object]()
+ rtCommentGroup = reflect.TypeFor[*ast.CommentGroup]()
)
var (
diff --git a/vendor/honnef.co/go/tools/pattern/parser.go b/vendor/honnef.co/go/tools/pattern/parser.go
index ba0897524..e9af70201 100644
--- a/vendor/honnef.co/go/tools/pattern/parser.go
+++ b/vendor/honnef.co/go/tools/pattern/parser.go
@@ -5,14 +5,25 @@ import (
"fmt"
"go/ast"
"go/token"
+ "iter"
"reflect"
+ "strings"
)
type Pattern struct {
Root Node
- // Relevant contains instances of ast.Node that could potentially
+ // EntryNodes contains instances of ast.Node that could potentially
// initiate a successful match of the pattern.
- Relevant map[reflect.Type]struct{}
+ EntryNodes []ast.Node
+
+ // SymbolsPattern is a pattern consisting or Any, Or, And, and IndexSymbol,
+ // that can be used to implement fast rejection of whole packages using
+ // typeindex.
+ SymbolsPattern Node
+
+ // If non-empty, all possible candidate nodes for this pattern can be found
+ // by finding all call expressions for this list of symbols.
+ RootCallSymbols []IndexSymbol
// Mapping from binding index to binding name
Bindings []string
@@ -27,16 +38,183 @@ func MustParse(s string) Pattern {
return pat
}
-func roots(node Node, m map[reflect.Type]struct{}) {
+func symbolToIndexSymbol(name string) IndexSymbol {
+ if len(name) == 0 {
+ return IndexSymbol{}
+ }
+ if name[0] == '(' {
+ end := strings.IndexAny(name, ")")
+ // Ensure there's a ), and also that there are at least two more
+ // characters after it, for a dot and an identifier.
+ if end == -1 || end > len(name)-2 {
+ return IndexSymbol{}
+ }
+ pathAndType := strings.TrimPrefix(name[1:end], "*")
+ dot := strings.LastIndex(pathAndType, ".")
+ if dot == -1 {
+ return IndexSymbol{}
+ }
+ path := pathAndType[:dot]
+ typ := pathAndType[dot+1:]
+ ident := name[end+2:]
+ return IndexSymbol{path, typ, ident}
+ } else {
+ dot := strings.LastIndex(name, ".")
+ if dot == -1 {
+ return IndexSymbol{"", "", name}
+ }
+ path := name[:dot]
+ ident := name[dot+1:]
+ return IndexSymbol{path, "", ident}
+ }
+}
+
+func collectSymbols(node Node, inSymbol bool) Node {
+ and := func(c Node, out *And) {
+ switch cc := c.(type) {
+ case And:
+ out.Nodes = append(out.Nodes, cc.Nodes...)
+ case Any:
+ case nil:
+ default:
+ out.Nodes = append(out.Nodes, c)
+ }
+ }
+
+ switch node := node.(type) {
+ case Or:
+ s := Or{}
+ for _, el := range node.Nodes {
+ c := collectSymbols(el, inSymbol)
+ switch cc := c.(type) {
+ case Or:
+ s.Nodes = append(s.Nodes, cc.Nodes...)
+ case Any:
+ return Any{}
+ case nil:
+ default:
+ s.Nodes = append(s.Nodes, c)
+ }
+ }
+ switch len(s.Nodes) {
+ case 0:
+ return nil
+ case 1:
+ return s.Nodes[0]
+ default:
+ return s
+ }
+ case Not, Token, nil:
+ return Any{}
+ case Symbol:
+ return collectSymbols(node.Name, true)
+ case String:
+ if !inSymbol {
+ return Any{}
+ }
+ // In logically correct patterns, all Strings that are children of
+ // Symbols describe the names of symbols.
+ return symbolToIndexSymbol(string(node))
+ case Binding:
+ return collectSymbols(node.Node, inSymbol)
+ case Any:
+ return Any{}
+ case List:
+ var out And
+ and(collectSymbols(node.Head, inSymbol), &out)
+ and(collectSymbols(node.Tail, inSymbol), &out)
+ switch len(out.Nodes) {
+ case 0:
+ return Any{}
+ case 1:
+ return out.Nodes[0]
+ default:
+ return out
+ }
+ default:
+ var out And
+ rv := reflect.ValueOf(node)
+ for i := range rv.NumField() {
+ c := collectSymbols(rv.Field(i).Interface().(Node), inSymbol)
+ and(c, &out)
+ }
+ switch len(out.Nodes) {
+ case 0:
+ return Any{}
+ case 1:
+ return out.Nodes[0]
+ default:
+ return out
+ }
+ }
+}
+
+func collectRootCallSymbols(node Node) []IndexSymbol {
+ root, ok := node.(CallExpr)
+ if !ok {
+ return nil
+ }
+
+ var names []String
+ var handleSymName func(name Node) bool
+ handleSymName = func(name Node) bool {
+ switch name := name.(type) {
+ case String:
+ names = append(names, name)
+ case Or:
+ for _, node := range name.Nodes {
+ if name, ok := node.(String); ok {
+ names = append(names, name)
+ } else {
+ return false
+ }
+ }
+ case Binding:
+ return handleSymName(name.Node)
+ default:
+ return false
+ }
+ return true
+ }
+ var handleRootFun func(node Node) bool
+ handleRootFun = func(node Node) bool {
+ switch fun := node.(type) {
+ case Binding:
+ return handleRootFun(fun.Node)
+ case Symbol:
+ return handleSymName(fun.Name)
+ case Or:
+ for _, node := range fun.Nodes {
+ if sym, ok := node.(Symbol); !ok || !handleSymName(sym.Name) {
+ return false
+ }
+ }
+ return true
+ default:
+ return false
+ }
+ }
+ if !handleRootFun(root.Fun) {
+ return nil
+ }
+
+ out := make([]IndexSymbol, len(names))
+ for i, name := range names {
+ out[i] = symbolToIndexSymbol(string(name))
+ }
+ return out
+}
+
+func collectEntryNodes(node Node, m map[reflect.Type]struct{}) {
switch node := node.(type) {
case Or:
for _, el := range node.Nodes {
- roots(el, m)
+ collectEntryNodes(el, m)
}
case Not:
- roots(node.Node, m)
+ collectEntryNodes(node.Node, m)
case Binding:
- roots(node.Node, m)
+ collectEntryNodes(node.Node, m)
case Nil, nil:
// this branch is reached via bindings
for _, T := range allTypes {
@@ -54,100 +232,100 @@ func roots(node Node, m map[reflect.Type]struct{}) {
}
var allTypes = []reflect.Type{
- reflect.TypeOf((*ast.RangeStmt)(nil)),
- reflect.TypeOf((*ast.AssignStmt)(nil)),
- reflect.TypeOf((*ast.IndexExpr)(nil)),
- reflect.TypeOf((*ast.Ident)(nil)),
- reflect.TypeOf((*ast.ValueSpec)(nil)),
- reflect.TypeOf((*ast.GenDecl)(nil)),
- reflect.TypeOf((*ast.BinaryExpr)(nil)),
- reflect.TypeOf((*ast.ForStmt)(nil)),
- reflect.TypeOf((*ast.ArrayType)(nil)),
- reflect.TypeOf((*ast.DeferStmt)(nil)),
- reflect.TypeOf((*ast.MapType)(nil)),
- reflect.TypeOf((*ast.ReturnStmt)(nil)),
- reflect.TypeOf((*ast.SliceExpr)(nil)),
- reflect.TypeOf((*ast.StarExpr)(nil)),
- reflect.TypeOf((*ast.UnaryExpr)(nil)),
- reflect.TypeOf((*ast.SendStmt)(nil)),
- reflect.TypeOf((*ast.SelectStmt)(nil)),
- reflect.TypeOf((*ast.ImportSpec)(nil)),
- reflect.TypeOf((*ast.IfStmt)(nil)),
- reflect.TypeOf((*ast.GoStmt)(nil)),
- reflect.TypeOf((*ast.Field)(nil)),
- reflect.TypeOf((*ast.SelectorExpr)(nil)),
- reflect.TypeOf((*ast.StructType)(nil)),
- reflect.TypeOf((*ast.KeyValueExpr)(nil)),
- reflect.TypeOf((*ast.FuncType)(nil)),
- reflect.TypeOf((*ast.FuncLit)(nil)),
- reflect.TypeOf((*ast.FuncDecl)(nil)),
- reflect.TypeOf((*ast.ChanType)(nil)),
- reflect.TypeOf((*ast.CallExpr)(nil)),
- reflect.TypeOf((*ast.CaseClause)(nil)),
- reflect.TypeOf((*ast.CommClause)(nil)),
- reflect.TypeOf((*ast.CompositeLit)(nil)),
- reflect.TypeOf((*ast.EmptyStmt)(nil)),
- reflect.TypeOf((*ast.SwitchStmt)(nil)),
- reflect.TypeOf((*ast.TypeSwitchStmt)(nil)),
- reflect.TypeOf((*ast.TypeAssertExpr)(nil)),
- reflect.TypeOf((*ast.TypeSpec)(nil)),
- reflect.TypeOf((*ast.InterfaceType)(nil)),
- reflect.TypeOf((*ast.BranchStmt)(nil)),
- reflect.TypeOf((*ast.IncDecStmt)(nil)),
- reflect.TypeOf((*ast.BasicLit)(nil)),
+ reflect.TypeFor[*ast.RangeStmt](),
+ reflect.TypeFor[*ast.AssignStmt](),
+ reflect.TypeFor[*ast.IndexExpr](),
+ reflect.TypeFor[*ast.Ident](),
+ reflect.TypeFor[*ast.ValueSpec](),
+ reflect.TypeFor[*ast.GenDecl](),
+ reflect.TypeFor[*ast.BinaryExpr](),
+ reflect.TypeFor[*ast.ForStmt](),
+ reflect.TypeFor[*ast.ArrayType](),
+ reflect.TypeFor[*ast.DeferStmt](),
+ reflect.TypeFor[*ast.MapType](),
+ reflect.TypeFor[*ast.ReturnStmt](),
+ reflect.TypeFor[*ast.SliceExpr](),
+ reflect.TypeFor[*ast.StarExpr](),
+ reflect.TypeFor[*ast.UnaryExpr](),
+ reflect.TypeFor[*ast.SendStmt](),
+ reflect.TypeFor[*ast.SelectStmt](),
+ reflect.TypeFor[*ast.ImportSpec](),
+ reflect.TypeFor[*ast.IfStmt](),
+ reflect.TypeFor[*ast.GoStmt](),
+ reflect.TypeFor[*ast.Field](),
+ reflect.TypeFor[*ast.SelectorExpr](),
+ reflect.TypeFor[*ast.StructType](),
+ reflect.TypeFor[*ast.KeyValueExpr](),
+ reflect.TypeFor[*ast.FuncType](),
+ reflect.TypeFor[*ast.FuncLit](),
+ reflect.TypeFor[*ast.FuncDecl](),
+ reflect.TypeFor[*ast.ChanType](),
+ reflect.TypeFor[*ast.CallExpr](),
+ reflect.TypeFor[*ast.CaseClause](),
+ reflect.TypeFor[*ast.CommClause](),
+ reflect.TypeFor[*ast.CompositeLit](),
+ reflect.TypeFor[*ast.EmptyStmt](),
+ reflect.TypeFor[*ast.SwitchStmt](),
+ reflect.TypeFor[*ast.TypeSwitchStmt](),
+ reflect.TypeFor[*ast.TypeAssertExpr](),
+ reflect.TypeFor[*ast.TypeSpec](),
+ reflect.TypeFor[*ast.InterfaceType](),
+ reflect.TypeFor[*ast.BranchStmt](),
+ reflect.TypeFor[*ast.IncDecStmt](),
+ reflect.TypeFor[*ast.BasicLit](),
}
var nodeToASTTypes = map[reflect.Type][]reflect.Type{
- reflect.TypeOf(String("")): nil,
- reflect.TypeOf(Token(0)): nil,
- reflect.TypeOf(List{}): {reflect.TypeOf((*ast.BlockStmt)(nil)), reflect.TypeOf((*ast.FieldList)(nil))},
- reflect.TypeOf(Builtin{}): {reflect.TypeOf((*ast.Ident)(nil))},
- reflect.TypeOf(Object{}): {reflect.TypeOf((*ast.Ident)(nil))},
- reflect.TypeOf(Symbol{}): {reflect.TypeOf((*ast.Ident)(nil)), reflect.TypeOf((*ast.SelectorExpr)(nil))},
- reflect.TypeOf(Any{}): allTypes,
- reflect.TypeOf(RangeStmt{}): {reflect.TypeOf((*ast.RangeStmt)(nil))},
- reflect.TypeOf(AssignStmt{}): {reflect.TypeOf((*ast.AssignStmt)(nil))},
- reflect.TypeOf(IndexExpr{}): {reflect.TypeOf((*ast.IndexExpr)(nil))},
- reflect.TypeOf(Ident{}): {reflect.TypeOf((*ast.Ident)(nil))},
- reflect.TypeOf(ValueSpec{}): {reflect.TypeOf((*ast.ValueSpec)(nil))},
- reflect.TypeOf(GenDecl{}): {reflect.TypeOf((*ast.GenDecl)(nil))},
- reflect.TypeOf(BinaryExpr{}): {reflect.TypeOf((*ast.BinaryExpr)(nil))},
- reflect.TypeOf(ForStmt{}): {reflect.TypeOf((*ast.ForStmt)(nil))},
- reflect.TypeOf(ArrayType{}): {reflect.TypeOf((*ast.ArrayType)(nil))},
- reflect.TypeOf(DeferStmt{}): {reflect.TypeOf((*ast.DeferStmt)(nil))},
- reflect.TypeOf(MapType{}): {reflect.TypeOf((*ast.MapType)(nil))},
- reflect.TypeOf(ReturnStmt{}): {reflect.TypeOf((*ast.ReturnStmt)(nil))},
- reflect.TypeOf(SliceExpr{}): {reflect.TypeOf((*ast.SliceExpr)(nil))},
- reflect.TypeOf(StarExpr{}): {reflect.TypeOf((*ast.StarExpr)(nil))},
- reflect.TypeOf(UnaryExpr{}): {reflect.TypeOf((*ast.UnaryExpr)(nil))},
- reflect.TypeOf(SendStmt{}): {reflect.TypeOf((*ast.SendStmt)(nil))},
- reflect.TypeOf(SelectStmt{}): {reflect.TypeOf((*ast.SelectStmt)(nil))},
- reflect.TypeOf(ImportSpec{}): {reflect.TypeOf((*ast.ImportSpec)(nil))},
- reflect.TypeOf(IfStmt{}): {reflect.TypeOf((*ast.IfStmt)(nil))},
- reflect.TypeOf(GoStmt{}): {reflect.TypeOf((*ast.GoStmt)(nil))},
- reflect.TypeOf(Field{}): {reflect.TypeOf((*ast.Field)(nil))},
- reflect.TypeOf(SelectorExpr{}): {reflect.TypeOf((*ast.SelectorExpr)(nil))},
- reflect.TypeOf(StructType{}): {reflect.TypeOf((*ast.StructType)(nil))},
- reflect.TypeOf(KeyValueExpr{}): {reflect.TypeOf((*ast.KeyValueExpr)(nil))},
- reflect.TypeOf(FuncType{}): {reflect.TypeOf((*ast.FuncType)(nil))},
- reflect.TypeOf(FuncLit{}): {reflect.TypeOf((*ast.FuncLit)(nil))},
- reflect.TypeOf(FuncDecl{}): {reflect.TypeOf((*ast.FuncDecl)(nil))},
- reflect.TypeOf(ChanType{}): {reflect.TypeOf((*ast.ChanType)(nil))},
- reflect.TypeOf(CallExpr{}): {reflect.TypeOf((*ast.CallExpr)(nil))},
- reflect.TypeOf(CaseClause{}): {reflect.TypeOf((*ast.CaseClause)(nil))},
- reflect.TypeOf(CommClause{}): {reflect.TypeOf((*ast.CommClause)(nil))},
- reflect.TypeOf(CompositeLit{}): {reflect.TypeOf((*ast.CompositeLit)(nil))},
- reflect.TypeOf(EmptyStmt{}): {reflect.TypeOf((*ast.EmptyStmt)(nil))},
- reflect.TypeOf(SwitchStmt{}): {reflect.TypeOf((*ast.SwitchStmt)(nil))},
- reflect.TypeOf(TypeSwitchStmt{}): {reflect.TypeOf((*ast.TypeSwitchStmt)(nil))},
- reflect.TypeOf(TypeAssertExpr{}): {reflect.TypeOf((*ast.TypeAssertExpr)(nil))},
- reflect.TypeOf(TypeSpec{}): {reflect.TypeOf((*ast.TypeSpec)(nil))},
- reflect.TypeOf(InterfaceType{}): {reflect.TypeOf((*ast.InterfaceType)(nil))},
- reflect.TypeOf(BranchStmt{}): {reflect.TypeOf((*ast.BranchStmt)(nil))},
- reflect.TypeOf(IncDecStmt{}): {reflect.TypeOf((*ast.IncDecStmt)(nil))},
- reflect.TypeOf(BasicLit{}): {reflect.TypeOf((*ast.BasicLit)(nil))},
- reflect.TypeOf(IntegerLiteral{}): {reflect.TypeOf((*ast.BasicLit)(nil)), reflect.TypeOf((*ast.UnaryExpr)(nil))},
- reflect.TypeOf(TrulyConstantExpression{}): allTypes, // this is an over-approximation, which is fine
+ reflect.TypeFor[String](): nil,
+ reflect.TypeFor[Token](): nil,
+ reflect.TypeFor[List](): {reflect.TypeFor[*ast.BlockStmt](), reflect.TypeFor[*ast.FieldList]()},
+ reflect.TypeFor[Builtin](): {reflect.TypeFor[*ast.Ident]()},
+ reflect.TypeFor[Object](): {reflect.TypeFor[*ast.Ident]()},
+ reflect.TypeFor[Symbol](): {reflect.TypeFor[*ast.Ident](), reflect.TypeFor[*ast.SelectorExpr]()},
+ reflect.TypeFor[Any](): allTypes,
+ reflect.TypeFor[RangeStmt](): {reflect.TypeFor[*ast.RangeStmt]()},
+ reflect.TypeFor[AssignStmt](): {reflect.TypeFor[*ast.AssignStmt]()},
+ reflect.TypeFor[IndexExpr](): {reflect.TypeFor[*ast.IndexExpr]()},
+ reflect.TypeFor[Ident](): {reflect.TypeFor[*ast.Ident]()},
+ reflect.TypeFor[ValueSpec](): {reflect.TypeFor[*ast.ValueSpec]()},
+ reflect.TypeFor[GenDecl](): {reflect.TypeFor[*ast.GenDecl]()},
+ reflect.TypeFor[BinaryExpr](): {reflect.TypeFor[*ast.BinaryExpr]()},
+ reflect.TypeFor[ForStmt](): {reflect.TypeFor[*ast.ForStmt]()},
+ reflect.TypeFor[ArrayType](): {reflect.TypeFor[*ast.ArrayType]()},
+ reflect.TypeFor[DeferStmt](): {reflect.TypeFor[*ast.DeferStmt]()},
+ reflect.TypeFor[MapType](): {reflect.TypeFor[*ast.MapType]()},
+ reflect.TypeFor[ReturnStmt](): {reflect.TypeFor[*ast.ReturnStmt]()},
+ reflect.TypeFor[SliceExpr](): {reflect.TypeFor[*ast.SliceExpr]()},
+ reflect.TypeFor[StarExpr](): {reflect.TypeFor[*ast.StarExpr]()},
+ reflect.TypeFor[UnaryExpr](): {reflect.TypeFor[*ast.UnaryExpr]()},
+ reflect.TypeFor[SendStmt](): {reflect.TypeFor[*ast.SendStmt]()},
+ reflect.TypeFor[SelectStmt](): {reflect.TypeFor[*ast.SelectStmt]()},
+ reflect.TypeFor[ImportSpec](): {reflect.TypeFor[*ast.ImportSpec]()},
+ reflect.TypeFor[IfStmt](): {reflect.TypeFor[*ast.IfStmt]()},
+ reflect.TypeFor[GoStmt](): {reflect.TypeFor[*ast.GoStmt]()},
+ reflect.TypeFor[Field](): {reflect.TypeFor[*ast.Field]()},
+ reflect.TypeFor[SelectorExpr](): {reflect.TypeFor[*ast.SelectorExpr]()},
+ reflect.TypeFor[StructType](): {reflect.TypeFor[*ast.StructType]()},
+ reflect.TypeFor[KeyValueExpr](): {reflect.TypeFor[*ast.KeyValueExpr]()},
+ reflect.TypeFor[FuncType](): {reflect.TypeFor[*ast.FuncType]()},
+ reflect.TypeFor[FuncLit](): {reflect.TypeFor[*ast.FuncLit]()},
+ reflect.TypeFor[FuncDecl](): {reflect.TypeFor[*ast.FuncDecl]()},
+ reflect.TypeFor[ChanType](): {reflect.TypeFor[*ast.ChanType]()},
+ reflect.TypeFor[CallExpr](): {reflect.TypeFor[*ast.CallExpr]()},
+ reflect.TypeFor[CaseClause](): {reflect.TypeFor[*ast.CaseClause]()},
+ reflect.TypeFor[CommClause](): {reflect.TypeFor[*ast.CommClause]()},
+ reflect.TypeFor[CompositeLit](): {reflect.TypeFor[*ast.CompositeLit]()},
+ reflect.TypeFor[EmptyStmt](): {reflect.TypeFor[*ast.EmptyStmt]()},
+ reflect.TypeFor[SwitchStmt](): {reflect.TypeFor[*ast.SwitchStmt]()},
+ reflect.TypeFor[TypeSwitchStmt](): {reflect.TypeFor[*ast.TypeSwitchStmt]()},
+ reflect.TypeFor[TypeAssertExpr](): {reflect.TypeFor[*ast.TypeAssertExpr]()},
+ reflect.TypeFor[TypeSpec](): {reflect.TypeFor[*ast.TypeSpec]()},
+ reflect.TypeFor[InterfaceType](): {reflect.TypeFor[*ast.InterfaceType]()},
+ reflect.TypeFor[BranchStmt](): {reflect.TypeFor[*ast.BranchStmt]()},
+ reflect.TypeFor[IncDecStmt](): {reflect.TypeFor[*ast.IncDecStmt]()},
+ reflect.TypeFor[BasicLit](): {reflect.TypeFor[*ast.BasicLit]()},
+ reflect.TypeFor[IntegerLiteral](): {reflect.TypeFor[*ast.BasicLit](), reflect.TypeFor[*ast.UnaryExpr]()},
+ reflect.TypeFor[TrulyConstantExpression](): allTypes, // this is an over-approximation, which is fine
}
var requiresTypeInfo = map[string]bool{
@@ -162,10 +340,10 @@ type Parser struct {
// Allow nodes that rely on type information
AllowTypeInfo bool
- lex *lexer
- cur item
- last *item
- items chan item
+ f *token.File
+ cur item
+ last *item
+ nextItem func() (item, bool)
bindings map[string]int
}
@@ -183,26 +361,27 @@ func (p *Parser) bindingIndex(name string) int {
}
func (p *Parser) Parse(s string) (Pattern, error) {
+ f := token.NewFileSet().AddFile(" ", -1, len(s))
+
+ // Run the lexer iterator as a coroutine.
+ // The parser will call 'next' to consume each item.
+ // After the parser returns, we must call 'stop' to
+ // terminate the coroutine.
+ next, stop := iter.Pull(lex(f, s))
+ defer stop()
+
p.cur = item{}
p.last = nil
- p.items = nil
+ p.f = f
+ p.nextItem = next
- fset := token.NewFileSet()
- p.lex = &lexer{
- f: fset.AddFile(" ", -1, len(s)),
- input: s,
- items: make(chan item),
- }
- go p.lex.run()
- p.items = p.lex.items
+ // Parse.
root, err := p.node()
if err != nil {
- // drain lexer if parsing failed
- for range p.lex.items {
- }
return Pattern{}, err
}
- if item := <-p.lex.items; item.typ != itemEOF {
+ // Consume final EOF token.
+ if item, ok := next(); !ok || item.typ != itemEOF {
return Pattern{}, fmt.Errorf("unexpected token %s after end of pattern", item.typ)
}
@@ -215,12 +394,21 @@ func (p *Parser) Parse(s string) (Pattern, error) {
bindings[idx] = name
}
- relevant := map[reflect.Type]struct{}{}
- roots(root, relevant)
+ _, isSymbol := root.(Symbol)
+ sym := collectSymbols(root, isSymbol)
+ rootSyms := collectRootCallSymbols(root)
+ relevantMap := map[reflect.Type]struct{}{}
+ collectEntryNodes(root, relevantMap)
+ relevantNodes := make([]ast.Node, 0, len(relevantMap))
+ for k := range relevantMap {
+ relevantNodes = append(relevantNodes, reflect.Zero(k).Interface().(ast.Node))
+ }
return Pattern{
- Root: root,
- Relevant: relevant,
- Bindings: bindings,
+ Root: root,
+ EntryNodes: relevantNodes,
+ SymbolsPattern: sym,
+ RootCallSymbols: rootSyms,
+ Bindings: bindings,
}, nil
}
@@ -231,7 +419,7 @@ func (p *Parser) next() item {
return n
}
var ok bool
- p.cur, ok = <-p.items
+ p.cur, ok = p.nextItem()
if !ok {
p.cur = item{typ: eof}
}
@@ -269,7 +457,7 @@ func (p *Parser) unexpectedToken(valid string) error {
got = "'" + p.cur.typ.String() + "'"
}
- pos := p.lex.f.Position(token.Pos(p.cur.pos))
+ pos := p.f.Position(token.Pos(p.cur.pos))
return fmt.Errorf("%s: expected %s, found %s", pos, valid, got)
}
@@ -363,58 +551,58 @@ func (p *Parser) populateNode(typ string, objs []Node) (Node, error) {
}
var structNodes = map[string]reflect.Type{
- "Any": reflect.TypeOf(Any{}),
- "Ellipsis": reflect.TypeOf(Ellipsis{}),
- "List": reflect.TypeOf(List{}),
- "Binding": reflect.TypeOf(Binding{}),
- "RangeStmt": reflect.TypeOf(RangeStmt{}),
- "AssignStmt": reflect.TypeOf(AssignStmt{}),
- "IndexExpr": reflect.TypeOf(IndexExpr{}),
- "Ident": reflect.TypeOf(Ident{}),
- "Builtin": reflect.TypeOf(Builtin{}),
- "ValueSpec": reflect.TypeOf(ValueSpec{}),
- "GenDecl": reflect.TypeOf(GenDecl{}),
- "BinaryExpr": reflect.TypeOf(BinaryExpr{}),
- "ForStmt": reflect.TypeOf(ForStmt{}),
- "ArrayType": reflect.TypeOf(ArrayType{}),
- "DeferStmt": reflect.TypeOf(DeferStmt{}),
- "MapType": reflect.TypeOf(MapType{}),
- "ReturnStmt": reflect.TypeOf(ReturnStmt{}),
- "SliceExpr": reflect.TypeOf(SliceExpr{}),
- "StarExpr": reflect.TypeOf(StarExpr{}),
- "UnaryExpr": reflect.TypeOf(UnaryExpr{}),
- "SendStmt": reflect.TypeOf(SendStmt{}),
- "SelectStmt": reflect.TypeOf(SelectStmt{}),
- "ImportSpec": reflect.TypeOf(ImportSpec{}),
- "IfStmt": reflect.TypeOf(IfStmt{}),
- "GoStmt": reflect.TypeOf(GoStmt{}),
- "Field": reflect.TypeOf(Field{}),
- "SelectorExpr": reflect.TypeOf(SelectorExpr{}),
- "StructType": reflect.TypeOf(StructType{}),
- "KeyValueExpr": reflect.TypeOf(KeyValueExpr{}),
- "FuncType": reflect.TypeOf(FuncType{}),
- "FuncLit": reflect.TypeOf(FuncLit{}),
- "FuncDecl": reflect.TypeOf(FuncDecl{}),
- "ChanType": reflect.TypeOf(ChanType{}),
- "CallExpr": reflect.TypeOf(CallExpr{}),
- "CaseClause": reflect.TypeOf(CaseClause{}),
- "CommClause": reflect.TypeOf(CommClause{}),
- "CompositeLit": reflect.TypeOf(CompositeLit{}),
- "EmptyStmt": reflect.TypeOf(EmptyStmt{}),
- "SwitchStmt": reflect.TypeOf(SwitchStmt{}),
- "TypeSwitchStmt": reflect.TypeOf(TypeSwitchStmt{}),
- "TypeAssertExpr": reflect.TypeOf(TypeAssertExpr{}),
- "TypeSpec": reflect.TypeOf(TypeSpec{}),
- "InterfaceType": reflect.TypeOf(InterfaceType{}),
- "BranchStmt": reflect.TypeOf(BranchStmt{}),
- "IncDecStmt": reflect.TypeOf(IncDecStmt{}),
- "BasicLit": reflect.TypeOf(BasicLit{}),
- "Object": reflect.TypeOf(Object{}),
- "Symbol": reflect.TypeOf(Symbol{}),
- "Or": reflect.TypeOf(Or{}),
- "Not": reflect.TypeOf(Not{}),
- "IntegerLiteral": reflect.TypeOf(IntegerLiteral{}),
- "TrulyConstantExpression": reflect.TypeOf(TrulyConstantExpression{}),
+ "Any": reflect.TypeFor[Any](),
+ "Ellipsis": reflect.TypeFor[Ellipsis](),
+ "List": reflect.TypeFor[List](),
+ "Binding": reflect.TypeFor[Binding](),
+ "RangeStmt": reflect.TypeFor[RangeStmt](),
+ "AssignStmt": reflect.TypeFor[AssignStmt](),
+ "IndexExpr": reflect.TypeFor[IndexExpr](),
+ "Ident": reflect.TypeFor[Ident](),
+ "Builtin": reflect.TypeFor[Builtin](),
+ "ValueSpec": reflect.TypeFor[ValueSpec](),
+ "GenDecl": reflect.TypeFor[GenDecl](),
+ "BinaryExpr": reflect.TypeFor[BinaryExpr](),
+ "ForStmt": reflect.TypeFor[ForStmt](),
+ "ArrayType": reflect.TypeFor[ArrayType](),
+ "DeferStmt": reflect.TypeFor[DeferStmt](),
+ "MapType": reflect.TypeFor[MapType](),
+ "ReturnStmt": reflect.TypeFor[ReturnStmt](),
+ "SliceExpr": reflect.TypeFor[SliceExpr](),
+ "StarExpr": reflect.TypeFor[StarExpr](),
+ "UnaryExpr": reflect.TypeFor[UnaryExpr](),
+ "SendStmt": reflect.TypeFor[SendStmt](),
+ "SelectStmt": reflect.TypeFor[SelectStmt](),
+ "ImportSpec": reflect.TypeFor[ImportSpec](),
+ "IfStmt": reflect.TypeFor[IfStmt](),
+ "GoStmt": reflect.TypeFor[GoStmt](),
+ "Field": reflect.TypeFor[Field](),
+ "SelectorExpr": reflect.TypeFor[SelectorExpr](),
+ "StructType": reflect.TypeFor[StructType](),
+ "KeyValueExpr": reflect.TypeFor[KeyValueExpr](),
+ "FuncType": reflect.TypeFor[FuncType](),
+ "FuncLit": reflect.TypeFor[FuncLit](),
+ "FuncDecl": reflect.TypeFor[FuncDecl](),
+ "ChanType": reflect.TypeFor[ChanType](),
+ "CallExpr": reflect.TypeFor[CallExpr](),
+ "CaseClause": reflect.TypeFor[CaseClause](),
+ "CommClause": reflect.TypeFor[CommClause](),
+ "CompositeLit": reflect.TypeFor[CompositeLit](),
+ "EmptyStmt": reflect.TypeFor[EmptyStmt](),
+ "SwitchStmt": reflect.TypeFor[SwitchStmt](),
+ "TypeSwitchStmt": reflect.TypeFor[TypeSwitchStmt](),
+ "TypeAssertExpr": reflect.TypeFor[TypeAssertExpr](),
+ "TypeSpec": reflect.TypeFor[TypeSpec](),
+ "InterfaceType": reflect.TypeFor[InterfaceType](),
+ "BranchStmt": reflect.TypeFor[BranchStmt](),
+ "IncDecStmt": reflect.TypeFor[IncDecStmt](),
+ "BasicLit": reflect.TypeFor[BasicLit](),
+ "Object": reflect.TypeFor[Object](),
+ "Symbol": reflect.TypeFor[Symbol](),
+ "Or": reflect.TypeFor[Or](),
+ "Not": reflect.TypeFor[Not](),
+ "IntegerLiteral": reflect.TypeFor[IntegerLiteral](),
+ "TrulyConstantExpression": reflect.TypeFor[TrulyConstantExpression](),
}
func (p *Parser) object() (Node, error) {
diff --git a/vendor/honnef.co/go/tools/pattern/pattern.go b/vendor/honnef.co/go/tools/pattern/pattern.go
index 15886b1f3..107f95b12 100644
--- a/vendor/honnef.co/go/tools/pattern/pattern.go
+++ b/vendor/honnef.co/go/tools/pattern/pattern.go
@@ -338,6 +338,10 @@ type Or struct {
Nodes []Node
}
+type And struct {
+ Nodes []Node
+}
+
type Not struct {
Node Node
}
@@ -348,6 +352,12 @@ type TrulyConstantExpression struct {
Value Node
}
+type IndexSymbol struct {
+ Path string
+ Type string
+ Ident string
+}
+
func stringify(n Node) string {
v := reflect.ValueOf(n)
var parts []string
@@ -408,15 +418,30 @@ func (el Ellipsis) String() string { return stringify(el) }
func (not Not) String() string { return stringify(not) }
func (lit IntegerLiteral) String() string { return stringify(lit) }
func (expr TrulyConstantExpression) String() string { return stringify(expr) }
+func (sym IndexSymbol) String() string {
+ return fmt.Sprintf("(IndexSymbol %q %q %q)", sym.Path, sym.Type, sym.Ident)
+}
func (or Or) String() string {
- s := "(Or"
+ var s strings.Builder
+ s.WriteString("(Or")
for _, node := range or.Nodes {
- s += " "
- s += node.String()
+ s.WriteString(" ")
+ s.WriteString(node.String())
+ }
+ s.WriteString(")")
+ return s.String()
+}
+
+func (and And) String() string {
+ var s strings.Builder
+ s.WriteString("(And")
+ for _, node := range and.Nodes {
+ s.WriteString(" ")
+ s.WriteString(node.String())
}
- s += ")"
- return s
+ s.WriteString(")")
+ return s.String()
}
func isProperList(l List) bool {
@@ -514,6 +539,7 @@ func (Object) isNode() {}
func (Symbol) isNode() {}
func (Ellipsis) isNode() {}
func (Or) isNode() {}
+func (And) isNode() {}
func (List) isNode() {}
func (String) isNode() {}
func (Token) isNode() {}
@@ -522,3 +548,4 @@ func (Binding) isNode() {}
func (Not) isNode() {}
func (IntegerLiteral) isNode() {}
func (TrulyConstantExpression) isNode() {}
+func (IndexSymbol) isNode() {}
diff --git a/vendor/honnef.co/go/tools/printf/fuzz.go b/vendor/honnef.co/go/tools/printf/fuzz.go
index 41c34c631..cf6310a7e 100644
--- a/vendor/honnef.co/go/tools/printf/fuzz.go
+++ b/vendor/honnef.co/go/tools/printf/fuzz.go
@@ -1,5 +1,4 @@
//go:build gofuzz
-// +build gofuzz
package printf
diff --git a/vendor/honnef.co/go/tools/printf/printf.go b/vendor/honnef.co/go/tools/printf/printf.go
index 3ce4dc018..b4d4bac7b 100644
--- a/vendor/honnef.co/go/tools/printf/printf.go
+++ b/vendor/honnef.co/go/tools/printf/printf.go
@@ -74,8 +74,8 @@ func (Literal) isArgument() {}
// Parse parses f and returns a list of actions.
// An action may either be a literal string, or a Verb.
-func Parse(f string) ([]interface{}, error) {
- var out []interface{}
+func Parse(f string) ([]any, error) {
+ var out []any
for len(f) > 0 {
if f[0] == '%' {
v, n, err := ParseVerb(f)
diff --git a/vendor/honnef.co/go/tools/quickfix/qf1001/qf1001.go b/vendor/honnef.co/go/tools/quickfix/qf1001/qf1001.go
index 65835717f..b338dbac9 100644
--- a/vendor/honnef.co/go/tools/quickfix/qf1001/qf1001.go
+++ b/vendor/honnef.co/go/tools/quickfix/qf1001/qf1001.go
@@ -32,7 +32,7 @@ var Analyzer = SCAnalyzer.Analyzer
var demorganQ = pattern.MustParse(`(UnaryExpr "!" expr@(BinaryExpr _ _ _))`)
-func CheckDeMorgan(pass *analysis.Pass) (interface{}, error) {
+func CheckDeMorgan(pass *analysis.Pass) (any, error) {
// TODO(dh): support going in the other direction, e.g. turning `!a && !b && !c` into `!(a || b || c)`
// hasFloats reports whether any subexpression is of type float.
@@ -54,34 +54,35 @@ func CheckDeMorgan(pass *analysis.Pass) (interface{}, error) {
return found
}
- fn := func(node ast.Node, stack []ast.Node) {
+ for c := range code.Cursor(pass).Preorder((*ast.UnaryExpr)(nil)) {
+ node := c.Node()
matcher, ok := code.Match(pass, demorganQ, node)
if !ok {
- return
+ continue
}
expr := matcher.State["expr"].(ast.Expr)
// be extremely conservative when it comes to floats
if hasFloats(expr) {
- return
+ continue
}
n := astutil.NegateDeMorgan(expr, false)
nr := astutil.NegateDeMorgan(expr, true)
nc, ok := astutil.CopyExpr(n)
if !ok {
- return
+ continue
}
ns := astutil.SimplifyParentheses(nc)
nrc, ok := astutil.CopyExpr(nr)
if !ok {
- return
+ continue
}
nrs := astutil.SimplifyParentheses(nrc)
var bn, bnr, bns, bnrs string
- switch parent := stack[len(stack)-2]; parent.(type) {
+ switch c.Parent().Node().(type) {
case *ast.BinaryExpr, *ast.IfStmt, *ast.ForStmt, *ast.SwitchStmt:
// Always add parentheses for if, for and switch. If
// they're unnecessary, go/printer will strip them when
@@ -118,7 +119,5 @@ func CheckDeMorgan(pass *analysis.Pass) (interface{}, error) {
report.Report(pass, node, "could apply De Morgan's law", report.Fixes(fixes...))
}
- code.PreorderStack(pass, fn, (*ast.UnaryExpr)(nil))
-
return nil, nil
}
diff --git a/vendor/honnef.co/go/tools/quickfix/qf1002/qf1002.go b/vendor/honnef.co/go/tools/quickfix/qf1002/qf1002.go
index ff4bf9cd0..84b847232 100644
--- a/vendor/honnef.co/go/tools/quickfix/qf1002/qf1002.go
+++ b/vendor/honnef.co/go/tools/quickfix/qf1002/qf1002.go
@@ -53,7 +53,7 @@ default:
var Analyzer = SCAnalyzer.Analyzer
-func run(pass *analysis.Pass) (interface{}, error) {
+func run(pass *analysis.Pass) (any, error) {
fn := func(node ast.Node) {
swtch := node.(*ast.SwitchStmt)
if swtch.Tag != nil || len(swtch.Body.List) == 0 {
@@ -112,7 +112,8 @@ func run(pass *analysis.Pass) (interface{}, error) {
pos := swtch.Body.Lbrace
edits = append(edits, edit.ReplaceWithString(edit.Range{pos, pos}, " "+report.Render(pass, x)))
report.Report(pass, swtch, fmt.Sprintf("could use tagged switch on %s", report.Render(pass, x)),
- report.Fixes(edit.Fix("Replace with tagged switch", edits...)))
+ report.Fixes(edit.Fix("Replace with tagged switch", edits...)),
+ report.ShortRange())
}
code.Preorder(pass, fn, (*ast.SwitchStmt)(nil))
diff --git a/vendor/honnef.co/go/tools/quickfix/qf1003/qf1003.go b/vendor/honnef.co/go/tools/quickfix/qf1003/qf1003.go
index dd537f958..f8be70d4c 100644
--- a/vendor/honnef.co/go/tools/quickfix/qf1003/qf1003.go
+++ b/vendor/honnef.co/go/tools/quickfix/qf1003/qf1003.go
@@ -52,21 +52,23 @@ default:
var Analyzer = SCAnalyzer.Analyzer
-func run(pass *analysis.Pass) (interface{}, error) {
- fn := func(node ast.Node, stack []ast.Node) {
- if _, ok := stack[len(stack)-2].(*ast.IfStmt); ok {
+func run(pass *analysis.Pass) (any, error) {
+nodeLoop:
+ for c := range code.Cursor(pass).Preorder((*ast.IfStmt)(nil)) {
+ node := c.Node()
+ if _, ok := c.Parent().Node().(*ast.IfStmt); ok {
// this if statement is part of an if-else chain
- return
+ continue
}
ifstmt := node.(*ast.IfStmt)
m := map[ast.Expr][]*ast.BinaryExpr{}
for item := ifstmt; item != nil; {
if item.Init != nil {
- return
+ continue nodeLoop
}
if item.Body == nil {
- return
+ continue nodeLoop
}
skip := false
@@ -78,12 +80,12 @@ func run(pass *analysis.Pass) (interface{}, error) {
return true
})
if skip {
- return
+ continue nodeLoop
}
var pairs []*ast.BinaryExpr
if !findSwitchPairs(pass, item.Cond, &pairs) {
- return
+ continue nodeLoop
}
m[item.Cond] = pairs
switch els := item.Else.(type) {
@@ -105,19 +107,19 @@ func run(pass *analysis.Pass) (interface{}, error) {
x = pair[0].X
} else {
if !astutil.Equal(x, pair[0].X) {
- return
+ continue nodeLoop
}
}
}
if x == nil {
// shouldn't happen
- return
+ continue nodeLoop
}
// We require at least two 'if' to make this suggestion, to
// avoid clutter in the editor.
if len(m) < 2 {
- return
+ continue nodeLoop
}
// Note that we insert the switch statement as the first text edit instead of the last one so that gopls has an
@@ -174,7 +176,6 @@ func run(pass *analysis.Pass) (interface{}, error) {
report.Fixes(edit.Fix("Replace with tagged switch", edits...)),
report.ShortRange())
}
- code.PreorderStack(pass, fn, (*ast.IfStmt)(nil))
return nil, nil
}
diff --git a/vendor/honnef.co/go/tools/quickfix/qf1004/qf1004.go b/vendor/honnef.co/go/tools/quickfix/qf1004/qf1004.go
index 27f04320f..e18c4d53d 100644
--- a/vendor/honnef.co/go/tools/quickfix/qf1004/qf1004.go
+++ b/vendor/honnef.co/go/tools/quickfix/qf1004/qf1004.go
@@ -3,24 +3,22 @@ package qf1004
import (
"fmt"
"go/ast"
- "go/types"
+ "go/token"
- "honnef.co/go/tools/analysis/code"
"honnef.co/go/tools/analysis/edit"
"honnef.co/go/tools/analysis/lint"
"honnef.co/go/tools/analysis/report"
- "honnef.co/go/tools/go/types/typeutil"
- "honnef.co/go/tools/pattern"
+ typeindexanalyzer "honnef.co/go/tools/internal/analysisinternal/typeindex"
+ "honnef.co/go/tools/internal/typesinternal/typeindex"
"golang.org/x/tools/go/analysis"
- "golang.org/x/tools/go/analysis/passes/inspect"
)
var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
Analyzer: &analysis.Analyzer{
Name: "QF1004",
Run: run,
- Requires: []*analysis.Analyzer{inspect.Analyzer},
+ Requires: []*analysis.Analyzer{typeindexanalyzer.Analyzer},
},
Doc: &lint.RawDocumentation{
Title: `Use \'strings.ReplaceAll\' instead of \'strings.Replace\' with \'n == -1\'`,
@@ -31,49 +29,37 @@ var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
var Analyzer = SCAnalyzer.Analyzer
-var stringsReplaceAllQ = pattern.MustParse(`(Or
- (CallExpr fn@(Symbol "strings.Replace") [_ _ _ lit@(IntegerLiteral "-1")])
- (CallExpr fn@(Symbol "strings.SplitN") [_ _ lit@(IntegerLiteral "-1")])
- (CallExpr fn@(Symbol "strings.SplitAfterN") [_ _ lit@(IntegerLiteral "-1")])
- (CallExpr fn@(Symbol "bytes.Replace") [_ _ _ lit@(IntegerLiteral "-1")])
- (CallExpr fn@(Symbol "bytes.SplitN") [_ _ lit@(IntegerLiteral "-1")])
- (CallExpr fn@(Symbol "bytes.SplitAfterN") [_ _ lit@(IntegerLiteral "-1")]))`)
+var fns = []struct {
+ path string
+ name string
+ replacement string
+}{
+ {"strings", "Replace", "strings.ReplaceAll"},
+ {"strings", "SplitN", "strings.Split"},
+ {"strings", "SplitAfterN", "strings.SplitAfter"},
+ {"bytes", "Replace", "bytes.ReplaceAll"},
+ {"bytes", "SplitN", "bytes.Split"},
+ {"bytes", "SplitAfterN", "bytes.SplitAfter"},
+}
-func run(pass *analysis.Pass) (interface{}, error) {
+func run(pass *analysis.Pass) (any, error) {
// XXX respect minimum Go version
// FIXME(dh): create proper suggested fix for renamed import
- fn := func(node ast.Node) {
- matcher, ok := code.Match(pass, stringsReplaceAllQ, node)
- if !ok {
- return
- }
-
- var replacement string
- switch typeutil.FuncName(matcher.State["fn"].(*types.Func)) {
- case "strings.Replace":
- replacement = "strings.ReplaceAll"
- case "strings.SplitN":
- replacement = "strings.Split"
- case "strings.SplitAfterN":
- replacement = "strings.SplitAfter"
- case "bytes.Replace":
- replacement = "bytes.ReplaceAll"
- case "bytes.SplitN":
- replacement = "bytes.Split"
- case "bytes.SplitAfterN":
- replacement = "bytes.SplitAfter"
- default:
- panic("unreachable")
+ index := pass.ResultOf[typeindexanalyzer.Analyzer].(*typeindex.Index)
+ for _, fn := range fns {
+ for c := range index.Calls(index.Object(fn.path, fn.name)) {
+ call := c.Node().(*ast.CallExpr)
+ if op, ok := call.Args[len(call.Args)-1].(*ast.UnaryExpr); ok && op.Op == token.SUB {
+ if lit, ok := op.X.(*ast.BasicLit); ok && lit.Value == "1" {
+ report.Report(pass, call.Fun, fmt.Sprintf("could use %s instead", fn.replacement),
+ report.Fixes(edit.Fix(fmt.Sprintf("Use %s instead", fn.replacement),
+ edit.ReplaceWithString(call.Fun, fn.replacement),
+ edit.Delete(op))))
+ }
+ }
}
-
- call := node.(*ast.CallExpr)
- report.Report(pass, call.Fun, fmt.Sprintf("could use %s instead", replacement),
- report.Fixes(edit.Fix(fmt.Sprintf("Use %s instead", replacement),
- edit.ReplaceWithString(call.Fun, replacement),
- edit.Delete(matcher.State["lit"].(ast.Node)))))
}
- code.Preorder(pass, fn, (*ast.CallExpr)(nil))
return nil, nil
}
diff --git a/vendor/honnef.co/go/tools/quickfix/qf1005/qf1005.go b/vendor/honnef.co/go/tools/quickfix/qf1005/qf1005.go
index d859bfeb5..048a1dbd2 100644
--- a/vendor/honnef.co/go/tools/quickfix/qf1005/qf1005.go
+++ b/vendor/honnef.co/go/tools/quickfix/qf1005/qf1005.go
@@ -14,14 +14,13 @@ import (
"honnef.co/go/tools/pattern"
"golang.org/x/tools/go/analysis"
- "golang.org/x/tools/go/analysis/passes/inspect"
)
var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
Analyzer: &analysis.Analyzer{
Name: "QF1005",
Run: run,
- Requires: []*analysis.Analyzer{inspect.Analyzer},
+ Requires: code.RequiredAnalyzers,
},
Doc: &lint.RawDocumentation{
Title: `Expand call to \'math.Pow\'`,
@@ -37,20 +36,15 @@ var Analyzer = SCAnalyzer.Analyzer
var mathPowQ = pattern.MustParse(`(CallExpr (Symbol "math.Pow") [x (IntegerLiteral n)])`)
-func run(pass *analysis.Pass) (interface{}, error) {
- fn := func(node ast.Node) {
- matcher, ok := code.Match(pass, mathPowQ, node)
- if !ok {
- return
- }
-
+func run(pass *analysis.Pass) (any, error) {
+ for node, matcher := range code.Matches(pass, mathPowQ) {
x := matcher.State["x"].(ast.Expr)
if code.MayHaveSideEffects(pass, x, nil) {
- return
+ continue
}
n, ok := constant.Int64Val(constant.ToInt(matcher.State["n"].(types.TypeAndValue).Value))
if !ok {
- return
+ continue
}
needConversion := false
@@ -62,7 +56,7 @@ func run(pass *analysis.Pass) (interface{}, error) {
// determine if the constant expression would have type float64 if used on its own
if err := types.CheckExpr(pass.Fset, pass.Pkg, x.Pos(), x, &info); err != nil {
// This should not happen
- return
+ continue
}
if T, ok := info.Types[x].Type.(*types.Basic); ok {
if T.Kind() != types.UntypedFloat && T.Kind() != types.Float64 {
@@ -98,11 +92,11 @@ func run(pass *analysis.Pass) (interface{}, error) {
rc, ok := astutil.CopyExpr(r)
if !ok {
- return
+ continue
}
replacement = astutil.SimplifyParentheses(rc)
default:
- return
+ continue
}
if needConversion && n != 0 {
replacement = &ast.CallExpr{
@@ -113,6 +107,5 @@ func run(pass *analysis.Pass) (interface{}, error) {
report.Report(pass, node, "could expand call to math.Pow",
report.Fixes(edit.Fix("Expand call to math.Pow", edit.ReplaceWithNode(pass.Fset, node, replacement))))
}
- code.Preorder(pass, fn, (*ast.CallExpr)(nil))
return nil, nil
}
diff --git a/vendor/honnef.co/go/tools/quickfix/qf1006/qf1006.go b/vendor/honnef.co/go/tools/quickfix/qf1006/qf1006.go
index 47d4dd0d4..66d5fc538 100644
--- a/vendor/honnef.co/go/tools/quickfix/qf1006/qf1006.go
+++ b/vendor/honnef.co/go/tools/quickfix/qf1006/qf1006.go
@@ -12,14 +12,13 @@ import (
"honnef.co/go/tools/pattern"
"golang.org/x/tools/go/analysis"
- "golang.org/x/tools/go/analysis/passes/inspect"
)
var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
Analyzer: &analysis.Analyzer{
Name: "QF1006",
Run: run,
- Requires: []*analysis.Analyzer{inspect.Analyzer},
+ Requires: code.RequiredAnalyzers,
},
Doc: &lint.RawDocumentation{
Title: `Lift \'if\'+\'break\' into loop condition`,
@@ -44,13 +43,8 @@ var Analyzer = SCAnalyzer.Analyzer
var checkForLoopIfBreak = pattern.MustParse(`(ForStmt nil nil nil if@(IfStmt nil cond (BranchStmt "BREAK" nil) nil):_)`)
-func run(pass *analysis.Pass) (interface{}, error) {
- fn := func(node ast.Node) {
- m, ok := code.Match(pass, checkForLoopIfBreak, node)
- if !ok {
- return
- }
-
+func run(pass *analysis.Pass) (any, error) {
+ for node, m := range code.Matches(pass, checkForLoopIfBreak) {
pos := node.Pos() + token.Pos(len("for"))
r := astutil.NegateDeMorgan(m.State["cond"].(ast.Expr), false)
@@ -63,6 +57,5 @@ func run(pass *analysis.Pass) (interface{}, error) {
edit.ReplaceWithString(edit.Range{pos, pos}, " "+report.Render(pass, r)),
edit.Delete(m.State["if"].(ast.Node)))))
}
- code.Preorder(pass, fn, (*ast.ForStmt)(nil))
return nil, nil
}
diff --git a/vendor/honnef.co/go/tools/quickfix/qf1007/qf1007.go b/vendor/honnef.co/go/tools/quickfix/qf1007/qf1007.go
index 62a339c7f..ab3be1978 100644
--- a/vendor/honnef.co/go/tools/quickfix/qf1007/qf1007.go
+++ b/vendor/honnef.co/go/tools/quickfix/qf1007/qf1007.go
@@ -38,7 +38,7 @@ var Analyzer = SCAnalyzer.Analyzer
var checkConditionalAssignmentQ = pattern.MustParse(`(AssignStmt x@(Object _) ":=" assign@(Builtin b@(Or "true" "false")))`)
var checkConditionalAssignmentIfQ = pattern.MustParse(`(IfStmt nil cond [(AssignStmt x@(Object _) "=" (Builtin b@(Or "true" "false")))] nil)`)
-func run(pass *analysis.Pass) (interface{}, error) {
+func run(pass *analysis.Pass) (any, error) {
fn := func(node ast.Node) {
var body *ast.BlockStmt
switch node := node.(type) {
diff --git a/vendor/honnef.co/go/tools/quickfix/qf1008/qf1008.go b/vendor/honnef.co/go/tools/quickfix/qf1008/qf1008.go
index 799db53d0..e71d6377b 100644
--- a/vendor/honnef.co/go/tools/quickfix/qf1008/qf1008.go
+++ b/vendor/honnef.co/go/tools/quickfix/qf1008/qf1008.go
@@ -30,7 +30,7 @@ var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
var Analyzer = SCAnalyzer.Analyzer
-func run(pass *analysis.Pass) (interface{}, error) {
+func run(pass *analysis.Pass) (any, error) {
type Selector struct {
Node *ast.SelectorExpr
X ast.Expr
@@ -85,7 +85,6 @@ func run(pass *analysis.Pass) (interface{}, error) {
return
}
- var edits []analysis.TextEdit
for _, sel := range sels {
fieldLoop:
for base, fields := pass.TypesInfo.TypeOf(sel.X), sel.Fields; len(fields) >= 2; base, fields = pass.TypesInfo.ObjectOf(fields[0]).Type(), fields[1:] {
@@ -138,18 +137,10 @@ func run(pass *analysis.Pass) (interface{}, error) {
}
e := edit.Delete(edit.Range{hop1.Pos(), hop2.Pos()})
- edits = append(edits, e)
report.Report(pass, hop1, fmt.Sprintf("could remove embedded field %q from selector", hop1.Name),
report.Fixes(edit.Fix(fmt.Sprintf("Remove embedded field %q from selector", hop1.Name), e)))
}
}
-
- // Offer to simplify all selector expressions at once
- if len(edits) > 1 {
- // Hack to prevent gopls from applying the Unnecessary tag to the diagnostic. It applies the tag when all edits are deletions.
- edits = append(edits, edit.ReplaceWithString(edit.Range{node.Pos(), node.Pos()}, ""))
- report.Report(pass, node, "could simplify selectors", report.Fixes(edit.Fix("Remove all embedded fields from selector", edits...)))
- }
}
code.Preorder(pass, fn, (*ast.SelectorExpr)(nil))
return nil, nil
diff --git a/vendor/honnef.co/go/tools/quickfix/qf1009/qf1009.go b/vendor/honnef.co/go/tools/quickfix/qf1009/qf1009.go
index e9fe9fb24..d16e67cdd 100644
--- a/vendor/honnef.co/go/tools/quickfix/qf1009/qf1009.go
+++ b/vendor/honnef.co/go/tools/quickfix/qf1009/qf1009.go
@@ -31,7 +31,7 @@ var Analyzer = SCAnalyzer.Analyzer
var timeEqualR = pattern.MustParse(`(CallExpr (SelectorExpr lhs (Ident "Equal")) rhs)`)
-func run(pass *analysis.Pass) (interface{}, error) {
+func run(pass *analysis.Pass) (any, error) {
// FIXME(dh): create proper suggested fix for renamed import
fn := func(node ast.Node) {
diff --git a/vendor/honnef.co/go/tools/quickfix/qf1010/qf1010.go b/vendor/honnef.co/go/tools/quickfix/qf1010/qf1010.go
index 2062d1f5c..1942bc062 100644
--- a/vendor/honnef.co/go/tools/quickfix/qf1010/qf1010.go
+++ b/vendor/honnef.co/go/tools/quickfix/qf1010/qf1010.go
@@ -12,14 +12,13 @@ import (
"honnef.co/go/tools/pattern"
"golang.org/x/tools/go/analysis"
- "golang.org/x/tools/go/analysis/passes/inspect"
)
var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
Analyzer: &analysis.Analyzer{
Name: "QF1010",
Run: run,
- Requires: []*analysis.Analyzer{inspect.Analyzer},
+ Requires: code.RequiredAnalyzers,
},
Doc: &lint.RawDocumentation{
Title: "Convert slice of bytes to string when printing it",
@@ -57,12 +56,8 @@ var byteSlicePrintingQ = pattern.MustParse(`
var byteSlicePrintingR = pattern.MustParse(`(CallExpr (Ident "string") [arg])`)
-func run(pass *analysis.Pass) (interface{}, error) {
- fn := func(node ast.Node) {
- m, ok := code.Match(pass, byteSlicePrintingQ, node)
- if !ok {
- return
- }
+func run(pass *analysis.Pass) (any, error) {
+ for _, m := range code.Matches(pass, byteSlicePrintingQ) {
args := m.State["args"].([]ast.Expr)
for _, arg := range args {
if !code.IsOfStringConvertibleByteSlice(pass, arg) {
@@ -76,6 +71,5 @@ func run(pass *analysis.Pass) (interface{}, error) {
report.Report(pass, arg, "could convert argument to string", report.Fixes(fix))
}
}
- code.Preorder(pass, fn, (*ast.CallExpr)(nil))
return nil, nil
}
diff --git a/vendor/honnef.co/go/tools/quickfix/qf1012/qf1012.go b/vendor/honnef.co/go/tools/quickfix/qf1012/qf1012.go
index 430610bb2..45784d94e 100644
--- a/vendor/honnef.co/go/tools/quickfix/qf1012/qf1012.go
+++ b/vendor/honnef.co/go/tools/quickfix/qf1012/qf1012.go
@@ -3,6 +3,7 @@ package qf1012
import (
"fmt"
"go/ast"
+ "go/token"
"go/types"
"strings"
@@ -14,14 +15,13 @@ import (
"honnef.co/go/tools/pattern"
"golang.org/x/tools/go/analysis"
- "golang.org/x/tools/go/analysis/passes/inspect"
)
var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
Analyzer: &analysis.Analyzer{
Name: "QF1012",
Run: run,
- Requires: []*analysis.Analyzer{inspect.Analyzer},
+ Requires: code.RequiredAnalyzers,
},
Doc: &lint.RawDocumentation{
Title: `Use \'fmt.Fprintf(x, ...)\' instead of \'x.Write(fmt.Sprintf(...))\'`,
@@ -56,11 +56,27 @@ var (
args))`)
)
-func run(pass *analysis.Pass) (interface{}, error) {
+func run(pass *analysis.Pass) (any, error) {
fn := func(node ast.Node) {
- if m, ok := code.Match(pass, checkWriteBytesSprintfQ, node); ok {
+ getRecv := func(m *pattern.Matcher) (ast.Expr, types.Type) {
recv := m.State["recv"].(ast.Expr)
recvT := pass.TypesInfo.TypeOf(recv)
+
+ // Use *N, not N, for the interface check if N
+ // is a named non-interface type, since the pointer
+ // has a larger method set (https://staticcheck.dev/issues/1097).
+ // We assume the receiver expression is addressable
+ // since otherwise the code wouldn't compile.
+ if _, ok := types.Unalias(recvT).(*types.Named); ok && !types.IsInterface(recvT) {
+ recvT = types.NewPointer(recvT)
+ recv = &ast.UnaryExpr{Op: token.AND, X: recv}
+
+ }
+ return recv, recvT
+ }
+
+ if m, ok := code.Match(pass, checkWriteBytesSprintfQ, node); ok {
+ recv, recvT := getRecv(m)
if !types.Implements(recvT, knowledge.Interfaces["io.Writer"]) {
return
}
@@ -79,8 +95,7 @@ func run(pass *analysis.Pass) (interface{}, error) {
}))
report.Report(pass, node, msg, report.Fixes(fix))
} else if m, ok := code.Match(pass, checkWriteStringSprintfQ, node); ok {
- recv := m.State["recv"].(ast.Expr)
- recvT := pass.TypesInfo.TypeOf(recv)
+ recv, recvT := getRecv(m)
if !types.Implements(recvT, knowledge.Interfaces["io.StringWriter"]) {
return
}
@@ -105,6 +120,9 @@ func run(pass *analysis.Pass) (interface{}, error) {
report.Report(pass, node, msg, report.Fixes(fix))
}
}
+ if !code.CouldMatchAny(pass, checkWriteBytesSprintfQ, checkWriteStringSprintfQ) {
+ return nil, nil
+ }
code.Preorder(pass, fn, (*ast.CallExpr)(nil))
return nil, nil
}
diff --git a/vendor/honnef.co/go/tools/simple/s1000/s1000.go b/vendor/honnef.co/go/tools/simple/s1000/s1000.go
index c5b9a1408..3e4adf917 100644
--- a/vendor/honnef.co/go/tools/simple/s1000/s1000.go
+++ b/vendor/honnef.co/go/tools/simple/s1000/s1000.go
@@ -52,7 +52,7 @@ var (
checkSingleCaseSelectQ2 = pattern.MustParse(`(SelectStmt (CommClause _ _))`)
)
-func run(pass *analysis.Pass) (interface{}, error) {
+func run(pass *analysis.Pass) (any, error) {
seen := map[ast.Node]struct{}{}
fn := func(node ast.Node) {
if m, ok := code.Match(pass, checkSingleCaseSelectQ1, node); ok {
diff --git a/vendor/honnef.co/go/tools/simple/s1001/s1001.go b/vendor/honnef.co/go/tools/simple/s1001/s1001.go
index 889227cd8..ae026e266 100644
--- a/vendor/honnef.co/go/tools/simple/s1001/s1001.go
+++ b/vendor/honnef.co/go/tools/simple/s1001/s1001.go
@@ -14,14 +14,13 @@ import (
"honnef.co/go/tools/pattern"
"golang.org/x/tools/go/analysis"
- "golang.org/x/tools/go/analysis/passes/inspect"
)
var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
Analyzer: &analysis.Analyzer{
Name: "S1001",
Run: run,
- Requires: []*analysis.Analyzer{inspect.Analyzer, generated.Analyzer},
+ Requires: append([]*analysis.Analyzer{generated.Analyzer}, code.RequiredAnalyzers...),
},
Doc: &lint.RawDocumentation{
Title: `Replace for loop with call to copy`,
@@ -58,7 +57,7 @@ var (
[(AssignStmt (IndexExpr dst key) "=" (IndexExpr src key))]))`)
)
-func run(pass *analysis.Pass) (interface{}, error) {
+func run(pass *analysis.Pass) (any, error) {
// TODO revisit once range doesn't require a structural type
isInvariant := func(k, v types.Object, node ast.Expr) bool {
@@ -95,12 +94,7 @@ func run(pass *analysis.Pass) (interface{}, error) {
}
}
- fn := func(node ast.Node) {
- m, ok := code.Match(pass, checkLoopCopyQ, node)
- if !ok {
- return
- }
-
+ for node, m := range code.Matches(pass, checkLoopCopyQ) {
src := m.State["src"].(ast.Expr)
dst := m.State["dst"].(ast.Expr)
@@ -110,32 +104,32 @@ func run(pass *analysis.Pass) (interface{}, error) {
v = pass.TypesInfo.ObjectOf(value.(*ast.Ident))
}
if !isInvariant(k, v, dst) {
- return
+ continue
}
if !isInvariant(k, v, src) {
// For example: 'for i := range foo()'
- return
+ continue
}
Tsrc := pass.TypesInfo.TypeOf(src)
Tdst := pass.TypesInfo.TypeOf(dst)
TsrcElem, TsrcArray, TsrcPointer, ok := elType(Tsrc)
if !ok {
- return
+ continue
}
if TsrcPointer {
Tsrc = Tsrc.Underlying().(*types.Pointer).Elem()
}
TdstElem, TdstArray, TdstPointer, ok := elType(Tdst)
if !ok {
- return
+ continue
}
if TdstPointer {
Tdst = Tdst.Underlying().(*types.Pointer).Elem()
}
if !types.Identical(TsrcElem, TdstElem) {
- return
+ continue
}
if TsrcArray && TdstArray && types.Identical(Tsrc, Tdst) {
@@ -158,7 +152,7 @@ func run(pass *analysis.Pass) (interface{}, error) {
report.Report(pass, node, "should copy arrays using assignment instead of using a loop",
report.FilterGenerated(),
report.ShortRange(),
- report.Fixes(edit.Fix("replace loop with assignment", edit.ReplaceWithNode(pass.Fset, node, r))))
+ report.Fixes(edit.Fix("Replace loop with assignment", edit.ReplaceWithNode(pass.Fset, node, r))))
} else {
tv, err := types.Eval(pass.Fset, pass.Pkg, node.Pos(), "copy")
if err == nil && tv.IsBuiltin() {
@@ -186,12 +180,11 @@ func run(pass *analysis.Pass) (interface{}, error) {
opts := []report.Option{
report.ShortRange(),
report.FilterGenerated(),
- report.Fixes(edit.Fix("replace loop with call to copy()", edit.ReplaceWithNode(pass.Fset, node, r))),
+ report.Fixes(edit.Fix("Replace loop with call to copy()", edit.ReplaceWithNode(pass.Fset, node, r))),
}
report.Report(pass, node, fmt.Sprintf("should use copy(%s, %s) instead of a loop", to, from), opts...)
}
}
}
- code.Preorder(pass, fn, (*ast.ForStmt)(nil), (*ast.RangeStmt)(nil))
return nil, nil
}
diff --git a/vendor/honnef.co/go/tools/simple/s1002/s1002.go b/vendor/honnef.co/go/tools/simple/s1002/s1002.go
index 8cc37fd2a..7d7d8b8d2 100644
--- a/vendor/honnef.co/go/tools/simple/s1002/s1002.go
+++ b/vendor/honnef.co/go/tools/simple/s1002/s1002.go
@@ -37,7 +37,7 @@ var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
var Analyzer = SCAnalyzer.Analyzer
-func run(pass *analysis.Pass) (interface{}, error) {
+func run(pass *analysis.Pass) (any, error) {
fn := func(node ast.Node) {
if code.IsInTest(pass, node) {
return
@@ -81,7 +81,7 @@ func run(pass *analysis.Pass) (interface{}, error) {
}
report.Report(pass, expr, fmt.Sprintf("should omit comparison to bool constant, can be simplified to %s", r),
report.FilterGenerated(),
- report.Fixes(edit.Fix("simplify bool comparison", edit.ReplaceWithString(expr, r))))
+ report.Fixes(edit.Fix("Simplify bool comparison", edit.ReplaceWithString(expr, r))))
}
code.Preorder(pass, fn, (*ast.BinaryExpr)(nil))
return nil, nil
diff --git a/vendor/honnef.co/go/tools/simple/s1003/s1003.go b/vendor/honnef.co/go/tools/simple/s1003/s1003.go
index aa649c5d5..0bd1e0234 100644
--- a/vendor/honnef.co/go/tools/simple/s1003/s1003.go
+++ b/vendor/honnef.co/go/tools/simple/s1003/s1003.go
@@ -32,7 +32,7 @@ var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
var Analyzer = SCAnalyzer.Analyzer
-func run(pass *analysis.Pass) (interface{}, error) {
+func run(pass *analysis.Pass) (any, error) {
// map of value to token to bool value
allowed := map[int64]map[token.Token]bool{
-1: {token.GTR: true, token.NEQ: true, token.EQL: false},
@@ -111,7 +111,7 @@ func run(pass *analysis.Pass) (interface{}, error) {
report.Report(pass, node, fmt.Sprintf("should use %s instead", report.Render(pass, r)),
report.FilterGenerated(),
- report.Fixes(edit.Fix(fmt.Sprintf("simplify use of %s", report.Render(pass, call.Fun)), edit.ReplaceWithNode(pass.Fset, node, r))))
+ report.Fixes(edit.Fix(fmt.Sprintf("Simplify use of %s", report.Render(pass, call.Fun)), edit.ReplaceWithNode(pass.Fset, node, r))))
}
code.Preorder(pass, fn, (*ast.BinaryExpr)(nil))
return nil, nil
diff --git a/vendor/honnef.co/go/tools/simple/s1004/s1004.go b/vendor/honnef.co/go/tools/simple/s1004/s1004.go
index d2b7f58d0..12996835f 100644
--- a/vendor/honnef.co/go/tools/simple/s1004/s1004.go
+++ b/vendor/honnef.co/go/tools/simple/s1004/s1004.go
@@ -13,14 +13,13 @@ import (
"honnef.co/go/tools/pattern"
"golang.org/x/tools/go/analysis"
- "golang.org/x/tools/go/analysis/passes/inspect"
)
var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
Analyzer: &analysis.Analyzer{
Name: "S1004",
Run: CheckBytesCompare,
- Requires: []*analysis.Analyzer{inspect.Analyzer, generated.Analyzer},
+ Requires: append([]*analysis.Analyzer{generated.Analyzer}, code.RequiredAnalyzers...),
},
Doc: &lint.RawDocumentation{
Title: `Replace call to \'bytes.Compare\' with \'bytes.Equal\'`,
@@ -39,17 +38,12 @@ var (
checkBytesCompareRn = pattern.MustParse(`(UnaryExpr "!" (CallExpr (SelectorExpr (Ident "bytes") (Ident "Equal")) args))`)
)
-func CheckBytesCompare(pass *analysis.Pass) (interface{}, error) {
+func CheckBytesCompare(pass *analysis.Pass) (any, error) {
if pass.Pkg.Path() == "bytes" || pass.Pkg.Path() == "bytes_test" {
// the bytes package is free to use bytes.Compare as it sees fit
return nil, nil
}
- fn := func(node ast.Node) {
- m, ok := code.Match(pass, checkBytesCompareQ, node)
- if !ok {
- return
- }
-
+ for node, m := range code.Matches(pass, checkBytesCompareQ) {
args := report.RenderArgs(pass, m.State["args"].([]ast.Expr))
prefix := ""
if m.State["op"].(token.Token) == token.NEQ {
@@ -59,14 +53,13 @@ func CheckBytesCompare(pass *analysis.Pass) (interface{}, error) {
var fix analysis.SuggestedFix
switch tok := m.State["op"].(token.Token); tok {
case token.EQL:
- fix = edit.Fix("simplify use of bytes.Compare", edit.ReplaceWithPattern(pass.Fset, node, checkBytesCompareRe, m.State))
+ fix = edit.Fix("Simplify use of bytes.Compare", edit.ReplaceWithPattern(pass.Fset, node, checkBytesCompareRe, m.State))
case token.NEQ:
- fix = edit.Fix("simplify use of bytes.Compare", edit.ReplaceWithPattern(pass.Fset, node, checkBytesCompareRn, m.State))
+ fix = edit.Fix("Simplify use of bytes.Compare", edit.ReplaceWithPattern(pass.Fset, node, checkBytesCompareRn, m.State))
default:
panic(fmt.Sprintf("unexpected token %v", tok))
}
report.Report(pass, node, fmt.Sprintf("should use %sbytes.Equal(%s) instead", prefix, args), report.FilterGenerated(), report.Fixes(fix))
}
- code.Preorder(pass, fn, (*ast.BinaryExpr)(nil))
return nil, nil
}
diff --git a/vendor/honnef.co/go/tools/simple/s1005/s1005.go b/vendor/honnef.co/go/tools/simple/s1005/s1005.go
index e84ede29a..466f38a4f 100644
--- a/vendor/honnef.co/go/tools/simple/s1005/s1005.go
+++ b/vendor/honnef.co/go/tools/simple/s1005/s1005.go
@@ -53,18 +53,18 @@ var (
(Ident "_") _ recv@(UnaryExpr "<-" _))`)
)
-func run(pass *analysis.Pass) (interface{}, error) {
+func run(pass *analysis.Pass) (any, error) {
fn1 := func(node ast.Node) {
if _, ok := code.Match(pass, checkUnnecessaryBlankQ1, node); ok {
r := *node.(*ast.AssignStmt)
r.Lhs = r.Lhs[0:1]
report.Report(pass, node, "unnecessary assignment to the blank identifier",
report.FilterGenerated(),
- report.Fixes(edit.Fix("remove assignment to blank identifier", edit.ReplaceWithNode(pass.Fset, node, &r))))
+ report.Fixes(edit.Fix("Remove assignment to blank identifier", edit.ReplaceWithNode(pass.Fset, node, &r))))
} else if m, ok := code.Match(pass, checkUnnecessaryBlankQ2, node); ok {
report.Report(pass, node, "unnecessary assignment to the blank identifier",
report.FilterGenerated(),
- report.Fixes(edit.Fix("simplify channel receive operation", edit.ReplaceWithNode(pass.Fset, node, m.State["recv"].(ast.Node)))))
+ report.Fixes(edit.Fix("Simplify channel receive operation", edit.ReplaceWithNode(pass.Fset, node, m.State["recv"].(ast.Node)))))
}
}
@@ -81,7 +81,7 @@ func run(pass *analysis.Pass) (interface{}, error) {
report.Report(pass, rs.Key, "unnecessary assignment to the blank identifier",
report.FilterGenerated(),
report.MinimumLanguageVersion("go1.4"),
- report.Fixes(edit.Fix("remove assignment to blank identifier", edit.Delete(edit.Range{rs.Key.Pos(), rs.TokPos + 1}))))
+ report.Fixes(edit.Fix("Remove assignment to blank identifier", edit.Delete(edit.Range{rs.Key.Pos(), rs.TokPos + 1}))))
}
// for _, _
@@ -90,7 +90,7 @@ func run(pass *analysis.Pass) (interface{}, error) {
report.Report(pass, rs.Key, "unnecessary assignment to the blank identifier",
report.FilterGenerated(),
report.MinimumLanguageVersion("go1.4"),
- report.Fixes(edit.Fix("remove assignment to blank identifier", edit.Delete(edit.Range{rs.Key.Pos(), rs.TokPos + 1}))))
+ report.Fixes(edit.Fix("Remove assignment to blank identifier", edit.Delete(edit.Range{rs.Key.Pos(), rs.TokPos + 1}))))
}
// for x, _
@@ -98,7 +98,7 @@ func run(pass *analysis.Pass) (interface{}, error) {
report.Report(pass, rs.Value, "unnecessary assignment to the blank identifier",
report.FilterGenerated(),
report.MinimumLanguageVersion("go1.4"),
- report.Fixes(edit.Fix("remove assignment to blank identifier", edit.Delete(edit.Range{rs.Key.End(), rs.Value.End()}))))
+ report.Fixes(edit.Fix("Remove assignment to blank identifier", edit.Delete(edit.Range{rs.Key.End(), rs.Value.End()}))))
}
}
diff --git a/vendor/honnef.co/go/tools/simple/s1006/s1006.go b/vendor/honnef.co/go/tools/simple/s1006/s1006.go
index fa177531e..faa58a61a 100644
--- a/vendor/honnef.co/go/tools/simple/s1006/s1006.go
+++ b/vendor/honnef.co/go/tools/simple/s1006/s1006.go
@@ -28,7 +28,7 @@ var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
var Analyzer = SCAnalyzer.Analyzer
-func run(pass *analysis.Pass) (interface{}, error) {
+func run(pass *analysis.Pass) (any, error) {
fn := func(node ast.Node) {
loop := node.(*ast.ForStmt)
if loop.Init != nil || loop.Post != nil {
diff --git a/vendor/honnef.co/go/tools/simple/s1007/s1007.go b/vendor/honnef.co/go/tools/simple/s1007/s1007.go
index ac42c8d18..a92a2bd7c 100644
--- a/vendor/honnef.co/go/tools/simple/s1007/s1007.go
+++ b/vendor/honnef.co/go/tools/simple/s1007/s1007.go
@@ -3,24 +3,22 @@ package s1007
import (
"fmt"
"go/ast"
- "go/token"
"strings"
"honnef.co/go/tools/analysis/code"
"honnef.co/go/tools/analysis/facts/generated"
"honnef.co/go/tools/analysis/lint"
"honnef.co/go/tools/analysis/report"
- "honnef.co/go/tools/knowledge"
+ "honnef.co/go/tools/pattern"
"golang.org/x/tools/go/analysis"
- "golang.org/x/tools/go/analysis/passes/inspect"
)
var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
Analyzer: &analysis.Analyzer{
Name: "S1007",
Run: run,
- Requires: []*analysis.Analyzer{inspect.Analyzer, generated.Analyzer},
+ Requires: append([]*analysis.Analyzer{generated.Analyzer}, code.RequiredAnalyzers...),
},
Doc: &lint.RawDocumentation{
Title: `Simplify regular expression by using raw string literal`,
@@ -39,35 +37,23 @@ can improve their readability.`,
var Analyzer = SCAnalyzer.Analyzer
-func run(pass *analysis.Pass) (interface{}, error) {
- fn := func(node ast.Node) {
- call := node.(*ast.CallExpr)
- if !code.IsCallToAny(pass, call, "regexp.MustCompile", "regexp.Compile") {
- return
- }
- sel, ok := call.Fun.(*ast.SelectorExpr)
- if !ok {
- return
- }
- lit, ok := call.Args[knowledge.Arg("regexp.Compile.expr")].(*ast.BasicLit)
- if !ok {
- // TODO(dominikh): support string concat, maybe support constants
- return
- }
- if lit.Kind != token.STRING {
- // invalid function call
- return
- }
+// TODO(dominikh): support string concat, maybe support constants
+var query = pattern.MustParse(`(CallExpr (Symbol fn@(Or "regexp.MustCompile" "regexp.Compile")) [lit@(BasicLit "STRING" _)])`)
+
+func run(pass *analysis.Pass) (any, error) {
+outer:
+ for _, m := range code.Matches(pass, query) {
+ lit := m.State["lit"].(*ast.BasicLit)
+ val := lit.Value
if lit.Value[0] != '"' {
// already a raw string
- return
+ continue
}
- val := lit.Value
if !strings.Contains(val, `\\`) {
- return
+ continue
}
if strings.Contains(val, "`") {
- return
+ continue
}
bs := false
@@ -82,12 +68,11 @@ func run(pass *analysis.Pass) (interface{}, error) {
}
if bs {
// backslash followed by non-backslash -> escape sequence
- return
+ continue outer
}
}
- report.Report(pass, call, fmt.Sprintf("should use raw string (`...`) with regexp.%s to avoid having to escape twice", sel.Sel.Name), report.FilterGenerated())
+ report.Report(pass, lit, fmt.Sprintf("should use raw string (`...`) with %s to avoid having to escape twice", m.State["fn"]), report.FilterGenerated())
}
- code.Preorder(pass, fn, (*ast.CallExpr)(nil))
return nil, nil
}
diff --git a/vendor/honnef.co/go/tools/simple/s1009/s1009.go b/vendor/honnef.co/go/tools/simple/s1009/s1009.go
index 270215c74..fda7ec085 100644
--- a/vendor/honnef.co/go/tools/simple/s1009/s1009.go
+++ b/vendor/honnef.co/go/tools/simple/s1009/s1009.go
@@ -12,17 +12,16 @@ import (
"honnef.co/go/tools/analysis/lint"
"honnef.co/go/tools/analysis/report"
"honnef.co/go/tools/go/types/typeutil"
- "honnef.co/go/tools/knowledge"
+ "honnef.co/go/tools/pattern"
"golang.org/x/tools/go/analysis"
- "golang.org/x/tools/go/analysis/passes/inspect"
)
var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
Analyzer: &analysis.Analyzer{
Name: "S1009",
Run: run,
- Requires: []*analysis.Analyzer{inspect.Analyzer, generated.Analyzer},
+ Requires: append([]*analysis.Analyzer{generated.Analyzer}, code.RequiredAnalyzers...),
},
Doc: &lint.RawDocumentation{
Title: `Omit redundant nil check on slices, maps, and channels`,
@@ -38,6 +37,18 @@ check for nil before checking that their length is not zero.`,
var Analyzer = SCAnalyzer.Analyzer
+var query = pattern.MustParse(`
+ (BinaryExpr
+ (BinaryExpr
+ x
+ lhsOp@(Or "==" "!=")
+ nilly)
+ outerOp@(Or "&&" "||")
+ (BinaryExpr
+ (CallExpr (Builtin "len") [x])
+ rhsOp
+ k))`)
+
// run checks for the following redundant nil-checks:
//
// if x == nil || len(x) == 0 {}
@@ -47,7 +58,7 @@ var Analyzer = SCAnalyzer.Analyzer
// if x != nil && len(x) == N {} (where N != 0)
// if x != nil && len(x) > N {}
// if x != nil && len(x) >= N {} (where N != 0)
-func run(pass *analysis.Pass) (interface{}, error) {
+func run(pass *analysis.Pass) (any, error) {
isConstZero := func(expr ast.Expr) (isConst bool, isZero bool) {
_, ok := expr.(*ast.BasicLit)
if ok {
@@ -64,116 +75,79 @@ func run(pass *analysis.Pass) (interface{}, error) {
return true, c.Val().Kind() == constant.Int && c.Val().String() == "0"
}
- fn := func(node ast.Node) {
- // check that expr is "x || y" or "x && y"
- expr := node.(*ast.BinaryExpr)
- if expr.Op != token.LOR && expr.Op != token.LAND {
- return
- }
- eqNil := expr.Op == token.LOR
+ for node, m := range code.Matches(pass, query) {
+ x := m.State["x"].(ast.Expr)
+ outerOp := m.State["outerOp"].(token.Token)
+ lhsOp := m.State["lhsOp"].(token.Token)
+ rhsOp := m.State["rhsOp"].(token.Token)
+ nilly := m.State["nilly"].(ast.Expr)
+ k := m.State["k"].(ast.Expr)
+ eqNil := outerOp == token.LOR
- // check that x is "xx == nil" or "xx != nil"
- x, ok := expr.X.(*ast.BinaryExpr)
- if !ok {
- return
- }
- if eqNil && x.Op != token.EQL {
- return
- }
- if !eqNil && x.Op != token.NEQ {
- return
- }
- var xx *ast.Ident
- switch s := x.X.(type) {
- case *ast.Ident:
- xx = s
- case *ast.SelectorExpr:
- xx = s.Sel
- default:
- return
- }
- if !code.IsNil(pass, x.Y) {
- return
+ if code.MayHaveSideEffects(pass, x, nil) {
+ continue
}
- // check that y is "len(xx) == 0" or "len(xx) ... "
- y, ok := expr.Y.(*ast.BinaryExpr)
- if !ok {
- return
+ if eqNil && lhsOp != token.EQL {
+ continue
}
- yx, ok := y.X.(*ast.CallExpr)
- if !ok {
- return
- }
- if !code.IsCallTo(pass, yx, "len") {
- return
+ if !eqNil && lhsOp != token.NEQ {
+ continue
}
- var yxArg *ast.Ident
- switch s := yx.Args[knowledge.Arg("len.v")].(type) {
- case *ast.Ident:
- yxArg = s
- case *ast.SelectorExpr:
- yxArg = s.Sel
- default:
- return
+ if !code.IsNil(pass, nilly) {
+ continue
}
- if yxArg.Name != xx.Name {
- return
- }
-
- isConst, isZero := isConstZero(y.Y)
+ isConst, isZero := isConstZero(k)
if !isConst {
- return
+ continue
}
if eqNil {
- switch y.Op {
+ switch rhsOp {
case token.EQL:
// avoid false positive for "xx == nil || len(xx) == "
if !isZero {
- return
+ continue
}
case token.LEQ:
// ok
case token.LSS:
// avoid false positive for "xx == nil || len(xx) < 0"
if isZero {
- return
+ continue
}
default:
- return
+ continue
}
- }
-
- if !eqNil {
- switch y.Op {
+ } else {
+ switch rhsOp {
case token.EQL:
// avoid false positive for "xx != nil && len(xx) == 0"
if isZero {
- return
+ continue
}
case token.GEQ:
// avoid false positive for "xx != nil && len(xx) >= 0"
if isZero {
- return
+ continue
}
case token.NEQ:
// avoid false positive for "xx != nil && len(xx) != "
if !isZero {
- return
+ continue
}
case token.GTR:
// ok
default:
- return
+ continue
}
}
// finally check that xx type is one of array, slice, map or chan
// this is to prevent false positive in case if xx is a pointer to an array
- typ := pass.TypesInfo.TypeOf(xx)
+ typ := pass.TypesInfo.TypeOf(x)
var nilType string
- ok = typeutil.All(typ, func(term *types.Term) bool {
+ ok := typeutil.All(typ, func(term *types.Term) bool {
switch term.Type().Underlying().(type) {
case *types.Slice:
nilType = "nil slices"
@@ -194,11 +168,13 @@ func run(pass *analysis.Pass) (interface{}, error) {
}
})
if !ok {
- return
+ continue
}
- report.Report(pass, expr, fmt.Sprintf("should omit nil check; len() for %s is defined as zero", nilType), report.FilterGenerated())
+ report.Report(pass, node,
+ fmt.Sprintf("should omit nil check; len() for %s is defined as zero", nilType),
+ report.FilterGenerated())
}
- code.Preorder(pass, fn, (*ast.BinaryExpr)(nil))
+
return nil, nil
}
diff --git a/vendor/honnef.co/go/tools/simple/s1010/s1010.go b/vendor/honnef.co/go/tools/simple/s1010/s1010.go
index 0545718a4..899a65494 100644
--- a/vendor/honnef.co/go/tools/simple/s1010/s1010.go
+++ b/vendor/honnef.co/go/tools/simple/s1010/s1010.go
@@ -11,14 +11,13 @@ import (
"honnef.co/go/tools/pattern"
"golang.org/x/tools/go/analysis"
- "golang.org/x/tools/go/analysis/passes/inspect"
)
var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
Analyzer: &analysis.Analyzer{
Name: "S1010",
Run: run,
- Requires: []*analysis.Analyzer{inspect.Analyzer, generated.Analyzer},
+ Requires: append([]*analysis.Analyzer{generated.Analyzer}, code.RequiredAnalyzers...),
},
Doc: &lint.RawDocumentation{
Title: `Omit default slice index`,
@@ -33,16 +32,13 @@ var Analyzer = SCAnalyzer.Analyzer
var checkSlicingQ = pattern.MustParse(`(SliceExpr x@(Object _) low (CallExpr (Builtin "len") [x]) nil)`)
-func run(pass *analysis.Pass) (interface{}, error) {
- fn := func(node ast.Node) {
- if _, ok := code.Match(pass, checkSlicingQ, node); ok {
- expr := node.(*ast.SliceExpr)
- report.Report(pass, expr.High,
- "should omit second index in slice, s[a:len(s)] is identical to s[a:]",
- report.FilterGenerated(),
- report.Fixes(edit.Fix("simplify slice expression", edit.Delete(expr.High))))
- }
+func run(pass *analysis.Pass) (any, error) {
+ for node := range code.Matches(pass, checkSlicingQ) {
+ expr := node.(*ast.SliceExpr)
+ report.Report(pass, expr.High,
+ "should omit second index in slice, s[a:len(s)] is identical to s[a:]",
+ report.FilterGenerated(),
+ report.Fixes(edit.Fix("Simplify slice expression", edit.Delete(expr.High))))
}
- code.Preorder(pass, fn, (*ast.SliceExpr)(nil))
return nil, nil
}
diff --git a/vendor/honnef.co/go/tools/simple/s1011/s1011.go b/vendor/honnef.co/go/tools/simple/s1011/s1011.go
index 73169266d..50d254964 100644
--- a/vendor/honnef.co/go/tools/simple/s1011/s1011.go
+++ b/vendor/honnef.co/go/tools/simple/s1011/s1011.go
@@ -15,14 +15,13 @@ import (
"honnef.co/go/tools/pattern"
"golang.org/x/tools/go/analysis"
- "golang.org/x/tools/go/analysis/passes/inspect"
)
var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
Analyzer: &analysis.Analyzer{
Name: "S1011",
Run: run,
- Requires: []*analysis.Analyzer{inspect.Analyzer, generated.Analyzer, purity.Analyzer},
+ Requires: append([]*analysis.Analyzer{generated.Analyzer, purity.Analyzer}, code.RequiredAnalyzers...),
},
Doc: &lint.RawDocumentation{
Title: `Use a single \'append\' to concatenate two slices`,
@@ -74,28 +73,23 @@ var checkLoopAppendQ = pattern.MustParse(`
[(AssignStmt val@(Object _) ":=" (IndexExpr x idx))
(AssignStmt [lhs] "=" [(CallExpr (Builtin "append") [lhs val])])]))`)
-func run(pass *analysis.Pass) (interface{}, error) {
+func run(pass *analysis.Pass) (any, error) {
pure := pass.ResultOf[purity.Analyzer].(purity.Result)
- fn := func(node ast.Node) {
- m, ok := code.Match(pass, checkLoopAppendQ, node)
- if !ok {
- return
- }
-
+ for node, m := range code.Matches(pass, checkLoopAppendQ) {
if val, ok := m.State["val"].(types.Object); ok && code.RefersTo(pass, m.State["lhs"].(ast.Expr), val) {
- return
+ continue
}
if m.State["idx"] != nil && code.MayHaveSideEffects(pass, m.State["x"].(ast.Expr), pure) {
// When using an index-based loop, x gets evaluated repeatedly and thus should be pure.
// This doesn't matter for value-based loops, because x only gets evaluated once.
- return
+ continue
}
if idx, ok := m.State["idx"].(types.Object); ok && code.RefersTo(pass, m.State["lhs"].(ast.Expr), idx) {
// The lhs mustn't refer to the index loop variable.
- return
+ continue
}
if code.MayHaveSideEffects(pass, m.State["lhs"].(ast.Expr), pure) {
@@ -110,13 +104,13 @@ func run(pass *analysis.Pass) (interface{}, error) {
// }
//
// The dynamic nature of the lhs might also affect the value of the index.
- return
+ continue
}
src := pass.TypesInfo.TypeOf(m.State["x"].(ast.Expr))
dst := pass.TypesInfo.TypeOf(m.State["lhs"].(ast.Expr))
if !types.Identical(src, dst) {
- return
+ continue
}
r := &ast.AssignStmt{
@@ -137,8 +131,7 @@ func run(pass *analysis.Pass) (interface{}, error) {
report.Report(pass, node, fmt.Sprintf("should replace loop with %s", report.Render(pass, r)),
report.ShortRange(),
report.FilterGenerated(),
- report.Fixes(edit.Fix("replace loop with call to append", edit.ReplaceWithNode(pass.Fset, node, r))))
+ report.Fixes(edit.Fix("Replace loop with call to append", edit.ReplaceWithNode(pass.Fset, node, r))))
}
- code.Preorder(pass, fn, (*ast.RangeStmt)(nil))
return nil, nil
}
diff --git a/vendor/honnef.co/go/tools/simple/s1012/s1012.go b/vendor/honnef.co/go/tools/simple/s1012/s1012.go
index ceabd2cff..33edd55b8 100644
--- a/vendor/honnef.co/go/tools/simple/s1012/s1012.go
+++ b/vendor/honnef.co/go/tools/simple/s1012/s1012.go
@@ -1,8 +1,6 @@
package s1012
import (
- "go/ast"
-
"honnef.co/go/tools/analysis/code"
"honnef.co/go/tools/analysis/edit"
"honnef.co/go/tools/analysis/facts/generated"
@@ -11,14 +9,13 @@ import (
"honnef.co/go/tools/pattern"
"golang.org/x/tools/go/analysis"
- "golang.org/x/tools/go/analysis/passes/inspect"
)
var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
Analyzer: &analysis.Analyzer{
Name: "S1012",
Run: run,
- Requires: []*analysis.Analyzer{inspect.Analyzer, generated.Analyzer},
+ Requires: append([]*analysis.Analyzer{generated.Analyzer}, code.RequiredAnalyzers...),
},
Doc: &lint.RawDocumentation{
Title: `Replace \'time.Now().Sub(x)\' with \'time.Since(x)\'`,
@@ -38,14 +35,12 @@ var (
checkTimeSinceR = pattern.MustParse(`(CallExpr (SelectorExpr (Ident "time") (Ident "Since")) [arg])`)
)
-func run(pass *analysis.Pass) (interface{}, error) {
- fn := func(node ast.Node) {
- if _, edits, ok := code.MatchAndEdit(pass, checkTimeSinceQ, checkTimeSinceR, node); ok {
- report.Report(pass, node, "should use time.Since instead of time.Now().Sub",
- report.FilterGenerated(),
- report.Fixes(edit.Fix("replace with call to time.Since", edits...)))
- }
+func run(pass *analysis.Pass) (any, error) {
+ for node, m := range code.Matches(pass, checkTimeSinceQ) {
+ edits := code.EditMatch(pass, node, m, checkTimeSinceR)
+ report.Report(pass, node, "should use time.Since instead of time.Now().Sub",
+ report.FilterGenerated(),
+ report.Fixes(edit.Fix("Replace with call to time.Since", edits...)))
}
- code.Preorder(pass, fn, (*ast.CallExpr)(nil))
return nil, nil
}
diff --git a/vendor/honnef.co/go/tools/simple/s1016/s1016.go b/vendor/honnef.co/go/tools/simple/s1016/s1016.go
index 01c844aa7..9f0ab30db 100644
--- a/vendor/honnef.co/go/tools/simple/s1016/s1016.go
+++ b/vendor/honnef.co/go/tools/simple/s1016/s1016.go
@@ -15,6 +15,7 @@ import (
"golang.org/x/tools/go/analysis"
"golang.org/x/tools/go/analysis/passes/inspect"
+ "golang.org/x/tools/go/ast/inspector"
)
var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
@@ -46,10 +47,11 @@ y := T2(x)`,
var Analyzer = SCAnalyzer.Analyzer
-func run(pass *analysis.Pass) (interface{}, error) {
+func run(pass *analysis.Pass) (any, error) {
// TODO(dh): support conversions between type parameters
- fn := func(node ast.Node, stack []ast.Node) {
- if unary, ok := stack[len(stack)-2].(*ast.UnaryExpr); ok && unary.Op == token.AND {
+ fn := func(c inspector.Cursor) {
+ node := c.Node()
+ if unary, ok := c.Parent().Node().(*ast.UnaryExpr); ok && unary.Op == token.AND {
// Do not suggest type conversion between pointers
return
}
@@ -182,8 +184,10 @@ func run(pass *analysis.Pass) (interface{}, error) {
report.Report(pass, node,
fmt.Sprintf("should convert %s (type %s) to %s instead of using struct literal", ident.Name, types.TypeString(typ2, types.RelativeTo(pass.Pkg)), types.TypeString(typ1, types.RelativeTo(pass.Pkg))),
report.FilterGenerated(),
- report.Fixes(edit.Fix("use type conversion", edit.ReplaceWithNode(pass.Fset, node, r))))
+ report.Fixes(edit.Fix("Use type conversion", edit.ReplaceWithNode(pass.Fset, node, r))))
+ }
+ for c := range code.Cursor(pass).Preorder((*ast.CompositeLit)(nil)) {
+ fn(c)
}
- code.PreorderStack(pass, fn, (*ast.CompositeLit)(nil))
return nil, nil
}
diff --git a/vendor/honnef.co/go/tools/simple/s1017/s1017.go b/vendor/honnef.co/go/tools/simple/s1017/s1017.go
index aa99b7c2a..cae41eba7 100644
--- a/vendor/honnef.co/go/tools/simple/s1017/s1017.go
+++ b/vendor/honnef.co/go/tools/simple/s1017/s1017.go
@@ -42,7 +42,7 @@ if strings.HasPrefix(str, prefix) {
var Analyzer = SCAnalyzer.Analyzer
-func run(pass *analysis.Pass) (interface{}, error) {
+func run(pass *analysis.Pass) (any, error) {
sameNonDynamic := func(node1, node2 ast.Node) bool {
if reflect.TypeOf(node1) != reflect.TypeOf(node2) {
return false
diff --git a/vendor/honnef.co/go/tools/simple/s1018/s1018.go b/vendor/honnef.co/go/tools/simple/s1018/s1018.go
index ef3ee897c..98e397564 100644
--- a/vendor/honnef.co/go/tools/simple/s1018/s1018.go
+++ b/vendor/honnef.co/go/tools/simple/s1018/s1018.go
@@ -12,14 +12,13 @@ import (
"honnef.co/go/tools/pattern"
"golang.org/x/tools/go/analysis"
- "golang.org/x/tools/go/analysis/passes/inspect"
)
var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
Analyzer: &analysis.Analyzer{
Name: "S1018",
Run: run,
- Requires: []*analysis.Analyzer{inspect.Analyzer, generated.Analyzer},
+ Requires: append([]*analysis.Analyzer{generated.Analyzer}, code.RequiredAnalyzers...),
},
Doc: &lint.RawDocumentation{
Title: `Use \"copy\" for sliding elements`,
@@ -56,29 +55,24 @@ var (
(SliceExpr slice offset nil nil)])`)
)
-func run(pass *analysis.Pass) (interface{}, error) {
+func run(pass *analysis.Pass) (any, error) {
// TODO(dh): detect bs[i+offset] in addition to bs[offset+i]
// TODO(dh): consider merging this function with LintLoopCopy
// TODO(dh): detect length that is an expression, not a variable name
// TODO(dh): support sliding to a different offset than the beginning of the slice
- fn := func(node ast.Node) {
- loop := node.(*ast.ForStmt)
- m, edits, ok := code.MatchAndEdit(pass, checkLoopSlideQ, checkLoopSlideR, loop)
- if !ok {
- return
- }
+ for node, m := range code.Matches(pass, checkLoopSlideQ) {
typ := pass.TypesInfo.TypeOf(m.State["slice"].(*ast.Ident))
// The pattern probably needs a core type, but All is fine, too. Either way we only accept slices.
if !typeutil.All(typ, typeutil.IsSlice) {
- return
+ continue
}
- report.Report(pass, loop, "should use copy() instead of loop for sliding slice elements",
+ edits := code.EditMatch(pass, node, m, checkLoopSlideR)
+ report.Report(pass, node, "should use copy() instead of loop for sliding slice elements",
report.ShortRange(),
report.FilterGenerated(),
- report.Fixes(edit.Fix("use copy() instead of loop", edits...)))
+ report.Fixes(edit.Fix("Use copy() instead of loop", edits...)))
}
- code.Preorder(pass, fn, (*ast.ForStmt)(nil))
return nil, nil
}
diff --git a/vendor/honnef.co/go/tools/simple/s1019/s1019.go b/vendor/honnef.co/go/tools/simple/s1019/s1019.go
index 4f3288edb..03e2b10c7 100644
--- a/vendor/honnef.co/go/tools/simple/s1019/s1019.go
+++ b/vendor/honnef.co/go/tools/simple/s1019/s1019.go
@@ -42,7 +42,7 @@ var (
checkMakeLenCapQ2 = pattern.MustParse(`(CallExpr (Builtin "make") [typ size size])`)
)
-func run(pass *analysis.Pass) (interface{}, error) {
+func run(pass *analysis.Pass) (any, error) {
fn := func(node ast.Node) {
if pass.Pkg.Path() == "runtime_test" && filepath.Base(pass.Fset.Position(node.Pos()).Filename) == "map_test.go" {
// special case of runtime tests testing map creation
diff --git a/vendor/honnef.co/go/tools/simple/s1020/s1020.go b/vendor/honnef.co/go/tools/simple/s1020/s1020.go
index 8795847ef..19835563a 100644
--- a/vendor/honnef.co/go/tools/simple/s1020/s1020.go
+++ b/vendor/honnef.co/go/tools/simple/s1020/s1020.go
@@ -12,14 +12,13 @@ import (
"honnef.co/go/tools/pattern"
"golang.org/x/tools/go/analysis"
- "golang.org/x/tools/go/analysis/passes/inspect"
)
var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
Analyzer: &analysis.Analyzer{
Name: "S1020",
Run: run,
- Requires: []*analysis.Analyzer{inspect.Analyzer, generated.Analyzer},
+ Requires: append([]*analysis.Analyzer{generated.Analyzer}, code.RequiredAnalyzers...),
},
Doc: &lint.RawDocumentation{
Title: `Omit redundant nil check in type assertion`,
@@ -55,23 +54,15 @@ var (
nil)`)
)
-func run(pass *analysis.Pass) (interface{}, error) {
- fn1 := func(node ast.Node) {
- m, ok := code.Match(pass, checkAssertNotNilFn1Q, node)
- if !ok {
- return
- }
+func run(pass *analysis.Pass) (any, error) {
+ for node, m := range code.Matches(pass, checkAssertNotNilFn1Q) {
assert := m.State["assert"].(types.Object)
assign := m.State["ok"].(types.Object)
report.Report(pass, node, fmt.Sprintf("when %s is true, %s can't be nil", assign.Name(), assert.Name()),
report.ShortRange(),
report.FilterGenerated())
}
- fn2 := func(node ast.Node) {
- m, ok := code.Match(pass, checkAssertNotNilFn2Q, node)
- if !ok {
- return
- }
+ for _, m := range code.Matches(pass, checkAssertNotNilFn2Q) {
ifstmt := m.State["ifstmt"].(*ast.IfStmt)
lhs := m.State["lhs"].(types.Object)
assignIdent := m.State["ok"].(types.Object)
@@ -79,8 +70,5 @@ func run(pass *analysis.Pass) (interface{}, error) {
report.ShortRange(),
report.FilterGenerated())
}
- // OPT(dh): merge fn1 and fn2
- code.Preorder(pass, fn1, (*ast.IfStmt)(nil))
- code.Preorder(pass, fn2, (*ast.IfStmt)(nil))
return nil, nil
}
diff --git a/vendor/honnef.co/go/tools/simple/s1021/s1021.go b/vendor/honnef.co/go/tools/simple/s1021/s1021.go
index 6ea8e4f60..14f32f04b 100644
--- a/vendor/honnef.co/go/tools/simple/s1021/s1021.go
+++ b/vendor/honnef.co/go/tools/simple/s1021/s1021.go
@@ -33,7 +33,7 @@ x = 1`,
var Analyzer = SCAnalyzer.Analyzer
-func run(pass *analysis.Pass) (interface{}, error) {
+func run(pass *analysis.Pass) (any, error) {
hasMultipleAssignments := func(root ast.Node, ident *ast.Ident) bool {
num := 0
ast.Inspect(root, func(node ast.Node) bool {
@@ -110,7 +110,7 @@ func run(pass *analysis.Pass) (interface{}, error) {
}
report.Report(pass, decl, "should merge variable declaration with assignment on next line",
report.FilterGenerated(),
- report.Fixes(edit.Fix("merge declaration with assignment", edit.ReplaceWithNode(pass.Fset, edit.Range{decl.Pos(), assign.End()}, r))))
+ report.Fixes(edit.Fix("Merge declaration with assignment", edit.ReplaceWithNode(pass.Fset, edit.Range{decl.Pos(), assign.End()}, r))))
}
}
code.Preorder(pass, fn, (*ast.BlockStmt)(nil))
diff --git a/vendor/honnef.co/go/tools/simple/s1023/s1023.go b/vendor/honnef.co/go/tools/simple/s1023/s1023.go
index a2e8fcd2b..f106d3154 100644
--- a/vendor/honnef.co/go/tools/simple/s1023/s1023.go
+++ b/vendor/honnef.co/go/tools/simple/s1023/s1023.go
@@ -34,7 +34,7 @@ statement in a case block.`,
var Analyzer = SCAnalyzer.Analyzer
-func run(pass *analysis.Pass) (interface{}, error) {
+func run(pass *analysis.Pass) (any, error) {
fn1 := func(node ast.Node) {
clause := node.(*ast.CaseClause)
if len(clause.Body) < 2 {
diff --git a/vendor/honnef.co/go/tools/simple/s1024/s1024.go b/vendor/honnef.co/go/tools/simple/s1024/s1024.go
index dbf8940b3..82d3730d6 100644
--- a/vendor/honnef.co/go/tools/simple/s1024/s1024.go
+++ b/vendor/honnef.co/go/tools/simple/s1024/s1024.go
@@ -11,14 +11,13 @@ import (
"honnef.co/go/tools/pattern"
"golang.org/x/tools/go/analysis"
- "golang.org/x/tools/go/analysis/passes/inspect"
)
var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
Analyzer: &analysis.Analyzer{
Name: "S1024",
Run: run,
- Requires: []*analysis.Analyzer{inspect.Analyzer, generated.Analyzer},
+ Requires: append([]*analysis.Analyzer{generated.Analyzer}, code.RequiredAnalyzers...),
},
Doc: &lint.RawDocumentation{
Title: `Replace \'x.Sub(time.Now())\' with \'time.Until(x)\'`,
@@ -38,22 +37,19 @@ var (
checkTimeUntilR = pattern.MustParse(`(CallExpr (SelectorExpr (Ident "time") (Ident "Until")) [arg])`)
)
-func run(pass *analysis.Pass) (interface{}, error) {
- fn := func(node ast.Node) {
- if _, ok := code.Match(pass, checkTimeUntilQ, node); ok {
- if sel, ok := node.(*ast.CallExpr).Fun.(*ast.SelectorExpr); ok {
- r := pattern.NodeToAST(checkTimeUntilR.Root, map[string]interface{}{"arg": sel.X}).(ast.Node)
- report.Report(pass, node, "should use time.Until instead of t.Sub(time.Now())",
- report.FilterGenerated(),
- report.MinimumStdlibVersion("go1.8"),
- report.Fixes(edit.Fix("replace with call to time.Until", edit.ReplaceWithNode(pass.Fset, node, r))))
- } else {
- report.Report(pass, node, "should use time.Until instead of t.Sub(time.Now())",
- report.MinimumStdlibVersion("go1.8"),
- report.FilterGenerated())
- }
+func run(pass *analysis.Pass) (any, error) {
+ for node := range code.Matches(pass, checkTimeUntilQ) {
+ if sel, ok := node.(*ast.CallExpr).Fun.(*ast.SelectorExpr); ok {
+ r := pattern.NodeToAST(checkTimeUntilR.Root, map[string]any{"arg": sel.X}).(ast.Node)
+ report.Report(pass, node, "should use time.Until instead of t.Sub(time.Now())",
+ report.FilterGenerated(),
+ report.MinimumStdlibVersion("go1.8"),
+ report.Fixes(edit.Fix("Replace with call to time.Until", edit.ReplaceWithNode(pass.Fset, node, r))))
+ } else {
+ report.Report(pass, node, "should use time.Until instead of t.Sub(time.Now())",
+ report.MinimumStdlibVersion("go1.8"),
+ report.FilterGenerated())
}
}
- code.Preorder(pass, fn, (*ast.CallExpr)(nil))
return nil, nil
}
diff --git a/vendor/honnef.co/go/tools/simple/s1025/s1025.go b/vendor/honnef.co/go/tools/simple/s1025/s1025.go
index 3ea2996d1..9260789b9 100644
--- a/vendor/honnef.co/go/tools/simple/s1025/s1025.go
+++ b/vendor/honnef.co/go/tools/simple/s1025/s1025.go
@@ -16,14 +16,16 @@ import (
"golang.org/x/exp/typeparams"
"golang.org/x/tools/go/analysis"
- "golang.org/x/tools/go/analysis/passes/inspect"
)
var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
Analyzer: &analysis.Analyzer{
- Name: "S1025",
- Run: run,
- Requires: []*analysis.Analyzer{buildir.Analyzer, inspect.Analyzer, generated.Analyzer},
+ Name: "S1025",
+ Run: run,
+ Requires: append([]*analysis.Analyzer{
+ buildir.Analyzer,
+ generated.Analyzer,
+ }, code.RequiredAnalyzers...),
},
Doc: &lint.RawDocumentation{
Title: `Don't use \'fmt.Sprintf("%s", x)\' unnecessarily`,
@@ -64,36 +66,31 @@ var Analyzer = SCAnalyzer.Analyzer
var checkRedundantSprintfQ = pattern.MustParse(`(CallExpr (Symbol "fmt.Sprintf") [format arg])`)
-func run(pass *analysis.Pass) (interface{}, error) {
- fn := func(node ast.Node) {
- m, ok := code.Match(pass, checkRedundantSprintfQ, node)
- if !ok {
- return
- }
-
+func run(pass *analysis.Pass) (any, error) {
+ for node, m := range code.Matches(pass, checkRedundantSprintfQ) {
format := m.State["format"].(ast.Expr)
arg := m.State["arg"].(ast.Expr)
// TODO(dh): should we really support named constants here?
// shouldn't we only look for string literals? to avoid false
// positives via build tags?
if s, ok := code.ExprToString(pass, format); !ok || s != "%s" {
- return
+ continue
}
typ := pass.TypesInfo.TypeOf(arg)
if typeparams.IsTypeParam(typ) {
- return
+ continue
}
irpkg := pass.ResultOf[buildir.Analyzer].(*buildir.IR).Pkg
if typeutil.IsTypeWithName(typ, "reflect.Value") {
// printing with %s produces output different from using
// the String method
- return
+ continue
}
if isFormatter(typ, &irpkg.Prog.MethodSets) {
// the type may choose to handle %s in arbitrary ways
- return
+ continue
}
if types.Implements(typ, knowledge.Interfaces["fmt.Stringer"]) {
@@ -104,11 +101,11 @@ func run(pass *analysis.Pass) (interface{}, error) {
},
}
report.Report(pass, node, "should use String() instead of fmt.Sprintf",
- report.Fixes(edit.Fix("replace with call to String method", edit.ReplaceWithNode(pass.Fset, node, replacement))))
+ report.Fixes(edit.Fix("Replace with call to String method", edit.ReplaceWithNode(pass.Fset, node, replacement))))
} else if types.Unalias(typ) == types.Universe.Lookup("string").Type() {
report.Report(pass, node, "the argument is already a string, there's no need to use fmt.Sprintf",
report.FilterGenerated(),
- report.Fixes(edit.Fix("remove unnecessary call to fmt.Sprintf", edit.ReplaceWithNode(pass.Fset, node, arg))))
+ report.Fixes(edit.Fix("Remove unnecessary call to fmt.Sprintf", edit.ReplaceWithNode(pass.Fset, node, arg))))
} else if typ.Underlying() == types.Universe.Lookup("string").Type() {
replacement := &ast.CallExpr{
Fun: &ast.Ident{Name: "string"},
@@ -116,7 +113,7 @@ func run(pass *analysis.Pass) (interface{}, error) {
}
report.Report(pass, node, "the argument's underlying type is a string, should use a simple conversion instead of fmt.Sprintf",
report.FilterGenerated(),
- report.Fixes(edit.Fix("replace with conversion to string", edit.ReplaceWithNode(pass.Fset, node, replacement))))
+ report.Fixes(edit.Fix("Replace with conversion to string", edit.ReplaceWithNode(pass.Fset, node, replacement))))
} else if code.IsOfStringConvertibleByteSlice(pass, arg) {
replacement := &ast.CallExpr{
Fun: &ast.Ident{Name: "string"},
@@ -124,11 +121,10 @@ func run(pass *analysis.Pass) (interface{}, error) {
}
report.Report(pass, node, "the argument's underlying type is a slice of bytes, should use a simple conversion instead of fmt.Sprintf",
report.FilterGenerated(),
- report.Fixes(edit.Fix("replace with conversion to string", edit.ReplaceWithNode(pass.Fset, node, replacement))))
+ report.Fixes(edit.Fix("Replace with conversion to string", edit.ReplaceWithNode(pass.Fset, node, replacement))))
}
}
- code.Preorder(pass, fn, (*ast.CallExpr)(nil))
return nil, nil
}
diff --git a/vendor/honnef.co/go/tools/simple/s1028/s1028.go b/vendor/honnef.co/go/tools/simple/s1028/s1028.go
index 2d2588e23..45da204d2 100644
--- a/vendor/honnef.co/go/tools/simple/s1028/s1028.go
+++ b/vendor/honnef.co/go/tools/simple/s1028/s1028.go
@@ -1,8 +1,6 @@
package s1028
import (
- "go/ast"
-
"honnef.co/go/tools/analysis/code"
"honnef.co/go/tools/analysis/edit"
"honnef.co/go/tools/analysis/facts/generated"
@@ -11,14 +9,13 @@ import (
"honnef.co/go/tools/pattern"
"golang.org/x/tools/go/analysis"
- "golang.org/x/tools/go/analysis/passes/inspect"
)
var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
Analyzer: &analysis.Analyzer{
Name: "S1028",
Run: run,
- Requires: []*analysis.Analyzer{inspect.Analyzer, generated.Analyzer},
+ Requires: append([]*analysis.Analyzer{generated.Analyzer}, code.RequiredAnalyzers...),
},
Doc: &lint.RawDocumentation{
Title: `Simplify error construction with \'fmt.Errorf\'`,
@@ -36,15 +33,13 @@ var (
checkErrorsNewSprintfR = pattern.MustParse(`(CallExpr (SelectorExpr (Ident "fmt") (Ident "Errorf")) args)`)
)
-func run(pass *analysis.Pass) (interface{}, error) {
- fn := func(node ast.Node) {
- if _, edits, ok := code.MatchAndEdit(pass, checkErrorsNewSprintfQ, checkErrorsNewSprintfR, node); ok {
- // TODO(dh): the suggested fix may leave an unused import behind
- report.Report(pass, node, "should use fmt.Errorf(...) instead of errors.New(fmt.Sprintf(...))",
- report.FilterGenerated(),
- report.Fixes(edit.Fix("use fmt.Errorf", edits...)))
- }
+func run(pass *analysis.Pass) (any, error) {
+ for node, m := range code.Matches(pass, checkErrorsNewSprintfQ) {
+ edits := code.EditMatch(pass, node, m, checkErrorsNewSprintfR)
+ // TODO(dh): the suggested fix may leave an unused import behind
+ report.Report(pass, node, "should use fmt.Errorf(...) instead of errors.New(fmt.Sprintf(...))",
+ report.FilterGenerated(),
+ report.Fixes(edit.Fix("Use fmt.Errorf", edits...)))
}
- code.Preorder(pass, fn, (*ast.CallExpr)(nil))
return nil, nil
}
diff --git a/vendor/honnef.co/go/tools/simple/s1030/s1030.go b/vendor/honnef.co/go/tools/simple/s1030/s1030.go
index 4adf8d8b5..44c8820cd 100644
--- a/vendor/honnef.co/go/tools/simple/s1030/s1030.go
+++ b/vendor/honnef.co/go/tools/simple/s1030/s1030.go
@@ -14,6 +14,7 @@ import (
"golang.org/x/tools/go/analysis"
"golang.org/x/tools/go/analysis/passes/inspect"
+ "golang.org/x/tools/go/ast/inspector"
)
var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
@@ -44,12 +45,13 @@ var (
checkBytesBufferConversionsRb = pattern.MustParse(`(CallExpr (SelectorExpr recv (Ident "Bytes")) [])`)
)
-func run(pass *analysis.Pass) (interface{}, error) {
+func run(pass *analysis.Pass) (any, error) {
if pass.Pkg.Path() == "bytes" || pass.Pkg.Path() == "bytes_test" {
// The bytes package can use itself however it wants
return nil, nil
}
- fn := func(node ast.Node, stack []ast.Node) {
+ fn := func(c inspector.Cursor) {
+ node := c.Node()
m, ok := code.Match(pass, checkBytesBufferConversionsQ, node)
if !ok {
return
@@ -59,7 +61,7 @@ func run(pass *analysis.Pass) (interface{}, error) {
typ := pass.TypesInfo.TypeOf(call.Fun)
if types.Unalias(typ) == types.Universe.Lookup("string").Type() && code.IsCallTo(pass, call.Args[0], "(*bytes.Buffer).Bytes") {
- if _, ok := stack[len(stack)-2].(*ast.IndexExpr); ok {
+ if _, ok := c.Parent().Node().(*ast.IndexExpr); ok {
// Don't flag m[string(buf.Bytes())] – thanks to a
// compiler optimization, this is actually faster than
// m[buf.String()]
@@ -68,16 +70,18 @@ func run(pass *analysis.Pass) (interface{}, error) {
report.Report(pass, call, fmt.Sprintf("should use %v.String() instead of %v", report.Render(pass, sel.X), report.Render(pass, call)),
report.FilterGenerated(),
- report.Fixes(edit.Fix("simplify conversion", edit.ReplaceWithPattern(pass.Fset, node, checkBytesBufferConversionsRs, m.State))))
+ report.Fixes(edit.Fix("Simplify conversion", edit.ReplaceWithPattern(pass.Fset, node, checkBytesBufferConversionsRs, m.State))))
} else if typ, ok := types.Unalias(typ).(*types.Slice); ok &&
types.Unalias(typ.Elem()) == types.Universe.Lookup("byte").Type() &&
code.IsCallTo(pass, call.Args[0], "(*bytes.Buffer).String") {
report.Report(pass, call, fmt.Sprintf("should use %v.Bytes() instead of %v", report.Render(pass, sel.X), report.Render(pass, call)),
report.FilterGenerated(),
- report.Fixes(edit.Fix("simplify conversion", edit.ReplaceWithPattern(pass.Fset, node, checkBytesBufferConversionsRb, m.State))))
+ report.Fixes(edit.Fix("Simplify conversion", edit.ReplaceWithPattern(pass.Fset, node, checkBytesBufferConversionsRb, m.State))))
}
}
- code.PreorderStack(pass, fn, (*ast.CallExpr)(nil))
+ for c := range code.Cursor(pass).Preorder((*ast.CallExpr)(nil)) {
+ fn(c)
+ }
return nil, nil
}
diff --git a/vendor/honnef.co/go/tools/simple/s1031/s1031.go b/vendor/honnef.co/go/tools/simple/s1031/s1031.go
index e1ce6aa04..4be017191 100644
--- a/vendor/honnef.co/go/tools/simple/s1031/s1031.go
+++ b/vendor/honnef.co/go/tools/simple/s1031/s1031.go
@@ -1,7 +1,6 @@
package s1031
import (
- "go/ast"
"go/types"
"honnef.co/go/tools/analysis/code"
@@ -12,14 +11,13 @@ import (
"honnef.co/go/tools/pattern"
"golang.org/x/tools/go/analysis"
- "golang.org/x/tools/go/analysis/passes/inspect"
)
var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
Analyzer: &analysis.Analyzer{
Name: "S1031",
Run: run,
- Requires: []*analysis.Analyzer{inspect.Analyzer, generated.Analyzer},
+ Requires: append([]*analysis.Analyzer{generated.Analyzer}, code.RequiredAnalyzers...),
},
Doc: &lint.RawDocumentation{
Title: `Omit redundant nil check around loop`,
@@ -52,13 +50,9 @@ var checkNilCheckAroundRangeQ = pattern.MustParse(`
[(RangeStmt _ _ _ x _)]
nil)`)
-func run(pass *analysis.Pass) (interface{}, error) {
- fn := func(node ast.Node) {
- m, ok := code.Match(pass, checkNilCheckAroundRangeQ, node)
- if !ok {
- return
- }
- ok = typeutil.All(m.State["x"].(types.Object).Type(), func(term *types.Term) bool {
+func run(pass *analysis.Pass) (any, error) {
+ for node, m := range code.Matches(pass, checkNilCheckAroundRangeQ) {
+ ok := typeutil.All(m.State["x"].(types.Object).Type(), func(term *types.Term) bool {
switch term.Type().Underlying().(type) {
case *types.Slice, *types.Map:
return true
@@ -69,11 +63,9 @@ func run(pass *analysis.Pass) (interface{}, error) {
return false
}
})
- if !ok {
- return
+ if ok {
+ report.Report(pass, node, "unnecessary nil check around range", report.ShortRange(), report.FilterGenerated())
}
- report.Report(pass, node, "unnecessary nil check around range", report.ShortRange(), report.FilterGenerated())
}
- code.Preorder(pass, fn, (*ast.IfStmt)(nil))
return nil, nil
}
diff --git a/vendor/honnef.co/go/tools/simple/s1032/s1032.go b/vendor/honnef.co/go/tools/simple/s1032/s1032.go
index 7a0873cca..6684db8f3 100644
--- a/vendor/honnef.co/go/tools/simple/s1032/s1032.go
+++ b/vendor/honnef.co/go/tools/simple/s1032/s1032.go
@@ -56,7 +56,7 @@ func isPermissibleSort(pass *analysis.Pass, node ast.Node) bool {
return false
}
-func run(pass *analysis.Pass) (interface{}, error) {
+func run(pass *analysis.Pass) (any, error) {
type Error struct {
node ast.Node
msg string
diff --git a/vendor/honnef.co/go/tools/simple/s1033/s1033.go b/vendor/honnef.co/go/tools/simple/s1033/s1033.go
index bf2895298..f6704f45b 100644
--- a/vendor/honnef.co/go/tools/simple/s1033/s1033.go
+++ b/vendor/honnef.co/go/tools/simple/s1033/s1033.go
@@ -11,14 +11,13 @@ import (
"honnef.co/go/tools/pattern"
"golang.org/x/tools/go/analysis"
- "golang.org/x/tools/go/analysis/passes/inspect"
)
var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
Analyzer: &analysis.Analyzer{
Name: "S1033",
Run: run,
- Requires: []*analysis.Analyzer{inspect.Analyzer, generated.Analyzer},
+ Requires: append([]*analysis.Analyzer{generated.Analyzer}, code.RequiredAnalyzers...),
},
Doc: &lint.RawDocumentation{
Title: `Unnecessary guard around call to \"delete\"`,
@@ -40,16 +39,12 @@ var checkGuardedDeleteQ = pattern.MustParse(`
[call@(CallExpr (Builtin "delete") [m key])]
nil)`)
-func run(pass *analysis.Pass) (interface{}, error) {
- fn := func(node ast.Node) {
- if m, ok := code.Match(pass, checkGuardedDeleteQ, node); ok {
- report.Report(pass, node, "unnecessary guard around call to delete",
- report.ShortRange(),
- report.FilterGenerated(),
- report.Fixes(edit.Fix("remove guard", edit.ReplaceWithNode(pass.Fset, node, m.State["call"].(ast.Node)))))
- }
+func run(pass *analysis.Pass) (any, error) {
+ for node, m := range code.Matches(pass, checkGuardedDeleteQ) {
+ report.Report(pass, node, "unnecessary guard around call to delete",
+ report.ShortRange(),
+ report.FilterGenerated(),
+ report.Fixes(edit.Fix("Remove guard", edit.ReplaceWithNode(pass.Fset, node, m.State["call"].(ast.Node)))))
}
-
- code.Preorder(pass, fn, (*ast.IfStmt)(nil))
return nil, nil
}
diff --git a/vendor/honnef.co/go/tools/simple/s1034/s1034.go b/vendor/honnef.co/go/tools/simple/s1034/s1034.go
index e561dfe4f..9eb953127 100644
--- a/vendor/honnef.co/go/tools/simple/s1034/s1034.go
+++ b/vendor/honnef.co/go/tools/simple/s1034/s1034.go
@@ -13,14 +13,13 @@ import (
"honnef.co/go/tools/pattern"
"golang.org/x/tools/go/analysis"
- "golang.org/x/tools/go/analysis/passes/inspect"
)
var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
Analyzer: &analysis.Analyzer{
Name: "S1034",
Run: run,
- Requires: []*analysis.Analyzer{inspect.Analyzer, generated.Analyzer},
+ Requires: append([]*analysis.Analyzer{generated.Analyzer}, code.RequiredAnalyzers...),
},
Doc: &lint.RawDocumentation{
Title: `Use result of type assertion to simplify cases`,
@@ -40,12 +39,8 @@ var (
checkSimplifyTypeSwitchR = pattern.MustParse(`(AssignStmt ident ":=" expr)`)
)
-func run(pass *analysis.Pass) (interface{}, error) {
- fn := func(node ast.Node) {
- m, ok := code.Match(pass, checkSimplifyTypeSwitchQ, node)
- if !ok {
- return
- }
+func run(pass *analysis.Pass) (any, error) {
+ for node, m := range code.Matches(pass, checkSimplifyTypeSwitchQ) {
stmt := node.(*ast.TypeSwitchStmt)
expr := m.State["expr"].(ast.Node)
ident := m.State["ident"].(*ast.Ident)
@@ -107,13 +102,12 @@ func run(pass *analysis.Pass) (interface{}, error) {
for _, offender := range allOffenders {
edits = append(edits, edit.ReplaceWithNode(pass.Fset, offender, offender.X))
}
- opts = append(opts, report.Fixes(edit.Fix("simplify type switch", edits...)))
+ opts = append(opts, report.Fixes(edit.Fix("Simplify type switch", edits...)))
report.Report(pass, expr, msg, opts...)
} else {
report.Report(pass, expr, msg, opts...)
}
}
}
- code.Preorder(pass, fn, (*ast.TypeSwitchStmt)(nil))
return nil, nil
}
diff --git a/vendor/honnef.co/go/tools/simple/s1035/s1035.go b/vendor/honnef.co/go/tools/simple/s1035/s1035.go
index ed5faf757..969502a90 100644
--- a/vendor/honnef.co/go/tools/simple/s1035/s1035.go
+++ b/vendor/honnef.co/go/tools/simple/s1035/s1035.go
@@ -9,16 +9,16 @@ import (
"honnef.co/go/tools/analysis/facts/generated"
"honnef.co/go/tools/analysis/lint"
"honnef.co/go/tools/analysis/report"
+ "honnef.co/go/tools/pattern"
"golang.org/x/tools/go/analysis"
- "golang.org/x/tools/go/analysis/passes/inspect"
)
var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
Analyzer: &analysis.Analyzer{
Name: "S1035",
Run: run,
- Requires: []*analysis.Analyzer{inspect.Analyzer, generated.Analyzer},
+ Requires: append([]*analysis.Analyzer{generated.Analyzer}, code.RequiredAnalyzers...),
},
Doc: &lint.RawDocumentation{
Title: `Redundant call to \'net/http.CanonicalHeaderKey\' in method call on \'net/http.Header\'`,
@@ -32,25 +32,23 @@ and \'Set\', already canonicalize the given header name.`,
var Analyzer = SCAnalyzer.Analyzer
-func run(pass *analysis.Pass) (interface{}, error) {
- fn := func(node ast.Node) {
- call := node.(*ast.CallExpr)
- callName := code.CallName(pass, call)
- switch callName {
- case "(net/http.Header).Add", "(net/http.Header).Del", "(net/http.Header).Get", "(net/http.Header).Set":
- default:
- return
- }
-
- if !code.IsCallTo(pass, call.Args[0], "net/http.CanonicalHeaderKey") {
- return
- }
-
- report.Report(pass, call,
- fmt.Sprintf("calling net/http.CanonicalHeaderKey on the 'key' argument of %s is redundant", callName),
+var query = pattern.MustParse(`
+ (CallExpr
+ (Symbol
+ callName@(Or
+ "(net/http.Header).Add"
+ "(net/http.Header).Del"
+ "(net/http.Header).Get"
+ "(net/http.Header).Set"))
+ arg@(CallExpr (Symbol "net/http.CanonicalHeaderKey") _):_)`)
+
+func run(pass *analysis.Pass) (any, error) {
+ for _, m := range code.Matches(pass, query) {
+ arg := m.State["arg"].(*ast.CallExpr)
+ report.Report(pass, m.State["arg"].(ast.Expr),
+ fmt.Sprintf("calling net/http.CanonicalHeaderKey on the 'key' argument of %s is redundant", m.State["callName"].(string)),
report.FilterGenerated(),
- report.Fixes(edit.Fix("remove call to CanonicalHeaderKey", edit.ReplaceWithNode(pass.Fset, call.Args[0], call.Args[0].(*ast.CallExpr).Args[0]))))
+ report.Fixes(edit.Fix("Remove call to CanonicalHeaderKey", edit.ReplaceWithNode(pass.Fset, arg, arg.Args[0]))))
}
- code.Preorder(pass, fn, (*ast.CallExpr)(nil))
return nil, nil
}
diff --git a/vendor/honnef.co/go/tools/simple/s1036/s1036.go b/vendor/honnef.co/go/tools/simple/s1036/s1036.go
index ea675b13c..2d07874e6 100644
--- a/vendor/honnef.co/go/tools/simple/s1036/s1036.go
+++ b/vendor/honnef.co/go/tools/simple/s1036/s1036.go
@@ -10,14 +10,13 @@ import (
"honnef.co/go/tools/pattern"
"golang.org/x/tools/go/analysis"
- "golang.org/x/tools/go/analysis/passes/inspect"
)
var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
Analyzer: &analysis.Analyzer{
Name: "S1036",
Run: run,
- Requires: []*analysis.Analyzer{inspect.Analyzer},
+ Requires: code.RequiredAnalyzers,
},
Doc: &lint.RawDocumentation{
Title: `Unnecessary guard around map access`,
@@ -76,17 +75,14 @@ var checkUnnecessaryGuardQ = pattern.MustParse(`
set@(IncDecStmt indexexpr "++")
(AssignStmt indexexpr "=" (IntegerLiteral "1"))))`)
-func run(pass *analysis.Pass) (interface{}, error) {
- fn := func(node ast.Node) {
- if m, ok := code.Match(pass, checkUnnecessaryGuardQ, node); ok {
- if code.MayHaveSideEffects(pass, m.State["indexexpr"].(ast.Expr), nil) {
- return
- }
- report.Report(pass, node, "unnecessary guard around map access",
- report.ShortRange(),
- report.Fixes(edit.Fix("simplify map access", edit.ReplaceWithNode(pass.Fset, node, m.State["set"].(ast.Node)))))
+func run(pass *analysis.Pass) (any, error) {
+ for node, m := range code.Matches(pass, checkUnnecessaryGuardQ) {
+ if code.MayHaveSideEffects(pass, m.State["indexexpr"].(ast.Expr), nil) {
+ continue
}
+ report.Report(pass, node, "unnecessary guard around map access",
+ report.ShortRange(),
+ report.Fixes(edit.Fix("Simplify map access", edit.ReplaceWithNode(pass.Fset, node, m.State["set"].(ast.Node)))))
}
- code.Preorder(pass, fn, (*ast.IfStmt)(nil))
return nil, nil
}
diff --git a/vendor/honnef.co/go/tools/simple/s1037/s1037.go b/vendor/honnef.co/go/tools/simple/s1037/s1037.go
index a72d42ccc..a067c1ab7 100644
--- a/vendor/honnef.co/go/tools/simple/s1037/s1037.go
+++ b/vendor/honnef.co/go/tools/simple/s1037/s1037.go
@@ -11,14 +11,13 @@ import (
"honnef.co/go/tools/pattern"
"golang.org/x/tools/go/analysis"
- "golang.org/x/tools/go/analysis/passes/inspect"
)
var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
Analyzer: &analysis.Analyzer{
Name: "S1037",
Run: run,
- Requires: []*analysis.Analyzer{inspect.Analyzer, generated.Analyzer},
+ Requires: append([]*analysis.Analyzer{generated.Analyzer}, code.RequiredAnalyzers...),
},
Doc: &lint.RawDocumentation{
Title: `Elaborate way of sleeping`,
@@ -37,23 +36,20 @@ var (
checkElaborateSleepR = pattern.MustParse(`(CallExpr (SelectorExpr (Ident "time") (Ident "Sleep")) [arg])`)
)
-func run(pass *analysis.Pass) (interface{}, error) {
- fn := func(node ast.Node) {
- if m, ok := code.Match(pass, checkElaborateSleepQ, node); ok {
- if body, ok := m.State["body"].([]ast.Stmt); ok && len(body) == 0 {
- report.Report(pass, node, "should use time.Sleep instead of elaborate way of sleeping",
- report.ShortRange(),
- report.FilterGenerated(),
- report.Fixes(edit.Fix("Use time.Sleep", edit.ReplaceWithPattern(pass.Fset, node, checkElaborateSleepR, m.State))))
- } else {
- // TODO(dh): we could make a suggested fix if the body
- // doesn't declare or shadow any identifiers
- report.Report(pass, node, "should use time.Sleep instead of elaborate way of sleeping",
- report.ShortRange(),
- report.FilterGenerated())
- }
+func run(pass *analysis.Pass) (any, error) {
+ for node, m := range code.Matches(pass, checkElaborateSleepQ) {
+ if body, ok := m.State["body"].([]ast.Stmt); ok && len(body) == 0 {
+ report.Report(pass, node, "should use time.Sleep instead of elaborate way of sleeping",
+ report.ShortRange(),
+ report.FilterGenerated(),
+ report.Fixes(edit.Fix("Use time.Sleep", edit.ReplaceWithPattern(pass.Fset, node, checkElaborateSleepR, m.State))))
+ } else {
+ // TODO(dh): we could make a suggested fix if the body
+ // doesn't declare or shadow any identifiers
+ report.Report(pass, node, "should use time.Sleep instead of elaborate way of sleeping",
+ report.ShortRange(),
+ report.FilterGenerated())
}
}
- code.Preorder(pass, fn, (*ast.SelectStmt)(nil))
return nil, nil
}
diff --git a/vendor/honnef.co/go/tools/simple/s1038/s1038.go b/vendor/honnef.co/go/tools/simple/s1038/s1038.go
index 301b90164..7987a56c6 100644
--- a/vendor/honnef.co/go/tools/simple/s1038/s1038.go
+++ b/vendor/honnef.co/go/tools/simple/s1038/s1038.go
@@ -13,14 +13,13 @@ import (
"honnef.co/go/tools/pattern"
"golang.org/x/tools/go/analysis"
- "golang.org/x/tools/go/analysis/passes/inspect"
)
var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
Analyzer: &analysis.Analyzer{
Name: "S1038",
Run: run,
- Requires: []*analysis.Analyzer{inspect.Analyzer, generated.Analyzer},
+ Requires: append([]*analysis.Analyzer{generated.Analyzer}, code.RequiredAnalyzers...),
},
Doc: &lint.RawDocumentation{
Title: "Unnecessarily complex way of printing formatted string",
@@ -104,7 +103,7 @@ var (
}
)
-func run(pass *analysis.Pass) (interface{}, error) {
+func run(pass *analysis.Pass) (any, error) {
fmtPrintf := func(node ast.Node) {
m, ok := code.Match(pass, checkPrintSprintQ, node)
if !ok {
@@ -183,6 +182,9 @@ func run(pass *analysis.Pass) (interface{}, error) {
methSprintf(node)
pkgSprintf(node)
}
+ if !code.CouldMatchAny(pass, checkLogSprintfQ, checkPrintSprintQ, checkTestingErrorSprintfQ) {
+ return nil, nil
+ }
code.Preorder(pass, fn, (*ast.CallExpr)(nil))
return nil, nil
}
diff --git a/vendor/honnef.co/go/tools/simple/s1039/s1039.go b/vendor/honnef.co/go/tools/simple/s1039/s1039.go
index 24eef6a11..81670469f 100644
--- a/vendor/honnef.co/go/tools/simple/s1039/s1039.go
+++ b/vendor/honnef.co/go/tools/simple/s1039/s1039.go
@@ -14,14 +14,13 @@ import (
"honnef.co/go/tools/pattern"
"golang.org/x/tools/go/analysis"
- "golang.org/x/tools/go/analysis/passes/inspect"
)
var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
Analyzer: &analysis.Analyzer{
Name: "S1039",
Run: run,
- Requires: []*analysis.Analyzer{inspect.Analyzer, generated.Analyzer},
+ Requires: append([]*analysis.Analyzer{generated.Analyzer}, code.RequiredAnalyzers...),
},
Doc: &lint.RawDocumentation{
Title: `Unnecessary use of \'fmt.Sprint\'`,
@@ -44,28 +43,24 @@ var checkSprintLiteralQ = pattern.MustParse(`
(Symbol "fmt.Sprintf"))
[lit@(BasicLit "STRING" _)])`)
-func run(pass *analysis.Pass) (interface{}, error) {
+func run(pass *analysis.Pass) (any, error) {
// We only flag calls with string literals, not expressions of
// type string, because some people use fmt.Sprint(s) as a pattern
// for copying strings, which may be useful when extracting a small
// substring from a large string.
- fn := func(node ast.Node) {
- m, ok := code.Match(pass, checkSprintLiteralQ, node)
- if !ok {
- return
- }
+
+ for node, m := range code.Matches(pass, checkSprintLiteralQ) {
callee := m.State["fn"].(*types.Func)
lit := m.State["lit"].(*ast.BasicLit)
if callee.Name() == "Sprintf" {
if strings.ContainsRune(lit.Value, '%') {
// This might be a format string
- return
+ continue
}
}
report.Report(pass, node, fmt.Sprintf("unnecessary use of fmt.%s", callee.Name()),
report.FilterGenerated(),
report.Fixes(edit.Fix("Replace with string literal", edit.ReplaceWithNode(pass.Fset, node, lit))))
}
- code.Preorder(pass, fn, (*ast.CallExpr)(nil))
return nil, nil
}
diff --git a/vendor/honnef.co/go/tools/simple/s1040/s1040.go b/vendor/honnef.co/go/tools/simple/s1040/s1040.go
index d13dae4d4..62cc8c776 100644
--- a/vendor/honnef.co/go/tools/simple/s1040/s1040.go
+++ b/vendor/honnef.co/go/tools/simple/s1040/s1040.go
@@ -37,7 +37,7 @@ instead of relying on the type assertion panicking.`,
var Analyzer = SCAnalyzer.Analyzer
-func run(pass *analysis.Pass) (interface{}, error) {
+func run(pass *analysis.Pass) (any, error) {
fn := func(node ast.Node) {
expr := node.(*ast.TypeAssertExpr)
if expr.Type == nil {
diff --git a/vendor/honnef.co/go/tools/staticcheck/fakejson/encode.go b/vendor/honnef.co/go/tools/staticcheck/fakejson/encode.go
index f65f2ddf9..13e31822b 100644
--- a/vendor/honnef.co/go/tools/staticcheck/fakejson/encode.go
+++ b/vendor/honnef.co/go/tools/staticcheck/fakejson/encode.go
@@ -25,8 +25,8 @@ import (
// parseTag splits a struct field's json tag into its name and
// comma-separated options.
func parseTag(tag string) string {
- if idx := strings.Index(tag, ","); idx != -1 {
- return tag[:idx]
+ if before, _, ok := strings.Cut(tag, ","); ok {
+ return before
}
return tag
}
@@ -160,15 +160,15 @@ func typeByIndex(t fakereflect.TypeAndCanAddr, index []int) fakereflect.TypeAndC
}
func pathByIndex(t fakereflect.TypeAndCanAddr, index []int) string {
- path := ""
+ var path strings.Builder
for _, i := range index {
if t.IsPtr() {
t = t.Elem()
}
- path += "." + t.Field(i).Name
+ path.WriteString("." + t.Field(i).Name)
t = t.Field(i).Type
}
- return path
+ return path.String()
}
// A field represents a single field found in a struct.
diff --git a/vendor/honnef.co/go/tools/staticcheck/fakexml/marshal.go b/vendor/honnef.co/go/tools/staticcheck/fakexml/marshal.go
index 6a30d7907..9c71e8632 100644
--- a/vendor/honnef.co/go/tools/staticcheck/fakexml/marshal.go
+++ b/vendor/honnef.co/go/tools/staticcheck/fakexml/marshal.go
@@ -15,6 +15,7 @@ package fakexml
import (
"fmt"
"go/types"
+ "strings"
"honnef.co/go/tools/go/types/typeutil"
"honnef.co/go/tools/knowledge"
@@ -309,15 +310,15 @@ func indirect(vf fakereflect.TypeAndCanAddr) fakereflect.TypeAndCanAddr {
}
func pathByIndex(t fakereflect.TypeAndCanAddr, index []int) string {
- path := ""
+ var path strings.Builder
for _, i := range index {
if t.IsPtr() {
t = t.Elem()
}
- path += "." + t.Field(i).Name
+ path.WriteString("." + t.Field(i).Name)
t = t.Field(i).Type
}
- return path
+ return path.String()
}
func (e *Encoder) marshalStruct(tinfo *typeInfo, val fakereflect.TypeAndCanAddr, stack string) error {
diff --git a/vendor/honnef.co/go/tools/staticcheck/fakexml/typeinfo.go b/vendor/honnef.co/go/tools/staticcheck/fakexml/typeinfo.go
index cbde81bd9..bf5c73bfb 100644
--- a/vendor/honnef.co/go/tools/staticcheck/fakexml/typeinfo.go
+++ b/vendor/honnef.co/go/tools/staticcheck/fakexml/typeinfo.go
@@ -82,7 +82,7 @@ func getTypeInfo(typ fakereflect.TypeAndCanAddr) (*typeInfo, error) {
tinfo := &typeInfo{}
if typ.IsStruct() && !typeutil.IsTypeWithName(typ.Type, "encoding/xml.Name") {
n := typ.NumField()
- for i := 0; i < n; i++ {
+ for i := range n {
f := typ.Field(i)
if (!f.IsExported() && !f.Anonymous) || f.Tag.Get("xml") == "-" {
continue // Private field
@@ -276,13 +276,6 @@ func lookupXMLName(typ fakereflect.TypeAndCanAddr) (xmlname *fieldInfo) {
return nil
}
-func min(a, b int) int {
- if a <= b {
- return a
- }
- return b
-}
-
// addFieldInfo adds finfo to tinfo.fields if there are no
// conflicts, or if conflicts arise from previous fields that were
// obtained from deeper embedded structures than finfo. In the latter
@@ -303,7 +296,7 @@ Loop:
continue
}
minl := min(len(newf.parents), len(oldf.parents))
- for p := 0; p < minl; p++ {
+ for p := range minl {
if oldf.parents[p] != newf.parents[p] {
continue Loop
}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa1001/sa1001.go b/vendor/honnef.co/go/tools/staticcheck/sa1001/sa1001.go
index 659a9a63b..4e8e4ff7b 100644
--- a/vendor/honnef.co/go/tools/staticcheck/sa1001/sa1001.go
+++ b/vendor/honnef.co/go/tools/staticcheck/sa1001/sa1001.go
@@ -10,16 +10,16 @@ import (
"honnef.co/go/tools/analysis/lint"
"honnef.co/go/tools/analysis/report"
"honnef.co/go/tools/knowledge"
+ "honnef.co/go/tools/pattern"
"golang.org/x/tools/go/analysis"
- "golang.org/x/tools/go/analysis/passes/inspect"
)
var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
Analyzer: &analysis.Analyzer{
Name: "SA1001",
Run: run,
- Requires: []*analysis.Analyzer{inspect.Analyzer},
+ Requires: code.RequiredAnalyzers,
},
Doc: &lint.RawDocumentation{
Title: `Invalid template`,
@@ -31,30 +31,38 @@ var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
var Analyzer = SCAnalyzer.Analyzer
-func run(pass *analysis.Pass) (interface{}, error) {
- fn := func(node ast.Node) {
- call := node.(*ast.CallExpr)
- // OPT(dh): use integer for kind
+var query = pattern.MustParse(`
+ (CallExpr
+ (Symbol
+ name@(Or
+ "(*text/template.Template).Parse"
+ "(*html/template.Template).Parse"))
+ [s])`)
+
+func run(pass *analysis.Pass) (any, error) {
+ for node, m := range code.Matches(pass, query) {
+ name := m.State["name"].(string)
var kind string
- switch code.CallName(pass, call) {
+ switch name {
case "(*text/template.Template).Parse":
kind = "text"
case "(*html/template.Template).Parse":
kind = "html"
- default:
- return
}
+
+ call := node.(*ast.CallExpr)
sel := call.Fun.(*ast.SelectorExpr)
if !code.IsCallToAny(pass, sel.X, "text/template.New", "html/template.New") {
// TODO(dh): this is a cheap workaround for templates with
// different delims. A better solution with less false
// negatives would use data flow analysis to see where the
// template comes from and where it has been
- return
+ continue
}
- s, ok := code.ExprToString(pass, call.Args[knowledge.Arg("(*text/template.Template).Parse.text")])
+
+ s, ok := code.ExprToString(pass, m.State["s"].(ast.Expr))
if !ok {
- return
+ continue
}
var err error
switch kind {
@@ -71,6 +79,5 @@ func run(pass *analysis.Pass) (interface{}, error) {
}
}
}
- code.Preorder(pass, fn, (*ast.CallExpr)(nil))
return nil, nil
}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa1003/sa1003.go b/vendor/honnef.co/go/tools/staticcheck/sa1003/sa1003.go
index 4513ed244..087f03152 100644
--- a/vendor/honnef.co/go/tools/staticcheck/sa1003/sa1003.go
+++ b/vendor/honnef.co/go/tools/staticcheck/sa1003/sa1003.go
@@ -76,7 +76,7 @@ func validEncodingBinaryType(pass *analysis.Pass, node code.Positioner, typ type
return false
case *types.Struct:
n := typ.NumFields()
- for i := 0; i < n; i++ {
+ for i := range n {
if !validEncodingBinaryType(pass, node, typ.Field(i).Type()) {
return false
}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa1004/sa1004.go b/vendor/honnef.co/go/tools/staticcheck/sa1004/sa1004.go
index c65de9271..b3dee1621 100644
--- a/vendor/honnef.co/go/tools/staticcheck/sa1004/sa1004.go
+++ b/vendor/honnef.co/go/tools/staticcheck/sa1004/sa1004.go
@@ -13,14 +13,13 @@ import (
"honnef.co/go/tools/pattern"
"golang.org/x/tools/go/analysis"
- "golang.org/x/tools/go/analysis/passes/inspect"
)
var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
Analyzer: &analysis.Analyzer{
Name: "SA1004",
Run: run,
- Requires: []*analysis.Analyzer{inspect.Analyzer},
+ Requires: code.RequiredAnalyzers,
},
Doc: &lint.RawDocumentation{
Title: `Suspiciously small untyped constant in \'time.Sleep\'`,
@@ -50,29 +49,24 @@ var (
checkTimeSleepConstantPatternRs = pattern.MustParse(`(BinaryExpr duration "*" (SelectorExpr (Ident "time") (Ident "Second")))`)
)
-func run(pass *analysis.Pass) (interface{}, error) {
- fn := func(node ast.Node) {
- m, ok := code.Match(pass, checkTimeSleepConstantPatternQ, node)
- if !ok {
- return
- }
+func run(pass *analysis.Pass) (any, error) {
+ for _, m := range code.Matches(pass, checkTimeSleepConstantPatternQ) {
n, ok := constant.Int64Val(m.State["value"].(types.TypeAndValue).Value)
if !ok {
- return
+ continue
}
if n == 0 || n > 120 {
// time.Sleep(0) is a seldom used pattern in concurrency
// tests. >120 might be intentional. 120 was chosen
// because the user could've meant 2 minutes.
- return
+ continue
}
lit := m.State["lit"].(ast.Node)
report.Report(pass, lit,
fmt.Sprintf("sleeping for %d nanoseconds is probably a bug; be explicit if it isn't", n), report.Fixes(
- edit.Fix("explicitly use nanoseconds", edit.ReplaceWithPattern(pass.Fset, lit, checkTimeSleepConstantPatternRns, pattern.State{"duration": lit})),
- edit.Fix("use seconds", edit.ReplaceWithPattern(pass.Fset, lit, checkTimeSleepConstantPatternRs, pattern.State{"duration": lit}))))
+ edit.Fix("Explicitly use nanoseconds", edit.ReplaceWithPattern(pass.Fset, lit, checkTimeSleepConstantPatternRns, pattern.State{"duration": lit})),
+ edit.Fix("Use seconds", edit.ReplaceWithPattern(pass.Fset, lit, checkTimeSleepConstantPatternRs, pattern.State{"duration": lit}))))
}
- code.Preorder(pass, fn, (*ast.CallExpr)(nil))
return nil, nil
}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa1005/sa1005.go b/vendor/honnef.co/go/tools/staticcheck/sa1005/sa1005.go
index 454dc01c6..65edb5151 100644
--- a/vendor/honnef.co/go/tools/staticcheck/sa1005/sa1005.go
+++ b/vendor/honnef.co/go/tools/staticcheck/sa1005/sa1005.go
@@ -7,17 +7,16 @@ import (
"honnef.co/go/tools/analysis/code"
"honnef.co/go/tools/analysis/lint"
"honnef.co/go/tools/analysis/report"
- "honnef.co/go/tools/knowledge"
+ "honnef.co/go/tools/pattern"
"golang.org/x/tools/go/analysis"
- "golang.org/x/tools/go/analysis/passes/inspect"
)
var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
Analyzer: &analysis.Analyzer{
Name: "SA1005",
Run: run,
- Requires: []*analysis.Analyzer{inspect.Analyzer},
+ Requires: code.RequiredAnalyzers,
},
Doc: &lint.RawDocumentation{
Title: `Invalid first argument to \'exec.Command\'`,
@@ -47,22 +46,20 @@ Windows, will have a \'/bin/sh\' program:
var Analyzer = SCAnalyzer.Analyzer
-func run(pass *analysis.Pass) (interface{}, error) {
- fn := func(node ast.Node) {
- call := node.(*ast.CallExpr)
- if !code.IsCallTo(pass, call, "os/exec.Command") {
- return
- }
- val, ok := code.ExprToString(pass, call.Args[knowledge.Arg("os/exec.Command.name")])
+var query = pattern.MustParse(`(CallExpr (Symbol "os/exec.Command") arg1:_)`)
+
+func run(pass *analysis.Pass) (any, error) {
+ for _, m := range code.Matches(pass, query) {
+ arg1 := m.State["arg1"].(ast.Expr)
+ val, ok := code.ExprToString(pass, arg1)
if !ok {
- return
+ continue
}
if !strings.Contains(val, " ") || strings.Contains(val, `\`) || strings.Contains(val, "/") {
- return
+ continue
}
- report.Report(pass, call.Args[knowledge.Arg("os/exec.Command.name")],
+ report.Report(pass, arg1,
"first argument to exec.Command looks like a shell command, but a program name or path are expected")
}
- code.Preorder(pass, fn, (*ast.CallExpr)(nil))
return nil, nil
}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa1006/sa1006.go b/vendor/honnef.co/go/tools/staticcheck/sa1006/sa1006.go
index 06b77436d..c613808dd 100644
--- a/vendor/honnef.co/go/tools/staticcheck/sa1006/sa1006.go
+++ b/vendor/honnef.co/go/tools/staticcheck/sa1006/sa1006.go
@@ -9,17 +9,16 @@ import (
"honnef.co/go/tools/analysis/edit"
"honnef.co/go/tools/analysis/lint"
"honnef.co/go/tools/analysis/report"
- "honnef.co/go/tools/knowledge"
+ "honnef.co/go/tools/pattern"
"golang.org/x/tools/go/analysis"
- "golang.org/x/tools/go/analysis/passes/inspect"
)
var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
Analyzer: &analysis.Analyzer{
Name: "SA1006",
Run: run,
- Requires: []*analysis.Analyzer{inspect.Analyzer},
+ Requires: code.RequiredAnalyzers,
},
Doc: &lint.RawDocumentation{
Title: `\'Printf\' with dynamic first argument and no further arguments`,
@@ -50,40 +49,50 @@ and pass the string as an argument.`,
var Analyzer = SCAnalyzer.Analyzer
-func run(pass *analysis.Pass) (interface{}, error) {
- fn := func(node ast.Node) {
+var query1 = pattern.MustParse(`
+ (CallExpr
+ (Symbol
+ name@(Or
+ "fmt.Errorf"
+ "fmt.Printf"
+ "fmt.Sprintf"
+ "log.Fatalf"
+ "log.Panicf"
+ "log.Printf"
+ "(*log.Logger).Printf"
+ "(*testing.common).Logf"
+ "(*testing.common).Errorf"
+ "(*testing.common).Fatalf"
+ "(*testing.common).Skipf"
+ "(testing.TB).Logf"
+ "(testing.TB).Errorf"
+ "(testing.TB).Fatalf"
+ "(testing.TB).Skipf"))
+ format:[])
+`)
+
+var query2 = pattern.MustParse(`(CallExpr (Symbol "fmt.Fprintf") _:format:[])`)
+
+func run(pass *analysis.Pass) (any, error) {
+ for node, m := range code.Matches(pass, query1, query2) {
call := node.(*ast.CallExpr)
- name := code.CallName(pass, call)
- var arg int
-
- switch name {
- case "fmt.Errorf", "fmt.Printf", "fmt.Sprintf",
- "log.Fatalf", "log.Panicf", "log.Printf", "(*log.Logger).Printf",
- "(*testing.common).Logf", "(*testing.common).Errorf",
- "(*testing.common).Fatalf", "(*testing.common).Skipf",
- "(testing.TB).Logf", "(testing.TB).Errorf",
- "(testing.TB).Fatalf", "(testing.TB).Skipf":
- arg = knowledge.Arg("fmt.Printf.format")
- case "fmt.Fprintf":
- arg = knowledge.Arg("fmt.Fprintf.format")
- default:
- return
+ name, ok := m.State["name"].(string)
+ if !ok {
+ name = "fmt.Fprintf"
}
- if len(call.Args) != arg+1 {
- // This filters out calls of method expressions like (*log.Logger).Printf(nil, s)
- return
- }
- switch call.Args[arg].(type) {
+
+ arg := m.State["format"].(ast.Expr)
+ switch arg.(type) {
case *ast.CallExpr, *ast.Ident:
default:
- return
+ continue
}
- if _, ok := pass.TypesInfo.TypeOf(call.Args[arg]).(*types.Tuple); ok {
+ if _, ok := pass.TypesInfo.TypeOf(arg).(*types.Tuple); ok {
// the called function returns multiple values and got
// splatted into the call. for all we know, it is
// returning good arguments.
- return
+ continue
}
var alt string
@@ -100,8 +109,7 @@ func run(pass *analysis.Pass) (interface{}, error) {
}
report.Report(pass, call,
"printf-style function with dynamic format string and no further arguments should use print-style function instead",
- report.Fixes(edit.Fix(fmt.Sprintf("use %s instead of %s", alt, name), edit.ReplaceWithString(call.Fun, alt))))
+ report.Fixes(edit.Fix(fmt.Sprintf("Use %s instead of %s", alt, name), edit.ReplaceWithString(call.Fun, alt))))
}
- code.Preorder(pass, fn, (*ast.CallExpr)(nil))
return nil, nil
}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa1008/sa1008.go b/vendor/honnef.co/go/tools/staticcheck/sa1008/sa1008.go
index 60e78d5be..3e0d1bb54 100644
--- a/vendor/honnef.co/go/tools/staticcheck/sa1008/sa1008.go
+++ b/vendor/honnef.co/go/tools/staticcheck/sa1008/sa1008.go
@@ -52,7 +52,7 @@ The easiest way of obtaining the canonical form of a key is to use
var Analyzer = SCAnalyzer.Analyzer
-func run(pass *analysis.Pass) (interface{}, error) {
+func run(pass *analysis.Pass) (any, error) {
fn := func(node ast.Node, push bool) bool {
if !push {
return false
@@ -90,13 +90,13 @@ func run(pass *analysis.Pass) (interface{}, error) {
var fix analysis.SuggestedFix
switch op.Index.(type) {
case *ast.BasicLit:
- fix = edit.Fix("canonicalize header key", edit.ReplaceWithString(op.Index, strconv.Quote(canonical)))
+ fix = edit.Fix("Canonicalize header key", edit.ReplaceWithString(op.Index, strconv.Quote(canonical)))
case *ast.Ident:
call := &ast.CallExpr{
Fun: edit.Selector("http", "CanonicalHeaderKey"),
Args: []ast.Expr{op.Index},
}
- fix = edit.Fix("wrap in http.CanonicalHeaderKey", edit.ReplaceWithNode(pass.Fset, op.Index, call))
+ fix = edit.Fix("Wrap in http.CanonicalHeaderKey", edit.ReplaceWithNode(pass.Fset, op.Index, call))
}
msg := fmt.Sprintf("keys in http.Header are canonicalized, %q is not canonical; fix the constant or use http.CanonicalHeaderKey", s)
if fix.Message != "" {
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa1012/sa1012.go b/vendor/honnef.co/go/tools/staticcheck/sa1012/sa1012.go
index 1bf771210..16bd07984 100644
--- a/vendor/honnef.co/go/tools/staticcheck/sa1012/sa1012.go
+++ b/vendor/honnef.co/go/tools/staticcheck/sa1012/sa1012.go
@@ -12,14 +12,13 @@ import (
"honnef.co/go/tools/pattern"
"golang.org/x/tools/go/analysis"
- "golang.org/x/tools/go/analysis/passes/inspect"
)
var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
Analyzer: &analysis.Analyzer{
Name: "SA1012",
Run: run,
- Requires: []*analysis.Analyzer{inspect.Analyzer},
+ Requires: code.RequiredAnalyzers,
},
Doc: &lint.RawDocumentation{
Title: `A nil \'context.Context\' is being passed to a function, consider using \'context.TODO\' instead`,
@@ -33,40 +32,34 @@ var Analyzer = SCAnalyzer.Analyzer
var checkNilContextQ = pattern.MustParse(`(CallExpr fun@(Symbol _) (Builtin "nil"):_)`)
-func run(pass *analysis.Pass) (interface{}, error) {
+func run(pass *analysis.Pass) (any, error) {
todo := &ast.CallExpr{
Fun: edit.Selector("context", "TODO"),
}
bg := &ast.CallExpr{
Fun: edit.Selector("context", "Background"),
}
- fn := func(node ast.Node) {
- m, ok := code.Match(pass, checkNilContextQ, node)
- if !ok {
- return
- }
-
+ for node, m := range code.Matches(pass, checkNilContextQ) {
call := node.(*ast.CallExpr)
fun, ok := m.State["fun"].(*types.Func)
if !ok {
// it might also be a builtin
- return
+ continue
}
sig := fun.Type().(*types.Signature)
if sig.Params().Len() == 0 {
// Our CallExpr might've matched a method expression, like
// (*T).Foo(nil) – here, nil isn't the first argument of
// the Foo method, but the method receiver.
- return
+ continue
}
if !typeutil.IsTypeWithName(sig.Params().At(0).Type(), "context.Context") {
- return
+ continue
}
report.Report(pass, call.Args[0],
"do not pass a nil Context, even if a function permits it; pass context.TODO if you are unsure about which Context to use", report.Fixes(
- edit.Fix("use context.TODO", edit.ReplaceWithNode(pass.Fset, call.Args[0], todo)),
- edit.Fix("use context.Background", edit.ReplaceWithNode(pass.Fset, call.Args[0], bg))))
+ edit.Fix("Use context.TODO", edit.ReplaceWithNode(pass.Fset, call.Args[0], todo)),
+ edit.Fix("Use context.Background", edit.ReplaceWithNode(pass.Fset, call.Args[0], bg))))
}
- code.Preorder(pass, fn, (*ast.CallExpr)(nil))
return nil, nil
}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa1013/sa1013.go b/vendor/honnef.co/go/tools/staticcheck/sa1013/sa1013.go
index 722baaa6f..cbcbe4ec1 100644
--- a/vendor/honnef.co/go/tools/staticcheck/sa1013/sa1013.go
+++ b/vendor/honnef.co/go/tools/staticcheck/sa1013/sa1013.go
@@ -11,14 +11,13 @@ import (
"honnef.co/go/tools/pattern"
"golang.org/x/tools/go/analysis"
- "golang.org/x/tools/go/analysis/passes/inspect"
)
var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
Analyzer: &analysis.Analyzer{
Name: "SA1013",
Run: run,
- Requires: []*analysis.Analyzer{inspect.Analyzer},
+ Requires: code.RequiredAnalyzers,
},
Doc: &lint.RawDocumentation{
Title: `\'io.Seeker.Seek\' is being called with the whence constant as the first argument, but it should be the second`,
@@ -35,16 +34,14 @@ var (
checkSeekerR = pattern.MustParse(`(CallExpr fun [arg2 arg1])`)
)
-func run(pass *analysis.Pass) (interface{}, error) {
- fn := func(node ast.Node) {
- if m, edits, ok := code.MatchAndEdit(pass, checkSeekerQ, checkSeekerR, node); ok {
- if !code.IsMethod(pass, m.State["fun"].(*ast.SelectorExpr), "Seek", knowledge.Signatures["(io.Seeker).Seek"]) {
- return
- }
- report.Report(pass, node, "the first argument of io.Seeker is the offset, but an io.Seek* constant is being used instead",
- report.Fixes(edit.Fix("swap arguments", edits...)))
+func run(pass *analysis.Pass) (any, error) {
+ for node, m := range code.Matches(pass, checkSeekerQ) {
+ if !code.IsMethod(pass, m.State["fun"].(*ast.SelectorExpr), "Seek", knowledge.Signatures["(io.Seeker).Seek"]) {
+ continue
}
+ edits := code.EditMatch(pass, node, m, checkSeekerR)
+ report.Report(pass, node, "the first argument of io.Seeker is the offset, but an io.Seek* constant is being used instead",
+ report.Fixes(edit.Fix("Swap arguments", edits...)))
}
- code.Preorder(pass, fn, (*ast.CallExpr)(nil))
return nil, nil
}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa1015/sa1015.go b/vendor/honnef.co/go/tools/staticcheck/sa1015/sa1015.go
index 386c1a255..a416c3406 100644
--- a/vendor/honnef.co/go/tools/staticcheck/sa1015/sa1015.go
+++ b/vendor/honnef.co/go/tools/staticcheck/sa1015/sa1015.go
@@ -36,7 +36,7 @@ Go 1.23 fixes this by allowing tickers to be collected even if they weren't clos
var Analyzer = SCAnalyzer.Analyzer
-func run(pass *analysis.Pass) (interface{}, error) {
+func run(pass *analysis.Pass) (any, error) {
for _, fn := range pass.ResultOf[buildir.Analyzer].(*buildir.IR).SrcFuncs {
if fn.Pos() == token.NoPos || version.Compare(code.StdlibVersion(pass, fn), "go1.23") >= 0 {
// Beginning with Go 1.23, the GC is able to collect unreferenced, unclosed
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa1016/sa1016.go b/vendor/honnef.co/go/tools/staticcheck/sa1016/sa1016.go
index fa9c62024..bf89f6cc0 100644
--- a/vendor/honnef.co/go/tools/staticcheck/sa1016/sa1016.go
+++ b/vendor/honnef.co/go/tools/staticcheck/sa1016/sa1016.go
@@ -8,16 +8,16 @@ import (
"honnef.co/go/tools/analysis/edit"
"honnef.co/go/tools/analysis/lint"
"honnef.co/go/tools/analysis/report"
+ "honnef.co/go/tools/pattern"
"golang.org/x/tools/go/analysis"
- "golang.org/x/tools/go/analysis/passes/inspect"
)
var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
Analyzer: &analysis.Analyzer{
Name: "SA1016",
Run: run,
- Requires: []*analysis.Analyzer{inspect.Analyzer},
+ Requires: code.RequiredAnalyzers,
},
Doc: &lint.RawDocumentation{
Title: `Trapping a signal that cannot be trapped`,
@@ -33,7 +33,16 @@ kernel. It is therefore pointless to try and handle these signals.`,
var Analyzer = SCAnalyzer.Analyzer
-func run(pass *analysis.Pass) (interface{}, error) {
+var query = pattern.MustParse(`
+ (CallExpr
+ (Symbol
+ (Or
+ "os/signal.Ignore"
+ "os/signal.Notify"
+ "os/signal.Reset"))
+ _)`)
+
+func run(pass *analysis.Pass) (any, error) {
isSignal := func(pass *analysis.Pass, expr ast.Expr, name string) bool {
if expr, ok := expr.(*ast.SelectorExpr); ok {
return code.SelectorName(pass, expr) == name
@@ -42,13 +51,8 @@ func run(pass *analysis.Pass) (interface{}, error) {
}
}
- fn := func(node ast.Node) {
+ for node := range code.Matches(pass, query) {
call := node.(*ast.CallExpr)
- if !code.IsCallToAny(pass, call,
- "os/signal.Ignore", "os/signal.Notify", "os/signal.Reset") {
- return
- }
-
hasSigterm := false
for _, arg := range call.Args {
if conv, ok := arg.(*ast.CallExpr); ok && isSignal(pass, conv.Fun, "os.Signal") {
@@ -79,7 +83,7 @@ func run(pass *analysis.Pass) (interface{}, error) {
}
ncall := *call
ncall.Args = nargs
- fixes = append(fixes, edit.Fix(fmt.Sprintf("use syscall.SIGTERM instead of %s", report.Render(pass, arg)), edit.ReplaceWithNode(pass.Fset, call, &ncall)))
+ fixes = append(fixes, edit.Fix(fmt.Sprintf("Use syscall.SIGTERM instead of %s", report.Render(pass, arg)), edit.ReplaceWithNode(pass.Fset, call, &ncall)))
}
nargs := make([]ast.Expr, 0, len(call.Args))
for j, a := range call.Args {
@@ -90,7 +94,7 @@ func run(pass *analysis.Pass) (interface{}, error) {
}
ncall := *call
ncall.Args = nargs
- fixes = append(fixes, edit.Fix(fmt.Sprintf("remove %s from list of arguments", report.Render(pass, arg)), edit.ReplaceWithNode(pass.Fset, call, &ncall)))
+ fixes = append(fixes, edit.Fix(fmt.Sprintf("Remove %s from list of arguments", report.Render(pass, arg)), edit.ReplaceWithNode(pass.Fset, call, &ncall)))
report.Report(pass, arg, fmt.Sprintf("%s cannot be trapped (did you mean syscall.SIGTERM?)", report.Render(pass, arg)), report.Fixes(fixes...))
}
if isSignal(pass, arg, "syscall.SIGSTOP") {
@@ -103,10 +107,9 @@ func run(pass *analysis.Pass) (interface{}, error) {
}
ncall := *call
ncall.Args = nargs
- report.Report(pass, arg, "syscall.SIGSTOP cannot be trapped", report.Fixes(edit.Fix("remove syscall.SIGSTOP from list of arguments", edit.ReplaceWithNode(pass.Fset, call, &ncall))))
+ report.Report(pass, arg, "syscall.SIGSTOP cannot be trapped", report.Fixes(edit.Fix("Remove syscall.SIGSTOP from list of arguments", edit.ReplaceWithNode(pass.Fset, call, &ncall))))
}
}
}
- code.Preorder(pass, fn, (*ast.CallExpr)(nil))
return nil, nil
}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa1019/sa1019.go b/vendor/honnef.co/go/tools/staticcheck/sa1019/sa1019.go
index 50a400669..97040e8f5 100644
--- a/vendor/honnef.co/go/tools/staticcheck/sa1019/sa1019.go
+++ b/vendor/honnef.co/go/tools/staticcheck/sa1019/sa1019.go
@@ -39,7 +39,7 @@ func formatGoVersion(s string) string {
return "Go " + strings.TrimPrefix(s, "go")
}
-func run(pass *analysis.Pass) (interface{}, error) {
+func run(pass *analysis.Pass) (any, error) {
deprs := pass.ResultOf[deprecated.Analyzer].(deprecated.Result)
// Selectors can appear outside of function literals, e.g. when
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa1023/sa1023.go b/vendor/honnef.co/go/tools/staticcheck/sa1023/sa1023.go
index 1ebfe7e93..22d21e258 100644
--- a/vendor/honnef.co/go/tools/staticcheck/sa1023/sa1023.go
+++ b/vendor/honnef.co/go/tools/staticcheck/sa1023/sa1023.go
@@ -30,7 +30,7 @@ var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
var Analyzer = SCAnalyzer.Analyzer
-func run(pass *analysis.Pass) (interface{}, error) {
+func run(pass *analysis.Pass) (any, error) {
// TODO(dh): this might be a good candidate for taint analysis.
// Taint the argument as MUST_NOT_MODIFY, then propagate that
// through functions like bytes.Split
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa1025/sa1025.go b/vendor/honnef.co/go/tools/staticcheck/sa1025/sa1025.go
index 9445c7d6e..9b7b6afc6 100644
--- a/vendor/honnef.co/go/tools/staticcheck/sa1025/sa1025.go
+++ b/vendor/honnef.co/go/tools/staticcheck/sa1025/sa1025.go
@@ -28,7 +28,7 @@ var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
var Analyzer = SCAnalyzer.Analyzer
-func run(pass *analysis.Pass) (interface{}, error) {
+func run(pass *analysis.Pass) (any, error) {
for _, fn := range pass.ResultOf[buildir.Analyzer].(*buildir.IR).SrcFuncs {
for _, block := range fn.Blocks {
for _, ins := range block.Instrs {
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa1026/sa1026.go b/vendor/honnef.co/go/tools/staticcheck/sa1026/sa1026.go
index 51ea62e5d..0c685c3a4 100644
--- a/vendor/honnef.co/go/tools/staticcheck/sa1026/sa1026.go
+++ b/vendor/honnef.co/go/tools/staticcheck/sa1026/sa1026.go
@@ -40,7 +40,7 @@ func checkJSON(call *callcheck.Call) {
arg := call.Args[0]
T := arg.Value.Value.Type()
if err := fakejson.Marshal(T); err != nil {
- typ := types.TypeString(err.Type, types.RelativeTo(arg.Value.Value.Parent().Pkg.Pkg))
+ typ := types.TypeString(err.Type, types.RelativeTo(call.Parent.Pkg.Pkg))
if err.Path == "x" {
arg.Invalid(fmt.Sprintf("trying to marshal unsupported type %s", typ))
} else {
@@ -55,14 +55,14 @@ func checkXML(call *callcheck.Call) {
if err := fakexml.Marshal(T); err != nil {
switch err := err.(type) {
case *fakexml.UnsupportedTypeError:
- typ := types.TypeString(err.Type, types.RelativeTo(arg.Value.Value.Parent().Pkg.Pkg))
+ typ := types.TypeString(err.Type, types.RelativeTo(call.Parent.Pkg.Pkg))
if err.Path == "x" {
arg.Invalid(fmt.Sprintf("trying to marshal unsupported type %s", typ))
} else {
arg.Invalid(fmt.Sprintf("trying to marshal unsupported type %s, via %s", typ, err.Path))
}
case *fakexml.CyclicTypeError:
- typ := types.TypeString(err.Type, types.RelativeTo(arg.Value.Value.Parent().Pkg.Pkg))
+ typ := types.TypeString(err.Type, types.RelativeTo(call.Parent.Pkg.Pkg))
if err.Path == "x" {
arg.Invalid(fmt.Sprintf("trying to marshal cyclic type %s", typ))
} else {
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa2000/sa2000.go b/vendor/honnef.co/go/tools/staticcheck/sa2000/sa2000.go
index 2de4f5626..008742921 100644
--- a/vendor/honnef.co/go/tools/staticcheck/sa2000/sa2000.go
+++ b/vendor/honnef.co/go/tools/staticcheck/sa2000/sa2000.go
@@ -10,14 +10,13 @@ import (
"honnef.co/go/tools/pattern"
"golang.org/x/tools/go/analysis"
- "golang.org/x/tools/go/analysis/passes/inspect"
)
var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
Analyzer: &analysis.Analyzer{
Name: "SA2000",
Run: run,
- Requires: []*analysis.Analyzer{inspect.Analyzer},
+ Requires: code.RequiredAnalyzers,
},
Doc: &lint.RawDocumentation{
Title: `\'sync.WaitGroup.Add\' called inside the goroutine, leading to a race condition`,
@@ -36,13 +35,10 @@ var checkWaitgroupAddQ = pattern.MustParse(`
_
call@(CallExpr (Symbol "(*sync.WaitGroup).Add") _):_) _))`)
-func run(pass *analysis.Pass) (interface{}, error) {
- fn := func(node ast.Node) {
- if m, ok := code.Match(pass, checkWaitgroupAddQ, node); ok {
- call := m.State["call"].(ast.Node)
- report.Report(pass, call, fmt.Sprintf("should call %s before starting the goroutine to avoid a race", report.Render(pass, call)))
- }
+func run(pass *analysis.Pass) (any, error) {
+ for _, m := range code.Matches(pass, checkWaitgroupAddQ) {
+ call := m.State["call"].(ast.Node)
+ report.Report(pass, call, fmt.Sprintf("should call %s before starting the goroutine to avoid a race", report.Render(pass, call)))
}
- code.Preorder(pass, fn, (*ast.GoStmt)(nil))
return nil, nil
}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa2001/sa2001.go b/vendor/honnef.co/go/tools/staticcheck/sa2001/sa2001.go
index 21ca99c61..e248250fe 100644
--- a/vendor/honnef.co/go/tools/staticcheck/sa2001/sa2001.go
+++ b/vendor/honnef.co/go/tools/staticcheck/sa2001/sa2001.go
@@ -45,7 +45,7 @@ rare false positive.`,
var Analyzer = SCAnalyzer.Analyzer
-func run(pass *analysis.Pass) (interface{}, error) {
+func run(pass *analysis.Pass) (any, error) {
if pass.Pkg.Path() == "sync_test" {
// exception for the sync package's tests
return nil, nil
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa2002/sa2002.go b/vendor/honnef.co/go/tools/staticcheck/sa2002/sa2002.go
index 1f3eefadd..5641dd877 100644
--- a/vendor/honnef.co/go/tools/staticcheck/sa2002/sa2002.go
+++ b/vendor/honnef.co/go/tools/staticcheck/sa2002/sa2002.go
@@ -29,7 +29,7 @@ var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
var Analyzer = SCAnalyzer.Analyzer
-func run(pass *analysis.Pass) (interface{}, error) {
+func run(pass *analysis.Pass) (any, error) {
for _, fn := range pass.ResultOf[buildir.Analyzer].(*buildir.IR).SrcFuncs {
for _, block := range fn.Blocks {
for _, ins := range block.Instrs {
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa2003/sa2003.go b/vendor/honnef.co/go/tools/staticcheck/sa2003/sa2003.go
index 9085d3052..a7163493a 100644
--- a/vendor/honnef.co/go/tools/staticcheck/sa2003/sa2003.go
+++ b/vendor/honnef.co/go/tools/staticcheck/sa2003/sa2003.go
@@ -29,7 +29,7 @@ var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
var Analyzer = SCAnalyzer.Analyzer
-func run(pass *analysis.Pass) (interface{}, error) {
+func run(pass *analysis.Pass) (any, error) {
for _, fn := range pass.ResultOf[buildir.Analyzer].(*buildir.IR).SrcFuncs {
for _, block := range fn.Blocks {
instrs := irutil.FilterDebug(block.Instrs)
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa3000/sa3000.go b/vendor/honnef.co/go/tools/staticcheck/sa3000/sa3000.go
index 2f1106065..69d4dc1db 100644
--- a/vendor/honnef.co/go/tools/staticcheck/sa3000/sa3000.go
+++ b/vendor/honnef.co/go/tools/staticcheck/sa3000/sa3000.go
@@ -36,7 +36,7 @@ the usual way of implementing \'TestMain\' is to end it with
var Analyzer = SCAnalyzer.Analyzer
-func run(pass *analysis.Pass) (interface{}, error) {
+func run(pass *analysis.Pass) (any, error) {
var (
fnmain ast.Node
callsExit bool
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa3001/sa3001.go b/vendor/honnef.co/go/tools/staticcheck/sa3001/sa3001.go
index c51f179e3..eebd13b0c 100644
--- a/vendor/honnef.co/go/tools/staticcheck/sa3001/sa3001.go
+++ b/vendor/honnef.co/go/tools/staticcheck/sa3001/sa3001.go
@@ -7,16 +7,16 @@ import (
"honnef.co/go/tools/analysis/code"
"honnef.co/go/tools/analysis/lint"
"honnef.co/go/tools/analysis/report"
+ "honnef.co/go/tools/pattern"
"golang.org/x/tools/go/analysis"
- "golang.org/x/tools/go/analysis/passes/inspect"
)
var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
Analyzer: &analysis.Analyzer{
Name: "SA3001",
Run: run,
- Requires: []*analysis.Analyzer{inspect.Analyzer},
+ Requires: code.RequiredAnalyzers,
},
Doc: &lint.RawDocumentation{
Title: `Assigning to \'b.N\' in benchmarks distorts the results`,
@@ -32,24 +32,16 @@ falsify results.`,
var Analyzer = SCAnalyzer.Analyzer
-func run(pass *analysis.Pass) (interface{}, error) {
- fn := func(node ast.Node) {
+var query = pattern.MustParse(`(AssignStmt sel@(SelectorExpr selX (Ident "N")) "=" [_] )`)
+
+func run(pass *analysis.Pass) (any, error) {
+ for node, m := range code.Matches(pass, query) {
assign := node.(*ast.AssignStmt)
- if len(assign.Lhs) != 1 || len(assign.Rhs) != 1 {
- return
- }
- sel, ok := assign.Lhs[0].(*ast.SelectorExpr)
- if !ok {
- return
- }
- if sel.Sel.Name != "N" {
- return
- }
- if !code.IsOfPointerToTypeWithName(pass, sel.X, "testing.B") {
- return
+ if !code.IsOfPointerToTypeWithName(pass, m.State["selX"].(ast.Expr), "testing.B") {
+ continue
}
- report.Report(pass, assign, fmt.Sprintf("should not assign to %s", report.Render(pass, sel)))
+ report.Report(pass, assign,
+ fmt.Sprintf("should not assign to %s", report.Render(pass, m.State["sel"])))
}
- code.Preorder(pass, fn, (*ast.AssignStmt)(nil))
return nil, nil
}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa4000/sa4000.go b/vendor/honnef.co/go/tools/staticcheck/sa4000/sa4000.go
index 577bc3938..bec2afd5f 100644
--- a/vendor/honnef.co/go/tools/staticcheck/sa4000/sa4000.go
+++ b/vendor/honnef.co/go/tools/staticcheck/sa4000/sa4000.go
@@ -15,6 +15,8 @@ import (
"golang.org/x/tools/go/analysis"
"golang.org/x/tools/go/analysis/passes/inspect"
+ "golang.org/x/tools/go/ast/edge"
+ "golang.org/x/tools/go/ast/inspector"
)
var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
@@ -33,7 +35,7 @@ var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
var Analyzer = SCAnalyzer.Analyzer
-func run(pass *analysis.Pass) (interface{}, error) {
+func run(pass *analysis.Pass) (any, error) {
var isFloat func(T types.Type) bool
isFloat = func(T types.Type) bool {
tset := typeutil.NewTypeSet(T)
@@ -49,12 +51,12 @@ func run(pass *analysis.Pass) (interface{}, error) {
case *types.Array:
return isFloat(typ.Elem())
case *types.Struct:
- for i := 0; i < typ.NumFields(); i++ {
- if !isFloat(typ.Field(i).Type()) {
- return false
+ for field := range typ.Fields() {
+ if isFloat(field.Type()) {
+ return true
}
}
- return true
+ return false
default:
return false
}
@@ -62,35 +64,70 @@ func run(pass *analysis.Pass) (interface{}, error) {
}
// TODO(dh): this check ignores the existence of side-effects and
- // happily flags fn() == fn() – so far, we've had nobody complain
- // about a false positive, and it's caught several bugs in real
+ // happily flags fn() == fn() – so far, we've had only two complains
+ // about false positives, and it's caught several bugs in real
// code.
//
// We special case functions from the math/rand package. Someone ran
// into the following false positive: "rand.Intn(2) - rand.Intn(2), which I wrote to generate values {-1, 0, 1} with {0.25, 0.5, 0.25} probability."
- fn := func(node ast.Node) {
+
+ skipComparableCheck := func(c inspector.Cursor) bool {
+ op, ok := c.Node().(*ast.BinaryExpr)
+ if !ok {
+ return false
+ }
+ if clit, ok := op.X.(*ast.CompositeLit); !ok || len(clit.Elts) != 0 {
+ return false
+ }
+ if clit, ok := op.Y.(*ast.CompositeLit); !ok || len(clit.Elts) != 0 {
+ return false
+ }
+
+ // TODO(dh): we should probably skip ParenExprs, but users should
+ // probably not use unnecessary ParenExprs.
+ vspec, ok := c.Parent().Node().(*ast.ValueSpec)
+ if !ok {
+ return false
+ }
+ e, i := c.ParentEdge()
+ if e != edge.ValueSpec_Values {
+ return false
+ }
+ if vspec.Names[i].Name == "_" {
+ // `var _ = T{} == T{}` is permitted, as a compile-time
+ // check that T implements comparable.
+ return true
+ }
+ return false
+ }
+
+ for c := range code.Cursor(pass).Preorder((*ast.BinaryExpr)(nil)) {
+ node := c.Node()
op := node.(*ast.BinaryExpr)
switch op.Op {
case token.EQL, token.NEQ:
+ if skipComparableCheck(c) {
+ continue
+ }
case token.SUB, token.QUO, token.AND, token.REM, token.OR, token.XOR, token.AND_NOT,
token.LAND, token.LOR, token.LSS, token.GTR, token.LEQ, token.GEQ:
default:
// For some ops, such as + and *, it can make sense to
// have identical operands
- return
+ continue
}
if isFloat(pass.TypesInfo.TypeOf(op.X)) {
// 'float float' makes sense for several operators.
// We've tried keeping an exact list of operators to allow, but floats keep surprising us. Let's just give up instead.
- return
+ continue
}
if reflect.TypeOf(op.X) != reflect.TypeOf(op.Y) {
- return
+ continue
}
if report.Render(pass, op.X) != report.Render(pass, op.Y) {
- return
+ continue
}
l1, ok1 := op.X.(*ast.BasicLit)
l2, ok2 := op.Y.(*ast.BasicLit)
@@ -105,7 +142,7 @@ func run(pass *analysis.Pass) (interface{}, error) {
// for them to catch typos such as 1 == 1 where the user
// meant to type i == 1. The odds of a false negative for
// 0 == 0 are slim.
- return
+ continue
}
if expr, ok := op.X.(*ast.CallExpr); ok {
@@ -134,13 +171,47 @@ func run(pass *analysis.Pass) (interface{}, error) {
"(*math/rand.Rand).ExpFloat64",
"(*math/rand.Rand).Float32",
"(*math/rand.Rand).Float64",
- "(*math/rand.Rand).NormFloat64":
- return
+ "(*math/rand.Rand).NormFloat64",
+ "math/rand/v2.Int",
+ "math/rand/v2.Int32",
+ "math/rand/v2.Int32N",
+ "math/rand/v2.Int64",
+ "math/rand/v2.Int64N",
+ "math/rand/v2.IntN",
+ "math/rand/v2.N",
+ "math/rand/v2.Uint",
+ "math/rand/v2.Uint32",
+ "math/rand/v2.Uint32N",
+ "math/rand/v2.Uint64",
+ "math/rand/v2.Uint64N",
+ "math/rand/v2.UintN",
+ "math/rand/v2.ExpFloat64",
+ "math/rand/v2.Float32",
+ "math/rand/v2.Float64",
+ "math/rand/v2.NormFloat64",
+ "(*math/rand/v2.Rand).Int",
+ "(*math/rand/v2.Rand).Int32",
+ "(*math/rand/v2.Rand).Int32N",
+ "(*math/rand/v2.Rand).Int64",
+ "(*math/rand/v2.Rand).Int64N",
+ "(*math/rand/v2.Rand).IntN",
+ "(*math/rand/v2.Rand).N",
+ "(*math/rand/v2.Rand).Uint",
+ "(*math/rand/v2.Rand).Uint32",
+ "(*math/rand/v2.Rand).Uint32N",
+ "(*math/rand/v2.Rand).Uint64",
+ "(*math/rand/v2.Rand).Uint64N",
+ "(*math/rand/v2.Rand).UintN",
+ "(*math/rand/v2.Rand).ExpFloat64",
+ "(*math/rand/v2.Rand).Float32",
+ "(*math/rand/v2.Rand).Float64",
+ "(*math/rand/v2.Rand).NormFloat64":
+ continue
}
}
report.Report(pass, op, fmt.Sprintf("identical expressions on the left and right side of the '%s' operator", op.Op))
}
- code.Preorder(pass, fn, (*ast.BinaryExpr)(nil))
+
return nil, nil
}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa4001/sa4001.go b/vendor/honnef.co/go/tools/staticcheck/sa4001/sa4001.go
index 63e527f6a..2ca43702a 100644
--- a/vendor/honnef.co/go/tools/staticcheck/sa4001/sa4001.go
+++ b/vendor/honnef.co/go/tools/staticcheck/sa4001/sa4001.go
@@ -37,7 +37,7 @@ var (
checkIneffectiveCopyQ2 = pattern.MustParse(`(StarExpr (UnaryExpr "&" _))`)
)
-func run(pass *analysis.Pass) (interface{}, error) {
+func run(pass *analysis.Pass) (any, error) {
fn := func(node ast.Node) {
if m, ok := code.Match(pass, checkIneffectiveCopyQ1, node); ok {
if ident, ok := m.State["obj"].(*ast.Ident); !ok || !cgoIdent.MatchString(ident.Name) {
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa4003/sa4003.go b/vendor/honnef.co/go/tools/staticcheck/sa4003/sa4003.go
index 033ee3a6c..a399c338f 100644
--- a/vendor/honnef.co/go/tools/staticcheck/sa4003/sa4003.go
+++ b/vendor/honnef.co/go/tools/staticcheck/sa4003/sa4003.go
@@ -9,6 +9,7 @@ import (
"math"
"honnef.co/go/tools/analysis/code"
+ "honnef.co/go/tools/analysis/facts/generated"
"honnef.co/go/tools/analysis/lint"
"honnef.co/go/tools/analysis/report"
"honnef.co/go/tools/go/types/typeutil"
@@ -21,7 +22,7 @@ var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
Analyzer: &analysis.Analyzer{
Name: "SA4003",
Run: run,
- Requires: []*analysis.Analyzer{inspect.Analyzer},
+ Requires: []*analysis.Analyzer{inspect.Analyzer, generated.Analyzer},
},
Doc: &lint.RawDocumentation{
Title: `Comparing unsigned values against negative values is pointless`,
@@ -33,7 +34,7 @@ var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
var Analyzer = SCAnalyzer.Analyzer
-func run(pass *analysis.Pass) (interface{}, error) {
+func run(pass *analysis.Pass) (any, error) {
isobj := func(expr ast.Expr, name string) bool {
if name == "" {
return false
@@ -125,31 +126,31 @@ func run(pass *analysis.Pass) (interface{}, error) {
if (expr.Op == token.GTR || expr.Op == token.GEQ) && (isobj(expr.Y, maxMathConst) || isLiteral(expr.Y, maxLiteral)) ||
(expr.Op == token.LSS || expr.Op == token.LEQ) && (isobj(expr.X, maxMathConst) || isLiteral(expr.X, maxLiteral)) {
- report.Report(pass, expr, fmt.Sprintf("no value of type %s is greater than %s", basic, maxMathConst))
+ report.Report(pass, expr, fmt.Sprintf("no value of type %s is greater than %s", basic, maxMathConst), report.FilterGenerated())
}
if expr.Op == token.LEQ && (isobj(expr.Y, maxMathConst) || isLiteral(expr.Y, maxLiteral)) ||
expr.Op == token.GEQ && (isobj(expr.X, maxMathConst) || isLiteral(expr.X, maxLiteral)) {
- report.Report(pass, expr, fmt.Sprintf("every value of type %s is <= %s", basic, maxMathConst))
+ report.Report(pass, expr, fmt.Sprintf("every value of type %s is <= %s", basic, maxMathConst), report.FilterGenerated())
}
if (basic.Info() & types.IsUnsigned) != 0 {
if (expr.Op == token.LSS && isZeroLiteral(expr.Y)) ||
(expr.Op == token.GTR && isZeroLiteral(expr.X)) {
- report.Report(pass, expr, fmt.Sprintf("no value of type %s is less than 0", basic))
+ report.Report(pass, expr, fmt.Sprintf("no value of type %s is less than 0", basic), report.FilterGenerated())
}
if expr.Op == token.GEQ && isZeroLiteral(expr.Y) ||
expr.Op == token.LEQ && isZeroLiteral(expr.X) {
- report.Report(pass, expr, fmt.Sprintf("every value of type %s is >= 0", basic))
+ report.Report(pass, expr, fmt.Sprintf("every value of type %s is >= 0", basic), report.FilterGenerated())
}
} else {
if (expr.Op == token.LSS || expr.Op == token.LEQ) && (isobj(expr.Y, minMathConst) || isLiteral(expr.Y, minLiteral)) ||
(expr.Op == token.GTR || expr.Op == token.GEQ) && (isobj(expr.X, minMathConst) || isLiteral(expr.X, minLiteral)) {
- report.Report(pass, expr, fmt.Sprintf("no value of type %s is less than %s", basic, minMathConst))
+ report.Report(pass, expr, fmt.Sprintf("no value of type %s is less than %s", basic, minMathConst), report.FilterGenerated())
}
if expr.Op == token.GEQ && (isobj(expr.Y, minMathConst) || isLiteral(expr.Y, minLiteral)) ||
expr.Op == token.LEQ && (isobj(expr.X, minMathConst) || isLiteral(expr.X, minLiteral)) {
- report.Report(pass, expr, fmt.Sprintf("every value of type %s is >= %s", basic, minMathConst))
+ report.Report(pass, expr, fmt.Sprintf("every value of type %s is >= %s", basic, minMathConst), report.FilterGenerated())
}
}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa4004/sa4004.go b/vendor/honnef.co/go/tools/staticcheck/sa4004/sa4004.go
index e38f9f3ee..8f20350f5 100644
--- a/vendor/honnef.co/go/tools/staticcheck/sa4004/sa4004.go
+++ b/vendor/honnef.co/go/tools/staticcheck/sa4004/sa4004.go
@@ -30,7 +30,7 @@ var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
var Analyzer = SCAnalyzer.Analyzer
-func run(pass *analysis.Pass) (interface{}, error) {
+func run(pass *analysis.Pass) (any, error) {
// This check detects some, but not all unconditional loop exits.
// We give up in the following cases:
//
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa4005/sa4005.go b/vendor/honnef.co/go/tools/staticcheck/sa4005/sa4005.go
index fc1d78c8c..f900ed21d 100644
--- a/vendor/honnef.co/go/tools/staticcheck/sa4005/sa4005.go
+++ b/vendor/honnef.co/go/tools/staticcheck/sa4005/sa4005.go
@@ -29,7 +29,7 @@ var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
var Analyzer = SCAnalyzer.Analyzer
-func run(pass *analysis.Pass) (interface{}, error) {
+func run(pass *analysis.Pass) (any, error) {
// The analysis only considers the receiver and its first level
// fields. It doesn't look at other parameters, nor at nested
// fields.
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa4006/sa4006.go b/vendor/honnef.co/go/tools/staticcheck/sa4006/sa4006.go
index e980434a4..dac27b752 100644
--- a/vendor/honnef.co/go/tools/staticcheck/sa4006/sa4006.go
+++ b/vendor/honnef.co/go/tools/staticcheck/sa4006/sa4006.go
@@ -31,7 +31,7 @@ var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
var Analyzer = SCAnalyzer.Analyzer
-func run(pass *analysis.Pass) (interface{}, error) {
+func run(pass *analysis.Pass) (any, error) {
for _, fn := range pass.ResultOf[buildir.Analyzer].(*buildir.IR).SrcFuncs {
if irutil.IsExample(fn) {
continue
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa4008/sa4008.go b/vendor/honnef.co/go/tools/staticcheck/sa4008/sa4008.go
index 704273723..41c56e355 100644
--- a/vendor/honnef.co/go/tools/staticcheck/sa4008/sa4008.go
+++ b/vendor/honnef.co/go/tools/staticcheck/sa4008/sa4008.go
@@ -45,7 +45,7 @@ unconditional break, return, or panic:
var Analyzer = SCAnalyzer.Analyzer
-func run(pass *analysis.Pass) (interface{}, error) {
+func run(pass *analysis.Pass) (any, error) {
for _, fn := range pass.ResultOf[buildir.Analyzer].(*buildir.IR).SrcFuncs {
cb := func(node ast.Node) bool {
loop, ok := node.(*ast.ForStmt)
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa4009/sa4009.go b/vendor/honnef.co/go/tools/staticcheck/sa4009/sa4009.go
index c1aa50bd4..8ae8dd27e 100644
--- a/vendor/honnef.co/go/tools/staticcheck/sa4009/sa4009.go
+++ b/vendor/honnef.co/go/tools/staticcheck/sa4009/sa4009.go
@@ -29,7 +29,7 @@ var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
var Analyzer = SCAnalyzer.Analyzer
-func run(pass *analysis.Pass) (interface{}, error) {
+func run(pass *analysis.Pass) (any, error) {
for _, fn := range pass.ResultOf[buildir.Analyzer].(*buildir.IR).SrcFuncs {
cb := func(node ast.Node) bool {
var typ *ast.FuncType
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa4010/sa4010.go b/vendor/honnef.co/go/tools/staticcheck/sa4010/sa4010.go
index 771ebbd1a..2e11e6f26 100644
--- a/vendor/honnef.co/go/tools/staticcheck/sa4010/sa4010.go
+++ b/vendor/honnef.co/go/tools/staticcheck/sa4010/sa4010.go
@@ -25,7 +25,7 @@ var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
var Analyzer = SCAnalyzer.Analyzer
-func run(pass *analysis.Pass) (interface{}, error) {
+func run(pass *analysis.Pass) (any, error) {
isAppend := func(ins ir.Value) bool {
call, ok := ins.(*ir.Call)
if !ok {
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa4011/sa4011.go b/vendor/honnef.co/go/tools/staticcheck/sa4011/sa4011.go
index f9197bddf..7cfa2ea4c 100644
--- a/vendor/honnef.co/go/tools/staticcheck/sa4011/sa4011.go
+++ b/vendor/honnef.co/go/tools/staticcheck/sa4011/sa4011.go
@@ -28,7 +28,7 @@ var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
var Analyzer = SCAnalyzer.Analyzer
-func run(pass *analysis.Pass) (interface{}, error) {
+func run(pass *analysis.Pass) (any, error) {
fn := func(node ast.Node) {
var body *ast.BlockStmt
switch node := node.(type) {
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa4012/sa4012.go b/vendor/honnef.co/go/tools/staticcheck/sa4012/sa4012.go
index d2e42a3e9..4234a28a2 100644
--- a/vendor/honnef.co/go/tools/staticcheck/sa4012/sa4012.go
+++ b/vendor/honnef.co/go/tools/staticcheck/sa4012/sa4012.go
@@ -26,7 +26,7 @@ var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
var Analyzer = SCAnalyzer.Analyzer
-func run(pass *analysis.Pass) (interface{}, error) {
+func run(pass *analysis.Pass) (any, error) {
isNaN := func(v ir.Value) bool {
call, ok := v.(*ir.Call)
if !ok {
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa4013/sa4013.go b/vendor/honnef.co/go/tools/staticcheck/sa4013/sa4013.go
index ca451c622..1bd48f602 100644
--- a/vendor/honnef.co/go/tools/staticcheck/sa4013/sa4013.go
+++ b/vendor/honnef.co/go/tools/staticcheck/sa4013/sa4013.go
@@ -10,14 +10,13 @@ import (
"honnef.co/go/tools/pattern"
"golang.org/x/tools/go/analysis"
- "golang.org/x/tools/go/analysis/passes/inspect"
)
var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
Analyzer: &analysis.Analyzer{
Name: "SA4013",
Run: run,
- Requires: []*analysis.Analyzer{inspect.Analyzer},
+ Requires: code.RequiredAnalyzers,
},
Doc: &lint.RawDocumentation{
Title: `Negating a boolean twice (\'!!b\') is the same as writing \'b\'. This is either redundant, or a typo.`,
@@ -31,14 +30,11 @@ var Analyzer = SCAnalyzer.Analyzer
var checkDoubleNegationQ = pattern.MustParse(`(UnaryExpr "!" single@(UnaryExpr "!" x))`)
-func run(pass *analysis.Pass) (interface{}, error) {
- fn := func(node ast.Node) {
- if m, ok := code.Match(pass, checkDoubleNegationQ, node); ok {
- report.Report(pass, node, "negating a boolean twice has no effect; is this a typo?", report.Fixes(
- edit.Fix("turn into single negation", edit.ReplaceWithNode(pass.Fset, node, m.State["single"].(ast.Node))),
- edit.Fix("remove double negation", edit.ReplaceWithNode(pass.Fset, node, m.State["x"].(ast.Node)))))
- }
+func run(pass *analysis.Pass) (any, error) {
+ for node, m := range code.Matches(pass, checkDoubleNegationQ) {
+ report.Report(pass, node, "negating a boolean twice has no effect; is this a typo?", report.Fixes(
+ edit.Fix("Turn into single negation", edit.ReplaceWithNode(pass.Fset, node, m.State["single"].(ast.Node))),
+ edit.Fix("Remove double negation", edit.ReplaceWithNode(pass.Fset, node, m.State["x"].(ast.Node)))))
}
- code.Preorder(pass, fn, (*ast.UnaryExpr)(nil))
return nil, nil
}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa4014/sa4014.go b/vendor/honnef.co/go/tools/staticcheck/sa4014/sa4014.go
index 642c80ca6..de11648cd 100644
--- a/vendor/honnef.co/go/tools/staticcheck/sa4014/sa4014.go
+++ b/vendor/honnef.co/go/tools/staticcheck/sa4014/sa4014.go
@@ -27,7 +27,7 @@ var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
var Analyzer = SCAnalyzer.Analyzer
-func run(pass *analysis.Pass) (interface{}, error) {
+func run(pass *analysis.Pass) (any, error) {
seen := map[ast.Node]bool{}
var collectConds func(ifstmt *ast.IfStmt, conds []ast.Expr) ([]ast.Expr, bool)
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa4016/sa4016.go b/vendor/honnef.co/go/tools/staticcheck/sa4016/sa4016.go
index cc644370c..993ea65cd 100644
--- a/vendor/honnef.co/go/tools/staticcheck/sa4016/sa4016.go
+++ b/vendor/honnef.co/go/tools/staticcheck/sa4016/sa4016.go
@@ -33,7 +33,7 @@ var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
var Analyzer = SCAnalyzer.Analyzer
-func run(pass *analysis.Pass) (interface{}, error) {
+func run(pass *analysis.Pass) (any, error) {
fn := func(node ast.Node) {
binop := node.(*ast.BinaryExpr)
if !typeutil.All(pass.TypesInfo.TypeOf(binop), func(term *types.Term) bool {
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa4017/sa4017.go b/vendor/honnef.co/go/tools/staticcheck/sa4017/sa4017.go
index f0d10a4b9..6177d17e6 100644
--- a/vendor/honnef.co/go/tools/staticcheck/sa4017/sa4017.go
+++ b/vendor/honnef.co/go/tools/staticcheck/sa4017/sa4017.go
@@ -32,15 +32,14 @@ var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
var Analyzer = SCAnalyzer.Analyzer
-func run(pass *analysis.Pass) (interface{}, error) {
+func run(pass *analysis.Pass) (any, error) {
pure := pass.ResultOf[purity.Analyzer].(purity.Result)
fnLoop:
for _, fn := range pass.ResultOf[buildir.Analyzer].(*buildir.IR).SrcFuncs {
if code.IsInTest(pass, fn) {
params := fn.Signature.Params()
- for i := 0; i < params.Len(); i++ {
- param := params.At(i)
+ for param := range params.Variables() {
if typeutil.IsPointerToTypeWithName(param.Type(), "testing.B") {
// Ignore discarded pure functions in code related
// to benchmarks. Instead of matching BenchmarkFoo
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa4018/sa4018.go b/vendor/honnef.co/go/tools/staticcheck/sa4018/sa4018.go
index f04ed33ef..e4c499958 100644
--- a/vendor/honnef.co/go/tools/staticcheck/sa4018/sa4018.go
+++ b/vendor/honnef.co/go/tools/staticcheck/sa4018/sa4018.go
@@ -32,7 +32,7 @@ var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
var Analyzer = SCAnalyzer.Analyzer
-func run(pass *analysis.Pass) (interface{}, error) {
+func run(pass *analysis.Pass) (any, error) {
pure := pass.ResultOf[purity.Analyzer].(purity.Result)
fn := func(node ast.Node) {
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa4019/sa4019.go b/vendor/honnef.co/go/tools/staticcheck/sa4019/sa4019.go
index dca7d23f1..dd4f0e6aa 100644
--- a/vendor/honnef.co/go/tools/staticcheck/sa4019/sa4019.go
+++ b/vendor/honnef.co/go/tools/staticcheck/sa4019/sa4019.go
@@ -48,7 +48,7 @@ func buildTagsIdentical(s1, s2 []string) bool {
return true
}
-func run(pass *analysis.Pass) (interface{}, error) {
+func run(pass *analysis.Pass) (any, error) {
for _, f := range pass.Files {
constraints := buildTags(f)
for i, constraint1 := range constraints {
@@ -70,7 +70,7 @@ func run(pass *analysis.Pass) (interface{}, error) {
func buildTags(f *ast.File) [][]string {
var out [][]string
- for _, line := range strings.Split(astutil.Preamble(f), "\n") {
+ for line := range strings.SplitSeq(astutil.Preamble(f), "\n") {
if !strings.HasPrefix(line, "+build ") {
continue
}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa4020/sa4020.go b/vendor/honnef.co/go/tools/staticcheck/sa4020/sa4020.go
index 8994cc5d7..8ff2fb342 100644
--- a/vendor/honnef.co/go/tools/staticcheck/sa4020/sa4020.go
+++ b/vendor/honnef.co/go/tools/staticcheck/sa4020/sa4020.go
@@ -27,7 +27,7 @@ var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
type T struct{}
func (T) Read(b []byte) (int, error) { return 0, nil }
- var v interface{} = T{}
+ var v any = T{}
switch v.(type) {
case io.Reader:
@@ -45,7 +45,7 @@ Another example:
func (T) Read(b []byte) (int, error) { return 0, nil }
func (T) Close() error { return nil }
- var v interface{} = T{}
+ var v any = T{}
switch v.(type) {
case io.Reader:
@@ -96,7 +96,7 @@ and therefore \'doSomething()\''s return value implements both.`,
var Analyzer = SCAnalyzer.Analyzer
-func run(pass *analysis.Pass) (interface{}, error) {
+func run(pass *analysis.Pass) (any, error) {
// Check if T subsumes V in a type switch. T subsumes V if T is an interface and T's method set is a subset of V's method set.
subsumes := func(T, V types.Type) bool {
if typeparams.IsTypeParam(T) {
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa4021/sa4021.go b/vendor/honnef.co/go/tools/staticcheck/sa4021/sa4021.go
index 76d923524..6f2133c96 100644
--- a/vendor/honnef.co/go/tools/staticcheck/sa4021/sa4021.go
+++ b/vendor/honnef.co/go/tools/staticcheck/sa4021/sa4021.go
@@ -1,8 +1,6 @@
package sa4021
import (
- "go/ast"
-
"honnef.co/go/tools/analysis/code"
"honnef.co/go/tools/analysis/facts/generated"
"honnef.co/go/tools/analysis/lint"
@@ -10,14 +8,13 @@ import (
"honnef.co/go/tools/pattern"
"golang.org/x/tools/go/analysis"
- "golang.org/x/tools/go/analysis/passes/inspect"
)
var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
Analyzer: &analysis.Analyzer{
Name: "SA4021",
Run: run,
- Requires: []*analysis.Analyzer{inspect.Analyzer, generated.Analyzer},
+ Requires: append([]*analysis.Analyzer{generated.Analyzer}, code.RequiredAnalyzers...),
},
Doc: &lint.RawDocumentation{
Title: `\"x = append(y)\" is equivalent to \"x = y\"`,
@@ -31,14 +28,9 @@ var Analyzer = SCAnalyzer.Analyzer
var checkSingleArgAppendQ = pattern.MustParse(`(CallExpr (Builtin "append") [_])`)
-func run(pass *analysis.Pass) (interface{}, error) {
- fn := func(node ast.Node) {
- _, ok := code.Match(pass, checkSingleArgAppendQ, node)
- if !ok {
- return
- }
+func run(pass *analysis.Pass) (any, error) {
+ for node := range code.Matches(pass, checkSingleArgAppendQ) {
report.Report(pass, node, "x = append(y) is equivalent to x = y", report.FilterGenerated())
}
- code.Preorder(pass, fn, (*ast.CallExpr)(nil))
return nil, nil
}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa4022/sa4022.go b/vendor/honnef.co/go/tools/staticcheck/sa4022/sa4022.go
index c6575442c..efa32e470 100644
--- a/vendor/honnef.co/go/tools/staticcheck/sa4022/sa4022.go
+++ b/vendor/honnef.co/go/tools/staticcheck/sa4022/sa4022.go
@@ -1,22 +1,19 @@
package sa4022
import (
- "go/ast"
-
"honnef.co/go/tools/analysis/code"
"honnef.co/go/tools/analysis/lint"
"honnef.co/go/tools/analysis/report"
"honnef.co/go/tools/pattern"
"golang.org/x/tools/go/analysis"
- "golang.org/x/tools/go/analysis/passes/inspect"
)
var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
Analyzer: &analysis.Analyzer{
Name: "SA4022",
Run: run,
- Requires: []*analysis.Analyzer{inspect.Analyzer},
+ Requires: code.RequiredAnalyzers,
},
Doc: &lint.RawDocumentation{
Title: `Comparing the address of a variable against nil`,
@@ -35,14 +32,9 @@ var CheckAddressIsNilQ = pattern.MustParse(
(Or "==" "!=")
(Builtin "nil"))`)
-func run(pass *analysis.Pass) (interface{}, error) {
- fn := func(node ast.Node) {
- _, ok := code.Match(pass, CheckAddressIsNilQ, node)
- if !ok {
- return
- }
+func run(pass *analysis.Pass) (any, error) {
+ for node := range code.Matches(pass, CheckAddressIsNilQ) {
report.Report(pass, node, "the address of a variable cannot be nil")
}
- code.Preorder(pass, fn, (*ast.BinaryExpr)(nil))
return nil, nil
}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa4023/sa4023.go b/vendor/honnef.co/go/tools/staticcheck/sa4023/sa4023.go
index 6546ffa76..4ab13c835 100644
--- a/vendor/honnef.co/go/tools/staticcheck/sa4023/sa4023.go
+++ b/vendor/honnef.co/go/tools/staticcheck/sa4023/sa4023.go
@@ -92,7 +92,7 @@ Commons Attribution 3.0 License.`,
var Analyzer = SCAnalyzer.Analyzer
-func run(pass *analysis.Pass) (interface{}, error) {
+func run(pass *analysis.Pass) (any, error) {
// The comparison 'fn() == nil' can never be true if fn() returns
// an interface value and only returns typed nils. This is usually
// a mistake in the function itself, but all we can say for
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa4024/sa4024.go b/vendor/honnef.co/go/tools/staticcheck/sa4024/sa4024.go
index fad0742bd..a956050f4 100644
--- a/vendor/honnef.co/go/tools/staticcheck/sa4024/sa4024.go
+++ b/vendor/honnef.co/go/tools/staticcheck/sa4024/sa4024.go
@@ -10,14 +10,13 @@ import (
"honnef.co/go/tools/pattern"
"golang.org/x/tools/go/analysis"
- "golang.org/x/tools/go/analysis/passes/inspect"
)
var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
Analyzer: &analysis.Analyzer{
Name: "SA4024",
Run: run,
- Requires: []*analysis.Analyzer{inspect.Analyzer},
+ Requires: code.RequiredAnalyzers,
},
Doc: &lint.RawDocumentation{
Title: `Checking for impossible return value from a builtin function`,
@@ -50,17 +49,10 @@ var builtinLessThanZeroQ = pattern.MustParse(`
(IntegerLiteral "0")))
`)
-func run(pass *analysis.Pass) (interface{}, error) {
- fn := func(node ast.Node) {
- matcher, ok := code.Match(pass, builtinLessThanZeroQ, node)
- if !ok {
- return
- }
-
+func run(pass *analysis.Pass) (any, error) {
+ for node, matcher := range code.Matches(pass, builtinLessThanZeroQ) {
builtin := matcher.State["builtin"].(*ast.Ident)
report.Report(pass, node, fmt.Sprintf("builtin function %s does not return negative values", builtin.Name))
}
- code.Preorder(pass, fn, (*ast.BinaryExpr)(nil))
-
return nil, nil
}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa4025/sa4025.go b/vendor/honnef.co/go/tools/staticcheck/sa4025/sa4025.go
index 2a2262b2c..a8bc2e87d 100644
--- a/vendor/honnef.co/go/tools/staticcheck/sa4025/sa4025.go
+++ b/vendor/honnef.co/go/tools/staticcheck/sa4025/sa4025.go
@@ -11,14 +11,13 @@ import (
"honnef.co/go/tools/pattern"
"golang.org/x/tools/go/analysis"
- "golang.org/x/tools/go/analysis/passes/inspect"
)
var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
Analyzer: &analysis.Analyzer{
Name: "SA4025",
Run: run,
- Requires: []*analysis.Analyzer{inspect.Analyzer},
+ Requires: code.RequiredAnalyzers,
},
Doc: &lint.RawDocumentation{
Title: "Integer division of literals that results in zero",
@@ -46,13 +45,8 @@ var Analyzer = SCAnalyzer.Analyzer
var integerDivisionQ = pattern.MustParse(`(BinaryExpr (IntegerLiteral _) "/" (IntegerLiteral _))`)
-func run(pass *analysis.Pass) (interface{}, error) {
- fn := func(node ast.Node) {
- _, ok := code.Match(pass, integerDivisionQ, node)
- if !ok {
- return
- }
-
+func run(pass *analysis.Pass) (any, error) {
+ for node := range code.Matches(pass, integerDivisionQ) {
val := constant.ToInt(pass.TypesInfo.Types[node.(ast.Expr)].Value)
if v, ok := constant.Uint64Val(val); ok && v == 0 {
report.Report(pass, node, fmt.Sprintf("the integer division '%s' results in zero", report.Render(pass, node)))
@@ -71,7 +65,5 @@ func run(pass *analysis.Pass) (interface{}, error) {
// The check also found a real bug in other code, but I don't
// think we can outright ban this kind of division.
}
- code.Preorder(pass, fn, (*ast.BinaryExpr)(nil))
-
return nil, nil
}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa4026/sa4026.go b/vendor/honnef.co/go/tools/staticcheck/sa4026/sa4026.go
index 9fde1329b..31681d178 100644
--- a/vendor/honnef.co/go/tools/staticcheck/sa4026/sa4026.go
+++ b/vendor/honnef.co/go/tools/staticcheck/sa4026/sa4026.go
@@ -2,7 +2,6 @@ package sa4026
import (
"fmt"
- "go/ast"
"go/types"
"honnef.co/go/tools/analysis/code"
@@ -12,14 +11,13 @@ import (
"honnef.co/go/tools/pattern"
"golang.org/x/tools/go/analysis"
- "golang.org/x/tools/go/analysis/passes/inspect"
)
var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
Analyzer: &analysis.Analyzer{
Name: "SA4026",
Run: run,
- Requires: []*analysis.Analyzer{inspect.Analyzer},
+ Requires: code.RequiredAnalyzers,
},
Doc: &lint.RawDocumentation{
Title: "Go constants cannot express negative zero",
@@ -54,13 +52,8 @@ var negativeZeroFloatQ = pattern.MustParse(`
conv@(Object (Or "float32" "float64"))
(UnaryExpr "-" lit@(BasicLit "INT" "0"))))`)
-func run(pass *analysis.Pass) (interface{}, error) {
- fn := func(node ast.Node) {
- m, ok := code.Match(pass, negativeZeroFloatQ, node)
- if !ok {
- return
- }
-
+func run(pass *analysis.Pass) (any, error) {
+ for node, m := range code.Matches(pass, negativeZeroFloatQ) {
if conv, ok := m.State["conv"].(*types.TypeName); ok {
var replacement string
// TODO(dh): how does this handle type aliases?
@@ -74,14 +67,13 @@ func run(pass *analysis.Pass) (interface{}, error) {
report.Render(pass, node),
conv.Name(),
report.Render(pass, m.State["lit"])),
- report.Fixes(edit.Fix("use math.Copysign to create negative zero", edit.ReplaceWithString(node, replacement))))
+ report.Fixes(edit.Fix("Use math.Copysign to create negative zero", edit.ReplaceWithString(node, replacement))))
} else {
const replacement = `math.Copysign(0, -1)`
report.Report(pass, node,
"in Go, the floating-point literal '-0.0' is the same as '0.0', it does not produce a negative zero",
- report.Fixes(edit.Fix("use math.Copysign to create negative zero", edit.ReplaceWithString(node, replacement))))
+ report.Fixes(edit.Fix("Use math.Copysign to create negative zero", edit.ReplaceWithString(node, replacement))))
}
}
- code.Preorder(pass, fn, (*ast.UnaryExpr)(nil), (*ast.CallExpr)(nil))
return nil, nil
}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa4027/sa4027.go b/vendor/honnef.co/go/tools/staticcheck/sa4027/sa4027.go
index 99092fb36..cb8c73978 100644
--- a/vendor/honnef.co/go/tools/staticcheck/sa4027/sa4027.go
+++ b/vendor/honnef.co/go/tools/staticcheck/sa4027/sa4027.go
@@ -9,14 +9,13 @@ import (
"honnef.co/go/tools/pattern"
"golang.org/x/tools/go/analysis"
- "golang.org/x/tools/go/analysis/passes/inspect"
)
var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
Analyzer: &analysis.Analyzer{
Name: "SA4027",
Run: run,
- Requires: []*analysis.Analyzer{inspect.Analyzer},
+ Requires: code.RequiredAnalyzers,
},
Doc: &lint.RawDocumentation{
Title: `\'(*net/url.URL).Query\' returns a copy, modifying it doesn't change the URL`,
@@ -37,28 +36,22 @@ var Analyzer = SCAnalyzer.Analyzer
var ineffectiveURLQueryAddQ = pattern.MustParse(`(CallExpr (SelectorExpr (CallExpr (SelectorExpr recv (Ident "Query")) []) (Ident meth)) _)`)
-func run(pass *analysis.Pass) (interface{}, error) {
+func run(pass *analysis.Pass) (any, error) {
// TODO(dh): We could make this check more complex and detect
// pointless modifications of net/url.Values in general, but that
// requires us to get the state machine correct, else we'll cause
// false positives.
- fn := func(node ast.Node) {
- m, ok := code.Match(pass, ineffectiveURLQueryAddQ, node)
- if !ok {
- return
- }
+ for node, m := range code.Matches(pass, ineffectiveURLQueryAddQ) {
if !code.IsOfPointerToTypeWithName(pass, m.State["recv"].(ast.Expr), "net/url.URL") {
- return
+ continue
}
switch m.State["meth"].(string) {
case "Add", "Del", "Set":
default:
- return
+ continue
}
report.Report(pass, node, "(*net/url.URL).Query returns a copy, modifying it doesn't change the URL")
}
- code.Preorder(pass, fn, (*ast.CallExpr)(nil))
-
return nil, nil
}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa4028/sa4028.go b/vendor/honnef.co/go/tools/staticcheck/sa4028/sa4028.go
index afcdcdda5..1873d7bc0 100644
--- a/vendor/honnef.co/go/tools/staticcheck/sa4028/sa4028.go
+++ b/vendor/honnef.co/go/tools/staticcheck/sa4028/sa4028.go
@@ -1,22 +1,19 @@
package sa4028
import (
- "go/ast"
-
"honnef.co/go/tools/analysis/code"
"honnef.co/go/tools/analysis/lint"
"honnef.co/go/tools/analysis/report"
"honnef.co/go/tools/pattern"
"golang.org/x/tools/go/analysis"
- "golang.org/x/tools/go/analysis/passes/inspect"
)
var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
Analyzer: &analysis.Analyzer{
Name: "SA4028",
Run: run,
- Requires: []*analysis.Analyzer{inspect.Analyzer},
+ Requires: code.RequiredAnalyzers,
},
Doc: &lint.RawDocumentation{
Title: `\'x % 1\' is always zero`,
@@ -30,14 +27,9 @@ var Analyzer = SCAnalyzer.Analyzer
var moduloOneQ = pattern.MustParse(`(BinaryExpr _ "%" (IntegerLiteral "1"))`)
-func run(pass *analysis.Pass) (interface{}, error) {
- fn := func(node ast.Node) {
- _, ok := code.Match(pass, moduloOneQ, node)
- if !ok {
- return
- }
+func run(pass *analysis.Pass) (any, error) {
+ for node := range code.Matches(pass, moduloOneQ) {
report.Report(pass, node, "x % 1 is always zero")
}
- code.Preorder(pass, fn, (*ast.BinaryExpr)(nil))
return nil, nil
}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa4029/sa4029.go b/vendor/honnef.co/go/tools/staticcheck/sa4029/sa4029.go
index a2d830ee7..de77e23b9 100644
--- a/vendor/honnef.co/go/tools/staticcheck/sa4029/sa4029.go
+++ b/vendor/honnef.co/go/tools/staticcheck/sa4029/sa4029.go
@@ -12,14 +12,13 @@ import (
"honnef.co/go/tools/pattern"
"golang.org/x/tools/go/analysis"
- "golang.org/x/tools/go/analysis/passes/inspect"
)
var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
Analyzer: &analysis.Analyzer{
Name: "SA4029",
Run: run,
- Requires: []*analysis.Analyzer{inspect.Analyzer},
+ Requires: code.RequiredAnalyzers,
},
Doc: &lint.RawDocumentation{
Title: "Ineffective attempt at sorting slice",
@@ -41,17 +40,12 @@ var Analyzer = SCAnalyzer.Analyzer
var ineffectiveSortQ = pattern.MustParse(`(AssignStmt target@(Ident _) "=" (CallExpr typ@(Symbol (Or "sort.Float64Slice" "sort.IntSlice" "sort.StringSlice")) [target]))`)
-func run(pass *analysis.Pass) (interface{}, error) {
- fn := func(node ast.Node) {
- m, ok := code.Match(pass, ineffectiveSortQ, node)
- if !ok {
- return
- }
-
- _, ok = types.Unalias(pass.TypesInfo.TypeOf(m.State["target"].(ast.Expr))).(*types.Slice)
+func run(pass *analysis.Pass) (any, error) {
+ for node, m := range code.Matches(pass, ineffectiveSortQ) {
+ _, ok := types.Unalias(pass.TypesInfo.TypeOf(m.State["target"].(ast.Expr))).(*types.Slice)
if !ok {
// Avoid flagging 'x = sort.StringSlice(x)' where TypeOf(x) == sort.StringSlice
- return
+ continue
}
var alternative string
@@ -80,8 +74,7 @@ func run(pass *analysis.Pass) (interface{}, error) {
typeName,
report.Render(pass, node.(*ast.AssignStmt).Rhs[0]),
alternative),
- report.Fixes(edit.Fix(fmt.Sprintf("replace with call to sort.%s", alternative), edit.ReplaceWithNode(pass.Fset, node, r))))
+ report.Fixes(edit.Fix(fmt.Sprintf("Replace with call to sort.%s", alternative), edit.ReplaceWithNode(pass.Fset, node, r))))
}
- code.Preorder(pass, fn, (*ast.AssignStmt)(nil))
return nil, nil
}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa4030/sa4030.go b/vendor/honnef.co/go/tools/staticcheck/sa4030/sa4030.go
index e54edc263..fad7c5bc7 100644
--- a/vendor/honnef.co/go/tools/staticcheck/sa4030/sa4030.go
+++ b/vendor/honnef.co/go/tools/staticcheck/sa4030/sa4030.go
@@ -2,7 +2,6 @@ package sa4030
import (
"fmt"
- "go/ast"
"honnef.co/go/tools/analysis/code"
"honnef.co/go/tools/analysis/lint"
@@ -10,14 +9,13 @@ import (
"honnef.co/go/tools/pattern"
"golang.org/x/tools/go/analysis"
- "golang.org/x/tools/go/analysis/passes/inspect"
)
var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
Analyzer: &analysis.Analyzer{
Name: "SA4030",
Run: run,
- Requires: []*analysis.Analyzer{inspect.Analyzer},
+ Requires: code.RequiredAnalyzers,
},
Doc: &lint.RawDocumentation{
Title: "Ineffective attempt at generating random number",
@@ -44,21 +42,29 @@ var ineffectiveRandIntQ = pattern.MustParse(`
"math/rand.Intn"
"(*math/rand.Rand).Int31n"
"(*math/rand.Rand).Int63n"
- "(*math/rand.Rand).Intn"))
- [(IntegerLiteral "1")])`)
+ "(*math/rand.Rand).Intn"
+
+ "math/rand/v2.Int32N"
+ "math/rand/v2.Int64N"
+ "math/rand/v2.IntN"
+ "math/rand/v2.N"
+ "math/rand/v2.Uint32N"
+ "math/rand/v2.Uint64N"
+ "math/rand/v2.UintN"
-func run(pass *analysis.Pass) (interface{}, error) {
- fn := func(node ast.Node) {
- m, ok := code.Match(pass, ineffectiveRandIntQ, node)
- if !ok {
- return
- }
+ "(*math/rand/v2.Rand).Int32N"
+ "(*math/rand/v2.Rand).Int64N"
+ "(*math/rand/v2.Rand).IntN"
+ "(*math/rand/v2.Rand).Uint32N"
+ "(*math/rand/v2.Rand).Uint64N"
+ "(*math/rand/v2.Rand).UintN"))
+ [(IntegerLiteral "1")])`)
+func run(pass *analysis.Pass) (any, error) {
+ for node, m := range code.Matches(pass, ineffectiveRandIntQ) {
report.Report(pass, node,
fmt.Sprintf("%s(n) generates a random value 0 <= x < n; that is, the generated values don't include n; %s therefore always returns 0",
m.State["name"], report.Render(pass, node)))
}
-
- code.Preorder(pass, fn, (*ast.CallExpr)(nil))
return nil, nil
}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa4031/sa4031.go b/vendor/honnef.co/go/tools/staticcheck/sa4031/sa4031.go
index c7740b4a6..e91e5ecd1 100644
--- a/vendor/honnef.co/go/tools/staticcheck/sa4031/sa4031.go
+++ b/vendor/honnef.co/go/tools/staticcheck/sa4031/sa4031.go
@@ -37,7 +37,7 @@ var Analyzer = SCAnalyzer.Analyzer
var allocationNilCheckQ = pattern.MustParse(`(IfStmt _ cond@(BinaryExpr lhs op@(Or "==" "!=") (Builtin "nil")) _ _)`)
-func run(pass *analysis.Pass) (interface{}, error) {
+func run(pass *analysis.Pass) (any, error) {
irpkg := pass.ResultOf[buildir.Analyzer].(*buildir.IR).Pkg
var path []ast.Node
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa4032/sa4032.go b/vendor/honnef.co/go/tools/staticcheck/sa4032/sa4032.go
index 28dae9a05..99012dab9 100644
--- a/vendor/honnef.co/go/tools/staticcheck/sa4032/sa4032.go
+++ b/vendor/honnef.co/go/tools/staticcheck/sa4032/sa4032.go
@@ -7,7 +7,6 @@ import (
"go/constant"
"golang.org/x/tools/go/analysis"
- "golang.org/x/tools/go/analysis/passes/inspect"
"honnef.co/go/tools/analysis/code"
"honnef.co/go/tools/analysis/lint"
"honnef.co/go/tools/analysis/report"
@@ -19,7 +18,7 @@ var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
Analyzer: &analysis.Analyzer{
Name: "SA4032",
Run: CheckImpossibleGOOSGOARCH,
- Requires: []*analysis.Analyzer{inspect.Analyzer},
+ Requires: code.RequiredAnalyzers,
},
Doc: &lint.RawDocumentation{
Title: `Comparing \'runtime.GOOS\' or \'runtime.GOARCH\' against impossible value`,
@@ -45,6 +44,10 @@ func CheckImpossibleGOOSGOARCH(pass *analysis.Pass) (any, error) {
// 'runtime.GOOS == "windows"' will just become 'false'. We can't use the AST-based CFG builder from x/tools,
// because it doesn't model branch conditions.
+ if !code.CouldMatchAny(pass, goarchComparisonQ, goosComparisonQ) {
+ return nil, nil
+ }
+
for _, f := range pass.Files {
expr, ok := code.BuildConstraints(pass, f)
if !ok {
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa5000/sa5000.go b/vendor/honnef.co/go/tools/staticcheck/sa5000/sa5000.go
index f77f9b5c0..d510f596a 100644
--- a/vendor/honnef.co/go/tools/staticcheck/sa5000/sa5000.go
+++ b/vendor/honnef.co/go/tools/staticcheck/sa5000/sa5000.go
@@ -26,7 +26,7 @@ var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
var Analyzer = SCAnalyzer.Analyzer
-func run(pass *analysis.Pass) (interface{}, error) {
+func run(pass *analysis.Pass) (any, error) {
for _, fn := range pass.ResultOf[buildir.Analyzer].(*buildir.IR).SrcFuncs {
for _, block := range fn.Blocks {
for _, ins := range block.Instrs {
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa5001/sa5001.go b/vendor/honnef.co/go/tools/staticcheck/sa5001/sa5001.go
index c46acb6a5..d4540d3fa 100644
--- a/vendor/honnef.co/go/tools/staticcheck/sa5001/sa5001.go
+++ b/vendor/honnef.co/go/tools/staticcheck/sa5001/sa5001.go
@@ -29,7 +29,7 @@ var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
var Analyzer = SCAnalyzer.Analyzer
-func run(pass *analysis.Pass) (interface{}, error) {
+func run(pass *analysis.Pass) (any, error) {
fn := func(node ast.Node) {
block := node.(*ast.BlockStmt)
if len(block.List) < 2 {
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa5002/sa5002.go b/vendor/honnef.co/go/tools/staticcheck/sa5002/sa5002.go
index a5c108678..b3ff58976 100644
--- a/vendor/honnef.co/go/tools/staticcheck/sa5002/sa5002.go
+++ b/vendor/honnef.co/go/tools/staticcheck/sa5002/sa5002.go
@@ -29,7 +29,7 @@ var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
var Analyzer = SCAnalyzer.Analyzer
-func run(pass *analysis.Pass) (interface{}, error) {
+func run(pass *analysis.Pass) (any, error) {
fn := func(node ast.Node) {
loop := node.(*ast.ForStmt)
if len(loop.Body.List) != 0 || loop.Post != nil {
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa5003/sa5003.go b/vendor/honnef.co/go/tools/staticcheck/sa5003/sa5003.go
index 36bfcb3f6..1062d6204 100644
--- a/vendor/honnef.co/go/tools/staticcheck/sa5003/sa5003.go
+++ b/vendor/honnef.co/go/tools/staticcheck/sa5003/sa5003.go
@@ -31,7 +31,7 @@ infinite loop, defers will never execute.`,
var Analyzer = SCAnalyzer.Analyzer
-func run(pass *analysis.Pass) (interface{}, error) {
+func run(pass *analysis.Pass) (any, error) {
fn := func(node ast.Node) {
mightExit := false
var defers []ast.Stmt
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa5004/sa5004.go b/vendor/honnef.co/go/tools/staticcheck/sa5004/sa5004.go
index 5f909e1f5..c8c6e6648 100644
--- a/vendor/honnef.co/go/tools/staticcheck/sa5004/sa5004.go
+++ b/vendor/honnef.co/go/tools/staticcheck/sa5004/sa5004.go
@@ -7,16 +7,16 @@ import (
"honnef.co/go/tools/analysis/edit"
"honnef.co/go/tools/analysis/lint"
"honnef.co/go/tools/analysis/report"
+ "honnef.co/go/tools/pattern"
"golang.org/x/tools/go/analysis"
- "golang.org/x/tools/go/analysis/passes/inspect"
)
var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
Analyzer: &analysis.Analyzer{
Name: "SA5004",
Run: run,
- Requires: []*analysis.Analyzer{inspect.Analyzer},
+ Requires: code.RequiredAnalyzers,
},
Doc: &lint.RawDocumentation{
Title: `\"for { select { ...\" with an empty default branch spins`,
@@ -28,28 +28,22 @@ var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
var Analyzer = SCAnalyzer.Analyzer
-func run(pass *analysis.Pass) (interface{}, error) {
- fn := func(node ast.Node) {
- loop := node.(*ast.ForStmt)
- if len(loop.Body.List) != 1 || loop.Cond != nil || loop.Init != nil {
- return
- }
- sel, ok := loop.Body.List[0].(*ast.SelectStmt)
- if !ok {
- return
- }
- for _, c := range sel.Body.List {
+var query = pattern.MustParse(`(ForStmt nil nil nil (SelectStmt body))`)
+
+func run(pass *analysis.Pass) (any, error) {
+ for _, m := range code.Matches(pass, query) {
+ for _, c := range m.State["body"].([]ast.Stmt) {
// FIXME this leaves behind an empty line, and possibly
// comments in the default branch. We can't easily fix
// either.
if comm, ok := c.(*ast.CommClause); ok && comm.Comm == nil && len(comm.Body) == 0 {
- report.Report(pass, comm, "should not have an empty default case in a for+select loop; the loop will spin",
- report.Fixes(edit.Fix("remove empty default branch", edit.Delete(comm))))
+ report.Report(pass, comm,
+ "should not have an empty default case in a for+select loop; the loop will spin",
+ report.Fixes(edit.Fix("Remove empty default branch", edit.Delete(comm))))
// there can only be one default case
break
}
}
}
- code.Preorder(pass, fn, (*ast.ForStmt)(nil))
return nil, nil
}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa5005/sa5005.go b/vendor/honnef.co/go/tools/staticcheck/sa5005/sa5005.go
index a5aff7d22..b51e90d21 100644
--- a/vendor/honnef.co/go/tools/staticcheck/sa5005/sa5005.go
+++ b/vendor/honnef.co/go/tools/staticcheck/sa5005/sa5005.go
@@ -39,7 +39,7 @@ to zero before the object is being passed to the finalizer.`,
var Analyzer = SCAnalyzer.Analyzer
-func run(pass *analysis.Pass) (interface{}, error) {
+func run(pass *analysis.Pass) (any, error) {
cb := func(caller *ir.Function, site ir.CallInstruction, callee *ir.Function) {
if callee.RelString(nil) != "runtime.SetFinalizer" {
return
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa5007/sa5007.go b/vendor/honnef.co/go/tools/staticcheck/sa5007/sa5007.go
index 2b627f27c..d9a1dd7e4 100644
--- a/vendor/honnef.co/go/tools/staticcheck/sa5007/sa5007.go
+++ b/vendor/honnef.co/go/tools/staticcheck/sa5007/sa5007.go
@@ -34,7 +34,7 @@ should be used instead.`,
var Analyzer = SCAnalyzer.Analyzer
-func run(pass *analysis.Pass) (interface{}, error) {
+func run(pass *analysis.Pass) (any, error) {
for _, fn := range pass.ResultOf[buildir.Analyzer].(*buildir.IR).SrcFuncs {
eachCall(fn, func(caller *ir.Function, site ir.CallInstruction, callee *ir.Function) {
if callee != fn {
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa5008/jsonv2.go b/vendor/honnef.co/go/tools/staticcheck/sa5008/jsonv2.go
new file mode 100644
index 000000000..be5339d53
--- /dev/null
+++ b/vendor/honnef.co/go/tools/staticcheck/sa5008/jsonv2.go
@@ -0,0 +1,288 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+
+// This file is a modified copy of Go's encoding/json/v2/field.go
+
+package sa5008
+
+import (
+ "fmt"
+ "go/ast"
+ "go/types"
+ "io"
+ "strconv"
+ "strings"
+ "unicode"
+ "unicode/utf8"
+
+ "honnef.co/go/tools/analysis/report"
+ "honnef.co/go/tools/go/types/typeutil"
+
+ "golang.org/x/tools/go/analysis"
+)
+
+func validateJSONTag(pass *analysis.Pass, field *ast.Field, tag string) {
+ hasTag := tag != ""
+ tagOrig := tag
+
+ // Check whether this field is explicitly ignored.
+ if tag == "-" {
+ return
+ }
+
+ // Check whether this field is unexported and not embedded,
+ // which Go reflection cannot mutate for the sake of serialization.
+ //
+ // An embedded field of an unexported type is still capable of
+ // forwarding exported fields, which may be JSON serialized.
+ // This technically operates on the edge of what is permissible by
+ // the Go language, but the most recent decision is to permit this.
+ //
+ // See https://go.dev/issue/24153 and https://go.dev/issue/32772.
+ anonymous := len(field.Names) == 0
+ if !anonymous && !field.Names[0].IsExported() {
+ // Tag options specified on an unexported field suggests user error.
+ if hasTag {
+ report.Report(pass, field.Tag,
+ fmt.Sprintf("unexported struct field cannot have non-ignored `json:%q` tag", tag))
+ }
+ return
+ }
+
+ if len(tag) > 0 && !strings.HasPrefix(tag, ",") {
+ // For better compatibility with v1, accept almost any unescaped name.
+ n := len(tag) - len(strings.TrimLeftFunc(tag, func(r rune) bool {
+ return !strings.ContainsRune(",\\'\"`", r) // reserve comma, backslash, and quotes
+ }))
+ name := tag[:n]
+
+ // If the next character is not a comma, then the name is either
+ // malformed (if n > 0) or a single-quoted name.
+ // In either case, call consumeTagOption to handle it further.
+ var err error
+ if !strings.HasPrefix(tag[n:], ",") && len(name) != len(tag) {
+ name, n, err = consumeTagOption(tag)
+ if err != nil {
+ report.Report(pass, field.Tag, fmt.Sprintf("malformed `json` tag: %v", err))
+ }
+ }
+ if !utf8.ValidString(name) {
+ report.Report(pass, field.Tag,
+ fmt.Sprintf("invalid UTF-8 in JSON object name %q", name))
+ name = string([]rune(name)) // replace invalid UTF-8 with utf8.RuneError
+ }
+ if name == "-" && tag[0] == '-' {
+ // TODO(dh): offer automatic fix
+ report.Report(pass, field.Tag,
+ fmt.Sprintf("should encoding/json ignore this field or name it \"-\"? Either use `json:\"-\"` to ignore the field or use `json:\"'-'%s` to specify %q as the name",
+ strings.TrimPrefix(strconv.Quote(tagOrig), `"-`), name))
+ }
+ tag = tag[n:]
+ }
+
+ // Handle any additional tag options (if any).
+ var wasFormat bool
+ seenOpts := make(map[string]bool)
+ for len(tag) > 0 {
+ // Consume comma delimiter.
+ if tag[0] != ',' {
+ report.Report(pass, field.Tag,
+ fmt.Sprintf("malformed `json` tag: invalid character %q before next option (expecting ',')",
+ tag[0]))
+ } else {
+ tag = tag[len(","):]
+ if len(tag) == 0 {
+ report.Report(pass, field.Tag, "malformed `json` tag: invalid trailing ',' character")
+ break
+ }
+ }
+
+ // Consume and process the tag option.
+ opt, n, err := consumeTagOption(tag)
+ if err != nil {
+ report.Report(pass, field.Tag, fmt.Sprintf("malformed `json` tag: %v", err))
+ }
+ rawOpt := tag[:n]
+ tag = tag[n:]
+ switch {
+ case wasFormat:
+ report.Report(pass, field.Tag, "`format` tag option was not specified last")
+ case strings.HasPrefix(rawOpt, "'") && strings.TrimFunc(opt, isLetterOrDigit) == "":
+ // TODO(dh): offer automatic fix
+ report.Report(pass, field.Tag,
+ fmt.Sprintf("unnecessarily quoted appearance of `%s` tag option; specify `%s` instead", rawOpt, opt))
+ }
+ switch opt {
+ case "case":
+ if !strings.HasPrefix(tag, ":") {
+ // TODO(dh): offer automatic fix
+ report.Report(pass, field.Tag,
+ "missing value for `case` tag option; specify `case:ignore` or `case:strict` instead")
+ break
+ }
+ tag = tag[len(":"):]
+ opt, n, err := consumeTagOption(tag)
+ if err != nil {
+ report.Report(pass, field.Tag,
+ fmt.Sprintf("malformed value for `case` tag option: %v", err))
+ break
+ }
+ rawOpt := tag[:n]
+ tag = tag[n:]
+ if strings.HasPrefix(rawOpt, "'") {
+ // TODO(dh): offer automatic fix
+ report.Report(pass, field.Tag,
+ fmt.Sprintf("unnecessarily quoted appearance of `case:%s` tag option; specify `case:%s` instead",
+ rawOpt, opt))
+ }
+ switch opt {
+ case "ignore":
+ case "strict":
+ default:
+ report.Report(pass, field.Tag,
+ fmt.Sprintf("invalid appearance of unknown `case:%s` tag value", rawOpt))
+ }
+ case "inline":
+ case "unknown":
+ case "omitzero":
+ case "omitempty":
+ case "string":
+ const msg = "invalid appearance of `string` tag option; it is only intended for fields of numeric types or pointers to those"
+ tset := typeutil.NewTypeSet(pass.TypesInfo.TypeOf(field.Type))
+ if len(tset.Terms) == 0 {
+ // TODO(dh): improve message, call out the use of type parameters
+ report.Report(pass, field.Tag, msg)
+ continue
+ }
+ for _, term := range tset.Terms {
+ T := typeutil.Dereference(term.Type().Underlying())
+ for _, term2 := range typeutil.NewTypeSet(T).Terms {
+ basic, ok := term2.Type().Underlying().(*types.Basic)
+ // We accept bools and strings because v1 of encoding/json
+ // supports those. We don't mention that in the message,
+ // however, because their support is accidental, and v2
+ // doesn't support it.
+ if !ok || (basic.Info()&(types.IsBoolean|types.IsInteger|types.IsFloat|types.IsString)) == 0 {
+ // TODO(dh): improve message, show how we arrived at the type
+ report.Report(pass, field.Tag, msg)
+ }
+ }
+ }
+ case "format":
+ if !strings.HasPrefix(tag, ":") {
+ report.Report(pass, field.Tag, "missing value for `format` tag option")
+ break
+ }
+ tag = tag[len(":"):]
+ _, n, err := consumeTagOption(tag)
+ if err != nil {
+ report.Report(pass, field.Tag,
+ fmt.Sprintf("malformed value for `format` tag option: %v", err))
+ break
+ }
+ tag = tag[n:]
+ wasFormat = true
+ default:
+ // Reject keys that resemble one of the supported options.
+ // This catches invalid mutants such as "omitEmpty" or "omit_empty".
+ normOpt := strings.ReplaceAll(strings.ToLower(opt), "_", "")
+ switch normOpt {
+ case "case", "inline", "unknown", "omitzero", "omitempty", "string", "format":
+ report.Report(pass, field.Tag,
+ fmt.Sprintf("invalid appearance of `%s` tag option; specify `%s` instead",
+ opt, normOpt))
+ default:
+ report.Report(pass, field.Tag,
+ fmt.Sprintf("invalid appearance of unknown `%s` tag option", opt))
+ }
+ }
+
+ // Reject duplicates.
+ if seenOpts[opt] {
+ report.Report(pass, field.Tag,
+ fmt.Sprintf("duplicate appearance of `%s` tag option", rawOpt))
+ }
+ seenOpts[opt] = true
+ }
+
+ if seenOpts["inline"] && seenOpts["unknown"] {
+ report.Report(pass, field.Tag,
+ "field cannot have both `inline` and `unknown` specified")
+ }
+
+ // TODO(dh): implement more restrictions for types of inlined and unknown
+ // fields, including recursive restrictions:
+ //
+ // - Go struct field %s cannot have any options other than `inline` or `unknown` specified
+ // - inlined Go struct field %s of type %s with `unknown` tag must be a Go map of string key or a jsontext.Value
+ // - inlined Go struct field %s is not exported
+ // - inlined map field %s of type %s must have a string key that does not implement marshal or unmarshal methods
+ // - inlined Go struct field %s of type %s must be a Go struct, Go map of string key, or jsontext.Value
+}
+
+// consumeTagOption consumes the next option,
+// which is either a Go identifier or a single-quoted string.
+// If the next option is invalid, it returns all of in until the next comma,
+// and reports an error.
+func consumeTagOption(in string) (string, int, error) {
+ // For legacy compatibility with v1, assume options are comma-separated.
+ i := strings.IndexByte(in, ',')
+ if i < 0 {
+ i = len(in)
+ }
+
+ switch r, _ := utf8.DecodeRuneInString(in); {
+ // Option as a Go identifier.
+ case r == '_' || unicode.IsLetter(r):
+ n := len(in) - len(strings.TrimLeftFunc(in, isLetterOrDigit))
+ return in[:n], n, nil
+ // Option as a single-quoted string.
+ case r == '\'':
+ // The grammar is nearly identical to a double-quoted Go string literal,
+ // but uses single quotes as the terminators. The reason for a custom
+ // grammar is because both backtick and double quotes cannot be used
+ // verbatim in a struct tag.
+ //
+ // Convert a single-quoted string to a double-quote string and rely on
+ // strconv.Unquote to handle the rest.
+ var inEscape bool
+ b := []byte{'"'}
+ n := len(`'`)
+ for len(in) > n {
+ r, rn := utf8.DecodeRuneInString(in[n:])
+ switch {
+ case inEscape:
+ if r == '\'' {
+ b = b[:len(b)-1] // remove escape character: `\'` => `'`
+ }
+ inEscape = false
+ case r == '\\':
+ inEscape = true
+ case r == '"':
+ b = append(b, '\\') // insert escape character: `"` => `\"`
+ case r == '\'':
+ b = append(b, '"')
+ n += len(`'`)
+ out, err := strconv.Unquote(string(b))
+ if err != nil {
+ return in[:i], i, fmt.Errorf("invalid single-quoted string: %s", in[:n])
+ }
+ return out, n, nil
+ }
+ b = append(b, in[n:][:rn]...)
+ n += rn
+ }
+ if n > 10 {
+ n = 10 // limit the amount of context printed in the error
+ }
+ //lint:ignore ST1005 The ellipsis denotes truncated text
+ return in[:i], i, fmt.Errorf("single-quoted string not terminated: %s...", in[:n])
+ case len(in) == 0:
+ return in[:i], i, io.ErrUnexpectedEOF
+ default:
+ return in[:i], i, fmt.Errorf("invalid character %q at start of option (expecting Unicode letter or single quote)", r)
+ }
+}
+
+func isLetterOrDigit(r rune) bool {
+ return r == '_' || unicode.IsLetter(r) || unicode.IsNumber(r)
+}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa5008/sa5008.go b/vendor/honnef.co/go/tools/staticcheck/sa5008/sa5008.go
index a9fa27154..2b3453f5e 100644
--- a/vendor/honnef.co/go/tools/staticcheck/sa5008/sa5008.go
+++ b/vendor/honnef.co/go/tools/staticcheck/sa5008/sa5008.go
@@ -4,14 +4,11 @@ import (
"fmt"
"go/ast"
"go/types"
- "sort"
"strings"
- "unicode"
"honnef.co/go/tools/analysis/code"
"honnef.co/go/tools/analysis/lint"
"honnef.co/go/tools/analysis/report"
- "honnef.co/go/tools/go/types/typeutil"
"honnef.co/go/tools/staticcheck/fakereflect"
"honnef.co/go/tools/staticcheck/fakexml"
@@ -35,7 +32,7 @@ var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
var Analyzer = SCAnalyzer.Analyzer
-func run(pass *analysis.Pass) (interface{}, error) {
+func run(pass *analysis.Pass) (any, error) {
importsGoFlags := false
// we use the AST instead of (*types.Package).Imports to work
@@ -92,7 +89,10 @@ func run(pass *analysis.Pass) (interface{}, error) {
}
func checkJSONTag(pass *analysis.Pass, field *ast.Field, tag string) {
- if pass.Pkg.Path() == "encoding/json" || pass.Pkg.Path() == "encoding/json_test" {
+ if pass.Pkg.Path() == "encoding/json" ||
+ pass.Pkg.Path() == "encoding/json_test" ||
+ pass.Pkg.Path() == "encoding/json/v2" ||
+ pass.Pkg.Path() == "encoding/json/v2_test" {
// don't flag malformed JSON tags in the encoding/json
// package; it knows what it is doing, and it is testing
// itself.
@@ -101,57 +101,8 @@ func checkJSONTag(pass *analysis.Pass, field *ast.Field, tag string) {
//lint:ignore SA9003 TODO(dh): should we flag empty tags?
if len(tag) == 0 {
}
- if i := strings.Index(tag, ",format:"); i >= 0 {
- tag = tag[:i]
- }
- fields := strings.Split(tag, ",")
- for _, r := range fields[0] {
- if !unicode.IsLetter(r) && !unicode.IsDigit(r) && !strings.ContainsRune("!#$%&()*+-./:<=>?@[]^_{|}~ ", r) {
- report.Report(pass, field.Tag, fmt.Sprintf("invalid JSON field name %q", fields[0]))
- }
- }
- options := make(map[string]int)
- for _, s := range fields[1:] {
- switch s {
- case "":
- // allow stuff like "-,"
- case "string":
- // only for string, floating point, integer and bool
- options[s]++
- tset := typeutil.NewTypeSet(pass.TypesInfo.TypeOf(field.Type))
- if len(tset.Terms) == 0 {
- // TODO(dh): improve message, call out the use of type parameters
- report.Report(pass, field.Tag, "the JSON string option only applies to fields of type string, floating point, integer or bool, or pointers to those")
- continue
- }
- for _, term := range tset.Terms {
- T := typeutil.Dereference(term.Type().Underlying())
- for _, term2 := range typeutil.NewTypeSet(T).Terms {
- basic, ok := term2.Type().Underlying().(*types.Basic)
- if !ok || (basic.Info()&(types.IsBoolean|types.IsInteger|types.IsFloat|types.IsString)) == 0 {
- // TODO(dh): improve message, show how we arrived at the type
- report.Report(pass, field.Tag, "the JSON string option only applies to fields of type string, floating point, integer or bool, or pointers to those")
- }
- }
- }
- case "omitzero", "omitempty", "nocase", "inline", "unknown":
- options[s]++
- default:
- report.Report(pass, field.Tag, fmt.Sprintf("unknown JSON option %q", s))
- }
- }
- var duplicates []string
- for option, n := range options {
- if n > 1 {
- duplicates = append(duplicates, option)
- }
- }
- if len(duplicates) > 0 {
- sort.Strings(duplicates)
- for _, option := range duplicates {
- report.Report(pass, field.Tag, fmt.Sprintf("duplicate JSON option %q", option))
- }
- }
+
+ validateJSONTag(pass, field, tag)
}
func checkXMLTag(pass *analysis.Pass, field *ast.Field, tag string) {
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa5009/sa5009.go b/vendor/honnef.co/go/tools/staticcheck/sa5009/sa5009.go
index 4375c7fdc..7eaa095c8 100644
--- a/vendor/honnef.co/go/tools/staticcheck/sa5009/sa5009.go
+++ b/vendor/honnef.co/go/tools/staticcheck/sa5009/sa5009.go
@@ -127,8 +127,8 @@ func checkImpl(carg *callcheck.Argument, f ir.Value, args []ir.Value) {
return []types.Type{key, val}, true
case *types.Struct:
out := make([]types.Type, 0, T.NumFields())
- for i := 0; i < T.NumFields(); i++ {
- out = append(out, T.Field(i).Type())
+ for field := range T.Fields() {
+ out = append(out, field.Type())
}
return out, true
case *types.Array:
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa5010/sa5010.go b/vendor/honnef.co/go/tools/staticcheck/sa5010/sa5010.go
index 49c8ec287..684d53058 100644
--- a/vendor/honnef.co/go/tools/staticcheck/sa5010/sa5010.go
+++ b/vendor/honnef.co/go/tools/staticcheck/sa5010/sa5010.go
@@ -3,6 +3,7 @@ package sa5010
import (
"fmt"
"go/types"
+ "strings"
"honnef.co/go/tools/analysis/lint"
"honnef.co/go/tools/analysis/report"
@@ -48,7 +49,7 @@ either.`,
var Analyzer = SCAnalyzer.Analyzer
-func run(pass *analysis.Pass) (interface{}, error) {
+func run(pass *analysis.Pass) (any, error) {
type entry struct {
l, r *types.Func
}
@@ -56,6 +57,7 @@ func run(pass *analysis.Pass) (interface{}, error) {
msc := &pass.ResultOf[buildir.Analyzer].(*buildir.IR).Pkg.Prog.MethodSets
for _, fn := range pass.ResultOf[buildir.Analyzer].(*buildir.IR).SrcFuncs {
for _, b := range fn.Blocks {
+ instrLoop:
for _, instr := range b.Instrs {
assert, ok := instr.(*ir.TypeAssert)
if !ok {
@@ -74,13 +76,19 @@ func run(pass *analysis.Pass) (interface{}, error) {
}
ms := msc.MethodSet(left)
- for i := 0; i < righti.NumMethods(); i++ {
- mr := righti.Method(i).Origin()
+ for mr := range righti.Methods() {
sel := ms.Lookup(mr.Pkg(), mr.Name())
if sel == nil {
continue
}
- ml := sel.Obj().(*types.Func).Origin()
+ ml := sel.Obj().(*types.Func)
+ if ml.Origin() != ml || mr.Origin() != mr {
+ // Give up when we see generics.
+ //
+ // TODO(dh): support generics once go/types gets an
+ // exported API for type unification.
+ continue instrLoop
+ }
if types.AssignableTo(ml.Type(), mr.Type()) {
continue
}
@@ -89,15 +97,16 @@ func run(pass *analysis.Pass) (interface{}, error) {
}
if len(wrong) != 0 {
- s := fmt.Sprintf("impossible type assertion; %s and %s contradict each other:",
+ var s strings.Builder
+ s.WriteString(fmt.Sprintf("impossible type assertion; %s and %s contradict each other:",
types.TypeString(left, types.RelativeTo(pass.Pkg)),
- types.TypeString(right, types.RelativeTo(pass.Pkg)))
+ types.TypeString(right, types.RelativeTo(pass.Pkg))))
for _, e := range wrong {
- s += fmt.Sprintf("\n\twrong type for %s method", e.l.Name())
- s += fmt.Sprintf("\n\t\thave %s", e.l.Type())
- s += fmt.Sprintf("\n\t\twant %s", e.r.Type())
+ s.WriteString(fmt.Sprintf("\n\twrong type for %s method", e.l.Name()))
+ s.WriteString(fmt.Sprintf("\n\t\thave %s", e.l.Type()))
+ s.WriteString(fmt.Sprintf("\n\t\twant %s", e.r.Type()))
}
- report.Report(pass, assert, s)
+ report.Report(pass, assert, s.String())
}
}
}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa5011/sa5011.go b/vendor/honnef.co/go/tools/staticcheck/sa5011/sa5011.go
index 9f2f75799..7b1b13332 100644
--- a/vendor/honnef.co/go/tools/staticcheck/sa5011/sa5011.go
+++ b/vendor/honnef.co/go/tools/staticcheck/sa5011/sa5011.go
@@ -91,7 +91,7 @@ popular package.`,
var Analyzer = SCAnalyzer.Analyzer
-func run(pass *analysis.Pass) (interface{}, error) {
+func run(pass *analysis.Pass) (any, error) {
// This is an extremely trivial check that doesn't try to reason
// about control flow. That is, phis and sigmas do not propagate
// any information. As such, we can flag this:
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa5012/sa5012.go b/vendor/honnef.co/go/tools/staticcheck/sa5012/sa5012.go
index 350cf43d9..4c3911980 100644
--- a/vendor/honnef.co/go/tools/staticcheck/sa5012/sa5012.go
+++ b/vendor/honnef.co/go/tools/staticcheck/sa5012/sa5012.go
@@ -277,7 +277,7 @@ func findIndirectSliceLenChecks(pass *analysis.Pass) {
}
}
-func run(pass *analysis.Pass) (interface{}, error) {
+func run(pass *analysis.Pass) (any, error) {
findSliceLenChecks(pass)
findIndirectSliceLenChecks(pass)
flagSliceLens(pass)
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa6001/sa6001.go b/vendor/honnef.co/go/tools/staticcheck/sa6001/sa6001.go
index ae19f0297..9a1c86ab2 100644
--- a/vendor/honnef.co/go/tools/staticcheck/sa6001/sa6001.go
+++ b/vendor/honnef.co/go/tools/staticcheck/sa6001/sa6001.go
@@ -54,7 +54,7 @@ f5f5a8b6209f84961687d993b93ea0d397f5d5bf in the Go repository.`,
var Analyzer = SCAnalyzer.Analyzer
-func run(pass *analysis.Pass) (interface{}, error) {
+func run(pass *analysis.Pass) (any, error) {
for _, fn := range pass.ResultOf[buildir.Analyzer].(*buildir.IR).SrcFuncs {
for _, b := range fn.Blocks {
insLoop:
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa6005/sa6005.go b/vendor/honnef.co/go/tools/staticcheck/sa6005/sa6005.go
index f7c151198..387875a79 100644
--- a/vendor/honnef.co/go/tools/staticcheck/sa6005/sa6005.go
+++ b/vendor/honnef.co/go/tools/staticcheck/sa6005/sa6005.go
@@ -11,14 +11,13 @@ import (
"honnef.co/go/tools/pattern"
"golang.org/x/tools/go/analysis"
- "golang.org/x/tools/go/analysis/passes/inspect"
)
var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
Analyzer: &analysis.Analyzer{
Name: "SA6005",
Run: run,
- Requires: []*analysis.Analyzer{inspect.Analyzer},
+ Requires: code.RequiredAnalyzers,
},
Doc: &lint.RawDocumentation{
Title: `Inefficient string comparison with \'strings.ToLower\' or \'strings.ToUpper\'`,
@@ -58,12 +57,8 @@ var (
checkToLowerToUpperComparisonR = pattern.MustParse(`(CallExpr (SelectorExpr (Ident "strings") (Ident "EqualFold")) [a b])`)
)
-func run(pass *analysis.Pass) (interface{}, error) {
- fn := func(node ast.Node) {
- m, ok := code.Match(pass, checkToLowerToUpperComparisonQ, node)
- if !ok {
- return
- }
+func run(pass *analysis.Pass) (any, error) {
+ for node, m := range code.Matches(pass, checkToLowerToUpperComparisonQ) {
rn := pattern.NodeToAST(checkToLowerToUpperComparisonR.Root, m.State).(ast.Expr)
if m.State["tok"].(token.Token) == token.NEQ {
rn = &ast.UnaryExpr{
@@ -72,9 +67,9 @@ func run(pass *analysis.Pass) (interface{}, error) {
}
}
- report.Report(pass, node, "should use strings.EqualFold instead", report.Fixes(edit.Fix("replace with strings.EqualFold", edit.ReplaceWithNode(pass.Fset, node, rn))))
+ report.Report(pass, node,
+ "should use strings.EqualFold instead",
+ report.Fixes(edit.Fix("Replace with strings.EqualFold", edit.ReplaceWithNode(pass.Fset, node, rn))))
}
-
- code.Preorder(pass, fn, (*ast.BinaryExpr)(nil))
return nil, nil
}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa6006/sa6006.go b/vendor/honnef.co/go/tools/staticcheck/sa6006/sa6006.go
index 768905ab4..bc5684852 100644
--- a/vendor/honnef.co/go/tools/staticcheck/sa6006/sa6006.go
+++ b/vendor/honnef.co/go/tools/staticcheck/sa6006/sa6006.go
@@ -9,14 +9,13 @@ import (
"honnef.co/go/tools/pattern"
"golang.org/x/tools/go/analysis"
- "golang.org/x/tools/go/analysis/passes/inspect"
)
var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
Analyzer: &analysis.Analyzer{
Name: "SA6006",
Run: run,
- Requires: []*analysis.Analyzer{inspect.Analyzer},
+ Requires: code.RequiredAnalyzers,
},
Doc: &lint.RawDocumentation{
Title: `Using io.WriteString to write \'[]byte\'`,
@@ -36,18 +35,12 @@ var Analyzer = SCAnalyzer.Analyzer
var ioWriteStringConversion = pattern.MustParse(`(CallExpr (Symbol "io.WriteString") [_ (CallExpr (Builtin "string") [arg])])`)
-func run(pass *analysis.Pass) (interface{}, error) {
- fn := func(node ast.Node) {
- m, ok := code.Match(pass, ioWriteStringConversion, node)
- if !ok {
- return
- }
+func run(pass *analysis.Pass) (any, error) {
+ for node, m := range code.Matches(pass, ioWriteStringConversion) {
if !code.IsOfStringConvertibleByteSlice(pass, m.State["arg"].(ast.Expr)) {
- return
+ continue
}
report.Report(pass, node, "use io.Writer.Write instead of converting from []byte to string to use io.WriteString")
}
- code.Preorder(pass, fn, (*ast.CallExpr)(nil))
-
return nil, nil
}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa9001/sa9001.go b/vendor/honnef.co/go/tools/staticcheck/sa9001/sa9001.go
index 1c97ccd55..2be35c037 100644
--- a/vendor/honnef.co/go/tools/staticcheck/sa9001/sa9001.go
+++ b/vendor/honnef.co/go/tools/staticcheck/sa9001/sa9001.go
@@ -30,7 +30,7 @@ var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
var Analyzer = SCAnalyzer.Analyzer
-func run(pass *analysis.Pass) (interface{}, error) {
+func run(pass *analysis.Pass) (any, error) {
fn := func(node ast.Node) {
loop := node.(*ast.RangeStmt)
typ := pass.TypesInfo.TypeOf(loop.X)
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa9002/sa9002.go b/vendor/honnef.co/go/tools/staticcheck/sa9002/sa9002.go
index 054aa284a..4923bae5a 100644
--- a/vendor/honnef.co/go/tools/staticcheck/sa9002/sa9002.go
+++ b/vendor/honnef.co/go/tools/staticcheck/sa9002/sa9002.go
@@ -31,7 +31,7 @@ var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
var Analyzer = SCAnalyzer.Analyzer
-func run(pass *analysis.Pass) (interface{}, error) {
+func run(pass *analysis.Pass) (any, error) {
fn := func(node ast.Node) {
call := node.(*ast.CallExpr)
for _, arg := range call.Args {
@@ -54,7 +54,7 @@ func run(pass *analysis.Pass) (interface{}, error) {
continue
}
report.Report(pass, arg, fmt.Sprintf("file mode '%s' evaluates to %#o; did you mean '0%s'?", lit.Value, v, lit.Value),
- report.Fixes(edit.Fix("fix octal literal", edit.ReplaceWithString(arg, "0"+lit.Value))))
+ report.Fixes(edit.Fix("Fix octal literal", edit.ReplaceWithString(arg, "0"+lit.Value))))
}
}
}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa9003/sa9003.go b/vendor/honnef.co/go/tools/staticcheck/sa9003/sa9003.go
index 9ee66475f..0824eb49d 100644
--- a/vendor/honnef.co/go/tools/staticcheck/sa9003/sa9003.go
+++ b/vendor/honnef.co/go/tools/staticcheck/sa9003/sa9003.go
@@ -28,7 +28,7 @@ var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
var Analyzer = SCAnalyzer.Analyzer
-func run(pass *analysis.Pass) (interface{}, error) {
+func run(pass *analysis.Pass) (any, error) {
for _, fn := range pass.ResultOf[buildir.Analyzer].(*buildir.IR).SrcFuncs {
if fn.Source() == nil {
continue
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa9004/sa9004.go b/vendor/honnef.co/go/tools/staticcheck/sa9004/sa9004.go
index 2e8838ee0..acf242e1d 100644
--- a/vendor/honnef.co/go/tools/staticcheck/sa9004/sa9004.go
+++ b/vendor/honnef.co/go/tools/staticcheck/sa9004/sa9004.go
@@ -118,7 +118,7 @@ as \'EnumSecond\' has no explicit type, and thus defaults to \'int\'.`,
var Analyzer = SCAnalyzer.Analyzer
-func run(pass *analysis.Pass) (interface{}, error) {
+func run(pass *analysis.Pass) (any, error) {
fn := func(node ast.Node) {
decl := node.(*ast.GenDecl)
if !decl.Lparen.IsValid() {
@@ -175,7 +175,9 @@ func run(pass *analysis.Pass) (interface{}, error) {
nspec.Comment = nil
edits = append(edits, edit.ReplaceWithNode(pass.Fset, spec, &nspec))
}
- report.Report(pass, group[0], "only the first constant in this group has an explicit type", report.Fixes(edit.Fix("add type to all constants in group", edits...)))
+ report.Report(pass, group[0],
+ "only the first constant in this group has an explicit type",
+ report.Fixes(edit.Fix("Add type to all constants in group", edits...)))
}
}
code.Preorder(pass, fn, (*ast.GenDecl)(nil))
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa9006/sa9006.go b/vendor/honnef.co/go/tools/staticcheck/sa9006/sa9006.go
index 44f992399..4f92ee102 100644
--- a/vendor/honnef.co/go/tools/staticcheck/sa9006/sa9006.go
+++ b/vendor/honnef.co/go/tools/staticcheck/sa9006/sa9006.go
@@ -11,14 +11,13 @@ import (
"honnef.co/go/tools/pattern"
"golang.org/x/tools/go/analysis"
- "golang.org/x/tools/go/analysis/passes/inspect"
)
var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
Analyzer: &analysis.Analyzer{
Name: "SA9006",
Run: run,
- Requires: []*analysis.Analyzer{inspect.Analyzer},
+ Requires: code.RequiredAnalyzers,
},
Doc: &lint.RawDocumentation{
Title: `Dubious bit shifting of a fixed size integer value`,
@@ -59,7 +58,7 @@ var (
`)
)
-func run(pass *analysis.Pass) (interface{}, error) {
+func run(pass *analysis.Pass) (any, error) {
isDubiousShift := func(x, y ast.Expr) (int64, int64, bool) {
typ, ok := pass.TypesInfo.TypeOf(x).Underlying().(*types.Basic)
if !ok {
@@ -84,11 +83,7 @@ func run(pass *analysis.Pass) (interface{}, error) {
return typeBits, shiftLength, shiftLength >= typeBits
}
- fn := func(node ast.Node) {
- if _, ok := code.Match(pass, checkFixedLengthTypeShiftQ, node); !ok {
- return
- }
-
+ for node := range code.Matches(pass, checkFixedLengthTypeShiftQ) {
switch e := node.(type) {
case *ast.AssignStmt:
if size, shift, yes := isDubiousShift(e.Lhs[0], e.Rhs[0]); yes {
@@ -100,7 +95,6 @@ func run(pass *analysis.Pass) (interface{}, error) {
}
}
}
- code.Preorder(pass, fn, (*ast.AssignStmt)(nil), (*ast.BinaryExpr)(nil))
return nil, nil
}
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa9007/sa9007.go b/vendor/honnef.co/go/tools/staticcheck/sa9007/sa9007.go
index 685e1e134..45225906f 100644
--- a/vendor/honnef.co/go/tools/staticcheck/sa9007/sa9007.go
+++ b/vendor/honnef.co/go/tools/staticcheck/sa9007/sa9007.go
@@ -50,7 +50,7 @@ This check flags attempts at deleting the following directories:
var Analyzer = SCAnalyzer.Analyzer
-func run(pass *analysis.Pass) (interface{}, error) {
+func run(pass *analysis.Pass) (any, error) {
for _, fn := range pass.ResultOf[buildir.Analyzer].(*buildir.IR).SrcFuncs {
for _, b := range fn.Blocks {
for _, instr := range b.Instrs {
diff --git a/vendor/honnef.co/go/tools/staticcheck/sa9008/sa9008.go b/vendor/honnef.co/go/tools/staticcheck/sa9008/sa9008.go
index 355b11e42..b565ab602 100644
--- a/vendor/honnef.co/go/tools/staticcheck/sa9008/sa9008.go
+++ b/vendor/honnef.co/go/tools/staticcheck/sa9008/sa9008.go
@@ -14,14 +14,13 @@ import (
"honnef.co/go/tools/pattern"
"golang.org/x/tools/go/analysis"
- "golang.org/x/tools/go/analysis/passes/inspect"
)
var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
Analyzer: &analysis.Analyzer{
Name: "SA9008",
Run: run,
- Requires: []*analysis.Analyzer{inspect.Analyzer, buildir.Analyzer},
+ Requires: append([]*analysis.Analyzer{buildir.Analyzer}, code.RequiredAnalyzers...),
},
Doc: &lint.RawDocumentation{
Title: `\'else\' branch of a type assertion is probably not reading the right value`,
@@ -52,36 +51,32 @@ var Analyzer = SCAnalyzer.Analyzer
var typeAssertionShadowingElseQ = pattern.MustParse(`(IfStmt (AssignStmt [obj@(Ident _) ok@(Ident _)] ":=" assert@(TypeAssertExpr obj _)) ok _ elseBranch)`)
-func run(pass *analysis.Pass) (interface{}, error) {
+func run(pass *analysis.Pass) (any, error) {
// TODO(dh): without the IR-based verification, this check is able
// to find more bugs, but also more prone to false positives. It
// would be a good candidate for the 'codereview' category of
// checks.
irpkg := pass.ResultOf[buildir.Analyzer].(*buildir.IR).Pkg
- fn := func(node ast.Node) {
- m, ok := code.Match(pass, typeAssertionShadowingElseQ, node)
- if !ok {
- return
- }
+ for _, m := range code.Matches(pass, typeAssertionShadowingElseQ) {
shadow := pass.TypesInfo.ObjectOf(m.State["obj"].(*ast.Ident))
shadowed := m.State["assert"].(*ast.TypeAssertExpr).X
path, exact := astutil.PathEnclosingInterval(code.File(pass, shadow), shadow.Pos(), shadow.Pos())
if !exact {
// TODO(dh): when can this happen?
- return
+ continue
}
irfn := ir.EnclosingFunction(irpkg, path)
if irfn == nil {
// For example for functions named "_", because we don't generate IR for them.
- return
+ continue
}
shadoweeIR, isAddr := irfn.ValueForExpr(m.State["obj"].(*ast.Ident))
if shadoweeIR == nil || isAddr {
// TODO(dh): is this possible?
- return
+ continue
}
var branch ast.Node
@@ -91,7 +86,7 @@ func run(pass *analysis.Pass) (interface{}, error) {
case []ast.Stmt:
branch = &ast.BlockStmt{List: br}
case nil:
- return
+ continue
default:
panic(fmt.Sprintf("unexpected type %T", br))
}
@@ -125,6 +120,5 @@ func run(pass *analysis.Pass) (interface{}, error) {
return true
})
}
- code.Preorder(pass, fn, (*ast.IfStmt)(nil))
return nil, nil
}
diff --git a/vendor/honnef.co/go/tools/stylecheck/st1000/st1000.go b/vendor/honnef.co/go/tools/stylecheck/st1000/st1000.go
index 246dbc247..a3cf8c32a 100644
--- a/vendor/honnef.co/go/tools/stylecheck/st1000/st1000.go
+++ b/vendor/honnef.co/go/tools/stylecheck/st1000/st1000.go
@@ -30,7 +30,7 @@ https://go.dev/wiki/CodeReviewComments#package-comments.`,
var Analyzer = SCAnalyzer.Analyzer
-func run(pass *analysis.Pass) (interface{}, error) {
+func run(pass *analysis.Pass) (any, error) {
// - At least one file in a non-main package should have a package comment
//
// - The comment should be of the form
diff --git a/vendor/honnef.co/go/tools/stylecheck/st1001/st1001.go b/vendor/honnef.co/go/tools/stylecheck/st1001/st1001.go
index 3b2fd2ad2..b4fd06cc4 100644
--- a/vendor/honnef.co/go/tools/stylecheck/st1001/st1001.go
+++ b/vendor/honnef.co/go/tools/stylecheck/st1001/st1001.go
@@ -50,7 +50,7 @@ Quoting Go Code Review Comments:
var Analyzer = SCAnalyzer.Analyzer
-func run(pass *analysis.Pass) (interface{}, error) {
+func run(pass *analysis.Pass) (any, error) {
for _, f := range pass.Files {
imports:
for _, imp := range f.Imports {
diff --git a/vendor/honnef.co/go/tools/stylecheck/st1003/st1003.go b/vendor/honnef.co/go/tools/stylecheck/st1003/st1003.go
index d2ff5a9e5..a8c26e797 100644
--- a/vendor/honnef.co/go/tools/stylecheck/st1003/st1003.go
+++ b/vendor/honnef.co/go/tools/stylecheck/st1003/st1003.go
@@ -50,7 +50,7 @@ var knownNameExceptions = map[string]bool{
"kWh": true,
}
-func run(pass *analysis.Pass) (interface{}, error) {
+func run(pass *analysis.Pass) (any, error) {
// A large part of this function is copied from
// github.com/golang/lint, Copyright (c) 2013 The Go Authors,
// licensed under the BSD 3-clause license.
@@ -112,10 +112,10 @@ func run(pass *analysis.Pass) (interface{}, error) {
for _, f := range pass.Files {
// Package names need slightly different handling than other names.
if !strings.HasSuffix(f.Name.Name, "_test") && strings.Contains(f.Name.Name, "_") {
- report.Report(pass, f, "should not use underscores in package names", report.FilterGenerated())
+ report.Report(pass, f.Name, "should not use underscores in package names", report.FilterGenerated())
}
if strings.IndexFunc(f.Name.Name, unicode.IsUpper) != -1 {
- report.Report(pass, f, fmt.Sprintf("should not use MixedCaps in package name; %s should be %s", f.Name.Name, strings.ToLower(f.Name.Name)), report.FilterGenerated())
+ report.Report(pass, f.Name, fmt.Sprintf("should not use MixedCaps in package name; %s should be %s", f.Name.Name, strings.ToLower(f.Name.Name)), report.FilterGenerated())
}
}
diff --git a/vendor/honnef.co/go/tools/stylecheck/st1005/st1005.go b/vendor/honnef.co/go/tools/stylecheck/st1005/st1005.go
index a2909c377..477c0a118 100644
--- a/vendor/honnef.co/go/tools/stylecheck/st1005/st1005.go
+++ b/vendor/honnef.co/go/tools/stylecheck/st1005/st1005.go
@@ -42,7 +42,7 @@ Quoting Go Code Review Comments:
var Analyzer = SCAnalyzer.Analyzer
-func run(pass *analysis.Pass) (interface{}, error) {
+func run(pass *analysis.Pass) (any, error) {
objNames := map[*ir.Package]map[string]bool{}
irpkg := pass.ResultOf[buildir.Analyzer].(*buildir.IR).Pkg
objNames[irpkg] = map[string]bool{}
@@ -86,14 +86,14 @@ func run(pass *analysis.Pass) (interface{}, error) {
case '.', ':', '!', '\n':
report.Report(pass, call, "error strings should not end with punctuation or newlines")
}
- idx := strings.IndexByte(s, ' ')
- if idx == -1 {
+ before, _, ok0 := strings.Cut(s, " ")
+ if !ok0 {
// single word error message, probably not a real
// error but something used in tests or during
// debugging
continue
}
- word := s[:idx]
+ word := before
first, n := utf8.DecodeRuneInString(word)
if !unicode.IsUpper(first) {
continue
diff --git a/vendor/honnef.co/go/tools/stylecheck/st1006/st1006.go b/vendor/honnef.co/go/tools/stylecheck/st1006/st1006.go
index 42aad45cd..30b0dc868 100644
--- a/vendor/honnef.co/go/tools/stylecheck/st1006/st1006.go
+++ b/vendor/honnef.co/go/tools/stylecheck/st1006/st1006.go
@@ -40,7 +40,7 @@ var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
var Analyzer = SCAnalyzer.Analyzer
-func run(pass *analysis.Pass) (interface{}, error) {
+func run(pass *analysis.Pass) (any, error) {
irpkg := pass.ResultOf[buildir.Analyzer].(*buildir.IR).Pkg
for _, m := range irpkg.Members {
if T, ok := m.Object().(*types.TypeName); ok && !T.IsAlias() {
diff --git a/vendor/honnef.co/go/tools/stylecheck/st1008/st1008.go b/vendor/honnef.co/go/tools/stylecheck/st1008/st1008.go
index 23c557ea9..8c9f3264c 100644
--- a/vendor/honnef.co/go/tools/stylecheck/st1008/st1008.go
+++ b/vendor/honnef.co/go/tools/stylecheck/st1008/st1008.go
@@ -26,7 +26,7 @@ var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
var Analyzer = SCAnalyzer.Analyzer
-func run(pass *analysis.Pass) (interface{}, error) {
+func run(pass *analysis.Pass) (any, error) {
fnLoop:
for _, fn := range pass.ResultOf[buildir.Analyzer].(*buildir.IR).SrcFuncs {
sig := fn.Type().(*types.Signature)
diff --git a/vendor/honnef.co/go/tools/stylecheck/st1011/st1011.go b/vendor/honnef.co/go/tools/stylecheck/st1011/st1011.go
index 3bf7ecdf1..cb43bba17 100644
--- a/vendor/honnef.co/go/tools/stylecheck/st1011/st1011.go
+++ b/vendor/honnef.co/go/tools/stylecheck/st1011/st1011.go
@@ -35,7 +35,7 @@ variable of type \'time.Duration\' with any time unit, such as \'Msec\' or
var Analyzer = SCAnalyzer.Analyzer
-func run(pass *analysis.Pass) (interface{}, error) {
+func run(pass *analysis.Pass) (any, error) {
suffixes := []string{
"Sec", "Secs", "Seconds",
"Msec", "Msecs",
diff --git a/vendor/honnef.co/go/tools/stylecheck/st1012/st1012.go b/vendor/honnef.co/go/tools/stylecheck/st1012/st1012.go
index fdeaee76d..cf921fe0f 100644
--- a/vendor/honnef.co/go/tools/stylecheck/st1012/st1012.go
+++ b/vendor/honnef.co/go/tools/stylecheck/st1012/st1012.go
@@ -29,7 +29,7 @@ var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
var Analyzer = SCAnalyzer.Analyzer
-func run(pass *analysis.Pass) (interface{}, error) {
+func run(pass *analysis.Pass) (any, error) {
for _, f := range pass.Files {
for _, decl := range f.Decls {
gen, ok := decl.(*ast.GenDecl)
diff --git a/vendor/honnef.co/go/tools/stylecheck/st1013/st1013.go b/vendor/honnef.co/go/tools/stylecheck/st1013/st1013.go
index d28daa35e..01fe71c7d 100644
--- a/vendor/honnef.co/go/tools/stylecheck/st1013/st1013.go
+++ b/vendor/honnef.co/go/tools/stylecheck/st1013/st1013.go
@@ -12,16 +12,16 @@ import (
"honnef.co/go/tools/analysis/lint"
"honnef.co/go/tools/analysis/report"
"honnef.co/go/tools/config"
+ "honnef.co/go/tools/pattern"
"golang.org/x/tools/go/analysis"
- "golang.org/x/tools/go/analysis/passes/inspect"
)
var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
Analyzer: &analysis.Analyzer{
Name: "ST1013",
Run: run,
- Requires: []*analysis.Analyzer{generated.Analyzer, config.Analyzer, inspect.Analyzer},
+ Requires: append([]*analysis.Analyzer{generated.Analyzer, config.Analyzer}, code.RequiredAnalyzers...),
},
Doc: &lint.RawDocumentation{
Title: `Should use constants for HTTP error codes, not magic numbers`,
@@ -39,16 +39,24 @@ readability of your code.`,
var Analyzer = SCAnalyzer.Analyzer
-func run(pass *analysis.Pass) (interface{}, error) {
+var query = pattern.MustParse(`
+ (CallExpr
+ (Symbol
+ name@(Or
+ "net/http.Error"
+ "net/http.Redirect"
+ "net/http.StatusText"
+ "net/http.RedirectHandler"))
+ args)`)
+
+func run(pass *analysis.Pass) (any, error) {
whitelist := map[string]bool{}
for _, code := range config.For(pass).HTTPStatusCodeWhitelist {
whitelist[code] = true
}
- fn := func(node ast.Node) {
- call := node.(*ast.CallExpr)
-
+ for _, m := range code.Matches(pass, query) {
var arg int
- switch code.CallName(pass, call) {
+ switch m.State["name"].(string) {
case "net/http.Error":
arg = 2
case "net/http.Redirect":
@@ -58,33 +66,33 @@ func run(pass *analysis.Pass) (interface{}, error) {
case "net/http.RedirectHandler":
arg = 1
default:
- return
+ continue
}
- if arg >= len(call.Args) {
- return
+ args := m.State["args"].([]ast.Expr)
+ if arg >= len(args) {
+ continue
}
- tv, ok := code.IntegerLiteral(pass, call.Args[arg])
+ tv, ok := code.IntegerLiteral(pass, args[arg])
if !ok {
- return
+ continue
}
n, ok := constant.Int64Val(tv.Value)
if !ok {
- return
+ continue
}
if whitelist[strconv.FormatInt(n, 10)] {
- return
+ continue
}
s, ok := httpStatusCodes[n]
if !ok {
- return
+ continue
}
- lit := call.Args[arg]
+ lit := args[arg]
report.Report(pass, lit, fmt.Sprintf("should use constant http.%s instead of numeric literal %d", s, n),
report.FilterGenerated(),
- report.Fixes(edit.Fix(fmt.Sprintf("use http.%s instead of %d", s, n), edit.ReplaceWithString(lit, "http."+s))))
+ report.Fixes(edit.Fix(fmt.Sprintf("Use http.%s instead of %d", s, n), edit.ReplaceWithString(lit, "http."+s))))
}
- code.Preorder(pass, fn, (*ast.CallExpr)(nil))
return nil, nil
}
diff --git a/vendor/honnef.co/go/tools/stylecheck/st1015/st1015.go b/vendor/honnef.co/go/tools/stylecheck/st1015/st1015.go
index a03be7471..18d0e207c 100644
--- a/vendor/honnef.co/go/tools/stylecheck/st1015/st1015.go
+++ b/vendor/honnef.co/go/tools/stylecheck/st1015/st1015.go
@@ -28,7 +28,7 @@ var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
var Analyzer = SCAnalyzer.Analyzer
-func run(pass *analysis.Pass) (interface{}, error) {
+func run(pass *analysis.Pass) (any, error) {
hasFallthrough := func(clause ast.Stmt) bool {
// A valid fallthrough statement may be used only as the final non-empty statement in a case clause. Thus we can
// easily avoid falsely matching fallthroughs in nested switches by not descending into blocks.
diff --git a/vendor/honnef.co/go/tools/stylecheck/st1016/st1016.go b/vendor/honnef.co/go/tools/stylecheck/st1016/st1016.go
index d175a749a..56aa2ead7 100644
--- a/vendor/honnef.co/go/tools/stylecheck/st1016/st1016.go
+++ b/vendor/honnef.co/go/tools/stylecheck/st1016/st1016.go
@@ -32,7 +32,7 @@ var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
var Analyzer = SCAnalyzer.Analyzer
-func run(pass *analysis.Pass) (interface{}, error) {
+func run(pass *analysis.Pass) (any, error) {
irpkg := pass.ResultOf[buildir.Analyzer].(*buildir.IR).Pkg
for _, m := range irpkg.Members {
names := map[string]int{}
diff --git a/vendor/honnef.co/go/tools/stylecheck/st1017/st1017.go b/vendor/honnef.co/go/tools/stylecheck/st1017/st1017.go
index 6e8ccca64..d27980896 100644
--- a/vendor/honnef.co/go/tools/stylecheck/st1017/st1017.go
+++ b/vendor/honnef.co/go/tools/stylecheck/st1017/st1017.go
@@ -1,8 +1,6 @@
package st1017
import (
- "go/ast"
-
"honnef.co/go/tools/analysis/code"
"honnef.co/go/tools/analysis/edit"
"honnef.co/go/tools/analysis/facts/generated"
@@ -11,14 +9,13 @@ import (
"honnef.co/go/tools/pattern"
"golang.org/x/tools/go/analysis"
- "golang.org/x/tools/go/analysis/passes/inspect"
)
var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
Analyzer: &analysis.Analyzer{
Name: "ST1017",
Run: run,
- Requires: []*analysis.Analyzer{inspect.Analyzer, generated.Analyzer},
+ Requires: append([]*analysis.Analyzer{generated.Analyzer}, code.RequiredAnalyzers...),
},
Doc: &lint.RawDocumentation{
Title: `Don't use Yoda conditions`,
@@ -39,14 +36,12 @@ var (
checkYodaConditionsR = pattern.MustParse(`(BinaryExpr right tok left)`)
)
-func run(pass *analysis.Pass) (interface{}, error) {
- fn := func(node ast.Node) {
- if _, edits, ok := code.MatchAndEdit(pass, checkYodaConditionsQ, checkYodaConditionsR, node); ok {
- report.Report(pass, node, "don't use Yoda conditions",
- report.FilterGenerated(),
- report.Fixes(edit.Fix("un-Yoda-fy", edits...)))
- }
+func run(pass *analysis.Pass) (any, error) {
+ for node, m := range code.Matches(pass, checkYodaConditionsQ) {
+ edits := code.EditMatch(pass, node, m, checkYodaConditionsR)
+ report.Report(pass, node, "don't use Yoda conditions",
+ report.FilterGenerated(),
+ report.Fixes(edit.Fix("Un-Yoda-fy", edits...)))
}
- code.Preorder(pass, fn, (*ast.BinaryExpr)(nil))
return nil, nil
}
diff --git a/vendor/honnef.co/go/tools/stylecheck/st1018/st1018.go b/vendor/honnef.co/go/tools/stylecheck/st1018/st1018.go
index 85d961c61..a479c8d23 100644
--- a/vendor/honnef.co/go/tools/stylecheck/st1018/st1018.go
+++ b/vendor/honnef.co/go/tools/stylecheck/st1018/st1018.go
@@ -31,7 +31,7 @@ var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
var Analyzer = SCAnalyzer.Analyzer
-func run(pass *analysis.Pass) (interface{}, error) {
+func run(pass *analysis.Pass) (any, error) {
fn := func(node ast.Node) {
lit := node.(*ast.BasicLit)
if lit.Kind != token.STRING {
diff --git a/vendor/honnef.co/go/tools/stylecheck/st1019/st1019.go b/vendor/honnef.co/go/tools/stylecheck/st1019/st1019.go
index f08781ec3..d43c81866 100644
--- a/vendor/honnef.co/go/tools/stylecheck/st1019/st1019.go
+++ b/vendor/honnef.co/go/tools/stylecheck/st1019/st1019.go
@@ -27,7 +27,6 @@ bit of code is valid:
"fmt"
fumpt "fmt"
format "fmt"
- _ "fmt"
)
However, this is very rarely done on purpose. Usually, it is a
@@ -39,7 +38,12 @@ Do note that sometimes, this feature may be used
intentionally (see for example
https://github.com/golang/go/commit/3409ce39bfd7584523b7a8c150a310cea92d879d)
– if you want to allow this pattern in your code base, you're
-advised to disable this check.`,
+advised to disable this check.
+
+It is acceptable to import the same package twice if one of the imports
+uses the blank identifier. This is allowed in order to increase
+resilience against erroneous changes when using the same package for its
+side effects as well as its exported API.`,
Since: "2020.1",
MergeIf: lint.MergeIfAny,
},
@@ -47,20 +51,25 @@ advised to disable this check.`,
var Analyzer = SCAnalyzer.Analyzer
-func run(pass *analysis.Pass) (interface{}, error) {
+func run(pass *analysis.Pass) (any, error) {
for _, f := range pass.Files {
// Collect all imports by their import path
imports := make(map[string][]*ast.ImportSpec, len(f.Imports))
for _, imp := range f.Imports {
+ if imp.Name != nil && imp.Name.Name == "_" {
+ // Allow blank imports to coexist with one normal import.
+ //
+ // We don't have to count the number of blank imports,
+ // goimports removes duplicates.
+ continue
+ }
imports[imp.Path.Value] = append(imports[imp.Path.Value], imp)
}
for path, value := range imports {
if path[1:len(path)-1] == "unsafe" {
// Don't flag unsafe. Cgo generated code imports
- // unsafe using the blank identifier, and most
- // user-written cgo code also imports unsafe
- // explicitly.
+ // unsafe as _cgo_unsafe, in addition to the user's import.
continue
}
// If there's more than one import per path, we flag that
diff --git a/vendor/honnef.co/go/tools/stylecheck/st1020/st1020.go b/vendor/honnef.co/go/tools/stylecheck/st1020/st1020.go
index aed4290b6..b395f2cbf 100644
--- a/vendor/honnef.co/go/tools/stylecheck/st1020/st1020.go
+++ b/vendor/honnef.co/go/tools/stylecheck/st1020/st1020.go
@@ -41,7 +41,7 @@ information on how to write good documentation.`,
var Analyzer = SCAnalyzer.Analyzer
-func run(pass *analysis.Pass) (interface{}, error) {
+func run(pass *analysis.Pass) (any, error) {
fn := func(node ast.Node) {
if code.IsInTest(pass, node) {
return
diff --git a/vendor/honnef.co/go/tools/stylecheck/st1021/st1021.go b/vendor/honnef.co/go/tools/stylecheck/st1021/st1021.go
index 8ba6a5b23..9a43c8117 100644
--- a/vendor/honnef.co/go/tools/stylecheck/st1021/st1021.go
+++ b/vendor/honnef.co/go/tools/stylecheck/st1021/st1021.go
@@ -43,7 +43,7 @@ information on how to write good documentation.`,
var Analyzer = SCAnalyzer.Analyzer
-func run(pass *analysis.Pass) (interface{}, error) {
+func run(pass *analysis.Pass) (any, error) {
var genDecl *ast.GenDecl
fn := func(node ast.Node, push bool) bool {
if !push {
diff --git a/vendor/honnef.co/go/tools/stylecheck/st1022/st1022.go b/vendor/honnef.co/go/tools/stylecheck/st1022/st1022.go
index d37711988..2813632fd 100644
--- a/vendor/honnef.co/go/tools/stylecheck/st1022/st1022.go
+++ b/vendor/honnef.co/go/tools/stylecheck/st1022/st1022.go
@@ -43,7 +43,7 @@ information on how to write good documentation.`,
var Analyzer = SCAnalyzer.Analyzer
-func run(pass *analysis.Pass) (interface{}, error) {
+func run(pass *analysis.Pass) (any, error) {
var genDecl *ast.GenDecl
fn := func(node ast.Node, push bool) bool {
if !push {
diff --git a/vendor/honnef.co/go/tools/unused/implements.go b/vendor/honnef.co/go/tools/unused/implements.go
index 05f87bbbc..1207e4a8c 100644
--- a/vendor/honnef.co/go/tools/unused/implements.go
+++ b/vendor/honnef.co/go/tools/unused/implements.go
@@ -47,8 +47,7 @@ func implements(V types.Type, T *types.Interface, msV *types.MethodSet) ([]*type
if ityp, _ := V.Underlying().(*types.Interface); ityp != nil {
// TODO(dh): is this code reachable?
- for i := 0; i < T.NumMethods(); i++ {
- m := T.Method(i)
+ for m := range T.Methods() {
_, obj := lookupMethod(ityp, m.Pkg(), m.Name())
switch {
case obj == nil:
@@ -63,8 +62,7 @@ func implements(V types.Type, T *types.Interface, msV *types.MethodSet) ([]*type
// A concrete type implements T if it implements all methods of T.
var sels []*types.Selection
var c methodsChecker
- for i := 0; i < T.NumMethods(); i++ {
- m := T.Method(i)
+ for m := range T.Methods() {
sel := msV.Lookup(m.Pkg(), m.Name())
if sel == nil {
return nil, false
diff --git a/vendor/honnef.co/go/tools/unused/serialize.go b/vendor/honnef.co/go/tools/unused/serialize.go
index 126e7400a..e97154153 100644
--- a/vendor/honnef.co/go/tools/unused/serialize.go
+++ b/vendor/honnef.co/go/tools/unused/serialize.go
@@ -23,7 +23,7 @@ type SerializedGraph struct {
nodesByPosition map[token.Position]NodeID
}
-func trace(f string, args ...interface{}) {
+func trace(f string, args ...any) {
fmt.Fprintf(os.Stderr, f, args...)
fmt.Fprintln(os.Stderr)
}
diff --git a/vendor/honnef.co/go/tools/unused/unused.go b/vendor/honnef.co/go/tools/unused/unused.go
index e05cef0a9..99060a35b 100644
--- a/vendor/honnef.co/go/tools/unused/unused.go
+++ b/vendor/honnef.co/go/tools/unused/unused.go
@@ -8,6 +8,7 @@ import (
"go/types"
"io"
"reflect"
+ "slices"
"strings"
"honnef.co/go/tools/analysis/facts/directives"
@@ -177,7 +178,7 @@ var Analyzer = &lint.Analyzer{
Doc: "Unused code",
Run: run,
Requires: []*analysis.Analyzer{generated.Analyzer, directives.Analyzer},
- ResultType: reflect.TypeOf(Result{}),
+ ResultType: reflect.TypeFor[Result](),
},
}
@@ -206,7 +207,7 @@ func newGraph(
return &g
}
-func run(pass *analysis.Pass) (interface{}, error) {
+func run(pass *analysis.Pass) (any, error) {
g := newGraph(
pass.Fset,
pass.Files,
@@ -550,8 +551,7 @@ func (g *graph) entry() {
}
processMethodSet := func(named *types.TypeName, ms *types.MethodSet) {
if g.opts.ExportedIsUsed {
- for i := 0; i < ms.Len(); i++ {
- m := ms.At(i)
+ for m := range ms.Methods() {
if token.IsExported(m.Obj().Name()) {
// (2.1) named types use exported methods
// (6.4) structs use embedded fields that have exported methods
@@ -597,26 +597,23 @@ func (g *graph) entry() {
if len(dir.Arguments) == 0 {
continue
}
- for _, check := range strings.Split(dir.Arguments[0], ",") {
- if check == "U1000" {
- pos := g.fset.PositionFor(dir.Node.Pos(), false)
- var key ignoredKey
- switch dir.Command {
- case "ignore":
- key = ignoredKey{
- pos.Filename,
- pos.Line,
- }
- case "file-ignore":
- key = ignoredKey{
- pos.Filename,
- -1,
- }
+ if slices.Contains(strings.Split(dir.Arguments[0], ","), "U1000") {
+ pos := g.fset.PositionFor(dir.Node.Pos(), false)
+ var key ignoredKey
+ switch dir.Command {
+ case "ignore":
+ key = ignoredKey{
+ pos.Filename,
+ pos.Line,
+ }
+ case "file-ignore":
+ key = ignoredKey{
+ pos.Filename,
+ -1,
}
-
- ignores[key] = struct{}{}
- break
}
+
+ ignores[key] = struct{}{}
}
}
@@ -652,13 +649,13 @@ func (g *graph) entry() {
}
}
if typ, ok := types.Unalias(obj.Type()).(*types.Named); ok {
- for i := 0; i < typ.NumMethods(); i++ {
- g.use(typ.Method(i), nil)
+ for method := range typ.Methods() {
+ g.use(method, nil)
}
}
if typ, ok := obj.Type().Underlying().(*types.Struct); ok {
- for i := 0; i < typ.NumFields(); i++ {
- g.use(typ.Field(i), nil)
+ for field := range typ.Fields() {
+ g.use(field, nil)
}
}
}
@@ -736,8 +733,8 @@ func (g *graph) read(node ast.Node, by types.Object) {
if g.opts.FieldWritesAreUses && unkeyed {
// Untagged struct literal that specifies all fields. We have to manually use the fields in the type,
// because the unkeyd literal doesn't contain any nodes referring to the fields.
- for i := 0; i < typ.NumFields(); i++ {
- g.use(typ.Field(i), by)
+ for field := range typ.Fields() {
+ g.use(field, by)
}
}
if g.opts.FieldWritesAreUses || unkeyed {
@@ -934,8 +931,7 @@ func (g *graph) read(node ast.Node, by types.Object) {
func (g *graph) useAllFieldsRecursively(typ types.Type, by types.Object) {
switch typ := typ.Underlying().(type) {
case *types.Struct:
- for i := 0; i < typ.NumFields(); i++ {
- field := typ.Field(i)
+ for field := range typ.Fields() {
g.use(field, by)
g.useAllFieldsRecursively(field.Type(), by)
}
@@ -1477,7 +1473,7 @@ func isNoCopyType(typ types.Type) bool {
}
switch num := named.NumMethods(); num {
case 1, 2:
- for i := 0; i < num; i++ {
+ for i := range num {
meth := named.Method(i)
if meth.Name() != "Lock" && meth.Name() != "Unlock" {
return false
@@ -1516,8 +1512,7 @@ func (g *graph) namedType(typ *types.TypeName, spec ast.Expr) {
return false
}
seen[t] = struct{}{}
- for i := 0; i < t.NumFields(); i++ {
- field := t.Field(i)
+ for field := range t.Fields() {
if field.Exported() {
return true
}
diff --git a/vendor/k8s.io/api/admission/v1/generated.proto b/vendor/k8s.io/api/admission/v1/generated.proto
index cd5c88bad..38a0fcea6 100644
--- a/vendor/k8s.io/api/admission/v1/generated.proto
+++ b/vendor/k8s.io/api/admission/v1/generated.proto
@@ -35,12 +35,15 @@ message AdmissionRequest {
// otherwise identical (parallel requests, requests when earlier requests did not modify etc)
// The UID is meant to track the round trip (request/response) between the KAS and the WebHook, not the user request.
// It is suitable for correlating log entries between the webhook and apiserver, for either auditing or debugging.
+ // +optional
optional string uid = 1;
// kind is the fully-qualified type of object being submitted (for example, v1.Pod or autoscaling.v1.Scale)
+ // +optional
optional .k8s.io.apimachinery.pkg.apis.meta.v1.GroupVersionKind kind = 2;
// resource is the fully-qualified resource being requested (for example, v1.pods)
+ // +optional
optional .k8s.io.apimachinery.pkg.apis.meta.v1.GroupVersionResource resource = 3;
// subResource is the subresource being requested, if any (for example, "status" or "scale")
@@ -90,9 +93,11 @@ message AdmissionRequest {
// operation is the operation being performed. This may be different than the operation
// requested. e.g. a patch can result in either a CREATE or UPDATE Operation.
+ // +optional
optional string operation = 7;
// userInfo is information about the requesting user
+ // +optional
optional .k8s.io.api.authentication.v1.UserInfo userInfo = 8;
// object is the object from the incoming request.
@@ -121,9 +126,11 @@ message AdmissionRequest {
message AdmissionResponse {
// uid is an identifier for the individual request/response.
// This must be copied over from the corresponding AdmissionRequest.
+ // +optional
optional string uid = 1;
// allowed indicates whether or not the admission request was permitted.
+ // +optional
optional bool allowed = 2;
// status is the result contains extra details into why an admission request was denied.
diff --git a/vendor/k8s.io/api/admission/v1/generated.protomessage.pb.go b/vendor/k8s.io/api/admission/v1/generated.protomessage.pb.go
deleted file mode 100644
index 4e1ec547d..000000000
--- a/vendor/k8s.io/api/admission/v1/generated.protomessage.pb.go
+++ /dev/null
@@ -1,28 +0,0 @@
-//go:build kubernetes_protomessage_one_more_release
-// +build kubernetes_protomessage_one_more_release
-
-/*
-Copyright The Kubernetes Authors.
-
-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.
-*/
-
-// Code generated by go-to-protobuf. DO NOT EDIT.
-
-package v1
-
-func (*AdmissionRequest) ProtoMessage() {}
-
-func (*AdmissionResponse) ProtoMessage() {}
-
-func (*AdmissionReview) ProtoMessage() {}
diff --git a/vendor/k8s.io/api/admission/v1/types.go b/vendor/k8s.io/api/admission/v1/types.go
index 395672c39..34cbf2f59 100644
--- a/vendor/k8s.io/api/admission/v1/types.go
+++ b/vendor/k8s.io/api/admission/v1/types.go
@@ -43,10 +43,13 @@ type AdmissionRequest struct {
// otherwise identical (parallel requests, requests when earlier requests did not modify etc)
// The UID is meant to track the round trip (request/response) between the KAS and the WebHook, not the user request.
// It is suitable for correlating log entries between the webhook and apiserver, for either auditing or debugging.
+ // +optional
UID types.UID `json:"uid" protobuf:"bytes,1,opt,name=uid"`
// kind is the fully-qualified type of object being submitted (for example, v1.Pod or autoscaling.v1.Scale)
+ // +optional
Kind metav1.GroupVersionKind `json:"kind" protobuf:"bytes,2,opt,name=kind"`
// resource is the fully-qualified resource being requested (for example, v1.pods)
+ // +optional
Resource metav1.GroupVersionResource `json:"resource" protobuf:"bytes,3,opt,name=resource"`
// subResource is the subresource being requested, if any (for example, "status" or "scale")
// +optional
@@ -91,8 +94,10 @@ type AdmissionRequest struct {
Namespace string `json:"namespace,omitempty" protobuf:"bytes,6,opt,name=namespace"`
// operation is the operation being performed. This may be different than the operation
// requested. e.g. a patch can result in either a CREATE or UPDATE Operation.
+ // +optional
Operation Operation `json:"operation" protobuf:"bytes,7,opt,name=operation"`
// userInfo is information about the requesting user
+ // +optional
UserInfo authenticationv1.UserInfo `json:"userInfo" protobuf:"bytes,8,opt,name=userInfo"`
// object is the object from the incoming request.
// +optional
@@ -117,9 +122,11 @@ type AdmissionRequest struct {
type AdmissionResponse struct {
// uid is an identifier for the individual request/response.
// This must be copied over from the corresponding AdmissionRequest.
+ // +optional
UID types.UID `json:"uid" protobuf:"bytes,1,opt,name=uid"`
// allowed indicates whether or not the admission request was permitted.
+ // +optional
Allowed bool `json:"allowed" protobuf:"varint,2,opt,name=allowed"`
// status is the result contains extra details into why an admission request was denied.
diff --git a/vendor/k8s.io/api/admission/v1beta1/generated.proto b/vendor/k8s.io/api/admission/v1beta1/generated.proto
index 5af234993..9514719ba 100644
--- a/vendor/k8s.io/api/admission/v1beta1/generated.proto
+++ b/vendor/k8s.io/api/admission/v1beta1/generated.proto
@@ -35,12 +35,15 @@ message AdmissionRequest {
// otherwise identical (parallel requests, requests when earlier requests did not modify etc)
// The UID is meant to track the round trip (request/response) between the KAS and the WebHook, not the user request.
// It is suitable for correlating log entries between the webhook and apiserver, for either auditing or debugging.
+ // +optional
optional string uid = 1;
// kind is the fully-qualified type of object being submitted (for example, v1.Pod or autoscaling.v1.Scale)
+ // +optional
optional .k8s.io.apimachinery.pkg.apis.meta.v1.GroupVersionKind kind = 2;
// resource is the fully-qualified resource being requested (for example, v1.pods)
+ // +optional
optional .k8s.io.apimachinery.pkg.apis.meta.v1.GroupVersionResource resource = 3;
// subResource is the subresource being requested, if any (for example, "status" or "scale")
@@ -90,9 +93,11 @@ message AdmissionRequest {
// operation is the operation being performed. This may be different than the operation
// requested. e.g. a patch can result in either a CREATE or UPDATE Operation.
+ // +optional
optional string operation = 7;
// userInfo is information about the requesting user
+ // +optional
optional .k8s.io.api.authentication.v1.UserInfo userInfo = 8;
// object is the object from the incoming request.
@@ -121,9 +126,11 @@ message AdmissionRequest {
message AdmissionResponse {
// uid is an identifier for the individual request/response.
// This should be copied over from the corresponding AdmissionRequest.
+ // +optional
optional string uid = 1;
// allowed indicates whether or not the admission request was permitted.
+ // +optional
optional bool allowed = 2;
// status is the result contains extra details into why an admission request was denied.
diff --git a/vendor/k8s.io/api/admission/v1beta1/generated.protomessage.pb.go b/vendor/k8s.io/api/admission/v1beta1/generated.protomessage.pb.go
deleted file mode 100644
index 95c702293..000000000
--- a/vendor/k8s.io/api/admission/v1beta1/generated.protomessage.pb.go
+++ /dev/null
@@ -1,28 +0,0 @@
-//go:build kubernetes_protomessage_one_more_release
-// +build kubernetes_protomessage_one_more_release
-
-/*
-Copyright The Kubernetes Authors.
-
-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.
-*/
-
-// Code generated by go-to-protobuf. DO NOT EDIT.
-
-package v1beta1
-
-func (*AdmissionRequest) ProtoMessage() {}
-
-func (*AdmissionResponse) ProtoMessage() {}
-
-func (*AdmissionReview) ProtoMessage() {}
diff --git a/vendor/k8s.io/api/admission/v1beta1/types.go b/vendor/k8s.io/api/admission/v1beta1/types.go
index 81941eb32..015dc8ba3 100644
--- a/vendor/k8s.io/api/admission/v1beta1/types.go
+++ b/vendor/k8s.io/api/admission/v1beta1/types.go
@@ -47,10 +47,13 @@ type AdmissionRequest struct {
// otherwise identical (parallel requests, requests when earlier requests did not modify etc)
// The UID is meant to track the round trip (request/response) between the KAS and the WebHook, not the user request.
// It is suitable for correlating log entries between the webhook and apiserver, for either auditing or debugging.
+ // +optional
UID types.UID `json:"uid" protobuf:"bytes,1,opt,name=uid"`
// kind is the fully-qualified type of object being submitted (for example, v1.Pod or autoscaling.v1.Scale)
+ // +optional
Kind metav1.GroupVersionKind `json:"kind" protobuf:"bytes,2,opt,name=kind"`
// resource is the fully-qualified resource being requested (for example, v1.pods)
+ // +optional
Resource metav1.GroupVersionResource `json:"resource" protobuf:"bytes,3,opt,name=resource"`
// subResource is the subresource being requested, if any (for example, "status" or "scale")
// +optional
@@ -95,8 +98,10 @@ type AdmissionRequest struct {
Namespace string `json:"namespace,omitempty" protobuf:"bytes,6,opt,name=namespace"`
// operation is the operation being performed. This may be different than the operation
// requested. e.g. a patch can result in either a CREATE or UPDATE Operation.
+ // +optional
Operation Operation `json:"operation" protobuf:"bytes,7,opt,name=operation"`
// userInfo is information about the requesting user
+ // +optional
UserInfo authenticationv1.UserInfo `json:"userInfo" protobuf:"bytes,8,opt,name=userInfo"`
// object is the object from the incoming request.
// +optional
@@ -121,9 +126,11 @@ type AdmissionRequest struct {
type AdmissionResponse struct {
// uid is an identifier for the individual request/response.
// This should be copied over from the corresponding AdmissionRequest.
+ // +optional
UID types.UID `json:"uid" protobuf:"bytes,1,opt,name=uid"`
// allowed indicates whether or not the admission request was permitted.
+ // +optional
Allowed bool `json:"allowed" protobuf:"varint,2,opt,name=allowed"`
// status is the result contains extra details into why an admission request was denied.
diff --git a/vendor/k8s.io/api/admissionregistration/v1/generated.pb.go b/vendor/k8s.io/api/admissionregistration/v1/generated.pb.go
index 91b2f1cba..e2def5040 100644
--- a/vendor/k8s.io/api/admissionregistration/v1/generated.pb.go
+++ b/vendor/k8s.io/api/admissionregistration/v1/generated.pb.go
@@ -32,20 +32,38 @@ import (
strings "strings"
)
+func (m *ApplyConfiguration) Reset() { *m = ApplyConfiguration{} }
+
func (m *AuditAnnotation) Reset() { *m = AuditAnnotation{} }
func (m *ExpressionWarning) Reset() { *m = ExpressionWarning{} }
+func (m *JSONPatch) Reset() { *m = JSONPatch{} }
+
func (m *MatchCondition) Reset() { *m = MatchCondition{} }
func (m *MatchResources) Reset() { *m = MatchResources{} }
+func (m *MutatingAdmissionPolicy) Reset() { *m = MutatingAdmissionPolicy{} }
+
+func (m *MutatingAdmissionPolicyBinding) Reset() { *m = MutatingAdmissionPolicyBinding{} }
+
+func (m *MutatingAdmissionPolicyBindingList) Reset() { *m = MutatingAdmissionPolicyBindingList{} }
+
+func (m *MutatingAdmissionPolicyBindingSpec) Reset() { *m = MutatingAdmissionPolicyBindingSpec{} }
+
+func (m *MutatingAdmissionPolicyList) Reset() { *m = MutatingAdmissionPolicyList{} }
+
+func (m *MutatingAdmissionPolicySpec) Reset() { *m = MutatingAdmissionPolicySpec{} }
+
func (m *MutatingWebhook) Reset() { *m = MutatingWebhook{} }
func (m *MutatingWebhookConfiguration) Reset() { *m = MutatingWebhookConfiguration{} }
func (m *MutatingWebhookConfigurationList) Reset() { *m = MutatingWebhookConfigurationList{} }
+func (m *Mutation) Reset() { *m = Mutation{} }
+
func (m *NamedRuleWithOperations) Reset() { *m = NamedRuleWithOperations{} }
func (m *ParamKind) Reset() { *m = ParamKind{} }
@@ -86,6 +104,34 @@ func (m *Variable) Reset() { *m = Variable{} }
func (m *WebhookClientConfig) Reset() { *m = WebhookClientConfig{} }
+func (m *ApplyConfiguration) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
+ }
+ return dAtA[:n], nil
+}
+
+func (m *ApplyConfiguration) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *ApplyConfiguration) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
+ var l int
+ _ = l
+ i -= len(m.Expression)
+ copy(dAtA[i:], m.Expression)
+ i = encodeVarintGenerated(dAtA, i, uint64(len(m.Expression)))
+ i--
+ dAtA[i] = 0xa
+ return len(dAtA) - i, nil
+}
+
func (m *AuditAnnotation) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
@@ -152,6 +198,34 @@ func (m *ExpressionWarning) MarshalToSizedBuffer(dAtA []byte) (int, error) {
return len(dAtA) - i, nil
}
+func (m *JSONPatch) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
+ }
+ return dAtA[:n], nil
+}
+
+func (m *JSONPatch) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *JSONPatch) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
+ var l int
+ _ = l
+ i -= len(m.Expression)
+ copy(dAtA[i:], m.Expression)
+ i = encodeVarintGenerated(dAtA, i, uint64(len(m.Expression)))
+ i--
+ dAtA[i] = 0xa
+ return len(dAtA) - i, nil
+}
+
func (m *MatchCondition) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
@@ -267,7 +341,7 @@ func (m *MatchResources) MarshalToSizedBuffer(dAtA []byte) (int, error) {
return len(dAtA) - i, nil
}
-func (m *MutatingWebhook) Marshal() (dAtA []byte, err error) {
+func (m *MutatingAdmissionPolicy) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBuffer(dAtA[:size])
@@ -277,112 +351,18 @@ func (m *MutatingWebhook) Marshal() (dAtA []byte, err error) {
return dAtA[:n], nil
}
-func (m *MutatingWebhook) MarshalTo(dAtA []byte) (int, error) {
+func (m *MutatingAdmissionPolicy) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
-func (m *MutatingWebhook) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+func (m *MutatingAdmissionPolicy) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
- if len(m.MatchConditions) > 0 {
- for iNdEx := len(m.MatchConditions) - 1; iNdEx >= 0; iNdEx-- {
- {
- size, err := m.MatchConditions[iNdEx].MarshalToSizedBuffer(dAtA[:i])
- if err != nil {
- return 0, err
- }
- i -= size
- i = encodeVarintGenerated(dAtA, i, uint64(size))
- }
- i--
- dAtA[i] = 0x62
- }
- }
- if m.ObjectSelector != nil {
- {
- size, err := m.ObjectSelector.MarshalToSizedBuffer(dAtA[:i])
- if err != nil {
- return 0, err
- }
- i -= size
- i = encodeVarintGenerated(dAtA, i, uint64(size))
- }
- i--
- dAtA[i] = 0x5a
- }
- if m.ReinvocationPolicy != nil {
- i -= len(*m.ReinvocationPolicy)
- copy(dAtA[i:], *m.ReinvocationPolicy)
- i = encodeVarintGenerated(dAtA, i, uint64(len(*m.ReinvocationPolicy)))
- i--
- dAtA[i] = 0x52
- }
- if m.MatchPolicy != nil {
- i -= len(*m.MatchPolicy)
- copy(dAtA[i:], *m.MatchPolicy)
- i = encodeVarintGenerated(dAtA, i, uint64(len(*m.MatchPolicy)))
- i--
- dAtA[i] = 0x4a
- }
- if len(m.AdmissionReviewVersions) > 0 {
- for iNdEx := len(m.AdmissionReviewVersions) - 1; iNdEx >= 0; iNdEx-- {
- i -= len(m.AdmissionReviewVersions[iNdEx])
- copy(dAtA[i:], m.AdmissionReviewVersions[iNdEx])
- i = encodeVarintGenerated(dAtA, i, uint64(len(m.AdmissionReviewVersions[iNdEx])))
- i--
- dAtA[i] = 0x42
- }
- }
- if m.TimeoutSeconds != nil {
- i = encodeVarintGenerated(dAtA, i, uint64(*m.TimeoutSeconds))
- i--
- dAtA[i] = 0x38
- }
- if m.SideEffects != nil {
- i -= len(*m.SideEffects)
- copy(dAtA[i:], *m.SideEffects)
- i = encodeVarintGenerated(dAtA, i, uint64(len(*m.SideEffects)))
- i--
- dAtA[i] = 0x32
- }
- if m.NamespaceSelector != nil {
- {
- size, err := m.NamespaceSelector.MarshalToSizedBuffer(dAtA[:i])
- if err != nil {
- return 0, err
- }
- i -= size
- i = encodeVarintGenerated(dAtA, i, uint64(size))
- }
- i--
- dAtA[i] = 0x2a
- }
- if m.FailurePolicy != nil {
- i -= len(*m.FailurePolicy)
- copy(dAtA[i:], *m.FailurePolicy)
- i = encodeVarintGenerated(dAtA, i, uint64(len(*m.FailurePolicy)))
- i--
- dAtA[i] = 0x22
- }
- if len(m.Rules) > 0 {
- for iNdEx := len(m.Rules) - 1; iNdEx >= 0; iNdEx-- {
- {
- size, err := m.Rules[iNdEx].MarshalToSizedBuffer(dAtA[:i])
- if err != nil {
- return 0, err
- }
- i -= size
- i = encodeVarintGenerated(dAtA, i, uint64(size))
- }
- i--
- dAtA[i] = 0x1a
- }
- }
{
- size, err := m.ClientConfig.MarshalToSizedBuffer(dAtA[:i])
+ size, err := m.Spec.MarshalToSizedBuffer(dAtA[:i])
if err != nil {
return 0, err
}
@@ -391,15 +371,20 @@ func (m *MutatingWebhook) MarshalToSizedBuffer(dAtA []byte) (int, error) {
}
i--
dAtA[i] = 0x12
- i -= len(m.Name)
- copy(dAtA[i:], m.Name)
- i = encodeVarintGenerated(dAtA, i, uint64(len(m.Name)))
+ {
+ size, err := m.ObjectMeta.MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
+ }
+ i -= size
+ i = encodeVarintGenerated(dAtA, i, uint64(size))
+ }
i--
dAtA[i] = 0xa
return len(dAtA) - i, nil
}
-func (m *MutatingWebhookConfiguration) Marshal() (dAtA []byte, err error) {
+func (m *MutatingAdmissionPolicyBinding) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBuffer(dAtA[:size])
@@ -409,30 +394,26 @@ func (m *MutatingWebhookConfiguration) Marshal() (dAtA []byte, err error) {
return dAtA[:n], nil
}
-func (m *MutatingWebhookConfiguration) MarshalTo(dAtA []byte) (int, error) {
+func (m *MutatingAdmissionPolicyBinding) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
-func (m *MutatingWebhookConfiguration) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+func (m *MutatingAdmissionPolicyBinding) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
- if len(m.Webhooks) > 0 {
- for iNdEx := len(m.Webhooks) - 1; iNdEx >= 0; iNdEx-- {
- {
- size, err := m.Webhooks[iNdEx].MarshalToSizedBuffer(dAtA[:i])
- if err != nil {
- return 0, err
- }
- i -= size
- i = encodeVarintGenerated(dAtA, i, uint64(size))
- }
- i--
- dAtA[i] = 0x12
+ {
+ size, err := m.Spec.MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
}
+ i -= size
+ i = encodeVarintGenerated(dAtA, i, uint64(size))
}
+ i--
+ dAtA[i] = 0x12
{
size, err := m.ObjectMeta.MarshalToSizedBuffer(dAtA[:i])
if err != nil {
@@ -446,7 +427,7 @@ func (m *MutatingWebhookConfiguration) MarshalToSizedBuffer(dAtA []byte) (int, e
return len(dAtA) - i, nil
}
-func (m *MutatingWebhookConfigurationList) Marshal() (dAtA []byte, err error) {
+func (m *MutatingAdmissionPolicyBindingList) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBuffer(dAtA[:size])
@@ -456,12 +437,12 @@ func (m *MutatingWebhookConfigurationList) Marshal() (dAtA []byte, err error) {
return dAtA[:n], nil
}
-func (m *MutatingWebhookConfigurationList) MarshalTo(dAtA []byte) (int, error) {
+func (m *MutatingAdmissionPolicyBindingList) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
-func (m *MutatingWebhookConfigurationList) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+func (m *MutatingAdmissionPolicyBindingList) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
@@ -493,7 +474,7 @@ func (m *MutatingWebhookConfigurationList) MarshalToSizedBuffer(dAtA []byte) (in
return len(dAtA) - i, nil
}
-func (m *NamedRuleWithOperations) Marshal() (dAtA []byte, err error) {
+func (m *MutatingAdmissionPolicyBindingSpec) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBuffer(dAtA[:size])
@@ -503,39 +484,49 @@ func (m *NamedRuleWithOperations) Marshal() (dAtA []byte, err error) {
return dAtA[:n], nil
}
-func (m *NamedRuleWithOperations) MarshalTo(dAtA []byte) (int, error) {
+func (m *MutatingAdmissionPolicyBindingSpec) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
-func (m *NamedRuleWithOperations) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+func (m *MutatingAdmissionPolicyBindingSpec) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
- {
- size, err := m.RuleWithOperations.MarshalToSizedBuffer(dAtA[:i])
- if err != nil {
- return 0, err
+ if m.MatchResources != nil {
+ {
+ size, err := m.MatchResources.MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
+ }
+ i -= size
+ i = encodeVarintGenerated(dAtA, i, uint64(size))
}
- i -= size
- i = encodeVarintGenerated(dAtA, i, uint64(size))
+ i--
+ dAtA[i] = 0x1a
}
- i--
- dAtA[i] = 0x12
- if len(m.ResourceNames) > 0 {
- for iNdEx := len(m.ResourceNames) - 1; iNdEx >= 0; iNdEx-- {
- i -= len(m.ResourceNames[iNdEx])
- copy(dAtA[i:], m.ResourceNames[iNdEx])
- i = encodeVarintGenerated(dAtA, i, uint64(len(m.ResourceNames[iNdEx])))
- i--
- dAtA[i] = 0xa
+ if m.ParamRef != nil {
+ {
+ size, err := m.ParamRef.MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
+ }
+ i -= size
+ i = encodeVarintGenerated(dAtA, i, uint64(size))
}
+ i--
+ dAtA[i] = 0x12
}
+ i -= len(m.PolicyName)
+ copy(dAtA[i:], m.PolicyName)
+ i = encodeVarintGenerated(dAtA, i, uint64(len(m.PolicyName)))
+ i--
+ dAtA[i] = 0xa
return len(dAtA) - i, nil
}
-func (m *ParamKind) Marshal() (dAtA []byte, err error) {
+func (m *MutatingAdmissionPolicyList) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBuffer(dAtA[:size])
@@ -545,31 +536,45 @@ func (m *ParamKind) Marshal() (dAtA []byte, err error) {
return dAtA[:n], nil
}
-func (m *ParamKind) MarshalTo(dAtA []byte) (int, error) {
+func (m *MutatingAdmissionPolicyList) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
-func (m *ParamKind) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+func (m *MutatingAdmissionPolicyList) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
- i -= len(m.Kind)
- copy(dAtA[i:], m.Kind)
- i = encodeVarintGenerated(dAtA, i, uint64(len(m.Kind)))
- i--
- dAtA[i] = 0x12
- i -= len(m.APIVersion)
- copy(dAtA[i:], m.APIVersion)
- i = encodeVarintGenerated(dAtA, i, uint64(len(m.APIVersion)))
- i--
- dAtA[i] = 0xa
- return len(dAtA) - i, nil
-}
-
-func (m *ParamRef) Marshal() (dAtA []byte, err error) {
- size := m.Size()
+ if len(m.Items) > 0 {
+ for iNdEx := len(m.Items) - 1; iNdEx >= 0; iNdEx-- {
+ {
+ size, err := m.Items[iNdEx].MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
+ }
+ i -= size
+ i = encodeVarintGenerated(dAtA, i, uint64(size))
+ }
+ i--
+ dAtA[i] = 0x12
+ }
+ }
+ {
+ size, err := m.ListMeta.MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
+ }
+ i -= size
+ i = encodeVarintGenerated(dAtA, i, uint64(size))
+ }
+ i--
+ dAtA[i] = 0xa
+ return len(dAtA) - i, nil
+}
+
+func (m *MutatingAdmissionPolicySpec) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBuffer(dAtA[:size])
if err != nil {
@@ -578,26 +583,73 @@ func (m *ParamRef) Marshal() (dAtA []byte, err error) {
return dAtA[:n], nil
}
-func (m *ParamRef) MarshalTo(dAtA []byte) (int, error) {
+func (m *MutatingAdmissionPolicySpec) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
-func (m *ParamRef) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+func (m *MutatingAdmissionPolicySpec) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
- if m.ParameterNotFoundAction != nil {
- i -= len(*m.ParameterNotFoundAction)
- copy(dAtA[i:], *m.ParameterNotFoundAction)
- i = encodeVarintGenerated(dAtA, i, uint64(len(*m.ParameterNotFoundAction)))
+ i -= len(m.ReinvocationPolicy)
+ copy(dAtA[i:], m.ReinvocationPolicy)
+ i = encodeVarintGenerated(dAtA, i, uint64(len(m.ReinvocationPolicy)))
+ i--
+ dAtA[i] = 0x3a
+ if len(m.MatchConditions) > 0 {
+ for iNdEx := len(m.MatchConditions) - 1; iNdEx >= 0; iNdEx-- {
+ {
+ size, err := m.MatchConditions[iNdEx].MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
+ }
+ i -= size
+ i = encodeVarintGenerated(dAtA, i, uint64(size))
+ }
+ i--
+ dAtA[i] = 0x32
+ }
+ }
+ if m.FailurePolicy != nil {
+ i -= len(*m.FailurePolicy)
+ copy(dAtA[i:], *m.FailurePolicy)
+ i = encodeVarintGenerated(dAtA, i, uint64(len(*m.FailurePolicy)))
i--
- dAtA[i] = 0x22
+ dAtA[i] = 0x2a
}
- if m.Selector != nil {
+ if len(m.Mutations) > 0 {
+ for iNdEx := len(m.Mutations) - 1; iNdEx >= 0; iNdEx-- {
+ {
+ size, err := m.Mutations[iNdEx].MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
+ }
+ i -= size
+ i = encodeVarintGenerated(dAtA, i, uint64(size))
+ }
+ i--
+ dAtA[i] = 0x22
+ }
+ }
+ if len(m.Variables) > 0 {
+ for iNdEx := len(m.Variables) - 1; iNdEx >= 0; iNdEx-- {
+ {
+ size, err := m.Variables[iNdEx].MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
+ }
+ i -= size
+ i = encodeVarintGenerated(dAtA, i, uint64(size))
+ }
+ i--
+ dAtA[i] = 0x1a
+ }
+ }
+ if m.MatchConstraints != nil {
{
- size, err := m.Selector.MarshalToSizedBuffer(dAtA[:i])
+ size, err := m.MatchConstraints.MarshalToSizedBuffer(dAtA[:i])
if err != nil {
return 0, err
}
@@ -605,22 +657,24 @@ func (m *ParamRef) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i = encodeVarintGenerated(dAtA, i, uint64(size))
}
i--
- dAtA[i] = 0x1a
+ dAtA[i] = 0x12
+ }
+ if m.ParamKind != nil {
+ {
+ size, err := m.ParamKind.MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
+ }
+ i -= size
+ i = encodeVarintGenerated(dAtA, i, uint64(size))
+ }
+ i--
+ dAtA[i] = 0xa
}
- i -= len(m.Namespace)
- copy(dAtA[i:], m.Namespace)
- i = encodeVarintGenerated(dAtA, i, uint64(len(m.Namespace)))
- i--
- dAtA[i] = 0x12
- i -= len(m.Name)
- copy(dAtA[i:], m.Name)
- i = encodeVarintGenerated(dAtA, i, uint64(len(m.Name)))
- i--
- dAtA[i] = 0xa
return len(dAtA) - i, nil
}
-func (m *Rule) Marshal() (dAtA []byte, err error) {
+func (m *MutatingWebhook) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBuffer(dAtA[:size])
@@ -630,54 +684,129 @@ func (m *Rule) Marshal() (dAtA []byte, err error) {
return dAtA[:n], nil
}
-func (m *Rule) MarshalTo(dAtA []byte) (int, error) {
+func (m *MutatingWebhook) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
-func (m *Rule) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+func (m *MutatingWebhook) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
- if m.Scope != nil {
- i -= len(*m.Scope)
- copy(dAtA[i:], *m.Scope)
- i = encodeVarintGenerated(dAtA, i, uint64(len(*m.Scope)))
+ if len(m.MatchConditions) > 0 {
+ for iNdEx := len(m.MatchConditions) - 1; iNdEx >= 0; iNdEx-- {
+ {
+ size, err := m.MatchConditions[iNdEx].MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
+ }
+ i -= size
+ i = encodeVarintGenerated(dAtA, i, uint64(size))
+ }
+ i--
+ dAtA[i] = 0x62
+ }
+ }
+ if m.ObjectSelector != nil {
+ {
+ size, err := m.ObjectSelector.MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
+ }
+ i -= size
+ i = encodeVarintGenerated(dAtA, i, uint64(size))
+ }
i--
- dAtA[i] = 0x22
+ dAtA[i] = 0x5a
}
- if len(m.Resources) > 0 {
- for iNdEx := len(m.Resources) - 1; iNdEx >= 0; iNdEx-- {
- i -= len(m.Resources[iNdEx])
- copy(dAtA[i:], m.Resources[iNdEx])
- i = encodeVarintGenerated(dAtA, i, uint64(len(m.Resources[iNdEx])))
+ if m.ReinvocationPolicy != nil {
+ i -= len(*m.ReinvocationPolicy)
+ copy(dAtA[i:], *m.ReinvocationPolicy)
+ i = encodeVarintGenerated(dAtA, i, uint64(len(*m.ReinvocationPolicy)))
+ i--
+ dAtA[i] = 0x52
+ }
+ if m.MatchPolicy != nil {
+ i -= len(*m.MatchPolicy)
+ copy(dAtA[i:], *m.MatchPolicy)
+ i = encodeVarintGenerated(dAtA, i, uint64(len(*m.MatchPolicy)))
+ i--
+ dAtA[i] = 0x4a
+ }
+ if len(m.AdmissionReviewVersions) > 0 {
+ for iNdEx := len(m.AdmissionReviewVersions) - 1; iNdEx >= 0; iNdEx-- {
+ i -= len(m.AdmissionReviewVersions[iNdEx])
+ copy(dAtA[i:], m.AdmissionReviewVersions[iNdEx])
+ i = encodeVarintGenerated(dAtA, i, uint64(len(m.AdmissionReviewVersions[iNdEx])))
i--
- dAtA[i] = 0x1a
+ dAtA[i] = 0x42
}
}
- if len(m.APIVersions) > 0 {
- for iNdEx := len(m.APIVersions) - 1; iNdEx >= 0; iNdEx-- {
- i -= len(m.APIVersions[iNdEx])
- copy(dAtA[i:], m.APIVersions[iNdEx])
- i = encodeVarintGenerated(dAtA, i, uint64(len(m.APIVersions[iNdEx])))
- i--
- dAtA[i] = 0x12
+ if m.TimeoutSeconds != nil {
+ i = encodeVarintGenerated(dAtA, i, uint64(*m.TimeoutSeconds))
+ i--
+ dAtA[i] = 0x38
+ }
+ if m.SideEffects != nil {
+ i -= len(*m.SideEffects)
+ copy(dAtA[i:], *m.SideEffects)
+ i = encodeVarintGenerated(dAtA, i, uint64(len(*m.SideEffects)))
+ i--
+ dAtA[i] = 0x32
+ }
+ if m.NamespaceSelector != nil {
+ {
+ size, err := m.NamespaceSelector.MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
+ }
+ i -= size
+ i = encodeVarintGenerated(dAtA, i, uint64(size))
}
+ i--
+ dAtA[i] = 0x2a
}
- if len(m.APIGroups) > 0 {
- for iNdEx := len(m.APIGroups) - 1; iNdEx >= 0; iNdEx-- {
- i -= len(m.APIGroups[iNdEx])
- copy(dAtA[i:], m.APIGroups[iNdEx])
- i = encodeVarintGenerated(dAtA, i, uint64(len(m.APIGroups[iNdEx])))
+ if m.FailurePolicy != nil {
+ i -= len(*m.FailurePolicy)
+ copy(dAtA[i:], *m.FailurePolicy)
+ i = encodeVarintGenerated(dAtA, i, uint64(len(*m.FailurePolicy)))
+ i--
+ dAtA[i] = 0x22
+ }
+ if len(m.Rules) > 0 {
+ for iNdEx := len(m.Rules) - 1; iNdEx >= 0; iNdEx-- {
+ {
+ size, err := m.Rules[iNdEx].MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
+ }
+ i -= size
+ i = encodeVarintGenerated(dAtA, i, uint64(size))
+ }
i--
- dAtA[i] = 0xa
+ dAtA[i] = 0x1a
+ }
+ }
+ {
+ size, err := m.ClientConfig.MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
}
+ i -= size
+ i = encodeVarintGenerated(dAtA, i, uint64(size))
}
+ i--
+ dAtA[i] = 0x12
+ i -= len(m.Name)
+ copy(dAtA[i:], m.Name)
+ i = encodeVarintGenerated(dAtA, i, uint64(len(m.Name)))
+ i--
+ dAtA[i] = 0xa
return len(dAtA) - i, nil
}
-func (m *RuleWithOperations) Marshal() (dAtA []byte, err error) {
+func (m *MutatingWebhookConfiguration) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBuffer(dAtA[:size])
@@ -687,84 +816,44 @@ func (m *RuleWithOperations) Marshal() (dAtA []byte, err error) {
return dAtA[:n], nil
}
-func (m *RuleWithOperations) MarshalTo(dAtA []byte) (int, error) {
+func (m *MutatingWebhookConfiguration) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
-func (m *RuleWithOperations) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+func (m *MutatingWebhookConfiguration) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
- {
- size, err := m.Rule.MarshalToSizedBuffer(dAtA[:i])
- if err != nil {
- return 0, err
- }
- i -= size
- i = encodeVarintGenerated(dAtA, i, uint64(size))
- }
- i--
- dAtA[i] = 0x12
- if len(m.Operations) > 0 {
- for iNdEx := len(m.Operations) - 1; iNdEx >= 0; iNdEx-- {
- i -= len(m.Operations[iNdEx])
- copy(dAtA[i:], m.Operations[iNdEx])
- i = encodeVarintGenerated(dAtA, i, uint64(len(m.Operations[iNdEx])))
+ if len(m.Webhooks) > 0 {
+ for iNdEx := len(m.Webhooks) - 1; iNdEx >= 0; iNdEx-- {
+ {
+ size, err := m.Webhooks[iNdEx].MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
+ }
+ i -= size
+ i = encodeVarintGenerated(dAtA, i, uint64(size))
+ }
i--
- dAtA[i] = 0xa
+ dAtA[i] = 0x12
}
}
- return len(dAtA) - i, nil
-}
-
-func (m *ServiceReference) Marshal() (dAtA []byte, err error) {
- size := m.Size()
- dAtA = make([]byte, size)
- n, err := m.MarshalToSizedBuffer(dAtA[:size])
- if err != nil {
- return nil, err
- }
- return dAtA[:n], nil
-}
-
-func (m *ServiceReference) MarshalTo(dAtA []byte) (int, error) {
- size := m.Size()
- return m.MarshalToSizedBuffer(dAtA[:size])
-}
-
-func (m *ServiceReference) MarshalToSizedBuffer(dAtA []byte) (int, error) {
- i := len(dAtA)
- _ = i
- var l int
- _ = l
- if m.Port != nil {
- i = encodeVarintGenerated(dAtA, i, uint64(*m.Port))
- i--
- dAtA[i] = 0x20
- }
- if m.Path != nil {
- i -= len(*m.Path)
- copy(dAtA[i:], *m.Path)
- i = encodeVarintGenerated(dAtA, i, uint64(len(*m.Path)))
- i--
- dAtA[i] = 0x1a
+ {
+ size, err := m.ObjectMeta.MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
+ }
+ i -= size
+ i = encodeVarintGenerated(dAtA, i, uint64(size))
}
- i -= len(m.Name)
- copy(dAtA[i:], m.Name)
- i = encodeVarintGenerated(dAtA, i, uint64(len(m.Name)))
- i--
- dAtA[i] = 0x12
- i -= len(m.Namespace)
- copy(dAtA[i:], m.Namespace)
- i = encodeVarintGenerated(dAtA, i, uint64(len(m.Namespace)))
i--
dAtA[i] = 0xa
return len(dAtA) - i, nil
}
-func (m *TypeChecking) Marshal() (dAtA []byte, err error) {
+func (m *MutatingWebhookConfigurationList) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBuffer(dAtA[:size])
@@ -774,20 +863,20 @@ func (m *TypeChecking) Marshal() (dAtA []byte, err error) {
return dAtA[:n], nil
}
-func (m *TypeChecking) MarshalTo(dAtA []byte) (int, error) {
+func (m *MutatingWebhookConfigurationList) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
-func (m *TypeChecking) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+func (m *MutatingWebhookConfigurationList) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
- if len(m.ExpressionWarnings) > 0 {
- for iNdEx := len(m.ExpressionWarnings) - 1; iNdEx >= 0; iNdEx-- {
+ if len(m.Items) > 0 {
+ for iNdEx := len(m.Items) - 1; iNdEx >= 0; iNdEx-- {
{
- size, err := m.ExpressionWarnings[iNdEx].MarshalToSizedBuffer(dAtA[:i])
+ size, err := m.Items[iNdEx].MarshalToSizedBuffer(dAtA[:i])
if err != nil {
return 0, err
}
@@ -795,13 +884,23 @@ func (m *TypeChecking) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i = encodeVarintGenerated(dAtA, i, uint64(size))
}
i--
- dAtA[i] = 0xa
+ dAtA[i] = 0x12
+ }
+ }
+ {
+ size, err := m.ListMeta.MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
}
+ i -= size
+ i = encodeVarintGenerated(dAtA, i, uint64(size))
}
+ i--
+ dAtA[i] = 0xa
return len(dAtA) - i, nil
}
-func (m *ValidatingAdmissionPolicy) Marshal() (dAtA []byte, err error) {
+func (m *Mutation) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBuffer(dAtA[:size])
@@ -811,50 +910,49 @@ func (m *ValidatingAdmissionPolicy) Marshal() (dAtA []byte, err error) {
return dAtA[:n], nil
}
-func (m *ValidatingAdmissionPolicy) MarshalTo(dAtA []byte) (int, error) {
+func (m *Mutation) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
-func (m *ValidatingAdmissionPolicy) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+func (m *Mutation) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
- {
- size, err := m.Status.MarshalToSizedBuffer(dAtA[:i])
- if err != nil {
- return 0, err
+ if m.JSONPatch != nil {
+ {
+ size, err := m.JSONPatch.MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
+ }
+ i -= size
+ i = encodeVarintGenerated(dAtA, i, uint64(size))
}
- i -= size
- i = encodeVarintGenerated(dAtA, i, uint64(size))
+ i--
+ dAtA[i] = 0x22
}
- i--
- dAtA[i] = 0x1a
- {
- size, err := m.Spec.MarshalToSizedBuffer(dAtA[:i])
- if err != nil {
- return 0, err
+ if m.ApplyConfiguration != nil {
+ {
+ size, err := m.ApplyConfiguration.MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
+ }
+ i -= size
+ i = encodeVarintGenerated(dAtA, i, uint64(size))
}
- i -= size
- i = encodeVarintGenerated(dAtA, i, uint64(size))
+ i--
+ dAtA[i] = 0x1a
}
+ i -= len(m.PatchType)
+ copy(dAtA[i:], m.PatchType)
+ i = encodeVarintGenerated(dAtA, i, uint64(len(m.PatchType)))
i--
dAtA[i] = 0x12
- {
- size, err := m.ObjectMeta.MarshalToSizedBuffer(dAtA[:i])
- if err != nil {
- return 0, err
- }
- i -= size
- i = encodeVarintGenerated(dAtA, i, uint64(size))
- }
- i--
- dAtA[i] = 0xa
return len(dAtA) - i, nil
}
-func (m *ValidatingAdmissionPolicyBinding) Marshal() (dAtA []byte, err error) {
+func (m *NamedRuleWithOperations) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBuffer(dAtA[:size])
@@ -864,18 +962,18 @@ func (m *ValidatingAdmissionPolicyBinding) Marshal() (dAtA []byte, err error) {
return dAtA[:n], nil
}
-func (m *ValidatingAdmissionPolicyBinding) MarshalTo(dAtA []byte) (int, error) {
+func (m *NamedRuleWithOperations) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
-func (m *ValidatingAdmissionPolicyBinding) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+func (m *NamedRuleWithOperations) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
{
- size, err := m.Spec.MarshalToSizedBuffer(dAtA[:i])
+ size, err := m.RuleWithOperations.MarshalToSizedBuffer(dAtA[:i])
if err != nil {
return 0, err
}
@@ -884,20 +982,19 @@ func (m *ValidatingAdmissionPolicyBinding) MarshalToSizedBuffer(dAtA []byte) (in
}
i--
dAtA[i] = 0x12
- {
- size, err := m.ObjectMeta.MarshalToSizedBuffer(dAtA[:i])
- if err != nil {
- return 0, err
+ if len(m.ResourceNames) > 0 {
+ for iNdEx := len(m.ResourceNames) - 1; iNdEx >= 0; iNdEx-- {
+ i -= len(m.ResourceNames[iNdEx])
+ copy(dAtA[i:], m.ResourceNames[iNdEx])
+ i = encodeVarintGenerated(dAtA, i, uint64(len(m.ResourceNames[iNdEx])))
+ i--
+ dAtA[i] = 0xa
}
- i -= size
- i = encodeVarintGenerated(dAtA, i, uint64(size))
}
- i--
- dAtA[i] = 0xa
return len(dAtA) - i, nil
}
-func (m *ValidatingAdmissionPolicyBindingList) Marshal() (dAtA []byte, err error) {
+func (m *ParamKind) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBuffer(dAtA[:size])
@@ -907,44 +1004,30 @@ func (m *ValidatingAdmissionPolicyBindingList) Marshal() (dAtA []byte, err error
return dAtA[:n], nil
}
-func (m *ValidatingAdmissionPolicyBindingList) MarshalTo(dAtA []byte) (int, error) {
+func (m *ParamKind) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
-func (m *ValidatingAdmissionPolicyBindingList) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+func (m *ParamKind) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
- if len(m.Items) > 0 {
- for iNdEx := len(m.Items) - 1; iNdEx >= 0; iNdEx-- {
- {
- size, err := m.Items[iNdEx].MarshalToSizedBuffer(dAtA[:i])
- if err != nil {
- return 0, err
- }
- i -= size
- i = encodeVarintGenerated(dAtA, i, uint64(size))
- }
- i--
- dAtA[i] = 0x12
- }
- }
- {
- size, err := m.ListMeta.MarshalToSizedBuffer(dAtA[:i])
- if err != nil {
- return 0, err
- }
- i -= size
- i = encodeVarintGenerated(dAtA, i, uint64(size))
- }
+ i -= len(m.Kind)
+ copy(dAtA[i:], m.Kind)
+ i = encodeVarintGenerated(dAtA, i, uint64(len(m.Kind)))
+ i--
+ dAtA[i] = 0x12
+ i -= len(m.APIVersion)
+ copy(dAtA[i:], m.APIVersion)
+ i = encodeVarintGenerated(dAtA, i, uint64(len(m.APIVersion)))
i--
dAtA[i] = 0xa
return len(dAtA) - i, nil
}
-func (m *ValidatingAdmissionPolicyBindingSpec) Marshal() (dAtA []byte, err error) {
+func (m *ParamRef) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBuffer(dAtA[:size])
@@ -954,40 +1037,26 @@ func (m *ValidatingAdmissionPolicyBindingSpec) Marshal() (dAtA []byte, err error
return dAtA[:n], nil
}
-func (m *ValidatingAdmissionPolicyBindingSpec) MarshalTo(dAtA []byte) (int, error) {
+func (m *ParamRef) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
-func (m *ValidatingAdmissionPolicyBindingSpec) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+func (m *ParamRef) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
- if len(m.ValidationActions) > 0 {
- for iNdEx := len(m.ValidationActions) - 1; iNdEx >= 0; iNdEx-- {
- i -= len(m.ValidationActions[iNdEx])
- copy(dAtA[i:], m.ValidationActions[iNdEx])
- i = encodeVarintGenerated(dAtA, i, uint64(len(m.ValidationActions[iNdEx])))
- i--
- dAtA[i] = 0x22
- }
- }
- if m.MatchResources != nil {
- {
- size, err := m.MatchResources.MarshalToSizedBuffer(dAtA[:i])
- if err != nil {
- return 0, err
- }
- i -= size
- i = encodeVarintGenerated(dAtA, i, uint64(size))
- }
+ if m.ParameterNotFoundAction != nil {
+ i -= len(*m.ParameterNotFoundAction)
+ copy(dAtA[i:], *m.ParameterNotFoundAction)
+ i = encodeVarintGenerated(dAtA, i, uint64(len(*m.ParameterNotFoundAction)))
i--
- dAtA[i] = 0x1a
+ dAtA[i] = 0x22
}
- if m.ParamRef != nil {
+ if m.Selector != nil {
{
- size, err := m.ParamRef.MarshalToSizedBuffer(dAtA[:i])
+ size, err := m.Selector.MarshalToSizedBuffer(dAtA[:i])
if err != nil {
return 0, err
}
@@ -995,17 +1064,22 @@ func (m *ValidatingAdmissionPolicyBindingSpec) MarshalToSizedBuffer(dAtA []byte)
i = encodeVarintGenerated(dAtA, i, uint64(size))
}
i--
- dAtA[i] = 0x12
+ dAtA[i] = 0x1a
}
- i -= len(m.PolicyName)
- copy(dAtA[i:], m.PolicyName)
- i = encodeVarintGenerated(dAtA, i, uint64(len(m.PolicyName)))
+ i -= len(m.Namespace)
+ copy(dAtA[i:], m.Namespace)
+ i = encodeVarintGenerated(dAtA, i, uint64(len(m.Namespace)))
+ i--
+ dAtA[i] = 0x12
+ i -= len(m.Name)
+ copy(dAtA[i:], m.Name)
+ i = encodeVarintGenerated(dAtA, i, uint64(len(m.Name)))
i--
dAtA[i] = 0xa
return len(dAtA) - i, nil
}
-func (m *ValidatingAdmissionPolicyList) Marshal() (dAtA []byte, err error) {
+func (m *Rule) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBuffer(dAtA[:size])
@@ -1015,44 +1089,54 @@ func (m *ValidatingAdmissionPolicyList) Marshal() (dAtA []byte, err error) {
return dAtA[:n], nil
}
-func (m *ValidatingAdmissionPolicyList) MarshalTo(dAtA []byte) (int, error) {
+func (m *Rule) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
-func (m *ValidatingAdmissionPolicyList) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+func (m *Rule) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
- if len(m.Items) > 0 {
- for iNdEx := len(m.Items) - 1; iNdEx >= 0; iNdEx-- {
- {
- size, err := m.Items[iNdEx].MarshalToSizedBuffer(dAtA[:i])
- if err != nil {
- return 0, err
- }
- i -= size
- i = encodeVarintGenerated(dAtA, i, uint64(size))
- }
- i--
- dAtA[i] = 0x12
- }
- }
- {
- size, err := m.ListMeta.MarshalToSizedBuffer(dAtA[:i])
- if err != nil {
- return 0, err
+ if m.Scope != nil {
+ i -= len(*m.Scope)
+ copy(dAtA[i:], *m.Scope)
+ i = encodeVarintGenerated(dAtA, i, uint64(len(*m.Scope)))
+ i--
+ dAtA[i] = 0x22
+ }
+ if len(m.Resources) > 0 {
+ for iNdEx := len(m.Resources) - 1; iNdEx >= 0; iNdEx-- {
+ i -= len(m.Resources[iNdEx])
+ copy(dAtA[i:], m.Resources[iNdEx])
+ i = encodeVarintGenerated(dAtA, i, uint64(len(m.Resources[iNdEx])))
+ i--
+ dAtA[i] = 0x1a
+ }
+ }
+ if len(m.APIVersions) > 0 {
+ for iNdEx := len(m.APIVersions) - 1; iNdEx >= 0; iNdEx-- {
+ i -= len(m.APIVersions[iNdEx])
+ copy(dAtA[i:], m.APIVersions[iNdEx])
+ i = encodeVarintGenerated(dAtA, i, uint64(len(m.APIVersions[iNdEx])))
+ i--
+ dAtA[i] = 0x12
+ }
+ }
+ if len(m.APIGroups) > 0 {
+ for iNdEx := len(m.APIGroups) - 1; iNdEx >= 0; iNdEx-- {
+ i -= len(m.APIGroups[iNdEx])
+ copy(dAtA[i:], m.APIGroups[iNdEx])
+ i = encodeVarintGenerated(dAtA, i, uint64(len(m.APIGroups[iNdEx])))
+ i--
+ dAtA[i] = 0xa
}
- i -= size
- i = encodeVarintGenerated(dAtA, i, uint64(size))
}
- i--
- dAtA[i] = 0xa
return len(dAtA) - i, nil
}
-func (m *ValidatingAdmissionPolicySpec) Marshal() (dAtA []byte, err error) {
+func (m *RuleWithOperations) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBuffer(dAtA[:size])
@@ -1062,107 +1146,84 @@ func (m *ValidatingAdmissionPolicySpec) Marshal() (dAtA []byte, err error) {
return dAtA[:n], nil
}
-func (m *ValidatingAdmissionPolicySpec) MarshalTo(dAtA []byte) (int, error) {
+func (m *RuleWithOperations) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
-func (m *ValidatingAdmissionPolicySpec) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+func (m *RuleWithOperations) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
- if len(m.Variables) > 0 {
- for iNdEx := len(m.Variables) - 1; iNdEx >= 0; iNdEx-- {
- {
- size, err := m.Variables[iNdEx].MarshalToSizedBuffer(dAtA[:i])
- if err != nil {
- return 0, err
- }
- i -= size
- i = encodeVarintGenerated(dAtA, i, uint64(size))
- }
- i--
- dAtA[i] = 0x3a
- }
- }
- if len(m.MatchConditions) > 0 {
- for iNdEx := len(m.MatchConditions) - 1; iNdEx >= 0; iNdEx-- {
- {
- size, err := m.MatchConditions[iNdEx].MarshalToSizedBuffer(dAtA[:i])
- if err != nil {
- return 0, err
- }
- i -= size
- i = encodeVarintGenerated(dAtA, i, uint64(size))
- }
- i--
- dAtA[i] = 0x32
+ {
+ size, err := m.Rule.MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
}
+ i -= size
+ i = encodeVarintGenerated(dAtA, i, uint64(size))
}
- if len(m.AuditAnnotations) > 0 {
- for iNdEx := len(m.AuditAnnotations) - 1; iNdEx >= 0; iNdEx-- {
- {
- size, err := m.AuditAnnotations[iNdEx].MarshalToSizedBuffer(dAtA[:i])
- if err != nil {
- return 0, err
- }
- i -= size
- i = encodeVarintGenerated(dAtA, i, uint64(size))
- }
+ i--
+ dAtA[i] = 0x12
+ if len(m.Operations) > 0 {
+ for iNdEx := len(m.Operations) - 1; iNdEx >= 0; iNdEx-- {
+ i -= len(m.Operations[iNdEx])
+ copy(dAtA[i:], m.Operations[iNdEx])
+ i = encodeVarintGenerated(dAtA, i, uint64(len(m.Operations[iNdEx])))
i--
- dAtA[i] = 0x2a
+ dAtA[i] = 0xa
}
}
- if m.FailurePolicy != nil {
- i -= len(*m.FailurePolicy)
- copy(dAtA[i:], *m.FailurePolicy)
- i = encodeVarintGenerated(dAtA, i, uint64(len(*m.FailurePolicy)))
- i--
- dAtA[i] = 0x22
- }
- if len(m.Validations) > 0 {
- for iNdEx := len(m.Validations) - 1; iNdEx >= 0; iNdEx-- {
- {
- size, err := m.Validations[iNdEx].MarshalToSizedBuffer(dAtA[:i])
- if err != nil {
- return 0, err
- }
- i -= size
- i = encodeVarintGenerated(dAtA, i, uint64(size))
- }
- i--
- dAtA[i] = 0x1a
- }
+ return len(dAtA) - i, nil
+}
+
+func (m *ServiceReference) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
}
- if m.MatchConstraints != nil {
- {
- size, err := m.MatchConstraints.MarshalToSizedBuffer(dAtA[:i])
- if err != nil {
- return 0, err
- }
- i -= size
- i = encodeVarintGenerated(dAtA, i, uint64(size))
- }
+ return dAtA[:n], nil
+}
+
+func (m *ServiceReference) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *ServiceReference) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
+ var l int
+ _ = l
+ if m.Port != nil {
+ i = encodeVarintGenerated(dAtA, i, uint64(*m.Port))
i--
- dAtA[i] = 0x12
+ dAtA[i] = 0x20
}
- if m.ParamKind != nil {
- {
- size, err := m.ParamKind.MarshalToSizedBuffer(dAtA[:i])
- if err != nil {
- return 0, err
- }
- i -= size
- i = encodeVarintGenerated(dAtA, i, uint64(size))
- }
+ if m.Path != nil {
+ i -= len(*m.Path)
+ copy(dAtA[i:], *m.Path)
+ i = encodeVarintGenerated(dAtA, i, uint64(len(*m.Path)))
i--
- dAtA[i] = 0xa
+ dAtA[i] = 0x1a
}
+ i -= len(m.Name)
+ copy(dAtA[i:], m.Name)
+ i = encodeVarintGenerated(dAtA, i, uint64(len(m.Name)))
+ i--
+ dAtA[i] = 0x12
+ i -= len(m.Namespace)
+ copy(dAtA[i:], m.Namespace)
+ i = encodeVarintGenerated(dAtA, i, uint64(len(m.Namespace)))
+ i--
+ dAtA[i] = 0xa
return len(dAtA) - i, nil
}
-func (m *ValidatingAdmissionPolicyStatus) Marshal() (dAtA []byte, err error) {
+func (m *TypeChecking) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBuffer(dAtA[:size])
@@ -1172,20 +1233,20 @@ func (m *ValidatingAdmissionPolicyStatus) Marshal() (dAtA []byte, err error) {
return dAtA[:n], nil
}
-func (m *ValidatingAdmissionPolicyStatus) MarshalTo(dAtA []byte) (int, error) {
+func (m *TypeChecking) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
-func (m *ValidatingAdmissionPolicyStatus) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+func (m *TypeChecking) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
- if len(m.Conditions) > 0 {
- for iNdEx := len(m.Conditions) - 1; iNdEx >= 0; iNdEx-- {
+ if len(m.ExpressionWarnings) > 0 {
+ for iNdEx := len(m.ExpressionWarnings) - 1; iNdEx >= 0; iNdEx-- {
{
- size, err := m.Conditions[iNdEx].MarshalToSizedBuffer(dAtA[:i])
+ size, err := m.ExpressionWarnings[iNdEx].MarshalToSizedBuffer(dAtA[:i])
if err != nil {
return 0, err
}
@@ -1193,28 +1254,13 @@ func (m *ValidatingAdmissionPolicyStatus) MarshalToSizedBuffer(dAtA []byte) (int
i = encodeVarintGenerated(dAtA, i, uint64(size))
}
i--
- dAtA[i] = 0x1a
- }
- }
- if m.TypeChecking != nil {
- {
- size, err := m.TypeChecking.MarshalToSizedBuffer(dAtA[:i])
- if err != nil {
- return 0, err
- }
- i -= size
- i = encodeVarintGenerated(dAtA, i, uint64(size))
+ dAtA[i] = 0xa
}
- i--
- dAtA[i] = 0x12
}
- i = encodeVarintGenerated(dAtA, i, uint64(m.ObservedGeneration))
- i--
- dAtA[i] = 0x8
return len(dAtA) - i, nil
}
-func (m *ValidatingWebhook) Marshal() (dAtA []byte, err error) {
+func (m *ValidatingAdmissionPolicy) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBuffer(dAtA[:size])
@@ -1224,105 +1270,38 @@ func (m *ValidatingWebhook) Marshal() (dAtA []byte, err error) {
return dAtA[:n], nil
}
-func (m *ValidatingWebhook) MarshalTo(dAtA []byte) (int, error) {
+func (m *ValidatingAdmissionPolicy) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
-func (m *ValidatingWebhook) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+func (m *ValidatingAdmissionPolicy) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
- if len(m.MatchConditions) > 0 {
- for iNdEx := len(m.MatchConditions) - 1; iNdEx >= 0; iNdEx-- {
- {
- size, err := m.MatchConditions[iNdEx].MarshalToSizedBuffer(dAtA[:i])
- if err != nil {
- return 0, err
- }
- i -= size
- i = encodeVarintGenerated(dAtA, i, uint64(size))
- }
- i--
- dAtA[i] = 0x5a
+ {
+ size, err := m.Status.MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
}
+ i -= size
+ i = encodeVarintGenerated(dAtA, i, uint64(size))
}
- if m.ObjectSelector != nil {
- {
- size, err := m.ObjectSelector.MarshalToSizedBuffer(dAtA[:i])
- if err != nil {
- return 0, err
- }
- i -= size
- i = encodeVarintGenerated(dAtA, i, uint64(size))
- }
- i--
- dAtA[i] = 0x52
- }
- if m.MatchPolicy != nil {
- i -= len(*m.MatchPolicy)
- copy(dAtA[i:], *m.MatchPolicy)
- i = encodeVarintGenerated(dAtA, i, uint64(len(*m.MatchPolicy)))
- i--
- dAtA[i] = 0x4a
- }
- if len(m.AdmissionReviewVersions) > 0 {
- for iNdEx := len(m.AdmissionReviewVersions) - 1; iNdEx >= 0; iNdEx-- {
- i -= len(m.AdmissionReviewVersions[iNdEx])
- copy(dAtA[i:], m.AdmissionReviewVersions[iNdEx])
- i = encodeVarintGenerated(dAtA, i, uint64(len(m.AdmissionReviewVersions[iNdEx])))
- i--
- dAtA[i] = 0x42
- }
- }
- if m.TimeoutSeconds != nil {
- i = encodeVarintGenerated(dAtA, i, uint64(*m.TimeoutSeconds))
- i--
- dAtA[i] = 0x38
- }
- if m.SideEffects != nil {
- i -= len(*m.SideEffects)
- copy(dAtA[i:], *m.SideEffects)
- i = encodeVarintGenerated(dAtA, i, uint64(len(*m.SideEffects)))
- i--
- dAtA[i] = 0x32
- }
- if m.NamespaceSelector != nil {
- {
- size, err := m.NamespaceSelector.MarshalToSizedBuffer(dAtA[:i])
- if err != nil {
- return 0, err
- }
- i -= size
- i = encodeVarintGenerated(dAtA, i, uint64(size))
- }
- i--
- dAtA[i] = 0x2a
- }
- if m.FailurePolicy != nil {
- i -= len(*m.FailurePolicy)
- copy(dAtA[i:], *m.FailurePolicy)
- i = encodeVarintGenerated(dAtA, i, uint64(len(*m.FailurePolicy)))
- i--
- dAtA[i] = 0x22
- }
- if len(m.Rules) > 0 {
- for iNdEx := len(m.Rules) - 1; iNdEx >= 0; iNdEx-- {
- {
- size, err := m.Rules[iNdEx].MarshalToSizedBuffer(dAtA[:i])
- if err != nil {
- return 0, err
- }
- i -= size
- i = encodeVarintGenerated(dAtA, i, uint64(size))
- }
- i--
- dAtA[i] = 0x1a
+ i--
+ dAtA[i] = 0x1a
+ {
+ size, err := m.Spec.MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
}
+ i -= size
+ i = encodeVarintGenerated(dAtA, i, uint64(size))
}
+ i--
+ dAtA[i] = 0x12
{
- size, err := m.ClientConfig.MarshalToSizedBuffer(dAtA[:i])
+ size, err := m.ObjectMeta.MarshalToSizedBuffer(dAtA[:i])
if err != nil {
return 0, err
}
@@ -1330,16 +1309,11 @@ func (m *ValidatingWebhook) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i = encodeVarintGenerated(dAtA, i, uint64(size))
}
i--
- dAtA[i] = 0x12
- i -= len(m.Name)
- copy(dAtA[i:], m.Name)
- i = encodeVarintGenerated(dAtA, i, uint64(len(m.Name)))
- i--
dAtA[i] = 0xa
return len(dAtA) - i, nil
}
-func (m *ValidatingWebhookConfiguration) Marshal() (dAtA []byte, err error) {
+func (m *ValidatingAdmissionPolicyBinding) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBuffer(dAtA[:size])
@@ -1349,30 +1323,26 @@ func (m *ValidatingWebhookConfiguration) Marshal() (dAtA []byte, err error) {
return dAtA[:n], nil
}
-func (m *ValidatingWebhookConfiguration) MarshalTo(dAtA []byte) (int, error) {
+func (m *ValidatingAdmissionPolicyBinding) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
-func (m *ValidatingWebhookConfiguration) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+func (m *ValidatingAdmissionPolicyBinding) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
- if len(m.Webhooks) > 0 {
- for iNdEx := len(m.Webhooks) - 1; iNdEx >= 0; iNdEx-- {
- {
- size, err := m.Webhooks[iNdEx].MarshalToSizedBuffer(dAtA[:i])
- if err != nil {
- return 0, err
- }
- i -= size
- i = encodeVarintGenerated(dAtA, i, uint64(size))
- }
- i--
- dAtA[i] = 0x12
+ {
+ size, err := m.Spec.MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
}
+ i -= size
+ i = encodeVarintGenerated(dAtA, i, uint64(size))
}
+ i--
+ dAtA[i] = 0x12
{
size, err := m.ObjectMeta.MarshalToSizedBuffer(dAtA[:i])
if err != nil {
@@ -1386,7 +1356,7 @@ func (m *ValidatingWebhookConfiguration) MarshalToSizedBuffer(dAtA []byte) (int,
return len(dAtA) - i, nil
}
-func (m *ValidatingWebhookConfigurationList) Marshal() (dAtA []byte, err error) {
+func (m *ValidatingAdmissionPolicyBindingList) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBuffer(dAtA[:size])
@@ -1396,12 +1366,12 @@ func (m *ValidatingWebhookConfigurationList) Marshal() (dAtA []byte, err error)
return dAtA[:n], nil
}
-func (m *ValidatingWebhookConfigurationList) MarshalTo(dAtA []byte) (int, error) {
+func (m *ValidatingAdmissionPolicyBindingList) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
-func (m *ValidatingWebhookConfigurationList) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+func (m *ValidatingAdmissionPolicyBindingList) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
@@ -1433,7 +1403,7 @@ func (m *ValidatingWebhookConfigurationList) MarshalToSizedBuffer(dAtA []byte) (
return len(dAtA) - i, nil
}
-func (m *Validation) Marshal() (dAtA []byte, err error) {
+func (m *ValidatingAdmissionPolicyBindingSpec) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBuffer(dAtA[:size])
@@ -1443,42 +1413,58 @@ func (m *Validation) Marshal() (dAtA []byte, err error) {
return dAtA[:n], nil
}
-func (m *Validation) MarshalTo(dAtA []byte) (int, error) {
+func (m *ValidatingAdmissionPolicyBindingSpec) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
-func (m *Validation) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+func (m *ValidatingAdmissionPolicyBindingSpec) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
- i -= len(m.MessageExpression)
- copy(dAtA[i:], m.MessageExpression)
- i = encodeVarintGenerated(dAtA, i, uint64(len(m.MessageExpression)))
- i--
- dAtA[i] = 0x22
- if m.Reason != nil {
- i -= len(*m.Reason)
- copy(dAtA[i:], *m.Reason)
- i = encodeVarintGenerated(dAtA, i, uint64(len(*m.Reason)))
+ if len(m.ValidationActions) > 0 {
+ for iNdEx := len(m.ValidationActions) - 1; iNdEx >= 0; iNdEx-- {
+ i -= len(m.ValidationActions[iNdEx])
+ copy(dAtA[i:], m.ValidationActions[iNdEx])
+ i = encodeVarintGenerated(dAtA, i, uint64(len(m.ValidationActions[iNdEx])))
+ i--
+ dAtA[i] = 0x22
+ }
+ }
+ if m.MatchResources != nil {
+ {
+ size, err := m.MatchResources.MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
+ }
+ i -= size
+ i = encodeVarintGenerated(dAtA, i, uint64(size))
+ }
i--
dAtA[i] = 0x1a
}
- i -= len(m.Message)
- copy(dAtA[i:], m.Message)
- i = encodeVarintGenerated(dAtA, i, uint64(len(m.Message)))
- i--
- dAtA[i] = 0x12
- i -= len(m.Expression)
- copy(dAtA[i:], m.Expression)
- i = encodeVarintGenerated(dAtA, i, uint64(len(m.Expression)))
+ if m.ParamRef != nil {
+ {
+ size, err := m.ParamRef.MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
+ }
+ i -= size
+ i = encodeVarintGenerated(dAtA, i, uint64(size))
+ }
+ i--
+ dAtA[i] = 0x12
+ }
+ i -= len(m.PolicyName)
+ copy(dAtA[i:], m.PolicyName)
+ i = encodeVarintGenerated(dAtA, i, uint64(len(m.PolicyName)))
i--
dAtA[i] = 0xa
return len(dAtA) - i, nil
}
-func (m *Variable) Marshal() (dAtA []byte, err error) {
+func (m *ValidatingAdmissionPolicyList) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBuffer(dAtA[:size])
@@ -1488,30 +1474,44 @@ func (m *Variable) Marshal() (dAtA []byte, err error) {
return dAtA[:n], nil
}
-func (m *Variable) MarshalTo(dAtA []byte) (int, error) {
+func (m *ValidatingAdmissionPolicyList) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
-func (m *Variable) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+func (m *ValidatingAdmissionPolicyList) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
- i -= len(m.Expression)
- copy(dAtA[i:], m.Expression)
- i = encodeVarintGenerated(dAtA, i, uint64(len(m.Expression)))
- i--
- dAtA[i] = 0x12
- i -= len(m.Name)
- copy(dAtA[i:], m.Name)
- i = encodeVarintGenerated(dAtA, i, uint64(len(m.Name)))
+ if len(m.Items) > 0 {
+ for iNdEx := len(m.Items) - 1; iNdEx >= 0; iNdEx-- {
+ {
+ size, err := m.Items[iNdEx].MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
+ }
+ i -= size
+ i = encodeVarintGenerated(dAtA, i, uint64(size))
+ }
+ i--
+ dAtA[i] = 0x12
+ }
+ }
+ {
+ size, err := m.ListMeta.MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
+ }
+ i -= size
+ i = encodeVarintGenerated(dAtA, i, uint64(size))
+ }
i--
dAtA[i] = 0xa
return len(dAtA) - i, nil
}
-func (m *WebhookClientConfig) Marshal() (dAtA []byte, err error) {
+func (m *ValidatingAdmissionPolicySpec) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBuffer(dAtA[:size])
@@ -1521,355 +1521,610 @@ func (m *WebhookClientConfig) Marshal() (dAtA []byte, err error) {
return dAtA[:n], nil
}
-func (m *WebhookClientConfig) MarshalTo(dAtA []byte) (int, error) {
+func (m *ValidatingAdmissionPolicySpec) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
-func (m *WebhookClientConfig) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+func (m *ValidatingAdmissionPolicySpec) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
- if m.URL != nil {
- i -= len(*m.URL)
- copy(dAtA[i:], *m.URL)
- i = encodeVarintGenerated(dAtA, i, uint64(len(*m.URL)))
- i--
- dAtA[i] = 0x1a
+ if len(m.Variables) > 0 {
+ for iNdEx := len(m.Variables) - 1; iNdEx >= 0; iNdEx-- {
+ {
+ size, err := m.Variables[iNdEx].MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
+ }
+ i -= size
+ i = encodeVarintGenerated(dAtA, i, uint64(size))
+ }
+ i--
+ dAtA[i] = 0x3a
+ }
}
- if m.CABundle != nil {
- i -= len(m.CABundle)
- copy(dAtA[i:], m.CABundle)
- i = encodeVarintGenerated(dAtA, i, uint64(len(m.CABundle)))
- i--
- dAtA[i] = 0x12
+ if len(m.MatchConditions) > 0 {
+ for iNdEx := len(m.MatchConditions) - 1; iNdEx >= 0; iNdEx-- {
+ {
+ size, err := m.MatchConditions[iNdEx].MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
+ }
+ i -= size
+ i = encodeVarintGenerated(dAtA, i, uint64(size))
+ }
+ i--
+ dAtA[i] = 0x32
+ }
}
- if m.Service != nil {
- {
- size, err := m.Service.MarshalToSizedBuffer(dAtA[:i])
- if err != nil {
- return 0, err
+ if len(m.AuditAnnotations) > 0 {
+ for iNdEx := len(m.AuditAnnotations) - 1; iNdEx >= 0; iNdEx-- {
+ {
+ size, err := m.AuditAnnotations[iNdEx].MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
+ }
+ i -= size
+ i = encodeVarintGenerated(dAtA, i, uint64(size))
}
- i -= size
- i = encodeVarintGenerated(dAtA, i, uint64(size))
+ i--
+ dAtA[i] = 0x2a
}
+ }
+ if m.FailurePolicy != nil {
+ i -= len(*m.FailurePolicy)
+ copy(dAtA[i:], *m.FailurePolicy)
+ i = encodeVarintGenerated(dAtA, i, uint64(len(*m.FailurePolicy)))
i--
- dAtA[i] = 0xa
+ dAtA[i] = 0x22
}
- return len(dAtA) - i, nil
-}
-
-func encodeVarintGenerated(dAtA []byte, offset int, v uint64) int {
- offset -= sovGenerated(v)
- base := offset
- for v >= 1<<7 {
- dAtA[offset] = uint8(v&0x7f | 0x80)
- v >>= 7
- offset++
+ if len(m.Validations) > 0 {
+ for iNdEx := len(m.Validations) - 1; iNdEx >= 0; iNdEx-- {
+ {
+ size, err := m.Validations[iNdEx].MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
+ }
+ i -= size
+ i = encodeVarintGenerated(dAtA, i, uint64(size))
+ }
+ i--
+ dAtA[i] = 0x1a
+ }
}
- dAtA[offset] = uint8(v)
- return base
-}
-func (m *AuditAnnotation) Size() (n int) {
- if m == nil {
- return 0
+ if m.MatchConstraints != nil {
+ {
+ size, err := m.MatchConstraints.MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
+ }
+ i -= size
+ i = encodeVarintGenerated(dAtA, i, uint64(size))
+ }
+ i--
+ dAtA[i] = 0x12
}
- var l int
- _ = l
- l = len(m.Key)
- n += 1 + l + sovGenerated(uint64(l))
- l = len(m.ValueExpression)
- n += 1 + l + sovGenerated(uint64(l))
- return n
+ if m.ParamKind != nil {
+ {
+ size, err := m.ParamKind.MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
+ }
+ i -= size
+ i = encodeVarintGenerated(dAtA, i, uint64(size))
+ }
+ i--
+ dAtA[i] = 0xa
+ }
+ return len(dAtA) - i, nil
}
-func (m *ExpressionWarning) Size() (n int) {
- if m == nil {
- return 0
+func (m *ValidatingAdmissionPolicyStatus) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
}
- var l int
- _ = l
- l = len(m.FieldRef)
- n += 1 + l + sovGenerated(uint64(l))
- l = len(m.Warning)
- n += 1 + l + sovGenerated(uint64(l))
- return n
+ return dAtA[:n], nil
}
-func (m *MatchCondition) Size() (n int) {
- if m == nil {
- return 0
- }
- var l int
- _ = l
- l = len(m.Name)
- n += 1 + l + sovGenerated(uint64(l))
- l = len(m.Expression)
- n += 1 + l + sovGenerated(uint64(l))
- return n
+func (m *ValidatingAdmissionPolicyStatus) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
}
-func (m *MatchResources) Size() (n int) {
- if m == nil {
- return 0
- }
+func (m *ValidatingAdmissionPolicyStatus) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
var l int
_ = l
- if m.NamespaceSelector != nil {
- l = m.NamespaceSelector.Size()
- n += 1 + l + sovGenerated(uint64(l))
- }
- if m.ObjectSelector != nil {
- l = m.ObjectSelector.Size()
- n += 1 + l + sovGenerated(uint64(l))
- }
- if len(m.ResourceRules) > 0 {
- for _, e := range m.ResourceRules {
- l = e.Size()
- n += 1 + l + sovGenerated(uint64(l))
+ if len(m.Conditions) > 0 {
+ for iNdEx := len(m.Conditions) - 1; iNdEx >= 0; iNdEx-- {
+ {
+ size, err := m.Conditions[iNdEx].MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
+ }
+ i -= size
+ i = encodeVarintGenerated(dAtA, i, uint64(size))
+ }
+ i--
+ dAtA[i] = 0x1a
}
}
- if len(m.ExcludeResourceRules) > 0 {
- for _, e := range m.ExcludeResourceRules {
- l = e.Size()
- n += 1 + l + sovGenerated(uint64(l))
+ if m.TypeChecking != nil {
+ {
+ size, err := m.TypeChecking.MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
+ }
+ i -= size
+ i = encodeVarintGenerated(dAtA, i, uint64(size))
}
+ i--
+ dAtA[i] = 0x12
}
- if m.MatchPolicy != nil {
- l = len(*m.MatchPolicy)
- n += 1 + l + sovGenerated(uint64(l))
- }
- return n
+ i = encodeVarintGenerated(dAtA, i, uint64(m.ObservedGeneration))
+ i--
+ dAtA[i] = 0x8
+ return len(dAtA) - i, nil
}
-func (m *MutatingWebhook) Size() (n int) {
- if m == nil {
- return 0
+func (m *ValidatingWebhook) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
}
+ return dAtA[:n], nil
+}
+
+func (m *ValidatingWebhook) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *ValidatingWebhook) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
var l int
_ = l
- l = len(m.Name)
- n += 1 + l + sovGenerated(uint64(l))
- l = m.ClientConfig.Size()
- n += 1 + l + sovGenerated(uint64(l))
- if len(m.Rules) > 0 {
- for _, e := range m.Rules {
- l = e.Size()
- n += 1 + l + sovGenerated(uint64(l))
+ if len(m.MatchConditions) > 0 {
+ for iNdEx := len(m.MatchConditions) - 1; iNdEx >= 0; iNdEx-- {
+ {
+ size, err := m.MatchConditions[iNdEx].MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
+ }
+ i -= size
+ i = encodeVarintGenerated(dAtA, i, uint64(size))
+ }
+ i--
+ dAtA[i] = 0x5a
}
}
- if m.FailurePolicy != nil {
- l = len(*m.FailurePolicy)
- n += 1 + l + sovGenerated(uint64(l))
- }
- if m.NamespaceSelector != nil {
- l = m.NamespaceSelector.Size()
- n += 1 + l + sovGenerated(uint64(l))
- }
- if m.SideEffects != nil {
- l = len(*m.SideEffects)
- n += 1 + l + sovGenerated(uint64(l))
+ if m.ObjectSelector != nil {
+ {
+ size, err := m.ObjectSelector.MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
+ }
+ i -= size
+ i = encodeVarintGenerated(dAtA, i, uint64(size))
+ }
+ i--
+ dAtA[i] = 0x52
}
- if m.TimeoutSeconds != nil {
- n += 1 + sovGenerated(uint64(*m.TimeoutSeconds))
+ if m.MatchPolicy != nil {
+ i -= len(*m.MatchPolicy)
+ copy(dAtA[i:], *m.MatchPolicy)
+ i = encodeVarintGenerated(dAtA, i, uint64(len(*m.MatchPolicy)))
+ i--
+ dAtA[i] = 0x4a
}
if len(m.AdmissionReviewVersions) > 0 {
- for _, s := range m.AdmissionReviewVersions {
- l = len(s)
- n += 1 + l + sovGenerated(uint64(l))
+ for iNdEx := len(m.AdmissionReviewVersions) - 1; iNdEx >= 0; iNdEx-- {
+ i -= len(m.AdmissionReviewVersions[iNdEx])
+ copy(dAtA[i:], m.AdmissionReviewVersions[iNdEx])
+ i = encodeVarintGenerated(dAtA, i, uint64(len(m.AdmissionReviewVersions[iNdEx])))
+ i--
+ dAtA[i] = 0x42
}
}
- if m.MatchPolicy != nil {
- l = len(*m.MatchPolicy)
- n += 1 + l + sovGenerated(uint64(l))
- }
- if m.ReinvocationPolicy != nil {
- l = len(*m.ReinvocationPolicy)
- n += 1 + l + sovGenerated(uint64(l))
+ if m.TimeoutSeconds != nil {
+ i = encodeVarintGenerated(dAtA, i, uint64(*m.TimeoutSeconds))
+ i--
+ dAtA[i] = 0x38
}
- if m.ObjectSelector != nil {
- l = m.ObjectSelector.Size()
- n += 1 + l + sovGenerated(uint64(l))
+ if m.SideEffects != nil {
+ i -= len(*m.SideEffects)
+ copy(dAtA[i:], *m.SideEffects)
+ i = encodeVarintGenerated(dAtA, i, uint64(len(*m.SideEffects)))
+ i--
+ dAtA[i] = 0x32
}
- if len(m.MatchConditions) > 0 {
- for _, e := range m.MatchConditions {
- l = e.Size()
- n += 1 + l + sovGenerated(uint64(l))
+ if m.NamespaceSelector != nil {
+ {
+ size, err := m.NamespaceSelector.MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
+ }
+ i -= size
+ i = encodeVarintGenerated(dAtA, i, uint64(size))
}
+ i--
+ dAtA[i] = 0x2a
}
- return n
-}
-
-func (m *MutatingWebhookConfiguration) Size() (n int) {
- if m == nil {
- return 0
- }
- var l int
- _ = l
- l = m.ObjectMeta.Size()
- n += 1 + l + sovGenerated(uint64(l))
- if len(m.Webhooks) > 0 {
- for _, e := range m.Webhooks {
- l = e.Size()
- n += 1 + l + sovGenerated(uint64(l))
- }
+ if m.FailurePolicy != nil {
+ i -= len(*m.FailurePolicy)
+ copy(dAtA[i:], *m.FailurePolicy)
+ i = encodeVarintGenerated(dAtA, i, uint64(len(*m.FailurePolicy)))
+ i--
+ dAtA[i] = 0x22
}
- return n
-}
-
-func (m *MutatingWebhookConfigurationList) Size() (n int) {
- if m == nil {
- return 0
+ if len(m.Rules) > 0 {
+ for iNdEx := len(m.Rules) - 1; iNdEx >= 0; iNdEx-- {
+ {
+ size, err := m.Rules[iNdEx].MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
+ }
+ i -= size
+ i = encodeVarintGenerated(dAtA, i, uint64(size))
+ }
+ i--
+ dAtA[i] = 0x1a
+ }
}
- var l int
- _ = l
- l = m.ListMeta.Size()
- n += 1 + l + sovGenerated(uint64(l))
- if len(m.Items) > 0 {
- for _, e := range m.Items {
- l = e.Size()
- n += 1 + l + sovGenerated(uint64(l))
+ {
+ size, err := m.ClientConfig.MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
}
+ i -= size
+ i = encodeVarintGenerated(dAtA, i, uint64(size))
}
- return n
+ i--
+ dAtA[i] = 0x12
+ i -= len(m.Name)
+ copy(dAtA[i:], m.Name)
+ i = encodeVarintGenerated(dAtA, i, uint64(len(m.Name)))
+ i--
+ dAtA[i] = 0xa
+ return len(dAtA) - i, nil
}
-func (m *NamedRuleWithOperations) Size() (n int) {
- if m == nil {
- return 0
- }
- var l int
- _ = l
- if len(m.ResourceNames) > 0 {
- for _, s := range m.ResourceNames {
- l = len(s)
- n += 1 + l + sovGenerated(uint64(l))
- }
+func (m *ValidatingWebhookConfiguration) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
}
- l = m.RuleWithOperations.Size()
- n += 1 + l + sovGenerated(uint64(l))
- return n
+ return dAtA[:n], nil
}
-func (m *ParamKind) Size() (n int) {
- if m == nil {
- return 0
- }
- var l int
- _ = l
- l = len(m.APIVersion)
- n += 1 + l + sovGenerated(uint64(l))
- l = len(m.Kind)
- n += 1 + l + sovGenerated(uint64(l))
- return n
+func (m *ValidatingWebhookConfiguration) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
}
-func (m *ParamRef) Size() (n int) {
- if m == nil {
- return 0
- }
+func (m *ValidatingWebhookConfiguration) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
var l int
_ = l
- l = len(m.Name)
- n += 1 + l + sovGenerated(uint64(l))
- l = len(m.Namespace)
- n += 1 + l + sovGenerated(uint64(l))
- if m.Selector != nil {
- l = m.Selector.Size()
- n += 1 + l + sovGenerated(uint64(l))
+ if len(m.Webhooks) > 0 {
+ for iNdEx := len(m.Webhooks) - 1; iNdEx >= 0; iNdEx-- {
+ {
+ size, err := m.Webhooks[iNdEx].MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
+ }
+ i -= size
+ i = encodeVarintGenerated(dAtA, i, uint64(size))
+ }
+ i--
+ dAtA[i] = 0x12
+ }
}
- if m.ParameterNotFoundAction != nil {
- l = len(*m.ParameterNotFoundAction)
- n += 1 + l + sovGenerated(uint64(l))
+ {
+ size, err := m.ObjectMeta.MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
+ }
+ i -= size
+ i = encodeVarintGenerated(dAtA, i, uint64(size))
}
- return n
+ i--
+ dAtA[i] = 0xa
+ return len(dAtA) - i, nil
}
-func (m *Rule) Size() (n int) {
- if m == nil {
- return 0
+func (m *ValidatingWebhookConfigurationList) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
}
+ return dAtA[:n], nil
+}
+
+func (m *ValidatingWebhookConfigurationList) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *ValidatingWebhookConfigurationList) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
var l int
_ = l
- if len(m.APIGroups) > 0 {
- for _, s := range m.APIGroups {
- l = len(s)
- n += 1 + l + sovGenerated(uint64(l))
- }
- }
- if len(m.APIVersions) > 0 {
- for _, s := range m.APIVersions {
- l = len(s)
- n += 1 + l + sovGenerated(uint64(l))
+ if len(m.Items) > 0 {
+ for iNdEx := len(m.Items) - 1; iNdEx >= 0; iNdEx-- {
+ {
+ size, err := m.Items[iNdEx].MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
+ }
+ i -= size
+ i = encodeVarintGenerated(dAtA, i, uint64(size))
+ }
+ i--
+ dAtA[i] = 0x12
}
}
- if len(m.Resources) > 0 {
- for _, s := range m.Resources {
- l = len(s)
- n += 1 + l + sovGenerated(uint64(l))
+ {
+ size, err := m.ListMeta.MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
}
+ i -= size
+ i = encodeVarintGenerated(dAtA, i, uint64(size))
}
- if m.Scope != nil {
- l = len(*m.Scope)
- n += 1 + l + sovGenerated(uint64(l))
- }
- return n
+ i--
+ dAtA[i] = 0xa
+ return len(dAtA) - i, nil
}
-func (m *RuleWithOperations) Size() (n int) {
- if m == nil {
- return 0
- }
- var l int
- _ = l
- if len(m.Operations) > 0 {
- for _, s := range m.Operations {
- l = len(s)
- n += 1 + l + sovGenerated(uint64(l))
- }
+func (m *Validation) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
}
- l = m.Rule.Size()
- n += 1 + l + sovGenerated(uint64(l))
- return n
+ return dAtA[:n], nil
}
-func (m *ServiceReference) Size() (n int) {
- if m == nil {
- return 0
- }
- var l int
- _ = l
- l = len(m.Namespace)
- n += 1 + l + sovGenerated(uint64(l))
- l = len(m.Name)
- n += 1 + l + sovGenerated(uint64(l))
- if m.Path != nil {
- l = len(*m.Path)
- n += 1 + l + sovGenerated(uint64(l))
- }
- if m.Port != nil {
- n += 1 + sovGenerated(uint64(*m.Port))
- }
- return n
+func (m *Validation) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
}
-func (m *TypeChecking) Size() (n int) {
- if m == nil {
- return 0
- }
+func (m *Validation) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
var l int
_ = l
- if len(m.ExpressionWarnings) > 0 {
- for _, e := range m.ExpressionWarnings {
- l = e.Size()
- n += 1 + l + sovGenerated(uint64(l))
- }
- }
+ i -= len(m.MessageExpression)
+ copy(dAtA[i:], m.MessageExpression)
+ i = encodeVarintGenerated(dAtA, i, uint64(len(m.MessageExpression)))
+ i--
+ dAtA[i] = 0x22
+ if m.Reason != nil {
+ i -= len(*m.Reason)
+ copy(dAtA[i:], *m.Reason)
+ i = encodeVarintGenerated(dAtA, i, uint64(len(*m.Reason)))
+ i--
+ dAtA[i] = 0x1a
+ }
+ i -= len(m.Message)
+ copy(dAtA[i:], m.Message)
+ i = encodeVarintGenerated(dAtA, i, uint64(len(m.Message)))
+ i--
+ dAtA[i] = 0x12
+ i -= len(m.Expression)
+ copy(dAtA[i:], m.Expression)
+ i = encodeVarintGenerated(dAtA, i, uint64(len(m.Expression)))
+ i--
+ dAtA[i] = 0xa
+ return len(dAtA) - i, nil
+}
+
+func (m *Variable) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
+ }
+ return dAtA[:n], nil
+}
+
+func (m *Variable) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *Variable) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
+ var l int
+ _ = l
+ i -= len(m.Expression)
+ copy(dAtA[i:], m.Expression)
+ i = encodeVarintGenerated(dAtA, i, uint64(len(m.Expression)))
+ i--
+ dAtA[i] = 0x12
+ i -= len(m.Name)
+ copy(dAtA[i:], m.Name)
+ i = encodeVarintGenerated(dAtA, i, uint64(len(m.Name)))
+ i--
+ dAtA[i] = 0xa
+ return len(dAtA) - i, nil
+}
+
+func (m *WebhookClientConfig) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
+ }
+ return dAtA[:n], nil
+}
+
+func (m *WebhookClientConfig) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *WebhookClientConfig) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
+ var l int
+ _ = l
+ if m.URL != nil {
+ i -= len(*m.URL)
+ copy(dAtA[i:], *m.URL)
+ i = encodeVarintGenerated(dAtA, i, uint64(len(*m.URL)))
+ i--
+ dAtA[i] = 0x1a
+ }
+ if m.CABundle != nil {
+ i -= len(m.CABundle)
+ copy(dAtA[i:], m.CABundle)
+ i = encodeVarintGenerated(dAtA, i, uint64(len(m.CABundle)))
+ i--
+ dAtA[i] = 0x12
+ }
+ if m.Service != nil {
+ {
+ size, err := m.Service.MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
+ }
+ i -= size
+ i = encodeVarintGenerated(dAtA, i, uint64(size))
+ }
+ i--
+ dAtA[i] = 0xa
+ }
+ return len(dAtA) - i, nil
+}
+
+func encodeVarintGenerated(dAtA []byte, offset int, v uint64) int {
+ offset -= sovGenerated(v)
+ base := offset
+ for v >= 1<<7 {
+ dAtA[offset] = uint8(v&0x7f | 0x80)
+ v >>= 7
+ offset++
+ }
+ dAtA[offset] = uint8(v)
+ return base
+}
+func (m *ApplyConfiguration) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ l = len(m.Expression)
+ n += 1 + l + sovGenerated(uint64(l))
return n
}
-func (m *ValidatingAdmissionPolicy) Size() (n int) {
+func (m *AuditAnnotation) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ l = len(m.Key)
+ n += 1 + l + sovGenerated(uint64(l))
+ l = len(m.ValueExpression)
+ n += 1 + l + sovGenerated(uint64(l))
+ return n
+}
+
+func (m *ExpressionWarning) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ l = len(m.FieldRef)
+ n += 1 + l + sovGenerated(uint64(l))
+ l = len(m.Warning)
+ n += 1 + l + sovGenerated(uint64(l))
+ return n
+}
+
+func (m *JSONPatch) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ l = len(m.Expression)
+ n += 1 + l + sovGenerated(uint64(l))
+ return n
+}
+
+func (m *MatchCondition) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ l = len(m.Name)
+ n += 1 + l + sovGenerated(uint64(l))
+ l = len(m.Expression)
+ n += 1 + l + sovGenerated(uint64(l))
+ return n
+}
+
+func (m *MatchResources) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ if m.NamespaceSelector != nil {
+ l = m.NamespaceSelector.Size()
+ n += 1 + l + sovGenerated(uint64(l))
+ }
+ if m.ObjectSelector != nil {
+ l = m.ObjectSelector.Size()
+ n += 1 + l + sovGenerated(uint64(l))
+ }
+ if len(m.ResourceRules) > 0 {
+ for _, e := range m.ResourceRules {
+ l = e.Size()
+ n += 1 + l + sovGenerated(uint64(l))
+ }
+ }
+ if len(m.ExcludeResourceRules) > 0 {
+ for _, e := range m.ExcludeResourceRules {
+ l = e.Size()
+ n += 1 + l + sovGenerated(uint64(l))
+ }
+ }
+ if m.MatchPolicy != nil {
+ l = len(*m.MatchPolicy)
+ n += 1 + l + sovGenerated(uint64(l))
+ }
+ return n
+}
+
+func (m *MutatingAdmissionPolicy) Size() (n int) {
if m == nil {
return 0
}
@@ -1879,12 +2134,10 @@ func (m *ValidatingAdmissionPolicy) Size() (n int) {
n += 1 + l + sovGenerated(uint64(l))
l = m.Spec.Size()
n += 1 + l + sovGenerated(uint64(l))
- l = m.Status.Size()
- n += 1 + l + sovGenerated(uint64(l))
return n
}
-func (m *ValidatingAdmissionPolicyBinding) Size() (n int) {
+func (m *MutatingAdmissionPolicyBinding) Size() (n int) {
if m == nil {
return 0
}
@@ -1897,7 +2150,7 @@ func (m *ValidatingAdmissionPolicyBinding) Size() (n int) {
return n
}
-func (m *ValidatingAdmissionPolicyBindingList) Size() (n int) {
+func (m *MutatingAdmissionPolicyBindingList) Size() (n int) {
if m == nil {
return 0
}
@@ -1914,7 +2167,7 @@ func (m *ValidatingAdmissionPolicyBindingList) Size() (n int) {
return n
}
-func (m *ValidatingAdmissionPolicyBindingSpec) Size() (n int) {
+func (m *MutatingAdmissionPolicyBindingSpec) Size() (n int) {
if m == nil {
return 0
}
@@ -1930,16 +2183,10 @@ func (m *ValidatingAdmissionPolicyBindingSpec) Size() (n int) {
l = m.MatchResources.Size()
n += 1 + l + sovGenerated(uint64(l))
}
- if len(m.ValidationActions) > 0 {
- for _, s := range m.ValidationActions {
- l = len(s)
- n += 1 + l + sovGenerated(uint64(l))
- }
- }
return n
}
-func (m *ValidatingAdmissionPolicyList) Size() (n int) {
+func (m *MutatingAdmissionPolicyList) Size() (n int) {
if m == nil {
return 0
}
@@ -1956,7 +2203,7 @@ func (m *ValidatingAdmissionPolicyList) Size() (n int) {
return n
}
-func (m *ValidatingAdmissionPolicySpec) Size() (n int) {
+func (m *MutatingAdmissionPolicySpec) Size() (n int) {
if m == nil {
return 0
}
@@ -1970,58 +2217,34 @@ func (m *ValidatingAdmissionPolicySpec) Size() (n int) {
l = m.MatchConstraints.Size()
n += 1 + l + sovGenerated(uint64(l))
}
- if len(m.Validations) > 0 {
- for _, e := range m.Validations {
+ if len(m.Variables) > 0 {
+ for _, e := range m.Variables {
l = e.Size()
n += 1 + l + sovGenerated(uint64(l))
}
}
- if m.FailurePolicy != nil {
- l = len(*m.FailurePolicy)
- n += 1 + l + sovGenerated(uint64(l))
- }
- if len(m.AuditAnnotations) > 0 {
- for _, e := range m.AuditAnnotations {
+ if len(m.Mutations) > 0 {
+ for _, e := range m.Mutations {
l = e.Size()
n += 1 + l + sovGenerated(uint64(l))
}
}
+ if m.FailurePolicy != nil {
+ l = len(*m.FailurePolicy)
+ n += 1 + l + sovGenerated(uint64(l))
+ }
if len(m.MatchConditions) > 0 {
for _, e := range m.MatchConditions {
l = e.Size()
n += 1 + l + sovGenerated(uint64(l))
}
}
- if len(m.Variables) > 0 {
- for _, e := range m.Variables {
- l = e.Size()
- n += 1 + l + sovGenerated(uint64(l))
- }
- }
+ l = len(m.ReinvocationPolicy)
+ n += 1 + l + sovGenerated(uint64(l))
return n
}
-func (m *ValidatingAdmissionPolicyStatus) Size() (n int) {
- if m == nil {
- return 0
- }
- var l int
- _ = l
- n += 1 + sovGenerated(uint64(m.ObservedGeneration))
- if m.TypeChecking != nil {
- l = m.TypeChecking.Size()
- n += 1 + l + sovGenerated(uint64(l))
- }
- if len(m.Conditions) > 0 {
- for _, e := range m.Conditions {
- l = e.Size()
- n += 1 + l + sovGenerated(uint64(l))
- }
- }
- return n
-}
-
-func (m *ValidatingWebhook) Size() (n int) {
+func (m *MutatingWebhook) Size() (n int) {
if m == nil {
return 0
}
@@ -2062,6 +2285,10 @@ func (m *ValidatingWebhook) Size() (n int) {
l = len(*m.MatchPolicy)
n += 1 + l + sovGenerated(uint64(l))
}
+ if m.ReinvocationPolicy != nil {
+ l = len(*m.ReinvocationPolicy)
+ n += 1 + l + sovGenerated(uint64(l))
+ }
if m.ObjectSelector != nil {
l = m.ObjectSelector.Size()
n += 1 + l + sovGenerated(uint64(l))
@@ -2075,7 +2302,7 @@ func (m *ValidatingWebhook) Size() (n int) {
return n
}
-func (m *ValidatingWebhookConfiguration) Size() (n int) {
+func (m *MutatingWebhookConfiguration) Size() (n int) {
if m == nil {
return 0
}
@@ -2092,7 +2319,7 @@ func (m *ValidatingWebhookConfiguration) Size() (n int) {
return n
}
-func (m *ValidatingWebhookConfigurationList) Size() (n int) {
+func (m *MutatingWebhookConfigurationList) Size() (n int) {
if m == nil {
return 0
}
@@ -2109,500 +2336,1983 @@ func (m *ValidatingWebhookConfigurationList) Size() (n int) {
return n
}
-func (m *Validation) Size() (n int) {
+func (m *Mutation) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
- l = len(m.Expression)
- n += 1 + l + sovGenerated(uint64(l))
- l = len(m.Message)
+ l = len(m.PatchType)
n += 1 + l + sovGenerated(uint64(l))
- if m.Reason != nil {
- l = len(*m.Reason)
+ if m.ApplyConfiguration != nil {
+ l = m.ApplyConfiguration.Size()
n += 1 + l + sovGenerated(uint64(l))
}
- l = len(m.MessageExpression)
+ if m.JSONPatch != nil {
+ l = m.JSONPatch.Size()
+ n += 1 + l + sovGenerated(uint64(l))
+ }
+ return n
+}
+
+func (m *NamedRuleWithOperations) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ if len(m.ResourceNames) > 0 {
+ for _, s := range m.ResourceNames {
+ l = len(s)
+ n += 1 + l + sovGenerated(uint64(l))
+ }
+ }
+ l = m.RuleWithOperations.Size()
n += 1 + l + sovGenerated(uint64(l))
return n
}
-func (m *Variable) Size() (n int) {
+func (m *ParamKind) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
- l = len(m.Name)
+ l = len(m.APIVersion)
n += 1 + l + sovGenerated(uint64(l))
- l = len(m.Expression)
+ l = len(m.Kind)
n += 1 + l + sovGenerated(uint64(l))
return n
}
-func (m *WebhookClientConfig) Size() (n int) {
+func (m *ParamRef) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
- if m.Service != nil {
- l = m.Service.Size()
- n += 1 + l + sovGenerated(uint64(l))
- }
- if m.CABundle != nil {
- l = len(m.CABundle)
+ l = len(m.Name)
+ n += 1 + l + sovGenerated(uint64(l))
+ l = len(m.Namespace)
+ n += 1 + l + sovGenerated(uint64(l))
+ if m.Selector != nil {
+ l = m.Selector.Size()
n += 1 + l + sovGenerated(uint64(l))
}
- if m.URL != nil {
- l = len(*m.URL)
+ if m.ParameterNotFoundAction != nil {
+ l = len(*m.ParameterNotFoundAction)
n += 1 + l + sovGenerated(uint64(l))
}
return n
}
-func sovGenerated(x uint64) (n int) {
- return (math_bits.Len64(x|1) + 6) / 7
-}
-func sozGenerated(x uint64) (n int) {
- return sovGenerated(uint64((x << 1) ^ uint64((int64(x) >> 63))))
-}
-func (this *AuditAnnotation) String() string {
- if this == nil {
- return "nil"
- }
- s := strings.Join([]string{`&AuditAnnotation{`,
- `Key:` + fmt.Sprintf("%v", this.Key) + `,`,
- `ValueExpression:` + fmt.Sprintf("%v", this.ValueExpression) + `,`,
- `}`,
- }, "")
- return s
-}
-func (this *ExpressionWarning) String() string {
- if this == nil {
- return "nil"
+func (m *Rule) Size() (n int) {
+ if m == nil {
+ return 0
}
- s := strings.Join([]string{`&ExpressionWarning{`,
- `FieldRef:` + fmt.Sprintf("%v", this.FieldRef) + `,`,
- `Warning:` + fmt.Sprintf("%v", this.Warning) + `,`,
- `}`,
- }, "")
- return s
-}
-func (this *MatchCondition) String() string {
- if this == nil {
- return "nil"
+ var l int
+ _ = l
+ if len(m.APIGroups) > 0 {
+ for _, s := range m.APIGroups {
+ l = len(s)
+ n += 1 + l + sovGenerated(uint64(l))
+ }
}
- s := strings.Join([]string{`&MatchCondition{`,
- `Name:` + fmt.Sprintf("%v", this.Name) + `,`,
- `Expression:` + fmt.Sprintf("%v", this.Expression) + `,`,
- `}`,
- }, "")
- return s
-}
-func (this *MatchResources) String() string {
- if this == nil {
- return "nil"
+ if len(m.APIVersions) > 0 {
+ for _, s := range m.APIVersions {
+ l = len(s)
+ n += 1 + l + sovGenerated(uint64(l))
+ }
}
- repeatedStringForResourceRules := "[]NamedRuleWithOperations{"
- for _, f := range this.ResourceRules {
- repeatedStringForResourceRules += strings.Replace(strings.Replace(f.String(), "NamedRuleWithOperations", "NamedRuleWithOperations", 1), `&`, ``, 1) + ","
+ if len(m.Resources) > 0 {
+ for _, s := range m.Resources {
+ l = len(s)
+ n += 1 + l + sovGenerated(uint64(l))
+ }
}
- repeatedStringForResourceRules += "}"
- repeatedStringForExcludeResourceRules := "[]NamedRuleWithOperations{"
- for _, f := range this.ExcludeResourceRules {
- repeatedStringForExcludeResourceRules += strings.Replace(strings.Replace(f.String(), "NamedRuleWithOperations", "NamedRuleWithOperations", 1), `&`, ``, 1) + ","
+ if m.Scope != nil {
+ l = len(*m.Scope)
+ n += 1 + l + sovGenerated(uint64(l))
}
- repeatedStringForExcludeResourceRules += "}"
- s := strings.Join([]string{`&MatchResources{`,
- `NamespaceSelector:` + strings.Replace(fmt.Sprintf("%v", this.NamespaceSelector), "LabelSelector", "v1.LabelSelector", 1) + `,`,
- `ObjectSelector:` + strings.Replace(fmt.Sprintf("%v", this.ObjectSelector), "LabelSelector", "v1.LabelSelector", 1) + `,`,
- `ResourceRules:` + repeatedStringForResourceRules + `,`,
- `ExcludeResourceRules:` + repeatedStringForExcludeResourceRules + `,`,
- `MatchPolicy:` + valueToStringGenerated(this.MatchPolicy) + `,`,
- `}`,
- }, "")
- return s
+ return n
}
-func (this *MutatingWebhook) String() string {
- if this == nil {
- return "nil"
- }
- repeatedStringForRules := "[]RuleWithOperations{"
- for _, f := range this.Rules {
- repeatedStringForRules += strings.Replace(strings.Replace(f.String(), "RuleWithOperations", "RuleWithOperations", 1), `&`, ``, 1) + ","
+
+func (m *RuleWithOperations) Size() (n int) {
+ if m == nil {
+ return 0
}
- repeatedStringForRules += "}"
- repeatedStringForMatchConditions := "[]MatchCondition{"
- for _, f := range this.MatchConditions {
- repeatedStringForMatchConditions += strings.Replace(strings.Replace(f.String(), "MatchCondition", "MatchCondition", 1), `&`, ``, 1) + ","
+ var l int
+ _ = l
+ if len(m.Operations) > 0 {
+ for _, s := range m.Operations {
+ l = len(s)
+ n += 1 + l + sovGenerated(uint64(l))
+ }
}
- repeatedStringForMatchConditions += "}"
- s := strings.Join([]string{`&MutatingWebhook{`,
- `Name:` + fmt.Sprintf("%v", this.Name) + `,`,
- `ClientConfig:` + strings.Replace(strings.Replace(this.ClientConfig.String(), "WebhookClientConfig", "WebhookClientConfig", 1), `&`, ``, 1) + `,`,
- `Rules:` + repeatedStringForRules + `,`,
- `FailurePolicy:` + valueToStringGenerated(this.FailurePolicy) + `,`,
- `NamespaceSelector:` + strings.Replace(fmt.Sprintf("%v", this.NamespaceSelector), "LabelSelector", "v1.LabelSelector", 1) + `,`,
- `SideEffects:` + valueToStringGenerated(this.SideEffects) + `,`,
- `TimeoutSeconds:` + valueToStringGenerated(this.TimeoutSeconds) + `,`,
- `AdmissionReviewVersions:` + fmt.Sprintf("%v", this.AdmissionReviewVersions) + `,`,
- `MatchPolicy:` + valueToStringGenerated(this.MatchPolicy) + `,`,
- `ReinvocationPolicy:` + valueToStringGenerated(this.ReinvocationPolicy) + `,`,
- `ObjectSelector:` + strings.Replace(fmt.Sprintf("%v", this.ObjectSelector), "LabelSelector", "v1.LabelSelector", 1) + `,`,
- `MatchConditions:` + repeatedStringForMatchConditions + `,`,
- `}`,
- }, "")
- return s
+ l = m.Rule.Size()
+ n += 1 + l + sovGenerated(uint64(l))
+ return n
}
-func (this *MutatingWebhookConfiguration) String() string {
- if this == nil {
- return "nil"
+
+func (m *ServiceReference) Size() (n int) {
+ if m == nil {
+ return 0
}
- repeatedStringForWebhooks := "[]MutatingWebhook{"
- for _, f := range this.Webhooks {
- repeatedStringForWebhooks += strings.Replace(strings.Replace(f.String(), "MutatingWebhook", "MutatingWebhook", 1), `&`, ``, 1) + ","
+ var l int
+ _ = l
+ l = len(m.Namespace)
+ n += 1 + l + sovGenerated(uint64(l))
+ l = len(m.Name)
+ n += 1 + l + sovGenerated(uint64(l))
+ if m.Path != nil {
+ l = len(*m.Path)
+ n += 1 + l + sovGenerated(uint64(l))
}
- repeatedStringForWebhooks += "}"
- s := strings.Join([]string{`&MutatingWebhookConfiguration{`,
- `ObjectMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ObjectMeta), "ObjectMeta", "v1.ObjectMeta", 1), `&`, ``, 1) + `,`,
- `Webhooks:` + repeatedStringForWebhooks + `,`,
- `}`,
- }, "")
- return s
+ if m.Port != nil {
+ n += 1 + sovGenerated(uint64(*m.Port))
+ }
+ return n
}
-func (this *MutatingWebhookConfigurationList) String() string {
- if this == nil {
- return "nil"
+
+func (m *TypeChecking) Size() (n int) {
+ if m == nil {
+ return 0
}
- repeatedStringForItems := "[]MutatingWebhookConfiguration{"
- for _, f := range this.Items {
- repeatedStringForItems += strings.Replace(strings.Replace(f.String(), "MutatingWebhookConfiguration", "MutatingWebhookConfiguration", 1), `&`, ``, 1) + ","
+ var l int
+ _ = l
+ if len(m.ExpressionWarnings) > 0 {
+ for _, e := range m.ExpressionWarnings {
+ l = e.Size()
+ n += 1 + l + sovGenerated(uint64(l))
+ }
}
- repeatedStringForItems += "}"
- s := strings.Join([]string{`&MutatingWebhookConfigurationList{`,
- `ListMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ListMeta), "ListMeta", "v1.ListMeta", 1), `&`, ``, 1) + `,`,
- `Items:` + repeatedStringForItems + `,`,
- `}`,
- }, "")
- return s
+ return n
}
-func (this *NamedRuleWithOperations) String() string {
- if this == nil {
- return "nil"
+
+func (m *ValidatingAdmissionPolicy) Size() (n int) {
+ if m == nil {
+ return 0
}
- s := strings.Join([]string{`&NamedRuleWithOperations{`,
- `ResourceNames:` + fmt.Sprintf("%v", this.ResourceNames) + `,`,
- `RuleWithOperations:` + strings.Replace(strings.Replace(this.RuleWithOperations.String(), "RuleWithOperations", "RuleWithOperations", 1), `&`, ``, 1) + `,`,
- `}`,
- }, "")
- return s
+ var l int
+ _ = l
+ l = m.ObjectMeta.Size()
+ n += 1 + l + sovGenerated(uint64(l))
+ l = m.Spec.Size()
+ n += 1 + l + sovGenerated(uint64(l))
+ l = m.Status.Size()
+ n += 1 + l + sovGenerated(uint64(l))
+ return n
}
-func (this *ParamKind) String() string {
- if this == nil {
- return "nil"
+
+func (m *ValidatingAdmissionPolicyBinding) Size() (n int) {
+ if m == nil {
+ return 0
}
- s := strings.Join([]string{`&ParamKind{`,
- `APIVersion:` + fmt.Sprintf("%v", this.APIVersion) + `,`,
- `Kind:` + fmt.Sprintf("%v", this.Kind) + `,`,
- `}`,
- }, "")
- return s
+ var l int
+ _ = l
+ l = m.ObjectMeta.Size()
+ n += 1 + l + sovGenerated(uint64(l))
+ l = m.Spec.Size()
+ n += 1 + l + sovGenerated(uint64(l))
+ return n
}
-func (this *ParamRef) String() string {
- if this == nil {
- return "nil"
+
+func (m *ValidatingAdmissionPolicyBindingList) Size() (n int) {
+ if m == nil {
+ return 0
}
- s := strings.Join([]string{`&ParamRef{`,
- `Name:` + fmt.Sprintf("%v", this.Name) + `,`,
- `Namespace:` + fmt.Sprintf("%v", this.Namespace) + `,`,
- `Selector:` + strings.Replace(fmt.Sprintf("%v", this.Selector), "LabelSelector", "v1.LabelSelector", 1) + `,`,
- `ParameterNotFoundAction:` + valueToStringGenerated(this.ParameterNotFoundAction) + `,`,
- `}`,
- }, "")
- return s
-}
-func (this *Rule) String() string {
- if this == nil {
- return "nil"
+ var l int
+ _ = l
+ l = m.ListMeta.Size()
+ n += 1 + l + sovGenerated(uint64(l))
+ if len(m.Items) > 0 {
+ for _, e := range m.Items {
+ l = e.Size()
+ n += 1 + l + sovGenerated(uint64(l))
+ }
}
- s := strings.Join([]string{`&Rule{`,
- `APIGroups:` + fmt.Sprintf("%v", this.APIGroups) + `,`,
- `APIVersions:` + fmt.Sprintf("%v", this.APIVersions) + `,`,
- `Resources:` + fmt.Sprintf("%v", this.Resources) + `,`,
- `Scope:` + valueToStringGenerated(this.Scope) + `,`,
- `}`,
- }, "")
- return s
+ return n
}
-func (this *RuleWithOperations) String() string {
- if this == nil {
- return "nil"
+
+func (m *ValidatingAdmissionPolicyBindingSpec) Size() (n int) {
+ if m == nil {
+ return 0
}
- s := strings.Join([]string{`&RuleWithOperations{`,
- `Operations:` + fmt.Sprintf("%v", this.Operations) + `,`,
- `Rule:` + strings.Replace(strings.Replace(this.Rule.String(), "Rule", "Rule", 1), `&`, ``, 1) + `,`,
- `}`,
- }, "")
- return s
-}
-func (this *ServiceReference) String() string {
- if this == nil {
- return "nil"
+ var l int
+ _ = l
+ l = len(m.PolicyName)
+ n += 1 + l + sovGenerated(uint64(l))
+ if m.ParamRef != nil {
+ l = m.ParamRef.Size()
+ n += 1 + l + sovGenerated(uint64(l))
}
- s := strings.Join([]string{`&ServiceReference{`,
- `Namespace:` + fmt.Sprintf("%v", this.Namespace) + `,`,
- `Name:` + fmt.Sprintf("%v", this.Name) + `,`,
- `Path:` + valueToStringGenerated(this.Path) + `,`,
- `Port:` + valueToStringGenerated(this.Port) + `,`,
- `}`,
- }, "")
- return s
-}
-func (this *TypeChecking) String() string {
- if this == nil {
- return "nil"
+ if m.MatchResources != nil {
+ l = m.MatchResources.Size()
+ n += 1 + l + sovGenerated(uint64(l))
}
- repeatedStringForExpressionWarnings := "[]ExpressionWarning{"
- for _, f := range this.ExpressionWarnings {
- repeatedStringForExpressionWarnings += strings.Replace(strings.Replace(f.String(), "ExpressionWarning", "ExpressionWarning", 1), `&`, ``, 1) + ","
+ if len(m.ValidationActions) > 0 {
+ for _, s := range m.ValidationActions {
+ l = len(s)
+ n += 1 + l + sovGenerated(uint64(l))
+ }
}
- repeatedStringForExpressionWarnings += "}"
- s := strings.Join([]string{`&TypeChecking{`,
- `ExpressionWarnings:` + repeatedStringForExpressionWarnings + `,`,
- `}`,
- }, "")
- return s
+ return n
}
-func (this *ValidatingAdmissionPolicy) String() string {
- if this == nil {
- return "nil"
+
+func (m *ValidatingAdmissionPolicyList) Size() (n int) {
+ if m == nil {
+ return 0
}
- s := strings.Join([]string{`&ValidatingAdmissionPolicy{`,
- `ObjectMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ObjectMeta), "ObjectMeta", "v1.ObjectMeta", 1), `&`, ``, 1) + `,`,
- `Spec:` + strings.Replace(strings.Replace(this.Spec.String(), "ValidatingAdmissionPolicySpec", "ValidatingAdmissionPolicySpec", 1), `&`, ``, 1) + `,`,
- `Status:` + strings.Replace(strings.Replace(this.Status.String(), "ValidatingAdmissionPolicyStatus", "ValidatingAdmissionPolicyStatus", 1), `&`, ``, 1) + `,`,
- `}`,
- }, "")
- return s
-}
-func (this *ValidatingAdmissionPolicyBinding) String() string {
- if this == nil {
- return "nil"
+ var l int
+ _ = l
+ l = m.ListMeta.Size()
+ n += 1 + l + sovGenerated(uint64(l))
+ if len(m.Items) > 0 {
+ for _, e := range m.Items {
+ l = e.Size()
+ n += 1 + l + sovGenerated(uint64(l))
+ }
}
- s := strings.Join([]string{`&ValidatingAdmissionPolicyBinding{`,
- `ObjectMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ObjectMeta), "ObjectMeta", "v1.ObjectMeta", 1), `&`, ``, 1) + `,`,
- `Spec:` + strings.Replace(strings.Replace(this.Spec.String(), "ValidatingAdmissionPolicyBindingSpec", "ValidatingAdmissionPolicyBindingSpec", 1), `&`, ``, 1) + `,`,
- `}`,
- }, "")
- return s
+ return n
}
-func (this *ValidatingAdmissionPolicyBindingList) String() string {
- if this == nil {
- return "nil"
- }
- repeatedStringForItems := "[]ValidatingAdmissionPolicyBinding{"
- for _, f := range this.Items {
- repeatedStringForItems += strings.Replace(strings.Replace(f.String(), "ValidatingAdmissionPolicyBinding", "ValidatingAdmissionPolicyBinding", 1), `&`, ``, 1) + ","
+
+func (m *ValidatingAdmissionPolicySpec) Size() (n int) {
+ if m == nil {
+ return 0
}
- repeatedStringForItems += "}"
- s := strings.Join([]string{`&ValidatingAdmissionPolicyBindingList{`,
- `ListMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ListMeta), "ListMeta", "v1.ListMeta", 1), `&`, ``, 1) + `,`,
- `Items:` + repeatedStringForItems + `,`,
- `}`,
- }, "")
- return s
-}
-func (this *ValidatingAdmissionPolicyBindingSpec) String() string {
- if this == nil {
- return "nil"
+ var l int
+ _ = l
+ if m.ParamKind != nil {
+ l = m.ParamKind.Size()
+ n += 1 + l + sovGenerated(uint64(l))
}
- s := strings.Join([]string{`&ValidatingAdmissionPolicyBindingSpec{`,
- `PolicyName:` + fmt.Sprintf("%v", this.PolicyName) + `,`,
- `ParamRef:` + strings.Replace(this.ParamRef.String(), "ParamRef", "ParamRef", 1) + `,`,
- `MatchResources:` + strings.Replace(this.MatchResources.String(), "MatchResources", "MatchResources", 1) + `,`,
- `ValidationActions:` + fmt.Sprintf("%v", this.ValidationActions) + `,`,
- `}`,
- }, "")
- return s
-}
-func (this *ValidatingAdmissionPolicyList) String() string {
- if this == nil {
- return "nil"
+ if m.MatchConstraints != nil {
+ l = m.MatchConstraints.Size()
+ n += 1 + l + sovGenerated(uint64(l))
}
- repeatedStringForItems := "[]ValidatingAdmissionPolicy{"
- for _, f := range this.Items {
- repeatedStringForItems += strings.Replace(strings.Replace(f.String(), "ValidatingAdmissionPolicy", "ValidatingAdmissionPolicy", 1), `&`, ``, 1) + ","
+ if len(m.Validations) > 0 {
+ for _, e := range m.Validations {
+ l = e.Size()
+ n += 1 + l + sovGenerated(uint64(l))
+ }
}
- repeatedStringForItems += "}"
- s := strings.Join([]string{`&ValidatingAdmissionPolicyList{`,
- `ListMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ListMeta), "ListMeta", "v1.ListMeta", 1), `&`, ``, 1) + `,`,
- `Items:` + repeatedStringForItems + `,`,
- `}`,
- }, "")
- return s
-}
-func (this *ValidatingAdmissionPolicySpec) String() string {
- if this == nil {
- return "nil"
+ if m.FailurePolicy != nil {
+ l = len(*m.FailurePolicy)
+ n += 1 + l + sovGenerated(uint64(l))
}
- repeatedStringForValidations := "[]Validation{"
- for _, f := range this.Validations {
- repeatedStringForValidations += strings.Replace(strings.Replace(f.String(), "Validation", "Validation", 1), `&`, ``, 1) + ","
+ if len(m.AuditAnnotations) > 0 {
+ for _, e := range m.AuditAnnotations {
+ l = e.Size()
+ n += 1 + l + sovGenerated(uint64(l))
+ }
}
- repeatedStringForValidations += "}"
- repeatedStringForAuditAnnotations := "[]AuditAnnotation{"
- for _, f := range this.AuditAnnotations {
- repeatedStringForAuditAnnotations += strings.Replace(strings.Replace(f.String(), "AuditAnnotation", "AuditAnnotation", 1), `&`, ``, 1) + ","
+ if len(m.MatchConditions) > 0 {
+ for _, e := range m.MatchConditions {
+ l = e.Size()
+ n += 1 + l + sovGenerated(uint64(l))
+ }
}
- repeatedStringForAuditAnnotations += "}"
- repeatedStringForMatchConditions := "[]MatchCondition{"
- for _, f := range this.MatchConditions {
- repeatedStringForMatchConditions += strings.Replace(strings.Replace(f.String(), "MatchCondition", "MatchCondition", 1), `&`, ``, 1) + ","
+ if len(m.Variables) > 0 {
+ for _, e := range m.Variables {
+ l = e.Size()
+ n += 1 + l + sovGenerated(uint64(l))
+ }
}
- repeatedStringForMatchConditions += "}"
- repeatedStringForVariables := "[]Variable{"
- for _, f := range this.Variables {
- repeatedStringForVariables += strings.Replace(strings.Replace(f.String(), "Variable", "Variable", 1), `&`, ``, 1) + ","
+ return n
+}
+
+func (m *ValidatingAdmissionPolicyStatus) Size() (n int) {
+ if m == nil {
+ return 0
}
- repeatedStringForVariables += "}"
- s := strings.Join([]string{`&ValidatingAdmissionPolicySpec{`,
- `ParamKind:` + strings.Replace(this.ParamKind.String(), "ParamKind", "ParamKind", 1) + `,`,
- `MatchConstraints:` + strings.Replace(this.MatchConstraints.String(), "MatchResources", "MatchResources", 1) + `,`,
- `Validations:` + repeatedStringForValidations + `,`,
- `FailurePolicy:` + valueToStringGenerated(this.FailurePolicy) + `,`,
- `AuditAnnotations:` + repeatedStringForAuditAnnotations + `,`,
- `MatchConditions:` + repeatedStringForMatchConditions + `,`,
- `Variables:` + repeatedStringForVariables + `,`,
- `}`,
- }, "")
- return s
+ var l int
+ _ = l
+ n += 1 + sovGenerated(uint64(m.ObservedGeneration))
+ if m.TypeChecking != nil {
+ l = m.TypeChecking.Size()
+ n += 1 + l + sovGenerated(uint64(l))
+ }
+ if len(m.Conditions) > 0 {
+ for _, e := range m.Conditions {
+ l = e.Size()
+ n += 1 + l + sovGenerated(uint64(l))
+ }
+ }
+ return n
}
-func (this *ValidatingAdmissionPolicyStatus) String() string {
+
+func (m *ValidatingWebhook) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ l = len(m.Name)
+ n += 1 + l + sovGenerated(uint64(l))
+ l = m.ClientConfig.Size()
+ n += 1 + l + sovGenerated(uint64(l))
+ if len(m.Rules) > 0 {
+ for _, e := range m.Rules {
+ l = e.Size()
+ n += 1 + l + sovGenerated(uint64(l))
+ }
+ }
+ if m.FailurePolicy != nil {
+ l = len(*m.FailurePolicy)
+ n += 1 + l + sovGenerated(uint64(l))
+ }
+ if m.NamespaceSelector != nil {
+ l = m.NamespaceSelector.Size()
+ n += 1 + l + sovGenerated(uint64(l))
+ }
+ if m.SideEffects != nil {
+ l = len(*m.SideEffects)
+ n += 1 + l + sovGenerated(uint64(l))
+ }
+ if m.TimeoutSeconds != nil {
+ n += 1 + sovGenerated(uint64(*m.TimeoutSeconds))
+ }
+ if len(m.AdmissionReviewVersions) > 0 {
+ for _, s := range m.AdmissionReviewVersions {
+ l = len(s)
+ n += 1 + l + sovGenerated(uint64(l))
+ }
+ }
+ if m.MatchPolicy != nil {
+ l = len(*m.MatchPolicy)
+ n += 1 + l + sovGenerated(uint64(l))
+ }
+ if m.ObjectSelector != nil {
+ l = m.ObjectSelector.Size()
+ n += 1 + l + sovGenerated(uint64(l))
+ }
+ if len(m.MatchConditions) > 0 {
+ for _, e := range m.MatchConditions {
+ l = e.Size()
+ n += 1 + l + sovGenerated(uint64(l))
+ }
+ }
+ return n
+}
+
+func (m *ValidatingWebhookConfiguration) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ l = m.ObjectMeta.Size()
+ n += 1 + l + sovGenerated(uint64(l))
+ if len(m.Webhooks) > 0 {
+ for _, e := range m.Webhooks {
+ l = e.Size()
+ n += 1 + l + sovGenerated(uint64(l))
+ }
+ }
+ return n
+}
+
+func (m *ValidatingWebhookConfigurationList) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ l = m.ListMeta.Size()
+ n += 1 + l + sovGenerated(uint64(l))
+ if len(m.Items) > 0 {
+ for _, e := range m.Items {
+ l = e.Size()
+ n += 1 + l + sovGenerated(uint64(l))
+ }
+ }
+ return n
+}
+
+func (m *Validation) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ l = len(m.Expression)
+ n += 1 + l + sovGenerated(uint64(l))
+ l = len(m.Message)
+ n += 1 + l + sovGenerated(uint64(l))
+ if m.Reason != nil {
+ l = len(*m.Reason)
+ n += 1 + l + sovGenerated(uint64(l))
+ }
+ l = len(m.MessageExpression)
+ n += 1 + l + sovGenerated(uint64(l))
+ return n
+}
+
+func (m *Variable) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ l = len(m.Name)
+ n += 1 + l + sovGenerated(uint64(l))
+ l = len(m.Expression)
+ n += 1 + l + sovGenerated(uint64(l))
+ return n
+}
+
+func (m *WebhookClientConfig) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ if m.Service != nil {
+ l = m.Service.Size()
+ n += 1 + l + sovGenerated(uint64(l))
+ }
+ if m.CABundle != nil {
+ l = len(m.CABundle)
+ n += 1 + l + sovGenerated(uint64(l))
+ }
+ if m.URL != nil {
+ l = len(*m.URL)
+ n += 1 + l + sovGenerated(uint64(l))
+ }
+ return n
+}
+
+func sovGenerated(x uint64) (n int) {
+ return (math_bits.Len64(x|1) + 6) / 7
+}
+func sozGenerated(x uint64) (n int) {
+ return sovGenerated(uint64((x << 1) ^ uint64((int64(x) >> 63))))
+}
+func (this *ApplyConfiguration) String() string {
if this == nil {
return "nil"
}
- repeatedStringForConditions := "[]Condition{"
- for _, f := range this.Conditions {
- repeatedStringForConditions += fmt.Sprintf("%v", f) + ","
- }
- repeatedStringForConditions += "}"
- s := strings.Join([]string{`&ValidatingAdmissionPolicyStatus{`,
- `ObservedGeneration:` + fmt.Sprintf("%v", this.ObservedGeneration) + `,`,
- `TypeChecking:` + strings.Replace(this.TypeChecking.String(), "TypeChecking", "TypeChecking", 1) + `,`,
- `Conditions:` + repeatedStringForConditions + `,`,
+ s := strings.Join([]string{`&ApplyConfiguration{`,
+ `Expression:` + fmt.Sprintf("%v", this.Expression) + `,`,
`}`,
}, "")
return s
}
-func (this *ValidatingWebhook) String() string {
+func (this *AuditAnnotation) String() string {
if this == nil {
return "nil"
}
- repeatedStringForRules := "[]RuleWithOperations{"
- for _, f := range this.Rules {
- repeatedStringForRules += strings.Replace(strings.Replace(f.String(), "RuleWithOperations", "RuleWithOperations", 1), `&`, ``, 1) + ","
- }
- repeatedStringForRules += "}"
- repeatedStringForMatchConditions := "[]MatchCondition{"
- for _, f := range this.MatchConditions {
- repeatedStringForMatchConditions += strings.Replace(strings.Replace(f.String(), "MatchCondition", "MatchCondition", 1), `&`, ``, 1) + ","
- }
- repeatedStringForMatchConditions += "}"
- s := strings.Join([]string{`&ValidatingWebhook{`,
- `Name:` + fmt.Sprintf("%v", this.Name) + `,`,
- `ClientConfig:` + strings.Replace(strings.Replace(this.ClientConfig.String(), "WebhookClientConfig", "WebhookClientConfig", 1), `&`, ``, 1) + `,`,
- `Rules:` + repeatedStringForRules + `,`,
- `FailurePolicy:` + valueToStringGenerated(this.FailurePolicy) + `,`,
- `NamespaceSelector:` + strings.Replace(fmt.Sprintf("%v", this.NamespaceSelector), "LabelSelector", "v1.LabelSelector", 1) + `,`,
- `SideEffects:` + valueToStringGenerated(this.SideEffects) + `,`,
- `TimeoutSeconds:` + valueToStringGenerated(this.TimeoutSeconds) + `,`,
- `AdmissionReviewVersions:` + fmt.Sprintf("%v", this.AdmissionReviewVersions) + `,`,
- `MatchPolicy:` + valueToStringGenerated(this.MatchPolicy) + `,`,
- `ObjectSelector:` + strings.Replace(fmt.Sprintf("%v", this.ObjectSelector), "LabelSelector", "v1.LabelSelector", 1) + `,`,
- `MatchConditions:` + repeatedStringForMatchConditions + `,`,
+ s := strings.Join([]string{`&AuditAnnotation{`,
+ `Key:` + fmt.Sprintf("%v", this.Key) + `,`,
+ `ValueExpression:` + fmt.Sprintf("%v", this.ValueExpression) + `,`,
`}`,
}, "")
return s
}
-func (this *ValidatingWebhookConfiguration) String() string {
+func (this *ExpressionWarning) String() string {
if this == nil {
return "nil"
}
- repeatedStringForWebhooks := "[]ValidatingWebhook{"
- for _, f := range this.Webhooks {
- repeatedStringForWebhooks += strings.Replace(strings.Replace(f.String(), "ValidatingWebhook", "ValidatingWebhook", 1), `&`, ``, 1) + ","
- }
- repeatedStringForWebhooks += "}"
- s := strings.Join([]string{`&ValidatingWebhookConfiguration{`,
- `ObjectMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ObjectMeta), "ObjectMeta", "v1.ObjectMeta", 1), `&`, ``, 1) + `,`,
- `Webhooks:` + repeatedStringForWebhooks + `,`,
+ s := strings.Join([]string{`&ExpressionWarning{`,
+ `FieldRef:` + fmt.Sprintf("%v", this.FieldRef) + `,`,
+ `Warning:` + fmt.Sprintf("%v", this.Warning) + `,`,
`}`,
}, "")
return s
}
-func (this *ValidatingWebhookConfigurationList) String() string {
+func (this *JSONPatch) String() string {
if this == nil {
return "nil"
}
- repeatedStringForItems := "[]ValidatingWebhookConfiguration{"
- for _, f := range this.Items {
- repeatedStringForItems += strings.Replace(strings.Replace(f.String(), "ValidatingWebhookConfiguration", "ValidatingWebhookConfiguration", 1), `&`, ``, 1) + ","
- }
- repeatedStringForItems += "}"
- s := strings.Join([]string{`&ValidatingWebhookConfigurationList{`,
- `ListMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ListMeta), "ListMeta", "v1.ListMeta", 1), `&`, ``, 1) + `,`,
- `Items:` + repeatedStringForItems + `,`,
+ s := strings.Join([]string{`&JSONPatch{`,
+ `Expression:` + fmt.Sprintf("%v", this.Expression) + `,`,
`}`,
}, "")
return s
}
-func (this *Validation) String() string {
+func (this *MatchCondition) String() string {
if this == nil {
return "nil"
}
- s := strings.Join([]string{`&Validation{`,
+ s := strings.Join([]string{`&MatchCondition{`,
+ `Name:` + fmt.Sprintf("%v", this.Name) + `,`,
`Expression:` + fmt.Sprintf("%v", this.Expression) + `,`,
- `Message:` + fmt.Sprintf("%v", this.Message) + `,`,
- `Reason:` + valueToStringGenerated(this.Reason) + `,`,
- `MessageExpression:` + fmt.Sprintf("%v", this.MessageExpression) + `,`,
`}`,
}, "")
return s
}
-func (this *Variable) String() string {
+func (this *MatchResources) String() string {
if this == nil {
return "nil"
}
- s := strings.Join([]string{`&Variable{`,
- `Name:` + fmt.Sprintf("%v", this.Name) + `,`,
- `Expression:` + fmt.Sprintf("%v", this.Expression) + `,`,
- `}`,
- }, "")
- return s
-}
-func (this *WebhookClientConfig) String() string {
- if this == nil {
- return "nil"
+ repeatedStringForResourceRules := "[]NamedRuleWithOperations{"
+ for _, f := range this.ResourceRules {
+ repeatedStringForResourceRules += strings.Replace(strings.Replace(f.String(), "NamedRuleWithOperations", "NamedRuleWithOperations", 1), `&`, ``, 1) + ","
+ }
+ repeatedStringForResourceRules += "}"
+ repeatedStringForExcludeResourceRules := "[]NamedRuleWithOperations{"
+ for _, f := range this.ExcludeResourceRules {
+ repeatedStringForExcludeResourceRules += strings.Replace(strings.Replace(f.String(), "NamedRuleWithOperations", "NamedRuleWithOperations", 1), `&`, ``, 1) + ","
+ }
+ repeatedStringForExcludeResourceRules += "}"
+ s := strings.Join([]string{`&MatchResources{`,
+ `NamespaceSelector:` + strings.Replace(fmt.Sprintf("%v", this.NamespaceSelector), "LabelSelector", "v1.LabelSelector", 1) + `,`,
+ `ObjectSelector:` + strings.Replace(fmt.Sprintf("%v", this.ObjectSelector), "LabelSelector", "v1.LabelSelector", 1) + `,`,
+ `ResourceRules:` + repeatedStringForResourceRules + `,`,
+ `ExcludeResourceRules:` + repeatedStringForExcludeResourceRules + `,`,
+ `MatchPolicy:` + valueToStringGenerated(this.MatchPolicy) + `,`,
+ `}`,
+ }, "")
+ return s
+}
+func (this *MutatingAdmissionPolicy) String() string {
+ if this == nil {
+ return "nil"
+ }
+ s := strings.Join([]string{`&MutatingAdmissionPolicy{`,
+ `ObjectMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ObjectMeta), "ObjectMeta", "v1.ObjectMeta", 1), `&`, ``, 1) + `,`,
+ `Spec:` + strings.Replace(strings.Replace(this.Spec.String(), "MutatingAdmissionPolicySpec", "MutatingAdmissionPolicySpec", 1), `&`, ``, 1) + `,`,
+ `}`,
+ }, "")
+ return s
+}
+func (this *MutatingAdmissionPolicyBinding) String() string {
+ if this == nil {
+ return "nil"
+ }
+ s := strings.Join([]string{`&MutatingAdmissionPolicyBinding{`,
+ `ObjectMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ObjectMeta), "ObjectMeta", "v1.ObjectMeta", 1), `&`, ``, 1) + `,`,
+ `Spec:` + strings.Replace(strings.Replace(this.Spec.String(), "MutatingAdmissionPolicyBindingSpec", "MutatingAdmissionPolicyBindingSpec", 1), `&`, ``, 1) + `,`,
+ `}`,
+ }, "")
+ return s
+}
+func (this *MutatingAdmissionPolicyBindingList) String() string {
+ if this == nil {
+ return "nil"
+ }
+ repeatedStringForItems := "[]MutatingAdmissionPolicyBinding{"
+ for _, f := range this.Items {
+ repeatedStringForItems += strings.Replace(strings.Replace(f.String(), "MutatingAdmissionPolicyBinding", "MutatingAdmissionPolicyBinding", 1), `&`, ``, 1) + ","
+ }
+ repeatedStringForItems += "}"
+ s := strings.Join([]string{`&MutatingAdmissionPolicyBindingList{`,
+ `ListMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ListMeta), "ListMeta", "v1.ListMeta", 1), `&`, ``, 1) + `,`,
+ `Items:` + repeatedStringForItems + `,`,
+ `}`,
+ }, "")
+ return s
+}
+func (this *MutatingAdmissionPolicyBindingSpec) String() string {
+ if this == nil {
+ return "nil"
+ }
+ s := strings.Join([]string{`&MutatingAdmissionPolicyBindingSpec{`,
+ `PolicyName:` + fmt.Sprintf("%v", this.PolicyName) + `,`,
+ `ParamRef:` + strings.Replace(this.ParamRef.String(), "ParamRef", "ParamRef", 1) + `,`,
+ `MatchResources:` + strings.Replace(this.MatchResources.String(), "MatchResources", "MatchResources", 1) + `,`,
+ `}`,
+ }, "")
+ return s
+}
+func (this *MutatingAdmissionPolicyList) String() string {
+ if this == nil {
+ return "nil"
+ }
+ repeatedStringForItems := "[]MutatingAdmissionPolicy{"
+ for _, f := range this.Items {
+ repeatedStringForItems += strings.Replace(strings.Replace(f.String(), "MutatingAdmissionPolicy", "MutatingAdmissionPolicy", 1), `&`, ``, 1) + ","
+ }
+ repeatedStringForItems += "}"
+ s := strings.Join([]string{`&MutatingAdmissionPolicyList{`,
+ `ListMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ListMeta), "ListMeta", "v1.ListMeta", 1), `&`, ``, 1) + `,`,
+ `Items:` + repeatedStringForItems + `,`,
+ `}`,
+ }, "")
+ return s
+}
+func (this *MutatingAdmissionPolicySpec) String() string {
+ if this == nil {
+ return "nil"
+ }
+ repeatedStringForVariables := "[]Variable{"
+ for _, f := range this.Variables {
+ repeatedStringForVariables += strings.Replace(strings.Replace(f.String(), "Variable", "Variable", 1), `&`, ``, 1) + ","
+ }
+ repeatedStringForVariables += "}"
+ repeatedStringForMutations := "[]Mutation{"
+ for _, f := range this.Mutations {
+ repeatedStringForMutations += strings.Replace(strings.Replace(f.String(), "Mutation", "Mutation", 1), `&`, ``, 1) + ","
+ }
+ repeatedStringForMutations += "}"
+ repeatedStringForMatchConditions := "[]MatchCondition{"
+ for _, f := range this.MatchConditions {
+ repeatedStringForMatchConditions += strings.Replace(strings.Replace(f.String(), "MatchCondition", "MatchCondition", 1), `&`, ``, 1) + ","
+ }
+ repeatedStringForMatchConditions += "}"
+ s := strings.Join([]string{`&MutatingAdmissionPolicySpec{`,
+ `ParamKind:` + strings.Replace(this.ParamKind.String(), "ParamKind", "ParamKind", 1) + `,`,
+ `MatchConstraints:` + strings.Replace(this.MatchConstraints.String(), "MatchResources", "MatchResources", 1) + `,`,
+ `Variables:` + repeatedStringForVariables + `,`,
+ `Mutations:` + repeatedStringForMutations + `,`,
+ `FailurePolicy:` + valueToStringGenerated(this.FailurePolicy) + `,`,
+ `MatchConditions:` + repeatedStringForMatchConditions + `,`,
+ `ReinvocationPolicy:` + fmt.Sprintf("%v", this.ReinvocationPolicy) + `,`,
+ `}`,
+ }, "")
+ return s
+}
+func (this *MutatingWebhook) String() string {
+ if this == nil {
+ return "nil"
+ }
+ repeatedStringForRules := "[]RuleWithOperations{"
+ for _, f := range this.Rules {
+ repeatedStringForRules += strings.Replace(strings.Replace(f.String(), "RuleWithOperations", "RuleWithOperations", 1), `&`, ``, 1) + ","
+ }
+ repeatedStringForRules += "}"
+ repeatedStringForMatchConditions := "[]MatchCondition{"
+ for _, f := range this.MatchConditions {
+ repeatedStringForMatchConditions += strings.Replace(strings.Replace(f.String(), "MatchCondition", "MatchCondition", 1), `&`, ``, 1) + ","
+ }
+ repeatedStringForMatchConditions += "}"
+ s := strings.Join([]string{`&MutatingWebhook{`,
+ `Name:` + fmt.Sprintf("%v", this.Name) + `,`,
+ `ClientConfig:` + strings.Replace(strings.Replace(this.ClientConfig.String(), "WebhookClientConfig", "WebhookClientConfig", 1), `&`, ``, 1) + `,`,
+ `Rules:` + repeatedStringForRules + `,`,
+ `FailurePolicy:` + valueToStringGenerated(this.FailurePolicy) + `,`,
+ `NamespaceSelector:` + strings.Replace(fmt.Sprintf("%v", this.NamespaceSelector), "LabelSelector", "v1.LabelSelector", 1) + `,`,
+ `SideEffects:` + valueToStringGenerated(this.SideEffects) + `,`,
+ `TimeoutSeconds:` + valueToStringGenerated(this.TimeoutSeconds) + `,`,
+ `AdmissionReviewVersions:` + fmt.Sprintf("%v", this.AdmissionReviewVersions) + `,`,
+ `MatchPolicy:` + valueToStringGenerated(this.MatchPolicy) + `,`,
+ `ReinvocationPolicy:` + valueToStringGenerated(this.ReinvocationPolicy) + `,`,
+ `ObjectSelector:` + strings.Replace(fmt.Sprintf("%v", this.ObjectSelector), "LabelSelector", "v1.LabelSelector", 1) + `,`,
+ `MatchConditions:` + repeatedStringForMatchConditions + `,`,
+ `}`,
+ }, "")
+ return s
+}
+func (this *MutatingWebhookConfiguration) String() string {
+ if this == nil {
+ return "nil"
+ }
+ repeatedStringForWebhooks := "[]MutatingWebhook{"
+ for _, f := range this.Webhooks {
+ repeatedStringForWebhooks += strings.Replace(strings.Replace(f.String(), "MutatingWebhook", "MutatingWebhook", 1), `&`, ``, 1) + ","
+ }
+ repeatedStringForWebhooks += "}"
+ s := strings.Join([]string{`&MutatingWebhookConfiguration{`,
+ `ObjectMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ObjectMeta), "ObjectMeta", "v1.ObjectMeta", 1), `&`, ``, 1) + `,`,
+ `Webhooks:` + repeatedStringForWebhooks + `,`,
+ `}`,
+ }, "")
+ return s
+}
+func (this *MutatingWebhookConfigurationList) String() string {
+ if this == nil {
+ return "nil"
+ }
+ repeatedStringForItems := "[]MutatingWebhookConfiguration{"
+ for _, f := range this.Items {
+ repeatedStringForItems += strings.Replace(strings.Replace(f.String(), "MutatingWebhookConfiguration", "MutatingWebhookConfiguration", 1), `&`, ``, 1) + ","
+ }
+ repeatedStringForItems += "}"
+ s := strings.Join([]string{`&MutatingWebhookConfigurationList{`,
+ `ListMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ListMeta), "ListMeta", "v1.ListMeta", 1), `&`, ``, 1) + `,`,
+ `Items:` + repeatedStringForItems + `,`,
+ `}`,
+ }, "")
+ return s
+}
+func (this *Mutation) String() string {
+ if this == nil {
+ return "nil"
+ }
+ s := strings.Join([]string{`&Mutation{`,
+ `PatchType:` + fmt.Sprintf("%v", this.PatchType) + `,`,
+ `ApplyConfiguration:` + strings.Replace(this.ApplyConfiguration.String(), "ApplyConfiguration", "ApplyConfiguration", 1) + `,`,
+ `JSONPatch:` + strings.Replace(this.JSONPatch.String(), "JSONPatch", "JSONPatch", 1) + `,`,
+ `}`,
+ }, "")
+ return s
+}
+func (this *NamedRuleWithOperations) String() string {
+ if this == nil {
+ return "nil"
+ }
+ s := strings.Join([]string{`&NamedRuleWithOperations{`,
+ `ResourceNames:` + fmt.Sprintf("%v", this.ResourceNames) + `,`,
+ `RuleWithOperations:` + strings.Replace(strings.Replace(this.RuleWithOperations.String(), "RuleWithOperations", "RuleWithOperations", 1), `&`, ``, 1) + `,`,
+ `}`,
+ }, "")
+ return s
+}
+func (this *ParamKind) String() string {
+ if this == nil {
+ return "nil"
+ }
+ s := strings.Join([]string{`&ParamKind{`,
+ `APIVersion:` + fmt.Sprintf("%v", this.APIVersion) + `,`,
+ `Kind:` + fmt.Sprintf("%v", this.Kind) + `,`,
+ `}`,
+ }, "")
+ return s
+}
+func (this *ParamRef) String() string {
+ if this == nil {
+ return "nil"
+ }
+ s := strings.Join([]string{`&ParamRef{`,
+ `Name:` + fmt.Sprintf("%v", this.Name) + `,`,
+ `Namespace:` + fmt.Sprintf("%v", this.Namespace) + `,`,
+ `Selector:` + strings.Replace(fmt.Sprintf("%v", this.Selector), "LabelSelector", "v1.LabelSelector", 1) + `,`,
+ `ParameterNotFoundAction:` + valueToStringGenerated(this.ParameterNotFoundAction) + `,`,
+ `}`,
+ }, "")
+ return s
+}
+func (this *Rule) String() string {
+ if this == nil {
+ return "nil"
+ }
+ s := strings.Join([]string{`&Rule{`,
+ `APIGroups:` + fmt.Sprintf("%v", this.APIGroups) + `,`,
+ `APIVersions:` + fmt.Sprintf("%v", this.APIVersions) + `,`,
+ `Resources:` + fmt.Sprintf("%v", this.Resources) + `,`,
+ `Scope:` + valueToStringGenerated(this.Scope) + `,`,
+ `}`,
+ }, "")
+ return s
+}
+func (this *RuleWithOperations) String() string {
+ if this == nil {
+ return "nil"
+ }
+ s := strings.Join([]string{`&RuleWithOperations{`,
+ `Operations:` + fmt.Sprintf("%v", this.Operations) + `,`,
+ `Rule:` + strings.Replace(strings.Replace(this.Rule.String(), "Rule", "Rule", 1), `&`, ``, 1) + `,`,
+ `}`,
+ }, "")
+ return s
+}
+func (this *ServiceReference) String() string {
+ if this == nil {
+ return "nil"
+ }
+ s := strings.Join([]string{`&ServiceReference{`,
+ `Namespace:` + fmt.Sprintf("%v", this.Namespace) + `,`,
+ `Name:` + fmt.Sprintf("%v", this.Name) + `,`,
+ `Path:` + valueToStringGenerated(this.Path) + `,`,
+ `Port:` + valueToStringGenerated(this.Port) + `,`,
+ `}`,
+ }, "")
+ return s
+}
+func (this *TypeChecking) String() string {
+ if this == nil {
+ return "nil"
+ }
+ repeatedStringForExpressionWarnings := "[]ExpressionWarning{"
+ for _, f := range this.ExpressionWarnings {
+ repeatedStringForExpressionWarnings += strings.Replace(strings.Replace(f.String(), "ExpressionWarning", "ExpressionWarning", 1), `&`, ``, 1) + ","
+ }
+ repeatedStringForExpressionWarnings += "}"
+ s := strings.Join([]string{`&TypeChecking{`,
+ `ExpressionWarnings:` + repeatedStringForExpressionWarnings + `,`,
+ `}`,
+ }, "")
+ return s
+}
+func (this *ValidatingAdmissionPolicy) String() string {
+ if this == nil {
+ return "nil"
+ }
+ s := strings.Join([]string{`&ValidatingAdmissionPolicy{`,
+ `ObjectMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ObjectMeta), "ObjectMeta", "v1.ObjectMeta", 1), `&`, ``, 1) + `,`,
+ `Spec:` + strings.Replace(strings.Replace(this.Spec.String(), "ValidatingAdmissionPolicySpec", "ValidatingAdmissionPolicySpec", 1), `&`, ``, 1) + `,`,
+ `Status:` + strings.Replace(strings.Replace(this.Status.String(), "ValidatingAdmissionPolicyStatus", "ValidatingAdmissionPolicyStatus", 1), `&`, ``, 1) + `,`,
+ `}`,
+ }, "")
+ return s
+}
+func (this *ValidatingAdmissionPolicyBinding) String() string {
+ if this == nil {
+ return "nil"
+ }
+ s := strings.Join([]string{`&ValidatingAdmissionPolicyBinding{`,
+ `ObjectMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ObjectMeta), "ObjectMeta", "v1.ObjectMeta", 1), `&`, ``, 1) + `,`,
+ `Spec:` + strings.Replace(strings.Replace(this.Spec.String(), "ValidatingAdmissionPolicyBindingSpec", "ValidatingAdmissionPolicyBindingSpec", 1), `&`, ``, 1) + `,`,
+ `}`,
+ }, "")
+ return s
+}
+func (this *ValidatingAdmissionPolicyBindingList) String() string {
+ if this == nil {
+ return "nil"
+ }
+ repeatedStringForItems := "[]ValidatingAdmissionPolicyBinding{"
+ for _, f := range this.Items {
+ repeatedStringForItems += strings.Replace(strings.Replace(f.String(), "ValidatingAdmissionPolicyBinding", "ValidatingAdmissionPolicyBinding", 1), `&`, ``, 1) + ","
+ }
+ repeatedStringForItems += "}"
+ s := strings.Join([]string{`&ValidatingAdmissionPolicyBindingList{`,
+ `ListMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ListMeta), "ListMeta", "v1.ListMeta", 1), `&`, ``, 1) + `,`,
+ `Items:` + repeatedStringForItems + `,`,
+ `}`,
+ }, "")
+ return s
+}
+func (this *ValidatingAdmissionPolicyBindingSpec) String() string {
+ if this == nil {
+ return "nil"
+ }
+ s := strings.Join([]string{`&ValidatingAdmissionPolicyBindingSpec{`,
+ `PolicyName:` + fmt.Sprintf("%v", this.PolicyName) + `,`,
+ `ParamRef:` + strings.Replace(this.ParamRef.String(), "ParamRef", "ParamRef", 1) + `,`,
+ `MatchResources:` + strings.Replace(this.MatchResources.String(), "MatchResources", "MatchResources", 1) + `,`,
+ `ValidationActions:` + fmt.Sprintf("%v", this.ValidationActions) + `,`,
+ `}`,
+ }, "")
+ return s
+}
+func (this *ValidatingAdmissionPolicyList) String() string {
+ if this == nil {
+ return "nil"
+ }
+ repeatedStringForItems := "[]ValidatingAdmissionPolicy{"
+ for _, f := range this.Items {
+ repeatedStringForItems += strings.Replace(strings.Replace(f.String(), "ValidatingAdmissionPolicy", "ValidatingAdmissionPolicy", 1), `&`, ``, 1) + ","
+ }
+ repeatedStringForItems += "}"
+ s := strings.Join([]string{`&ValidatingAdmissionPolicyList{`,
+ `ListMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ListMeta), "ListMeta", "v1.ListMeta", 1), `&`, ``, 1) + `,`,
+ `Items:` + repeatedStringForItems + `,`,
+ `}`,
+ }, "")
+ return s
+}
+func (this *ValidatingAdmissionPolicySpec) String() string {
+ if this == nil {
+ return "nil"
+ }
+ repeatedStringForValidations := "[]Validation{"
+ for _, f := range this.Validations {
+ repeatedStringForValidations += strings.Replace(strings.Replace(f.String(), "Validation", "Validation", 1), `&`, ``, 1) + ","
+ }
+ repeatedStringForValidations += "}"
+ repeatedStringForAuditAnnotations := "[]AuditAnnotation{"
+ for _, f := range this.AuditAnnotations {
+ repeatedStringForAuditAnnotations += strings.Replace(strings.Replace(f.String(), "AuditAnnotation", "AuditAnnotation", 1), `&`, ``, 1) + ","
+ }
+ repeatedStringForAuditAnnotations += "}"
+ repeatedStringForMatchConditions := "[]MatchCondition{"
+ for _, f := range this.MatchConditions {
+ repeatedStringForMatchConditions += strings.Replace(strings.Replace(f.String(), "MatchCondition", "MatchCondition", 1), `&`, ``, 1) + ","
+ }
+ repeatedStringForMatchConditions += "}"
+ repeatedStringForVariables := "[]Variable{"
+ for _, f := range this.Variables {
+ repeatedStringForVariables += strings.Replace(strings.Replace(f.String(), "Variable", "Variable", 1), `&`, ``, 1) + ","
+ }
+ repeatedStringForVariables += "}"
+ s := strings.Join([]string{`&ValidatingAdmissionPolicySpec{`,
+ `ParamKind:` + strings.Replace(this.ParamKind.String(), "ParamKind", "ParamKind", 1) + `,`,
+ `MatchConstraints:` + strings.Replace(this.MatchConstraints.String(), "MatchResources", "MatchResources", 1) + `,`,
+ `Validations:` + repeatedStringForValidations + `,`,
+ `FailurePolicy:` + valueToStringGenerated(this.FailurePolicy) + `,`,
+ `AuditAnnotations:` + repeatedStringForAuditAnnotations + `,`,
+ `MatchConditions:` + repeatedStringForMatchConditions + `,`,
+ `Variables:` + repeatedStringForVariables + `,`,
+ `}`,
+ }, "")
+ return s
+}
+func (this *ValidatingAdmissionPolicyStatus) String() string {
+ if this == nil {
+ return "nil"
+ }
+ repeatedStringForConditions := "[]Condition{"
+ for _, f := range this.Conditions {
+ repeatedStringForConditions += fmt.Sprintf("%v", f) + ","
+ }
+ repeatedStringForConditions += "}"
+ s := strings.Join([]string{`&ValidatingAdmissionPolicyStatus{`,
+ `ObservedGeneration:` + fmt.Sprintf("%v", this.ObservedGeneration) + `,`,
+ `TypeChecking:` + strings.Replace(this.TypeChecking.String(), "TypeChecking", "TypeChecking", 1) + `,`,
+ `Conditions:` + repeatedStringForConditions + `,`,
+ `}`,
+ }, "")
+ return s
+}
+func (this *ValidatingWebhook) String() string {
+ if this == nil {
+ return "nil"
+ }
+ repeatedStringForRules := "[]RuleWithOperations{"
+ for _, f := range this.Rules {
+ repeatedStringForRules += strings.Replace(strings.Replace(f.String(), "RuleWithOperations", "RuleWithOperations", 1), `&`, ``, 1) + ","
+ }
+ repeatedStringForRules += "}"
+ repeatedStringForMatchConditions := "[]MatchCondition{"
+ for _, f := range this.MatchConditions {
+ repeatedStringForMatchConditions += strings.Replace(strings.Replace(f.String(), "MatchCondition", "MatchCondition", 1), `&`, ``, 1) + ","
+ }
+ repeatedStringForMatchConditions += "}"
+ s := strings.Join([]string{`&ValidatingWebhook{`,
+ `Name:` + fmt.Sprintf("%v", this.Name) + `,`,
+ `ClientConfig:` + strings.Replace(strings.Replace(this.ClientConfig.String(), "WebhookClientConfig", "WebhookClientConfig", 1), `&`, ``, 1) + `,`,
+ `Rules:` + repeatedStringForRules + `,`,
+ `FailurePolicy:` + valueToStringGenerated(this.FailurePolicy) + `,`,
+ `NamespaceSelector:` + strings.Replace(fmt.Sprintf("%v", this.NamespaceSelector), "LabelSelector", "v1.LabelSelector", 1) + `,`,
+ `SideEffects:` + valueToStringGenerated(this.SideEffects) + `,`,
+ `TimeoutSeconds:` + valueToStringGenerated(this.TimeoutSeconds) + `,`,
+ `AdmissionReviewVersions:` + fmt.Sprintf("%v", this.AdmissionReviewVersions) + `,`,
+ `MatchPolicy:` + valueToStringGenerated(this.MatchPolicy) + `,`,
+ `ObjectSelector:` + strings.Replace(fmt.Sprintf("%v", this.ObjectSelector), "LabelSelector", "v1.LabelSelector", 1) + `,`,
+ `MatchConditions:` + repeatedStringForMatchConditions + `,`,
+ `}`,
+ }, "")
+ return s
+}
+func (this *ValidatingWebhookConfiguration) String() string {
+ if this == nil {
+ return "nil"
+ }
+ repeatedStringForWebhooks := "[]ValidatingWebhook{"
+ for _, f := range this.Webhooks {
+ repeatedStringForWebhooks += strings.Replace(strings.Replace(f.String(), "ValidatingWebhook", "ValidatingWebhook", 1), `&`, ``, 1) + ","
+ }
+ repeatedStringForWebhooks += "}"
+ s := strings.Join([]string{`&ValidatingWebhookConfiguration{`,
+ `ObjectMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ObjectMeta), "ObjectMeta", "v1.ObjectMeta", 1), `&`, ``, 1) + `,`,
+ `Webhooks:` + repeatedStringForWebhooks + `,`,
+ `}`,
+ }, "")
+ return s
+}
+func (this *ValidatingWebhookConfigurationList) String() string {
+ if this == nil {
+ return "nil"
+ }
+ repeatedStringForItems := "[]ValidatingWebhookConfiguration{"
+ for _, f := range this.Items {
+ repeatedStringForItems += strings.Replace(strings.Replace(f.String(), "ValidatingWebhookConfiguration", "ValidatingWebhookConfiguration", 1), `&`, ``, 1) + ","
+ }
+ repeatedStringForItems += "}"
+ s := strings.Join([]string{`&ValidatingWebhookConfigurationList{`,
+ `ListMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ListMeta), "ListMeta", "v1.ListMeta", 1), `&`, ``, 1) + `,`,
+ `Items:` + repeatedStringForItems + `,`,
+ `}`,
+ }, "")
+ return s
+}
+func (this *Validation) String() string {
+ if this == nil {
+ return "nil"
+ }
+ s := strings.Join([]string{`&Validation{`,
+ `Expression:` + fmt.Sprintf("%v", this.Expression) + `,`,
+ `Message:` + fmt.Sprintf("%v", this.Message) + `,`,
+ `Reason:` + valueToStringGenerated(this.Reason) + `,`,
+ `MessageExpression:` + fmt.Sprintf("%v", this.MessageExpression) + `,`,
+ `}`,
+ }, "")
+ return s
+}
+func (this *Variable) String() string {
+ if this == nil {
+ return "nil"
+ }
+ s := strings.Join([]string{`&Variable{`,
+ `Name:` + fmt.Sprintf("%v", this.Name) + `,`,
+ `Expression:` + fmt.Sprintf("%v", this.Expression) + `,`,
+ `}`,
+ }, "")
+ return s
+}
+func (this *WebhookClientConfig) String() string {
+ if this == nil {
+ return "nil"
+ }
+ s := strings.Join([]string{`&WebhookClientConfig{`,
+ `Service:` + strings.Replace(this.Service.String(), "ServiceReference", "ServiceReference", 1) + `,`,
+ `CABundle:` + valueToStringGenerated(this.CABundle) + `,`,
+ `URL:` + valueToStringGenerated(this.URL) + `,`,
+ `}`,
+ }, "")
+ return s
+}
+func valueToStringGenerated(v interface{}) string {
+ rv := reflect.ValueOf(v)
+ if rv.IsNil() {
+ return "nil"
+ }
+ pv := reflect.Indirect(rv).Interface()
+ return fmt.Sprintf("*%v", pv)
+}
+func (m *ApplyConfiguration) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGenerated
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: ApplyConfiguration: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: ApplyConfiguration: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ case 1:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Expression", wireType)
+ }
+ var stringLen uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGenerated
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ stringLen |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ intStringLen := int(stringLen)
+ if intStringLen < 0 {
+ return ErrInvalidLengthGenerated
+ }
+ postIndex := iNdEx + intStringLen
+ if postIndex < 0 {
+ return ErrInvalidLengthGenerated
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.Expression = string(dAtA[iNdEx:postIndex])
+ iNdEx = postIndex
+ default:
+ iNdEx = preIndex
+ skippy, err := skipGenerated(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if (skippy < 0) || (iNdEx+skippy) < 0 {
+ return ErrInvalidLengthGenerated
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
+func (m *AuditAnnotation) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGenerated
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: AuditAnnotation: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: AuditAnnotation: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ case 1:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Key", wireType)
+ }
+ var stringLen uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGenerated
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ stringLen |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ intStringLen := int(stringLen)
+ if intStringLen < 0 {
+ return ErrInvalidLengthGenerated
+ }
+ postIndex := iNdEx + intStringLen
+ if postIndex < 0 {
+ return ErrInvalidLengthGenerated
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.Key = string(dAtA[iNdEx:postIndex])
+ iNdEx = postIndex
+ case 2:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field ValueExpression", wireType)
+ }
+ var stringLen uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGenerated
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ stringLen |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ intStringLen := int(stringLen)
+ if intStringLen < 0 {
+ return ErrInvalidLengthGenerated
+ }
+ postIndex := iNdEx + intStringLen
+ if postIndex < 0 {
+ return ErrInvalidLengthGenerated
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.ValueExpression = string(dAtA[iNdEx:postIndex])
+ iNdEx = postIndex
+ default:
+ iNdEx = preIndex
+ skippy, err := skipGenerated(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if (skippy < 0) || (iNdEx+skippy) < 0 {
+ return ErrInvalidLengthGenerated
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
+func (m *ExpressionWarning) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGenerated
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: ExpressionWarning: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: ExpressionWarning: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ case 2:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field FieldRef", wireType)
+ }
+ var stringLen uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGenerated
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ stringLen |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ intStringLen := int(stringLen)
+ if intStringLen < 0 {
+ return ErrInvalidLengthGenerated
+ }
+ postIndex := iNdEx + intStringLen
+ if postIndex < 0 {
+ return ErrInvalidLengthGenerated
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.FieldRef = string(dAtA[iNdEx:postIndex])
+ iNdEx = postIndex
+ case 3:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Warning", wireType)
+ }
+ var stringLen uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGenerated
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ stringLen |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ intStringLen := int(stringLen)
+ if intStringLen < 0 {
+ return ErrInvalidLengthGenerated
+ }
+ postIndex := iNdEx + intStringLen
+ if postIndex < 0 {
+ return ErrInvalidLengthGenerated
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.Warning = string(dAtA[iNdEx:postIndex])
+ iNdEx = postIndex
+ default:
+ iNdEx = preIndex
+ skippy, err := skipGenerated(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if (skippy < 0) || (iNdEx+skippy) < 0 {
+ return ErrInvalidLengthGenerated
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
+func (m *JSONPatch) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGenerated
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: JSONPatch: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: JSONPatch: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ case 1:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Expression", wireType)
+ }
+ var stringLen uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGenerated
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ stringLen |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ intStringLen := int(stringLen)
+ if intStringLen < 0 {
+ return ErrInvalidLengthGenerated
+ }
+ postIndex := iNdEx + intStringLen
+ if postIndex < 0 {
+ return ErrInvalidLengthGenerated
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.Expression = string(dAtA[iNdEx:postIndex])
+ iNdEx = postIndex
+ default:
+ iNdEx = preIndex
+ skippy, err := skipGenerated(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if (skippy < 0) || (iNdEx+skippy) < 0 {
+ return ErrInvalidLengthGenerated
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
+func (m *MatchCondition) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGenerated
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: MatchCondition: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: MatchCondition: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ case 1:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType)
+ }
+ var stringLen uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGenerated
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ stringLen |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ intStringLen := int(stringLen)
+ if intStringLen < 0 {
+ return ErrInvalidLengthGenerated
+ }
+ postIndex := iNdEx + intStringLen
+ if postIndex < 0 {
+ return ErrInvalidLengthGenerated
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.Name = string(dAtA[iNdEx:postIndex])
+ iNdEx = postIndex
+ case 2:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Expression", wireType)
+ }
+ var stringLen uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGenerated
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ stringLen |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ intStringLen := int(stringLen)
+ if intStringLen < 0 {
+ return ErrInvalidLengthGenerated
+ }
+ postIndex := iNdEx + intStringLen
+ if postIndex < 0 {
+ return ErrInvalidLengthGenerated
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.Expression = string(dAtA[iNdEx:postIndex])
+ iNdEx = postIndex
+ default:
+ iNdEx = preIndex
+ skippy, err := skipGenerated(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if (skippy < 0) || (iNdEx+skippy) < 0 {
+ return ErrInvalidLengthGenerated
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
+func (m *MatchResources) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGenerated
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: MatchResources: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: MatchResources: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ case 1:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field NamespaceSelector", wireType)
+ }
+ var msglen int
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGenerated
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ msglen |= int(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ if msglen < 0 {
+ return ErrInvalidLengthGenerated
+ }
+ postIndex := iNdEx + msglen
+ if postIndex < 0 {
+ return ErrInvalidLengthGenerated
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ if m.NamespaceSelector == nil {
+ m.NamespaceSelector = &v1.LabelSelector{}
+ }
+ if err := m.NamespaceSelector.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+ return err
+ }
+ iNdEx = postIndex
+ case 2:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field ObjectSelector", wireType)
+ }
+ var msglen int
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGenerated
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ msglen |= int(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ if msglen < 0 {
+ return ErrInvalidLengthGenerated
+ }
+ postIndex := iNdEx + msglen
+ if postIndex < 0 {
+ return ErrInvalidLengthGenerated
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ if m.ObjectSelector == nil {
+ m.ObjectSelector = &v1.LabelSelector{}
+ }
+ if err := m.ObjectSelector.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+ return err
+ }
+ iNdEx = postIndex
+ case 3:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field ResourceRules", wireType)
+ }
+ var msglen int
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGenerated
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ msglen |= int(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ if msglen < 0 {
+ return ErrInvalidLengthGenerated
+ }
+ postIndex := iNdEx + msglen
+ if postIndex < 0 {
+ return ErrInvalidLengthGenerated
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.ResourceRules = append(m.ResourceRules, NamedRuleWithOperations{})
+ if err := m.ResourceRules[len(m.ResourceRules)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+ return err
+ }
+ iNdEx = postIndex
+ case 4:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field ExcludeResourceRules", wireType)
+ }
+ var msglen int
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGenerated
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ msglen |= int(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ if msglen < 0 {
+ return ErrInvalidLengthGenerated
+ }
+ postIndex := iNdEx + msglen
+ if postIndex < 0 {
+ return ErrInvalidLengthGenerated
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.ExcludeResourceRules = append(m.ExcludeResourceRules, NamedRuleWithOperations{})
+ if err := m.ExcludeResourceRules[len(m.ExcludeResourceRules)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+ return err
+ }
+ iNdEx = postIndex
+ case 7:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field MatchPolicy", wireType)
+ }
+ var stringLen uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGenerated
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ stringLen |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ intStringLen := int(stringLen)
+ if intStringLen < 0 {
+ return ErrInvalidLengthGenerated
+ }
+ postIndex := iNdEx + intStringLen
+ if postIndex < 0 {
+ return ErrInvalidLengthGenerated
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ s := MatchPolicyType(dAtA[iNdEx:postIndex])
+ m.MatchPolicy = &s
+ iNdEx = postIndex
+ default:
+ iNdEx = preIndex
+ skippy, err := skipGenerated(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if (skippy < 0) || (iNdEx+skippy) < 0 {
+ return ErrInvalidLengthGenerated
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
+func (m *MutatingAdmissionPolicy) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGenerated
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: MutatingAdmissionPolicy: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: MutatingAdmissionPolicy: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ case 1:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field ObjectMeta", wireType)
+ }
+ var msglen int
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGenerated
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ msglen |= int(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ if msglen < 0 {
+ return ErrInvalidLengthGenerated
+ }
+ postIndex := iNdEx + msglen
+ if postIndex < 0 {
+ return ErrInvalidLengthGenerated
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ if err := m.ObjectMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+ return err
+ }
+ iNdEx = postIndex
+ case 2:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Spec", wireType)
+ }
+ var msglen int
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGenerated
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ msglen |= int(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ if msglen < 0 {
+ return ErrInvalidLengthGenerated
+ }
+ postIndex := iNdEx + msglen
+ if postIndex < 0 {
+ return ErrInvalidLengthGenerated
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ if err := m.Spec.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+ return err
+ }
+ iNdEx = postIndex
+ default:
+ iNdEx = preIndex
+ skippy, err := skipGenerated(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if (skippy < 0) || (iNdEx+skippy) < 0 {
+ return ErrInvalidLengthGenerated
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
}
- s := strings.Join([]string{`&WebhookClientConfig{`,
- `Service:` + strings.Replace(this.Service.String(), "ServiceReference", "ServiceReference", 1) + `,`,
- `CABundle:` + valueToStringGenerated(this.CABundle) + `,`,
- `URL:` + valueToStringGenerated(this.URL) + `,`,
- `}`,
- }, "")
- return s
+ return nil
}
-func valueToStringGenerated(v interface{}) string {
- rv := reflect.ValueOf(v)
- if rv.IsNil() {
- return "nil"
+func (m *MutatingAdmissionPolicyBinding) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGenerated
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: MutatingAdmissionPolicyBinding: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: MutatingAdmissionPolicyBinding: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ case 1:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field ObjectMeta", wireType)
+ }
+ var msglen int
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGenerated
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ msglen |= int(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ if msglen < 0 {
+ return ErrInvalidLengthGenerated
+ }
+ postIndex := iNdEx + msglen
+ if postIndex < 0 {
+ return ErrInvalidLengthGenerated
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ if err := m.ObjectMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+ return err
+ }
+ iNdEx = postIndex
+ case 2:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Spec", wireType)
+ }
+ var msglen int
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGenerated
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ msglen |= int(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ if msglen < 0 {
+ return ErrInvalidLengthGenerated
+ }
+ postIndex := iNdEx + msglen
+ if postIndex < 0 {
+ return ErrInvalidLengthGenerated
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ if err := m.Spec.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+ return err
+ }
+ iNdEx = postIndex
+ default:
+ iNdEx = preIndex
+ skippy, err := skipGenerated(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if (skippy < 0) || (iNdEx+skippy) < 0 {
+ return ErrInvalidLengthGenerated
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
}
- pv := reflect.Indirect(rv).Interface()
- return fmt.Sprintf("*%v", pv)
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
}
-func (m *AuditAnnotation) Unmarshal(dAtA []byte) error {
+func (m *MutatingAdmissionPolicyBindingList) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
@@ -2625,17 +4335,17 @@ func (m *AuditAnnotation) Unmarshal(dAtA []byte) error {
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
- return fmt.Errorf("proto: AuditAnnotation: wiretype end group for non-group")
+ return fmt.Errorf("proto: MutatingAdmissionPolicyBindingList: wiretype end group for non-group")
}
if fieldNum <= 0 {
- return fmt.Errorf("proto: AuditAnnotation: illegal tag %d (wire type %d)", fieldNum, wire)
+ return fmt.Errorf("proto: MutatingAdmissionPolicyBindingList: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
- return fmt.Errorf("proto: wrong wireType = %d for field Key", wireType)
+ return fmt.Errorf("proto: wrong wireType = %d for field ListMeta", wireType)
}
- var stringLen uint64
+ var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenerated
@@ -2645,29 +4355,30 @@ func (m *AuditAnnotation) Unmarshal(dAtA []byte) error {
}
b := dAtA[iNdEx]
iNdEx++
- stringLen |= uint64(b&0x7F) << shift
+ msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
- intStringLen := int(stringLen)
- if intStringLen < 0 {
+ if msglen < 0 {
return ErrInvalidLengthGenerated
}
- postIndex := iNdEx + intStringLen
+ postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthGenerated
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
- m.Key = string(dAtA[iNdEx:postIndex])
+ if err := m.ListMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+ return err
+ }
iNdEx = postIndex
case 2:
if wireType != 2 {
- return fmt.Errorf("proto: wrong wireType = %d for field ValueExpression", wireType)
+ return fmt.Errorf("proto: wrong wireType = %d for field Items", wireType)
}
- var stringLen uint64
+ var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenerated
@@ -2677,23 +4388,25 @@ func (m *AuditAnnotation) Unmarshal(dAtA []byte) error {
}
b := dAtA[iNdEx]
iNdEx++
- stringLen |= uint64(b&0x7F) << shift
+ msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
- intStringLen := int(stringLen)
- if intStringLen < 0 {
+ if msglen < 0 {
return ErrInvalidLengthGenerated
}
- postIndex := iNdEx + intStringLen
+ postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthGenerated
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
- m.ValueExpression = string(dAtA[iNdEx:postIndex])
+ m.Items = append(m.Items, MutatingAdmissionPolicyBinding{})
+ if err := m.Items[len(m.Items)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+ return err
+ }
iNdEx = postIndex
default:
iNdEx = preIndex
@@ -2716,7 +4429,7 @@ func (m *AuditAnnotation) Unmarshal(dAtA []byte) error {
}
return nil
}
-func (m *ExpressionWarning) Unmarshal(dAtA []byte) error {
+func (m *MutatingAdmissionPolicyBindingSpec) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
@@ -2739,15 +4452,15 @@ func (m *ExpressionWarning) Unmarshal(dAtA []byte) error {
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
- return fmt.Errorf("proto: ExpressionWarning: wiretype end group for non-group")
+ return fmt.Errorf("proto: MutatingAdmissionPolicyBindingSpec: wiretype end group for non-group")
}
if fieldNum <= 0 {
- return fmt.Errorf("proto: ExpressionWarning: illegal tag %d (wire type %d)", fieldNum, wire)
+ return fmt.Errorf("proto: MutatingAdmissionPolicyBindingSpec: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
- case 2:
+ case 1:
if wireType != 2 {
- return fmt.Errorf("proto: wrong wireType = %d for field FieldRef", wireType)
+ return fmt.Errorf("proto: wrong wireType = %d for field PolicyName", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
@@ -2775,13 +4488,49 @@ func (m *ExpressionWarning) Unmarshal(dAtA []byte) error {
if postIndex > l {
return io.ErrUnexpectedEOF
}
- m.FieldRef = string(dAtA[iNdEx:postIndex])
+ m.PolicyName = string(dAtA[iNdEx:postIndex])
+ iNdEx = postIndex
+ case 2:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field ParamRef", wireType)
+ }
+ var msglen int
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGenerated
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ msglen |= int(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ if msglen < 0 {
+ return ErrInvalidLengthGenerated
+ }
+ postIndex := iNdEx + msglen
+ if postIndex < 0 {
+ return ErrInvalidLengthGenerated
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ if m.ParamRef == nil {
+ m.ParamRef = &ParamRef{}
+ }
+ if err := m.ParamRef.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+ return err
+ }
iNdEx = postIndex
case 3:
if wireType != 2 {
- return fmt.Errorf("proto: wrong wireType = %d for field Warning", wireType)
+ return fmt.Errorf("proto: wrong wireType = %d for field MatchResources", wireType)
}
- var stringLen uint64
+ var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenerated
@@ -2791,23 +4540,27 @@ func (m *ExpressionWarning) Unmarshal(dAtA []byte) error {
}
b := dAtA[iNdEx]
iNdEx++
- stringLen |= uint64(b&0x7F) << shift
+ msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
- intStringLen := int(stringLen)
- if intStringLen < 0 {
+ if msglen < 0 {
return ErrInvalidLengthGenerated
}
- postIndex := iNdEx + intStringLen
+ postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthGenerated
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
- m.Warning = string(dAtA[iNdEx:postIndex])
+ if m.MatchResources == nil {
+ m.MatchResources = &MatchResources{}
+ }
+ if err := m.MatchResources.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+ return err
+ }
iNdEx = postIndex
default:
iNdEx = preIndex
@@ -2830,7 +4583,7 @@ func (m *ExpressionWarning) Unmarshal(dAtA []byte) error {
}
return nil
}
-func (m *MatchCondition) Unmarshal(dAtA []byte) error {
+func (m *MutatingAdmissionPolicyList) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
@@ -2853,17 +4606,17 @@ func (m *MatchCondition) Unmarshal(dAtA []byte) error {
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
- return fmt.Errorf("proto: MatchCondition: wiretype end group for non-group")
+ return fmt.Errorf("proto: MutatingAdmissionPolicyList: wiretype end group for non-group")
}
if fieldNum <= 0 {
- return fmt.Errorf("proto: MatchCondition: illegal tag %d (wire type %d)", fieldNum, wire)
+ return fmt.Errorf("proto: MutatingAdmissionPolicyList: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
- return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType)
+ return fmt.Errorf("proto: wrong wireType = %d for field ListMeta", wireType)
}
- var stringLen uint64
+ var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenerated
@@ -2873,29 +4626,30 @@ func (m *MatchCondition) Unmarshal(dAtA []byte) error {
}
b := dAtA[iNdEx]
iNdEx++
- stringLen |= uint64(b&0x7F) << shift
+ msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
- intStringLen := int(stringLen)
- if intStringLen < 0 {
+ if msglen < 0 {
return ErrInvalidLengthGenerated
}
- postIndex := iNdEx + intStringLen
+ postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthGenerated
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
- m.Name = string(dAtA[iNdEx:postIndex])
+ if err := m.ListMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+ return err
+ }
iNdEx = postIndex
case 2:
if wireType != 2 {
- return fmt.Errorf("proto: wrong wireType = %d for field Expression", wireType)
+ return fmt.Errorf("proto: wrong wireType = %d for field Items", wireType)
}
- var stringLen uint64
+ var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenerated
@@ -2905,23 +4659,25 @@ func (m *MatchCondition) Unmarshal(dAtA []byte) error {
}
b := dAtA[iNdEx]
iNdEx++
- stringLen |= uint64(b&0x7F) << shift
+ msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
- intStringLen := int(stringLen)
- if intStringLen < 0 {
+ if msglen < 0 {
return ErrInvalidLengthGenerated
}
- postIndex := iNdEx + intStringLen
+ postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthGenerated
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
- m.Expression = string(dAtA[iNdEx:postIndex])
+ m.Items = append(m.Items, MutatingAdmissionPolicy{})
+ if err := m.Items[len(m.Items)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+ return err
+ }
iNdEx = postIndex
default:
iNdEx = preIndex
@@ -2944,7 +4700,7 @@ func (m *MatchCondition) Unmarshal(dAtA []byte) error {
}
return nil
}
-func (m *MatchResources) Unmarshal(dAtA []byte) error {
+func (m *MutatingAdmissionPolicySpec) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
@@ -2967,15 +4723,15 @@ func (m *MatchResources) Unmarshal(dAtA []byte) error {
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
- return fmt.Errorf("proto: MatchResources: wiretype end group for non-group")
+ return fmt.Errorf("proto: MutatingAdmissionPolicySpec: wiretype end group for non-group")
}
if fieldNum <= 0 {
- return fmt.Errorf("proto: MatchResources: illegal tag %d (wire type %d)", fieldNum, wire)
+ return fmt.Errorf("proto: MutatingAdmissionPolicySpec: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
- return fmt.Errorf("proto: wrong wireType = %d for field NamespaceSelector", wireType)
+ return fmt.Errorf("proto: wrong wireType = %d for field ParamKind", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
@@ -3002,16 +4758,16 @@ func (m *MatchResources) Unmarshal(dAtA []byte) error {
if postIndex > l {
return io.ErrUnexpectedEOF
}
- if m.NamespaceSelector == nil {
- m.NamespaceSelector = &v1.LabelSelector{}
+ if m.ParamKind == nil {
+ m.ParamKind = &ParamKind{}
}
- if err := m.NamespaceSelector.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+ if err := m.ParamKind.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
case 2:
if wireType != 2 {
- return fmt.Errorf("proto: wrong wireType = %d for field ObjectSelector", wireType)
+ return fmt.Errorf("proto: wrong wireType = %d for field MatchConstraints", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
@@ -3038,16 +4794,16 @@ func (m *MatchResources) Unmarshal(dAtA []byte) error {
if postIndex > l {
return io.ErrUnexpectedEOF
}
- if m.ObjectSelector == nil {
- m.ObjectSelector = &v1.LabelSelector{}
+ if m.MatchConstraints == nil {
+ m.MatchConstraints = &MatchResources{}
}
- if err := m.ObjectSelector.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+ if err := m.MatchConstraints.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
case 3:
if wireType != 2 {
- return fmt.Errorf("proto: wrong wireType = %d for field ResourceRules", wireType)
+ return fmt.Errorf("proto: wrong wireType = %d for field Variables", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
@@ -3074,14 +4830,14 @@ func (m *MatchResources) Unmarshal(dAtA []byte) error {
if postIndex > l {
return io.ErrUnexpectedEOF
}
- m.ResourceRules = append(m.ResourceRules, NamedRuleWithOperations{})
- if err := m.ResourceRules[len(m.ResourceRules)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+ m.Variables = append(m.Variables, Variable{})
+ if err := m.Variables[len(m.Variables)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
case 4:
if wireType != 2 {
- return fmt.Errorf("proto: wrong wireType = %d for field ExcludeResourceRules", wireType)
+ return fmt.Errorf("proto: wrong wireType = %d for field Mutations", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
@@ -3108,14 +4864,81 @@ func (m *MatchResources) Unmarshal(dAtA []byte) error {
if postIndex > l {
return io.ErrUnexpectedEOF
}
- m.ExcludeResourceRules = append(m.ExcludeResourceRules, NamedRuleWithOperations{})
- if err := m.ExcludeResourceRules[len(m.ExcludeResourceRules)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+ m.Mutations = append(m.Mutations, Mutation{})
+ if err := m.Mutations[len(m.Mutations)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+ return err
+ }
+ iNdEx = postIndex
+ case 5:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field FailurePolicy", wireType)
+ }
+ var stringLen uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGenerated
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ stringLen |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ intStringLen := int(stringLen)
+ if intStringLen < 0 {
+ return ErrInvalidLengthGenerated
+ }
+ postIndex := iNdEx + intStringLen
+ if postIndex < 0 {
+ return ErrInvalidLengthGenerated
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ s := FailurePolicyType(dAtA[iNdEx:postIndex])
+ m.FailurePolicy = &s
+ iNdEx = postIndex
+ case 6:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field MatchConditions", wireType)
+ }
+ var msglen int
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGenerated
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ msglen |= int(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ if msglen < 0 {
+ return ErrInvalidLengthGenerated
+ }
+ postIndex := iNdEx + msglen
+ if postIndex < 0 {
+ return ErrInvalidLengthGenerated
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.MatchConditions = append(m.MatchConditions, MatchCondition{})
+ if err := m.MatchConditions[len(m.MatchConditions)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
case 7:
if wireType != 2 {
- return fmt.Errorf("proto: wrong wireType = %d for field MatchPolicy", wireType)
+ return fmt.Errorf("proto: wrong wireType = %d for field ReinvocationPolicy", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
@@ -3143,8 +4966,7 @@ func (m *MatchResources) Unmarshal(dAtA []byte) error {
if postIndex > l {
return io.ErrUnexpectedEOF
}
- s := MatchPolicyType(dAtA[iNdEx:postIndex])
- m.MatchPolicy = &s
+ m.ReinvocationPolicy = ReinvocationPolicyType(dAtA[iNdEx:postIndex])
iNdEx = postIndex
default:
iNdEx = preIndex
@@ -3840,6 +5662,160 @@ func (m *MutatingWebhookConfigurationList) Unmarshal(dAtA []byte) error {
}
return nil
}
+func (m *Mutation) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGenerated
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: Mutation: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: Mutation: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ case 2:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field PatchType", wireType)
+ }
+ var stringLen uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGenerated
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ stringLen |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ intStringLen := int(stringLen)
+ if intStringLen < 0 {
+ return ErrInvalidLengthGenerated
+ }
+ postIndex := iNdEx + intStringLen
+ if postIndex < 0 {
+ return ErrInvalidLengthGenerated
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.PatchType = PatchType(dAtA[iNdEx:postIndex])
+ iNdEx = postIndex
+ case 3:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field ApplyConfiguration", wireType)
+ }
+ var msglen int
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGenerated
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ msglen |= int(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ if msglen < 0 {
+ return ErrInvalidLengthGenerated
+ }
+ postIndex := iNdEx + msglen
+ if postIndex < 0 {
+ return ErrInvalidLengthGenerated
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ if m.ApplyConfiguration == nil {
+ m.ApplyConfiguration = &ApplyConfiguration{}
+ }
+ if err := m.ApplyConfiguration.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+ return err
+ }
+ iNdEx = postIndex
+ case 4:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field JSONPatch", wireType)
+ }
+ var msglen int
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGenerated
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ msglen |= int(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ if msglen < 0 {
+ return ErrInvalidLengthGenerated
+ }
+ postIndex := iNdEx + msglen
+ if postIndex < 0 {
+ return ErrInvalidLengthGenerated
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ if m.JSONPatch == nil {
+ m.JSONPatch = &JSONPatch{}
+ }
+ if err := m.JSONPatch.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+ return err
+ }
+ iNdEx = postIndex
+ default:
+ iNdEx = preIndex
+ skippy, err := skipGenerated(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if (skippy < 0) || (iNdEx+skippy) < 0 {
+ return ErrInvalidLengthGenerated
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
func (m *NamedRuleWithOperations) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
diff --git a/vendor/k8s.io/api/admissionregistration/v1/generated.proto b/vendor/k8s.io/api/admissionregistration/v1/generated.proto
index e856e9eaf..89c1475b2 100644
--- a/vendor/k8s.io/api/admissionregistration/v1/generated.proto
+++ b/vendor/k8s.io/api/admissionregistration/v1/generated.proto
@@ -28,6 +28,51 @@ import "k8s.io/apimachinery/pkg/runtime/schema/generated.proto";
// Package-wide variables from generator "generated".
option go_package = "k8s.io/api/admissionregistration/v1";
+// ApplyConfiguration defines the desired configuration values of an object.
+message ApplyConfiguration {
+ // expression will be evaluated by CEL to create an apply configuration.
+ // ref: https://github.com/google/cel-spec
+ //
+ // Apply configurations are declared in CEL using object initialization. For example, this CEL expression
+ // returns an apply configuration to set a single field:
+ //
+ // Object{
+ // spec: Object.spec{
+ // serviceAccountName: "example"
+ // }
+ // }
+ //
+ // Apply configurations may not modify atomic structs, maps or arrays due to the risk of accidental deletion of
+ // values not included in the apply configuration.
+ //
+ // CEL expressions have access to the object types needed to create apply configurations:
+ //
+ // - 'Object' - CEL type of the resource object.
+ // - 'Object.' - CEL type of object field (such as 'Object.spec')
+ // - 'Object.....` - CEL type of nested field (such as 'Object.spec.containers')
+ //
+ // CEL expressions have access to the contents of the API request, organized into CEL variables as well as some other useful variables:
+ //
+ // - 'object' - The object from the incoming request. The value is null for DELETE requests.
+ // - 'oldObject' - The existing object. The value is null for CREATE requests.
+ // - 'request' - Attributes of the API request([ref](/pkg/apis/admission/types.go#AdmissionRequest)).
+ // - 'params' - Parameter resource referred to by the policy binding being evaluated. Only populated if the policy has a ParamKind.
+ // - 'namespaceObject' - The namespace object that the incoming object belongs to. The value is null for cluster-scoped resources.
+ // - 'variables' - Map of composited variables, from its name to its lazily evaluated value.
+ // For example, a variable named 'foo' can be accessed as 'variables.foo'.
+ // - 'authorizer' - A CEL Authorizer. May be used to perform authorization checks for the principal (user or service account) of the request.
+ // See https://pkg.go.dev/k8s.io/apiserver/pkg/cel/library#Authz
+ // - 'authorizer.requestResource' - A CEL ResourceCheck constructed from the 'authorizer' and configured with the
+ // request resource.
+ //
+ // The `apiVersion`, `kind`, `metadata.name` and `metadata.generateName` are always accessible from the root of the
+ // object. No other metadata properties are accessible.
+ //
+ // Only property names of the form `[a-zA-Z_.-/][a-zA-Z0-9_.-/]*` are accessible.
+ // Required.
+ optional string expression = 1;
+}
+
// AuditAnnotation describes how to produce an audit annotation for an API request.
message AuditAnnotation {
// key specifies the audit annotation key. The audit annotation keys of
@@ -67,20 +112,89 @@ message AuditAnnotation {
// ExpressionWarning is a warning information that targets a specific expression.
message ExpressionWarning {
- // The path to the field that refers the expression.
+ // fieldRef is the path to the field that refers to the expression.
// For example, the reference to the expression of the first item of
// validations is "spec.validations[0].expression"
optional string fieldRef = 2;
- // The content of type checking information in a human-readable form.
+ // warning contains the content of type checking information in a human-readable form.
// Each line of the warning contains the type that the expression is checked
// against, followed by the type check error from the compiler.
optional string warning = 3;
}
+// JSONPatch defines a JSON Patch.
+message JSONPatch {
+ // expression will be evaluated by CEL to create a [JSON patch](https://jsonpatch.com/).
+ // ref: https://github.com/google/cel-spec
+ //
+ // expression must return an array of JSONPatch values.
+ //
+ // For example, this CEL expression returns a JSON patch to conditionally modify a value:
+ //
+ // [
+ // JSONPatch{op: "test", path: "/spec/example", value: "Red"},
+ // JSONPatch{op: "replace", path: "/spec/example", value: "Green"}
+ // ]
+ //
+ // To define an object for the patch value, use Object types. For example:
+ //
+ // [
+ // JSONPatch{
+ // op: "add",
+ // path: "/spec/selector",
+ // value: Object.spec.selector{matchLabels: {"environment": "test"}}
+ // }
+ // ]
+ //
+ // To use strings containing '/' and '~' as JSONPatch path keys, use "jsonpatch.escapeKey". For example:
+ //
+ // [
+ // JSONPatch{
+ // op: "add",
+ // path: "/metadata/labels/" + jsonpatch.escapeKey("example.com/environment"),
+ // value: "test"
+ // },
+ // ]
+ //
+ // CEL expressions have access to the types needed to create JSON patches and objects:
+ //
+ // - 'JSONPatch' - CEL type of JSON Patch operations. JSONPatch has the fields 'op', 'from', 'path' and 'value'.
+ // See [JSON patch](https://jsonpatch.com/) for more details. The 'value' field may be set to any of: string,
+ // integer, array, map or object. If set, the 'path' and 'from' fields must be set to a
+ // [JSON pointer](https://datatracker.ietf.org/doc/html/rfc6901/) string, where the 'jsonpatch.escapeKey()' CEL
+ // function may be used to escape path keys containing '/' and '~'.
+ // - 'Object' - CEL type of the resource object.
+ // - 'Object.' - CEL type of object field (such as 'Object.spec')
+ // - 'Object.....` - CEL type of nested field (such as 'Object.spec.containers')
+ //
+ // CEL expressions have access to the contents of the API request, organized into CEL variables as well as some other useful variables:
+ //
+ // - 'object' - The object from the incoming request. The value is null for DELETE requests.
+ // - 'oldObject' - The existing object. The value is null for CREATE requests.
+ // - 'request' - Attributes of the API request([ref](/pkg/apis/admission/types.go#AdmissionRequest)).
+ // - 'params' - Parameter resource referred to by the policy binding being evaluated. Only populated if the policy has a ParamKind.
+ // - 'namespaceObject' - The namespace object that the incoming object belongs to. The value is null for cluster-scoped resources.
+ // - 'variables' - Map of composited variables, from its name to its lazily evaluated value.
+ // For example, a variable named 'foo' can be accessed as 'variables.foo'.
+ // - 'authorizer' - A CEL Authorizer. May be used to perform authorization checks for the principal (user or service account) of the request.
+ // See https://pkg.go.dev/k8s.io/apiserver/pkg/cel/library#Authz
+ // - 'authorizer.requestResource' - A CEL ResourceCheck constructed from the 'authorizer' and configured with the
+ // request resource.
+ //
+ // CEL expressions have access to [Kubernetes CEL function libraries](https://kubernetes.io/docs/reference/using-api/cel/#cel-options-language-features-and-libraries)
+ // as well as:
+ //
+ // - 'jsonpatch.escapeKey' - Performs JSONPatch key escaping. '~' and '/' are escaped as '~0' and `~1' respectively).
+ //
+ // Only property names of the form `[a-zA-Z_.-/][a-zA-Z0-9_.-/]*` are accessible.
+ // Required.
+ optional string expression = 1;
+}
+
// MatchCondition represents a condition which must by fulfilled for a request to be sent to a webhook.
message MatchCondition {
- // Name is an identifier for this match condition, used for strategic merging of MatchConditions,
+ // name is an identifier for this match condition, used for strategic merging of MatchConditions,
// as well as providing an identifier for logging purposes. A good name should be descriptive of
// the associated expression.
// Name must be a qualified name consisting of alphanumeric characters, '-', '_' or '.', and
@@ -91,7 +205,7 @@ message MatchCondition {
// Required.
optional string name = 1;
- // Expression represents the expression which will be evaluated by CEL. Must evaluate to bool.
+ // expression represents the expression which will be evaluated by CEL. Must evaluate to bool.
// CEL expressions have access to the contents of the AdmissionRequest and Authorizer, organized into CEL variables:
//
// 'object' - The object from the incoming request. The value is null for DELETE requests.
@@ -112,7 +226,7 @@ message MatchCondition {
// The exclude rules take precedence over include rules (if a resource matches both, it is excluded)
// +structType=atomic
message MatchResources {
- // NamespaceSelector decides whether to run the admission control policy on an object based
+ // namespaceSelector decides whether to run the admission control policy on an object based
// on whether the namespace for that object matches the selector. If the
// object itself is a namespace, the matching is performed on
// object.metadata.labels. If the object is another cluster scoped resource,
@@ -158,7 +272,7 @@ message MatchResources {
// +optional
optional .k8s.io.apimachinery.pkg.apis.meta.v1.LabelSelector namespaceSelector = 1;
- // ObjectSelector decides whether to run the validation based on if the
+ // objectSelector decides whether to run the validation based on if the
// object has matching labels. objectSelector is evaluated against both
// the oldObject and newObject that would be sent to the cel validation, and
// is considered to match if either object matches the selector. A null
@@ -172,13 +286,13 @@ message MatchResources {
// +optional
optional .k8s.io.apimachinery.pkg.apis.meta.v1.LabelSelector objectSelector = 2;
- // ResourceRules describes what operations on what resources/subresources the ValidatingAdmissionPolicy matches.
+ // resourceRules describes what operations on what resources/subresources the ValidatingAdmissionPolicy matches.
// The policy cares about an operation if it matches _any_ Rule.
// +listType=atomic
// +optional
repeated NamedRuleWithOperations resourceRules = 3;
- // ExcludeResourceRules describes what operations on what resources/subresources the ValidatingAdmissionPolicy should not care about.
+ // excludeResourceRules describes what operations on what resources/subresources the ValidatingAdmissionPolicy should not care about.
// The exclude rules take precedence over include rules (if a resource matches both, it is excluded)
// +listType=atomic
// +optional
@@ -202,20 +316,187 @@ message MatchResources {
optional string matchPolicy = 7;
}
+// MutatingAdmissionPolicy describes the definition of an admission mutation policy that mutates the object coming into admission chain.
+message MutatingAdmissionPolicy {
+ // metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.
+ // +optional
+ optional .k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1;
+
+ // spec defines the desired behavior of the MutatingAdmissionPolicy.
+ optional MutatingAdmissionPolicySpec spec = 2;
+}
+
+// MutatingAdmissionPolicyBinding binds the MutatingAdmissionPolicy with parametrized resources.
+// MutatingAdmissionPolicyBinding and the optional parameter resource together define how cluster administrators
+// configure policies for clusters.
+//
+// For a given admission request, each binding will cause its policy to be
+// evaluated N times, where N is 1 for policies/bindings that don't use
+// params, otherwise N is the number of parameters selected by the binding.
+// Each evaluation is constrained by a [runtime cost budget](https://kubernetes.io/docs/reference/using-api/cel/#runtime-cost-budget).
+//
+// Adding/removing policies, bindings, or params can not affect whether a
+// given (policy, binding, param) combination is within its own CEL budget.
+message MutatingAdmissionPolicyBinding {
+ // metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.
+ // +optional
+ optional .k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1;
+
+ // spec defines the desired behavior of the MutatingAdmissionPolicyBinding.
+ optional MutatingAdmissionPolicyBindingSpec spec = 2;
+}
+
+// MutatingAdmissionPolicyBindingList is a list of MutatingAdmissionPolicyBinding.
+message MutatingAdmissionPolicyBindingList {
+ // metadata is the standard list metadata.
+ // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
+ // +optional
+ optional .k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1;
+
+ // List of PolicyBinding.
+ repeated MutatingAdmissionPolicyBinding items = 2;
+}
+
+// MutatingAdmissionPolicyBindingSpec defines the specification of the MutatingAdmissionPolicyBinding.
+message MutatingAdmissionPolicyBindingSpec {
+ // policyName references a MutatingAdmissionPolicy name which the MutatingAdmissionPolicyBinding binds to.
+ // If the referenced resource does not exist, this binding is considered invalid and will be ignored
+ // Required.
+ optional string policyName = 1;
+
+ // paramRef specifies the parameter resource used to configure the admission control policy.
+ // It should point to a resource of the type specified in spec.ParamKind of the bound MutatingAdmissionPolicy.
+ // If the policy specifies a ParamKind and the resource referred to by ParamRef does not exist, this binding is considered mis-configured and the FailurePolicy of the MutatingAdmissionPolicy applied.
+ // If the policy does not specify a ParamKind then this field is ignored, and the rules are evaluated without a param.
+ // +optional
+ optional ParamRef paramRef = 2;
+
+ // matchResources limits what resources match this binding and may be mutated by it.
+ // Note that if matchResources matches a resource, the resource must also match a policy's matchConstraints and
+ // matchConditions before the resource may be mutated.
+ // When matchResources is unset, it does not constrain resource matching, and only the policy's matchConstraints
+ // and matchConditions must match for the resource to be mutated.
+ // Additionally, matchResources.resourceRules are optional and do not constraint matching when unset.
+ // Note that this is differs from MutatingAdmissionPolicy matchConstraints, where resourceRules are required.
+ // The CREATE, UPDATE and CONNECT operations are allowed. The DELETE operation may not be matched.
+ // '*' matches CREATE, UPDATE and CONNECT.
+ // +optional
+ optional MatchResources matchResources = 3;
+}
+
+// MutatingAdmissionPolicyList is a list of MutatingAdmissionPolicy.
+message MutatingAdmissionPolicyList {
+ // metadata is the standard list metadata.
+ // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
+ // +optional
+ optional .k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1;
+
+ // List of ValidatingAdmissionPolicy.
+ repeated MutatingAdmissionPolicy items = 2;
+}
+
+// MutatingAdmissionPolicySpec defines the desired behavior of the admission policy.
+message MutatingAdmissionPolicySpec {
+ // paramKind specifies the kind of resources used to parameterize this policy.
+ // If absent, there are no parameters for this policy and the param CEL variable will not be provided to validation expressions.
+ // If paramKind refers to a non-existent kind, this policy definition is mis-configured and the FailurePolicy is applied.
+ // If paramKind is specified but paramRef is unset in MutatingAdmissionPolicyBinding, the params variable will be null.
+ // +optional
+ optional ParamKind paramKind = 1;
+
+ // matchConstraints specifies what resources this policy is designed to validate.
+ // The MutatingAdmissionPolicy cares about a request if it matches _all_ Constraints.
+ // However, in order to prevent clusters from being put into an unstable state that cannot be recovered from via the API
+ // MutatingAdmissionPolicy cannot match MutatingAdmissionPolicy and MutatingAdmissionPolicyBinding.
+ // The CREATE, UPDATE and CONNECT operations are allowed. The DELETE operation may not be matched.
+ // '*' matches CREATE, UPDATE and CONNECT.
+ // Required.
+ optional MatchResources matchConstraints = 2;
+
+ // variables contain definitions of variables that can be used in composition of other expressions.
+ // Each variable is defined as a named CEL expression.
+ // The variables defined here will be available under `variables` in other expressions of the policy
+ // except matchConditions because matchConditions are evaluated before the rest of the policy.
+ //
+ // The expression of a variable can refer to other variables defined earlier in the list but not those after.
+ // Thus, variables must be sorted by the order of first appearance and acyclic.
+ // +listType=atomic
+ // +optional
+ repeated Variable variables = 3;
+
+ // mutations contain operations to perform on matching objects.
+ // mutations may not be empty; a minimum of one mutation is required.
+ // mutations are evaluated in order, and are reinvoked according to
+ // the reinvocationPolicy.
+ // The mutations of a policy are invoked for each binding of this policy
+ // and reinvocation of mutations occurs on a per binding basis.
+ //
+ // +listType=atomic
+ // +optional
+ repeated Mutation mutations = 4;
+
+ // failurePolicy defines how to handle failures for the admission policy. Failures can
+ // occur from CEL expression parse errors, type check errors, runtime errors and invalid
+ // or mis-configured policy definitions or bindings.
+ //
+ // A policy is invalid if paramKind refers to a non-existent Kind.
+ // A binding is invalid if paramRef.name refers to a non-existent resource.
+ //
+ // failurePolicy does not define how validations that evaluate to false are handled.
+ //
+ // Allowed values are Ignore or Fail. Defaults to Fail.
+ // +optional
+ optional string failurePolicy = 5;
+
+ // matchConditions is a list of conditions that must be met for a request to be validated.
+ // Match conditions filter requests that have already been matched by the matchConstraints.
+ // An empty list of matchConditions matches all requests.
+ // There are a maximum of 64 match conditions allowed.
+ //
+ // If a parameter object is provided, it can be accessed via the `params` handle in the same
+ // manner as validation expressions.
+ //
+ // The exact matching logic is (in order):
+ // 1. If ANY matchCondition evaluates to FALSE, the policy is skipped.
+ // 2. If ALL matchConditions evaluate to TRUE, the policy is evaluated.
+ // 3. If any matchCondition evaluates to an error (but none are FALSE):
+ // - If failurePolicy=Fail, reject the request
+ // - If failurePolicy=Ignore, the policy is skipped
+ //
+ // +patchMergeKey=name
+ // +patchStrategy=merge
+ // +listType=map
+ // +listMapKey=name
+ // +optional
+ repeated MatchCondition matchConditions = 6;
+
+ // reinvocationPolicy indicates whether mutations may be called multiple times per MutatingAdmissionPolicyBinding
+ // as part of a single admission evaluation.
+ // Allowed values are "Never" and "IfNeeded".
+ //
+ // Never: These mutations will not be called more than once per binding in a single admission evaluation.
+ //
+ // IfNeeded: These mutations may be invoked more than once per binding for a single admission request and there is no guarantee of
+ // order with respect to other admission plugins, admission webhooks, bindings of this policy and admission policies. Mutations are only
+ // reinvoked when mutations change the object after this mutation is invoked.
+ // Required.
+ optional string reinvocationPolicy = 7;
+}
+
// MutatingWebhook describes an admission webhook and the resources and operations it applies to.
message MutatingWebhook {
- // The name of the admission webhook.
+ // name is the name of the admission webhook.
// Name should be fully qualified, e.g., imagepolicy.kubernetes.io, where
// "imagepolicy" is the name of the webhook, and kubernetes.io is the name
// of the organization.
// Required.
optional string name = 1;
- // ClientConfig defines how to communicate with the hook.
+ // clientConfig defines how to communicate with the hook.
// Required
optional WebhookClientConfig clientConfig = 2;
- // Rules describes what operations on what resources/subresources the webhook cares about.
+ // rules describes what operations on what resources/subresources the webhook cares about.
// The webhook cares about an operation if it matches _any_ Rule.
// However, in order to prevent ValidatingAdmissionWebhooks and MutatingAdmissionWebhooks
// from putting the cluster in a state which cannot be recovered from without completely
@@ -224,7 +505,7 @@ message MutatingWebhook {
// +listType=atomic
repeated RuleWithOperations rules = 3;
- // FailurePolicy defines how unrecognized errors from the admission endpoint are handled -
+ // failurePolicy defines how unrecognized errors from the admission endpoint are handled -
// allowed values are Ignore or Fail. Defaults to Fail.
// +optional
optional string failurePolicy = 4;
@@ -246,7 +527,7 @@ message MutatingWebhook {
// +optional
optional string matchPolicy = 9;
- // NamespaceSelector decides whether to run the webhook on an object based
+ // namespaceSelector decides whether to run the webhook on an object based
// on whether the namespace for that object matches the selector. If the
// object itself is a namespace, the matching is performed on
// object.metadata.labels. If the object is another cluster scoped resource,
@@ -292,7 +573,7 @@ message MutatingWebhook {
// +optional
optional .k8s.io.apimachinery.pkg.apis.meta.v1.LabelSelector namespaceSelector = 5;
- // ObjectSelector decides whether to run the webhook based on if the
+ // objectSelector decides whether to run the webhook based on if the
// object has matching labels. objectSelector is evaluated against both
// the oldObject and newObject that would be sent to the webhook, and
// is considered to match if either object matches the selector. A null
@@ -306,7 +587,7 @@ message MutatingWebhook {
// +optional
optional .k8s.io.apimachinery.pkg.apis.meta.v1.LabelSelector objectSelector = 11;
- // SideEffects states whether this webhook has side effects.
+ // sideEffects states whether this webhook has side effects.
// Acceptable values are: None, NoneOnDryRun (webhooks created via v1beta1 may also specify Some or Unknown).
// Webhooks with side effects MUST implement a reconciliation system, since a request may be
// rejected by a future step in the admission chain and the side effects therefore need to be undone.
@@ -314,7 +595,7 @@ message MutatingWebhook {
// sideEffects == Unknown or Some.
optional string sideEffects = 6;
- // TimeoutSeconds specifies the timeout for this webhook. After the timeout passes,
+ // timeoutSeconds specifies the timeout for this webhook. After the timeout passes,
// the webhook call will be ignored or the API call will fail based on the
// failure policy.
// The timeout value must be between 1 and 30 seconds.
@@ -322,7 +603,7 @@ message MutatingWebhook {
// +optional
optional int32 timeoutSeconds = 7;
- // AdmissionReviewVersions is an ordered list of preferred `AdmissionReview`
+ // admissionReviewVersions is an ordered list of preferred `AdmissionReview`
// versions the Webhook expects. API server will try to use first version in
// the list which it supports. If none of the versions specified in this list
// supported by API server, validation will fail for this object.
@@ -350,7 +631,7 @@ message MutatingWebhook {
// +optional
optional string reinvocationPolicy = 10;
- // MatchConditions is a list of conditions that must be met for a request to be sent to this
+ // matchConditions is a list of conditions that must be met for a request to be sent to this
// webhook. Match conditions filter requests that have already been matched by the rules,
// namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests.
// There are a maximum of 64 match conditions allowed.
@@ -372,11 +653,11 @@ message MutatingWebhook {
// MutatingWebhookConfiguration describes the configuration of and admission webhook that accept or reject and may change the object.
message MutatingWebhookConfiguration {
- // Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.
+ // metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.
// +optional
optional .k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1;
- // Webhooks is a list of webhooks and the affected resources and operations.
+ // webhooks is a list of webhooks and the affected resources and operations.
// +optional
// +patchMergeKey=name
// +patchStrategy=merge
@@ -387,7 +668,7 @@ message MutatingWebhookConfiguration {
// MutatingWebhookConfigurationList is a list of MutatingWebhookConfiguration.
message MutatingWebhookConfigurationList {
- // Standard list metadata.
+ // metadata is the standard list metadata.
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
// +optional
optional .k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1;
@@ -396,10 +677,30 @@ message MutatingWebhookConfigurationList {
repeated MutatingWebhookConfiguration items = 2;
}
+// Mutation specifies the CEL expression which is used to apply the Mutation.
+message Mutation {
+ // patchType indicates the patch strategy used.
+ // Allowed values are "ApplyConfiguration" and "JSONPatch".
+ // Required.
+ //
+ // +unionDiscriminator
+ optional string patchType = 2;
+
+ // applyConfiguration defines the desired configuration values of an object.
+ // The configuration is applied to the admission object using
+ // [structured merge diff](https://github.com/kubernetes-sigs/structured-merge-diff).
+ // A CEL expression is used to create apply configuration.
+ optional ApplyConfiguration applyConfiguration = 3;
+
+ // jsonPatch defines a [JSON patch](https://jsonpatch.com/) operation to perform a mutation to the object.
+ // A CEL expression is used to create the JSON patch.
+ optional JSONPatch jsonPatch = 4;
+}
+
// NamedRuleWithOperations is a tuple of Operations and Resources with ResourceNames.
// +structType=atomic
message NamedRuleWithOperations {
- // ResourceNames is an optional white list of names that the rule applies to. An empty set means that everything is allowed.
+ // resourceNames is an optional white list of names that the rule applies to. An empty set means that everything is allowed.
// +listType=atomic
// +optional
repeated string resourceNames = 1;
@@ -411,12 +712,12 @@ message NamedRuleWithOperations {
// ParamKind is a tuple of Group Kind and Version.
// +structType=atomic
message ParamKind {
- // APIVersion is the API group version the resources belong to.
+ // apiVersion is the API group version the resources belong to.
// In format of "group/version".
// Required.
optional string apiVersion = 1;
- // Kind is the API kind the resources belong to.
+ // kind is the API kind the resources belong to.
// Required.
optional string kind = 2;
}
@@ -465,7 +766,7 @@ message ParamRef {
// +optional
optional .k8s.io.apimachinery.pkg.apis.meta.v1.LabelSelector selector = 3;
- // `parameterNotFoundAction` controls the behavior of the binding when the resource
+ // parameterNotFoundAction controls the behavior of the binding when the resource
// exists, and name or selector is valid, but there are no parameters
// matched by the binding. If the value is set to `Allow`, then no
// matched parameters will be treated as successful validation by the binding.
@@ -481,19 +782,19 @@ message ParamRef {
// Rule is a tuple of APIGroups, APIVersion, and Resources.It is recommended
// to make sure that all the tuple expansions are valid.
message Rule {
- // APIGroups is the API groups the resources belong to. '*' is all groups.
+ // apiGroups is the API groups the resources belong to. '*' is all groups.
// If '*' is present, the length of the slice must be one.
// Required.
// +listType=atomic
repeated string apiGroups = 1;
- // APIVersions is the API versions the resources belong to. '*' is all versions.
+ // apiVersions is the API versions the resources belong to. '*' is all versions.
// If '*' is present, the length of the slice must be one.
// Required.
// +listType=atomic
repeated string apiVersions = 2;
- // Resources is a list of resources this rule applies to.
+ // resources is a list of resources this rule applies to.
//
// For example:
// 'pods' means pods.
@@ -527,7 +828,7 @@ message Rule {
// RuleWithOperations is a tuple of Operations and Resources. It is recommended to make
// sure that all the tuple expansions are valid.
message RuleWithOperations {
- // Operations is the operations the admission hook cares about - CREATE, UPDATE, DELETE, CONNECT or *
+ // operations is the operations the admission hook cares about - CREATE, UPDATE, DELETE, CONNECT or *
// for all of those operations and any future admission operations that are added.
// If '*' is present, the length of the slice must be one.
// Required.
@@ -541,20 +842,20 @@ message RuleWithOperations {
// ServiceReference holds a reference to Service.legacy.k8s.io
message ServiceReference {
- // `namespace` is the namespace of the service.
+ // namespace is the namespace of the service.
// Required
optional string namespace = 1;
- // `name` is the name of the service.
+ // name is the name of the service.
// Required
optional string name = 2;
- // `path` is an optional URL path which will be sent in any request to
+ // path is an optional URL path which will be sent in any request to
// this service.
// +optional
optional string path = 3;
- // If specified, the port on the service that hosting webhook.
+ // port is the port on the service that hosts the webhook.
// Default to 443 for backward compatibility.
// `port` should be a valid port number (1-65535, inclusive).
// +optional
@@ -564,7 +865,7 @@ message ServiceReference {
// TypeChecking contains results of type checking the expressions in the
// ValidatingAdmissionPolicy
message TypeChecking {
- // The type checking warnings for each expression.
+ // expressionWarnings contains the type checking warnings for each expression.
// +optional
// +listType=atomic
repeated ExpressionWarning expressionWarnings = 1;
@@ -572,14 +873,14 @@ message TypeChecking {
// ValidatingAdmissionPolicy describes the definition of an admission validation policy that accepts or rejects an object without changing it.
message ValidatingAdmissionPolicy {
- // Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.
+ // metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.
// +optional
optional .k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1;
- // Specification of the desired behavior of the ValidatingAdmissionPolicy.
+ // spec defines the desired behavior of the ValidatingAdmissionPolicy.
optional ValidatingAdmissionPolicySpec spec = 2;
- // The status of the ValidatingAdmissionPolicy, including warnings that are useful to determine if the policy
+ // status represents the current status of the ValidatingAdmissionPolicy, including warnings that are useful to determine if the policy
// behaves in the expected way.
// Populated by the system.
// Read-only.
@@ -599,17 +900,18 @@ message ValidatingAdmissionPolicy {
// Adding/removing policies, bindings, or params can not affect whether a
// given (policy, binding, param) combination is within its own CEL budget.
message ValidatingAdmissionPolicyBinding {
- // Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.
+ // metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.
// +optional
optional .k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1;
- // Specification of the desired behavior of the ValidatingAdmissionPolicyBinding.
+ // spec defines the desired behavior of the ValidatingAdmissionPolicyBinding.
+ // +required
optional ValidatingAdmissionPolicyBindingSpec spec = 2;
}
// ValidatingAdmissionPolicyBindingList is a list of ValidatingAdmissionPolicyBinding.
message ValidatingAdmissionPolicyBindingList {
- // Standard list metadata.
+ // metadata is the standard list metadata.
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
// +optional
optional .k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1;
@@ -620,9 +922,11 @@ message ValidatingAdmissionPolicyBindingList {
// ValidatingAdmissionPolicyBindingSpec is the specification of the ValidatingAdmissionPolicyBinding.
message ValidatingAdmissionPolicyBindingSpec {
- // PolicyName references a ValidatingAdmissionPolicy name which the ValidatingAdmissionPolicyBinding binds to.
+ // policyName references a ValidatingAdmissionPolicy name which the ValidatingAdmissionPolicyBinding binds to.
// If the referenced resource does not exist, this binding is considered invalid and will be ignored
// Required.
+ // +required
+ // +k8s:alpha(since: "1.36")=+k8s:required
optional string policyName = 1;
// paramRef specifies the parameter resource used to configure the admission control policy.
@@ -632,7 +936,7 @@ message ValidatingAdmissionPolicyBindingSpec {
// +optional
optional ParamRef paramRef = 2;
- // MatchResources declares what resources match this binding and will be validated by it.
+ // matchResources declares what resources match this binding and will be validated by it.
// Note that this is intersected with the policy's matchConstraints, so only requests that are matched by the policy can be selected by this.
// If this is unset, all resources matched by the policy are validated by this binding
// When resourceRules is unset, it does not constrain resource matching. If a resource is matched by the other fields of this object, it will be validated.
@@ -680,12 +984,14 @@ message ValidatingAdmissionPolicyBindingSpec {
//
// Required.
// +listType=set
+ // +required
+ // +k8s:alpha(since: "1.36")=+k8s:required
repeated string validationActions = 4;
}
// ValidatingAdmissionPolicyList is a list of ValidatingAdmissionPolicy.
message ValidatingAdmissionPolicyList {
- // Standard list metadata.
+ // metadata is the standard list metadata.
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
// +optional
optional .k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1;
@@ -696,21 +1002,21 @@ message ValidatingAdmissionPolicyList {
// ValidatingAdmissionPolicySpec is the specification of the desired behavior of the AdmissionPolicy.
message ValidatingAdmissionPolicySpec {
- // ParamKind specifies the kind of resources used to parameterize this policy.
+ // paramKind specifies the kind of resources used to parameterize this policy.
// If absent, there are no parameters for this policy and the param CEL variable will not be provided to validation expressions.
// If ParamKind refers to a non-existent kind, this policy definition is mis-configured and the FailurePolicy is applied.
// If paramKind is specified but paramRef is unset in ValidatingAdmissionPolicyBinding, the params variable will be null.
// +optional
optional ParamKind paramKind = 1;
- // MatchConstraints specifies what resources this policy is designed to validate.
+ // matchConstraints specifies what resources this policy is designed to validate.
// The AdmissionPolicy cares about a request if it matches _all_ Constraints.
// However, in order to prevent clusters from being put into an unstable state that cannot be recovered from via the API
// ValidatingAdmissionPolicy cannot match ValidatingAdmissionPolicy and ValidatingAdmissionPolicyBinding.
// Required.
optional MatchResources matchConstraints = 2;
- // Validations contain CEL expressions which is used to apply the validation.
+ // validations contain CEL expressions which is used to apply the validation.
// Validations and AuditAnnotations may not both be empty; a minimum of one Validations or AuditAnnotations is
// required.
// +listType=atomic
@@ -741,7 +1047,7 @@ message ValidatingAdmissionPolicySpec {
// +optional
repeated AuditAnnotation auditAnnotations = 5;
- // MatchConditions is a list of conditions that must be met for a request to be validated.
+ // matchConditions is a list of conditions that must be met for a request to be validated.
// Match conditions filter requests that have already been matched by the rules,
// namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests.
// There are a maximum of 64 match conditions allowed.
@@ -763,7 +1069,7 @@ message ValidatingAdmissionPolicySpec {
// +optional
repeated MatchCondition matchConditions = 6;
- // Variables contain definitions of variables that can be used in composition of other expressions.
+ // variables contain definitions of variables that can be used in composition of other expressions.
// Each variable is defined as a named CEL expression.
// The variables defined here will be available under `variables` in other expressions of the policy
// except MatchConditions because MatchConditions are evaluated before the rest of the policy.
@@ -780,16 +1086,16 @@ message ValidatingAdmissionPolicySpec {
// ValidatingAdmissionPolicyStatus represents the status of an admission validation policy.
message ValidatingAdmissionPolicyStatus {
- // The generation observed by the controller.
+ // observedGeneration is the generation observed by the controller.
// +optional
optional int64 observedGeneration = 1;
- // The results of type checking for each expression.
+ // typeChecking contains the results of type checking for each expression.
// Presence of this field indicates the completion of the type checking.
// +optional
optional TypeChecking typeChecking = 2;
- // The conditions represent the latest available observations of a policy's current state.
+ // conditions represent the latest available observations of a policy's current state.
// +optional
// +listType=map
// +listMapKey=type
@@ -798,18 +1104,18 @@ message ValidatingAdmissionPolicyStatus {
// ValidatingWebhook describes an admission webhook and the resources and operations it applies to.
message ValidatingWebhook {
- // The name of the admission webhook.
+ // name is the name of the admission webhook.
// Name should be fully qualified, e.g., imagepolicy.kubernetes.io, where
// "imagepolicy" is the name of the webhook, and kubernetes.io is the name
// of the organization.
// Required.
optional string name = 1;
- // ClientConfig defines how to communicate with the hook.
+ // clientConfig defines how to communicate with the hook.
// Required
optional WebhookClientConfig clientConfig = 2;
- // Rules describes what operations on what resources/subresources the webhook cares about.
+ // rules describes what operations on what resources/subresources the webhook cares about.
// The webhook cares about an operation if it matches _any_ Rule.
// However, in order to prevent ValidatingAdmissionWebhooks and MutatingAdmissionWebhooks
// from putting the cluster in a state which cannot be recovered from without completely
@@ -818,7 +1124,7 @@ message ValidatingWebhook {
// +listType=atomic
repeated RuleWithOperations rules = 3;
- // FailurePolicy defines how unrecognized errors from the admission endpoint are handled -
+ // failurePolicy defines how unrecognized errors from the admission endpoint are handled -
// allowed values are Ignore or Fail. Defaults to Fail.
// +optional
optional string failurePolicy = 4;
@@ -840,7 +1146,7 @@ message ValidatingWebhook {
// +optional
optional string matchPolicy = 9;
- // NamespaceSelector decides whether to run the webhook on an object based
+ // namespaceSelector decides whether to run the webhook on an object based
// on whether the namespace for that object matches the selector. If the
// object itself is a namespace, the matching is performed on
// object.metadata.labels. If the object is another cluster scoped resource,
@@ -886,7 +1192,7 @@ message ValidatingWebhook {
// +optional
optional .k8s.io.apimachinery.pkg.apis.meta.v1.LabelSelector namespaceSelector = 5;
- // ObjectSelector decides whether to run the webhook based on if the
+ // objectSelector decides whether to run the webhook based on if the
// object has matching labels. objectSelector is evaluated against both
// the oldObject and newObject that would be sent to the webhook, and
// is considered to match if either object matches the selector. A null
@@ -900,7 +1206,7 @@ message ValidatingWebhook {
// +optional
optional .k8s.io.apimachinery.pkg.apis.meta.v1.LabelSelector objectSelector = 10;
- // SideEffects states whether this webhook has side effects.
+ // sideEffects states whether this webhook has side effects.
// Acceptable values are: None, NoneOnDryRun (webhooks created via v1beta1 may also specify Some or Unknown).
// Webhooks with side effects MUST implement a reconciliation system, since a request may be
// rejected by a future step in the admission chain and the side effects therefore need to be undone.
@@ -908,7 +1214,7 @@ message ValidatingWebhook {
// sideEffects == Unknown or Some.
optional string sideEffects = 6;
- // TimeoutSeconds specifies the timeout for this webhook. After the timeout passes,
+ // timeoutSeconds specifies the timeout for this webhook. After the timeout passes,
// the webhook call will be ignored or the API call will fail based on the
// failure policy.
// The timeout value must be between 1 and 30 seconds.
@@ -916,7 +1222,7 @@ message ValidatingWebhook {
// +optional
optional int32 timeoutSeconds = 7;
- // AdmissionReviewVersions is an ordered list of preferred `AdmissionReview`
+ // admissionReviewVersions is an ordered list of preferred `AdmissionReview`
// versions the Webhook expects. API server will try to use first version in
// the list which it supports. If none of the versions specified in this list
// supported by API server, validation will fail for this object.
@@ -926,7 +1232,7 @@ message ValidatingWebhook {
// +listType=atomic
repeated string admissionReviewVersions = 8;
- // MatchConditions is a list of conditions that must be met for a request to be sent to this
+ // matchConditions is a list of conditions that must be met for a request to be sent to this
// webhook. Match conditions filter requests that have already been matched by the rules,
// namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests.
// There are a maximum of 64 match conditions allowed.
@@ -948,11 +1254,11 @@ message ValidatingWebhook {
// ValidatingWebhookConfiguration describes the configuration of and admission webhook that accept or reject and object without changing it.
message ValidatingWebhookConfiguration {
- // Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.
+ // metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.
// +optional
optional .k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1;
- // Webhooks is a list of webhooks and the affected resources and operations.
+ // webhooks is a list of webhooks and the affected resources and operations.
// +optional
// +patchMergeKey=name
// +patchStrategy=merge
@@ -963,7 +1269,7 @@ message ValidatingWebhookConfiguration {
// ValidatingWebhookConfigurationList is a list of ValidatingWebhookConfiguration.
message ValidatingWebhookConfigurationList {
- // Standard list metadata.
+ // metadata is the standard list metadata.
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
// +optional
optional .k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1;
@@ -974,7 +1280,7 @@ message ValidatingWebhookConfigurationList {
// Validation specifies the CEL expression which is used to apply the validation.
message Validation {
- // Expression represents the expression which will be evaluated by CEL.
+ // expression represents the expression which will be evaluated by CEL.
// ref: https://github.com/google/cel-spec
// CEL expressions have access to the contents of the API request/response, organized into CEL variables as well as some other useful variables:
//
@@ -1017,7 +1323,7 @@ message Validation {
// Required.
optional string Expression = 1;
- // Message represents the message displayed when validation fails. The message is required if the Expression contains
+ // message represents the message displayed when validation fails. The message is required if the Expression contains
// line breaks. The message must not contain line breaks.
// If unset, the message is "failed rule: {Rule}".
// e.g. "must be a URL with the host matching spec.host"
@@ -1027,7 +1333,7 @@ message Validation {
// +optional
optional string message = 2;
- // Reason represents a machine-readable description of why this validation failed.
+ // reason represents a machine-readable description of why this validation failed.
// If this is the first validation in the list to fail, this reason, as well as the
// corresponding HTTP response code, are used in the
// HTTP response to the client.
@@ -1053,12 +1359,12 @@ message Validation {
// Variable is the definition of a variable that is used for composition. A variable is defined as a named expression.
// +structType=atomic
message Variable {
- // Name is the name of the variable. The name must be a valid CEL identifier and unique among all variables.
+ // name is the name of the variable. The name must be a valid CEL identifier and unique among all variables.
// The variable can be accessed in other expressions through `variables`
// For example, if name is "foo", the variable will be available as `variables.foo`
optional string Name = 1;
- // Expression is the expression that will be evaluated as the value of the variable.
+ // expression is the expression that will be evaluated as the value of the variable.
// The CEL expression has access to the same identifiers as the CEL expressions in Validation.
optional string Expression = 2;
}
@@ -1066,7 +1372,7 @@ message Variable {
// WebhookClientConfig contains the information to make a TLS
// connection with the webhook
message WebhookClientConfig {
- // `url` gives the location of the webhook, in standard URL form
+ // url gives the location of the webhook, in standard URL form
// (`scheme://host:port/path`). Exactly one of `url` or `service`
// must be specified.
//
@@ -1095,7 +1401,7 @@ message WebhookClientConfig {
// +optional
optional string url = 3;
- // `service` is a reference to the service for this webhook. Either
+ // service is a reference to the service for this webhook. Either
// `service` or `url` must be specified.
//
// If the webhook is running within the cluster, then you should use `service`.
@@ -1103,7 +1409,7 @@ message WebhookClientConfig {
// +optional
optional ServiceReference service = 1;
- // `caBundle` is a PEM encoded CA bundle which will be used to validate the webhook's server certificate.
+ // caBundle is a PEM encoded CA bundle which will be used to validate the webhook's server certificate.
// If unspecified, system trust roots on the apiserver are used.
// +optional
optional bytes caBundle = 2;
diff --git a/vendor/k8s.io/api/admissionregistration/v1/generated.protomessage.pb.go b/vendor/k8s.io/api/admissionregistration/v1/generated.protomessage.pb.go
deleted file mode 100644
index 04a23c597..000000000
--- a/vendor/k8s.io/api/admissionregistration/v1/generated.protomessage.pb.go
+++ /dev/null
@@ -1,76 +0,0 @@
-//go:build kubernetes_protomessage_one_more_release
-// +build kubernetes_protomessage_one_more_release
-
-/*
-Copyright The Kubernetes Authors.
-
-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.
-*/
-
-// Code generated by go-to-protobuf. DO NOT EDIT.
-
-package v1
-
-func (*AuditAnnotation) ProtoMessage() {}
-
-func (*ExpressionWarning) ProtoMessage() {}
-
-func (*MatchCondition) ProtoMessage() {}
-
-func (*MatchResources) ProtoMessage() {}
-
-func (*MutatingWebhook) ProtoMessage() {}
-
-func (*MutatingWebhookConfiguration) ProtoMessage() {}
-
-func (*MutatingWebhookConfigurationList) ProtoMessage() {}
-
-func (*NamedRuleWithOperations) ProtoMessage() {}
-
-func (*ParamKind) ProtoMessage() {}
-
-func (*ParamRef) ProtoMessage() {}
-
-func (*Rule) ProtoMessage() {}
-
-func (*RuleWithOperations) ProtoMessage() {}
-
-func (*ServiceReference) ProtoMessage() {}
-
-func (*TypeChecking) ProtoMessage() {}
-
-func (*ValidatingAdmissionPolicy) ProtoMessage() {}
-
-func (*ValidatingAdmissionPolicyBinding) ProtoMessage() {}
-
-func (*ValidatingAdmissionPolicyBindingList) ProtoMessage() {}
-
-func (*ValidatingAdmissionPolicyBindingSpec) ProtoMessage() {}
-
-func (*ValidatingAdmissionPolicyList) ProtoMessage() {}
-
-func (*ValidatingAdmissionPolicySpec) ProtoMessage() {}
-
-func (*ValidatingAdmissionPolicyStatus) ProtoMessage() {}
-
-func (*ValidatingWebhook) ProtoMessage() {}
-
-func (*ValidatingWebhookConfiguration) ProtoMessage() {}
-
-func (*ValidatingWebhookConfigurationList) ProtoMessage() {}
-
-func (*Validation) ProtoMessage() {}
-
-func (*Variable) ProtoMessage() {}
-
-func (*WebhookClientConfig) ProtoMessage() {}
diff --git a/vendor/k8s.io/api/admissionregistration/v1/register.go b/vendor/k8s.io/api/admissionregistration/v1/register.go
index da74379ce..c1137d2bd 100644
--- a/vendor/k8s.io/api/admissionregistration/v1/register.go
+++ b/vendor/k8s.io/api/admissionregistration/v1/register.go
@@ -54,6 +54,10 @@ func addKnownTypes(scheme *runtime.Scheme) error {
&ValidatingAdmissionPolicyList{},
&ValidatingAdmissionPolicyBinding{},
&ValidatingAdmissionPolicyBindingList{},
+ &MutatingAdmissionPolicy{},
+ &MutatingAdmissionPolicyList{},
+ &MutatingAdmissionPolicyBinding{},
+ &MutatingAdmissionPolicyBindingList{},
)
metav1.AddToGroupVersion(scheme, SchemeGroupVersion)
return nil
diff --git a/vendor/k8s.io/api/admissionregistration/v1/types.go b/vendor/k8s.io/api/admissionregistration/v1/types.go
index 311c05c0f..f7a07b645 100644
--- a/vendor/k8s.io/api/admissionregistration/v1/types.go
+++ b/vendor/k8s.io/api/admissionregistration/v1/types.go
@@ -23,19 +23,19 @@ import (
// Rule is a tuple of APIGroups, APIVersion, and Resources.It is recommended
// to make sure that all the tuple expansions are valid.
type Rule struct {
- // APIGroups is the API groups the resources belong to. '*' is all groups.
+ // apiGroups is the API groups the resources belong to. '*' is all groups.
// If '*' is present, the length of the slice must be one.
// Required.
// +listType=atomic
APIGroups []string `json:"apiGroups,omitempty" protobuf:"bytes,1,rep,name=apiGroups"`
- // APIVersions is the API versions the resources belong to. '*' is all versions.
+ // apiVersions is the API versions the resources belong to. '*' is all versions.
// If '*' is present, the length of the slice must be one.
// Required.
// +listType=atomic
APIVersions []string `json:"apiVersions,omitempty" protobuf:"bytes,2,rep,name=apiVersions"`
- // Resources is a list of resources this rule applies to.
+ // resources is a list of resources this rule applies to.
//
// For example:
// 'pods' means pods.
@@ -141,12 +141,12 @@ const (
// ValidatingAdmissionPolicy describes the definition of an admission validation policy that accepts or rejects an object without changing it.
type ValidatingAdmissionPolicy struct {
metav1.TypeMeta `json:",inline"`
- // Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.
+ // metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.
// +optional
metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
- // Specification of the desired behavior of the ValidatingAdmissionPolicy.
+ // spec defines the desired behavior of the ValidatingAdmissionPolicy.
Spec ValidatingAdmissionPolicySpec `json:"spec,omitempty" protobuf:"bytes,2,opt,name=spec"`
- // The status of the ValidatingAdmissionPolicy, including warnings that are useful to determine if the policy
+ // status represents the current status of the ValidatingAdmissionPolicy, including warnings that are useful to determine if the policy
// behaves in the expected way.
// Populated by the system.
// Read-only.
@@ -156,14 +156,14 @@ type ValidatingAdmissionPolicy struct {
// ValidatingAdmissionPolicyStatus represents the status of an admission validation policy.
type ValidatingAdmissionPolicyStatus struct {
- // The generation observed by the controller.
+ // observedGeneration is the generation observed by the controller.
// +optional
ObservedGeneration int64 `json:"observedGeneration,omitempty" protobuf:"varint,1,opt,name=observedGeneration"`
- // The results of type checking for each expression.
+ // typeChecking contains the results of type checking for each expression.
// Presence of this field indicates the completion of the type checking.
// +optional
TypeChecking *TypeChecking `json:"typeChecking,omitempty" protobuf:"bytes,2,opt,name=typeChecking"`
- // The conditions represent the latest available observations of a policy's current state.
+ // conditions represent the latest available observations of a policy's current state.
// +optional
// +listType=map
// +listMapKey=type
@@ -176,7 +176,7 @@ type ValidatingAdmissionPolicyConditionType string
// TypeChecking contains results of type checking the expressions in the
// ValidatingAdmissionPolicy
type TypeChecking struct {
- // The type checking warnings for each expression.
+ // expressionWarnings contains the type checking warnings for each expression.
// +optional
// +listType=atomic
ExpressionWarnings []ExpressionWarning `json:"expressionWarnings,omitempty" protobuf:"bytes,1,rep,name=expressionWarnings"`
@@ -184,11 +184,11 @@ type TypeChecking struct {
// ExpressionWarning is a warning information that targets a specific expression.
type ExpressionWarning struct {
- // The path to the field that refers the expression.
+ // fieldRef is the path to the field that refers to the expression.
// For example, the reference to the expression of the first item of
// validations is "spec.validations[0].expression"
FieldRef string `json:"fieldRef" protobuf:"bytes,2,opt,name=fieldRef"`
- // The content of type checking information in a human-readable form.
+ // warning contains the content of type checking information in a human-readable form.
// Each line of the warning contains the type that the expression is checked
// against, followed by the type check error from the compiler.
Warning string `json:"warning" protobuf:"bytes,3,opt,name=warning"`
@@ -200,7 +200,7 @@ type ExpressionWarning struct {
// ValidatingAdmissionPolicyList is a list of ValidatingAdmissionPolicy.
type ValidatingAdmissionPolicyList struct {
metav1.TypeMeta `json:",inline"`
- // Standard list metadata.
+ // metadata is the standard list metadata.
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
// +optional
metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
@@ -210,21 +210,21 @@ type ValidatingAdmissionPolicyList struct {
// ValidatingAdmissionPolicySpec is the specification of the desired behavior of the AdmissionPolicy.
type ValidatingAdmissionPolicySpec struct {
- // ParamKind specifies the kind of resources used to parameterize this policy.
+ // paramKind specifies the kind of resources used to parameterize this policy.
// If absent, there are no parameters for this policy and the param CEL variable will not be provided to validation expressions.
// If ParamKind refers to a non-existent kind, this policy definition is mis-configured and the FailurePolicy is applied.
// If paramKind is specified but paramRef is unset in ValidatingAdmissionPolicyBinding, the params variable will be null.
// +optional
ParamKind *ParamKind `json:"paramKind,omitempty" protobuf:"bytes,1,rep,name=paramKind"`
- // MatchConstraints specifies what resources this policy is designed to validate.
+ // matchConstraints specifies what resources this policy is designed to validate.
// The AdmissionPolicy cares about a request if it matches _all_ Constraints.
// However, in order to prevent clusters from being put into an unstable state that cannot be recovered from via the API
// ValidatingAdmissionPolicy cannot match ValidatingAdmissionPolicy and ValidatingAdmissionPolicyBinding.
// Required.
MatchConstraints *MatchResources `json:"matchConstraints,omitempty" protobuf:"bytes,2,rep,name=matchConstraints"`
- // Validations contain CEL expressions which is used to apply the validation.
+ // validations contain CEL expressions which is used to apply the validation.
// Validations and AuditAnnotations may not both be empty; a minimum of one Validations or AuditAnnotations is
// required.
// +listType=atomic
@@ -255,7 +255,7 @@ type ValidatingAdmissionPolicySpec struct {
// +optional
AuditAnnotations []AuditAnnotation `json:"auditAnnotations,omitempty" protobuf:"bytes,5,rep,name=auditAnnotations"`
- // MatchConditions is a list of conditions that must be met for a request to be validated.
+ // matchConditions is a list of conditions that must be met for a request to be validated.
// Match conditions filter requests that have already been matched by the rules,
// namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests.
// There are a maximum of 64 match conditions allowed.
@@ -277,7 +277,7 @@ type ValidatingAdmissionPolicySpec struct {
// +optional
MatchConditions []MatchCondition `json:"matchConditions,omitempty" patchStrategy:"merge" patchMergeKey:"name" protobuf:"bytes,6,rep,name=matchConditions"`
- // Variables contain definitions of variables that can be used in composition of other expressions.
+ // variables contain definitions of variables that can be used in composition of other expressions.
// Each variable is defined as a named CEL expression.
// The variables defined here will be available under `variables` in other expressions of the policy
// except MatchConditions because MatchConditions are evaluated before the rest of the policy.
@@ -295,19 +295,19 @@ type ValidatingAdmissionPolicySpec struct {
// ParamKind is a tuple of Group Kind and Version.
// +structType=atomic
type ParamKind struct {
- // APIVersion is the API group version the resources belong to.
+ // apiVersion is the API group version the resources belong to.
// In format of "group/version".
// Required.
APIVersion string `json:"apiVersion,omitempty" protobuf:"bytes,1,rep,name=apiVersion"`
- // Kind is the API kind the resources belong to.
+ // kind is the API kind the resources belong to.
// Required.
Kind string `json:"kind,omitempty" protobuf:"bytes,2,rep,name=kind"`
}
// Validation specifies the CEL expression which is used to apply the validation.
type Validation struct {
- // Expression represents the expression which will be evaluated by CEL.
+ // expression represents the expression which will be evaluated by CEL.
// ref: https://github.com/google/cel-spec
// CEL expressions have access to the contents of the API request/response, organized into CEL variables as well as some other useful variables:
//
@@ -349,7 +349,7 @@ type Validation struct {
// non-intersecting keys are appended, retaining their partial order.
// Required.
Expression string `json:"expression" protobuf:"bytes,1,opt,name=Expression"`
- // Message represents the message displayed when validation fails. The message is required if the Expression contains
+ // message represents the message displayed when validation fails. The message is required if the Expression contains
// line breaks. The message must not contain line breaks.
// If unset, the message is "failed rule: {Rule}".
// e.g. "must be a URL with the host matching spec.host"
@@ -358,7 +358,7 @@ type Validation struct {
// If unset, the message is "failed Expression: {Expression}".
// +optional
Message string `json:"message,omitempty" protobuf:"bytes,2,opt,name=message"`
- // Reason represents a machine-readable description of why this validation failed.
+ // reason represents a machine-readable description of why this validation failed.
// If this is the first validation in the list to fail, this reason, as well as the
// corresponding HTTP response code, are used in the
// HTTP response to the client.
@@ -383,12 +383,12 @@ type Validation struct {
// Variable is the definition of a variable that is used for composition. A variable is defined as a named expression.
// +structType=atomic
type Variable struct {
- // Name is the name of the variable. The name must be a valid CEL identifier and unique among all variables.
+ // name is the name of the variable. The name must be a valid CEL identifier and unique among all variables.
// The variable can be accessed in other expressions through `variables`
// For example, if name is "foo", the variable will be available as `variables.foo`
Name string `json:"name" protobuf:"bytes,1,opt,name=Name"`
- // Expression is the expression that will be evaluated as the value of the variable.
+ // expression is the expression that will be evaluated as the value of the variable.
// The CEL expression has access to the same identifiers as the CEL expressions in Validation.
Expression string `json:"expression" protobuf:"bytes,2,opt,name=Expression"`
}
@@ -448,10 +448,11 @@ type AuditAnnotation struct {
// given (policy, binding, param) combination is within its own CEL budget.
type ValidatingAdmissionPolicyBinding struct {
metav1.TypeMeta `json:",inline"`
- // Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.
+ // metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.
// +optional
metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
- // Specification of the desired behavior of the ValidatingAdmissionPolicyBinding.
+ // spec defines the desired behavior of the ValidatingAdmissionPolicyBinding.
+ // +required
Spec ValidatingAdmissionPolicyBindingSpec `json:"spec,omitempty" protobuf:"bytes,2,opt,name=spec"`
}
@@ -461,7 +462,7 @@ type ValidatingAdmissionPolicyBinding struct {
// ValidatingAdmissionPolicyBindingList is a list of ValidatingAdmissionPolicyBinding.
type ValidatingAdmissionPolicyBindingList struct {
metav1.TypeMeta `json:",inline"`
- // Standard list metadata.
+ // metadata is the standard list metadata.
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
// +optional
metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
@@ -471,9 +472,11 @@ type ValidatingAdmissionPolicyBindingList struct {
// ValidatingAdmissionPolicyBindingSpec is the specification of the ValidatingAdmissionPolicyBinding.
type ValidatingAdmissionPolicyBindingSpec struct {
- // PolicyName references a ValidatingAdmissionPolicy name which the ValidatingAdmissionPolicyBinding binds to.
+ // policyName references a ValidatingAdmissionPolicy name which the ValidatingAdmissionPolicyBinding binds to.
// If the referenced resource does not exist, this binding is considered invalid and will be ignored
// Required.
+ // +required
+ // +k8s:alpha(since: "1.36")=+k8s:required
PolicyName string `json:"policyName,omitempty" protobuf:"bytes,1,rep,name=policyName"`
// paramRef specifies the parameter resource used to configure the admission control policy.
@@ -483,7 +486,7 @@ type ValidatingAdmissionPolicyBindingSpec struct {
// +optional
ParamRef *ParamRef `json:"paramRef,omitempty" protobuf:"bytes,2,rep,name=paramRef"`
- // MatchResources declares what resources match this binding and will be validated by it.
+ // matchResources declares what resources match this binding and will be validated by it.
// Note that this is intersected with the policy's matchConstraints, so only requests that are matched by the policy can be selected by this.
// If this is unset, all resources matched by the policy are validated by this binding
// When resourceRules is unset, it does not constrain resource matching. If a resource is matched by the other fields of this object, it will be validated.
@@ -531,6 +534,8 @@ type ValidatingAdmissionPolicyBindingSpec struct {
//
// Required.
// +listType=set
+ // +required
+ // +k8s:alpha(since: "1.36")=+k8s:required
ValidationActions []ValidationAction `json:"validationActions,omitempty" protobuf:"bytes,4,rep,name=validationActions"`
}
@@ -579,7 +584,7 @@ type ParamRef struct {
// +optional
Selector *metav1.LabelSelector `json:"selector,omitempty" protobuf:"bytes,3,rep,name=selector"`
- // `parameterNotFoundAction` controls the behavior of the binding when the resource
+ // parameterNotFoundAction controls the behavior of the binding when the resource
// exists, and name or selector is valid, but there are no parameters
// matched by the binding. If the value is set to `Allow`, then no
// matched parameters will be treated as successful validation by the binding.
@@ -597,7 +602,7 @@ type ParamRef struct {
// The exclude rules take precedence over include rules (if a resource matches both, it is excluded)
// +structType=atomic
type MatchResources struct {
- // NamespaceSelector decides whether to run the admission control policy on an object based
+ // namespaceSelector decides whether to run the admission control policy on an object based
// on whether the namespace for that object matches the selector. If the
// object itself is a namespace, the matching is performed on
// object.metadata.labels. If the object is another cluster scoped resource,
@@ -642,7 +647,7 @@ type MatchResources struct {
// Default to the empty LabelSelector, which matches everything.
// +optional
NamespaceSelector *metav1.LabelSelector `json:"namespaceSelector,omitempty" protobuf:"bytes,1,opt,name=namespaceSelector"`
- // ObjectSelector decides whether to run the validation based on if the
+ // objectSelector decides whether to run the validation based on if the
// object has matching labels. objectSelector is evaluated against both
// the oldObject and newObject that would be sent to the cel validation, and
// is considered to match if either object matches the selector. A null
@@ -655,12 +660,12 @@ type MatchResources struct {
// Default to the empty LabelSelector, which matches everything.
// +optional
ObjectSelector *metav1.LabelSelector `json:"objectSelector,omitempty" protobuf:"bytes,2,opt,name=objectSelector"`
- // ResourceRules describes what operations on what resources/subresources the ValidatingAdmissionPolicy matches.
+ // resourceRules describes what operations on what resources/subresources the ValidatingAdmissionPolicy matches.
// The policy cares about an operation if it matches _any_ Rule.
// +listType=atomic
// +optional
ResourceRules []NamedRuleWithOperations `json:"resourceRules,omitempty" protobuf:"bytes,3,rep,name=resourceRules"`
- // ExcludeResourceRules describes what operations on what resources/subresources the ValidatingAdmissionPolicy should not care about.
+ // excludeResourceRules describes what operations on what resources/subresources the ValidatingAdmissionPolicy should not care about.
// The exclude rules take precedence over include rules (if a resource matches both, it is excluded)
// +listType=atomic
// +optional
@@ -704,7 +709,7 @@ const (
// NamedRuleWithOperations is a tuple of Operations and Resources with ResourceNames.
// +structType=atomic
type NamedRuleWithOperations struct {
- // ResourceNames is an optional white list of names that the rule applies to. An empty set means that everything is allowed.
+ // resourceNames is an optional white list of names that the rule applies to. An empty set means that everything is allowed.
// +listType=atomic
// +optional
ResourceNames []string `json:"resourceNames,omitempty" protobuf:"bytes,1,rep,name=resourceNames"`
@@ -720,10 +725,10 @@ type NamedRuleWithOperations struct {
// ValidatingWebhookConfiguration describes the configuration of and admission webhook that accept or reject and object without changing it.
type ValidatingWebhookConfiguration struct {
metav1.TypeMeta `json:",inline"`
- // Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.
+ // metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.
// +optional
metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
- // Webhooks is a list of webhooks and the affected resources and operations.
+ // webhooks is a list of webhooks and the affected resources and operations.
// +optional
// +patchMergeKey=name
// +patchStrategy=merge
@@ -738,7 +743,7 @@ type ValidatingWebhookConfiguration struct {
// ValidatingWebhookConfigurationList is a list of ValidatingWebhookConfiguration.
type ValidatingWebhookConfigurationList struct {
metav1.TypeMeta `json:",inline"`
- // Standard list metadata.
+ // metadata is the standard list metadata.
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
// +optional
metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
@@ -754,10 +759,10 @@ type ValidatingWebhookConfigurationList struct {
// MutatingWebhookConfiguration describes the configuration of and admission webhook that accept or reject and may change the object.
type MutatingWebhookConfiguration struct {
metav1.TypeMeta `json:",inline"`
- // Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.
+ // metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.
// +optional
metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
- // Webhooks is a list of webhooks and the affected resources and operations.
+ // webhooks is a list of webhooks and the affected resources and operations.
// +optional
// +patchMergeKey=name
// +patchStrategy=merge
@@ -772,7 +777,7 @@ type MutatingWebhookConfiguration struct {
// MutatingWebhookConfigurationList is a list of MutatingWebhookConfiguration.
type MutatingWebhookConfigurationList struct {
metav1.TypeMeta `json:",inline"`
- // Standard list metadata.
+ // metadata is the standard list metadata.
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
// +optional
metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
@@ -782,18 +787,18 @@ type MutatingWebhookConfigurationList struct {
// ValidatingWebhook describes an admission webhook and the resources and operations it applies to.
type ValidatingWebhook struct {
- // The name of the admission webhook.
+ // name is the name of the admission webhook.
// Name should be fully qualified, e.g., imagepolicy.kubernetes.io, where
// "imagepolicy" is the name of the webhook, and kubernetes.io is the name
// of the organization.
// Required.
Name string `json:"name" protobuf:"bytes,1,opt,name=name"`
- // ClientConfig defines how to communicate with the hook.
+ // clientConfig defines how to communicate with the hook.
// Required
ClientConfig WebhookClientConfig `json:"clientConfig" protobuf:"bytes,2,opt,name=clientConfig"`
- // Rules describes what operations on what resources/subresources the webhook cares about.
+ // rules describes what operations on what resources/subresources the webhook cares about.
// The webhook cares about an operation if it matches _any_ Rule.
// However, in order to prevent ValidatingAdmissionWebhooks and MutatingAdmissionWebhooks
// from putting the cluster in a state which cannot be recovered from without completely
@@ -802,7 +807,7 @@ type ValidatingWebhook struct {
// +listType=atomic
Rules []RuleWithOperations `json:"rules,omitempty" protobuf:"bytes,3,rep,name=rules"`
- // FailurePolicy defines how unrecognized errors from the admission endpoint are handled -
+ // failurePolicy defines how unrecognized errors from the admission endpoint are handled -
// allowed values are Ignore or Fail. Defaults to Fail.
// +optional
FailurePolicy *FailurePolicyType `json:"failurePolicy,omitempty" protobuf:"bytes,4,opt,name=failurePolicy,casttype=FailurePolicyType"`
@@ -824,7 +829,7 @@ type ValidatingWebhook struct {
// +optional
MatchPolicy *MatchPolicyType `json:"matchPolicy,omitempty" protobuf:"bytes,9,opt,name=matchPolicy,casttype=MatchPolicyType"`
- // NamespaceSelector decides whether to run the webhook on an object based
+ // namespaceSelector decides whether to run the webhook on an object based
// on whether the namespace for that object matches the selector. If the
// object itself is a namespace, the matching is performed on
// object.metadata.labels. If the object is another cluster scoped resource,
@@ -870,7 +875,7 @@ type ValidatingWebhook struct {
// +optional
NamespaceSelector *metav1.LabelSelector `json:"namespaceSelector,omitempty" protobuf:"bytes,5,opt,name=namespaceSelector"`
- // ObjectSelector decides whether to run the webhook based on if the
+ // objectSelector decides whether to run the webhook based on if the
// object has matching labels. objectSelector is evaluated against both
// the oldObject and newObject that would be sent to the webhook, and
// is considered to match if either object matches the selector. A null
@@ -884,7 +889,7 @@ type ValidatingWebhook struct {
// +optional
ObjectSelector *metav1.LabelSelector `json:"objectSelector,omitempty" protobuf:"bytes,10,opt,name=objectSelector"`
- // SideEffects states whether this webhook has side effects.
+ // sideEffects states whether this webhook has side effects.
// Acceptable values are: None, NoneOnDryRun (webhooks created via v1beta1 may also specify Some or Unknown).
// Webhooks with side effects MUST implement a reconciliation system, since a request may be
// rejected by a future step in the admission chain and the side effects therefore need to be undone.
@@ -892,7 +897,7 @@ type ValidatingWebhook struct {
// sideEffects == Unknown or Some.
SideEffects *SideEffectClass `json:"sideEffects" protobuf:"bytes,6,opt,name=sideEffects,casttype=SideEffectClass"`
- // TimeoutSeconds specifies the timeout for this webhook. After the timeout passes,
+ // timeoutSeconds specifies the timeout for this webhook. After the timeout passes,
// the webhook call will be ignored or the API call will fail based on the
// failure policy.
// The timeout value must be between 1 and 30 seconds.
@@ -900,7 +905,7 @@ type ValidatingWebhook struct {
// +optional
TimeoutSeconds *int32 `json:"timeoutSeconds,omitempty" protobuf:"varint,7,opt,name=timeoutSeconds"`
- // AdmissionReviewVersions is an ordered list of preferred `AdmissionReview`
+ // admissionReviewVersions is an ordered list of preferred `AdmissionReview`
// versions the Webhook expects. API server will try to use first version in
// the list which it supports. If none of the versions specified in this list
// supported by API server, validation will fail for this object.
@@ -910,7 +915,7 @@ type ValidatingWebhook struct {
// +listType=atomic
AdmissionReviewVersions []string `json:"admissionReviewVersions" protobuf:"bytes,8,rep,name=admissionReviewVersions"`
- // MatchConditions is a list of conditions that must be met for a request to be sent to this
+ // matchConditions is a list of conditions that must be met for a request to be sent to this
// webhook. Match conditions filter requests that have already been matched by the rules,
// namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests.
// There are a maximum of 64 match conditions allowed.
@@ -932,18 +937,18 @@ type ValidatingWebhook struct {
// MutatingWebhook describes an admission webhook and the resources and operations it applies to.
type MutatingWebhook struct {
- // The name of the admission webhook.
+ // name is the name of the admission webhook.
// Name should be fully qualified, e.g., imagepolicy.kubernetes.io, where
// "imagepolicy" is the name of the webhook, and kubernetes.io is the name
// of the organization.
// Required.
Name string `json:"name" protobuf:"bytes,1,opt,name=name"`
- // ClientConfig defines how to communicate with the hook.
+ // clientConfig defines how to communicate with the hook.
// Required
ClientConfig WebhookClientConfig `json:"clientConfig" protobuf:"bytes,2,opt,name=clientConfig"`
- // Rules describes what operations on what resources/subresources the webhook cares about.
+ // rules describes what operations on what resources/subresources the webhook cares about.
// The webhook cares about an operation if it matches _any_ Rule.
// However, in order to prevent ValidatingAdmissionWebhooks and MutatingAdmissionWebhooks
// from putting the cluster in a state which cannot be recovered from without completely
@@ -952,7 +957,7 @@ type MutatingWebhook struct {
// +listType=atomic
Rules []RuleWithOperations `json:"rules,omitempty" protobuf:"bytes,3,rep,name=rules"`
- // FailurePolicy defines how unrecognized errors from the admission endpoint are handled -
+ // failurePolicy defines how unrecognized errors from the admission endpoint are handled -
// allowed values are Ignore or Fail. Defaults to Fail.
// +optional
FailurePolicy *FailurePolicyType `json:"failurePolicy,omitempty" protobuf:"bytes,4,opt,name=failurePolicy,casttype=FailurePolicyType"`
@@ -974,7 +979,7 @@ type MutatingWebhook struct {
// +optional
MatchPolicy *MatchPolicyType `json:"matchPolicy,omitempty" protobuf:"bytes,9,opt,name=matchPolicy,casttype=MatchPolicyType"`
- // NamespaceSelector decides whether to run the webhook on an object based
+ // namespaceSelector decides whether to run the webhook on an object based
// on whether the namespace for that object matches the selector. If the
// object itself is a namespace, the matching is performed on
// object.metadata.labels. If the object is another cluster scoped resource,
@@ -1020,7 +1025,7 @@ type MutatingWebhook struct {
// +optional
NamespaceSelector *metav1.LabelSelector `json:"namespaceSelector,omitempty" protobuf:"bytes,5,opt,name=namespaceSelector"`
- // ObjectSelector decides whether to run the webhook based on if the
+ // objectSelector decides whether to run the webhook based on if the
// object has matching labels. objectSelector is evaluated against both
// the oldObject and newObject that would be sent to the webhook, and
// is considered to match if either object matches the selector. A null
@@ -1034,7 +1039,7 @@ type MutatingWebhook struct {
// +optional
ObjectSelector *metav1.LabelSelector `json:"objectSelector,omitempty" protobuf:"bytes,11,opt,name=objectSelector"`
- // SideEffects states whether this webhook has side effects.
+ // sideEffects states whether this webhook has side effects.
// Acceptable values are: None, NoneOnDryRun (webhooks created via v1beta1 may also specify Some or Unknown).
// Webhooks with side effects MUST implement a reconciliation system, since a request may be
// rejected by a future step in the admission chain and the side effects therefore need to be undone.
@@ -1042,7 +1047,7 @@ type MutatingWebhook struct {
// sideEffects == Unknown or Some.
SideEffects *SideEffectClass `json:"sideEffects" protobuf:"bytes,6,opt,name=sideEffects,casttype=SideEffectClass"`
- // TimeoutSeconds specifies the timeout for this webhook. After the timeout passes,
+ // timeoutSeconds specifies the timeout for this webhook. After the timeout passes,
// the webhook call will be ignored or the API call will fail based on the
// failure policy.
// The timeout value must be between 1 and 30 seconds.
@@ -1050,7 +1055,7 @@ type MutatingWebhook struct {
// +optional
TimeoutSeconds *int32 `json:"timeoutSeconds,omitempty" protobuf:"varint,7,opt,name=timeoutSeconds"`
- // AdmissionReviewVersions is an ordered list of preferred `AdmissionReview`
+ // admissionReviewVersions is an ordered list of preferred `AdmissionReview`
// versions the Webhook expects. API server will try to use first version in
// the list which it supports. If none of the versions specified in this list
// supported by API server, validation will fail for this object.
@@ -1078,7 +1083,7 @@ type MutatingWebhook struct {
// +optional
ReinvocationPolicy *ReinvocationPolicyType `json:"reinvocationPolicy,omitempty" protobuf:"bytes,10,opt,name=reinvocationPolicy,casttype=ReinvocationPolicyType"`
- // MatchConditions is a list of conditions that must be met for a request to be sent to this
+ // matchConditions is a list of conditions that must be met for a request to be sent to this
// webhook. Match conditions filter requests that have already been matched by the rules,
// namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests.
// There are a maximum of 64 match conditions allowed.
@@ -1098,6 +1103,335 @@ type MutatingWebhook struct {
MatchConditions []MatchCondition `json:"matchConditions,omitempty" patchStrategy:"merge" patchMergeKey:"name" protobuf:"bytes,12,opt,name=matchConditions"`
}
+// +genclient
+// +genclient:nonNamespaced
+// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
+// +k8s:prerelease-lifecycle-gen:introduced=1.36
+
+// MutatingAdmissionPolicy describes the definition of an admission mutation policy that mutates the object coming into admission chain.
+type MutatingAdmissionPolicy struct {
+ metav1.TypeMeta `json:",inline"`
+ // metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.
+ // +optional
+ metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
+ // spec defines the desired behavior of the MutatingAdmissionPolicy.
+ Spec MutatingAdmissionPolicySpec `json:"spec,omitempty" protobuf:"bytes,2,opt,name=spec"`
+}
+
+// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
+// +k8s:prerelease-lifecycle-gen:introduced=1.36
+
+// MutatingAdmissionPolicyList is a list of MutatingAdmissionPolicy.
+type MutatingAdmissionPolicyList struct {
+ metav1.TypeMeta `json:",inline"`
+ // metadata is the standard list metadata.
+ // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
+ // +optional
+ metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
+ // List of ValidatingAdmissionPolicy.
+ Items []MutatingAdmissionPolicy `json:"items" protobuf:"bytes,2,rep,name=items"`
+}
+
+// MutatingAdmissionPolicySpec defines the desired behavior of the admission policy.
+type MutatingAdmissionPolicySpec struct {
+ // paramKind specifies the kind of resources used to parameterize this policy.
+ // If absent, there are no parameters for this policy and the param CEL variable will not be provided to validation expressions.
+ // If paramKind refers to a non-existent kind, this policy definition is mis-configured and the FailurePolicy is applied.
+ // If paramKind is specified but paramRef is unset in MutatingAdmissionPolicyBinding, the params variable will be null.
+ // +optional
+ ParamKind *ParamKind `json:"paramKind,omitempty" protobuf:"bytes,1,rep,name=paramKind"`
+
+ // matchConstraints specifies what resources this policy is designed to validate.
+ // The MutatingAdmissionPolicy cares about a request if it matches _all_ Constraints.
+ // However, in order to prevent clusters from being put into an unstable state that cannot be recovered from via the API
+ // MutatingAdmissionPolicy cannot match MutatingAdmissionPolicy and MutatingAdmissionPolicyBinding.
+ // The CREATE, UPDATE and CONNECT operations are allowed. The DELETE operation may not be matched.
+ // '*' matches CREATE, UPDATE and CONNECT.
+ // Required.
+ MatchConstraints *MatchResources `json:"matchConstraints,omitempty" protobuf:"bytes,2,rep,name=matchConstraints"`
+
+ // variables contain definitions of variables that can be used in composition of other expressions.
+ // Each variable is defined as a named CEL expression.
+ // The variables defined here will be available under `variables` in other expressions of the policy
+ // except matchConditions because matchConditions are evaluated before the rest of the policy.
+ //
+ // The expression of a variable can refer to other variables defined earlier in the list but not those after.
+ // Thus, variables must be sorted by the order of first appearance and acyclic.
+ // +listType=atomic
+ // +optional
+ Variables []Variable `json:"variables,omitempty" protobuf:"bytes,3,rep,name=variables"`
+
+ // mutations contain operations to perform on matching objects.
+ // mutations may not be empty; a minimum of one mutation is required.
+ // mutations are evaluated in order, and are reinvoked according to
+ // the reinvocationPolicy.
+ // The mutations of a policy are invoked for each binding of this policy
+ // and reinvocation of mutations occurs on a per binding basis.
+ //
+ // +listType=atomic
+ // +optional
+ Mutations []Mutation `json:"mutations,omitempty" protobuf:"bytes,4,rep,name=mutations"`
+
+ // failurePolicy defines how to handle failures for the admission policy. Failures can
+ // occur from CEL expression parse errors, type check errors, runtime errors and invalid
+ // or mis-configured policy definitions or bindings.
+ //
+ // A policy is invalid if paramKind refers to a non-existent Kind.
+ // A binding is invalid if paramRef.name refers to a non-existent resource.
+ //
+ // failurePolicy does not define how validations that evaluate to false are handled.
+ //
+ // Allowed values are Ignore or Fail. Defaults to Fail.
+ // +optional
+ FailurePolicy *FailurePolicyType `json:"failurePolicy,omitempty" protobuf:"bytes,5,opt,name=failurePolicy,casttype=FailurePolicyType"`
+
+ // matchConditions is a list of conditions that must be met for a request to be validated.
+ // Match conditions filter requests that have already been matched by the matchConstraints.
+ // An empty list of matchConditions matches all requests.
+ // There are a maximum of 64 match conditions allowed.
+ //
+ // If a parameter object is provided, it can be accessed via the `params` handle in the same
+ // manner as validation expressions.
+ //
+ // The exact matching logic is (in order):
+ // 1. If ANY matchCondition evaluates to FALSE, the policy is skipped.
+ // 2. If ALL matchConditions evaluate to TRUE, the policy is evaluated.
+ // 3. If any matchCondition evaluates to an error (but none are FALSE):
+ // - If failurePolicy=Fail, reject the request
+ // - If failurePolicy=Ignore, the policy is skipped
+ //
+ // +patchMergeKey=name
+ // +patchStrategy=merge
+ // +listType=map
+ // +listMapKey=name
+ // +optional
+ MatchConditions []MatchCondition `json:"matchConditions,omitempty" patchStrategy:"merge" patchMergeKey:"name" protobuf:"bytes,6,rep,name=matchConditions"`
+
+ // reinvocationPolicy indicates whether mutations may be called multiple times per MutatingAdmissionPolicyBinding
+ // as part of a single admission evaluation.
+ // Allowed values are "Never" and "IfNeeded".
+ //
+ // Never: These mutations will not be called more than once per binding in a single admission evaluation.
+ //
+ // IfNeeded: These mutations may be invoked more than once per binding for a single admission request and there is no guarantee of
+ // order with respect to other admission plugins, admission webhooks, bindings of this policy and admission policies. Mutations are only
+ // reinvoked when mutations change the object after this mutation is invoked.
+ // Required.
+ ReinvocationPolicy ReinvocationPolicyType `json:"reinvocationPolicy,omitempty" protobuf:"bytes,7,opt,name=reinvocationPolicy,casttype=ReinvocationPolicyType"`
+}
+
+// Mutation specifies the CEL expression which is used to apply the Mutation.
+type Mutation struct {
+ // patchType indicates the patch strategy used.
+ // Allowed values are "ApplyConfiguration" and "JSONPatch".
+ // Required.
+ //
+ // +unionDiscriminator
+ PatchType PatchType `json:"patchType" protobuf:"bytes,2,opt,name=patchType,casttype=PatchType"`
+
+ // applyConfiguration defines the desired configuration values of an object.
+ // The configuration is applied to the admission object using
+ // [structured merge diff](https://github.com/kubernetes-sigs/structured-merge-diff).
+ // A CEL expression is used to create apply configuration.
+ ApplyConfiguration *ApplyConfiguration `json:"applyConfiguration,omitempty" protobuf:"bytes,3,opt,name=applyConfiguration"`
+
+ // jsonPatch defines a [JSON patch](https://jsonpatch.com/) operation to perform a mutation to the object.
+ // A CEL expression is used to create the JSON patch.
+ JSONPatch *JSONPatch `json:"jsonPatch,omitempty" protobuf:"bytes,4,opt,name=jsonPatch"`
+}
+
+// PatchType specifies the type of patch operation for a mutation.
+// +enum
+type PatchType string
+
+const (
+ // ApplyConfiguration indicates that the mutation is using apply configuration to mutate the object.
+ PatchTypeApplyConfiguration PatchType = "ApplyConfiguration"
+ // JSONPatch indicates that the object is mutated through JSON Patch.
+ PatchTypeJSONPatch PatchType = "JSONPatch"
+)
+
+// ApplyConfiguration defines the desired configuration values of an object.
+type ApplyConfiguration struct {
+ // expression will be evaluated by CEL to create an apply configuration.
+ // ref: https://github.com/google/cel-spec
+ //
+ // Apply configurations are declared in CEL using object initialization. For example, this CEL expression
+ // returns an apply configuration to set a single field:
+ //
+ // Object{
+ // spec: Object.spec{
+ // serviceAccountName: "example"
+ // }
+ // }
+ //
+ // Apply configurations may not modify atomic structs, maps or arrays due to the risk of accidental deletion of
+ // values not included in the apply configuration.
+ //
+ // CEL expressions have access to the object types needed to create apply configurations:
+ //
+ // - 'Object' - CEL type of the resource object.
+ // - 'Object.' - CEL type of object field (such as 'Object.spec')
+ // - 'Object.....` - CEL type of nested field (such as 'Object.spec.containers')
+ //
+ // CEL expressions have access to the contents of the API request, organized into CEL variables as well as some other useful variables:
+ //
+ // - 'object' - The object from the incoming request. The value is null for DELETE requests.
+ // - 'oldObject' - The existing object. The value is null for CREATE requests.
+ // - 'request' - Attributes of the API request([ref](/pkg/apis/admission/types.go#AdmissionRequest)).
+ // - 'params' - Parameter resource referred to by the policy binding being evaluated. Only populated if the policy has a ParamKind.
+ // - 'namespaceObject' - The namespace object that the incoming object belongs to. The value is null for cluster-scoped resources.
+ // - 'variables' - Map of composited variables, from its name to its lazily evaluated value.
+ // For example, a variable named 'foo' can be accessed as 'variables.foo'.
+ // - 'authorizer' - A CEL Authorizer. May be used to perform authorization checks for the principal (user or service account) of the request.
+ // See https://pkg.go.dev/k8s.io/apiserver/pkg/cel/library#Authz
+ // - 'authorizer.requestResource' - A CEL ResourceCheck constructed from the 'authorizer' and configured with the
+ // request resource.
+ //
+ // The `apiVersion`, `kind`, `metadata.name` and `metadata.generateName` are always accessible from the root of the
+ // object. No other metadata properties are accessible.
+ //
+ // Only property names of the form `[a-zA-Z_.-/][a-zA-Z0-9_.-/]*` are accessible.
+ // Required.
+ Expression string `json:"expression,omitempty" protobuf:"bytes,1,opt,name=expression"`
+}
+
+// JSONPatch defines a JSON Patch.
+type JSONPatch struct {
+ // expression will be evaluated by CEL to create a [JSON patch](https://jsonpatch.com/).
+ // ref: https://github.com/google/cel-spec
+ //
+ // expression must return an array of JSONPatch values.
+ //
+ // For example, this CEL expression returns a JSON patch to conditionally modify a value:
+ //
+ // [
+ // JSONPatch{op: "test", path: "/spec/example", value: "Red"},
+ // JSONPatch{op: "replace", path: "/spec/example", value: "Green"}
+ // ]
+ //
+ // To define an object for the patch value, use Object types. For example:
+ //
+ // [
+ // JSONPatch{
+ // op: "add",
+ // path: "/spec/selector",
+ // value: Object.spec.selector{matchLabels: {"environment": "test"}}
+ // }
+ // ]
+ //
+ // To use strings containing '/' and '~' as JSONPatch path keys, use "jsonpatch.escapeKey". For example:
+ //
+ // [
+ // JSONPatch{
+ // op: "add",
+ // path: "/metadata/labels/" + jsonpatch.escapeKey("example.com/environment"),
+ // value: "test"
+ // },
+ // ]
+ //
+ // CEL expressions have access to the types needed to create JSON patches and objects:
+ //
+ // - 'JSONPatch' - CEL type of JSON Patch operations. JSONPatch has the fields 'op', 'from', 'path' and 'value'.
+ // See [JSON patch](https://jsonpatch.com/) for more details. The 'value' field may be set to any of: string,
+ // integer, array, map or object. If set, the 'path' and 'from' fields must be set to a
+ // [JSON pointer](https://datatracker.ietf.org/doc/html/rfc6901/) string, where the 'jsonpatch.escapeKey()' CEL
+ // function may be used to escape path keys containing '/' and '~'.
+ // - 'Object' - CEL type of the resource object.
+ // - 'Object.' - CEL type of object field (such as 'Object.spec')
+ // - 'Object.....` - CEL type of nested field (such as 'Object.spec.containers')
+ //
+ // CEL expressions have access to the contents of the API request, organized into CEL variables as well as some other useful variables:
+ //
+ // - 'object' - The object from the incoming request. The value is null for DELETE requests.
+ // - 'oldObject' - The existing object. The value is null for CREATE requests.
+ // - 'request' - Attributes of the API request([ref](/pkg/apis/admission/types.go#AdmissionRequest)).
+ // - 'params' - Parameter resource referred to by the policy binding being evaluated. Only populated if the policy has a ParamKind.
+ // - 'namespaceObject' - The namespace object that the incoming object belongs to. The value is null for cluster-scoped resources.
+ // - 'variables' - Map of composited variables, from its name to its lazily evaluated value.
+ // For example, a variable named 'foo' can be accessed as 'variables.foo'.
+ // - 'authorizer' - A CEL Authorizer. May be used to perform authorization checks for the principal (user or service account) of the request.
+ // See https://pkg.go.dev/k8s.io/apiserver/pkg/cel/library#Authz
+ // - 'authorizer.requestResource' - A CEL ResourceCheck constructed from the 'authorizer' and configured with the
+ // request resource.
+ //
+ // CEL expressions have access to [Kubernetes CEL function libraries](https://kubernetes.io/docs/reference/using-api/cel/#cel-options-language-features-and-libraries)
+ // as well as:
+ //
+ // - 'jsonpatch.escapeKey' - Performs JSONPatch key escaping. '~' and '/' are escaped as '~0' and `~1' respectively).
+ //
+ //
+ // Only property names of the form `[a-zA-Z_.-/][a-zA-Z0-9_.-/]*` are accessible.
+ // Required.
+ Expression string `json:"expression,omitempty" protobuf:"bytes,1,opt,name=expression"`
+}
+
+// +genclient
+// +genclient:nonNamespaced
+// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
+// +k8s:prerelease-lifecycle-gen:introduced=1.36
+
+// MutatingAdmissionPolicyBinding binds the MutatingAdmissionPolicy with parametrized resources.
+// MutatingAdmissionPolicyBinding and the optional parameter resource together define how cluster administrators
+// configure policies for clusters.
+//
+// For a given admission request, each binding will cause its policy to be
+// evaluated N times, where N is 1 for policies/bindings that don't use
+// params, otherwise N is the number of parameters selected by the binding.
+// Each evaluation is constrained by a [runtime cost budget](https://kubernetes.io/docs/reference/using-api/cel/#runtime-cost-budget).
+//
+// Adding/removing policies, bindings, or params can not affect whether a
+// given (policy, binding, param) combination is within its own CEL budget.
+type MutatingAdmissionPolicyBinding struct {
+ metav1.TypeMeta `json:",inline"`
+ // metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.
+ // +optional
+ metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
+ // spec defines the desired behavior of the MutatingAdmissionPolicyBinding.
+ Spec MutatingAdmissionPolicyBindingSpec `json:"spec,omitempty" protobuf:"bytes,2,opt,name=spec"`
+}
+
+// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
+// +k8s:prerelease-lifecycle-gen:introduced=1.36
+
+// MutatingAdmissionPolicyBindingList is a list of MutatingAdmissionPolicyBinding.
+type MutatingAdmissionPolicyBindingList struct {
+ metav1.TypeMeta `json:",inline"`
+ // metadata is the standard list metadata.
+ // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
+ // +optional
+ metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
+ // List of PolicyBinding.
+ Items []MutatingAdmissionPolicyBinding `json:"items" protobuf:"bytes,2,rep,name=items"`
+}
+
+// MutatingAdmissionPolicyBindingSpec defines the specification of the MutatingAdmissionPolicyBinding.
+type MutatingAdmissionPolicyBindingSpec struct {
+ // policyName references a MutatingAdmissionPolicy name which the MutatingAdmissionPolicyBinding binds to.
+ // If the referenced resource does not exist, this binding is considered invalid and will be ignored
+ // Required.
+ PolicyName string `json:"policyName,omitempty" protobuf:"bytes,1,rep,name=policyName"`
+
+ // paramRef specifies the parameter resource used to configure the admission control policy.
+ // It should point to a resource of the type specified in spec.ParamKind of the bound MutatingAdmissionPolicy.
+ // If the policy specifies a ParamKind and the resource referred to by ParamRef does not exist, this binding is considered mis-configured and the FailurePolicy of the MutatingAdmissionPolicy applied.
+ // If the policy does not specify a ParamKind then this field is ignored, and the rules are evaluated without a param.
+ // +optional
+ ParamRef *ParamRef `json:"paramRef,omitempty" protobuf:"bytes,2,rep,name=paramRef"`
+
+ // matchResources limits what resources match this binding and may be mutated by it.
+ // Note that if matchResources matches a resource, the resource must also match a policy's matchConstraints and
+ // matchConditions before the resource may be mutated.
+ // When matchResources is unset, it does not constrain resource matching, and only the policy's matchConstraints
+ // and matchConditions must match for the resource to be mutated.
+ // Additionally, matchResources.resourceRules are optional and do not constraint matching when unset.
+ // Note that this is differs from MutatingAdmissionPolicy matchConstraints, where resourceRules are required.
+ // The CREATE, UPDATE and CONNECT operations are allowed. The DELETE operation may not be matched.
+ // '*' matches CREATE, UPDATE and CONNECT.
+ // +optional
+ MatchResources *MatchResources `json:"matchResources,omitempty" protobuf:"bytes,3,rep,name=matchResources"`
+}
+
// ReinvocationPolicyType specifies what type of policy is used when other admission plugins also perform
// modifications.
// +enum
@@ -1116,7 +1450,7 @@ const (
// RuleWithOperations is a tuple of Operations and Resources. It is recommended to make
// sure that all the tuple expansions are valid.
type RuleWithOperations struct {
- // Operations is the operations the admission hook cares about - CREATE, UPDATE, DELETE, CONNECT or *
+ // operations is the operations the admission hook cares about - CREATE, UPDATE, DELETE, CONNECT or *
// for all of those operations and any future admission operations that are added.
// If '*' is present, the length of the slice must be one.
// Required.
@@ -1143,7 +1477,7 @@ const (
// WebhookClientConfig contains the information to make a TLS
// connection with the webhook
type WebhookClientConfig struct {
- // `url` gives the location of the webhook, in standard URL form
+ // url gives the location of the webhook, in standard URL form
// (`scheme://host:port/path`). Exactly one of `url` or `service`
// must be specified.
//
@@ -1172,7 +1506,7 @@ type WebhookClientConfig struct {
// +optional
URL *string `json:"url,omitempty" protobuf:"bytes,3,opt,name=url"`
- // `service` is a reference to the service for this webhook. Either
+ // service is a reference to the service for this webhook. Either
// `service` or `url` must be specified.
//
// If the webhook is running within the cluster, then you should use `service`.
@@ -1180,7 +1514,7 @@ type WebhookClientConfig struct {
// +optional
Service *ServiceReference `json:"service,omitempty" protobuf:"bytes,1,opt,name=service"`
- // `caBundle` is a PEM encoded CA bundle which will be used to validate the webhook's server certificate.
+ // caBundle is a PEM encoded CA bundle which will be used to validate the webhook's server certificate.
// If unspecified, system trust roots on the apiserver are used.
// +optional
CABundle []byte `json:"caBundle,omitempty" protobuf:"bytes,2,opt,name=caBundle"`
@@ -1188,19 +1522,19 @@ type WebhookClientConfig struct {
// ServiceReference holds a reference to Service.legacy.k8s.io
type ServiceReference struct {
- // `namespace` is the namespace of the service.
+ // namespace is the namespace of the service.
// Required
Namespace string `json:"namespace" protobuf:"bytes,1,opt,name=namespace"`
- // `name` is the name of the service.
+ // name is the name of the service.
// Required
Name string `json:"name" protobuf:"bytes,2,opt,name=name"`
- // `path` is an optional URL path which will be sent in any request to
+ // path is an optional URL path which will be sent in any request to
// this service.
// +optional
Path *string `json:"path,omitempty" protobuf:"bytes,3,opt,name=path"`
- // If specified, the port on the service that hosting webhook.
+ // port is the port on the service that hosts the webhook.
// Default to 443 for backward compatibility.
// `port` should be a valid port number (1-65535, inclusive).
// +optional
@@ -1209,7 +1543,7 @@ type ServiceReference struct {
// MatchCondition represents a condition which must by fulfilled for a request to be sent to a webhook.
type MatchCondition struct {
- // Name is an identifier for this match condition, used for strategic merging of MatchConditions,
+ // name is an identifier for this match condition, used for strategic merging of MatchConditions,
// as well as providing an identifier for logging purposes. A good name should be descriptive of
// the associated expression.
// Name must be a qualified name consisting of alphanumeric characters, '-', '_' or '.', and
@@ -1220,7 +1554,7 @@ type MatchCondition struct {
// Required.
Name string `json:"name" protobuf:"bytes,1,opt,name=name"`
- // Expression represents the expression which will be evaluated by CEL. Must evaluate to bool.
+ // expression represents the expression which will be evaluated by CEL. Must evaluate to bool.
// CEL expressions have access to the contents of the AdmissionRequest and Authorizer, organized into CEL variables:
//
// 'object' - The object from the incoming request. The value is null for DELETE requests.
diff --git a/vendor/k8s.io/api/admissionregistration/v1/types_swagger_doc_generated.go b/vendor/k8s.io/api/admissionregistration/v1/types_swagger_doc_generated.go
index f43139505..182f8ad0f 100644
--- a/vendor/k8s.io/api/admissionregistration/v1/types_swagger_doc_generated.go
+++ b/vendor/k8s.io/api/admissionregistration/v1/types_swagger_doc_generated.go
@@ -27,6 +27,15 @@ package v1
// Those methods can be generated by using hack/update-codegen.sh
// AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT.
+var map_ApplyConfiguration = map[string]string{
+ "": "ApplyConfiguration defines the desired configuration values of an object.",
+ "expression": "expression will be evaluated by CEL to create an apply configuration. ref: https://github.com/google/cel-spec\n\nApply configurations are declared in CEL using object initialization. For example, this CEL expression returns an apply configuration to set a single field:\n\n\tObject{\n\t spec: Object.spec{\n\t serviceAccountName: \"example\"\n\t }\n\t}\n\nApply configurations may not modify atomic structs, maps or arrays due to the risk of accidental deletion of values not included in the apply configuration.\n\nCEL expressions have access to the object types needed to create apply configurations:\n\n- 'Object' - CEL type of the resource object. - 'Object.' - CEL type of object field (such as 'Object.spec') - 'Object.....` - CEL type of nested field (such as 'Object.spec.containers')\n\nCEL expressions have access to the contents of the API request, organized into CEL variables as well as some other useful variables:\n\n- 'object' - The object from the incoming request. The value is null for DELETE requests. - 'oldObject' - The existing object. The value is null for CREATE requests. - 'request' - Attributes of the API request([ref](/pkg/apis/admission/types.go#AdmissionRequest)). - 'params' - Parameter resource referred to by the policy binding being evaluated. Only populated if the policy has a ParamKind. - 'namespaceObject' - The namespace object that the incoming object belongs to. The value is null for cluster-scoped resources. - 'variables' - Map of composited variables, from its name to its lazily evaluated value.\n For example, a variable named 'foo' can be accessed as 'variables.foo'.\n- 'authorizer' - A CEL Authorizer. May be used to perform authorization checks for the principal (user or service account) of the request.\n See https://pkg.go.dev/k8s.io/apiserver/pkg/cel/library#Authz\n- 'authorizer.requestResource' - A CEL ResourceCheck constructed from the 'authorizer' and configured with the\n request resource.\n\nThe `apiVersion`, `kind`, `metadata.name` and `metadata.generateName` are always accessible from the root of the object. No other metadata properties are accessible.\n\nOnly property names of the form `[a-zA-Z_.-/][a-zA-Z0-9_.-/]*` are accessible. Required.",
+}
+
+func (ApplyConfiguration) SwaggerDoc() map[string]string {
+ return map_ApplyConfiguration
+}
+
var map_AuditAnnotation = map[string]string{
"": "AuditAnnotation describes how to produce an audit annotation for an API request.",
"key": "key specifies the audit annotation key. The audit annotation keys of a ValidatingAdmissionPolicy must be unique. The key must be a qualified name ([A-Za-z0-9][-A-Za-z0-9_.]*) no more than 63 bytes in length.\n\nThe key is combined with the resource name of the ValidatingAdmissionPolicy to construct an audit annotation key: \"{ValidatingAdmissionPolicy name}/{key}\".\n\nIf an admission webhook uses the same resource name as this ValidatingAdmissionPolicy and the same audit annotation key, the annotation key will be identical. In this case, the first annotation written with the key will be included in the audit event and all subsequent annotations with the same key will be discarded.\n\nRequired.",
@@ -39,18 +48,27 @@ func (AuditAnnotation) SwaggerDoc() map[string]string {
var map_ExpressionWarning = map[string]string{
"": "ExpressionWarning is a warning information that targets a specific expression.",
- "fieldRef": "The path to the field that refers the expression. For example, the reference to the expression of the first item of validations is \"spec.validations[0].expression\"",
- "warning": "The content of type checking information in a human-readable form. Each line of the warning contains the type that the expression is checked against, followed by the type check error from the compiler.",
+ "fieldRef": "fieldRef is the path to the field that refers to the expression. For example, the reference to the expression of the first item of validations is \"spec.validations[0].expression\"",
+ "warning": "warning contains the content of type checking information in a human-readable form. Each line of the warning contains the type that the expression is checked against, followed by the type check error from the compiler.",
}
func (ExpressionWarning) SwaggerDoc() map[string]string {
return map_ExpressionWarning
}
+var map_JSONPatch = map[string]string{
+ "": "JSONPatch defines a JSON Patch.",
+ "expression": "expression will be evaluated by CEL to create a [JSON patch](https://jsonpatch.com/). ref: https://github.com/google/cel-spec\n\nexpression must return an array of JSONPatch values.\n\nFor example, this CEL expression returns a JSON patch to conditionally modify a value:\n\n\t [\n\t JSONPatch{op: \"test\", path: \"/spec/example\", value: \"Red\"},\n\t JSONPatch{op: \"replace\", path: \"/spec/example\", value: \"Green\"}\n\t ]\n\nTo define an object for the patch value, use Object types. For example:\n\n\t [\n\t JSONPatch{\n\t op: \"add\",\n\t path: \"/spec/selector\",\n\t value: Object.spec.selector{matchLabels: {\"environment\": \"test\"}}\n\t }\n\t ]\n\nTo use strings containing '/' and '~' as JSONPatch path keys, use \"jsonpatch.escapeKey\". For example:\n\n\t [\n\t JSONPatch{\n\t op: \"add\",\n\t path: \"/metadata/labels/\" + jsonpatch.escapeKey(\"example.com/environment\"),\n\t value: \"test\"\n\t },\n\t ]\n\nCEL expressions have access to the types needed to create JSON patches and objects:\n\n- 'JSONPatch' - CEL type of JSON Patch operations. JSONPatch has the fields 'op', 'from', 'path' and 'value'.\n See [JSON patch](https://jsonpatch.com/) for more details. The 'value' field may be set to any of: string,\n integer, array, map or object. If set, the 'path' and 'from' fields must be set to a\n [JSON pointer](https://datatracker.ietf.org/doc/html/rfc6901/) string, where the 'jsonpatch.escapeKey()' CEL\n function may be used to escape path keys containing '/' and '~'.\n- 'Object' - CEL type of the resource object. - 'Object.' - CEL type of object field (such as 'Object.spec') - 'Object.....` - CEL type of nested field (such as 'Object.spec.containers')\n\nCEL expressions have access to the contents of the API request, organized into CEL variables as well as some other useful variables:\n\n- 'object' - The object from the incoming request. The value is null for DELETE requests. - 'oldObject' - The existing object. The value is null for CREATE requests. - 'request' - Attributes of the API request([ref](/pkg/apis/admission/types.go#AdmissionRequest)). - 'params' - Parameter resource referred to by the policy binding being evaluated. Only populated if the policy has a ParamKind. - 'namespaceObject' - The namespace object that the incoming object belongs to. The value is null for cluster-scoped resources. - 'variables' - Map of composited variables, from its name to its lazily evaluated value.\n For example, a variable named 'foo' can be accessed as 'variables.foo'.\n- 'authorizer' - A CEL Authorizer. May be used to perform authorization checks for the principal (user or service account) of the request.\n See https://pkg.go.dev/k8s.io/apiserver/pkg/cel/library#Authz\n- 'authorizer.requestResource' - A CEL ResourceCheck constructed from the 'authorizer' and configured with the\n request resource.\n\nCEL expressions have access to [Kubernetes CEL function libraries](https://kubernetes.io/docs/reference/using-api/cel/#cel-options-language-features-and-libraries) as well as:\n\n- 'jsonpatch.escapeKey' - Performs JSONPatch key escaping. '~' and '/' are escaped as '~0' and `~1' respectively).\n\nOnly property names of the form `[a-zA-Z_.-/][a-zA-Z0-9_.-/]*` are accessible. Required.",
+}
+
+func (JSONPatch) SwaggerDoc() map[string]string {
+ return map_JSONPatch
+}
+
var map_MatchCondition = map[string]string{
"": "MatchCondition represents a condition which must by fulfilled for a request to be sent to a webhook.",
- "name": "Name is an identifier for this match condition, used for strategic merging of MatchConditions, as well as providing an identifier for logging purposes. A good name should be descriptive of the associated expression. Name must be a qualified name consisting of alphanumeric characters, '-', '_' or '.', and must start and end with an alphanumeric character (e.g. 'MyName', or 'my.name', or '123-abc', regex used for validation is '([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]') with an optional DNS subdomain prefix and '/' (e.g. 'example.com/MyName')\n\nRequired.",
- "expression": "Expression represents the expression which will be evaluated by CEL. Must evaluate to bool. CEL expressions have access to the contents of the AdmissionRequest and Authorizer, organized into CEL variables:\n\n'object' - The object from the incoming request. The value is null for DELETE requests. 'oldObject' - The existing object. The value is null for CREATE requests. 'request' - Attributes of the admission request(/pkg/apis/admission/types.go#AdmissionRequest). 'authorizer' - A CEL Authorizer. May be used to perform authorization checks for the principal (user or service account) of the request.\n See https://pkg.go.dev/k8s.io/apiserver/pkg/cel/library#Authz\n'authorizer.requestResource' - A CEL ResourceCheck constructed from the 'authorizer' and configured with the\n request resource.\nDocumentation on CEL: https://kubernetes.io/docs/reference/using-api/cel/\n\nRequired.",
+ "name": "name is an identifier for this match condition, used for strategic merging of MatchConditions, as well as providing an identifier for logging purposes. A good name should be descriptive of the associated expression. Name must be a qualified name consisting of alphanumeric characters, '-', '_' or '.', and must start and end with an alphanumeric character (e.g. 'MyName', or 'my.name', or '123-abc', regex used for validation is '([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]') with an optional DNS subdomain prefix and '/' (e.g. 'example.com/MyName')\n\nRequired.",
+ "expression": "expression represents the expression which will be evaluated by CEL. Must evaluate to bool. CEL expressions have access to the contents of the AdmissionRequest and Authorizer, organized into CEL variables:\n\n'object' - The object from the incoming request. The value is null for DELETE requests. 'oldObject' - The existing object. The value is null for CREATE requests. 'request' - Attributes of the admission request(/pkg/apis/admission/types.go#AdmissionRequest). 'authorizer' - A CEL Authorizer. May be used to perform authorization checks for the principal (user or service account) of the request.\n See https://pkg.go.dev/k8s.io/apiserver/pkg/cel/library#Authz\n'authorizer.requestResource' - A CEL ResourceCheck constructed from the 'authorizer' and configured with the\n request resource.\nDocumentation on CEL: https://kubernetes.io/docs/reference/using-api/cel/\n\nRequired.",
}
func (MatchCondition) SwaggerDoc() map[string]string {
@@ -59,10 +77,10 @@ func (MatchCondition) SwaggerDoc() map[string]string {
var map_MatchResources = map[string]string{
"": "MatchResources decides whether to run the admission control policy on an object based on whether it meets the match criteria. The exclude rules take precedence over include rules (if a resource matches both, it is excluded)",
- "namespaceSelector": "NamespaceSelector decides whether to run the admission control policy on an object based on whether the namespace for that object matches the selector. If the object itself is a namespace, the matching is performed on object.metadata.labels. If the object is another cluster scoped resource, it never skips the policy.\n\nFor example, to run the webhook on any objects whose namespace is not associated with \"runlevel\" of \"0\" or \"1\"; you will set the selector as follows: \"namespaceSelector\": {\n \"matchExpressions\": [\n {\n \"key\": \"runlevel\",\n \"operator\": \"NotIn\",\n \"values\": [\n \"0\",\n \"1\"\n ]\n }\n ]\n}\n\nIf instead you want to only run the policy on any objects whose namespace is associated with the \"environment\" of \"prod\" or \"staging\"; you will set the selector as follows: \"namespaceSelector\": {\n \"matchExpressions\": [\n {\n \"key\": \"environment\",\n \"operator\": \"In\",\n \"values\": [\n \"prod\",\n \"staging\"\n ]\n }\n ]\n}\n\nSee https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ for more examples of label selectors.\n\nDefault to the empty LabelSelector, which matches everything.",
- "objectSelector": "ObjectSelector decides whether to run the validation based on if the object has matching labels. objectSelector is evaluated against both the oldObject and newObject that would be sent to the cel validation, and is considered to match if either object matches the selector. A null object (oldObject in the case of create, or newObject in the case of delete) or an object that cannot have labels (like a DeploymentRollback or a PodProxyOptions object) is not considered to match. Use the object selector only if the webhook is opt-in, because end users may skip the admission webhook by setting the labels. Default to the empty LabelSelector, which matches everything.",
- "resourceRules": "ResourceRules describes what operations on what resources/subresources the ValidatingAdmissionPolicy matches. The policy cares about an operation if it matches _any_ Rule.",
- "excludeResourceRules": "ExcludeResourceRules describes what operations on what resources/subresources the ValidatingAdmissionPolicy should not care about. The exclude rules take precedence over include rules (if a resource matches both, it is excluded)",
+ "namespaceSelector": "namespaceSelector decides whether to run the admission control policy on an object based on whether the namespace for that object matches the selector. If the object itself is a namespace, the matching is performed on object.metadata.labels. If the object is another cluster scoped resource, it never skips the policy.\n\nFor example, to run the webhook on any objects whose namespace is not associated with \"runlevel\" of \"0\" or \"1\"; you will set the selector as follows: \"namespaceSelector\": {\n \"matchExpressions\": [\n {\n \"key\": \"runlevel\",\n \"operator\": \"NotIn\",\n \"values\": [\n \"0\",\n \"1\"\n ]\n }\n ]\n}\n\nIf instead you want to only run the policy on any objects whose namespace is associated with the \"environment\" of \"prod\" or \"staging\"; you will set the selector as follows: \"namespaceSelector\": {\n \"matchExpressions\": [\n {\n \"key\": \"environment\",\n \"operator\": \"In\",\n \"values\": [\n \"prod\",\n \"staging\"\n ]\n }\n ]\n}\n\nSee https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ for more examples of label selectors.\n\nDefault to the empty LabelSelector, which matches everything.",
+ "objectSelector": "objectSelector decides whether to run the validation based on if the object has matching labels. objectSelector is evaluated against both the oldObject and newObject that would be sent to the cel validation, and is considered to match if either object matches the selector. A null object (oldObject in the case of create, or newObject in the case of delete) or an object that cannot have labels (like a DeploymentRollback or a PodProxyOptions object) is not considered to match. Use the object selector only if the webhook is opt-in, because end users may skip the admission webhook by setting the labels. Default to the empty LabelSelector, which matches everything.",
+ "resourceRules": "resourceRules describes what operations on what resources/subresources the ValidatingAdmissionPolicy matches. The policy cares about an operation if it matches _any_ Rule.",
+ "excludeResourceRules": "excludeResourceRules describes what operations on what resources/subresources the ValidatingAdmissionPolicy should not care about. The exclude rules take precedence over include rules (if a resource matches both, it is excluded)",
"matchPolicy": "matchPolicy defines how the \"MatchResources\" list is used to match incoming requests. Allowed values are \"Exact\" or \"Equivalent\".\n\n- Exact: match a request only if it exactly matches a specified rule. For example, if deployments can be modified via apps/v1, apps/v1beta1, and extensions/v1beta1, but \"rules\" only included `apiGroups:[\"apps\"], apiVersions:[\"v1\"], resources: [\"deployments\"]`, a request to apps/v1beta1 or extensions/v1beta1 would not be sent to the ValidatingAdmissionPolicy.\n\n- Equivalent: match a request if modifies a resource listed in rules, even via another API group or version. For example, if deployments can be modified via apps/v1, apps/v1beta1, and extensions/v1beta1, and \"rules\" only included `apiGroups:[\"apps\"], apiVersions:[\"v1\"], resources: [\"deployments\"]`, a request to apps/v1beta1 or extensions/v1beta1 would be converted to apps/v1 and sent to the ValidatingAdmissionPolicy.\n\nDefaults to \"Equivalent\"",
}
@@ -70,20 +88,86 @@ func (MatchResources) SwaggerDoc() map[string]string {
return map_MatchResources
}
+var map_MutatingAdmissionPolicy = map[string]string{
+ "": "MutatingAdmissionPolicy describes the definition of an admission mutation policy that mutates the object coming into admission chain.",
+ "metadata": "metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.",
+ "spec": "spec defines the desired behavior of the MutatingAdmissionPolicy.",
+}
+
+func (MutatingAdmissionPolicy) SwaggerDoc() map[string]string {
+ return map_MutatingAdmissionPolicy
+}
+
+var map_MutatingAdmissionPolicyBinding = map[string]string{
+ "": "MutatingAdmissionPolicyBinding binds the MutatingAdmissionPolicy with parametrized resources. MutatingAdmissionPolicyBinding and the optional parameter resource together define how cluster administrators configure policies for clusters.\n\nFor a given admission request, each binding will cause its policy to be evaluated N times, where N is 1 for policies/bindings that don't use params, otherwise N is the number of parameters selected by the binding. Each evaluation is constrained by a [runtime cost budget](https://kubernetes.io/docs/reference/using-api/cel/#runtime-cost-budget).\n\nAdding/removing policies, bindings, or params can not affect whether a given (policy, binding, param) combination is within its own CEL budget.",
+ "metadata": "metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.",
+ "spec": "spec defines the desired behavior of the MutatingAdmissionPolicyBinding.",
+}
+
+func (MutatingAdmissionPolicyBinding) SwaggerDoc() map[string]string {
+ return map_MutatingAdmissionPolicyBinding
+}
+
+var map_MutatingAdmissionPolicyBindingList = map[string]string{
+ "": "MutatingAdmissionPolicyBindingList is a list of MutatingAdmissionPolicyBinding.",
+ "metadata": "metadata is the standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds",
+ "items": "List of PolicyBinding.",
+}
+
+func (MutatingAdmissionPolicyBindingList) SwaggerDoc() map[string]string {
+ return map_MutatingAdmissionPolicyBindingList
+}
+
+var map_MutatingAdmissionPolicyBindingSpec = map[string]string{
+ "": "MutatingAdmissionPolicyBindingSpec defines the specification of the MutatingAdmissionPolicyBinding.",
+ "policyName": "policyName references a MutatingAdmissionPolicy name which the MutatingAdmissionPolicyBinding binds to. If the referenced resource does not exist, this binding is considered invalid and will be ignored Required.",
+ "paramRef": "paramRef specifies the parameter resource used to configure the admission control policy. It should point to a resource of the type specified in spec.ParamKind of the bound MutatingAdmissionPolicy. If the policy specifies a ParamKind and the resource referred to by ParamRef does not exist, this binding is considered mis-configured and the FailurePolicy of the MutatingAdmissionPolicy applied. If the policy does not specify a ParamKind then this field is ignored, and the rules are evaluated without a param.",
+ "matchResources": "matchResources limits what resources match this binding and may be mutated by it. Note that if matchResources matches a resource, the resource must also match a policy's matchConstraints and matchConditions before the resource may be mutated. When matchResources is unset, it does not constrain resource matching, and only the policy's matchConstraints and matchConditions must match for the resource to be mutated. Additionally, matchResources.resourceRules are optional and do not constraint matching when unset. Note that this is differs from MutatingAdmissionPolicy matchConstraints, where resourceRules are required. The CREATE, UPDATE and CONNECT operations are allowed. The DELETE operation may not be matched. '*' matches CREATE, UPDATE and CONNECT.",
+}
+
+func (MutatingAdmissionPolicyBindingSpec) SwaggerDoc() map[string]string {
+ return map_MutatingAdmissionPolicyBindingSpec
+}
+
+var map_MutatingAdmissionPolicyList = map[string]string{
+ "": "MutatingAdmissionPolicyList is a list of MutatingAdmissionPolicy.",
+ "metadata": "metadata is the standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds",
+ "items": "List of ValidatingAdmissionPolicy.",
+}
+
+func (MutatingAdmissionPolicyList) SwaggerDoc() map[string]string {
+ return map_MutatingAdmissionPolicyList
+}
+
+var map_MutatingAdmissionPolicySpec = map[string]string{
+ "": "MutatingAdmissionPolicySpec defines the desired behavior of the admission policy.",
+ "paramKind": "paramKind specifies the kind of resources used to parameterize this policy. If absent, there are no parameters for this policy and the param CEL variable will not be provided to validation expressions. If paramKind refers to a non-existent kind, this policy definition is mis-configured and the FailurePolicy is applied. If paramKind is specified but paramRef is unset in MutatingAdmissionPolicyBinding, the params variable will be null.",
+ "matchConstraints": "matchConstraints specifies what resources this policy is designed to validate. The MutatingAdmissionPolicy cares about a request if it matches _all_ Constraints. However, in order to prevent clusters from being put into an unstable state that cannot be recovered from via the API MutatingAdmissionPolicy cannot match MutatingAdmissionPolicy and MutatingAdmissionPolicyBinding. The CREATE, UPDATE and CONNECT operations are allowed. The DELETE operation may not be matched. '*' matches CREATE, UPDATE and CONNECT. Required.",
+ "variables": "variables contain definitions of variables that can be used in composition of other expressions. Each variable is defined as a named CEL expression. The variables defined here will be available under `variables` in other expressions of the policy except matchConditions because matchConditions are evaluated before the rest of the policy.\n\nThe expression of a variable can refer to other variables defined earlier in the list but not those after. Thus, variables must be sorted by the order of first appearance and acyclic.",
+ "mutations": "mutations contain operations to perform on matching objects. mutations may not be empty; a minimum of one mutation is required. mutations are evaluated in order, and are reinvoked according to the reinvocationPolicy. The mutations of a policy are invoked for each binding of this policy and reinvocation of mutations occurs on a per binding basis.",
+ "failurePolicy": "failurePolicy defines how to handle failures for the admission policy. Failures can occur from CEL expression parse errors, type check errors, runtime errors and invalid or mis-configured policy definitions or bindings.\n\nA policy is invalid if paramKind refers to a non-existent Kind. A binding is invalid if paramRef.name refers to a non-existent resource.\n\nfailurePolicy does not define how validations that evaluate to false are handled.\n\nAllowed values are Ignore or Fail. Defaults to Fail.",
+ "matchConditions": "matchConditions is a list of conditions that must be met for a request to be validated. Match conditions filter requests that have already been matched by the matchConstraints. An empty list of matchConditions matches all requests. There are a maximum of 64 match conditions allowed.\n\nIf a parameter object is provided, it can be accessed via the `params` handle in the same manner as validation expressions.\n\nThe exact matching logic is (in order):\n 1. If ANY matchCondition evaluates to FALSE, the policy is skipped.\n 2. If ALL matchConditions evaluate to TRUE, the policy is evaluated.\n 3. If any matchCondition evaluates to an error (but none are FALSE):\n - If failurePolicy=Fail, reject the request\n - If failurePolicy=Ignore, the policy is skipped",
+ "reinvocationPolicy": "reinvocationPolicy indicates whether mutations may be called multiple times per MutatingAdmissionPolicyBinding as part of a single admission evaluation. Allowed values are \"Never\" and \"IfNeeded\".\n\nNever: These mutations will not be called more than once per binding in a single admission evaluation.\n\nIfNeeded: These mutations may be invoked more than once per binding for a single admission request and there is no guarantee of order with respect to other admission plugins, admission webhooks, bindings of this policy and admission policies. Mutations are only reinvoked when mutations change the object after this mutation is invoked. Required.",
+}
+
+func (MutatingAdmissionPolicySpec) SwaggerDoc() map[string]string {
+ return map_MutatingAdmissionPolicySpec
+}
+
var map_MutatingWebhook = map[string]string{
"": "MutatingWebhook describes an admission webhook and the resources and operations it applies to.",
- "name": "The name of the admission webhook. Name should be fully qualified, e.g., imagepolicy.kubernetes.io, where \"imagepolicy\" is the name of the webhook, and kubernetes.io is the name of the organization. Required.",
- "clientConfig": "ClientConfig defines how to communicate with the hook. Required",
- "rules": "Rules describes what operations on what resources/subresources the webhook cares about. The webhook cares about an operation if it matches _any_ Rule. However, in order to prevent ValidatingAdmissionWebhooks and MutatingAdmissionWebhooks from putting the cluster in a state which cannot be recovered from without completely disabling the plugin, ValidatingAdmissionWebhooks and MutatingAdmissionWebhooks are never called on admission requests for ValidatingWebhookConfiguration and MutatingWebhookConfiguration objects.",
- "failurePolicy": "FailurePolicy defines how unrecognized errors from the admission endpoint are handled - allowed values are Ignore or Fail. Defaults to Fail.",
+ "name": "name is the name of the admission webhook. Name should be fully qualified, e.g., imagepolicy.kubernetes.io, where \"imagepolicy\" is the name of the webhook, and kubernetes.io is the name of the organization. Required.",
+ "clientConfig": "clientConfig defines how to communicate with the hook. Required",
+ "rules": "rules describes what operations on what resources/subresources the webhook cares about. The webhook cares about an operation if it matches _any_ Rule. However, in order to prevent ValidatingAdmissionWebhooks and MutatingAdmissionWebhooks from putting the cluster in a state which cannot be recovered from without completely disabling the plugin, ValidatingAdmissionWebhooks and MutatingAdmissionWebhooks are never called on admission requests for ValidatingWebhookConfiguration and MutatingWebhookConfiguration objects.",
+ "failurePolicy": "failurePolicy defines how unrecognized errors from the admission endpoint are handled - allowed values are Ignore or Fail. Defaults to Fail.",
"matchPolicy": "matchPolicy defines how the \"rules\" list is used to match incoming requests. Allowed values are \"Exact\" or \"Equivalent\".\n\n- Exact: match a request only if it exactly matches a specified rule. For example, if deployments can be modified via apps/v1, apps/v1beta1, and extensions/v1beta1, but \"rules\" only included `apiGroups:[\"apps\"], apiVersions:[\"v1\"], resources: [\"deployments\"]`, a request to apps/v1beta1 or extensions/v1beta1 would not be sent to the webhook.\n\n- Equivalent: match a request if modifies a resource listed in rules, even via another API group or version. For example, if deployments can be modified via apps/v1, apps/v1beta1, and extensions/v1beta1, and \"rules\" only included `apiGroups:[\"apps\"], apiVersions:[\"v1\"], resources: [\"deployments\"]`, a request to apps/v1beta1 or extensions/v1beta1 would be converted to apps/v1 and sent to the webhook.\n\nDefaults to \"Equivalent\"",
- "namespaceSelector": "NamespaceSelector decides whether to run the webhook on an object based on whether the namespace for that object matches the selector. If the object itself is a namespace, the matching is performed on object.metadata.labels. If the object is another cluster scoped resource, it never skips the webhook.\n\nFor example, to run the webhook on any objects whose namespace is not associated with \"runlevel\" of \"0\" or \"1\"; you will set the selector as follows: \"namespaceSelector\": {\n \"matchExpressions\": [\n {\n \"key\": \"runlevel\",\n \"operator\": \"NotIn\",\n \"values\": [\n \"0\",\n \"1\"\n ]\n }\n ]\n}\n\nIf instead you want to only run the webhook on any objects whose namespace is associated with the \"environment\" of \"prod\" or \"staging\"; you will set the selector as follows: \"namespaceSelector\": {\n \"matchExpressions\": [\n {\n \"key\": \"environment\",\n \"operator\": \"In\",\n \"values\": [\n \"prod\",\n \"staging\"\n ]\n }\n ]\n}\n\nSee https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ for more examples of label selectors.\n\nDefault to the empty LabelSelector, which matches everything.",
- "objectSelector": "ObjectSelector decides whether to run the webhook based on if the object has matching labels. objectSelector is evaluated against both the oldObject and newObject that would be sent to the webhook, and is considered to match if either object matches the selector. A null object (oldObject in the case of create, or newObject in the case of delete) or an object that cannot have labels (like a DeploymentRollback or a PodProxyOptions object) is not considered to match. Use the object selector only if the webhook is opt-in, because end users may skip the admission webhook by setting the labels. Default to the empty LabelSelector, which matches everything.",
- "sideEffects": "SideEffects states whether this webhook has side effects. Acceptable values are: None, NoneOnDryRun (webhooks created via v1beta1 may also specify Some or Unknown). Webhooks with side effects MUST implement a reconciliation system, since a request may be rejected by a future step in the admission chain and the side effects therefore need to be undone. Requests with the dryRun attribute will be auto-rejected if they match a webhook with sideEffects == Unknown or Some.",
- "timeoutSeconds": "TimeoutSeconds specifies the timeout for this webhook. After the timeout passes, the webhook call will be ignored or the API call will fail based on the failure policy. The timeout value must be between 1 and 30 seconds. Default to 10 seconds.",
- "admissionReviewVersions": "AdmissionReviewVersions is an ordered list of preferred `AdmissionReview` versions the Webhook expects. API server will try to use first version in the list which it supports. If none of the versions specified in this list supported by API server, validation will fail for this object. If a persisted webhook configuration specifies allowed versions and does not include any versions known to the API Server, calls to the webhook will fail and be subject to the failure policy.",
+ "namespaceSelector": "namespaceSelector decides whether to run the webhook on an object based on whether the namespace for that object matches the selector. If the object itself is a namespace, the matching is performed on object.metadata.labels. If the object is another cluster scoped resource, it never skips the webhook.\n\nFor example, to run the webhook on any objects whose namespace is not associated with \"runlevel\" of \"0\" or \"1\"; you will set the selector as follows: \"namespaceSelector\": {\n \"matchExpressions\": [\n {\n \"key\": \"runlevel\",\n \"operator\": \"NotIn\",\n \"values\": [\n \"0\",\n \"1\"\n ]\n }\n ]\n}\n\nIf instead you want to only run the webhook on any objects whose namespace is associated with the \"environment\" of \"prod\" or \"staging\"; you will set the selector as follows: \"namespaceSelector\": {\n \"matchExpressions\": [\n {\n \"key\": \"environment\",\n \"operator\": \"In\",\n \"values\": [\n \"prod\",\n \"staging\"\n ]\n }\n ]\n}\n\nSee https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ for more examples of label selectors.\n\nDefault to the empty LabelSelector, which matches everything.",
+ "objectSelector": "objectSelector decides whether to run the webhook based on if the object has matching labels. objectSelector is evaluated against both the oldObject and newObject that would be sent to the webhook, and is considered to match if either object matches the selector. A null object (oldObject in the case of create, or newObject in the case of delete) or an object that cannot have labels (like a DeploymentRollback or a PodProxyOptions object) is not considered to match. Use the object selector only if the webhook is opt-in, because end users may skip the admission webhook by setting the labels. Default to the empty LabelSelector, which matches everything.",
+ "sideEffects": "sideEffects states whether this webhook has side effects. Acceptable values are: None, NoneOnDryRun (webhooks created via v1beta1 may also specify Some or Unknown). Webhooks with side effects MUST implement a reconciliation system, since a request may be rejected by a future step in the admission chain and the side effects therefore need to be undone. Requests with the dryRun attribute will be auto-rejected if they match a webhook with sideEffects == Unknown or Some.",
+ "timeoutSeconds": "timeoutSeconds specifies the timeout for this webhook. After the timeout passes, the webhook call will be ignored or the API call will fail based on the failure policy. The timeout value must be between 1 and 30 seconds. Default to 10 seconds.",
+ "admissionReviewVersions": "admissionReviewVersions is an ordered list of preferred `AdmissionReview` versions the Webhook expects. API server will try to use first version in the list which it supports. If none of the versions specified in this list supported by API server, validation will fail for this object. If a persisted webhook configuration specifies allowed versions and does not include any versions known to the API Server, calls to the webhook will fail and be subject to the failure policy.",
"reinvocationPolicy": "reinvocationPolicy indicates whether this webhook should be called multiple times as part of a single admission evaluation. Allowed values are \"Never\" and \"IfNeeded\".\n\nNever: the webhook will not be called more than once in a single admission evaluation.\n\nIfNeeded: the webhook will be called at least one additional time as part of the admission evaluation if the object being admitted is modified by other admission plugins after the initial webhook call. Webhooks that specify this option *must* be idempotent, able to process objects they previously admitted. Note: * the number of additional invocations is not guaranteed to be exactly one. * if additional invocations result in further modifications to the object, webhooks are not guaranteed to be invoked again. * webhooks that use this option may be reordered to minimize the number of additional invocations. * to validate an object after all mutations are guaranteed complete, use a validating admission webhook instead.\n\nDefaults to \"Never\".",
- "matchConditions": "MatchConditions is a list of conditions that must be met for a request to be sent to this webhook. Match conditions filter requests that have already been matched by the rules, namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests. There are a maximum of 64 match conditions allowed.\n\nThe exact matching logic is (in order):\n 1. If ANY matchCondition evaluates to FALSE, the webhook is skipped.\n 2. If ALL matchConditions evaluate to TRUE, the webhook is called.\n 3. If any matchCondition evaluates to an error (but none are FALSE):\n - If failurePolicy=Fail, reject the request\n - If failurePolicy=Ignore, the error is ignored and the webhook is skipped",
+ "matchConditions": "matchConditions is a list of conditions that must be met for a request to be sent to this webhook. Match conditions filter requests that have already been matched by the rules, namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests. There are a maximum of 64 match conditions allowed.\n\nThe exact matching logic is (in order):\n 1. If ANY matchCondition evaluates to FALSE, the webhook is skipped.\n 2. If ALL matchConditions evaluate to TRUE, the webhook is called.\n 3. If any matchCondition evaluates to an error (but none are FALSE):\n - If failurePolicy=Fail, reject the request\n - If failurePolicy=Ignore, the error is ignored and the webhook is skipped",
}
func (MutatingWebhook) SwaggerDoc() map[string]string {
@@ -92,8 +176,8 @@ func (MutatingWebhook) SwaggerDoc() map[string]string {
var map_MutatingWebhookConfiguration = map[string]string{
"": "MutatingWebhookConfiguration describes the configuration of and admission webhook that accept or reject and may change the object.",
- "metadata": "Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.",
- "webhooks": "Webhooks is a list of webhooks and the affected resources and operations.",
+ "metadata": "metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.",
+ "webhooks": "webhooks is a list of webhooks and the affected resources and operations.",
}
func (MutatingWebhookConfiguration) SwaggerDoc() map[string]string {
@@ -102,7 +186,7 @@ func (MutatingWebhookConfiguration) SwaggerDoc() map[string]string {
var map_MutatingWebhookConfigurationList = map[string]string{
"": "MutatingWebhookConfigurationList is a list of MutatingWebhookConfiguration.",
- "metadata": "Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds",
+ "metadata": "metadata is the standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds",
"items": "List of MutatingWebhookConfiguration.",
}
@@ -110,9 +194,20 @@ func (MutatingWebhookConfigurationList) SwaggerDoc() map[string]string {
return map_MutatingWebhookConfigurationList
}
+var map_Mutation = map[string]string{
+ "": "Mutation specifies the CEL expression which is used to apply the Mutation.",
+ "patchType": "patchType indicates the patch strategy used. Allowed values are \"ApplyConfiguration\" and \"JSONPatch\". Required.",
+ "applyConfiguration": "applyConfiguration defines the desired configuration values of an object. The configuration is applied to the admission object using [structured merge diff](https://github.com/kubernetes-sigs/structured-merge-diff). A CEL expression is used to create apply configuration.",
+ "jsonPatch": "jsonPatch defines a [JSON patch](https://jsonpatch.com/) operation to perform a mutation to the object. A CEL expression is used to create the JSON patch.",
+}
+
+func (Mutation) SwaggerDoc() map[string]string {
+ return map_Mutation
+}
+
var map_NamedRuleWithOperations = map[string]string{
"": "NamedRuleWithOperations is a tuple of Operations and Resources with ResourceNames.",
- "resourceNames": "ResourceNames is an optional white list of names that the rule applies to. An empty set means that everything is allowed.",
+ "resourceNames": "resourceNames is an optional white list of names that the rule applies to. An empty set means that everything is allowed.",
}
func (NamedRuleWithOperations) SwaggerDoc() map[string]string {
@@ -121,8 +216,8 @@ func (NamedRuleWithOperations) SwaggerDoc() map[string]string {
var map_ParamKind = map[string]string{
"": "ParamKind is a tuple of Group Kind and Version.",
- "apiVersion": "APIVersion is the API group version the resources belong to. In format of \"group/version\". Required.",
- "kind": "Kind is the API kind the resources belong to. Required.",
+ "apiVersion": "apiVersion is the API group version the resources belong to. In format of \"group/version\". Required.",
+ "kind": "kind is the API kind the resources belong to. Required.",
}
func (ParamKind) SwaggerDoc() map[string]string {
@@ -134,7 +229,7 @@ var map_ParamRef = map[string]string{
"name": "name is the name of the resource being referenced.\n\nOne of `name` or `selector` must be set, but `name` and `selector` are mutually exclusive properties. If one is set, the other must be unset.\n\nA single parameter used for all admission requests can be configured by setting the `name` field, leaving `selector` blank, and setting namespace if `paramKind` is namespace-scoped.",
"namespace": "namespace is the namespace of the referenced resource. Allows limiting the search for params to a specific namespace. Applies to both `name` and `selector` fields.\n\nA per-namespace parameter may be used by specifying a namespace-scoped `paramKind` in the policy and leaving this field empty.\n\n- If `paramKind` is cluster-scoped, this field MUST be unset. Setting this field results in a configuration error.\n\n- If `paramKind` is namespace-scoped, the namespace of the object being evaluated for admission will be used when this field is left unset. Take care that if this is left empty the binding must not match any cluster-scoped resources, which will result in an error.",
"selector": "selector can be used to match multiple param objects based on their labels. Supply selector: {} to match all resources of the ParamKind.\n\nIf multiple params are found, they are all evaluated with the policy expressions and the results are ANDed together.\n\nOne of `name` or `selector` must be set, but `name` and `selector` are mutually exclusive properties. If one is set, the other must be unset.",
- "parameterNotFoundAction": "`parameterNotFoundAction` controls the behavior of the binding when the resource exists, and name or selector is valid, but there are no parameters matched by the binding. If the value is set to `Allow`, then no matched parameters will be treated as successful validation by the binding. If set to `Deny`, then no matched parameters will be subject to the `failurePolicy` of the policy.\n\nAllowed values are `Allow` or `Deny`\n\nRequired",
+ "parameterNotFoundAction": "parameterNotFoundAction controls the behavior of the binding when the resource exists, and name or selector is valid, but there are no parameters matched by the binding. If the value is set to `Allow`, then no matched parameters will be treated as successful validation by the binding. If set to `Deny`, then no matched parameters will be subject to the `failurePolicy` of the policy.\n\nAllowed values are `Allow` or `Deny`\n\nRequired",
}
func (ParamRef) SwaggerDoc() map[string]string {
@@ -143,9 +238,9 @@ func (ParamRef) SwaggerDoc() map[string]string {
var map_Rule = map[string]string{
"": "Rule is a tuple of APIGroups, APIVersion, and Resources.It is recommended to make sure that all the tuple expansions are valid.",
- "apiGroups": "APIGroups is the API groups the resources belong to. '*' is all groups. If '*' is present, the length of the slice must be one. Required.",
- "apiVersions": "APIVersions is the API versions the resources belong to. '*' is all versions. If '*' is present, the length of the slice must be one. Required.",
- "resources": "Resources is a list of resources this rule applies to.\n\nFor example: 'pods' means pods. 'pods/log' means the log subresource of pods. '*' means all resources, but not subresources. 'pods/*' means all subresources of pods. '*/scale' means all scale subresources. '*/*' means all resources and their subresources.\n\nIf wildcard is present, the validation rule will ensure resources do not overlap with each other.\n\nDepending on the enclosing object, subresources might not be allowed. Required.",
+ "apiGroups": "apiGroups is the API groups the resources belong to. '*' is all groups. If '*' is present, the length of the slice must be one. Required.",
+ "apiVersions": "apiVersions is the API versions the resources belong to. '*' is all versions. If '*' is present, the length of the slice must be one. Required.",
+ "resources": "resources is a list of resources this rule applies to.\n\nFor example: 'pods' means pods. 'pods/log' means the log subresource of pods. '*' means all resources, but not subresources. 'pods/*' means all subresources of pods. '*/scale' means all scale subresources. '*/*' means all resources and their subresources.\n\nIf wildcard is present, the validation rule will ensure resources do not overlap with each other.\n\nDepending on the enclosing object, subresources might not be allowed. Required.",
"scope": "scope specifies the scope of this rule. Valid values are \"Cluster\", \"Namespaced\", and \"*\" \"Cluster\" means that only cluster-scoped resources will match this rule. Namespace API objects are cluster-scoped. \"Namespaced\" means that only namespaced resources will match this rule. \"*\" means that there are no scope restrictions. Subresources match the scope of their parent resource. Default is \"*\".",
}
@@ -155,7 +250,7 @@ func (Rule) SwaggerDoc() map[string]string {
var map_RuleWithOperations = map[string]string{
"": "RuleWithOperations is a tuple of Operations and Resources. It is recommended to make sure that all the tuple expansions are valid.",
- "operations": "Operations is the operations the admission hook cares about - CREATE, UPDATE, DELETE, CONNECT or * for all of those operations and any future admission operations that are added. If '*' is present, the length of the slice must be one. Required.",
+ "operations": "operations is the operations the admission hook cares about - CREATE, UPDATE, DELETE, CONNECT or * for all of those operations and any future admission operations that are added. If '*' is present, the length of the slice must be one. Required.",
}
func (RuleWithOperations) SwaggerDoc() map[string]string {
@@ -164,10 +259,10 @@ func (RuleWithOperations) SwaggerDoc() map[string]string {
var map_ServiceReference = map[string]string{
"": "ServiceReference holds a reference to Service.legacy.k8s.io",
- "namespace": "`namespace` is the namespace of the service. Required",
- "name": "`name` is the name of the service. Required",
- "path": "`path` is an optional URL path which will be sent in any request to this service.",
- "port": "If specified, the port on the service that hosting webhook. Default to 443 for backward compatibility. `port` should be a valid port number (1-65535, inclusive).",
+ "namespace": "namespace is the namespace of the service. Required",
+ "name": "name is the name of the service. Required",
+ "path": "path is an optional URL path which will be sent in any request to this service.",
+ "port": "port is the port on the service that hosts the webhook. Default to 443 for backward compatibility. `port` should be a valid port number (1-65535, inclusive).",
}
func (ServiceReference) SwaggerDoc() map[string]string {
@@ -176,7 +271,7 @@ func (ServiceReference) SwaggerDoc() map[string]string {
var map_TypeChecking = map[string]string{
"": "TypeChecking contains results of type checking the expressions in the ValidatingAdmissionPolicy",
- "expressionWarnings": "The type checking warnings for each expression.",
+ "expressionWarnings": "expressionWarnings contains the type checking warnings for each expression.",
}
func (TypeChecking) SwaggerDoc() map[string]string {
@@ -185,9 +280,9 @@ func (TypeChecking) SwaggerDoc() map[string]string {
var map_ValidatingAdmissionPolicy = map[string]string{
"": "ValidatingAdmissionPolicy describes the definition of an admission validation policy that accepts or rejects an object without changing it.",
- "metadata": "Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.",
- "spec": "Specification of the desired behavior of the ValidatingAdmissionPolicy.",
- "status": "The status of the ValidatingAdmissionPolicy, including warnings that are useful to determine if the policy behaves in the expected way. Populated by the system. Read-only.",
+ "metadata": "metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.",
+ "spec": "spec defines the desired behavior of the ValidatingAdmissionPolicy.",
+ "status": "status represents the current status of the ValidatingAdmissionPolicy, including warnings that are useful to determine if the policy behaves in the expected way. Populated by the system. Read-only.",
}
func (ValidatingAdmissionPolicy) SwaggerDoc() map[string]string {
@@ -196,8 +291,8 @@ func (ValidatingAdmissionPolicy) SwaggerDoc() map[string]string {
var map_ValidatingAdmissionPolicyBinding = map[string]string{
"": "ValidatingAdmissionPolicyBinding binds the ValidatingAdmissionPolicy with paramerized resources. ValidatingAdmissionPolicyBinding and parameter CRDs together define how cluster administrators configure policies for clusters.\n\nFor a given admission request, each binding will cause its policy to be evaluated N times, where N is 1 for policies/bindings that don't use params, otherwise N is the number of parameters selected by the binding.\n\nThe CEL expressions of a policy must have a computed CEL cost below the maximum CEL budget. Each evaluation of the policy is given an independent CEL cost budget. Adding/removing policies, bindings, or params can not affect whether a given (policy, binding, param) combination is within its own CEL budget.",
- "metadata": "Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.",
- "spec": "Specification of the desired behavior of the ValidatingAdmissionPolicyBinding.",
+ "metadata": "metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.",
+ "spec": "spec defines the desired behavior of the ValidatingAdmissionPolicyBinding.",
}
func (ValidatingAdmissionPolicyBinding) SwaggerDoc() map[string]string {
@@ -206,7 +301,7 @@ func (ValidatingAdmissionPolicyBinding) SwaggerDoc() map[string]string {
var map_ValidatingAdmissionPolicyBindingList = map[string]string{
"": "ValidatingAdmissionPolicyBindingList is a list of ValidatingAdmissionPolicyBinding.",
- "metadata": "Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds",
+ "metadata": "metadata is the standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds",
"items": "List of PolicyBinding.",
}
@@ -216,9 +311,9 @@ func (ValidatingAdmissionPolicyBindingList) SwaggerDoc() map[string]string {
var map_ValidatingAdmissionPolicyBindingSpec = map[string]string{
"": "ValidatingAdmissionPolicyBindingSpec is the specification of the ValidatingAdmissionPolicyBinding.",
- "policyName": "PolicyName references a ValidatingAdmissionPolicy name which the ValidatingAdmissionPolicyBinding binds to. If the referenced resource does not exist, this binding is considered invalid and will be ignored Required.",
+ "policyName": "policyName references a ValidatingAdmissionPolicy name which the ValidatingAdmissionPolicyBinding binds to. If the referenced resource does not exist, this binding is considered invalid and will be ignored Required.",
"paramRef": "paramRef specifies the parameter resource used to configure the admission control policy. It should point to a resource of the type specified in ParamKind of the bound ValidatingAdmissionPolicy. If the policy specifies a ParamKind and the resource referred to by ParamRef does not exist, this binding is considered mis-configured and the FailurePolicy of the ValidatingAdmissionPolicy applied. If the policy does not specify a ParamKind then this field is ignored, and the rules are evaluated without a param.",
- "matchResources": "MatchResources declares what resources match this binding and will be validated by it. Note that this is intersected with the policy's matchConstraints, so only requests that are matched by the policy can be selected by this. If this is unset, all resources matched by the policy are validated by this binding When resourceRules is unset, it does not constrain resource matching. If a resource is matched by the other fields of this object, it will be validated. Note that this is differs from ValidatingAdmissionPolicy matchConstraints, where resourceRules are required.",
+ "matchResources": "matchResources declares what resources match this binding and will be validated by it. Note that this is intersected with the policy's matchConstraints, so only requests that are matched by the policy can be selected by this. If this is unset, all resources matched by the policy are validated by this binding When resourceRules is unset, it does not constrain resource matching. If a resource is matched by the other fields of this object, it will be validated. Note that this is differs from ValidatingAdmissionPolicy matchConstraints, where resourceRules are required.",
"validationActions": "validationActions declares how Validations of the referenced ValidatingAdmissionPolicy are enforced. If a validation evaluates to false it is always enforced according to these actions.\n\nFailures defined by the ValidatingAdmissionPolicy's FailurePolicy are enforced according to these actions only if the FailurePolicy is set to Fail, otherwise the failures are ignored. This includes compilation errors, runtime errors and misconfigurations of the policy.\n\nvalidationActions is declared as a set of action values. Order does not matter. validationActions may not contain duplicates of the same action.\n\nThe supported actions values are:\n\n\"Deny\" specifies that a validation failure results in a denied request.\n\n\"Warn\" specifies that a validation failure is reported to the request client in HTTP Warning headers, with a warning code of 299. Warnings can be sent both for allowed or denied admission responses.\n\n\"Audit\" specifies that a validation failure is included in the published audit event for the request. The audit event will contain a `validation.policy.admission.k8s.io/validation_failure` audit annotation with a value containing the details of the validation failures, formatted as a JSON list of objects, each with the following fields: - message: The validation failure message string - policy: The resource name of the ValidatingAdmissionPolicy - binding: The resource name of the ValidatingAdmissionPolicyBinding - expressionIndex: The index of the failed validations in the ValidatingAdmissionPolicy - validationActions: The enforcement actions enacted for the validation failure Example audit annotation: `\"validation.policy.admission.k8s.io/validation_failure\": \"[{\"message\": \"Invalid value\", {\"policy\": \"policy.example.com\", {\"binding\": \"policybinding.example.com\", {\"expressionIndex\": \"1\", {\"validationActions\": [\"Audit\"]}]\"`\n\nClients should expect to handle additional values by ignoring any values not recognized.\n\n\"Deny\" and \"Warn\" may not be used together since this combination needlessly duplicates the validation failure both in the API response body and the HTTP warning headers.\n\nRequired.",
}
@@ -228,7 +323,7 @@ func (ValidatingAdmissionPolicyBindingSpec) SwaggerDoc() map[string]string {
var map_ValidatingAdmissionPolicyList = map[string]string{
"": "ValidatingAdmissionPolicyList is a list of ValidatingAdmissionPolicy.",
- "metadata": "Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds",
+ "metadata": "metadata is the standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds",
"items": "List of ValidatingAdmissionPolicy.",
}
@@ -238,13 +333,13 @@ func (ValidatingAdmissionPolicyList) SwaggerDoc() map[string]string {
var map_ValidatingAdmissionPolicySpec = map[string]string{
"": "ValidatingAdmissionPolicySpec is the specification of the desired behavior of the AdmissionPolicy.",
- "paramKind": "ParamKind specifies the kind of resources used to parameterize this policy. If absent, there are no parameters for this policy and the param CEL variable will not be provided to validation expressions. If ParamKind refers to a non-existent kind, this policy definition is mis-configured and the FailurePolicy is applied. If paramKind is specified but paramRef is unset in ValidatingAdmissionPolicyBinding, the params variable will be null.",
- "matchConstraints": "MatchConstraints specifies what resources this policy is designed to validate. The AdmissionPolicy cares about a request if it matches _all_ Constraints. However, in order to prevent clusters from being put into an unstable state that cannot be recovered from via the API ValidatingAdmissionPolicy cannot match ValidatingAdmissionPolicy and ValidatingAdmissionPolicyBinding. Required.",
- "validations": "Validations contain CEL expressions which is used to apply the validation. Validations and AuditAnnotations may not both be empty; a minimum of one Validations or AuditAnnotations is required.",
+ "paramKind": "paramKind specifies the kind of resources used to parameterize this policy. If absent, there are no parameters for this policy and the param CEL variable will not be provided to validation expressions. If ParamKind refers to a non-existent kind, this policy definition is mis-configured and the FailurePolicy is applied. If paramKind is specified but paramRef is unset in ValidatingAdmissionPolicyBinding, the params variable will be null.",
+ "matchConstraints": "matchConstraints specifies what resources this policy is designed to validate. The AdmissionPolicy cares about a request if it matches _all_ Constraints. However, in order to prevent clusters from being put into an unstable state that cannot be recovered from via the API ValidatingAdmissionPolicy cannot match ValidatingAdmissionPolicy and ValidatingAdmissionPolicyBinding. Required.",
+ "validations": "validations contain CEL expressions which is used to apply the validation. Validations and AuditAnnotations may not both be empty; a minimum of one Validations or AuditAnnotations is required.",
"failurePolicy": "failurePolicy defines how to handle failures for the admission policy. Failures can occur from CEL expression parse errors, type check errors, runtime errors and invalid or mis-configured policy definitions or bindings.\n\nA policy is invalid if spec.paramKind refers to a non-existent Kind. A binding is invalid if spec.paramRef.name refers to a non-existent resource.\n\nfailurePolicy does not define how validations that evaluate to false are handled.\n\nWhen failurePolicy is set to Fail, ValidatingAdmissionPolicyBinding validationActions define how failures are enforced.\n\nAllowed values are Ignore or Fail. Defaults to Fail.",
"auditAnnotations": "auditAnnotations contains CEL expressions which are used to produce audit annotations for the audit event of the API request. validations and auditAnnotations may not both be empty; a least one of validations or auditAnnotations is required.",
- "matchConditions": "MatchConditions is a list of conditions that must be met for a request to be validated. Match conditions filter requests that have already been matched by the rules, namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests. There are a maximum of 64 match conditions allowed.\n\nIf a parameter object is provided, it can be accessed via the `params` handle in the same manner as validation expressions.\n\nThe exact matching logic is (in order):\n 1. If ANY matchCondition evaluates to FALSE, the policy is skipped.\n 2. If ALL matchConditions evaluate to TRUE, the policy is evaluated.\n 3. If any matchCondition evaluates to an error (but none are FALSE):\n - If failurePolicy=Fail, reject the request\n - If failurePolicy=Ignore, the policy is skipped",
- "variables": "Variables contain definitions of variables that can be used in composition of other expressions. Each variable is defined as a named CEL expression. The variables defined here will be available under `variables` in other expressions of the policy except MatchConditions because MatchConditions are evaluated before the rest of the policy.\n\nThe expression of a variable can refer to other variables defined earlier in the list but not those after. Thus, Variables must be sorted by the order of first appearance and acyclic.",
+ "matchConditions": "matchConditions is a list of conditions that must be met for a request to be validated. Match conditions filter requests that have already been matched by the rules, namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests. There are a maximum of 64 match conditions allowed.\n\nIf a parameter object is provided, it can be accessed via the `params` handle in the same manner as validation expressions.\n\nThe exact matching logic is (in order):\n 1. If ANY matchCondition evaluates to FALSE, the policy is skipped.\n 2. If ALL matchConditions evaluate to TRUE, the policy is evaluated.\n 3. If any matchCondition evaluates to an error (but none are FALSE):\n - If failurePolicy=Fail, reject the request\n - If failurePolicy=Ignore, the policy is skipped",
+ "variables": "variables contain definitions of variables that can be used in composition of other expressions. Each variable is defined as a named CEL expression. The variables defined here will be available under `variables` in other expressions of the policy except MatchConditions because MatchConditions are evaluated before the rest of the policy.\n\nThe expression of a variable can refer to other variables defined earlier in the list but not those after. Thus, Variables must be sorted by the order of first appearance and acyclic.",
}
func (ValidatingAdmissionPolicySpec) SwaggerDoc() map[string]string {
@@ -253,9 +348,9 @@ func (ValidatingAdmissionPolicySpec) SwaggerDoc() map[string]string {
var map_ValidatingAdmissionPolicyStatus = map[string]string{
"": "ValidatingAdmissionPolicyStatus represents the status of an admission validation policy.",
- "observedGeneration": "The generation observed by the controller.",
- "typeChecking": "The results of type checking for each expression. Presence of this field indicates the completion of the type checking.",
- "conditions": "The conditions represent the latest available observations of a policy's current state.",
+ "observedGeneration": "observedGeneration is the generation observed by the controller.",
+ "typeChecking": "typeChecking contains the results of type checking for each expression. Presence of this field indicates the completion of the type checking.",
+ "conditions": "conditions represent the latest available observations of a policy's current state.",
}
func (ValidatingAdmissionPolicyStatus) SwaggerDoc() map[string]string {
@@ -264,17 +359,17 @@ func (ValidatingAdmissionPolicyStatus) SwaggerDoc() map[string]string {
var map_ValidatingWebhook = map[string]string{
"": "ValidatingWebhook describes an admission webhook and the resources and operations it applies to.",
- "name": "The name of the admission webhook. Name should be fully qualified, e.g., imagepolicy.kubernetes.io, where \"imagepolicy\" is the name of the webhook, and kubernetes.io is the name of the organization. Required.",
- "clientConfig": "ClientConfig defines how to communicate with the hook. Required",
- "rules": "Rules describes what operations on what resources/subresources the webhook cares about. The webhook cares about an operation if it matches _any_ Rule. However, in order to prevent ValidatingAdmissionWebhooks and MutatingAdmissionWebhooks from putting the cluster in a state which cannot be recovered from without completely disabling the plugin, ValidatingAdmissionWebhooks and MutatingAdmissionWebhooks are never called on admission requests for ValidatingWebhookConfiguration and MutatingWebhookConfiguration objects.",
- "failurePolicy": "FailurePolicy defines how unrecognized errors from the admission endpoint are handled - allowed values are Ignore or Fail. Defaults to Fail.",
+ "name": "name is the name of the admission webhook. Name should be fully qualified, e.g., imagepolicy.kubernetes.io, where \"imagepolicy\" is the name of the webhook, and kubernetes.io is the name of the organization. Required.",
+ "clientConfig": "clientConfig defines how to communicate with the hook. Required",
+ "rules": "rules describes what operations on what resources/subresources the webhook cares about. The webhook cares about an operation if it matches _any_ Rule. However, in order to prevent ValidatingAdmissionWebhooks and MutatingAdmissionWebhooks from putting the cluster in a state which cannot be recovered from without completely disabling the plugin, ValidatingAdmissionWebhooks and MutatingAdmissionWebhooks are never called on admission requests for ValidatingWebhookConfiguration and MutatingWebhookConfiguration objects.",
+ "failurePolicy": "failurePolicy defines how unrecognized errors from the admission endpoint are handled - allowed values are Ignore or Fail. Defaults to Fail.",
"matchPolicy": "matchPolicy defines how the \"rules\" list is used to match incoming requests. Allowed values are \"Exact\" or \"Equivalent\".\n\n- Exact: match a request only if it exactly matches a specified rule. For example, if deployments can be modified via apps/v1, apps/v1beta1, and extensions/v1beta1, but \"rules\" only included `apiGroups:[\"apps\"], apiVersions:[\"v1\"], resources: [\"deployments\"]`, a request to apps/v1beta1 or extensions/v1beta1 would not be sent to the webhook.\n\n- Equivalent: match a request if modifies a resource listed in rules, even via another API group or version. For example, if deployments can be modified via apps/v1, apps/v1beta1, and extensions/v1beta1, and \"rules\" only included `apiGroups:[\"apps\"], apiVersions:[\"v1\"], resources: [\"deployments\"]`, a request to apps/v1beta1 or extensions/v1beta1 would be converted to apps/v1 and sent to the webhook.\n\nDefaults to \"Equivalent\"",
- "namespaceSelector": "NamespaceSelector decides whether to run the webhook on an object based on whether the namespace for that object matches the selector. If the object itself is a namespace, the matching is performed on object.metadata.labels. If the object is another cluster scoped resource, it never skips the webhook.\n\nFor example, to run the webhook on any objects whose namespace is not associated with \"runlevel\" of \"0\" or \"1\"; you will set the selector as follows: \"namespaceSelector\": {\n \"matchExpressions\": [\n {\n \"key\": \"runlevel\",\n \"operator\": \"NotIn\",\n \"values\": [\n \"0\",\n \"1\"\n ]\n }\n ]\n}\n\nIf instead you want to only run the webhook on any objects whose namespace is associated with the \"environment\" of \"prod\" or \"staging\"; you will set the selector as follows: \"namespaceSelector\": {\n \"matchExpressions\": [\n {\n \"key\": \"environment\",\n \"operator\": \"In\",\n \"values\": [\n \"prod\",\n \"staging\"\n ]\n }\n ]\n}\n\nSee https://kubernetes.io/docs/concepts/overview/working-with-objects/labels for more examples of label selectors.\n\nDefault to the empty LabelSelector, which matches everything.",
- "objectSelector": "ObjectSelector decides whether to run the webhook based on if the object has matching labels. objectSelector is evaluated against both the oldObject and newObject that would be sent to the webhook, and is considered to match if either object matches the selector. A null object (oldObject in the case of create, or newObject in the case of delete) or an object that cannot have labels (like a DeploymentRollback or a PodProxyOptions object) is not considered to match. Use the object selector only if the webhook is opt-in, because end users may skip the admission webhook by setting the labels. Default to the empty LabelSelector, which matches everything.",
- "sideEffects": "SideEffects states whether this webhook has side effects. Acceptable values are: None, NoneOnDryRun (webhooks created via v1beta1 may also specify Some or Unknown). Webhooks with side effects MUST implement a reconciliation system, since a request may be rejected by a future step in the admission chain and the side effects therefore need to be undone. Requests with the dryRun attribute will be auto-rejected if they match a webhook with sideEffects == Unknown or Some.",
- "timeoutSeconds": "TimeoutSeconds specifies the timeout for this webhook. After the timeout passes, the webhook call will be ignored or the API call will fail based on the failure policy. The timeout value must be between 1 and 30 seconds. Default to 10 seconds.",
- "admissionReviewVersions": "AdmissionReviewVersions is an ordered list of preferred `AdmissionReview` versions the Webhook expects. API server will try to use first version in the list which it supports. If none of the versions specified in this list supported by API server, validation will fail for this object. If a persisted webhook configuration specifies allowed versions and does not include any versions known to the API Server, calls to the webhook will fail and be subject to the failure policy.",
- "matchConditions": "MatchConditions is a list of conditions that must be met for a request to be sent to this webhook. Match conditions filter requests that have already been matched by the rules, namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests. There are a maximum of 64 match conditions allowed.\n\nThe exact matching logic is (in order):\n 1. If ANY matchCondition evaluates to FALSE, the webhook is skipped.\n 2. If ALL matchConditions evaluate to TRUE, the webhook is called.\n 3. If any matchCondition evaluates to an error (but none are FALSE):\n - If failurePolicy=Fail, reject the request\n - If failurePolicy=Ignore, the error is ignored and the webhook is skipped",
+ "namespaceSelector": "namespaceSelector decides whether to run the webhook on an object based on whether the namespace for that object matches the selector. If the object itself is a namespace, the matching is performed on object.metadata.labels. If the object is another cluster scoped resource, it never skips the webhook.\n\nFor example, to run the webhook on any objects whose namespace is not associated with \"runlevel\" of \"0\" or \"1\"; you will set the selector as follows: \"namespaceSelector\": {\n \"matchExpressions\": [\n {\n \"key\": \"runlevel\",\n \"operator\": \"NotIn\",\n \"values\": [\n \"0\",\n \"1\"\n ]\n }\n ]\n}\n\nIf instead you want to only run the webhook on any objects whose namespace is associated with the \"environment\" of \"prod\" or \"staging\"; you will set the selector as follows: \"namespaceSelector\": {\n \"matchExpressions\": [\n {\n \"key\": \"environment\",\n \"operator\": \"In\",\n \"values\": [\n \"prod\",\n \"staging\"\n ]\n }\n ]\n}\n\nSee https://kubernetes.io/docs/concepts/overview/working-with-objects/labels for more examples of label selectors.\n\nDefault to the empty LabelSelector, which matches everything.",
+ "objectSelector": "objectSelector decides whether to run the webhook based on if the object has matching labels. objectSelector is evaluated against both the oldObject and newObject that would be sent to the webhook, and is considered to match if either object matches the selector. A null object (oldObject in the case of create, or newObject in the case of delete) or an object that cannot have labels (like a DeploymentRollback or a PodProxyOptions object) is not considered to match. Use the object selector only if the webhook is opt-in, because end users may skip the admission webhook by setting the labels. Default to the empty LabelSelector, which matches everything.",
+ "sideEffects": "sideEffects states whether this webhook has side effects. Acceptable values are: None, NoneOnDryRun (webhooks created via v1beta1 may also specify Some or Unknown). Webhooks with side effects MUST implement a reconciliation system, since a request may be rejected by a future step in the admission chain and the side effects therefore need to be undone. Requests with the dryRun attribute will be auto-rejected if they match a webhook with sideEffects == Unknown or Some.",
+ "timeoutSeconds": "timeoutSeconds specifies the timeout for this webhook. After the timeout passes, the webhook call will be ignored or the API call will fail based on the failure policy. The timeout value must be between 1 and 30 seconds. Default to 10 seconds.",
+ "admissionReviewVersions": "admissionReviewVersions is an ordered list of preferred `AdmissionReview` versions the Webhook expects. API server will try to use first version in the list which it supports. If none of the versions specified in this list supported by API server, validation will fail for this object. If a persisted webhook configuration specifies allowed versions and does not include any versions known to the API Server, calls to the webhook will fail and be subject to the failure policy.",
+ "matchConditions": "matchConditions is a list of conditions that must be met for a request to be sent to this webhook. Match conditions filter requests that have already been matched by the rules, namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests. There are a maximum of 64 match conditions allowed.\n\nThe exact matching logic is (in order):\n 1. If ANY matchCondition evaluates to FALSE, the webhook is skipped.\n 2. If ALL matchConditions evaluate to TRUE, the webhook is called.\n 3. If any matchCondition evaluates to an error (but none are FALSE):\n - If failurePolicy=Fail, reject the request\n - If failurePolicy=Ignore, the error is ignored and the webhook is skipped",
}
func (ValidatingWebhook) SwaggerDoc() map[string]string {
@@ -283,8 +378,8 @@ func (ValidatingWebhook) SwaggerDoc() map[string]string {
var map_ValidatingWebhookConfiguration = map[string]string{
"": "ValidatingWebhookConfiguration describes the configuration of and admission webhook that accept or reject and object without changing it.",
- "metadata": "Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.",
- "webhooks": "Webhooks is a list of webhooks and the affected resources and operations.",
+ "metadata": "metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.",
+ "webhooks": "webhooks is a list of webhooks and the affected resources and operations.",
}
func (ValidatingWebhookConfiguration) SwaggerDoc() map[string]string {
@@ -293,7 +388,7 @@ func (ValidatingWebhookConfiguration) SwaggerDoc() map[string]string {
var map_ValidatingWebhookConfigurationList = map[string]string{
"": "ValidatingWebhookConfigurationList is a list of ValidatingWebhookConfiguration.",
- "metadata": "Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds",
+ "metadata": "metadata is the standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds",
"items": "List of ValidatingWebhookConfiguration.",
}
@@ -303,9 +398,9 @@ func (ValidatingWebhookConfigurationList) SwaggerDoc() map[string]string {
var map_Validation = map[string]string{
"": "Validation specifies the CEL expression which is used to apply the validation.",
- "expression": "Expression represents the expression which will be evaluated by CEL. ref: https://github.com/google/cel-spec CEL expressions have access to the contents of the API request/response, organized into CEL variables as well as some other useful variables:\n\n- 'object' - The object from the incoming request. The value is null for DELETE requests. - 'oldObject' - The existing object. The value is null for CREATE requests. - 'request' - Attributes of the API request([ref](/pkg/apis/admission/types.go#AdmissionRequest)). - 'params' - Parameter resource referred to by the policy binding being evaluated. Only populated if the policy has a ParamKind. - 'namespaceObject' - The namespace object that the incoming object belongs to. The value is null for cluster-scoped resources. - 'variables' - Map of composited variables, from its name to its lazily evaluated value.\n For example, a variable named 'foo' can be accessed as 'variables.foo'.\n- 'authorizer' - A CEL Authorizer. May be used to perform authorization checks for the principal (user or service account) of the request.\n See https://pkg.go.dev/k8s.io/apiserver/pkg/cel/library#Authz\n- 'authorizer.requestResource' - A CEL ResourceCheck constructed from the 'authorizer' and configured with the\n request resource.\n\nThe `apiVersion`, `kind`, `metadata.name` and `metadata.generateName` are always accessible from the root of the object. No other metadata properties are accessible.\n\nOnly property names of the form `[a-zA-Z_.-/][a-zA-Z0-9_.-/]*` are accessible. Accessible property names are escaped according to the following rules when accessed in the expression: - '__' escapes to '__underscores__' - '.' escapes to '__dot__' - '-' escapes to '__dash__' - '/' escapes to '__slash__' - Property names that exactly match a CEL RESERVED keyword escape to '__{keyword}__'. The keywords are:\n\t \"true\", \"false\", \"null\", \"in\", \"as\", \"break\", \"const\", \"continue\", \"else\", \"for\", \"function\", \"if\",\n\t \"import\", \"let\", \"loop\", \"package\", \"namespace\", \"return\".\nExamples:\n - Expression accessing a property named \"namespace\": {\"Expression\": \"object.__namespace__ > 0\"}\n - Expression accessing a property named \"x-prop\": {\"Expression\": \"object.x__dash__prop > 0\"}\n - Expression accessing a property named \"redact__d\": {\"Expression\": \"object.redact__underscores__d > 0\"}\n\nEquality on arrays with list type of 'set' or 'map' ignores element order, i.e. [1, 2] == [2, 1]. Concatenation on arrays with x-kubernetes-list-type use the semantics of the list type:\n - 'set': `X + Y` performs a union where the array positions of all elements in `X` are preserved and\n non-intersecting elements in `Y` are appended, retaining their partial order.\n - 'map': `X + Y` performs a merge where the array positions of all keys in `X` are preserved but the values\n are overwritten by values in `Y` when the key sets of `X` and `Y` intersect. Elements in `Y` with\n non-intersecting keys are appended, retaining their partial order.\nRequired.",
- "message": "Message represents the message displayed when validation fails. The message is required if the Expression contains line breaks. The message must not contain line breaks. If unset, the message is \"failed rule: {Rule}\". e.g. \"must be a URL with the host matching spec.host\" If the Expression contains line breaks. Message is required. The message must not contain line breaks. If unset, the message is \"failed Expression: {Expression}\".",
- "reason": "Reason represents a machine-readable description of why this validation failed. If this is the first validation in the list to fail, this reason, as well as the corresponding HTTP response code, are used in the HTTP response to the client. The currently supported reasons are: \"Unauthorized\", \"Forbidden\", \"Invalid\", \"RequestEntityTooLarge\". If not set, StatusReasonInvalid is used in the response to the client.",
+ "expression": "expression represents the expression which will be evaluated by CEL. ref: https://github.com/google/cel-spec CEL expressions have access to the contents of the API request/response, organized into CEL variables as well as some other useful variables:\n\n- 'object' - The object from the incoming request. The value is null for DELETE requests. - 'oldObject' - The existing object. The value is null for CREATE requests. - 'request' - Attributes of the API request([ref](/pkg/apis/admission/types.go#AdmissionRequest)). - 'params' - Parameter resource referred to by the policy binding being evaluated. Only populated if the policy has a ParamKind. - 'namespaceObject' - The namespace object that the incoming object belongs to. The value is null for cluster-scoped resources. - 'variables' - Map of composited variables, from its name to its lazily evaluated value.\n For example, a variable named 'foo' can be accessed as 'variables.foo'.\n- 'authorizer' - A CEL Authorizer. May be used to perform authorization checks for the principal (user or service account) of the request.\n See https://pkg.go.dev/k8s.io/apiserver/pkg/cel/library#Authz\n- 'authorizer.requestResource' - A CEL ResourceCheck constructed from the 'authorizer' and configured with the\n request resource.\n\nThe `apiVersion`, `kind`, `metadata.name` and `metadata.generateName` are always accessible from the root of the object. No other metadata properties are accessible.\n\nOnly property names of the form `[a-zA-Z_.-/][a-zA-Z0-9_.-/]*` are accessible. Accessible property names are escaped according to the following rules when accessed in the expression: - '__' escapes to '__underscores__' - '.' escapes to '__dot__' - '-' escapes to '__dash__' - '/' escapes to '__slash__' - Property names that exactly match a CEL RESERVED keyword escape to '__{keyword}__'. The keywords are:\n\t \"true\", \"false\", \"null\", \"in\", \"as\", \"break\", \"const\", \"continue\", \"else\", \"for\", \"function\", \"if\",\n\t \"import\", \"let\", \"loop\", \"package\", \"namespace\", \"return\".\nExamples:\n - Expression accessing a property named \"namespace\": {\"Expression\": \"object.__namespace__ > 0\"}\n - Expression accessing a property named \"x-prop\": {\"Expression\": \"object.x__dash__prop > 0\"}\n - Expression accessing a property named \"redact__d\": {\"Expression\": \"object.redact__underscores__d > 0\"}\n\nEquality on arrays with list type of 'set' or 'map' ignores element order, i.e. [1, 2] == [2, 1]. Concatenation on arrays with x-kubernetes-list-type use the semantics of the list type:\n - 'set': `X + Y` performs a union where the array positions of all elements in `X` are preserved and\n non-intersecting elements in `Y` are appended, retaining their partial order.\n - 'map': `X + Y` performs a merge where the array positions of all keys in `X` are preserved but the values\n are overwritten by values in `Y` when the key sets of `X` and `Y` intersect. Elements in `Y` with\n non-intersecting keys are appended, retaining their partial order.\nRequired.",
+ "message": "message represents the message displayed when validation fails. The message is required if the Expression contains line breaks. The message must not contain line breaks. If unset, the message is \"failed rule: {Rule}\". e.g. \"must be a URL with the host matching spec.host\" If the Expression contains line breaks. Message is required. The message must not contain line breaks. If unset, the message is \"failed Expression: {Expression}\".",
+ "reason": "reason represents a machine-readable description of why this validation failed. If this is the first validation in the list to fail, this reason, as well as the corresponding HTTP response code, are used in the HTTP response to the client. The currently supported reasons are: \"Unauthorized\", \"Forbidden\", \"Invalid\", \"RequestEntityTooLarge\". If not set, StatusReasonInvalid is used in the response to the client.",
"messageExpression": "messageExpression declares a CEL expression that evaluates to the validation failure message that is returned when this rule fails. Since messageExpression is used as a failure message, it must evaluate to a string. If both message and messageExpression are present on a validation, then messageExpression will be used if validation fails. If messageExpression results in a runtime error, the runtime error is logged, and the validation failure message is produced as if the messageExpression field were unset. If messageExpression evaluates to an empty string, a string with only spaces, or a string that contains line breaks, then the validation failure message will also be produced as if the messageExpression field were unset, and the fact that messageExpression produced an empty string/string with only spaces/string with line breaks will be logged. messageExpression has access to all the same variables as the `expression` except for 'authorizer' and 'authorizer.requestResource'. Example: \"object.x must be less than max (\"+string(params.max)+\")\"",
}
@@ -315,8 +410,8 @@ func (Validation) SwaggerDoc() map[string]string {
var map_Variable = map[string]string{
"": "Variable is the definition of a variable that is used for composition. A variable is defined as a named expression.",
- "name": "Name is the name of the variable. The name must be a valid CEL identifier and unique among all variables. The variable can be accessed in other expressions through `variables` For example, if name is \"foo\", the variable will be available as `variables.foo`",
- "expression": "Expression is the expression that will be evaluated as the value of the variable. The CEL expression has access to the same identifiers as the CEL expressions in Validation.",
+ "name": "name is the name of the variable. The name must be a valid CEL identifier and unique among all variables. The variable can be accessed in other expressions through `variables` For example, if name is \"foo\", the variable will be available as `variables.foo`",
+ "expression": "expression is the expression that will be evaluated as the value of the variable. The CEL expression has access to the same identifiers as the CEL expressions in Validation.",
}
func (Variable) SwaggerDoc() map[string]string {
@@ -325,9 +420,9 @@ func (Variable) SwaggerDoc() map[string]string {
var map_WebhookClientConfig = map[string]string{
"": "WebhookClientConfig contains the information to make a TLS connection with the webhook",
- "url": "`url` gives the location of the webhook, in standard URL form (`scheme://host:port/path`). Exactly one of `url` or `service` must be specified.\n\nThe `host` should not refer to a service running in the cluster; use the `service` field instead. The host might be resolved via external DNS in some apiservers (e.g., `kube-apiserver` cannot resolve in-cluster DNS as that would be a layering violation). `host` may also be an IP address.\n\nPlease note that using `localhost` or `127.0.0.1` as a `host` is risky unless you take great care to run this webhook on all hosts which run an apiserver which might need to make calls to this webhook. Such installs are likely to be non-portable, i.e., not easy to turn up in a new cluster.\n\nThe scheme must be \"https\"; the URL must begin with \"https://\".\n\nA path is optional, and if present may be any string permissible in a URL. You may use the path to pass an arbitrary string to the webhook, for example, a cluster identifier.\n\nAttempting to use a user or basic auth e.g. \"user:password@\" is not allowed. Fragments (\"#...\") and query parameters (\"?...\") are not allowed, either.",
- "service": "`service` is a reference to the service for this webhook. Either `service` or `url` must be specified.\n\nIf the webhook is running within the cluster, then you should use `service`.",
- "caBundle": "`caBundle` is a PEM encoded CA bundle which will be used to validate the webhook's server certificate. If unspecified, system trust roots on the apiserver are used.",
+ "url": "url gives the location of the webhook, in standard URL form (`scheme://host:port/path`). Exactly one of `url` or `service` must be specified.\n\nThe `host` should not refer to a service running in the cluster; use the `service` field instead. The host might be resolved via external DNS in some apiservers (e.g., `kube-apiserver` cannot resolve in-cluster DNS as that would be a layering violation). `host` may also be an IP address.\n\nPlease note that using `localhost` or `127.0.0.1` as a `host` is risky unless you take great care to run this webhook on all hosts which run an apiserver which might need to make calls to this webhook. Such installs are likely to be non-portable, i.e., not easy to turn up in a new cluster.\n\nThe scheme must be \"https\"; the URL must begin with \"https://\".\n\nA path is optional, and if present may be any string permissible in a URL. You may use the path to pass an arbitrary string to the webhook, for example, a cluster identifier.\n\nAttempting to use a user or basic auth e.g. \"user:password@\" is not allowed. Fragments (\"#...\") and query parameters (\"?...\") are not allowed, either.",
+ "service": "service is a reference to the service for this webhook. Either `service` or `url` must be specified.\n\nIf the webhook is running within the cluster, then you should use `service`.",
+ "caBundle": "caBundle is a PEM encoded CA bundle which will be used to validate the webhook's server certificate. If unspecified, system trust roots on the apiserver are used.",
}
func (WebhookClientConfig) SwaggerDoc() map[string]string {
diff --git a/vendor/k8s.io/api/admissionregistration/v1/zz_generated.deepcopy.go b/vendor/k8s.io/api/admissionregistration/v1/zz_generated.deepcopy.go
index bfe599c1d..afdbfd914 100644
--- a/vendor/k8s.io/api/admissionregistration/v1/zz_generated.deepcopy.go
+++ b/vendor/k8s.io/api/admissionregistration/v1/zz_generated.deepcopy.go
@@ -26,6 +26,22 @@ import (
runtime "k8s.io/apimachinery/pkg/runtime"
)
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *ApplyConfiguration) DeepCopyInto(out *ApplyConfiguration) {
+ *out = *in
+ return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ApplyConfiguration.
+func (in *ApplyConfiguration) DeepCopy() *ApplyConfiguration {
+ if in == nil {
+ return nil
+ }
+ out := new(ApplyConfiguration)
+ in.DeepCopyInto(out)
+ return out
+}
+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *AuditAnnotation) DeepCopyInto(out *AuditAnnotation) {
*out = *in
@@ -58,6 +74,22 @@ func (in *ExpressionWarning) DeepCopy() *ExpressionWarning {
return out
}
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *JSONPatch) DeepCopyInto(out *JSONPatch) {
+ *out = *in
+ return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new JSONPatch.
+func (in *JSONPatch) DeepCopy() *JSONPatch {
+ if in == nil {
+ return nil
+ }
+ out := new(JSONPatch)
+ in.DeepCopyInto(out)
+ return out
+}
+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *MatchCondition) DeepCopyInto(out *MatchCondition) {
*out = *in
@@ -119,6 +151,200 @@ func (in *MatchResources) DeepCopy() *MatchResources {
return out
}
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *MutatingAdmissionPolicy) DeepCopyInto(out *MutatingAdmissionPolicy) {
+ *out = *in
+ out.TypeMeta = in.TypeMeta
+ in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
+ in.Spec.DeepCopyInto(&out.Spec)
+ return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MutatingAdmissionPolicy.
+func (in *MutatingAdmissionPolicy) DeepCopy() *MutatingAdmissionPolicy {
+ if in == nil {
+ return nil
+ }
+ out := new(MutatingAdmissionPolicy)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
+func (in *MutatingAdmissionPolicy) DeepCopyObject() runtime.Object {
+ if c := in.DeepCopy(); c != nil {
+ return c
+ }
+ return nil
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *MutatingAdmissionPolicyBinding) DeepCopyInto(out *MutatingAdmissionPolicyBinding) {
+ *out = *in
+ out.TypeMeta = in.TypeMeta
+ in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
+ in.Spec.DeepCopyInto(&out.Spec)
+ return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MutatingAdmissionPolicyBinding.
+func (in *MutatingAdmissionPolicyBinding) DeepCopy() *MutatingAdmissionPolicyBinding {
+ if in == nil {
+ return nil
+ }
+ out := new(MutatingAdmissionPolicyBinding)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
+func (in *MutatingAdmissionPolicyBinding) DeepCopyObject() runtime.Object {
+ if c := in.DeepCopy(); c != nil {
+ return c
+ }
+ return nil
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *MutatingAdmissionPolicyBindingList) DeepCopyInto(out *MutatingAdmissionPolicyBindingList) {
+ *out = *in
+ out.TypeMeta = in.TypeMeta
+ in.ListMeta.DeepCopyInto(&out.ListMeta)
+ if in.Items != nil {
+ in, out := &in.Items, &out.Items
+ *out = make([]MutatingAdmissionPolicyBinding, len(*in))
+ for i := range *in {
+ (*in)[i].DeepCopyInto(&(*out)[i])
+ }
+ }
+ return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MutatingAdmissionPolicyBindingList.
+func (in *MutatingAdmissionPolicyBindingList) DeepCopy() *MutatingAdmissionPolicyBindingList {
+ if in == nil {
+ return nil
+ }
+ out := new(MutatingAdmissionPolicyBindingList)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
+func (in *MutatingAdmissionPolicyBindingList) DeepCopyObject() runtime.Object {
+ if c := in.DeepCopy(); c != nil {
+ return c
+ }
+ return nil
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *MutatingAdmissionPolicyBindingSpec) DeepCopyInto(out *MutatingAdmissionPolicyBindingSpec) {
+ *out = *in
+ if in.ParamRef != nil {
+ in, out := &in.ParamRef, &out.ParamRef
+ *out = new(ParamRef)
+ (*in).DeepCopyInto(*out)
+ }
+ if in.MatchResources != nil {
+ in, out := &in.MatchResources, &out.MatchResources
+ *out = new(MatchResources)
+ (*in).DeepCopyInto(*out)
+ }
+ return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MutatingAdmissionPolicyBindingSpec.
+func (in *MutatingAdmissionPolicyBindingSpec) DeepCopy() *MutatingAdmissionPolicyBindingSpec {
+ if in == nil {
+ return nil
+ }
+ out := new(MutatingAdmissionPolicyBindingSpec)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *MutatingAdmissionPolicyList) DeepCopyInto(out *MutatingAdmissionPolicyList) {
+ *out = *in
+ out.TypeMeta = in.TypeMeta
+ in.ListMeta.DeepCopyInto(&out.ListMeta)
+ if in.Items != nil {
+ in, out := &in.Items, &out.Items
+ *out = make([]MutatingAdmissionPolicy, len(*in))
+ for i := range *in {
+ (*in)[i].DeepCopyInto(&(*out)[i])
+ }
+ }
+ return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MutatingAdmissionPolicyList.
+func (in *MutatingAdmissionPolicyList) DeepCopy() *MutatingAdmissionPolicyList {
+ if in == nil {
+ return nil
+ }
+ out := new(MutatingAdmissionPolicyList)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
+func (in *MutatingAdmissionPolicyList) DeepCopyObject() runtime.Object {
+ if c := in.DeepCopy(); c != nil {
+ return c
+ }
+ return nil
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *MutatingAdmissionPolicySpec) DeepCopyInto(out *MutatingAdmissionPolicySpec) {
+ *out = *in
+ if in.ParamKind != nil {
+ in, out := &in.ParamKind, &out.ParamKind
+ *out = new(ParamKind)
+ **out = **in
+ }
+ if in.MatchConstraints != nil {
+ in, out := &in.MatchConstraints, &out.MatchConstraints
+ *out = new(MatchResources)
+ (*in).DeepCopyInto(*out)
+ }
+ if in.Variables != nil {
+ in, out := &in.Variables, &out.Variables
+ *out = make([]Variable, len(*in))
+ copy(*out, *in)
+ }
+ if in.Mutations != nil {
+ in, out := &in.Mutations, &out.Mutations
+ *out = make([]Mutation, len(*in))
+ for i := range *in {
+ (*in)[i].DeepCopyInto(&(*out)[i])
+ }
+ }
+ if in.FailurePolicy != nil {
+ in, out := &in.FailurePolicy, &out.FailurePolicy
+ *out = new(FailurePolicyType)
+ **out = **in
+ }
+ if in.MatchConditions != nil {
+ in, out := &in.MatchConditions, &out.MatchConditions
+ *out = make([]MatchCondition, len(*in))
+ copy(*out, *in)
+ }
+ return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MutatingAdmissionPolicySpec.
+func (in *MutatingAdmissionPolicySpec) DeepCopy() *MutatingAdmissionPolicySpec {
+ if in == nil {
+ return nil
+ }
+ out := new(MutatingAdmissionPolicySpec)
+ in.DeepCopyInto(out)
+ return out
+}
+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *MutatingWebhook) DeepCopyInto(out *MutatingWebhook) {
*out = *in
@@ -254,6 +480,32 @@ func (in *MutatingWebhookConfigurationList) DeepCopyObject() runtime.Object {
return nil
}
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *Mutation) DeepCopyInto(out *Mutation) {
+ *out = *in
+ if in.ApplyConfiguration != nil {
+ in, out := &in.ApplyConfiguration, &out.ApplyConfiguration
+ *out = new(ApplyConfiguration)
+ **out = **in
+ }
+ if in.JSONPatch != nil {
+ in, out := &in.JSONPatch, &out.JSONPatch
+ *out = new(JSONPatch)
+ **out = **in
+ }
+ return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Mutation.
+func (in *Mutation) DeepCopy() *Mutation {
+ if in == nil {
+ return nil
+ }
+ out := new(Mutation)
+ in.DeepCopyInto(out)
+ return out
+}
+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *NamedRuleWithOperations) DeepCopyInto(out *NamedRuleWithOperations) {
*out = *in
diff --git a/vendor/k8s.io/api/admissionregistration/v1/zz_generated.model_name.go b/vendor/k8s.io/api/admissionregistration/v1/zz_generated.model_name.go
index 3264285cd..b7baac8d1 100644
--- a/vendor/k8s.io/api/admissionregistration/v1/zz_generated.model_name.go
+++ b/vendor/k8s.io/api/admissionregistration/v1/zz_generated.model_name.go
@@ -21,6 +21,11 @@ limitations under the License.
package v1
+// OpenAPIModelName returns the OpenAPI model name for this type.
+func (in ApplyConfiguration) OpenAPIModelName() string {
+ return "io.k8s.api.admissionregistration.v1.ApplyConfiguration"
+}
+
// OpenAPIModelName returns the OpenAPI model name for this type.
func (in AuditAnnotation) OpenAPIModelName() string {
return "io.k8s.api.admissionregistration.v1.AuditAnnotation"
@@ -31,6 +36,11 @@ func (in ExpressionWarning) OpenAPIModelName() string {
return "io.k8s.api.admissionregistration.v1.ExpressionWarning"
}
+// OpenAPIModelName returns the OpenAPI model name for this type.
+func (in JSONPatch) OpenAPIModelName() string {
+ return "io.k8s.api.admissionregistration.v1.JSONPatch"
+}
+
// OpenAPIModelName returns the OpenAPI model name for this type.
func (in MatchCondition) OpenAPIModelName() string {
return "io.k8s.api.admissionregistration.v1.MatchCondition"
@@ -41,6 +51,36 @@ func (in MatchResources) OpenAPIModelName() string {
return "io.k8s.api.admissionregistration.v1.MatchResources"
}
+// OpenAPIModelName returns the OpenAPI model name for this type.
+func (in MutatingAdmissionPolicy) OpenAPIModelName() string {
+ return "io.k8s.api.admissionregistration.v1.MutatingAdmissionPolicy"
+}
+
+// OpenAPIModelName returns the OpenAPI model name for this type.
+func (in MutatingAdmissionPolicyBinding) OpenAPIModelName() string {
+ return "io.k8s.api.admissionregistration.v1.MutatingAdmissionPolicyBinding"
+}
+
+// OpenAPIModelName returns the OpenAPI model name for this type.
+func (in MutatingAdmissionPolicyBindingList) OpenAPIModelName() string {
+ return "io.k8s.api.admissionregistration.v1.MutatingAdmissionPolicyBindingList"
+}
+
+// OpenAPIModelName returns the OpenAPI model name for this type.
+func (in MutatingAdmissionPolicyBindingSpec) OpenAPIModelName() string {
+ return "io.k8s.api.admissionregistration.v1.MutatingAdmissionPolicyBindingSpec"
+}
+
+// OpenAPIModelName returns the OpenAPI model name for this type.
+func (in MutatingAdmissionPolicyList) OpenAPIModelName() string {
+ return "io.k8s.api.admissionregistration.v1.MutatingAdmissionPolicyList"
+}
+
+// OpenAPIModelName returns the OpenAPI model name for this type.
+func (in MutatingAdmissionPolicySpec) OpenAPIModelName() string {
+ return "io.k8s.api.admissionregistration.v1.MutatingAdmissionPolicySpec"
+}
+
// OpenAPIModelName returns the OpenAPI model name for this type.
func (in MutatingWebhook) OpenAPIModelName() string {
return "io.k8s.api.admissionregistration.v1.MutatingWebhook"
@@ -56,6 +96,11 @@ func (in MutatingWebhookConfigurationList) OpenAPIModelName() string {
return "io.k8s.api.admissionregistration.v1.MutatingWebhookConfigurationList"
}
+// OpenAPIModelName returns the OpenAPI model name for this type.
+func (in Mutation) OpenAPIModelName() string {
+ return "io.k8s.api.admissionregistration.v1.Mutation"
+}
+
// OpenAPIModelName returns the OpenAPI model name for this type.
func (in NamedRuleWithOperations) OpenAPIModelName() string {
return "io.k8s.api.admissionregistration.v1.NamedRuleWithOperations"
diff --git a/vendor/k8s.io/api/admissionregistration/v1/zz_generated.prerelease-lifecycle.go b/vendor/k8s.io/api/admissionregistration/v1/zz_generated.prerelease-lifecycle.go
index 0862bb1f2..5fde55f15 100644
--- a/vendor/k8s.io/api/admissionregistration/v1/zz_generated.prerelease-lifecycle.go
+++ b/vendor/k8s.io/api/admissionregistration/v1/zz_generated.prerelease-lifecycle.go
@@ -21,6 +21,30 @@ limitations under the License.
package v1
+// APILifecycleIntroduced is an autogenerated function, returning the release in which the API struct was introduced as int versions of major and minor for comparison.
+// It is controlled by "k8s:prerelease-lifecycle-gen:introduced" tags in types.go.
+func (in *MutatingAdmissionPolicy) APILifecycleIntroduced() (major, minor int) {
+ return 1, 36
+}
+
+// APILifecycleIntroduced is an autogenerated function, returning the release in which the API struct was introduced as int versions of major and minor for comparison.
+// It is controlled by "k8s:prerelease-lifecycle-gen:introduced" tags in types.go.
+func (in *MutatingAdmissionPolicyBinding) APILifecycleIntroduced() (major, minor int) {
+ return 1, 36
+}
+
+// APILifecycleIntroduced is an autogenerated function, returning the release in which the API struct was introduced as int versions of major and minor for comparison.
+// It is controlled by "k8s:prerelease-lifecycle-gen:introduced" tags in types.go.
+func (in *MutatingAdmissionPolicyBindingList) APILifecycleIntroduced() (major, minor int) {
+ return 1, 36
+}
+
+// APILifecycleIntroduced is an autogenerated function, returning the release in which the API struct was introduced as int versions of major and minor for comparison.
+// It is controlled by "k8s:prerelease-lifecycle-gen:introduced" tags in types.go.
+func (in *MutatingAdmissionPolicyList) APILifecycleIntroduced() (major, minor int) {
+ return 1, 36
+}
+
// APILifecycleIntroduced is an autogenerated function, returning the release in which the API struct was introduced as int versions of major and minor for comparison.
// It is controlled by "k8s:prerelease-lifecycle-gen:introduced" tags in types.go.
func (in *MutatingWebhookConfiguration) APILifecycleIntroduced() (major, minor int) {
diff --git a/vendor/k8s.io/api/admissionregistration/v1alpha1/generated.proto b/vendor/k8s.io/api/admissionregistration/v1alpha1/generated.proto
index d23f21cc8..57c7cd2b1 100644
--- a/vendor/k8s.io/api/admissionregistration/v1alpha1/generated.proto
+++ b/vendor/k8s.io/api/admissionregistration/v1alpha1/generated.proto
@@ -113,12 +113,12 @@ message AuditAnnotation {
// ExpressionWarning is a warning information that targets a specific expression.
message ExpressionWarning {
- // The path to the field that refers the expression.
+ // fieldRef is the path to the field that refers to the expression.
// For example, the reference to the expression of the first item of
// validations is "spec.validations[0].expression"
optional string fieldRef = 2;
- // The content of type checking information in a human-readable form.
+ // warning contains the content of type checking information in a human-readable form.
// Each line of the warning contains the type that the expression is checked
// against, followed by the type check error from the compiler.
optional string warning = 3;
@@ -194,7 +194,7 @@ message JSONPatch {
}
message MatchCondition {
- // Name is an identifier for this match condition, used for strategic merging of MatchConditions,
+ // name is an identifier for this match condition, used for strategic merging of MatchConditions,
// as well as providing an identifier for logging purposes. A good name should be descriptive of
// the associated expression.
// Name must be a qualified name consisting of alphanumeric characters, '-', '_' or '.', and
@@ -205,7 +205,7 @@ message MatchCondition {
// Required.
optional string name = 1;
- // Expression represents the expression which will be evaluated by CEL. Must evaluate to bool.
+ // expression represents the expression which will be evaluated by CEL. Must evaluate to bool.
// CEL expressions have access to the contents of the AdmissionRequest and Authorizer, organized into CEL variables:
//
// 'object' - The object from the incoming request. The value is null for DELETE requests.
@@ -226,7 +226,7 @@ message MatchCondition {
// The exclude rules take precedence over include rules (if a resource matches both, it is excluded)
// +structType=atomic
message MatchResources {
- // NamespaceSelector decides whether to run the admission control policy on an object based
+ // namespaceSelector decides whether to run the admission control policy on an object based
// on whether the namespace for that object matches the selector. If the
// object itself is a namespace, the matching is performed on
// object.metadata.labels. If the object is another cluster scoped resource,
@@ -272,7 +272,7 @@ message MatchResources {
// +optional
optional .k8s.io.apimachinery.pkg.apis.meta.v1.LabelSelector namespaceSelector = 1;
- // ObjectSelector decides whether to run the policy based on if the
+ // objectSelector decides whether to run the policy based on if the
// object has matching labels. objectSelector is evaluated against both
// the oldObject and newObject that would be sent to the policy's expression (CEL), and
// is considered to match if either object matches the selector. A null
@@ -286,13 +286,13 @@ message MatchResources {
// +optional
optional .k8s.io.apimachinery.pkg.apis.meta.v1.LabelSelector objectSelector = 2;
- // ResourceRules describes what operations on what resources/subresources the admission policy matches.
+ // resourceRules describes what operations on what resources/subresources the admission policy matches.
// The policy cares about an operation if it matches _any_ Rule.
// +listType=atomic
// +optional
repeated NamedRuleWithOperations resourceRules = 3;
- // ExcludeResourceRules describes what operations on what resources/subresources the policy should not care about.
+ // excludeResourceRules describes what operations on what resources/subresources the policy should not care about.
// The exclude rules take precedence over include rules (if a resource matches both, it is excluded)
// +listType=atomic
// +optional
@@ -319,11 +319,11 @@ message MatchResources {
// MutatingAdmissionPolicy describes the definition of an admission mutation policy that mutates the object coming into admission chain.
message MutatingAdmissionPolicy {
- // Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.
+ // metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.
// +optional
optional .k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1;
- // Specification of the desired behavior of the MutatingAdmissionPolicy.
+ // spec defines the desired behavior of the MutatingAdmissionPolicy.
optional MutatingAdmissionPolicySpec spec = 2;
}
@@ -339,17 +339,17 @@ message MutatingAdmissionPolicy {
// Adding/removing policies, bindings, or params can not affect whether a
// given (policy, binding, param) combination is within its own CEL budget.
message MutatingAdmissionPolicyBinding {
- // Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.
+ // metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.
// +optional
optional .k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1;
- // Specification of the desired behavior of the MutatingAdmissionPolicyBinding.
+ // spec defines the desired behavior of the MutatingAdmissionPolicyBinding.
optional MutatingAdmissionPolicyBindingSpec spec = 2;
}
// MutatingAdmissionPolicyBindingList is a list of MutatingAdmissionPolicyBinding.
message MutatingAdmissionPolicyBindingList {
- // Standard list metadata.
+ // metadata is the standard list metadata.
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
// +optional
optional .k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1;
@@ -387,7 +387,7 @@ message MutatingAdmissionPolicyBindingSpec {
// MutatingAdmissionPolicyList is a list of MutatingAdmissionPolicy.
message MutatingAdmissionPolicyList {
- // Standard list metadata.
+ // metadata is the standard list metadata.
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
// +optional
optional .k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1;
@@ -507,7 +507,7 @@ message Mutation {
// NamedRuleWithOperations is a tuple of Operations and Resources with ResourceNames.
// +structType=atomic
message NamedRuleWithOperations {
- // ResourceNames is an optional white list of names that the rule applies to. An empty set means that everything is allowed.
+ // resourceNames is an optional white list of names that the rule applies to. An empty set means that everything is allowed.
// +listType=atomic
// +optional
repeated string resourceNames = 1;
@@ -519,12 +519,12 @@ message NamedRuleWithOperations {
// ParamKind is a tuple of Group Kind and Version.
// +structType=atomic
message ParamKind {
- // APIVersion is the API group version the resources belong to.
+ // apiVersion is the API group version the resources belong to.
// In format of "group/version".
// Required.
optional string apiVersion = 1;
- // Kind is the API kind the resources belong to.
+ // kind is the API kind the resources belong to.
// Required.
optional string kind = 2;
}
@@ -533,7 +533,7 @@ message ParamKind {
// expressions of rules applied by a policy binding.
// +structType=atomic
message ParamRef {
- // `name` is the name of the resource being referenced.
+ // name is the name of the resource being referenced.
//
// `name` and `selector` are mutually exclusive properties. If one is set,
// the other must be unset.
@@ -571,7 +571,7 @@ message ParamRef {
// +optional
optional .k8s.io.apimachinery.pkg.apis.meta.v1.LabelSelector selector = 3;
- // `parameterNotFoundAction` controls the behavior of the binding when the resource
+ // parameterNotFoundAction controls the behavior of the binding when the resource
// exists, and name or selector is valid, but there are no parameters
// matched by the binding. If the value is set to `Allow`, then no
// matched parameters will be treated as successful validation by the binding.
@@ -587,7 +587,7 @@ message ParamRef {
// TypeChecking contains results of type checking the expressions in the
// ValidatingAdmissionPolicy
message TypeChecking {
- // The type checking warnings for each expression.
+ // expressionWarnings contains the type checking warnings for each expression.
// +optional
// +listType=atomic
repeated ExpressionWarning expressionWarnings = 1;
@@ -595,14 +595,14 @@ message TypeChecking {
// ValidatingAdmissionPolicy describes the definition of an admission validation policy that accepts or rejects an object without changing it.
message ValidatingAdmissionPolicy {
- // Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.
+ // metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.
// +optional
optional .k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1;
- // Specification of the desired behavior of the ValidatingAdmissionPolicy.
+ // spec defines the desired behavior of the ValidatingAdmissionPolicy.
optional ValidatingAdmissionPolicySpec spec = 2;
- // The status of the ValidatingAdmissionPolicy, including warnings that are useful to determine if the policy
+ // status represents the current status of the ValidatingAdmissionPolicy, including warnings that are useful to determine if the policy
// behaves in the expected way.
// Populated by the system.
// Read-only.
@@ -622,17 +622,18 @@ message ValidatingAdmissionPolicy {
// Adding/removing policies, bindings, or params can not affect whether a
// given (policy, binding, param) combination is within its own CEL budget.
message ValidatingAdmissionPolicyBinding {
- // Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.
+ // metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.
// +optional
optional .k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1;
- // Specification of the desired behavior of the ValidatingAdmissionPolicyBinding.
+ // spec defines the desired behavior of the ValidatingAdmissionPolicyBinding.
+ // +required
optional ValidatingAdmissionPolicyBindingSpec spec = 2;
}
// ValidatingAdmissionPolicyBindingList is a list of ValidatingAdmissionPolicyBinding.
message ValidatingAdmissionPolicyBindingList {
- // Standard list metadata.
+ // metadata is the standard list metadata.
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
// +optional
optional .k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1;
@@ -643,9 +644,11 @@ message ValidatingAdmissionPolicyBindingList {
// ValidatingAdmissionPolicyBindingSpec is the specification of the ValidatingAdmissionPolicyBinding.
message ValidatingAdmissionPolicyBindingSpec {
- // PolicyName references a ValidatingAdmissionPolicy name which the ValidatingAdmissionPolicyBinding binds to.
+ // policyName references a ValidatingAdmissionPolicy name which the ValidatingAdmissionPolicyBinding binds to.
// If the referenced resource does not exist, this binding is considered invalid and will be ignored
// Required.
+ // +required
+ // +k8s:alpha(since: "1.36")=+k8s:required
optional string policyName = 1;
// paramRef specifies the parameter resource used to configure the admission control policy.
@@ -655,7 +658,7 @@ message ValidatingAdmissionPolicyBindingSpec {
// +optional
optional ParamRef paramRef = 2;
- // MatchResources declares what resources match this binding and will be validated by it.
+ // matchResources declares what resources match this binding and will be validated by it.
// Note that this is intersected with the policy's matchConstraints, so only requests that are matched by the policy can be selected by this.
// If this is unset, all resources matched by the policy are validated by this binding
// When resourceRules is unset, it does not constrain resource matching. If a resource is matched by the other fields of this object, it will be validated.
@@ -703,12 +706,14 @@ message ValidatingAdmissionPolicyBindingSpec {
//
// Required.
// +listType=set
+ // +required
+ // +k8s:alpha(since: "1.36")=+k8s:required
repeated string validationActions = 4;
}
// ValidatingAdmissionPolicyList is a list of ValidatingAdmissionPolicy.
message ValidatingAdmissionPolicyList {
- // Standard list metadata.
+ // metadata is the standard list metadata.
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
// +optional
optional .k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1;
@@ -719,21 +724,21 @@ message ValidatingAdmissionPolicyList {
// ValidatingAdmissionPolicySpec is the specification of the desired behavior of the AdmissionPolicy.
message ValidatingAdmissionPolicySpec {
- // ParamKind specifies the kind of resources used to parameterize this policy.
+ // paramKind specifies the kind of resources used to parameterize this policy.
// If absent, there are no parameters for this policy and the param CEL variable will not be provided to validation expressions.
// If ParamKind refers to a non-existent kind, this policy definition is mis-configured and the FailurePolicy is applied.
// If paramKind is specified but paramRef is unset in ValidatingAdmissionPolicyBinding, the params variable will be null.
// +optional
optional ParamKind paramKind = 1;
- // MatchConstraints specifies what resources this policy is designed to validate.
+ // matchConstraints specifies what resources this policy is designed to validate.
// The AdmissionPolicy cares about a request if it matches _all_ Constraints.
// However, in order to prevent clusters from being put into an unstable state that cannot be recovered from via the API
// ValidatingAdmissionPolicy cannot match ValidatingAdmissionPolicy and ValidatingAdmissionPolicyBinding.
// Required.
optional MatchResources matchConstraints = 2;
- // Validations contain CEL expressions which is used to apply the validation.
+ // validations contain CEL expressions which is used to apply the validation.
// Validations and AuditAnnotations may not both be empty; a minimum of one Validations or AuditAnnotations is
// required.
// +listType=atomic
@@ -764,7 +769,7 @@ message ValidatingAdmissionPolicySpec {
// +optional
repeated AuditAnnotation auditAnnotations = 5;
- // MatchConditions is a list of conditions that must be met for a request to be validated.
+ // matchConditions is a list of conditions that must be met for a request to be validated.
// Match conditions filter requests that have already been matched by the rules,
// namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests.
// There are a maximum of 64 match conditions allowed.
@@ -786,7 +791,7 @@ message ValidatingAdmissionPolicySpec {
// +optional
repeated MatchCondition matchConditions = 6;
- // Variables contain definitions of variables that can be used in composition of other expressions.
+ // variables contain definitions of variables that can be used in composition of other expressions.
// Each variable is defined as a named CEL expression.
// The variables defined here will be available under `variables` in other expressions of the policy
// except MatchConditions because MatchConditions are evaluated before the rest of the policy.
@@ -803,16 +808,16 @@ message ValidatingAdmissionPolicySpec {
// ValidatingAdmissionPolicyStatus represents the status of a ValidatingAdmissionPolicy.
message ValidatingAdmissionPolicyStatus {
- // The generation observed by the controller.
+ // observedGeneration is the generation observed by the controller.
// +optional
optional int64 observedGeneration = 1;
- // The results of type checking for each expression.
+ // typeChecking contains the results of type checking for each expression.
// Presence of this field indicates the completion of the type checking.
// +optional
optional TypeChecking typeChecking = 2;
- // The conditions represent the latest available observations of a policy's current state.
+ // conditions represent the latest available observations of a policy's current state.
// +optional
// +listType=map
// +listMapKey=type
@@ -821,7 +826,7 @@ message ValidatingAdmissionPolicyStatus {
// Validation specifies the CEL expression which is used to apply the validation.
message Validation {
- // Expression represents the expression which will be evaluated by CEL.
+ // expression represents the expression which will be evaluated by CEL.
// ref: https://github.com/google/cel-spec
// CEL expressions have access to the contents of the API request/response, organized into CEL variables as well as some other useful variables:
//
@@ -864,7 +869,7 @@ message Validation {
// Required.
optional string Expression = 1;
- // Message represents the message displayed when validation fails. The message is required if the Expression contains
+ // message represents the message displayed when validation fails. The message is required if the Expression contains
// line breaks. The message must not contain line breaks.
// If unset, the message is "failed rule: {Rule}".
// e.g. "must be a URL with the host matching spec.host"
@@ -874,7 +879,7 @@ message Validation {
// +optional
optional string message = 2;
- // Reason represents a machine-readable description of why this validation failed.
+ // reason represents a machine-readable description of why this validation failed.
// If this is the first validation in the list to fail, this reason, as well as the
// corresponding HTTP response code, are used in the
// HTTP response to the client.
@@ -899,12 +904,12 @@ message Validation {
// Variable is the definition of a variable that is used for composition.
message Variable {
- // Name is the name of the variable. The name must be a valid CEL identifier and unique among all variables.
+ // name is the name of the variable. The name must be a valid CEL identifier and unique among all variables.
// The variable can be accessed in other expressions through `variables`
// For example, if name is "foo", the variable will be available as `variables.foo`
optional string Name = 1;
- // Expression is the expression that will be evaluated as the value of the variable.
+ // expression is the expression that will be evaluated as the value of the variable.
// The CEL expression has access to the same identifiers as the CEL expressions in Validation.
optional string Expression = 2;
}
diff --git a/vendor/k8s.io/api/admissionregistration/v1alpha1/generated.protomessage.pb.go b/vendor/k8s.io/api/admissionregistration/v1alpha1/generated.protomessage.pb.go
deleted file mode 100644
index 651a01f0b..000000000
--- a/vendor/k8s.io/api/admissionregistration/v1alpha1/generated.protomessage.pb.go
+++ /dev/null
@@ -1,74 +0,0 @@
-//go:build kubernetes_protomessage_one_more_release
-// +build kubernetes_protomessage_one_more_release
-
-/*
-Copyright The Kubernetes Authors.
-
-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.
-*/
-
-// Code generated by go-to-protobuf. DO NOT EDIT.
-
-package v1alpha1
-
-func (*ApplyConfiguration) ProtoMessage() {}
-
-func (*AuditAnnotation) ProtoMessage() {}
-
-func (*ExpressionWarning) ProtoMessage() {}
-
-func (*JSONPatch) ProtoMessage() {}
-
-func (*MatchCondition) ProtoMessage() {}
-
-func (*MatchResources) ProtoMessage() {}
-
-func (*MutatingAdmissionPolicy) ProtoMessage() {}
-
-func (*MutatingAdmissionPolicyBinding) ProtoMessage() {}
-
-func (*MutatingAdmissionPolicyBindingList) ProtoMessage() {}
-
-func (*MutatingAdmissionPolicyBindingSpec) ProtoMessage() {}
-
-func (*MutatingAdmissionPolicyList) ProtoMessage() {}
-
-func (*MutatingAdmissionPolicySpec) ProtoMessage() {}
-
-func (*Mutation) ProtoMessage() {}
-
-func (*NamedRuleWithOperations) ProtoMessage() {}
-
-func (*ParamKind) ProtoMessage() {}
-
-func (*ParamRef) ProtoMessage() {}
-
-func (*TypeChecking) ProtoMessage() {}
-
-func (*ValidatingAdmissionPolicy) ProtoMessage() {}
-
-func (*ValidatingAdmissionPolicyBinding) ProtoMessage() {}
-
-func (*ValidatingAdmissionPolicyBindingList) ProtoMessage() {}
-
-func (*ValidatingAdmissionPolicyBindingSpec) ProtoMessage() {}
-
-func (*ValidatingAdmissionPolicyList) ProtoMessage() {}
-
-func (*ValidatingAdmissionPolicySpec) ProtoMessage() {}
-
-func (*ValidatingAdmissionPolicyStatus) ProtoMessage() {}
-
-func (*Validation) ProtoMessage() {}
-
-func (*Variable) ProtoMessage() {}
diff --git a/vendor/k8s.io/api/admissionregistration/v1alpha1/types.go b/vendor/k8s.io/api/admissionregistration/v1alpha1/types.go
index 459f7944c..6a789b2d7 100644
--- a/vendor/k8s.io/api/admissionregistration/v1alpha1/types.go
+++ b/vendor/k8s.io/api/admissionregistration/v1alpha1/types.go
@@ -83,12 +83,12 @@ const (
// ValidatingAdmissionPolicy describes the definition of an admission validation policy that accepts or rejects an object without changing it.
type ValidatingAdmissionPolicy struct {
metav1.TypeMeta `json:",inline"`
- // Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.
+ // metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.
// +optional
metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
- // Specification of the desired behavior of the ValidatingAdmissionPolicy.
+ // spec defines the desired behavior of the ValidatingAdmissionPolicy.
Spec ValidatingAdmissionPolicySpec `json:"spec,omitempty" protobuf:"bytes,2,opt,name=spec"`
- // The status of the ValidatingAdmissionPolicy, including warnings that are useful to determine if the policy
+ // status represents the current status of the ValidatingAdmissionPolicy, including warnings that are useful to determine if the policy
// behaves in the expected way.
// Populated by the system.
// Read-only.
@@ -98,14 +98,14 @@ type ValidatingAdmissionPolicy struct {
// ValidatingAdmissionPolicyStatus represents the status of a ValidatingAdmissionPolicy.
type ValidatingAdmissionPolicyStatus struct {
- // The generation observed by the controller.
+ // observedGeneration is the generation observed by the controller.
// +optional
ObservedGeneration int64 `json:"observedGeneration,omitempty" protobuf:"varint,1,opt,name=observedGeneration"`
- // The results of type checking for each expression.
+ // typeChecking contains the results of type checking for each expression.
// Presence of this field indicates the completion of the type checking.
// +optional
TypeChecking *TypeChecking `json:"typeChecking,omitempty" protobuf:"bytes,2,opt,name=typeChecking"`
- // The conditions represent the latest available observations of a policy's current state.
+ // conditions represent the latest available observations of a policy's current state.
// +optional
// +listType=map
// +listMapKey=type
@@ -115,7 +115,7 @@ type ValidatingAdmissionPolicyStatus struct {
// TypeChecking contains results of type checking the expressions in the
// ValidatingAdmissionPolicy
type TypeChecking struct {
- // The type checking warnings for each expression.
+ // expressionWarnings contains the type checking warnings for each expression.
// +optional
// +listType=atomic
ExpressionWarnings []ExpressionWarning `json:"expressionWarnings,omitempty" protobuf:"bytes,1,rep,name=expressionWarnings"`
@@ -123,11 +123,11 @@ type TypeChecking struct {
// ExpressionWarning is a warning information that targets a specific expression.
type ExpressionWarning struct {
- // The path to the field that refers the expression.
+ // fieldRef is the path to the field that refers to the expression.
// For example, the reference to the expression of the first item of
// validations is "spec.validations[0].expression"
FieldRef string `json:"fieldRef" protobuf:"bytes,2,opt,name=fieldRef"`
- // The content of type checking information in a human-readable form.
+ // warning contains the content of type checking information in a human-readable form.
// Each line of the warning contains the type that the expression is checked
// against, followed by the type check error from the compiler.
Warning string `json:"warning" protobuf:"bytes,3,opt,name=warning"`
@@ -139,7 +139,7 @@ type ExpressionWarning struct {
// ValidatingAdmissionPolicyList is a list of ValidatingAdmissionPolicy.
type ValidatingAdmissionPolicyList struct {
metav1.TypeMeta `json:",inline"`
- // Standard list metadata.
+ // metadata is the standard list metadata.
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
// +optional
metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
@@ -149,21 +149,21 @@ type ValidatingAdmissionPolicyList struct {
// ValidatingAdmissionPolicySpec is the specification of the desired behavior of the AdmissionPolicy.
type ValidatingAdmissionPolicySpec struct {
- // ParamKind specifies the kind of resources used to parameterize this policy.
+ // paramKind specifies the kind of resources used to parameterize this policy.
// If absent, there are no parameters for this policy and the param CEL variable will not be provided to validation expressions.
// If ParamKind refers to a non-existent kind, this policy definition is mis-configured and the FailurePolicy is applied.
// If paramKind is specified but paramRef is unset in ValidatingAdmissionPolicyBinding, the params variable will be null.
// +optional
ParamKind *ParamKind `json:"paramKind,omitempty" protobuf:"bytes,1,rep,name=paramKind"`
- // MatchConstraints specifies what resources this policy is designed to validate.
+ // matchConstraints specifies what resources this policy is designed to validate.
// The AdmissionPolicy cares about a request if it matches _all_ Constraints.
// However, in order to prevent clusters from being put into an unstable state that cannot be recovered from via the API
// ValidatingAdmissionPolicy cannot match ValidatingAdmissionPolicy and ValidatingAdmissionPolicyBinding.
// Required.
MatchConstraints *MatchResources `json:"matchConstraints,omitempty" protobuf:"bytes,2,rep,name=matchConstraints"`
- // Validations contain CEL expressions which is used to apply the validation.
+ // validations contain CEL expressions which is used to apply the validation.
// Validations and AuditAnnotations may not both be empty; a minimum of one Validations or AuditAnnotations is
// required.
// +listType=atomic
@@ -194,7 +194,7 @@ type ValidatingAdmissionPolicySpec struct {
// +optional
AuditAnnotations []AuditAnnotation `json:"auditAnnotations,omitempty" protobuf:"bytes,5,rep,name=auditAnnotations"`
- // MatchConditions is a list of conditions that must be met for a request to be validated.
+ // matchConditions is a list of conditions that must be met for a request to be validated.
// Match conditions filter requests that have already been matched by the rules,
// namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests.
// There are a maximum of 64 match conditions allowed.
@@ -216,7 +216,7 @@ type ValidatingAdmissionPolicySpec struct {
// +optional
MatchConditions []MatchCondition `json:"matchConditions,omitempty" patchStrategy:"merge" patchMergeKey:"name" protobuf:"bytes,6,rep,name=matchConditions"`
- // Variables contain definitions of variables that can be used in composition of other expressions.
+ // variables contain definitions of variables that can be used in composition of other expressions.
// Each variable is defined as a named CEL expression.
// The variables defined here will be available under `variables` in other expressions of the policy
// except MatchConditions because MatchConditions are evaluated before the rest of the policy.
@@ -236,19 +236,19 @@ type MatchCondition v1.MatchCondition
// ParamKind is a tuple of Group Kind and Version.
// +structType=atomic
type ParamKind struct {
- // APIVersion is the API group version the resources belong to.
+ // apiVersion is the API group version the resources belong to.
// In format of "group/version".
// Required.
APIVersion string `json:"apiVersion,omitempty" protobuf:"bytes,1,rep,name=apiVersion"`
- // Kind is the API kind the resources belong to.
+ // kind is the API kind the resources belong to.
// Required.
Kind string `json:"kind,omitempty" protobuf:"bytes,2,rep,name=kind"`
}
// Validation specifies the CEL expression which is used to apply the validation.
type Validation struct {
- // Expression represents the expression which will be evaluated by CEL.
+ // expression represents the expression which will be evaluated by CEL.
// ref: https://github.com/google/cel-spec
// CEL expressions have access to the contents of the API request/response, organized into CEL variables as well as some other useful variables:
//
@@ -290,7 +290,7 @@ type Validation struct {
// non-intersecting keys are appended, retaining their partial order.
// Required.
Expression string `json:"expression" protobuf:"bytes,1,opt,name=Expression"`
- // Message represents the message displayed when validation fails. The message is required if the Expression contains
+ // message represents the message displayed when validation fails. The message is required if the Expression contains
// line breaks. The message must not contain line breaks.
// If unset, the message is "failed rule: {Rule}".
// e.g. "must be a URL with the host matching spec.host"
@@ -299,7 +299,7 @@ type Validation struct {
// If unset, the message is "failed Expression: {Expression}".
// +optional
Message string `json:"message,omitempty" protobuf:"bytes,2,opt,name=message"`
- // Reason represents a machine-readable description of why this validation failed.
+ // reason represents a machine-readable description of why this validation failed.
// If this is the first validation in the list to fail, this reason, as well as the
// corresponding HTTP response code, are used in the
// HTTP response to the client.
@@ -323,12 +323,12 @@ type Validation struct {
// Variable is the definition of a variable that is used for composition.
type Variable struct {
- // Name is the name of the variable. The name must be a valid CEL identifier and unique among all variables.
+ // name is the name of the variable. The name must be a valid CEL identifier and unique among all variables.
// The variable can be accessed in other expressions through `variables`
// For example, if name is "foo", the variable will be available as `variables.foo`
Name string `json:"name" protobuf:"bytes,1,opt,name=Name"`
- // Expression is the expression that will be evaluated as the value of the variable.
+ // expression is the expression that will be evaluated as the value of the variable.
// The CEL expression has access to the same identifiers as the CEL expressions in Validation.
Expression string `json:"expression" protobuf:"bytes,2,opt,name=Expression"`
}
@@ -388,10 +388,11 @@ type AuditAnnotation struct {
// given (policy, binding, param) combination is within its own CEL budget.
type ValidatingAdmissionPolicyBinding struct {
metav1.TypeMeta `json:",inline"`
- // Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.
+ // metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.
// +optional
metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
- // Specification of the desired behavior of the ValidatingAdmissionPolicyBinding.
+ // spec defines the desired behavior of the ValidatingAdmissionPolicyBinding.
+ // +required
Spec ValidatingAdmissionPolicyBindingSpec `json:"spec,omitempty" protobuf:"bytes,2,opt,name=spec"`
}
@@ -401,7 +402,7 @@ type ValidatingAdmissionPolicyBinding struct {
// ValidatingAdmissionPolicyBindingList is a list of ValidatingAdmissionPolicyBinding.
type ValidatingAdmissionPolicyBindingList struct {
metav1.TypeMeta `json:",inline"`
- // Standard list metadata.
+ // metadata is the standard list metadata.
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
// +optional
metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
@@ -411,9 +412,11 @@ type ValidatingAdmissionPolicyBindingList struct {
// ValidatingAdmissionPolicyBindingSpec is the specification of the ValidatingAdmissionPolicyBinding.
type ValidatingAdmissionPolicyBindingSpec struct {
- // PolicyName references a ValidatingAdmissionPolicy name which the ValidatingAdmissionPolicyBinding binds to.
+ // policyName references a ValidatingAdmissionPolicy name which the ValidatingAdmissionPolicyBinding binds to.
// If the referenced resource does not exist, this binding is considered invalid and will be ignored
// Required.
+ // +required
+ // +k8s:alpha(since: "1.36")=+k8s:required
PolicyName string `json:"policyName,omitempty" protobuf:"bytes,1,rep,name=policyName"`
// paramRef specifies the parameter resource used to configure the admission control policy.
@@ -423,7 +426,7 @@ type ValidatingAdmissionPolicyBindingSpec struct {
// +optional
ParamRef *ParamRef `json:"paramRef,omitempty" protobuf:"bytes,2,rep,name=paramRef"`
- // MatchResources declares what resources match this binding and will be validated by it.
+ // matchResources declares what resources match this binding and will be validated by it.
// Note that this is intersected with the policy's matchConstraints, so only requests that are matched by the policy can be selected by this.
// If this is unset, all resources matched by the policy are validated by this binding
// When resourceRules is unset, it does not constrain resource matching. If a resource is matched by the other fields of this object, it will be validated.
@@ -471,6 +474,8 @@ type ValidatingAdmissionPolicyBindingSpec struct {
//
// Required.
// +listType=set
+ // +required
+ // +k8s:alpha(since: "1.36")=+k8s:required
ValidationActions []ValidationAction `json:"validationActions,omitempty" protobuf:"bytes,4,rep,name=validationActions"`
}
@@ -478,7 +483,7 @@ type ValidatingAdmissionPolicyBindingSpec struct {
// expressions of rules applied by a policy binding.
// +structType=atomic
type ParamRef struct {
- // `name` is the name of the resource being referenced.
+ // name is the name of the resource being referenced.
//
// `name` and `selector` are mutually exclusive properties. If one is set,
// the other must be unset.
@@ -516,7 +521,7 @@ type ParamRef struct {
// +optional
Selector *metav1.LabelSelector `json:"selector,omitempty" protobuf:"bytes,3,rep,name=selector"`
- // `parameterNotFoundAction` controls the behavior of the binding when the resource
+ // parameterNotFoundAction controls the behavior of the binding when the resource
// exists, and name or selector is valid, but there are no parameters
// matched by the binding. If the value is set to `Allow`, then no
// matched parameters will be treated as successful validation by the binding.
@@ -534,7 +539,7 @@ type ParamRef struct {
// The exclude rules take precedence over include rules (if a resource matches both, it is excluded)
// +structType=atomic
type MatchResources struct {
- // NamespaceSelector decides whether to run the admission control policy on an object based
+ // namespaceSelector decides whether to run the admission control policy on an object based
// on whether the namespace for that object matches the selector. If the
// object itself is a namespace, the matching is performed on
// object.metadata.labels. If the object is another cluster scoped resource,
@@ -579,7 +584,7 @@ type MatchResources struct {
// Default to the empty LabelSelector, which matches everything.
// +optional
NamespaceSelector *metav1.LabelSelector `json:"namespaceSelector,omitempty" protobuf:"bytes,1,opt,name=namespaceSelector"`
- // ObjectSelector decides whether to run the policy based on if the
+ // objectSelector decides whether to run the policy based on if the
// object has matching labels. objectSelector is evaluated against both
// the oldObject and newObject that would be sent to the policy's expression (CEL), and
// is considered to match if either object matches the selector. A null
@@ -592,12 +597,12 @@ type MatchResources struct {
// Default to the empty LabelSelector, which matches everything.
// +optional
ObjectSelector *metav1.LabelSelector `json:"objectSelector,omitempty" protobuf:"bytes,2,opt,name=objectSelector"`
- // ResourceRules describes what operations on what resources/subresources the admission policy matches.
+ // resourceRules describes what operations on what resources/subresources the admission policy matches.
// The policy cares about an operation if it matches _any_ Rule.
// +listType=atomic
// +optional
ResourceRules []NamedRuleWithOperations `json:"resourceRules,omitempty" protobuf:"bytes,3,rep,name=resourceRules"`
- // ExcludeResourceRules describes what operations on what resources/subresources the policy should not care about.
+ // excludeResourceRules describes what operations on what resources/subresources the policy should not care about.
// The exclude rules take precedence over include rules (if a resource matches both, it is excluded)
// +listType=atomic
// +optional
@@ -642,7 +647,7 @@ const (
// NamedRuleWithOperations is a tuple of Operations and Resources with ResourceNames.
// +structType=atomic
type NamedRuleWithOperations struct {
- // ResourceNames is an optional white list of names that the rule applies to. An empty set means that everything is allowed.
+ // resourceNames is an optional white list of names that the rule applies to. An empty set means that everything is allowed.
// +listType=atomic
// +optional
ResourceNames []string `json:"resourceNames,omitempty" protobuf:"bytes,1,rep,name=resourceNames"`
@@ -675,10 +680,10 @@ const (
// MutatingAdmissionPolicy describes the definition of an admission mutation policy that mutates the object coming into admission chain.
type MutatingAdmissionPolicy struct {
metav1.TypeMeta `json:",inline"`
- // Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.
+ // metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.
// +optional
metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
- // Specification of the desired behavior of the MutatingAdmissionPolicy.
+ // spec defines the desired behavior of the MutatingAdmissionPolicy.
Spec MutatingAdmissionPolicySpec `json:"spec,omitempty" protobuf:"bytes,2,opt,name=spec"`
}
@@ -688,7 +693,7 @@ type MutatingAdmissionPolicy struct {
// MutatingAdmissionPolicyList is a list of MutatingAdmissionPolicy.
type MutatingAdmissionPolicyList struct {
metav1.TypeMeta `json:",inline"`
- // Standard list metadata.
+ // metadata is the standard list metadata.
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
// +optional
metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
@@ -963,10 +968,10 @@ const (
// given (policy, binding, param) combination is within its own CEL budget.
type MutatingAdmissionPolicyBinding struct {
metav1.TypeMeta `json:",inline"`
- // Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.
+ // metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.
// +optional
metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
- // Specification of the desired behavior of the MutatingAdmissionPolicyBinding.
+ // spec defines the desired behavior of the MutatingAdmissionPolicyBinding.
Spec MutatingAdmissionPolicyBindingSpec `json:"spec,omitempty" protobuf:"bytes,2,opt,name=spec"`
}
@@ -976,7 +981,7 @@ type MutatingAdmissionPolicyBinding struct {
// MutatingAdmissionPolicyBindingList is a list of MutatingAdmissionPolicyBinding.
type MutatingAdmissionPolicyBindingList struct {
metav1.TypeMeta `json:",inline"`
- // Standard list metadata.
+ // metadata is the standard list metadata.
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
// +optional
metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
diff --git a/vendor/k8s.io/api/admissionregistration/v1alpha1/types_swagger_doc_generated.go b/vendor/k8s.io/api/admissionregistration/v1alpha1/types_swagger_doc_generated.go
index 116e56e06..4b2b13bc4 100644
--- a/vendor/k8s.io/api/admissionregistration/v1alpha1/types_swagger_doc_generated.go
+++ b/vendor/k8s.io/api/admissionregistration/v1alpha1/types_swagger_doc_generated.go
@@ -48,8 +48,8 @@ func (AuditAnnotation) SwaggerDoc() map[string]string {
var map_ExpressionWarning = map[string]string{
"": "ExpressionWarning is a warning information that targets a specific expression.",
- "fieldRef": "The path to the field that refers the expression. For example, the reference to the expression of the first item of validations is \"spec.validations[0].expression\"",
- "warning": "The content of type checking information in a human-readable form. Each line of the warning contains the type that the expression is checked against, followed by the type check error from the compiler.",
+ "fieldRef": "fieldRef is the path to the field that refers to the expression. For example, the reference to the expression of the first item of validations is \"spec.validations[0].expression\"",
+ "warning": "warning contains the content of type checking information in a human-readable form. Each line of the warning contains the type that the expression is checked against, followed by the type check error from the compiler.",
}
func (ExpressionWarning) SwaggerDoc() map[string]string {
@@ -67,10 +67,10 @@ func (JSONPatch) SwaggerDoc() map[string]string {
var map_MatchResources = map[string]string{
"": "MatchResources decides whether to run the admission control policy on an object based on whether it meets the match criteria. The exclude rules take precedence over include rules (if a resource matches both, it is excluded)",
- "namespaceSelector": "NamespaceSelector decides whether to run the admission control policy on an object based on whether the namespace for that object matches the selector. If the object itself is a namespace, the matching is performed on object.metadata.labels. If the object is another cluster scoped resource, it never skips the policy.\n\nFor example, to run the webhook on any objects whose namespace is not associated with \"runlevel\" of \"0\" or \"1\"; you will set the selector as follows: \"namespaceSelector\": {\n \"matchExpressions\": [\n {\n \"key\": \"runlevel\",\n \"operator\": \"NotIn\",\n \"values\": [\n \"0\",\n \"1\"\n ]\n }\n ]\n}\n\nIf instead you want to only run the policy on any objects whose namespace is associated with the \"environment\" of \"prod\" or \"staging\"; you will set the selector as follows: \"namespaceSelector\": {\n \"matchExpressions\": [\n {\n \"key\": \"environment\",\n \"operator\": \"In\",\n \"values\": [\n \"prod\",\n \"staging\"\n ]\n }\n ]\n}\n\nSee https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ for more examples of label selectors.\n\nDefault to the empty LabelSelector, which matches everything.",
- "objectSelector": "ObjectSelector decides whether to run the policy based on if the object has matching labels. objectSelector is evaluated against both the oldObject and newObject that would be sent to the policy's expression (CEL), and is considered to match if either object matches the selector. A null object (oldObject in the case of create, or newObject in the case of delete) or an object that cannot have labels (like a DeploymentRollback or a PodProxyOptions object) is not considered to match. Use the object selector only if the webhook is opt-in, because end users may skip the admission webhook by setting the labels. Default to the empty LabelSelector, which matches everything.",
- "resourceRules": "ResourceRules describes what operations on what resources/subresources the admission policy matches. The policy cares about an operation if it matches _any_ Rule.",
- "excludeResourceRules": "ExcludeResourceRules describes what operations on what resources/subresources the policy should not care about. The exclude rules take precedence over include rules (if a resource matches both, it is excluded)",
+ "namespaceSelector": "namespaceSelector decides whether to run the admission control policy on an object based on whether the namespace for that object matches the selector. If the object itself is a namespace, the matching is performed on object.metadata.labels. If the object is another cluster scoped resource, it never skips the policy.\n\nFor example, to run the webhook on any objects whose namespace is not associated with \"runlevel\" of \"0\" or \"1\"; you will set the selector as follows: \"namespaceSelector\": {\n \"matchExpressions\": [\n {\n \"key\": \"runlevel\",\n \"operator\": \"NotIn\",\n \"values\": [\n \"0\",\n \"1\"\n ]\n }\n ]\n}\n\nIf instead you want to only run the policy on any objects whose namespace is associated with the \"environment\" of \"prod\" or \"staging\"; you will set the selector as follows: \"namespaceSelector\": {\n \"matchExpressions\": [\n {\n \"key\": \"environment\",\n \"operator\": \"In\",\n \"values\": [\n \"prod\",\n \"staging\"\n ]\n }\n ]\n}\n\nSee https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ for more examples of label selectors.\n\nDefault to the empty LabelSelector, which matches everything.",
+ "objectSelector": "objectSelector decides whether to run the policy based on if the object has matching labels. objectSelector is evaluated against both the oldObject and newObject that would be sent to the policy's expression (CEL), and is considered to match if either object matches the selector. A null object (oldObject in the case of create, or newObject in the case of delete) or an object that cannot have labels (like a DeploymentRollback or a PodProxyOptions object) is not considered to match. Use the object selector only if the webhook is opt-in, because end users may skip the admission webhook by setting the labels. Default to the empty LabelSelector, which matches everything.",
+ "resourceRules": "resourceRules describes what operations on what resources/subresources the admission policy matches. The policy cares about an operation if it matches _any_ Rule.",
+ "excludeResourceRules": "excludeResourceRules describes what operations on what resources/subresources the policy should not care about. The exclude rules take precedence over include rules (if a resource matches both, it is excluded)",
"matchPolicy": "matchPolicy defines how the \"MatchResources\" list is used to match incoming requests. Allowed values are \"Exact\" or \"Equivalent\".\n\n- Exact: match a request only if it exactly matches a specified rule. For example, if deployments can be modified via apps/v1, apps/v1beta1, and extensions/v1beta1, but \"rules\" only included `apiGroups:[\"apps\"], apiVersions:[\"v1\"], resources: [\"deployments\"]`, the admission policy does not consider requests to apps/v1beta1 or extensions/v1beta1 API groups.\n\n- Equivalent: match a request if modifies a resource listed in rules, even via another API group or version. For example, if deployments can be modified via apps/v1, apps/v1beta1, and extensions/v1beta1, and \"rules\" only included `apiGroups:[\"apps\"], apiVersions:[\"v1\"], resources: [\"deployments\"]`, the admission policy **does** consider requests made to apps/v1beta1 or extensions/v1beta1 API groups. The API server translates the request to a matched resource API if necessary.\n\nDefaults to \"Equivalent\"",
}
@@ -80,8 +80,8 @@ func (MatchResources) SwaggerDoc() map[string]string {
var map_MutatingAdmissionPolicy = map[string]string{
"": "MutatingAdmissionPolicy describes the definition of an admission mutation policy that mutates the object coming into admission chain.",
- "metadata": "Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.",
- "spec": "Specification of the desired behavior of the MutatingAdmissionPolicy.",
+ "metadata": "metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.",
+ "spec": "spec defines the desired behavior of the MutatingAdmissionPolicy.",
}
func (MutatingAdmissionPolicy) SwaggerDoc() map[string]string {
@@ -90,8 +90,8 @@ func (MutatingAdmissionPolicy) SwaggerDoc() map[string]string {
var map_MutatingAdmissionPolicyBinding = map[string]string{
"": "MutatingAdmissionPolicyBinding binds the MutatingAdmissionPolicy with parametrized resources. MutatingAdmissionPolicyBinding and the optional parameter resource together define how cluster administrators configure policies for clusters.\n\nFor a given admission request, each binding will cause its policy to be evaluated N times, where N is 1 for policies/bindings that don't use params, otherwise N is the number of parameters selected by the binding. Each evaluation is constrained by a [runtime cost budget](https://kubernetes.io/docs/reference/using-api/cel/#runtime-cost-budget).\n\nAdding/removing policies, bindings, or params can not affect whether a given (policy, binding, param) combination is within its own CEL budget.",
- "metadata": "Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.",
- "spec": "Specification of the desired behavior of the MutatingAdmissionPolicyBinding.",
+ "metadata": "metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.",
+ "spec": "spec defines the desired behavior of the MutatingAdmissionPolicyBinding.",
}
func (MutatingAdmissionPolicyBinding) SwaggerDoc() map[string]string {
@@ -100,7 +100,7 @@ func (MutatingAdmissionPolicyBinding) SwaggerDoc() map[string]string {
var map_MutatingAdmissionPolicyBindingList = map[string]string{
"": "MutatingAdmissionPolicyBindingList is a list of MutatingAdmissionPolicyBinding.",
- "metadata": "Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds",
+ "metadata": "metadata is the standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds",
"items": "List of PolicyBinding.",
}
@@ -121,7 +121,7 @@ func (MutatingAdmissionPolicyBindingSpec) SwaggerDoc() map[string]string {
var map_MutatingAdmissionPolicyList = map[string]string{
"": "MutatingAdmissionPolicyList is a list of MutatingAdmissionPolicy.",
- "metadata": "Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds",
+ "metadata": "metadata is the standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds",
"items": "List of ValidatingAdmissionPolicy.",
}
@@ -157,7 +157,7 @@ func (Mutation) SwaggerDoc() map[string]string {
var map_NamedRuleWithOperations = map[string]string{
"": "NamedRuleWithOperations is a tuple of Operations and Resources with ResourceNames.",
- "resourceNames": "ResourceNames is an optional white list of names that the rule applies to. An empty set means that everything is allowed.",
+ "resourceNames": "resourceNames is an optional white list of names that the rule applies to. An empty set means that everything is allowed.",
}
func (NamedRuleWithOperations) SwaggerDoc() map[string]string {
@@ -166,8 +166,8 @@ func (NamedRuleWithOperations) SwaggerDoc() map[string]string {
var map_ParamKind = map[string]string{
"": "ParamKind is a tuple of Group Kind and Version.",
- "apiVersion": "APIVersion is the API group version the resources belong to. In format of \"group/version\". Required.",
- "kind": "Kind is the API kind the resources belong to. Required.",
+ "apiVersion": "apiVersion is the API group version the resources belong to. In format of \"group/version\". Required.",
+ "kind": "kind is the API kind the resources belong to. Required.",
}
func (ParamKind) SwaggerDoc() map[string]string {
@@ -176,10 +176,10 @@ func (ParamKind) SwaggerDoc() map[string]string {
var map_ParamRef = map[string]string{
"": "ParamRef describes how to locate the params to be used as input to expressions of rules applied by a policy binding.",
- "name": "`name` is the name of the resource being referenced.\n\n`name` and `selector` are mutually exclusive properties. If one is set, the other must be unset.",
+ "name": "name is the name of the resource being referenced.\n\n`name` and `selector` are mutually exclusive properties. If one is set, the other must be unset.",
"namespace": "namespace is the namespace of the referenced resource. Allows limiting the search for params to a specific namespace. Applies to both `name` and `selector` fields.\n\nA per-namespace parameter may be used by specifying a namespace-scoped `paramKind` in the policy and leaving this field empty.\n\n- If `paramKind` is cluster-scoped, this field MUST be unset. Setting this field results in a configuration error.\n\n- If `paramKind` is namespace-scoped, the namespace of the object being evaluated for admission will be used when this field is left unset. Take care that if this is left empty the binding must not match any cluster-scoped resources, which will result in an error.",
"selector": "selector can be used to match multiple param objects based on their labels. Supply selector: {} to match all resources of the ParamKind.\n\nIf multiple params are found, they are all evaluated with the policy expressions and the results are ANDed together.\n\nOne of `name` or `selector` must be set, but `name` and `selector` are mutually exclusive properties. If one is set, the other must be unset.",
- "parameterNotFoundAction": "`parameterNotFoundAction` controls the behavior of the binding when the resource exists, and name or selector is valid, but there are no parameters matched by the binding. If the value is set to `Allow`, then no matched parameters will be treated as successful validation by the binding. If set to `Deny`, then no matched parameters will be subject to the `failurePolicy` of the policy.\n\nAllowed values are `Allow` or `Deny` Default to `Deny`",
+ "parameterNotFoundAction": "parameterNotFoundAction controls the behavior of the binding when the resource exists, and name or selector is valid, but there are no parameters matched by the binding. If the value is set to `Allow`, then no matched parameters will be treated as successful validation by the binding. If set to `Deny`, then no matched parameters will be subject to the `failurePolicy` of the policy.\n\nAllowed values are `Allow` or `Deny` Default to `Deny`",
}
func (ParamRef) SwaggerDoc() map[string]string {
@@ -188,7 +188,7 @@ func (ParamRef) SwaggerDoc() map[string]string {
var map_TypeChecking = map[string]string{
"": "TypeChecking contains results of type checking the expressions in the ValidatingAdmissionPolicy",
- "expressionWarnings": "The type checking warnings for each expression.",
+ "expressionWarnings": "expressionWarnings contains the type checking warnings for each expression.",
}
func (TypeChecking) SwaggerDoc() map[string]string {
@@ -197,9 +197,9 @@ func (TypeChecking) SwaggerDoc() map[string]string {
var map_ValidatingAdmissionPolicy = map[string]string{
"": "ValidatingAdmissionPolicy describes the definition of an admission validation policy that accepts or rejects an object without changing it.",
- "metadata": "Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.",
- "spec": "Specification of the desired behavior of the ValidatingAdmissionPolicy.",
- "status": "The status of the ValidatingAdmissionPolicy, including warnings that are useful to determine if the policy behaves in the expected way. Populated by the system. Read-only.",
+ "metadata": "metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.",
+ "spec": "spec defines the desired behavior of the ValidatingAdmissionPolicy.",
+ "status": "status represents the current status of the ValidatingAdmissionPolicy, including warnings that are useful to determine if the policy behaves in the expected way. Populated by the system. Read-only.",
}
func (ValidatingAdmissionPolicy) SwaggerDoc() map[string]string {
@@ -208,8 +208,8 @@ func (ValidatingAdmissionPolicy) SwaggerDoc() map[string]string {
var map_ValidatingAdmissionPolicyBinding = map[string]string{
"": "ValidatingAdmissionPolicyBinding binds the ValidatingAdmissionPolicy with paramerized resources. ValidatingAdmissionPolicyBinding and parameter CRDs together define how cluster administrators configure policies for clusters.\n\nFor a given admission request, each binding will cause its policy to be evaluated N times, where N is 1 for policies/bindings that don't use params, otherwise N is the number of parameters selected by the binding.\n\nThe CEL expressions of a policy must have a computed CEL cost below the maximum CEL budget. Each evaluation of the policy is given an independent CEL cost budget. Adding/removing policies, bindings, or params can not affect whether a given (policy, binding, param) combination is within its own CEL budget.",
- "metadata": "Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.",
- "spec": "Specification of the desired behavior of the ValidatingAdmissionPolicyBinding.",
+ "metadata": "metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.",
+ "spec": "spec defines the desired behavior of the ValidatingAdmissionPolicyBinding.",
}
func (ValidatingAdmissionPolicyBinding) SwaggerDoc() map[string]string {
@@ -218,7 +218,7 @@ func (ValidatingAdmissionPolicyBinding) SwaggerDoc() map[string]string {
var map_ValidatingAdmissionPolicyBindingList = map[string]string{
"": "ValidatingAdmissionPolicyBindingList is a list of ValidatingAdmissionPolicyBinding.",
- "metadata": "Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds",
+ "metadata": "metadata is the standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds",
"items": "List of PolicyBinding.",
}
@@ -228,9 +228,9 @@ func (ValidatingAdmissionPolicyBindingList) SwaggerDoc() map[string]string {
var map_ValidatingAdmissionPolicyBindingSpec = map[string]string{
"": "ValidatingAdmissionPolicyBindingSpec is the specification of the ValidatingAdmissionPolicyBinding.",
- "policyName": "PolicyName references a ValidatingAdmissionPolicy name which the ValidatingAdmissionPolicyBinding binds to. If the referenced resource does not exist, this binding is considered invalid and will be ignored Required.",
+ "policyName": "policyName references a ValidatingAdmissionPolicy name which the ValidatingAdmissionPolicyBinding binds to. If the referenced resource does not exist, this binding is considered invalid and will be ignored Required.",
"paramRef": "paramRef specifies the parameter resource used to configure the admission control policy. It should point to a resource of the type specified in ParamKind of the bound ValidatingAdmissionPolicy. If the policy specifies a ParamKind and the resource referred to by ParamRef does not exist, this binding is considered mis-configured and the FailurePolicy of the ValidatingAdmissionPolicy applied. If the policy does not specify a ParamKind then this field is ignored, and the rules are evaluated without a param.",
- "matchResources": "MatchResources declares what resources match this binding and will be validated by it. Note that this is intersected with the policy's matchConstraints, so only requests that are matched by the policy can be selected by this. If this is unset, all resources matched by the policy are validated by this binding When resourceRules is unset, it does not constrain resource matching. If a resource is matched by the other fields of this object, it will be validated. Note that this is differs from ValidatingAdmissionPolicy matchConstraints, where resourceRules are required.",
+ "matchResources": "matchResources declares what resources match this binding and will be validated by it. Note that this is intersected with the policy's matchConstraints, so only requests that are matched by the policy can be selected by this. If this is unset, all resources matched by the policy are validated by this binding When resourceRules is unset, it does not constrain resource matching. If a resource is matched by the other fields of this object, it will be validated. Note that this is differs from ValidatingAdmissionPolicy matchConstraints, where resourceRules are required.",
"validationActions": "validationActions declares how Validations of the referenced ValidatingAdmissionPolicy are enforced. If a validation evaluates to false it is always enforced according to these actions.\n\nFailures defined by the ValidatingAdmissionPolicy's FailurePolicy are enforced according to these actions only if the FailurePolicy is set to Fail, otherwise the failures are ignored. This includes compilation errors, runtime errors and misconfigurations of the policy.\n\nvalidationActions is declared as a set of action values. Order does not matter. validationActions may not contain duplicates of the same action.\n\nThe supported actions values are:\n\n\"Deny\" specifies that a validation failure results in a denied request.\n\n\"Warn\" specifies that a validation failure is reported to the request client in HTTP Warning headers, with a warning code of 299. Warnings can be sent both for allowed or denied admission responses.\n\n\"Audit\" specifies that a validation failure is included in the published audit event for the request. The audit event will contain a `validation.policy.admission.k8s.io/validation_failure` audit annotation with a value containing the details of the validation failures, formatted as a JSON list of objects, each with the following fields: - message: The validation failure message string - policy: The resource name of the ValidatingAdmissionPolicy - binding: The resource name of the ValidatingAdmissionPolicyBinding - expressionIndex: The index of the failed validations in the ValidatingAdmissionPolicy - validationActions: The enforcement actions enacted for the validation failure Example audit annotation: `\"validation.policy.admission.k8s.io/validation_failure\": \"[{\"message\": \"Invalid value\", {\"policy\": \"policy.example.com\", {\"binding\": \"policybinding.example.com\", {\"expressionIndex\": \"1\", {\"validationActions\": [\"Audit\"]}]\"`\n\nClients should expect to handle additional values by ignoring any values not recognized.\n\n\"Deny\" and \"Warn\" may not be used together since this combination needlessly duplicates the validation failure both in the API response body and the HTTP warning headers.\n\nRequired.",
}
@@ -240,7 +240,7 @@ func (ValidatingAdmissionPolicyBindingSpec) SwaggerDoc() map[string]string {
var map_ValidatingAdmissionPolicyList = map[string]string{
"": "ValidatingAdmissionPolicyList is a list of ValidatingAdmissionPolicy.",
- "metadata": "Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds",
+ "metadata": "metadata is the standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds",
"items": "List of ValidatingAdmissionPolicy.",
}
@@ -250,13 +250,13 @@ func (ValidatingAdmissionPolicyList) SwaggerDoc() map[string]string {
var map_ValidatingAdmissionPolicySpec = map[string]string{
"": "ValidatingAdmissionPolicySpec is the specification of the desired behavior of the AdmissionPolicy.",
- "paramKind": "ParamKind specifies the kind of resources used to parameterize this policy. If absent, there are no parameters for this policy and the param CEL variable will not be provided to validation expressions. If ParamKind refers to a non-existent kind, this policy definition is mis-configured and the FailurePolicy is applied. If paramKind is specified but paramRef is unset in ValidatingAdmissionPolicyBinding, the params variable will be null.",
- "matchConstraints": "MatchConstraints specifies what resources this policy is designed to validate. The AdmissionPolicy cares about a request if it matches _all_ Constraints. However, in order to prevent clusters from being put into an unstable state that cannot be recovered from via the API ValidatingAdmissionPolicy cannot match ValidatingAdmissionPolicy and ValidatingAdmissionPolicyBinding. Required.",
- "validations": "Validations contain CEL expressions which is used to apply the validation. Validations and AuditAnnotations may not both be empty; a minimum of one Validations or AuditAnnotations is required.",
+ "paramKind": "paramKind specifies the kind of resources used to parameterize this policy. If absent, there are no parameters for this policy and the param CEL variable will not be provided to validation expressions. If ParamKind refers to a non-existent kind, this policy definition is mis-configured and the FailurePolicy is applied. If paramKind is specified but paramRef is unset in ValidatingAdmissionPolicyBinding, the params variable will be null.",
+ "matchConstraints": "matchConstraints specifies what resources this policy is designed to validate. The AdmissionPolicy cares about a request if it matches _all_ Constraints. However, in order to prevent clusters from being put into an unstable state that cannot be recovered from via the API ValidatingAdmissionPolicy cannot match ValidatingAdmissionPolicy and ValidatingAdmissionPolicyBinding. Required.",
+ "validations": "validations contain CEL expressions which is used to apply the validation. Validations and AuditAnnotations may not both be empty; a minimum of one Validations or AuditAnnotations is required.",
"failurePolicy": "failurePolicy defines how to handle failures for the admission policy. Failures can occur from CEL expression parse errors, type check errors, runtime errors and invalid or mis-configured policy definitions or bindings.\n\nA policy is invalid if spec.paramKind refers to a non-existent Kind. A binding is invalid if spec.paramRef.name refers to a non-existent resource.\n\nfailurePolicy does not define how validations that evaluate to false are handled.\n\nWhen failurePolicy is set to Fail, ValidatingAdmissionPolicyBinding validationActions define how failures are enforced.\n\nAllowed values are Ignore or Fail. Defaults to Fail.",
"auditAnnotations": "auditAnnotations contains CEL expressions which are used to produce audit annotations for the audit event of the API request. validations and auditAnnotations may not both be empty; a least one of validations or auditAnnotations is required.",
- "matchConditions": "MatchConditions is a list of conditions that must be met for a request to be validated. Match conditions filter requests that have already been matched by the rules, namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests. There are a maximum of 64 match conditions allowed.\n\nIf a parameter object is provided, it can be accessed via the `params` handle in the same manner as validation expressions.\n\nThe exact matching logic is (in order):\n 1. If ANY matchCondition evaluates to FALSE, the policy is skipped.\n 2. If ALL matchConditions evaluate to TRUE, the policy is evaluated.\n 3. If any matchCondition evaluates to an error (but none are FALSE):\n - If failurePolicy=Fail, reject the request\n - If failurePolicy=Ignore, the policy is skipped",
- "variables": "Variables contain definitions of variables that can be used in composition of other expressions. Each variable is defined as a named CEL expression. The variables defined here will be available under `variables` in other expressions of the policy except MatchConditions because MatchConditions are evaluated before the rest of the policy.\n\nThe expression of a variable can refer to other variables defined earlier in the list but not those after. Thus, Variables must be sorted by the order of first appearance and acyclic.",
+ "matchConditions": "matchConditions is a list of conditions that must be met for a request to be validated. Match conditions filter requests that have already been matched by the rules, namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests. There are a maximum of 64 match conditions allowed.\n\nIf a parameter object is provided, it can be accessed via the `params` handle in the same manner as validation expressions.\n\nThe exact matching logic is (in order):\n 1. If ANY matchCondition evaluates to FALSE, the policy is skipped.\n 2. If ALL matchConditions evaluate to TRUE, the policy is evaluated.\n 3. If any matchCondition evaluates to an error (but none are FALSE):\n - If failurePolicy=Fail, reject the request\n - If failurePolicy=Ignore, the policy is skipped",
+ "variables": "variables contain definitions of variables that can be used in composition of other expressions. Each variable is defined as a named CEL expression. The variables defined here will be available under `variables` in other expressions of the policy except MatchConditions because MatchConditions are evaluated before the rest of the policy.\n\nThe expression of a variable can refer to other variables defined earlier in the list but not those after. Thus, Variables must be sorted by the order of first appearance and acyclic.",
}
func (ValidatingAdmissionPolicySpec) SwaggerDoc() map[string]string {
@@ -265,9 +265,9 @@ func (ValidatingAdmissionPolicySpec) SwaggerDoc() map[string]string {
var map_ValidatingAdmissionPolicyStatus = map[string]string{
"": "ValidatingAdmissionPolicyStatus represents the status of a ValidatingAdmissionPolicy.",
- "observedGeneration": "The generation observed by the controller.",
- "typeChecking": "The results of type checking for each expression. Presence of this field indicates the completion of the type checking.",
- "conditions": "The conditions represent the latest available observations of a policy's current state.",
+ "observedGeneration": "observedGeneration is the generation observed by the controller.",
+ "typeChecking": "typeChecking contains the results of type checking for each expression. Presence of this field indicates the completion of the type checking.",
+ "conditions": "conditions represent the latest available observations of a policy's current state.",
}
func (ValidatingAdmissionPolicyStatus) SwaggerDoc() map[string]string {
@@ -276,9 +276,9 @@ func (ValidatingAdmissionPolicyStatus) SwaggerDoc() map[string]string {
var map_Validation = map[string]string{
"": "Validation specifies the CEL expression which is used to apply the validation.",
- "expression": "Expression represents the expression which will be evaluated by CEL. ref: https://github.com/google/cel-spec CEL expressions have access to the contents of the API request/response, organized into CEL variables as well as some other useful variables:\n\n- 'object' - The object from the incoming request. The value is null for DELETE requests. - 'oldObject' - The existing object. The value is null for CREATE requests. - 'request' - Attributes of the API request([ref](/pkg/apis/admission/types.go#AdmissionRequest)). - 'params' - Parameter resource referred to by the policy binding being evaluated. Only populated if the policy has a ParamKind. - 'namespaceObject' - The namespace object that the incoming object belongs to. The value is null for cluster-scoped resources. - 'variables' - Map of composited variables, from its name to its lazily evaluated value.\n For example, a variable named 'foo' can be accessed as 'variables.foo'.\n- 'authorizer' - A CEL Authorizer. May be used to perform authorization checks for the principal (user or service account) of the request.\n See https://pkg.go.dev/k8s.io/apiserver/pkg/cel/library#Authz\n- 'authorizer.requestResource' - A CEL ResourceCheck constructed from the 'authorizer' and configured with the\n request resource.\n\nThe `apiVersion`, `kind`, `metadata.name` and `metadata.generateName` are always accessible from the root of the object. No other metadata properties are accessible.\n\nOnly property names of the form `[a-zA-Z_.-/][a-zA-Z0-9_.-/]*` are accessible. Accessible property names are escaped according to the following rules when accessed in the expression: - '__' escapes to '__underscores__' - '.' escapes to '__dot__' - '-' escapes to '__dash__' - '/' escapes to '__slash__' - Property names that exactly match a CEL RESERVED keyword escape to '__{keyword}__'. The keywords are:\n\t \"true\", \"false\", \"null\", \"in\", \"as\", \"break\", \"const\", \"continue\", \"else\", \"for\", \"function\", \"if\",\n\t \"import\", \"let\", \"loop\", \"package\", \"namespace\", \"return\".\nExamples:\n - Expression accessing a property named \"namespace\": {\"Expression\": \"object.__namespace__ > 0\"}\n - Expression accessing a property named \"x-prop\": {\"Expression\": \"object.x__dash__prop > 0\"}\n - Expression accessing a property named \"redact__d\": {\"Expression\": \"object.redact__underscores__d > 0\"}\n\nEquality on arrays with list type of 'set' or 'map' ignores element order, i.e. [1, 2] == [2, 1]. Concatenation on arrays with x-kubernetes-list-type use the semantics of the list type:\n - 'set': `X + Y` performs a union where the array positions of all elements in `X` are preserved and\n non-intersecting elements in `Y` are appended, retaining their partial order.\n - 'map': `X + Y` performs a merge where the array positions of all keys in `X` are preserved but the values\n are overwritten by values in `Y` when the key sets of `X` and `Y` intersect. Elements in `Y` with\n non-intersecting keys are appended, retaining their partial order.\nRequired.",
- "message": "Message represents the message displayed when validation fails. The message is required if the Expression contains line breaks. The message must not contain line breaks. If unset, the message is \"failed rule: {Rule}\". e.g. \"must be a URL with the host matching spec.host\" If the Expression contains line breaks. Message is required. The message must not contain line breaks. If unset, the message is \"failed Expression: {Expression}\".",
- "reason": "Reason represents a machine-readable description of why this validation failed. If this is the first validation in the list to fail, this reason, as well as the corresponding HTTP response code, are used in the HTTP response to the client. The currently supported reasons are: \"Unauthorized\", \"Forbidden\", \"Invalid\", \"RequestEntityTooLarge\". If not set, StatusReasonInvalid is used in the response to the client.",
+ "expression": "expression represents the expression which will be evaluated by CEL. ref: https://github.com/google/cel-spec CEL expressions have access to the contents of the API request/response, organized into CEL variables as well as some other useful variables:\n\n- 'object' - The object from the incoming request. The value is null for DELETE requests. - 'oldObject' - The existing object. The value is null for CREATE requests. - 'request' - Attributes of the API request([ref](/pkg/apis/admission/types.go#AdmissionRequest)). - 'params' - Parameter resource referred to by the policy binding being evaluated. Only populated if the policy has a ParamKind. - 'namespaceObject' - The namespace object that the incoming object belongs to. The value is null for cluster-scoped resources. - 'variables' - Map of composited variables, from its name to its lazily evaluated value.\n For example, a variable named 'foo' can be accessed as 'variables.foo'.\n- 'authorizer' - A CEL Authorizer. May be used to perform authorization checks for the principal (user or service account) of the request.\n See https://pkg.go.dev/k8s.io/apiserver/pkg/cel/library#Authz\n- 'authorizer.requestResource' - A CEL ResourceCheck constructed from the 'authorizer' and configured with the\n request resource.\n\nThe `apiVersion`, `kind`, `metadata.name` and `metadata.generateName` are always accessible from the root of the object. No other metadata properties are accessible.\n\nOnly property names of the form `[a-zA-Z_.-/][a-zA-Z0-9_.-/]*` are accessible. Accessible property names are escaped according to the following rules when accessed in the expression: - '__' escapes to '__underscores__' - '.' escapes to '__dot__' - '-' escapes to '__dash__' - '/' escapes to '__slash__' - Property names that exactly match a CEL RESERVED keyword escape to '__{keyword}__'. The keywords are:\n\t \"true\", \"false\", \"null\", \"in\", \"as\", \"break\", \"const\", \"continue\", \"else\", \"for\", \"function\", \"if\",\n\t \"import\", \"let\", \"loop\", \"package\", \"namespace\", \"return\".\nExamples:\n - Expression accessing a property named \"namespace\": {\"Expression\": \"object.__namespace__ > 0\"}\n - Expression accessing a property named \"x-prop\": {\"Expression\": \"object.x__dash__prop > 0\"}\n - Expression accessing a property named \"redact__d\": {\"Expression\": \"object.redact__underscores__d > 0\"}\n\nEquality on arrays with list type of 'set' or 'map' ignores element order, i.e. [1, 2] == [2, 1]. Concatenation on arrays with x-kubernetes-list-type use the semantics of the list type:\n - 'set': `X + Y` performs a union where the array positions of all elements in `X` are preserved and\n non-intersecting elements in `Y` are appended, retaining their partial order.\n - 'map': `X + Y` performs a merge where the array positions of all keys in `X` are preserved but the values\n are overwritten by values in `Y` when the key sets of `X` and `Y` intersect. Elements in `Y` with\n non-intersecting keys are appended, retaining their partial order.\nRequired.",
+ "message": "message represents the message displayed when validation fails. The message is required if the Expression contains line breaks. The message must not contain line breaks. If unset, the message is \"failed rule: {Rule}\". e.g. \"must be a URL with the host matching spec.host\" If the Expression contains line breaks. Message is required. The message must not contain line breaks. If unset, the message is \"failed Expression: {Expression}\".",
+ "reason": "reason represents a machine-readable description of why this validation failed. If this is the first validation in the list to fail, this reason, as well as the corresponding HTTP response code, are used in the HTTP response to the client. The currently supported reasons are: \"Unauthorized\", \"Forbidden\", \"Invalid\", \"RequestEntityTooLarge\". If not set, StatusReasonInvalid is used in the response to the client.",
"messageExpression": "messageExpression declares a CEL expression that evaluates to the validation failure message that is returned when this rule fails. Since messageExpression is used as a failure message, it must evaluate to a string. If both message and messageExpression are present on a validation, then messageExpression will be used if validation fails. If messageExpression results in a runtime error, the runtime error is logged, and the validation failure message is produced as if the messageExpression field were unset. If messageExpression evaluates to an empty string, a string with only spaces, or a string that contains line breaks, then the validation failure message will also be produced as if the messageExpression field were unset, and the fact that messageExpression produced an empty string/string with only spaces/string with line breaks will be logged. messageExpression has access to all the same variables as the `expression` except for 'authorizer' and 'authorizer.requestResource'. Example: \"object.x must be less than max (\"+string(params.max)+\")\"",
}
@@ -288,8 +288,8 @@ func (Validation) SwaggerDoc() map[string]string {
var map_Variable = map[string]string{
"": "Variable is the definition of a variable that is used for composition.",
- "name": "Name is the name of the variable. The name must be a valid CEL identifier and unique among all variables. The variable can be accessed in other expressions through `variables` For example, if name is \"foo\", the variable will be available as `variables.foo`",
- "expression": "Expression is the expression that will be evaluated as the value of the variable. The CEL expression has access to the same identifiers as the CEL expressions in Validation.",
+ "name": "name is the name of the variable. The name must be a valid CEL identifier and unique among all variables. The variable can be accessed in other expressions through `variables` For example, if name is \"foo\", the variable will be available as `variables.foo`",
+ "expression": "expression is the expression that will be evaluated as the value of the variable. The CEL expression has access to the same identifiers as the CEL expressions in Validation.",
}
func (Variable) SwaggerDoc() map[string]string {
diff --git a/vendor/k8s.io/api/admissionregistration/v1beta1/generated.proto b/vendor/k8s.io/api/admissionregistration/v1beta1/generated.proto
index d184664e5..5fcb74f8b 100644
--- a/vendor/k8s.io/api/admissionregistration/v1beta1/generated.proto
+++ b/vendor/k8s.io/api/admissionregistration/v1beta1/generated.proto
@@ -113,12 +113,12 @@ message AuditAnnotation {
// ExpressionWarning is a warning information that targets a specific expression.
message ExpressionWarning {
- // The path to the field that refers the expression.
+ // fieldRef is the path to the field that refers to the expression.
// For example, the reference to the expression of the first item of
// validations is "spec.validations[0].expression"
optional string fieldRef = 2;
- // The content of type checking information in a human-readable form.
+ // warning contains the content of type checking information in a human-readable form.
// Each line of the warning contains the type that the expression is checked
// against, followed by the type check error from the compiler.
optional string warning = 3;
@@ -195,7 +195,7 @@ message JSONPatch {
// MatchCondition represents a condition which must be fulfilled for a request to be sent to a webhook.
message MatchCondition {
- // Name is an identifier for this match condition, used for strategic merging of MatchConditions,
+ // name is an identifier for this match condition, used for strategic merging of MatchConditions,
// as well as providing an identifier for logging purposes. A good name should be descriptive of
// the associated expression.
// Name must be a qualified name consisting of alphanumeric characters, '-', '_' or '.', and
@@ -206,7 +206,7 @@ message MatchCondition {
// Required.
optional string name = 1;
- // Expression represents the expression which will be evaluated by CEL. Must evaluate to bool.
+ // expression represents the expression which will be evaluated by CEL. Must evaluate to bool.
// CEL expressions have access to the contents of the AdmissionRequest and Authorizer, organized into CEL variables:
//
// 'object' - The object from the incoming request. The value is null for DELETE requests.
@@ -227,7 +227,7 @@ message MatchCondition {
// The exclude rules take precedence over include rules (if a resource matches both, it is excluded)
// +structType=atomic
message MatchResources {
- // NamespaceSelector decides whether to run the admission control policy on an object based
+ // namespaceSelector decides whether to run the admission control policy on an object based
// on whether the namespace for that object matches the selector. If the
// object itself is a namespace, the matching is performed on
// object.metadata.labels. If the object is another cluster scoped resource,
@@ -273,7 +273,7 @@ message MatchResources {
// +optional
optional .k8s.io.apimachinery.pkg.apis.meta.v1.LabelSelector namespaceSelector = 1;
- // ObjectSelector decides whether to run the validation based on if the
+ // objectSelector decides whether to run the validation based on if the
// object has matching labels. objectSelector is evaluated against both
// the oldObject and newObject that would be sent to the cel validation, and
// is considered to match if either object matches the selector. A null
@@ -287,13 +287,13 @@ message MatchResources {
// +optional
optional .k8s.io.apimachinery.pkg.apis.meta.v1.LabelSelector objectSelector = 2;
- // ResourceRules describes what operations on what resources/subresources the ValidatingAdmissionPolicy matches.
+ // resourceRules describes what operations on what resources/subresources the ValidatingAdmissionPolicy matches.
// The policy cares about an operation if it matches _any_ Rule.
// +listType=atomic
// +optional
repeated NamedRuleWithOperations resourceRules = 3;
- // ExcludeResourceRules describes what operations on what resources/subresources the ValidatingAdmissionPolicy should not care about.
+ // excludeResourceRules describes what operations on what resources/subresources the ValidatingAdmissionPolicy should not care about.
// The exclude rules take precedence over include rules (if a resource matches both, it is excluded)
// +listType=atomic
// +optional
@@ -319,11 +319,11 @@ message MatchResources {
// MutatingAdmissionPolicy describes the definition of an admission mutation policy that mutates the object coming into admission chain.
message MutatingAdmissionPolicy {
- // Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.
+ // metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.
// +optional
optional .k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1;
- // Specification of the desired behavior of the MutatingAdmissionPolicy.
+ // spec defines the desired behavior of the MutatingAdmissionPolicy.
optional MutatingAdmissionPolicySpec spec = 2;
}
@@ -339,17 +339,17 @@ message MutatingAdmissionPolicy {
// Adding/removing policies, bindings, or params can not affect whether a
// given (policy, binding, param) combination is within its own CEL budget.
message MutatingAdmissionPolicyBinding {
- // Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.
+ // metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.
// +optional
optional .k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1;
- // Specification of the desired behavior of the MutatingAdmissionPolicyBinding.
+ // spec defines the desired behavior of the MutatingAdmissionPolicyBinding.
optional MutatingAdmissionPolicyBindingSpec spec = 2;
}
// MutatingAdmissionPolicyBindingList is a list of MutatingAdmissionPolicyBinding.
message MutatingAdmissionPolicyBindingList {
- // Standard list metadata.
+ // metadata is the standard list metadata.
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
// +optional
optional .k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1;
@@ -387,7 +387,7 @@ message MutatingAdmissionPolicyBindingSpec {
// MutatingAdmissionPolicyList is a list of MutatingAdmissionPolicy.
message MutatingAdmissionPolicyList {
- // Standard list metadata.
+ // metadata is the standard list metadata.
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
// +optional
optional .k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1;
@@ -486,18 +486,18 @@ message MutatingAdmissionPolicySpec {
// MutatingWebhook describes an admission webhook and the resources and operations it applies to.
message MutatingWebhook {
- // The name of the admission webhook.
+ // name is the name of the admission webhook.
// Name should be fully qualified, e.g., imagepolicy.kubernetes.io, where
// "imagepolicy" is the name of the webhook, and kubernetes.io is the name
// of the organization.
// Required.
optional string name = 1;
- // ClientConfig defines how to communicate with the hook.
+ // clientConfig defines how to communicate with the hook.
// Required
optional WebhookClientConfig clientConfig = 2;
- // Rules describes what operations on what resources/subresources the webhook cares about.
+ // rules describes what operations on what resources/subresources the webhook cares about.
// The webhook cares about an operation if it matches _any_ Rule.
// However, in order to prevent ValidatingAdmissionWebhooks and MutatingAdmissionWebhooks
// from putting the cluster in a state which cannot be recovered from without completely
@@ -506,7 +506,7 @@ message MutatingWebhook {
// +listType=atomic
repeated .k8s.io.api.admissionregistration.v1.RuleWithOperations rules = 3;
- // FailurePolicy defines how unrecognized errors from the admission endpoint are handled -
+ // failurePolicy defines how unrecognized errors from the admission endpoint are handled -
// allowed values are Ignore or Fail. Defaults to Ignore.
// +optional
optional string failurePolicy = 4;
@@ -528,7 +528,7 @@ message MutatingWebhook {
// +optional
optional string matchPolicy = 9;
- // NamespaceSelector decides whether to run the webhook on an object based
+ // namespaceSelector decides whether to run the webhook on an object based
// on whether the namespace for that object matches the selector. If the
// object itself is a namespace, the matching is performed on
// object.metadata.labels. If the object is another cluster scoped resource,
@@ -574,7 +574,7 @@ message MutatingWebhook {
// +optional
optional .k8s.io.apimachinery.pkg.apis.meta.v1.LabelSelector namespaceSelector = 5;
- // ObjectSelector decides whether to run the webhook based on if the
+ // objectSelector decides whether to run the webhook based on if the
// object has matching labels. objectSelector is evaluated against both
// the oldObject and newObject that would be sent to the webhook, and
// is considered to match if either object matches the selector. A null
@@ -588,7 +588,7 @@ message MutatingWebhook {
// +optional
optional .k8s.io.apimachinery.pkg.apis.meta.v1.LabelSelector objectSelector = 11;
- // SideEffects states whether this webhook has side effects.
+ // sideEffects states whether this webhook has side effects.
// Acceptable values are: Unknown, None, Some, NoneOnDryRun
// Webhooks with side effects MUST implement a reconciliation system, since a request may be
// rejected by a future step in the admission chain and the side effects therefore need to be undone.
@@ -597,7 +597,7 @@ message MutatingWebhook {
// +optional
optional string sideEffects = 6;
- // TimeoutSeconds specifies the timeout for this webhook. After the timeout passes,
+ // timeoutSeconds specifies the timeout for this webhook. After the timeout passes,
// the webhook call will be ignored or the API call will fail based on the
// failure policy.
// The timeout value must be between 1 and 30 seconds.
@@ -605,7 +605,7 @@ message MutatingWebhook {
// +optional
optional int32 timeoutSeconds = 7;
- // AdmissionReviewVersions is an ordered list of preferred `AdmissionReview`
+ // admissionReviewVersions is an ordered list of preferred `AdmissionReview`
// versions the Webhook expects. API server will try to use first version in
// the list which it supports. If none of the versions specified in this list
// supported by API server, validation will fail for this object.
@@ -635,7 +635,7 @@ message MutatingWebhook {
// +optional
optional string reinvocationPolicy = 10;
- // MatchConditions is a list of conditions that must be met for a request to be sent to this
+ // matchConditions is a list of conditions that must be met for a request to be sent to this
// webhook. Match conditions filter requests that have already been matched by the rules,
// namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests.
// There are a maximum of 64 match conditions allowed.
@@ -658,11 +658,11 @@ message MutatingWebhook {
// MutatingWebhookConfiguration describes the configuration of and admission webhook that accept or reject and may change the object.
// Deprecated in v1.16, planned for removal in v1.19. Use admissionregistration.k8s.io/v1 MutatingWebhookConfiguration instead.
message MutatingWebhookConfiguration {
- // Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.
+ // metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.
// +optional
optional .k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1;
- // Webhooks is a list of webhooks and the affected resources and operations.
+ // webhooks is a list of webhooks and the affected resources and operations.
// +optional
// +patchMergeKey=name
// +patchStrategy=merge
@@ -673,7 +673,7 @@ message MutatingWebhookConfiguration {
// MutatingWebhookConfigurationList is a list of MutatingWebhookConfiguration.
message MutatingWebhookConfigurationList {
- // Standard list metadata.
+ // metadata is the standard list metadata.
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
// +optional
optional .k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1;
@@ -705,7 +705,7 @@ message Mutation {
// NamedRuleWithOperations is a tuple of Operations and Resources with ResourceNames.
// +structType=atomic
message NamedRuleWithOperations {
- // ResourceNames is an optional white list of names that the rule applies to. An empty set means that everything is allowed.
+ // resourceNames is an optional white list of names that the rule applies to. An empty set means that everything is allowed.
// +listType=atomic
// +optional
repeated string resourceNames = 1;
@@ -717,12 +717,12 @@ message NamedRuleWithOperations {
// ParamKind is a tuple of Group Kind and Version.
// +structType=atomic
message ParamKind {
- // APIVersion is the API group version the resources belong to.
+ // apiVersion is the API group version the resources belong to.
// In format of "group/version".
// Required.
optional string apiVersion = 1;
- // Kind is the API kind the resources belong to.
+ // kind is the API kind the resources belong to.
// Required.
optional string kind = 2;
}
@@ -771,7 +771,7 @@ message ParamRef {
// +optional
optional .k8s.io.apimachinery.pkg.apis.meta.v1.LabelSelector selector = 3;
- // `parameterNotFoundAction` controls the behavior of the binding when the resource
+ // parameterNotFoundAction controls the behavior of the binding when the resource
// exists, and name or selector is valid, but there are no parameters
// matched by the binding. If the value is set to `Allow`, then no
// matched parameters will be treated as successful validation by the binding.
@@ -786,22 +786,22 @@ message ParamRef {
// ServiceReference holds a reference to Service.legacy.k8s.io
message ServiceReference {
- // `namespace` is the namespace of the service.
+ // namespace is the namespace of the service.
// Required
optional string namespace = 1;
- // `name` is the name of the service.
+ // name is the name of the service.
// Required
optional string name = 2;
- // `path` is an optional URL path which will be sent in any request to
+ // path is an optional URL path which will be sent in any request to
// this service.
// +optional
optional string path = 3;
- // If specified, the port on the service that hosting webhook.
+ // port is the port on the service that hosts the webhook.
// Default to 443 for backward compatibility.
- // `port` should be a valid port number (1-65535, inclusive).
+ // port should be a valid port number (1-65535, inclusive).
// +optional
optional int32 port = 4;
}
@@ -809,7 +809,7 @@ message ServiceReference {
// TypeChecking contains results of type checking the expressions in the
// ValidatingAdmissionPolicy
message TypeChecking {
- // The type checking warnings for each expression.
+ // expressionWarnings contains the type checking warnings for each expression.
// +optional
// +listType=atomic
repeated ExpressionWarning expressionWarnings = 1;
@@ -821,14 +821,14 @@ message TypeChecking {
// +k8s:prerelease-lifecycle-gen:introduced=1.28
// ValidatingAdmissionPolicy describes the definition of an admission validation policy that accepts or rejects an object without changing it.
message ValidatingAdmissionPolicy {
- // Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.
+ // metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.
// +optional
optional .k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1;
- // Specification of the desired behavior of the ValidatingAdmissionPolicy.
+ // spec defines the desired behavior of the ValidatingAdmissionPolicy.
optional ValidatingAdmissionPolicySpec spec = 2;
- // The status of the ValidatingAdmissionPolicy, including warnings that are useful to determine if the policy
+ // status represents the current status of the ValidatingAdmissionPolicy, including warnings that are useful to determine if the policy
// behaves in the expected way.
// Populated by the system.
// Read-only.
@@ -848,17 +848,18 @@ message ValidatingAdmissionPolicy {
// Adding/removing policies, bindings, or params can not affect whether a
// given (policy, binding, param) combination is within its own CEL budget.
message ValidatingAdmissionPolicyBinding {
- // Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.
+ // metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.
// +optional
optional .k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1;
- // Specification of the desired behavior of the ValidatingAdmissionPolicyBinding.
+ // spec defines the desired behavior of the ValidatingAdmissionPolicyBinding.
+ // +required
optional ValidatingAdmissionPolicyBindingSpec spec = 2;
}
// ValidatingAdmissionPolicyBindingList is a list of ValidatingAdmissionPolicyBinding.
message ValidatingAdmissionPolicyBindingList {
- // Standard list metadata.
+ // metadata is the standard list metadata.
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
// +optional
optional .k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1;
@@ -869,9 +870,11 @@ message ValidatingAdmissionPolicyBindingList {
// ValidatingAdmissionPolicyBindingSpec is the specification of the ValidatingAdmissionPolicyBinding.
message ValidatingAdmissionPolicyBindingSpec {
- // PolicyName references a ValidatingAdmissionPolicy name which the ValidatingAdmissionPolicyBinding binds to.
+ // policyName references a ValidatingAdmissionPolicy name which the ValidatingAdmissionPolicyBinding binds to.
// If the referenced resource does not exist, this binding is considered invalid and will be ignored
// Required.
+ // +required
+ // +k8s:alpha(since: "1.36")=+k8s:required
optional string policyName = 1;
// paramRef specifies the parameter resource used to configure the admission control policy.
@@ -881,7 +884,7 @@ message ValidatingAdmissionPolicyBindingSpec {
// +optional
optional ParamRef paramRef = 2;
- // MatchResources declares what resources match this binding and will be validated by it.
+ // matchResources declares what resources match this binding and will be validated by it.
// Note that this is intersected with the policy's matchConstraints, so only requests that are matched by the policy can be selected by this.
// If this is unset, all resources matched by the policy are validated by this binding
// When resourceRules is unset, it does not constrain resource matching. If a resource is matched by the other fields of this object, it will be validated.
@@ -929,6 +932,8 @@ message ValidatingAdmissionPolicyBindingSpec {
//
// Required.
// +listType=set
+ // +required
+ // +k8s:alpha(since: "1.36")=+k8s:required
repeated string validationActions = 4;
}
@@ -936,7 +941,7 @@ message ValidatingAdmissionPolicyBindingSpec {
// +k8s:prerelease-lifecycle-gen:introduced=1.28
// ValidatingAdmissionPolicyList is a list of ValidatingAdmissionPolicy.
message ValidatingAdmissionPolicyList {
- // Standard list metadata.
+ // metadata is the standard list metadata.
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
// +optional
optional .k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1;
@@ -947,21 +952,21 @@ message ValidatingAdmissionPolicyList {
// ValidatingAdmissionPolicySpec is the specification of the desired behavior of the AdmissionPolicy.
message ValidatingAdmissionPolicySpec {
- // ParamKind specifies the kind of resources used to parameterize this policy.
+ // paramKind specifies the kind of resources used to parameterize this policy.
// If absent, there are no parameters for this policy and the param CEL variable will not be provided to validation expressions.
// If ParamKind refers to a non-existent kind, this policy definition is mis-configured and the FailurePolicy is applied.
// If paramKind is specified but paramRef is unset in ValidatingAdmissionPolicyBinding, the params variable will be null.
// +optional
optional ParamKind paramKind = 1;
- // MatchConstraints specifies what resources this policy is designed to validate.
+ // matchConstraints specifies what resources this policy is designed to validate.
// The AdmissionPolicy cares about a request if it matches _all_ Constraints.
// However, in order to prevent clusters from being put into an unstable state that cannot be recovered from via the API
// ValidatingAdmissionPolicy cannot match ValidatingAdmissionPolicy and ValidatingAdmissionPolicyBinding.
// Required.
optional MatchResources matchConstraints = 2;
- // Validations contain CEL expressions which is used to apply the validation.
+ // validations contain CEL expressions which is used to apply the validation.
// Validations and AuditAnnotations may not both be empty; a minimum of one Validations or AuditAnnotations is
// required.
// +listType=atomic
@@ -992,7 +997,7 @@ message ValidatingAdmissionPolicySpec {
// +optional
repeated AuditAnnotation auditAnnotations = 5;
- // MatchConditions is a list of conditions that must be met for a request to be validated.
+ // matchConditions is a list of conditions that must be met for a request to be validated.
// Match conditions filter requests that have already been matched by the rules,
// namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests.
// There are a maximum of 64 match conditions allowed.
@@ -1014,7 +1019,7 @@ message ValidatingAdmissionPolicySpec {
// +optional
repeated MatchCondition matchConditions = 6;
- // Variables contain definitions of variables that can be used in composition of other expressions.
+ // variables contain definitions of variables that can be used in composition of other expressions.
// Each variable is defined as a named CEL expression.
// The variables defined here will be available under `variables` in other expressions of the policy
// except MatchConditions because MatchConditions are evaluated before the rest of the policy.
@@ -1031,16 +1036,16 @@ message ValidatingAdmissionPolicySpec {
// ValidatingAdmissionPolicyStatus represents the status of an admission validation policy.
message ValidatingAdmissionPolicyStatus {
- // The generation observed by the controller.
+ // observedGeneration is the generation observed by the controller.
// +optional
optional int64 observedGeneration = 1;
- // The results of type checking for each expression.
+ // typeChecking contains the results of type checking for each expression.
// Presence of this field indicates the completion of the type checking.
// +optional
optional TypeChecking typeChecking = 2;
- // The conditions represent the latest available observations of a policy's current state.
+ // conditions represent the latest available observations of a policy's current state.
// +optional
// +listType=map
// +listMapKey=type
@@ -1049,18 +1054,18 @@ message ValidatingAdmissionPolicyStatus {
// ValidatingWebhook describes an admission webhook and the resources and operations it applies to.
message ValidatingWebhook {
- // The name of the admission webhook.
+ // name is the name of the admission webhook.
// Name should be fully qualified, e.g., imagepolicy.kubernetes.io, where
// "imagepolicy" is the name of the webhook, and kubernetes.io is the name
// of the organization.
// Required.
optional string name = 1;
- // ClientConfig defines how to communicate with the hook.
+ // clientConfig defines how to communicate with the hook.
// Required
optional WebhookClientConfig clientConfig = 2;
- // Rules describes what operations on what resources/subresources the webhook cares about.
+ // rules describes what operations on what resources/subresources the webhook cares about.
// The webhook cares about an operation if it matches _any_ Rule.
// However, in order to prevent ValidatingAdmissionWebhooks and MutatingAdmissionWebhooks
// from putting the cluster in a state which cannot be recovered from without completely
@@ -1069,7 +1074,7 @@ message ValidatingWebhook {
// +listType=atomic
repeated .k8s.io.api.admissionregistration.v1.RuleWithOperations rules = 3;
- // FailurePolicy defines how unrecognized errors from the admission endpoint are handled -
+ // failurePolicy defines how unrecognized errors from the admission endpoint are handled -
// allowed values are Ignore or Fail. Defaults to Ignore.
// +optional
optional string failurePolicy = 4;
@@ -1091,7 +1096,7 @@ message ValidatingWebhook {
// +optional
optional string matchPolicy = 9;
- // NamespaceSelector decides whether to run the webhook on an object based
+ // namespaceSelector decides whether to run the webhook on an object based
// on whether the namespace for that object matches the selector. If the
// object itself is a namespace, the matching is performed on
// object.metadata.labels. If the object is another cluster scoped resource,
@@ -1137,7 +1142,7 @@ message ValidatingWebhook {
// +optional
optional .k8s.io.apimachinery.pkg.apis.meta.v1.LabelSelector namespaceSelector = 5;
- // ObjectSelector decides whether to run the webhook based on if the
+ // objectSelector decides whether to run the webhook based on if the
// object has matching labels. objectSelector is evaluated against both
// the oldObject and newObject that would be sent to the webhook, and
// is considered to match if either object matches the selector. A null
@@ -1151,7 +1156,7 @@ message ValidatingWebhook {
// +optional
optional .k8s.io.apimachinery.pkg.apis.meta.v1.LabelSelector objectSelector = 10;
- // SideEffects states whether this webhook has side effects.
+ // sideEffects states whether this webhook has side effects.
// Acceptable values are: Unknown, None, Some, NoneOnDryRun
// Webhooks with side effects MUST implement a reconciliation system, since a request may be
// rejected by a future step in the admission chain and the side effects therefore need to be undone.
@@ -1161,7 +1166,7 @@ message ValidatingWebhook {
// +listType=atomic
optional string sideEffects = 6;
- // TimeoutSeconds specifies the timeout for this webhook. After the timeout passes,
+ // timeoutSeconds specifies the timeout for this webhook. After the timeout passes,
// the webhook call will be ignored or the API call will fail based on the
// failure policy.
// The timeout value must be between 1 and 30 seconds.
@@ -1169,7 +1174,7 @@ message ValidatingWebhook {
// +optional
optional int32 timeoutSeconds = 7;
- // AdmissionReviewVersions is an ordered list of preferred `AdmissionReview`
+ // admissionReviewVersions is an ordered list of preferred `AdmissionReview`
// versions the Webhook expects. API server will try to use first version in
// the list which it supports. If none of the versions specified in this list
// supported by API server, validation will fail for this object.
@@ -1181,7 +1186,7 @@ message ValidatingWebhook {
// +listType=atomic
repeated string admissionReviewVersions = 8;
- // MatchConditions is a list of conditions that must be met for a request to be sent to this
+ // matchConditions is a list of conditions that must be met for a request to be sent to this
// webhook. Match conditions filter requests that have already been matched by the rules,
// namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests.
// There are a maximum of 64 match conditions allowed.
@@ -1204,11 +1209,11 @@ message ValidatingWebhook {
// ValidatingWebhookConfiguration describes the configuration of and admission webhook that accept or reject and object without changing it.
// Deprecated in v1.16, planned for removal in v1.19. Use admissionregistration.k8s.io/v1 ValidatingWebhookConfiguration instead.
message ValidatingWebhookConfiguration {
- // Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.
+ // metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.
// +optional
optional .k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1;
- // Webhooks is a list of webhooks and the affected resources and operations.
+ // webhooks is a list of webhooks and the affected resources and operations.
// +optional
// +patchMergeKey=name
// +patchStrategy=merge
@@ -1219,7 +1224,7 @@ message ValidatingWebhookConfiguration {
// ValidatingWebhookConfigurationList is a list of ValidatingWebhookConfiguration.
message ValidatingWebhookConfigurationList {
- // Standard list metadata.
+ // metadata is the standard list metadata.
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
// +optional
optional .k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1;
@@ -1230,7 +1235,7 @@ message ValidatingWebhookConfigurationList {
// Validation specifies the CEL expression which is used to apply the validation.
message Validation {
- // Expression represents the expression which will be evaluated by CEL.
+ // expression represents the expression which will be evaluated by CEL.
// ref: https://github.com/google/cel-spec
// CEL expressions have access to the contents of the API request/response, organized into CEL variables as well as some other useful variables:
//
@@ -1273,7 +1278,7 @@ message Validation {
// Required.
optional string Expression = 1;
- // Message represents the message displayed when validation fails. The message is required if the Expression contains
+ // message represents the message displayed when validation fails. The message is required if the Expression contains
// line breaks. The message must not contain line breaks.
// If unset, the message is "failed rule: {Rule}".
// e.g. "must be a URL with the host matching spec.host"
@@ -1283,7 +1288,7 @@ message Validation {
// +optional
optional string message = 2;
- // Reason represents a machine-readable description of why this validation failed.
+ // reason represents a machine-readable description of why this validation failed.
// If this is the first validation in the list to fail, this reason, as well as the
// corresponding HTTP response code, are used in the
// HTTP response to the client.
@@ -1309,12 +1314,12 @@ message Validation {
// Variable is the definition of a variable that is used for composition. A variable is defined as a named expression.
// +structType=atomic
message Variable {
- // Name is the name of the variable. The name must be a valid CEL identifier and unique among all variables.
+ // name is the name of the variable. The name must be a valid CEL identifier and unique among all variables.
// The variable can be accessed in other expressions through `variables`
// For example, if name is "foo", the variable will be available as `variables.foo`
optional string Name = 1;
- // Expression is the expression that will be evaluated as the value of the variable.
+ // expression is the expression that will be evaluated as the value of the variable.
// The CEL expression has access to the same identifiers as the CEL expressions in Validation.
optional string Expression = 2;
}
@@ -1322,7 +1327,7 @@ message Variable {
// WebhookClientConfig contains the information to make a TLS
// connection with the webhook
message WebhookClientConfig {
- // `url` gives the location of the webhook, in standard URL form
+ // url gives the location of the webhook, in standard URL form
// (`scheme://host:port/path`). Exactly one of `url` or `service`
// must be specified.
//
@@ -1351,7 +1356,7 @@ message WebhookClientConfig {
// +optional
optional string url = 3;
- // `service` is a reference to the service for this webhook. Either
+ // service is a reference to the service for this webhook. Either
// `service` or `url` must be specified.
//
// If the webhook is running within the cluster, then you should use `service`.
@@ -1359,7 +1364,7 @@ message WebhookClientConfig {
// +optional
optional ServiceReference service = 1;
- // `caBundle` is a PEM encoded CA bundle which will be used to validate the webhook's server certificate.
+ // caBundle is a PEM encoded CA bundle which will be used to validate the webhook's server certificate.
// If unspecified, system trust roots on the apiserver are used.
// +optional
optional bytes caBundle = 2;
diff --git a/vendor/k8s.io/api/admissionregistration/v1beta1/generated.protomessage.pb.go b/vendor/k8s.io/api/admissionregistration/v1beta1/generated.protomessage.pb.go
deleted file mode 100644
index 67b85ac62..000000000
--- a/vendor/k8s.io/api/admissionregistration/v1beta1/generated.protomessage.pb.go
+++ /dev/null
@@ -1,90 +0,0 @@
-//go:build kubernetes_protomessage_one_more_release
-// +build kubernetes_protomessage_one_more_release
-
-/*
-Copyright The Kubernetes Authors.
-
-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.
-*/
-
-// Code generated by go-to-protobuf. DO NOT EDIT.
-
-package v1beta1
-
-func (*ApplyConfiguration) ProtoMessage() {}
-
-func (*AuditAnnotation) ProtoMessage() {}
-
-func (*ExpressionWarning) ProtoMessage() {}
-
-func (*JSONPatch) ProtoMessage() {}
-
-func (*MatchCondition) ProtoMessage() {}
-
-func (*MatchResources) ProtoMessage() {}
-
-func (*MutatingAdmissionPolicy) ProtoMessage() {}
-
-func (*MutatingAdmissionPolicyBinding) ProtoMessage() {}
-
-func (*MutatingAdmissionPolicyBindingList) ProtoMessage() {}
-
-func (*MutatingAdmissionPolicyBindingSpec) ProtoMessage() {}
-
-func (*MutatingAdmissionPolicyList) ProtoMessage() {}
-
-func (*MutatingAdmissionPolicySpec) ProtoMessage() {}
-
-func (*MutatingWebhook) ProtoMessage() {}
-
-func (*MutatingWebhookConfiguration) ProtoMessage() {}
-
-func (*MutatingWebhookConfigurationList) ProtoMessage() {}
-
-func (*Mutation) ProtoMessage() {}
-
-func (*NamedRuleWithOperations) ProtoMessage() {}
-
-func (*ParamKind) ProtoMessage() {}
-
-func (*ParamRef) ProtoMessage() {}
-
-func (*ServiceReference) ProtoMessage() {}
-
-func (*TypeChecking) ProtoMessage() {}
-
-func (*ValidatingAdmissionPolicy) ProtoMessage() {}
-
-func (*ValidatingAdmissionPolicyBinding) ProtoMessage() {}
-
-func (*ValidatingAdmissionPolicyBindingList) ProtoMessage() {}
-
-func (*ValidatingAdmissionPolicyBindingSpec) ProtoMessage() {}
-
-func (*ValidatingAdmissionPolicyList) ProtoMessage() {}
-
-func (*ValidatingAdmissionPolicySpec) ProtoMessage() {}
-
-func (*ValidatingAdmissionPolicyStatus) ProtoMessage() {}
-
-func (*ValidatingWebhook) ProtoMessage() {}
-
-func (*ValidatingWebhookConfiguration) ProtoMessage() {}
-
-func (*ValidatingWebhookConfigurationList) ProtoMessage() {}
-
-func (*Validation) ProtoMessage() {}
-
-func (*Variable) ProtoMessage() {}
-
-func (*WebhookClientConfig) ProtoMessage() {}
diff --git a/vendor/k8s.io/api/admissionregistration/v1beta1/types.go b/vendor/k8s.io/api/admissionregistration/v1beta1/types.go
index c7259d3d3..734a606f4 100644
--- a/vendor/k8s.io/api/admissionregistration/v1beta1/types.go
+++ b/vendor/k8s.io/api/admissionregistration/v1beta1/types.go
@@ -95,12 +95,12 @@ const (
// ValidatingAdmissionPolicy describes the definition of an admission validation policy that accepts or rejects an object without changing it.
type ValidatingAdmissionPolicy struct {
metav1.TypeMeta `json:",inline"`
- // Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.
+ // metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.
// +optional
metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
- // Specification of the desired behavior of the ValidatingAdmissionPolicy.
+ // spec defines the desired behavior of the ValidatingAdmissionPolicy.
Spec ValidatingAdmissionPolicySpec `json:"spec,omitempty" protobuf:"bytes,2,opt,name=spec"`
- // The status of the ValidatingAdmissionPolicy, including warnings that are useful to determine if the policy
+ // status represents the current status of the ValidatingAdmissionPolicy, including warnings that are useful to determine if the policy
// behaves in the expected way.
// Populated by the system.
// Read-only.
@@ -110,14 +110,14 @@ type ValidatingAdmissionPolicy struct {
// ValidatingAdmissionPolicyStatus represents the status of an admission validation policy.
type ValidatingAdmissionPolicyStatus struct {
- // The generation observed by the controller.
+ // observedGeneration is the generation observed by the controller.
// +optional
ObservedGeneration int64 `json:"observedGeneration,omitempty" protobuf:"varint,1,opt,name=observedGeneration"`
- // The results of type checking for each expression.
+ // typeChecking contains the results of type checking for each expression.
// Presence of this field indicates the completion of the type checking.
// +optional
TypeChecking *TypeChecking `json:"typeChecking,omitempty" protobuf:"bytes,2,opt,name=typeChecking"`
- // The conditions represent the latest available observations of a policy's current state.
+ // conditions represent the latest available observations of a policy's current state.
// +optional
// +listType=map
// +listMapKey=type
@@ -130,7 +130,7 @@ type ValidatingAdmissionPolicyConditionType string
// TypeChecking contains results of type checking the expressions in the
// ValidatingAdmissionPolicy
type TypeChecking struct {
- // The type checking warnings for each expression.
+ // expressionWarnings contains the type checking warnings for each expression.
// +optional
// +listType=atomic
ExpressionWarnings []ExpressionWarning `json:"expressionWarnings,omitempty" protobuf:"bytes,1,rep,name=expressionWarnings"`
@@ -138,11 +138,11 @@ type TypeChecking struct {
// ExpressionWarning is a warning information that targets a specific expression.
type ExpressionWarning struct {
- // The path to the field that refers the expression.
+ // fieldRef is the path to the field that refers to the expression.
// For example, the reference to the expression of the first item of
// validations is "spec.validations[0].expression"
FieldRef string `json:"fieldRef" protobuf:"bytes,2,opt,name=fieldRef"`
- // The content of type checking information in a human-readable form.
+ // warning contains the content of type checking information in a human-readable form.
// Each line of the warning contains the type that the expression is checked
// against, followed by the type check error from the compiler.
Warning string `json:"warning" protobuf:"bytes,3,opt,name=warning"`
@@ -153,7 +153,7 @@ type ExpressionWarning struct {
// ValidatingAdmissionPolicyList is a list of ValidatingAdmissionPolicy.
type ValidatingAdmissionPolicyList struct {
metav1.TypeMeta `json:",inline"`
- // Standard list metadata.
+ // metadata is the standard list metadata.
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
// +optional
metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
@@ -163,21 +163,21 @@ type ValidatingAdmissionPolicyList struct {
// ValidatingAdmissionPolicySpec is the specification of the desired behavior of the AdmissionPolicy.
type ValidatingAdmissionPolicySpec struct {
- // ParamKind specifies the kind of resources used to parameterize this policy.
+ // paramKind specifies the kind of resources used to parameterize this policy.
// If absent, there are no parameters for this policy and the param CEL variable will not be provided to validation expressions.
// If ParamKind refers to a non-existent kind, this policy definition is mis-configured and the FailurePolicy is applied.
// If paramKind is specified but paramRef is unset in ValidatingAdmissionPolicyBinding, the params variable will be null.
// +optional
ParamKind *ParamKind `json:"paramKind,omitempty" protobuf:"bytes,1,rep,name=paramKind"`
- // MatchConstraints specifies what resources this policy is designed to validate.
+ // matchConstraints specifies what resources this policy is designed to validate.
// The AdmissionPolicy cares about a request if it matches _all_ Constraints.
// However, in order to prevent clusters from being put into an unstable state that cannot be recovered from via the API
// ValidatingAdmissionPolicy cannot match ValidatingAdmissionPolicy and ValidatingAdmissionPolicyBinding.
// Required.
MatchConstraints *MatchResources `json:"matchConstraints,omitempty" protobuf:"bytes,2,rep,name=matchConstraints"`
- // Validations contain CEL expressions which is used to apply the validation.
+ // validations contain CEL expressions which is used to apply the validation.
// Validations and AuditAnnotations may not both be empty; a minimum of one Validations or AuditAnnotations is
// required.
// +listType=atomic
@@ -208,7 +208,7 @@ type ValidatingAdmissionPolicySpec struct {
// +optional
AuditAnnotations []AuditAnnotation `json:"auditAnnotations,omitempty" protobuf:"bytes,5,rep,name=auditAnnotations"`
- // MatchConditions is a list of conditions that must be met for a request to be validated.
+ // matchConditions is a list of conditions that must be met for a request to be validated.
// Match conditions filter requests that have already been matched by the rules,
// namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests.
// There are a maximum of 64 match conditions allowed.
@@ -230,7 +230,7 @@ type ValidatingAdmissionPolicySpec struct {
// +optional
MatchConditions []MatchCondition `json:"matchConditions,omitempty" patchStrategy:"merge" patchMergeKey:"name" protobuf:"bytes,6,rep,name=matchConditions"`
- // Variables contain definitions of variables that can be used in composition of other expressions.
+ // variables contain definitions of variables that can be used in composition of other expressions.
// Each variable is defined as a named CEL expression.
// The variables defined here will be available under `variables` in other expressions of the policy
// except MatchConditions because MatchConditions are evaluated before the rest of the policy.
@@ -248,19 +248,19 @@ type ValidatingAdmissionPolicySpec struct {
// ParamKind is a tuple of Group Kind and Version.
// +structType=atomic
type ParamKind struct {
- // APIVersion is the API group version the resources belong to.
+ // apiVersion is the API group version the resources belong to.
// In format of "group/version".
// Required.
APIVersion string `json:"apiVersion,omitempty" protobuf:"bytes,1,rep,name=apiVersion"`
- // Kind is the API kind the resources belong to.
+ // kind is the API kind the resources belong to.
// Required.
Kind string `json:"kind,omitempty" protobuf:"bytes,2,rep,name=kind"`
}
// Validation specifies the CEL expression which is used to apply the validation.
type Validation struct {
- // Expression represents the expression which will be evaluated by CEL.
+ // expression represents the expression which will be evaluated by CEL.
// ref: https://github.com/google/cel-spec
// CEL expressions have access to the contents of the API request/response, organized into CEL variables as well as some other useful variables:
//
@@ -302,7 +302,7 @@ type Validation struct {
// non-intersecting keys are appended, retaining their partial order.
// Required.
Expression string `json:"expression" protobuf:"bytes,1,opt,name=Expression"`
- // Message represents the message displayed when validation fails. The message is required if the Expression contains
+ // message represents the message displayed when validation fails. The message is required if the Expression contains
// line breaks. The message must not contain line breaks.
// If unset, the message is "failed rule: {Rule}".
// e.g. "must be a URL with the host matching spec.host"
@@ -311,7 +311,7 @@ type Validation struct {
// If unset, the message is "failed Expression: {Expression}".
// +optional
Message string `json:"message,omitempty" protobuf:"bytes,2,opt,name=message"`
- // Reason represents a machine-readable description of why this validation failed.
+ // reason represents a machine-readable description of why this validation failed.
// If this is the first validation in the list to fail, this reason, as well as the
// corresponding HTTP response code, are used in the
// HTTP response to the client.
@@ -336,12 +336,12 @@ type Validation struct {
// Variable is the definition of a variable that is used for composition. A variable is defined as a named expression.
// +structType=atomic
type Variable struct {
- // Name is the name of the variable. The name must be a valid CEL identifier and unique among all variables.
+ // name is the name of the variable. The name must be a valid CEL identifier and unique among all variables.
// The variable can be accessed in other expressions through `variables`
// For example, if name is "foo", the variable will be available as `variables.foo`
Name string `json:"name" protobuf:"bytes,1,opt,name=Name"`
- // Expression is the expression that will be evaluated as the value of the variable.
+ // expression is the expression that will be evaluated as the value of the variable.
// The CEL expression has access to the same identifiers as the CEL expressions in Validation.
Expression string `json:"expression" protobuf:"bytes,2,opt,name=Expression"`
}
@@ -401,10 +401,11 @@ type AuditAnnotation struct {
// given (policy, binding, param) combination is within its own CEL budget.
type ValidatingAdmissionPolicyBinding struct {
metav1.TypeMeta `json:",inline"`
- // Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.
+ // metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.
// +optional
metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
- // Specification of the desired behavior of the ValidatingAdmissionPolicyBinding.
+ // spec defines the desired behavior of the ValidatingAdmissionPolicyBinding.
+ // +required
Spec ValidatingAdmissionPolicyBindingSpec `json:"spec,omitempty" protobuf:"bytes,2,opt,name=spec"`
}
@@ -414,7 +415,7 @@ type ValidatingAdmissionPolicyBinding struct {
// ValidatingAdmissionPolicyBindingList is a list of ValidatingAdmissionPolicyBinding.
type ValidatingAdmissionPolicyBindingList struct {
metav1.TypeMeta `json:",inline"`
- // Standard list metadata.
+ // metadata is the standard list metadata.
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
// +optional
metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
@@ -424,9 +425,11 @@ type ValidatingAdmissionPolicyBindingList struct {
// ValidatingAdmissionPolicyBindingSpec is the specification of the ValidatingAdmissionPolicyBinding.
type ValidatingAdmissionPolicyBindingSpec struct {
- // PolicyName references a ValidatingAdmissionPolicy name which the ValidatingAdmissionPolicyBinding binds to.
+ // policyName references a ValidatingAdmissionPolicy name which the ValidatingAdmissionPolicyBinding binds to.
// If the referenced resource does not exist, this binding is considered invalid and will be ignored
// Required.
+ // +required
+ // +k8s:alpha(since: "1.36")=+k8s:required
PolicyName string `json:"policyName,omitempty" protobuf:"bytes,1,rep,name=policyName"`
// paramRef specifies the parameter resource used to configure the admission control policy.
@@ -436,7 +439,7 @@ type ValidatingAdmissionPolicyBindingSpec struct {
// +optional
ParamRef *ParamRef `json:"paramRef,omitempty" protobuf:"bytes,2,rep,name=paramRef"`
- // MatchResources declares what resources match this binding and will be validated by it.
+ // matchResources declares what resources match this binding and will be validated by it.
// Note that this is intersected with the policy's matchConstraints, so only requests that are matched by the policy can be selected by this.
// If this is unset, all resources matched by the policy are validated by this binding
// When resourceRules is unset, it does not constrain resource matching. If a resource is matched by the other fields of this object, it will be validated.
@@ -484,6 +487,8 @@ type ValidatingAdmissionPolicyBindingSpec struct {
//
// Required.
// +listType=set
+ // +required
+ // +k8s:alpha(since: "1.36")=+k8s:required
ValidationActions []ValidationAction `json:"validationActions,omitempty" protobuf:"bytes,4,rep,name=validationActions"`
}
@@ -532,7 +537,7 @@ type ParamRef struct {
// +optional
Selector *metav1.LabelSelector `json:"selector,omitempty" protobuf:"bytes,3,rep,name=selector"`
- // `parameterNotFoundAction` controls the behavior of the binding when the resource
+ // parameterNotFoundAction controls the behavior of the binding when the resource
// exists, and name or selector is valid, but there are no parameters
// matched by the binding. If the value is set to `Allow`, then no
// matched parameters will be treated as successful validation by the binding.
@@ -550,7 +555,7 @@ type ParamRef struct {
// The exclude rules take precedence over include rules (if a resource matches both, it is excluded)
// +structType=atomic
type MatchResources struct {
- // NamespaceSelector decides whether to run the admission control policy on an object based
+ // namespaceSelector decides whether to run the admission control policy on an object based
// on whether the namespace for that object matches the selector. If the
// object itself is a namespace, the matching is performed on
// object.metadata.labels. If the object is another cluster scoped resource,
@@ -595,7 +600,7 @@ type MatchResources struct {
// Default to the empty LabelSelector, which matches everything.
// +optional
NamespaceSelector *metav1.LabelSelector `json:"namespaceSelector,omitempty" protobuf:"bytes,1,opt,name=namespaceSelector"`
- // ObjectSelector decides whether to run the validation based on if the
+ // objectSelector decides whether to run the validation based on if the
// object has matching labels. objectSelector is evaluated against both
// the oldObject and newObject that would be sent to the cel validation, and
// is considered to match if either object matches the selector. A null
@@ -608,12 +613,12 @@ type MatchResources struct {
// Default to the empty LabelSelector, which matches everything.
// +optional
ObjectSelector *metav1.LabelSelector `json:"objectSelector,omitempty" protobuf:"bytes,2,opt,name=objectSelector"`
- // ResourceRules describes what operations on what resources/subresources the ValidatingAdmissionPolicy matches.
+ // resourceRules describes what operations on what resources/subresources the ValidatingAdmissionPolicy matches.
// The policy cares about an operation if it matches _any_ Rule.
// +listType=atomic
// +optional
ResourceRules []NamedRuleWithOperations `json:"resourceRules,omitempty" protobuf:"bytes,3,rep,name=resourceRules"`
- // ExcludeResourceRules describes what operations on what resources/subresources the ValidatingAdmissionPolicy should not care about.
+ // excludeResourceRules describes what operations on what resources/subresources the ValidatingAdmissionPolicy should not care about.
// The exclude rules take precedence over include rules (if a resource matches both, it is excluded)
// +listType=atomic
// +optional
@@ -657,7 +662,7 @@ const (
// NamedRuleWithOperations is a tuple of Operations and Resources with ResourceNames.
// +structType=atomic
type NamedRuleWithOperations struct {
- // ResourceNames is an optional white list of names that the rule applies to. An empty set means that everything is allowed.
+ // resourceNames is an optional white list of names that the rule applies to. An empty set means that everything is allowed.
// +listType=atomic
// +optional
ResourceNames []string `json:"resourceNames,omitempty" protobuf:"bytes,1,rep,name=resourceNames"`
@@ -677,10 +682,10 @@ type NamedRuleWithOperations struct {
// Deprecated in v1.16, planned for removal in v1.19. Use admissionregistration.k8s.io/v1 ValidatingWebhookConfiguration instead.
type ValidatingWebhookConfiguration struct {
metav1.TypeMeta `json:",inline"`
- // Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.
+ // metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.
// +optional
metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
- // Webhooks is a list of webhooks and the affected resources and operations.
+ // webhooks is a list of webhooks and the affected resources and operations.
// +optional
// +patchMergeKey=name
// +patchStrategy=merge
@@ -698,7 +703,7 @@ type ValidatingWebhookConfiguration struct {
// ValidatingWebhookConfigurationList is a list of ValidatingWebhookConfiguration.
type ValidatingWebhookConfigurationList struct {
metav1.TypeMeta `json:",inline"`
- // Standard list metadata.
+ // metadata is the standard list metadata.
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
// +optional
metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
@@ -718,10 +723,10 @@ type ValidatingWebhookConfigurationList struct {
// Deprecated in v1.16, planned for removal in v1.19. Use admissionregistration.k8s.io/v1 MutatingWebhookConfiguration instead.
type MutatingWebhookConfiguration struct {
metav1.TypeMeta `json:",inline"`
- // Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.
+ // metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.
// +optional
metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
- // Webhooks is a list of webhooks and the affected resources and operations.
+ // webhooks is a list of webhooks and the affected resources and operations.
// +optional
// +patchMergeKey=name
// +patchStrategy=merge
@@ -739,7 +744,7 @@ type MutatingWebhookConfiguration struct {
// MutatingWebhookConfigurationList is a list of MutatingWebhookConfiguration.
type MutatingWebhookConfigurationList struct {
metav1.TypeMeta `json:",inline"`
- // Standard list metadata.
+ // metadata is the standard list metadata.
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
// +optional
metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
@@ -749,18 +754,18 @@ type MutatingWebhookConfigurationList struct {
// ValidatingWebhook describes an admission webhook and the resources and operations it applies to.
type ValidatingWebhook struct {
- // The name of the admission webhook.
+ // name is the name of the admission webhook.
// Name should be fully qualified, e.g., imagepolicy.kubernetes.io, where
// "imagepolicy" is the name of the webhook, and kubernetes.io is the name
// of the organization.
// Required.
Name string `json:"name" protobuf:"bytes,1,opt,name=name"`
- // ClientConfig defines how to communicate with the hook.
+ // clientConfig defines how to communicate with the hook.
// Required
ClientConfig WebhookClientConfig `json:"clientConfig" protobuf:"bytes,2,opt,name=clientConfig"`
- // Rules describes what operations on what resources/subresources the webhook cares about.
+ // rules describes what operations on what resources/subresources the webhook cares about.
// The webhook cares about an operation if it matches _any_ Rule.
// However, in order to prevent ValidatingAdmissionWebhooks and MutatingAdmissionWebhooks
// from putting the cluster in a state which cannot be recovered from without completely
@@ -769,7 +774,7 @@ type ValidatingWebhook struct {
// +listType=atomic
Rules []RuleWithOperations `json:"rules,omitempty" protobuf:"bytes,3,rep,name=rules"`
- // FailurePolicy defines how unrecognized errors from the admission endpoint are handled -
+ // failurePolicy defines how unrecognized errors from the admission endpoint are handled -
// allowed values are Ignore or Fail. Defaults to Ignore.
// +optional
FailurePolicy *FailurePolicyType `json:"failurePolicy,omitempty" protobuf:"bytes,4,opt,name=failurePolicy,casttype=FailurePolicyType"`
@@ -791,7 +796,7 @@ type ValidatingWebhook struct {
// +optional
MatchPolicy *MatchPolicyType `json:"matchPolicy,omitempty" protobuf:"bytes,9,opt,name=matchPolicy,casttype=MatchPolicyType"`
- // NamespaceSelector decides whether to run the webhook on an object based
+ // namespaceSelector decides whether to run the webhook on an object based
// on whether the namespace for that object matches the selector. If the
// object itself is a namespace, the matching is performed on
// object.metadata.labels. If the object is another cluster scoped resource,
@@ -837,7 +842,7 @@ type ValidatingWebhook struct {
// +optional
NamespaceSelector *metav1.LabelSelector `json:"namespaceSelector,omitempty" protobuf:"bytes,5,opt,name=namespaceSelector"`
- // ObjectSelector decides whether to run the webhook based on if the
+ // objectSelector decides whether to run the webhook based on if the
// object has matching labels. objectSelector is evaluated against both
// the oldObject and newObject that would be sent to the webhook, and
// is considered to match if either object matches the selector. A null
@@ -851,7 +856,7 @@ type ValidatingWebhook struct {
// +optional
ObjectSelector *metav1.LabelSelector `json:"objectSelector,omitempty" protobuf:"bytes,10,opt,name=objectSelector"`
- // SideEffects states whether this webhook has side effects.
+ // sideEffects states whether this webhook has side effects.
// Acceptable values are: Unknown, None, Some, NoneOnDryRun
// Webhooks with side effects MUST implement a reconciliation system, since a request may be
// rejected by a future step in the admission chain and the side effects therefore need to be undone.
@@ -861,7 +866,7 @@ type ValidatingWebhook struct {
// +listType=atomic
SideEffects *SideEffectClass `json:"sideEffects,omitempty" protobuf:"bytes,6,opt,name=sideEffects,casttype=SideEffectClass"`
- // TimeoutSeconds specifies the timeout for this webhook. After the timeout passes,
+ // timeoutSeconds specifies the timeout for this webhook. After the timeout passes,
// the webhook call will be ignored or the API call will fail based on the
// failure policy.
// The timeout value must be between 1 and 30 seconds.
@@ -869,7 +874,7 @@ type ValidatingWebhook struct {
// +optional
TimeoutSeconds *int32 `json:"timeoutSeconds,omitempty" protobuf:"varint,7,opt,name=timeoutSeconds"`
- // AdmissionReviewVersions is an ordered list of preferred `AdmissionReview`
+ // admissionReviewVersions is an ordered list of preferred `AdmissionReview`
// versions the Webhook expects. API server will try to use first version in
// the list which it supports. If none of the versions specified in this list
// supported by API server, validation will fail for this object.
@@ -881,7 +886,7 @@ type ValidatingWebhook struct {
// +listType=atomic
AdmissionReviewVersions []string `json:"admissionReviewVersions,omitempty" protobuf:"bytes,8,rep,name=admissionReviewVersions"`
- // MatchConditions is a list of conditions that must be met for a request to be sent to this
+ // matchConditions is a list of conditions that must be met for a request to be sent to this
// webhook. Match conditions filter requests that have already been matched by the rules,
// namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests.
// There are a maximum of 64 match conditions allowed.
@@ -903,18 +908,18 @@ type ValidatingWebhook struct {
// MutatingWebhook describes an admission webhook and the resources and operations it applies to.
type MutatingWebhook struct {
- // The name of the admission webhook.
+ // name is the name of the admission webhook.
// Name should be fully qualified, e.g., imagepolicy.kubernetes.io, where
// "imagepolicy" is the name of the webhook, and kubernetes.io is the name
// of the organization.
// Required.
Name string `json:"name" protobuf:"bytes,1,opt,name=name"`
- // ClientConfig defines how to communicate with the hook.
+ // clientConfig defines how to communicate with the hook.
// Required
ClientConfig WebhookClientConfig `json:"clientConfig" protobuf:"bytes,2,opt,name=clientConfig"`
- // Rules describes what operations on what resources/subresources the webhook cares about.
+ // rules describes what operations on what resources/subresources the webhook cares about.
// The webhook cares about an operation if it matches _any_ Rule.
// However, in order to prevent ValidatingAdmissionWebhooks and MutatingAdmissionWebhooks
// from putting the cluster in a state which cannot be recovered from without completely
@@ -923,7 +928,7 @@ type MutatingWebhook struct {
// +listType=atomic
Rules []RuleWithOperations `json:"rules,omitempty" protobuf:"bytes,3,rep,name=rules"`
- // FailurePolicy defines how unrecognized errors from the admission endpoint are handled -
+ // failurePolicy defines how unrecognized errors from the admission endpoint are handled -
// allowed values are Ignore or Fail. Defaults to Ignore.
// +optional
FailurePolicy *FailurePolicyType `json:"failurePolicy,omitempty" protobuf:"bytes,4,opt,name=failurePolicy,casttype=FailurePolicyType"`
@@ -945,7 +950,7 @@ type MutatingWebhook struct {
// +optional
MatchPolicy *MatchPolicyType `json:"matchPolicy,omitempty" protobuf:"bytes,9,opt,name=matchPolicy,casttype=MatchPolicyType"`
- // NamespaceSelector decides whether to run the webhook on an object based
+ // namespaceSelector decides whether to run the webhook on an object based
// on whether the namespace for that object matches the selector. If the
// object itself is a namespace, the matching is performed on
// object.metadata.labels. If the object is another cluster scoped resource,
@@ -991,7 +996,7 @@ type MutatingWebhook struct {
// +optional
NamespaceSelector *metav1.LabelSelector `json:"namespaceSelector,omitempty" protobuf:"bytes,5,opt,name=namespaceSelector"`
- // ObjectSelector decides whether to run the webhook based on if the
+ // objectSelector decides whether to run the webhook based on if the
// object has matching labels. objectSelector is evaluated against both
// the oldObject and newObject that would be sent to the webhook, and
// is considered to match if either object matches the selector. A null
@@ -1005,7 +1010,7 @@ type MutatingWebhook struct {
// +optional
ObjectSelector *metav1.LabelSelector `json:"objectSelector,omitempty" protobuf:"bytes,11,opt,name=objectSelector"`
- // SideEffects states whether this webhook has side effects.
+ // sideEffects states whether this webhook has side effects.
// Acceptable values are: Unknown, None, Some, NoneOnDryRun
// Webhooks with side effects MUST implement a reconciliation system, since a request may be
// rejected by a future step in the admission chain and the side effects therefore need to be undone.
@@ -1014,7 +1019,7 @@ type MutatingWebhook struct {
// +optional
SideEffects *SideEffectClass `json:"sideEffects,omitempty" protobuf:"bytes,6,opt,name=sideEffects,casttype=SideEffectClass"`
- // TimeoutSeconds specifies the timeout for this webhook. After the timeout passes,
+ // timeoutSeconds specifies the timeout for this webhook. After the timeout passes,
// the webhook call will be ignored or the API call will fail based on the
// failure policy.
// The timeout value must be between 1 and 30 seconds.
@@ -1022,7 +1027,7 @@ type MutatingWebhook struct {
// +optional
TimeoutSeconds *int32 `json:"timeoutSeconds,omitempty" protobuf:"varint,7,opt,name=timeoutSeconds"`
- // AdmissionReviewVersions is an ordered list of preferred `AdmissionReview`
+ // admissionReviewVersions is an ordered list of preferred `AdmissionReview`
// versions the Webhook expects. API server will try to use first version in
// the list which it supports. If none of the versions specified in this list
// supported by API server, validation will fail for this object.
@@ -1052,7 +1057,7 @@ type MutatingWebhook struct {
// +optional
ReinvocationPolicy *ReinvocationPolicyType `json:"reinvocationPolicy,omitempty" protobuf:"bytes,10,opt,name=reinvocationPolicy,casttype=ReinvocationPolicyType"`
- // MatchConditions is a list of conditions that must be met for a request to be sent to this
+ // matchConditions is a list of conditions that must be met for a request to be sent to this
// webhook. Match conditions filter requests that have already been matched by the rules,
// namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests.
// There are a maximum of 64 match conditions allowed.
@@ -1107,7 +1112,7 @@ const (
// WebhookClientConfig contains the information to make a TLS
// connection with the webhook
type WebhookClientConfig struct {
- // `url` gives the location of the webhook, in standard URL form
+ // url gives the location of the webhook, in standard URL form
// (`scheme://host:port/path`). Exactly one of `url` or `service`
// must be specified.
//
@@ -1136,7 +1141,7 @@ type WebhookClientConfig struct {
// +optional
URL *string `json:"url,omitempty" protobuf:"bytes,3,opt,name=url"`
- // `service` is a reference to the service for this webhook. Either
+ // service is a reference to the service for this webhook. Either
// `service` or `url` must be specified.
//
// If the webhook is running within the cluster, then you should use `service`.
@@ -1144,7 +1149,7 @@ type WebhookClientConfig struct {
// +optional
Service *ServiceReference `json:"service,omitempty" protobuf:"bytes,1,opt,name=service"`
- // `caBundle` is a PEM encoded CA bundle which will be used to validate the webhook's server certificate.
+ // caBundle is a PEM encoded CA bundle which will be used to validate the webhook's server certificate.
// If unspecified, system trust roots on the apiserver are used.
// +optional
CABundle []byte `json:"caBundle,omitempty" protobuf:"bytes,2,opt,name=caBundle"`
@@ -1152,28 +1157,28 @@ type WebhookClientConfig struct {
// ServiceReference holds a reference to Service.legacy.k8s.io
type ServiceReference struct {
- // `namespace` is the namespace of the service.
+ // namespace is the namespace of the service.
// Required
Namespace string `json:"namespace" protobuf:"bytes,1,opt,name=namespace"`
- // `name` is the name of the service.
+ // name is the name of the service.
// Required
Name string `json:"name" protobuf:"bytes,2,opt,name=name"`
- // `path` is an optional URL path which will be sent in any request to
+ // path is an optional URL path which will be sent in any request to
// this service.
// +optional
Path *string `json:"path,omitempty" protobuf:"bytes,3,opt,name=path"`
- // If specified, the port on the service that hosting webhook.
+ // port is the port on the service that hosts the webhook.
// Default to 443 for backward compatibility.
- // `port` should be a valid port number (1-65535, inclusive).
+ // port should be a valid port number (1-65535, inclusive).
// +optional
Port *int32 `json:"port,omitempty" protobuf:"varint,4,opt,name=port"`
}
// MatchCondition represents a condition which must be fulfilled for a request to be sent to a webhook.
type MatchCondition struct {
- // Name is an identifier for this match condition, used for strategic merging of MatchConditions,
+ // name is an identifier for this match condition, used for strategic merging of MatchConditions,
// as well as providing an identifier for logging purposes. A good name should be descriptive of
// the associated expression.
// Name must be a qualified name consisting of alphanumeric characters, '-', '_' or '.', and
@@ -1184,7 +1189,7 @@ type MatchCondition struct {
// Required.
Name string `json:"name" protobuf:"bytes,1,opt,name=name"`
- // Expression represents the expression which will be evaluated by CEL. Must evaluate to bool.
+ // expression represents the expression which will be evaluated by CEL. Must evaluate to bool.
// CEL expressions have access to the contents of the AdmissionRequest and Authorizer, organized into CEL variables:
//
// 'object' - The object from the incoming request. The value is null for DELETE requests.
@@ -1204,24 +1209,26 @@ type MatchCondition struct {
// +genclient:nonNamespaced
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// +k8s:prerelease-lifecycle-gen:introduced=1.34
+// +k8s:prerelease-lifecycle-gen:replacement=admissionregistration.k8s.io,v1,MutatingAdmissionPolicy
// MutatingAdmissionPolicy describes the definition of an admission mutation policy that mutates the object coming into admission chain.
type MutatingAdmissionPolicy struct {
metav1.TypeMeta `json:",inline"`
- // Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.
+ // metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.
// +optional
metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
- // Specification of the desired behavior of the MutatingAdmissionPolicy.
+ // spec defines the desired behavior of the MutatingAdmissionPolicy.
Spec MutatingAdmissionPolicySpec `json:"spec,omitempty" protobuf:"bytes,2,opt,name=spec"`
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// +k8s:prerelease-lifecycle-gen:introduced=1.34
+// +k8s:prerelease-lifecycle-gen:replacement=admissionregistration.k8s.io,v1,MutatingAdmissionPolicyList
// MutatingAdmissionPolicyList is a list of MutatingAdmissionPolicy.
type MutatingAdmissionPolicyList struct {
metav1.TypeMeta `json:",inline"`
- // Standard list metadata.
+ // metadata is the standard list metadata.
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
// +optional
metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
@@ -1467,6 +1474,7 @@ type JSONPatch struct {
// +genclient:nonNamespaced
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// +k8s:prerelease-lifecycle-gen:introduced=1.34
+// +k8s:prerelease-lifecycle-gen:replacement=admissionregistration.k8s.io,v1,MutatingAdmissionPolicyBinding
// MutatingAdmissionPolicyBinding binds the MutatingAdmissionPolicy with parametrized resources.
// MutatingAdmissionPolicyBinding and the optional parameter resource together define how cluster administrators
@@ -1481,20 +1489,21 @@ type JSONPatch struct {
// given (policy, binding, param) combination is within its own CEL budget.
type MutatingAdmissionPolicyBinding struct {
metav1.TypeMeta `json:",inline"`
- // Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.
+ // metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.
// +optional
metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
- // Specification of the desired behavior of the MutatingAdmissionPolicyBinding.
+ // spec defines the desired behavior of the MutatingAdmissionPolicyBinding.
Spec MutatingAdmissionPolicyBindingSpec `json:"spec,omitempty" protobuf:"bytes,2,opt,name=spec"`
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// +k8s:prerelease-lifecycle-gen:introduced=1.34
+// +k8s:prerelease-lifecycle-gen:replacement=admissionregistration.k8s.io,v1,MutatingAdmissionPolicyBindingList
// MutatingAdmissionPolicyBindingList is a list of MutatingAdmissionPolicyBinding.
type MutatingAdmissionPolicyBindingList struct {
metav1.TypeMeta `json:",inline"`
- // Standard list metadata.
+ // metadata is the standard list metadata.
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
// +optional
metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
diff --git a/vendor/k8s.io/api/admissionregistration/v1beta1/types_swagger_doc_generated.go b/vendor/k8s.io/api/admissionregistration/v1beta1/types_swagger_doc_generated.go
index 1a97c9472..0fcf37aa1 100644
--- a/vendor/k8s.io/api/admissionregistration/v1beta1/types_swagger_doc_generated.go
+++ b/vendor/k8s.io/api/admissionregistration/v1beta1/types_swagger_doc_generated.go
@@ -48,8 +48,8 @@ func (AuditAnnotation) SwaggerDoc() map[string]string {
var map_ExpressionWarning = map[string]string{
"": "ExpressionWarning is a warning information that targets a specific expression.",
- "fieldRef": "The path to the field that refers the expression. For example, the reference to the expression of the first item of validations is \"spec.validations[0].expression\"",
- "warning": "The content of type checking information in a human-readable form. Each line of the warning contains the type that the expression is checked against, followed by the type check error from the compiler.",
+ "fieldRef": "fieldRef is the path to the field that refers to the expression. For example, the reference to the expression of the first item of validations is \"spec.validations[0].expression\"",
+ "warning": "warning contains the content of type checking information in a human-readable form. Each line of the warning contains the type that the expression is checked against, followed by the type check error from the compiler.",
}
func (ExpressionWarning) SwaggerDoc() map[string]string {
@@ -67,8 +67,8 @@ func (JSONPatch) SwaggerDoc() map[string]string {
var map_MatchCondition = map[string]string{
"": "MatchCondition represents a condition which must be fulfilled for a request to be sent to a webhook.",
- "name": "Name is an identifier for this match condition, used for strategic merging of MatchConditions, as well as providing an identifier for logging purposes. A good name should be descriptive of the associated expression. Name must be a qualified name consisting of alphanumeric characters, '-', '_' or '.', and must start and end with an alphanumeric character (e.g. 'MyName', or 'my.name', or '123-abc', regex used for validation is '([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]') with an optional DNS subdomain prefix and '/' (e.g. 'example.com/MyName')\n\nRequired.",
- "expression": "Expression represents the expression which will be evaluated by CEL. Must evaluate to bool. CEL expressions have access to the contents of the AdmissionRequest and Authorizer, organized into CEL variables:\n\n'object' - The object from the incoming request. The value is null for DELETE requests. 'oldObject' - The existing object. The value is null for CREATE requests. 'request' - Attributes of the admission request(/pkg/apis/admission/types.go#AdmissionRequest). 'authorizer' - A CEL Authorizer. May be used to perform authorization checks for the principal (user or service account) of the request.\n See https://pkg.go.dev/k8s.io/apiserver/pkg/cel/library#Authz\n'authorizer.requestResource' - A CEL ResourceCheck constructed from the 'authorizer' and configured with the\n request resource.\nDocumentation on CEL: https://kubernetes.io/docs/reference/using-api/cel/\n\nRequired.",
+ "name": "name is an identifier for this match condition, used for strategic merging of MatchConditions, as well as providing an identifier for logging purposes. A good name should be descriptive of the associated expression. Name must be a qualified name consisting of alphanumeric characters, '-', '_' or '.', and must start and end with an alphanumeric character (e.g. 'MyName', or 'my.name', or '123-abc', regex used for validation is '([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]') with an optional DNS subdomain prefix and '/' (e.g. 'example.com/MyName')\n\nRequired.",
+ "expression": "expression represents the expression which will be evaluated by CEL. Must evaluate to bool. CEL expressions have access to the contents of the AdmissionRequest and Authorizer, organized into CEL variables:\n\n'object' - The object from the incoming request. The value is null for DELETE requests. 'oldObject' - The existing object. The value is null for CREATE requests. 'request' - Attributes of the admission request(/pkg/apis/admission/types.go#AdmissionRequest). 'authorizer' - A CEL Authorizer. May be used to perform authorization checks for the principal (user or service account) of the request.\n See https://pkg.go.dev/k8s.io/apiserver/pkg/cel/library#Authz\n'authorizer.requestResource' - A CEL ResourceCheck constructed from the 'authorizer' and configured with the\n request resource.\nDocumentation on CEL: https://kubernetes.io/docs/reference/using-api/cel/\n\nRequired.",
}
func (MatchCondition) SwaggerDoc() map[string]string {
@@ -77,10 +77,10 @@ func (MatchCondition) SwaggerDoc() map[string]string {
var map_MatchResources = map[string]string{
"": "MatchResources decides whether to run the admission control policy on an object based on whether it meets the match criteria. The exclude rules take precedence over include rules (if a resource matches both, it is excluded)",
- "namespaceSelector": "NamespaceSelector decides whether to run the admission control policy on an object based on whether the namespace for that object matches the selector. If the object itself is a namespace, the matching is performed on object.metadata.labels. If the object is another cluster scoped resource, it never skips the policy.\n\nFor example, to run the webhook on any objects whose namespace is not associated with \"runlevel\" of \"0\" or \"1\"; you will set the selector as follows: \"namespaceSelector\": {\n \"matchExpressions\": [\n {\n \"key\": \"runlevel\",\n \"operator\": \"NotIn\",\n \"values\": [\n \"0\",\n \"1\"\n ]\n }\n ]\n}\n\nIf instead you want to only run the policy on any objects whose namespace is associated with the \"environment\" of \"prod\" or \"staging\"; you will set the selector as follows: \"namespaceSelector\": {\n \"matchExpressions\": [\n {\n \"key\": \"environment\",\n \"operator\": \"In\",\n \"values\": [\n \"prod\",\n \"staging\"\n ]\n }\n ]\n}\n\nSee https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ for more examples of label selectors.\n\nDefault to the empty LabelSelector, which matches everything.",
- "objectSelector": "ObjectSelector decides whether to run the validation based on if the object has matching labels. objectSelector is evaluated against both the oldObject and newObject that would be sent to the cel validation, and is considered to match if either object matches the selector. A null object (oldObject in the case of create, or newObject in the case of delete) or an object that cannot have labels (like a DeploymentRollback or a PodProxyOptions object) is not considered to match. Use the object selector only if the webhook is opt-in, because end users may skip the admission webhook by setting the labels. Default to the empty LabelSelector, which matches everything.",
- "resourceRules": "ResourceRules describes what operations on what resources/subresources the ValidatingAdmissionPolicy matches. The policy cares about an operation if it matches _any_ Rule.",
- "excludeResourceRules": "ExcludeResourceRules describes what operations on what resources/subresources the ValidatingAdmissionPolicy should not care about. The exclude rules take precedence over include rules (if a resource matches both, it is excluded)",
+ "namespaceSelector": "namespaceSelector decides whether to run the admission control policy on an object based on whether the namespace for that object matches the selector. If the object itself is a namespace, the matching is performed on object.metadata.labels. If the object is another cluster scoped resource, it never skips the policy.\n\nFor example, to run the webhook on any objects whose namespace is not associated with \"runlevel\" of \"0\" or \"1\"; you will set the selector as follows: \"namespaceSelector\": {\n \"matchExpressions\": [\n {\n \"key\": \"runlevel\",\n \"operator\": \"NotIn\",\n \"values\": [\n \"0\",\n \"1\"\n ]\n }\n ]\n}\n\nIf instead you want to only run the policy on any objects whose namespace is associated with the \"environment\" of \"prod\" or \"staging\"; you will set the selector as follows: \"namespaceSelector\": {\n \"matchExpressions\": [\n {\n \"key\": \"environment\",\n \"operator\": \"In\",\n \"values\": [\n \"prod\",\n \"staging\"\n ]\n }\n ]\n}\n\nSee https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ for more examples of label selectors.\n\nDefault to the empty LabelSelector, which matches everything.",
+ "objectSelector": "objectSelector decides whether to run the validation based on if the object has matching labels. objectSelector is evaluated against both the oldObject and newObject that would be sent to the cel validation, and is considered to match if either object matches the selector. A null object (oldObject in the case of create, or newObject in the case of delete) or an object that cannot have labels (like a DeploymentRollback or a PodProxyOptions object) is not considered to match. Use the object selector only if the webhook is opt-in, because end users may skip the admission webhook by setting the labels. Default to the empty LabelSelector, which matches everything.",
+ "resourceRules": "resourceRules describes what operations on what resources/subresources the ValidatingAdmissionPolicy matches. The policy cares about an operation if it matches _any_ Rule.",
+ "excludeResourceRules": "excludeResourceRules describes what operations on what resources/subresources the ValidatingAdmissionPolicy should not care about. The exclude rules take precedence over include rules (if a resource matches both, it is excluded)",
"matchPolicy": "matchPolicy defines how the \"MatchResources\" list is used to match incoming requests. Allowed values are \"Exact\" or \"Equivalent\".\n\n- Exact: match a request only if it exactly matches a specified rule. For example, if deployments can be modified via apps/v1, apps/v1beta1, and extensions/v1beta1, but \"rules\" only included `apiGroups:[\"apps\"], apiVersions:[\"v1\"], resources: [\"deployments\"]`, a request to apps/v1beta1 or extensions/v1beta1 would not be sent to the ValidatingAdmissionPolicy.\n\n- Equivalent: match a request if modifies a resource listed in rules, even via another API group or version. For example, if deployments can be modified via apps/v1, apps/v1beta1, and extensions/v1beta1, and \"rules\" only included `apiGroups:[\"apps\"], apiVersions:[\"v1\"], resources: [\"deployments\"]`, a request to apps/v1beta1 or extensions/v1beta1 would be converted to apps/v1 and sent to the ValidatingAdmissionPolicy.\n\nDefaults to \"Equivalent\"",
}
@@ -90,8 +90,8 @@ func (MatchResources) SwaggerDoc() map[string]string {
var map_MutatingAdmissionPolicy = map[string]string{
"": "MutatingAdmissionPolicy describes the definition of an admission mutation policy that mutates the object coming into admission chain.",
- "metadata": "Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.",
- "spec": "Specification of the desired behavior of the MutatingAdmissionPolicy.",
+ "metadata": "metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.",
+ "spec": "spec defines the desired behavior of the MutatingAdmissionPolicy.",
}
func (MutatingAdmissionPolicy) SwaggerDoc() map[string]string {
@@ -100,8 +100,8 @@ func (MutatingAdmissionPolicy) SwaggerDoc() map[string]string {
var map_MutatingAdmissionPolicyBinding = map[string]string{
"": "MutatingAdmissionPolicyBinding binds the MutatingAdmissionPolicy with parametrized resources. MutatingAdmissionPolicyBinding and the optional parameter resource together define how cluster administrators configure policies for clusters.\n\nFor a given admission request, each binding will cause its policy to be evaluated N times, where N is 1 for policies/bindings that don't use params, otherwise N is the number of parameters selected by the binding. Each evaluation is constrained by a [runtime cost budget](https://kubernetes.io/docs/reference/using-api/cel/#runtime-cost-budget).\n\nAdding/removing policies, bindings, or params can not affect whether a given (policy, binding, param) combination is within its own CEL budget.",
- "metadata": "Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.",
- "spec": "Specification of the desired behavior of the MutatingAdmissionPolicyBinding.",
+ "metadata": "metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.",
+ "spec": "spec defines the desired behavior of the MutatingAdmissionPolicyBinding.",
}
func (MutatingAdmissionPolicyBinding) SwaggerDoc() map[string]string {
@@ -110,7 +110,7 @@ func (MutatingAdmissionPolicyBinding) SwaggerDoc() map[string]string {
var map_MutatingAdmissionPolicyBindingList = map[string]string{
"": "MutatingAdmissionPolicyBindingList is a list of MutatingAdmissionPolicyBinding.",
- "metadata": "Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds",
+ "metadata": "metadata is the standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds",
"items": "List of PolicyBinding.",
}
@@ -131,7 +131,7 @@ func (MutatingAdmissionPolicyBindingSpec) SwaggerDoc() map[string]string {
var map_MutatingAdmissionPolicyList = map[string]string{
"": "MutatingAdmissionPolicyList is a list of MutatingAdmissionPolicy.",
- "metadata": "Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds",
+ "metadata": "metadata is the standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds",
"items": "List of ValidatingAdmissionPolicy.",
}
@@ -156,18 +156,18 @@ func (MutatingAdmissionPolicySpec) SwaggerDoc() map[string]string {
var map_MutatingWebhook = map[string]string{
"": "MutatingWebhook describes an admission webhook and the resources and operations it applies to.",
- "name": "The name of the admission webhook. Name should be fully qualified, e.g., imagepolicy.kubernetes.io, where \"imagepolicy\" is the name of the webhook, and kubernetes.io is the name of the organization. Required.",
- "clientConfig": "ClientConfig defines how to communicate with the hook. Required",
- "rules": "Rules describes what operations on what resources/subresources the webhook cares about. The webhook cares about an operation if it matches _any_ Rule. However, in order to prevent ValidatingAdmissionWebhooks and MutatingAdmissionWebhooks from putting the cluster in a state which cannot be recovered from without completely disabling the plugin, ValidatingAdmissionWebhooks and MutatingAdmissionWebhooks are never called on admission requests for ValidatingWebhookConfiguration and MutatingWebhookConfiguration objects.",
- "failurePolicy": "FailurePolicy defines how unrecognized errors from the admission endpoint are handled - allowed values are Ignore or Fail. Defaults to Ignore.",
+ "name": "name is the name of the admission webhook. Name should be fully qualified, e.g., imagepolicy.kubernetes.io, where \"imagepolicy\" is the name of the webhook, and kubernetes.io is the name of the organization. Required.",
+ "clientConfig": "clientConfig defines how to communicate with the hook. Required",
+ "rules": "rules describes what operations on what resources/subresources the webhook cares about. The webhook cares about an operation if it matches _any_ Rule. However, in order to prevent ValidatingAdmissionWebhooks and MutatingAdmissionWebhooks from putting the cluster in a state which cannot be recovered from without completely disabling the plugin, ValidatingAdmissionWebhooks and MutatingAdmissionWebhooks are never called on admission requests for ValidatingWebhookConfiguration and MutatingWebhookConfiguration objects.",
+ "failurePolicy": "failurePolicy defines how unrecognized errors from the admission endpoint are handled - allowed values are Ignore or Fail. Defaults to Ignore.",
"matchPolicy": "matchPolicy defines how the \"rules\" list is used to match incoming requests. Allowed values are \"Exact\" or \"Equivalent\".\n\n- Exact: match a request only if it exactly matches a specified rule. For example, if deployments can be modified via apps/v1, apps/v1beta1, and extensions/v1beta1, but \"rules\" only included `apiGroups:[\"apps\"], apiVersions:[\"v1\"], resources: [\"deployments\"]`, a request to apps/v1beta1 or extensions/v1beta1 would not be sent to the webhook.\n\n- Equivalent: match a request if modifies a resource listed in rules, even via another API group or version. For example, if deployments can be modified via apps/v1, apps/v1beta1, and extensions/v1beta1, and \"rules\" only included `apiGroups:[\"apps\"], apiVersions:[\"v1\"], resources: [\"deployments\"]`, a request to apps/v1beta1 or extensions/v1beta1 would be converted to apps/v1 and sent to the webhook.\n\nDefaults to \"Exact\"",
- "namespaceSelector": "NamespaceSelector decides whether to run the webhook on an object based on whether the namespace for that object matches the selector. If the object itself is a namespace, the matching is performed on object.metadata.labels. If the object is another cluster scoped resource, it never skips the webhook.\n\nFor example, to run the webhook on any objects whose namespace is not associated with \"runlevel\" of \"0\" or \"1\"; you will set the selector as follows: \"namespaceSelector\": {\n \"matchExpressions\": [\n {\n \"key\": \"runlevel\",\n \"operator\": \"NotIn\",\n \"values\": [\n \"0\",\n \"1\"\n ]\n }\n ]\n}\n\nIf instead you want to only run the webhook on any objects whose namespace is associated with the \"environment\" of \"prod\" or \"staging\"; you will set the selector as follows: \"namespaceSelector\": {\n \"matchExpressions\": [\n {\n \"key\": \"environment\",\n \"operator\": \"In\",\n \"values\": [\n \"prod\",\n \"staging\"\n ]\n }\n ]\n}\n\nSee https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ for more examples of label selectors.\n\nDefault to the empty LabelSelector, which matches everything.",
- "objectSelector": "ObjectSelector decides whether to run the webhook based on if the object has matching labels. objectSelector is evaluated against both the oldObject and newObject that would be sent to the webhook, and is considered to match if either object matches the selector. A null object (oldObject in the case of create, or newObject in the case of delete) or an object that cannot have labels (like a DeploymentRollback or a PodProxyOptions object) is not considered to match. Use the object selector only if the webhook is opt-in, because end users may skip the admission webhook by setting the labels. Default to the empty LabelSelector, which matches everything.",
- "sideEffects": "SideEffects states whether this webhook has side effects. Acceptable values are: Unknown, None, Some, NoneOnDryRun Webhooks with side effects MUST implement a reconciliation system, since a request may be rejected by a future step in the admission chain and the side effects therefore need to be undone. Requests with the dryRun attribute will be auto-rejected if they match a webhook with sideEffects == Unknown or Some. Defaults to Unknown.",
- "timeoutSeconds": "TimeoutSeconds specifies the timeout for this webhook. After the timeout passes, the webhook call will be ignored or the API call will fail based on the failure policy. The timeout value must be between 1 and 30 seconds. Default to 30 seconds.",
- "admissionReviewVersions": "AdmissionReviewVersions is an ordered list of preferred `AdmissionReview` versions the Webhook expects. API server will try to use first version in the list which it supports. If none of the versions specified in this list supported by API server, validation will fail for this object. If a persisted webhook configuration specifies allowed versions and does not include any versions known to the API Server, calls to the webhook will fail and be subject to the failure policy. Default to `['v1beta1']`.",
+ "namespaceSelector": "namespaceSelector decides whether to run the webhook on an object based on whether the namespace for that object matches the selector. If the object itself is a namespace, the matching is performed on object.metadata.labels. If the object is another cluster scoped resource, it never skips the webhook.\n\nFor example, to run the webhook on any objects whose namespace is not associated with \"runlevel\" of \"0\" or \"1\"; you will set the selector as follows: \"namespaceSelector\": {\n \"matchExpressions\": [\n {\n \"key\": \"runlevel\",\n \"operator\": \"NotIn\",\n \"values\": [\n \"0\",\n \"1\"\n ]\n }\n ]\n}\n\nIf instead you want to only run the webhook on any objects whose namespace is associated with the \"environment\" of \"prod\" or \"staging\"; you will set the selector as follows: \"namespaceSelector\": {\n \"matchExpressions\": [\n {\n \"key\": \"environment\",\n \"operator\": \"In\",\n \"values\": [\n \"prod\",\n \"staging\"\n ]\n }\n ]\n}\n\nSee https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ for more examples of label selectors.\n\nDefault to the empty LabelSelector, which matches everything.",
+ "objectSelector": "objectSelector decides whether to run the webhook based on if the object has matching labels. objectSelector is evaluated against both the oldObject and newObject that would be sent to the webhook, and is considered to match if either object matches the selector. A null object (oldObject in the case of create, or newObject in the case of delete) or an object that cannot have labels (like a DeploymentRollback or a PodProxyOptions object) is not considered to match. Use the object selector only if the webhook is opt-in, because end users may skip the admission webhook by setting the labels. Default to the empty LabelSelector, which matches everything.",
+ "sideEffects": "sideEffects states whether this webhook has side effects. Acceptable values are: Unknown, None, Some, NoneOnDryRun Webhooks with side effects MUST implement a reconciliation system, since a request may be rejected by a future step in the admission chain and the side effects therefore need to be undone. Requests with the dryRun attribute will be auto-rejected if they match a webhook with sideEffects == Unknown or Some. Defaults to Unknown.",
+ "timeoutSeconds": "timeoutSeconds specifies the timeout for this webhook. After the timeout passes, the webhook call will be ignored or the API call will fail based on the failure policy. The timeout value must be between 1 and 30 seconds. Default to 30 seconds.",
+ "admissionReviewVersions": "admissionReviewVersions is an ordered list of preferred `AdmissionReview` versions the Webhook expects. API server will try to use first version in the list which it supports. If none of the versions specified in this list supported by API server, validation will fail for this object. If a persisted webhook configuration specifies allowed versions and does not include any versions known to the API Server, calls to the webhook will fail and be subject to the failure policy. Default to `['v1beta1']`.",
"reinvocationPolicy": "reinvocationPolicy indicates whether this webhook should be called multiple times as part of a single admission evaluation. Allowed values are \"Never\" and \"IfNeeded\".\n\nNever: the webhook will not be called more than once in a single admission evaluation.\n\nIfNeeded: the webhook will be called at least one additional time as part of the admission evaluation if the object being admitted is modified by other admission plugins after the initial webhook call. Webhooks that specify this option *must* be idempotent, able to process objects they previously admitted. Note: * the number of additional invocations is not guaranteed to be exactly one. * if additional invocations result in further modifications to the object, webhooks are not guaranteed to be invoked again. * webhooks that use this option may be reordered to minimize the number of additional invocations. * to validate an object after all mutations are guaranteed complete, use a validating admission webhook instead.\n\nDefaults to \"Never\".",
- "matchConditions": "MatchConditions is a list of conditions that must be met for a request to be sent to this webhook. Match conditions filter requests that have already been matched by the rules, namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests. There are a maximum of 64 match conditions allowed.\n\nThe exact matching logic is (in order):\n 1. If ANY matchCondition evaluates to FALSE, the webhook is skipped.\n 2. If ALL matchConditions evaluate to TRUE, the webhook is called.\n 3. If any matchCondition evaluates to an error (but none are FALSE):\n - If failurePolicy=Fail, reject the request\n - If failurePolicy=Ignore, the error is ignored and the webhook is skipped",
+ "matchConditions": "matchConditions is a list of conditions that must be met for a request to be sent to this webhook. Match conditions filter requests that have already been matched by the rules, namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests. There are a maximum of 64 match conditions allowed.\n\nThe exact matching logic is (in order):\n 1. If ANY matchCondition evaluates to FALSE, the webhook is skipped.\n 2. If ALL matchConditions evaluate to TRUE, the webhook is called.\n 3. If any matchCondition evaluates to an error (but none are FALSE):\n - If failurePolicy=Fail, reject the request\n - If failurePolicy=Ignore, the error is ignored and the webhook is skipped",
}
func (MutatingWebhook) SwaggerDoc() map[string]string {
@@ -176,8 +176,8 @@ func (MutatingWebhook) SwaggerDoc() map[string]string {
var map_MutatingWebhookConfiguration = map[string]string{
"": "MutatingWebhookConfiguration describes the configuration of and admission webhook that accept or reject and may change the object. Deprecated in v1.16, planned for removal in v1.19. Use admissionregistration.k8s.io/v1 MutatingWebhookConfiguration instead.",
- "metadata": "Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.",
- "webhooks": "Webhooks is a list of webhooks and the affected resources and operations.",
+ "metadata": "metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.",
+ "webhooks": "webhooks is a list of webhooks and the affected resources and operations.",
}
func (MutatingWebhookConfiguration) SwaggerDoc() map[string]string {
@@ -186,7 +186,7 @@ func (MutatingWebhookConfiguration) SwaggerDoc() map[string]string {
var map_MutatingWebhookConfigurationList = map[string]string{
"": "MutatingWebhookConfigurationList is a list of MutatingWebhookConfiguration.",
- "metadata": "Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds",
+ "metadata": "metadata is the standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds",
"items": "List of MutatingWebhookConfiguration.",
}
@@ -207,7 +207,7 @@ func (Mutation) SwaggerDoc() map[string]string {
var map_NamedRuleWithOperations = map[string]string{
"": "NamedRuleWithOperations is a tuple of Operations and Resources with ResourceNames.",
- "resourceNames": "ResourceNames is an optional white list of names that the rule applies to. An empty set means that everything is allowed.",
+ "resourceNames": "resourceNames is an optional white list of names that the rule applies to. An empty set means that everything is allowed.",
}
func (NamedRuleWithOperations) SwaggerDoc() map[string]string {
@@ -216,8 +216,8 @@ func (NamedRuleWithOperations) SwaggerDoc() map[string]string {
var map_ParamKind = map[string]string{
"": "ParamKind is a tuple of Group Kind and Version.",
- "apiVersion": "APIVersion is the API group version the resources belong to. In format of \"group/version\". Required.",
- "kind": "Kind is the API kind the resources belong to. Required.",
+ "apiVersion": "apiVersion is the API group version the resources belong to. In format of \"group/version\". Required.",
+ "kind": "kind is the API kind the resources belong to. Required.",
}
func (ParamKind) SwaggerDoc() map[string]string {
@@ -229,7 +229,7 @@ var map_ParamRef = map[string]string{
"name": "name is the name of the resource being referenced.\n\nOne of `name` or `selector` must be set, but `name` and `selector` are mutually exclusive properties. If one is set, the other must be unset.\n\nA single parameter used for all admission requests can be configured by setting the `name` field, leaving `selector` blank, and setting namespace if `paramKind` is namespace-scoped.",
"namespace": "namespace is the namespace of the referenced resource. Allows limiting the search for params to a specific namespace. Applies to both `name` and `selector` fields.\n\nA per-namespace parameter may be used by specifying a namespace-scoped `paramKind` in the policy and leaving this field empty.\n\n- If `paramKind` is cluster-scoped, this field MUST be unset. Setting this field results in a configuration error.\n\n- If `paramKind` is namespace-scoped, the namespace of the object being evaluated for admission will be used when this field is left unset. Take care that if this is left empty the binding must not match any cluster-scoped resources, which will result in an error.",
"selector": "selector can be used to match multiple param objects based on their labels. Supply selector: {} to match all resources of the ParamKind.\n\nIf multiple params are found, they are all evaluated with the policy expressions and the results are ANDed together.\n\nOne of `name` or `selector` must be set, but `name` and `selector` are mutually exclusive properties. If one is set, the other must be unset.",
- "parameterNotFoundAction": "`parameterNotFoundAction` controls the behavior of the binding when the resource exists, and name or selector is valid, but there are no parameters matched by the binding. If the value is set to `Allow`, then no matched parameters will be treated as successful validation by the binding. If set to `Deny`, then no matched parameters will be subject to the `failurePolicy` of the policy.\n\nAllowed values are `Allow` or `Deny`\n\nRequired",
+ "parameterNotFoundAction": "parameterNotFoundAction controls the behavior of the binding when the resource exists, and name or selector is valid, but there are no parameters matched by the binding. If the value is set to `Allow`, then no matched parameters will be treated as successful validation by the binding. If set to `Deny`, then no matched parameters will be subject to the `failurePolicy` of the policy.\n\nAllowed values are `Allow` or `Deny`\n\nRequired",
}
func (ParamRef) SwaggerDoc() map[string]string {
@@ -238,10 +238,10 @@ func (ParamRef) SwaggerDoc() map[string]string {
var map_ServiceReference = map[string]string{
"": "ServiceReference holds a reference to Service.legacy.k8s.io",
- "namespace": "`namespace` is the namespace of the service. Required",
- "name": "`name` is the name of the service. Required",
- "path": "`path` is an optional URL path which will be sent in any request to this service.",
- "port": "If specified, the port on the service that hosting webhook. Default to 443 for backward compatibility. `port` should be a valid port number (1-65535, inclusive).",
+ "namespace": "namespace is the namespace of the service. Required",
+ "name": "name is the name of the service. Required",
+ "path": "path is an optional URL path which will be sent in any request to this service.",
+ "port": "port is the port on the service that hosts the webhook. Default to 443 for backward compatibility. port should be a valid port number (1-65535, inclusive).",
}
func (ServiceReference) SwaggerDoc() map[string]string {
@@ -250,7 +250,7 @@ func (ServiceReference) SwaggerDoc() map[string]string {
var map_TypeChecking = map[string]string{
"": "TypeChecking contains results of type checking the expressions in the ValidatingAdmissionPolicy",
- "expressionWarnings": "The type checking warnings for each expression.",
+ "expressionWarnings": "expressionWarnings contains the type checking warnings for each expression.",
}
func (TypeChecking) SwaggerDoc() map[string]string {
@@ -259,9 +259,9 @@ func (TypeChecking) SwaggerDoc() map[string]string {
var map_ValidatingAdmissionPolicy = map[string]string{
"": "ValidatingAdmissionPolicy describes the definition of an admission validation policy that accepts or rejects an object without changing it.",
- "metadata": "Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.",
- "spec": "Specification of the desired behavior of the ValidatingAdmissionPolicy.",
- "status": "The status of the ValidatingAdmissionPolicy, including warnings that are useful to determine if the policy behaves in the expected way. Populated by the system. Read-only.",
+ "metadata": "metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.",
+ "spec": "spec defines the desired behavior of the ValidatingAdmissionPolicy.",
+ "status": "status represents the current status of the ValidatingAdmissionPolicy, including warnings that are useful to determine if the policy behaves in the expected way. Populated by the system. Read-only.",
}
func (ValidatingAdmissionPolicy) SwaggerDoc() map[string]string {
@@ -270,8 +270,8 @@ func (ValidatingAdmissionPolicy) SwaggerDoc() map[string]string {
var map_ValidatingAdmissionPolicyBinding = map[string]string{
"": "ValidatingAdmissionPolicyBinding binds the ValidatingAdmissionPolicy with paramerized resources. ValidatingAdmissionPolicyBinding and parameter CRDs together define how cluster administrators configure policies for clusters.\n\nFor a given admission request, each binding will cause its policy to be evaluated N times, where N is 1 for policies/bindings that don't use params, otherwise N is the number of parameters selected by the binding.\n\nThe CEL expressions of a policy must have a computed CEL cost below the maximum CEL budget. Each evaluation of the policy is given an independent CEL cost budget. Adding/removing policies, bindings, or params can not affect whether a given (policy, binding, param) combination is within its own CEL budget.",
- "metadata": "Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.",
- "spec": "Specification of the desired behavior of the ValidatingAdmissionPolicyBinding.",
+ "metadata": "metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.",
+ "spec": "spec defines the desired behavior of the ValidatingAdmissionPolicyBinding.",
}
func (ValidatingAdmissionPolicyBinding) SwaggerDoc() map[string]string {
@@ -280,7 +280,7 @@ func (ValidatingAdmissionPolicyBinding) SwaggerDoc() map[string]string {
var map_ValidatingAdmissionPolicyBindingList = map[string]string{
"": "ValidatingAdmissionPolicyBindingList is a list of ValidatingAdmissionPolicyBinding.",
- "metadata": "Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds",
+ "metadata": "metadata is the standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds",
"items": "List of PolicyBinding.",
}
@@ -290,9 +290,9 @@ func (ValidatingAdmissionPolicyBindingList) SwaggerDoc() map[string]string {
var map_ValidatingAdmissionPolicyBindingSpec = map[string]string{
"": "ValidatingAdmissionPolicyBindingSpec is the specification of the ValidatingAdmissionPolicyBinding.",
- "policyName": "PolicyName references a ValidatingAdmissionPolicy name which the ValidatingAdmissionPolicyBinding binds to. If the referenced resource does not exist, this binding is considered invalid and will be ignored Required.",
+ "policyName": "policyName references a ValidatingAdmissionPolicy name which the ValidatingAdmissionPolicyBinding binds to. If the referenced resource does not exist, this binding is considered invalid and will be ignored Required.",
"paramRef": "paramRef specifies the parameter resource used to configure the admission control policy. It should point to a resource of the type specified in ParamKind of the bound ValidatingAdmissionPolicy. If the policy specifies a ParamKind and the resource referred to by ParamRef does not exist, this binding is considered mis-configured and the FailurePolicy of the ValidatingAdmissionPolicy applied. If the policy does not specify a ParamKind then this field is ignored, and the rules are evaluated without a param.",
- "matchResources": "MatchResources declares what resources match this binding and will be validated by it. Note that this is intersected with the policy's matchConstraints, so only requests that are matched by the policy can be selected by this. If this is unset, all resources matched by the policy are validated by this binding When resourceRules is unset, it does not constrain resource matching. If a resource is matched by the other fields of this object, it will be validated. Note that this is differs from ValidatingAdmissionPolicy matchConstraints, where resourceRules are required.",
+ "matchResources": "matchResources declares what resources match this binding and will be validated by it. Note that this is intersected with the policy's matchConstraints, so only requests that are matched by the policy can be selected by this. If this is unset, all resources matched by the policy are validated by this binding When resourceRules is unset, it does not constrain resource matching. If a resource is matched by the other fields of this object, it will be validated. Note that this is differs from ValidatingAdmissionPolicy matchConstraints, where resourceRules are required.",
"validationActions": "validationActions declares how Validations of the referenced ValidatingAdmissionPolicy are enforced. If a validation evaluates to false it is always enforced according to these actions.\n\nFailures defined by the ValidatingAdmissionPolicy's FailurePolicy are enforced according to these actions only if the FailurePolicy is set to Fail, otherwise the failures are ignored. This includes compilation errors, runtime errors and misconfigurations of the policy.\n\nvalidationActions is declared as a set of action values. Order does not matter. validationActions may not contain duplicates of the same action.\n\nThe supported actions values are:\n\n\"Deny\" specifies that a validation failure results in a denied request.\n\n\"Warn\" specifies that a validation failure is reported to the request client in HTTP Warning headers, with a warning code of 299. Warnings can be sent both for allowed or denied admission responses.\n\n\"Audit\" specifies that a validation failure is included in the published audit event for the request. The audit event will contain a `validation.policy.admission.k8s.io/validation_failure` audit annotation with a value containing the details of the validation failures, formatted as a JSON list of objects, each with the following fields: - message: The validation failure message string - policy: The resource name of the ValidatingAdmissionPolicy - binding: The resource name of the ValidatingAdmissionPolicyBinding - expressionIndex: The index of the failed validations in the ValidatingAdmissionPolicy - validationActions: The enforcement actions enacted for the validation failure Example audit annotation: `\"validation.policy.admission.k8s.io/validation_failure\": \"[{\"message\": \"Invalid value\", {\"policy\": \"policy.example.com\", {\"binding\": \"policybinding.example.com\", {\"expressionIndex\": \"1\", {\"validationActions\": [\"Audit\"]}]\"`\n\nClients should expect to handle additional values by ignoring any values not recognized.\n\n\"Deny\" and \"Warn\" may not be used together since this combination needlessly duplicates the validation failure both in the API response body and the HTTP warning headers.\n\nRequired.",
}
@@ -302,7 +302,7 @@ func (ValidatingAdmissionPolicyBindingSpec) SwaggerDoc() map[string]string {
var map_ValidatingAdmissionPolicyList = map[string]string{
"": "ValidatingAdmissionPolicyList is a list of ValidatingAdmissionPolicy.",
- "metadata": "Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds",
+ "metadata": "metadata is the standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds",
"items": "List of ValidatingAdmissionPolicy.",
}
@@ -312,13 +312,13 @@ func (ValidatingAdmissionPolicyList) SwaggerDoc() map[string]string {
var map_ValidatingAdmissionPolicySpec = map[string]string{
"": "ValidatingAdmissionPolicySpec is the specification of the desired behavior of the AdmissionPolicy.",
- "paramKind": "ParamKind specifies the kind of resources used to parameterize this policy. If absent, there are no parameters for this policy and the param CEL variable will not be provided to validation expressions. If ParamKind refers to a non-existent kind, this policy definition is mis-configured and the FailurePolicy is applied. If paramKind is specified but paramRef is unset in ValidatingAdmissionPolicyBinding, the params variable will be null.",
- "matchConstraints": "MatchConstraints specifies what resources this policy is designed to validate. The AdmissionPolicy cares about a request if it matches _all_ Constraints. However, in order to prevent clusters from being put into an unstable state that cannot be recovered from via the API ValidatingAdmissionPolicy cannot match ValidatingAdmissionPolicy and ValidatingAdmissionPolicyBinding. Required.",
- "validations": "Validations contain CEL expressions which is used to apply the validation. Validations and AuditAnnotations may not both be empty; a minimum of one Validations or AuditAnnotations is required.",
+ "paramKind": "paramKind specifies the kind of resources used to parameterize this policy. If absent, there are no parameters for this policy and the param CEL variable will not be provided to validation expressions. If ParamKind refers to a non-existent kind, this policy definition is mis-configured and the FailurePolicy is applied. If paramKind is specified but paramRef is unset in ValidatingAdmissionPolicyBinding, the params variable will be null.",
+ "matchConstraints": "matchConstraints specifies what resources this policy is designed to validate. The AdmissionPolicy cares about a request if it matches _all_ Constraints. However, in order to prevent clusters from being put into an unstable state that cannot be recovered from via the API ValidatingAdmissionPolicy cannot match ValidatingAdmissionPolicy and ValidatingAdmissionPolicyBinding. Required.",
+ "validations": "validations contain CEL expressions which is used to apply the validation. Validations and AuditAnnotations may not both be empty; a minimum of one Validations or AuditAnnotations is required.",
"failurePolicy": "failurePolicy defines how to handle failures for the admission policy. Failures can occur from CEL expression parse errors, type check errors, runtime errors and invalid or mis-configured policy definitions or bindings.\n\nA policy is invalid if spec.paramKind refers to a non-existent Kind. A binding is invalid if spec.paramRef.name refers to a non-existent resource.\n\nfailurePolicy does not define how validations that evaluate to false are handled.\n\nWhen failurePolicy is set to Fail, ValidatingAdmissionPolicyBinding validationActions define how failures are enforced.\n\nAllowed values are Ignore or Fail. Defaults to Fail.",
"auditAnnotations": "auditAnnotations contains CEL expressions which are used to produce audit annotations for the audit event of the API request. validations and auditAnnotations may not both be empty; a least one of validations or auditAnnotations is required.",
- "matchConditions": "MatchConditions is a list of conditions that must be met for a request to be validated. Match conditions filter requests that have already been matched by the rules, namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests. There are a maximum of 64 match conditions allowed.\n\nIf a parameter object is provided, it can be accessed via the `params` handle in the same manner as validation expressions.\n\nThe exact matching logic is (in order):\n 1. If ANY matchCondition evaluates to FALSE, the policy is skipped.\n 2. If ALL matchConditions evaluate to TRUE, the policy is evaluated.\n 3. If any matchCondition evaluates to an error (but none are FALSE):\n - If failurePolicy=Fail, reject the request\n - If failurePolicy=Ignore, the policy is skipped",
- "variables": "Variables contain definitions of variables that can be used in composition of other expressions. Each variable is defined as a named CEL expression. The variables defined here will be available under `variables` in other expressions of the policy except MatchConditions because MatchConditions are evaluated before the rest of the policy.\n\nThe expression of a variable can refer to other variables defined earlier in the list but not those after. Thus, Variables must be sorted by the order of first appearance and acyclic.",
+ "matchConditions": "matchConditions is a list of conditions that must be met for a request to be validated. Match conditions filter requests that have already been matched by the rules, namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests. There are a maximum of 64 match conditions allowed.\n\nIf a parameter object is provided, it can be accessed via the `params` handle in the same manner as validation expressions.\n\nThe exact matching logic is (in order):\n 1. If ANY matchCondition evaluates to FALSE, the policy is skipped.\n 2. If ALL matchConditions evaluate to TRUE, the policy is evaluated.\n 3. If any matchCondition evaluates to an error (but none are FALSE):\n - If failurePolicy=Fail, reject the request\n - If failurePolicy=Ignore, the policy is skipped",
+ "variables": "variables contain definitions of variables that can be used in composition of other expressions. Each variable is defined as a named CEL expression. The variables defined here will be available under `variables` in other expressions of the policy except MatchConditions because MatchConditions are evaluated before the rest of the policy.\n\nThe expression of a variable can refer to other variables defined earlier in the list but not those after. Thus, Variables must be sorted by the order of first appearance and acyclic.",
}
func (ValidatingAdmissionPolicySpec) SwaggerDoc() map[string]string {
@@ -327,9 +327,9 @@ func (ValidatingAdmissionPolicySpec) SwaggerDoc() map[string]string {
var map_ValidatingAdmissionPolicyStatus = map[string]string{
"": "ValidatingAdmissionPolicyStatus represents the status of an admission validation policy.",
- "observedGeneration": "The generation observed by the controller.",
- "typeChecking": "The results of type checking for each expression. Presence of this field indicates the completion of the type checking.",
- "conditions": "The conditions represent the latest available observations of a policy's current state.",
+ "observedGeneration": "observedGeneration is the generation observed by the controller.",
+ "typeChecking": "typeChecking contains the results of type checking for each expression. Presence of this field indicates the completion of the type checking.",
+ "conditions": "conditions represent the latest available observations of a policy's current state.",
}
func (ValidatingAdmissionPolicyStatus) SwaggerDoc() map[string]string {
@@ -338,17 +338,17 @@ func (ValidatingAdmissionPolicyStatus) SwaggerDoc() map[string]string {
var map_ValidatingWebhook = map[string]string{
"": "ValidatingWebhook describes an admission webhook and the resources and operations it applies to.",
- "name": "The name of the admission webhook. Name should be fully qualified, e.g., imagepolicy.kubernetes.io, where \"imagepolicy\" is the name of the webhook, and kubernetes.io is the name of the organization. Required.",
- "clientConfig": "ClientConfig defines how to communicate with the hook. Required",
- "rules": "Rules describes what operations on what resources/subresources the webhook cares about. The webhook cares about an operation if it matches _any_ Rule. However, in order to prevent ValidatingAdmissionWebhooks and MutatingAdmissionWebhooks from putting the cluster in a state which cannot be recovered from without completely disabling the plugin, ValidatingAdmissionWebhooks and MutatingAdmissionWebhooks are never called on admission requests for ValidatingWebhookConfiguration and MutatingWebhookConfiguration objects.",
- "failurePolicy": "FailurePolicy defines how unrecognized errors from the admission endpoint are handled - allowed values are Ignore or Fail. Defaults to Ignore.",
+ "name": "name is the name of the admission webhook. Name should be fully qualified, e.g., imagepolicy.kubernetes.io, where \"imagepolicy\" is the name of the webhook, and kubernetes.io is the name of the organization. Required.",
+ "clientConfig": "clientConfig defines how to communicate with the hook. Required",
+ "rules": "rules describes what operations on what resources/subresources the webhook cares about. The webhook cares about an operation if it matches _any_ Rule. However, in order to prevent ValidatingAdmissionWebhooks and MutatingAdmissionWebhooks from putting the cluster in a state which cannot be recovered from without completely disabling the plugin, ValidatingAdmissionWebhooks and MutatingAdmissionWebhooks are never called on admission requests for ValidatingWebhookConfiguration and MutatingWebhookConfiguration objects.",
+ "failurePolicy": "failurePolicy defines how unrecognized errors from the admission endpoint are handled - allowed values are Ignore or Fail. Defaults to Ignore.",
"matchPolicy": "matchPolicy defines how the \"rules\" list is used to match incoming requests. Allowed values are \"Exact\" or \"Equivalent\".\n\n- Exact: match a request only if it exactly matches a specified rule. For example, if deployments can be modified via apps/v1, apps/v1beta1, and extensions/v1beta1, but \"rules\" only included `apiGroups:[\"apps\"], apiVersions:[\"v1\"], resources: [\"deployments\"]`, a request to apps/v1beta1 or extensions/v1beta1 would not be sent to the webhook.\n\n- Equivalent: match a request if modifies a resource listed in rules, even via another API group or version. For example, if deployments can be modified via apps/v1, apps/v1beta1, and extensions/v1beta1, and \"rules\" only included `apiGroups:[\"apps\"], apiVersions:[\"v1\"], resources: [\"deployments\"]`, a request to apps/v1beta1 or extensions/v1beta1 would be converted to apps/v1 and sent to the webhook.\n\nDefaults to \"Exact\"",
- "namespaceSelector": "NamespaceSelector decides whether to run the webhook on an object based on whether the namespace for that object matches the selector. If the object itself is a namespace, the matching is performed on object.metadata.labels. If the object is another cluster scoped resource, it never skips the webhook.\n\nFor example, to run the webhook on any objects whose namespace is not associated with \"runlevel\" of \"0\" or \"1\"; you will set the selector as follows: \"namespaceSelector\": {\n \"matchExpressions\": [\n {\n \"key\": \"runlevel\",\n \"operator\": \"NotIn\",\n \"values\": [\n \"0\",\n \"1\"\n ]\n }\n ]\n}\n\nIf instead you want to only run the webhook on any objects whose namespace is associated with the \"environment\" of \"prod\" or \"staging\"; you will set the selector as follows: \"namespaceSelector\": {\n \"matchExpressions\": [\n {\n \"key\": \"environment\",\n \"operator\": \"In\",\n \"values\": [\n \"prod\",\n \"staging\"\n ]\n }\n ]\n}\n\nSee https://kubernetes.io/docs/concepts/overview/working-with-objects/labels for more examples of label selectors.\n\nDefault to the empty LabelSelector, which matches everything.",
- "objectSelector": "ObjectSelector decides whether to run the webhook based on if the object has matching labels. objectSelector is evaluated against both the oldObject and newObject that would be sent to the webhook, and is considered to match if either object matches the selector. A null object (oldObject in the case of create, or newObject in the case of delete) or an object that cannot have labels (like a DeploymentRollback or a PodProxyOptions object) is not considered to match. Use the object selector only if the webhook is opt-in, because end users may skip the admission webhook by setting the labels. Default to the empty LabelSelector, which matches everything.",
- "sideEffects": "SideEffects states whether this webhook has side effects. Acceptable values are: Unknown, None, Some, NoneOnDryRun Webhooks with side effects MUST implement a reconciliation system, since a request may be rejected by a future step in the admission chain and the side effects therefore need to be undone. Requests with the dryRun attribute will be auto-rejected if they match a webhook with sideEffects == Unknown or Some. Defaults to Unknown.",
- "timeoutSeconds": "TimeoutSeconds specifies the timeout for this webhook. After the timeout passes, the webhook call will be ignored or the API call will fail based on the failure policy. The timeout value must be between 1 and 30 seconds. Default to 30 seconds.",
- "admissionReviewVersions": "AdmissionReviewVersions is an ordered list of preferred `AdmissionReview` versions the Webhook expects. API server will try to use first version in the list which it supports. If none of the versions specified in this list supported by API server, validation will fail for this object. If a persisted webhook configuration specifies allowed versions and does not include any versions known to the API Server, calls to the webhook will fail and be subject to the failure policy. Default to `['v1beta1']`.",
- "matchConditions": "MatchConditions is a list of conditions that must be met for a request to be sent to this webhook. Match conditions filter requests that have already been matched by the rules, namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests. There are a maximum of 64 match conditions allowed.\n\nThe exact matching logic is (in order):\n 1. If ANY matchCondition evaluates to FALSE, the webhook is skipped.\n 2. If ALL matchConditions evaluate to TRUE, the webhook is called.\n 3. If any matchCondition evaluates to an error (but none are FALSE):\n - If failurePolicy=Fail, reject the request\n - If failurePolicy=Ignore, the error is ignored and the webhook is skipped",
+ "namespaceSelector": "namespaceSelector decides whether to run the webhook on an object based on whether the namespace for that object matches the selector. If the object itself is a namespace, the matching is performed on object.metadata.labels. If the object is another cluster scoped resource, it never skips the webhook.\n\nFor example, to run the webhook on any objects whose namespace is not associated with \"runlevel\" of \"0\" or \"1\"; you will set the selector as follows: \"namespaceSelector\": {\n \"matchExpressions\": [\n {\n \"key\": \"runlevel\",\n \"operator\": \"NotIn\",\n \"values\": [\n \"0\",\n \"1\"\n ]\n }\n ]\n}\n\nIf instead you want to only run the webhook on any objects whose namespace is associated with the \"environment\" of \"prod\" or \"staging\"; you will set the selector as follows: \"namespaceSelector\": {\n \"matchExpressions\": [\n {\n \"key\": \"environment\",\n \"operator\": \"In\",\n \"values\": [\n \"prod\",\n \"staging\"\n ]\n }\n ]\n}\n\nSee https://kubernetes.io/docs/concepts/overview/working-with-objects/labels for more examples of label selectors.\n\nDefault to the empty LabelSelector, which matches everything.",
+ "objectSelector": "objectSelector decides whether to run the webhook based on if the object has matching labels. objectSelector is evaluated against both the oldObject and newObject that would be sent to the webhook, and is considered to match if either object matches the selector. A null object (oldObject in the case of create, or newObject in the case of delete) or an object that cannot have labels (like a DeploymentRollback or a PodProxyOptions object) is not considered to match. Use the object selector only if the webhook is opt-in, because end users may skip the admission webhook by setting the labels. Default to the empty LabelSelector, which matches everything.",
+ "sideEffects": "sideEffects states whether this webhook has side effects. Acceptable values are: Unknown, None, Some, NoneOnDryRun Webhooks with side effects MUST implement a reconciliation system, since a request may be rejected by a future step in the admission chain and the side effects therefore need to be undone. Requests with the dryRun attribute will be auto-rejected if they match a webhook with sideEffects == Unknown or Some. Defaults to Unknown.",
+ "timeoutSeconds": "timeoutSeconds specifies the timeout for this webhook. After the timeout passes, the webhook call will be ignored or the API call will fail based on the failure policy. The timeout value must be between 1 and 30 seconds. Default to 30 seconds.",
+ "admissionReviewVersions": "admissionReviewVersions is an ordered list of preferred `AdmissionReview` versions the Webhook expects. API server will try to use first version in the list which it supports. If none of the versions specified in this list supported by API server, validation will fail for this object. If a persisted webhook configuration specifies allowed versions and does not include any versions known to the API Server, calls to the webhook will fail and be subject to the failure policy. Default to `['v1beta1']`.",
+ "matchConditions": "matchConditions is a list of conditions that must be met for a request to be sent to this webhook. Match conditions filter requests that have already been matched by the rules, namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests. There are a maximum of 64 match conditions allowed.\n\nThe exact matching logic is (in order):\n 1. If ANY matchCondition evaluates to FALSE, the webhook is skipped.\n 2. If ALL matchConditions evaluate to TRUE, the webhook is called.\n 3. If any matchCondition evaluates to an error (but none are FALSE):\n - If failurePolicy=Fail, reject the request\n - If failurePolicy=Ignore, the error is ignored and the webhook is skipped",
}
func (ValidatingWebhook) SwaggerDoc() map[string]string {
@@ -357,8 +357,8 @@ func (ValidatingWebhook) SwaggerDoc() map[string]string {
var map_ValidatingWebhookConfiguration = map[string]string{
"": "ValidatingWebhookConfiguration describes the configuration of and admission webhook that accept or reject and object without changing it. Deprecated in v1.16, planned for removal in v1.19. Use admissionregistration.k8s.io/v1 ValidatingWebhookConfiguration instead.",
- "metadata": "Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.",
- "webhooks": "Webhooks is a list of webhooks and the affected resources and operations.",
+ "metadata": "metadata is the standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.",
+ "webhooks": "webhooks is a list of webhooks and the affected resources and operations.",
}
func (ValidatingWebhookConfiguration) SwaggerDoc() map[string]string {
@@ -367,7 +367,7 @@ func (ValidatingWebhookConfiguration) SwaggerDoc() map[string]string {
var map_ValidatingWebhookConfigurationList = map[string]string{
"": "ValidatingWebhookConfigurationList is a list of ValidatingWebhookConfiguration.",
- "metadata": "Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds",
+ "metadata": "metadata is the standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds",
"items": "List of ValidatingWebhookConfiguration.",
}
@@ -377,9 +377,9 @@ func (ValidatingWebhookConfigurationList) SwaggerDoc() map[string]string {
var map_Validation = map[string]string{
"": "Validation specifies the CEL expression which is used to apply the validation.",
- "expression": "Expression represents the expression which will be evaluated by CEL. ref: https://github.com/google/cel-spec CEL expressions have access to the contents of the API request/response, organized into CEL variables as well as some other useful variables:\n\n- 'object' - The object from the incoming request. The value is null for DELETE requests. - 'oldObject' - The existing object. The value is null for CREATE requests. - 'request' - Attributes of the API request([ref](/pkg/apis/admission/types.go#AdmissionRequest)). - 'params' - Parameter resource referred to by the policy binding being evaluated. Only populated if the policy has a ParamKind. - 'namespaceObject' - The namespace object that the incoming object belongs to. The value is null for cluster-scoped resources. - 'variables' - Map of composited variables, from its name to its lazily evaluated value.\n For example, a variable named 'foo' can be accessed as 'variables.foo'.\n- 'authorizer' - A CEL Authorizer. May be used to perform authorization checks for the principal (user or service account) of the request.\n See https://pkg.go.dev/k8s.io/apiserver/pkg/cel/library#Authz\n- 'authorizer.requestResource' - A CEL ResourceCheck constructed from the 'authorizer' and configured with the\n request resource.\n\nThe `apiVersion`, `kind`, `metadata.name` and `metadata.generateName` are always accessible from the root of the object. No other metadata properties are accessible.\n\nOnly property names of the form `[a-zA-Z_.-/][a-zA-Z0-9_.-/]*` are accessible. Accessible property names are escaped according to the following rules when accessed in the expression: - '__' escapes to '__underscores__' - '.' escapes to '__dot__' - '-' escapes to '__dash__' - '/' escapes to '__slash__' - Property names that exactly match a CEL RESERVED keyword escape to '__{keyword}__'. The keywords are:\n\t \"true\", \"false\", \"null\", \"in\", \"as\", \"break\", \"const\", \"continue\", \"else\", \"for\", \"function\", \"if\",\n\t \"import\", \"let\", \"loop\", \"package\", \"namespace\", \"return\".\nExamples:\n - Expression accessing a property named \"namespace\": {\"Expression\": \"object.__namespace__ > 0\"}\n - Expression accessing a property named \"x-prop\": {\"Expression\": \"object.x__dash__prop > 0\"}\n - Expression accessing a property named \"redact__d\": {\"Expression\": \"object.redact__underscores__d > 0\"}\n\nEquality on arrays with list type of 'set' or 'map' ignores element order, i.e. [1, 2] == [2, 1]. Concatenation on arrays with x-kubernetes-list-type use the semantics of the list type:\n - 'set': `X + Y` performs a union where the array positions of all elements in `X` are preserved and\n non-intersecting elements in `Y` are appended, retaining their partial order.\n - 'map': `X + Y` performs a merge where the array positions of all keys in `X` are preserved but the values\n are overwritten by values in `Y` when the key sets of `X` and `Y` intersect. Elements in `Y` with\n non-intersecting keys are appended, retaining their partial order.\nRequired.",
- "message": "Message represents the message displayed when validation fails. The message is required if the Expression contains line breaks. The message must not contain line breaks. If unset, the message is \"failed rule: {Rule}\". e.g. \"must be a URL with the host matching spec.host\" If the Expression contains line breaks. Message is required. The message must not contain line breaks. If unset, the message is \"failed Expression: {Expression}\".",
- "reason": "Reason represents a machine-readable description of why this validation failed. If this is the first validation in the list to fail, this reason, as well as the corresponding HTTP response code, are used in the HTTP response to the client. The currently supported reasons are: \"Unauthorized\", \"Forbidden\", \"Invalid\", \"RequestEntityTooLarge\". If not set, StatusReasonInvalid is used in the response to the client.",
+ "expression": "expression represents the expression which will be evaluated by CEL. ref: https://github.com/google/cel-spec CEL expressions have access to the contents of the API request/response, organized into CEL variables as well as some other useful variables:\n\n- 'object' - The object from the incoming request. The value is null for DELETE requests. - 'oldObject' - The existing object. The value is null for CREATE requests. - 'request' - Attributes of the API request([ref](/pkg/apis/admission/types.go#AdmissionRequest)). - 'params' - Parameter resource referred to by the policy binding being evaluated. Only populated if the policy has a ParamKind. - 'namespaceObject' - The namespace object that the incoming object belongs to. The value is null for cluster-scoped resources. - 'variables' - Map of composited variables, from its name to its lazily evaluated value.\n For example, a variable named 'foo' can be accessed as 'variables.foo'.\n- 'authorizer' - A CEL Authorizer. May be used to perform authorization checks for the principal (user or service account) of the request.\n See https://pkg.go.dev/k8s.io/apiserver/pkg/cel/library#Authz\n- 'authorizer.requestResource' - A CEL ResourceCheck constructed from the 'authorizer' and configured with the\n request resource.\n\nThe `apiVersion`, `kind`, `metadata.name` and `metadata.generateName` are always accessible from the root of the object. No other metadata properties are accessible.\n\nOnly property names of the form `[a-zA-Z_.-/][a-zA-Z0-9_.-/]*` are accessible. Accessible property names are escaped according to the following rules when accessed in the expression: - '__' escapes to '__underscores__' - '.' escapes to '__dot__' - '-' escapes to '__dash__' - '/' escapes to '__slash__' - Property names that exactly match a CEL RESERVED keyword escape to '__{keyword}__'. The keywords are:\n\t \"true\", \"false\", \"null\", \"in\", \"as\", \"break\", \"const\", \"continue\", \"else\", \"for\", \"function\", \"if\",\n\t \"import\", \"let\", \"loop\", \"package\", \"namespace\", \"return\".\nExamples:\n - Expression accessing a property named \"namespace\": {\"Expression\": \"object.__namespace__ > 0\"}\n - Expression accessing a property named \"x-prop\": {\"Expression\": \"object.x__dash__prop > 0\"}\n - Expression accessing a property named \"redact__d\": {\"Expression\": \"object.redact__underscores__d > 0\"}\n\nEquality on arrays with list type of 'set' or 'map' ignores element order, i.e. [1, 2] == [2, 1]. Concatenation on arrays with x-kubernetes-list-type use the semantics of the list type:\n - 'set': `X + Y` performs a union where the array positions of all elements in `X` are preserved and\n non-intersecting elements in `Y` are appended, retaining their partial order.\n - 'map': `X + Y` performs a merge where the array positions of all keys in `X` are preserved but the values\n are overwritten by values in `Y` when the key sets of `X` and `Y` intersect. Elements in `Y` with\n non-intersecting keys are appended, retaining their partial order.\nRequired.",
+ "message": "message represents the message displayed when validation fails. The message is required if the Expression contains line breaks. The message must not contain line breaks. If unset, the message is \"failed rule: {Rule}\". e.g. \"must be a URL with the host matching spec.host\" If the Expression contains line breaks. Message is required. The message must not contain line breaks. If unset, the message is \"failed Expression: {Expression}\".",
+ "reason": "reason represents a machine-readable description of why this validation failed. If this is the first validation in the list to fail, this reason, as well as the corresponding HTTP response code, are used in the HTTP response to the client. The currently supported reasons are: \"Unauthorized\", \"Forbidden\", \"Invalid\", \"RequestEntityTooLarge\". If not set, StatusReasonInvalid is used in the response to the client.",
"messageExpression": "messageExpression declares a CEL expression that evaluates to the validation failure message that is returned when this rule fails. Since messageExpression is used as a failure message, it must evaluate to a string. If both message and messageExpression are present on a validation, then messageExpression will be used if validation fails. If messageExpression results in a runtime error, the runtime error is logged, and the validation failure message is produced as if the messageExpression field were unset. If messageExpression evaluates to an empty string, a string with only spaces, or a string that contains line breaks, then the validation failure message will also be produced as if the messageExpression field were unset, and the fact that messageExpression produced an empty string/string with only spaces/string with line breaks will be logged. messageExpression has access to all the same variables as the `expression` except for 'authorizer' and 'authorizer.requestResource'. Example: \"object.x must be less than max (\"+string(params.max)+\")\"",
}
@@ -389,8 +389,8 @@ func (Validation) SwaggerDoc() map[string]string {
var map_Variable = map[string]string{
"": "Variable is the definition of a variable that is used for composition. A variable is defined as a named expression.",
- "name": "Name is the name of the variable. The name must be a valid CEL identifier and unique among all variables. The variable can be accessed in other expressions through `variables` For example, if name is \"foo\", the variable will be available as `variables.foo`",
- "expression": "Expression is the expression that will be evaluated as the value of the variable. The CEL expression has access to the same identifiers as the CEL expressions in Validation.",
+ "name": "name is the name of the variable. The name must be a valid CEL identifier and unique among all variables. The variable can be accessed in other expressions through `variables` For example, if name is \"foo\", the variable will be available as `variables.foo`",
+ "expression": "expression is the expression that will be evaluated as the value of the variable. The CEL expression has access to the same identifiers as the CEL expressions in Validation.",
}
func (Variable) SwaggerDoc() map[string]string {
@@ -399,9 +399,9 @@ func (Variable) SwaggerDoc() map[string]string {
var map_WebhookClientConfig = map[string]string{
"": "WebhookClientConfig contains the information to make a TLS connection with the webhook",
- "url": "`url` gives the location of the webhook, in standard URL form (`scheme://host:port/path`). Exactly one of `url` or `service` must be specified.\n\nThe `host` should not refer to a service running in the cluster; use the `service` field instead. The host might be resolved via external DNS in some apiservers (e.g., `kube-apiserver` cannot resolve in-cluster DNS as that would be a layering violation). `host` may also be an IP address.\n\nPlease note that using `localhost` or `127.0.0.1` as a `host` is risky unless you take great care to run this webhook on all hosts which run an apiserver which might need to make calls to this webhook. Such installs are likely to be non-portable, i.e., not easy to turn up in a new cluster.\n\nThe scheme must be \"https\"; the URL must begin with \"https://\".\n\nA path is optional, and if present may be any string permissible in a URL. You may use the path to pass an arbitrary string to the webhook, for example, a cluster identifier.\n\nAttempting to use a user or basic auth e.g. \"user:password@\" is not allowed. Fragments (\"#...\") and query parameters (\"?...\") are not allowed, either.",
- "service": "`service` is a reference to the service for this webhook. Either `service` or `url` must be specified.\n\nIf the webhook is running within the cluster, then you should use `service`.",
- "caBundle": "`caBundle` is a PEM encoded CA bundle which will be used to validate the webhook's server certificate. If unspecified, system trust roots on the apiserver are used.",
+ "url": "url gives the location of the webhook, in standard URL form (`scheme://host:port/path`). Exactly one of `url` or `service` must be specified.\n\nThe `host` should not refer to a service running in the cluster; use the `service` field instead. The host might be resolved via external DNS in some apiservers (e.g., `kube-apiserver` cannot resolve in-cluster DNS as that would be a layering violation). `host` may also be an IP address.\n\nPlease note that using `localhost` or `127.0.0.1` as a `host` is risky unless you take great care to run this webhook on all hosts which run an apiserver which might need to make calls to this webhook. Such installs are likely to be non-portable, i.e., not easy to turn up in a new cluster.\n\nThe scheme must be \"https\"; the URL must begin with \"https://\".\n\nA path is optional, and if present may be any string permissible in a URL. You may use the path to pass an arbitrary string to the webhook, for example, a cluster identifier.\n\nAttempting to use a user or basic auth e.g. \"user:password@\" is not allowed. Fragments (\"#...\") and query parameters (\"?...\") are not allowed, either.",
+ "service": "service is a reference to the service for this webhook. Either `service` or `url` must be specified.\n\nIf the webhook is running within the cluster, then you should use `service`.",
+ "caBundle": "caBundle is a PEM encoded CA bundle which will be used to validate the webhook's server certificate. If unspecified, system trust roots on the apiserver are used.",
}
func (WebhookClientConfig) SwaggerDoc() map[string]string {
diff --git a/vendor/k8s.io/api/admissionregistration/v1beta1/zz_generated.prerelease-lifecycle.go b/vendor/k8s.io/api/admissionregistration/v1beta1/zz_generated.prerelease-lifecycle.go
index 4fc0596b3..80064734e 100644
--- a/vendor/k8s.io/api/admissionregistration/v1beta1/zz_generated.prerelease-lifecycle.go
+++ b/vendor/k8s.io/api/admissionregistration/v1beta1/zz_generated.prerelease-lifecycle.go
@@ -37,6 +37,12 @@ func (in *MutatingAdmissionPolicy) APILifecycleDeprecated() (major, minor int) {
return 1, 37
}
+// APILifecycleReplacement is an autogenerated function, returning the group, version, and kind that should be used instead of this deprecated type.
+// It is controlled by "k8s:prerelease-lifecycle-gen:replacement=,," tags in types.go.
+func (in *MutatingAdmissionPolicy) APILifecycleReplacement() schema.GroupVersionKind {
+ return schema.GroupVersionKind{Group: "admissionregistration.k8s.io", Version: "v1", Kind: "MutatingAdmissionPolicy"}
+}
+
// APILifecycleRemoved is an autogenerated function, returning the release in which the API is no longer served as int versions of major and minor for comparison.
// It is controlled by "k8s:prerelease-lifecycle-gen:removed" tags in types.go or "k8s:prerelease-lifecycle-gen:deprecated" plus three minor.
func (in *MutatingAdmissionPolicy) APILifecycleRemoved() (major, minor int) {
@@ -55,6 +61,12 @@ func (in *MutatingAdmissionPolicyBinding) APILifecycleDeprecated() (major, minor
return 1, 37
}
+// APILifecycleReplacement is an autogenerated function, returning the group, version, and kind that should be used instead of this deprecated type.
+// It is controlled by "k8s:prerelease-lifecycle-gen:replacement=,," tags in types.go.
+func (in *MutatingAdmissionPolicyBinding) APILifecycleReplacement() schema.GroupVersionKind {
+ return schema.GroupVersionKind{Group: "admissionregistration.k8s.io", Version: "v1", Kind: "MutatingAdmissionPolicyBinding"}
+}
+
// APILifecycleRemoved is an autogenerated function, returning the release in which the API is no longer served as int versions of major and minor for comparison.
// It is controlled by "k8s:prerelease-lifecycle-gen:removed" tags in types.go or "k8s:prerelease-lifecycle-gen:deprecated" plus three minor.
func (in *MutatingAdmissionPolicyBinding) APILifecycleRemoved() (major, minor int) {
@@ -73,6 +85,12 @@ func (in *MutatingAdmissionPolicyBindingList) APILifecycleDeprecated() (major, m
return 1, 37
}
+// APILifecycleReplacement is an autogenerated function, returning the group, version, and kind that should be used instead of this deprecated type.
+// It is controlled by "k8s:prerelease-lifecycle-gen:replacement=,," tags in types.go.
+func (in *MutatingAdmissionPolicyBindingList) APILifecycleReplacement() schema.GroupVersionKind {
+ return schema.GroupVersionKind{Group: "admissionregistration.k8s.io", Version: "v1", Kind: "MutatingAdmissionPolicyBindingList"}
+}
+
// APILifecycleRemoved is an autogenerated function, returning the release in which the API is no longer served as int versions of major and minor for comparison.
// It is controlled by "k8s:prerelease-lifecycle-gen:removed" tags in types.go or "k8s:prerelease-lifecycle-gen:deprecated" plus three minor.
func (in *MutatingAdmissionPolicyBindingList) APILifecycleRemoved() (major, minor int) {
@@ -91,6 +109,12 @@ func (in *MutatingAdmissionPolicyList) APILifecycleDeprecated() (major, minor in
return 1, 37
}
+// APILifecycleReplacement is an autogenerated function, returning the group, version, and kind that should be used instead of this deprecated type.
+// It is controlled by "k8s:prerelease-lifecycle-gen:replacement=,," tags in types.go.
+func (in *MutatingAdmissionPolicyList) APILifecycleReplacement() schema.GroupVersionKind {
+ return schema.GroupVersionKind{Group: "admissionregistration.k8s.io", Version: "v1", Kind: "MutatingAdmissionPolicyList"}
+}
+
// APILifecycleRemoved is an autogenerated function, returning the release in which the API is no longer served as int versions of major and minor for comparison.
// It is controlled by "k8s:prerelease-lifecycle-gen:removed" tags in types.go or "k8s:prerelease-lifecycle-gen:deprecated" plus three minor.
func (in *MutatingAdmissionPolicyList) APILifecycleRemoved() (major, minor int) {
diff --git a/vendor/k8s.io/api/apidiscovery/v2/generated.proto b/vendor/k8s.io/api/apidiscovery/v2/generated.proto
index 62f2d7f2c..7f58048e1 100644
--- a/vendor/k8s.io/api/apidiscovery/v2/generated.proto
+++ b/vendor/k8s.io/api/apidiscovery/v2/generated.proto
@@ -32,7 +32,7 @@ option go_package = "k8s.io/api/apidiscovery/v2";
// It contains a list of APIVersionDiscovery that holds a list of APIResourceDiscovery types served for a version.
// Versions are in descending order of preference, with the first version being the preferred entry.
message APIGroupDiscovery {
- // Standard object's metadata.
+ // metadata is standard object's metadata.
// The only field completed will be name. For instance, resourceVersion will be empty.
// name is the name of the API group whose discovery information is presented here.
// name is allowed to be "" to represent the legacy, ungroupified resources.
diff --git a/vendor/k8s.io/api/apidiscovery/v2/generated.protomessage.pb.go b/vendor/k8s.io/api/apidiscovery/v2/generated.protomessage.pb.go
deleted file mode 100644
index 35fe0d2a8..000000000
--- a/vendor/k8s.io/api/apidiscovery/v2/generated.protomessage.pb.go
+++ /dev/null
@@ -1,32 +0,0 @@
-//go:build kubernetes_protomessage_one_more_release
-// +build kubernetes_protomessage_one_more_release
-
-/*
-Copyright The Kubernetes Authors.
-
-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.
-*/
-
-// Code generated by go-to-protobuf. DO NOT EDIT.
-
-package v2
-
-func (*APIGroupDiscovery) ProtoMessage() {}
-
-func (*APIGroupDiscoveryList) ProtoMessage() {}
-
-func (*APIResourceDiscovery) ProtoMessage() {}
-
-func (*APISubresourceDiscovery) ProtoMessage() {}
-
-func (*APIVersionDiscovery) ProtoMessage() {}
diff --git a/vendor/k8s.io/api/apidiscovery/v2/types.go b/vendor/k8s.io/api/apidiscovery/v2/types.go
index 449679b61..761bb6990 100644
--- a/vendor/k8s.io/api/apidiscovery/v2/types.go
+++ b/vendor/k8s.io/api/apidiscovery/v2/types.go
@@ -45,7 +45,7 @@ type APIGroupDiscoveryList struct {
// Versions are in descending order of preference, with the first version being the preferred entry.
type APIGroupDiscovery struct {
v1.TypeMeta `json:",inline"`
- // Standard object's metadata.
+ // metadata is standard object's metadata.
// The only field completed will be name. For instance, resourceVersion will be empty.
// name is the name of the API group whose discovery information is presented here.
// name is allowed to be "" to represent the legacy, ungroupified resources.
diff --git a/vendor/k8s.io/api/apidiscovery/v2beta1/generated.proto b/vendor/k8s.io/api/apidiscovery/v2beta1/generated.proto
index e9ae88072..f81449e6a 100644
--- a/vendor/k8s.io/api/apidiscovery/v2beta1/generated.proto
+++ b/vendor/k8s.io/api/apidiscovery/v2beta1/generated.proto
@@ -32,7 +32,7 @@ option go_package = "k8s.io/api/apidiscovery/v2beta1";
// It contains a list of APIVersionDiscovery that holds a list of APIResourceDiscovery types served for a version.
// Versions are in descending order of preference, with the first version being the preferred entry.
message APIGroupDiscovery {
- // Standard object's metadata.
+ // metadata is standard object's metadata.
// The only field completed will be name. For instance, resourceVersion will be empty.
// name is the name of the API group whose discovery information is presented here.
// name is allowed to be "" to represent the legacy, ungroupified resources.
diff --git a/vendor/k8s.io/api/apidiscovery/v2beta1/generated.protomessage.pb.go b/vendor/k8s.io/api/apidiscovery/v2beta1/generated.protomessage.pb.go
deleted file mode 100644
index 0998c461b..000000000
--- a/vendor/k8s.io/api/apidiscovery/v2beta1/generated.protomessage.pb.go
+++ /dev/null
@@ -1,32 +0,0 @@
-//go:build kubernetes_protomessage_one_more_release
-// +build kubernetes_protomessage_one_more_release
-
-/*
-Copyright The Kubernetes Authors.
-
-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.
-*/
-
-// Code generated by go-to-protobuf. DO NOT EDIT.
-
-package v2beta1
-
-func (*APIGroupDiscovery) ProtoMessage() {}
-
-func (*APIGroupDiscoveryList) ProtoMessage() {}
-
-func (*APIResourceDiscovery) ProtoMessage() {}
-
-func (*APISubresourceDiscovery) ProtoMessage() {}
-
-func (*APIVersionDiscovery) ProtoMessage() {}
diff --git a/vendor/k8s.io/api/apidiscovery/v2beta1/types.go b/vendor/k8s.io/api/apidiscovery/v2beta1/types.go
index 834293773..306264da4 100644
--- a/vendor/k8s.io/api/apidiscovery/v2beta1/types.go
+++ b/vendor/k8s.io/api/apidiscovery/v2beta1/types.go
@@ -51,7 +51,7 @@ type APIGroupDiscoveryList struct {
// Versions are in descending order of preference, with the first version being the preferred entry.
type APIGroupDiscovery struct {
v1.TypeMeta `json:",inline"`
- // Standard object's metadata.
+ // metadata is standard object's metadata.
// The only field completed will be name. For instance, resourceVersion will be empty.
// name is the name of the API group whose discovery information is presented here.
// name is allowed to be "" to represent the legacy, ungroupified resources.
diff --git a/vendor/k8s.io/api/apiserverinternal/v1alpha1/generated.proto b/vendor/k8s.io/api/apiserverinternal/v1alpha1/generated.proto
index 8a7786072..e8f8c339d 100644
--- a/vendor/k8s.io/api/apiserverinternal/v1alpha1/generated.proto
+++ b/vendor/k8s.io/api/apiserverinternal/v1alpha1/generated.proto
@@ -31,59 +31,69 @@ option go_package = "k8s.io/api/apiserverinternal/v1alpha1";
// An API server instance reports the version it can decode and the version it
// encodes objects to when persisting objects in the backend.
message ServerStorageVersion {
- // The ID of the reporting API server.
+ // apiServerID is the ID of the reporting API server.
+ // +required
optional string apiServerID = 1;
- // The API server encodes the object to this version when persisting it in
+ // encodingVersion the API server encodes the object to when persisting it in
// the backend (e.g., etcd).
+ // +required
optional string encodingVersion = 2;
+ // decodableVersions are the encoding versions the API server can handle to decode.
// The API server can decode objects encoded in these versions.
// The encodingVersion must be included in the decodableVersions.
// +listType=set
+ // +required
repeated string decodableVersions = 3;
- // The API server can serve these versions.
+ // servedVersions lists all versions the API server can serve.
// DecodableVersions must include all ServedVersions.
// +listType=set
+ // +optional
repeated string servedVersions = 4;
}
// Storage version of a specific resource.
message StorageVersion {
+ // metadata is the standard object metadata.
// The name is .